panchang-ts 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -6
- package/dist/calendar/eclipsesTable.cjs +404 -0
- package/dist/calendar/eclipsesTable.d.cts +40 -0
- package/dist/calendar/eclipsesTable.d.ts +40 -0
- package/dist/calendar/eclipsesTable.js +399 -0
- package/dist/calendar/moonPhasesTable.cjs +6811 -0
- package/dist/calendar/moonPhasesTable.d.cts +37 -0
- package/dist/calendar/moonPhasesTable.d.ts +37 -0
- package/dist/calendar/moonPhasesTable.js +6806 -0
- package/dist/eclipsesTableTypes-D-tSQMQd.d.cts +98 -0
- package/dist/eclipsesTableTypes-D-tSQMQd.d.ts +98 -0
- package/dist/index.cjs +361 -16
- package/dist/index.d.cts +166 -1
- package/dist/index.d.ts +166 -1
- package/dist/index.js +357 -17
- package/dist/moonPhasesTableTypes-TH0T5rVD.d.cts +56 -0
- package/dist/moonPhasesTableTypes-TH0T5rVD.d.ts +56 -0
- package/package.json +25 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
Pure TypeScript Hindu Panchang (almanac), Jyotish, and Birth Chart calculations.
|
|
6
6
|
Zero native dependencies. Works offline in React Native (Hermes), Node.js, and browsers.
|
|
7
7
|
|
|
8
|
-
**Fast** (~0.1 ms names-only, ~0.5 ms full) · **Typed** (full TypeScript) · **Offline** (pure JS math) · **8,
|
|
8
|
+
**Fast** (~0.1 ms names-only, ~0.5 ms full) · **Typed** (full TypeScript) · **Offline** (pure JS math) · **8,164 tests across 100 files**
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -290,8 +290,9 @@ FESTIVALS_META.languages; // ["en", "hi"]
|
|
|
290
290
|
This entry point is engine-free — it ships only the JSON + accessors, so
|
|
291
291
|
importing it won't pull the calculation engine into your bundle. Both `en`
|
|
292
292
|
and `hi` are bundled (names *and* descriptions); pass the locale as the
|
|
293
|
-
second argument. Eclipses are excluded (visibility is location-dependent
|
|
294
|
-
|
|
293
|
+
second argument. Eclipses are excluded here (visibility is location-dependent)
|
|
294
|
+
— they ship as their own bundled table at `panchang-ts/eclipses` (see
|
|
295
|
+
[Eclipses](#eclipses)).
|
|
295
296
|
|
|
296
297
|
### Festivals outside India — build a location table and cache it
|
|
297
298
|
|
|
@@ -353,6 +354,117 @@ import { getUpcomingSolarEclipse, getUpcomingLunarEclipse } from 'panchang-ts';
|
|
|
353
354
|
const next = getUpcomingSolarEclipse(new Date(), loc, 365 /* days */);
|
|
354
355
|
```
|
|
355
356
|
|
|
357
|
+
### Pre-computed table (bundled, India / IST)
|
|
358
|
+
|
|
359
|
+
Like the festivals table, eclipse data ships as a static, engine-free entry
|
|
360
|
+
at `panchang-ts/eclipses` — a rolling **2-years-past / 5-years-future** window
|
|
361
|
+
pre-computed against Varanasi (IST). It lists every eclipse **visible from
|
|
362
|
+
there during any phase** (so an eclipse already in progress at moon/sunrise or
|
|
363
|
+
moon/sunset is included); the `visibleAtPeak` flag tells you whether greatest
|
|
364
|
+
eclipse itself is observable. Within India visibility is essentially uniform.
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
import {
|
|
368
|
+
getEclipsesForYear,
|
|
369
|
+
getEclipsesForDate,
|
|
370
|
+
ECLIPSES_META,
|
|
371
|
+
ECLIPSES_YEAR_RANGE,
|
|
372
|
+
} from 'panchang-ts/eclipses';
|
|
373
|
+
|
|
374
|
+
const e = getEclipsesForYear(2025)![0].eclipses[0];
|
|
375
|
+
e.kind; // 'lunar'
|
|
376
|
+
e.subtype; // 'total'
|
|
377
|
+
e.start; e.peak; e.end; // ISO UTC strings
|
|
378
|
+
e.magnitude; // 0..1 obscuration at peak
|
|
379
|
+
e.visibleFromLocation; // visible during any phase? (always true in bundled table)
|
|
380
|
+
e.visibleAtPeak; // is greatest eclipse itself above the horizon?
|
|
381
|
+
e.sutak; // { start, end } — see note below
|
|
382
|
+
getEclipsesForDate('2025-09-07', 'hi'); // [पूर्ण चंद्र ग्रहण]
|
|
383
|
+
ECLIPSES_META.referenceLocation; // "Varanasi"
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Each entry carries `en` + `hi` text. Solar eclipses report the subtype seen
|
|
387
|
+
**locally** (a globally-total eclipse may read `partial` from Varanasi). The
|
|
388
|
+
`sutak` window is present only where it applies — all visible solar eclipses
|
|
389
|
+
and visible **umbral** (partial/total) lunar eclipses; **penumbral** lunar
|
|
390
|
+
eclipses carry no `sutak` and are not religiously observed (drik / pandit
|
|
391
|
+
consensus). For full astronomical detail (e.g. eclipses *not* visible in
|
|
392
|
+
India), use `getUpcomingEclipses` / `getEclipsesInRange` from the main entry.
|
|
393
|
+
|
|
394
|
+
**Outside India:** which eclipses are visible — and thus carry `sutak` —
|
|
395
|
+
differs by location. Build and cache a location-specific table with
|
|
396
|
+
`buildEclipsesTable` (main entry, uses the engine), then read it back via the
|
|
397
|
+
same accessors' `source` argument — the same compute-once-then-cache pattern
|
|
398
|
+
as festivals:
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import { buildEclipsesTable } from 'panchang-ts';
|
|
402
|
+
import { getEclipsesForYear } from 'panchang-ts/eclipses';
|
|
403
|
+
|
|
404
|
+
const table = buildEclipsesTable({
|
|
405
|
+
location: { latitude: 51.5074, longitude: -0.1278 },
|
|
406
|
+
timezoneOffsetMinutes: 0, // UK / GMT
|
|
407
|
+
startYear: 2024,
|
|
408
|
+
endYear: 2031,
|
|
409
|
+
// visibleOnly: false → also include eclipses below the horizon (no sutak)
|
|
410
|
+
});
|
|
411
|
+
getEclipsesForYear(2025, 'en', table);
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
To regenerate the bundled India table, run `npm run eclipses:gen` (rolling
|
|
415
|
+
window, no constants to edit).
|
|
416
|
+
|
|
417
|
+
## Moon Phases
|
|
418
|
+
|
|
419
|
+
The four principal lunar phases — **new** (Amavasya), **first quarter**,
|
|
420
|
+
**full** (Purnima), **last quarter** — as precise instants. (These are the
|
|
421
|
+
astronomical quarter moments, distinct from the same-named *tithis*, which are
|
|
422
|
+
~24h windows.)
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { getMoonPhasesInRange } from 'panchang-ts';
|
|
426
|
+
const phases = getMoonPhasesInRange(new Date('2026-01-01'), new Date('2026-12-31'));
|
|
427
|
+
phases.forEach(p => console.log(p.phase, p.time.toISOString())); // ~49 / year
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Pre-computed table (bundled, India / IST)
|
|
431
|
+
|
|
432
|
+
Same engine-free pattern as festivals and eclipses, at `panchang-ts/moon-phases`
|
|
433
|
+
— a rolling **2-years-past / 5-years-future** window. Phases are global
|
|
434
|
+
instants; the bundled table maps each onto its **IST** calendar date (so a new
|
|
435
|
+
moon at 19:52 UTC on Jan 18 is listed under Jan 19 in India).
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import {
|
|
439
|
+
getMoonPhasesForYear,
|
|
440
|
+
getMoonPhasesForDate,
|
|
441
|
+
MOON_PHASES_META,
|
|
442
|
+
MOON_PHASES_YEAR_RANGE,
|
|
443
|
+
} from 'panchang-ts/moon-phases';
|
|
444
|
+
|
|
445
|
+
getMoonPhasesForYear(2026)!.length; // ~49 phase days
|
|
446
|
+
getMoonPhasesForDate('2026-01-03'); // [{ phase: 'full', name: 'Full Moon', ... }]
|
|
447
|
+
getMoonPhasesForDate('2026-01-03', 'hi'); // [{ phase: 'full', name: 'पूर्णिमा', ... }]
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Each entry carries `phase`, the phase `time` (ISO UTC), and `en` + `hi` text.
|
|
451
|
+
For another timezone, build and cache a table with `buildMoonPhasesTable` (main
|
|
452
|
+
entry) and pass it as the accessors' `source` argument — it takes only a
|
|
453
|
+
`timezoneOffsetMinutes` (no coordinates, since phases are location-independent):
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
import { buildMoonPhasesTable } from 'panchang-ts';
|
|
457
|
+
import { getMoonPhasesForYear } from 'panchang-ts/moon-phases';
|
|
458
|
+
|
|
459
|
+
const table = buildMoonPhasesTable({
|
|
460
|
+
timezoneOffsetMinutes: -300, // US Eastern
|
|
461
|
+
startYear: 2024, endYear: 2031,
|
|
462
|
+
});
|
|
463
|
+
getMoonPhasesForYear(2026, 'en', table);
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Regenerate the bundled India table with `npm run moon-phases:gen`.
|
|
467
|
+
|
|
356
468
|
## Planetary Positions
|
|
357
469
|
|
|
358
470
|
```typescript
|
|
@@ -730,7 +842,7 @@ import {
|
|
|
730
842
|
convertGregorianToHindu, convertHinduToGregorian,
|
|
731
843
|
getKaliYugaYear, getHinduNewYear,
|
|
732
844
|
getEkadashiDatesForYear, getSankrantisForYear,
|
|
733
|
-
getFestivalsInRange, getUpcomingEclipses,
|
|
845
|
+
getFestivalsInRange, getUpcomingEclipses, getEclipsesInRange,
|
|
734
846
|
} from 'panchang-ts';
|
|
735
847
|
|
|
736
848
|
// Gregorian → Hindu coords at sunrise
|
|
@@ -927,6 +1039,10 @@ computeMadhyahna, computePratahSandhya, computeSayahnaSandhya
|
|
|
927
1039
|
|
|
928
1040
|
// Eclipses
|
|
929
1041
|
getUpcomingSolarEclipse, getUpcomingLunarEclipse, getEclipseDuringDay
|
|
1042
|
+
isEclipseVisibleAnyPhase
|
|
1043
|
+
|
|
1044
|
+
// Moon phases (new / quarters / full as precise instants)
|
|
1045
|
+
getMoonPhasesInRange
|
|
930
1046
|
|
|
931
1047
|
// Jyotish — planets, dashas, transits
|
|
932
1048
|
computePlanetaryPositions, GRAHA_ABBR
|
|
@@ -961,7 +1077,12 @@ aksharabhyasamRule, seemanthamRule, shopOpeningRule, travelStartRule
|
|
|
961
1077
|
// Calendar conversion + yearly listings
|
|
962
1078
|
convertGregorianToHindu, convertHinduToGregorian
|
|
963
1079
|
getKaliYugaYear, getHinduNewYear, computeSamvat
|
|
964
|
-
getEkadashiDatesForYear, getSankrantisForYear, getFestivalsInRange
|
|
1080
|
+
getEkadashiDatesForYear, getSankrantisForYear, getFestivalsInRange
|
|
1081
|
+
getUpcomingEclipses, getEclipsesInRange
|
|
1082
|
+
|
|
1083
|
+
// Static data tables (engine-using runtime builders; bundled JSON at
|
|
1084
|
+
// panchang-ts/festivals, panchang-ts/eclipses, panchang-ts/moon-phases)
|
|
1085
|
+
buildFestivalsTable, buildEclipsesTable, buildMoonPhasesTable
|
|
965
1086
|
|
|
966
1087
|
// Errors
|
|
967
1088
|
PanchangError
|
|
@@ -999,7 +1120,7 @@ InteractionManager.runAfterInteractions(() => {
|
|
|
999
1120
|
|
|
1000
1121
|
## Accuracy
|
|
1001
1122
|
|
|
1002
|
-
8,
|
|
1123
|
+
8,164 tests across 100 files, including fixtures cross-verified against reference
|
|
1003
1124
|
panchang calculations spanning 2025–2026 across 10 Indian cities plus New York,
|
|
1004
1125
|
London, Sydney, Dubai, Singapore (diaspora fixtures cover DST on
|
|
1005
1126
|
`America/New_York`).
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/data/eclipses.json
|
|
4
|
+
var eclipses_default = {
|
|
5
|
+
_meta: {
|
|
6
|
+
referenceLocation: "Varanasi",
|
|
7
|
+
latitude: 25.3176,
|
|
8
|
+
longitude: 82.9739,
|
|
9
|
+
timezoneOffsetMinutes: 330,
|
|
10
|
+
visibleOnly: true,
|
|
11
|
+
languages: [
|
|
12
|
+
"en",
|
|
13
|
+
"hi"
|
|
14
|
+
],
|
|
15
|
+
startYear: 2024,
|
|
16
|
+
endYear: 2031,
|
|
17
|
+
generatedAt: "2026-05-30T14:11:40.371Z",
|
|
18
|
+
note: "Eclipses pre-computed for Varanasi (IST), visible from there during any phase (eclipsed body above the horizon between first and last contact \u2014 so an eclipse in progress at moon/sunrise or moon/sunset is included). visibleAtPeak flags whether greatest eclipse itself is observable. Within India visibility is essentially uniform; elsewhere it differs, so build a location-specific table at runtime with buildEclipsesTable and cache it. Solar eclipses carry the subtype seen from Varanasi (a globally-total eclipse may show as partial). Times are ISO UTC. Sutak: 4 prahara (12h) before first contact for solar, 3 prahara (9h) for umbral (partial/total) lunar, ending at moksha; penumbral lunar eclipses carry no sutak and are not religiously observed (drik / pandit consensus). Each entry carries both en and hi text."
|
|
19
|
+
},
|
|
20
|
+
years: {
|
|
21
|
+
"2024": [],
|
|
22
|
+
"2025": [
|
|
23
|
+
{
|
|
24
|
+
date: "2025-09-07",
|
|
25
|
+
eclipses: [
|
|
26
|
+
{
|
|
27
|
+
name: {
|
|
28
|
+
en: "Total Lunar Eclipse",
|
|
29
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
30
|
+
},
|
|
31
|
+
kind: "lunar",
|
|
32
|
+
subtype: "total",
|
|
33
|
+
start: "2025-09-07T15:28:02.515Z",
|
|
34
|
+
peak: "2025-09-07T18:11:41.501Z",
|
|
35
|
+
end: "2025-09-07T20:55:20.486Z",
|
|
36
|
+
magnitude: 1,
|
|
37
|
+
visibleFromLocation: true,
|
|
38
|
+
visibleAtPeak: true,
|
|
39
|
+
description: {
|
|
40
|
+
en: "Total Lunar Eclipse \u2014 100% obscuration.",
|
|
41
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 100% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
42
|
+
},
|
|
43
|
+
sutak: {
|
|
44
|
+
start: "2025-09-07T06:28:02.515Z",
|
|
45
|
+
end: "2025-09-07T20:55:20.486Z"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"2026": [
|
|
52
|
+
{
|
|
53
|
+
date: "2026-03-03",
|
|
54
|
+
eclipses: [
|
|
55
|
+
{
|
|
56
|
+
name: {
|
|
57
|
+
en: "Total Lunar Eclipse",
|
|
58
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
59
|
+
},
|
|
60
|
+
kind: "lunar",
|
|
61
|
+
subtype: "total",
|
|
62
|
+
start: "2026-03-03T08:44:01.948Z",
|
|
63
|
+
peak: "2026-03-03T11:33:40.289Z",
|
|
64
|
+
end: "2026-03-03T14:23:18.629Z",
|
|
65
|
+
magnitude: 1,
|
|
66
|
+
visibleFromLocation: true,
|
|
67
|
+
visibleAtPeak: false,
|
|
68
|
+
description: {
|
|
69
|
+
en: "Total Lunar Eclipse \u2014 100% obscuration.",
|
|
70
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 100% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
71
|
+
},
|
|
72
|
+
sutak: {
|
|
73
|
+
start: "2026-03-02T23:44:01.948Z",
|
|
74
|
+
end: "2026-03-03T14:23:18.629Z"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"2027": [
|
|
81
|
+
{
|
|
82
|
+
date: "2027-02-21",
|
|
83
|
+
eclipses: [
|
|
84
|
+
{
|
|
85
|
+
name: {
|
|
86
|
+
en: "Penumbral Lunar Eclipse",
|
|
87
|
+
hi: "\u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
88
|
+
},
|
|
89
|
+
kind: "lunar",
|
|
90
|
+
subtype: "penumbral",
|
|
91
|
+
start: "2027-02-20T21:11:52.109Z",
|
|
92
|
+
peak: "2027-02-20T23:12:44.142Z",
|
|
93
|
+
end: "2027-02-21T01:13:36.174Z",
|
|
94
|
+
magnitude: 0,
|
|
95
|
+
visibleFromLocation: true,
|
|
96
|
+
visibleAtPeak: true,
|
|
97
|
+
description: {
|
|
98
|
+
en: "Penumbral Lunar Eclipse \u2014 penumbral shadow only; no sutak.",
|
|
99
|
+
hi: "\u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 \u0915\u0947\u0935\u0932 \u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091B\u093E\u092F\u093E; \u0938\u0942\u0924\u0915 \u0928\u0939\u0940\u0902\u0964"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
date: "2027-07-18",
|
|
106
|
+
eclipses: [
|
|
107
|
+
{
|
|
108
|
+
name: {
|
|
109
|
+
en: "Penumbral Lunar Eclipse",
|
|
110
|
+
hi: "\u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
111
|
+
},
|
|
112
|
+
kind: "lunar",
|
|
113
|
+
subtype: "penumbral",
|
|
114
|
+
start: "2027-07-18T15:50:13.585Z",
|
|
115
|
+
peak: "2027-07-18T16:02:54.880Z",
|
|
116
|
+
end: "2027-07-18T16:15:36.174Z",
|
|
117
|
+
magnitude: 0,
|
|
118
|
+
visibleFromLocation: true,
|
|
119
|
+
visibleAtPeak: true,
|
|
120
|
+
description: {
|
|
121
|
+
en: "Penumbral Lunar Eclipse \u2014 penumbral shadow only; no sutak.",
|
|
122
|
+
hi: "\u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 \u0915\u0947\u0935\u0932 \u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091B\u093E\u092F\u093E; \u0938\u0942\u0924\u0915 \u0928\u0939\u0940\u0902\u0964"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
date: "2027-08-02",
|
|
129
|
+
eclipses: [
|
|
130
|
+
{
|
|
131
|
+
name: {
|
|
132
|
+
en: "Partial Solar Eclipse",
|
|
133
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u0938\u0942\u0930\u094D\u092F \u0917\u094D\u0930\u0939\u0923"
|
|
134
|
+
},
|
|
135
|
+
kind: "solar",
|
|
136
|
+
subtype: "partial",
|
|
137
|
+
start: "2027-08-02T10:35:33.763Z",
|
|
138
|
+
peak: "2027-08-02T11:07:37.251Z",
|
|
139
|
+
end: "2027-08-02T11:38:16.999Z",
|
|
140
|
+
magnitude: 0.06923317826751327,
|
|
141
|
+
visibleFromLocation: true,
|
|
142
|
+
visibleAtPeak: true,
|
|
143
|
+
description: {
|
|
144
|
+
en: "Partial Solar Eclipse \u2014 7% obscuration.",
|
|
145
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u0938\u0942\u0930\u094D\u092F \u0917\u094D\u0930\u0939\u0923 \u2014 7% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
146
|
+
},
|
|
147
|
+
sutak: {
|
|
148
|
+
start: "2027-08-01T22:35:33.763Z",
|
|
149
|
+
end: "2027-08-02T11:38:16.999Z"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
"2028": [
|
|
156
|
+
{
|
|
157
|
+
date: "2028-07-06",
|
|
158
|
+
eclipses: [
|
|
159
|
+
{
|
|
160
|
+
name: {
|
|
161
|
+
en: "Partial Lunar Eclipse",
|
|
162
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
163
|
+
},
|
|
164
|
+
kind: "lunar",
|
|
165
|
+
subtype: "partial",
|
|
166
|
+
start: "2028-07-06T15:43:55.421Z",
|
|
167
|
+
peak: "2028-07-06T18:19:38.379Z",
|
|
168
|
+
end: "2028-07-06T20:55:21.336Z",
|
|
169
|
+
magnitude: 0.3322998217792101,
|
|
170
|
+
visibleFromLocation: true,
|
|
171
|
+
visibleAtPeak: true,
|
|
172
|
+
description: {
|
|
173
|
+
en: "Partial Lunar Eclipse \u2014 33% obscuration.",
|
|
174
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 33% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
175
|
+
},
|
|
176
|
+
sutak: {
|
|
177
|
+
start: "2028-07-06T06:43:55.421Z",
|
|
178
|
+
end: "2028-07-06T20:55:21.336Z"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
date: "2028-12-31",
|
|
185
|
+
eclipses: [
|
|
186
|
+
{
|
|
187
|
+
name: {
|
|
188
|
+
en: "Total Lunar Eclipse",
|
|
189
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
190
|
+
},
|
|
191
|
+
kind: "lunar",
|
|
192
|
+
subtype: "total",
|
|
193
|
+
start: "2028-12-31T14:03:27.574Z",
|
|
194
|
+
peak: "2028-12-31T16:51:54.549Z",
|
|
195
|
+
end: "2028-12-31T19:40:21.523Z",
|
|
196
|
+
magnitude: 1,
|
|
197
|
+
visibleFromLocation: true,
|
|
198
|
+
visibleAtPeak: true,
|
|
199
|
+
description: {
|
|
200
|
+
en: "Total Lunar Eclipse \u2014 100% obscuration.",
|
|
201
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 100% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
202
|
+
},
|
|
203
|
+
sutak: {
|
|
204
|
+
start: "2028-12-31T05:03:27.574Z",
|
|
205
|
+
end: "2028-12-31T19:40:21.523Z"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
"2029": [
|
|
212
|
+
{
|
|
213
|
+
date: "2029-12-21",
|
|
214
|
+
eclipses: [
|
|
215
|
+
{
|
|
216
|
+
name: {
|
|
217
|
+
en: "Total Lunar Eclipse",
|
|
218
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
219
|
+
},
|
|
220
|
+
kind: "lunar",
|
|
221
|
+
subtype: "total",
|
|
222
|
+
start: "2029-12-20T19:42:34.436Z",
|
|
223
|
+
peak: "2029-12-20T22:41:54.610Z",
|
|
224
|
+
end: "2029-12-21T01:41:14.783Z",
|
|
225
|
+
magnitude: 1,
|
|
226
|
+
visibleFromLocation: true,
|
|
227
|
+
visibleAtPeak: true,
|
|
228
|
+
description: {
|
|
229
|
+
en: "Total Lunar Eclipse \u2014 100% obscuration.",
|
|
230
|
+
hi: "\u092A\u0942\u0930\u094D\u0923 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 100% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
231
|
+
},
|
|
232
|
+
sutak: {
|
|
233
|
+
start: "2029-12-20T10:42:34.436Z",
|
|
234
|
+
end: "2029-12-21T01:41:14.783Z"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
}
|
|
239
|
+
],
|
|
240
|
+
"2030": [
|
|
241
|
+
{
|
|
242
|
+
date: "2030-06-01",
|
|
243
|
+
eclipses: [
|
|
244
|
+
{
|
|
245
|
+
name: {
|
|
246
|
+
en: "Partial Solar Eclipse",
|
|
247
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u0938\u0942\u0930\u094D\u092F \u0917\u094D\u0930\u0939\u0923"
|
|
248
|
+
},
|
|
249
|
+
kind: "solar",
|
|
250
|
+
subtype: "partial",
|
|
251
|
+
start: "2030-06-01T05:29:15.459Z",
|
|
252
|
+
peak: "2030-06-01T06:26:07.220Z",
|
|
253
|
+
end: "2030-06-01T07:23:32.918Z",
|
|
254
|
+
magnitude: 0.03201876826173855,
|
|
255
|
+
visibleFromLocation: true,
|
|
256
|
+
visibleAtPeak: true,
|
|
257
|
+
description: {
|
|
258
|
+
en: "Partial Solar Eclipse \u2014 3% obscuration.",
|
|
259
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u0938\u0942\u0930\u094D\u092F \u0917\u094D\u0930\u0939\u0923 \u2014 3% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
260
|
+
},
|
|
261
|
+
sutak: {
|
|
262
|
+
start: "2030-05-31T17:29:15.459Z",
|
|
263
|
+
end: "2030-06-01T07:23:32.918Z"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
date: "2030-06-16",
|
|
270
|
+
eclipses: [
|
|
271
|
+
{
|
|
272
|
+
name: {
|
|
273
|
+
en: "Partial Lunar Eclipse",
|
|
274
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
275
|
+
},
|
|
276
|
+
kind: "lunar",
|
|
277
|
+
subtype: "partial",
|
|
278
|
+
start: "2030-06-15T16:13:48.134Z",
|
|
279
|
+
peak: "2030-06-15T18:33:14.732Z",
|
|
280
|
+
end: "2030-06-15T20:52:41.329Z",
|
|
281
|
+
magnitude: 0.4708077570686115,
|
|
282
|
+
visibleFromLocation: true,
|
|
283
|
+
visibleAtPeak: true,
|
|
284
|
+
description: {
|
|
285
|
+
en: "Partial Lunar Eclipse \u2014 47% obscuration.",
|
|
286
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 47% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
287
|
+
},
|
|
288
|
+
sutak: {
|
|
289
|
+
start: "2030-06-15T07:13:48.134Z",
|
|
290
|
+
end: "2030-06-15T20:52:41.329Z"
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
date: "2030-12-10",
|
|
297
|
+
eclipses: [
|
|
298
|
+
{
|
|
299
|
+
name: {
|
|
300
|
+
en: "Penumbral Lunar Eclipse",
|
|
301
|
+
hi: "\u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923"
|
|
302
|
+
},
|
|
303
|
+
kind: "lunar",
|
|
304
|
+
subtype: "penumbral",
|
|
305
|
+
start: "2030-12-09T20:07:30.214Z",
|
|
306
|
+
peak: "2030-12-09T22:27:32.805Z",
|
|
307
|
+
end: "2030-12-10T00:47:35.395Z",
|
|
308
|
+
magnitude: 0,
|
|
309
|
+
visibleFromLocation: true,
|
|
310
|
+
visibleAtPeak: true,
|
|
311
|
+
description: {
|
|
312
|
+
en: "Penumbral Lunar Eclipse \u2014 penumbral shadow only; no sutak.",
|
|
313
|
+
hi: "\u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091A\u0902\u0926\u094D\u0930 \u0917\u094D\u0930\u0939\u0923 \u2014 \u0915\u0947\u0935\u0932 \u0909\u092A\u091A\u094D\u091B\u093E\u092F\u093E \u091B\u093E\u092F\u093E; \u0938\u0942\u0924\u0915 \u0928\u0939\u0940\u0902\u0964"
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
]
|
|
317
|
+
}
|
|
318
|
+
],
|
|
319
|
+
"2031": [
|
|
320
|
+
{
|
|
321
|
+
date: "2031-05-21",
|
|
322
|
+
eclipses: [
|
|
323
|
+
{
|
|
324
|
+
name: {
|
|
325
|
+
en: "Partial Solar Eclipse",
|
|
326
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u0938\u0942\u0930\u094D\u092F \u0917\u094D\u0930\u0939\u0923"
|
|
327
|
+
},
|
|
328
|
+
kind: "solar",
|
|
329
|
+
subtype: "partial",
|
|
330
|
+
start: "2031-05-21T06:16:35.159Z",
|
|
331
|
+
peak: "2031-05-21T07:56:20.750Z",
|
|
332
|
+
end: "2031-05-21T09:26:36.965Z",
|
|
333
|
+
magnitude: 0.3939059024675881,
|
|
334
|
+
visibleFromLocation: true,
|
|
335
|
+
visibleAtPeak: true,
|
|
336
|
+
description: {
|
|
337
|
+
en: "Partial Solar Eclipse \u2014 39% obscuration.",
|
|
338
|
+
hi: "\u0906\u0902\u0936\u093F\u0915 \u0938\u0942\u0930\u094D\u092F \u0917\u094D\u0930\u0939\u0923 \u2014 39% \u0917\u094D\u0930\u093E\u0938\u0964"
|
|
339
|
+
},
|
|
340
|
+
sutak: {
|
|
341
|
+
start: "2031-05-20T18:16:35.159Z",
|
|
342
|
+
end: "2031-05-21T09:26:36.965Z"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// src/calendar/eclipsesTable.ts
|
|
352
|
+
var bundled = eclipses_default;
|
|
353
|
+
var ECLIPSES_META = bundled._meta;
|
|
354
|
+
var ECLIPSES_YEAR_RANGE = {
|
|
355
|
+
start: bundled._meta.startYear,
|
|
356
|
+
end: bundled._meta.endYear
|
|
357
|
+
};
|
|
358
|
+
function flatten(raw, lang) {
|
|
359
|
+
const name = raw.name[lang] ?? Object.values(raw.name)[0] ?? "";
|
|
360
|
+
const out = {
|
|
361
|
+
name,
|
|
362
|
+
kind: raw.kind,
|
|
363
|
+
subtype: raw.subtype,
|
|
364
|
+
start: raw.start,
|
|
365
|
+
peak: raw.peak,
|
|
366
|
+
end: raw.end,
|
|
367
|
+
magnitude: raw.magnitude,
|
|
368
|
+
visibleFromLocation: raw.visibleFromLocation,
|
|
369
|
+
visibleAtPeak: raw.visibleAtPeak
|
|
370
|
+
};
|
|
371
|
+
if (raw.sutak) out.sutak = raw.sutak;
|
|
372
|
+
if (raw.description) {
|
|
373
|
+
out.description = raw.description[lang] ?? Object.values(raw.description)[0] ?? "";
|
|
374
|
+
}
|
|
375
|
+
return out;
|
|
376
|
+
}
|
|
377
|
+
function getEclipsesForYear(year, lang = "en", source = bundled) {
|
|
378
|
+
const days = source.years[String(year)];
|
|
379
|
+
if (!days) return null;
|
|
380
|
+
return days.map((d) => ({
|
|
381
|
+
date: d.date,
|
|
382
|
+
eclipses: d.eclipses.map((e) => flatten(e, lang))
|
|
383
|
+
}));
|
|
384
|
+
}
|
|
385
|
+
function getEclipsesForDate(date, lang = "en", source = bundled) {
|
|
386
|
+
const key = typeof date === "string" ? date : toDateKey(date, source._meta.timezoneOffsetMinutes);
|
|
387
|
+
const yearKey = key.slice(0, 4);
|
|
388
|
+
const days = source.years[yearKey];
|
|
389
|
+
if (!days) return [];
|
|
390
|
+
const day = days.find((d) => d.date === key);
|
|
391
|
+
return day ? day.eclipses.map((e) => flatten(e, lang)) : [];
|
|
392
|
+
}
|
|
393
|
+
function toDateKey(d, offsetMinutes) {
|
|
394
|
+
const shifted = new Date(d.getTime() + offsetMinutes * 6e4);
|
|
395
|
+
const y = shifted.getUTCFullYear();
|
|
396
|
+
const m = String(shifted.getUTCMonth() + 1).padStart(2, "0");
|
|
397
|
+
const day = String(shifted.getUTCDate()).padStart(2, "0");
|
|
398
|
+
return `${y}-${m}-${day}`;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
exports.ECLIPSES_META = ECLIPSES_META;
|
|
402
|
+
exports.ECLIPSES_YEAR_RANGE = ECLIPSES_YEAR_RANGE;
|
|
403
|
+
exports.getEclipsesForDate = getEclipsesForDate;
|
|
404
|
+
exports.getEclipsesForYear = getEclipsesForYear;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { g as EclipseTableMeta, E as EclipsesTableLanguage, a as EclipsesFile, d as EclipseTableEntry, c as EclipseTableDay } from '../eclipsesTableTypes-D-tSQMQd.cjs';
|
|
2
|
+
export { b as EclipseSutak, e as EclipseTableEntryRaw, f as EclipseTableKind, h as EclipseTableSubtype, R as RawEclipseTableDay } from '../eclipsesTableTypes-D-tSQMQd.cjs';
|
|
3
|
+
|
|
4
|
+
/** Metadata describing what the bundled table was generated from. */
|
|
5
|
+
declare const ECLIPSES_META: EclipseTableMeta;
|
|
6
|
+
/** Inclusive year range covered by the bundled table. */
|
|
7
|
+
declare const ECLIPSES_YEAR_RANGE: {
|
|
8
|
+
readonly start: number;
|
|
9
|
+
readonly end: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Eclipse days for a Gregorian year, flattened to the requested locale.
|
|
13
|
+
*
|
|
14
|
+
* Returns `null` if `year` is outside the table's range, or an empty array if
|
|
15
|
+
* the year is in range but had no (visible) eclipses.
|
|
16
|
+
*
|
|
17
|
+
* @param year Gregorian year.
|
|
18
|
+
* @param lang `'en'` (default) or `'hi'`.
|
|
19
|
+
* @param source Table to read from. Defaults to the bundled Varanasi table;
|
|
20
|
+
* pass a {@link buildEclipsesTable} result to read a
|
|
21
|
+
* location-specific table you built and cached.
|
|
22
|
+
*/
|
|
23
|
+
declare function getEclipsesForYear(year: number, lang?: EclipsesTableLanguage, source?: EclipsesFile): EclipseTableDay[] | null;
|
|
24
|
+
/**
|
|
25
|
+
* Eclipses on a specific date, flattened to the requested locale.
|
|
26
|
+
*
|
|
27
|
+
* Returns an empty array if the date has no eclipse or is outside the table's
|
|
28
|
+
* range. The date is matched against the eclipse peak's local date.
|
|
29
|
+
*
|
|
30
|
+
* @param date Either an ISO `YYYY-MM-DD` string (interpreted in the table's
|
|
31
|
+
* reference timezone) or a `Date` (its local calendar date in the
|
|
32
|
+
* table's reference timezone is used).
|
|
33
|
+
* @param lang `'en'` (default) or `'hi'`.
|
|
34
|
+
* @param source Table to read from. Defaults to the bundled Varanasi table;
|
|
35
|
+
* pass a {@link buildEclipsesTable} result for a
|
|
36
|
+
* location-specific table.
|
|
37
|
+
*/
|
|
38
|
+
declare function getEclipsesForDate(date: string | Date, lang?: EclipsesTableLanguage, source?: EclipsesFile): EclipseTableEntry[];
|
|
39
|
+
|
|
40
|
+
export { ECLIPSES_META, ECLIPSES_YEAR_RANGE, EclipseTableDay, EclipseTableEntry, EclipseTableMeta, EclipsesFile, EclipsesTableLanguage, getEclipsesForDate, getEclipsesForYear };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { g as EclipseTableMeta, E as EclipsesTableLanguage, a as EclipsesFile, d as EclipseTableEntry, c as EclipseTableDay } from '../eclipsesTableTypes-D-tSQMQd.js';
|
|
2
|
+
export { b as EclipseSutak, e as EclipseTableEntryRaw, f as EclipseTableKind, h as EclipseTableSubtype, R as RawEclipseTableDay } from '../eclipsesTableTypes-D-tSQMQd.js';
|
|
3
|
+
|
|
4
|
+
/** Metadata describing what the bundled table was generated from. */
|
|
5
|
+
declare const ECLIPSES_META: EclipseTableMeta;
|
|
6
|
+
/** Inclusive year range covered by the bundled table. */
|
|
7
|
+
declare const ECLIPSES_YEAR_RANGE: {
|
|
8
|
+
readonly start: number;
|
|
9
|
+
readonly end: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Eclipse days for a Gregorian year, flattened to the requested locale.
|
|
13
|
+
*
|
|
14
|
+
* Returns `null` if `year` is outside the table's range, or an empty array if
|
|
15
|
+
* the year is in range but had no (visible) eclipses.
|
|
16
|
+
*
|
|
17
|
+
* @param year Gregorian year.
|
|
18
|
+
* @param lang `'en'` (default) or `'hi'`.
|
|
19
|
+
* @param source Table to read from. Defaults to the bundled Varanasi table;
|
|
20
|
+
* pass a {@link buildEclipsesTable} result to read a
|
|
21
|
+
* location-specific table you built and cached.
|
|
22
|
+
*/
|
|
23
|
+
declare function getEclipsesForYear(year: number, lang?: EclipsesTableLanguage, source?: EclipsesFile): EclipseTableDay[] | null;
|
|
24
|
+
/**
|
|
25
|
+
* Eclipses on a specific date, flattened to the requested locale.
|
|
26
|
+
*
|
|
27
|
+
* Returns an empty array if the date has no eclipse or is outside the table's
|
|
28
|
+
* range. The date is matched against the eclipse peak's local date.
|
|
29
|
+
*
|
|
30
|
+
* @param date Either an ISO `YYYY-MM-DD` string (interpreted in the table's
|
|
31
|
+
* reference timezone) or a `Date` (its local calendar date in the
|
|
32
|
+
* table's reference timezone is used).
|
|
33
|
+
* @param lang `'en'` (default) or `'hi'`.
|
|
34
|
+
* @param source Table to read from. Defaults to the bundled Varanasi table;
|
|
35
|
+
* pass a {@link buildEclipsesTable} result for a
|
|
36
|
+
* location-specific table.
|
|
37
|
+
*/
|
|
38
|
+
declare function getEclipsesForDate(date: string | Date, lang?: EclipsesTableLanguage, source?: EclipsesFile): EclipseTableEntry[];
|
|
39
|
+
|
|
40
|
+
export { ECLIPSES_META, ECLIPSES_YEAR_RANGE, EclipseTableDay, EclipseTableEntry, EclipseTableMeta, EclipsesFile, EclipsesTableLanguage, getEclipsesForDate, getEclipsesForYear };
|