From a295afa40f98b7ef06d16b080cdefa4d34a4d45b Mon Sep 17 00:00:00 2001 From: jesse-ux Date: Tue, 13 Oct 2026 14:02:26 +0800 Subject: [PATCH] fix(report): draw charts in the full-data body and clean Chinese residue New reports draw one north-Indian chart for each ready divisional in the body, so the trailing duplicate section drops. Chinese full-data prose no longer glues English onto Han or leaves listed, background, or native. The birth table starts with the ascendant. The D9 same-sign column says yes or no. Self-test: tsc exit 0; npm run lint exit 0 (0 errors, 125 existing warnings); three frontend test files 39 pass, 0 fail, 0 cancelled; pytest test_report_chart_blank_columns.py 16 passed; seven related report files 88 passed, exit 0; privacy markers 63 passed. Co-Authored-By: Grok (agent loop) --- CHANGELOG.md | 7 + docs/BUG_HISTORY.md | 59 + ...OGRESS-report-translation-gaps-20261013.md | 33 + frontend/DESIGN.md | 2 +- .../components/chart-page/chart-vedic-tab.tsx | 4 +- frontend/tests/chart-varga-table.test.tsx | 17 +- .../report-full-data-chart-fences.json | 2857 +++++++++++++++++ .../tests/report-calculation-charts.test.tsx | 13 + scripts/pl9_full_data_export.py | 35 +- scripts/pl9_interpretation_packs.py | 7 +- scripts/pl9_language_terms.py | 120 + scripts/pl9_reader_english_terms.py | 23 + scripts/pl9_reader_export.py | 191 +- tests/test_report_chart_blank_columns.py | 108 + 14 files changed, 3466 insertions(+), 10 deletions(-) create mode 100644 docs/tasks/PROGRESS-report-translation-gaps-20261013.md create mode 100644 frontend/tests/fixtures/report-full-data-chart-fences.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 69198910..c1e9167d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # 印度占星 Skill 更新日志 +## 2026-10-13 — 新报告正文画出分盘,中文更干净,上升行和同位列能读懂(待合入 staging) + +- 重新生成的报告里,「本命与分盘北印度图盘」每张有数据的盘下面有一张北印度图。同一张盘只画一次。报告最末不再重复「分盘核对」。旧报告打开仍是当时保存的正文。 +- 中文报告正文去掉 listed、background、native、Custom condition met 这类英文,也不再把中文和英文粘成一个词。括号里的星宿、瑜伽名保留。 +- 「本命盘行星原始位置」第一行是上升,星宿和 pada 有值。尊贵状态写「不适用」。没有可填的格子与其它空格一样写「未列」。 +- 星盘页 D9 表的「同位」列:同座写「是」,不同座写「否」。其它分盘仍没有这一列。Skill 版本不变(BUG-1312~1315)。 + ## 2026-10-12 — 设置里的岁差说明改对:新开的生时校正也跟着设置走(已合入 staging) - 设置页换岁差时的说明原来写「生时校正目前仍固定按 Raman」,与实际相反。改为:之后的咨询、报告、星盘库、每日星语和新开的生时校正会按新岁差算;已经开始的那次校正仍按开始时的岁差。Skill 版本不变(BUG-1310)。 diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 2638f05d..d8de4433 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -17615,3 +17615,62 @@ - 相关记录:BUG-511、BUG-1309。 - 复发自:无。 - 修复版本:已部署 staging `586561eb`(2026-10-12 核对:health gitCommit / apiGitCommit=586561eb、`requiredMigrationsPresent` true,`/login` 200,未登录 `/api/account` 401;合并后 npm test 5025 条、失败 24 逐名同 `798e15ef` 基线)。Claude 直接执行,产品 10-12 授权。 + +## BUG-1312 | 中文完整数据报告正文仍有英文功能词,并与汉字粘在一起 + +- 状态:fixed-pending-verify(只对新生成的报告生效;真机清单 `docs/testing/report-translation-gaps-20261013.md` 未走,不标 resolved) +- 首次发现 / 最近更新:2026-10-13 / 2026-10-13 +- 来源:issue #53。任务书在 `941b06c19` 重跑虚构日盘:附录之前英文功能词 218 处、汉字与英文粘连 14 处。 +- 现象:中文报告里出现 listed、background、native、Custom condition met,以及「木星Jupiter…」这种中英粘在一起的字。星宿、瑜伽名放在括号里是允许的。 +- 根因:中文完整数据版是在英文原文上做短词替换。短词先换会把长句切碎;有的格子本身就是英文枚举,中文版原样印出。瑜伽组合在中文路径仍优先取了英文组合句。行星中文名已经带英文,庙旺又紧挨着拼上去,中间没有空格。 +- 修复:中文路径先整句、长词,再短词。宫主状态换成「当前运行 / 背景」,listed 换成「已列出」,native 换成「本命」,自定义条件换成「满足自定义条件」。中文瑜伽用中文组合句。不改行星中文名本身,也不改八分法引擎文件;报告层把粘在一起的方法名改成带空格的读法。残留门只数附录之前的正文,图盘围栏不计入:汉字与至少 3 个拉丁字母直接粘连为 0,功能词 of/in/the/and/by/from/with/listed/background/native/condition/met/satisfied/occupied 为 0。括号里的梵文和表头缩写 SAV、BAV、KP、D1–D60 不在这两项里。 +- 验证:故意写入「木星Jupiterexalted」时残留门为 fail。虚构日盘、虚构夜盘、一张公开名人盘(爱因斯坦)的中文完整数据版都是粘连 0、功能词 0。`tests/test_report_chart_blank_columns.py` 16 通过。 +- 防复发:`_pl9_markdown_hygiene_receipt(language="zh")` 把上述两项写成违规。 +- 相关记录:BUG-1313、BUG-1314。 +- 复发自:无。 +- 修复版本:分支 `codex/report-translation-gaps-20261013`,尚未合入 staging。 + +## BUG-1313 | 完整数据版「本命与分盘北印度图盘」只有空标题,正文不画图 + +- 状态:fixed-pending-verify(旧报告正文不变,须重新生成;真机清单未走,不标 resolved) +- 首次发现 / 最近更新:2026-10-13 / 2026-10-13 +- 来源:issue #53。 +- 现象:该节是一列盘名,没有北印度方形图。报告末尾因此仍出现第二遍「分盘核对」。 +- 根因:完整数据版只写空的小标题,不写图盘围栏。10-07 个人报告改用完整数据版之后,BUG-1203「正文画全分盘、末尾整段消失」的前提没了。当时的测试只用读者版样例,没拦住这次切换。 +- 修复:这一节里每张有星座可画的盘写一张北印度图,同一编号只画一次。去掉与九分盘重复的第二张,以及画不出来的空宫位标题。逆行跟本命。中英标题都有。末尾「分盘核对」仍用原来的去重,不新做折叠。旧样例保留,用来锁住「旧正文仍显示分盘核对」。 +- 验证:虚构日盘中英两版该节围栏可解析、版式为北印度、编号不重复、没有空标题。新的完整数据样例覆盖计算图全部编号时,末尾核对段渲染为空。前端相关测试 39 通过、0 失败、0 取消。 +- 防复发:`tests/test_report_chart_blank_columns.py::test_full_data_chart_section_draws_each_ready_chart_once`;`frontend/tests/report-calculation-charts.test.tsx` 用真实引擎输出的新样例锁住末尾消失,旧样例仍锁住旧正文保留该节。 +- 相关记录:BUG-1203、BUG-1312。 +- 复发自:BUG-1203(完整数据版切换后正文无围栏;当时只用读者版样例)。 +- 修复版本:分支 `codex/report-translation-gaps-20261013`,尚未合入 staging。 + +## BUG-1314 | 报告「本命盘行星原始位置」没有上升行 + +- 状态:fixed-pending-verify(真机清单未走,不标 resolved) +- 首次发现 / 最近更新:2026-10-13 / 2026-10-13 +- 来源:issue #53。星盘页上升行已由 BUG-1201 补上星宿、宿主、pada;报告这张表没有。 +- 现象:报告本命位置表从九曜开始,看不到上升的星座、度数、星宿和 pada。 +- 根因:表只遍历九曜。上升点上的星宿字段已经算好,报告没用。 +- 修复:中文表首行写「上升」,英文写 Ascendant。宫位为 1,星宿用「中文(梵文)」,pada 与星宿计算一致。主星表上升行的尊贵状态写「不适用」(英文 not applicable),星宿主用星宿主星。不给上升另造庙旺。 +- 偏离:任务书要求逆行和速度两格写横杠。完整数据版原有的空格清理会把单独的横杠格改成「未列」(英文 not listed),和别的空格子一样。主星表里相邻的两个空格,后一格仍会留下一条横杠。尊贵状态保持「不适用」。测试不要求必须看见那条横杠。 +- 验证:虚构日盘上升行的星宿、pada、宫位 1、星宿主与星宿计算一致;尊贵状态为「不适用」。同文件既有用例仍通过(16 通过)。 +- 防复发:`test_birth_position_table_starts_with_the_ascendant`。 +- 相关记录:BUG-1201、BUG-1099。 +- 复发自:无。 +- 修复版本:分支 `codex/report-translation-gaps-20261013`,尚未合入 staging。 + +## BUG-1315 | 星盘页 D9「同位」列几乎全是横杠,读起来像没算 + +- 状态:fixed-pending-verify(真机清单第 7 步未走,不标 resolved) +- 首次发现 / 最近更新:2026-10-13 / 2026-10-13 +- 来源:issue #53。庙旺列已由 BUG-1202 修好;这一列不是。 +- 现象:D9 表「同位」列里,不是同座的行星显示「—」。大多数行星都不是同座,整列几乎都是横杠。 +- 根因:横杠表示「不是同位」,和「这一格没数据」长得一样。 +- 决策:按任务书 D2 的推荐执行。同座写「是」,不同座写「否」,表头仍是「同位」。不改 BUG-1099:不是 D9 就不显示这一列;旧缓存没有能力声明时整列隐藏。 +- 修复:行星行和上升行都改成「是 / 否」。`frontend/DESIGN.md` 同步。缺星宿、庙旺、宫位时别处仍用横杠,本轮没改。 +- 验证:`frontend/tests/chart-varga-table.test.tsx` 断言三栏——原值:同位格「同位」、非同位「—」;新值:「是」「否」;原因:BUG-1315。另加「非同位行显示否」和「非 D9 没有同位列」。`chart-page-hook` 里表头「同位」的检查仍在。前端这三份测试 39 通过、0 失败、0 取消。`tsc --noEmit` 退出码 0。 +- 防复发:同上前端测试。 +- 相关记录:BUG-1099、BUG-1202。 +- 复发自:无。 +- 修复版本:分支 `codex/report-translation-gaps-20261013`,尚未合入 staging。 + diff --git a/docs/tasks/PROGRESS-report-translation-gaps-20261013.md b/docs/tasks/PROGRESS-report-translation-gaps-20261013.md new file mode 100644 index 00000000..6a37bd65 --- /dev/null +++ b/docs/tasks/PROGRESS-report-translation-gaps-20261013.md @@ -0,0 +1,33 @@ +# PROGRESS · 报告翻译缺口 · 2026-10-13 + +任务书:`docs/tasks/TASK-report-translation-gaps-20261013.md`。Issue #53。执行分支 `codex/report-translation-gaps-20261013`,基于当时的 `origin/staging` `05f880053`(任务书基线 `941b06c19` 的后代)。D1、D2 按任务书推荐执行:图盘并入正文,同位列写「是 / 否」。不需要另请拍板。 + +## 状态一览 + +| 任务 | 状态 | 说明 | +| --- | --- | --- | +| T1 正文图盘 | 完成 | 有星座可画的盘各一张北印度图,编号不重复;去掉重复的九分盘和画不出的空宫位标题 | +| T2 中文残留 | 完成 | 虚构日盘、虚构夜盘、公开名人盘(爱因斯坦)粘连 0、功能词 0。基线是粘连 14、功能词 218。未让步 | +| T3 上升行 | 完成 | 位置表首行是上升;主星表尊贵状态「不适用」 | +| T4 同位列 | 完成 | D9 写「是 / 否」,表头仍是「同位」;非 D9 无此列 | +| T5 记录 | 完成 | BUG-1312~1315、本文件、CHANGELOG。真机清单在基线上已有,步骤与实现一致,未改写 | + +## 偏离 + +- 上升行的逆行、速度,任务书写横杠。完整数据版原有清理会把单独的横杠格改成「未列」(英文 not listed),与其它空格相同。主星表相邻两个空格里,后一格仍留下一条横杠。尊贵状态仍是「不适用」。测试不把那条横杠当成必须出现。 +- `next build` 与首屏 gzip 未跑。任务书 §8 与执行提示把全量前端测试和 Python 快速门留给验收侧;本轮自测不含这两项,不写成通过。 +- `test:db` 未跑:没有改数据库。 +- 真机清单 `docs/testing/report-translation-gaps-20261013.md` 已在分支基线上,八步与当前行为一致,本轮没有改它,也没有往 `BLOCKED.md` 加浏览器项。 + +## 自测 + +| 检查 | 命令 | 结果 | +| --- | --- | --- | +| 类型 | `frontend\node_modules\.bin\tsc --noEmit -p frontend` | 退出码 0 | +| 规范 | 在 `frontend` 下 `npm run lint` | 退出码 0;0 error,125 条既有 warning | +| 改到的前端测试 | `node node_modules/tsx/dist/cli.mjs --test tests/chart-varga-table.test.tsx tests/chart-page-hook.test.ts tests/report-calculation-charts.test.tsx` | 39 通过,0 失败,0 取消 | +| 图盘 / 上升 / 残留 | `.venv\Scripts\python -m pytest tests/test_report_chart_blank_columns.py -q --tb=line` | 16 通过,退出码 0 | +| 英文版、附录、读者版、星盘表合同、完整数据修复、图盘围栏 | `.venv\Scripts\python -m pytest tests/test_report_english_edition.py tests/test_reader_appendix_language.py tests/test_reader_appendix_shared_rules.py tests/test_report_reader_main.py tests/test_chart_page_vedic_tables_contract.py tests/test_report_full_data_fix.py tests/test_report_chart_block.py -q --tb=line` | 88 通过,退出码 0 | +| 隐私标记 | `.venv\Scripts\python -m pytest tests/test_repo_privacy_markers.py -q --tb=line` | 63 通过,退出码 0 | + +未跑:前端全量 `npm test`、Python 快速门、`npm run test:db`、`next build`。 diff --git a/frontend/DESIGN.md b/frontend/DESIGN.md index d9074fc8..33413422 100644 --- a/frontend/DESIGN.md +++ b/frontend/DESIGN.md @@ -1183,7 +1183,7 @@ D40 / D45 / D60 的表格上方,出生时间不是「已校正」时多一句 | 盘型 | 列 | 说明 | | --- | --- | --- | | 本命 | 上面八列 | 不变(与基线渲染逐字节相同) | -| D2–D60 | 行星 · 分盘星座(度°分′)· 宫位 · 本命星座 · 庙旺;仅 D9 再有同位 | 宫位从该分盘上升数;庙旺是引擎给的十档(入旺 / 本垣 / 入庙 / 极友 / 入友 / 中性 / 入敌 / 极敌 / 落陷 / 落陷取消),措辞与本命「状态」列一字不差(2026-10-03,BUG-1202,取代原先「入旺 / 自宫 / 落陷,其余—」的三档);旧缓存没有引擎等级时整列不显示,页面不自算;上升此格「不适用」。2026-09-29 收口:仅 D9 的 D1↔D9 同座比较显示为同位,其他分盘不显示此列。两列各由服务端能力声明控制,缺声明保守隐藏,不以是否命中推断支持性。**没有星宿 / 宿主 / 足**:那是本命经度的属性。逆行在行星格后标「逆」(分盘不改顺逆)。首行是分盘上升 | +| D2–D60 | 行星 · 分盘星座(度°分′)· 宫位 · 本命星座 · 庙旺;仅 D9 再有同位 | 宫位从该分盘上升数;庙旺是引擎给的十档(入旺 / 本垣 / 入庙 / 极友 / 入友 / 中性 / 入敌 / 极敌 / 落陷 / 落陷取消),措辞与本命「状态」列一字不差(2026-10-03,BUG-1202,取代原先「入旺 / 自宫 / 落陷,其余—」的三档);旧缓存没有引擎等级时整列不显示,页面不自算;上升此格「不适用」。2026-09-29 收口:仅 D9 的 D1↔D9 同座比较显示此列,其他分盘不显示。2026-10-13:同座写「是」,不同座写「否」,表头仍是「同位」(不再用横杠,避免看成没算)。两列各由服务端能力声明控制,缺声明保守隐藏,不以是否命中推断支持性。**没有星宿 / 宿主 / 足**:那是本命经度的属性。逆行在行星格后标「逆」(分盘不改顺逆)。首行是分盘上升 | | 月亮盘 | 本命八列 | 宫位从月亮所在星座数;表头「月亮盘 · 以月亮所在星座(X)为第 1 宫」;盘上「As」画在本命上升落的那一宫(`VedicChartSvg` 的 `ascendantHouse`,其它盘默认 1 宫不变) | | Bhava | 行星 · 黄道经度 · 星座宫 · Bhava 宫 · 换宫;另一张「宫 · 宫头 · 起点(sandhi)」12 行 | Sripati。换宫的行用 `--color-selected` 浅底。拿不到真实 MC 时这一栏走失败句,不画等宫(BUG-1077) | | 行运 | 行星 · 今天的位置 · 速度 · 落本命 · 本命同星 | 表头写计算时刻「行运 · YYYY-MM-DD 12:00(时区)」,上方一句「以本命上升为第 1 宫,放的是这一天中午的行星位置。岁差和交点与本命相同。」 | diff --git a/frontend/src/components/chart-page/chart-vedic-tab.tsx b/frontend/src/components/chart-page/chart-vedic-tab.tsx index c02cd5e5..3a768db5 100644 --- a/frontend/src/components/chart-page/chart-vedic-tab.tsx +++ b/frontend/src/components/chart-page/chart-vedic-tab.tsx @@ -152,7 +152,7 @@ function VargaRow({ row, supportsDignity, supportsVargottama }: { row: ChartView {row.house}宫 {row.natalSignLabel} {supportsDignity && {row.dignity ? VARGA_DIGNITY_LABEL[row.dignity] : "—"}} - {supportsVargottama && {row.vargottama ? "同位" : "—"}} + {supportsVargottama && {row.vargottama ? "是" : "否"}} ); } @@ -167,7 +167,7 @@ function VargaAscendantRow({ row, supportsDignity, supportsVargottama }: { row: 1宫 {row.natalSignLabel} {supportsDignity && 不适用} - {supportsVargottama && {row.vargottama ? "同位" : "—"}} + {supportsVargottama && {row.vargottama ? "是" : "否"}} ); } diff --git a/frontend/tests/chart-varga-table.test.tsx b/frontend/tests/chart-varga-table.test.tsx index 829ed4e4..12451038 100644 --- a/frontend/tests/chart-varga-table.test.tsx +++ b/frontend/tests/chart-varga-table.test.tsx @@ -138,7 +138,11 @@ test("divisional rows carry engine dignity and vargottama, and drop nakshatra co for (const column of ["行星", "分盘星座", "宫位", "本命星座", "庙旺", "同位"]) assert.match(header, new RegExp(`>${column}<`)); assert.doesNotMatch(header, /星宿|宿主|pada/); // Same wording as the D1 status column (BUG-1202), friendship levels included. - assert.match(row(markup, "土星"), />入庙\(Own Sign\)<[\s\S]*>同位入庙\(Own Sign\)<[\s\S]*>是否落陷\(Debilitated\)入友\(Friendly Sign\)中性\(Neutral\) { + const view = await vargaView(); + const d9 = render(view, "D9"); + assert.match(row(d9, "太阳"), />否 item.id === "D10")!; + assert.equal(d10.supportsVargottama, false); + const markup = tableMarkup(d10); + assert.doesNotMatch(markup, />同位否 { const view = await vargaView(); for (const varga of view.vedic.vargas) { diff --git a/frontend/tests/fixtures/report-full-data-chart-fences.json b/frontend/tests/fixtures/report-full-data-chart-fences.json new file mode 100644 index 00000000..c290791f --- /dev/null +++ b/frontend/tests/fixtures/report-full-data-chart-fences.json @@ -0,0 +1,2857 @@ +{ + "fixtureProvenance": { + "fictional": true, + "sourceCommand": "PYTHONPATH=.:scripts python -c \"from tests.test_report_english_edition import CASES, _packet; from scripts.pl9_reader_export import _pl9_export_markdown_for_edition\"", + "note": "Fictional day chart from tests/test_report_english_edition.py CASES[day], full_data edition, chart section only." + }, + "markdown": "### 本命与分盘北印度图盘\n\n分盘对出生时间敏感,原始计算供核对,不单独增加结论的确定性。\n\n##### D1 本命盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D1\",\"title\":\"D1 本命盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Taurus\",\"degree\":8.85},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Pisces\",\"degree\":22.99,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Sagittarius\",\"degree\":20.5,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Gemini\",\"degree\":8.4,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Aries\",\"degree\":4.99,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Cancer\",\"degree\":9.9,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Aries\",\"degree\":29.22,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Capricorn\",\"degree\":11.82,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Capricorn\",\"degree\":0.31,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":0.31,\"retrograde\":true}]}\n```\n\n##### 月亮盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"MOON\",\"title\":\"月亮盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Sagittarius\",\"degree\":20.5},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Pisces\",\"degree\":22.99,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Sagittarius\",\"degree\":20.5,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Gemini\",\"degree\":8.4,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Aries\",\"degree\":4.99,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Cancer\",\"degree\":9.9,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Aries\",\"degree\":29.22,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Capricorn\",\"degree\":11.82,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Capricorn\",\"degree\":0.31,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":0.31,\"retrograde\":true}]}\n```\n\n##### D2 财富分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D2\",\"title\":\"D2 财富分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Cancer\",\"degree\":17.7},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Leo\",\"degree\":15.98,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Cancer\",\"degree\":11.0,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Leo\",\"degree\":16.8,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Leo\",\"degree\":9.98,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Cancer\",\"degree\":19.8,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Cancer\",\"degree\":28.45,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Cancer\",\"degree\":23.64,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Cancer\",\"degree\":0.62,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":0.62,\"retrograde\":true}]}\n```\n\n##### D3 手足分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D3\",\"title\":\"D3 手足分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Taurus\",\"degree\":26.55},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Scorpio\",\"degree\":8.97,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Leo\",\"degree\":1.49,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Gemini\",\"degree\":25.2,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Aries\",\"degree\":14.97,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Cancer\",\"degree\":29.7,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Sagittarius\",\"degree\":27.67,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Taurus\",\"degree\":5.46,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Capricorn\",\"degree\":0.93,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":0.93,\"retrograde\":true}]}\n```\n\n##### D4 居所分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D4\",\"title\":\"D4 居所分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Leo\",\"degree\":5.4},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Sagittarius\",\"degree\":1.96,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Gemini\",\"degree\":21.99,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Virgo\",\"degree\":3.59,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Aries\",\"degree\":19.96,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Libra\",\"degree\":9.59,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Capricorn\",\"degree\":26.89,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Aries\",\"degree\":17.27,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Capricorn\",\"degree\":1.23,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":1.23,\"retrograde\":true}]}\n```\n\n##### D5 声望分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D5\",\"title\":\"D5 声望分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Virgo\",\"degree\":14.26},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Capricorn\",\"degree\":24.95,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Gemini\",\"degree\":12.49,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Aquarius\",\"degree\":11.99,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Aries\",\"degree\":24.94,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Virgo\",\"degree\":19.49,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Libra\",\"degree\":26.12,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Virgo\",\"degree\":29.09,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Taurus\",\"degree\":1.54,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Taurus\",\"degree\":1.54,\"retrograde\":true}]}\n```\n\n##### D6 压力分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D6\",\"title\":\"D6 压力分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Scorpio\",\"degree\":23.11},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Aquarius\",\"degree\":17.94,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Leo\",\"degree\":2.99,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Taurus\",\"degree\":20.39,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Aries\",\"degree\":29.93,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Scorpio\",\"degree\":29.39,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Virgo\",\"degree\":25.34,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Sagittarius\",\"degree\":10.91,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Libra\",\"degree\":1.85,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Libra\",\"degree\":1.85,\"retrograde\":true}]}\n```\n\n##### D7 子女分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D7\",\"title\":\"D7 子女分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Capricorn\",\"degree\":1.96},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Aquarius\",\"degree\":10.93,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Aries\",\"degree\":23.48,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Cancer\",\"degree\":28.79,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Taurus\",\"degree\":4.92,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Pisces\",\"degree\":9.29,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Libra\",\"degree\":24.56,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Virgo\",\"degree\":22.73,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Cancer\",\"degree\":2.16,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Capricorn\",\"degree\":2.16,\"retrograde\":true}]}\n```\n\n##### D8 变化分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D8\",\"title\":\"D8 变化分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Aquarius\",\"degree\":10.81},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Aquarius\",\"degree\":3.92,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Capricorn\",\"degree\":13.98,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Libra\",\"degree\":7.19,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Taurus\",\"degree\":9.91,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Gemini\",\"degree\":19.19,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Scorpio\",\"degree\":23.79,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Cancer\",\"degree\":4.55,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Aries\",\"degree\":2.47,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Aries\",\"degree\":2.47,\"retrograde\":true}]}\n```\n\n##### D9 九分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D9\",\"title\":\"D9 九分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Pisces\",\"degree\":19.66},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Capricorn\",\"degree\":26.91,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Libra\",\"degree\":4.48,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Sagittarius\",\"degree\":15.59,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Taurus\",\"degree\":14.9,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Virgo\",\"degree\":29.09,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Sagittarius\",\"degree\":23.01,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Aries\",\"degree\":16.37,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Capricorn\",\"degree\":2.78,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":2.78,\"retrograde\":true}]}\n```\n\n##### D10 事业分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D10\",\"title\":\"D10 事业分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Pisces\",\"degree\":28.51},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Gemini\",\"degree\":19.9,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Gemini\",\"degree\":24.98,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Leo\",\"degree\":23.99,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Taurus\",\"degree\":19.89,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Gemini\",\"degree\":8.99,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Capricorn\",\"degree\":22.23,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Sagittarius\",\"degree\":28.19,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Virgo\",\"degree\":3.09,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Pisces\",\"degree\":3.09,\"retrograde\":true}]}\n```\n\n##### D11 收益分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D11\",\"title\":\"D11 收益分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Gemini\",\"degree\":7.36},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Capricorn\",\"degree\":12.89,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Pisces\",\"degree\":15.48,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Taurus\",\"degree\":2.38,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Taurus\",\"degree\":24.88,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Aries\",\"degree\":18.89,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Aquarius\",\"degree\":21.46,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Scorpio\",\"degree\":10.0,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Cancer\",\"degree\":3.4,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Capricorn\",\"degree\":3.4,\"retrograde\":true}]}\n```\n\n##### D12 父母分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D12\",\"title\":\"D12 父母分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Leo\",\"degree\":16.21},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Sagittarius\",\"degree\":5.88,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Leo\",\"degree\":5.97,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Virgo\",\"degree\":10.78,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Taurus\",\"degree\":29.87,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Libra\",\"degree\":28.78,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Pisces\",\"degree\":20.68,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Taurus\",\"degree\":21.82,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Capricorn\",\"degree\":3.7,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":3.7,\"retrograde\":true}]}\n```\n\n##### D16 享受分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D16\",\"title\":\"D16 享受分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Sagittarius\",\"degree\":21.62},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Leo\",\"degree\":7.84,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Aquarius\",\"degree\":27.97,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Leo\",\"degree\":14.38,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Gemini\",\"degree\":19.82,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Capricorn\",\"degree\":8.38,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Cancer\",\"degree\":17.57,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Aquarius\",\"degree\":9.1,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Leo\",\"degree\":4.94,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Leo\",\"degree\":4.94,\"retrograde\":true}]}\n```\n\n##### D20 灵修分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D20\",\"title\":\"D20 灵修分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Taurus\",\"degree\":27.02},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Pisces\",\"degree\":9.8,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Taurus\",\"degree\":19.96,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Virgo\",\"degree\":17.97,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Cancer\",\"degree\":9.78,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Gemini\",\"degree\":17.97,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Scorpio\",\"degree\":14.46,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Cancer\",\"degree\":26.37,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Sagittarius\",\"degree\":6.17,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Sagittarius\",\"degree\":6.17,\"retrograde\":true}]}\n```\n\n##### D24 学习分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D24\",\"title\":\"D24 学习分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Aquarius\",\"degree\":2.42},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Capricorn\",\"degree\":11.77,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Sagittarius\",\"degree\":11.95,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Aquarius\",\"degree\":21.57,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Scorpio\",\"degree\":29.73,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Aquarius\",\"degree\":27.57,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Cancer\",\"degree\":11.36,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Aries\",\"degree\":13.65,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Cancer\",\"degree\":7.41,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Cancer\",\"degree\":7.41,\"retrograde\":true}]}\n```\n\n##### D27 内在分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D27\",\"title\":\"D27 内在分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Taurus\",\"degree\":28.98},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Gemini\",\"degree\":20.74,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Libra\",\"degree\":13.44,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Scorpio\",\"degree\":16.76,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Leo\",\"degree\":14.7,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Gemini\",\"degree\":27.27,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Gemini\",\"degree\":9.03,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Leo\",\"degree\":19.1,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Libra\",\"degree\":8.33,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Libra\",\"degree\":8.33,\"retrograde\":true}]}\n```\n\n##### D30 困难分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D30\",\"title\":\"D30 困难分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Virgo\",\"degree\":25.53},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Scorpio\",\"degree\":29.71,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Gemini\",\"degree\":14.93,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Aquarius\",\"degree\":11.96,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Aries\",\"degree\":29.67,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Virgo\",\"degree\":26.96,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Libra\",\"degree\":6.7,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Virgo\",\"degree\":24.56,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Taurus\",\"degree\":9.26,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Taurus\",\"degree\":9.26,\"retrograde\":true}]}\n```\n\n##### D40 母系分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D40\",\"title\":\"D40 母系分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Virgo\",\"degree\":24.04},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Aries\",\"degree\":19.61,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Cancer\",\"degree\":9.91,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Pisces\",\"degree\":5.94,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Libra\",\"degree\":19.56,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Scorpio\",\"degree\":5.95,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Gemini\",\"degree\":28.93,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Capricorn\",\"degree\":22.75,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Libra\",\"degree\":12.35,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Libra\",\"degree\":12.35,\"retrograde\":true}]}\n```\n\n##### D45 父系分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D45\",\"title\":\"D45 父系分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Scorpio\",\"degree\":8.29},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Leo\",\"degree\":14.56,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Libra\",\"degree\":22.4,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Aries\",\"degree\":17.94,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Scorpio\",\"degree\":14.5,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Sagittarius\",\"degree\":25.44,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Scorpio\",\"degree\":25.05,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Pisces\",\"degree\":21.84,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Libra\",\"degree\":13.89,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Libra\",\"degree\":13.89,\"retrograde\":true}]}\n```\n\n##### D60 深层分盘\n\n```jyotish-chart\n{\"version\":1,\"id\":\"D60\",\"title\":\"D60 深层分盘\",\"layout\":\"north\",\"ascendant\":{\"sign\":\"Scorpio\",\"degree\":21.06},\"planets\":[{\"name\":\"Sun\",\"sign\":\"Capricorn\",\"degree\":29.41,\"retrograde\":false},{\"name\":\"Moon\",\"sign\":\"Aries\",\"degree\":29.87,\"retrograde\":false},{\"name\":\"Mars\",\"sign\":\"Libra\",\"degree\":23.92,\"retrograde\":false},{\"name\":\"Mercury\",\"sign\":\"Capricorn\",\"degree\":29.34,\"retrograde\":true},{\"name\":\"Jupiter\",\"sign\":\"Pisces\",\"degree\":23.92,\"retrograde\":false},{\"name\":\"Venus\",\"sign\":\"Aquarius\",\"degree\":13.39,\"retrograde\":false},{\"name\":\"Saturn\",\"sign\":\"Capricorn\",\"degree\":19.12,\"retrograde\":false},{\"name\":\"Rahu\",\"sign\":\"Aquarius\",\"degree\":18.52,\"retrograde\":true},{\"name\":\"Ketu\",\"sign\":\"Leo\",\"degree\":18.52,\"retrograde\":true}]}\n```\n\n#### D1 Rashi 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 太阳 | 双鱼座 | 22.99° | 352.99° | 11 |\n| 月亮 | 射手座 | 20.50° | 260.50° | 8 |\n| 火星 | 双子座 | 8.40° | 68.40° | 2 |\n| 水星 | 白羊座 | 4.99° | 4.99° | 12 |\n| 木星 | 巨蟹座 | 9.90° | 99.90° | 3 |\n| 金星 | 白羊座 | 29.22° | 29.22° | 12 |\n| 土星 | 摩羯座 | 11.82° | 281.82° | 9 |\n| 北交点 | 摩羯座 | 0.31° | 270.31° | 9 |\n| 南交点 | 巨蟹座 | 0.31° | 90.31° | 3 |\n\n#### D2 Hora 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 巨蟹座 | 17.70° | 107.70° | 1 |\n| 太阳 | 狮子座 | 15.98° | 135.98° | 2 |\n| 月亮 | 巨蟹座 | 11.00° | 101.00° | 1 |\n| 火星 | 狮子座 | 16.80° | 136.80° | 2 |\n| 水星 | 狮子座 | 9.98° | 129.98° | 2 |\n| 木星 | 巨蟹座 | 19.80° | 109.80° | 1 |\n| 金星 | 巨蟹座 | 28.45° | 118.45° | 1 |\n| 土星 | 巨蟹座 | 23.64° | 113.64° | 1 |\n| 北交点 | 巨蟹座 | 0.62° | 90.62° | 1 |\n| 南交点 | 巨蟹座 | 0.62° | 90.62° | 1 |\n\n#### D3 Drekkana 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 金牛座 | 26.55° | 56.55° | 1 |\n| 太阳 | 天蝎座 | 8.97° | 218.97° | 7 |\n| 月亮 | 狮子座 | 1.49° | 121.49° | 4 |\n| 火星 | 双子座 | 25.20° | 85.20° | 2 |\n| 水星 | 白羊座 | 14.97° | 14.97° | 12 |\n| 木星 | 巨蟹座 | 29.70° | 119.70° | 3 |\n| 金星 | 射手座 | 27.67° | 267.67° | 8 |\n| 土星 | 金牛座 | 5.46° | 35.46° | 1 |\n| 北交点 | 摩羯座 | 0.93° | 270.93° | 9 |\n| 南交点 | 巨蟹座 | 0.93° | 90.93° | 3 |\n\n#### D4 Turyamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 狮子座 | 5.40° | 125.40° | 1 |\n| 太阳 | 射手座 | 1.96° | 241.96° | 5 |\n| 月亮 | 双子座 | 21.99° | 81.99° | 11 |\n| 火星 | 处女座 | 3.59° | 153.59° | 2 |\n| 水星 | 白羊座 | 19.96° | 19.96° | 9 |\n| 木星 | 天秤座 | 9.59° | 189.59° | 3 |\n| 金星 | 摩羯座 | 26.89° | 296.89° | 6 |\n| 土星 | 白羊座 | 17.27° | 17.27° | 9 |\n| 北交点 | 摩羯座 | 1.23° | 271.23° | 6 |\n| 南交点 | 巨蟹座 | 1.23° | 91.23° | 12 |\n\n#### D5 Panchamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 处女座 | 14.26° | 164.25° | 1 |\n| 太阳 | 摩羯座 | 24.95° | 294.95° | 5 |\n| 月亮 | 双子座 | 12.49° | 72.49° | 10 |\n| 火星 | 水瓶座 | 11.99° | 311.99° | 6 |\n| 水星 | 白羊座 | 24.94° | 24.94° | 8 |\n| 木星 | 处女座 | 19.49° | 169.49° | 1 |\n| 金星 | 天秤座 | 26.12° | 206.12° | 2 |\n| 土星 | 处女座 | 29.09° | 179.09° | 1 |\n| 北交点 | 金牛座 | 1.54° | 31.54° | 9 |\n| 南交点 | 金牛座 | 1.54° | 31.54° | 9 |\n\n#### D6 Shashthamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 天蝎座 | 23.11° | 233.11° | 1 |\n| 太阳 | 水瓶座 | 17.94° | 317.94° | 4 |\n| 月亮 | 狮子座 | 2.99° | 122.99° | 10 |\n| 火星 | 金牛座 | 20.39° | 50.39° | 7 |\n| 水星 | 白羊座 | 29.93° | 29.93° | 6 |\n| 木星 | 天蝎座 | 29.39° | 239.39° | 1 |\n| 金星 | 处女座 | 25.34° | 175.34° | 11 |\n| 土星 | 射手座 | 10.91° | 250.91° | 2 |\n| 北交点 | 天秤座 | 1.85° | 181.85° | 12 |\n| 南交点 | 天秤座 | 1.85° | 181.85° | 12 |\n\n#### D7 Saptamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 摩羯座 | 1.96° | 271.96° | 1 |\n| 太阳 | 水瓶座 | 10.93° | 310.93° | 2 |\n| 月亮 | 白羊座 | 23.48° | 23.48° | 4 |\n| 火星 | 巨蟹座 | 28.79° | 118.79° | 7 |\n| 水星 | 金牛座 | 4.92° | 34.92° | 5 |\n| 木星 | 双鱼座 | 9.29° | 339.29° | 3 |\n| 金星 | 天秤座 | 24.56° | 204.56° | 10 |\n| 土星 | 处女座 | 22.73° | 172.73° | 9 |\n| 北交点 | 巨蟹座 | 2.16° | 92.16° | 7 |\n| 南交点 | 摩羯座 | 2.16° | 272.16° | 1 |\n\n#### D8 Ashtamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 水瓶座 | 10.81° | 310.81° | 1 |\n| 太阳 | 水瓶座 | 3.92° | 303.92° | 1 |\n| 月亮 | 摩羯座 | 13.98° | 283.98° | 12 |\n| 火星 | 天秤座 | 7.19° | 187.19° | 9 |\n| 水星 | 金牛座 | 9.91° | 39.91° | 4 |\n| 木星 | 双子座 | 19.19° | 79.19° | 5 |\n| 金星 | 天蝎座 | 23.79° | 233.79° | 10 |\n| 土星 | 巨蟹座 | 4.55° | 94.55° | 6 |\n| 北交点 | 白羊座 | 2.47° | 2.47° | 3 |\n| 南交点 | 白羊座 | 2.47° | 2.47° | 3 |\n\n#### D9 九分盘 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 双鱼座 | 19.66° | 349.66° | 1 |\n| 太阳 | 摩羯座 | 26.91° | 296.91° | 11 |\n| 月亮 | 天秤座 | 4.48° | 184.48° | 8 |\n| 火星 | 射手座 | 15.59° | 255.59° | 10 |\n| 水星 | 金牛座 | 14.90° | 44.90° | 3 |\n| 木星 | 处女座 | 29.09° | 179.09° | 7 |\n| 金星 | 射手座 | 23.01° | 263.01° | 10 |\n| 土星 | 白羊座 | 16.37° | 16.37° | 2 |\n| 北交点 | 摩羯座 | 2.78° | 272.78° | 11 |\n| 南交点 | 巨蟹座 | 2.78° | 92.78° | 5 |\n\n#### D10 Dasamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 双鱼座 | 28.51° | 358.51° | 1 |\n| 太阳 | 双子座 | 19.90° | 79.90° | 4 |\n| 月亮 | 双子座 | 24.98° | 84.98° | 4 |\n| 火星 | 狮子座 | 23.99° | 143.99° | 6 |\n| 水星 | 金牛座 | 19.89° | 49.89° | 3 |\n| 木星 | 双子座 | 8.99° | 68.99° | 4 |\n| 金星 | 摩羯座 | 22.23° | 292.23° | 11 |\n| 土星 | 射手座 | 28.19° | 268.19° | 10 |\n| 北交点 | 处女座 | 3.09° | 153.09° | 7 |\n| 南交点 | 双鱼座 | 3.09° | 333.09° | 1 |\n\n#### D11 Rudramsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 双子座 | 7.36° | 67.36° | 1 |\n| 太阳 | 摩羯座 | 12.89° | 282.89° | 8 |\n| 月亮 | 双鱼座 | 15.48° | 345.48° | 10 |\n| 火星 | 金牛座 | 2.38° | 32.38° | 12 |\n| 水星 | 金牛座 | 24.88° | 54.88° | 12 |\n| 木星 | 白羊座 | 18.89° | 18.89° | 11 |\n| 金星 | 水瓶座 | 21.46° | 321.46° | 9 |\n| 土星 | 天蝎座 | 10.00° | 220.00° | 6 |\n| 北交点 | 巨蟹座 | 3.40° | 93.40° | 2 |\n| 南交点 | 摩羯座 | 3.40° | 273.40° | 8 |\n\n#### D12 Dwadashamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 狮子座 | 16.21° | 136.21° | 1 |\n| 太阳 | 射手座 | 5.88° | 245.88° | 5 |\n| 月亮 | 狮子座 | 5.97° | 125.97° | 1 |\n| 火星 | 处女座 | 10.78° | 160.78° | 2 |\n| 水星 | 金牛座 | 29.87° | 59.87° | 10 |\n| 木星 | 天秤座 | 28.78° | 208.78° | 3 |\n| 金星 | 双鱼座 | 20.68° | 350.68° | 8 |\n| 土星 | 金牛座 | 21.82° | 51.82° | 10 |\n| 北交点 | 摩羯座 | 3.70° | 273.70° | 6 |\n| 南交点 | 巨蟹座 | 3.70° | 93.70° | 12 |\n\n#### D16 Shodasamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 射手座 | 21.62° | 261.62° | 1 |\n| 太阳 | 狮子座 | 7.84° | 127.84° | 9 |\n| 月亮 | 水瓶座 | 27.97° | 327.97° | 3 |\n| 火星 | 狮子座 | 14.38° | 134.38° | 9 |\n| 水星 | 双子座 | 19.82° | 79.82° | 7 |\n| 木星 | 摩羯座 | 8.38° | 278.38° | 2 |\n| 金星 | 巨蟹座 | 17.57° | 107.57° | 8 |\n| 土星 | 水瓶座 | 9.10° | 309.10° | 3 |\n| 北交点 | 狮子座 | 4.94° | 124.94° | 9 |\n| 南交点 | 狮子座 | 4.94° | 124.94° | 9 |\n\n#### D20 Vimsamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 金牛座 | 27.02° | 57.02° | 1 |\n| 太阳 | 双鱼座 | 9.80° | 339.80° | 11 |\n| 月亮 | 金牛座 | 19.96° | 49.96° | 1 |\n| 火星 | 处女座 | 17.97° | 167.97° | 5 |\n| 水星 | 巨蟹座 | 9.78° | 99.78° | 3 |\n| 木星 | 双子座 | 17.97° | 77.97° | 2 |\n| 金星 | 天蝎座 | 14.46° | 224.47° | 7 |\n| 土星 | 巨蟹座 | 26.37° | 116.37° | 3 |\n| 北交点 | 射手座 | 6.17° | 246.17° | 8 |\n| 南交点 | 射手座 | 6.17° | 246.17° | 8 |\n\n#### D24 Siddhamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 水瓶座 | 2.42° | 302.42° | 1 |\n| 太阳 | 摩羯座 | 11.77° | 281.77° | 12 |\n| 月亮 | 射手座 | 11.95° | 251.95° | 11 |\n| 火星 | 水瓶座 | 21.57° | 321.57° | 1 |\n| 水星 | 天蝎座 | 29.73° | 239.73° | 10 |\n| 木星 | 水瓶座 | 27.57° | 327.57° | 1 |\n| 金星 | 巨蟹座 | 11.36° | 101.36° | 6 |\n| 土星 | 白羊座 | 13.65° | 13.65° | 3 |\n| 北交点 | 巨蟹座 | 7.41° | 97.41° | 6 |\n| 南交点 | 巨蟹座 | 7.41° | 97.41° | 6 |\n\n#### D27 Bhamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 金牛座 | 28.98° | 58.98° | 1 |\n| 太阳 | 双子座 | 20.74° | 80.74° | 2 |\n| 月亮 | 天秤座 | 13.44° | 193.44° | 6 |\n| 火星 | 天蝎座 | 16.76° | 226.76° | 7 |\n| 水星 | 狮子座 | 14.70° | 134.70° | 4 |\n| 木星 | 双子座 | 27.27° | 87.27° | 2 |\n| 金星 | 双子座 | 9.03° | 69.03° | 2 |\n| 土星 | 狮子座 | 19.10° | 139.10° | 4 |\n| 北交点 | 天秤座 | 8.33° | 188.33° | 6 |\n| 南交点 | 天秤座 | 8.33° | 188.33° | 6 |\n\n#### D30 Trimsamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 处女座 | 25.53° | 175.53° | 1 |\n| 太阳 | 天蝎座 | 29.71° | 239.71° | 3 |\n| 月亮 | 双子座 | 14.93° | 74.93° | 10 |\n| 火星 | 水瓶座 | 11.96° | 311.96° | 6 |\n| 水星 | 白羊座 | 29.67° | 29.67° | 8 |\n| 木星 | 处女座 | 26.96° | 176.96° | 1 |\n| 金星 | 天秤座 | 6.70° | 186.70° | 2 |\n| 土星 | 处女座 | 24.56° | 174.56° | 1 |\n| 北交点 | 金牛座 | 9.26° | 39.26° | 9 |\n| 南交点 | 金牛座 | 9.26° | 39.26° | 9 |\n\n#### D40 Khavedamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 处女座 | 24.04° | 174.04° | 1 |\n| 太阳 | 白羊座 | 19.61° | 19.61° | 8 |\n| 月亮 | 巨蟹座 | 9.91° | 99.91° | 11 |\n| 火星 | 双鱼座 | 5.94° | 335.94° | 7 |\n| 水星 | 天秤座 | 19.56° | 199.56° | 2 |\n| 木星 | 天蝎座 | 5.95° | 215.95° | 3 |\n| 金星 | 双子座 | 28.93° | 88.93° | 10 |\n| 土星 | 摩羯座 | 22.75° | 292.75° | 5 |\n| 北交点 | 天秤座 | 12.35° | 192.35° | 2 |\n| 南交点 | 天秤座 | 12.35° | 192.35° | 2 |\n\n#### D45 Akshavedamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 天蝎座 | 8.29° | 218.29° | 1 |\n| 太阳 | 狮子座 | 14.56° | 134.56° | 10 |\n| 月亮 | 天秤座 | 22.40° | 202.40° | 12 |\n| 火星 | 白羊座 | 17.94° | 17.94° | 6 |\n| 水星 | 天蝎座 | 14.50° | 224.50° | 1 |\n| 木星 | 射手座 | 25.44° | 265.44° | 2 |\n| 金星 | 天蝎座 | 25.05° | 235.05° | 1 |\n| 土星 | 双鱼座 | 21.84° | 351.84° | 5 |\n| 北交点 | 天秤座 | 13.89° | 193.89° | 12 |\n| 南交点 | 天秤座 | 13.89° | 193.89° | 12 |\n\n#### D60 Shashtyamsa 数值位置表\n\n| 对象 | 落座 | 落座度数 | 黄经 | 整宫宫位 |\n| ------ | ------ | ---------- | ------ | ---------- |\n| 上升 | 天蝎座 | 21.06° | 231.06° | 1 |\n| 太阳 | 摩羯座 | 29.41° | 299.41° | 3 |\n| 月亮 | 白羊座 | 29.87° | 29.87° | 6 |\n| 火星 | 天秤座 | 23.92° | 203.92° | 12 |\n| 水星 | 摩羯座 | 29.34° | 299.33° | 3 |\n| 木星 | 双鱼座 | 23.92° | 353.92° | 5 |\n| 金星 | 水瓶座 | 13.39° | 313.39° | 4 |\n| 土星 | 摩羯座 | 19.12° | 289.12° | 3 |\n| 北交点 | 水瓶座 | 18.52° | 318.52° | 4 |\n| 南交点 | 狮子座 | 18.52° | 138.52° | 10 |\n", + "packet": { + "core_chart": { + "ascendant": { + "sign": "Taurus", + "sign_cn": "金牛座", + "degree": 8.851, + "degree_raw": 38.851, + "degree_in_sign": 8.851, + "degree_in_sign_raw": 8.851045207490053, + "lon": 38.851, + "lord": "Venus", + "nakshatra": "Krittika", + "nakshatra_pada": 4, + "nakshatra_lord": "Sun" + }, + "planets": { + "Sun": { + "sign": "Pisces", + "sign_cn": "双鱼座", + "degree": 352.9902, + "degree_raw": 352.99024068125937, + "degree_in_sign": 22.9902, + "degree_in_sign_raw": 22.990240681259365, + "house": 11, + "status": "中性(Neutral)", + "retrograde": false, + "speed": 0.983816, + "nakshatra": "Revati", + "nakshatra_pada": 2, + "nakshatra_lord": "Mercury", + "lon": 352.99024068125937, + "sign_idx": 11, + "rasi_lord": "Jupiter", + "pada": 2, + "sub_lord": "Moon", + "sub_sub_lord": "Mercury", + "combust": false, + "r_c": "", + "sb": 1.45 + }, + "Moon": { + "sign": "Sagittarius", + "sign_cn": "射手座", + "degree": 260.4978, + "degree_raw": 260.4978298734044, + "degree_in_sign": 20.4978, + "degree_in_sign_raw": 20.497829873404385, + "house": 8, + "status": "入敌(Enemy Sign)", + "retrograde": false, + "speed": 11.838419, + "nakshatra": "Purva Ashadha", + "nakshatra_pada": 3, + "nakshatra_lord": "Venus", + "lon": 260.4978298734044, + "sign_idx": 8, + "rasi_lord": "Jupiter", + "pada": 3, + "sub_lord": "Jupiter", + "sub_sub_lord": "Saturn", + "combust": false, + "combustion_threshold_degrees": 12, + "r_c": "", + "sb": 1.15 + }, + "Mars": { + "sign": "Gemini", + "sign_cn": "双子座", + "degree": 68.3986, + "degree_raw": 68.39859184834907, + "degree_in_sign": 8.3986, + "degree_in_sign_raw": 8.39859184834907, + "house": 2, + "status": "中性(Neutral)", + "retrograde": false, + "speed": 0.535139, + "nakshatra": "Ardra", + "nakshatra_pada": 1, + "nakshatra_lord": "Rahu", + "lon": 68.39859184834907, + "sign_idx": 2, + "rasi_lord": "Mercury", + "pada": 1, + "sub_lord": "Rahu", + "sub_sub_lord": "Moon", + "combust": false, + "combustion_threshold_degrees": 17, + "r_c": "", + "sb": 1.1 + }, + "Mercury": { + "sign": "Aries", + "sign_cn": "白羊座", + "degree": 4.9889, + "degree_raw": 4.988916238201053, + "degree_in_sign": 4.9889, + "degree_in_sign_raw": 4.988916238201053, + "house": 12, + "status": "入友(Friendly Sign)", + "retrograde": true, + "speed": -0.251851, + "nakshatra": "Ashwini", + "nakshatra_pada": 2, + "nakshatra_lord": "Ketu", + "lon": 4.988916238201053, + "sign_idx": 0, + "rasi_lord": "Mars", + "pada": 2, + "sub_lord": "Mars", + "sub_sub_lord": "Jupiter", + "combust": true, + "combustion_threshold_degrees": 12, + "r_c": "R", + "sb": 1.28 + }, + "Jupiter": { + "sign": "Cancer", + "sign_cn": "巨蟹座", + "degree": 99.8987, + "degree_raw": 99.89871811971885, + "degree_in_sign": 9.8987, + "degree_in_sign_raw": 9.89871811971885, + "house": 3, + "status": "入旺(Exalted)", + "retrograde": false, + "speed": 0.023622, + "nakshatra": "Pushya", + "nakshatra_pada": 2, + "nakshatra_lord": "Saturn", + "lon": 99.89871811971885, + "sign_idx": 3, + "rasi_lord": "Moon", + "pada": 2, + "sub_lord": "Venus", + "sub_sub_lord": "Mercury", + "combust": false, + "combustion_threshold_degrees": 11, + "r_c": "", + "sb": 1.17 + }, + "Venus": { + "sign": "Aries", + "sign_cn": "白羊座", + "degree": 29.2232, + "degree_raw": 29.223249375854067, + "degree_in_sign": 29.2232, + "degree_in_sign_raw": 29.223249375854067, + "house": 12, + "status": "入友(Friendly Sign)", + "retrograde": false, + "speed": 1.186233, + "nakshatra": "Krittika", + "nakshatra_pada": 1, + "nakshatra_lord": "Sun", + "lon": 29.223249375854067, + "sign_idx": 0, + "rasi_lord": "Mars", + "pada": 1, + "sub_lord": "Rahu", + "sub_sub_lord": "Rahu", + "combust": false, + "combustion_threshold_degrees": 10, + "r_c": "", + "sb": 1.43 + }, + "Saturn": { + "sign": "Capricorn", + "sign_cn": "摩羯座", + "degree": 281.8186, + "degree_raw": 281.81862796658356, + "degree_in_sign": 11.8186, + "degree_in_sign_raw": 11.818627966583563, + "house": 9, + "status": "入庙(Own Sign)", + "retrograde": false, + "speed": 0.062245, + "nakshatra": "Shravana", + "nakshatra_pada": 1, + "nakshatra_lord": "Moon", + "lon": 281.81862796658356, + "sign_idx": 9, + "rasi_lord": "Saturn", + "pada": 1, + "sub_lord": "Mars", + "sub_sub_lord": "Sun", + "combust": false, + "combustion_threshold_degrees": 15, + "r_c": "", + "sb": 1.44 + }, + "Rahu": { + "sign": "Capricorn", + "sign_cn": "摩羯座", + "degree": 270.3087, + "degree_raw": 270.30868402468377, + "degree_in_sign": 0.3087, + "degree_in_sign_raw": 0.308684024683771, + "house": 9, + "status": "中性(Neutral)", + "retrograde": true, + "speed": -0.052944, + "nakshatra": "Uttara Ashadha", + "nakshatra_pada": 2, + "nakshatra_lord": "Sun", + "lon": 270.30868402468377, + "sign_idx": 9, + "rasi_lord": "Saturn", + "pada": 2, + "sub_lord": "Rahu", + "sub_sub_lord": "Mercury", + "r_c": "" + }, + "Ketu": { + "sign": "Cancer", + "sign_cn": "巨蟹座", + "degree": 90.3087, + "degree_raw": 90.30868402468377, + "degree_in_sign": 0.3087, + "degree_in_sign_raw": 0.308684024683771, + "house": 3, + "status": "极敌(Great Enemy)", + "retrograde": true, + "speed": -0.052944, + "nakshatra": "Punarvasu", + "nakshatra_pada": 4, + "nakshatra_lord": "Jupiter", + "lon": 90.30868402468377, + "sign_idx": 3, + "rasi_lord": "Moon", + "pada": 4, + "sub_lord": "Moon", + "sub_sub_lord": "Ketu", + "r_c": "" + } + }, + "houses": { + "house_1": { + "cusp_sign": "Taurus", + "cusp_sign_cn": "金牛座", + "cusp_degree": 38.851, + "lord": "Venus" + }, + "house_2": { + "cusp_sign": "Gemini", + "cusp_sign_cn": "双子座", + "cusp_degree": 68.851, + "lord": "Mercury" + }, + "house_3": { + "cusp_sign": "Cancer", + "cusp_sign_cn": "巨蟹座", + "cusp_degree": 98.851, + "lord": "Moon" + }, + "house_4": { + "cusp_sign": "Leo", + "cusp_sign_cn": "狮子座", + "cusp_degree": 128.851, + "lord": "Sun" + }, + "house_5": { + "cusp_sign": "Virgo", + "cusp_sign_cn": "处女座", + "cusp_degree": 158.851, + "lord": "Mercury" + }, + "house_6": { + "cusp_sign": "Libra", + "cusp_sign_cn": "天秤座", + "cusp_degree": 188.851, + "lord": "Venus" + }, + "house_7": { + "cusp_sign": "Scorpio", + "cusp_sign_cn": "天蝎座", + "cusp_degree": 218.851, + "lord": "Mars" + }, + "house_8": { + "cusp_sign": "Sagittarius", + "cusp_sign_cn": "射手座", + "cusp_degree": 248.851, + "lord": "Jupiter" + }, + "house_9": { + "cusp_sign": "Capricorn", + "cusp_sign_cn": "摩羯座", + "cusp_degree": 278.851, + "lord": "Saturn" + }, + "house_10": { + "cusp_sign": "Aquarius", + "cusp_sign_cn": "水瓶座", + "cusp_degree": 308.851, + "lord": "Saturn" + }, + "house_11": { + "cusp_sign": "Pisces", + "cusp_sign_cn": "双鱼座", + "cusp_degree": 338.851, + "lord": "Jupiter" + }, + "house_12": { + "cusp_sign": "Aries", + "cusp_sign_cn": "白羊座", + "cusp_degree": 8.851, + "lord": "Mars" + } + }, + "chart": { + "birth_info": { + "date": "1991-04-07", + "time": "09:15", + "hour": 9, + "minute": 15, + "second": 0, + "tz": "UTC+8.0", + "lat": 30.5728, + "lon": 104.0668, + "julian_day": 2448353.552083, + "ayanamsa": 23.7392, + "ayanamsa_name": "lahiri", + "ayanamsa_display": "Lahiri", + "node_mode": "mean", + "node_mode_note": "mean=Mean Node; true=True Node. PyJHora默认true,本skill默认mean。" + }, + "ascendant": { + "sign": "Taurus", + "sign_cn": "金牛座", + "degree": 8.851, + "degree_raw": 38.851, + "degree_in_sign": 8.851, + "degree_in_sign_raw": 8.851045207490053, + "lon": 38.851, + "lord": "Venus", + "nakshatra": "Krittika", + "nakshatra_pada": 4, + "nakshatra_lord": "Sun" + }, + "planets": { + "Sun": { + "sign": "Pisces", + "sign_cn": "双鱼座", + "degree": 352.9902, + "degree_raw": 352.99024068125937, + "degree_in_sign": 22.9902, + "degree_in_sign_raw": 22.990240681259365, + "house": 11, + "status": "中性(Neutral)", + "retrograde": false, + "speed": 0.983816, + "nakshatra": "Revati", + "nakshatra_pada": 2, + "nakshatra_lord": "Mercury", + "lon": 352.99024068125937, + "sign_idx": 11, + "rasi_lord": "Jupiter", + "pada": 2, + "sub_lord": "Moon", + "sub_sub_lord": "Mercury", + "combust": false, + "r_c": "", + "sb": 1.45 + }, + "Moon": { + "sign": "Sagittarius", + "sign_cn": "射手座", + "degree": 260.4978, + "degree_raw": 260.4978298734044, + "degree_in_sign": 20.4978, + "degree_in_sign_raw": 20.497829873404385, + "house": 8, + "status": "入敌(Enemy Sign)", + "retrograde": false, + "speed": 11.838419, + "nakshatra": "Purva Ashadha", + "nakshatra_pada": 3, + "nakshatra_lord": "Venus", + "lon": 260.4978298734044, + "sign_idx": 8, + "rasi_lord": "Jupiter", + "pada": 3, + "sub_lord": "Jupiter", + "sub_sub_lord": "Saturn", + "combust": false, + "combustion_threshold_degrees": 12, + "r_c": "", + "sb": 1.15 + }, + "Mars": { + "sign": "Gemini", + "sign_cn": "双子座", + "degree": 68.3986, + "degree_raw": 68.39859184834907, + "degree_in_sign": 8.3986, + "degree_in_sign_raw": 8.39859184834907, + "house": 2, + "status": "中性(Neutral)", + "retrograde": false, + "speed": 0.535139, + "nakshatra": "Ardra", + "nakshatra_pada": 1, + "nakshatra_lord": "Rahu", + "lon": 68.39859184834907, + "sign_idx": 2, + "rasi_lord": "Mercury", + "pada": 1, + "sub_lord": "Rahu", + "sub_sub_lord": "Moon", + "combust": false, + "combustion_threshold_degrees": 17, + "r_c": "", + "sb": 1.1 + }, + "Mercury": { + "sign": "Aries", + "sign_cn": "白羊座", + "degree": 4.9889, + "degree_raw": 4.988916238201053, + "degree_in_sign": 4.9889, + "degree_in_sign_raw": 4.988916238201053, + "house": 12, + "status": "入友(Friendly Sign)", + "retrograde": true, + "speed": -0.251851, + "nakshatra": "Ashwini", + "nakshatra_pada": 2, + "nakshatra_lord": "Ketu", + "lon": 4.988916238201053, + "sign_idx": 0, + "rasi_lord": "Mars", + "pada": 2, + "sub_lord": "Mars", + "sub_sub_lord": "Jupiter", + "combust": true, + "combustion_threshold_degrees": 12, + "r_c": "R", + "sb": 1.28 + }, + "Jupiter": { + "sign": "Cancer", + "sign_cn": "巨蟹座", + "degree": 99.8987, + "degree_raw": 99.89871811971885, + "degree_in_sign": 9.8987, + "degree_in_sign_raw": 9.89871811971885, + "house": 3, + "status": "入旺(Exalted)", + "retrograde": false, + "speed": 0.023622, + "nakshatra": "Pushya", + "nakshatra_pada": 2, + "nakshatra_lord": "Saturn", + "lon": 99.89871811971885, + "sign_idx": 3, + "rasi_lord": "Moon", + "pada": 2, + "sub_lord": "Venus", + "sub_sub_lord": "Mercury", + "combust": false, + "combustion_threshold_degrees": 11, + "r_c": "", + "sb": 1.17 + }, + "Venus": { + "sign": "Aries", + "sign_cn": "白羊座", + "degree": 29.2232, + "degree_raw": 29.223249375854067, + "degree_in_sign": 29.2232, + "degree_in_sign_raw": 29.223249375854067, + "house": 12, + "status": "入友(Friendly Sign)", + "retrograde": false, + "speed": 1.186233, + "nakshatra": "Krittika", + "nakshatra_pada": 1, + "nakshatra_lord": "Sun", + "lon": 29.223249375854067, + "sign_idx": 0, + "rasi_lord": "Mars", + "pada": 1, + "sub_lord": "Rahu", + "sub_sub_lord": "Rahu", + "combust": false, + "combustion_threshold_degrees": 10, + "r_c": "", + "sb": 1.43 + }, + "Saturn": { + "sign": "Capricorn", + "sign_cn": "摩羯座", + "degree": 281.8186, + "degree_raw": 281.81862796658356, + "degree_in_sign": 11.8186, + "degree_in_sign_raw": 11.818627966583563, + "house": 9, + "status": "入庙(Own Sign)", + "retrograde": false, + "speed": 0.062245, + "nakshatra": "Shravana", + "nakshatra_pada": 1, + "nakshatra_lord": "Moon", + "lon": 281.81862796658356, + "sign_idx": 9, + "rasi_lord": "Saturn", + "pada": 1, + "sub_lord": "Mars", + "sub_sub_lord": "Sun", + "combust": false, + "combustion_threshold_degrees": 15, + "r_c": "", + "sb": 1.44 + }, + "Rahu": { + "sign": "Capricorn", + "sign_cn": "摩羯座", + "degree": 270.3087, + "degree_raw": 270.30868402468377, + "degree_in_sign": 0.3087, + "degree_in_sign_raw": 0.308684024683771, + "house": 9, + "status": "中性(Neutral)", + "retrograde": true, + "speed": -0.052944, + "nakshatra": "Uttara Ashadha", + "nakshatra_pada": 2, + "nakshatra_lord": "Sun", + "lon": 270.30868402468377, + "sign_idx": 9, + "rasi_lord": "Saturn", + "pada": 2, + "sub_lord": "Rahu", + "sub_sub_lord": "Mercury", + "r_c": "" + }, + "Ketu": { + "sign": "Cancer", + "sign_cn": "巨蟹座", + "degree": 90.3087, + "degree_raw": 90.30868402468377, + "degree_in_sign": 0.3087, + "degree_in_sign_raw": 0.308684024683771, + "house": 3, + "status": "极敌(Great Enemy)", + "retrograde": true, + "speed": -0.052944, + "nakshatra": "Punarvasu", + "nakshatra_pada": 4, + "nakshatra_lord": "Jupiter", + "lon": 90.30868402468377, + "sign_idx": 3, + "rasi_lord": "Moon", + "pada": 4, + "sub_lord": "Moon", + "sub_sub_lord": "Ketu", + "r_c": "" + } + }, + "houses": { + "house_1": { + "cusp_sign": "Taurus", + "cusp_sign_cn": "金牛座", + "cusp_degree": 38.851, + "lord": "Venus" + }, + "house_2": { + "cusp_sign": "Gemini", + "cusp_sign_cn": "双子座", + "cusp_degree": 68.851, + "lord": "Mercury" + }, + "house_3": { + "cusp_sign": "Cancer", + "cusp_sign_cn": "巨蟹座", + "cusp_degree": 98.851, + "lord": "Moon" + }, + "house_4": { + "cusp_sign": "Leo", + "cusp_sign_cn": "狮子座", + "cusp_degree": 128.851, + "lord": "Sun" + }, + "house_5": { + "cusp_sign": "Virgo", + "cusp_sign_cn": "处女座", + "cusp_degree": 158.851, + "lord": "Mercury" + }, + "house_6": { + "cusp_sign": "Libra", + "cusp_sign_cn": "天秤座", + "cusp_degree": 188.851, + "lord": "Venus" + }, + "house_7": { + "cusp_sign": "Scorpio", + "cusp_sign_cn": "天蝎座", + "cusp_degree": 218.851, + "lord": "Mars" + }, + "house_8": { + "cusp_sign": "Sagittarius", + "cusp_sign_cn": "射手座", + "cusp_degree": 248.851, + "lord": "Jupiter" + }, + "house_9": { + "cusp_sign": "Capricorn", + "cusp_sign_cn": "摩羯座", + "cusp_degree": 278.851, + "lord": "Saturn" + }, + "house_10": { + "cusp_sign": "Aquarius", + "cusp_sign_cn": "水瓶座", + "cusp_degree": 308.851, + "lord": "Saturn" + }, + "house_11": { + "cusp_sign": "Pisces", + "cusp_sign_cn": "双鱼座", + "cusp_degree": 338.851, + "lord": "Jupiter" + }, + "house_12": { + "cusp_sign": "Aries", + "cusp_sign_cn": "白羊座", + "cusp_degree": 8.851, + "lord": "Mars" + } + }, + "calculation_contract": { + "contract_version": "1.0.0", + "algorithm": "sidereal_natal_chart", + "requested": { + "ayanamsa": "lahiri", + "node_mode": "mean", + "timezone_offset": 8.0 + }, + "effective": { + "ayanamsa": "lahiri", + "node_mode": "mean", + "timezone_offset": 8.0, + "timezone_source": "explicit_offset", + "ephemeris_source": "swisseph_calc_ut", + "ephemeris_flags_verified": false + } + }, + "result_hash": "19bf270c80162ade57d98714ea040209ada357c29ba6db598815143c530fc308", + "source": "local_engine_fallback", + "primary_source": "local_engine", + "fallback_reason": "VedAstro official snapshot blocked: service_endpoint_not_configured", + "local_engine_role": "fallback_only_because_official_blocked", + "source_priority": [ + "vedastro_official_snapshot", + "local_supplemental_modules", + "local_engine_fallback_when_official_blocked" + ] + } + }, + "worksheets": { + "divisional_and_special_charts": { + "varga_full": { + "D2_Hora": { + "_meta": { + "div": 2, + "name": "Hora", + "cn": "财富", + "area": "财富资源", + "part_size": 15.0, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 17.702, + "longitude": 107.702 + }, + "Sun": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 15.9805, + "part_index": 1, + "lord": "Sun" + }, + "Moon": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 10.9957, + "part_index": 1, + "lord": "Moon" + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 16.7972, + "part_index": 0, + "lord": "Sun" + }, + "Mercury": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 9.9778, + "part_index": 0, + "lord": "Sun" + }, + "Jupiter": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 19.7974, + "part_index": 0, + "lord": "Moon" + }, + "Venus": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 28.4465, + "part_index": 1, + "lord": "Moon" + }, + "Saturn": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 23.6373, + "part_index": 0, + "lord": "Moon" + }, + "Rahu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 0.6174, + "part_index": 0, + "lord": "Moon" + }, + "Ketu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 0.6174, + "part_index": 0, + "lord": "Moon" + }, + "_dignity": { + "Sun": "Own Sign", + "Moon": "Own Sign", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Exalted", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D3_Drekkana": { + "_meta": { + "div": 3, + "name": "Drekkana", + "cn": "兄弟", + "area": "兄弟姐妹", + "part_size": 10.0, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 26.553, + "longitude": 56.553 + }, + "Sun": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 8.9707, + "part_index": 2, + "lord": "Mars" + }, + "Moon": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 1.4935, + "part_index": 2, + "lord": "Sun" + }, + "Mars": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 25.1958, + "part_index": 0, + "lord": "Mercury" + }, + "Mercury": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 14.9667, + "part_index": 0, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 29.6962, + "part_index": 0, + "lord": "Moon" + }, + "Venus": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 27.6697, + "part_index": 2, + "lord": "Jupiter" + }, + "Saturn": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 5.4559, + "part_index": 1, + "lord": "Venus" + }, + "Rahu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 0.9261, + "part_index": 0, + "lord": "Saturn" + }, + "Ketu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 0.9261, + "part_index": 0, + "lord": "Moon" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Exalted", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D4_Turyamsa": { + "_meta": { + "div": 4, + "name": "Turyamsa", + "cn": "财产", + "area": "财产住所", + "part_size": 7.5, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 5.404, + "longitude": 125.404 + }, + "Sun": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 1.961, + "part_index": 3, + "lord": "Jupiter" + }, + "Moon": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 21.9913, + "part_index": 2, + "lord": "Mercury" + }, + "Mars": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 3.5944, + "part_index": 1, + "lord": "Mercury" + }, + "Mercury": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 19.9557, + "part_index": 0, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 9.5949, + "part_index": 1, + "lord": "Venus" + }, + "Venus": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 26.893, + "part_index": 3, + "lord": "Saturn" + }, + "Saturn": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 17.2745, + "part_index": 1, + "lord": "Mars" + }, + "Rahu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 1.2347, + "part_index": 0, + "lord": "Saturn" + }, + "Ketu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 1.2347, + "part_index": 0, + "lord": "Moon" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Debilitated", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D5_Panchamsa": { + "_meta": { + "div": 5, + "name": "Panchamsa", + "cn": "名声", + "area": "名声权力", + "part_size": 6.0, + "mapping_status": "classical_local", + "mapping_source": "PVR Integrated Approach sections 6.2.5-6.2.11; D8 movable Aries, fixed Sagittarius, dual Leo" + }, + "Ascendant": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 14.255, + "longitude": 164.255 + }, + "Sun": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 24.9512, + "part_index": 3, + "lord": "Saturn" + }, + "Moon": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 12.4891, + "part_index": 3, + "lord": "Mercury" + }, + "Mars": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 11.993, + "part_index": 1, + "lord": "Saturn" + }, + "Mercury": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 24.9446, + "part_index": 0, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 19.4936, + "part_index": 1, + "lord": "Mercury" + }, + "Venus": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 26.1162, + "part_index": 4, + "lord": "Venus" + }, + "Saturn": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 29.0931, + "part_index": 1, + "lord": "Mercury" + }, + "Rahu": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 1.5434, + "part_index": 0, + "lord": "Venus" + }, + "Ketu": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 1.5434, + "part_index": 0, + "lord": "Venus" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Own Sign", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D6_Shashthamsa": { + "_meta": { + "div": 6, + "name": "Shashthamsa", + "cn": "健康", + "area": "健康敌人", + "part_size": 5.0, + "mapping_status": "classical_local", + "mapping_source": "PVR Integrated Approach sections 6.2.5-6.2.11; D8 movable Aries, fixed Sagittarius, dual Leo" + }, + "Ascendant": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 23.106, + "longitude": 233.106 + }, + "Sun": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 17.9414, + "part_index": 4, + "lord": "Saturn" + }, + "Moon": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 2.987, + "part_index": 4, + "lord": "Sun" + }, + "Mars": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 20.3916, + "part_index": 1, + "lord": "Venus" + }, + "Mercury": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 29.9335, + "part_index": 0, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 29.3923, + "part_index": 1, + "lord": "Mars" + }, + "Venus": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 25.3395, + "part_index": 5, + "lord": "Mercury" + }, + "Saturn": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 10.9118, + "part_index": 2, + "lord": "Jupiter" + }, + "Rahu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 1.8521, + "part_index": 0, + "lord": "Venus" + }, + "Ketu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 1.8521, + "part_index": 0, + "lord": "Venus" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Debilitated", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D7_Saptamsa": { + "_meta": { + "div": 7, + "name": "Saptamsa", + "cn": "子女", + "area": "子女后代", + "part_size": 4.285714285714286, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 1.957, + "longitude": 271.957 + }, + "Sun": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 10.9317, + "part_index": 5, + "lord": "Saturn" + }, + "Moon": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 23.4848, + "part_index": 4, + "lord": "Mars" + }, + "Mars": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 28.7901, + "part_index": 1, + "lord": "Moon" + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 4.9224, + "part_index": 1, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 9.291, + "part_index": 2, + "lord": "Jupiter" + }, + "Venus": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 24.5627, + "part_index": 6, + "lord": "Venus" + }, + "Saturn": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 22.7304, + "part_index": 2, + "lord": "Mercury" + }, + "Rahu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 2.1608, + "part_index": 0, + "lord": "Moon" + }, + "Ketu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 2.1608, + "part_index": 0, + "lord": "Saturn" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Debilitated", + "Mercury": "Neutral", + "Jupiter": "Own Sign", + "Venus": "Own Sign", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D8_Ashtamsa": { + "_meta": { + "div": 8, + "name": "Ashtamsa", + "cn": "突发", + "area": "突发转化", + "part_size": 3.75, + "mapping_status": "classical_local", + "mapping_source": "PVR Integrated Approach sections 6.2.5-6.2.11; D8 movable Aries, fixed Sagittarius, dual Leo" + }, + "Ascendant": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 10.808, + "longitude": 310.808 + }, + "Sun": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 3.9219, + "part_index": 6, + "lord": "Saturn" + }, + "Moon": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 13.9826, + "part_index": 5, + "lord": "Saturn" + }, + "Mars": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 7.1887, + "part_index": 2, + "lord": "Venus" + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 9.9113, + "part_index": 1, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 19.1897, + "part_index": 2, + "lord": "Mercury" + }, + "Venus": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 23.786, + "part_index": 7, + "lord": "Mars" + }, + "Saturn": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 4.549, + "part_index": 3, + "lord": "Moon" + }, + "Rahu": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 2.4695, + "part_index": 0, + "lord": "Mars" + }, + "Ketu": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 2.4695, + "part_index": 0, + "lord": "Mars" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D9_Navamsa": { + "_meta": { + "div": 9, + "name": "Navamsa", + "cn": "婚姻", + "area": "婚姻伴侣灵魂", + "part_size": 3.3333333333333335, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 19.659, + "longitude": 349.659 + }, + "Sun": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 26.9122, + "part_index": 6, + "lord": "Saturn", + "pada": 7 + }, + "Moon": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 4.4805, + "part_index": 6, + "lord": "Venus", + "pada": 7 + }, + "Mars": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 15.5873, + "part_index": 2, + "lord": "Jupiter", + "pada": 3 + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 14.9002, + "part_index": 1, + "lord": "Venus", + "pada": 2 + }, + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 29.0885, + "part_index": 2, + "lord": "Mercury", + "pada": 3 + }, + "Venus": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 23.0092, + "part_index": 8, + "lord": "Jupiter", + "pada": 9 + }, + "Saturn": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 16.3677, + "part_index": 3, + "lord": "Mars", + "pada": 4 + }, + "Rahu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 2.7782, + "part_index": 0, + "lord": "Saturn", + "pada": 1 + }, + "Ketu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 2.7782, + "part_index": 0, + "lord": "Moon", + "pada": 1 + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Debilitated", + "Rahu": "Neutral", + "Ketu": "Neutral" + }, + "_d9_analysis": { + "navamsa_7th_sign": "Virgo", + "navamsa_7th_lord": "Mercury", + "planets_in_d9_7th": [ + "Jupiter" + ], + "venus_d9": "Sagittarius 23.01°", + "jupiter_d9": "Virgo 29.09°", + "venus_dignity": "Neutral", + "jupiter_dignity": "Neutral" + } + }, + "D10_Dasamsa": { + "_meta": { + "div": 10, + "name": "Dasamsa", + "cn": "事业", + "area": "事业公众形象", + "part_size": 3.0, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 28.51, + "longitude": 358.51 + }, + "Sun": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 19.9024, + "part_index": 7, + "lord": "Mercury" + }, + "Moon": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 24.9783, + "part_index": 6, + "lord": "Mercury" + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 23.9859, + "part_index": 2, + "lord": "Sun" + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 19.8892, + "part_index": 1, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 8.9872, + "part_index": 3, + "lord": "Mercury" + }, + "Venus": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 22.2325, + "part_index": 9, + "lord": "Saturn" + }, + "Saturn": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 28.1863, + "part_index": 3, + "lord": "Jupiter" + }, + "Rahu": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 3.0868, + "part_index": 0, + "lord": "Mercury" + }, + "Ketu": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 3.0868, + "part_index": 0, + "lord": "Jupiter" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D11_Rudramsa": { + "_meta": { + "div": 11, + "name": "Rudramsa", + "cn": "收益转化", + "area": "收益朋友愿望", + "part_size": 2.727272727272727, + "mapping_status": "classical_local", + "mapping_source": "PVR Integrated Approach sections 6.2.5-6.2.11; D8 movable Aries, fixed Sagittarius, dual Leo" + }, + "Ascendant": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 7.361, + "longitude": 67.361 + }, + "Sun": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 12.8926, + "part_index": 8, + "lord": "Saturn" + }, + "Moon": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 15.4761, + "part_index": 7, + "lord": "Jupiter" + }, + "Mars": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 2.3845, + "part_index": 3, + "lord": "Venus" + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 24.8781, + "part_index": 1, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 18.8859, + "part_index": 3, + "lord": "Mars" + }, + "Venus": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 21.4557, + "part_index": 10, + "lord": "Saturn" + }, + "Saturn": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 10.0049, + "part_index": 4, + "lord": "Mars" + }, + "Rahu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 3.3955, + "part_index": 0, + "lord": "Moon" + }, + "Ketu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 3.3955, + "part_index": 0, + "lord": "Saturn" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + }, + "planets": { + "Sun": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 12.8926, + "part_index": 8, + "lord": "Saturn", + "house": 8 + }, + "Moon": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 15.4761, + "part_index": 7, + "lord": "Jupiter", + "house": 10 + }, + "Mars": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 2.3845, + "part_index": 3, + "lord": "Venus", + "house": 12 + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 24.8781, + "part_index": 1, + "lord": "Venus", + "house": 12 + }, + "Jupiter": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 18.8859, + "part_index": 3, + "lord": "Mars", + "house": 11 + }, + "Venus": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 21.4557, + "part_index": 10, + "lord": "Saturn", + "house": 9 + }, + "Saturn": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 10.0049, + "part_index": 4, + "lord": "Mars", + "house": 6 + }, + "Rahu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 3.3955, + "part_index": 0, + "lord": "Moon", + "house": 2 + }, + "Ketu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 3.3955, + "part_index": 0, + "lord": "Saturn", + "house": 8 + } + } + }, + "D12_Dwadashamsa": { + "_meta": { + "div": 12, + "name": "Dwadashamsa", + "cn": "父母", + "area": "父母祖先", + "part_size": 2.5, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 16.212, + "longitude": 136.212 + }, + "Sun": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 5.8829, + "part_index": 9, + "lord": "Jupiter" + }, + "Moon": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 5.974, + "part_index": 8, + "lord": "Sun" + }, + "Mars": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 10.7831, + "part_index": 3, + "lord": "Mercury" + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 29.867, + "part_index": 1, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 28.7846, + "part_index": 3, + "lord": "Venus" + }, + "Venus": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 20.679, + "part_index": 11, + "lord": "Jupiter" + }, + "Saturn": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 21.8235, + "part_index": 4, + "lord": "Venus" + }, + "Rahu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 3.7042, + "part_index": 0, + "lord": "Saturn" + }, + "Ketu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 3.7042, + "part_index": 0, + "lord": "Moon" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Exalted", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D16_Shodasamsa": { + "_meta": { + "div": 16, + "name": "Shodasamsa", + "cn": "享受", + "area": "车辆物质", + "part_size": 1.875, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 21.616, + "longitude": 261.616 + }, + "Sun": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 7.8439, + "part_index": 12, + "lord": "Sun" + }, + "Moon": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 27.9653, + "part_index": 10, + "lord": "Saturn" + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 14.3775, + "part_index": 4, + "lord": "Sun" + }, + "Mercury": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 19.8227, + "part_index": 2, + "lord": "Mercury" + }, + "Jupiter": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 8.3795, + "part_index": 5, + "lord": "Saturn" + }, + "Venus": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 17.572, + "part_index": 15, + "lord": "Moon" + }, + "Saturn": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 9.098, + "part_index": 6, + "lord": "Saturn" + }, + "Rahu": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 4.9389, + "part_index": 0, + "lord": "Sun" + }, + "Ketu": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 4.9389, + "part_index": 0, + "lord": "Sun" + }, + "_dignity": { + "Sun": "Own Sign", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Own Sign", + "Jupiter": "Debilitated", + "Venus": "Neutral", + "Saturn": "Own Sign", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D20_Vimsamsa": { + "_meta": { + "div": 20, + "name": "Vimsamsa", + "cn": "修行", + "area": "精神修行", + "part_size": 1.5, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 27.02, + "longitude": 57.02 + }, + "Sun": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 9.8048, + "part_index": 15, + "lord": "Jupiter" + }, + "Moon": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 19.9566, + "part_index": 13, + "lord": "Venus" + }, + "Mars": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 17.9718, + "part_index": 5, + "lord": "Mercury" + }, + "Mercury": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 9.7783, + "part_index": 3, + "lord": "Moon" + }, + "Jupiter": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 17.9744, + "part_index": 6, + "lord": "Mercury" + }, + "Venus": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 14.465, + "part_index": 19, + "lord": "Mars" + }, + "Saturn": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 26.3726, + "part_index": 7, + "lord": "Moon" + }, + "Rahu": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 6.1737, + "part_index": 0, + "lord": "Jupiter" + }, + "Ketu": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 6.1737, + "part_index": 0, + "lord": "Jupiter" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Exalted", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D24_Siddhamsa": { + "_meta": { + "div": 24, + "name": "Siddhamsa", + "cn": "学识", + "area": "教育学识", + "part_size": 1.25, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 2.424, + "longitude": 302.424 + }, + "Sun": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 11.7658, + "part_index": 18, + "lord": "Saturn" + }, + "Moon": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 11.9479, + "part_index": 16, + "lord": "Jupiter" + }, + "Mars": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 21.5662, + "part_index": 6, + "lord": "Saturn" + }, + "Mercury": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 29.734, + "part_index": 3, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 27.5692, + "part_index": 7, + "lord": "Saturn" + }, + "Venus": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 11.358, + "part_index": 23, + "lord": "Moon" + }, + "Saturn": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 13.6471, + "part_index": 9, + "lord": "Mars" + }, + "Rahu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 7.4084, + "part_index": 0, + "lord": "Moon" + }, + "Ketu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 7.4084, + "part_index": 0, + "lord": "Moon" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Debilitated", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D27_Bhamsa": { + "_meta": { + "div": 27, + "name": "Bhamsa", + "cn": "力量", + "area": "力量弱点", + "part_size": 1.1111111111111112, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 28.977, + "longitude": 58.977 + }, + "Sun": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 20.7365, + "part_index": 20, + "lord": "Mercury" + }, + "Moon": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 13.4414, + "part_index": 18, + "lord": "Venus" + }, + "Mars": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 16.762, + "part_index": 7, + "lord": "Mars" + }, + "Mercury": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 14.7007, + "part_index": 4, + "lord": "Sun" + }, + "Jupiter": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 27.2654, + "part_index": 8, + "lord": "Mercury" + }, + "Venus": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 9.0277, + "part_index": 26, + "lord": "Mercury" + }, + "Saturn": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 19.103, + "part_index": 10, + "lord": "Sun" + }, + "Rahu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 8.3345, + "part_index": 0, + "lord": "Venus" + }, + "Ketu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 8.3345, + "part_index": 0, + "lord": "Venus" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Own Sign", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D30_Trimsamsa": { + "_meta": { + "div": 30, + "name": "Trimsamsa", + "cn": "苦难", + "area": "灾难苦难", + "part_size": 1.0, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 25.53, + "longitude": 175.53 + }, + "Sun": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 29.7072, + "part_index": 22, + "lord": "Mars" + }, + "Moon": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 14.9349, + "part_index": 20, + "lord": "Mercury" + }, + "Mars": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 11.9578, + "part_index": 8, + "lord": "Saturn" + }, + "Mercury": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 29.6675, + "part_index": 4, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 26.9615, + "part_index": 9, + "lord": "Mercury" + }, + "Venus": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 6.6975, + "part_index": 29, + "lord": "Venus" + }, + "Saturn": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 24.5588, + "part_index": 11, + "lord": "Mercury" + }, + "Rahu": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 9.2605, + "part_index": 0, + "lord": "Venus" + }, + "Ketu": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 9.2605, + "part_index": 0, + "lord": "Venus" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Own Sign", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D40_Khavedamsa": { + "_meta": { + "div": 40, + "name": "Khavedamsa", + "cn": "运势", + "area": "吉凶运势", + "part_size": 0.75, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 24.04, + "longitude": 174.04 + }, + "Sun": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 19.6096, + "part_index": 30, + "lord": "Mars" + }, + "Moon": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 9.9132, + "part_index": 27, + "lord": "Moon" + }, + "Mars": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 5.9437, + "part_index": 11, + "lord": "Jupiter" + }, + "Mercury": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 19.5566, + "part_index": 6, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 5.9487, + "part_index": 13, + "lord": "Mars" + }, + "Venus": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 28.93, + "part_index": 38, + "lord": "Mercury" + }, + "Saturn": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 22.7451, + "part_index": 15, + "lord": "Saturn" + }, + "Rahu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 12.3474, + "part_index": 0, + "lord": "Venus" + }, + "Ketu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 12.3474, + "part_index": 0, + "lord": "Venus" + }, + "_dignity": { + "Sun": "Exalted", + "Moon": "Own Sign", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Own Sign", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D45_Akshavedamsa": { + "_meta": { + "div": 45, + "name": "Akshavedamsa", + "cn": "格局", + "area": "整体格局", + "part_size": 0.6666666666666666, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 8.295, + "longitude": 218.295 + }, + "Sun": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 14.5608, + "part_index": 34, + "lord": "Sun" + }, + "Moon": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 22.4023, + "part_index": 30, + "lord": "Venus" + }, + "Mars": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 17.9366, + "part_index": 12, + "lord": "Mars" + }, + "Mercury": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 14.5012, + "part_index": 7, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 25.4423, + "part_index": 14, + "lord": "Jupiter" + }, + "Venus": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 25.0462, + "part_index": 43, + "lord": "Mars" + }, + "Saturn": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 21.8383, + "part_index": 17, + "lord": "Jupiter" + }, + "Rahu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 13.8908, + "part_index": 0, + "lord": "Venus" + }, + "Ketu": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 13.8908, + "part_index": 0, + "lord": "Venus" + }, + "_dignity": { + "Sun": "Own Sign", + "Moon": "Neutral", + "Mars": "Own Sign", + "Mercury": "Neutral", + "Jupiter": "Own Sign", + "Venus": "Neutral", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D60_Shashtyamsa": { + "_meta": { + "div": 60, + "name": "Shashtyamsa", + "cn": "业力", + "area": "前世业力同盘区分", + "part_size": 0.5, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 21.06, + "longitude": 231.06 + }, + "Sun": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 29.4144, + "part_index": 45, + "lord": "Saturn" + }, + "Moon": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 29.8698, + "part_index": 40, + "lord": "Mars" + }, + "Mars": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 23.9155, + "part_index": 16, + "lord": "Venus" + }, + "Mercury": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 29.335, + "part_index": 9, + "lord": "Saturn" + }, + "Jupiter": { + "sign": "Pisces", + "sign_idx": 11, + "degree_in_sign": 23.9231, + "part_index": 19, + "lord": "Jupiter" + }, + "Venus": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 13.395, + "part_index": 58, + "lord": "Saturn" + }, + "Saturn": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 19.1177, + "part_index": 23, + "lord": "Saturn" + }, + "Rahu": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 18.521, + "part_index": 0, + "lord": "Saturn" + }, + "Ketu": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 18.521, + "part_index": 0, + "lord": "Sun" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Own Sign", + "Venus": "Neutral", + "Saturn": "Own Sign", + "Rahu": "Neutral", + "Ketu": "Neutral" + }, + "_d60_analysis": { + "benefics_in_kendras": [ + "Venus(4宫)" + ], + "malefics_in_kendras": [ + "Rahu(4宫)", + "Ketu(10宫)" + ], + "karma_hint": "前世有业力课题" + } + }, + "D81_Navamsa-Navamsa": { + "_meta": { + "div": 81, + "name": "Navamsa-Navamsa", + "cn": "D9之D9", + "area": "配偶灵性精微层", + "part_size": 0.37037037037037035, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Sagittarius", + "sign_idx": 8, + "degree_in_sign": 26.931, + "longitude": 266.931 + }, + "Sun": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 2.2095, + "part_index": 62, + "lord": "Mercury" + }, + "Moon": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 10.3242, + "part_index": 55, + "lord": "Mars" + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 20.2859, + "part_index": 22, + "lord": "Sun" + }, + "Mercury": { + "sign": "Taurus", + "sign_idx": 1, + "degree_in_sign": 14.1022, + "part_index": 13, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 21.7962, + "part_index": 26, + "lord": "Mercury" + }, + "Venus": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 27.0832, + "part_index": 78, + "lord": "Venus" + }, + "Saturn": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 27.3089, + "part_index": 31, + "lord": "Sun" + }, + "Rahu": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 25.0034, + "part_index": 0, + "lord": "Saturn" + }, + "Ketu": { + "sign": "Cancer", + "sign_idx": 3, + "degree_in_sign": 25.0034, + "part_index": 0, + "lord": "Moon" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Debilitated", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Own Sign", + "Saturn": "Neutral", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D108_Dwadasamsa-Navamsa": { + "_meta": { + "div": 108, + "name": "Dwadasamsa-Navamsa", + "cn": "D12之D9", + "area": "祖先父母精微层", + "part_size": 0.2777777777777778, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 25.908, + "longitude": 205.908 + }, + "Sun": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 22.946, + "part_index": 82, + "lord": "Mars" + }, + "Moon": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 23.7656, + "part_index": 73, + "lord": "Mars" + }, + "Mars": { + "sign": "Gemini", + "sign_idx": 2, + "degree_in_sign": 7.0479, + "part_index": 30, + "lord": "Mercury" + }, + "Mercury": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 28.803, + "part_index": 17, + "lord": "Venus" + }, + "Jupiter": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 19.0616, + "part_index": 35, + "lord": "Sun" + }, + "Venus": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 6.1109, + "part_index": 105, + "lord": "Mercury" + }, + "Saturn": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 16.4118, + "part_index": 42, + "lord": "Venus" + }, + "Rahu": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 3.3379, + "part_index": 1, + "lord": "Saturn" + }, + "Ketu": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 3.3379, + "part_index": 1, + "lord": "Sun" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Debilitated", + "Mars": "Neutral", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Debilitated", + "Saturn": "Exalted", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D144_Dwadasamsa-Dwadasamsa": { + "_meta": { + "div": 144, + "name": "Dwadasamsa-Dwadasamsa", + "cn": "D12之D12", + "area": "父母祖先精微层", + "part_size": 0.20833333333333334, + "mapping_status": "classical_local", + "mapping_source": "classical_local" + }, + "Ascendant": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 14.544, + "longitude": 314.544 + }, + "Sun": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 10.5947, + "part_index": 110, + "lord": "Saturn" + }, + "Moon": { + "sign": "Libra", + "sign_idx": 6, + "degree_in_sign": 11.6875, + "part_index": 98, + "lord": "Venus" + }, + "Mars": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 9.3972, + "part_index": 40, + "lord": "Saturn" + }, + "Mercury": { + "sign": "Aries", + "sign_idx": 0, + "degree_in_sign": 28.4039, + "part_index": 23, + "lord": "Mars" + }, + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "degree_in_sign": 15.4154, + "part_index": 47, + "lord": "Mercury" + }, + "Venus": { + "sign": "Scorpio", + "sign_idx": 7, + "degree_in_sign": 8.1479, + "part_index": 140, + "lord": "Mars" + }, + "Saturn": { + "sign": "Capricorn", + "sign_idx": 9, + "degree_in_sign": 21.8824, + "part_index": 56, + "lord": "Saturn" + }, + "Rahu": { + "sign": "Aquarius", + "sign_idx": 10, + "degree_in_sign": 14.4505, + "part_index": 1, + "lord": "Saturn" + }, + "Ketu": { + "sign": "Leo", + "sign_idx": 4, + "degree_in_sign": 14.4505, + "part_index": 1, + "lord": "Sun" + }, + "_dignity": { + "Sun": "Neutral", + "Moon": "Neutral", + "Mars": "Exalted", + "Mercury": "Neutral", + "Jupiter": "Neutral", + "Venus": "Neutral", + "Saturn": "Own Sign", + "Rahu": "Neutral", + "Ketu": "Neutral" + } + }, + "D1_Rashi": { + "Sun": { + "sign": "Pisces", + "degree": 352.9902, + "degree_in_sign": 22.9902, + "house": 11, + "nakshatra": "Revati", + "nakshatra_pada": 2 + }, + "Moon": { + "sign": "Sagittarius", + "degree": 260.4978, + "degree_in_sign": 20.4978, + "house": 8, + "nakshatra": "Purva Ashadha", + "nakshatra_pada": 3 + }, + "Mars": { + "sign": "Gemini", + "degree": 68.3986, + "degree_in_sign": 8.3986, + "house": 2, + "nakshatra": "Ardra", + "nakshatra_pada": 1 + }, + "Mercury": { + "sign": "Aries", + "degree": 4.9889, + "degree_in_sign": 4.9889, + "house": 12, + "nakshatra": "Ashwini", + "nakshatra_pada": 2 + }, + "Jupiter": { + "sign": "Cancer", + "degree": 99.8987, + "degree_in_sign": 9.8987, + "house": 3, + "nakshatra": "Pushya", + "nakshatra_pada": 2 + }, + "Venus": { + "sign": "Aries", + "degree": 29.2232, + "degree_in_sign": 29.2232, + "house": 12, + "nakshatra": "Krittika", + "nakshatra_pada": 1 + }, + "Saturn": { + "sign": "Capricorn", + "degree": 281.8186, + "degree_in_sign": 11.8186, + "house": 9, + "nakshatra": "Shravana", + "nakshatra_pada": 1 + }, + "Rahu": { + "sign": "Capricorn", + "degree": 270.3087, + "degree_in_sign": 0.3087, + "house": 9, + "nakshatra": "Uttara Ashadha", + "nakshatra_pada": 2 + }, + "Ketu": { + "sign": "Cancer", + "degree": 90.3087, + "degree_in_sign": 0.3087, + "house": 3, + "nakshatra": "Punarvasu", + "nakshatra_pada": 4 + } + } + } + } + } + } +} diff --git a/frontend/tests/report-calculation-charts.test.tsx b/frontend/tests/report-calculation-charts.test.tsx index 4afe3fd4..d7a7ae0b 100644 --- a/frontend/tests/report-calculation-charts.test.tsx +++ b/frontend/tests/report-calculation-charts.test.tsx @@ -36,6 +36,19 @@ test("an older body without chart fences keeps its charts, without the moved cav assert.doesNotMatch(markup, /出生时间敏感/); }); +test("a full-data body that fences every calculation chart drops the trailing section", () => { + const fullData = JSON.parse(readFileSync(new URL("./fixtures/report-full-data-chart-fences.json", import.meta.url), "utf8")); + const fullCharts = assembleLongformCharts(fullData.packet, "ev-cover-longform"); + const drawn = fencedReportChartIds(fullData.markdown); + assert.ok(fullCharts.length > 0); + for (const chart of fullCharts) assert.ok(drawn.has(chart.id), chart.id); + assert.equal(renderToStaticMarkup(React.createElement(ReportCalculationCharts, { + charts: fullCharts, + markdown: fullData.markdown, + language: "zh", + })), ""); +}); + test("the page and the export skip the same charts", () => { const first = /```jyotish-chart\n[\s\S]*?```/.exec(fixture.markdown)![0]; const drawn = [...fencedReportChartIds(first)]; diff --git a/scripts/pl9_full_data_export.py b/scripts/pl9_full_data_export.py index e948977e..d5283154 100644 --- a/scripts/pl9_full_data_export.py +++ b/scripts/pl9_full_data_export.py @@ -107,7 +107,13 @@ def _sanitize_pl9_ai_density_markdown(markdown: str, title: str = "印度占星 strip_han_plural_s, ) - text = _sanitize_pl9_public_markdown(markdown) + try: + from pl9_language_terms import translate_zh_glued_phrases + except ModuleNotFoundError: # pragma: no cover - package import compatibility + from scripts.pl9_language_terms import translate_zh_glued_phrases + # Whole phrases and glued planet+dignity tokens before shorter word swaps. + # Chapters appended after the parity strip still pass through here. + text = translate_zh_glued_phrases(_sanitize_pl9_public_markdown(markdown)) replacements = { "# PL9 对标主册": f"# {title}", "出生资料与图盘(PL9 p1-p17)": "出生资料与图盘", @@ -1264,6 +1270,27 @@ def _sanitize_pl9_ai_density_markdown_en(markdown: str, title: str = "Vedic Astr +# Body residue (BUG-1312). Parenthetical Sanskrit names (nakshatra, yoga, +# Dasha) and header abbreviations (SAV, BAV, KP, D1-D60) are separated from +# Han by parentheses or spaces, so they are not "glued". They are not function +# words. Chart fences are structured payload and are not part of the prose count. +_ZH_GLUE_RE = re.compile(r"[\u4e00-\u9fff][A-Za-z]{3,}|[A-Za-z]{3,}[\u4e00-\u9fff]") +_ZH_FUNCTION_WORD_RE = re.compile( + r"(? dict[str, int]: + body = (markdown or "").split("## 结构化资料附录", 1)[0] + body = _ZH_CHART_FENCE_RE.sub("", body) + return { + "glued_latin": len(_ZH_GLUE_RE.findall(body)), + "function_words": len(_ZH_FUNCTION_WORD_RE.findall(body)), + } + + def _pl9_markdown_hygiene_receipt(markdown: str, *, language: str) -> dict[str, Any]: """Check the Markdown before rendering user-facing PDF.""" @@ -1327,6 +1354,12 @@ def _pl9_markdown_hygiene_receipt(markdown: str, *, language: str) -> dict[str, chinese_chars = len(re.findall(r"[\u4e00-\u9fff]", markdown)) if chinese_chars: violations.append(f"chinese_characters:{chinese_chars}") + if language == 'zh': + residue = _zh_body_residue(markdown) + if residue["glued_latin"]: + violations.append(f"glued_latin:{residue['glued_latin']}") + if residue["function_words"]: + violations.append(f"function_words:{residue['function_words']}") language_receipt = language_quality_receipt(markdown, language=language) violations.extend(language_receipt.get("violations") or []) orphan_lines = orphan_separator_lines(markdown) diff --git a/scripts/pl9_interpretation_packs.py b/scripts/pl9_interpretation_packs.py index 108d71a6..d40ba05a 100644 --- a/scripts/pl9_interpretation_packs.py +++ b/scripts/pl9_interpretation_packs.py @@ -864,11 +864,14 @@ def build_yoga_interpretation_pack( if name in seen: continue seen.add(name) - combination = str(raw.get("combination_en") or raw.get("combination") or raw.get("reason") or "") if language == "en": - combination = str(raw.get("combination_en") or raw.get("name") or combination) + combination = str(raw.get("combination_en") or raw.get("name") or raw.get("combination") or "") if re.search(r"[\u4e00-\u9fff]", combination): combination = "combination text is not listed separately" + else: + # Chinese pages keep the Chinese combination. combination_en is the + # English twin and must not leak into the Chinese report. + combination = str(raw.get("combination") or raw.get("reason") or "") planets = [str(item) for item in _list(raw.get("planets"))] overlap = sorted(set(planets) & set(active)) if language == "zh": diff --git a/scripts/pl9_language_terms.py b/scripts/pl9_language_terms.py index b493f5b1..4e90b683 100644 --- a/scripts/pl9_language_terms.py +++ b/scripts/pl9_language_terms.py @@ -11,6 +11,126 @@ import re from typing import Any +# Bilingual planet tokens from yoga combination text, longest first. +# Dignity is glued on with no space ("木星Jupiterexalted"), so the long form +# has to be translated before the short planet name. +_BILINGUAL_PLANETS = ( + ("南交点Ketu", "南交点"), + ("北交点Rahu", "北交点"), + ("水星Mercury", "水星"), + ("木星Jupiter", "木星"), + ("金星Venus", "金星"), + ("土星Saturn", "土星"), + ("火星Mars", "火星"), + ("月亮Moon", "月亮"), + ("太阳Sun", "太阳"), +) +_GLUED_DIGNITY = { + "exalted": "入旺", + "debilitated": "落陷", + "moolatrikona": "本垣", + "own": "入庙", + "strong": "强", +} +_BILINGUAL_PLANET_RE = re.compile( + "(" + "|".join(re.escape(raw) for raw, _public in _BILINGUAL_PLANETS) + ")" + + "(exalted|debilitated|moolatrikona|own|strong)?" +) +_BILINGUAL_PLANET_ZH = dict(_BILINGUAL_PLANETS) + +# Whole formation sentences and status tokens. Longer phrases stay above the +# short-word glossary so "of" / "in" are not left stuck to Chinese. +_ZH_FORMATION_PHRASES = ( + ( + "| Bhava Number | Bhava Arambha / House beginning | Bhava Madhya / Middle of House | Bhava Antya / House ending |", + "| 宫位编号 | 宫位起点 | 宫位中点 | 宫位终点 |", + ), + ( + "Lord of sign occupied in navamsa by 2nd/5th/11th lord, exalted and joins the 9th lord", + "第2、第5或第11宫主在九分盘所落星座的宫主入旺,并与第9宫主会合", + ), + ( + "Lord of navamsa occupied by 4th lord in 12th", + "第4宫主在九分盘所落星座的宫主位于第12宫", + ), + ("Learned, eloquent, wealthy from knowledge", "有学识,善表达,学问带来资源"), + ("Loss or destruction of property/house", "房屋或产业有损耗"), + ( + "Lagna lord, his dispositor, the latter's dispositor in rasi and navamsa, all in kendras/trines/exaltation", + "上升主星、它的定位星,以及定位星的定位星,在本命盘和九分盘都落在角宫、三方宫或入旺", + ), + ("Fulfills all desires, great king, supreme wealth", "愿望容易得到回应,传统上对应较高的地位与丰厚资源"), + ("Eloquent, skilled in debate, good communicator", "善表达,辩论清楚,沟通能力强"), + ("Enjoyment of food, pleasure in dining, hospitality", "饮食安稳,待客从容"), + ("Courage, initiative, status and practical drive", "有行动力,做事务实"), + ("Fear of deception, theft; deceptive nature", "容易担心受骗或失物,需要再核对事实"), + ( + "Lagna malefic/Gulika in trine OR Gulika with Kendra/Trine lords OR L1 with Rahu/Sat/Ket", + "凶星或吉利伽在三方宫,或吉利伽与角宫、三方宫主同在,或上升主与罗睺、土星、计都同在", + ), + ("或BVR精神扰动变体", "或(BVR)精神扰动变体"), + ("very_rare", "极少"), + ("Not supplied by source", "源数据未提供"), + ("Crux of Vedic Astrology", "《吠陀占星精要》"), + ("Viparita Raja Yoga", "颠倒王者格"), + ("Dhana Yoga", "财富瑜伽"), + ("Raj Yoga", "王者格"), + ("Custom condition met", "满足自定义条件"), + ("custom condition satisfied", "满足自定义条件"), + ("自定义条件满足", "满足自定义条件"), + ("hemmed in by malefics", "被凶星夹制"), + ("hemmed in by benefics", "被吉星夹制"), + ("occupied in navamsa", "在九分盘所落"), + ("occupied in navamsha", "在九分盘所落"), + ("Mutual aspect", "互照"), + ("mutual aspect", "互照"), + ("drig_rath_aspect_sequence_v1", "Drig 相位顺序 v1"), + ("Ashtakavarga八分法(BPHS/PVR书例校准v2.1)", "Ashtakavarga 八分法(BPHS / PVR 书例校准 v2.1)"), + ("Sade Sati阶段框架", "Sade Sati 阶段框架"), + ("灵魂星AK", "灵魂星(AK)"), + ("事业星AmK", "事业星(AmK)"), + ("兄弟星BK", "兄弟星(BK)"), + ("母亲星MK", "母亲星(MK)"), + ("子女星PK", "子女星(PK)"), + ("障碍星GK", "障碍星(GK)"), + ("配偶星DK", "配偶星(DK)"), + ("父亲星PiK", "父亲星(PiK)"), +) + + +def translate_zh_glued_phrases(text: str) -> str: + """Translate whole bilingual tokens before any shorter English word.""" + + if not text: + return text + + def planet(match: re.Match) -> str: + name = _BILINGUAL_PLANET_ZH[match.group(1)] + dignity = _GLUED_DIGNITY.get(match.group(2) or "", "") + return name + dignity + + text = _BILINGUAL_PLANET_RE.sub(planet, text) + for raw, public in _ZH_FORMATION_PHRASES: + text = text.replace(raw, public) + # House-lord combinations are printed as H6_Lord(Venus) in H12. Translate + # the whole pattern before the short word "in" is left beside Chinese. + text = re.sub( + r"H(\d+)_Lord\(([^)]+)\) in H(\d+)", + r"第\1宫主(\2)在第\3宫", + text, + ) + text = re.sub(r"H(\d+)_Lord\(([^)]+)\)", r"第\1宫主(\2)", text) + # Status tokens printed as bare English words. Longer phrases above already + # consumed "not listed" / "Custom condition met", so these are the leftovers. + for raw, public in ( + ("listed", "已列出"), + ("background", "背景"), + ("native", "本命"), + ): + text = re.sub(rf"(? str: """Replace one glossary term in prose only. diff --git a/scripts/pl9_reader_english_terms.py b/scripts/pl9_reader_english_terms.py index e58ba9f8..f19c8779 100644 --- a/scripts/pl9_reader_english_terms.py +++ b/scripts/pl9_reader_english_terms.py @@ -35,6 +35,29 @@ _PHRASES: dict[str, str] = { "特殊上升与派生点补充": "Special Lagnas and Points (supplement)", "敏感点与特殊落点": "Sensitive Points and Special Placements", "本命与分盘北印度图盘": "Natal and Divisional Charts (North Indian)", + # Chart fences in the parity volume. The Chinese label is the key; the + # English edition looks these up instead of keeping a second title list. + "D1 本命盘": "D1 natal chart", + "月亮盘": "Moon chart", + "D2 财富分盘": "D2 wealth chart", + "D3 手足分盘": "D3 siblings chart", + "D4 居所分盘": "D4 home chart", + "D5 声望分盘": "D5 reputation chart", + "D6 压力分盘": "D6 pressure chart", + "D7 子女分盘": "D7 children chart", + "D8 变化分盘": "D8 change chart", + "D9 九分盘": "D9 navamsha", + "D10 事业分盘": "D10 career chart", + "D11 收益分盘": "D11 gains chart", + "D12 父母分盘": "D12 parents chart", + "D16 享受分盘": "D16 comforts chart", + "D20 灵修分盘": "D20 practice chart", + "D24 学习分盘": "D24 learning chart", + "D27 内在分盘": "D27 inner chart", + "D30 困难分盘": "D30 difficulty chart", + "D40 母系分盘": "D40 maternal chart", + "D45 父系分盘": "D45 paternal chart", + "D60 深层分盘": "D60 deep chart", "分盘对出生时间敏感,原始计算供核对,不单独增加结论的确定性。": "Divisional charts are sensitive to birth time. The raw calculations are here for checking and do not by themselves make a conclusion more certain.", " 数值位置表": " Position Table", diff --git a/scripts/pl9_reader_export.py b/scripts/pl9_reader_export.py index 9681392e..830ba468 100644 --- a/scripts/pl9_reader_export.py +++ b/scripts/pl9_reader_export.py @@ -111,7 +111,11 @@ def _pl9_report_language(packet: dict) -> str: def _strip_pl9_user_engineering_markers(markdown: str) -> str: """Remove internal audit/profile vocabulary from user-facing report text.""" - text = markdown + try: + from scripts.pl9_language_terms import translate_zh_glued_phrases + except ModuleNotFoundError: # pragma: no cover - direct scripts/ execution + from pl9_language_terms import translate_zh_glued_phrases + text = translate_zh_glued_phrases(markdown) replacements = { "parameter_sensitive / unverified": "参考", "parameter_sensitive": "参考", @@ -481,6 +485,149 @@ def _render_pl9_user_markdown(packet: dict) -> str: return cleaned +# Drawable charts in the parity "north Indian charts" section. Bhava (Sripati) +# has no chart id (its numbers stay in the Sripati table). Navamsha is not +# listed again: it is the same id as D9. English titles live in +# pl9_reader_english_terms, keyed by these Chinese labels. +_PARITY_CHARTS = ( + ("D1", "D1 本命盘", "d1"), + ("MOON", "月亮盘", "moon"), + ("D2", "D2 财富分盘", ("D2_Hora", "D2")), + ("D3", "D3 手足分盘", ("D3_Drekkana", "D3")), + ("D4", "D4 居所分盘", ("D4_Turyamsa", "D4_Chaturthamsa", "D4")), + ("D5", "D5 声望分盘", ("D5_Panchamsa", "D5")), + ("D6", "D6 压力分盘", ("D6_Shashthamsa", "D6")), + ("D7", "D7 子女分盘", ("D7_Saptamsa", "D7")), + ("D8", "D8 变化分盘", ("D8_Ashtamsa", "D8")), + ("D9", "D9 九分盘", ("D9_Navamsa", "D9")), + ("D10", "D10 事业分盘", ("D10_Dasamsa", "D10")), + ("D11", "D11 收益分盘", ("D11_Rudramsa", "D11")), + ("D12", "D12 父母分盘", ("D12_Dwadashamsa", "D12_Dvadasamsa", "D12")), + ("D16", "D16 享受分盘", ("D16_Shodasamsa", "D16")), + ("D20", "D20 灵修分盘", ("D20_Vimsamsa", "D20")), + ("D24", "D24 学习分盘", ("D24_Siddhamsa", "D24_Chaturvimsamsa", "D24")), + ("D27", "D27 内在分盘", ("D27_Bhamsa", "D27")), + ("D30", "D30 困难分盘", ("D30_Trimsamsa", "D30")), + ("D40", "D40 母系分盘", ("D40_Khavedamsa", "D40")), + ("D45", "D45 父系分盘", ("D45_Akshavedamsa", "D45")), + ("D60", "D60 深层分盘", ("D60_Shashtyamsa", "D60_Shashtiamsa", "D60")), +) + + +def _parity_chart_title(zh: str, language: str) -> str: + if language != "en": + return zh + try: + from scripts.pl9_reader_english_terms import PHRASES_EN + except ModuleNotFoundError: # pragma: no cover - direct scripts/ execution + from pl9_reader_english_terms import PHRASES_EN + return dict(PHRASES_EN).get(zh, zh) + + +def _parity_chart_source(kind, core_chart, worksheets, divisional, varga_full): + if kind == "d1": + planets = core_chart.get("planets") if isinstance(core_chart.get("planets"), dict) else {} + ascendant = core_chart.get("ascendant") if isinstance(core_chart.get("ascendant"), dict) else {} + return planets, ascendant + if kind == "moon": + d1_sheet = worksheets.get("d1_rasi_bhava") if isinstance(worksheets.get("d1_rasi_bhava"), dict) else {} + moon = d1_sheet.get("moon_chart") if isinstance(d1_sheet.get("moon_chart"), dict) else {} + if not moon and isinstance(divisional.get("moon_chart"), dict): + moon = divisional["moon_chart"] + raw = moon.get("raw") if isinstance(moon.get("raw"), dict) else {} + if not raw and isinstance(moon.get("data"), dict): + raw = moon["data"] + if not raw: + raw = moon + if isinstance(raw.get("raw"), dict): + raw = raw["raw"] + ascendant = {} + for key in ("Ascendant", "ascendant", "Asc"): + if isinstance(raw.get(key), dict): + ascendant = raw[key] + break + planets = raw.get("planets") if isinstance(raw.get("planets"), dict) else {} + return planets, ascendant + chart = {} + for key in kind: + candidate = varga_full.get(key) if isinstance(varga_full, dict) else None + if isinstance(candidate, dict) and candidate: + chart = candidate + break + ascendant = {} + for key in ("Ascendant", "ascendant", "Asc"): + if isinstance(chart.get(key), dict): + ascendant = chart[key] + break + return chart, ascendant + + +def _append_parity_chart_fences(lines, *, language, core_chart, worksheets, divisional, varga_full) -> None: + """One north-Indian fence per chart that has a sign to draw. No empty heading.""" + try: + from scripts.report_chart_block import PLANET_ORDER, build_chart_block + except ModuleNotFoundError: # pragma: no cover - direct scripts/ execution + from report_chart_block import PLANET_ORDER, build_chart_block + natal = core_chart.get("planets") if isinstance(core_chart.get("planets"), dict) else {} + retrograde = { + name: bool(row.get("retrograde")) if isinstance(row, dict) else False + for name in PLANET_ORDER + for row in [natal.get(name)] + } + seen: set[str] = set() + for chart_id, title_zh, kind in _PARITY_CHARTS: + if chart_id in seen: + continue + positions, ascendant = _parity_chart_source(kind, core_chart, worksheets, divisional, varga_full) + title = _parity_chart_title(title_zh, language) + try: + block = build_chart_block(chart_id, title, positions, ascendant, retrograde) + except (TypeError, ValueError): + continue + seen.add(chart_id) + lines.extend([f"##### {title}", "", block, ""]) + + +def _ascendant_report_fields(asc: dict) -> dict: + """Longitude, nakshatra and lords for the report's ascendant row. No new dignity.""" + longitude = None + for key in ("lon", "longitude", "degree_raw"): + value = asc.get(key) + if isinstance(value, (int, float)): + longitude = float(value) % 360.0 + break + if longitude is None: + sign = asc.get("sign") + degree = asc.get("degree_in_sign") + if not isinstance(degree, (int, float)): + degree = asc.get("degree") + signs = globals().get("SIGNS") or [] + if sign in signs and isinstance(degree, (int, float)): + longitude = signs.index(sign) * 30.0 + float(degree) + fields = {} + if longitude is not None: + try: + from scripts.jyotish_engine import _nakshatra_fields + except ModuleNotFoundError: # pragma: no cover - direct scripts/ execution + from jyotish_engine import _nakshatra_fields + fields = _nakshatra_fields(longitude) + degree = asc.get("degree_in_sign") + if not isinstance(degree, (int, float)): + degree = asc.get("degree") + pada = fields.get("nakshatra_pada") if fields else None + if pada is None: + pada = asc.get("nakshatra_pada") or asc.get("pada") + return { + "sign": asc.get("sign"), + "degree": degree, + "longitude": longitude, + "nakshatra": fields.get("nakshatra") or asc.get("nakshatra"), + "pada": pada, + "nakshatra_lord": fields.get("nakshatra_lord") or asc.get("nakshatra_lord"), + "sign_lord": asc.get("lord") or asc.get("rasi_lord"), + } + + def render_pl9_parity_markdown(packet: dict) -> str: """Render only PL9 page-family material admitted to the parity main volume.""" _bind_engine_symbols() @@ -544,6 +691,18 @@ def render_pl9_parity_markdown(packet: dict) -> str: elif isinstance(value, (list, tuple)): value = ';'.join(str(item) for item in value if item not in (None, '', [], {})) text = str(value if value not in (None, '') else '-').replace('\n', ' ').strip() + if _lang != 'en': + # Whole status tokens. Longer phrases are handled in the glossary + # before these short words, so a half-translated fragment is not + # cleaned up by deleting letters here. + text = { + 'active': '当前运行', + 'background': '背景', + 'listed': '已列出', + 'native': '本命', + 'Custom condition met': '满足自定义条件', + 'custom condition satisfied': '满足自定义条件', + }.get(text, text) return text.replace('|', '/') def _brief(items, limit=2) -> str: @@ -668,6 +827,10 @@ def render_pl9_parity_markdown(packet: dict) -> str: def _public_status_note(value) -> str: zh_mapping = { 'partial_verified': '已生成', + 'listed': '已列出', + 'active': '当前运行', + 'background': '背景', + 'native': '本命', 'parameter_sensitive': '参数敏感', 'blocked': '需补资料', 'verified': '已核验', @@ -856,6 +1019,14 @@ def render_pl9_parity_markdown(packet: dict) -> str: '| Planet | R/C | Sign | Degree | Longitude | House | Nakshatra | Pada | Speed |', '|--------|-----|------|--------|-----------|-------|-----------|------|-------|', ]) + ascendant = _dict(core_chart.get('ascendant')) + if ascendant: + info = _ascendant_report_fields(ascendant) + asc_label = 'Ascendant' if _lang == 'en' else '上升' + lines.append( + f"| {_cell(asc_label)} | - | {_cell(_token(info['sign']))} | {_cell(_degree(info['degree']))} | " + f"{_cell(_degree(info['longitude']))} | 1 | {_cell(info['nakshatra'])} | {_cell(info['pada'])} | - |" + ) for planet in ('Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu'): row = _dict(planets.get(planet)) if not row: @@ -875,6 +1046,14 @@ def render_pl9_parity_markdown(packet: dict) -> str: '| 行星 | 星座主 | 星宿主 | 分主 | 分分主 | 尊贵状态 | 力量比 |', '|------|--------|--------|------|--------|----------|--------|', ]) + if ascendant: + info = _ascendant_report_fields(ascendant) + asc_label = 'Ascendant' if _lang == 'en' else '上升' + dignity = 'not applicable' if _lang == 'en' else '不适用' + lines.append( + f"| {_cell(asc_label)} | {_cell(_token(info['sign_lord']))} | {_cell(_token(info['nakshatra_lord']))} | " + f"- | - | {_cell(dignity)} | - |" + ) for planet in ('Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu'): row = _dict(planets.get(planet)) if not row: @@ -1078,8 +1257,14 @@ def render_pl9_parity_markdown(packet: dict) -> str: ready_natal_specs = [spec for spec in natal_specs if spec[2]] if ready_natal_specs: lines.extend(['### p6-p17 本命与分盘北印度图盘', '', '分盘对出生时间敏感,原始计算供核对,不单独增加结论的确定性。', '']) - for page, label, _ready in ready_natal_specs: - lines.extend([f'##### p{page} · {label}', '']) + _append_parity_chart_fences( + lines, + language=_lang, + core_chart=core_chart, + worksheets=worksheets, + divisional=divisional, + varga_full=varga_full, + ) # The original PL9 charts are visual, but their sign placements are # still part of the visible evidence. Keep the chart drawing and add # a compact numeric transcription so an AI reader can recover the diff --git a/tests/test_report_chart_blank_columns.py b/tests/test_report_chart_blank_columns.py index 0aceffd7..13199233 100644 --- a/tests/test_report_chart_blank_columns.py +++ b/tests/test_report_chart_blank_columns.py @@ -150,6 +150,114 @@ def test_ashtakavarga_house_table_never_labels_the_total_as_sav(editions) -> Non assert row[5].isdigit() +_CALCULATION_CHART_IDS = { + "D1", "D2", "D3", "D4", "D7", "D9", "D10", "D11", "D12", + "D16", "D20", "D24", "D27", "D30", "D40", "D60", +} + + +def _section_until_next_h2(markdown: str, heading: str) -> str: + start = markdown.index(heading) + lines = [heading] + for line in markdown[start + len(heading):].splitlines(): + if line.startswith("## "): + break + lines.append(line) + return "\n".join(lines) + + +def test_full_data_chart_section_draws_each_ready_chart_once(editions) -> None: + from scripts.report_chart_block import FENCE_RE + zh, en, _packet = editions + for markdown, heading in ( + (zh, "### 本命与分盘北印度图盘"), + (en, "### Natal and Divisional North Indian Charts"), + ): + section = _section_until_next_h2(markdown, heading) + blocks = [] + for match in FENCE_RE.finditer(section): + block = json.loads(match.group(1)) + assert block["layout"] == "north" + blocks.append(block) + ids = [block["id"] for block in blocks] + assert ids + assert len(ids) == len(set(ids)) + assert _CALCULATION_CHART_IDS <= set(ids) + assert "MOON" in ids + assert not re.search(r"(?m)^##### .+\n\n+##### ", section) + assert not re.search(r"(?m)^##### .*Bhava", section) + assert "##### Navamsha" not in section and "##### p7 · Navamsha" not in section + + +def _heading_table(markdown: str, heading: str) -> list[list[str]]: + """Like _table_after, but the lord table is a #### heading, not ###.""" + lines = markdown.splitlines() + start = next(i for i, line in enumerate(lines) if line.startswith("#") and heading in line) + rows = [] + for line in lines[start + 1:]: + if line.startswith("#") or (rows and not line.startswith("|")): + break + if line.startswith("|") and not set(line) <= set("|- "): + rows.append([cell.strip() for cell in line.strip("|").split("|")]) + return rows + + +def test_birth_position_table_starts_with_the_ascendant(editions) -> None: + zh, en, packet = editions + asc = packet["core_chart"]["ascendant"] + longitude = asc.get("lon") if isinstance(asc.get("lon"), (int, float)) else asc.get("degree_raw") + fields = _nakshatra_fields(float(longitude)) + lord_zh = { + "Sun": "太阳", "Moon": "月亮", "Mars": "火星", "Mercury": "水星", + "Jupiter": "木星", "Venus": "金星", "Saturn": "土星", + "Rahu": "北交点", "Ketu": "南交点", + } + zh_rows = _heading_table(zh, "行星原始位置") + assert zh_rows[1][0] == "上升" + assert fields["nakshatra"] in zh_rows[1][6] + assert zh_rows[1][7] == str(fields["nakshatra_pada"]) + assert zh_rows[1][5] == "1" + lords = _heading_table(zh, "行星主星与状态") + assert lords[1][0] == "上升" + assert lords[1][5] == "不适用" + assert lords[1][2] in {fields["nakshatra_lord"], lord_zh.get(fields["nakshatra_lord"])} + en_rows = _heading_table(en, "Planetary Raw Positions") + assert en_rows[1][0] in {"Ascendant", "Lagna", "上升"} + assert fields["nakshatra"] in en_rows[1][6] + assert en_rows[1][7] == str(fields["nakshatra_pada"]) + + +def test_zh_hygiene_rejects_glued_english(editions) -> None: + from scripts.pl9_full_data_export import _pl9_markdown_hygiene_receipt, _zh_body_residue + injected = _pl9_markdown_hygiene_receipt("木星Jupiterexalted在巨蟹座\n", language="zh") + assert injected["status"] == "fail" + assert any(str(item).startswith("glued_latin:") for item in injected["violations"]) + residue = _zh_body_residue(editions[0]) + assert residue == {"glued_latin": 0, "function_words": 0} + + +def test_zh_hygiene_is_clean_on_night_and_a_public_chart() -> None: + from scripts.pl9_full_data_export import _zh_body_residue + # Public birth used by tests/smoke_test_runner.py. Not a private user. + public = { + **CASES["day"], + "name": "Albert Einstein", + "year": 1879, + "month": 3, + "day": 14, + "hour": 11, + "minute": 30, + "lat": 48.4, + "lon": 9.98, + "tz": 0.89, + "age": 76, + } + for case in (CASES["night"], public): + packet = _packet(case) + markdown = _pl9_export_markdown_for_edition(copy.deepcopy(packet), "full_data") + assert _zh_body_residue(markdown) == {"glued_latin": 0, "function_words": 0} + + def test_chart_section_carries_the_divisional_caveat(editions) -> None: zh, en, _ = editions assert re.search(r"### 本命与分盘北印度图盘\n\n" + re.escape(CAVEAT_ZH) + r"\n", zh)