panchang-ts 3.0.1 → 4.0.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 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 types) | **Offline** (pure JS math, no network) | **6,912 tests**
8
+ **Fast** (~0.1 ms names-only, ~0.5 ms full) | **Typed** (full TypeScript types) | **Offline** (pure JS math, no network) | **7,156 tests**
9
9
 
10
10
  ---
11
11
 
@@ -41,10 +41,16 @@ sources, and exposed through the public API. Click a row to jump to its usage ex
41
41
  | **Planetary Positions** | All 9 grahas (sidereal) with rashi, nakshatra, pada, retrograde — mean or true Rahu/Ketu | [↓](#11-planetary-positions) |
42
42
  | **Vimshottari Dasha** | Maha → Antar → Pratyantar (3-level) breakdown from birth | [↓](#12-vimshottari-dasha) |
43
43
  | **Personal Transits** | Chandra Balam, Tarabala (9-tara cycle), Sade Sati (Saturn arc) | [↓](#13-personal-transits) |
44
- | **Birth Chart (Kundli)** | Lagna (sidereal), Bhava under 3 house systems, D1 (Rashi), D9 (Navamsa), Planetary Dignity | [↓](#14-birth-chart-kundli) |
45
- | **Compatibility & Doshas** | Ashtakoot Guna Milan (36-point), Mangal Dosha (Manglik) | [↓](#15-compatibility--doshas) |
46
- | **Localization** | English + Hindi (Devanagari) on every returned name | [↓](#16-localization) |
47
- | **Configuration** | 5 ayanamsas (Lahiri, Raman, KP, True Chitrapaksha, Thirukanitham), 2 masa systems, 3 house systems, 21 regional festival scopes | [↓](#17-configuration) |
44
+ | **Birth Chart (Kundli)** | Lagna (sidereal), Bhava under 3 house systems, D1 / D2 / D3 / D7 / D9 / D10 / D12 / D30 charts, Planetary Dignity | [↓](#14-birth-chart-kundli) |
45
+ | **Compatibility & Doshas** | Ashtakoot Guna Milan (36-point), Pathu Porutham (Tamil 10-fold), Mangal Dosha, Kaal Sarp Dosha (12 subtypes), Pitru Dosha | [↓](#15-compatibility--doshas) |
46
+ | **Aspects & Strength** | Drishti (graha aspects), Shadbala (six-fold strength), Ashtakavarga (Bhinnashtaka + Sarvashtaka), Yogas (25 named), Karakas, Bhava Bala, Argala | [↓](#16-aspects--strength) |
47
+ | **Annual & Sensitive Layers** | Varshaphala (Tajik annual chart + 27 Sahams), Tithi Pravesha, Arudha padas, Hora/Ghati/Bhava/Sripati lagnas, Upagrahas (Gulika, Mandi, Dhuma, Vyatipata, Parivesha, Indrachapa, Upaketu) | [↓](#16-aspects--strength) |
48
+ | **KP & Prashna** | KP sub-lord at any longitude, cuspal sub-lords (Placidus-KP), KP significators, Prashna (horary) chart | [↓](#16-aspects--strength) |
49
+ | **Dasha Systems** | Vimshottari (Maha→Antar→Pratyantar), Ashtottari, Yogini, Chara (Jaimini), Narayan (Jaimini with padi direction) | [↓](#17-dasha-systems) |
50
+ | **Muhurta Engine** | Configurable scoring + 13 stock occasions (vivah, griha pravesh, namakarana, …) | [↓](#18-muhurta-engine) |
51
+ | **Calendar Conversion** | Gregorian↔Hindu, Kali Yuga year, Hindu New Year, yearly Ekadashi / Sankranti / festival listings | [↓](#19-calendar-conversion) |
52
+ | **Localization** | English + Hindi (Devanagari) on every returned name | [↓](#20-localization) |
53
+ | **Configuration** | 5 ayanamsas (Lahiri, Raman, KP, True Chitrapaksha, Thirukanitham), 2 masa systems, 3 house systems, 21 regional festival scopes | [↓](#21-configuration) |
48
54
 
49
55
  ---
50
56
 
@@ -221,7 +227,7 @@ Pratah / Sayahna Sandhya, and nakshatra-keyed Amrit Kala.
221
227
  const r = getDailyPanchang(date, loc, { timezone: 330 })!;
222
228
 
223
229
  r.brahmaMuhurta; // two muhurtas before sunrise
224
- r.abhijitMuhurta; // 8th day-muhurta universally auspicious
230
+ r.abhijitMuhurta; // 8th day-muhurta, or null on Wednesday (Buddha-vara, Drik convention)
225
231
  r.vijayaMuhurta; // 11th day-muhurta — auspicious for success
226
232
  r.godhuliMuhurta; // "cow-dust" — sunset muhurta
227
233
  r.nishitaMuhurta; // midnight muhurta (Shivaratri)
@@ -471,13 +477,15 @@ const sadeSati = computeSadeSati(natalMoonRashiIndex, new Date());
471
477
 
472
478
  ## 14. Birth Chart (Kundli)
473
479
 
474
- Sidereal **Lagna**, **Bhava** under three house systems, **D1 (Rashi)** and **D9
475
- (Navamsa)** charts placing all 9 grahas, and **Planetary Dignity**.
480
+ Sidereal **Lagna**, **Bhava** under three house systems, **D1 (Rashi)** + six classical
481
+ divisional charts (**D2 Hora**, **D3 Drekkana**, **D7 Saptamsa**, **D9 Navamsa**, **D10
482
+ Dasamsa**, **D12 Dwadasamsa**, **D30 Trimsamsa**) placing all 9 grahas, and **Planetary
483
+ Dignity**.
476
484
 
477
485
  ```typescript
478
486
  import {
479
487
  computeLagna, computeBhava, computeRashiChart, computeNavamsa,
480
- computeDignity,
488
+ computeDivisionalChart, computeDignity,
481
489
  } from 'panchang-ts';
482
490
 
483
491
  const birth = new Date('1995-08-15T05:30:00Z');
@@ -501,23 +509,39 @@ d1.planets.find(p => p.planet === 'Saturn')?.isRetrograde;
501
509
  // 4. D9 (Navamsa) chart — classical sign-based per-rashi-type rule
502
510
  const d9 = computeNavamsa(birth, loc);
503
511
 
504
- // 5. Planetary dignity (BPHS Ch.3-4)
512
+ // 5. Divisional charts (D2/D3/D7/D10/D12/D30) via the unified API
513
+ const d10 = computeDivisionalChart(birth, loc, 'D10'); // career
514
+ const d30 = computeDivisionalChart(birth, loc, 'D30'); // misfortune
515
+ // → { divisional: 'D10', lagnaRashi, planets[] }
516
+
517
+ // 6. Planetary dignity (BPHS Ch.3-4)
505
518
  computeDignity('Mars', 0); // 'moolatrikona' (Aries)
506
519
  computeDignity('Mars', 9); // 'exalted' (Capricorn)
507
520
  computeDignity('Sun', 6); // 'debilitated' (Libra)
508
521
  ```
509
522
 
523
+ The seven divisional kinds are: **D2 Hora** (wealth), **D3 Drekkana** (siblings),
524
+ **D7 Saptamsa** (children), **D9 Navamsa** (partner / dharma), **D10 Dasamsa** (career),
525
+ **D12 Dwadasamsa** (parents), **D30 Trimsamsa** (misfortune). Each follows its classical
526
+ per-rashi-type mapping per BPHS Ch. 6; D30 uses the non-uniform 5-segment split with
527
+ Mars / Saturn / Jupiter / Mercury / Venus rulership (no Sun / Moon segments).
528
+
510
529
  Birth-chart helpers accept the full ayanamsa set including `'true-chitra'` (True
511
530
  Chitrapaksha) and `'thirukanitham'` (Tamil-Vakya). Pass via `options.ayanamsa` or the
512
531
  ayanamsa positional arg.
513
532
 
514
533
  ## 15. Compatibility & Doshas
515
534
 
516
- **Ashtakoot Guna Milan** (36-point marriage compatibility) and **Mangal Dosha** (Manglik
517
- affliction with cancellations).
535
+ **Ashtakoot Guna Milan** (36-point marriage compatibility), **Pathu Porutham**
536
+ (Tamil 10-fold counterpart — see ["Pathu Porutham" in §16](#pathu-porutham-tamil-10-fold-marriage-matching)),
537
+ **Mangal Dosha** (Manglik with cancellations), **Kaal Sarp Dosha** (12 named subtypes
538
+ by Rahu's house), and **Pitru Dosha** (ancestral affliction triggers).
518
539
 
519
540
  ```typescript
520
- import { computeAshtakoot, computeMangalDosha } from 'panchang-ts';
541
+ import {
542
+ computeAshtakoot, computeMangalDosha,
543
+ computeKaalSarp, computePitruDosha,
544
+ } from 'panchang-ts';
521
545
 
522
546
  // Ashtakoot — from natal Moons
523
547
  const match = computeAshtakoot(
@@ -531,14 +555,753 @@ const match = computeAshtakoot(
531
555
  // Mangal Dosha — checks Mars from lagna, Moon, and Venus
532
556
  const mangal = computeMangalDosha(d1);
533
557
  // → { afflicted, fromLagna, fromMoon, fromVenus, cancellations }
558
+
559
+ // Kaal Sarp Dosha — all 7 visible planets between Rahu and Ketu axis
560
+ const ksd = computeKaalSarp(d1);
561
+ // → { afflicted, subtype, partial, rahuHouse, ketuHouse }
562
+ // subtype is one of: anant, kulik, vasuki, shankhpal, padma, mahapadma,
563
+ // takshak, karkotak, shankhachud, ghatak, vishdhar, sheshnag — by Rahu's house.
564
+
565
+ // Pitru Dosha — Sun + Rahu/Ketu in same house, OR Sun + Saturn in 9th
566
+ const pitru = computePitruDosha(d1);
567
+ // → { afflicted, reasons: string[] }
534
568
  ```
535
569
 
536
570
  **Documented limitations** — Mangal Dosha cancellations only cover Mars in own sign
537
571
  (Aries / Scorpio) or exalted (Capricorn); other classical cancellations (mutual Mangalik,
538
572
  Mars-Jupiter aspect, Mars-Saturn conjunction) are not applied. Ashtakoot Vashya koot is
539
- simplified to single-vashya per rashi.
573
+ simplified to single-vashya per rashi. Pitru Dosha surfaces the two highest-frequency
574
+ classical triggers (Sun + node, Sun + Saturn in 9th); the full BPHS catalog of triggers
575
+ (debilitated 9th lord, 9th lord in dusthana, etc.) is out of scope.
576
+
577
+ ## 16. Aspects & Strength
578
+
579
+ **Drishti** (planetary aspects per BPHS Ch. 26) and **Shadbala** (six-fold strength per
580
+ BPHS Ch. 27).
581
+
582
+ ```typescript
583
+ import { computeAspects, computeShadbala } from 'panchang-ts';
584
+
585
+ // Aspects — every graha aspects the 7th house from itself; malefics gain
586
+ // extra special aspects (Mars 4 + 8, Jupiter 5 + 9, Saturn 3 + 10).
587
+ const aspects = computeAspects(d1);
588
+ // → { Sun: [houses…], Moon: [...], …, Saturn: [...], Rahu: [...], Ketu: [...] }
589
+ //
590
+ // Default treats Rahu/Ketu with the 7th-only BPHS-literal rule. Pass
591
+ // { nodeAspects: '5-and-9' } to extend nodes with Jupiter-like 5/9 aspects
592
+ // (BV Raman / KP convention).
593
+
594
+ // Shadbala — 7 visible grahas, 6 components per planet, in Virupas (60 V = 1 Rupa).
595
+ const bala = computeShadbala(birth, loc);
596
+ // → { Sun: { sthana, dig, kala, chesta, naisargika, drik, total }, Moon: …, … }
597
+ //
598
+ // Components implemented at the simplified-model level used by ProKerala /
599
+ // PyJHora — Uchcha-only Sthana, Dig from directional cusp, Nathonatha + Paksha
600
+ // for Kala, retrograde-bucket Chesta, fixed Naisargika rank, weighted Drik.
601
+ ```
602
+
603
+ Both functions return additive surface — they do **not** modify the
604
+ `getDailyPanchang` / birth-chart pipelines. Call them on demand.
605
+
606
+ ### Ashtakavarga
607
+
608
+ **Ashtakavarga** (BPHS Ch. 66) — per-graha 12-rashi bindu grids
609
+ (Bhinnashtaka) and the summed Sarvashtaka grid. Each cell counts how many
610
+ of the 8 contributors (the 7 visible grahas + the lagna) donate a benefic
611
+ dot to that rashi for the given receiver.
612
+
613
+ ```typescript
614
+ import { computeRashiChart, computeAshtakavarga } from 'panchang-ts';
615
+
616
+ const chart = computeRashiChart(birth, loc);
617
+ const av = computeAshtakavarga(chart);
618
+
619
+ av.sarvashtaka;
620
+ // → 12-cell grid (Mesha … Meena), each 0..56, total 336.
621
+
622
+ av.bhinnashtaka.Jupiter;
623
+ // → Jupiter's 12-cell grid; total = 56 (chart-invariant per BPHS).
624
+ // Other invariant totals: Sun=47, Moon=49, Mars=39, Mercury=54,
625
+ // Venus=52, Saturn=39.
626
+
627
+ // Opt in to Trikona + Ekadhipatya Sodhana reductions (BPHS Ch. 67):
628
+ const reduced = computeAshtakavarga(chart, { reductions: true });
629
+ reduced.reduced!.sarvashtaka; // post-reduction Sarvashtaka
630
+ reduced.reduced!.bhinnashtaka.Jupiter; // post-reduction Bhinnashtaka
631
+ ```
632
+
633
+ The BENEFIC_OFFSETS lookup table is the canonical BPHS Ch. 66 form used by
634
+ every public Ashtakavarga calculator (ProKerala, AstroSage, PyJHora). Rahu
635
+ and Ketu are not Ashtakavarga receivers or contributors in the classical
636
+ Parashara scheme.
637
+
638
+ ### Yogas (named classical combinations)
639
+
640
+ **Yogas** (BPHS Chs. 36–43) — detect ~25 classical combinations from a
641
+ natal chart against a fixed declarative catalog. Each entry returns a
642
+ `name`, a `type` (one of `mahapurusha | lunar | solar | raja | dhana |
643
+ special | cancellation | negative`), and one-or-more `reasons[]` strings
644
+ describing why the rule matched.
645
+
646
+ ```typescript
647
+ import { computeRashiChart, computeNavamsa, computeYogas } from 'panchang-ts';
648
+
649
+ const chart = computeRashiChart(birth, loc);
650
+ const yogas = computeYogas(chart);
651
+ // → [{ name: 'Gajakesari', type: 'lunar',
652
+ // reasons: ['Jupiter in 4th from Moon (kendra)'] }, …]
653
+
654
+ // Filter by type — restricts evaluation to a subset of the catalog.
655
+ const raja = computeYogas(chart, { types: ['raja', 'dhana'] });
656
+
657
+ // Vargottama needs the D9 — pass it via options.
658
+ const d9 = computeNavamsa(birth, loc);
659
+ const all = computeYogas(chart, { navamsa: d9 });
660
+ ```
661
+
662
+ The catalog covers Pancha Mahapurusha (Ruchaka / Bhadra / Hamsa / Malavya
663
+ / Sasha), lunar yogas (Gajakesari, Sunapha, Anapha, Durudhura, Kemadruma),
664
+ solar yogas (Budha-Aditya, Veshi, Vasi, Ubhayachari), Raja yogas (generic
665
+ kendra/trikona-lord rule, Dharma-Karmadhipati, Vipareeta Raja, Lakshmi),
666
+ Dhana yogas (2–11, 5–9, Vasumati), Vargottama, Yogakaraka, Neecha Bhanga,
667
+ and Daridra. Yoga names are English/transliterated proper nouns and are
668
+ intentionally **not** locale-resolved — `'Gajakesari'` reads the same in
669
+ `'en'` and `'hi'`.
670
+
671
+ Adding a new yoga is a data-only change in
672
+ [src/jyotish/yogasCatalog.ts](src/jyotish/yogasCatalog.ts) — the engine
673
+ is a thin loop over the catalog. Each rule receives the chart plus
674
+ precomputed `dignity` / `aspects` (and optionally a D9 chart) and returns
675
+ a `YogaMatch | null`.
676
+
677
+ ### Jaimini Karakas
678
+
679
+ **Karakas** (Jaimini *Upadesa Sutras* Ch. 1, Parashara variant) — the 7
680
+ Chara Karakas ranked by descending degree-in-rashi of the visible grahas.
681
+ Atmakaraka (highest) signifies the Self; Darakaraka (lowest) signifies
682
+ spouse.
683
+
684
+ ```typescript
685
+ import { computeRashiChart, computeJaiminiKarakas } from 'panchang-ts';
686
+
687
+ const chart = computeRashiChart(birth, loc);
688
+ const k = computeJaiminiKarakas(chart);
689
+ k.Atmakaraka; // graha at the highest degree-in-rashi (e.g. 'Saturn')
690
+ k.Amatyakaraka; // 2nd-highest
691
+ k.Darakaraka; // graha at the lowest degree-in-rashi
692
+ ```
693
+
694
+ The 7 visible grahas are ranked — Rahu and Ketu are not included (this is
695
+ the **7-Karaka Parashara variant**, not the reversed-Rahu 8-Karaka Jaimini
696
+ variant). On the rare exact tie in degree-in-rashi, the canonical order
697
+ Sun → Moon → Mars → Mercury → Jupiter → Venus → Saturn breaks the tie
698
+ (stable sort) — the earlier graha wins the more-significant Karaka role.
699
+
700
+ Karaka names are English/transliterated proper nouns and intentionally
701
+ **not** locale-resolved.
702
+
703
+ ### Bhava Bala
704
+
705
+ **Bhava Bala** (BPHS Ch. 27) — four-source house strength for the 12 bhavas
706
+ of a natal chart, in Virupas (60 V = 1 Rupa). Built on top of `computeShadbala`
707
+ — the natural-strength table, drishti weights, and benefic/malefic
708
+ classification are all shared.
709
+
710
+ ```typescript
711
+ import { computeBhavaBala } from 'panchang-ts';
712
+
713
+ const bhavaBala = computeBhavaBala(birth, loc);
714
+ bhavaBala.houses.length; // 12 (one entry per bhava, index 0 = bhava 1)
715
+ bhavaBala.houses[0].total; // 1st-bhava total in Virupas
716
+ bhavaBala.houses[9].bhavadhipati; // 10th-bhava lord's Shadbala total
717
+ // → each entry: { bhavadhipati, dik, drik, sthana, total }
718
+ ```
719
+
720
+ `bhavadhipati` is the total Shadbala of the rashi-lord of the bhava cusp;
721
+ `dik` is a fixed directional value from a simplified cardinal-anchor table
722
+ (cardinal bhavas anchor at 60 / 0 / 15 / 30 V; intermediates linearly
723
+ interpolated around the wheel — not the canonical BPHS Ch. 27 numbers);
724
+ `drik` is the net aspect strength on the cusp from the 7 visible grahas
725
+ (benefics +, malefics −, clamped ≥ 0); `sthana` sums the natural strength
726
+ of grahas occupying the bhava (Mercury counted as benefic per BPHS — the
727
+ "associated benefic" nuance is intentionally out of scope). Rahu and Ketu
728
+ do not contribute. `total` is the arithmetic sum of the four components.
729
+
730
+ ### Varshaphala (Tajik annual horoscope)
731
+
732
+ **Varshaphala** is the Tajik solar-return chart for a given age of the
733
+ native, with the classical analytical layer — Muntha, year lord
734
+ (Varsha Pati), and the 27 core Sahams — already computed.
735
+
736
+ ```typescript
737
+ import { computeVarshaphala } from 'panchang-ts';
738
+
739
+ const birth = new Date('1995-08-15T05:30:00Z');
740
+ const loc = { latitude: 28.6139, longitude: 77.2090 };
741
+
742
+ const varsha = computeVarshaphala(birth, 30, loc); // 30th solar return
743
+ varsha.solarReturnInstant; // exact UTC moment Sun returns to natal lon
744
+ varsha.varshaLagna.rashi.name; // ascendant rashi at the SR instant
745
+ varsha.muntha.rashi; // (natalLagnaRashi + 30) mod 12
746
+ varsha.muntha.lord; // rashi-lord of muntha rashi
747
+ varsha.muntha.house; // muntha's house from varsha lagna (1..12)
748
+ varsha.yearLord; // strongest of 4 candidates by Shadbala
749
+ varsha.isDayBirth; // Sun above horizon at SR instant?
750
+
751
+ // 27 Sahams (Punya, Vidya, …, Tapas) — each: { longitude, rashi, rashiName, house }
752
+ varsha.sahams.Punya.longitude;
753
+ varsha.sahams.Punya.house; // Punya's house from varsha lagna
754
+ varsha.sahams.Vivaha.rashi; // Vivaha (marriage) Saham rashi
755
+ ```
756
+
757
+ **Solar-return search.** A Newton-style refinement around `birth +
758
+ N × 365.25636 days` finds the UTC instant where sidereal Sun returns
759
+ to its natal longitude (within 0.0001° / ~9 arcseconds). Convergence
760
+ is 3–5 iterations on cooperative inputs.
761
+
762
+ **Year lord (Varsha Pati).** Picked as the planet with the highest
763
+ total Shadbala among:
764
+ 1. Varsha lagna lord
765
+ 2. Muntha lord
766
+ 3. Lord of the Sun's rashi at the varsha instant
767
+ 4. Triraashi Pati (3-rashi-trine ruler) of the varsha lagna's element,
768
+ per the Tajik day/night table (fire→Sun day / Jupiter night;
769
+ earth→Venus / Moon; air→Saturn / Mercury; water→Venus / Mars)
770
+
771
+ **Sahams scope.** This is the **27-Saham core set** — Punya, Vidya,
772
+ Yasas, Mitra, Karma, Vivaha, Putra, Roga, Marana, Rajya, Raja, Bandhu,
773
+ Dharma, Gnati, Apamrityu, Bhratri, Matri, Pitri, Sama, Bandhana,
774
+ Karyasiddhi, Vyapara, Sastra, Asha, Labha, Susha, Tapas. The extended
775
+ 50-Saham list (Mahaprasna, Adhana, Krodha, Kali, …) is deferred to a
776
+ later release. Day/night X-Y operand swap follows **Neelakantha**'s
777
+ *Tajika Neelakanthi*; 9 Sahams (Punya, Vidya, Karma, Putra, Roga,
778
+ Gnati, Bhratri, Matri, Pitri) flip on night birth. Other Tajik
779
+ commentators (Hari Hara) define different swap subsets — documented
780
+ in [src/jyotish/sahamsTables.ts](src/jyotish/sahamsTables.ts).
781
+
782
+ **Sourcing:** Neelakantha *Tajika Neelakanthi* (1587 CE); B.V. Raman
783
+ *Annual Horoscope*; Sanjay Rath *Crux of Vedic Astrology* Tajik
784
+ appendix; PVR Narasimha Rao *Tajik notes* (Saptarishis Astrology).
785
+ Saham names are English/transliterated proper nouns and intentionally
786
+ **not** locale-resolved (same convention as Yoga names).
787
+
788
+ ### Tithi Pravesha (annual soli-lunar return)
789
+
790
+ **Tithi Pravesha** is the South-Indian annual chart cast at the moment
791
+ in year-N when *both* (a) the sidereal Sun is in its natal sidereal
792
+ sign **and** (b) the Sun-Moon angular separation equals the natal
793
+ separation. The tithi is preserved exactly — `praveshTithi` always
794
+ equals `natalTithi`.
795
+
796
+ ```typescript
797
+ import { computeTithiPravesha } from 'panchang-ts';
798
+
799
+ const tp = computeTithiPravesha(
800
+ new Date('1995-08-15T05:30:00Z'),
801
+ 30, // 30th annual cycle
802
+ { latitude: 28.6139, longitude: 77.2090 }, // New Delhi
803
+ );
804
+ tp.praveshInstant; // exact UTC moment
805
+ tp.natalTithi === tp.praveshTithi; // always true
806
+ tp.varshaLagna.rashi.name; // ascendant at pravesha
807
+ tp.planets; // 9-graha placements
808
+ tp.bhava.houses; // 12 cusps under configured house system
809
+ ```
810
+
811
+ **Algorithm.** The implementation follows **PVR Narasimha Rao's
812
+ redefinition** (Saptarishis Astrology) rather than the older calendar-
813
+ anniversary heuristic:
814
+
815
+ 1. Compute the natal Sun-Moon angular separation `Δ_natal`.
816
+ 2. Locate the **solar-return instant** for the requested year (re-uses
817
+ the Varshaphala Newton search).
818
+ 3. Newton-iterate on the Moon-Sun phase deviation until
819
+ `(Moon − Sun) mod 360°` equals `Δ_natal` to better than 0.0001°.
820
+ 4. If Sun's rashi at that instant differs from natal Sun's rashi
821
+ (closest tithi-match landed across a sign boundary), shift by one
822
+ synodic month (~29.5 days) toward the solar-return centre and
823
+ re-iterate. Adjacent tithi-matches are 29.53 days apart and the
824
+ Sun-in-natal-sign window is 30.4 days wide, so exactly one
825
+ neighbour falls in the natal sign for every fixture.
826
+
827
+ The pravesha instant can therefore be up to ~30 days before or after
828
+ the calendar anniversary depending on where the natal moon was in the
829
+ synodic cycle.
830
+
831
+ **Sourcing:** Sanjay Rath, *Tithi Pravesha* (srath.com); PVR Narasimha
832
+ Rao, *Re-Defining Tithi Pravesha Chart* (Saptarishis Astrology Vol. 8).
833
+
834
+ ### Arudha Lagna + 12 Arudha Padas
835
+
836
+ The **Arudha pada** of a bhava is the rashi reached by counting from the
837
+ bhava's lord the same number of houses as the lord is from the bhava
838
+ itself. Each Arudha is the *image / reflection* of its bhava — Bhava 1's
839
+ Arudha is **Arudha Lagna (AL)**, the social / public-facing self
840
+ (distinct from Lagna, which is the inner / soul-rooted self).
841
+
842
+ ```typescript
843
+ import { computeRashiChart, computeArudhas } from 'panchang-ts';
844
+
845
+ const chart = computeRashiChart(
846
+ new Date('1995-08-15T05:30:00Z'),
847
+ { latitude: 28.6139, longitude: 77.2090 },
848
+ );
849
+ const arudhas = computeArudhas(chart);
850
+ arudhas.length; // 12
851
+ arudhas[0]!.bhava; // 1 — this is Arudha Lagna (AL)
852
+ arudhas[0]!.arudhaRashi; // 0..11
853
+ arudhas[0]!.arudhaRashiName; // localized rashi name
854
+ arudhas[0]!.arudhaLord; // rashi-lord of arudha rashi
855
+ arudhas[6]!.bhava; // 7 — Darapada (spouse pada)
856
+ ```
857
+
858
+ **Algorithm.** Per Jaimini *Upadesa Sutras* Ch. 1 (Sanjay Rath
859
+ commentary):
860
+
861
+ 1. For each bhava `B`, find the rashi the bhava's lord *occupies*.
862
+ 2. Compute `D` = inclusive distance from the bhava to its lord (1..12,
863
+ so lord-in-own-bhava → D=1).
864
+ 3. Standard rule: count another `D` houses from the lord →
865
+ `arudha = (lordRashi + D − 1) mod 12`.
866
+ 4. **Two exceptions** to avoid the Arudha collapsing onto the bhava
867
+ itself or its 7th:
868
+ - `D == 1` (lord in own bhava) → Arudha = **10th** from lord
869
+ (`lordRashi + 9 mod 12`).
870
+ - `D == 7` (lord in 7th from bhava) → Arudha = **4th** from lord
871
+ (`lordRashi + 3 mod 12`).
872
+
873
+ `arudhaLord` is the rashi-lord of the *Arudha rashi itself* (not the
874
+ original bhava's lord) — useful for analysing the pada's significations
875
+ directly.
876
+
877
+ **Sourcing:** Jaimini, *Upadesa Sutras* Ch. 1; Sanjay Rath, *Jaimini
878
+ Maharishi's Upadesa Sutras* (commentary); BPHS Ch. 29.
879
+
880
+ ### Special Lagnas (Hora / Ghati / Bhava / Sripati)
881
+
882
+ Time-derived sensitive lagnas used in classical timing analysis. Each
883
+ advances at a different rate from the sunrise on or before the birth
884
+ instant.
885
+
886
+ ```typescript
887
+ import {
888
+ computeHoraLagna, computeGhatiLagna, computeBhavaLagna, computeSripatiLagna,
889
+ } from 'panchang-ts';
890
+
891
+ const birth = new Date('1995-08-15T05:30:00Z');
892
+ const loc = { latitude: 28.6139, longitude: 77.2090 };
893
+
894
+ const hora = computeHoraLagna(birth, loc); // 1 rashi / 1 hour from sunrise
895
+ const ghati = computeGhatiLagna(birth, loc); // 1 rashi / 1 ghatika (24 min)
896
+ const bhava = computeBhavaLagna(birth, loc); // 1 rashi / 5 ghatikas (2 hours)
897
+ const sripati = computeSripatiLagna(birth, loc); // Sripati cusp 1 = natal lagna
898
+ hora.rashi.name; // each returns a `LagnaInfo` with rashi / nakshatra / pada
899
+ ```
900
+
901
+ | Lagna | Rate | Period |
902
+ |-------|------|--------|
903
+ | Hora | 30°/hour (1 rashi / 1 hour) | 12 hours |
904
+ | Ghati | 75°/hour (1 rashi / 24 min) | 4 h 48 min |
905
+ | Bhava | 15°/hour (1 rashi / 2 hours) | 24 hours |
906
+ | Sripati | n/a (= natal lagna) | n/a |
907
+
908
+ > **Note.** Hora Lagna advances at 30°/hour (1 rashi / hour) per BPHS
909
+ > Ch. 4 and *Phaladeepika* Ch. 1 — twice the rate of Bhava Lagna,
910
+ > which advances at 15°/hour (1 rashi / 5 ghatikas). The two are
911
+ > numerically distinct timing anchors, not interchangeable. Sripati
912
+ > Lagna currently returns the natal ascendant (Sripati cusp-1 by
913
+ > construction); the bhava-midpoint form is a future extension.
914
+
915
+ **Sourcing:** BPHS Ch. 4; *Phaladeepika* Ch. 1; Sripati, *Sripati Paddhati*.
916
+
917
+ ### Upagrahas (sub-grahas as positions)
918
+
919
+ The 7 upagrahas are sensitive points used in Vedic and Tajik analysis.
920
+ The library returns each one as a **longitude** + rashi + house — the
921
+ position-form, distinct from Phase-2 Gulika *Kalam* (the time-form).
922
+
923
+ ```typescript
924
+ import { computeUpagrahas } from 'panchang-ts';
925
+
926
+ const u = computeUpagrahas(
927
+ new Date('1995-08-15T05:30:00Z'),
928
+ { latitude: 28.6139, longitude: 77.2090 },
929
+ );
930
+ u.gulika.longitude; // sidereal degrees
931
+ u.gulika.rashi; // 0..11
932
+ u.gulika.rashiName; // localized
933
+ u.gulika.house; // whole-sign from natal lagna
934
+ u.mandi.longitude; // Saturn-segment midpoint
935
+ u.dhuma.longitude; // Sun + 133°20'
936
+ u.upaketu.longitude; // Sun + ~150° (after the chain)
937
+ ```
938
+
939
+ **Gulika & Mandi.** Day birth: divide sunrise → sunset into 8 equal
940
+ segments; the day-lord rotation Sun → Moon → Mars → Mercury → Jupiter
941
+ → Venus → Saturn places Saturn at one segment per weekday. Gulika is
942
+ the **rising ascendant at the *start*** of Saturn's segment; Mandi is
943
+ the **rising ascendant at the *midpoint***. Night birth: same procedure
944
+ on the sunset → next-sunrise window, with the rotation starting from
945
+ the planet 5 weekdays from the day-lord (Phaladeepika Ch. 5).
946
+
947
+ **Sun-derived upagrahas.** Fixed offsets from sidereal Sun:
948
+
949
+ | Upagraha | Formula |
950
+ |----------|---------|
951
+ | Dhuma | `Sun + 133°20'` |
952
+ | Vyatipata | `360° − Dhuma` |
953
+ | Parivesha | `Vyatipata + 180°` |
954
+ | Indrachapa | `360° − Parivesha` |
955
+ | Upaketu | `Indrachapa + 16°40'` |
956
+
957
+ `Dhuma + Vyatipata ≡ 360°` and `Parivesha + Indrachapa ≡ 360°` are
958
+ structural invariants that hold for every chart.
959
+
960
+ **Sourcing:** BPHS Ch. 5; Sanjay Rath, *Brihat Nakshatra* (upagraha
961
+ section); Phaladeepika Ch. 5.
962
+
963
+ ### Argala (Jaimini intervention)
964
+
965
+ Per-bhava arc-influence rules from Jaimini *Upadesa Sutras* Ch. 1 and
966
+ BPHS Ch. 51. Planets in the 2nd, 4th, or 11th from a bhava form
967
+ **Argala** (intervention / help); planets in the 3rd, 10th, or 12th
968
+ form **Virodhargala** (counter-intervention).
969
+
970
+ ```typescript
971
+ import { computeRashiChart, computeArgala } from 'panchang-ts';
972
+
973
+ const chart = computeRashiChart(
974
+ new Date('1995-08-15T05:30:00Z'),
975
+ { latitude: 28.6139, longitude: 77.2090 },
976
+ );
977
+ const argala = computeArgala(chart);
978
+ argala[0]!.bhava; // 1
979
+ argala[0]!.argala; // PlanetPlacement[] in 2nd / 4th / 11th from lagna
980
+ argala[0]!.virodhargala; // PlanetPlacement[] in 3rd / 10th / 12th from lagna
981
+ ```
982
+
983
+ **Structural invariant.** Each planet contributes to **exactly 6 of
984
+ the 12 bhavas** — 3 Argala + 3 Virodhargala. The 2/4/11 and 3/10/12
985
+ offsets are mutually exclusive, so a planet's house position
986
+ deterministically partitions the bhava wheel into a 6-cell influence
987
+ set.
988
+
989
+ All 9 grahas (Sun..Saturn + Rahu + Ketu) participate. Benefic / malefic
990
+ distinction is not applied — the caller can filter the returned lists
991
+ by graha if their tradition requires it. The 5th-from-bhava ("primary
992
+ Argala") and 9th ("primary Virodhargala") are not included in this
993
+ simplified BPHS Ch. 51 form.
994
+
995
+ **Sourcing:** Jaimini, *Upadesa Sutras* Ch. 1; BPHS Ch. 51.
996
+
997
+ ### Pathu Porutham (Tamil 10-fold marriage matching)
998
+
999
+ Tamil/Kerala marriage compatibility test, scored across **10 koots**.
1000
+ Used instead of Ashtakoot in Tamil Nadu, Kerala, and parts of Karnataka.
1001
+ Each koot is binary-scored (pass / fail) per the AstroVed / Drik Tamil
1002
+ convention; the aggregate score is the count of passing koots in 0..10.
1003
+ Three koots (Yoni, Rajju, Vedha) are **strong vetoes** — if any fails,
1004
+ `recommended` flips to false regardless of the count.
1005
+
1006
+ ```typescript
1007
+ import { computePathuPorutham } from 'panchang-ts';
1008
+
1009
+ const result = computePathuPorutham(
1010
+ { rashi: 4, nakshatra: 9 }, // Boy: Magha / Leo
1011
+ { rashi: 0, nakshatra: 1 }, // Girl: Bharani / Aries
1012
+ );
1013
+ result.totalPasses; // 0..10
1014
+ result.recommended; // boolean (no veto + ≥5 passes)
1015
+ result.poruthams[4]!.name; // 'Yoni' (a veto-level koot)
1016
+ result.poruthams[8]!.veto; // true if Rajju fails
1017
+ ```
1018
+
1019
+ **Koot catalog:**
1020
+
1021
+ | Koot | Tests | Veto |
1022
+ |----------------|-----------------------------------------------------|:----:|
1023
+ | Dina | Boy→Girl nakshatra distance mod 9 ∈ {1, 3, 5, 7} | no |
1024
+ | Gana | Reuses Phase 29 NAKSHATRA_GANA — Manushya↔Rakshasa fails | no |
1025
+ | Mahendra | Distance ∈ {4, 7, 10, 13, 16, 19, 22, 25} | no |
1026
+ | Sthree Deergha | Boy→Girl nakshatra distance > 9 | no |
1027
+ | Yoni | Reuses Phase 29 NAKSHATRA_YONI / YONI_SCORE | yes |
1028
+ | Rashi | Distance not in doshic set ({2,12}, {6,8}) | no |
1029
+ | Rashyathipathi | Rashi-lord friendship (Naisargika Maitri) | no |
1030
+ | Vasya | Reuses Phase 29 RASHI_VASHYA / VASHYA_SCORE | no |
1031
+ | Rajju | Same Rajju (Pada/Kati/Nabhi/Kantha/Sira) fails | yes |
1032
+ | Vedha | Same Vedha pair fails | yes |
1033
+
1034
+ Pathu Porutham and Ashtakoot consume the same `NatalMoon` shape
1035
+ (`{ rashi, nakshatra }`) — call both side-by-side to surface both
1036
+ North-Indian and South-Indian compatibility views.
1037
+
1038
+ **Sources.** *Jathaka Tatva* (Tamil); AstroVed.com 10-Porutham reference;
1039
+ ProKerala's free Pathu Porutham implementation; drikpanchang.com Tamil
1040
+ porutham panel.
1041
+
1042
+ ### Narayan Dasha (Jaimini sign-dasha with padi direction)
1043
+
1044
+ Jaimini sign-based dasha that incorporates the **vishama-pada / sama-pada**
1045
+ parity rule per Sanjay Rath's *Narayana Dasa* (Sagar Publications). Cycle
1046
+ direction depends on which parity-class the lagna's rashi falls into:
1047
+
1048
+ - **Vishama-pada** lagna in {Aries, Taurus, Gemini, Libra, Scorpio,
1049
+ Sagittarius} → cycle proceeds **forward** (zodiacal).
1050
+ - **Sama-pada** lagna in {Cancer, Leo, Virgo, Capricorn, Aquarius,
1051
+ Pisces} → cycle proceeds **backward** (anti-zodiacal).
1052
+
1053
+ ```typescript
1054
+ import { computeNarayanDasha } from 'panchang-ts';
1055
+
1056
+ const narayan = computeNarayanDasha(
1057
+ new Date('1995-08-15T05:30:00Z'),
1058
+ { latitude: 28.6139, longitude: 77.2090 },
1059
+ );
1060
+ narayan.direction; // 'forward' | 'backward'
1061
+ narayan.startingRashi; // lagna rashi (0..11)
1062
+ narayan.mahaDashas[0]!.rashi; // same as startingRashi
1063
+ narayan.mahaDashas[0]!.lord; // sign-lord of starting rashi
1064
+ narayan.mahaDashas[0]!.years; // 7, 8, or 9 per modality
1065
+ ```
1066
+
1067
+ Years per rashi follow the same Movable 9 / Fixed 8 / Dual 7 scheme as
1068
+ Chara Dasha. The Mahadasha sequence covers ~96 years (sum of all 12
1069
+ rashi durations). Lord assignment is the rashi's natural lord (Mars for
1070
+ Aries / Scorpio, Venus for Taurus / Libra, etc.). Antardasha breakdown
1071
+ is not exposed — the Mahadasha alone is the dominant Jaimini timing
1072
+ layer for Narayan analysis.
1073
+
1074
+ **Difference from Chara Dasha** (already shipped): Chara always advances
1075
+ forward from lagna; Narayan applies the parity-based direction. For
1076
+ vishama-pada lagnas the two systems' Mahadasha sequence is identical.
1077
+
1078
+ **Sources.** Sanjay Rath, *Narayana Dasa* (Sagar Publications);
1079
+ *Jaimini Upadesa Sutras* Ch. 2.
1080
+
1081
+ ### KP sub-lord layer
1082
+
1083
+ K.S. Krishnamurti's KP-Paddhati uses a 9-fold subdivision of each
1084
+ nakshatra (243 sub-divisions across the zodiac), proportional to the
1085
+ Vimshottari dasha years of the 9 planets. The sub-lord at any longitude
1086
+ is one of the 9 KP planets (Sun..Saturn + Rahu + Ketu).
1087
+
1088
+ ```typescript
1089
+ import {
1090
+ computeKpSubLord, computeKpCuspalSubLords, computeKpSignificators,
1091
+ computeRashiChart,
1092
+ } from 'panchang-ts';
1093
+
1094
+ // 1. Sub-lord at any sidereal longitude.
1095
+ const info = computeKpSubLord(45.5); // 15°30' Taurus
1096
+ info.signLord; // 'Venus' (rashi lord of Taurus)
1097
+ info.starLord; // 'Moon' (nakshatra lord of Rohini)
1098
+ info.subLord; // KP sub-lord — depends on degree
1099
+
1100
+ // 2. Cuspal sub-lords for the 12 Placidus-KP cusps.
1101
+ const cusps = computeKpCuspalSubLords(
1102
+ new Date('1995-08-15T05:30:00Z'),
1103
+ { latitude: 28.6139, longitude: 77.2090 },
1104
+ );
1105
+ cusps.cusps[0]!.subLord; // sub-lord of cusp 1 (ascendant)
1106
+ cusps.cusps[6]!.subLord; // sub-lord of cusp 7 (descendant)
1107
+
1108
+ // 3. Significators — for each planet, the houses it signifies via the
1109
+ // 4-fold KP rule (occupant + star-lord-occupant + owner + star-lord-owner).
1110
+ const chart = computeRashiChart(birth, location);
1111
+ const sig = computeKpSignificators(chart);
1112
+ sig.byPlanet.Sun; // [houses Sun signifies]
1113
+ sig.byHouse[10]; // [planets that signify the 10th house]
1114
+ ```
1115
+
1116
+ `computeKpCuspalSubLords` always uses the Placidus-KP house system —
1117
+ the cuspal scheme KP analysis is built on. Whole-sign and equal-house
1118
+ cusps fall on rashi boundaries by construction and lose the cuspal-sub-
1119
+ lord granularity that drives KP timing analysis.
1120
+
1121
+ **Sources.** K.S. Krishnamurti, *Krishnamurti Paddhati* (5 vols);
1122
+ KP Astrology online references.
1123
+
1124
+ ### Prashna foundation (horary chart)
1125
+
1126
+ Cast a chart for the precise moment a question is asked, with the
1127
+ querent's location as the geographic anchor. Prashna analysis proceeds
1128
+ on the resulting chart in the same way as a natal chart — houses,
1129
+ planets, dignity, dashas all apply to the question being asked.
1130
+
1131
+ ```typescript
1132
+ import { computePrashnaChart, computeKpCuspalSubLords } from 'panchang-ts';
1133
+
1134
+ // Question asked at a specific UTC moment from Mumbai.
1135
+ const chart = computePrashnaChart(
1136
+ new Date('2026-05-09T14:30:00Z'),
1137
+ { latitude: 19.0760, longitude: 72.8777 },
1138
+ );
1139
+ chart.lagna.rashi.name; // ascendant of the prashna
1140
+ chart.bhava.system; // 'placidus-kp' (KP horary anchor) by default
1141
+ chart.planets[1]!.house; // Moon's house — primary mind significator
1142
+
1143
+ // KP cuspal sub-lord analysis on the prashna cusps:
1144
+ const cusps = computeKpCuspalSubLords(
1145
+ new Date('2026-05-09T14:30:00Z'),
1146
+ { latitude: 19.0760, longitude: 72.8777 },
1147
+ );
1148
+ ```
1149
+
1150
+ The returned shape is identical to a natal `BirthChart`. The dedicated
1151
+ function is intent-named so callers' analysis context is explicit at
1152
+ the call site, and so future Prashna-specific layers (Ruling Planets,
1153
+ horary numbers 1..249, significator-driven event timing) can land
1154
+ additively in this module.
1155
+
1156
+ **Default house system.** Defaults to `'placidus-kp'` — KP horary's
1157
+ standard cuspal scheme. Pass `{ houseSystem: 'whole-sign' }` for
1158
+ traditional Vedic Prashna.
1159
+
1160
+ **Out of scope** (deferred to a later phase):
1161
+ - Ruling Planets (5-fold lord set used to refine timing in KP horary).
1162
+ - Horary number mapping (KP 1..249 number → cusp sub-lord table).
1163
+ - Significator-driven event timing (dasha-walk against significator sets).
1164
+
1165
+ **Sources.** B. Suryanarain Rao, *Prasna Marga*; K.S. Krishnamurti,
1166
+ *Horary Astrology* (KP Reader VI); Sanjay Rath, *Horary Astrology*
1167
+ (srath.com).
1168
+
1169
+ ## 17. Dasha Systems
1170
+
1171
+ Five classical dasha systems are exposed:
1172
+
1173
+ ```typescript
1174
+ import {
1175
+ computeVimshottariDashaFromBirth, computeVimshottariPratyantar,
1176
+ computeAshtottariDasha, computeYoginiDasha, computeCharaDasha,
1177
+ computeNarayanDasha,
1178
+ } from 'panchang-ts';
1179
+
1180
+ const birth = new Date('1995-08-15T05:30:00Z');
1181
+ const loc = { latitude: 28.6139, longitude: 77.2090 };
1182
+
1183
+ // 1. Vimshottari (120-year, 9-lord) — already in v1; pratyantar (3-level) added in v3
1184
+ const vim = computeVimshottariDashaFromBirth(birth);
1185
+ const pratyantars = computeVimshottariPratyantar(vim.mahaDashas[0].antarDashas[0]);
1186
+
1187
+ // 2. Ashtottari (108-year, 8-lord, no Ketu) — used when Moon in Krishna Paksha
1188
+ const moonLon = /* sidereal Moon longitude */ 145.7;
1189
+ const ash = computeAshtottariDasha(birth, moonLon);
1190
+ // → mahaDashas[0..7], lord cycle Sun(6)→Moon(15)→Mars(8)→Mercury(17)→
1191
+ // Saturn(10)→Jupiter(19)→Rahu(12)→Venus(21)
1192
+
1193
+ // 3. Yogini (36-year, 8 yoginis with planetary lords)
1194
+ const yog = computeYoginiDasha(birth, moonLon);
1195
+ yog.mahaDashas[0].yogini; // 'Dhanya' (Magha → nakshatra 10, 10 % 8 = 2)
1196
+ yog.mahaDashas[0].lord; // 'Jupiter' (Dhanya's planet)
1197
+
1198
+ // 4. Chara (Jaimini, sign-based, 9-8-7 years per modality, forward only)
1199
+ const cha = computeCharaDasha(birth, loc);
1200
+ cha.mahaDashas[0].rashi; // lagna's rashi
1201
+ cha.mahaDashas[0].lord; // sign-lord planet
1202
+ cha.mahaDashas[0].years; // 9 (movable) | 8 (fixed) | 7 (dual)
1203
+
1204
+ // 5. Narayan (Jaimini, sign-based, parity-based direction per Sanjay Rath)
1205
+ const nar = computeNarayanDasha(birth, loc);
1206
+ nar.direction; // 'forward' (vishama-pada) | 'backward' (sama-pada)
1207
+ nar.startingRashi; // lagna rashi
1208
+ nar.mahaDashas[0].rashi; // == startingRashi
1209
+ nar.mahaDashas[1].rashi; // depends on direction
1210
+ ```
1211
+
1212
+ **Sourcing:** Vimshottari per Parashara (BPHS Ch. 51); Ashtottari per Satya Acharya;
1213
+ Yogini per Sanjay Rath (1999) / Charak; Chara per Jaimini Sutras Ch. 1 (9-8-7 years
1214
+ variant); Narayan per Sanjay Rath, *Narayana Dasa* (Sagar Publications) — vishama /
1215
+ sama-pada parity rule. Documented limitations: Chara uses the forward zodiacal
1216
+ direction unconditionally (Sundar / Achyutananda variant); the parity-based variant
1217
+ ships separately as `computeNarayanDasha`.
1218
+
1219
+ ## 18. Muhurta Engine
1220
+
1221
+ A configurable rule + scoring engine for picking auspicious dates. Ships with **13 stock
1222
+ rules** (vivah, griha pravesh, namakarana, vidyarambh, vahan kharidi, annaprashan,
1223
+ mundan, upanayanam, karnavedha, aksharabhyasam, seemantham, shop opening, travel
1224
+ start). Each rule is a pure data declaration — write your own without touching the
1225
+ engine.
1226
+
1227
+ ```typescript
1228
+ import { scoreMuhurta, findAuspiciousDates, vivahRule } from 'panchang-ts';
1229
+
1230
+ // Score a single date
1231
+ const r = scoreMuhurta(new Date('2026-05-12'), DELHI, vivahRule, { timezone: 330 });
1232
+ // → { date, score: 0..100, passes: boolean, reasons: string[] }
1233
+
1234
+ // Find all auspicious dates in a range, sorted by score descending
1235
+ const dates = findAuspiciousDates(
1236
+ vivahRule,
1237
+ new Date('2026-05-01'),
1238
+ new Date('2026-05-31'),
1239
+ DELHI,
1240
+ { timezone: 330 },
1241
+ );
1242
+ // → MuhurtaDay[] with full panchang attached for each result
1243
+
1244
+ // Custom rule
1245
+ const myRule: MuhurtaRule = {
1246
+ occasion: 'launch_party',
1247
+ auspiciousVaras: [3, 4, 5], // Wed/Thu/Fri
1248
+ auspiciousNakshatras: [11, 12, 21], // Uttara Phalguni / Hasta / Shravana
1249
+ excludeBhadra: true,
1250
+ excludeEkadashi: true,
1251
+ excludeAdhikaMasa: true,
1252
+ };
1253
+ ```
1254
+
1255
+ Scoring model: starts at 50 (neutral), +10 per matching auspicious axis (tithi,
1256
+ nakshatra, vara, yoga), -15 per matching inauspicious axis, hard exclusions
1257
+ (`excludeBhadra` / `excludeEkadashi` / `excludeEclipse` / `excludeAdhikaMasa` /
1258
+ `excludeGandaMula` / `excludePanchaka` / `requirePaksha` mismatch) zero the score.
1259
+ Special yogas — Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya — add +5;
1260
+ Jwalamukhi yoga subtracts -10. Final score clamped to 0..100; `passes: true` when
1261
+ score ≥ 50.
1262
+
1263
+ ## 19. Calendar Conversion
1264
+
1265
+ Gregorian↔Hindu lunar coordinates, Kali Yuga year, regional Hindu New Year, and
1266
+ yearly listings of Ekadashis / Sankrantis / festivals / eclipses.
1267
+
1268
+ ```typescript
1269
+ import {
1270
+ convertGregorianToHindu, convertHinduToGregorian,
1271
+ getKaliYugaYear, getHinduNewYear,
1272
+ getEkadashiDatesForYear, getSankrantisForYear,
1273
+ getFestivalsInRange, getUpcomingEclipses,
1274
+ } from 'panchang-ts';
1275
+
1276
+ // Gregorian → Hindu coordinates at sunrise
1277
+ const h = convertGregorianToHindu(new Date('2026-04-15'), DELHI, { timezone: 330 });
1278
+ // → { tithiName, tithi (1..30), pakshaTithi (1..15), paksha,
1279
+ // masaName, masaIndex, isAdhika, vikramSamvat, shakaSamvat,
1280
+ // varaName, varaIndex }
1281
+
1282
+ // Hindu → Gregorian: which Gregorian dates correspond to a (samvat, masa, paksha, tithi)?
1283
+ const dates = convertHinduToGregorian(
1284
+ { vikramSamvat: 2083, masaIndex: 0, paksha: 'shukla', pakshaTithi: 9 },
1285
+ DELHI, { timezone: 330 },
1286
+ );
1287
+ // dates[0] → Rama Navami in VS 2083
1288
+
1289
+ getKaliYugaYear(new Date('2026-04-01')); // 5127
1290
+ getHinduNewYear(2026, 'tamil-nadu', DELHI, { timezone: 330 }); // Puthandu
1291
+
1292
+ // Yearly listings
1293
+ getEkadashiDatesForYear(2026, DELHI, { timezone: 330 }); // ~24 Date[]
1294
+ getSankrantisForYear(2026, DELHI, { timezone: 330 }); // 12 SankrantiEvent[]
1295
+ getFestivalsInRange(start, end, DELHI, { timezone: 330 }); // FestivalDay[]
1296
+ getUpcomingEclipses(new Date(), DELHI, 5); // 5 EclipseInfo[]
1297
+ ```
1298
+
1299
+ `getHinduNewYear` is region-aware: Tamil Nadu / Kerala / Punjab / Bengal / Assam use
1300
+ the **solar** (Mesha Sankranti) anchor; everywhere else uses **Chaitra Shukla Pratipada**
1301
+ (Ugadi / Gudi Padwa / Cheti Chand). When the Pratipada is a kshaya tithi (e.g. Ugadi
1302
+ 2026), the function falls back to the Amanta-Chaitra-masa boundary.
540
1303
 
541
- ## 16. Localization
1304
+ ## 20. Localization
542
1305
 
543
1306
  All returned display names respect the `language` option. **English** and **Hindi
544
1307
  (Devanagari)** are supported.
@@ -555,7 +1318,7 @@ console.log(hi.choghadiya.day[0].name); // "अमृत"
555
1318
  console.log(hi.vara.englishName); // "Tuesday"
556
1319
  ```
557
1320
 
558
- ## 17. Configuration
1321
+ ## 21. Configuration
559
1322
 
560
1323
  ```typescript
561
1324
  const r = getDailyPanchang(date, loc, {
@@ -900,9 +1663,29 @@ getUpcomingSolarEclipse, getUpcomingLunarEclipse, getEclipseDuringDay
900
1663
  // Jyotish
901
1664
  computePlanetaryPositions, GRAHA_ABBR
902
1665
  computeVimshottariDasha, computeVimshottariDashaFromBirth, computeVimshottariPratyantar
1666
+ computeAshtottariDasha, computeYoginiDasha, computeCharaDasha, computeNarayanDasha
903
1667
  computeChandraBalam, computeTarabala
904
- computeLagna, computeBhava, computeRashiChart, computeNavamsa
905
- computeAshtakoot, computeMangalDosha, computeSadeSati, computeDignity
1668
+ computeLagna, computeBhava, computeRashiChart, computeNavamsa, computeDivisionalChart
1669
+ computeHoraLagna, computeGhatiLagna, computeBhavaLagna, computeSripatiLagna
1670
+ computeAspects, computeShadbala, computeBhavaBala, computeAshtakavarga
1671
+ computeYogas, computeJaiminiKarakas
1672
+ computeVarshaphala, computeTithiPravesha, computeArudhas, computeUpagrahas, computeArgala
1673
+ computeAshtakoot, computePathuPorutham
1674
+ computeMangalDosha, computeKaalSarp, computePitruDosha
1675
+ computeSadeSati, computeDignity
1676
+ computeKpSubLord, computeKpCuspalSubLords, computeKpSignificators
1677
+ computePrashnaChart
1678
+
1679
+ // Muhurta engine
1680
+ scoreMuhurta, findAuspiciousDates, STOCK_MUHURTA_RULES
1681
+ vivahRule, grihaPraveshRule, namakaranaRule, vidyarambhRule, vahanKharidiRule
1682
+ annaprashanRule, mundanRule, upanayanamRule, karnavedhaRule
1683
+ aksharabhyasamRule, seemanthamRule, shopOpeningRule, travelStartRule
1684
+
1685
+ // Calendar conversion + yearly listings
1686
+ convertGregorianToHindu, convertHinduToGregorian
1687
+ getKaliYugaYear, getHinduNewYear, computeSamvat
1688
+ getEkadashiDatesForYear, getSankrantisForYear, getFestivalsInRange, getUpcomingEclipses
906
1689
 
907
1690
  // Errors
908
1691
  PanchangError
@@ -940,7 +1723,7 @@ InteractionManager.runAfterInteractions(() => {
940
1723
 
941
1724
  ## Accuracy
942
1725
 
943
- 6,912 tests passing across 74 files, including fixtures cross-verified against reference
1726
+ 7,156 tests passing across 81 files, including fixtures cross-verified against reference
944
1727
  panchang calculations spanning 2025–2026 across 10 Indian cities, plus New York, London,
945
1728
  Sydney, Dubai, and Singapore (diaspora fixtures cover DST transitions on
946
1729
  `America/New_York`).