kundali-chart-mcp 0.2.7 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/azure-function/__pycache__/kundali_bridge.cpython-313.pyc +0 -0
  2. package/azure-function/function_app.py +17 -0
  3. package/azure-function/kundali_bridge.py +152 -0
  4. package/azure-function/python/kundali_lib/__pycache__/__init__.cpython-313.pyc +0 -0
  5. package/azure-function/python/kundali_lib/__pycache__/ephemeris.cpython-313.pyc +0 -0
  6. package/azure-function/python/kundali_lib/__pycache__/geocoder.cpython-313.pyc +0 -0
  7. package/azure-function/python/kundali_lib/__pycache__/vedicastro_bridge.cpython-313.pyc +0 -0
  8. package/azure-function/python/kundali_lib/vedic/__pycache__/__init__.cpython-313.pyc +0 -0
  9. package/azure-function/python/kundali_lib/vedic/__pycache__/arishta.cpython-313.pyc +0 -0
  10. package/azure-function/python/kundali_lib/vedic/__pycache__/arudha.cpython-313.pyc +0 -0
  11. package/azure-function/python/kundali_lib/vedic/__pycache__/ashtakavarga.cpython-313.pyc +0 -0
  12. package/azure-function/python/kundali_lib/vedic/__pycache__/avasthas.cpython-313.pyc +0 -0
  13. package/azure-function/python/kundali_lib/vedic/__pycache__/ayanamsa.cpython-313.pyc +0 -0
  14. package/azure-function/python/kundali_lib/vedic/__pycache__/bhava_chalit.cpython-313.pyc +0 -0
  15. package/azure-function/python/kundali_lib/vedic/__pycache__/char_dasha.cpython-313.pyc +0 -0
  16. package/azure-function/python/kundali_lib/vedic/__pycache__/chart.cpython-313.pyc +0 -0
  17. package/azure-function/python/kundali_lib/vedic/__pycache__/chart_types.cpython-313.pyc +0 -0
  18. package/azure-function/python/kundali_lib/vedic/__pycache__/compatibility.cpython-313.pyc +0 -0
  19. package/azure-function/python/kundali_lib/vedic/__pycache__/constants.cpython-313.pyc +0 -0
  20. package/azure-function/python/kundali_lib/vedic/__pycache__/dasha_extended.cpython-313.pyc +0 -0
  21. package/azure-function/python/kundali_lib/vedic/__pycache__/dasha_systems.cpython-313.pyc +0 -0
  22. package/azure-function/python/kundali_lib/vedic/__pycache__/doshas.cpython-313.pyc +0 -0
  23. package/azure-function/python/kundali_lib/vedic/__pycache__/gandanta.cpython-313.pyc +0 -0
  24. package/azure-function/python/kundali_lib/vedic/__pycache__/gochara.cpython-313.pyc +0 -0
  25. package/azure-function/python/kundali_lib/vedic/__pycache__/hora.cpython-313.pyc +0 -0
  26. package/azure-function/python/kundali_lib/vedic/__pycache__/houses.cpython-313.pyc +0 -0
  27. package/azure-function/python/kundali_lib/vedic/__pycache__/inauspicious_times.cpython-313.pyc +0 -0
  28. package/azure-function/python/kundali_lib/vedic/__pycache__/jaimini.cpython-313.pyc +0 -0
  29. package/azure-function/python/kundali_lib/vedic/__pycache__/kalachakra.cpython-313.pyc +0 -0
  30. package/azure-function/python/kundali_lib/vedic/__pycache__/kartari.cpython-313.pyc +0 -0
  31. package/azure-function/python/kundali_lib/vedic/__pycache__/kurmachakra.cpython-313.pyc +0 -0
  32. package/azure-function/python/kundali_lib/vedic/__pycache__/lunar_return.cpython-313.pyc +0 -0
  33. package/azure-function/python/kundali_lib/vedic/__pycache__/medical_astrology.cpython-313.pyc +0 -0
  34. package/azure-function/python/kundali_lib/vedic/__pycache__/muhurta.cpython-313.pyc +0 -0
  35. package/azure-function/python/kundali_lib/vedic/__pycache__/nabhasha.cpython-313.pyc +0 -0
  36. package/azure-function/python/kundali_lib/vedic/__pycache__/nakshatra_details.cpython-313.pyc +0 -0
  37. package/azure-function/python/kundali_lib/vedic/__pycache__/panchanga.cpython-313.pyc +0 -0
  38. package/azure-function/python/kundali_lib/vedic/__pycache__/planets.cpython-313.pyc +0 -0
  39. package/azure-function/python/kundali_lib/vedic/__pycache__/remedial.cpython-313.pyc +0 -0
  40. package/azure-function/python/kundali_lib/vedic/__pycache__/shadbala.cpython-313.pyc +0 -0
  41. package/azure-function/python/kundali_lib/vedic/__pycache__/special_conditions.cpython-313.pyc +0 -0
  42. package/azure-function/python/kundali_lib/vedic/__pycache__/sudarshana.cpython-313.pyc +0 -0
  43. package/azure-function/python/kundali_lib/vedic/__pycache__/tajaka.cpython-313.pyc +0 -0
  44. package/azure-function/python/kundali_lib/vedic/__pycache__/upagrahas.cpython-313.pyc +0 -0
  45. package/azure-function/python/kundali_lib/vedic/__pycache__/varshaphal.cpython-313.pyc +0 -0
  46. package/azure-function/python/kundali_lib/vedic/__pycache__/yogas.cpython-313.pyc +0 -0
  47. package/azure-function/python/kundali_lib/vedic/__pycache__/zodiac.cpython-313.pyc +0 -0
  48. package/azure-function/python/kundali_lib/vedic/arudha.py +189 -0
  49. package/azure-function/python/kundali_lib/vedic/inauspicious_times.py +303 -0
  50. package/azure-function/python/kundali_lib/vedic/medical_astrology.py +424 -0
  51. package/azure-function/python/kundali_lib/vedic/remedial.py +849 -0
  52. package/kundali-chart-mcp.js +67 -505
  53. package/package.json +2 -2
  54. package/python/kundali_lib/__pycache__/__init__.cpython-313.pyc +0 -0
  55. package/python/kundali_lib/__pycache__/ephemeris.cpython-313.pyc +0 -0
  56. package/python/kundali_lib/__pycache__/geocoder.cpython-313.pyc +0 -0
  57. package/python/kundali_lib/__pycache__/vedicastro_bridge.cpython-313.pyc +0 -0
  58. package/python/kundali_lib/vedic/__pycache__/__init__.cpython-313.pyc +0 -0
  59. package/python/kundali_lib/vedic/__pycache__/arishta.cpython-313.pyc +0 -0
  60. package/python/kundali_lib/vedic/__pycache__/arudha.cpython-313.pyc +0 -0
  61. package/python/kundali_lib/vedic/__pycache__/ashtakavarga.cpython-313.pyc +0 -0
  62. package/python/kundali_lib/vedic/__pycache__/avasthas.cpython-313.pyc +0 -0
  63. package/python/kundali_lib/vedic/__pycache__/ayanamsa.cpython-313.pyc +0 -0
  64. package/python/kundali_lib/vedic/__pycache__/bhava_chalit.cpython-313.pyc +0 -0
  65. package/python/kundali_lib/vedic/__pycache__/char_dasha.cpython-313.pyc +0 -0
  66. package/python/kundali_lib/vedic/__pycache__/chart.cpython-313.pyc +0 -0
  67. package/python/kundali_lib/vedic/__pycache__/chart_types.cpython-313.pyc +0 -0
  68. package/python/kundali_lib/vedic/__pycache__/compatibility.cpython-313.pyc +0 -0
  69. package/python/kundali_lib/vedic/__pycache__/constants.cpython-313.pyc +0 -0
  70. package/python/kundali_lib/vedic/__pycache__/dasha_extended.cpython-313.pyc +0 -0
  71. package/python/kundali_lib/vedic/__pycache__/dasha_systems.cpython-313.pyc +0 -0
  72. package/python/kundali_lib/vedic/__pycache__/doshas.cpython-313.pyc +0 -0
  73. package/python/kundali_lib/vedic/__pycache__/gandanta.cpython-313.pyc +0 -0
  74. package/python/kundali_lib/vedic/__pycache__/gochara.cpython-313.pyc +0 -0
  75. package/python/kundali_lib/vedic/__pycache__/hora.cpython-313.pyc +0 -0
  76. package/python/kundali_lib/vedic/__pycache__/houses.cpython-313.pyc +0 -0
  77. package/python/kundali_lib/vedic/__pycache__/inauspicious_times.cpython-313.pyc +0 -0
  78. package/python/kundali_lib/vedic/__pycache__/jaimini.cpython-313.pyc +0 -0
  79. package/python/kundali_lib/vedic/__pycache__/kalachakra.cpython-313.pyc +0 -0
  80. package/python/kundali_lib/vedic/__pycache__/kartari.cpython-313.pyc +0 -0
  81. package/python/kundali_lib/vedic/__pycache__/kurmachakra.cpython-313.pyc +0 -0
  82. package/python/kundali_lib/vedic/__pycache__/lunar_return.cpython-313.pyc +0 -0
  83. package/python/kundali_lib/vedic/__pycache__/medical_astrology.cpython-313.pyc +0 -0
  84. package/python/kundali_lib/vedic/__pycache__/muhurta.cpython-313.pyc +0 -0
  85. package/python/kundali_lib/vedic/__pycache__/nabhasha.cpython-313.pyc +0 -0
  86. package/python/kundali_lib/vedic/__pycache__/nakshatra_details.cpython-313.pyc +0 -0
  87. package/python/kundali_lib/vedic/__pycache__/panchanga.cpython-313.pyc +0 -0
  88. package/python/kundali_lib/vedic/__pycache__/planets.cpython-313.pyc +0 -0
  89. package/python/kundali_lib/vedic/__pycache__/remedial.cpython-313.pyc +0 -0
  90. package/python/kundali_lib/vedic/__pycache__/shadbala.cpython-313.pyc +0 -0
  91. package/python/kundali_lib/vedic/__pycache__/special_conditions.cpython-313.pyc +0 -0
  92. package/python/kundali_lib/vedic/__pycache__/sudarshana.cpython-313.pyc +0 -0
  93. package/python/kundali_lib/vedic/__pycache__/tajaka.cpython-313.pyc +0 -0
  94. package/python/kundali_lib/vedic/__pycache__/upagrahas.cpython-313.pyc +0 -0
  95. package/python/kundali_lib/vedic/__pycache__/varshaphal.cpython-313.pyc +0 -0
  96. package/python/kundali_lib/vedic/__pycache__/yogas.cpython-313.pyc +0 -0
  97. package/python/kundali_lib/vedic/__pycache__/zodiac.cpython-313.pyc +0 -0
  98. package/python/kundali_lib/vedic/arudha.py +189 -0
  99. package/python/kundali_lib/vedic/inauspicious_times.py +303 -0
  100. package/python/kundali_lib/vedic/medical_astrology.py +424 -0
  101. package/python/kundali_lib/vedic/remedial.py +849 -0
@@ -0,0 +1,303 @@
1
+ """Inauspicious time periods (Kala) calculations.
2
+
3
+ Calculates:
4
+ - Rahu Kala (Rahu's inauspicious period)
5
+ - Yamaganda Kala (Yama's inauspicious period)
6
+ - Gulika Kala (Gulika's inauspicious period)
7
+ - Choghadiya (8 time divisions of the day)
8
+ - Abhijit Muhurta (auspicious midday window)
9
+ - Brahma Muhurta (pre-dawn auspicious time)
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from datetime import datetime, timedelta
15
+ from typing import Any
16
+
17
+ # Weekday lords for Rahu Kala calculation
18
+ WEEKDAY_LORDS = {
19
+ "Sunday": "Sun",
20
+ "Monday": "Moon",
21
+ "Tuesday": "Mars",
22
+ "Wednesday": "Mercury",
23
+ "Thursday": "Jupiter",
24
+ "Friday": "Venus",
25
+ "Saturday": "Saturn",
26
+ }
27
+
28
+ # Rahu Kala order (8 parts of the day, starting from Sunday)
29
+ # Each day has a different 8th part that is Rahu Kala
30
+ RAHU_KALA_ORDER = {
31
+ "Sunday": 8, # 4:30-6:00 PM (if sunrise 6AM, sunset 6PM)
32
+ "Monday": 2, # 7:30-9:00 AM
33
+ "Tuesday": 7, # 3:00-4:30 PM
34
+ "Wednesday": 5, # 12:00-1:30 PM
35
+ "Thursday": 6, # 1:30-3:00 PM
36
+ "Friday": 4, # 10:30-12:00 PM
37
+ "Saturday": 3, # 9:00-10:30 AM
38
+ }
39
+
40
+ # Yamaganda Kala order
41
+ YAMAGANDA_ORDER = {
42
+ "Sunday": 5, # 12:00-1:30 PM
43
+ "Monday": 4, # 10:30-12:00 PM
44
+ "Tuesday": 3, # 9:00-10:30 AM
45
+ "Wednesday": 2, # 7:30-9:00 AM
46
+ "Thursday": 1, # 6:00-7:30 AM
47
+ "Friday": 7, # 3:00-4:30 PM
48
+ "Saturday": 6, # 1:30-3:00 PM
49
+ }
50
+
51
+ # Gulika Kala order
52
+ GULIKA_ORDER = {
53
+ "Sunday": 7, # 3:00-4:30 PM
54
+ "Monday": 6, # 1:30-3:00 PM
55
+ "Tuesday": 5, # 12:00-1:30 PM
56
+ "Wednesday": 4, # 10:30-12:00 PM
57
+ "Thursday": 3, # 9:00-10:30 AM
58
+ "Friday": 2, # 7:30-9:00 AM
59
+ "Saturday": 1, # 6:00-7:30 AM
60
+ }
61
+
62
+ # Choghadiya names and their nature
63
+ CHOGHADIYA_NAMES = [
64
+ "Udveg", # Anxiety (inauspicious)
65
+ "Chal", # Moving (neutral)
66
+ "Labh", # Gain (auspicious)
67
+ "Amrit", # Nectar (most auspicious)
68
+ "Kaal", # Death (inauspicious)
69
+ "Shubh", # Auspicious (good)
70
+ "Rog", # Disease (inauspicious)
71
+ "Char", # Moving (neutral)
72
+ ]
73
+
74
+ CHOGHADIYA_NATURE = {
75
+ "Udveg": "Inauspicious — avoid new beginnings",
76
+ "Chal": "Neutral — okay for travel and routine",
77
+ "Labh": "Auspicious — good for business and gains",
78
+ "Amrit": "Most Auspicious — best for all activities",
79
+ "Kaal": "Inauspicious — avoid important work",
80
+ "Shubh": "Auspicious — good for ceremonies",
81
+ "Rog": "Inauspicious — avoid health-related activities",
82
+ "Char": "Neutral — okay for communication",
83
+ }
84
+
85
+
86
+ def calculate_inauspicious_times(
87
+ date: datetime,
88
+ sunrise: datetime | None = None,
89
+ sunset: datetime | None = None,
90
+ ) -> dict[str, Any]:
91
+ """Calculate all inauspicious time periods for a given date.
92
+
93
+ Args:
94
+ date: The date to calculate for
95
+ sunrise: Optional sunrise time (defaults to 6:00 AM)
96
+ sunset: Optional sunset time (defaults to 6:00 PM)
97
+
98
+ Returns:
99
+ Dictionary with Rahu Kala, Yamaganda, Gulika, and Choghadiya
100
+ """
101
+ if sunrise is None:
102
+ sunrise = date.replace(hour=6, minute=0, second=0)
103
+ if sunset is None:
104
+ sunset = date.replace(hour=18, minute=0, second=0)
105
+
106
+ weekday = date.strftime("%A")
107
+
108
+ # Calculate day duration in minutes
109
+ day_duration = int((sunset - sunrise).total_seconds() / 60)
110
+ part_duration = day_duration / 8
111
+
112
+ # Rahu Kala
113
+ rahu_part = RAHU_KALA_ORDER.get(weekday, 1)
114
+ rahu_start = sunrise + timedelta(minutes=part_duration * (rahu_part - 1))
115
+ rahu_end = rahu_start + timedelta(minutes=part_duration)
116
+
117
+ # Yamaganda Kala
118
+ yama_part = YAMAGANDA_ORDER.get(weekday, 1)
119
+ yama_start = sunrise + timedelta(minutes=part_duration * (yama_part - 1))
120
+ yama_end = yama_start + timedelta(minutes=part_duration)
121
+
122
+ # Gulika Kala
123
+ gulika_part = GULIKA_ORDER.get(weekday, 1)
124
+ gulika_start = sunrise + timedelta(minutes=part_duration * (gulika_part - 1))
125
+ gulika_end = gulika_start + timedelta(minutes=part_duration)
126
+
127
+ # Choghadiya (daytime)
128
+ choghadiya_day = []
129
+ for i in range(8):
130
+ start = sunrise + timedelta(minutes=part_duration * i)
131
+ end = start + timedelta(minutes=part_duration)
132
+ name_index = (CHOGHADIYA_NAMES.index(_get_choghadiya_start(weekday)) + i) % 8
133
+ choghadiya_day.append(
134
+ {
135
+ "period": f"{start.strftime('%H:%M')}-{end.strftime('%H:%M')}",
136
+ "name": CHOGHADIYA_NAMES[name_index],
137
+ "nature": CHOGHADIYA_NATURE[CHOGHADIYA_NAMES[name_index]],
138
+ }
139
+ )
140
+
141
+ # Abhijit Muhurta (midday, ~48 minutes centered on noon)
142
+ noon = sunrise + timedelta(minutes=day_duration / 2)
143
+ abhijit_start = noon - timedelta(minutes=24)
144
+ abhijit_end = noon + timedelta(minutes=24)
145
+
146
+ # Brahma Muhurta (pre-dawn, ~48 minutes before sunrise)
147
+ brahma_start = sunrise - timedelta(minutes=48)
148
+ brahma_end = sunrise - timedelta(minutes=0)
149
+
150
+ return {
151
+ "date": date.strftime("%Y-%m-%d"),
152
+ "weekday": weekday,
153
+ "sunrise": sunrise.strftime("%H:%M"),
154
+ "sunset": sunset.strftime("%H:%M"),
155
+ "rahu_kala": {
156
+ "start": rahu_start.strftime("%H:%M"),
157
+ "end": rahu_end.strftime("%H:%M"),
158
+ "description": "Rahu's inauspicious period — avoid starting new ventures, travel, or important work",
159
+ },
160
+ "yamaganda": {
161
+ "start": yama_start.strftime("%H:%M"),
162
+ "end": yama_end.strftime("%H:%M"),
163
+ "description": "Yama's inauspicious period — avoid travel and new activities",
164
+ },
165
+ "gulika_kala": {
166
+ "start": gulika_start.strftime("%H:%M"),
167
+ "end": gulika_end.strftime("%H:%M"),
168
+ "description": "Gulika's inauspicious period — avoid important decisions and ceremonies",
169
+ },
170
+ "choghadiya": choghadiya_day,
171
+ "abhijit_muhurta": {
172
+ "start": abhijit_start.strftime("%H:%M"),
173
+ "end": abhijit_end.strftime("%H:%M"),
174
+ "description": "Most auspicious midday window — ideal for starting important work",
175
+ },
176
+ "brahma_muhurta": {
177
+ "start": brahma_start.strftime("%H:%M"),
178
+ "end": brahma_end.strftime("%H:%M"),
179
+ "description": "Pre-dawn auspicious time — best for meditation, yoga, and spiritual practices",
180
+ },
181
+ }
182
+
183
+
184
+ def _get_choghadiya_start(weekday: str) -> str:
185
+ """Get the starting Choghadiya name for a given weekday."""
186
+ starts = {
187
+ "Sunday": "Udveg",
188
+ "Monday": "Amrit",
189
+ "Tuesday": "Kaal",
190
+ "Wednesday": "Labh",
191
+ "Thursday": "Shubh",
192
+ "Friday": "Rog",
193
+ "Saturday": "Chal",
194
+ }
195
+ return starts.get(weekday, "Udveg")
196
+
197
+
198
+ def is_time_auspicious(
199
+ check_time: datetime,
200
+ sunrise: datetime | None = None,
201
+ sunset: datetime | None = None,
202
+ ) -> dict[str, Any]:
203
+ """Check if a given time is auspicious or inauspicious.
204
+
205
+ Args:
206
+ check_time: The time to check
207
+ sunrise: Optional sunrise time
208
+ sunset: Optional sunset time
209
+
210
+ Returns:
211
+ Dictionary with auspiciousness assessment
212
+ """
213
+ times = calculate_inauspicious_times(check_time, sunrise, sunset)
214
+
215
+ check_str = check_time.strftime("%H:%M")
216
+
217
+ inauspicious = []
218
+
219
+ # Check Rahu Kala
220
+ if _time_in_range(
221
+ check_str, times["rahu_kala"]["start"], times["rahu_kala"]["end"]
222
+ ):
223
+ inauspicious.append("Rahu Kala")
224
+
225
+ # Check Yamaganda
226
+ if _time_in_range(
227
+ check_str, times["yamaganda"]["start"], times["yamaganda"]["end"]
228
+ ):
229
+ inauspicious.append("Yamaganda")
230
+
231
+ # Check Gulika
232
+ if _time_in_range(
233
+ check_str, times["gulika_kala"]["start"], times["gulika_kala"]["end"]
234
+ ):
235
+ inauspicious.append("Gulika Kala")
236
+
237
+ # Check Abhijit Muhurta
238
+ is_abhijit = _time_in_range(
239
+ check_str, times["abhijit_muhurta"]["start"], times["abhijit_muhurta"]["end"]
240
+ )
241
+
242
+ # Check Brahma Muhurta
243
+ is_brahma = _time_in_range(
244
+ check_str, times["brahma_muhurta"]["start"], times["brahma_muhurta"]["end"]
245
+ )
246
+
247
+ # Find current Choghadiya
248
+ current_choghadiya = None
249
+ for c in times["choghadiya"]:
250
+ start, end = c["period"].split("-")
251
+ if _time_in_range(check_str, start, end):
252
+ current_choghadiya = c
253
+ break
254
+
255
+ if is_abhijit:
256
+ rating = "Highly Auspicious"
257
+ recommendation = (
258
+ "Excellent time for starting new ventures, ceremonies, or important work"
259
+ )
260
+ elif is_brahma:
261
+ rating = "Highly Auspicious"
262
+ recommendation = "Best time for spiritual practices, meditation, and yoga"
263
+ elif inauspicious:
264
+ rating = "Inauspicious"
265
+ recommendation = f"Avoid important activities. Current inauspicious periods: {', '.join(inauspicious)}"
266
+ elif current_choghadiya and "Auspicious" in current_choghadiya["nature"]:
267
+ rating = "Auspicious"
268
+ recommendation = "Good time for most activities"
269
+ elif current_choghadiya and "Inauspicious" in current_choghadiya["nature"]:
270
+ rating = "Inauspicious"
271
+ recommendation = current_choghadiya["nature"]
272
+ else:
273
+ rating = "Neutral"
274
+ recommendation = "Okay for routine activities"
275
+
276
+ return {
277
+ "time": check_str,
278
+ "rating": rating,
279
+ "recommendation": recommendation,
280
+ "inauspicious_periods": inauspicious,
281
+ "is_abhijit_muhurta": is_abhijit,
282
+ "is_brahma_muhurta": is_brahma,
283
+ "current_choghadiya": current_choghadiya,
284
+ }
285
+
286
+
287
+ def _time_in_range(check: str, start: str, end: str) -> bool:
288
+ """Check if a time string is within a range."""
289
+ check_min = _to_minutes(check)
290
+ start_min = _to_minutes(start)
291
+ end_min = _to_minutes(end)
292
+
293
+ if start_min <= end_min:
294
+ return start_min <= check_min <= end_min
295
+ else:
296
+ # Crosses midnight
297
+ return check_min >= start_min or check_min <= end_min
298
+
299
+
300
+ def _to_minutes(time_str: str) -> int:
301
+ """Convert HH:MM to minutes."""
302
+ parts = time_str.split(":")
303
+ return int(parts[0]) * 60 + int(parts[1])