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,338 @@
|
|
|
1
|
+
"""Derived Vedic chart type helpers.
|
|
2
|
+
|
|
3
|
+
The base chart calculation returns accurate sidereal planetary longitudes. These
|
|
4
|
+
helpers derive common chart views from those longitudes without changing the
|
|
5
|
+
underlying ephemeris calculation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from kundali_lib.vedic.constants import RASHIS
|
|
13
|
+
|
|
14
|
+
# Full traditional varga set with names.
|
|
15
|
+
DIVISIONAL_CHARTS = {
|
|
16
|
+
1: ("d1", "Rashi / Lagna"),
|
|
17
|
+
2: ("d2", "Hora"),
|
|
18
|
+
3: ("d3", "Drekkana"),
|
|
19
|
+
4: ("d4", "Chaturthamsa"),
|
|
20
|
+
7: ("d7", "Saptamsa"),
|
|
21
|
+
9: ("d9", "Navamsa"),
|
|
22
|
+
10: ("d10", "Dashamsa"),
|
|
23
|
+
12: ("d12", "Dwadashamsa"),
|
|
24
|
+
16: ("d16", "Shodashamsa"),
|
|
25
|
+
20: ("d20", "Vimshamsa"),
|
|
26
|
+
24: ("d24", "Chaturvimshamsa"),
|
|
27
|
+
27: ("d27", "Saptavimshamsa"),
|
|
28
|
+
30: ("d30", "Trimsamsa"),
|
|
29
|
+
40: ("d40", "Khavedamsa"),
|
|
30
|
+
45: ("d45", "Akshavedamsa"),
|
|
31
|
+
60: ("d60", "Shashtiamsa"),
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
SUPPORTED_CHART_TYPES: dict[str, dict[str, str]] = {
|
|
35
|
+
"lagna": {
|
|
36
|
+
"name": "Lagna / Rashi / D1",
|
|
37
|
+
"description": "Default birth chart using ascendant as the 1st house.",
|
|
38
|
+
},
|
|
39
|
+
"rashi": {
|
|
40
|
+
"name": "Rashi / D1",
|
|
41
|
+
"description": "Alias for the default Lagna/Rashi chart.",
|
|
42
|
+
},
|
|
43
|
+
"d1": {
|
|
44
|
+
"name": "D1 / Rashi",
|
|
45
|
+
"description": "Alias for the default Lagna/Rashi chart.",
|
|
46
|
+
},
|
|
47
|
+
"chandra": {
|
|
48
|
+
"name": "Chandra Kundali",
|
|
49
|
+
"description": "Moon sign treated as the 1st house; planet houses recalculated from Moon sign.",
|
|
50
|
+
},
|
|
51
|
+
"moon": {"name": "Chandra Kundali", "description": "Alias for Chandra Kundali."},
|
|
52
|
+
"surya": {
|
|
53
|
+
"name": "Surya Kundali",
|
|
54
|
+
"description": "Sun sign treated as the 1st house; planet houses recalculated from Sun sign.",
|
|
55
|
+
},
|
|
56
|
+
"sun": {"name": "Surya Kundali", "description": "Alias for Surya Kundali."},
|
|
57
|
+
"all": {
|
|
58
|
+
"name": "All quick derived charts",
|
|
59
|
+
"description": "Returns Lagna + Chandra + Surya + D9 + D10.",
|
|
60
|
+
},
|
|
61
|
+
"all_divisionals": {
|
|
62
|
+
"name": "All traditional divisional charts",
|
|
63
|
+
"description": "Returns Lagna chart plus all traditional vargas (D1, D2, D3, D4, D7, D9, D10, D12, D16, D20, D24, D27, D30, D40, D45, D60).",
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
for div, (key, name) in DIVISIONAL_CHARTS.items():
|
|
68
|
+
if key not in SUPPORTED_CHART_TYPES:
|
|
69
|
+
SUPPORTED_CHART_TYPES[key] = {
|
|
70
|
+
"name": f"{name} / D{div}",
|
|
71
|
+
"description": f"Divisional chart D{div} ({name}) derived from sidereal longitudes.",
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
ALIASES = {
|
|
75
|
+
"rashi": "lagna",
|
|
76
|
+
"d1": "lagna",
|
|
77
|
+
"moon": "chandra",
|
|
78
|
+
"sun": "surya",
|
|
79
|
+
"navamsa": "d9",
|
|
80
|
+
"dashamsa": "d10",
|
|
81
|
+
"drekkana": "d3",
|
|
82
|
+
"chaturthamsa": "d4",
|
|
83
|
+
"saptamsa": "d7",
|
|
84
|
+
"dwadashamsa": "d12",
|
|
85
|
+
"shodashamsa": "d16",
|
|
86
|
+
"vimshamsa": "d20",
|
|
87
|
+
"chaturvimshamsa": "d24",
|
|
88
|
+
"saptavimshamsa": "d27",
|
|
89
|
+
"trimsamsa": "d30",
|
|
90
|
+
"khavedamsa": "d40",
|
|
91
|
+
"akshavedamsa": "d45",
|
|
92
|
+
"shashtiamsa": "d60",
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
DEFAULT_CHART_TYPE = "lagna"
|
|
96
|
+
ALL_QUICK_TYPES = ["chandra", "surya", "d9", "d10"]
|
|
97
|
+
ALL_DIVISIONAL_KEYS = [key for div, (key, _) in DIVISIONAL_CHARTS.items()]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def normalize_chart_type(chart_type: str | None) -> str:
|
|
101
|
+
key = (chart_type or DEFAULT_CHART_TYPE).strip().lower().replace("-", "_")
|
|
102
|
+
key = ALIASES.get(key, key)
|
|
103
|
+
if key not in SUPPORTED_CHART_TYPES:
|
|
104
|
+
raise ValueError(
|
|
105
|
+
f"Unsupported chart_type '{chart_type}'. Supported values: "
|
|
106
|
+
+ ", ".join(sorted(SUPPORTED_CHART_TYPES))
|
|
107
|
+
)
|
|
108
|
+
return key
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def available_chart_types() -> dict[str, Any]:
|
|
112
|
+
canonical = {
|
|
113
|
+
k: v
|
|
114
|
+
for k, v in SUPPORTED_CHART_TYPES.items()
|
|
115
|
+
if "_" not in k or k in ["lagna", "chandra", "surya", "all", "all_divisionals"]
|
|
116
|
+
}
|
|
117
|
+
divisional_list = [
|
|
118
|
+
{"division": div, "key": key, "name": name}
|
|
119
|
+
for div, (key, name) in DIVISIONAL_CHARTS.items()
|
|
120
|
+
]
|
|
121
|
+
return {
|
|
122
|
+
"default": DEFAULT_CHART_TYPE,
|
|
123
|
+
"canonical_types": canonical,
|
|
124
|
+
"aliases": ALIASES,
|
|
125
|
+
"divisional_charts": divisional_list,
|
|
126
|
+
"note": "D1/Lagna is the original full chart. Chandra and Surya are house-reference views. Divisional charts (D2–D60) are derived from sidereal longitudes.",
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _sign_index_from_rashi(rashi: str) -> int:
|
|
131
|
+
return RASHIS.index(rashi)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _house_from_reference(planet_rashi: str, reference_rashi: str) -> int:
|
|
135
|
+
return (
|
|
136
|
+
_sign_index_from_rashi(planet_rashi) - _sign_index_from_rashi(reference_rashi)
|
|
137
|
+
) % 12 + 1
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _copy_planet_with_house(
|
|
141
|
+
planet: dict[str, Any], reference_rashi: str
|
|
142
|
+
) -> dict[str, Any]:
|
|
143
|
+
copied = dict(planet)
|
|
144
|
+
copied["house"] = _house_from_reference(copied["rashi"], reference_rashi)
|
|
145
|
+
return copied
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def chandra_chart(base_chart: dict[str, Any]) -> dict[str, Any]:
|
|
149
|
+
reference_rashi = base_chart["moon_sign"]
|
|
150
|
+
return {
|
|
151
|
+
"chart_type": "chandra",
|
|
152
|
+
"name": SUPPORTED_CHART_TYPES["chandra"]["name"],
|
|
153
|
+
"reference": {"planet": "Moon", "rashi": reference_rashi},
|
|
154
|
+
"houses": {
|
|
155
|
+
f"House_{i + 1}": RASHIS[(_sign_index_from_rashi(reference_rashi) + i) % 12]
|
|
156
|
+
for i in range(12)
|
|
157
|
+
},
|
|
158
|
+
"planetary_positions": [
|
|
159
|
+
_copy_planet_with_house(p, reference_rashi)
|
|
160
|
+
for p in base_chart["planetary_positions"]
|
|
161
|
+
],
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def surya_chart(base_chart: dict[str, Any]) -> dict[str, Any]:
|
|
166
|
+
reference_rashi = base_chart["sun_sign"]
|
|
167
|
+
return {
|
|
168
|
+
"chart_type": "surya",
|
|
169
|
+
"name": SUPPORTED_CHART_TYPES["surya"]["name"],
|
|
170
|
+
"reference": {"planet": "Sun", "rashi": reference_rashi},
|
|
171
|
+
"houses": {
|
|
172
|
+
f"House_{i + 1}": RASHIS[(_sign_index_from_rashi(reference_rashi) + i) % 12]
|
|
173
|
+
for i in range(12)
|
|
174
|
+
},
|
|
175
|
+
"planetary_positions": [
|
|
176
|
+
_copy_planet_with_house(p, reference_rashi)
|
|
177
|
+
for p in base_chart["planetary_positions"]
|
|
178
|
+
],
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _varga_sign_index(longitude: float, division: int) -> int:
|
|
183
|
+
sign_index = int(longitude / 30) % 12
|
|
184
|
+
degree_in_sign = longitude % 30
|
|
185
|
+
part_index = min(int(degree_in_sign / (30 / division)), division - 1)
|
|
186
|
+
|
|
187
|
+
if division == 1:
|
|
188
|
+
return sign_index
|
|
189
|
+
|
|
190
|
+
if division == 2:
|
|
191
|
+
# Hora: odd signs Sun, even signs Moon (simplified common rule)
|
|
192
|
+
return (
|
|
193
|
+
sign_index % 2
|
|
194
|
+
) * 6 # 0->0 (Leo range), 1->6 (Aquarius range) simplified mapping
|
|
195
|
+
|
|
196
|
+
if division == 3:
|
|
197
|
+
# Drekkana: 1st/2nd/3rd decan → same sign / 5th / 9th
|
|
198
|
+
offset = part_index * 4
|
|
199
|
+
return (sign_index + offset) % 12
|
|
200
|
+
|
|
201
|
+
if division == 4:
|
|
202
|
+
# Chaturthamsa: movable 1-4-7-10, fixed 4-7-10-1, dual 7-10-1-4
|
|
203
|
+
if sign_index % 3 == 0: # movable
|
|
204
|
+
start = sign_index
|
|
205
|
+
elif sign_index % 3 == 1: # fixed
|
|
206
|
+
start = (sign_index + 3) % 12
|
|
207
|
+
else: # dual
|
|
208
|
+
start = (sign_index + 6) % 12
|
|
209
|
+
return (start + part_index) % 12
|
|
210
|
+
|
|
211
|
+
if division == 7:
|
|
212
|
+
# Saptamsa: odd signs count forward, even backward
|
|
213
|
+
if sign_index % 2 == 0:
|
|
214
|
+
return (sign_index + part_index) % 12
|
|
215
|
+
else:
|
|
216
|
+
return (sign_index - part_index) % 12
|
|
217
|
+
|
|
218
|
+
if division == 9:
|
|
219
|
+
# Navamsa: movable starts same sign, fixed starts 9th, dual starts 5th
|
|
220
|
+
if sign_index % 3 == 0: # movable
|
|
221
|
+
start = sign_index
|
|
222
|
+
elif sign_index % 3 == 1: # fixed
|
|
223
|
+
start = (sign_index + 8) % 12
|
|
224
|
+
else: # dual
|
|
225
|
+
start = (sign_index + 4) % 12
|
|
226
|
+
return (start + part_index) % 12
|
|
227
|
+
|
|
228
|
+
if division == 10:
|
|
229
|
+
# Dashamsa: odd signs same, even signs 9th
|
|
230
|
+
start = sign_index if sign_index % 2 == 0 else (sign_index + 8) % 12
|
|
231
|
+
return (start + part_index) % 12
|
|
232
|
+
|
|
233
|
+
if division == 12:
|
|
234
|
+
# Dwadashamsa: each degree moves to next sign (simplified as part_index advance)
|
|
235
|
+
return (sign_index + part_index) % 12
|
|
236
|
+
|
|
237
|
+
if division == 16:
|
|
238
|
+
# Shodashamsa: common rule uses 16 parts; simplified as 4-part cycle repeated
|
|
239
|
+
return (sign_index + part_index) % 12
|
|
240
|
+
|
|
241
|
+
if division == 20:
|
|
242
|
+
# Vimshamsa: simplified cycle
|
|
243
|
+
return (sign_index * 2 + part_index) % 12
|
|
244
|
+
|
|
245
|
+
if division == 24:
|
|
246
|
+
# Chaturvimshamsa
|
|
247
|
+
return (sign_index * 2 + part_index) % 12
|
|
248
|
+
|
|
249
|
+
if division == 27:
|
|
250
|
+
# Saptavimshamsa
|
|
251
|
+
return (sign_index + part_index) % 12
|
|
252
|
+
|
|
253
|
+
if division == 30:
|
|
254
|
+
# Trimsamsa: special 5/7 part rules; simplified here
|
|
255
|
+
return (sign_index + part_index) % 12
|
|
256
|
+
|
|
257
|
+
if division in (40, 45):
|
|
258
|
+
# Khavedamsa / Akshavedamsa: complex gender-based rules; simplified as cyclic
|
|
259
|
+
return (sign_index + part_index) % 12
|
|
260
|
+
|
|
261
|
+
if division == 60:
|
|
262
|
+
# Shashtiamsa: pure 60-part cycle independent of sign
|
|
263
|
+
return part_index % 12
|
|
264
|
+
|
|
265
|
+
raise ValueError(f"Unsupported varga division D{division}")
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def divisional_chart(
|
|
269
|
+
base_chart: dict[str, Any], division: int, chart_type: str, name: str
|
|
270
|
+
) -> dict[str, Any]:
|
|
271
|
+
positions = []
|
|
272
|
+
for planet in base_chart["planetary_positions"]:
|
|
273
|
+
sign_index = _varga_sign_index(float(planet["longitude"]), division)
|
|
274
|
+
copied = dict(planet)
|
|
275
|
+
copied["rashi"] = RASHIS[sign_index]
|
|
276
|
+
copied["division"] = division
|
|
277
|
+
copied["source_longitude"] = planet["longitude"]
|
|
278
|
+
copied["house"] = 0
|
|
279
|
+
positions.append(copied)
|
|
280
|
+
|
|
281
|
+
asc_sign_index = _varga_sign_index(
|
|
282
|
+
float(base_chart["ascendant"]["longitude"]), division
|
|
283
|
+
)
|
|
284
|
+
houses = {f"House_{i + 1}": RASHIS[(asc_sign_index + i) % 12] for i in range(12)}
|
|
285
|
+
for planet in positions:
|
|
286
|
+
planet["house"] = _house_from_reference(planet["rashi"], RASHIS[asc_sign_index])
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
"chart_type": chart_type,
|
|
290
|
+
"name": name,
|
|
291
|
+
"division": division,
|
|
292
|
+
"ascendant": {
|
|
293
|
+
"rashi": RASHIS[asc_sign_index],
|
|
294
|
+
"source_longitude": base_chart["ascendant"]["longitude"],
|
|
295
|
+
},
|
|
296
|
+
"houses": houses,
|
|
297
|
+
"planetary_positions": positions,
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def derive_chart(base_chart: dict[str, Any], chart_type: str | None) -> dict[str, Any]:
|
|
302
|
+
normalized = normalize_chart_type(chart_type)
|
|
303
|
+
|
|
304
|
+
if normalized == "lagna":
|
|
305
|
+
result = dict(base_chart)
|
|
306
|
+
result["chart_type"] = "lagna"
|
|
307
|
+
return result
|
|
308
|
+
|
|
309
|
+
if normalized == "chandra":
|
|
310
|
+
return chandra_chart(base_chart)
|
|
311
|
+
|
|
312
|
+
if normalized == "surya":
|
|
313
|
+
return surya_chart(base_chart)
|
|
314
|
+
|
|
315
|
+
if normalized == "all":
|
|
316
|
+
result = dict(base_chart)
|
|
317
|
+
result["chart_type"] = "lagna"
|
|
318
|
+
result["derived_charts"] = {
|
|
319
|
+
ctype: derive_chart(base_chart, ctype) for ctype in ALL_QUICK_TYPES
|
|
320
|
+
}
|
|
321
|
+
return result
|
|
322
|
+
|
|
323
|
+
if normalized == "all_divisionals":
|
|
324
|
+
result = dict(base_chart)
|
|
325
|
+
result["chart_type"] = "lagna"
|
|
326
|
+
result["divisional_charts"] = {}
|
|
327
|
+
for div, (key, name) in DIVISIONAL_CHARTS.items():
|
|
328
|
+
result["divisional_charts"][key] = divisional_chart(
|
|
329
|
+
base_chart, div, key, name
|
|
330
|
+
)
|
|
331
|
+
return result
|
|
332
|
+
|
|
333
|
+
# Check if it's a divisional chart key
|
|
334
|
+
for div, (key, name) in DIVISIONAL_CHARTS.items():
|
|
335
|
+
if normalized == key:
|
|
336
|
+
return divisional_chart(base_chart, div, key, name)
|
|
337
|
+
|
|
338
|
+
raise ValueError(f"Unsupported chart_type '{chart_type}'")
|