dsh-metaphysics 0.46.5 → 0.50.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -0
- package/README.md +11 -6
- package/client.js +571 -54
- package/engine/almanac.js +7 -6
- package/engine/bazi.js +62 -0
- package/engine/classics.js +40 -3
- package/engine/crosscheck.js +29 -3
- package/engine/geju.js +49 -5
- package/engine/index.js +24 -6
- package/engine/interpret-knowledge.js +17 -8
- package/engine/interpret-plain.js +15 -2
- package/engine/interpret.js +41 -4
- package/engine/liuyao.js +100 -0
- package/package.json +2 -2
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +522 -76
|
@@ -14,17 +14,16 @@
|
|
|
14
14
|
<meta name="twitter:card" content="summary_large_image">
|
|
15
15
|
<style>
|
|
16
16
|
:root{--bg:#f3eee4;--panel:#fffdf8;--panel2:#f8f3e9;--line:#d6cbb7;--ink:#1a1916;--ink2:#3f3a33;--dim:#6f6a60;--gold:#a72c23;--gold-deep:#7d1f18;--good:#1f6f3f;--bad:#a72c23;--warn:#8a5a00;
|
|
17
|
+
/* 强调面(选中 tab、主按钮等实心底)与压在上面的文字色,两套配色各给一组 */
|
|
18
|
+
--accent-bg:#a72c23;--accent-bg2:#7d1f18;--on-accent:#fff;--on-accent-soft:rgba(255,255,255,.84);
|
|
17
19
|
--radius:12px;--shadow:0 1px 2px rgba(35,28,18,.05),0 18px 40px -30px rgba(35,28,18,.42);--ring:0 0 0 3px rgba(167,44,35,.16)}
|
|
18
20
|
/* 深色:跟随系统。只换变量,元素规则一条不改。@media screen 限定 → 打印永远浅色 */
|
|
19
21
|
@media screen and (prefers-color-scheme:dark){
|
|
20
22
|
:root{--bg:#12110d;--panel:#1b1913;--panel2:#221f18;--line:#3c372e;--ink:#e7e2d6;--ink2:#d5cfc2;--dim:#9b9488;--gold:#e2755f;--gold-deep:#b8503f;--good:#67b98a;--bad:#e2755f;--warn:#d9a052;
|
|
23
|
+
/* 深色下 --gold 是浅珊瑚,实心底若沿用原色,白字与深字都够不着 4.5:1;
|
|
24
|
+
所以强调面单独取一档更亮的珊瑚,压深色字(见 test/theme.test.mjs 的对比度复算) */
|
|
25
|
+
--accent-bg:#f0a38e;--accent-bg2:#e2755f;--on-accent:#14130f;--on-accent-soft:rgba(20,19,15,.84);
|
|
21
26
|
--shadow:0 1px 2px rgba(0,0,0,.5),0 18px 40px -30px rgba(0,0,0,.9);--ring:0 0 0 3px rgba(226,117,95,.2)}
|
|
22
|
-
/* 深色下强调色是浅色,这些实心底上的文字得反过来 */
|
|
23
|
-
.tab.on,.seg button.on,.go{color:#14130f}
|
|
24
|
-
.tool.on,.tool.on b{color:#14130f}
|
|
25
|
-
.tool.on span{color:rgba(20,19,15,.72)}
|
|
26
|
-
.mb-o.on b,.mb-o.on span,.mb-btn.primary{color:#14130f}
|
|
27
|
-
.err{background:rgba(226,117,95,.14)}
|
|
28
27
|
}
|
|
29
28
|
*{box-sizing:border-box}
|
|
30
29
|
html{-webkit-text-size-adjust:100%}
|
|
@@ -42,7 +41,7 @@ header{display:flex;flex-direction:column;align-items:stretch;gap:12px;margin-bo
|
|
|
42
41
|
.brand-row{display:flex;align-items:center;justify-content:space-between;gap:10px 16px;flex-wrap:wrap}
|
|
43
42
|
.brand{display:flex;align-items:center;gap:12px;font-size:22px;font-weight:700;letter-spacing:.14em;color:var(--gold);line-height:1.3}
|
|
44
43
|
.brand .seal{display:inline-flex;align-items:center;justify-content:center;flex:none;width:40px;height:40px;border-radius:11px;
|
|
45
|
-
background:linear-gradient(145deg,var(--
|
|
44
|
+
background:linear-gradient(145deg,var(--accent-bg),var(--accent-bg2));color:var(--on-accent);font:700 20px/1 "Songti SC","SimSun",serif;letter-spacing:0;
|
|
46
45
|
box-shadow:inset 0 0 0 1px rgba(255,255,255,.22),0 8px 18px -10px var(--gold)}
|
|
47
46
|
.brand-txt{display:block;min-width:0}
|
|
48
47
|
.brand-txt small{display:block;font-size:12.5px;letter-spacing:.02em;color:var(--dim);font-weight:400;margin-top:3px}
|
|
@@ -53,7 +52,7 @@ header{display:flex;flex-direction:column;align-items:stretch;gap:12px;margin-bo
|
|
|
53
52
|
.tab{display:flex;align-items:center;justify-content:center;text-align:center;padding:7px 10px;border-radius:999px;border:1px solid transparent;background:color-mix(in srgb,var(--panel) 62%,transparent);color:var(--dim);cursor:pointer;font-size:13.5px;font-family:inherit;white-space:nowrap;
|
|
54
53
|
transition:background .16s ease,color .16s ease,border-color .16s ease,box-shadow .16s ease}
|
|
55
54
|
.tab:hover{background:var(--panel);border-color:var(--line);color:var(--ink)}
|
|
56
|
-
.tab.on{background:linear-gradient(145deg,var(--
|
|
55
|
+
.tab.on{background:linear-gradient(145deg,var(--accent-bg),var(--accent-bg2));border-color:transparent;color:var(--on-accent);font-weight:600;box-shadow:0 8px 18px -12px var(--gold)}
|
|
57
56
|
/* 首屏按「想干什么」分组:19 个 tab 平铺时,第一次来的人得先猜「梅花」「称骨」是什么。
|
|
58
57
|
卡片只是另一套入口,点击仍走同一个 setTab;熟练用户可一键回到平铺(19 个 tab 原样保留)。 */
|
|
59
58
|
.view-switch{display:flex;align-items:center;gap:8px}
|
|
@@ -83,9 +82,9 @@ header{display:flex;flex-direction:column;align-items:stretch;gap:12px;margin-bo
|
|
|
83
82
|
.tool b{font-size:13.5px;font-weight:600;letter-spacing:.02em}
|
|
84
83
|
.tool span{font-size:11.5px;line-height:1.4;color:var(--dim)}
|
|
85
84
|
.tool:hover{border-color:var(--gold);background:var(--panel)}
|
|
86
|
-
.tool.on{border-color:transparent;background:linear-gradient(145deg,var(--
|
|
87
|
-
.tool.on b{color
|
|
88
|
-
.tool.on span{color:
|
|
85
|
+
.tool.on{border-color:transparent;background:linear-gradient(145deg,var(--accent-bg),var(--accent-bg2));box-shadow:0 8px 18px -12px var(--gold)}
|
|
86
|
+
.tool.on b{color:var(--on-accent)}
|
|
87
|
+
.tool.on span{color:var(--on-accent-soft)}
|
|
89
88
|
/* 奇数个的那一组:末项铺满整行,避免右下留一个孤格 */
|
|
90
89
|
.tool.wide{grid-column:1/-1}
|
|
91
90
|
/* 手机端每组先露 4 个,其余折在「还有 N 个」后面:三组全展开会把表单挤到第二屏 */
|
|
@@ -130,15 +129,15 @@ body.view-flat .start{display:none}
|
|
|
130
129
|
.mb-o b{font-size:14px;font-weight:600;color:var(--ink2);font-variant-numeric:tabular-nums}
|
|
131
130
|
.mb-o span{font-size:11.5px;line-height:1.3}
|
|
132
131
|
.mb-o:hover{border-color:color-mix(in srgb,var(--line) 40%,var(--gold))}
|
|
133
|
-
.mb-o.on{border-color:transparent;background:linear-gradient(145deg,var(--
|
|
134
|
-
.mb-o.on b,.mb-o.on span{color
|
|
132
|
+
.mb-o.on{border-color:transparent;background:linear-gradient(145deg,var(--accent-bg),var(--accent-bg2));box-shadow:0 8px 16px -12px var(--gold)}
|
|
133
|
+
.mb-o.on b,.mb-o.on span{color:var(--on-accent)}
|
|
135
134
|
.mb-o:focus-within{outline:2px solid var(--gold);outline-offset:2px}
|
|
136
135
|
.mb-nav{display:flex;align-items:center;gap:8px;margin-top:12px;flex-wrap:wrap}
|
|
137
136
|
.mb-btn{padding:8px 16px;border-radius:9px;border:1px solid var(--line);background:var(--panel2);color:var(--ink);font-family:inherit;font-size:13.5px;cursor:pointer;
|
|
138
137
|
transition:border-color .14s ease,background .14s ease,color .14s ease}
|
|
139
138
|
.mb-btn:hover:not(:disabled){border-color:var(--gold)}
|
|
140
139
|
.mb-btn:disabled{opacity:.42;cursor:not-allowed}
|
|
141
|
-
.mb-btn.primary{border-color:transparent;background:linear-gradient(145deg,var(--
|
|
140
|
+
.mb-btn.primary{border-color:transparent;background:linear-gradient(145deg,var(--accent-bg),var(--accent-bg2));color:var(--on-accent);font-weight:600;box-shadow:0 10px 20px -14px var(--gold)}
|
|
142
141
|
.mb-btn.primary:hover:not(:disabled){filter:brightness(1.05)}
|
|
143
142
|
.mb-hint{margin-left:auto;font-size:12.5px;color:var(--dim);line-height:1.6}
|
|
144
143
|
.mb-hint.warn{color:var(--bad);font-weight:600}
|
|
@@ -146,8 +145,8 @@ body.view-flat .start{display:none}
|
|
|
146
145
|
/* 必填未填:边框转红,提示复用 .err 的口径 */
|
|
147
146
|
.field.invalid textarea{border-color:var(--bad);background:rgba(224,102,95,.06)}
|
|
148
147
|
.field.check input{min-width:0;width:18px;height:18px;accent-color:var(--gold);padding:0}
|
|
149
|
-
.go{margin-left:0;grid-column:4;justify-self:end;align-self:end;padding:11px 24px;border-radius:9px;border:none;color
|
|
150
|
-
background:linear-gradient(145deg,var(--
|
|
148
|
+
.go{margin-left:0;grid-column:4;justify-self:end;align-self:end;padding:11px 24px;border-radius:9px;border:none;color:var(--on-accent);font-weight:600;cursor:pointer;font-family:inherit;font-size:15px;
|
|
149
|
+
background:linear-gradient(145deg,var(--accent-bg),var(--accent-bg2));box-shadow:0 10px 22px -14px var(--gold),inset 0 1px 0 rgba(255,255,255,.18);
|
|
151
150
|
transition:transform .14s ease,filter .14s ease,box-shadow .14s ease}
|
|
152
151
|
.go:hover{filter:brightness(1.06);transform:translateY(-1px);box-shadow:0 14px 26px -14px var(--gold),inset 0 1px 0 rgba(255,255,255,.22)}
|
|
153
152
|
.go:active{transform:translateY(0);filter:brightness(.98)}
|
|
@@ -167,7 +166,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
167
166
|
.seg{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden;background:var(--panel2)}
|
|
168
167
|
.seg button{padding:7px 14px;background:transparent;border:none;color:var(--dim);font-size:13.5px;font-family:inherit;cursor:pointer;transition:background .14s ease,color .14s ease}
|
|
169
168
|
.seg button:hover{color:var(--ink)}
|
|
170
|
-
.seg button.on{background:linear-gradient(145deg,var(--
|
|
169
|
+
.seg button.on{background:linear-gradient(145deg,var(--accent-bg),var(--accent-bg2));color:var(--on-accent);font-weight:600}
|
|
171
170
|
/* 结果入场:只做一次轻微上浮,不做循环动画 */
|
|
172
171
|
#out{animation:mp-rise .3s cubic-bezier(.2,.7,.3,1) both}
|
|
173
172
|
@keyframes mp-rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
|
|
@@ -190,7 +189,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
190
189
|
.askbox{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:16px 0 0;padding:11px 13px;border:1px dashed var(--line);border-radius:10px;background:color-mix(in srgb,var(--panel) 55%,transparent)}
|
|
191
190
|
.askbox input{flex:1 1 240px;min-width:0;background:var(--panel2);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:8px 12px;font-size:14px;font-family:inherit;outline:none}
|
|
192
191
|
.askbox input:focus{border-color:var(--gold);box-shadow:var(--ring)}
|
|
193
|
-
.askbox button{padding:8px 14px;border:1px solid transparent;border-radius:8px;background:var(--
|
|
192
|
+
.askbox button{padding:8px 14px;border:1px solid transparent;border-radius:8px;background:var(--accent-bg);color:var(--on-accent);font:inherit;font-size:13px;cursor:pointer}
|
|
194
193
|
.askbox button:hover{filter:brightness(1.08)}
|
|
195
194
|
.askbox .hint{font-size:12px;color:var(--dim)}
|
|
196
195
|
.method{max-width:860px;margin:0 auto;padding:24px 18px 40px;font-size:14px;line-height:1.9;color:var(--ink2)}
|
|
@@ -205,7 +204,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
205
204
|
.mp-verify-row{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:13px;padding:3px 0}
|
|
206
205
|
.mp-verify-btns{display:flex;gap:4px}
|
|
207
206
|
.mp-chip{font-size:12px;padding:2px 9px;border-radius:999px;border:1px solid var(--line);background:transparent;color:var(--dim);cursor:pointer;font-family:inherit}
|
|
208
|
-
.mp-chip.on{background:var(--
|
|
207
|
+
.mp-chip.on{background:var(--accent-bg);color:var(--on-accent);border-color:transparent}
|
|
209
208
|
.mp-verify-foot{display:flex;align-items:flex-start;gap:8px;margin-top:8px;flex-wrap:wrap}
|
|
210
209
|
.mp-verify-fit{font-size:12.5px;color:var(--dim);line-height:1.7;flex:1;min-width:0}
|
|
211
210
|
.mp-rect-row{display:flex;gap:6px;margin-bottom:6px}
|
|
@@ -264,8 +263,15 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
264
263
|
.bar{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;padding:14px}
|
|
265
264
|
.field{width:100%;min-width:0}
|
|
266
265
|
.field input,.field select,.field textarea,#addr,#changing,#direction{width:100%;min-width:0;padding:11px 12px;font-size:16px;min-height:44px}
|
|
266
|
+
/* 农历:子表单独占整行,方向分段按钮不再把「农历 → 公历」折成两行;
|
|
267
|
+
闰月改用 .field.check 的小号勾选框,不再被 .field input 的 width:100% 拉成大方块 */
|
|
268
|
+
#qk-convert{grid-column:1/-1}
|
|
269
|
+
#qk-convert .seg button{white-space:nowrap}
|
|
267
270
|
#for-ask{flex-direction:column;align-items:stretch}
|
|
268
|
-
.field
|
|
271
|
+
/* .field input 的 44px 高度是给文本框的;勾选框继承后会变成 18×44 的长条,
|
|
272
|
+
触摸区改由外层 label 撑(点文字也能勾),方块本身保持 18px */
|
|
273
|
+
.field.check{min-height:44px;padding-bottom:0;gap:10px}
|
|
274
|
+
.field.check input{min-height:0;height:18px}
|
|
269
275
|
#mh-num{flex-wrap:wrap}
|
|
270
276
|
#mh-num input{flex:1 1 30%;width:auto}
|
|
271
277
|
.seg{display:flex;width:100%}
|
|
@@ -338,7 +344,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
338
344
|
<div class="wrap">
|
|
339
345
|
<header>
|
|
340
346
|
<div class="brand-row">
|
|
341
|
-
<div class="brand"><span class="seal" aria-hidden="true">命</span><span class="brand-txt">命理排盘<span class="ver">v0.
|
|
347
|
+
<div class="brand"><span class="seal" aria-hidden="true">命</span><span class="brand-txt">命理排盘<span class="ver">v0.50.1</span><small>八字 · 紫微 · 六爻 · 梅花 · 六壬 · 奇门 · 合盘 · 塔罗 全部在本机计算</small></span></div>
|
|
342
348
|
<div class="view-switch">
|
|
343
349
|
<span class="hint">熟练了可以换回平铺</span>
|
|
344
350
|
<span class="seg" role="group" aria-label="首屏样式">
|
|
@@ -527,9 +533,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
527
533
|
</div>
|
|
528
534
|
<div id="qk-convert-lunar" style="display:none">
|
|
529
535
|
<label class="field">农历日期<input id="lunardate" placeholder="如 2026-9-17"></label>
|
|
530
|
-
<label class="field"
|
|
531
|
-
<input id="leapm" type="checkbox"> 闰月
|
|
532
|
-
</label>
|
|
536
|
+
<label class="field check">闰月<input id="leapm" type="checkbox"></label>
|
|
533
537
|
</div>
|
|
534
538
|
</div>
|
|
535
539
|
<div id="qk-xiaoliuren" style="display:none">
|
|
@@ -607,7 +611,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
607
611
|
<h3>对拍:把典籍当期望值</h3>
|
|
608
612
|
<ul><li>六爻:京房八宫卦序与世应,64 卦全表;旬空六旬表</li><li>六壬:日干寄宫、中气换将;紫微:纳音定五行局、紫微天府相照</li><li>卦例:《增删卜易》9 条 +《卜筮正宗》128 条(93 成对 + 35 静卦),核本变卦 / 动爻数 / 卦宫 / 缺爻 / 旬空</li></ul>
|
|
609
613
|
<h3>工程验证</h3>
|
|
610
|
-
<ul><li>测试:
|
|
614
|
+
<ul><li>测试:102 个测试文件 / 4406 条断言;七道闸(回归 · 断言基线 · 测试可失败自检 · HTML 注入面 · 工程约定 · 产物宿主形态 · 随机扫射)</li><li>可复现:seed / asOf 显式;同一输入同一输出</li><li>口径:晚子时、真太阳时、奇门三流派、闰月归月都可切换,并有字段级差异对照</li></ul>
|
|
611
615
|
<h3>已知边界(不猜)</h3>
|
|
612
616
|
<ul><li>六爻应期(具体哪天应验)不做;卦例只录动爻个数,不录爻位</li><li>财富/健康只给结构判断与档位,不给金额区间、不作诊断</li><li>紫微飞星已做「单一支化逐宫追到成环」与「三方四正 16 条按落宫归堆」,但都未叠大限流年四化、不折吉凶;八字交运日已能算到日/时,但未与第三方排盘案例批量对拍</li></ul>
|
|
613
617
|
<p class="note">内容用于传统文化学习与自我探索,不构成医疗、投资、法律或人事决策依据。</p>
|
|
@@ -3549,6 +3553,16 @@ const CLASSICS = [
|
|
|
3549
3553
|
plain: '成格不等于一路顺:成中带忌(官逢财又逢伤、官被合之类)就打了折;败格也未必无救——印来解伤、合来清煞,败中还能转成。',
|
|
3550
3554
|
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53629.html',
|
|
3551
3555
|
},
|
|
3556
|
+
{
|
|
3557
|
+
id: 'zp-zaji',
|
|
3558
|
+
book: 'ziping',
|
|
3559
|
+
chapter: '十六、论杂气如何取用',
|
|
3560
|
+
scene: '用神',
|
|
3561
|
+
tags: [],
|
|
3562
|
+
quote: '何谓透干?如甲生辰月,透戊则用偏财,透癸则用正印,透乙则用月劫是也。何谓会支?如甲生辰月,逢申与子会局,则用水印是也。一透则一用,兼透则兼用,透而又会,则透与会并用。',
|
|
3563
|
+
plain: '四墓(辰戌丑未)所藏不止一气,所以叫杂气:取用先看哪一藏干透到天干,透一个用一个;没有透干,再看地支有没有与月支会成三合局,会成什么局就取局中那一气。透干与会支同时成立时两样并用。原文对「兼透」只给原则,没有给取舍次序。',
|
|
3564
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53636.html',
|
|
3565
|
+
},
|
|
3552
3566
|
{
|
|
3553
3567
|
id: 'zp-bianhua',
|
|
3554
3568
|
book: 'ziping',
|
|
@@ -3825,6 +3839,20 @@ const CLASSICS = [
|
|
|
3825
3839
|
plain: '从财格要财会成局、日干无气;一见根气就破格,原文用「命损无猜」这种重话写明。以丁生酉月、柱多庚辛为例:只能弃命相从,行北方财官旺地为入格,南行则灾。',
|
|
3826
3840
|
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7652.html',
|
|
3827
3841
|
},
|
|
3842
|
+
// —— 三命通会 · 总论岁运:岁运提示一节的原文出处。
|
|
3843
|
+
// 原文的「返吟 / 伏吟」按「岁运与日柱相对 / 岁运压日」说,与本插件「干支相同为伏吟、天克地冲为反吟」
|
|
3844
|
+
// 不是同一套定义;口径照本插件,原文照录不改写,两者在 plain 里并列说明。
|
|
3845
|
+
// 这一条不进五条上限的取条表:它只在盘面有岁运信号时随「岁运提示」一起出现。
|
|
3846
|
+
{
|
|
3847
|
+
id: 'smt-suiyun',
|
|
3848
|
+
book: 'sanming',
|
|
3849
|
+
chapter: '卷二·总论岁运',
|
|
3850
|
+
scene: '岁运',
|
|
3851
|
+
tags: [],
|
|
3852
|
+
quote: '行运以生月为运元,最怕行运与太岁冲克,若岁运冲月必祸;若岁运与日相对,谓之返吟,岁运压日,谓之伏吟,二者不利六亲,非横破财,不为吉兆。',
|
|
3853
|
+
plain: '大运以生月为起点,最怕与流年(太岁)冲克:原文说岁运冲月为祸,又把「岁运与日柱相对」叫返吟、「岁运压日」叫伏吟。这两句是按「对日柱」说的,与本插件「干支相同为伏吟、天克地冲为反吟」不是同一套定义(本插件取后者);末句「不利六亲、破财」是旧说的重话,只作变动提示,不作断语。',
|
|
3854
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7539.html',
|
|
3855
|
+
},
|
|
3828
3856
|
];
|
|
3829
3857
|
|
|
3830
3858
|
const BY_ID = CLASSICS.reduce((m, e) => { m[e.id] = e; return m; }, {});
|
|
@@ -3861,6 +3889,14 @@ function classicOf(id) {
|
|
|
3861
3889
|
return BY_ID[id] || null;
|
|
3862
3890
|
}
|
|
3863
3891
|
|
|
3892
|
+
// 岁运提示的原文:盘面出现岁运并临 / 运年反吟 / 流年伏吟反吟时随该节给出,不占五条上限。
|
|
3893
|
+
// 没有信号就不给——这段原文讲的正是冲克,没冲没克时挂出来只会误导。
|
|
3894
|
+
function suiyunClassicOf(r) {
|
|
3895
|
+
const liunian = r && Array.isArray(r.liunian) ? r.liunian : [];
|
|
3896
|
+
const hit = liunian.some((l) => l && l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
3897
|
+
return hit ? classicOf('smt-suiyun') : null;
|
|
3898
|
+
}
|
|
3899
|
+
|
|
3864
3900
|
function tagOf(gejuName) {
|
|
3865
3901
|
const name = String(gejuName || '');
|
|
3866
3902
|
if (GEJU_KEY[name]) return GEJU_KEY[name];
|
|
@@ -3879,7 +3915,8 @@ function chapterTitle(e) {
|
|
|
3879
3915
|
}
|
|
3880
3916
|
|
|
3881
3917
|
// 根据一张八字结果挑原文:特殊结构(专旺/从格)先取单章,再月令格(子平真诠 + 三命通会对照),
|
|
3882
|
-
//
|
|
3918
|
+
// 再调候(寒暖/燥湿),最后「用神总纲」一位按盘四选一:有化气格取论用神变化、辰戌丑未月取论杂气如何取用、
|
|
3919
|
+
// 见组合取论用神成败救应、其余取通用总纲;去重、限量。
|
|
3883
3920
|
function classicsFor(r, limit = 5) {
|
|
3884
3921
|
if (!r) return [];
|
|
3885
3922
|
const out = [];
|
|
@@ -3917,12 +3954,16 @@ function classicsFor(r, limit = 5) {
|
|
|
3917
3954
|
if (tgEntry) {
|
|
3918
3955
|
push(tgEntry, `本盘忌${tg.foe}克用${tg.use},局中${tg.bridge}${tg.weight}分可作通关,故取${CLASSIC_BOOKS.ditian.name}「通关」一条`);
|
|
3919
3956
|
}
|
|
3920
|
-
//
|
|
3921
|
-
//
|
|
3957
|
+
// 用神总纲位只放一条,按盘四选一:化气看「变化」、四墓杂气看「杂气取用」、有组合看「成败救应」,
|
|
3958
|
+
// 都没有才回到四吉四凶总纲。不另加位次,是因为格局两条 + 气候两条正好占满 5 条上限。
|
|
3922
3959
|
const huagi = gejuList.find((g) => g && g.kind === '化气格');
|
|
3923
3960
|
const combo = gejuList.find((g) => g && g.kind === '组合');
|
|
3961
|
+
const monthBranch = r.monthBranch || (r.frame && r.frame.monthBranch) || (r.pillars && r.pillars.month && r.pillars.month.branch);
|
|
3962
|
+
const zaMonth = ['辰', '未', '戌', '丑'].includes(monthBranch);
|
|
3924
3963
|
if (huagi) {
|
|
3925
3964
|
push(classicOf('zp-bianhua'), `本盘列有「${huagi.name}」:用神由月令合化而变,总纲一位改取${CLASSIC_BOOKS.ziping.name}论用神变化`);
|
|
3965
|
+
} else if (zaMonth) {
|
|
3966
|
+
push(classicOf('zp-zaji'), `月令${monthBranch}属四墓杂气,取用先看透干、再看会支,总纲一位取${CLASSIC_BOOKS.ziping.name}论杂气如何取用`);
|
|
3926
3967
|
} else if (combo) {
|
|
3927
3968
|
push(classicOf('zp-chengbai'), `本盘另有「${combo.name}」组合:成格还要看带忌与救应,总纲一位改取${CLASSIC_BOOKS.ziping.name}论用神成败救应`);
|
|
3928
3969
|
} else {
|
|
@@ -3936,7 +3977,7 @@ function classicsText(rows) {
|
|
|
3936
3977
|
return rows.map((e) => `《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》「${e.quote}」`).join('\n');
|
|
3937
3978
|
}
|
|
3938
3979
|
|
|
3939
|
-
return { CLASSIC_BOOKS, CLASSICS, classicOf, classicsFor, classicsText };
|
|
3980
|
+
return { CLASSIC_BOOKS, CLASSICS, classicOf, suiyunClassicOf, classicsFor, classicsText };
|
|
3940
3981
|
})();
|
|
3941
3982
|
|
|
3942
3983
|
__mods.geju = (function () {
|
|
@@ -3951,6 +3992,7 @@ __mods.geju = (function () {
|
|
|
3951
3992
|
|
|
3952
3993
|
const { judgeClimate, arbitrate } = __mods.tiaohou;
|
|
3953
3994
|
const { qtOf } = __mods.qiongtong;
|
|
3995
|
+
const { sanheGroupOf } = __mods.sanhe;
|
|
3954
3996
|
|
|
3955
3997
|
const STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
|
|
3956
3998
|
const BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
|
|
@@ -4029,6 +4071,25 @@ function elementRoles(dayStem) {
|
|
|
4029
4071
|
|
|
4030
4072
|
// ── 月令格 ───────────────────────────────────────────────────
|
|
4031
4073
|
|
|
4074
|
+
// 四墓(杂气)月:辰戌丑未所藏多、用神不一,取用先看透干,再看会支。
|
|
4075
|
+
// 会支只认三合局——子平真诠十六「逢申与子会局」的例子即三合,三会方与兼透兼用仍不纳入。
|
|
4076
|
+
const ZA_MONTHS = ['辰', '未', '戌', '丑'];
|
|
4077
|
+
|
|
4078
|
+
function huiCandidate(pillars, monthBranch, cands) {
|
|
4079
|
+
if (!ZA_MONTHS.includes(monthBranch)) return null;
|
|
4080
|
+
const group = sanheGroupOf(monthBranch);
|
|
4081
|
+
if (!group) return null;
|
|
4082
|
+
const others = ['year', 'day', 'hour'];
|
|
4083
|
+
const need = group.branches.filter((b) => b !== monthBranch);
|
|
4084
|
+
if (!need.every((b) => others.some((k) => pillars[k].branch === b))) return null;
|
|
4085
|
+
const cand = cands.find((c) => STEM_ELEMENT[c.stem] === group.element);
|
|
4086
|
+
if (!cand) return null;
|
|
4087
|
+
const where = others
|
|
4088
|
+
.filter((k) => need.includes(pillars[k].branch))
|
|
4089
|
+
.map((k) => `${({ year: '年', day: '日', hour: '时' })[k]}支${pillars[k].branch}`);
|
|
4090
|
+
return { ...cand, group, where };
|
|
4091
|
+
}
|
|
4092
|
+
|
|
4032
4093
|
function monthPattern(pillars, dayStem, monthBranch) {
|
|
4033
4094
|
const hidden = HIDDEN[monthBranch] || [];
|
|
4034
4095
|
const cands = hidden.map((stem, i) => ({
|
|
@@ -4040,10 +4101,13 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
4040
4101
|
const others = ['year', 'month', 'hour'];
|
|
4041
4102
|
const exposedKey = others.find((k) => cands.some((c) => c.stem === pillars[k].stem));
|
|
4042
4103
|
const base = cands[0];
|
|
4043
|
-
const
|
|
4104
|
+
const hui = exposedKey ? null : huiCandidate(pillars, monthBranch, cands);
|
|
4105
|
+
const use = exposedKey ? cands.find((c) => c.stem === pillars[exposedKey].stem) : (hui || base);
|
|
4106
|
+
const usedBy = exposedKey ? '透干' : (hui ? '会支' : '本气');
|
|
4044
4107
|
const exposedPos = exposedKey ? { year: '年', month: '月', hour: '时' }[exposedKey] : null;
|
|
4045
4108
|
|
|
4046
|
-
|
|
4109
|
+
// 建禄只认日干的禄位;戊土辰月、己土未月这类「本气比肩但不在禄位」的杂气月不再冒称建禄
|
|
4110
|
+
if (base.god === '比肩' && LUSHEN_BRANCH[dayStem] === monthBranch) {
|
|
4047
4111
|
return {
|
|
4048
4112
|
name: '建禄格',
|
|
4049
4113
|
kind: '月令格',
|
|
@@ -4060,10 +4124,31 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
4060
4124
|
}
|
|
4061
4125
|
return { name: '月劫格', kind: '月令格', evidence: `月令${monthBranch}本气${base.stem}为劫财` };
|
|
4062
4126
|
}
|
|
4127
|
+
if (usedBy === '本气' && base.god === '比肩') {
|
|
4128
|
+
return {
|
|
4129
|
+
name: '比肩格',
|
|
4130
|
+
kind: '月令格',
|
|
4131
|
+
evidence: `月令${monthBranch}藏${hidden.join('')},本气${base.stem}为比肩,但${dayStem}禄在${LUSHEN_BRANCH[dayStem]}、不在${monthBranch},属杂气月比肩当权`,
|
|
4132
|
+
};
|
|
4133
|
+
}
|
|
4134
|
+
// 子平十六:「透乙则用月劫」——杂气月由透干或会支取到劫财时,仍作月劫论
|
|
4135
|
+
if (usedBy !== '本气' && use.god === '劫财') {
|
|
4136
|
+
const via = exposedKey ? `透于${exposedPos}干` : `${hui.where.join('、')}会成${hui.group.element}局`;
|
|
4137
|
+
return {
|
|
4138
|
+
name: '月劫格',
|
|
4139
|
+
kind: '月令格',
|
|
4140
|
+
evidence: `月令${monthBranch}藏${hidden.join('')},${use.pos}${use.stem}(劫财)${via},劫财为用,作月劫论`,
|
|
4141
|
+
};
|
|
4142
|
+
}
|
|
4063
4143
|
const name = `${use.god}格`;
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4144
|
+
let ex;
|
|
4145
|
+
if (exposedKey) {
|
|
4146
|
+
ex = `月令${monthBranch}藏${hidden.join('')},${use.pos}${use.stem}(${use.god})透于${exposedPos}干`;
|
|
4147
|
+
} else if (hui) {
|
|
4148
|
+
ex = `月令${monthBranch}藏${hidden.join('')},本气${base.stem}(${base.god})未透干,而${hui.where.join('、')}会成${hui.group.element}局,取${use.pos}${use.stem}(${use.god})为用`;
|
|
4149
|
+
} else {
|
|
4150
|
+
ex = `月令${monthBranch}藏${hidden.join('')},本气${base.stem}(${base.god})未透干,以月令本气取格`;
|
|
4151
|
+
}
|
|
4067
4152
|
return { name, kind: '月令格', evidence: ex };
|
|
4068
4153
|
}
|
|
4069
4154
|
|
|
@@ -4382,6 +4467,24 @@ const HIDDEN_STEMS = {
|
|
|
4382
4467
|
亥: ['壬', '甲'],
|
|
4383
4468
|
};
|
|
4384
4469
|
|
|
4470
|
+
// 人元司权的 30 日表:余气 → 中气 → 本气,按「节」当日起算。
|
|
4471
|
+
// 各家对日数分法不一(另有 7/7/16、9/3/18 等),这里固定通行 30 日表;
|
|
4472
|
+
// 只作解释层的一层细节,不参与取格。亥月的余气戊不在本柱藏干表中,两表各照原样。
|
|
4473
|
+
const RENYUAN_TABLE = {
|
|
4474
|
+
寅: [['戊', 7], ['丙', 7], ['甲', 16]],
|
|
4475
|
+
卯: [['甲', 10], ['乙', 20]],
|
|
4476
|
+
辰: [['乙', 9], ['癸', 3], ['戊', 18]],
|
|
4477
|
+
巳: [['戊', 5], ['庚', 9], ['丙', 16]],
|
|
4478
|
+
午: [['丙', 10], ['己', 9], ['丁', 11]],
|
|
4479
|
+
未: [['丁', 9], ['乙', 3], ['己', 18]],
|
|
4480
|
+
申: [['戊', 7], ['壬', 3], ['庚', 20]],
|
|
4481
|
+
酉: [['庚', 10], ['辛', 20]],
|
|
4482
|
+
戌: [['辛', 9], ['丁', 3], ['戊', 18]],
|
|
4483
|
+
亥: [['戊', 7], ['甲', 5], ['壬', 18]],
|
|
4484
|
+
子: [['壬', 10], ['癸', 20]],
|
|
4485
|
+
丑: [['癸', 9], ['辛', 3], ['己', 18]],
|
|
4486
|
+
};
|
|
4487
|
+
|
|
4385
4488
|
const STEM_ELEMENT = {
|
|
4386
4489
|
甲: '木', 乙: '木', 丙: '火', 丁: '火', 戊: '土',
|
|
4387
4490
|
己: '土', 庚: '金', 辛: '金', 壬: '水', 癸: '水',
|
|
@@ -4558,6 +4661,45 @@ function applyTrueSolar(jd, longitude) {
|
|
|
4558
4661
|
};
|
|
4559
4662
|
}
|
|
4560
4663
|
|
|
4664
|
+
/**
|
|
4665
|
+
* 人元司权:生在本月第几日、哪一藏干当权。
|
|
4666
|
+
* 日数按「节令日」与出生日的日差计,节当日为第 1 日;固定 30 日表,
|
|
4667
|
+
* 第 31 日以后不再硬分摊,按本气算并标 beyond。
|
|
4668
|
+
* @param {string} monthBranch 月支(寅…丑)
|
|
4669
|
+
* @param {number} birthJdn 出生日的儒略日数(含真太阳时修正后的日)
|
|
4670
|
+
* @param {number} termJd 本月「节」的儒略日
|
|
4671
|
+
*/
|
|
4672
|
+
function renyuanOf(monthBranch, birthJdn, termJd) {
|
|
4673
|
+
const table = RENYUAN_TABLE[monthBranch];
|
|
4674
|
+
if (!table) return null;
|
|
4675
|
+
const segments = [];
|
|
4676
|
+
let from = 1;
|
|
4677
|
+
for (const [stem, days] of table) {
|
|
4678
|
+
segments.push({ stem, element: STEM_ELEMENT[stem], from, to: from + days - 1 });
|
|
4679
|
+
from += days;
|
|
4680
|
+
}
|
|
4681
|
+
const tableDays = from - 1;
|
|
4682
|
+
const day = Math.max(1, Math.floor(birthJdn) - Math.floor(termJd + 0.5) + 1);
|
|
4683
|
+
const beyond = day > tableDays;
|
|
4684
|
+
const idx = beyond ? segments.length - 1 : segments.findIndex((s) => day >= s.from && day <= s.to);
|
|
4685
|
+
const seg = segments[idx] || segments[segments.length - 1];
|
|
4686
|
+
const next = segments[idx + 1] || null;
|
|
4687
|
+
return {
|
|
4688
|
+
month: monthBranch,
|
|
4689
|
+
day,
|
|
4690
|
+
tableDays,
|
|
4691
|
+
segments,
|
|
4692
|
+
active: seg.stem,
|
|
4693
|
+
activeElement: seg.element,
|
|
4694
|
+
segment: { from: seg.from, to: seg.to },
|
|
4695
|
+
next: next ? { stem: next.stem, element: next.element, from: next.from, inDays: next.from - day } : null,
|
|
4696
|
+
// 司权表与本柱藏干表口径不同:亥月的余气戊只出现在司权表里
|
|
4697
|
+
inHidden: (HIDDEN_STEMS[monthBranch] || []).includes(seg.stem),
|
|
4698
|
+
beyond,
|
|
4699
|
+
note: '人元司权按「节」当日起算,节当日为第 1 日,日差用本盘所用时刻(含真太阳时)所在日计;本插件固定 30 日表(余气 → 中气 → 本气),第 31 日以后按本气算。只作解释层的一层细节,不改取格。',
|
|
4700
|
+
};
|
|
4701
|
+
}
|
|
4702
|
+
|
|
4561
4703
|
/**
|
|
4562
4704
|
* 排四柱八字
|
|
4563
4705
|
* @param {object} input { year,month,day,hour,minute, gender:'male'|'female', longitude?, lateZi?:boolean, trueSolar?:boolean }
|
|
@@ -4880,6 +5022,10 @@ function buildBazi(input) {
|
|
|
4880
5022
|
const bodyStemIdx = (yinStem + ((bodyIdx - 2 + 12) % 12)) % 10;
|
|
4881
5023
|
const shengong = ganzhiName(sexagenaryIndex(bodyStemIdx, bodyIdx));
|
|
4882
5024
|
|
|
5025
|
+
// 人元司权:按节令到出生日的日差定当权藏干(节当日为第 1 日)
|
|
5026
|
+
const renyuan = renyuanOf(BRANCHES[monthBranchIdx], jdnBase, prevJieTerm.jd);
|
|
5027
|
+
if (renyuan) renyuan.term = { name: prevJieTerm.name, time: formatJd(prevJieTerm.jd) };
|
|
5028
|
+
|
|
4883
5029
|
return {
|
|
4884
5030
|
system: 'bazi',
|
|
4885
5031
|
relations: buildRelations(pillars),
|
|
@@ -4912,6 +5058,7 @@ function buildBazi(input) {
|
|
|
4912
5058
|
// 与 NAOJ 历要项对拍实测节气最多偏 13.5 分钟,20 分钟留出余量。
|
|
4913
5059
|
nearBoundaryMinutes: Math.round(Math.min(jd - prevJieTerm.jd, nextJieTerm.jd - jd) * 1440),
|
|
4914
5060
|
},
|
|
5061
|
+
renyuan,
|
|
4915
5062
|
pillars,
|
|
4916
5063
|
dayMaster: { stem: dayStem, element: STEM_ELEMENT[dayStem], yinYang: isYangStem(dayStem) ? '阳' : '阴' },
|
|
4917
5064
|
wuxing,
|
|
@@ -4944,7 +5091,7 @@ function buildBazi(input) {
|
|
|
4944
5091
|
};
|
|
4945
5092
|
}
|
|
4946
5093
|
|
|
4947
|
-
return { HIDDEN_STEMS, STEM_ELEMENT, BRANCH_ELEMENT, buildRelations, tenGod, nayin, applyTrueSolar, buildBazi };
|
|
5094
|
+
return { HIDDEN_STEMS, RENYUAN_TABLE, STEM_ELEMENT, BRANCH_ELEMENT, buildRelations, tenGod, nayin, applyTrueSolar, renyuanOf, buildBazi };
|
|
4948
5095
|
})();
|
|
4949
5096
|
|
|
4950
5097
|
__mods.liuyao = (function () {
|
|
@@ -5016,6 +5163,7 @@ const LIUSHEN_START = { 甲: 0, 乙: 0, 丙: 1, 丁: 1, 戊: 2, 己: 3, 庚: 4,
|
|
|
5016
5163
|
const ZHI_CHONG_PAIRS = [['子', '午'], ['丑', '未'], ['寅', '申'], ['卯', '酉'], ['辰', '戌'], ['巳', '亥']];
|
|
5017
5164
|
const ZHI_HE_PAIRS = [['子', '丑'], ['寅', '亥'], ['卯', '戌'], ['辰', '酉'], ['巳', '申'], ['午', '未']];
|
|
5018
5165
|
const CHONG_OF = Object.fromEntries(ZHI_CHONG_PAIRS.flatMap(([a, b]) => [[a, b], [b, a]]));
|
|
5166
|
+
const HE_OF = Object.fromEntries(ZHI_HE_PAIRS.flatMap(([a, b]) => [[a, b], [b, a]]));
|
|
5019
5167
|
const TRIGRAM_OPPOSITE = { 乾: '巽', 巽: '乾', 坎: '离', 离: '坎', 艮: '坤', 坤: '艮', 震: '兑', 兑: '震' };
|
|
5020
5168
|
|
|
5021
5169
|
// ── 化进神 / 化退神 ────────────────────────────────────────────────
|
|
@@ -5881,7 +6029,106 @@ function jinTuiPower(result, opts = {}) {
|
|
|
5881
6029
|
};
|
|
5882
6030
|
}
|
|
5883
6031
|
|
|
5884
|
-
|
|
6032
|
+
// ── 应期线索:只列「该留意哪一支」,不给日期 ─────────────────────────
|
|
6033
|
+
// 知识卡 liuyao-yingqi 的承诺是「只作时间窗口的提示」:传统取用神逢值、
|
|
6034
|
+
// 逢冲、逢合之期,旬空另等出空、冲空。这里只把这些地支列出来,再按月建给
|
|
6035
|
+
// 一个快慢方向;不换算成日期、不排先后、不判忌神受制,也不叠动变连环。
|
|
6036
|
+
const YINGQI_TEMPO = ['偏速', '偏缓', '待解', '未定'];
|
|
6037
|
+
const TEMPO_SAY = {
|
|
6038
|
+
偏速: '用神得月令之气,应期偏近',
|
|
6039
|
+
偏缓: '用神失月令之气,应期偏远',
|
|
6040
|
+
待解: '有月破或旬空的用神,先等条件解除',
|
|
6041
|
+
未定: '快慢不定(缺月建,或用神两现而旺衰不一)',
|
|
6042
|
+
};
|
|
6043
|
+
const TRIGGER_ORDER = ['逢值', '逢冲', '逢合', '出空填实', '冲空'];
|
|
6044
|
+
|
|
6045
|
+
/**
|
|
6046
|
+
* 应期线索:用神逢值、逢冲、逢合,旬空另标出空与冲空。
|
|
6047
|
+
* @param {object} result buildLiuyao 的结果
|
|
6048
|
+
* @param {object} useGod yongshenOf 的结果
|
|
6049
|
+
* @param {{monthBranch?: string}} opts
|
|
6050
|
+
*/
|
|
6051
|
+
function yingqiWindow(result, useGod, opts = {}) {
|
|
6052
|
+
if (!useGod || !useGod.liuqin) return null;
|
|
6053
|
+
const found = Array.isArray(useGod.found) ? useGod.found : [];
|
|
6054
|
+
const fushen = Array.isArray(useGod.fushen) ? useGod.fushen : [];
|
|
6055
|
+
const viaFushen = !found.length && fushen.length > 0;
|
|
6056
|
+
const source = found.length ? found : fushen;
|
|
6057
|
+
if (!source.length) return null;
|
|
6058
|
+
const monthBranch = opts.monthBranch || null;
|
|
6059
|
+
const monthElement = monthBranch ? zhiElementOf(monthBranch) : null;
|
|
6060
|
+
const kong = Array.isArray(result && result.xunKong)
|
|
6061
|
+
? result.xunKong
|
|
6062
|
+
: (result && typeof result.xunKong === 'string' ? result.xunKong.split('') : []);
|
|
6063
|
+
|
|
6064
|
+
const items = source.map((l) => {
|
|
6065
|
+
const branch = l.branch;
|
|
6066
|
+
const element = l.element || zhiElementOf(branch);
|
|
6067
|
+
const monthState = monthStateOf(element, monthElement);
|
|
6068
|
+
const isEmpty = kong.includes(branch);
|
|
6069
|
+
const monthChong = !!(monthBranch && CHONG_OF[branch] === monthBranch);
|
|
6070
|
+
const tempo = monthChong ? '待解'
|
|
6071
|
+
: isEmpty ? '待解'
|
|
6072
|
+
: monthState === 'unknown' ? '未定'
|
|
6073
|
+
: (monthState === '旺' || monthState === '相') ? '偏速' : '偏缓';
|
|
6074
|
+
const tempoSay = monthChong ? `遭${monthBranch}冲(月破),先待出月或填实`
|
|
6075
|
+
: isEmpty ? '用神旬空,先待出空填实'
|
|
6076
|
+
: monthState === 'unknown' ? '缺月建,快慢不定'
|
|
6077
|
+
: `月建${monthState},${tempo === '偏速' ? '应期偏近' : '应期偏远'}`;
|
|
6078
|
+
const triggers = [
|
|
6079
|
+
{ branch, labels: ['逢值'] },
|
|
6080
|
+
{ branch: CHONG_OF[branch] || null, labels: ['逢冲'] },
|
|
6081
|
+
{ branch: HE_OF[branch] || null, labels: ['逢合'] },
|
|
6082
|
+
];
|
|
6083
|
+
if (isEmpty) {
|
|
6084
|
+
triggers[0].labels.push('出空填实');
|
|
6085
|
+
triggers[1].labels.push('冲空');
|
|
6086
|
+
}
|
|
6087
|
+
return {
|
|
6088
|
+
position: l.position,
|
|
6089
|
+
branch,
|
|
6090
|
+
element,
|
|
6091
|
+
monthState,
|
|
6092
|
+
monthChong,
|
|
6093
|
+
kong: isEmpty,
|
|
6094
|
+
tempo,
|
|
6095
|
+
tempoSay,
|
|
6096
|
+
triggers,
|
|
6097
|
+
};
|
|
6098
|
+
});
|
|
6099
|
+
|
|
6100
|
+
// 用神两现时各爻的支可能不同:按支归并标签,不替谁选主用
|
|
6101
|
+
const merged = new Map();
|
|
6102
|
+
for (const it of items) {
|
|
6103
|
+
for (const t of it.triggers) {
|
|
6104
|
+
if (!t.branch) continue;
|
|
6105
|
+
const cur = merged.get(t.branch) || { branch: t.branch, labels: [] };
|
|
6106
|
+
for (const lb of t.labels) if (!cur.labels.includes(lb)) cur.labels.push(lb);
|
|
6107
|
+
merged.set(t.branch, cur);
|
|
6108
|
+
}
|
|
6109
|
+
}
|
|
6110
|
+
const triggers = [...merged.values()].map((t) => ({
|
|
6111
|
+
branch: t.branch,
|
|
6112
|
+
labels: [...t.labels].sort((a, b) => TRIGGER_ORDER.indexOf(a) - TRIGGER_ORDER.indexOf(b)),
|
|
6113
|
+
}));
|
|
6114
|
+
const tempos = items.map((x) => x.tempo);
|
|
6115
|
+
const tempo = tempos.includes('待解') ? '待解'
|
|
6116
|
+
: tempos.every((t) => t === '偏速') ? '偏速'
|
|
6117
|
+
: tempos.every((t) => t === '偏缓') ? '偏缓' : '未定';
|
|
6118
|
+
|
|
6119
|
+
return {
|
|
6120
|
+
month: monthBranch ? { branch: monthBranch, element: monthElement } : null,
|
|
6121
|
+
viaFushen,
|
|
6122
|
+
tempo,
|
|
6123
|
+
tempoSay: TEMPO_SAY[tempo],
|
|
6124
|
+
items,
|
|
6125
|
+
triggers,
|
|
6126
|
+
labels: [`应期${tempo}`, ...triggers.map((t) => `${t.labels.join('/')}${t.branch}`)],
|
|
6127
|
+
note: '应期只给「该留意哪一支」与快慢方向:用神逢值、逢冲、逢合,旬空另标出空与冲空。不换算成日期、不排先后、不判忌神受制;近事以日计、远事以月计,用哪把尺由事情远近决定,本插件不代选。',
|
|
6128
|
+
};
|
|
6129
|
+
}
|
|
6130
|
+
|
|
6131
|
+
return { jinTuiOf, hexBody, bodyRelations, bodyLabels, HEXAGRAM_COUNT, hexagramFromBits, YONGSHEN_RULES, yongshenOf, tossLines, buildLiuyao, zhiElementOf, monthStateOf, dayRelationOf, yongshenStrength, FUSHEN_VERDICTS, fushenAccess, hexagramStrength, jinTuiPower, YINGQI_TEMPO, yingqiWindow };
|
|
5885
6132
|
})();
|
|
5886
6133
|
|
|
5887
6134
|
__mods.ziwei = (function () {
|
|
@@ -11050,9 +11297,10 @@ __mods.almanac = (function () {
|
|
|
11050
11297
|
// 提供:农历日期、年/月/日干支(年按立春界,另列春节界生肖)、节气、建除十二神、
|
|
11051
11298
|
// 冲煞(冲什么生肖 / 煞在何方)、财神与喜神方位、建除简表宜忌、每日一卦。
|
|
11052
11299
|
//
|
|
11053
|
-
// 诚实边界:本插件不依赖 lunar-javascript
|
|
11054
|
-
//
|
|
11055
|
-
//
|
|
11300
|
+
// 诚实边界:本插件不依赖 lunar-javascript;逐日全量吉神凶煞与彭祖百忌未收录——
|
|
11301
|
+
// 输出里如实标注「未收录」,不臆造。值日十二神、二十八宿、胎神、吉神方位按通行表收录
|
|
11302
|
+
// (见返回值的 scope)。宜忌只按「建除十二神」通行简表给出(传统择日的第一层判据),
|
|
11303
|
+
// 不是逐日全量黄历。
|
|
11056
11304
|
const { solarToLunar } = __mods.lunar;
|
|
11057
11305
|
const { nayinOf } = __mods.nayin;
|
|
11058
11306
|
const { toJDN, fromJDN, dayGanzhiIndex, ganzhiName, termWindow, termInstantJd, partsToJd, STEMS, BRANCHES, TERM_NAMES } = __mods.calendar;
|
|
@@ -11155,7 +11403,7 @@ function tianShenOf(branch, anchorBranch) {
|
|
|
11155
11403
|
return { name, type, luck: type === '黄道' ? '吉' : '凶' };
|
|
11156
11404
|
}
|
|
11157
11405
|
|
|
11158
|
-
/** 二十八宿:值日宿按「日支 +
|
|
11406
|
+
/** 二十八宿:值日宿按「日支 + 星期」轮转(四组各七宿)。宿名按通行「宿·五行·动物」写法(壁水貐、胃土雉)。 */
|
|
11159
11407
|
const MANSIONS = {
|
|
11160
11408
|
角: { luck: '吉', zheng: '木', animal: '蛟', gong: '东' }, 亢: { luck: '凶', zheng: '金', animal: '龙', gong: '东' },
|
|
11161
11409
|
氐: { luck: '凶', zheng: '土', animal: '貉', gong: '东' }, 房: { luck: '吉', zheng: '日', animal: '兔', gong: '东' },
|
|
@@ -11163,9 +11411,9 @@ const MANSIONS = {
|
|
|
11163
11411
|
箕: { luck: '吉', zheng: '水', animal: '豹', gong: '东' }, 斗: { luck: '吉', zheng: '木', animal: '獬', gong: '北' },
|
|
11164
11412
|
牛: { luck: '凶', zheng: '金', animal: '牛', gong: '北' }, 女: { luck: '凶', zheng: '土', animal: '蝠', gong: '北' },
|
|
11165
11413
|
虚: { luck: '凶', zheng: '日', animal: '鼠', gong: '北' }, 危: { luck: '凶', zheng: '月', animal: '燕', gong: '北' },
|
|
11166
|
-
室: { luck: '吉', zheng: '火', animal: '猪', gong: '北' }, 壁: { luck: '吉', zheng: '水', animal: '
|
|
11414
|
+
室: { luck: '吉', zheng: '火', animal: '猪', gong: '北' }, 壁: { luck: '吉', zheng: '水', animal: '貐', gong: '北' },
|
|
11167
11415
|
奎: { luck: '凶', zheng: '木', animal: '狼', gong: '西' }, 娄: { luck: '吉', zheng: '金', animal: '狗', gong: '西' },
|
|
11168
|
-
胃: { luck: '吉', zheng: '土', animal: '
|
|
11416
|
+
胃: { luck: '吉', zheng: '土', animal: '雉', gong: '西' }, 昴: { luck: '凶', zheng: '日', animal: '鸡', gong: '西' },
|
|
11169
11417
|
毕: { luck: '吉', zheng: '月', animal: '乌', gong: '西' }, 觜: { luck: '凶', zheng: '火', animal: '猴', gong: '西' },
|
|
11170
11418
|
参: { luck: '吉', zheng: '水', animal: '猿', gong: '西' }, 井: { luck: '吉', zheng: '木', animal: '犴', gong: '南' },
|
|
11171
11419
|
鬼: { luck: '凶', zheng: '金', animal: '羊', gong: '南' }, 柳: { luck: '凶', zheng: '土', animal: '獐', gong: '南' },
|
|
@@ -12634,6 +12882,19 @@ function jinTuiPlain(r) {
|
|
|
12634
12882
|
return `动爻的进退还要看时令:${jp.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type},${sayOf(l)}`).join(';')}。`;
|
|
12635
12883
|
}
|
|
12636
12884
|
|
|
12885
|
+
// 应期线索 → 一句白话:只给快慢与可留意的支,不换算日期
|
|
12886
|
+
function yingqiPlain(r) {
|
|
12887
|
+
const yq = r && r.yingqi;
|
|
12888
|
+
if (!yq || !Array.isArray(yq.triggers) || !yq.triggers.length) return '';
|
|
12889
|
+
const when = yq.tempo === '偏速' ? '大体偏近,近事更容易先见分晓'
|
|
12890
|
+
: yq.tempo === '偏缓' ? '大体偏远,别指望立刻见分晓'
|
|
12891
|
+
: yq.tempo === '待解' ? '眼下还有月破或旬空,得先等条件解除'
|
|
12892
|
+
: '缺月建,快慢暂不定';
|
|
12893
|
+
const branches = yq.triggers.map((t) => t.branch).join('、');
|
|
12894
|
+
const fu = yq.viaFushen ? '(用神是伏神,先要出得来)' : '';
|
|
12895
|
+
return `应期上${when};传统会留意${branches}这几个地支${fu}——这只是提示,不换算成具体哪天。`;
|
|
12896
|
+
}
|
|
12897
|
+
|
|
12637
12898
|
// 全卦逐爻旺衰 → 一句白话:整张卦的气偏在哪一头(与用神那一句分开说)
|
|
12638
12899
|
function hexStrengthPlain(hs) {
|
|
12639
12900
|
if (!hs || !hs.counts) return '';
|
|
@@ -12744,7 +13005,7 @@ function buildAnswer(r, ask, ctx = {}) {
|
|
|
12744
13005
|
head + `先说结论:本卦是${s(ben.name, '—')}` +
|
|
12745
13006
|
`${ben.palace ? `(${ben.palace})` : ''}` +
|
|
12746
13007
|
`${moving.length ? `,第 ${moving.join('、')} 爻动,变为${s(bian.name, '—')}` : ',六爻安静没有动爻'}。` +
|
|
12747
|
-
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
13008
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${yingqiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
12748
13009
|
'断卦的落点在「世爻」(代表你)和「动爻」(事情的推动点),下面「看盘顺序」就按这个次序展开。',
|
|
12749
13010
|
].join('');
|
|
12750
13011
|
}
|
|
@@ -12812,7 +13073,7 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
12812
13073
|
const plainBody = bodyPlainOf(labels);
|
|
12813
13074
|
return `${s(ben.name, '这一卦')}讲的是一个「${moving.length ? '正在动、还会变' : '暂时不动、先看清'}」的局面——` +
|
|
12814
13075
|
`${moving.length ? '有动爻,说明事情还有转圜空间,不是死局。' : '六爻安静,说明当下更该观察而不是硬推。'}` +
|
|
12815
|
-
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
13076
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${yingqiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
12816
13077
|
}
|
|
12817
13078
|
return '';
|
|
12818
13079
|
}
|
|
@@ -12931,10 +13192,10 @@ const KNOWLEDGE = [
|
|
|
12931
13192
|
id: 'bazi-yueling-siquan',
|
|
12932
13193
|
system: 'bazi', dims: ['overall', 'career'],
|
|
12933
13194
|
gist: '月令不是「一个月」,是当月最有权的那一个字。',
|
|
12934
|
-
detail: '
|
|
13195
|
+
detail: '月令藏干按本气、中气、余气分日用事,本气当权的时间最长。所以判旺衰先看日主在月令是得令还是失令——得令者未看全局,已有三分底气。本插件按 30 日表算出「生在本月第几日、哪一干当权」,给的是月内轮值这一层细节;旺衰与取格仍以月令本气、透干与会支为主,不随轮值改判。',
|
|
12935
13196
|
source: '《子平真诠》论用神;人元司权分日之说见《渊海子平》',
|
|
12936
13197
|
status: 'variant',
|
|
12937
|
-
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18
|
|
13198
|
+
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18 等多说);本插件固定通行 30 日表(如寅月戊7丙7甲16),节当日为第 1 日,第 31 日以后按本气算、不硬分摊。司权表与本柱藏干表口径不同(子月壬、卯月甲、午月丙、酉月庚、亥月戊只出现在司权表里),两表各照原样;取格不随轮值改判。',
|
|
12938
13199
|
},
|
|
12939
13200
|
{
|
|
12940
13201
|
id: 'bazi-tonggen-tougan',
|
|
@@ -12982,8 +13243,8 @@ const KNOWLEDGE = [
|
|
|
12982
13243
|
id: 'bazi-suiyun',
|
|
12983
13244
|
system: 'bazi', dims: ['overall', 'career'],
|
|
12984
13245
|
gist: '大运管十年基调,流年管当年触发。',
|
|
12985
|
-
detail: '
|
|
12986
|
-
source: '
|
|
13246
|
+
detail: '大运像换了条路,流年像这条路上某一段的天气。岁运并临(当值大运与流年干支相同)、运年反吟(大运与流年天克地冲)、流年伏吟(流年与原局某柱干支相同)与流年反吟(流年与原局某柱天克地冲),是传统上标记「变动较大」的年份,属于提示而非断语。本插件逐年标出四类信号:当值大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列;只标干支重复与对冲,不折分数。原文里「返吟」指岁运与日柱相对、「伏吟」指岁运压日,与本插件「干支相同为伏吟、天克地冲为反吟」不是同一套定义,两者并列、不合并。',
|
|
13247
|
+
source: '《三命通会》卷二·总论岁运(https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7539.html);岁运并临之说出自《渊海子平》',
|
|
12987
13248
|
status: 'variant',
|
|
12988
13249
|
note: '「岁运并临主大凶」是流传最广也最被滥用的说法,本插件只作变动提示,不断吉凶;大运与原局之间的伏吟反吟未逐年标注,四柱十神层面的引化也未叠入。',
|
|
12989
13250
|
},
|
|
@@ -13041,6 +13302,15 @@ const KNOWLEDGE = [
|
|
|
13041
13302
|
status: 'variant',
|
|
13042
13303
|
note: '化气格成立条件各家宽严不一(是否要求月令为化神、日主是否允许有根),本插件只列条件、附原文,不据此断定化气已成。',
|
|
13043
13304
|
},
|
|
13305
|
+
{
|
|
13306
|
+
id: 'bazi-zaji-quyong',
|
|
13307
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
13308
|
+
gist: '辰戌丑未是杂气月:先看透干,再看会支。',
|
|
13309
|
+
detail: '四墓(辰戌丑未)每个字都藏着不止一气,用神不一,所以叫杂气。子平真诠的取法是:藏干透到天干的先用(甲生辰月,透戊用偏财、透癸用正印、透乙用月劫);没有透干,再看地支有没有与月支会成三合局(辰月逢申子会水,就取水印)。本插件按「透干 → 三合会支 → 本气」的次序取格,依据里写明走的是哪一条,并把《论杂气如何取用》附在结果里。',
|
|
13310
|
+
source: '《子平真诠》十六、论杂气如何取用',
|
|
13311
|
+
status: 'variant',
|
|
13312
|
+
note: '原文说「兼透则兼用」,但只给一个格名时总要落到一个藏干;本插件只取最先透出的那一干,会支也只认三合、不认三会方,且不判原文所说的「有情 / 无情」,取舍次序各家另有说法。',
|
|
13313
|
+
},
|
|
13044
13314
|
{
|
|
13045
13315
|
id: 'bazi-zhuanwang-yuanwen',
|
|
13046
13316
|
system: 'bazi', dims: ['overall', 'career'],
|
|
@@ -13206,10 +13476,10 @@ const KNOWLEDGE = [
|
|
|
13206
13476
|
id: 'liuyao-yingqi',
|
|
13207
13477
|
system: 'liuyao', dims: ['overall', 'career'],
|
|
13208
13478
|
gist: '应期是「什么时候见分晓」,不是「哪天」。',
|
|
13209
|
-
detail: '
|
|
13479
|
+
detail: '近事以日计、远事以月计;常见取法是等用神逢值、逢冲、逢合之期,或等忌神受制之期。本插件只做前一半:把用神(不上卦则取伏神)的逢值、逢冲、逢合三支列出,旬空另标出空与冲空,再按月建五态给「偏速 / 偏缓 / 待解 / 未定」一个快慢方向;忌神受制与具体日期仍未做。应期法各家互有出入,同一卦不同取法可以差出很远,所以只作时间窗口的提示。',
|
|
13210
13480
|
source: '《卜筮正宗》应期章;《增删卜易》',
|
|
13211
13481
|
status: 'variant',
|
|
13212
|
-
note: '
|
|
13482
|
+
note: '应期取法(值日、冲、合、填实、旬空出空)各家优先级不同,本插件只并列触发支、不排先后,也不换算日期;近事以日计、远事以月计,用哪把尺由事情远近决定,不代选。',
|
|
13213
13483
|
},
|
|
13214
13484
|
{
|
|
13215
13485
|
id: 'liuyao-liushen',
|
|
@@ -13366,10 +13636,10 @@ const KNOWLEDGE = [
|
|
|
13366
13636
|
id: 'liuyao-yingqi-exact',
|
|
13367
13637
|
system: 'liuyao', dims: [],
|
|
13368
13638
|
gist: '具体应期(哪一天应验)本插件尚未推算。',
|
|
13369
|
-
detail: '
|
|
13639
|
+
detail: '应期需要综合用神旺衰、动变、旬空出空、日月冲合多层条件,且各家取法不同。当前只给时间窗口的方向性提示(逢值 / 逢冲 / 逢合的触发支,加一个快慢方向),不给具体日期——与其给一个看起来精确、实则拍脑袋的日子,不如留白。',
|
|
13370
13640
|
source: '待补:《卜筮正宗》应期章逐条实现 + 已录 128 条卦例对拍(源 138 条)',
|
|
13371
13641
|
status: 'todo',
|
|
13372
|
-
note: '扩展方向:用《卜筮正宗》卦例里有明确应验日期的条目做回归,先验证再输出。',
|
|
13642
|
+
note: '扩展方向:用《卜筮正宗》卦例里有明确应验日期的条目做回归,先验证再输出。0.50.0 已给出触发支与快慢方向,仍不输出日期。',
|
|
13373
13643
|
},
|
|
13374
13644
|
];
|
|
13375
13645
|
|
|
@@ -14213,6 +14483,19 @@ function baziInterpret(r) {
|
|
|
14213
14483
|
`⑤ 落到维度:工作看喜用五行与十神权重;感情看配偶星与日支;健康看最旺与最弱的五行。五维度都只是这套推导的应用,不是另一套算法。`,
|
|
14214
14484
|
].join('\n'),
|
|
14215
14485
|
},
|
|
14486
|
+
...(r.renyuan ? [(() => {
|
|
14487
|
+
const ry = r.renyuan;
|
|
14488
|
+
const table = ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' / ');
|
|
14489
|
+
const nextSeg = ry.next ? `,第 ${ry.next.from} 日起交 ${ry.next.stem}${ry.next.element}` : '';
|
|
14490
|
+
const outside = ry.inHidden ? '' : ` 表里的 ${ry.active} 不在本柱藏干表中(属余气口径),两表各照原样,不互相改写。`;
|
|
14491
|
+
const beyond = ry.beyond ? ' 你生在第 31 日以后,已超出 30 日表,按本气算,不硬分摊。' : '';
|
|
14492
|
+
return {
|
|
14493
|
+
key: 'renyuan', label: '人元司权',
|
|
14494
|
+
text: `生于${ry.month}月第 ${ry.day} 日(从${ry.term ? ry.term.name : '节'}起算,节当日为第 1 日,日差按本盘所用时刻所在日计):这一日由 **${ry.active}${ry.activeElement}** 司权,第 ${ry.segment.from}–${ry.segment.to} 日属它${nextSeg}。\n`
|
|
14495
|
+
+ '月令这一个月里,余气、中气、本气轮值,不是整月同一个五行当值——所以「月令是什么」,还要看生在第几日。\n'
|
|
14496
|
+
+ `**口径**:本插件固定 30 日表(${table});另有 7/7/16、9/3/18 等分法,各家不一。分日只作解释层的一层细节,**不改取格**:取格仍按本气、透干与会支判定。${outside}${beyond}`,
|
|
14497
|
+
};
|
|
14498
|
+
})()] : []),
|
|
14216
14499
|
{
|
|
14217
14500
|
key: 'timeline', label: '时间窗',
|
|
14218
14501
|
text: (() => {
|
|
@@ -14233,6 +14516,8 @@ function baziInterpret(r) {
|
|
|
14233
14516
|
{ key: 'advice', label: '专业建议', text: adviceText },
|
|
14234
14517
|
(() => {
|
|
14235
14518
|
const hits = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
14519
|
+
const e = suiyunClassicOf(r);
|
|
14520
|
+
const src = e ? `\n原文:《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》「${e.quote}」\n白话:${e.plain}` : '';
|
|
14236
14521
|
return {
|
|
14237
14522
|
key: 'suiyun', label: '岁运提示',
|
|
14238
14523
|
text: hits.length
|
|
@@ -14240,7 +14525,7 @@ function baziInterpret(r) {
|
|
|
14240
14525
|
const stem = (l.suiyun.dayun || []).map((d) => `第${d.step}步${d.ganzhi}`).join('、');
|
|
14241
14526
|
return `${l.year} ${l.ganzhi}(${stem || '未到起运'}):${l.suiyun.signals.map((s) => s.detail).join(';')}`;
|
|
14242
14527
|
}).join('\n') +
|
|
14243
|
-
'\n读法:岁运并临、运年反吟与流年伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。'
|
|
14528
|
+
'\n读法:岁运并临、运年反吟与流年伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。' + src
|
|
14244
14529
|
: '近十年没有岁运并临、运年反吟或流年伏吟/反吟。「岁运并临主大凶」这类说法流传很广,本插件只把它当变动提示,没有命中就不作额外解读。',
|
|
14245
14530
|
};
|
|
14246
14531
|
})(),
|
|
@@ -15025,10 +15310,32 @@ function liuyaoInterpret(r, ask) {
|
|
|
15025
15310
|
useText.push(`时令对用神:${head},日辰 ${strength.day ? `${strength.day.branch}(${strength.day.element})` : '—'}。${body.join(';')}。`);
|
|
15026
15311
|
useText.push('月建看这一段时令站在哪一边,日辰看当天那股力量是扶还是克;两处同时看,只报状态,不折成分数。');
|
|
15027
15312
|
}
|
|
15028
|
-
useText.push('
|
|
15313
|
+
useText.push('这一层只把用神、卦体与时令对起来,不折成分数、不断成败;应期另在「应期线索」一节只给触发支与快慢。');
|
|
15029
15314
|
sections.push({ key: 'yongshen', label: '用神落位与卦体', text: useText.join('\n') });
|
|
15030
15315
|
}
|
|
15031
15316
|
|
|
15317
|
+
// 应期线索:只给触发支与快慢方向,不给日期
|
|
15318
|
+
{
|
|
15319
|
+
const yq = r.yingqi;
|
|
15320
|
+
if (yq && Array.isArray(yq.items) && yq.items.length) {
|
|
15321
|
+
const rows = yq.items.map((it) => {
|
|
15322
|
+
const flags = [
|
|
15323
|
+
it.monthState && it.monthState !== 'unknown' ? `月建${it.monthState}` : '',
|
|
15324
|
+
it.monthChong ? '月破' : '',
|
|
15325
|
+
it.kong ? '旬空' : '',
|
|
15326
|
+
].filter(Boolean).join('、');
|
|
15327
|
+
return `${it.position}爻${it.branch}${it.element}${flags ? `(${flags})` : ''}:${it.tempoSay}`;
|
|
15328
|
+
});
|
|
15329
|
+
sections.push({
|
|
15330
|
+
key: 'yingqi',
|
|
15331
|
+
label: '应期线索',
|
|
15332
|
+
text: `应期快慢:${yq.tempoSay}。${rows.join(';')}。可留意的地支:${yq.triggers.map((t) => `${t.branch}(${t.labels.join('、')})`).join(';')}。` +
|
|
15333
|
+
`${yq.viaFushen ? '用神不上卦,这里的支取自伏神;伏神要先得出才算数。' : ''}` +
|
|
15334
|
+
'这一节只把传统的「逢值、逢冲、逢合」与旬空的出空、冲空摆出来,不换算成具体日期、不排先后、也不判忌神受制;近事以日计、远事以月计,用哪把尺取决于事情本身。',
|
|
15335
|
+
});
|
|
15336
|
+
}
|
|
15337
|
+
}
|
|
15338
|
+
|
|
15032
15339
|
// 全卦逐爻旺衰:不挑用神,六爻都过一遍,看整张卦的气压在哪一头
|
|
15033
15340
|
{
|
|
15034
15341
|
const hs = r.hexStrength;
|
|
@@ -15058,7 +15365,7 @@ function liuyaoInterpret(r, ask) {
|
|
|
15058
15365
|
|
|
15059
15366
|
sections.push({
|
|
15060
15367
|
key: 'limits', label: '未纳入',
|
|
15061
|
-
text: '
|
|
15368
|
+
text: '本卦没有计算:用神两现时该取哪一爻的权重、应期的具体日期(只给逢值/逢冲/逢合的触发支与快慢方向)、忌神受制的时点、动变连环。化进/化退的力重只按月建五态给「得令/失令」这类档位,不折成加权分数;这些都会改变"旺不旺"的判断,所以这里只给取象与方向。',
|
|
15062
15369
|
});
|
|
15063
15370
|
|
|
15064
15371
|
const dimensions = [
|
|
@@ -15484,7 +15791,7 @@ const BUILDERS = {
|
|
|
15484
15791
|
const { interpretQimen } = __mods['qimen-interpret'];
|
|
15485
15792
|
const { buildAnswer, buildPlain, buildGlossary, buildFollowups, dimensionPlain } = __mods['interpret-plain'];
|
|
15486
15793
|
const { knowledgeFor, caveatsFor, STATUS_LABEL } = __mods['interpret-knowledge'];
|
|
15487
|
-
const { CLASSIC_BOOKS } = __mods.classics;
|
|
15794
|
+
const { CLASSIC_BOOKS, suiyunClassicOf } = __mods.classics;
|
|
15488
15795
|
|
|
15489
15796
|
/**
|
|
15490
15797
|
* 给任意体系的解析结果补上「白话四层」:直答 / 说人话 / 每维一句话 / 追问建议。
|
|
@@ -16012,16 +16319,33 @@ function crossCheck(bazi, zw) {
|
|
|
16012
16319
|
const bad = ['忌', '大忌'];
|
|
16013
16320
|
const baziGood = good.includes(t);
|
|
16014
16321
|
const baziBad = bad.includes(t);
|
|
16322
|
+
const baziKnown = t !== '—';
|
|
16015
16323
|
const ziweiHeavy = sha >= 2;
|
|
16324
|
+
const ziweiKnown = !!d;
|
|
16016
16325
|
let stance = '有张力';
|
|
16017
|
-
let note = '
|
|
16018
|
-
if (
|
|
16326
|
+
let note = '';
|
|
16327
|
+
if (!baziKnown || !ziweiKnown) {
|
|
16328
|
+
// 一边没取到就谈不上「同向 / 有张力」——只并列现有的一侧,并写清缺的是哪边
|
|
16329
|
+
stance = '互补';
|
|
16330
|
+
const missing = !baziKnown && !ziweiKnown
|
|
16331
|
+
? '八字当前大运与紫微当前大限都没取到'
|
|
16332
|
+
: !baziKnown
|
|
16333
|
+
? `八字当前大运未取到(${t}),只有紫微一侧可参考`
|
|
16334
|
+
: '紫微当前大限未取到,只有八字一侧可参考';
|
|
16335
|
+
note = `${missing}:这一项只作提醒,不下两边对照的结论`;
|
|
16336
|
+
} else if (baziGood && ziweiHeavy) {
|
|
16337
|
+
note = '八字这边顺、紫微大限煞星偏多:大方向可参考八字,具体动作按紫微标出的位置收一收';
|
|
16338
|
+
} else if (baziBad && !ziweiHeavy) {
|
|
16339
|
+
note = '八字这边偏紧、紫微大限没见到明显煞星:先按八字收着走,紫微一侧的平静不等于没有压力';
|
|
16340
|
+
} else if (!baziGood && !baziBad && ziweiHeavy) {
|
|
16341
|
+
note = '八字大运为平、紫微大限煞星偏多:只把紫微这一侧当作提醒,不据此判断阶段好坏';
|
|
16342
|
+
} else {
|
|
16019
16343
|
stance = '同向';
|
|
16020
16344
|
note = '两边对当前阶段的松紧判断接近';
|
|
16021
16345
|
}
|
|
16022
16346
|
push('rhythm', '当前节奏',
|
|
16023
16347
|
`大运档位 ${t}`,
|
|
16024
|
-
|
|
16348
|
+
d ? `大限在${d.palace}${sha ? `;煞星 ${sha} 颗` : ';无煞星'}` : '大限未取到',
|
|
16025
16349
|
stance, note);
|
|
16026
16350
|
}
|
|
16027
16351
|
|
|
@@ -16036,8 +16360,17 @@ function crossText(cross) {
|
|
|
16036
16360
|
.map((i) => `· ${i.label}:八字——${i.bazi};紫微——${i.ziwei};判断:${i.stance}(${i.note})`)
|
|
16037
16361
|
.join('\n');
|
|
16038
16362
|
}
|
|
16363
|
+
|
|
16364
|
+
/**
|
|
16365
|
+
* 交叉验证分节。文本给 Markdown/工具输出,items 给面板画对照卡——
|
|
16366
|
+
* 同一份数据两个去处,免得面板再去拆文本。
|
|
16367
|
+
*/
|
|
16368
|
+
function crossSection(cross) {
|
|
16369
|
+
const items = cross && Array.isArray(cross.items) ? cross.items : [];
|
|
16370
|
+
return { key: 'crossSystem', label: '八字 × 紫微 交叉验证', text: crossText(cross), items };
|
|
16371
|
+
}
|
|
16039
16372
|
|
|
16040
|
-
return { crossCheck, crossText };
|
|
16373
|
+
return { crossCheck, crossText, crossSection };
|
|
16041
16374
|
})();
|
|
16042
16375
|
|
|
16043
16376
|
__mods.verify = (function () {
|
|
@@ -16246,7 +16579,7 @@ return { matchEvent, rectifyBirth, RECTIFY_KINDS };
|
|
|
16246
16579
|
__mods.index = (function () {
|
|
16247
16580
|
// 统一入口:解析参数、分派到各体系、生成可读摘要
|
|
16248
16581
|
const { buildBazi } = __mods.bazi;
|
|
16249
|
-
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, fushenAccess, hexagramStrength, jinTuiPower } = __mods.liuyao;
|
|
16582
|
+
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, fushenAccess, hexagramStrength, jinTuiPower, yingqiWindow } = __mods.liuyao;
|
|
16250
16583
|
const { buildZiwei, BRIGHTNESS, flowOf, asOfParts, ZIWEI_SCHOOL_DEFAULTS } = __mods.ziwei;
|
|
16251
16584
|
const { drawTarot } = __mods.tarot;
|
|
16252
16585
|
const { buildMeihua } = __mods.meihua;
|
|
@@ -16259,7 +16592,7 @@ const { toJDN, ganzhiName, dayGanzhiIndex } = __mods.calendar;
|
|
|
16259
16592
|
const { randomOf, isSeed } = __mods.random;
|
|
16260
16593
|
const { interpret, DIRECTIONS, DIRECTION_DEFAULT } = __mods.interpret;
|
|
16261
16594
|
const { followup, askPrompt } = __mods.followup;
|
|
16262
|
-
const { crossCheck, crossText } = __mods.crosscheck;
|
|
16595
|
+
const { crossCheck, crossText, crossSection } = __mods.crosscheck;
|
|
16263
16596
|
const { pastSignals, verifyFit } = __mods.verify;
|
|
16264
16597
|
const { rectifyBirth } = __mods.rectify;
|
|
16265
16598
|
const { buildAlmanac } = __mods.almanac;
|
|
@@ -16270,7 +16603,7 @@ const { buildStar } = __mods.star;
|
|
|
16270
16603
|
const { buildNumerology } = __mods.numerology;
|
|
16271
16604
|
const { buildMbti, mbtiPaper } = __mods.mbti;
|
|
16272
16605
|
const { buildConvert } = __mods.convert;
|
|
16273
|
-
const { classicsFor, classicsText } = __mods.classics;
|
|
16606
|
+
const { classicsFor, classicsText, suiyunClassicOf, CLASSIC_BOOKS } = __mods.classics;
|
|
16274
16607
|
const { buildTrend } = __mods.trend;
|
|
16275
16608
|
const { buildFengshui } = __mods.fengshui;
|
|
16276
16609
|
const { buildName } = __mods.name;
|
|
@@ -16372,6 +16705,10 @@ function baziText(r) {
|
|
|
16372
16705
|
? `神煞(${r.shensha.count} 见):` + r.shensha.groups.map((g) =>
|
|
16373
16706
|
`${g.cat}|` + g.items.map((i) => `${i.name}(${i.pillars.map((k) => SHORT[k]).join('')})`).join('、')).join(';')
|
|
16374
16707
|
: '神煞:—';
|
|
16708
|
+
const ry = r.renyuan;
|
|
16709
|
+
const renyuanLine = ry
|
|
16710
|
+
? `人元:${ry.month}月第${ry.day}日,${ry.active}${ry.activeElement}司权(${ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' ')})${ry.beyond ? ';已过 30 日表,按本气算' : ''}`
|
|
16711
|
+
: '';
|
|
16375
16712
|
const gejuLine = r.frame ? [
|
|
16376
16713
|
`格局:${r.frame.primary ? `${r.frame.primary.name}(${r.frame.primary.evidence})` : '—'}`,
|
|
16377
16714
|
` ${r.frame.geju.map((g) => `${g.name}[${g.kind}]`).join(' ')}`,
|
|
@@ -16394,6 +16731,7 @@ function baziText(r) {
|
|
|
16394
16731
|
shenshaLine,
|
|
16395
16732
|
`真太阳时:${r.solarTime.trueSolarText}(${r.input.geo ? r.input.geo.note + ';' : ''}${r.solarTime.note}) 晚子时:${r.input.lateZi ? '23:00 后算次日' : '23:00 后仍算当日'}`,
|
|
16396
16733
|
`节气:上一节 ${r.jieqi.previous.name} ${r.jieqi.previous.time} 下一节 ${r.jieqi.next.name} ${r.jieqi.next.time}`,
|
|
16734
|
+
...(renyuanLine ? [renyuanLine] : []),
|
|
16397
16735
|
`大运:${r.dayun.rule}(${r.dayun.direction}),${r.dayun.startAge.years}岁${r.dayun.startAge.months}个月起运${jiao}`,
|
|
16398
16736
|
` ${dayun}`,
|
|
16399
16737
|
`流年:${r.liunian.slice(0, 10).map((l) => `${l.year}${l.ganzhi}(${l.stemTenGod})${l.luck ? `·${l.luck.tier}` : ''}`).join(' ')}`,
|
|
@@ -16401,8 +16739,10 @@ function baziText(r) {
|
|
|
16401
16739
|
const hits = r.liunian.filter((l) => l.suiyun && l.suiyun.signals && l.suiyun.signals.length);
|
|
16402
16740
|
if (!hits.length) return '岁运提示:近十年无岁运并临、运年反吟或流年伏吟/反吟(只标干支,不判吉凶)';
|
|
16403
16741
|
const label = (s) => `${s.type}${s.type.startsWith('流年') && s.target ? `(${s.target})` : ''}`;
|
|
16742
|
+
const e = suiyunClassicOf(r);
|
|
16743
|
+
const src = e ? `|古籍见《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》` : '';
|
|
16404
16744
|
return '岁运提示(只标干支变动,不判吉凶):' + hits
|
|
16405
|
-
.map((l) => `${l.year}${l.ganzhi} ${l.suiyun.signals.map(label).join('/')}`).join(';');
|
|
16745
|
+
.map((l) => `${l.year}${l.ganzhi} ${l.suiyun.signals.map(label).join('/')}`).join(';') + src;
|
|
16406
16746
|
})(),
|
|
16407
16747
|
'(格局、用神、行运吉凶为扶抑+简化调候的量化提示,非断语。)',
|
|
16408
16748
|
].join('\n') + near;
|
|
@@ -16654,6 +16994,11 @@ function liuyaoText(r) {
|
|
|
16654
16994
|
if (jt && Array.isArray(jt.lines) && jt.lines.length) {
|
|
16655
16995
|
out.push(`进退力重:${jt.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type}·${l.verdict}`).join(' · ')}`);
|
|
16656
16996
|
}
|
|
16997
|
+
// 应期线索:只列地支与快慢,不给日期
|
|
16998
|
+
const yq = r.yingqi;
|
|
16999
|
+
if (yq && Array.isArray(yq.triggers) && yq.triggers.length) {
|
|
17000
|
+
out.push(`应期线索:${yq.tempo} · ${yq.triggers.map((t) => `${t.labels.join('/')}${t.branch}`).join(' · ')}(只列地支,不出日期)`);
|
|
17001
|
+
}
|
|
16657
17002
|
return out.filter(Boolean).join('\n');
|
|
16658
17003
|
}
|
|
16659
17004
|
|
|
@@ -16674,6 +17019,9 @@ function compute(args = {}) {
|
|
|
16674
17019
|
r.classics = classicsFor(r);
|
|
16675
17020
|
const ct = classicsText(r.classics);
|
|
16676
17021
|
if (ct) r.summary = `${r.summary}\n【古籍】\n${ct}`;
|
|
17022
|
+
// 岁运提示的原文不占五条上限:只在盘面真有岁运信号时挂到结果上,摘要、解析层与面板各自取用
|
|
17023
|
+
const syc = suiyunClassicOf(r);
|
|
17024
|
+
if (syc) r.suiyunClassic = { ...syc, bookName: CLASSIC_BOOKS[syc.book].name };
|
|
16677
17025
|
}
|
|
16678
17026
|
// 超出 ΔT 覆盖范围时把精度提示顶到摘要最前,别让远期盘悄悄出错
|
|
16679
17027
|
if (r && r.precision && r.precision.level === 'approx' && r.summary) {
|
|
@@ -16708,7 +17056,7 @@ function compute(args = {}) {
|
|
|
16708
17056
|
: buildBazi({ ...common, lateZi: args.lateZi !== false, nowYear: asOf ? asOf.year : undefined });
|
|
16709
17057
|
r.cross = crossCheck(r.system === 'bazi' ? r : other, r.system === 'ziwei' ? r : other);
|
|
16710
17058
|
if (r.interpret) {
|
|
16711
|
-
r.interpret.sections.push(
|
|
17059
|
+
r.interpret.sections.push(crossSection(r.cross));
|
|
16712
17060
|
}
|
|
16713
17061
|
}
|
|
16714
17062
|
// 验前事:把过去若干年的流年信号摊开(只读,不改盘)
|
|
@@ -16991,6 +17339,9 @@ function computeRaw(args = {}) {
|
|
|
16991
17339
|
// 伏神出伏条件:飞伏生克叠月建日辰,只判条件、不出应期
|
|
16992
17340
|
const chufu = fushenAccess(result, ug, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
16993
17341
|
if (chufu) result.fushenAccess = chufu;
|
|
17342
|
+
// 应期线索:只列逢值/逢冲/逢合与旬空的出空/冲空,再给快慢方向,不换算日期
|
|
17343
|
+
const yq = yingqiWindow(result, ug, { monthBranch });
|
|
17344
|
+
if (yq) result.yingqi = yq;
|
|
16994
17345
|
}
|
|
16995
17346
|
if (args.seed !== undefined && args.seed !== null && args.seed !== '') result.seed = Number(args.seed);
|
|
16996
17347
|
return { ...result, ...(asOf ? { asOf } : {}), summary: liuyaoText(result) };
|
|
@@ -17455,7 +17806,7 @@ function renderText(result) {
|
|
|
17455
17806
|
|
|
17456
17807
|
|
|
17457
17808
|
|
|
17458
|
-
return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAddress, resolveAddress, buildBazi, buildLiuyao, tossLines, followup, askPrompt, pastSignals, verifyFit, rectifyBirth, crossCheck, crossText, buildAlmanac, buildZeri, buildChenggu, buildXiaoliuren, buildStar, buildNumerology, buildConvert, buildTrend, buildFengshui, buildName, parseDateTime, compute, interpretText, renderText };
|
|
17809
|
+
return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAddress, resolveAddress, buildBazi, buildLiuyao, tossLines, followup, askPrompt, pastSignals, verifyFit, rectifyBirth, crossCheck, crossText, crossSection, buildAlmanac, buildZeri, buildChenggu, buildXiaoliuren, buildStar, buildNumerology, buildConvert, buildTrend, buildFengshui, buildName, parseDateTime, compute, interpretText, renderText };
|
|
17459
17810
|
})();
|
|
17460
17811
|
|
|
17461
17812
|
window.Engine = __mods.index;
|
|
@@ -17623,6 +17974,8 @@ window.Engine = __mods.index;
|
|
|
17623
17974
|
.pp-str b{color:var(--red);font-size:15px;margin:0 4px}
|
|
17624
17975
|
.pp-drel{font-style:normal;color:var(--red);font-size:12px}
|
|
17625
17976
|
.pp-dim{color:var(--muted)}
|
|
17977
|
+
/* 岁运提示下的原文:比正文再轻一档,只做出处,不抢结论 */
|
|
17978
|
+
.pp-sy-src{margin-top:6px;font-size:11.5px;line-height:1.55}
|
|
17626
17979
|
.pp-r{display:none}
|
|
17627
17980
|
.pp-modes{display:flex;align-items:center;border-bottom:1px solid var(--line);font-family:system-ui,sans-serif}
|
|
17628
17981
|
/* min-height:44px —— 视图切换是本盘唯一的主要控件,触摸目标必须够。
|
|
@@ -17936,7 +18289,8 @@ window.Engine = __mods.index;
|
|
|
17936
18289
|
/* —— 解析与详解 —— */
|
|
17937
18290
|
/* 变量由上面的 .pp,.mp-it 共享块提供。这里原先写过 --ink:var(--ink) 这类自引用声明,
|
|
17938
18291
|
自引用会让变量变成 guaranteed-invalid,反而把继承值也挡掉了(--card 因此彻底失效)。 */
|
|
17939
|
-
|
|
18292
|
+
/* container-type:dsh 侧栏是「窗口宽、报告窄」,@media 不触发;下面 ≤640 的表格/目录规则另挂一份 @container */
|
|
18293
|
+
.mp-it{margin-top:14px;border:1px solid var(--line);background:var(--bg);color:var(--ink);border-radius:12px;overflow:hidden;box-shadow:var(--shadow);container-type:inline-size;
|
|
17940
18294
|
font-family:"Songti SC","SimSun","Microsoft YaHei",serif;font-size:13px;line-height:1.75}
|
|
17941
18295
|
.mp-it *{box-sizing:border-box}
|
|
17942
18296
|
/* 标题栏即折叠开关:整栏可点,箭头旋转表示状态 */
|
|
@@ -18037,6 +18391,19 @@ window.Engine = __mods.index;
|
|
|
18037
18391
|
.mp-it-conf.c-强{color:var(--lu);border-color:rgba(var(--lu-rgb),.4)}
|
|
18038
18392
|
.mp-it-conf.c-中{color:var(--label);border-color:var(--line)}
|
|
18039
18393
|
.mp-it-conf.c-弱{color:var(--red);border-color:rgba(var(--red-rgb),.4)}
|
|
18394
|
+
/* 交叉验证:一个方面一张对照卡,八字与紫微左右并列,判断做成语气标签 */
|
|
18395
|
+
.mp-cross{display:flex;flex-direction:column;gap:8px;font-family:system-ui,sans-serif}
|
|
18396
|
+
.mp-cross-row{border:1px solid var(--line);border-radius:8px;background:var(--card);padding:9px 11px}
|
|
18397
|
+
.mp-cross-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
18398
|
+
.mp-cross-l{font-size:13px;font-weight:700;color:var(--ink);letter-spacing:.02em}
|
|
18399
|
+
.mp-cross-tag{font-size:11px;line-height:1.5;padding:1px 8px;border:1px solid currentColor;border-radius:999px;color:var(--muted)}
|
|
18400
|
+
.mp-cross-tag.t-good{color:var(--lu)}
|
|
18401
|
+
.mp-cross-tag.t-watch{color:var(--quan)}
|
|
18402
|
+
.mp-cross-tag.t-alt{color:var(--ke)}
|
|
18403
|
+
.mp-cross-b{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:4px 14px;margin-top:7px}
|
|
18404
|
+
.mp-cross-cell{font-size:12.5px;line-height:1.75;color:var(--ink2)}
|
|
18405
|
+
.mp-cross-cell b{display:block;font-size:10.5px;letter-spacing:.1em;color:var(--muted);font-weight:600;margin-bottom:1px}
|
|
18406
|
+
.mp-cross-note{margin-top:7px;padding-top:6px;border-top:1px dashed var(--line);font-size:12px;line-height:1.7;color:var(--muted)}
|
|
18040
18407
|
/* 三张表:横向可滚动,避免窄栏撑破 */
|
|
18041
18408
|
.mp-tables{border-top:1px solid var(--line);padding:12px 16px 4px;background:var(--card)}
|
|
18042
18409
|
.mp-table-wrap{margin-bottom:12px}
|
|
@@ -18044,7 +18411,8 @@ window.Engine = __mods.index;
|
|
|
18044
18411
|
.mp-table-scroll{overflow-x:auto;border:1px solid var(--line);border-radius:8px}
|
|
18045
18412
|
.mp-table{width:100%;border-collapse:collapse;font-size:12px;line-height:1.6;color:var(--ink2);font-family:system-ui,sans-serif}
|
|
18046
18413
|
.mp-table th,.mp-table td{padding:5px 9px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line);white-space:nowrap}
|
|
18047
|
-
|
|
18414
|
+
/* 表头 11px 小字:用 ink2 而不是 label,浅色下 label 对 band 只有 3.5:1,读不清 */
|
|
18415
|
+
.mp-table th{background:var(--band);color:var(--ink2);font-weight:600;font-size:11px;letter-spacing:.06em}
|
|
18048
18416
|
.mp-table tbody tr:last-child td{border-bottom:none}
|
|
18049
18417
|
.mp-table tbody tr:nth-child(even) td{background:rgba(0,0,0,.02)}
|
|
18050
18418
|
/* 打印:表格不撕页、目录隐藏、折叠的内容要展开 */
|
|
@@ -18056,6 +18424,56 @@ window.Engine = __mods.index;
|
|
|
18056
18424
|
.mp-table-wrap,.mp-it-sec,.mp-it-dim{break-inside:avoid}
|
|
18057
18425
|
.mp-table-wrap{page-break-inside:avoid}
|
|
18058
18426
|
}
|
|
18427
|
+
/* —— ≤640px:大运表 6 列排到 748px,窄屏只能看到左边一段且没有「还能滑」的提示,
|
|
18428
|
+
这里改成一列一张卡;目录横滑成胶囊、证据摘要与名词解释的点击区抬到 44px —— */
|
|
18429
|
+
@media (max-width:640px){
|
|
18430
|
+
.mp-tables{padding:10px 11px 2px}
|
|
18431
|
+
.mp-table-wrap{margin-bottom:14px}
|
|
18432
|
+
.mp-table-scroll{overflow:visible;border:0;border-radius:0}
|
|
18433
|
+
.mp-table{display:block;width:100%}
|
|
18434
|
+
.mp-table thead{display:none}
|
|
18435
|
+
.mp-table tbody{display:block}
|
|
18436
|
+
.mp-table tr{display:block;border:1px solid var(--line);border-radius:8px;background:var(--card);padding:7px 10px;margin:0 0 8px}
|
|
18437
|
+
.mp-table td{display:grid;grid-template-columns:56px minmax(0,1fr);gap:8px;border-bottom:0;padding:2px 0;white-space:normal;font-size:12.5px;line-height:1.65}
|
|
18438
|
+
.mp-table td::before{content:attr(data-label);color:var(--muted);font-size:11px;line-height:1.9}
|
|
18439
|
+
.mp-table td:first-child{display:block;padding-bottom:3px;font-size:13px;font-weight:700;color:var(--ink)}
|
|
18440
|
+
.mp-table td:first-child::before{content:none}
|
|
18441
|
+
.mp-table tbody tr:nth-child(even) td{background:none}
|
|
18442
|
+
.mp-table tbody tr:last-child{margin-bottom:0}
|
|
18443
|
+
/* 对照卡:两列并排在 342px 里每边只剩 164px,竖排后标签跟正文走 */
|
|
18444
|
+
.mp-cross-b{grid-template-columns:1fr;gap:6px}
|
|
18445
|
+
.mp-cross-cell b{display:inline;margin-right:6px;letter-spacing:.06em}
|
|
18446
|
+
.mp-toc{flex-wrap:nowrap;overflow-x:auto;gap:8px;margin:10px 0 0;padding:6px 11px;border:0;border-bottom:1px solid var(--line);border-radius:0;scrollbar-width:none}
|
|
18447
|
+
.mp-toc::-webkit-scrollbar{display:none}
|
|
18448
|
+
.mp-toc a{flex:0 0 auto;display:inline-flex;align-items:center;min-height:44px;padding:0 12px;border:1px solid var(--line);border-radius:999px;color:var(--lu);text-decoration:none}
|
|
18449
|
+
.mp-toc a:hover{color:var(--ink)}
|
|
18450
|
+
.mp-it-ev>summary{display:flex;align-items:center;min-height:44px;padding:0 9px}
|
|
18451
|
+
.mp-it-gloss summary{display:flex;align-items:center;min-height:44px;margin-bottom:2px}
|
|
18452
|
+
}
|
|
18453
|
+
/* 容器查询版(dsh 侧栏 420px、窗口 1400px 时 @media 不会触发):与上面同规则,不另立一套口径 */
|
|
18454
|
+
@container (max-width:640px){
|
|
18455
|
+
.mp-tables{padding:10px 11px 2px}
|
|
18456
|
+
.mp-table-wrap{margin-bottom:14px}
|
|
18457
|
+
.mp-table-scroll{overflow:visible;border:0;border-radius:0}
|
|
18458
|
+
.mp-table{display:block;width:100%}
|
|
18459
|
+
.mp-table thead{display:none}
|
|
18460
|
+
.mp-table tbody{display:block}
|
|
18461
|
+
.mp-table tr{display:block;border:1px solid var(--line);border-radius:8px;background:var(--card);padding:7px 10px;margin:0 0 8px}
|
|
18462
|
+
.mp-table td{display:grid;grid-template-columns:56px minmax(0,1fr);gap:8px;border-bottom:0;padding:2px 0;white-space:normal;font-size:12.5px;line-height:1.65}
|
|
18463
|
+
.mp-table td::before{content:attr(data-label);color:var(--muted);font-size:11px;line-height:1.9}
|
|
18464
|
+
.mp-table td:first-child{display:block;padding-bottom:3px;font-size:13px;font-weight:700;color:var(--ink)}
|
|
18465
|
+
.mp-table td:first-child::before{content:none}
|
|
18466
|
+
.mp-table tbody tr:nth-child(even) td{background:none}
|
|
18467
|
+
.mp-table tbody tr:last-child{margin-bottom:0}
|
|
18468
|
+
.mp-cross-b{grid-template-columns:1fr;gap:6px}
|
|
18469
|
+
.mp-cross-cell b{display:inline;margin-right:6px;letter-spacing:.06em}
|
|
18470
|
+
.mp-toc{flex-wrap:nowrap;overflow-x:auto;gap:8px;margin:10px 0 0;padding:6px 11px;border:0;border-bottom:1px solid var(--line);border-radius:0;scrollbar-width:none}
|
|
18471
|
+
.mp-toc::-webkit-scrollbar{display:none}
|
|
18472
|
+
.mp-toc a{flex:0 0 auto;display:inline-flex;align-items:center;min-height:44px;padding:0 12px;border:1px solid var(--line);border-radius:999px;color:var(--lu);text-decoration:none}
|
|
18473
|
+
.mp-toc a:hover{color:var(--ink)}
|
|
18474
|
+
.mp-it-ev>summary{display:flex;align-items:center;min-height:44px;padding:0 9px}
|
|
18475
|
+
.mp-it-gloss summary{display:flex;align-items:center;min-height:44px;margin-bottom:2px}
|
|
18476
|
+
}
|
|
18059
18477
|
/* 追问结果 */
|
|
18060
18478
|
.mp-fu{margin:12px 16px;border:1px solid var(--line);border-left:3px solid var(--lu);border-radius:8px;background:var(--card);padding:10px 12px;font-size:13px;line-height:1.8;color:var(--ink2)}
|
|
18061
18479
|
.mp-fu.miss{border-left-color:var(--red)}
|
|
@@ -18931,6 +19349,14 @@ window.Engine = __mods.index;
|
|
|
18931
19349
|
return `<span class="pp-chip ${cls}">伏神${esc(l)}</span>`;
|
|
18932
19350
|
}).join('')}</div>`
|
|
18933
19351
|
: '';
|
|
19352
|
+
// 应期线索:只摆触发支与快慢方向,不写日期
|
|
19353
|
+
const yq = r.yingqi && Array.isArray(r.yingqi.labels) ? r.yingqi : null;
|
|
19354
|
+
const yingqiRow = yq && yq.labels.length
|
|
19355
|
+
? `<div class="pp-chips">${yq.labels.map((l) => {
|
|
19356
|
+
const cls = /应期偏速/.test(l) ? 'ok' : /应期待解/.test(l) ? 'warn' : '';
|
|
19357
|
+
return `<span class="pp-chip ${cls}" title="只列地支,不出日期">${esc(l)}</span>`;
|
|
19358
|
+
}).join('')}</div>`
|
|
19359
|
+
: '';
|
|
18934
19360
|
// 化进/化退的力重:方向之外再叠月建日辰,单列一排,免与卦体标签混读
|
|
18935
19361
|
const jp = r.jinTuiPower && Array.isArray(r.jinTuiPower.labels) ? r.jinTuiPower : null;
|
|
18936
19362
|
const jinRow = jp && jp.labels.length
|
|
@@ -18955,6 +19381,7 @@ window.Engine = __mods.index;
|
|
|
18955
19381
|
${useRow}
|
|
18956
19382
|
${strengthRow}
|
|
18957
19383
|
${fushenRow}
|
|
19384
|
+
${yingqiRow}
|
|
18958
19385
|
${jinRow}
|
|
18959
19386
|
${hexRow}
|
|
18960
19387
|
</div>`;
|
|
@@ -19730,8 +20157,10 @@ window.Engine = __mods.index;
|
|
|
19730
20157
|
return `<span class="pp-chip ${lk ? tierCls(lk.tier) : ''}" title="${esc(lk ? `${lk.tier} ${lk.score}|${(lk.reasons || []).join(';')}${syTip}` : syTip.replace(/^|/, ''))}">${l.year} ${l.ganzhi}${lk ? ` ${lk.tier}` : ''}</span>`;
|
|
19731
20158
|
}).join('')}</div>` : '';
|
|
19732
20159
|
const sy = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
20160
|
+
const syc = r.suiyunClassic;
|
|
20161
|
+
const sySrc = syc ? `<div class="pp-dim pp-sy-src" title="${esc(syc.plain || '')}">《${esc(syc.bookName || '')}·${esc(syc.chapter || '')}》「${esc(syc.quote || '')}」</div>` : '';
|
|
19733
20162
|
const syRow = sy.length ? `<div class="pp-tl pp-dim">岁运提示(只标干支变动,不判吉凶)</div><div class="pp-chips">${sy.map((l) =>
|
|
19734
|
-
`<span class="pp-chip" title="${esc(`${l.suiyun.signals.map((x) => x.detail).join(';')}|${l.suiyun.note || ''}`)}">${l.year} ${esc(l.suiyun.signals.map((x) => `${x.type}${x.type.startsWith('流年') && x.target ? `·${x.target}` : ''}`).join('/'))}</span>`).join('')}</div
|
|
20163
|
+
`<span class="pp-chip" title="${esc(`${l.suiyun.signals.map((x) => x.detail).join(';')}|${l.suiyun.note || ''}`)}">${l.year} ${esc(l.suiyun.signals.map((x) => `${x.type}${x.type.startsWith('流年') && x.target ? `·${x.target}` : ''}`).join('/'))}</span>`).join('')}</div>${sySrc}` : '';
|
|
19735
20164
|
const str = r.strength ? `<div class="pp-str">日主强弱:<b>${r.strength.level}</b>${r.strength.score} <span class="pp-dim">${r.strength.detail}</span></div>` : '';
|
|
19736
20165
|
const ssGroups = (r.shensha && r.shensha.groups) || [];
|
|
19737
20166
|
const ssx = ssGroups.length ? `
|
|
@@ -19772,6 +20201,21 @@ window.Engine = __mods.index;
|
|
|
19772
20201
|
// ── 解析与详解:把 interpret() 的结构化结果渲染成卡片 ──
|
|
19773
20202
|
const MT_LABEL = { natal: '命盘解析', divination: '卦象解析', card: '牌阵解析' };
|
|
19774
20203
|
|
|
20204
|
+
// 交叉验证的「判断」只有三档,各给一种语气色;未知值走中性色,不猜
|
|
20205
|
+
const STANCE_TONE = { 同向: 'good', 有张力: 'watch', 互补: 'alt' };
|
|
20206
|
+
// 一栏一个方面:标题带判断标签,八字与紫微并列,注解放最后一行,省得五段长句连读
|
|
20207
|
+
const crossHTML = (items) => `<div class="mp-cross">${items.map((c) => {
|
|
20208
|
+
const tone = STANCE_TONE[c.stance] || 'plain';
|
|
20209
|
+
return `<div class="mp-cross-row">
|
|
20210
|
+
<div class="mp-cross-h"><span class="mp-cross-l">${esc(c.label)}</span><span class="mp-cross-tag t-${tone}">${esc(c.stance || '—')}</span></div>
|
|
20211
|
+
<div class="mp-cross-b">
|
|
20212
|
+
<div class="mp-cross-cell"><b>八字</b><span>${esc(c.bazi || '—')}</span></div>
|
|
20213
|
+
<div class="mp-cross-cell"><b>紫微</b><span>${esc(c.ziwei || '—')}</span></div>
|
|
20214
|
+
</div>
|
|
20215
|
+
${c.note ? `<div class="mp-cross-note">${esc(c.note)}</div>` : ''}
|
|
20216
|
+
</div>`;
|
|
20217
|
+
}).join('')}</div>`;
|
|
20218
|
+
|
|
19775
20219
|
/**
|
|
19776
20220
|
* @param {object} it interpret() 的结果
|
|
19777
20221
|
* @param {object} [opt] { folded 是否收起 } —— 桌面默认展开、竖屏默认收起由调用方按视口决定
|
|
@@ -19803,8 +20247,8 @@ window.Engine = __mods.index;
|
|
|
19803
20247
|
? `<div class="mp-tables">${it.tables.filter((t) => Array.isArray(t.rows) && t.rows.length).map((t) => `<div class="mp-table-wrap">
|
|
19804
20248
|
<div class="mp-table-h">${esc(t.title)}</div>
|
|
19805
20249
|
<div class="mp-table-scroll"><table class="mp-table">
|
|
19806
|
-
<thead><tr>${t.columns.map((c) => `<th>${esc(c)}</th>`).join('')}</tr></thead>
|
|
19807
|
-
<tbody>${t.rows.map((row) => `<tr>${row.map((c) => `<td>${esc(c)}</td>`).join('')}</tr>`).join('')}</tbody>
|
|
20250
|
+
<thead><tr>${t.columns.map((c) => `<th scope="col">${esc(c)}</th>`).join('')}</tr></thead>
|
|
20251
|
+
<tbody>${t.rows.map((row) => `<tr>${row.map((c, ci) => `<td data-label="${esc(t.columns[ci] || '')}">${esc(c)}</td>`).join('')}</tr>`).join('')}</tbody>
|
|
19808
20252
|
</table></div>
|
|
19809
20253
|
</div>`).join('')}</div>`
|
|
19810
20254
|
: '';
|
|
@@ -19816,7 +20260,7 @@ window.Engine = __mods.index;
|
|
|
19816
20260
|
const secs = (it.sections && it.sections.length)
|
|
19817
20261
|
? `<div class="mp-it-secs">${it.sections.map((s) => `<div class="mp-it-sec${s.tone ? ` tone-${esc(s.tone)}` : ''}" id="mp-sec-${esc(s.key)}">
|
|
19818
20262
|
<div class="mp-it-sh">${esc(s.label)}</div>
|
|
19819
|
-
<div class="mp-it-stext">${richText(s.text)}</div>
|
|
20263
|
+
<div class="mp-it-stext">${(Array.isArray(s.items) && s.items.length) ? crossHTML(s.items) : richText(s.text)}</div>
|
|
19820
20264
|
</div>`).join('')}</div>`
|
|
19821
20265
|
: '';
|
|
19822
20266
|
const tags = [it.systemLabel, MT_LABEL[it.moduleType] || it.moduleType].filter(Boolean);
|
|
@@ -20443,8 +20887,8 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
20443
20887
|
it = window.Engine.interpret ? window.Engine.interpret(last.r, askArgs()) : (last.r.interpret || null);
|
|
20444
20888
|
} catch (e) { it = null; }
|
|
20445
20889
|
// 交叉验证结果由 compute 挂在盘面对象上,这里补进解析分节,保证与真实报告同一渲染路径
|
|
20446
|
-
if (it && last.r && last.r.cross && window.Engine.
|
|
20447
|
-
it.sections = [...(it.sections || []),
|
|
20890
|
+
if (it && last.r && last.r.cross && window.Engine.crossSection) {
|
|
20891
|
+
it.sections = [...(it.sections || []), window.Engine.crossSection(last.r.cross)];
|
|
20448
20892
|
}
|
|
20449
20893
|
el('out').innerHTML = castAtHTML(last.tab, last.timed, last.date, last.time)
|
|
20450
20894
|
+ window.__PP.resultWithInterpret(last.html, it, { folded: defaultFolded() })
|
|
@@ -20672,7 +21116,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
20672
21116
|
if (tab === 'convert') {
|
|
20673
21117
|
args.mode = convMode;
|
|
20674
21118
|
if (convMode === 'lunar2solar') {
|
|
20675
|
-
const m = /^(d{4})-(d{1,2})-(d{1,2})$/.exec(String(el('lunardate').value).trim());
|
|
21119
|
+
const m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(String(el('lunardate').value).trim());
|
|
20676
21120
|
if (!m) { el('out').innerHTML = '<div class="err">农历转公历请按「农历年-月-日」填写,例如 2026-9-17;闰月单独勾选。</div>'; return; }
|
|
20677
21121
|
args.lunarYear = Number(m[1]); args.lunarMonth = Number(m[2]); args.lunarDay = Number(m[3]);
|
|
20678
21122
|
args.isLeapMonth = !!(el('leapm') && el('leapm').checked);
|
|
@@ -20820,12 +21264,14 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
20820
21264
|
const fc = el('for-count');
|
|
20821
21265
|
if (fc) fc.style.display = tab === 'tarot' ? '' : 'none';
|
|
20822
21266
|
const castLabel = tab === 'qimen';
|
|
20823
|
-
|
|
21267
|
+
// 与 TIME_KIND 的 date 类共用一处口径:农历(convert)原先漏在名单外,标签错写成「起卦日期」
|
|
21268
|
+
const dateLabel = kindOf(tab) === 'date';
|
|
20824
21269
|
el('lbl-date').textContent = birth ? '出生日期(公历)' : dateLabel ? '日期(公历)' : (castLabel ? '起局日期(公历)' : '起卦日期(公历)');
|
|
20825
21270
|
el('lbl-time').textContent = birth ? '出生时刻' : (castLabel ? '起局时刻' : '起卦时刻');
|
|
20826
21271
|
const qk = el('for-quick');
|
|
20827
21272
|
if (qk) {
|
|
20828
21273
|
el('qk-zeri').style.display = tab === 'zeri' ? '' : 'none';
|
|
21274
|
+
el('qk-convert').style.display = tab === 'convert' ? '' : 'none';
|
|
20829
21275
|
el('qk-xiaoliuren').style.display = tab === 'xiaoliuren' ? '' : 'none';
|
|
20830
21276
|
el('qk-trend').style.display = tab === 'trend' ? '' : 'none';
|
|
20831
21277
|
el('qk-fengshui').style.display = tab === 'fengshui' ? '' : 'none';
|