kundali-chart-mcp 0.2.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.
- package/README.md +67 -0
- package/azure-function/function_app.py +93 -0
- package/azure-function/host.json +15 -0
- package/azure-function/kundali_bridge.py +952 -0
- package/azure-function/python/kundali_lib/__init__.py +1 -0
- package/azure-function/python/kundali_lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/__pycache__/ephemeris.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/__pycache__/geocoder.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/__pycache__/vedicastro_bridge.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/ephemeris.py +30 -0
- package/azure-function/python/kundali_lib/geocoder.py +82 -0
- package/azure-function/python/kundali_lib/vedic/__init__.py +1 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/arishta.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/ashtakavarga.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/avasthas.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/ayanamsa.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/bhava_chalit.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/char_dasha.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/chart.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/chart_types.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/compatibility.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/constants.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/dasha_extended.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/dasha_systems.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/doshas.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/gandanta.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/gochara.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/hora.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/houses.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/jaimini.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/kalachakra.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/kartari.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/kurmachakra.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/lunar_return.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/muhurta.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/nabhasha.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/nakshatra_details.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/panchanga.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/planets.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/shadbala.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/special_conditions.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/sudarshana.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/tajaka.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/upagrahas.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/varshaphal.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/yogas.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/__pycache__/zodiac.cpython-313.pyc +0 -0
- package/azure-function/python/kundali_lib/vedic/arishta.py +465 -0
- package/azure-function/python/kundali_lib/vedic/ashtakavarga.py +213 -0
- package/azure-function/python/kundali_lib/vedic/avasthas.py +292 -0
- package/azure-function/python/kundali_lib/vedic/ayanamsa.py +106 -0
- package/azure-function/python/kundali_lib/vedic/bhava_chalit.py +137 -0
- package/azure-function/python/kundali_lib/vedic/char_dasha.py +308 -0
- package/azure-function/python/kundali_lib/vedic/chart.py +126 -0
- package/azure-function/python/kundali_lib/vedic/chart_types.py +338 -0
- package/azure-function/python/kundali_lib/vedic/compatibility.py +705 -0
- package/azure-function/python/kundali_lib/vedic/constants.py +108 -0
- package/azure-function/python/kundali_lib/vedic/dasha_extended.py +262 -0
- package/azure-function/python/kundali_lib/vedic/dasha_systems.py +439 -0
- package/azure-function/python/kundali_lib/vedic/doshas.py +453 -0
- package/azure-function/python/kundali_lib/vedic/gandanta.py +213 -0
- package/azure-function/python/kundali_lib/vedic/gochara.py +277 -0
- package/azure-function/python/kundali_lib/vedic/hora.py +263 -0
- package/azure-function/python/kundali_lib/vedic/houses.py +30 -0
- package/azure-function/python/kundali_lib/vedic/jaimini.py +361 -0
- package/azure-function/python/kundali_lib/vedic/kalachakra.py +226 -0
- package/azure-function/python/kundali_lib/vedic/kartari.py +243 -0
- package/azure-function/python/kundali_lib/vedic/kurmachakra.py +383 -0
- package/azure-function/python/kundali_lib/vedic/lunar_return.py +402 -0
- package/azure-function/python/kundali_lib/vedic/muhurta.py +414 -0
- package/azure-function/python/kundali_lib/vedic/nabhasha.py +349 -0
- package/azure-function/python/kundali_lib/vedic/nakshatra_details.py +945 -0
- package/azure-function/python/kundali_lib/vedic/panchanga.py +297 -0
- package/azure-function/python/kundali_lib/vedic/planets.py +55 -0
- package/azure-function/python/kundali_lib/vedic/shadbala.py +500 -0
- package/azure-function/python/kundali_lib/vedic/special_conditions.py +319 -0
- package/azure-function/python/kundali_lib/vedic/sudarshana.py +232 -0
- package/azure-function/python/kundali_lib/vedic/tajaka.py +482 -0
- package/azure-function/python/kundali_lib/vedic/upagrahas.py +229 -0
- package/azure-function/python/kundali_lib/vedic/varshaphal.py +185 -0
- package/azure-function/python/kundali_lib/vedic/yogas.py +935 -0
- package/azure-function/python/kundali_lib/vedic/zodiac.py +42 -0
- package/azure-function/python/kundali_lib/vedicastro_bridge.py +198 -0
- package/azure-function/requirements.txt +9 -0
- package/index.js +747 -0
- package/kundali-chart-mcp.js +159 -0
- package/kundali_bridge.py +952 -0
- package/package.json +41 -0
- package/python/kundali_lib/__init__.py +1 -0
- package/python/kundali_lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/python/kundali_lib/__pycache__/ephemeris.cpython-313.pyc +0 -0
- package/python/kundali_lib/__pycache__/geocoder.cpython-313.pyc +0 -0
- package/python/kundali_lib/__pycache__/vedicastro_bridge.cpython-313.pyc +0 -0
- package/python/kundali_lib/ephemeris.py +30 -0
- package/python/kundali_lib/geocoder.py +82 -0
- package/python/kundali_lib/vedic/__init__.py +1 -0
- package/python/kundali_lib/vedic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/arishta.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/ashtakavarga.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/avasthas.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/ayanamsa.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/bhava_chalit.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/char_dasha.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/chart.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/chart_types.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/compatibility.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/constants.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/dasha_extended.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/dasha_systems.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/doshas.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/gandanta.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/gochara.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/hora.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/houses.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/jaimini.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/kalachakra.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/kartari.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/kurmachakra.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/lunar_return.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/muhurta.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/nabhasha.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/nakshatra_details.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/panchanga.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/planets.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/shadbala.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/special_conditions.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/sudarshana.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/tajaka.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/upagrahas.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/varshaphal.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/yogas.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/__pycache__/zodiac.cpython-313.pyc +0 -0
- package/python/kundali_lib/vedic/arishta.py +465 -0
- package/python/kundali_lib/vedic/ashtakavarga.py +213 -0
- package/python/kundali_lib/vedic/avasthas.py +292 -0
- package/python/kundali_lib/vedic/ayanamsa.py +106 -0
- package/python/kundali_lib/vedic/bhava_chalit.py +137 -0
- package/python/kundali_lib/vedic/char_dasha.py +308 -0
- package/python/kundali_lib/vedic/chart.py +126 -0
- package/python/kundali_lib/vedic/chart_types.py +338 -0
- package/python/kundali_lib/vedic/compatibility.py +705 -0
- package/python/kundali_lib/vedic/constants.py +108 -0
- package/python/kundali_lib/vedic/dasha_extended.py +262 -0
- package/python/kundali_lib/vedic/dasha_systems.py +439 -0
- package/python/kundali_lib/vedic/doshas.py +453 -0
- package/python/kundali_lib/vedic/gandanta.py +213 -0
- package/python/kundali_lib/vedic/gochara.py +277 -0
- package/python/kundali_lib/vedic/hora.py +263 -0
- package/python/kundali_lib/vedic/houses.py +30 -0
- package/python/kundali_lib/vedic/jaimini.py +361 -0
- package/python/kundali_lib/vedic/kalachakra.py +226 -0
- package/python/kundali_lib/vedic/kartari.py +243 -0
- package/python/kundali_lib/vedic/kurmachakra.py +383 -0
- package/python/kundali_lib/vedic/lunar_return.py +402 -0
- package/python/kundali_lib/vedic/muhurta.py +414 -0
- package/python/kundali_lib/vedic/nabhasha.py +349 -0
- package/python/kundali_lib/vedic/nakshatra_details.py +945 -0
- package/python/kundali_lib/vedic/panchanga.py +297 -0
- package/python/kundali_lib/vedic/planets.py +55 -0
- package/python/kundali_lib/vedic/shadbala.py +500 -0
- package/python/kundali_lib/vedic/special_conditions.py +319 -0
- package/python/kundali_lib/vedic/sudarshana.py +232 -0
- package/python/kundali_lib/vedic/tajaka.py +482 -0
- package/python/kundali_lib/vedic/upagrahas.py +229 -0
- package/python/kundali_lib/vedic/varshaphal.py +185 -0
- package/python/kundali_lib/vedic/yogas.py +935 -0
- package/python/kundali_lib/vedic/zodiac.py +42 -0
- package/python/kundali_lib/vedicastro_bridge.py +198 -0
- package/remote-server.js +590 -0
- package/requirements.txt +8 -0
- package/setup.sh +218 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"""Panchanga: the 5 limbs of Vedic time (Tithi, Vara, Nakshatra, Yoga, Karana)."""
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
|
|
5
|
+
# ---------------------------------------------------------------------------
|
|
6
|
+
# Constant tables
|
|
7
|
+
# ---------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
TITHI_NAMES = [
|
|
10
|
+
"Pratipada",
|
|
11
|
+
"Dwitiya",
|
|
12
|
+
"Tritiya",
|
|
13
|
+
"Chaturthi",
|
|
14
|
+
"Panchami",
|
|
15
|
+
"Shashthi",
|
|
16
|
+
"Saptami",
|
|
17
|
+
"Ashtami",
|
|
18
|
+
"Navami",
|
|
19
|
+
"Dashami",
|
|
20
|
+
"Ekadashi",
|
|
21
|
+
"Dwadashi",
|
|
22
|
+
"Trayodashi",
|
|
23
|
+
"Chaturdashi",
|
|
24
|
+
"Purnima",
|
|
25
|
+
# Krishna Paksha (indices 15-29 → tithis 16-30)
|
|
26
|
+
"Pratipada",
|
|
27
|
+
"Dwitiya",
|
|
28
|
+
"Tritiya",
|
|
29
|
+
"Chaturthi",
|
|
30
|
+
"Panchami",
|
|
31
|
+
"Shashthi",
|
|
32
|
+
"Saptami",
|
|
33
|
+
"Ashtami",
|
|
34
|
+
"Navami",
|
|
35
|
+
"Dashami",
|
|
36
|
+
"Ekadashi",
|
|
37
|
+
"Dwadashi",
|
|
38
|
+
"Trayodashi",
|
|
39
|
+
"Chaturdashi",
|
|
40
|
+
"Amavasya",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
VARA_NAMES = [
|
|
44
|
+
"Sunday",
|
|
45
|
+
"Monday",
|
|
46
|
+
"Tuesday",
|
|
47
|
+
"Wednesday",
|
|
48
|
+
"Thursday",
|
|
49
|
+
"Friday",
|
|
50
|
+
"Saturday",
|
|
51
|
+
]
|
|
52
|
+
VARA_LORDS = ["Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn"]
|
|
53
|
+
|
|
54
|
+
NAKSHATRA_NAMES = [
|
|
55
|
+
"Ashwini",
|
|
56
|
+
"Bharani",
|
|
57
|
+
"Krittika",
|
|
58
|
+
"Rohini",
|
|
59
|
+
"Mrigashira",
|
|
60
|
+
"Ardra",
|
|
61
|
+
"Punarvasu",
|
|
62
|
+
"Pushya",
|
|
63
|
+
"Ashlesha",
|
|
64
|
+
"Magha",
|
|
65
|
+
"Purva Phalguni",
|
|
66
|
+
"Uttara Phalguni",
|
|
67
|
+
"Hasta",
|
|
68
|
+
"Chitra",
|
|
69
|
+
"Swati",
|
|
70
|
+
"Vishakha",
|
|
71
|
+
"Anuradha",
|
|
72
|
+
"Jyeshtha",
|
|
73
|
+
"Mula",
|
|
74
|
+
"Purva Ashadha",
|
|
75
|
+
"Uttara Ashadha",
|
|
76
|
+
"Shravana",
|
|
77
|
+
"Dhanishta",
|
|
78
|
+
"Shatabhisha",
|
|
79
|
+
"Purva Bhadrapada",
|
|
80
|
+
"Uttara Bhadrapada",
|
|
81
|
+
"Revati",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
# Ketu, Venus, Sun, Moon, Mars, Rahu, Jupiter, Saturn, Mercury (×3)
|
|
85
|
+
NAKSHATRA_LORDS = [
|
|
86
|
+
"Ketu",
|
|
87
|
+
"Venus",
|
|
88
|
+
"Sun",
|
|
89
|
+
"Moon",
|
|
90
|
+
"Mars",
|
|
91
|
+
"Rahu",
|
|
92
|
+
"Jupiter",
|
|
93
|
+
"Saturn",
|
|
94
|
+
"Mercury",
|
|
95
|
+
] * 3
|
|
96
|
+
|
|
97
|
+
YOGA_NAMES = [
|
|
98
|
+
"Vishkumbha",
|
|
99
|
+
"Priti",
|
|
100
|
+
"Ayushman",
|
|
101
|
+
"Saubhagya",
|
|
102
|
+
"Shobhana",
|
|
103
|
+
"Atiganda",
|
|
104
|
+
"Sukarma",
|
|
105
|
+
"Dhriti",
|
|
106
|
+
"Shoola",
|
|
107
|
+
"Ganda",
|
|
108
|
+
"Vriddhi",
|
|
109
|
+
"Dhruva",
|
|
110
|
+
"Vyaghata",
|
|
111
|
+
"Harshana",
|
|
112
|
+
"Vajra",
|
|
113
|
+
"Siddhi",
|
|
114
|
+
"Vyatipata",
|
|
115
|
+
"Variyana",
|
|
116
|
+
"Parigha",
|
|
117
|
+
"Shiva",
|
|
118
|
+
"Siddha",
|
|
119
|
+
"Sadhya",
|
|
120
|
+
"Shubha",
|
|
121
|
+
"Shukla",
|
|
122
|
+
"Brahma",
|
|
123
|
+
"Indra",
|
|
124
|
+
"Vaidhriti",
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
# 1-indexed set of inauspicious yoga numbers
|
|
128
|
+
INAUSPICIOUS_YOGAS = {1, 6, 9, 10, 13, 15, 17, 19, 27}
|
|
129
|
+
|
|
130
|
+
# Fixed karanas at positions 1, 58, 59, 60
|
|
131
|
+
FIXED_KARANAS = {1: "Kimstughna", 58: "Shakuni", 59: "Chatushpada", 60: "Naga"}
|
|
132
|
+
MOVABLE_KARANAS = ["Bava", "Balava", "Kaulava", "Taitila", "Garija", "Vanija", "Vishti"]
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# ---------------------------------------------------------------------------
|
|
136
|
+
# Helper
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _normalize(lon: float) -> float:
|
|
141
|
+
"""Bring longitude into [0, 360)."""
|
|
142
|
+
return lon % 360
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# ---------------------------------------------------------------------------
|
|
146
|
+
# Main function
|
|
147
|
+
# ---------------------------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_panchanga(sun_lon: float, moon_lon: float, julian_day: float) -> dict:
|
|
151
|
+
"""Return the five limbs of Vedic time (Panchanga).
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
sun_lon : float
|
|
156
|
+
Sidereal longitude of the Sun in degrees [0, 360).
|
|
157
|
+
moon_lon : float
|
|
158
|
+
Sidereal longitude of the Moon in degrees [0, 360).
|
|
159
|
+
julian_day : float
|
|
160
|
+
Julian Day Number for the moment of interest.
|
|
161
|
+
|
|
162
|
+
Returns
|
|
163
|
+
-------
|
|
164
|
+
dict
|
|
165
|
+
Keys: tithi, vara, nakshatra, yoga, karana — each a dict with
|
|
166
|
+
relevant sub-fields.
|
|
167
|
+
"""
|
|
168
|
+
sun_lon = _normalize(sun_lon)
|
|
169
|
+
moon_lon = _normalize(moon_lon)
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
"tithi": _calc_tithi(sun_lon, moon_lon),
|
|
173
|
+
"vara": _calc_vara(julian_day),
|
|
174
|
+
"nakshatra": _calc_nakshatra(moon_lon),
|
|
175
|
+
"yoga": _calc_yoga(sun_lon, moon_lon),
|
|
176
|
+
"karana": _calc_karana(sun_lon, moon_lon),
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# ---------------------------------------------------------------------------
|
|
181
|
+
# Tithi
|
|
182
|
+
# ---------------------------------------------------------------------------
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _calc_tithi(sun_lon: float, moon_lon: float) -> dict:
|
|
186
|
+
diff = _normalize(moon_lon - sun_lon)
|
|
187
|
+
tithi_num = math.ceil(diff / 12)
|
|
188
|
+
if tithi_num == 0:
|
|
189
|
+
tithi_num = 30 # diff == 0 edge case
|
|
190
|
+
|
|
191
|
+
percentage_elapsed = ((diff % 12) / 12) * 100
|
|
192
|
+
|
|
193
|
+
if tithi_num <= 15:
|
|
194
|
+
paksha = "Shukla"
|
|
195
|
+
name = TITHI_NAMES[tithi_num - 1]
|
|
196
|
+
else:
|
|
197
|
+
paksha = "Krishna"
|
|
198
|
+
name = TITHI_NAMES[tithi_num - 1] # table has 30 entries
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
"number": tithi_num,
|
|
202
|
+
"name": name,
|
|
203
|
+
"paksha": paksha,
|
|
204
|
+
"percentage_elapsed": round(percentage_elapsed, 2),
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
# ---------------------------------------------------------------------------
|
|
209
|
+
# Vara
|
|
210
|
+
# ---------------------------------------------------------------------------
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _calc_vara(julian_day: float) -> dict:
|
|
214
|
+
# JD 0.0 is Monday noon; adding 1.5 shifts so index 0 = Sunday
|
|
215
|
+
vara_index = int(julian_day + 1.5) % 7 # 0=Sunday … 6=Saturday
|
|
216
|
+
number = vara_index + 1 # 1=Sunday … 7=Saturday
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
"number": number,
|
|
220
|
+
"name": VARA_NAMES[vara_index],
|
|
221
|
+
"lord": VARA_LORDS[vara_index],
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# ---------------------------------------------------------------------------
|
|
226
|
+
# Nakshatra
|
|
227
|
+
# ---------------------------------------------------------------------------
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _calc_nakshatra(moon_lon: float) -> dict:
|
|
231
|
+
span = 360 / 27 # ≈ 13.333°
|
|
232
|
+
pada_span = 360 / 108 # ≈ 3.333°
|
|
233
|
+
|
|
234
|
+
nakshatra_index = int(moon_lon / span) # 0-26
|
|
235
|
+
nakshatra_num = nakshatra_index + 1 # 1-27
|
|
236
|
+
|
|
237
|
+
lon_within = moon_lon % span
|
|
238
|
+
pada = int(lon_within / pada_span) + 1 # 1-4
|
|
239
|
+
pada = min(pada, 4) # safety clamp
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
"number": nakshatra_num,
|
|
243
|
+
"name": NAKSHATRA_NAMES[nakshatra_index],
|
|
244
|
+
"lord": NAKSHATRA_LORDS[nakshatra_index],
|
|
245
|
+
"pada": pada,
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
# ---------------------------------------------------------------------------
|
|
250
|
+
# Yoga
|
|
251
|
+
# ---------------------------------------------------------------------------
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _calc_yoga(sun_lon: float, moon_lon: float) -> dict:
|
|
255
|
+
combined = _normalize(sun_lon + moon_lon)
|
|
256
|
+
span = 360 / 27
|
|
257
|
+
yoga_index = int(combined / span) # 0-26
|
|
258
|
+
yoga_num = yoga_index + 1 # 1-27
|
|
259
|
+
|
|
260
|
+
if yoga_num in INAUSPICIOUS_YOGAS:
|
|
261
|
+
nature = "Inauspicious"
|
|
262
|
+
elif yoga_num in {3, 4, 5, 7, 8, 11, 12, 14, 16, 20, 21, 22, 23, 24, 25, 26}:
|
|
263
|
+
nature = "Auspicious"
|
|
264
|
+
else:
|
|
265
|
+
nature = "Neutral"
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
"number": yoga_num,
|
|
269
|
+
"name": YOGA_NAMES[yoga_index],
|
|
270
|
+
"nature": nature,
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
# ---------------------------------------------------------------------------
|
|
275
|
+
# Karana
|
|
276
|
+
# ---------------------------------------------------------------------------
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def _calc_karana(sun_lon: float, moon_lon: float) -> dict:
|
|
280
|
+
diff = _normalize(moon_lon - sun_lon)
|
|
281
|
+
karana_num = int(diff / 6) + 1 # 1-60
|
|
282
|
+
karana_num = max(1, min(karana_num, 60)) # safety clamp
|
|
283
|
+
|
|
284
|
+
if karana_num in FIXED_KARANAS:
|
|
285
|
+
name = FIXED_KARANAS[karana_num]
|
|
286
|
+
karana_type = "Fixed"
|
|
287
|
+
else:
|
|
288
|
+
# Movable karanas: positions 2-57 (index 0 in the 7-cycle = Bava)
|
|
289
|
+
movable_index = (karana_num - 2) % 7
|
|
290
|
+
name = MOVABLE_KARANAS[movable_index]
|
|
291
|
+
karana_type = "Movable"
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
"number": karana_num,
|
|
295
|
+
"name": name,
|
|
296
|
+
"type": karana_type,
|
|
297
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Planetary position calculation (sidereal)."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import swisseph as swe
|
|
6
|
+
|
|
7
|
+
from kundali_lib.vedic.constants import CALC_FLAGS, PLANET_IDS
|
|
8
|
+
from kundali_lib.vedic.zodiac import (
|
|
9
|
+
get_nakshatra,
|
|
10
|
+
get_nakshatra_lord,
|
|
11
|
+
get_pada,
|
|
12
|
+
get_rashi,
|
|
13
|
+
get_rashi_lord,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def calc_planet_position(planet_name: str, julian_day: float) -> dict:
|
|
18
|
+
"""Single planet sidereal position. Ketu derived from Rahu."""
|
|
19
|
+
if planet_name == "Ketu":
|
|
20
|
+
rahu = calc_planet_position("Rahu", julian_day)
|
|
21
|
+
lon = (rahu["longitude"] + 180) % 360
|
|
22
|
+
return _planet_row("Ketu", lon, 0, False, -rahu.get("speed_longitude", 0))
|
|
23
|
+
|
|
24
|
+
pid = PLANET_IDS.get(planet_name)
|
|
25
|
+
if pid is None:
|
|
26
|
+
raise ValueError(f"Unknown planet: {planet_name}")
|
|
27
|
+
|
|
28
|
+
xx, _ = swe.calc_ut(julian_day, pid, CALC_FLAGS)
|
|
29
|
+
lon, speed = xx[0], xx[3]
|
|
30
|
+
retro = speed < 0
|
|
31
|
+
|
|
32
|
+
return _planet_row(planet_name, lon, speed, retro)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _planet_row(
|
|
36
|
+
name: str,
|
|
37
|
+
longitude: float,
|
|
38
|
+
speed: float,
|
|
39
|
+
is_retro: bool,
|
|
40
|
+
speed_override: Optional[float] = None,
|
|
41
|
+
) -> dict:
|
|
42
|
+
sp = speed_override if speed_override is not None else speed
|
|
43
|
+
return {
|
|
44
|
+
"name": name,
|
|
45
|
+
"longitude": longitude,
|
|
46
|
+
"rashi": get_rashi(longitude),
|
|
47
|
+
"rashi_lord": get_rashi_lord(longitude),
|
|
48
|
+
"degree": longitude % 30,
|
|
49
|
+
"nakshatra": get_nakshatra(longitude),
|
|
50
|
+
"nakshatra_lord": get_nakshatra_lord(longitude),
|
|
51
|
+
"pada": get_pada(longitude),
|
|
52
|
+
"house": 0,
|
|
53
|
+
"is_retrograde": is_retro,
|
|
54
|
+
"speed_longitude": round(sp, 4),
|
|
55
|
+
}
|