panchanga 0.1.1

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.
@@ -0,0 +1,603 @@
1
+ /**
2
+ * src/elements.ts — calendar-elements core: tithi, nakshatra, karaṇa/Bhadra,
3
+ * new moons, solar ingress (saṅkrānti), and amānta/pūrṇimānta lunar months.
4
+ *
5
+ * SOURCING (the two fiddly conventions are pinned to authorities, not guessed):
6
+ *
7
+ * • KARAṆA SEQUENCE — Wikipedia "Karaṇa (pañcāṅga)"
8
+ * https://en.wikipedia.org/wiki/Karana_(pancanga)
9
+ * A karaṇa is half a tithi: the span over which Moon−Sun elongation grows 6°.
10
+ * A lunar month (0°…360° elongation) has 60 half-tithis, indexed h = 0..59:
11
+ * h = 0 → Kiṁstughna (fixed)
12
+ * h = 1..56 → the 7 movable karaṇas cycling with
13
+ * ((h−1) mod 7) over
14
+ * [Bava, Bālava, Kaulava, Taitila, Gara,
15
+ * Vaṇij, Viṣṭi] (8 full cycles = 56)
16
+ * h = 57 → Śakuni, 58 → Catuṣpāda, 59 → Nāga (fixed)
17
+ * Viṣṭi ≡ Bhadra. The Mukha/Pucchā subdivision + Vāsa is `bhadraSplit`;
18
+ * `bhadraIntervals` returns the whole Viṣṭi span it operates on.
19
+ *
20
+ * • LUNAR-MONTH NAMING / ADHIKA / KṢAYA — Wikipedia "Hindu calendar" &
21
+ * "Adhika-masa" (https://en.wikipedia.org/wiki/Adhika-masa,
22
+ * https://en.wikipedia.org/wiki/Hindu_calendar), consistent with
23
+ * drikpanchang's adhika-masa definition.
24
+ * An amānta lunation (new moon → next new moon) is named after the rāśi the
25
+ * Sun ENTERS (the saṅkrānti) DURING that lunation:
26
+ * Mesha saṅkrānti → Chaitra, Vṛṣabha → Vaiśākha, Mithuna → Jyeṣṭha, …
27
+ * i.e. month-name-index (0=Chaitra) = entered-rāśi-index (0=Mesha).
28
+ * • A lunation with NO saṅkrānti is **adhika** (leap): it takes the name of
29
+ * the FOLLOWING lunation's saṅkrānti, prefixed "Adhika"; the following
30
+ * lunation is then "Nija/Śuddha". (Algorithmically: an adhika lunation
31
+ * inherits the next lunation's month name.)
32
+ * • A lunation with TWO saṅkrāntis is **kṣaya** (lost month, ~1/140 yr).
33
+ *
34
+ * • PŪRṆIMĀNTA label — derived from the amānta result. A pūrṇimānta month runs
35
+ * full-moon → full-moon, so its kṛṣṇa-pakṣa (waning) half belongs to the
36
+ * amānta month one NAME EARLIER. Concretely: in the kṛṣṇa pakṣa the
37
+ * pūrṇimānta name = next amānta name; in the śukla pakṣa they coincide.
38
+ * Dates do not change — only the label.
39
+ *
40
+ * ASTRONOMY PRIMITIVES
41
+ * • Elongation = geocentric Moon−Sun ecliptic-longitude difference in [0,360):
42
+ * Astronomy.PairLongitude(Body.Moon, Body.Sun, date) (== MoonPhase(date)).
43
+ * • Tithi / karaṇa / new-moon boundaries via Astronomy.SearchMoonPhase(target,
44
+ * start, limitDays) — robust against intra-day non-monotonicity.
45
+ * • Nakshatra & saṅkrānti use the SIDEREAL longitudes from ayanamsha.ts
46
+ * (siderealLongitude / siderealSunRashi), kept consistent with Drik Panchang.
47
+ */
48
+ import { Body, PairLongitude, SearchMoonPhase, MakeTime, } from "astronomy-engine";
49
+ import { siderealLongitude, siderealSunRashi, normalize360 } from "./ayanamsha.js";
50
+ // ───────────────────────────────────────────────────────────────────────────
51
+ // Constants
52
+ // ───────────────────────────────────────────────────────────────────────────
53
+ /** Degrees of elongation per tithi (one of 30 in a lunation). */
54
+ const DEG_PER_TITHI = 12;
55
+ /** Degrees of elongation per karaṇa (half-tithi; 60 in a lunation). */
56
+ const DEG_PER_KARANA = 6;
57
+ /** Number of nakshatras; arc each spans = 360/27 = 13°20′. */
58
+ const NAKSHATRA_COUNT = 27;
59
+ const DEG_PER_NAKSHATRA = 360 / NAKSHATRA_COUNT;
60
+ /** Mean synodic month, days — used only to size search windows. */
61
+ const SYNODIC_MONTH_DAYS = 29.530588853;
62
+ /** The 30 tithi names (1-based: index 0 = tithi 1 = Pratipadā). */
63
+ export const TITHI_NAMES = [
64
+ "Pratipada", "Dvitiya", "Tritiya", "Chaturthi", "Panchami", "Shashthi",
65
+ "Saptami", "Ashtami", "Navami", "Dashami", "Ekadashi", "Dvadashi",
66
+ "Trayodashi", "Chaturdashi", "Purnima",
67
+ "Pratipada", "Dvitiya", "Tritiya", "Chaturthi", "Panchami", "Shashthi",
68
+ "Saptami", "Ashtami", "Navami", "Dashami", "Ekadashi", "Dvadashi",
69
+ "Trayodashi", "Chaturdashi", "Amavasya",
70
+ ];
71
+ /** The 27 nakshatra names (index 0 = Ashwini; Rohini = 3). */
72
+ export const NAKSHATRA_NAMES = [
73
+ "Ashwini", "Bharani", "Krittika", "Rohini", "Mrigashira", "Ardra",
74
+ "Punarvasu", "Pushya", "Ashlesha", "Magha", "Purva Phalguni",
75
+ "Uttara Phalguni", "Hasta", "Chitra", "Swati", "Vishakha", "Anuradha",
76
+ "Jyeshtha", "Mula", "Purva Ashadha", "Uttara Ashadha", "Shravana",
77
+ "Dhanishta", "Shatabhisha", "Purva Bhadrapada", "Uttara Bhadrapada", "Revati",
78
+ ];
79
+ /** The 7 movable (cara) karaṇas, in cyclic order. Viṣṭi (index 6) ≡ Bhadra. */
80
+ export const MOVABLE_KARANAS = [
81
+ "Bava", "Balava", "Kaulava", "Taitila", "Gara", "Vanij", "Vishti",
82
+ ];
83
+ /** Karaṇa name for a half-tithi index h ∈ 0..59 (see file header for sourcing). */
84
+ export function karanaName(h) {
85
+ if (h === 0)
86
+ return "Kimstughna";
87
+ if (h === 57)
88
+ return "Shakuni";
89
+ if (h === 58)
90
+ return "Chatushpada";
91
+ if (h === 59)
92
+ return "Naga";
93
+ // h = 1..56 → movable cycle
94
+ return MOVABLE_KARANAS[(h - 1) % 7];
95
+ }
96
+ /**
97
+ * The 12 amānta lunar-month names, indexed by the rāśi the Sun enters:
98
+ * index 0 = Mesha → Chaitra, … index 11 = Mīna → Phalguna.
99
+ */
100
+ export const LUNAR_MONTH_NAMES = [
101
+ "Chaitra", "Vaishakha", "Jyeshtha", "Ashadha", "Shravana", "Bhadrapada",
102
+ "Ashwina", "Kartika", "Margashirsha", "Pausha", "Magha", "Phalguna",
103
+ ];
104
+ // ───────────────────────────────────────────────────────────────────────────
105
+ // Generic root-finding helper (monotone longitude crossing, bisection)
106
+ // ───────────────────────────────────────────────────────────────────────────
107
+ /**
108
+ * Root-find the instant in (lo, hi] at which `f` (an angle in degrees, assumed
109
+ * to increase monotonically mod 360 across the bracket) crosses `target`.
110
+ *
111
+ * `lo` and `hi` are millisecond epochs bracketing exactly one crossing.
112
+ * `f(ms)` returns the angle in [0,360). We measure the signed forward gap from
113
+ * `target` (how far the angle has advanced past `target`, in [0,360)) and
114
+ * bisect on the sign change. Converges to ~sub-second.
115
+ */
116
+ function bisectLongitudeCrossing(f, target, lo, hi) {
117
+ // forward distance the angle has travelled past `target`, in [0,360)
118
+ const past = (ms) => normalize360(f(ms) - target);
119
+ // At lo the angle is just BEFORE target → past(lo) is near 360 (large).
120
+ // At hi the angle is just AFTER target → past(hi) is near 0 (small).
121
+ // We look for the step where past jumps from ~360 down to ~0; the crossing
122
+ // is where forward distance from the lo-side equals the bracket.
123
+ // Reframe as: g(ms) = angularDelta(f(ms), target) signed so it is negative
124
+ // before the crossing and non-negative after.
125
+ const signed = (ms) => {
126
+ const d = normalize360(f(ms) - target); // [0,360)
127
+ return d > 180 ? d - 360 : d; // (−180,180]
128
+ };
129
+ let a = lo;
130
+ let b = hi;
131
+ let fa = signed(a);
132
+ // Guard: ensure a sign change exists; if not, return the closest endpoint.
133
+ for (let i = 0; i < 100; i++) {
134
+ const m = (a + b) / 2;
135
+ const fm = signed(m);
136
+ if (Math.abs(b - a) < 50)
137
+ break; // < 50 ms
138
+ if ((fa < 0 && fm < 0) || (fa >= 0 && fm >= 0)) {
139
+ a = m;
140
+ fa = fm;
141
+ }
142
+ else {
143
+ b = m;
144
+ }
145
+ }
146
+ return new Date((a + b) / 2);
147
+ }
148
+ // ───────────────────────────────────────────────────────────────────────────
149
+ // 1. Elongation & tithi
150
+ // ───────────────────────────────────────────────────────────────────────────
151
+ /**
152
+ * Geocentric Moon−Sun ecliptic-longitude elongation in [0,360).
153
+ * 0 = new moon (conjunction), 180 = full moon.
154
+ */
155
+ export function elongation(date) {
156
+ return PairLongitude(Body.Moon, Body.Sun, date);
157
+ }
158
+ /**
159
+ * Tithi number 1..30 containing `date`.
160
+ * Tithi n spans elongation [(n−1)·12°, n·12°). 1 = Śukla Pratipadā … 30 = Amāvāsyā.
161
+ */
162
+ export function tithiAt(date) {
163
+ return Math.floor(elongation(date) / DEG_PER_TITHI) + 1;
164
+ }
165
+ /**
166
+ * Boundaries of the tithi containing `around`.
167
+ *
168
+ * Tithi n occupies elongation [(n−1)·12°, n·12°). We locate the start by
169
+ * searching backward for the (n−1)·12° phase and the end by searching forward
170
+ * for the n·12° phase (mod 360). The new-moon wrap is handled because phase
171
+ * 0° ≡ 360°: tithi 30 ends at phase 0 (the next new moon) and tithi 1 starts
172
+ * at phase 0 (the same new moon), so the SearchMoonPhase target is taken mod
173
+ * 360 and the wrap is seamless.
174
+ */
175
+ export function tithiBoundaries(around) {
176
+ const t = MakeTime(around);
177
+ const n = tithiAt(around);
178
+ const startTarget = ((n - 1) * DEG_PER_TITHI) % 360; // 0..348
179
+ const endTarget = (n * DEG_PER_TITHI) % 360; // 12..360→0
180
+ // Start: most recent time phase reached startTarget at or before `around`.
181
+ // Search backward up to ~2 tithis (a tithi is ~0.9–1.1 days; 3 d is safe).
182
+ const start = SearchMoonPhase(startTarget, t, -3);
183
+ // End: next time phase reaches endTarget after `around`.
184
+ const end = SearchMoonPhase(endTarget, t, +3);
185
+ if (!start || !end) {
186
+ throw new Error(`tithiBoundaries: SearchMoonPhase failed for tithi ${n} near ${new Date(t.date.getTime()).toISOString()}`);
187
+ }
188
+ return { number: n, start: start.date, end: end.date };
189
+ }
190
+ // ───────────────────────────────────────────────────────────────────────────
191
+ // 2. Nakshatra (sidereal Moon longitude)
192
+ // ───────────────────────────────────────────────────────────────────────────
193
+ /**
194
+ * Nakshatra index 0..26 of the Moon at `date` (0 = Ashwini; Rohini = 3).
195
+ * Each nakshatra spans 360/27 = 13°20′ of the Moon's sidereal longitude.
196
+ */
197
+ export function nakshatraAt(date) {
198
+ return Math.floor(siderealLongitude(date, Body.Moon) / DEG_PER_NAKSHATRA);
199
+ }
200
+ /**
201
+ * Boundaries of the nakshatra the Moon occupies at `around`.
202
+ *
203
+ * The Moon's sidereal longitude advances ~13.2°/day and is monotonic within a
204
+ * nakshatra, so each 13°20′ boundary is a clean single crossing. We bracket
205
+ * the start-edge by stepping back ~1.5 days and the end-edge forward ~1.5 days
206
+ * (a nakshatra lasts ~24 h) and bisect each crossing.
207
+ */
208
+ export function nakshatraBoundaries(around) {
209
+ const t = MakeTime(around);
210
+ const centerMs = t.date.getTime();
211
+ const idx = nakshatraAt(around);
212
+ const startEdge = idx * DEG_PER_NAKSHATRA; // lower boundary, deg
213
+ const endEdge = ((idx + 1) % NAKSHATRA_COUNT) * DEG_PER_NAKSHATRA; // upper
214
+ const moonSid = (ms) => siderealLongitude(new Date(ms), Body.Moon);
215
+ const DAY = 86_400_000;
216
+ // A nakshatra is ~24 h; ±2 days brackets the adjacent boundaries safely.
217
+ const start = bisectLongitudeCrossing(moonSid, startEdge, centerMs - 2 * DAY, centerMs);
218
+ const end = bisectLongitudeCrossing(moonSid, endEdge, centerMs, centerMs + 2 * DAY);
219
+ return { index: idx, start, end };
220
+ }
221
+ // ───────────────────────────────────────────────────────────────────────────
222
+ // 2b. Yoga (sidereal Sun + Moon longitude)
223
+ // ───────────────────────────────────────────────────────────────────────────
224
+ /** Number of nitya-yogas; arc each spans = 360/27 = 13°20′. */
225
+ const YOGA_COUNT = 27;
226
+ const DEG_PER_YOGA = 360 / YOGA_COUNT;
227
+ /** The 27 nitya-yoga names (index 0 = Vishkambha … 26 = Vaidhriti). */
228
+ export const YOGA_NAMES = [
229
+ "Vishkambha", "Priti", "Ayushman", "Saubhagya", "Shobhana", "Atiganda",
230
+ "Sukarman", "Dhriti", "Shula", "Ganda", "Vriddhi", "Dhruva",
231
+ "Vyaghata", "Harshana", "Vajra", "Siddhi", "Vyatipata", "Variyan",
232
+ "Parigha", "Shiva", "Siddha", "Sadhya", "Shubha", "Shukla",
233
+ "Brahma", "Indra", "Vaidhriti",
234
+ ];
235
+ /**
236
+ * The yoga "angle" at `date`: the SUM of the sidereal ecliptic longitudes of
237
+ * the Sun and Moon, reduced to [0,360). Contrast tithi/karaṇa (the Moon−Sun
238
+ * *difference*) and nakshatra (the Moon *alone*). The sum advances ~14.2°/day
239
+ * (Moon ~13.2 + Sun ~1) and is monotone, so each 13°20′ boundary is a clean
240
+ * single crossing.
241
+ */
242
+ function yogaAngle(date) {
243
+ return normalize360(siderealLongitude(date, Body.Sun) + siderealLongitude(date, Body.Moon));
244
+ }
245
+ /**
246
+ * Yoga index 0..26 at `date` (0 = Vishkambha; 26 = Vaidhriti).
247
+ * Each nitya-yoga spans 360/27 = 13°20′ of (Sun + Moon) sidereal longitude.
248
+ */
249
+ export function yogaAt(date) {
250
+ return Math.floor(yogaAngle(date) / DEG_PER_YOGA);
251
+ }
252
+ /**
253
+ * Boundaries of the yoga at `around`. The (Sun+Moon) sidereal sum advances
254
+ * monotonically (~14.2°/day), so a yoga lasts ~22–25 h; ±2 days brackets the
255
+ * adjacent boundaries safely and we bisect each crossing (the 360°→0° wrap for
256
+ * Vaidhriti→Vishkambha is handled by `bisectLongitudeCrossing`, exactly as for
257
+ * the Revati→Ashwini nakshatra wrap).
258
+ */
259
+ export function yogaBoundaries(around) {
260
+ const t = MakeTime(around);
261
+ const centerMs = t.date.getTime();
262
+ const idx = yogaAt(around);
263
+ const startEdge = idx * DEG_PER_YOGA;
264
+ const endEdge = ((idx + 1) % YOGA_COUNT) * DEG_PER_YOGA;
265
+ const angle = (ms) => yogaAngle(new Date(ms));
266
+ const DAY = 86_400_000;
267
+ const start = bisectLongitudeCrossing(angle, startEdge, centerMs - 2 * DAY, centerMs);
268
+ const end = bisectLongitudeCrossing(angle, endEdge, centerMs, centerMs + 2 * DAY);
269
+ return { index: idx, start, end };
270
+ }
271
+ // ───────────────────────────────────────────────────────────────────────────
272
+ // 3. Karaṇa & Bhadra (Viṣṭi)
273
+ // ───────────────────────────────────────────────────────────────────────────
274
+ /**
275
+ * Half-tithi index h ∈ 0..59 at `date` (h = floor(elongation/6°)), i.e. the
276
+ * karaṇa slot within the current lunation.
277
+ */
278
+ export function karanaIndexAt(date) {
279
+ return Math.floor(elongation(date) / DEG_PER_KARANA);
280
+ }
281
+ /** Karaṇa name at `date` (see karanaName / file header for the sequence). */
282
+ export function karanaAt(date) {
283
+ return karanaName(karanaIndexAt(date));
284
+ }
285
+ /**
286
+ * Boundaries of the karaṇa (half-tithi) containing `around`. Mirrors
287
+ * `tithiBoundaries` on a 6° grid: a karaṇa spans elongation [h·6°, (h+1)·6°),
288
+ * so we locate the start at h·6° (backward) and the end at (h+1)·6° (forward).
289
+ * The new-moon wrap (h=59 ends at phase 0°) is seamless because the target is
290
+ * taken mod 360.
291
+ */
292
+ export function karanaBoundaries(around) {
293
+ const t = MakeTime(around);
294
+ const h = karanaIndexAt(around);
295
+ const startTarget = (h * DEG_PER_KARANA) % 360;
296
+ const endTarget = ((h + 1) * DEG_PER_KARANA) % 360;
297
+ const start = SearchMoonPhase(startTarget, t, -3);
298
+ const end = SearchMoonPhase(endTarget, t, +3);
299
+ if (!start || !end) {
300
+ throw new Error(`karanaBoundaries: SearchMoonPhase failed for karaṇa ${h} near ${new Date(t.date.getTime()).toISOString()}`);
301
+ }
302
+ return { index: h, name: karanaName(h), start: start.date, end: end.date };
303
+ }
304
+ /**
305
+ * Viṣṭi (Bhadra) karaṇa interval(s) near `around`.
306
+ *
307
+ * Viṣṭi is the 7th movable karaṇa, so it falls at half-tithi indices h where
308
+ * ((h−1) mod 7) === 6 and h ∈ 1..56, i.e. h ∈ {7, 14, 21, 28, 35, 42, 49, 56}.
309
+ * Each such karaṇa is the elongation span [h·6°, (h+1)·6°). Within a lunar
310
+ * month Bhadra therefore occurs once per pakṣa-ish (8 times across a lunation).
311
+ *
312
+ * This scans a window of ±SYNODIC_MONTH_DAYS around `around`, locates every
313
+ * Viṣṭi slot via SearchMoonPhase on the 6° multiples, and returns each
314
+ * {start,end} (UTC) that overlaps the window. Adjacent to a date this yields
315
+ * the Bhadra window(s) on/near that date.
316
+ *
317
+ * NOTE: this returns the whole Viṣṭi karaṇa span. The Mukha/Pucchā "face/tail"
318
+ * subdivision and the Vāsa (loka) used for Holikā Dahan muhūrta are computed by
319
+ * `bhadraSplit`, which takes one of these intervals.
320
+ */
321
+ export function bhadraIntervals(around) {
322
+ const t = MakeTime(around);
323
+ const centerMs = t.date.getTime();
324
+ const DAY = 86_400_000;
325
+ const windowMs = SYNODIC_MONTH_DAYS * DAY;
326
+ const loMs = centerMs - windowMs;
327
+ const hiMs = centerMs + windowMs;
328
+ const result = [];
329
+ // Viṣṭi half-tithi indices within a lunation.
330
+ const vishtiSlots = [7, 14, 21, 28, 35, 42, 49, 56];
331
+ // We don't know which lunation we're in for absolute h, but SearchMoonPhase
332
+ // targets are absolute phase degrees in [0,360). Each Viṣṭi slot h maps to a
333
+ // phase target startDeg = h·6°; the karaṇa ends at (h+1)·6°. Search across a
334
+ // few lunations covering the window.
335
+ for (const h of vishtiSlots) {
336
+ const startDeg = h * DEG_PER_KARANA; // 42,84,…,336
337
+ const endDeg = (h + 1) * DEG_PER_KARANA;
338
+ // Walk lunation by lunation across the window. Anchor the search at loMs
339
+ // and step forward by ~1 synodic month until past hiMs.
340
+ let cursor = loMs;
341
+ while (cursor <= hiMs) {
342
+ const s = SearchMoonPhase(startDeg % 360, new Date(cursor), SYNODIC_MONTH_DAYS + 1);
343
+ if (!s)
344
+ break;
345
+ if (s.date.getTime() > hiMs)
346
+ break;
347
+ const e = SearchMoonPhase(endDeg % 360, s.date, 2);
348
+ if (!e)
349
+ break;
350
+ // Keep intervals overlapping the window.
351
+ if (e.date.getTime() >= loMs && s.date.getTime() <= hiMs) {
352
+ result.push({ start: s.date, end: e.date });
353
+ }
354
+ // Advance just past this start to the next lunation's same slot.
355
+ cursor = s.date.getTime() + SYNODIC_MONTH_DAYS * DAY * 0.5;
356
+ }
357
+ }
358
+ // De-duplicate (different cursors can re-find the same interval) and sort.
359
+ const uniq = new Map();
360
+ for (const iv of result) {
361
+ const key = Math.round(iv.start.getTime() / 1000); // 1-second bucket
362
+ if (!uniq.has(key))
363
+ uniq.set(key, iv);
364
+ }
365
+ return [...uniq.values()].sort((a, b) => a.start.getTime() - b.start.getTime());
366
+ }
367
+ /** Vāsa loka by rāśi index 0..11 (see the sourcing note above). */
368
+ const BHADRA_VASA_BY_RASHI = [
369
+ "svarga", // 0 Mesha
370
+ "svarga", // 1 Vrishabha
371
+ "svarga", // 2 Mithuna
372
+ "prithvi", // 3 Karka
373
+ "prithvi", // 4 Simha
374
+ "patala", // 5 Kanya
375
+ "patala", // 6 Tula
376
+ "svarga", // 7 Vrishchika
377
+ "patala", // 8 Dhanu
378
+ "patala", // 9 Makara
379
+ "prithvi", // 10 Kumbha
380
+ "prithvi", // 11 Meena
381
+ ];
382
+ /**
383
+ * Split a Bhadra (Viṣṭi karaṇa) `interval` into its Mukha (face) and Pucchā
384
+ * (tail) sub-windows and resolve its Vāsa from the Moon's rāśi at Bhadra's
385
+ * start. See the sourcing note above. PURE w.r.t. its argument + ephemeris.
386
+ */
387
+ export function bhadraSplit(interval) {
388
+ const startMs = interval.start.getTime();
389
+ const endMs = interval.end.getTime();
390
+ const span = endMs - startMs;
391
+ // Sample the Moon's rāśi at the Bhadra MIDPOINT — the representative instant
392
+ // for "during Bhadra" (a single endpoint can misclassify the rare case where
393
+ // the Moon crosses a rāśi boundary within the span).
394
+ const midpoint = new Date(startMs + span / 2);
395
+ const moonRashi = Math.floor(siderealLongitude(midpoint, Body.Moon) / 30) % 12;
396
+ return {
397
+ vasa: BHADRA_VASA_BY_RASHI[moonRashi],
398
+ moonRashi,
399
+ mukha: { start: new Date(startMs), end: new Date(startMs + span / 6) },
400
+ puccha: { start: new Date(endMs - span / 10), end: new Date(endMs) },
401
+ };
402
+ }
403
+ // ───────────────────────────────────────────────────────────────────────────
404
+ // 4. New moons & solar ingress (saṅkrānti)
405
+ // ───────────────────────────────────────────────────────────────────────────
406
+ /**
407
+ * All new-moon instants (elongation = 0°) whose UTC time falls within calendar
408
+ * year `year` (UTC), in increasing order. Uses SearchMoonPhase(0).
409
+ */
410
+ // Memoized by year: newMoons(year) is pure and location-independent, yet it is
411
+ // called once per tithi-bearing rule (~146× in a full computeFestivals). The
412
+ // returned array is treated read-only by all callers; the cache makes every
413
+ // call after the first O(1). (See also solarIngress below.)
414
+ const _newMoonsByYear = new Map();
415
+ export function newMoons(year) {
416
+ const cached = _newMoonsByYear.get(year);
417
+ if (cached)
418
+ return cached;
419
+ const out = [];
420
+ const yearEnd = Date.UTC(year + 1, 0, 1);
421
+ // Start a little before Jan 1 so we catch a new moon early in January.
422
+ let cursor = new Date(Date.UTC(year - 1, 11, 25));
423
+ for (let i = 0; i < 20; i++) {
424
+ const nm = SearchMoonPhase(0, cursor, 40);
425
+ if (!nm)
426
+ break;
427
+ const ms = nm.date.getTime();
428
+ if (ms >= yearEnd)
429
+ break;
430
+ if (ms >= Date.UTC(year, 0, 1))
431
+ out.push(nm.date);
432
+ // Advance past this new moon to find the next.
433
+ cursor = new Date(ms + SYNODIC_MONTH_DAYS * 86_400_000 * 0.5);
434
+ }
435
+ _newMoonsByYear.set(year, out);
436
+ return out;
437
+ }
438
+ /**
439
+ * The instant in calendar year `year` (UTC) at which the Sun's **sidereal**
440
+ * (Lahiri) longitude crosses `rashi`·30° — the saṅkrānti into that rāśi.
441
+ * rashi 0 = Mesha … 9 = Makara (Makara Saṅkrānti) … 11 = Mīna.
442
+ *
443
+ * Root-found on siderealLongitude(Sun): the Sun advances ~1°/day and is
444
+ * monotonic, so each 30° boundary is crossed once per year. We scan month by
445
+ * month for the rāśi change, then bisect.
446
+ */
447
+ // Memoized by (year, rashi): a 366-day sidereal scan re-run per solar rule.
448
+ const _solarIngressByKey = new Map();
449
+ export function solarIngress(year, rashi) {
450
+ const key = year * 12 + rashi;
451
+ const cached = _solarIngressByKey.get(key);
452
+ if (cached)
453
+ return cached;
454
+ const targetDeg = normalize360(rashi * 30);
455
+ const sunSid = (ms) => siderealLongitude(new Date(ms), Body.Sun);
456
+ // Find the day-bracket where siderealSunRashi steps into `rashi`.
457
+ // Scan the whole year at 1-day resolution.
458
+ const startMs = Date.UTC(year, 0, 1);
459
+ const DAY = 86_400_000;
460
+ let prevMs = startMs;
461
+ let prevRashi = siderealSunRashi(new Date(prevMs));
462
+ for (let d = 1; d <= 366; d++) {
463
+ const ms = startMs + d * DAY;
464
+ const r = siderealSunRashi(new Date(ms));
465
+ if (r !== prevRashi && r === rashi) {
466
+ // Crossing into `rashi` lies in (prevMs, ms]. Bisect the 30° boundary.
467
+ const result = bisectLongitudeCrossing(sunSid, targetDeg, prevMs, ms);
468
+ _solarIngressByKey.set(key, result);
469
+ return result;
470
+ }
471
+ prevMs = ms;
472
+ prevRashi = r;
473
+ }
474
+ throw new Error(`solarIngress: rashi ${rashi} not entered during ${year}`);
475
+ }
476
+ /** Find the new moon at or immediately before `ms` (UTC ms). */
477
+ function newMoonAtOrBefore(ms) {
478
+ const nm = SearchMoonPhase(0, new Date(ms), -(SYNODIC_MONTH_DAYS + 2));
479
+ if (!nm)
480
+ throw new Error("newMoonAtOrBefore: SearchMoonPhase failed");
481
+ return nm.date;
482
+ }
483
+ /** Find the first new moon strictly after `ms` (UTC ms). */
484
+ function newMoonAfter(ms) {
485
+ // Step a hair forward to avoid re-finding the same instant.
486
+ const nm = SearchMoonPhase(0, new Date(ms + 1000), SYNODIC_MONTH_DAYS + 2);
487
+ if (!nm)
488
+ throw new Error("newMoonAfter: SearchMoonPhase failed");
489
+ return nm.date;
490
+ }
491
+ /**
492
+ * Count saṅkrāntis (solar rāśi entries) strictly inside the open lunation
493
+ * (nmStart, nmEnd) and return the rāśi index entered for each, in order.
494
+ *
495
+ * A saṅkrānti is a step in siderealSunRashi. We sample at the two new-moon
496
+ * endpoints and detect rāśi changes by scanning at 12-hour resolution (the Sun
497
+ * never crosses two boundaries within 12 h), then refine is unnecessary — we
498
+ * only need the COUNT and the entered rāśi index(es).
499
+ */
500
+ function sankrantisInLunation(nmStartMs, nmEndMs) {
501
+ const entered = [];
502
+ const STEP = 12 * 3_600_000; // 12 h
503
+ let prevRashi = siderealSunRashi(new Date(nmStartMs));
504
+ for (let ms = nmStartMs + STEP; ms < nmEndMs; ms += STEP) {
505
+ const r = siderealSunRashi(new Date(ms));
506
+ if (r !== prevRashi) {
507
+ entered.push(r);
508
+ prevRashi = r;
509
+ }
510
+ }
511
+ // Also check the final endpoint approach (last step may overshoot nmEnd).
512
+ const rEnd = siderealSunRashi(new Date(nmEndMs - 1));
513
+ if (rEnd !== prevRashi) {
514
+ entered.push(rEnd);
515
+ }
516
+ return entered;
517
+ }
518
+ /**
519
+ * Classify the amānta lunation containing `at` and return amānta + pūrṇimānta
520
+ * labels, paksha, and adhika/kṣaya flags.
521
+ *
522
+ * Algorithm (see file header for sourcing):
523
+ * 1. Bracket the current amānta lunation: nmStart = new moon at/before `at`,
524
+ * nmEnd = next new moon. Paksha = śukla if elongation(at) < 180 else kṛṣṇa.
525
+ * 2. Count saṅkrāntis inside (nmStart, nmEnd):
526
+ * • exactly 1 → ordinary month, name = entered-rāśi index (0=Chaitra).
527
+ * • 0 → ADHIKA: name = the FOLLOWING lunation's saṅkrānti rāśi
528
+ * (look ahead to the next new moon and its saṅkrānti).
529
+ * • 2 → KṢAYA: month is lost; name = the FIRST entered rāśi
530
+ * (the kṣaya month carries the earlier name; the later
531
+ * one is dropped). Flagged kshaya:true.
532
+ * 3. Pūrṇimānta label: in the kṛṣṇa pakṣa it rolls forward to the next month
533
+ * name; in the śukla pakṣa it equals the amānta name. (Adhika/Nija prefix
534
+ * carries through unchanged.)
535
+ */
536
+ // Memoized by (instant, system): lunarMonth is pure and is queried ~2000× per
537
+ // computeFestivals (once per lunation per tithi rule), almost all for the same
538
+ // ~14 lunations. The label depends only on which lunation+pakṣa the instant
539
+ // falls in, so identical instants recur heavily across rules.
540
+ const _lunarMonthCache = new Map();
541
+ export function lunarMonth(at, options = {}) {
542
+ const system = options.system ?? "amanta";
543
+ const key = `${MakeTime(at).date.getTime()}:${system}`;
544
+ const cached = _lunarMonthCache.get(key);
545
+ if (cached)
546
+ return cached;
547
+ const result = lunarMonthUncached(at, system);
548
+ if (_lunarMonthCache.size < 50_000)
549
+ _lunarMonthCache.set(key, result); // bound memory
550
+ return result;
551
+ }
552
+ function lunarMonthUncached(at, system) {
553
+ const t = MakeTime(at);
554
+ const atMs = t.date.getTime();
555
+ const nmStart = newMoonAtOrBefore(atMs);
556
+ const nmEnd = newMoonAfter(nmStart.getTime());
557
+ const nmStartMs = nmStart.getTime();
558
+ const nmEndMs = nmEnd.getTime();
559
+ const elong = elongation(at);
560
+ const paksha = elong < 180 ? "shukla" : "krishna";
561
+ const sankrantis = sankrantisInLunation(nmStartMs, nmEndMs);
562
+ let amantaMonth;
563
+ let adhika = false;
564
+ let kshaya = false;
565
+ if (sankrantis.length === 1) {
566
+ amantaMonth = sankrantis[0];
567
+ }
568
+ else if (sankrantis.length === 0) {
569
+ // Adhika: inherit the following lunation's saṅkrānti name.
570
+ adhika = true;
571
+ const nmNextEnd = newMoonAfter(nmEndMs);
572
+ const nextSankrantis = sankrantisInLunation(nmEndMs, nmNextEnd.getTime());
573
+ // The following lunation should contain exactly one saṅkrānti; use its rāśi.
574
+ amantaMonth = nextSankrantis.length > 0 ? nextSankrantis[0]
575
+ // Degenerate fallback: name after the Sun's rāśi at nmEnd.
576
+ : siderealSunRashi(new Date(nmEndMs));
577
+ }
578
+ else {
579
+ // Two (or more) saṅkrāntis: kṣaya. Carry the first entered rāśi name.
580
+ kshaya = true;
581
+ amantaMonth = sankrantis[0];
582
+ }
583
+ const amantaName = LUNAR_MONTH_NAMES[amantaMonth];
584
+ const prefix = adhika ? "Adhika " : "";
585
+ const amantaLabel = `${prefix}${amantaName}`;
586
+ // Pūrṇimānta: kṛṣṇa pakṣa belongs to the NEXT month's name.
587
+ const purnimantaMonth = paksha === "krishna" ? (amantaMonth + 1) % 12 : amantaMonth;
588
+ const purnimantaName = LUNAR_MONTH_NAMES[purnimantaMonth];
589
+ const purnimantaLabel = `${prefix}${purnimantaName}`;
590
+ const month = system === "purnimanta" ? purnimantaMonth : amantaMonth;
591
+ const monthName = system === "purnimanta" ? purnimantaLabel : amantaLabel;
592
+ return {
593
+ month,
594
+ monthName,
595
+ paksha,
596
+ adhika,
597
+ kshaya,
598
+ amantaMonth,
599
+ amantaLabel,
600
+ purnimantaLabel,
601
+ };
602
+ }
603
+ //# sourceMappingURL=elements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements.js","sourceRoot":"","sources":["../src/elements.ts"],"names":[],"mappings":"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"}