mirror of
https://github.com/acamarata/pray-calc.git
synced 2026-07-02 20:00:40 +00:00
chore: bump to v2.1.1
- Flatten exports map to ADR-015 standard - Add coverage script (c8) - Migrate CI to corepack enable
This commit is contained in:
parent
bdb0615c16
commit
cbe283aaf8
5 changed files with 168 additions and 187 deletions
|
|
@ -1 +0,0 @@
|
||||||
CLAUDE.md
|
|
||||||
116
.claude/AGENTS.md
Normal file
116
.claude/AGENTS.md
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
# pray-calc — PRI (Per-Repo Instructions)
|
||||||
|
|
||||||
|
**Cascade:** GCI → ASI → PPI (`/Volumes/X9/Sites/acamarata/.claude/CLAUDE.md`) → **PRI (this file)**
|
||||||
|
|
||||||
|
## What This Is
|
||||||
|
|
||||||
|
High-precision Islamic prayer times calculator in TypeScript. Computes Fajr, Dhuhr, Asr,
|
||||||
|
Maghrib, Isha, Qiyam, Sunrise, and solar Noon for any location on Earth. Uses a physics-
|
||||||
|
grounded dynamic twilight angle algorithm as the primary method. Includes 14 traditional
|
||||||
|
fixed-angle methods for direct comparison.
|
||||||
|
|
||||||
|
**npm:** `pray-calc@2.1.0`
|
||||||
|
**Language:** TypeScript source → dual CJS/ESM build (tsup)
|
||||||
|
**Node requirement:** >=20
|
||||||
|
**License:** MIT
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **nrel-spa** (^2.0.1) — NREL Solar Position Algorithm (zero-dep, sync, acamarata's own)
|
||||||
|
- No moon dependency. Moon data: use `moon-sighting` package.
|
||||||
|
|
||||||
|
Dev: @types/node, tsup, typescript
|
||||||
|
|
||||||
|
## v2 API Surface
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Core functions
|
||||||
|
getTimes(date, lat, lng, tz?, elevation?, temperature?, pressure?, hanafi?): PrayerTimes
|
||||||
|
calcTimes(...): FormattedPrayerTimes
|
||||||
|
getTimesAll(...): PrayerTimesAll
|
||||||
|
calcTimesAll(...): FormattedPrayerTimesAll
|
||||||
|
|
||||||
|
// Low-level
|
||||||
|
getAngles(date, lat, lng, elevation?, temperature?, pressure?): TwilightAngles
|
||||||
|
getAsr(solarNoon, latitude, declination, hanafi?): number
|
||||||
|
getQiyam(fajrTime, ishaTime): number
|
||||||
|
getMscFajr(date, latitude): number // minutes before sunrise
|
||||||
|
getMscIsha(date, latitude, shafaq?): number // minutes after sunset
|
||||||
|
|
||||||
|
// Ephemeris
|
||||||
|
solarEphemeris(jd): { decl, r, eclLon }
|
||||||
|
toJulianDate(date): number
|
||||||
|
|
||||||
|
// Reference data
|
||||||
|
METHODS: MethodDefinition[]
|
||||||
|
```
|
||||||
|
|
||||||
|
`nrel-spa` API (v2.x): `getSpa(date, lat, lng, tz, opts, zeniths)` and `formatTime(h)`
|
||||||
|
Note: `fractalTime` was renamed to `formatTime` in v2.0.0. `fractalTime` does not exist.
|
||||||
|
|
||||||
|
## Module Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── index.ts Main exports
|
||||||
|
├── types.ts All TypeScript types
|
||||||
|
├── getSolarEphemeris.ts Jean Meeus Ch. 25 — decl, r, eclLon
|
||||||
|
├── getMSC.ts MSC piecewise seasonal model
|
||||||
|
├── getAngles.ts Dynamic angle algorithm (3 layers)
|
||||||
|
├── getAsr.ts Pure-math Asr (no SPA dependency)
|
||||||
|
├── getQiyam.ts Last-third-of-night
|
||||||
|
├── getTimes.ts Raw fractional-hour output
|
||||||
|
├── calcTimes.ts Formatted HH:MM:SS output
|
||||||
|
├── getTimesAll.ts All-methods batch SPA call
|
||||||
|
└── calcTimesAll.ts All-methods formatted output
|
||||||
|
```
|
||||||
|
|
||||||
|
## Domain Reference
|
||||||
|
|
||||||
|
Algorithm math, method angle table, and astronomical research facts:
|
||||||
|
— load when working on angle calculations or method constants.
|
||||||
|
|
||||||
|
## getSpa Batch Pattern
|
||||||
|
|
||||||
|
`getTimesAll` uses one SPA call for all 14×2 + 2 dynamic zenith angles:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
allZeniths = [90+fajrAngle, 90+ishaAngle, ...methodZeniths]
|
||||||
|
// methodZeniths: 14 methods × 2 = 28 entries
|
||||||
|
// Methods with null ishaAngle get placeholder 90+18 (overridden post-call)
|
||||||
|
spaData.angles[0].sunrise → dynamic Fajr
|
||||||
|
spaData.angles[1].sunset → dynamic Isha
|
||||||
|
spaData.angles[2+i*2].sunrise → method[i] Fajr
|
||||||
|
spaData.angles[2+i*2+1].sunset → method[i] Isha (if angle-based)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
- `pnpm build` — tsup dual CJS/ESM build
|
||||||
|
- `pnpm run typecheck` — tsc --noEmit
|
||||||
|
- `pnpm test` — build + node test.mjs + node test-cjs.cjs (94 ESM + 12 CJS = 106 tests)
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
|
||||||
|
- **v2.0.0** — TypeScript rewrite, 14 methods, physics corrections, no suncalc, no moon
|
||||||
|
- **v1.7.2** — Last CJS version with moon functions (getMoon, getMoonPhase, etc.)
|
||||||
|
- Moon functions migrated to `moon-sighting` package
|
||||||
|
|
||||||
|
## Moon Migration
|
||||||
|
|
||||||
|
All moon functions removed from v2. Users should:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm add moon-sighting
|
||||||
|
```
|
||||||
|
|
||||||
|
Map: `getMoon` → `getMoon`, `getMoonPhase` → `getMoonPhase`, etc.
|
||||||
|
See `.github/wiki/Moon-Migration.md` for full table. moon-sighting uses Meeus Ch.47/48 +
|
||||||
|
Odeh 2006 visibility, no suncalc dependency.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- nrel-spa: `~/Sites/acamarata/nrel-spa/` — solar foundation
|
||||||
|
- moon-sighting: `~/Sites/acamarata/moon-sighting/` — lunar data
|
||||||
|
- praycalc.com — live demo
|
||||||
|
- praycalc.net — documentation site
|
||||||
20
.github/workflows/ci.yml
vendored
20
.github/workflows/ci.yml
vendored
|
|
@ -15,13 +15,12 @@ jobs:
|
||||||
node-version: [20, 22, 24]
|
node-version: [20, 22, 24]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
with:
|
|
||||||
version: 10
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
- name: Enable corepack
|
||||||
|
run: corepack enable
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- run: pnpm build
|
- run: pnpm build
|
||||||
- run: node --test test.mjs
|
- run: node --test test.mjs
|
||||||
|
|
@ -32,13 +31,12 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
with:
|
|
||||||
version: 10
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
- name: Enable corepack
|
||||||
|
run: corepack enable
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- run: pnpm run lint
|
- run: pnpm run lint
|
||||||
- run: pnpm run format:check
|
- run: pnpm run format:check
|
||||||
|
|
@ -48,13 +46,12 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
with:
|
|
||||||
version: 10
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
- name: Enable corepack
|
||||||
|
run: corepack enable
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- run: pnpm run typecheck
|
- run: pnpm run typecheck
|
||||||
|
|
||||||
|
|
@ -63,13 +60,12 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
with:
|
|
||||||
version: 10
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
- name: Enable corepack
|
||||||
|
run: corepack enable
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- run: pnpm build
|
- run: pnpm build
|
||||||
- name: Verify pack contents
|
- name: Verify pack contents
|
||||||
|
|
|
||||||
21
CHANGELOG.md
Normal file
21
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2.1.1] - 2026-05-28
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Flatten exports map to ADR-015 standard (import/require/types at top level)
|
||||||
|
- Add "./package.json" export condition
|
||||||
|
- Add coverage script (c8 --reporter=lcov)
|
||||||
|
- Migrate CI from pnpm/action-setup to corepack enable
|
||||||
|
|
||||||
|
## [2.1.0] - 2026-05-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial release
|
||||||
174
README.md
174
README.md
|
|
@ -4,12 +4,12 @@
|
||||||
[](https://github.com/acamarata/pray-calc/actions/workflows/ci.yml)
|
[](https://github.com/acamarata/pray-calc/actions/workflows/ci.yml)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
Islamic prayer times for any location and date. The primary method uses a physics-grounded dynamic twilight angle algorithm that adjusts Fajr and Isha angles for latitude, season, Earth-Sun distance, and atmospheric conditions. Fourteen traditional fixed-angle methods are included for direct comparison.
|
Islamic prayer times for any location and date. The primary method uses a physics-grounded dynamic twilight angle algorithm that adjusts Fajr and Isha angles for latitude, season, Earth-Sun distance, and atmospheric conditions. Fourteen traditional fixed-angle methods are included for comparison. Single runtime dependency: [nrel-spa](https://github.com/acamarata/nrel-spa).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm add pray-calc # or npm install pray-calc
|
npm install pray-calc
|
||||||
```
|
```
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
@ -19,9 +19,9 @@ import { calcTimes } from 'pray-calc';
|
||||||
|
|
||||||
const times = calcTimes(
|
const times = calcTimes(
|
||||||
new Date('2024-06-21'),
|
new Date('2024-06-21'),
|
||||||
40.7128, // New York latitude
|
40.7128, // New York latitude
|
||||||
-74.0060, // longitude
|
-74.0060, // longitude
|
||||||
-4, // UTC offset (hours)
|
-4, // UTC offset (hours)
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(times.Fajr); // "03:51:24"
|
console.log(times.Fajr); // "03:51:24"
|
||||||
|
|
@ -30,150 +30,15 @@ console.log(times.Dhuhr); // "13:01:17"
|
||||||
console.log(times.Asr); // "17:02:43"
|
console.log(times.Asr); // "17:02:43"
|
||||||
console.log(times.Maghrib); // "20:31:17"
|
console.log(times.Maghrib); // "20:31:17"
|
||||||
console.log(times.Isha); // "22:07:43"
|
console.log(times.Isha); // "22:07:43"
|
||||||
console.log(times.angles); // { fajrAngle: 14.8, ishaAngle: 14.6 }
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### CJS
|
CommonJS:
|
||||||
|
|
||||||
```javascript
|
```js
|
||||||
const { calcTimes } = require('pray-calc');
|
const { calcTimes } = require('pray-calc');
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compare all methods
|
Use `calcTimesAll` to get all 14 traditional method times alongside the dynamic result.
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { calcTimesAll } from 'pray-calc';
|
|
||||||
|
|
||||||
const all = calcTimesAll(new Date('2024-06-21'), 40.7128, -74.0060, -4);
|
|
||||||
|
|
||||||
// Dynamic primary times
|
|
||||||
console.log(all.Fajr); // "03:51:24"
|
|
||||||
|
|
||||||
// Traditional method comparison
|
|
||||||
console.log(all.Methods.ISNA); // ["03:57:12", "22:22:18"] [fajr, isha]
|
|
||||||
console.log(all.Methods.MWL); // ["03:25:08", "22:40:31"]
|
|
||||||
console.log(all.Methods.MSC); // ["03:53:41", "22:09:12"]
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### `getTimes(date, lat, lng, tz?, elevation?, temperature?, pressure?, hanafi?)`
|
|
||||||
|
|
||||||
Returns raw fractional-hour prayer times using the dynamic method.
|
|
||||||
|
|
||||||
| Parameter | Type | Default | Description |
|
|
||||||
| --------- | ---- | ------- | ----------- |
|
|
||||||
| `date` | `Date` | required | Observer's local date |
|
|
||||||
| `lat` | `number` | required | Latitude, decimal degrees |
|
|
||||||
| `lng` | `number` | required | Longitude, decimal degrees |
|
|
||||||
| `tz` | `number` | system offset | UTC offset in hours |
|
|
||||||
| `elevation` | `number` | `0` | Meters above sea level |
|
|
||||||
| `temperature` | `number` | `15` | Ambient temperature, °C |
|
|
||||||
| `pressure` | `number` | `1013.25` | Atmospheric pressure, mbar |
|
|
||||||
| `hanafi` | `boolean` | `false` | Asr convention: false = Shafi'i, true = Hanafi |
|
|
||||||
|
|
||||||
Returns `PrayerTimes`: `{ Qiyam, Fajr, Sunrise, Noon, Dhuhr, Asr, Maghrib, Isha, Midnight, angles }`.
|
|
||||||
All times are fractional hours in local time (e.g., `5.5` = 05:30:00). `NaN` when an event
|
|
||||||
cannot be computed (polar night, etc.).
|
|
||||||
|
|
||||||
### `calcTimes(date, lat, lng, tz?, elevation?, temperature?, pressure?, hanafi?)`
|
|
||||||
|
|
||||||
Same as `getTimes`, formatted as `HH:MM:SS` strings. Returns `"N/A"` for unavailable times.
|
|
||||||
|
|
||||||
### `getTimesAll(...)`
|
|
||||||
|
|
||||||
Same signature. Returns `PrayerTimesAll`: extends `PrayerTimes` with `Methods`, a record
|
|
||||||
mapping each of the 14 method IDs to `[fajrTime, ishaTime]` as fractional hours.
|
|
||||||
|
|
||||||
### `calcTimesAll(...)`
|
|
||||||
|
|
||||||
Same as `getTimesAll`, fully formatted. `Methods` values are `[fajrString, ishaString]`.
|
|
||||||
|
|
||||||
### `getAngles(date, lat, lng, elevation?, temperature?, pressure?)`
|
|
||||||
|
|
||||||
Returns `{ fajrAngle, ishaAngle }` in degrees (positive = below horizon).
|
|
||||||
|
|
||||||
### `getAsr(solarNoon, latitude, declination, hanafi?)`
|
|
||||||
|
|
||||||
Computes Asr from solar noon time, latitude, and solar declination. Returns fractional hours.
|
|
||||||
|
|
||||||
### `getQiyam(fajrTime, ishaTime)`
|
|
||||||
|
|
||||||
Returns the start of the last third of the night as fractional hours.
|
|
||||||
|
|
||||||
### `getMidnight(maghribTime, endTime)`
|
|
||||||
|
|
||||||
Returns the midpoint of the night as fractional hours. Pass Fajr as `endTime` for the
|
|
||||||
standard definition (Maghrib-to-Fajr midpoint), or Sunrise for the astronomical variant.
|
|
||||||
|
|
||||||
### `getMscFajr(date, latitude)` / `getMscIsha(date, latitude, shafaq?)`
|
|
||||||
|
|
||||||
Moonsighting Committee Worldwide minute offsets: minutes before sunrise (Fajr) and
|
|
||||||
minutes after sunset (Isha). `shafaq` controls which twilight phase is used for Isha:
|
|
||||||
`'general'` (default), `'ahmer'` (red glow), or `'abyad'` (white glow).
|
|
||||||
|
|
||||||
### `METHODS`
|
|
||||||
|
|
||||||
Exported array of all 14 `MethodDefinition` objects.
|
|
||||||
|
|
||||||
## Supported Methods
|
|
||||||
|
|
||||||
| ID | Name | Fajr | Isha | Region |
|
|
||||||
| -- | ---- | ---- | ---- | ------ |
|
|
||||||
| `UOIF` | Union des Organisations Islamiques de France | 12° | 12° | France |
|
|
||||||
| `ISNACA` | IQNA / Islamic Council of North America | 13° | 13° | Canada |
|
|
||||||
| `ISNA` | FCNA / Islamic Society of North America | 15° | 15° | US, UK, AU, NZ |
|
|
||||||
| `SAMR` | Spiritual Administration of Muslims of Russia | 16° | 15° | Russia |
|
|
||||||
| `IGUT` | Institute of Geophysics, Univ. of Tehran | 17.7° | 14° | Iran |
|
|
||||||
| `MWL` | Muslim World League | 18° | 17° | Global |
|
|
||||||
| `DIBT` | Diyanet, Turkey | 18° | 17° | Turkey |
|
|
||||||
| `Karachi` | Univ. of Islamic Sciences, Karachi | 18° | 18° | PK, BD, IN, AF |
|
|
||||||
| `Kuwait` | Kuwait Ministry of Islamic Affairs | 18° | 17.5° | Kuwait |
|
|
||||||
| `UAQ` | Umm Al-Qura Univ., Makkah | 18.5° | +90 min | Saudi Arabia |
|
|
||||||
| `Qatar` | Qatar / Gulf Standard | 18° | +90 min | Qatar, Gulf |
|
|
||||||
| `Egypt` | Egyptian General Authority of Survey | 19.5° | 17.5° | EG, SY, IQ, LB |
|
|
||||||
| `MUIS` | Majlis Ugama Islam Singapura | 20° | 18° | Singapore |
|
|
||||||
| `MSC` | Moonsighting Committee Worldwide | seasonal | seasonal | Global |
|
|
||||||
|
|
||||||
## Dynamic Method
|
|
||||||
|
|
||||||
Standard prayer time libraries use a fixed angle (e.g., MWL: 18°) applied globally.
|
|
||||||
This works near the equator but fails at higher latitudes: above 48.5°N in summer, the
|
|
||||||
Sun never reaches 18° depression, so a 18°-everywhere library produces missing Isha
|
|
||||||
times. Observational campaigns also show that at mid-latitudes, true dawn appears when
|
|
||||||
the Sun is around 14–16° below the horizon, not 18°.
|
|
||||||
|
|
||||||
The dynamic method computes the angle in three layers:
|
|
||||||
|
|
||||||
1. **MSC seasonal base**: Khalid Shaukat's piecewise model, calibrated against field
|
|
||||||
observations across latitudes 0°–55°N/S. Returns minutes before/after sunrise/sunset,
|
|
||||||
converted to depression degrees via spherical trigonometry.
|
|
||||||
|
|
||||||
2. **Physics corrections**: Earth-Sun distance (r via Jean Meeus elliptical orbit),
|
|
||||||
Fourier harmonic smoothing, atmospheric refraction at the computed altitude, and
|
|
||||||
elevation horizon dip.
|
|
||||||
|
|
||||||
3. **Physical bounds**: clipped to [10°, 22°].
|
|
||||||
|
|
||||||
At the equator the result converges to approximately 18°, consistent with historical
|
|
||||||
usage. At 50–55°N in summer it falls to 12–14°, matching empirical UK observations.
|
|
||||||
|
|
||||||
Full detail: [Dynamic Algorithm wiki page](https://github.com/acamarata/pray-calc/wiki/Dynamic-Algorithm)
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
- Only runtime dependency: `nrel-spa` (NREL Solar Position Algorithm)
|
|
||||||
- `getSolarEphemeris`: Jean Meeus Ch. 25: declination, Earth-Sun distance, ecliptic lon
|
|
||||||
- `getTimesAll`: single batch SPA call for all 14×2 + 2 dynamic zenith angles
|
|
||||||
|
|
||||||
Full detail: [Architecture wiki page](https://github.com/acamarata/pray-calc/wiki/Architecture)
|
|
||||||
|
|
||||||
## Compatibility
|
|
||||||
|
|
||||||
- Node.js >= 20
|
|
||||||
- ESM and CJS builds included
|
|
||||||
- TypeScript types bundled
|
|
||||||
- No browser-incompatible APIs
|
|
||||||
|
|
||||||
## TypeScript
|
## TypeScript
|
||||||
|
|
||||||
|
|
@ -182,39 +47,24 @@ import type {
|
||||||
PrayerTimes,
|
PrayerTimes,
|
||||||
FormattedPrayerTimes,
|
FormattedPrayerTimes,
|
||||||
PrayerTimesAll,
|
PrayerTimesAll,
|
||||||
FormattedPrayerTimesAll,
|
|
||||||
TwilightAngles,
|
|
||||||
MethodDefinition,
|
MethodDefinition,
|
||||||
} from 'pray-calc';
|
} from 'pray-calc';
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Full documentation: [GitHub Wiki](https://github.com/acamarata/pray-calc/wiki)
|
Full API reference, dynamic algorithm details, traditional method table, and high-latitude handling: [GitHub Wiki](https://github.com/acamarata/pray-calc/wiki)
|
||||||
|
|
||||||
- [API Reference](https://github.com/acamarata/pray-calc/wiki/API-Reference)
|
|
||||||
- [Dynamic Algorithm](https://github.com/acamarata/pray-calc/wiki/Dynamic-Algorithm)
|
|
||||||
- [Traditional Methods](https://github.com/acamarata/pray-calc/wiki/Traditional-Methods)
|
|
||||||
- [Architecture](https://github.com/acamarata/pray-calc/wiki/Architecture)
|
|
||||||
- [Twilight Physics](https://github.com/acamarata/pray-calc/wiki/Twilight-Physics)
|
|
||||||
- [High-Latitude Handling](https://github.com/acamarata/pray-calc/wiki/High-Latitude)
|
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
- [nrel-spa](https://github.com/acamarata/nrel-spa): NREL Solar Position Algorithm
|
- [nrel-spa](https://github.com/acamarata/nrel-spa): NREL Solar Position Algorithm (the solar foundation)
|
||||||
- [luxon-hijri](https://github.com/acamarata/luxon-hijri): Hijri/Gregorian calendar
|
- [luxon-hijri](https://github.com/acamarata/luxon-hijri): Hijri/Gregorian calendar
|
||||||
- [moon-sighting](https://github.com/acamarata/moon-sighting): Crescent visibility
|
- [moon-sighting](https://github.com/acamarata/moon-sighting): Crescent visibility calculations
|
||||||
|
|
||||||
## Acknowledgments
|
## Acknowledgments
|
||||||
|
|
||||||
The solar position calculations use [nrel-spa](https://github.com/acamarata/nrel-spa), a pure JavaScript port of the Solar Position Algorithm (SPA) developed by Ibrahim Reda and Afshin Andreas at the National Renewable Energy Laboratory (NREL):
|
Solar position calculations use [nrel-spa](https://github.com/acamarata/nrel-spa), a port of the NREL SPA by Ibrahim Reda and Afshin Andreas. The seasonal twilight model builds on the work of Khalid Shaukat (Moonsighting Committee Worldwide).
|
||||||
|
|
||||||
> Reda, I., Andreas, A. (2004). "Solar Position Algorithm for Solar Radiation Applications." Solar Energy, 76(5), 577-589. <https://doi.org/10.1016/j.solener.2003.12.003>
|
|
||||||
|
|
||||||
The seasonal twilight model builds on the work of Khalid Shaukat (Moonsighting Committee Worldwide).
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT. Copyright (c) 2023-2026 Aric Camarata.
|
MIT. Copyright (c) 2023-2026 Aric Camarata.
|
||||||
|
|
||||||
See [LICENSE](LICENSE) for full terms.
|
|
||||||
|
|
|
||||||
23
package.json
23
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "pray-calc",
|
"name": "pray-calc",
|
||||||
"version": "2.1.0",
|
"version": "2.1.1",
|
||||||
"description": "Islamic prayer times with a physics-grounded dynamic twilight angle algorithm. Covers Fajr, Sunrise, Dhuhr, Asr, Maghrib, Isha, Qiyam. Includes 14 traditional fixed-angle methods for comparison.",
|
"description": "Islamic prayer times with a physics-grounded dynamic twilight angle algorithm. Covers Fajr, Sunrise, Dhuhr, Asr, Maghrib, Isha, Qiyam. Includes 14 traditional fixed-angle methods for comparison.",
|
||||||
"author": "Aric Camarata",
|
"author": "Aric Camarata",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -9,15 +9,11 @@
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": {
|
"types": "./dist/index.d.ts",
|
||||||
"types": "./dist/index.d.mts",
|
"import": "./dist/index.mjs",
|
||||||
"default": "./dist/index.mjs"
|
"require": "./dist/index.cjs"
|
||||||
},
|
},
|
||||||
"require": {
|
"./package.json": "./package.json"
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.cjs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"files": [
|
"files": [
|
||||||
|
|
@ -34,7 +30,8 @@
|
||||||
"lint": "eslint src/",
|
"lint": "eslint src/",
|
||||||
"format": "prettier --write src/",
|
"format": "prettier --write src/",
|
||||||
"format:check": "prettier --check src/",
|
"format:check": "prettier --check src/",
|
||||||
"prepublishOnly": "tsup"
|
"prepublishOnly": "tsup",
|
||||||
|
"coverage": "c8 --reporter=lcov --reporter=text node --test"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"prayer-times",
|
"prayer-times",
|
||||||
|
|
@ -82,5 +79,7 @@
|
||||||
"tsup": "^8.5.1",
|
"tsup": "^8.5.1",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.56.1"
|
"typescript-eslint": "^8.56.1"
|
||||||
}
|
},
|
||||||
|
"type": "module",
|
||||||
|
"packageManager": "pnpm@10.11.1"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue