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,243 @@
|
|
|
1
|
+
"""Kartari Yoga: planets hemmed between benefics (Subha) or malefics (Papa)."""
|
|
2
|
+
|
|
3
|
+
# ---------------------------------------------------------------------------
|
|
4
|
+
# Reference data
|
|
5
|
+
# ---------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
_NATURAL_BENEFICS = {"Moon", "Mercury", "Jupiter", "Venus"}
|
|
8
|
+
_NATURAL_MALEFICS = {"Sun", "Mars", "Saturn", "Rahu", "Ketu"}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _planet_type(name: str) -> str:
|
|
12
|
+
"""Return 'benefic', 'malefic', or 'neutral' for a planet name."""
|
|
13
|
+
if name in _NATURAL_BENEFICS:
|
|
14
|
+
return "benefic"
|
|
15
|
+
if name in _NATURAL_MALEFICS:
|
|
16
|
+
return "malefic"
|
|
17
|
+
return "neutral"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _dominant_type(planet_names: list) -> str:
|
|
21
|
+
"""Return the dominant type among a list of planet names."""
|
|
22
|
+
if not planet_names:
|
|
23
|
+
return "empty"
|
|
24
|
+
types = [_planet_type(n) for n in planet_names]
|
|
25
|
+
benefic_count = types.count("benefic")
|
|
26
|
+
malefic_count = types.count("malefic")
|
|
27
|
+
if benefic_count > 0 and malefic_count == 0:
|
|
28
|
+
return "benefic"
|
|
29
|
+
if malefic_count > 0 and benefic_count == 0:
|
|
30
|
+
return "malefic"
|
|
31
|
+
if benefic_count > 0 and malefic_count > 0:
|
|
32
|
+
return "mixed"
|
|
33
|
+
return "neutral"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _adjacent_houses(house: int) -> tuple:
|
|
37
|
+
"""Return the (preceding, following) house numbers (1–12, wrapping)."""
|
|
38
|
+
preceding = ((house - 2) % 12) + 1
|
|
39
|
+
following = (house % 12) + 1
|
|
40
|
+
return preceding, following
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ---------------------------------------------------------------------------
|
|
44
|
+
# Main function
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def check_kartari_yoga(planetary_positions: list, houses: dict) -> list:
|
|
49
|
+
"""Detect Kartari Yoga for every occupied house and every planet.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
planetary_positions : list
|
|
54
|
+
Each item is a planet dict with at least ``name`` and ``house``.
|
|
55
|
+
houses : dict
|
|
56
|
+
Maps house number (int) to a list of planet name strings
|
|
57
|
+
present in that house. E.g. ``{1: ["Sun"], 7: ["Mars", "Venus"]}``.
|
|
58
|
+
Houses with no planets should either be absent or map to ``[]``.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
list of dict
|
|
63
|
+
One entry per planet/point that is hemmed between two occupied houses.
|
|
64
|
+
Includes special Paapa Kartari on Lagna and Subha Kartari on Moon
|
|
65
|
+
annotations.
|
|
66
|
+
"""
|
|
67
|
+
results = []
|
|
68
|
+
seen_houses = set() # avoid duplicating house checks
|
|
69
|
+
|
|
70
|
+
# ----------------------------------------------------------------
|
|
71
|
+
# Per-planet analysis
|
|
72
|
+
# ----------------------------------------------------------------
|
|
73
|
+
for planet in planetary_positions:
|
|
74
|
+
name = planet["name"]
|
|
75
|
+
house = planet["house"]
|
|
76
|
+
|
|
77
|
+
pre_house, fol_house = _adjacent_houses(house)
|
|
78
|
+
pre_planets = houses.get(pre_house, [])
|
|
79
|
+
fol_planets = houses.get(fol_house, [])
|
|
80
|
+
|
|
81
|
+
pre_type = _dominant_type(pre_planets)
|
|
82
|
+
fol_type = _dominant_type(fol_planets)
|
|
83
|
+
|
|
84
|
+
# A Kartari Yoga requires at least one planet on each side
|
|
85
|
+
if not pre_planets or not fol_planets:
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
if pre_type in ("benefic", "malefic") and pre_type == fol_type:
|
|
89
|
+
yoga_type = "Subha Kartari" if pre_type == "benefic" else "Papa Kartari"
|
|
90
|
+
elif pre_type == "mixed" or fol_type == "mixed":
|
|
91
|
+
yoga_type = "Mixed Kartari"
|
|
92
|
+
elif pre_type in ("benefic", "malefic") and fol_type in ("benefic", "malefic"):
|
|
93
|
+
yoga_type = "Mixed Kartari"
|
|
94
|
+
else:
|
|
95
|
+
continue # neutral/empty — no Kartari
|
|
96
|
+
|
|
97
|
+
effect = (
|
|
98
|
+
"Highly beneficial — planet's significations are enhanced"
|
|
99
|
+
if yoga_type == "Subha Kartari"
|
|
100
|
+
else (
|
|
101
|
+
"Harmful — planet's significations are suppressed/afflicted"
|
|
102
|
+
if yoga_type == "Papa Kartari"
|
|
103
|
+
else "Mixed results — conflicting influences on either side"
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
results.append(
|
|
108
|
+
{
|
|
109
|
+
"planet_or_house": name,
|
|
110
|
+
"house_number": house,
|
|
111
|
+
"yoga_type": yoga_type,
|
|
112
|
+
"preceding_house": pre_house,
|
|
113
|
+
"following_house": fol_house,
|
|
114
|
+
"preceding_planets": list(pre_planets),
|
|
115
|
+
"following_planets": list(fol_planets),
|
|
116
|
+
"effect": effect,
|
|
117
|
+
"strength": "Strong",
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
seen_houses.add(house)
|
|
121
|
+
|
|
122
|
+
# ----------------------------------------------------------------
|
|
123
|
+
# Per-occupied-house analysis (catches houses with planets that
|
|
124
|
+
# might be hemmed even if individual planets were already checked,
|
|
125
|
+
# but primarily adds house-level entries not covered above)
|
|
126
|
+
# ----------------------------------------------------------------
|
|
127
|
+
all_occupied = set(h for h, plist in houses.items() if plist)
|
|
128
|
+
|
|
129
|
+
for house in sorted(all_occupied):
|
|
130
|
+
if house in seen_houses:
|
|
131
|
+
continue # already handled via a planet entry
|
|
132
|
+
|
|
133
|
+
pre_house, fol_house = _adjacent_houses(house)
|
|
134
|
+
pre_planets = houses.get(pre_house, [])
|
|
135
|
+
fol_planets = houses.get(fol_house, [])
|
|
136
|
+
|
|
137
|
+
if not pre_planets or not fol_planets:
|
|
138
|
+
continue
|
|
139
|
+
|
|
140
|
+
pre_type = _dominant_type(pre_planets)
|
|
141
|
+
fol_type = _dominant_type(fol_planets)
|
|
142
|
+
|
|
143
|
+
if pre_type in ("benefic", "malefic") and pre_type == fol_type:
|
|
144
|
+
yoga_type = "Subha Kartari" if pre_type == "benefic" else "Papa Kartari"
|
|
145
|
+
elif pre_type in ("benefic", "malefic") and fol_type in ("benefic", "malefic"):
|
|
146
|
+
yoga_type = "Mixed Kartari"
|
|
147
|
+
else:
|
|
148
|
+
continue
|
|
149
|
+
|
|
150
|
+
effect = (
|
|
151
|
+
"Highly beneficial — house significations are protected and enhanced"
|
|
152
|
+
if yoga_type == "Subha Kartari"
|
|
153
|
+
else (
|
|
154
|
+
"Harmful — house significations are hemmed and afflicted"
|
|
155
|
+
if yoga_type == "Papa Kartari"
|
|
156
|
+
else "Mixed results — conflicting influences on either side"
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
results.append(
|
|
161
|
+
{
|
|
162
|
+
"planet_or_house": f"House_{house}",
|
|
163
|
+
"house_number": house,
|
|
164
|
+
"yoga_type": yoga_type,
|
|
165
|
+
"preceding_house": pre_house,
|
|
166
|
+
"following_house": fol_house,
|
|
167
|
+
"preceding_planets": list(pre_planets),
|
|
168
|
+
"following_planets": list(fol_planets),
|
|
169
|
+
"effect": effect,
|
|
170
|
+
"strength": "Strong",
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# ----------------------------------------------------------------
|
|
175
|
+
# Special checks
|
|
176
|
+
# ----------------------------------------------------------------
|
|
177
|
+
_check_paapa_kartari_lagna(houses, results)
|
|
178
|
+
_check_subha_kartari_moon(planetary_positions, houses, results)
|
|
179
|
+
|
|
180
|
+
return results
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def _check_paapa_kartari_lagna(houses: dict, results: list) -> None:
|
|
184
|
+
"""Annotate if both 2nd and 12th houses from Lagna are occupied by malefics."""
|
|
185
|
+
h2 = houses.get(2, [])
|
|
186
|
+
h12 = houses.get(12, [])
|
|
187
|
+
if not h2 or not h12:
|
|
188
|
+
return
|
|
189
|
+
if _dominant_type(h2) == "malefic" and _dominant_type(h12) == "malefic":
|
|
190
|
+
results.append(
|
|
191
|
+
{
|
|
192
|
+
"planet_or_house": "Lagna (Special — Paapa Kartari)",
|
|
193
|
+
"house_number": 1,
|
|
194
|
+
"yoga_type": "Papa Kartari",
|
|
195
|
+
"preceding_house": 12,
|
|
196
|
+
"following_house": 2,
|
|
197
|
+
"preceding_planets": list(h12),
|
|
198
|
+
"following_planets": list(h2),
|
|
199
|
+
"effect": (
|
|
200
|
+
"Very harmful — Lagna hemmed between malefics. "
|
|
201
|
+
"Physical constitution and self-expression are strongly afflicted."
|
|
202
|
+
),
|
|
203
|
+
"strength": "Strong",
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _check_subha_kartari_moon(
|
|
209
|
+
planetary_positions: list, houses: dict, results: list
|
|
210
|
+
) -> None:
|
|
211
|
+
"""Annotate if Moon is hemmed by benefics on both sides (Durudhura Yoga)."""
|
|
212
|
+
moon = next((p for p in planetary_positions if p["name"] == "Moon"), None)
|
|
213
|
+
if moon is None:
|
|
214
|
+
return
|
|
215
|
+
|
|
216
|
+
moon_house = moon["house"]
|
|
217
|
+
pre_house, fol_house = _adjacent_houses(moon_house)
|
|
218
|
+
pre_planets = houses.get(pre_house, [])
|
|
219
|
+
fol_planets = houses.get(fol_house, [])
|
|
220
|
+
|
|
221
|
+
if not pre_planets or not fol_planets:
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
if (
|
|
225
|
+
_dominant_type(pre_planets) == "benefic"
|
|
226
|
+
and _dominant_type(fol_planets) == "benefic"
|
|
227
|
+
):
|
|
228
|
+
results.append(
|
|
229
|
+
{
|
|
230
|
+
"planet_or_house": "Moon (Special — Durudhura Yoga)",
|
|
231
|
+
"house_number": moon_house,
|
|
232
|
+
"yoga_type": "Subha Kartari",
|
|
233
|
+
"preceding_house": pre_house,
|
|
234
|
+
"following_house": fol_house,
|
|
235
|
+
"preceding_planets": list(pre_planets),
|
|
236
|
+
"following_planets": list(fol_planets),
|
|
237
|
+
"effect": (
|
|
238
|
+
"Very auspicious — Moon flanked by benefics (Durudhura Yoga). "
|
|
239
|
+
"Prosperity, fame, and good fortune throughout life."
|
|
240
|
+
),
|
|
241
|
+
"strength": "Strong",
|
|
242
|
+
}
|
|
243
|
+
)
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"""Kurmachakra: geographical direction system for auspicious travel and construction Muhurta.
|
|
2
|
+
|
|
3
|
+
The Kurmachakra (Tortoise Wheel) maps the 27 Nakshatras to the 8 cardinal directions
|
|
4
|
+
plus a centre/upward direction. It is used to determine:
|
|
5
|
+
1. Auspicious travel directions based on birth nakshatra (avoid the bad direction)
|
|
6
|
+
2. Current Moon nakshatra direction (avoid travelling in that direction on that day)
|
|
7
|
+
3. Auspicious directions for construction, marriage, and major events
|
|
8
|
+
4. Monthly/daily directional strength using the Moon's nakshatra
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
# ── Core mapping ───────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
# The 27 Nakshatras mapped to 8 directions + Centre (9 slots × 3 nakshatras each)
|
|
18
|
+
NAKSHATRA_DIRECTION: dict[str, str] = {
|
|
19
|
+
# East (Purva)
|
|
20
|
+
"Ashwini": "East",
|
|
21
|
+
"Bharani": "East",
|
|
22
|
+
"Krittika": "East",
|
|
23
|
+
# South-East (Agneya)
|
|
24
|
+
"Rohini": "South-East",
|
|
25
|
+
"Mrigashira": "South-East",
|
|
26
|
+
"Ardra": "South-East",
|
|
27
|
+
# South (Dakshina)
|
|
28
|
+
"Punarvasu": "South",
|
|
29
|
+
"Pushya": "South",
|
|
30
|
+
"Ashlesha": "South",
|
|
31
|
+
# South-West (Nairutya)
|
|
32
|
+
"Magha": "South-West",
|
|
33
|
+
"Purva Phalguni": "South-West",
|
|
34
|
+
"Uttara Phalguni": "South-West",
|
|
35
|
+
# West (Pashchima)
|
|
36
|
+
"Hasta": "West",
|
|
37
|
+
"Chitra": "West",
|
|
38
|
+
"Swati": "West",
|
|
39
|
+
# North-West (Vayavya)
|
|
40
|
+
"Vishakha": "North-West",
|
|
41
|
+
"Anuradha": "North-West",
|
|
42
|
+
"Jyeshtha": "North-West",
|
|
43
|
+
# North (Uttara)
|
|
44
|
+
"Mula": "North",
|
|
45
|
+
"Purva Ashadha": "North",
|
|
46
|
+
"Uttara Ashadha": "North",
|
|
47
|
+
# North-East (Ishanya)
|
|
48
|
+
"Shravana": "North-East",
|
|
49
|
+
"Dhanishta": "North-East",
|
|
50
|
+
"Shatabhisha": "North-East",
|
|
51
|
+
# Centre / Upward (Urdhva / Brahma)
|
|
52
|
+
"Purva Bhadrapada": "Centre",
|
|
53
|
+
"Uttara Bhadrapada": "Centre",
|
|
54
|
+
"Revati": "Centre",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
DIRECTIONS_ORDER = [
|
|
58
|
+
"East",
|
|
59
|
+
"South-East",
|
|
60
|
+
"South",
|
|
61
|
+
"South-West",
|
|
62
|
+
"West",
|
|
63
|
+
"North-West",
|
|
64
|
+
"North",
|
|
65
|
+
"North-East",
|
|
66
|
+
"Centre",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
# Sanskrit names
|
|
70
|
+
DIRECTION_SANSKRIT: dict[str, str] = {
|
|
71
|
+
"East": "Purva",
|
|
72
|
+
"South-East": "Agneya",
|
|
73
|
+
"South": "Dakshina",
|
|
74
|
+
"South-West": "Nairutya",
|
|
75
|
+
"West": "Pashchima",
|
|
76
|
+
"North-West": "Vayavya",
|
|
77
|
+
"North": "Uttara",
|
|
78
|
+
"North-East": "Ishanya",
|
|
79
|
+
"Centre": "Urdhva (Brahma)",
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# General auspiciousness for travel by direction (contextual — depends on event)
|
|
83
|
+
DIRECTION_GENERAL: dict[str, dict[str, str]] = {
|
|
84
|
+
"East": {
|
|
85
|
+
"nature": "Highly auspicious",
|
|
86
|
+
"good_for": "Education, jobs, seeking blessings from elders",
|
|
87
|
+
"avoid": "Nothing specific",
|
|
88
|
+
},
|
|
89
|
+
"South-East": {
|
|
90
|
+
"nature": "Mixed",
|
|
91
|
+
"good_for": "Trade, cooking, fire-related activities",
|
|
92
|
+
"avoid": "Long journeys",
|
|
93
|
+
},
|
|
94
|
+
"South": {
|
|
95
|
+
"nature": "Inauspicious",
|
|
96
|
+
"good_for": "War, competition, debt collection",
|
|
97
|
+
"avoid": "General travel, marriage, new ventures",
|
|
98
|
+
},
|
|
99
|
+
"South-West": {
|
|
100
|
+
"nature": "Inauspicious",
|
|
101
|
+
"good_for": "Endings, wrapping up matters",
|
|
102
|
+
"avoid": "New beginnings, travel, construction",
|
|
103
|
+
},
|
|
104
|
+
"West": {
|
|
105
|
+
"nature": "Neutral to auspicious",
|
|
106
|
+
"good_for": "Business, trade, water activities",
|
|
107
|
+
"avoid": "Aggressive activities",
|
|
108
|
+
},
|
|
109
|
+
"North-West": {
|
|
110
|
+
"nature": "Mixed",
|
|
111
|
+
"good_for": "Quick travel, messages, communication",
|
|
112
|
+
"avoid": "Long-term ventures",
|
|
113
|
+
},
|
|
114
|
+
"North": {
|
|
115
|
+
"nature": "Auspicious",
|
|
116
|
+
"good_for": "Wealth, new ventures, prosperity",
|
|
117
|
+
"avoid": "Nothing specific",
|
|
118
|
+
},
|
|
119
|
+
"North-East": {
|
|
120
|
+
"nature": "Highly auspicious",
|
|
121
|
+
"good_for": "Worship, spiritual activities, education, divine matters",
|
|
122
|
+
"avoid": "Nothing specific",
|
|
123
|
+
},
|
|
124
|
+
"Centre": {
|
|
125
|
+
"nature": "Upward / Special",
|
|
126
|
+
"good_for": "Spiritual elevation, liberation, meditation",
|
|
127
|
+
"avoid": "Mundane worldly activities",
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Nakshatras by direction for quick lookup
|
|
132
|
+
DIRECTION_NAKSHATRAS: dict[str, list[str]] = {}
|
|
133
|
+
for nak, direction in NAKSHATRA_DIRECTION.items():
|
|
134
|
+
DIRECTION_NAKSHATRAS.setdefault(direction, []).append(nak)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# ── Kurmachakra for Muhurta ───────────────────────────────────────────────────
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# Which directions are auspicious to travel when the Moon is in a specific direction
|
|
141
|
+
# (Avoid travelling in the same direction as Moon's nakshatra direction on that day)
|
|
142
|
+
def _directions_to_avoid_for_moon(moon_direction: str) -> list[str]:
|
|
143
|
+
"""Directions to avoid when Moon is in the given direction."""
|
|
144
|
+
# Standard rule: avoid Moon's direction and its immediate flanking directions
|
|
145
|
+
idx = DIRECTIONS_ORDER.index(moon_direction)
|
|
146
|
+
avoid = [moon_direction]
|
|
147
|
+
# Also avoid the two opposite quadrant (simplified traditional rule)
|
|
148
|
+
opp_idx = (idx + 4) % 8 if idx < 8 else idx
|
|
149
|
+
avoid.append(DIRECTIONS_ORDER[opp_idx])
|
|
150
|
+
return avoid
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# ── Public API ─────────────────────────────────────────────────────────────────
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_kurmachakra(
|
|
157
|
+
birth_nakshatra: str,
|
|
158
|
+
current_moon_nakshatra: str | None = None,
|
|
159
|
+
event_type: str = "travel",
|
|
160
|
+
) -> dict[str, Any]:
|
|
161
|
+
"""Get Kurmachakra directional analysis.
|
|
162
|
+
|
|
163
|
+
Parameters
|
|
164
|
+
----------
|
|
165
|
+
birth_nakshatra : person's birth nakshatra (Janma Nakshatra)
|
|
166
|
+
current_moon_nakshatra: today's Moon nakshatra (for daily Muhurta)
|
|
167
|
+
event_type : "travel", "construction", "marriage", "general"
|
|
168
|
+
"""
|
|
169
|
+
birth_direction = NAKSHATRA_DIRECTION.get(birth_nakshatra, "Unknown")
|
|
170
|
+
|
|
171
|
+
result: dict[str, Any] = {
|
|
172
|
+
"event_type": event_type,
|
|
173
|
+
"birth_nakshatra": birth_nakshatra,
|
|
174
|
+
"birth_direction": birth_direction,
|
|
175
|
+
"birth_direction_sanskrit": DIRECTION_SANSKRIT.get(birth_direction, ""),
|
|
176
|
+
"birth_direction_analysis": DIRECTION_GENERAL.get(birth_direction, {}),
|
|
177
|
+
"direction_map": {
|
|
178
|
+
direction: {
|
|
179
|
+
"sanskrit": DIRECTION_SANSKRIT[direction],
|
|
180
|
+
"nakshatras": DIRECTION_NAKSHATRAS[direction],
|
|
181
|
+
"nature": DIRECTION_GENERAL[direction]["nature"],
|
|
182
|
+
"good_for": DIRECTION_GENERAL[direction]["good_for"],
|
|
183
|
+
}
|
|
184
|
+
for direction in DIRECTIONS_ORDER
|
|
185
|
+
},
|
|
186
|
+
"auspicious_directions": [],
|
|
187
|
+
"inauspicious_directions": [],
|
|
188
|
+
"best_direction": "",
|
|
189
|
+
"direction_to_avoid": birth_direction,
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# Auspicious vs inauspicious directions for the birth nakshatra holder
|
|
193
|
+
auspicious = []
|
|
194
|
+
inauspicious = []
|
|
195
|
+
for direction in DIRECTIONS_ORDER:
|
|
196
|
+
nature = DIRECTION_GENERAL[direction]["nature"].lower()
|
|
197
|
+
if direction == birth_direction:
|
|
198
|
+
continue # own direction — special rules apply
|
|
199
|
+
if "highly auspicious" in nature or "auspicious" in nature:
|
|
200
|
+
auspicious.append(direction)
|
|
201
|
+
elif "inauspicious" in nature:
|
|
202
|
+
inauspicious.append(direction)
|
|
203
|
+
else:
|
|
204
|
+
auspicious.append(direction) # neutral counts as ok
|
|
205
|
+
|
|
206
|
+
result["auspicious_directions"] = auspicious
|
|
207
|
+
result["inauspicious_directions"] = inauspicious
|
|
208
|
+
result["best_direction"] = (
|
|
209
|
+
"North-East"
|
|
210
|
+
if "North-East" in auspicious
|
|
211
|
+
else (auspicious[0] if auspicious else "North")
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# If current Moon nakshatra is given, add daily guidance
|
|
215
|
+
if current_moon_nakshatra:
|
|
216
|
+
moon_direction = NAKSHATRA_DIRECTION.get(current_moon_nakshatra, "Unknown")
|
|
217
|
+
avoid_today = (
|
|
218
|
+
_directions_to_avoid_for_moon(moon_direction)
|
|
219
|
+
if moon_direction in DIRECTIONS_ORDER
|
|
220
|
+
else [moon_direction]
|
|
221
|
+
)
|
|
222
|
+
good_today = [d for d in DIRECTIONS_ORDER if d not in avoid_today]
|
|
223
|
+
result["daily_analysis"] = {
|
|
224
|
+
"current_moon_nakshatra": current_moon_nakshatra,
|
|
225
|
+
"moon_direction": moon_direction,
|
|
226
|
+
"moon_direction_sanskrit": DIRECTION_SANSKRIT.get(moon_direction, ""),
|
|
227
|
+
"avoid_today": avoid_today,
|
|
228
|
+
"good_directions_today": good_today,
|
|
229
|
+
"note": f"Avoid travelling towards {', '.join(avoid_today)} today as Moon is in that direction.",
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
# Event-specific recommendations
|
|
233
|
+
event_notes: dict[str, str] = {
|
|
234
|
+
"travel": (
|
|
235
|
+
f"Best direction for travel from birth nakshatra: {result['best_direction']}. "
|
|
236
|
+
f"Avoid: {birth_direction} (birth direction). "
|
|
237
|
+
"Never travel South on Tuesday, or South-West at night."
|
|
238
|
+
),
|
|
239
|
+
"construction": (
|
|
240
|
+
"North or North-East is ideal for main entrance. "
|
|
241
|
+
"South-West for master bedroom/safe room. "
|
|
242
|
+
"Avoid South-West for main gate."
|
|
243
|
+
),
|
|
244
|
+
"marriage": (
|
|
245
|
+
"North-East is ideal for sacred fire direction. "
|
|
246
|
+
"East is best for bride's entry. "
|
|
247
|
+
"Avoid South and South-West for ceremony timing."
|
|
248
|
+
),
|
|
249
|
+
"general": (
|
|
250
|
+
"North-East for spiritual and auspicious activities. "
|
|
251
|
+
"East for new beginnings. "
|
|
252
|
+
"Avoid South and South-West when possible."
|
|
253
|
+
),
|
|
254
|
+
}
|
|
255
|
+
result["recommendation"] = event_notes.get(event_type, event_notes["general"])
|
|
256
|
+
|
|
257
|
+
return result
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def get_travel_direction_score(
|
|
261
|
+
birth_nakshatra: str,
|
|
262
|
+
intended_direction: str,
|
|
263
|
+
current_moon_nakshatra: str | None = None,
|
|
264
|
+
weekday: str | None = None,
|
|
265
|
+
) -> dict[str, Any]:
|
|
266
|
+
"""Score a specific intended travel direction for auspiciousness.
|
|
267
|
+
|
|
268
|
+
Parameters
|
|
269
|
+
----------
|
|
270
|
+
birth_nakshatra : person's birth nakshatra
|
|
271
|
+
intended_direction : direction of travel ("North", "South", "East", etc.)
|
|
272
|
+
current_moon_nakshatra: current Moon's nakshatra
|
|
273
|
+
weekday : "Monday", "Tuesday", etc.
|
|
274
|
+
"""
|
|
275
|
+
birth_direction = NAKSHATRA_DIRECTION.get(birth_nakshatra, "Unknown")
|
|
276
|
+
moon_direction = (
|
|
277
|
+
NAKSHATRA_DIRECTION.get(current_moon_nakshatra, "")
|
|
278
|
+
if current_moon_nakshatra
|
|
279
|
+
else ""
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
score = 100.0
|
|
283
|
+
warnings = []
|
|
284
|
+
positives = []
|
|
285
|
+
|
|
286
|
+
nature = DIRECTION_GENERAL.get(intended_direction, {}).get("nature", "")
|
|
287
|
+
if "highly auspicious" in nature.lower():
|
|
288
|
+
positives.append(f"{intended_direction} is highly auspicious in general")
|
|
289
|
+
score += 10
|
|
290
|
+
elif "inauspicious" in nature.lower():
|
|
291
|
+
warnings.append(f"{intended_direction} is generally inauspicious for travel")
|
|
292
|
+
score -= 30
|
|
293
|
+
|
|
294
|
+
if intended_direction == birth_direction:
|
|
295
|
+
warnings.append(
|
|
296
|
+
f"Travelling in birth nakshatra direction ({birth_direction}) is generally avoided"
|
|
297
|
+
)
|
|
298
|
+
score -= 20
|
|
299
|
+
|
|
300
|
+
if moon_direction and intended_direction == moon_direction:
|
|
301
|
+
warnings.append(
|
|
302
|
+
f"Avoid travelling in Moon's current direction ({moon_direction})"
|
|
303
|
+
)
|
|
304
|
+
score -= 25
|
|
305
|
+
|
|
306
|
+
# Weekday-direction restrictions
|
|
307
|
+
BAD_WEEKDAY_DIRECTIONS: dict[str, list[str]] = {
|
|
308
|
+
"Sunday": ["West"],
|
|
309
|
+
"Monday": ["North-West"],
|
|
310
|
+
"Tuesday": ["South"],
|
|
311
|
+
"Wednesday": ["North"],
|
|
312
|
+
"Thursday": ["South-East"],
|
|
313
|
+
"Friday": ["South-West"],
|
|
314
|
+
"Saturday": ["East"],
|
|
315
|
+
}
|
|
316
|
+
if weekday and intended_direction in BAD_WEEKDAY_DIRECTIONS.get(weekday, []):
|
|
317
|
+
warnings.append(f"Avoid {intended_direction} on {weekday} (traditional rule)")
|
|
318
|
+
score -= 20
|
|
319
|
+
|
|
320
|
+
if not warnings:
|
|
321
|
+
positives.append("No directional conflicts found")
|
|
322
|
+
|
|
323
|
+
score = max(0.0, min(100.0, score))
|
|
324
|
+
grade = (
|
|
325
|
+
"Excellent"
|
|
326
|
+
if score >= 80
|
|
327
|
+
else "Good"
|
|
328
|
+
if score >= 60
|
|
329
|
+
else "Caution"
|
|
330
|
+
if score >= 40
|
|
331
|
+
else "Avoid"
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
"intended_direction": intended_direction,
|
|
336
|
+
"score": round(score, 1),
|
|
337
|
+
"grade": grade,
|
|
338
|
+
"birth_nakshatra": birth_nakshatra,
|
|
339
|
+
"birth_direction": birth_direction,
|
|
340
|
+
"moon_direction": moon_direction or "Not specified",
|
|
341
|
+
"warnings": warnings,
|
|
342
|
+
"positives": positives,
|
|
343
|
+
"good_for": DIRECTION_GENERAL.get(intended_direction, {}).get("good_for", ""),
|
|
344
|
+
"recommendation": f"Direction is {grade} for travel."
|
|
345
|
+
+ (" " + "; ".join(warnings) if warnings else ""),
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def get_full_kurmachakra_chart() -> dict[str, Any]:
|
|
350
|
+
"""Return the complete Kurmachakra chart — all 9 directions with all 27 nakshatras."""
|
|
351
|
+
return {
|
|
352
|
+
"description": (
|
|
353
|
+
"Kurmachakra (Tortoise Wheel): maps the 27 Nakshatras to 8 cardinal directions "
|
|
354
|
+
"+ Centre (Brahma/Urdhva). Used in Muhurta for travel, construction, and auspicious activities."
|
|
355
|
+
),
|
|
356
|
+
"directions": {
|
|
357
|
+
direction: {
|
|
358
|
+
"sanskrit": DIRECTION_SANSKRIT[direction],
|
|
359
|
+
"nakshatras": DIRECTION_NAKSHATRAS[direction],
|
|
360
|
+
"nature": DIRECTION_GENERAL[direction]["nature"],
|
|
361
|
+
"good_for": DIRECTION_GENERAL[direction]["good_for"],
|
|
362
|
+
"avoid": DIRECTION_GENERAL[direction]["avoid"],
|
|
363
|
+
}
|
|
364
|
+
for direction in DIRECTIONS_ORDER
|
|
365
|
+
},
|
|
366
|
+
"weekday_avoid_directions": {
|
|
367
|
+
"Sunday": "West",
|
|
368
|
+
"Monday": "North-West",
|
|
369
|
+
"Tuesday": "South",
|
|
370
|
+
"Wednesday": "North",
|
|
371
|
+
"Thursday": "South-East",
|
|
372
|
+
"Friday": "South-West",
|
|
373
|
+
"Saturday": "East",
|
|
374
|
+
},
|
|
375
|
+
"travel_rules": [
|
|
376
|
+
"Never travel in the direction of your birth nakshatra (Janma Nakshatra direction) for long journeys",
|
|
377
|
+
"Avoid the direction occupied by Moon's current nakshatra on that day",
|
|
378
|
+
"South and South-West are generally inauspicious for new ventures",
|
|
379
|
+
"North-East and North are generally auspicious",
|
|
380
|
+
"East is good for education and spiritual journeys",
|
|
381
|
+
"Check weekday-specific direction restrictions",
|
|
382
|
+
],
|
|
383
|
+
}
|