dsh-metaphysics 0.46.5 → 0.50.5
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 +148 -0
- package/README.md +18 -11
- package/client.js +1075 -78
- package/docs/assets/dsh-metaphysics-group.jpg +0 -0
- package/engine/almanac.js +7 -6
- package/engine/bazi.js +73 -1
- package/engine/classics.js +53 -3
- package/engine/crosscheck.js +29 -3
- package/engine/diff.js +301 -197
- package/engine/geju.js +78 -14
- package/engine/index.js +112 -10
- package/engine/interpret-knowledge.js +19 -10
- package/engine/interpret-plain.js +19 -3
- package/engine/interpret.js +46 -6
- package/engine/liuyao.js +100 -0
- package/index.js +12 -2
- package/package.json +2 -2
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +1082 -99
- package/docs/assets/dsh-metaphysics-group.png +0 -0
package/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({
|
|
2
2
|
id: 'dsh-metaphysics',
|
|
3
|
-
version: '0.
|
|
3
|
+
version: '0.50.5',
|
|
4
4
|
factory(require) {
|
|
5
5
|
const React = (function () {
|
|
6
6
|
try { return require('react'); } catch (e) { return globalThis.React; }
|
|
@@ -19,6 +19,277 @@ const fail = (code, message) => {
|
|
|
19
19
|
return { fail };
|
|
20
20
|
})();
|
|
21
21
|
|
|
22
|
+
__mods.diff = (function () {
|
|
23
|
+
|
|
24
|
+
const IGNORE_KEYS = new Set([
|
|
25
|
+
'summary', 'interpret', 'castAt', 'asOf', 'precision', 'disclaimer', 'note',
|
|
26
|
+
'trueSolarText', 'civilText', 'offsetMinutes',
|
|
27
|
+
'input', // 只是把调用参数回显出来,不是盘面变化
|
|
28
|
+
'jd', // 内部儒略日,人类不可读;对外展示用 time 等格式化字段
|
|
29
|
+
'juMethod', 'juMethodNote', 'lateZiHourMode',
|
|
30
|
+
'leapPolicy',
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const isObject = (v) => v !== null && typeof v === 'object';
|
|
34
|
+
|
|
35
|
+
function diffObjects(a, b, path = '', out = []) {
|
|
36
|
+
if (a === b) return out;
|
|
37
|
+
if (!isObject(a) || !isObject(b)) {
|
|
38
|
+
out.push({ path: path || '(root)', from: a, to: b });
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
42
|
+
for (const k of keys) {
|
|
43
|
+
if (IGNORE_KEYS.has(k)) continue;
|
|
44
|
+
const p = path ? `${path}.${k}` : k;
|
|
45
|
+
const va = a[k];
|
|
46
|
+
const vb = b[k];
|
|
47
|
+
if (isObject(va) && isObject(vb)) {
|
|
48
|
+
diffObjects(va, vb, p, out);
|
|
49
|
+
} else if (JSON.stringify(va) !== JSON.stringify(vb)) {
|
|
50
|
+
out.push({ path: p, from: va, to: vb });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const LABELS = [
|
|
57
|
+
[/^pillars\.year\.ganzhi$/, '年柱'],
|
|
58
|
+
[/^pillars\.month\.ganzhi$/, '月柱'],
|
|
59
|
+
[/^pillars\.day\.ganzhi$/, '日柱'],
|
|
60
|
+
[/^pillars\.hour\.ganzhi$/, '时柱'],
|
|
61
|
+
[/^pillars\.\w+\.hidden/, '藏干'],
|
|
62
|
+
[/^pillars\.\w+\.stemTenGod$/, '十神'],
|
|
63
|
+
[/^pillars\.\w+\.kongwang/, '空亡'],
|
|
64
|
+
[/^pillars\.\w+\.dishi$|^pillars\.\w+\.zizuo$/, '十二长生'],
|
|
65
|
+
[/^pillars\.\w+\.nayin$/, '纳音'],
|
|
66
|
+
[/^dayMaster\./, '日主'],
|
|
67
|
+
[/^palaces\.(taiyuan|minggong|shengong)\./, '命身宫'],
|
|
68
|
+
[/^palaces\.\d+\.(palace|branch|stem|ganzhi)$/, '宫位'],
|
|
69
|
+
[/^palaces\.\d+\.stars\.\d+\.(name|brightness|type)$/, '星曜'],
|
|
70
|
+
[/^palaces\.\d+\.shensha\./, '神煞'],
|
|
71
|
+
[/^palaces\.\d+\.(daxian|xiaoxian)\./, '大限'],
|
|
72
|
+
[/^palaces\.\d+\.sanfang\./, '三方四正'],
|
|
73
|
+
[/^palaces\.\d+\./, '宫位'],
|
|
74
|
+
[/^palaces\./, '命身宫'],
|
|
75
|
+
[/^soul\./, '命宫'],
|
|
76
|
+
[/^body\./, '身宫'],
|
|
77
|
+
[/^doujun\./, '流年斗君'],
|
|
78
|
+
[/^siZhu\.year$/, '年柱'],
|
|
79
|
+
[/^siZhu\.month$/, '月柱'],
|
|
80
|
+
[/^siZhu\.day$/, '日柱'],
|
|
81
|
+
[/^siZhu\.time$/, '时柱'],
|
|
82
|
+
[/^ju$|^juNumber$/, '局数'],
|
|
83
|
+
[/^yuan$/, '三元'],
|
|
84
|
+
[/^dun$/, '阴阳遁'],
|
|
85
|
+
[/^daxian(List)?\./, '大限'],
|
|
86
|
+
[/^fly(Chains|Composite)?\./, '飞星'],
|
|
87
|
+
[/^pattern/, '格局'],
|
|
88
|
+
[/^schools\./, '流派回显'],
|
|
89
|
+
[/^dayun\.jiao\./, '起运'],
|
|
90
|
+
[/^dayun\.toNextJieDays$/, '起运时间'],
|
|
91
|
+
[/^dayun\.list\.(\d+)\.ganzhi$/, '大运干支'],
|
|
92
|
+
[/^dayun\.startAge\./, '起运时间'],
|
|
93
|
+
[/^dayun\./, '大运评分'],
|
|
94
|
+
[/^liunian\./, '流年'],
|
|
95
|
+
[/^jieqi\./, '节气边界'],
|
|
96
|
+
[/^solarTime\./, '真太阳时'],
|
|
97
|
+
[/^dayGanZhi$/, '日辰'],
|
|
98
|
+
[/^hourZhi$/, '时支'],
|
|
99
|
+
[/^yueJiang\./, '月将'],
|
|
100
|
+
[/^xunKong$/, '旬空'],
|
|
101
|
+
[/^lines\.(\d+)\./, '爻'],
|
|
102
|
+
[/^shensha\./, '神煞'],
|
|
103
|
+
[/^frame\./, '格局用神'],
|
|
104
|
+
[/^strength\./, '旺衰'],
|
|
105
|
+
[/^wuxing\./, '五行计数'],
|
|
106
|
+
[/^relations\./, '干支关系'],
|
|
107
|
+
[/^input\./, '输入回显'],
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
const CATEGORY = [
|
|
111
|
+
[/^pillars\./, '四柱'],
|
|
112
|
+
[/^shensha\./, '神煞'],
|
|
113
|
+
[/^dayun\./, '大运'],
|
|
114
|
+
[/^liunian\./, '流年'],
|
|
115
|
+
[/^frame\./, '格局用神'],
|
|
116
|
+
[/^strength\./, '旺衰'],
|
|
117
|
+
[/^wuxing\./, '五行计数'],
|
|
118
|
+
[/^dayMaster\./, '日主'],
|
|
119
|
+
[/^relations\./, '干支关系'],
|
|
120
|
+
[/^palaces\.(taiyuan|minggong|shengong)\./, '命身宫'],
|
|
121
|
+
[/^palaces\.\d+\./, '宫位'],
|
|
122
|
+
[/^palaces\./, '命身宫'],
|
|
123
|
+
[/^soul\.|^body\.|^doujun\./, '命身宫'],
|
|
124
|
+
[/^siZhu\./, '四柱'],
|
|
125
|
+
[/^ju$|^juNumber$|^yuan$|^dun$/, '局数'],
|
|
126
|
+
[/^daxian/, '大限'],
|
|
127
|
+
[/^fly/, '飞星'],
|
|
128
|
+
[/^pattern/, '格局'],
|
|
129
|
+
[/^jieqi\./, '节气'],
|
|
130
|
+
[/^solarTime\./, '真太阳时'],
|
|
131
|
+
[/^input\./, '输入回显'],
|
|
132
|
+
[/^lines\./, '爻'],
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
const ROOT = [
|
|
136
|
+
[/^pillars\.(year|month|day|hour)\.ganzhi$/, '柱'],
|
|
137
|
+
[/^palaces\.(minggong|shengong)\.ganzhi$/, '命身宫'],
|
|
138
|
+
[/^soul\.ganzhi$/, '命宫'],
|
|
139
|
+
[/^body\.branch$/, '身宫'],
|
|
140
|
+
[/^siZhu\.(year|month|day|time)$/, '柱'],
|
|
141
|
+
[/^dayun\.jiao\.at$/, '起运'],
|
|
142
|
+
[/^dayGanZhi$/, '日辰'],
|
|
143
|
+
[/^hourZhi$/, '时支'],
|
|
144
|
+
[/^ju$|^juNumber$|^juName$/, '局数'],
|
|
145
|
+
[/^dun$/, '阴阳遁'],
|
|
146
|
+
[/^lines\.\d+\.(ganzhi|yinYang|name)$/, '爻'],
|
|
147
|
+
[/^yueJiang\.(name|zhi)$/, '月将'],
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
function labelOf(path) {
|
|
151
|
+
for (const [re, label] of LABELS) {
|
|
152
|
+
if (re.test(path)) return label;
|
|
153
|
+
}
|
|
154
|
+
return categoryOf(path) || path;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function categoryOf(path) {
|
|
158
|
+
for (const [re, cat] of CATEGORY) {
|
|
159
|
+
if (re.test(path)) return cat;
|
|
160
|
+
}
|
|
161
|
+
return '';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function rootOf(path) {
|
|
165
|
+
for (const [re, label] of ROOT) {
|
|
166
|
+
if (re.test(path)) return label;
|
|
167
|
+
}
|
|
168
|
+
return '';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function sortDiffs(diffs) {
|
|
172
|
+
return [...diffs].sort((x, y) => x.path.localeCompare(y.path, 'zh-Hans-CN', { numeric: true }));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function summarize(diffs) {
|
|
176
|
+
if (!diffs.length) return '本盘不受此口径影响:所有字段一致。';
|
|
177
|
+
const roots = diffs.filter((d) => rootOf(d.path));
|
|
178
|
+
const cats = [...new Set(diffs.map((d) => categoryOf(d.path)).filter(Boolean))];
|
|
179
|
+
const head = roots.length
|
|
180
|
+
? `根因 ${roots.length} 处:` + roots.slice(0, 4)
|
|
181
|
+
.map((d) => `${labelOf(d.path)} ${formatValue(d.from)}→${formatValue(d.to)}`).join('、')
|
|
182
|
+
+ (roots.length > 4 ? ' 等' : '')
|
|
183
|
+
: '无单一根因';
|
|
184
|
+
const tail = cats.length
|
|
185
|
+
? `;连带影响 ${cats.slice(0, 6).join('、')}${cats.length > 6 ? ' 等' : ''} ${cats.length} 类,共 ${diffs.length} 处`
|
|
186
|
+
: `;共 ${diffs.length} 处`;
|
|
187
|
+
return head + tail + '。';
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const formatValue = (v) => {
|
|
191
|
+
if (v === undefined) return '—';
|
|
192
|
+
if (v === null) return 'null';
|
|
193
|
+
if (typeof v === 'string') return v;
|
|
194
|
+
if (Array.isArray(v)) return v.join('') || '[]';
|
|
195
|
+
if (typeof v === 'object') return JSON.stringify(v);
|
|
196
|
+
return String(v);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
function renderDiff(diffs, { title = '', limit = 12 } = {}) {
|
|
200
|
+
const lines = [];
|
|
201
|
+
if (title) lines.push(`【${title}】`);
|
|
202
|
+
lines.push(summarize(diffs));
|
|
203
|
+
if (!diffs.length) return lines.join('\n');
|
|
204
|
+
|
|
205
|
+
const roots = sortDiffs(diffs.filter((d) => rootOf(d.path)));
|
|
206
|
+
const rest = sortDiffs(diffs.filter((d) => !rootOf(d.path)));
|
|
207
|
+
|
|
208
|
+
if (roots.length) {
|
|
209
|
+
lines.push('');
|
|
210
|
+
lines.push(' 根因(口径直接改动):');
|
|
211
|
+
for (const d of roots) {
|
|
212
|
+
lines.push(` ${labelOf(d.path).padEnd(6)} ${formatValue(d.from)} → ${formatValue(d.to)}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (rest.length) {
|
|
216
|
+
lines.push('');
|
|
217
|
+
lines.push(` 连带变化(${rest.length} 处,展示前 ${Math.min(limit, rest.length)} 处):`);
|
|
218
|
+
for (const d of rest.slice(0, limit)) {
|
|
219
|
+
lines.push(` ${labelOf(d.path).padEnd(6)} ${formatValue(d.from)} → ${formatValue(d.to)}`);
|
|
220
|
+
}
|
|
221
|
+
if (rest.length > limit) {
|
|
222
|
+
const byCat = {};
|
|
223
|
+
for (const d of rest.slice(limit)) {
|
|
224
|
+
const c = categoryOf(d.path) || '其他';
|
|
225
|
+
byCat[c] = (byCat[c] || 0) + 1;
|
|
226
|
+
}
|
|
227
|
+
lines.push(' 其余:' + Object.entries(byCat).map(([c, n]) => `${c} ${n} 处`).join('、'));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return lines.join('\n');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const CALIBER_SWITCHES = {
|
|
234
|
+
bazi: [
|
|
235
|
+
{
|
|
236
|
+
key: 'lateZi',
|
|
237
|
+
title: '晚子时:23:00 后是否换日',
|
|
238
|
+
short: '晚子时',
|
|
239
|
+
read: (a) => a.lateZi !== false,
|
|
240
|
+
alt: (v) => !v,
|
|
241
|
+
label: (v) => (v ? '换日' : '不换日'),
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
key: 'trueSolar',
|
|
245
|
+
title: '真太阳时:是否按出生地经度修正',
|
|
246
|
+
short: '真太阳时',
|
|
247
|
+
read: (a) => a.trueSolar !== false,
|
|
248
|
+
alt: (v) => !v,
|
|
249
|
+
label: (v) => (v ? '修正' : '不修正'),
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
ziwei: [
|
|
253
|
+
{
|
|
254
|
+
key: 'leapMonth',
|
|
255
|
+
title: '闰月归月:按日切分 / 整月归次月',
|
|
256
|
+
short: '闰月归月',
|
|
257
|
+
read: (a) => (a.leapMonth === 'next' || a.leapMonth === 'prev' ? a.leapMonth : 'split'),
|
|
258
|
+
alt: (v) => (v === 'split' ? 'next' : 'split'),
|
|
259
|
+
label: (v) => ({ split: '按日切分', next: '整月归次月', prev: '整月归本月' }[v] || v),
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
key: 'trueSolar',
|
|
263
|
+
title: '真太阳时:是否按出生地经度修正',
|
|
264
|
+
short: '真太阳时',
|
|
265
|
+
read: (a) => a.trueSolar !== false,
|
|
266
|
+
alt: (v) => !v,
|
|
267
|
+
label: (v) => (v ? '修正' : '不修正'),
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
qimen: [
|
|
271
|
+
{
|
|
272
|
+
key: 'juMethod',
|
|
273
|
+
title: '取局流派:拆补 / 超神接气 / 置闰',
|
|
274
|
+
short: '取局流派',
|
|
275
|
+
read: (a) => (['chaibu', 'chaoshen', 'zhirun'].includes(a.juMethod) ? a.juMethod : 'chaibu'),
|
|
276
|
+
alt: (v) => (v === 'chaibu' ? 'zhirun' : 'chaibu'),
|
|
277
|
+
label: (v) => ({ chaibu: '拆补法', chaoshen: '超神接气', zhirun: '置闰法' }[v] || v),
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
key: 'lateZiHourMode',
|
|
281
|
+
title: '晚子时:23:00 后归当日 / 次日',
|
|
282
|
+
short: '晚子时归日',
|
|
283
|
+
read: (a) => (a.lateZiHourMode === 'next-day' ? 'next-day' : 'same-day'),
|
|
284
|
+
alt: (v) => (v === 'next-day' ? 'same-day' : 'next-day'),
|
|
285
|
+
label: (v) => (v === 'next-day' ? '归次日' : '归当日'),
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
return { diffObjects, labelOf, categoryOf, rootOf, sortDiffs, summarize, formatValue, renderDiff, CALIBER_SWITCHES };
|
|
291
|
+
})();
|
|
292
|
+
|
|
22
293
|
__mods.validate = (function () {
|
|
23
294
|
const { fail } = __mods.fail;
|
|
24
295
|
|
|
@@ -2629,6 +2900,16 @@ const CLASSICS = [
|
|
|
2629
2900
|
plain: '成格不等于一路顺:成中带忌(官逢财又逢伤、官被合之类)就打了折;败格也未必无救——印来解伤、合来清煞,败中还能转成。',
|
|
2630
2901
|
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53629.html',
|
|
2631
2902
|
},
|
|
2903
|
+
{
|
|
2904
|
+
id: 'zp-zaji',
|
|
2905
|
+
book: 'ziping',
|
|
2906
|
+
chapter: '十六、论杂气如何取用',
|
|
2907
|
+
scene: '用神',
|
|
2908
|
+
tags: [],
|
|
2909
|
+
quote: '何谓透干?如甲生辰月,透戊则用偏财,透癸则用正印,透乙则用月劫是也。何谓会支?如甲生辰月,逢申与子会局,则用水印是也。一透则一用,兼透则兼用,透而又会,则透与会并用。',
|
|
2910
|
+
plain: '四墓(辰戌丑未)所藏不止一气,所以叫杂气:取用先看哪一藏干透到天干,透一个用一个;没有透干,再看地支有没有与月支会成三合局,会成什么局就取局中那一气。透干与会支同时成立时两样并用。原文对「兼透」只给原则,没有给取舍次序。',
|
|
2911
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53636.html',
|
|
2912
|
+
},
|
|
2632
2913
|
{
|
|
2633
2914
|
id: 'zp-bianhua',
|
|
2634
2915
|
book: 'ziping',
|
|
@@ -2899,6 +3180,26 @@ const CLASSICS = [
|
|
|
2899
3180
|
plain: '从财格要财会成局、日干无气;一见根气就破格,原文用「命损无猜」这种重话写明。以丁生酉月、柱多庚辛为例:只能弃命相从,行北方财官旺地为入格,南行则灾。',
|
|
2900
3181
|
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7652.html',
|
|
2901
3182
|
},
|
|
3183
|
+
{
|
|
3184
|
+
id: 'smt-suiyun',
|
|
3185
|
+
book: 'sanming',
|
|
3186
|
+
chapter: '卷二·总论岁运',
|
|
3187
|
+
scene: '岁运',
|
|
3188
|
+
tags: [],
|
|
3189
|
+
quote: '行运以生月为运元,最怕行运与太岁冲克,若岁运冲月必祸;若岁运与日相对,谓之返吟,岁运压日,谓之伏吟,二者不利六亲,非横破财,不为吉兆。',
|
|
3190
|
+
plain: '大运以生月为起点,最怕与流年(太岁)冲克:原文说岁运冲月为祸,又把「岁运与日柱相对」叫返吟、「岁运压日」叫伏吟。这两句是按「对日柱」说的,与本插件「干支相同为伏吟、天克地冲为反吟」不是同一套定义(本插件取后者);末句「不利六亲、破财」是旧说的重话,只作变动提示,不作断语。',
|
|
3191
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7539.html',
|
|
3192
|
+
},
|
|
3193
|
+
{
|
|
3194
|
+
id: 'smt-renyuan',
|
|
3195
|
+
book: 'sanming',
|
|
3196
|
+
chapter: '卷二·论人元司事',
|
|
3197
|
+
scene: '人元',
|
|
3198
|
+
tags: [],
|
|
3199
|
+
quote: '故支吕所藏者主命,谓之人元,名为司事之神,以命术言之为月令。如正月建寅,寅中有艮土用事五日,丙火长生五日,甲木二十日;二月建卯,卯中有甲木用事七日,乙木二十三日;',
|
|
3200
|
+
plain: '地支所藏为「人元」,按月令分日轮值。三命通会这一本给的是另一套日数:寅月艮土(戊土)五日、丙火五日、甲木二十日,卯月甲七日、乙二十三日。它与本插件采用的通行 30 日表(寅月戊7丙7甲16,即 7/7/16;卯月甲10乙20,即 10/20)不是同一套分法;两表各照原样并列,本插件仍按通行表给「第几日谁当权」,不改取格。',
|
|
3201
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7529.html',
|
|
3202
|
+
},
|
|
2902
3203
|
];
|
|
2903
3204
|
|
|
2904
3205
|
const BY_ID = CLASSICS.reduce((m, e) => { m[e.id] = e; return m; }, {});
|
|
@@ -2932,6 +3233,12 @@ function classicOf(id) {
|
|
|
2932
3233
|
return BY_ID[id] || null;
|
|
2933
3234
|
}
|
|
2934
3235
|
|
|
3236
|
+
function suiyunClassicOf(r) {
|
|
3237
|
+
const liunian = r && Array.isArray(r.liunian) ? r.liunian : [];
|
|
3238
|
+
const hit = liunian.some((l) => l && l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
3239
|
+
return hit ? classicOf('smt-suiyun') : null;
|
|
3240
|
+
}
|
|
3241
|
+
|
|
2935
3242
|
function tagOf(gejuName) {
|
|
2936
3243
|
const name = String(gejuName || '');
|
|
2937
3244
|
if (GEJU_KEY[name]) return GEJU_KEY[name];
|
|
@@ -2984,8 +3291,12 @@ function classicsFor(r, limit = 5) {
|
|
|
2984
3291
|
}
|
|
2985
3292
|
const huagi = gejuList.find((g) => g && g.kind === '化气格');
|
|
2986
3293
|
const combo = gejuList.find((g) => g && g.kind === '组合');
|
|
3294
|
+
const monthBranch = r.monthBranch || (r.frame && r.frame.monthBranch) || (r.pillars && r.pillars.month && r.pillars.month.branch);
|
|
3295
|
+
const zaMonth = ['辰', '未', '戌', '丑'].includes(monthBranch);
|
|
2987
3296
|
if (huagi) {
|
|
2988
3297
|
push(classicOf('zp-bianhua'), `本盘列有「${huagi.name}」:用神由月令合化而变,总纲一位改取${CLASSIC_BOOKS.ziping.name}论用神变化`);
|
|
3298
|
+
} else if (zaMonth) {
|
|
3299
|
+
push(classicOf('zp-zaji'), `月令${monthBranch}属四墓杂气,取用先看透干、再看会支,总纲一位取${CLASSIC_BOOKS.ziping.name}论杂气如何取用`);
|
|
2989
3300
|
} else if (combo) {
|
|
2990
3301
|
push(classicOf('zp-chengbai'), `本盘另有「${combo.name}」组合:成格还要看带忌与救应,总纲一位改取${CLASSIC_BOOKS.ziping.name}论用神成败救应`);
|
|
2991
3302
|
} else {
|
|
@@ -2999,13 +3310,14 @@ function classicsText(rows) {
|
|
|
2999
3310
|
return rows.map((e) => `《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》「${e.quote}」`).join('\n');
|
|
3000
3311
|
}
|
|
3001
3312
|
|
|
3002
|
-
return { CLASSIC_BOOKS, CLASSICS, classicOf, classicsFor, classicsText };
|
|
3313
|
+
return { CLASSIC_BOOKS, CLASSICS, classicOf, suiyunClassicOf, classicsFor, classicsText };
|
|
3003
3314
|
})();
|
|
3004
3315
|
|
|
3005
3316
|
__mods.geju = (function () {
|
|
3006
3317
|
|
|
3007
3318
|
const { judgeClimate, arbitrate } = __mods.tiaohou;
|
|
3008
3319
|
const { qtOf } = __mods.qiongtong;
|
|
3320
|
+
const { sanheGroupOf } = __mods.sanhe;
|
|
3009
3321
|
|
|
3010
3322
|
const STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
|
|
3011
3323
|
const BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
|
|
@@ -3079,6 +3391,23 @@ function elementRoles(dayStem) {
|
|
|
3079
3391
|
return { me, inMe, shi: GENERATES[me], cai: OVERCOMES[me], guan };
|
|
3080
3392
|
}
|
|
3081
3393
|
|
|
3394
|
+
const ZA_MONTHS = ['辰', '未', '戌', '丑'];
|
|
3395
|
+
|
|
3396
|
+
function huiCandidate(pillars, monthBranch, cands) {
|
|
3397
|
+
if (!ZA_MONTHS.includes(monthBranch)) return null;
|
|
3398
|
+
const group = sanheGroupOf(monthBranch);
|
|
3399
|
+
if (!group) return null;
|
|
3400
|
+
const others = ['year', 'day', 'hour'];
|
|
3401
|
+
const need = group.branches.filter((b) => b !== monthBranch);
|
|
3402
|
+
if (!need.every((b) => others.some((k) => pillars[k].branch === b))) return null;
|
|
3403
|
+
const cand = cands.find((c) => STEM_ELEMENT[c.stem] === group.element);
|
|
3404
|
+
if (!cand) return null;
|
|
3405
|
+
const where = others
|
|
3406
|
+
.filter((k) => need.includes(pillars[k].branch))
|
|
3407
|
+
.map((k) => `${({ year: '年', day: '日', hour: '时' })[k]}支${pillars[k].branch}`);
|
|
3408
|
+
return { ...cand, group, where };
|
|
3409
|
+
}
|
|
3410
|
+
|
|
3082
3411
|
function monthPattern(pillars, dayStem, monthBranch) {
|
|
3083
3412
|
const hidden = HIDDEN[monthBranch] || [];
|
|
3084
3413
|
const cands = hidden.map((stem, i) => ({
|
|
@@ -3090,10 +3419,12 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
3090
3419
|
const others = ['year', 'month', 'hour'];
|
|
3091
3420
|
const exposedKey = others.find((k) => cands.some((c) => c.stem === pillars[k].stem));
|
|
3092
3421
|
const base = cands[0];
|
|
3093
|
-
const
|
|
3422
|
+
const hui = exposedKey ? null : huiCandidate(pillars, monthBranch, cands);
|
|
3423
|
+
const use = exposedKey ? cands.find((c) => c.stem === pillars[exposedKey].stem) : (hui || base);
|
|
3424
|
+
const usedBy = exposedKey ? '透干' : (hui ? '会支' : '本气');
|
|
3094
3425
|
const exposedPos = exposedKey ? { year: '年', month: '月', hour: '时' }[exposedKey] : null;
|
|
3095
3426
|
|
|
3096
|
-
if (base.god === '比肩') {
|
|
3427
|
+
if (base.god === '比肩' && LUSHEN_BRANCH[dayStem] === monthBranch) {
|
|
3097
3428
|
return {
|
|
3098
3429
|
name: '建禄格',
|
|
3099
3430
|
kind: '月令格',
|
|
@@ -3110,10 +3441,30 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
3110
3441
|
}
|
|
3111
3442
|
return { name: '月劫格', kind: '月令格', evidence: `月令${monthBranch}本气${base.stem}为劫财` };
|
|
3112
3443
|
}
|
|
3444
|
+
if (usedBy === '本气' && base.god === '比肩') {
|
|
3445
|
+
return {
|
|
3446
|
+
name: '比肩格',
|
|
3447
|
+
kind: '月令格',
|
|
3448
|
+
evidence: `月令${monthBranch}藏${hidden.join('')},本气${base.stem}为比肩,但${dayStem}禄在${LUSHEN_BRANCH[dayStem]}、不在${monthBranch},属杂气月比肩当权`,
|
|
3449
|
+
};
|
|
3450
|
+
}
|
|
3451
|
+
if (usedBy !== '本气' && use.god === '劫财') {
|
|
3452
|
+
const via = exposedKey ? `透于${exposedPos}干` : `${hui.where.join('、')}会成${hui.group.element}局`;
|
|
3453
|
+
return {
|
|
3454
|
+
name: '月劫格',
|
|
3455
|
+
kind: '月令格',
|
|
3456
|
+
evidence: `月令${monthBranch}藏${hidden.join('')},${use.pos}${use.stem}(劫财)${via},劫财为用,作月劫论`,
|
|
3457
|
+
};
|
|
3458
|
+
}
|
|
3113
3459
|
const name = `${use.god}格`;
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3460
|
+
let ex;
|
|
3461
|
+
if (exposedKey) {
|
|
3462
|
+
ex = `月令${monthBranch}藏${hidden.join('')},${use.pos}${use.stem}(${use.god})透于${exposedPos}干`;
|
|
3463
|
+
} else if (hui) {
|
|
3464
|
+
ex = `月令${monthBranch}藏${hidden.join('')},本气${base.stem}(${base.god})未透干,而${hui.where.join('、')}会成${hui.group.element}局,取${use.pos}${use.stem}(${use.god})为用`;
|
|
3465
|
+
} else {
|
|
3466
|
+
ex = `月令${monthBranch}藏${hidden.join('')},本气${base.stem}(${base.god})未透干,以月令本气取格`;
|
|
3467
|
+
}
|
|
3117
3468
|
return { name, kind: '月令格', evidence: ex };
|
|
3118
3469
|
}
|
|
3119
3470
|
|
|
@@ -3215,11 +3566,15 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3215
3566
|
const me = roles.me;
|
|
3216
3567
|
const weak = strength.level === '身弱' || strength.level === '偏弱';
|
|
3217
3568
|
const strong = strength.level === '身强' || strength.level === '偏强';
|
|
3569
|
+
const roleName = (el) => (el === me ? '比劫' : el === roles.inMe ? '印'
|
|
3570
|
+
: el === roles.shi ? '食伤' : el === roles.cai ? '财' : '官杀');
|
|
3571
|
+
const ROLE_VERB = { 比劫: '帮身', 印: '生身', 食伤: '泄秀', 财: '耗', 官杀: '制' };
|
|
3218
3572
|
|
|
3219
3573
|
const baseFavor = weak ? [roles.inMe, me] : strong ? [roles.shi, roles.cai, roles.guan] : [roles.inMe, me, roles.shi];
|
|
3220
3574
|
const baseAvoid = weak ? [roles.shi, roles.cai, roles.guan] : strong ? [me, roles.inMe] : [roles.guan, roles.cai];
|
|
3221
3575
|
let favor = baseFavor.slice();
|
|
3222
3576
|
let avoid = baseAvoid.slice();
|
|
3577
|
+
const disputed = [];
|
|
3223
3578
|
|
|
3224
3579
|
const climate = judgeClimate({ monthBranch, dayStem, wuxing, branches });
|
|
3225
3580
|
const qt = qtOf(dayStem, monthBranch);
|
|
@@ -3228,27 +3583,39 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3228
3583
|
const needEl = climate.need.element;
|
|
3229
3584
|
if (!favor.includes(needEl)) favor.unshift(needEl);
|
|
3230
3585
|
avoid = avoid.filter((e) => e !== needEl);
|
|
3231
|
-
|
|
3586
|
+
const badEl = climate.avoidElement;
|
|
3587
|
+
if (badEl && favor.includes(badEl)) {
|
|
3588
|
+
disputed.push({
|
|
3589
|
+
element: badEl,
|
|
3590
|
+
favorRole: roleName(badEl),
|
|
3591
|
+
favorVerb: ROLE_VERB[roleName(badEl)],
|
|
3592
|
+
climate: climate.label,
|
|
3593
|
+
note: `调候忌${badEl}(${climate.label}),但它在扶抑里为${roleName(badEl)};本表保留在喜用,不列入忌。`,
|
|
3594
|
+
});
|
|
3595
|
+
} else if (badEl && !avoid.includes(badEl)) {
|
|
3596
|
+
avoid.unshift(badEl);
|
|
3597
|
+
}
|
|
3232
3598
|
}
|
|
3233
3599
|
|
|
3234
|
-
const roleName = (el) => (el === me ? '比劫' : el === roles.inMe ? '印'
|
|
3235
|
-
: el === roles.shi ? '食伤' : el === roles.cai ? '财' : '官杀');
|
|
3236
3600
|
const expand = {
|
|
3237
3601
|
比劫: ['比肩', '劫财'], 印: ['正印', '偏印'], 食伤: ['食神', '伤官'],
|
|
3238
3602
|
财: ['正财', '偏财'], 官杀: ['正官', '七杀'],
|
|
3239
3603
|
};
|
|
3240
3604
|
const favorTenGods = Array.from(new Set(favor.flatMap((el) => expand[roleName(el)] || [])));
|
|
3241
3605
|
const avoidTenGods = Array.from(new Set(avoid.flatMap((el) => expand[roleName(el)] || [])));
|
|
3606
|
+
const disputedTenGods = Array.from(new Set(disputed.flatMap((d) => expand[roleName(d.element)] || [])));
|
|
3242
3607
|
const tongguan = tongguanOf(favor, avoid, wuxing);
|
|
3243
3608
|
|
|
3609
|
+
const describe = (el) => `${el}(${roleName(el)}·${ROLE_VERB[roleName(el)]})`;
|
|
3610
|
+
const disputedText = disputed
|
|
3611
|
+
.map((d) => `${d.element}(扶抑为${d.favorRole}·${d.favorVerb};${d.climate}盘调候忌${d.element},本表保留在喜用)`)
|
|
3612
|
+
.join('、');
|
|
3244
3613
|
const detail = [
|
|
3245
3614
|
`日主${dayStem}${me},${strength.level}(${strength.score} 分):`,
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
: '身中和,先取调候与通关,喜忌随大运流年动态变化。',
|
|
3251
|
-
`调候:${climate.label}(${(climate.evidence || []).join('、')})${climate.need ? `,取${climate.need.stem}${climate.need.element},忌${climate.avoidElement}` : ',气候平和'}。`,
|
|
3615
|
+
`喜${favor.map(describe).join('、') || '—'};忌${avoid.map(describe).join('、') || '—'}。`,
|
|
3616
|
+
disputed.length ? `有争议:${disputedText}。` : '',
|
|
3617
|
+
!weak && !strong ? '身中和,先取调候与通关,喜忌随大运流年动态变化。' : '',
|
|
3618
|
+
`调候:${climate.label}(${(climate.evidence || []).join('、')})${climate.need ? `,取${climate.need.stem}${climate.need.element},忌${climate.avoidElement}${disputed.some((d) => d.element === climate.avoidElement) ? '(有争议)' : ''}` : ',气候平和'}。`,
|
|
3252
3619
|
qt ? `穷通宝鉴:${qt.month}${dayStem}${me},用神${qt.yong.join('、')}(首取${qt.primary})。` : '',
|
|
3253
3620
|
tongguan
|
|
3254
3621
|
? `通关:忌${tongguan.foe}克用${tongguan.use},五行以${tongguan.bridge}为关;局中${tongguan.level === '可通'
|
|
@@ -3268,10 +3635,12 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3268
3635
|
level: strength.level,
|
|
3269
3636
|
favor,
|
|
3270
3637
|
avoid,
|
|
3638
|
+
disputed,
|
|
3271
3639
|
favorRoles: favor.map(roleName),
|
|
3272
3640
|
avoidRoles: avoid.map(roleName),
|
|
3273
3641
|
favorTenGods,
|
|
3274
3642
|
avoidTenGods,
|
|
3643
|
+
disputedTenGods,
|
|
3275
3644
|
tiaohou: { ...climate, ...arb, element: climate.need ? climate.need.element : null },
|
|
3276
3645
|
climate,
|
|
3277
3646
|
qt,
|
|
@@ -3400,6 +3769,21 @@ const HIDDEN_STEMS = {
|
|
|
3400
3769
|
亥: ['壬', '甲'],
|
|
3401
3770
|
};
|
|
3402
3771
|
|
|
3772
|
+
const RENYUAN_TABLE = {
|
|
3773
|
+
寅: [['戊', 7], ['丙', 7], ['甲', 16]],
|
|
3774
|
+
卯: [['甲', 10], ['乙', 20]],
|
|
3775
|
+
辰: [['乙', 9], ['癸', 3], ['戊', 18]],
|
|
3776
|
+
巳: [['戊', 5], ['庚', 9], ['丙', 16]],
|
|
3777
|
+
午: [['丙', 10], ['己', 9], ['丁', 11]],
|
|
3778
|
+
未: [['丁', 9], ['乙', 3], ['己', 18]],
|
|
3779
|
+
申: [['戊', 7], ['壬', 3], ['庚', 20]],
|
|
3780
|
+
酉: [['庚', 10], ['辛', 20]],
|
|
3781
|
+
戌: [['辛', 9], ['丁', 3], ['戊', 18]],
|
|
3782
|
+
亥: [['戊', 7], ['甲', 5], ['壬', 18]],
|
|
3783
|
+
子: [['壬', 10], ['癸', 20]],
|
|
3784
|
+
丑: [['癸', 9], ['辛', 3], ['己', 18]],
|
|
3785
|
+
};
|
|
3786
|
+
|
|
3403
3787
|
const STEM_ELEMENT = {
|
|
3404
3788
|
甲: '木', 乙: '木', 丙: '火', 丁: '火', 戊: '土',
|
|
3405
3789
|
己: '土', 庚: '金', 辛: '金', 壬: '水', 癸: '水',
|
|
@@ -3563,6 +3947,36 @@ function applyTrueSolar(jd, longitude) {
|
|
|
3563
3947
|
};
|
|
3564
3948
|
}
|
|
3565
3949
|
|
|
3950
|
+
function renyuanOf(monthBranch, birthJdn, termJd) {
|
|
3951
|
+
const table = RENYUAN_TABLE[monthBranch];
|
|
3952
|
+
if (!table) return null;
|
|
3953
|
+
const segments = [];
|
|
3954
|
+
let from = 1;
|
|
3955
|
+
for (const [stem, days] of table) {
|
|
3956
|
+
segments.push({ stem, element: STEM_ELEMENT[stem], from, to: from + days - 1 });
|
|
3957
|
+
from += days;
|
|
3958
|
+
}
|
|
3959
|
+
const tableDays = from - 1;
|
|
3960
|
+
const day = Math.max(1, Math.floor(birthJdn) - Math.floor(termJd + 0.5) + 1);
|
|
3961
|
+
const beyond = day > tableDays;
|
|
3962
|
+
const idx = beyond ? segments.length - 1 : segments.findIndex((s) => day >= s.from && day <= s.to);
|
|
3963
|
+
const seg = segments[idx] || segments[segments.length - 1];
|
|
3964
|
+
const next = segments[idx + 1] || null;
|
|
3965
|
+
return {
|
|
3966
|
+
month: monthBranch,
|
|
3967
|
+
day,
|
|
3968
|
+
tableDays,
|
|
3969
|
+
segments,
|
|
3970
|
+
active: seg.stem,
|
|
3971
|
+
activeElement: seg.element,
|
|
3972
|
+
segment: { from: seg.from, to: seg.to },
|
|
3973
|
+
next: next ? { stem: next.stem, element: next.element, from: next.from, inDays: next.from - day } : null,
|
|
3974
|
+
inHidden: (HIDDEN_STEMS[monthBranch] || []).includes(seg.stem),
|
|
3975
|
+
beyond,
|
|
3976
|
+
note: '人元司权按「节」当日起算,节当日为第 1 日,日差用本盘所用时刻(含真太阳时)所在日计;本插件固定 30 日表(余气 → 中气 → 本气),第 31 日以后按本气算。只作解释层的一层细节,不改取格。',
|
|
3977
|
+
};
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3566
3980
|
function buildBazi(input) {
|
|
3567
3981
|
assertCivil(input);
|
|
3568
3982
|
let { year, month, day, hour = 0, minute = 0, gender = 'male' } = input;
|
|
@@ -3813,6 +4227,15 @@ function buildBazi(input) {
|
|
|
3813
4227
|
} else if (tianKeDiChong(w.ganzhi, l.ganzhi)) {
|
|
3814
4228
|
signals.push({ type: '运年反吟', target: `第${w.step}步大运`, detail: `大运${w.ganzhi}与流年${l.ganzhi}天克地冲` });
|
|
3815
4229
|
}
|
|
4230
|
+
for (const key of ['year', 'month', 'day', 'hour']) {
|
|
4231
|
+
const g = pillars[key].ganzhi;
|
|
4232
|
+
if (!g) continue;
|
|
4233
|
+
if (w.ganzhi === g) {
|
|
4234
|
+
signals.push({ type: '大运伏吟', target: `第${w.step}步大运·${NATAL_LABEL[key]}`, detail: `大运${w.ganzhi}与${NATAL_LABEL[key]}同干支` });
|
|
4235
|
+
} else if (tianKeDiChong(w.ganzhi, g)) {
|
|
4236
|
+
signals.push({ type: '大运反吟', target: `第${w.step}步大运·${NATAL_LABEL[key]}`, detail: `大运${w.ganzhi}与${NATAL_LABEL[key]}${g}天克地冲` });
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
3816
4239
|
}
|
|
3817
4240
|
for (const key of ['year', 'month', 'day', 'hour']) {
|
|
3818
4241
|
const g = pillars[key].ganzhi;
|
|
@@ -3826,7 +4249,7 @@ function buildBazi(input) {
|
|
|
3826
4249
|
l.suiyun = {
|
|
3827
4250
|
dayun: active.map((w) => ({ step: w.step, ganzhi: w.ganzhi })),
|
|
3828
4251
|
signals,
|
|
3829
|
-
note: '
|
|
4252
|
+
note: '只标干支重复与天克地冲这类变动信号,不判吉凶;大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列;大运与本命四柱的伏吟/反吟整步大运都在,逐年重复列出',
|
|
3830
4253
|
};
|
|
3831
4254
|
}
|
|
3832
4255
|
|
|
@@ -3844,6 +4267,9 @@ function buildBazi(input) {
|
|
|
3844
4267
|
const bodyStemIdx = (yinStem + ((bodyIdx - 2 + 12) % 12)) % 10;
|
|
3845
4268
|
const shengong = ganzhiName(sexagenaryIndex(bodyStemIdx, bodyIdx));
|
|
3846
4269
|
|
|
4270
|
+
const renyuan = renyuanOf(BRANCHES[monthBranchIdx], jdnBase, prevJieTerm.jd);
|
|
4271
|
+
if (renyuan) renyuan.term = { name: prevJieTerm.name, time: formatJd(prevJieTerm.jd) };
|
|
4272
|
+
|
|
3847
4273
|
return {
|
|
3848
4274
|
system: 'bazi',
|
|
3849
4275
|
relations: buildRelations(pillars),
|
|
@@ -3874,6 +4300,7 @@ function buildBazi(input) {
|
|
|
3874
4300
|
next: { name: nextJieTerm.name, time: formatJd(nextJieTerm.jd) },
|
|
3875
4301
|
nearBoundaryMinutes: Math.round(Math.min(jd - prevJieTerm.jd, nextJieTerm.jd - jd) * 1440),
|
|
3876
4302
|
},
|
|
4303
|
+
renyuan,
|
|
3877
4304
|
pillars,
|
|
3878
4305
|
dayMaster: { stem: dayStem, element: STEM_ELEMENT[dayStem], yinYang: isYangStem(dayStem) ? '阳' : '阴' },
|
|
3879
4306
|
wuxing,
|
|
@@ -3905,7 +4332,7 @@ function buildBazi(input) {
|
|
|
3905
4332
|
};
|
|
3906
4333
|
}
|
|
3907
4334
|
|
|
3908
|
-
return { HIDDEN_STEMS, STEM_ELEMENT, BRANCH_ELEMENT, buildRelations, tenGod, nayin, applyTrueSolar, buildBazi };
|
|
4335
|
+
return { HIDDEN_STEMS, RENYUAN_TABLE, STEM_ELEMENT, BRANCH_ELEMENT, buildRelations, tenGod, nayin, applyTrueSolar, renyuanOf, buildBazi };
|
|
3909
4336
|
})();
|
|
3910
4337
|
|
|
3911
4338
|
__mods.liuyao = (function () {
|
|
@@ -3962,6 +4389,7 @@ const LIUSHEN_START = { 甲: 0, 乙: 0, 丙: 1, 丁: 1, 戊: 2, 己: 3, 庚: 4,
|
|
|
3962
4389
|
const ZHI_CHONG_PAIRS = [['子', '午'], ['丑', '未'], ['寅', '申'], ['卯', '酉'], ['辰', '戌'], ['巳', '亥']];
|
|
3963
4390
|
const ZHI_HE_PAIRS = [['子', '丑'], ['寅', '亥'], ['卯', '戌'], ['辰', '酉'], ['巳', '申'], ['午', '未']];
|
|
3964
4391
|
const CHONG_OF = Object.fromEntries(ZHI_CHONG_PAIRS.flatMap(([a, b]) => [[a, b], [b, a]]));
|
|
4392
|
+
const HE_OF = Object.fromEntries(ZHI_HE_PAIRS.flatMap(([a, b]) => [[a, b], [b, a]]));
|
|
3965
4393
|
const TRIGRAM_OPPOSITE = { 乾: '巽', 巽: '乾', 坎: '离', 离: '坎', 艮: '坤', 坤: '艮', 震: '兑', 兑: '震' };
|
|
3966
4394
|
|
|
3967
4395
|
const JIN_TUI_PAIRS = [['寅', '卯'], ['巳', '午'], ['申', '酉'], ['亥', '子'], ['丑', '辰'], ['辰', '未'], ['未', '戌'], ['戌', '丑']];
|
|
@@ -4732,7 +5160,95 @@ function jinTuiPower(result, opts = {}) {
|
|
|
4732
5160
|
};
|
|
4733
5161
|
}
|
|
4734
5162
|
|
|
4735
|
-
|
|
5163
|
+
const YINGQI_TEMPO = ['偏速', '偏缓', '待解', '未定'];
|
|
5164
|
+
const TEMPO_SAY = {
|
|
5165
|
+
偏速: '用神得月令之气,应期偏近',
|
|
5166
|
+
偏缓: '用神失月令之气,应期偏远',
|
|
5167
|
+
待解: '有月破或旬空的用神,先等条件解除',
|
|
5168
|
+
未定: '快慢不定(缺月建,或用神两现而旺衰不一)',
|
|
5169
|
+
};
|
|
5170
|
+
const TRIGGER_ORDER = ['逢值', '逢冲', '逢合', '出空填实', '冲空'];
|
|
5171
|
+
|
|
5172
|
+
function yingqiWindow(result, useGod, opts = {}) {
|
|
5173
|
+
if (!useGod || !useGod.liuqin) return null;
|
|
5174
|
+
const found = Array.isArray(useGod.found) ? useGod.found : [];
|
|
5175
|
+
const fushen = Array.isArray(useGod.fushen) ? useGod.fushen : [];
|
|
5176
|
+
const viaFushen = !found.length && fushen.length > 0;
|
|
5177
|
+
const source = found.length ? found : fushen;
|
|
5178
|
+
if (!source.length) return null;
|
|
5179
|
+
const monthBranch = opts.monthBranch || null;
|
|
5180
|
+
const monthElement = monthBranch ? zhiElementOf(monthBranch) : null;
|
|
5181
|
+
const kong = Array.isArray(result && result.xunKong)
|
|
5182
|
+
? result.xunKong
|
|
5183
|
+
: (result && typeof result.xunKong === 'string' ? result.xunKong.split('') : []);
|
|
5184
|
+
|
|
5185
|
+
const items = source.map((l) => {
|
|
5186
|
+
const branch = l.branch;
|
|
5187
|
+
const element = l.element || zhiElementOf(branch);
|
|
5188
|
+
const monthState = monthStateOf(element, monthElement);
|
|
5189
|
+
const isEmpty = kong.includes(branch);
|
|
5190
|
+
const monthChong = !!(monthBranch && CHONG_OF[branch] === monthBranch);
|
|
5191
|
+
const tempo = monthChong ? '待解'
|
|
5192
|
+
: isEmpty ? '待解'
|
|
5193
|
+
: monthState === 'unknown' ? '未定'
|
|
5194
|
+
: (monthState === '旺' || monthState === '相') ? '偏速' : '偏缓';
|
|
5195
|
+
const tempoSay = monthChong ? `遭${monthBranch}冲(月破),先待出月或填实`
|
|
5196
|
+
: isEmpty ? '用神旬空,先待出空填实'
|
|
5197
|
+
: monthState === 'unknown' ? '缺月建,快慢不定'
|
|
5198
|
+
: `月建${monthState},${tempo === '偏速' ? '应期偏近' : '应期偏远'}`;
|
|
5199
|
+
const triggers = [
|
|
5200
|
+
{ branch, labels: ['逢值'] },
|
|
5201
|
+
{ branch: CHONG_OF[branch] || null, labels: ['逢冲'] },
|
|
5202
|
+
{ branch: HE_OF[branch] || null, labels: ['逢合'] },
|
|
5203
|
+
];
|
|
5204
|
+
if (isEmpty) {
|
|
5205
|
+
triggers[0].labels.push('出空填实');
|
|
5206
|
+
triggers[1].labels.push('冲空');
|
|
5207
|
+
}
|
|
5208
|
+
return {
|
|
5209
|
+
position: l.position,
|
|
5210
|
+
branch,
|
|
5211
|
+
element,
|
|
5212
|
+
monthState,
|
|
5213
|
+
monthChong,
|
|
5214
|
+
kong: isEmpty,
|
|
5215
|
+
tempo,
|
|
5216
|
+
tempoSay,
|
|
5217
|
+
triggers,
|
|
5218
|
+
};
|
|
5219
|
+
});
|
|
5220
|
+
|
|
5221
|
+
const merged = new Map();
|
|
5222
|
+
for (const it of items) {
|
|
5223
|
+
for (const t of it.triggers) {
|
|
5224
|
+
if (!t.branch) continue;
|
|
5225
|
+
const cur = merged.get(t.branch) || { branch: t.branch, labels: [] };
|
|
5226
|
+
for (const lb of t.labels) if (!cur.labels.includes(lb)) cur.labels.push(lb);
|
|
5227
|
+
merged.set(t.branch, cur);
|
|
5228
|
+
}
|
|
5229
|
+
}
|
|
5230
|
+
const triggers = [...merged.values()].map((t) => ({
|
|
5231
|
+
branch: t.branch,
|
|
5232
|
+
labels: [...t.labels].sort((a, b) => TRIGGER_ORDER.indexOf(a) - TRIGGER_ORDER.indexOf(b)),
|
|
5233
|
+
}));
|
|
5234
|
+
const tempos = items.map((x) => x.tempo);
|
|
5235
|
+
const tempo = tempos.includes('待解') ? '待解'
|
|
5236
|
+
: tempos.every((t) => t === '偏速') ? '偏速'
|
|
5237
|
+
: tempos.every((t) => t === '偏缓') ? '偏缓' : '未定';
|
|
5238
|
+
|
|
5239
|
+
return {
|
|
5240
|
+
month: monthBranch ? { branch: monthBranch, element: monthElement } : null,
|
|
5241
|
+
viaFushen,
|
|
5242
|
+
tempo,
|
|
5243
|
+
tempoSay: TEMPO_SAY[tempo],
|
|
5244
|
+
items,
|
|
5245
|
+
triggers,
|
|
5246
|
+
labels: [`应期${tempo}`, ...triggers.map((t) => `${t.labels.join('/')}${t.branch}`)],
|
|
5247
|
+
note: '应期只给「该留意哪一支」与快慢方向:用神逢值、逢冲、逢合,旬空另标出空与冲空。不换算成日期、不排先后、不判忌神受制;近事以日计、远事以月计,用哪把尺由事情远近决定,本插件不代选。',
|
|
5248
|
+
};
|
|
5249
|
+
}
|
|
5250
|
+
|
|
5251
|
+
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 };
|
|
4736
5252
|
})();
|
|
4737
5253
|
|
|
4738
5254
|
__mods.ziwei = (function () {
|
|
@@ -9539,9 +10055,9 @@ const MANSIONS = {
|
|
|
9539
10055
|
箕: { luck: '吉', zheng: '水', animal: '豹', gong: '东' }, 斗: { luck: '吉', zheng: '木', animal: '獬', gong: '北' },
|
|
9540
10056
|
牛: { luck: '凶', zheng: '金', animal: '牛', gong: '北' }, 女: { luck: '凶', zheng: '土', animal: '蝠', gong: '北' },
|
|
9541
10057
|
虚: { luck: '凶', zheng: '日', animal: '鼠', gong: '北' }, 危: { luck: '凶', zheng: '月', animal: '燕', gong: '北' },
|
|
9542
|
-
室: { luck: '吉', zheng: '火', animal: '猪', gong: '北' }, 壁: { luck: '吉', zheng: '水', animal: '
|
|
10058
|
+
室: { luck: '吉', zheng: '火', animal: '猪', gong: '北' }, 壁: { luck: '吉', zheng: '水', animal: '貐', gong: '北' },
|
|
9543
10059
|
奎: { luck: '凶', zheng: '木', animal: '狼', gong: '西' }, 娄: { luck: '吉', zheng: '金', animal: '狗', gong: '西' },
|
|
9544
|
-
胃: { luck: '吉', zheng: '土', animal: '
|
|
10060
|
+
胃: { luck: '吉', zheng: '土', animal: '雉', gong: '西' }, 昴: { luck: '凶', zheng: '日', animal: '鸡', gong: '西' },
|
|
9545
10061
|
毕: { luck: '吉', zheng: '月', animal: '乌', gong: '西' }, 觜: { luck: '凶', zheng: '火', animal: '猴', gong: '西' },
|
|
9546
10062
|
参: { luck: '吉', zheng: '水', animal: '猿', gong: '西' }, 井: { luck: '吉', zheng: '木', animal: '犴', gong: '南' },
|
|
9547
10063
|
鬼: { luck: '凶', zheng: '金', animal: '羊', gong: '南' }, 柳: { luck: '凶', zheng: '土', animal: '獐', gong: '南' },
|
|
@@ -10883,6 +11399,18 @@ function jinTuiPlain(r) {
|
|
|
10883
11399
|
return `动爻的进退还要看时令:${jp.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type},${sayOf(l)}`).join(';')}。`;
|
|
10884
11400
|
}
|
|
10885
11401
|
|
|
11402
|
+
function yingqiPlain(r) {
|
|
11403
|
+
const yq = r && r.yingqi;
|
|
11404
|
+
if (!yq || !Array.isArray(yq.triggers) || !yq.triggers.length) return '';
|
|
11405
|
+
const when = yq.tempo === '偏速' ? '大体偏近,近事更容易先见分晓'
|
|
11406
|
+
: yq.tempo === '偏缓' ? '大体偏远,别指望立刻见分晓'
|
|
11407
|
+
: yq.tempo === '待解' ? '眼下还有月破或旬空,得先等条件解除'
|
|
11408
|
+
: '缺月建,快慢暂不定';
|
|
11409
|
+
const branches = yq.triggers.map((t) => t.branch).join('、');
|
|
11410
|
+
const fu = yq.viaFushen ? '(用神是伏神,先要出得来)' : '';
|
|
11411
|
+
return `应期上${when};传统会留意${branches}这几个地支${fu}——这只是提示,不换算成具体哪天。`;
|
|
11412
|
+
}
|
|
11413
|
+
|
|
10886
11414
|
function hexStrengthPlain(hs) {
|
|
10887
11415
|
if (!hs || !hs.counts) return '';
|
|
10888
11416
|
const up = (hs.counts.旺 || 0) + (hs.counts.相 || 0);
|
|
@@ -10982,7 +11510,7 @@ function buildAnswer(r, ask, ctx = {}) {
|
|
|
10982
11510
|
head + `先说结论:本卦是${s(ben.name, '—')}` +
|
|
10983
11511
|
`${ben.palace ? `(${ben.palace})` : ''}` +
|
|
10984
11512
|
`${moving.length ? `,第 ${moving.join('、')} 爻动,变为${s(bian.name, '—')}` : ',六爻安静没有动爻'}。` +
|
|
10985
|
-
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
11513
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${yingqiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
10986
11514
|
'断卦的落点在「世爻」(代表你)和「动爻」(事情的推动点),下面「看盘顺序」就按这个次序展开。',
|
|
10987
11515
|
].join('');
|
|
10988
11516
|
}
|
|
@@ -11005,6 +11533,9 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
11005
11533
|
const ys = (r.frame && r.frame.yongshen) || {};
|
|
11006
11534
|
const favor = join(ys.favor);
|
|
11007
11535
|
const avoid = join(ys.avoid);
|
|
11536
|
+
const dis = Array.isArray(ys.disputed) && ys.disputed.length
|
|
11537
|
+
? `有一点要说明:${ys.disputed.map((d) => d.element).join('、')}在扶抑里算${ys.disputed.map((d) => d.favorRole).join('、')}(能${ys.disputed.map((d) => d.favorVerb).join('、')}),按调候看又偏忌(${ys.disputed.map((d) => `${d.climate}盘忌${d.element}`).join('、')}),两派说法不一;实际用在什么时候,看季节和环境取舍,不必当成绝对的好或坏。`
|
|
11538
|
+
: '';
|
|
11008
11539
|
const strength = STRENGTH_PLAIN[st.level] || '力量偏中性';
|
|
11009
11540
|
const tiaohou = ys.tiaohou && ys.tiaohou.note ? `另外,${ys.tiaohou.note},所以「暖一点、亮一点」的环境通常更舒服。` : '';
|
|
11010
11541
|
const sy = (r.liunian || []).find((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
@@ -11013,7 +11544,7 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
11013
11544
|
: '';
|
|
11014
11545
|
return `你的命局属于「${s(st.level, '中性')}」:${strength}。` +
|
|
11015
11546
|
`${favor ? `能补${favor}的环境(行业、方位、作息、相处的人)会让你省力;${avoid ? `而${avoid}偏重的场合容易空耗,能绕就绕。` : ''}` : ''}` +
|
|
11016
|
-
tiaohou + syPlain;
|
|
11547
|
+
dis + tiaohou + syPlain;
|
|
11017
11548
|
}
|
|
11018
11549
|
if (r.system === 'ziwei') {
|
|
11019
11550
|
const body = r.body || {};
|
|
@@ -11045,7 +11576,7 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
11045
11576
|
const plainBody = bodyPlainOf(labels);
|
|
11046
11577
|
return `${s(ben.name, '这一卦')}讲的是一个「${moving.length ? '正在动、还会变' : '暂时不动、先看清'}」的局面——` +
|
|
11047
11578
|
`${moving.length ? '有动爻,说明事情还有转圜空间,不是死局。' : '六爻安静,说明当下更该观察而不是硬推。'}` +
|
|
11048
|
-
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
11579
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${yingqiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
11049
11580
|
}
|
|
11050
11581
|
return '';
|
|
11051
11582
|
}
|
|
@@ -11148,10 +11679,10 @@ const KNOWLEDGE = [
|
|
|
11148
11679
|
id: 'bazi-yueling-siquan',
|
|
11149
11680
|
system: 'bazi', dims: ['overall', 'career'],
|
|
11150
11681
|
gist: '月令不是「一个月」,是当月最有权的那一个字。',
|
|
11151
|
-
detail: '
|
|
11152
|
-
source: '
|
|
11682
|
+
detail: '月令藏干按本气、中气、余气分日用事,本气当权的时间最长。所以判旺衰先看日主在月令是得令还是失令——得令者未看全局,已有三分底气。本插件按 30 日表算出「生在本月第几日、哪一干当权」,给的是月内轮值这一层细节;旺衰与取格仍以月令本气、透干与会支为主,不随轮值改判。三命通会卷二·论人元司事另列一套日数(寅月五日/五日/二十日),与本插件取的通行表不同;原文并列,不改判。',
|
|
11683
|
+
source: '《子平真诠》论用神;人元司权分日之说见《渊海子平》;三命通会卷二·论人元司事(典藏网 7529)另列一套日数',
|
|
11153
11684
|
status: 'variant',
|
|
11154
|
-
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18
|
|
11685
|
+
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18 等多说);本插件固定通行 30 日表(如寅月戊7丙7甲16),节当日为第 1 日,第 31 日以后按本气算、不硬分摊。三命通会此本寅月作 5/5/20、卯月作 7/23,与通行表不同,两表各照原样。司权表与本柱藏干表口径不同(子月壬、卯月甲、午月丙、酉月庚、亥月戊只出现在司权表里),两表各照原样;取格不随轮值改判。',
|
|
11155
11686
|
},
|
|
11156
11687
|
{
|
|
11157
11688
|
id: 'bazi-tonggen-tougan',
|
|
@@ -11199,10 +11730,10 @@ const KNOWLEDGE = [
|
|
|
11199
11730
|
id: 'bazi-suiyun',
|
|
11200
11731
|
system: 'bazi', dims: ['overall', 'career'],
|
|
11201
11732
|
gist: '大运管十年基调,流年管当年触发。',
|
|
11202
|
-
detail: '
|
|
11203
|
-
source: '
|
|
11733
|
+
detail: '大运像换了条路,流年像这条路上某一段的天气。岁运并临(当值大运与流年干支相同)、运年反吟(大运与流年天克地冲)、大运伏吟(大运与原局某柱干支相同)、大运反吟(大运与原局某柱天克地冲)、流年伏吟(流年与原局某柱干支相同)、流年反吟(流年与原局某柱天克地冲),是传统上标记「变动较大」的年份,属于提示而非断语。本插件逐年标出六类信号:当值大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列;大运与本命四柱的伏吟/反吟整步大运都在,会连续多年重复列出;只标干支重复与对冲,不折分数。原文里「返吟」指岁运与日柱相对、「伏吟」指岁运压日,与本插件「干支相同为伏吟、天克地冲为反吟」不是同一套定义,两者并列、不合并。',
|
|
11734
|
+
source: '《三命通会》卷二·总论岁运(https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7539.html);岁运并临之说出自《渊海子平》',
|
|
11204
11735
|
status: 'variant',
|
|
11205
|
-
note: '
|
|
11736
|
+
note: '「岁运并临主大凶」是流传最广也最被滥用的说法,本插件只作变动提示,不断吉凶;大运与本命四柱的伏吟/反吟会连续多年出现,不逐年加重;四柱十神层面的引化也未叠入。',
|
|
11206
11737
|
},
|
|
11207
11738
|
{
|
|
11208
11739
|
id: 'bazi-liuqin',
|
|
@@ -11258,6 +11789,15 @@ const KNOWLEDGE = [
|
|
|
11258
11789
|
status: 'variant',
|
|
11259
11790
|
note: '化气格成立条件各家宽严不一(是否要求月令为化神、日主是否允许有根),本插件只列条件、附原文,不据此断定化气已成。',
|
|
11260
11791
|
},
|
|
11792
|
+
{
|
|
11793
|
+
id: 'bazi-zaji-quyong',
|
|
11794
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
11795
|
+
gist: '辰戌丑未是杂气月:先看透干,再看会支。',
|
|
11796
|
+
detail: '四墓(辰戌丑未)每个字都藏着不止一气,用神不一,所以叫杂气。子平真诠的取法是:藏干透到天干的先用(甲生辰月,透戊用偏财、透癸用正印、透乙用月劫);没有透干,再看地支有没有与月支会成三合局(辰月逢申子会水,就取水印)。本插件按「透干 → 三合会支 → 本气」的次序取格,依据里写明走的是哪一条,并把《论杂气如何取用》附在结果里。',
|
|
11797
|
+
source: '《子平真诠》十六、论杂气如何取用',
|
|
11798
|
+
status: 'variant',
|
|
11799
|
+
note: '原文说「兼透则兼用」,但只给一个格名时总要落到一个藏干;本插件只取最先透出的那一干,会支也只认三合、不认三会方,且不判原文所说的「有情 / 无情」,取舍次序各家另有说法。',
|
|
11800
|
+
},
|
|
11261
11801
|
{
|
|
11262
11802
|
id: 'bazi-zhuanwang-yuanwen',
|
|
11263
11803
|
system: 'bazi', dims: ['overall', 'career'],
|
|
@@ -11421,10 +11961,10 @@ const KNOWLEDGE = [
|
|
|
11421
11961
|
id: 'liuyao-yingqi',
|
|
11422
11962
|
system: 'liuyao', dims: ['overall', 'career'],
|
|
11423
11963
|
gist: '应期是「什么时候见分晓」,不是「哪天」。',
|
|
11424
|
-
detail: '
|
|
11964
|
+
detail: '近事以日计、远事以月计;常见取法是等用神逢值、逢冲、逢合之期,或等忌神受制之期。本插件只做前一半:把用神(不上卦则取伏神)的逢值、逢冲、逢合三支列出,旬空另标出空与冲空,再按月建五态给「偏速 / 偏缓 / 待解 / 未定」一个快慢方向;忌神受制与具体日期仍未做。应期法各家互有出入,同一卦不同取法可以差出很远,所以只作时间窗口的提示。',
|
|
11425
11965
|
source: '《卜筮正宗》应期章;《增删卜易》',
|
|
11426
11966
|
status: 'variant',
|
|
11427
|
-
note: '
|
|
11967
|
+
note: '应期取法(值日、冲、合、填实、旬空出空)各家优先级不同,本插件只并列触发支、不排先后,也不换算日期;近事以日计、远事以月计,用哪把尺由事情远近决定,不代选。',
|
|
11428
11968
|
},
|
|
11429
11969
|
{
|
|
11430
11970
|
id: 'liuyao-liushen',
|
|
@@ -11579,10 +12119,10 @@ const KNOWLEDGE = [
|
|
|
11579
12119
|
id: 'liuyao-yingqi-exact',
|
|
11580
12120
|
system: 'liuyao', dims: [],
|
|
11581
12121
|
gist: '具体应期(哪一天应验)本插件尚未推算。',
|
|
11582
|
-
detail: '
|
|
12122
|
+
detail: '应期需要综合用神旺衰、动变、旬空出空、日月冲合多层条件,且各家取法不同。当前只给时间窗口的方向性提示(逢值 / 逢冲 / 逢合的触发支,加一个快慢方向),不给具体日期——与其给一个看起来精确、实则拍脑袋的日子,不如留白。',
|
|
11583
12123
|
source: '待补:《卜筮正宗》应期章逐条实现 + 已录 128 条卦例对拍(源 138 条)',
|
|
11584
12124
|
status: 'todo',
|
|
11585
|
-
note: '扩展方向:用《卜筮正宗》卦例里有明确应验日期的条目做回归,先验证再输出。',
|
|
12125
|
+
note: '扩展方向:用《卜筮正宗》卦例里有明确应验日期的条目做回归,先验证再输出。0.50.0 已给出触发支与快慢方向,仍不输出日期。',
|
|
11586
12126
|
},
|
|
11587
12127
|
];
|
|
11588
12128
|
|
|
@@ -12121,6 +12661,7 @@ function baziInterpret(r) {
|
|
|
12121
12661
|
const level = pick(st, 'level', '中和');
|
|
12122
12662
|
const favor = Array.isArray(ys.favor) ? ys.favor : [];
|
|
12123
12663
|
const avoid = Array.isArray(ys.avoid) ? ys.avoid : [];
|
|
12664
|
+
const disputed = Array.isArray(ys.disputed) ? ys.disputed : [];
|
|
12124
12665
|
const primary = pick(frame, 'primaryName', '未取定');
|
|
12125
12666
|
const gender = pick(r.input, 'gender', '');
|
|
12126
12667
|
const isMale = gender === 'male';
|
|
@@ -12329,6 +12870,21 @@ function baziInterpret(r) {
|
|
|
12329
12870
|
`⑤ 落到维度:工作看喜用五行与十神权重;感情看配偶星与日支;健康看最旺与最弱的五行。五维度都只是这套推导的应用,不是另一套算法。`,
|
|
12330
12871
|
].join('\n'),
|
|
12331
12872
|
},
|
|
12873
|
+
...(r.renyuan ? [(() => {
|
|
12874
|
+
const ry = r.renyuan;
|
|
12875
|
+
const table = ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' / ');
|
|
12876
|
+
const nextSeg = ry.next ? `,第 ${ry.next.from} 日起交 ${ry.next.stem}${ry.next.element}` : '';
|
|
12877
|
+
const outside = ry.inHidden ? '' : ` 表里的 ${ry.active} 不在本柱藏干表中(属余气口径),两表各照原样,不互相改写。`;
|
|
12878
|
+
const beyond = ry.beyond ? ' 你生在第 31 日以后,已超出 30 日表,按本气算,不硬分摊。' : '';
|
|
12879
|
+
const ryc = r.renyuanClassic || classicOf('smt-renyuan');
|
|
12880
|
+
const src = ryc ? `\n原文:《${CLASSIC_BOOKS[ryc.book].name}·${ryc.chapter}》「${ryc.quote}」\n白话:${ryc.plain}` : '';
|
|
12881
|
+
return {
|
|
12882
|
+
key: 'renyuan', label: '人元司权',
|
|
12883
|
+
text: `生于${ry.month}月第 ${ry.day} 日(从${ry.term ? ry.term.name : '节'}起算,节当日为第 1 日,日差按本盘所用时刻所在日计):这一日由 **${ry.active}${ry.activeElement}** 司权,第 ${ry.segment.from}–${ry.segment.to} 日属它${nextSeg}。\n`
|
|
12884
|
+
+ '月令这一个月里,余气、中气、本气轮值,不是整月同一个五行当值——所以「月令是什么」,还要看生在第几日。\n'
|
|
12885
|
+
+ `**口径**:本插件固定通行 30 日表(${table});另有 7/7/16、9/3/18 等分法,三命通会此本又作 5/5/20(见下原文),各家不一。分日只作解释层的一层细节,**不改取格**:取格仍按本气、透干与会支判定。${outside}${beyond}` + src,
|
|
12886
|
+
};
|
|
12887
|
+
})()] : []),
|
|
12332
12888
|
{
|
|
12333
12889
|
key: 'timeline', label: '时间窗',
|
|
12334
12890
|
text: (() => {
|
|
@@ -12349,6 +12905,8 @@ function baziInterpret(r) {
|
|
|
12349
12905
|
{ key: 'advice', label: '专业建议', text: adviceText },
|
|
12350
12906
|
(() => {
|
|
12351
12907
|
const hits = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
12908
|
+
const e = suiyunClassicOf(r);
|
|
12909
|
+
const src = e ? `\n原文:《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》「${e.quote}」\n白话:${e.plain}` : '';
|
|
12352
12910
|
return {
|
|
12353
12911
|
key: 'suiyun', label: '岁运提示',
|
|
12354
12912
|
text: hits.length
|
|
@@ -12356,8 +12914,8 @@ function baziInterpret(r) {
|
|
|
12356
12914
|
const stem = (l.suiyun.dayun || []).map((d) => `第${d.step}步${d.ganzhi}`).join('、');
|
|
12357
12915
|
return `${l.year} ${l.ganzhi}(${stem || '未到起运'}):${l.suiyun.signals.map((s) => s.detail).join(';')}`;
|
|
12358
12916
|
}).join('\n') +
|
|
12359
|
-
'\n
|
|
12360
|
-
: '
|
|
12917
|
+
'\n读法:岁运并临、运年反吟、大运与流年的伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。大运与本命四柱的伏吟/反吟整步大运都在,会连续多年出现,不当成逐年加重。' + src
|
|
12918
|
+
: '近十年没有岁运并临、运年反吟或大运/流年伏吟、反吟。「岁运并临主大凶」这类说法流传很广,本插件只把它当变动提示,没有命中就不作额外解读。',
|
|
12361
12919
|
};
|
|
12362
12920
|
})(),
|
|
12363
12921
|
{
|
|
@@ -12393,7 +12951,7 @@ function baziInterpret(r) {
|
|
|
12393
12951
|
...(cli ? [{
|
|
12394
12952
|
key: 'climate', label: '寒暖燥湿',
|
|
12395
12953
|
text: `${cli.narration}${cli.need
|
|
12396
|
-
? `调候取${cli.need.stem}${cli.need.element},忌${cli.avoidElement};${cli.clash ? '与扶抑冲突,本盘以调候为先' : '与扶抑同向'}`
|
|
12954
|
+
? `调候取${cli.need.stem}${cli.need.element},忌${cli.avoidElement}${disputed.some((d) => d.element === cli.avoidElement) ? '(有争议:该行在扶抑中为喜,见用神节)' : ''};${cli.clash ? '与扶抑冲突,本盘以调候为先' : disputed.some((d) => d.element === cli.avoidElement) ? '调候所忌在扶抑里为喜,两说并存' : '与扶抑同向'}`
|
|
12397
12955
|
: '气候平和,调候不作主取'}。`,
|
|
12398
12956
|
}] : []),
|
|
12399
12957
|
...(ys.qt ? [{
|
|
@@ -13088,10 +13646,31 @@ function liuyaoInterpret(r, ask) {
|
|
|
13088
13646
|
useText.push(`时令对用神:${head},日辰 ${strength.day ? `${strength.day.branch}(${strength.day.element})` : '—'}。${body.join(';')}。`);
|
|
13089
13647
|
useText.push('月建看这一段时令站在哪一边,日辰看当天那股力量是扶还是克;两处同时看,只报状态,不折成分数。');
|
|
13090
13648
|
}
|
|
13091
|
-
useText.push('
|
|
13649
|
+
useText.push('这一层只把用神、卦体与时令对起来,不折成分数、不断成败;应期另在「应期线索」一节只给触发支与快慢。');
|
|
13092
13650
|
sections.push({ key: 'yongshen', label: '用神落位与卦体', text: useText.join('\n') });
|
|
13093
13651
|
}
|
|
13094
13652
|
|
|
13653
|
+
{
|
|
13654
|
+
const yq = r.yingqi;
|
|
13655
|
+
if (yq && Array.isArray(yq.items) && yq.items.length) {
|
|
13656
|
+
const rows = yq.items.map((it) => {
|
|
13657
|
+
const flags = [
|
|
13658
|
+
it.monthState && it.monthState !== 'unknown' ? `月建${it.monthState}` : '',
|
|
13659
|
+
it.monthChong ? '月破' : '',
|
|
13660
|
+
it.kong ? '旬空' : '',
|
|
13661
|
+
].filter(Boolean).join('、');
|
|
13662
|
+
return `${it.position}爻${it.branch}${it.element}${flags ? `(${flags})` : ''}:${it.tempoSay}`;
|
|
13663
|
+
});
|
|
13664
|
+
sections.push({
|
|
13665
|
+
key: 'yingqi',
|
|
13666
|
+
label: '应期线索',
|
|
13667
|
+
text: `应期快慢:${yq.tempoSay}。${rows.join(';')}。可留意的地支:${yq.triggers.map((t) => `${t.branch}(${t.labels.join('、')})`).join(';')}。` +
|
|
13668
|
+
`${yq.viaFushen ? '用神不上卦,这里的支取自伏神;伏神要先得出才算数。' : ''}` +
|
|
13669
|
+
'这一节只把传统的「逢值、逢冲、逢合」与旬空的出空、冲空摆出来,不换算成具体日期、不排先后、也不判忌神受制;近事以日计、远事以月计,用哪把尺取决于事情本身。',
|
|
13670
|
+
});
|
|
13671
|
+
}
|
|
13672
|
+
}
|
|
13673
|
+
|
|
13095
13674
|
{
|
|
13096
13675
|
const hs = r.hexStrength;
|
|
13097
13676
|
if (hs && Array.isArray(hs.lines) && hs.lines.length) {
|
|
@@ -13120,7 +13699,7 @@ function liuyaoInterpret(r, ask) {
|
|
|
13120
13699
|
|
|
13121
13700
|
sections.push({
|
|
13122
13701
|
key: 'limits', label: '未纳入',
|
|
13123
|
-
text: '
|
|
13702
|
+
text: '本卦没有计算:用神两现时该取哪一爻的权重、应期的具体日期(只给逢值/逢冲/逢合的触发支与快慢方向)、忌神受制的时点、动变连环。化进/化退的力重只按月建五态给「得令/失令」这类档位,不折成加权分数;这些都会改变"旺不旺"的判断,所以这里只给取象与方向。',
|
|
13124
13703
|
});
|
|
13125
13704
|
|
|
13126
13705
|
const dimensions = [
|
|
@@ -13523,7 +14102,7 @@ const BUILDERS = {
|
|
|
13523
14102
|
const { interpretQimen } = __mods['qimen-interpret'];
|
|
13524
14103
|
const { buildAnswer, buildPlain, buildGlossary, buildFollowups, dimensionPlain } = __mods['interpret-plain'];
|
|
13525
14104
|
const { knowledgeFor, caveatsFor, STATUS_LABEL } = __mods['interpret-knowledge'];
|
|
13526
|
-
const { CLASSIC_BOOKS } = __mods.classics;
|
|
14105
|
+
const { CLASSIC_BOOKS, suiyunClassicOf, classicOf } = __mods.classics;
|
|
13527
14106
|
|
|
13528
14107
|
function enrichPlain(result, r, ask) {
|
|
13529
14108
|
if (!result) return result;
|
|
@@ -13992,16 +14571,32 @@ function crossCheck(bazi, zw) {
|
|
|
13992
14571
|
const bad = ['忌', '大忌'];
|
|
13993
14572
|
const baziGood = good.includes(t);
|
|
13994
14573
|
const baziBad = bad.includes(t);
|
|
14574
|
+
const baziKnown = t !== '—';
|
|
13995
14575
|
const ziweiHeavy = sha >= 2;
|
|
14576
|
+
const ziweiKnown = !!d;
|
|
13996
14577
|
let stance = '有张力';
|
|
13997
|
-
let note = '
|
|
13998
|
-
if (
|
|
14578
|
+
let note = '';
|
|
14579
|
+
if (!baziKnown || !ziweiKnown) {
|
|
14580
|
+
stance = '互补';
|
|
14581
|
+
const missing = !baziKnown && !ziweiKnown
|
|
14582
|
+
? '八字当前大运与紫微当前大限都没取到'
|
|
14583
|
+
: !baziKnown
|
|
14584
|
+
? `八字当前大运未取到(${t}),只有紫微一侧可参考`
|
|
14585
|
+
: '紫微当前大限未取到,只有八字一侧可参考';
|
|
14586
|
+
note = `${missing}:这一项只作提醒,不下两边对照的结论`;
|
|
14587
|
+
} else if (baziGood && ziweiHeavy) {
|
|
14588
|
+
note = '八字这边顺、紫微大限煞星偏多:大方向可参考八字,具体动作按紫微标出的位置收一收';
|
|
14589
|
+
} else if (baziBad && !ziweiHeavy) {
|
|
14590
|
+
note = '八字这边偏紧、紫微大限没见到明显煞星:先按八字收着走,紫微一侧的平静不等于没有压力';
|
|
14591
|
+
} else if (!baziGood && !baziBad && ziweiHeavy) {
|
|
14592
|
+
note = '八字大运为平、紫微大限煞星偏多:只把紫微这一侧当作提醒,不据此判断阶段好坏';
|
|
14593
|
+
} else {
|
|
13999
14594
|
stance = '同向';
|
|
14000
14595
|
note = '两边对当前阶段的松紧判断接近';
|
|
14001
14596
|
}
|
|
14002
14597
|
push('rhythm', '当前节奏',
|
|
14003
14598
|
`大运档位 ${t}`,
|
|
14004
|
-
|
|
14599
|
+
d ? `大限在${d.palace}${sha ? `;煞星 ${sha} 颗` : ';无煞星'}` : '大限未取到',
|
|
14005
14600
|
stance, note);
|
|
14006
14601
|
}
|
|
14007
14602
|
|
|
@@ -14015,7 +14610,12 @@ function crossText(cross) {
|
|
|
14015
14610
|
.join('\n');
|
|
14016
14611
|
}
|
|
14017
14612
|
|
|
14018
|
-
|
|
14613
|
+
function crossSection(cross) {
|
|
14614
|
+
const items = cross && Array.isArray(cross.items) ? cross.items : [];
|
|
14615
|
+
return { key: 'crossSystem', label: '八字 × 紫微 交叉验证', text: crossText(cross), items };
|
|
14616
|
+
}
|
|
14617
|
+
|
|
14618
|
+
return { crossCheck, crossText, crossSection };
|
|
14019
14619
|
})();
|
|
14020
14620
|
|
|
14021
14621
|
__mods.verify = (function () {
|
|
@@ -14184,7 +14784,7 @@ return { matchEvent, rectifyBirth, RECTIFY_KINDS };
|
|
|
14184
14784
|
|
|
14185
14785
|
__mods.index = (function () {
|
|
14186
14786
|
const { buildBazi } = __mods.bazi;
|
|
14187
|
-
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, fushenAccess, hexagramStrength, jinTuiPower } = __mods.liuyao;
|
|
14787
|
+
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, fushenAccess, hexagramStrength, jinTuiPower, yingqiWindow } = __mods.liuyao;
|
|
14188
14788
|
const { buildZiwei, BRIGHTNESS, flowOf, asOfParts, ZIWEI_SCHOOL_DEFAULTS } = __mods.ziwei;
|
|
14189
14789
|
const { drawTarot } = __mods.tarot;
|
|
14190
14790
|
const { buildMeihua } = __mods.meihua;
|
|
@@ -14197,7 +14797,7 @@ const { toJDN, ganzhiName, dayGanzhiIndex } = __mods.calendar;
|
|
|
14197
14797
|
const { randomOf, isSeed } = __mods.random;
|
|
14198
14798
|
const { interpret, DIRECTIONS, DIRECTION_DEFAULT } = __mods.interpret;
|
|
14199
14799
|
const { followup, askPrompt } = __mods.followup;
|
|
14200
|
-
const { crossCheck, crossText } = __mods.crosscheck;
|
|
14800
|
+
const { crossCheck, crossText, crossSection } = __mods.crosscheck;
|
|
14201
14801
|
const { pastSignals, verifyFit } = __mods.verify;
|
|
14202
14802
|
const { rectifyBirth } = __mods.rectify;
|
|
14203
14803
|
const { buildAlmanac } = __mods.almanac;
|
|
@@ -14208,7 +14808,8 @@ const { buildStar } = __mods.star;
|
|
|
14208
14808
|
const { buildNumerology } = __mods.numerology;
|
|
14209
14809
|
const { buildMbti, mbtiPaper } = __mods.mbti;
|
|
14210
14810
|
const { buildConvert } = __mods.convert;
|
|
14211
|
-
const { classicsFor, classicsText } = __mods.classics;
|
|
14811
|
+
const { classicsFor, classicsText, suiyunClassicOf, classicOf, CLASSIC_BOOKS } = __mods.classics;
|
|
14812
|
+
const { diffObjects, summarize, sortDiffs, labelOf, rootOf, categoryOf, formatValue, CALIBER_SWITCHES } = __mods.diff;
|
|
14212
14813
|
const { buildTrend } = __mods.trend;
|
|
14213
14814
|
const { buildFengshui } = __mods.fengshui;
|
|
14214
14815
|
const { buildName } = __mods.name;
|
|
@@ -14298,12 +14899,22 @@ function baziText(r) {
|
|
|
14298
14899
|
? `神煞(${r.shensha.count} 见):` + r.shensha.groups.map((g) =>
|
|
14299
14900
|
`${g.cat}|` + g.items.map((i) => `${i.name}(${i.pillars.map((k) => SHORT[k]).join('')})`).join('、')).join(';')
|
|
14300
14901
|
: '神煞:—';
|
|
14902
|
+
const ry = r.renyuan;
|
|
14903
|
+
const rySrc = classicOf('smt-renyuan');
|
|
14904
|
+
const renyuanLine = ry
|
|
14905
|
+
? `人元:${ry.month}月第${ry.day}日,${ry.active}${ry.activeElement}司权(${ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' ')})${ry.beyond ? ';已过 30 日表,按本气算' : ''}${rySrc ? `|原文见《${CLASSIC_BOOKS[rySrc.book].name}·${rySrc.chapter}》` : ''}`
|
|
14906
|
+
: '';
|
|
14907
|
+
const ysd = (r.frame && r.frame.yongshen && r.frame.yongshen.disputed) || [];
|
|
14908
|
+
const disText = ysd.length
|
|
14909
|
+
? ` 有争议:${ysd.map((d) => `${d.element}(${d.favorRole};${d.climate}盘调候忌${d.element})`).join('、')}`
|
|
14910
|
+
: '';
|
|
14911
|
+
const disEls = new Set(ysd.map((d) => d.element));
|
|
14301
14912
|
const gejuLine = r.frame ? [
|
|
14302
14913
|
`格局:${r.frame.primary ? `${r.frame.primary.name}(${r.frame.primary.evidence})` : '—'}`,
|
|
14303
14914
|
` ${r.frame.geju.map((g) => `${g.name}[${g.kind}]`).join(' ')}`,
|
|
14304
|
-
`用神:喜${r.frame.yongshen.favor.join('')}(${r.frame.yongshen.favorTenGods.join('、')}) 忌${r.frame.yongshen.avoid.join('')}(${r.frame.yongshen.avoidTenGods.join('、')}
|
|
14915
|
+
`用神:喜${r.frame.yongshen.favor.join('')}(${r.frame.yongshen.favorTenGods.join('、')}) 忌${r.frame.yongshen.avoid.join('')}(${r.frame.yongshen.avoidTenGods.join('、')})${disText} ${r.frame.yongshen.method}`,
|
|
14305
14916
|
` ${r.frame.yongshen.detail}`,
|
|
14306
|
-
`寒暖:${r.climate ? `${r.climate.label}(${(r.climate.evidence || []).join('、')})${r.climate.need ? ` 调候取${r.climate.need.stem}${r.climate.need.element} 忌${r.climate.avoidElement}` : ''}` : '—'}` +
|
|
14917
|
+
`寒暖:${r.climate ? `${r.climate.label}(${(r.climate.evidence || []).join('、')})${r.climate.need ? ` 调候取${r.climate.need.stem}${r.climate.need.element} 忌${r.climate.avoidElement}${disEls.has(r.climate.avoidElement) ? '(有争议)' : ''}` : ''}` : '—'}` +
|
|
14307
14918
|
(r.frame.yongshen.qt ? ` 穷通:${r.frame.yongshen.qt.month}${r.frame.yongshen.qt.stem}取${r.frame.yongshen.qt.yong.join('、')}(首取${r.frame.yongshen.qt.primary})` : ''),
|
|
14308
14919
|
`十神权重:${Object.entries(r.frame.godStats.groups).map(([k, v]) => `${k}${v}`).join(' ')}`,
|
|
14309
14920
|
] : [];
|
|
@@ -14320,15 +14931,18 @@ function baziText(r) {
|
|
|
14320
14931
|
shenshaLine,
|
|
14321
14932
|
`真太阳时:${r.solarTime.trueSolarText}(${r.input.geo ? r.input.geo.note + ';' : ''}${r.solarTime.note}) 晚子时:${r.input.lateZi ? '23:00 后算次日' : '23:00 后仍算当日'}`,
|
|
14322
14933
|
`节气:上一节 ${r.jieqi.previous.name} ${r.jieqi.previous.time} 下一节 ${r.jieqi.next.name} ${r.jieqi.next.time}`,
|
|
14934
|
+
...(renyuanLine ? [renyuanLine] : []),
|
|
14323
14935
|
`大运:${r.dayun.rule}(${r.dayun.direction}),${r.dayun.startAge.years}岁${r.dayun.startAge.months}个月起运${jiao}`,
|
|
14324
14936
|
` ${dayun}`,
|
|
14325
14937
|
`流年:${r.liunian.slice(0, 10).map((l) => `${l.year}${l.ganzhi}(${l.stemTenGod})${l.luck ? `·${l.luck.tier}` : ''}`).join(' ')}`,
|
|
14326
14938
|
(() => {
|
|
14327
14939
|
const hits = r.liunian.filter((l) => l.suiyun && l.suiyun.signals && l.suiyun.signals.length);
|
|
14328
|
-
if (!hits.length) return '
|
|
14329
|
-
const label = (s) => `${s.type}${s.type.startsWith('流年') && s.target ? `(${s.target})` : ''}`;
|
|
14940
|
+
if (!hits.length) return '岁运提示:近十年无岁运并临、运年反吟或大运/流年伏吟、反吟(只标干支,不判吉凶)';
|
|
14941
|
+
const label = (s) => `${s.type}${(s.type.startsWith('流年') || s.type.startsWith('大运')) && s.target ? `(${s.target})` : ''}`;
|
|
14942
|
+
const e = suiyunClassicOf(r);
|
|
14943
|
+
const src = e ? `|古籍见《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》` : '';
|
|
14330
14944
|
return '岁运提示(只标干支变动,不判吉凶):' + hits
|
|
14331
|
-
.map((l) => `${l.year}${l.ganzhi} ${l.suiyun.signals.map(label).join('/')}`).join(';');
|
|
14945
|
+
.map((l) => `${l.year}${l.ganzhi} ${l.suiyun.signals.map(label).join('/')}`).join(';') + src;
|
|
14332
14946
|
})(),
|
|
14333
14947
|
'(格局、用神、行运吉凶为扶抑+简化调候的量化提示,非断语。)',
|
|
14334
14948
|
].join('\n') + near;
|
|
@@ -14570,6 +15184,10 @@ function liuyaoText(r) {
|
|
|
14570
15184
|
if (jt && Array.isArray(jt.lines) && jt.lines.length) {
|
|
14571
15185
|
out.push(`进退力重:${jt.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type}·${l.verdict}`).join(' · ')}`);
|
|
14572
15186
|
}
|
|
15187
|
+
const yq = r.yingqi;
|
|
15188
|
+
if (yq && Array.isArray(yq.triggers) && yq.triggers.length) {
|
|
15189
|
+
out.push(`应期线索:${yq.tempo} · ${yq.triggers.map((t) => `${t.labels.join('/')}${t.branch}`).join(' · ')}(只列地支,不出日期)`);
|
|
15190
|
+
}
|
|
14573
15191
|
return out.filter(Boolean).join('\n');
|
|
14574
15192
|
}
|
|
14575
15193
|
|
|
@@ -14583,6 +15201,12 @@ function compute(args = {}) {
|
|
|
14583
15201
|
r.classics = classicsFor(r);
|
|
14584
15202
|
const ct = classicsText(r.classics);
|
|
14585
15203
|
if (ct) r.summary = `${r.summary}\n【古籍】\n${ct}`;
|
|
15204
|
+
const syc = suiyunClassicOf(r);
|
|
15205
|
+
if (syc) r.suiyunClassic = { ...syc, bookName: CLASSIC_BOOKS[syc.book].name };
|
|
15206
|
+
if (r.renyuan) {
|
|
15207
|
+
const ryc = classicOf('smt-renyuan');
|
|
15208
|
+
if (ryc) r.renyuanClassic = { ...ryc, bookName: CLASSIC_BOOKS[ryc.book].name };
|
|
15209
|
+
}
|
|
14586
15210
|
}
|
|
14587
15211
|
if (r && r.precision && r.precision.level === 'approx' && r.summary) {
|
|
14588
15212
|
r.summary = `⚠ ${r.precision.note}\n${r.summary}`;
|
|
@@ -14613,7 +15237,7 @@ function compute(args = {}) {
|
|
|
14613
15237
|
: buildBazi({ ...common, lateZi: args.lateZi !== false, nowYear: asOf ? asOf.year : undefined });
|
|
14614
15238
|
r.cross = crossCheck(r.system === 'bazi' ? r : other, r.system === 'ziwei' ? r : other);
|
|
14615
15239
|
if (r.interpret) {
|
|
14616
|
-
r.interpret.sections.push(
|
|
15240
|
+
r.interpret.sections.push(crossSection(r.cross));
|
|
14617
15241
|
}
|
|
14618
15242
|
}
|
|
14619
15243
|
if (Number.isInteger(args.verifyPast) && args.verifyPast > 0 && r.system === 'bazi') {
|
|
@@ -14689,6 +15313,64 @@ function interpretText(i) {
|
|
|
14689
15313
|
return out.join('\n');
|
|
14690
15314
|
}
|
|
14691
15315
|
|
|
15316
|
+
const CALIBER_IGNORE_ARGS = ['cross', 'verifyPast', 'withInterpret', 'question', 'direction', 'ask', 'geocode', 'rectify', 'events'];
|
|
15317
|
+
|
|
15318
|
+
function caliberCompare(args = {}, opts = {}) {
|
|
15319
|
+
const system = opts.system || args.system;
|
|
15320
|
+
const switches = opts.switches || CALIBER_SWITCHES[system] || [];
|
|
15321
|
+
if (!switches.length) return { system, switches: [], affected: 0, total: 0 };
|
|
15322
|
+
const base = { ...args };
|
|
15323
|
+
for (const k of CALIBER_IGNORE_ARGS) delete base[k];
|
|
15324
|
+
const rows = switches.map((sw) => {
|
|
15325
|
+
const current = sw.read(base);
|
|
15326
|
+
const alt = sw.alt(current);
|
|
15327
|
+
let diffs = [];
|
|
15328
|
+
let error = '';
|
|
15329
|
+
try {
|
|
15330
|
+
diffs = diffObjects(
|
|
15331
|
+
compute({ ...base, [sw.key]: current }),
|
|
15332
|
+
compute({ ...base, [sw.key]: alt }),
|
|
15333
|
+
);
|
|
15334
|
+
} catch (e) {
|
|
15335
|
+
error = (e && e.message) || String(e);
|
|
15336
|
+
}
|
|
15337
|
+
const roots = sortDiffs(diffs.filter((d) => rootOf(d.path))).map((d) => ({
|
|
15338
|
+
path: d.path,
|
|
15339
|
+
label: labelOf(d.path),
|
|
15340
|
+
from: formatValue(d.from),
|
|
15341
|
+
to: formatValue(d.to),
|
|
15342
|
+
}));
|
|
15343
|
+
const counts = new Map();
|
|
15344
|
+
for (const d of diffs) {
|
|
15345
|
+
const c = categoryOf(d.path) || '其他';
|
|
15346
|
+
counts.set(c, (counts.get(c) || 0) + 1);
|
|
15347
|
+
}
|
|
15348
|
+
const categories = [...counts.entries()]
|
|
15349
|
+
.map(([name, count]) => ({ name, count }))
|
|
15350
|
+
.sort((a, b) => b.count - a.count || a.name.localeCompare(b.name, 'zh-Hans-CN'));
|
|
15351
|
+
return {
|
|
15352
|
+
key: sw.key,
|
|
15353
|
+
title: sw.title,
|
|
15354
|
+
short: sw.short,
|
|
15355
|
+
current,
|
|
15356
|
+
alt,
|
|
15357
|
+
currentLabel: sw.label(current),
|
|
15358
|
+
altLabel: sw.label(alt),
|
|
15359
|
+
total: diffs.length,
|
|
15360
|
+
summary: error ? '' : summarize(diffs),
|
|
15361
|
+
roots,
|
|
15362
|
+
categories,
|
|
15363
|
+
error,
|
|
15364
|
+
};
|
|
15365
|
+
});
|
|
15366
|
+
return {
|
|
15367
|
+
system,
|
|
15368
|
+
switches: rows,
|
|
15369
|
+
affected: rows.filter((r) => !r.error && r.total > 0).length,
|
|
15370
|
+
total: rows.reduce((n, r) => n + r.total, 0),
|
|
15371
|
+
};
|
|
15372
|
+
}
|
|
15373
|
+
|
|
14692
15374
|
const JU_METHODS = ['chaibu', 'chaoshen', 'zhirun'];
|
|
14693
15375
|
const TAROT_COUNTS = [1, 3, 5];
|
|
14694
15376
|
const LATE_ZI_MODES = ['same-day', 'next-day'];
|
|
@@ -14871,6 +15553,8 @@ function computeRaw(args = {}) {
|
|
|
14871
15553
|
if (strength) result.useGodStrength = strength;
|
|
14872
15554
|
const chufu = fushenAccess(result, ug, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
14873
15555
|
if (chufu) result.fushenAccess = chufu;
|
|
15556
|
+
const yq = yingqiWindow(result, ug, { monthBranch });
|
|
15557
|
+
if (yq) result.yingqi = yq;
|
|
14874
15558
|
}
|
|
14875
15559
|
if (args.seed !== undefined && args.seed !== null && args.seed !== '') result.seed = Number(args.seed);
|
|
14876
15560
|
return { ...result, ...(asOf ? { asOf } : {}), summary: liuyaoText(result) };
|
|
@@ -15281,6 +15965,15 @@ function renderText(result) {
|
|
|
15281
15965
|
if (extra) parts.push(extra);
|
|
15282
15966
|
}
|
|
15283
15967
|
if (result.cross) parts.push(`【八字 × 紫微 交叉验证】\n${crossText(result.cross)}`);
|
|
15968
|
+
if (result.caliber && Array.isArray(result.caliber.switches) && result.caliber.switches.length) {
|
|
15969
|
+
const c = result.caliber;
|
|
15970
|
+
parts.push('【口径对照】同一组输入,只换一个口径(不判哪套更准,也不改盘面)\n'
|
|
15971
|
+
+ c.switches.map((s) => {
|
|
15972
|
+
if (s.error) return `· ${s.title}:未能对照(${s.error})`;
|
|
15973
|
+
if (!s.total) return `· ${s.title}:${s.currentLabel} → ${s.altLabel},本盘无变化`;
|
|
15974
|
+
return `· ${s.title}:${s.currentLabel} → ${s.altLabel}\n ${s.summary}`;
|
|
15975
|
+
}).join('\n'));
|
|
15976
|
+
}
|
|
15284
15977
|
if (result.followup) {
|
|
15285
15978
|
const f = result.followup;
|
|
15286
15979
|
parts.push(`【追问】${f.question}\n${f.answer}${f.evidence && f.evidence.length ? `\n 依据:${f.evidence.join(';')} 置信度:${f.confidence}` : ''}`);
|
|
@@ -15299,12 +15992,13 @@ function renderText(result) {
|
|
|
15299
15992
|
return parts.filter(Boolean).join('\n\n');
|
|
15300
15993
|
}
|
|
15301
15994
|
|
|
15302
|
-
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 };
|
|
15995
|
+
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, caliberCompare, renderText };
|
|
15303
15996
|
})();
|
|
15304
15997
|
|
|
15305
15998
|
const Engine = __mods.index;
|
|
15306
15999
|
window.Engine = Engine;
|
|
15307
|
-
window.__MP_VER = '0.
|
|
16000
|
+
window.__MP_VER = '0.50.5';
|
|
16001
|
+
window.__MPGroups = [{"title":"问一件事","hint":"心里有一件具体的事,起一卦再决定","items":[{"k":"liuyao","label":"六爻","tip":"摇六次,问一件事"},{"k":"meihua","label":"梅花","tip":"见闻起卦,看当下"},{"k":"tarot","label":"塔罗","tip":"抽牌,看关系与选择"},{"k":"qimen","label":"奇门","tip":"看方位、时机与取舍"},{"k":"daliuren","label":"六壬","tip":"占事,断来意与结果"},{"k":"xiaoliuren","label":"小六壬","tip":"掐指一算,快速断"}]},{"title":"看一个人","hint":"看自己或身边人的性情、格局与运程","items":[{"k":"bazi","label":"八字","tip":"四柱看一生格局"},{"k":"ziwei","label":"紫微","tip":"十二宫细看"},{"k":"hepan","label":"合盘","tip":"两个人合不合"},{"k":"mbti","label":"人格","tip":"16 型性格问卷"},{"k":"chenggu","label":"称骨","tip":"按生辰称命重"},{"k":"numerology","label":"数字","tip":"生日数字看性格"},{"k":"trend","label":"人生K","tip":"一生高低走势","wide":true}]},{"title":"查日子","hint":"挑时间、换农历,顺带看看家里和名字","items":[{"k":"almanac","label":"黄历","tip":"今天宜忌、时辰吉凶"},{"k":"zeri","label":"择日","tip":"挑个办事的好日子"},{"k":"convert","label":"农历","tip":"公历农历互转"},{"k":"star","label":"星座","tip":"星座性格与今日运"},{"k":"fengshui","label":"风水","tip":"房屋朝向与布置"},{"k":"name","label":"起名","tip":"按八字选字"}]}];
|
|
15308
16002
|
(function () {
|
|
15309
16003
|
const NEED_ASK = { liuyao: true, meihua: true, daliuren: true, tarot: true };
|
|
15310
16004
|
const needAsk = (kind) => !!NEED_ASK[kind];
|
|
@@ -15335,7 +16029,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15335
16029
|
|
|
15336
16030
|
(function () {
|
|
15337
16031
|
const CSS = `
|
|
15338
|
-
.pp,.mp-it,.mp-al,.mp-cg,.mp-cl,.mp-cli,.mp-kline,.mp-mb,.mp-mb-paper,.mp-nm,.mp-quick{--ink:#1b1b1b;--ink2:#3f3a33;--muted:#6f6a60;--label:#8a8378;--faint:#a9a296;
|
|
16032
|
+
.pp,.mp-it,.mp-al,.mp-cg,.mp-cl,.mp-cli,.mp-kline,.mp-mb,.mp-mb-paper,.mp-nm,.mp-quick,.mp-cdiff{--ink:#1b1b1b;--ink2:#3f3a33;--muted:#6f6a60;--label:#8a8378;--faint:#a9a296;
|
|
15339
16033
|
--line:#c8c1b2;--dimline:#b9b2a4;--hair:#e9e2d3;
|
|
15340
16034
|
--bg:#f6f1e6;--card:#fffdf8;--band:#fbf7ee;--hover:#f3ede1;--hover2:#ece5d6;
|
|
15341
16035
|
--tri:#f3e8cd;--soul:#fae4dc;--sel:#fceee7;--link:#f9ece0;
|
|
@@ -15348,7 +16042,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15348
16042
|
.pp{border:1px solid var(--line);background:var(--bg);color:var(--ink);font-family:"Songti SC","SimSun","Microsoft YaHei",serif;font-size:12.5px;line-height:1.55;
|
|
15349
16043
|
border-radius:12px;overflow:hidden;box-shadow:var(--shadow);container-type:inline-size}
|
|
15350
16044
|
@media screen and (prefers-color-scheme:dark){
|
|
15351
|
-
.pp,.mp-it,.mp-al,.mp-cg,.mp-cl,.mp-cli,.mp-kline,.mp-mb,.mp-mb-paper,.mp-nm,.mp-quick{--ink:#eae5d9;--ink2:#d5cfc2;--muted:#aca598;--label:#a49c8e;--faint:#928b7e;
|
|
16045
|
+
.pp,.mp-it,.mp-al,.mp-cg,.mp-cl,.mp-cli,.mp-kline,.mp-mb,.mp-mb-paper,.mp-nm,.mp-quick,.mp-cdiff{--ink:#eae5d9;--ink2:#d5cfc2;--muted:#aca598;--label:#a49c8e;--faint:#928b7e;
|
|
15352
16046
|
--line:#514a3e;--dimline:#5f5849;--hair:#2f2b23;
|
|
15353
16047
|
--bg:#12110c;--card:#211f18;--band:#282419;--hover:#2e2a1f;--hover2:#383322;
|
|
15354
16048
|
--tri:#332913;--soul:#3a231c;--sel:#43271f;--link:#33241c;
|
|
@@ -15431,6 +16125,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15431
16125
|
.pp-str b{color:var(--red);font-size:15px;margin:0 4px}
|
|
15432
16126
|
.pp-drel{font-style:normal;color:var(--red);font-size:12px}
|
|
15433
16127
|
.pp-dim{color:var(--muted)}
|
|
16128
|
+
.pp-sy-src{margin-top:6px;font-size:11.5px;line-height:1.55}
|
|
15434
16129
|
.pp-r{display:none}
|
|
15435
16130
|
.pp-modes{display:flex;align-items:center;border-bottom:1px solid var(--line);font-family:system-ui,sans-serif}
|
|
15436
16131
|
.pp-modes label{min-height:44px;display:inline-flex;align-items:center;padding:3px 20px;font-size:12.5px;color:var(--muted);cursor:pointer;border-right:1px solid var(--line);user-select:none}
|
|
@@ -15711,7 +16406,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15711
16406
|
.mp-tt-ta{width:100%;border:1px solid var(--line);background:var(--card);color:var(--ink);padding:8px;font-size:13px;font-family:inherit;line-height:1.7;resize:vertical;outline:none}
|
|
15712
16407
|
.mp-tt-ta:focus{border-color:var(--red)}
|
|
15713
16408
|
|
|
15714
|
-
.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);
|
|
16409
|
+
.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;
|
|
15715
16410
|
font-family:"Songti SC","SimSun","Microsoft YaHei",serif;font-size:13px;line-height:1.75}
|
|
15716
16411
|
.mp-it *{box-sizing:border-box}
|
|
15717
16412
|
.mp-it-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap;width:100%;padding:12px 16px;border:none;border-bottom:1px solid var(--line);background:var(--card);color:inherit;font:inherit;font-family:inherit;text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none}
|
|
@@ -15797,13 +16492,68 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15797
16492
|
.mp-it-conf.c-强{color:var(--lu);border-color:rgba(var(--lu-rgb),.4)}
|
|
15798
16493
|
.mp-it-conf.c-中{color:var(--label);border-color:var(--line)}
|
|
15799
16494
|
.mp-it-conf.c-弱{color:var(--red);border-color:rgba(var(--red-rgb),.4)}
|
|
16495
|
+
.mp-cross{display:flex;flex-direction:column;gap:8px;font-family:system-ui,sans-serif}
|
|
16496
|
+
.mp-cross-row{border:1px solid var(--line);border-radius:8px;background:var(--card);padding:9px 11px}
|
|
16497
|
+
.mp-cross-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
16498
|
+
.mp-cross-l{font-size:13px;font-weight:700;color:var(--ink);letter-spacing:.02em}
|
|
16499
|
+
.mp-cross-tag{font-size:11px;line-height:1.5;padding:1px 8px;border:1px solid currentColor;border-radius:999px;color:var(--muted)}
|
|
16500
|
+
.mp-cross-tag.t-good{color:var(--lu)}
|
|
16501
|
+
.mp-cross-tag.t-watch{color:var(--quan)}
|
|
16502
|
+
.mp-cross-tag.t-alt{color:var(--ke)}
|
|
16503
|
+
.mp-cross-b{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:4px 14px;margin-top:7px}
|
|
16504
|
+
.mp-cross-cell{font-size:12.5px;line-height:1.75;color:var(--ink2)}
|
|
16505
|
+
.mp-cross-cell b{display:block;font-size:10.5px;letter-spacing:.1em;color:var(--muted);font-weight:600;margin-bottom:1px}
|
|
16506
|
+
.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)}
|
|
16507
|
+
.mp-cdiff{margin:12px 0 0;border:1px solid var(--line);border-radius:10px;background:var(--card);overflow:hidden;font-family:system-ui,sans-serif}
|
|
16508
|
+
.mp-cdiff>summary{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-height:44px;padding:8px 13px;cursor:pointer;list-style:none;color:var(--ink2);font-size:12.5px;line-height:1.6}
|
|
16509
|
+
.mp-cdiff>summary::-webkit-details-marker{display:none}
|
|
16510
|
+
.mp-cdiff>summary::before{content:'▸';color:var(--red);font-size:12px}
|
|
16511
|
+
.mp-cdiff[open]>summary::before{content:'▾'}
|
|
16512
|
+
.mp-cdiff-title{font-size:13px;font-weight:700;letter-spacing:.06em;color:var(--red)}
|
|
16513
|
+
.mp-cdiff-lead{color:var(--muted)}
|
|
16514
|
+
.mp-cdiff-more{margin-left:auto;color:var(--label);font-size:11.5px;white-space:nowrap}
|
|
16515
|
+
.mp-cdiff[open] .mp-cdiff-more{display:none}
|
|
16516
|
+
.mp-cdiff-body{padding:0 13px 12px;border-top:1px dashed var(--line)}
|
|
16517
|
+
.mp-cdiff-row{padding:9px 0;border-bottom:1px dashed var(--line)}
|
|
16518
|
+
.mp-cdiff-row:last-of-type{border-bottom:none}
|
|
16519
|
+
.mp-cdiff-h{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
|
|
16520
|
+
.mp-cdiff-h b{font-size:12.5px;color:var(--ink);font-weight:700}
|
|
16521
|
+
.mp-cdiff-count{margin-left:auto;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
|
|
16522
|
+
.mp-cdiff-count.on{color:var(--red)}
|
|
16523
|
+
.mp-cdiff-ab{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:5px;font-size:11.5px;color:var(--muted)}
|
|
16524
|
+
.mp-cdiff-pill{border:1px solid var(--line);border-radius:999px;padding:1px 8px;background:var(--band)}
|
|
16525
|
+
.mp-cdiff-pill.now{color:var(--lu);border-color:rgba(var(--lu-rgb),.4);background:color-mix(in srgb,var(--lu) 10%,transparent)}
|
|
16526
|
+
.mp-cdiff-pill.alt{color:var(--red);border-color:rgba(var(--red-rgb),.4);background:color-mix(in srgb,var(--red) 8%,transparent)}
|
|
16527
|
+
.mp-cdiff-arrow{color:var(--dimline)}
|
|
16528
|
+
.mp-cdiff-roots{display:flex;flex-direction:column;gap:3px;margin-top:6px;font-size:12.5px;line-height:1.7}
|
|
16529
|
+
.mp-cdiff-root{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
|
|
16530
|
+
.mp-cdiff-k{color:var(--label);font-size:11px;letter-spacing:.08em;min-width:2.2em}
|
|
16531
|
+
.mp-cdiff-from{color:var(--ink2)}
|
|
16532
|
+
.mp-cdiff-to{color:var(--ink);font-weight:700}
|
|
16533
|
+
.mp-cdiff-cats{display:flex;flex-wrap:wrap;gap:4px 6px;margin-top:6px}
|
|
16534
|
+
.mp-cdiff-cat{font-size:11px;color:var(--muted);border:1px solid var(--line);border-radius:999px;padding:0 7px;background:var(--band)}
|
|
16535
|
+
.mp-cdiff-same{font-size:12px;color:var(--muted);margin-top:4px}
|
|
16536
|
+
.mp-cdiff-note{margin-top:8px;padding-top:7px;border-top:1px dashed var(--line);font-size:11.5px;line-height:1.7;color:var(--muted)}
|
|
16537
|
+
@media (max-width:640px){
|
|
16538
|
+
.mp-cdiff>summary{padding:8px 11px}
|
|
16539
|
+
.mp-cdiff-more{display:none}
|
|
16540
|
+
.mp-cdiff-body{padding:0 11px 10px}
|
|
16541
|
+
.mp-cdiff-h b{font-size:12px}
|
|
16542
|
+
.mp-cdiff-count{margin-left:0}
|
|
16543
|
+
}
|
|
16544
|
+
@media print{
|
|
16545
|
+
.mp-cdiff:not([open])>*{display:block!important}
|
|
16546
|
+
.mp-cdiff>summary{cursor:auto}
|
|
16547
|
+
.mp-cdiff-more{display:none}
|
|
16548
|
+
.mp-cdiff{break-inside:avoid}
|
|
16549
|
+
}
|
|
15800
16550
|
.mp-tables{border-top:1px solid var(--line);padding:12px 16px 4px;background:var(--card)}
|
|
15801
16551
|
.mp-table-wrap{margin-bottom:12px}
|
|
15802
16552
|
.mp-table-h{font-size:12px;font-weight:700;letter-spacing:.1em;color:var(--lu);margin-bottom:5px;font-family:system-ui,sans-serif}
|
|
15803
16553
|
.mp-table-scroll{overflow-x:auto;border:1px solid var(--line);border-radius:8px}
|
|
15804
16554
|
.mp-table{width:100%;border-collapse:collapse;font-size:12px;line-height:1.6;color:var(--ink2);font-family:system-ui,sans-serif}
|
|
15805
16555
|
.mp-table th,.mp-table td{padding:5px 9px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line);white-space:nowrap}
|
|
15806
|
-
.mp-table th{background:var(--band);color:var(--
|
|
16556
|
+
.mp-table th{background:var(--band);color:var(--ink2);font-weight:600;font-size:11px;letter-spacing:.06em}
|
|
15807
16557
|
.mp-table tbody tr:last-child td{border-bottom:none}
|
|
15808
16558
|
.mp-table tbody tr:nth-child(even) td{background:rgba(0,0,0,.02)}
|
|
15809
16559
|
@media print{
|
|
@@ -15814,6 +16564,52 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15814
16564
|
.mp-table-wrap,.mp-it-sec,.mp-it-dim{break-inside:avoid}
|
|
15815
16565
|
.mp-table-wrap{page-break-inside:avoid}
|
|
15816
16566
|
}
|
|
16567
|
+
@media (max-width:640px){
|
|
16568
|
+
.mp-tables{padding:10px 11px 2px}
|
|
16569
|
+
.mp-table-wrap{margin-bottom:14px}
|
|
16570
|
+
.mp-table-scroll{overflow:visible;border:0;border-radius:0}
|
|
16571
|
+
.mp-table{display:block;width:100%}
|
|
16572
|
+
.mp-table thead{display:none}
|
|
16573
|
+
.mp-table tbody{display:block}
|
|
16574
|
+
.mp-table tr{display:block;border:1px solid var(--line);border-radius:8px;background:var(--card);padding:7px 10px;margin:0 0 8px}
|
|
16575
|
+
.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}
|
|
16576
|
+
.mp-table td::before{content:attr(data-label);color:var(--muted);font-size:11px;line-height:1.9}
|
|
16577
|
+
.mp-table td:first-child{display:block;padding-bottom:3px;font-size:13px;font-weight:700;color:var(--ink)}
|
|
16578
|
+
.mp-table td:first-child::before{content:none}
|
|
16579
|
+
.mp-table tbody tr:nth-child(even) td{background:none}
|
|
16580
|
+
.mp-table tbody tr:last-child{margin-bottom:0}
|
|
16581
|
+
.mp-cross-b{grid-template-columns:1fr;gap:6px}
|
|
16582
|
+
.mp-cross-cell b{display:inline;margin-right:6px;letter-spacing:.06em}
|
|
16583
|
+
.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}
|
|
16584
|
+
.mp-toc::-webkit-scrollbar{display:none}
|
|
16585
|
+
.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}
|
|
16586
|
+
.mp-toc a:hover{color:var(--ink)}
|
|
16587
|
+
.mp-it-ev>summary{display:flex;align-items:center;min-height:44px;padding:0 9px}
|
|
16588
|
+
.mp-it-gloss summary{display:flex;align-items:center;min-height:44px;margin-bottom:2px}
|
|
16589
|
+
}
|
|
16590
|
+
@container (max-width:640px){
|
|
16591
|
+
.mp-tables{padding:10px 11px 2px}
|
|
16592
|
+
.mp-table-wrap{margin-bottom:14px}
|
|
16593
|
+
.mp-table-scroll{overflow:visible;border:0;border-radius:0}
|
|
16594
|
+
.mp-table{display:block;width:100%}
|
|
16595
|
+
.mp-table thead{display:none}
|
|
16596
|
+
.mp-table tbody{display:block}
|
|
16597
|
+
.mp-table tr{display:block;border:1px solid var(--line);border-radius:8px;background:var(--card);padding:7px 10px;margin:0 0 8px}
|
|
16598
|
+
.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}
|
|
16599
|
+
.mp-table td::before{content:attr(data-label);color:var(--muted);font-size:11px;line-height:1.9}
|
|
16600
|
+
.mp-table td:first-child{display:block;padding-bottom:3px;font-size:13px;font-weight:700;color:var(--ink)}
|
|
16601
|
+
.mp-table td:first-child::before{content:none}
|
|
16602
|
+
.mp-table tbody tr:nth-child(even) td{background:none}
|
|
16603
|
+
.mp-table tbody tr:last-child{margin-bottom:0}
|
|
16604
|
+
.mp-cross-b{grid-template-columns:1fr;gap:6px}
|
|
16605
|
+
.mp-cross-cell b{display:inline;margin-right:6px;letter-spacing:.06em}
|
|
16606
|
+
.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}
|
|
16607
|
+
.mp-toc::-webkit-scrollbar{display:none}
|
|
16608
|
+
.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}
|
|
16609
|
+
.mp-toc a:hover{color:var(--ink)}
|
|
16610
|
+
.mp-it-ev>summary{display:flex;align-items:center;min-height:44px;padding:0 9px}
|
|
16611
|
+
.mp-it-gloss summary{display:flex;align-items:center;min-height:44px;margin-bottom:2px}
|
|
16612
|
+
}
|
|
15817
16613
|
.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)}
|
|
15818
16614
|
.mp-fu.miss{border-left-color:var(--red)}
|
|
15819
16615
|
.mp-fu-h{font-size:12px;font-weight:700;letter-spacing:.08em;color:var(--lu);margin-bottom:4px;font-family:system-ui,sans-serif}
|
|
@@ -16617,6 +17413,13 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
16617
17413
|
return `<span class="pp-chip ${cls}">伏神${esc(l)}</span>`;
|
|
16618
17414
|
}).join('')}</div>`
|
|
16619
17415
|
: '';
|
|
17416
|
+
const yq = r.yingqi && Array.isArray(r.yingqi.labels) ? r.yingqi : null;
|
|
17417
|
+
const yingqiRow = yq && yq.labels.length
|
|
17418
|
+
? `<div class="pp-chips">${yq.labels.map((l) => {
|
|
17419
|
+
const cls = /应期偏速/.test(l) ? 'ok' : /应期待解/.test(l) ? 'warn' : '';
|
|
17420
|
+
return `<span class="pp-chip ${cls}" title="只列地支,不出日期">${esc(l)}</span>`;
|
|
17421
|
+
}).join('')}</div>`
|
|
17422
|
+
: '';
|
|
16620
17423
|
const jp = r.jinTuiPower && Array.isArray(r.jinTuiPower.labels) ? r.jinTuiPower : null;
|
|
16621
17424
|
const jinRow = jp && jp.labels.length
|
|
16622
17425
|
? `<div class="pp-chips">${jp.labels.map((l) => {
|
|
@@ -16639,6 +17442,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
16639
17442
|
${useRow}
|
|
16640
17443
|
${strengthRow}
|
|
16641
17444
|
${fushenRow}
|
|
17445
|
+
${yingqiRow}
|
|
16642
17446
|
${jinRow}
|
|
16643
17447
|
${hexRow}
|
|
16644
17448
|
</div>`;
|
|
@@ -17325,12 +18129,16 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17325
18129
|
const ys = fr.yongshen ? `
|
|
17326
18130
|
<div class="pp-tl">喜 ${fr.yongshen.favor.map(el).join('')} 忌 ${fr.yongshen.avoid.map(el).join('')} <span class="pp-dim">${esc(fr.yongshen.method)}</span></div>
|
|
17327
18131
|
<div class="pp-chips">${fr.yongshen.favorTenGods.map((t) => `<span class="pp-chip ok">${esc(t)}</span>`).join('')}${fr.yongshen.avoidTenGods ? fr.yongshen.avoidTenGods.map((t) => `<span class="pp-chip warn">${esc(t)}</span>`).join('') : ''}</div>
|
|
18132
|
+
${(fr.yongshen.disputed || []).length
|
|
18133
|
+
? `<div class="pp-tl pp-dim">有争议:${fr.yongshen.disputed.map((d) => `${esc(d.element)}(扶抑为${esc(d.favorRole)}·${esc(d.favorVerb)},${esc(d.climate)}盘调候忌${esc(d.element)})`).join('、')} 保留在喜用,不列入忌</div>`
|
|
18134
|
+
: ''}
|
|
17328
18135
|
<div class="pp-tl pp-dim">${esc(fr.yongshen.detail)}</div>` : '';
|
|
17329
18136
|
const cli = r.climate || (fr.yongshen && fr.yongshen.climate) || null;
|
|
17330
18137
|
const cliCard = cli ? (() => {
|
|
17331
18138
|
const pct = Math.max(2, Math.min(98, Math.round(((Number(cli.temp) || 0) + 3) / 6 * 100)));
|
|
17332
18139
|
const need = cli.need ? `<em>调候取</em><b>${esc(cli.need.stem + cli.need.element)}</b>` : '<em>气候平和</em>';
|
|
17333
|
-
const
|
|
18140
|
+
const cliDis = !!(fr.yongshen && Array.isArray(fr.yongshen.disputed)) && fr.yongshen.disputed.some((d) => d.element === cli.avoidElement);
|
|
18141
|
+
const avoid = cli.need ? `<em>忌</em><b>${esc(cli.avoidElement)}</b>${cliDis ? '<span class="pp-dim">(有争议)</span>' : ''}` : '';
|
|
17334
18142
|
const ev = (cli.evidence || []).length ? `<em>依据</em><span>${esc(cli.evidence.join('、'))}</span>` : '';
|
|
17335
18143
|
const pri = cli.priority === '调候优先' ? '<span class="mp-cli-p">调候优先</span>' : '<span class="mp-cli-p">扶抑为主</span>';
|
|
17336
18144
|
const qt = r.frame && r.frame.yongshen && r.frame.yongshen.qt;
|
|
@@ -17361,8 +18169,10 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17361
18169
|
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>`;
|
|
17362
18170
|
}).join('')}</div>` : '';
|
|
17363
18171
|
const sy = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
18172
|
+
const syc = r.suiyunClassic;
|
|
18173
|
+
const sySrc = syc ? `<div class="pp-dim pp-sy-src" title="${esc(syc.plain || '')}">《${esc(syc.bookName || '')}·${esc(syc.chapter || '')}》「${esc(syc.quote || '')}」</div>` : '';
|
|
17364
18174
|
const syRow = sy.length ? `<div class="pp-tl pp-dim">岁运提示(只标干支变动,不判吉凶)</div><div class="pp-chips">${sy.map((l) =>
|
|
17365
|
-
`<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
|
|
18175
|
+
`<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.type.startsWith('大运')) && x.target ? `·${x.target}` : ''}`).join('/'))}</span>`).join('')}</div>${sySrc}` : '';
|
|
17366
18176
|
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>` : '';
|
|
17367
18177
|
const ssGroups = (r.shensha && r.shensha.groups) || [];
|
|
17368
18178
|
const ssx = ssGroups.length ? `
|
|
@@ -17402,6 +18212,19 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17402
18212
|
|
|
17403
18213
|
const MT_LABEL = { natal: '命盘解析', divination: '卦象解析', card: '牌阵解析' };
|
|
17404
18214
|
|
|
18215
|
+
const STANCE_TONE = { 同向: 'good', 有张力: 'watch', 互补: 'alt' };
|
|
18216
|
+
const crossHTML = (items) => `<div class="mp-cross">${items.map((c) => {
|
|
18217
|
+
const tone = STANCE_TONE[c.stance] || 'plain';
|
|
18218
|
+
return `<div class="mp-cross-row">
|
|
18219
|
+
<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>
|
|
18220
|
+
<div class="mp-cross-b">
|
|
18221
|
+
<div class="mp-cross-cell"><b>八字</b><span>${esc(c.bazi || '—')}</span></div>
|
|
18222
|
+
<div class="mp-cross-cell"><b>紫微</b><span>${esc(c.ziwei || '—')}</span></div>
|
|
18223
|
+
</div>
|
|
18224
|
+
${c.note ? `<div class="mp-cross-note">${esc(c.note)}</div>` : ''}
|
|
18225
|
+
</div>`;
|
|
18226
|
+
}).join('')}</div>`;
|
|
18227
|
+
|
|
17405
18228
|
pp.interpretHTML = function (it, opt) {
|
|
17406
18229
|
if (!it) return '';
|
|
17407
18230
|
const hasBody = (it.dimensions && it.dimensions.length) || (it.sections && it.sections.length);
|
|
@@ -17425,8 +18248,8 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17425
18248
|
? `<div class="mp-tables">${it.tables.filter((t) => Array.isArray(t.rows) && t.rows.length).map((t) => `<div class="mp-table-wrap">
|
|
17426
18249
|
<div class="mp-table-h">${esc(t.title)}</div>
|
|
17427
18250
|
<div class="mp-table-scroll"><table class="mp-table">
|
|
17428
|
-
<thead><tr>${t.columns.map((c) => `<th>${esc(c)}</th>`).join('')}</tr></thead>
|
|
17429
|
-
<tbody>${t.rows.map((row) => `<tr>${row.map((c) => `<td>${esc(c)}</td>`).join('')}</tr>`).join('')}</tbody>
|
|
18251
|
+
<thead><tr>${t.columns.map((c) => `<th scope="col">${esc(c)}</th>`).join('')}</tr></thead>
|
|
18252
|
+
<tbody>${t.rows.map((row) => `<tr>${row.map((c, ci) => `<td data-label="${esc(t.columns[ci] || '')}">${esc(c)}</td>`).join('')}</tr>`).join('')}</tbody>
|
|
17430
18253
|
</table></div>
|
|
17431
18254
|
</div>`).join('')}</div>`
|
|
17432
18255
|
: '';
|
|
@@ -17437,7 +18260,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17437
18260
|
const secs = (it.sections && it.sections.length)
|
|
17438
18261
|
? `<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)}">
|
|
17439
18262
|
<div class="mp-it-sh">${esc(s.label)}</div>
|
|
17440
|
-
<div class="mp-it-stext">${richText(s.text)}</div>
|
|
18263
|
+
<div class="mp-it-stext">${(Array.isArray(s.items) && s.items.length) ? crossHTML(s.items) : richText(s.text)}</div>
|
|
17441
18264
|
</div>`).join('')}</div>`
|
|
17442
18265
|
: '';
|
|
17443
18266
|
const tags = [it.systemLabel, MT_LABEL[it.moduleType] || it.moduleType].filter(Boolean);
|
|
@@ -17494,6 +18317,43 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17494
18317
|
return (html || '') + pp.interpretHTML(it, opt);
|
|
17495
18318
|
};
|
|
17496
18319
|
|
|
18320
|
+
pp.caliberHTML = function (caliber) {
|
|
18321
|
+
const sws = caliber && Array.isArray(caliber.switches) ? caliber.switches.filter((s) => s && s.key) : [];
|
|
18322
|
+
if (!sws.length) return '';
|
|
18323
|
+
const affected = sws.filter((s) => !s.error && s.total > 0);
|
|
18324
|
+
const lead = affected.length
|
|
18325
|
+
? `${sws.length} 组开关中 ${affected.length} 组影响此盘:${affected.map((s) => s.short || s.title).join('、')}。`
|
|
18326
|
+
: `本盘对 ${sws.length} 组开关都不敏感:换成另一档也不变。`;
|
|
18327
|
+
const rootsHTML = (row) => {
|
|
18328
|
+
if (row.error) return `<div class="mp-cdiff-same">未能对照:${esc(row.error)}</div>`;
|
|
18329
|
+
if (!row.total) return '<div class="mp-cdiff-same">无变化 · 此盘不受这一开关影响</div>';
|
|
18330
|
+
const roots = Array.isArray(row.roots) ? row.roots : [];
|
|
18331
|
+
if (!roots.length) return `<div class="mp-cdiff-same">无单一根因;逐字段差异 ${Number(row.total) || 0} 处</div>`;
|
|
18332
|
+
return `<div class="mp-cdiff-roots">${roots.map((r) => `<div class="mp-cdiff-root">`
|
|
18333
|
+
+ `<span class="mp-cdiff-k">${esc(r.label)}</span><span class="mp-cdiff-from">${esc(r.from)}</span>`
|
|
18334
|
+
+ `<span class="mp-cdiff-arrow" aria-hidden="true">→</span><span class="mp-cdiff-to">${esc(r.to)}</span></div>`).join('')}</div>`;
|
|
18335
|
+
};
|
|
18336
|
+
const catsHTML = (row) => {
|
|
18337
|
+
const cats = Array.isArray(row.categories) ? row.categories : [];
|
|
18338
|
+
if (row.error || !row.total || !cats.length) return '';
|
|
18339
|
+
const shown = cats.slice(0, 6);
|
|
18340
|
+
return `<div class="mp-cdiff-cats">${shown.map((c) => `<span class="mp-cdiff-cat">${esc(c.name)} ${Number(c.count) || 0} 处</span>`).join('')}`
|
|
18341
|
+
+ (cats.length > shown.length ? `<span class="mp-cdiff-cat">另 ${cats.length - shown.length} 类</span>` : '') + '</div>';
|
|
18342
|
+
};
|
|
18343
|
+
const rows = sws.map((row) => `<div class="mp-cdiff-row">`
|
|
18344
|
+
+ `<div class="mp-cdiff-h"><b>${esc(row.title)}</b>`
|
|
18345
|
+
+ `<span class="mp-cdiff-count${row.total > 0 ? ' on' : ''}">${row.error ? '未能对照' : row.total ? `${Number(row.total) || 0} 处` : '无变化'}</span></div>`
|
|
18346
|
+
+ `<div class="mp-cdiff-ab"><span class="mp-cdiff-pill now">当前 · ${esc(row.currentLabel)}</span>`
|
|
18347
|
+
+ `<span class="mp-cdiff-arrow" aria-hidden="true">→</span><span class="mp-cdiff-pill alt">换成 · ${esc(row.altLabel)}</span></div>`
|
|
18348
|
+
+ `${rootsHTML(row)}${catsHTML(row)}</div>`).join('');
|
|
18349
|
+
return `<details class="mp-cdiff" aria-label="口径对照">
|
|
18350
|
+
<summary><span class="mp-cdiff-title">口径对照</span><span class="mp-cdiff-lead">${esc(lead)}</span><span class="mp-cdiff-more">展开逐字差异</span></summary>
|
|
18351
|
+
<div class="mp-cdiff-body">${rows}
|
|
18352
|
+
<div class="mp-cdiff-note">同一组输入、只换一个开关;只列变化字段与根因,不判哪套口径更准,也不改上方盘面。</div>
|
|
18353
|
+
</div>
|
|
18354
|
+
</details>`;
|
|
18355
|
+
};
|
|
18356
|
+
|
|
17497
18357
|
pp.almanacHTML = function (r) {
|
|
17498
18358
|
if (!r || !r.meta) return pp.quickHTML(r);
|
|
17499
18359
|
const g = r.ganzhi || {};
|
|
@@ -17814,7 +18674,7 @@ function HISTORY_LABEL(kind, r) {
|
|
|
17814
18674
|
}
|
|
17815
18675
|
const PP = window.__PP;
|
|
17816
18676
|
const CSS = `
|
|
17817
|
-
.mp-wrap{height:100%;overflow:auto;padding:20px 24px 40px;color:var(--dsw-alias-label-primary);font-size:14px}
|
|
18677
|
+
.mp-wrap{height:100%;width:100%;box-sizing:border-box;overflow:auto;padding:20px 24px 40px;color:var(--dsw-alias-label-primary);font-size:14px}
|
|
17818
18678
|
.mp-wrap>*{max-width:940px;margin-left:auto;margin-right:auto}
|
|
17819
18679
|
.mp-panel{background:linear-gradient(180deg,var(--dsw-alias-bg-layer-2),color-mix(in srgb,var(--dsw-alias-bg-layer-2) 88%,var(--dsw-alias-bg-layer-1)));border:1px solid var(--dsw-alias-border-l1);border-radius:16px;padding:18px 20px 16px;margin-bottom:16px;
|
|
17820
18680
|
box-shadow:0 1px 2px color-mix(in srgb,var(--dsw-alias-label-primary) 5%,transparent),0 16px 34px -30px color-mix(in srgb,var(--dsw-alias-label-primary) 45%,transparent)}
|
|
@@ -17824,10 +18684,53 @@ const CSS = `
|
|
|
17824
18684
|
.mp-checks label{display:inline-flex;align-items:center;gap:6px;cursor:pointer}
|
|
17825
18685
|
.mp-askblock{margin-top:14px;display:flex;flex-direction:column;gap:5px}
|
|
17826
18686
|
.mp-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:14px}
|
|
17827
|
-
.mp-
|
|
17828
|
-
.mp-
|
|
17829
|
-
.mp-
|
|
17830
|
-
.mp-
|
|
18687
|
+
.mp-start{margin-bottom:14px;container-type:inline-size}
|
|
18688
|
+
.mp-start-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
|
|
18689
|
+
.mp-recent{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
18690
|
+
.mp-recent[hidden]{display:none}
|
|
18691
|
+
.mp-recent-lbl{font-size:11.5px;font-weight:700;letter-spacing:.1em;color:var(--dsw-alias-brand-primary)}
|
|
18692
|
+
.mp-recent-list{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
18693
|
+
.mp-rc{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);
|
|
18694
|
+
background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 72%,transparent);color:var(--dsw-alias-label-primary);
|
|
18695
|
+
font-family:inherit;font-size:12.5px;cursor:pointer;transition:border-color .14s,background .14s}
|
|
18696
|
+
.mp-rc:hover{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2)}
|
|
18697
|
+
.mp-rc i{font-style:normal;font-size:11px;color:var(--dsw-alias-label-secondary)}
|
|
18698
|
+
.mp-viewsw{margin-left:auto;display:inline-flex;padding:3px;border:1px solid var(--dsw-alias-border-l1);border-radius:999px;background:var(--dsw-alias-bg-layer-2)}
|
|
18699
|
+
.mp-viewsw button{border:none;background:transparent;color:var(--dsw-alias-label-secondary);font-family:inherit;font-size:12px;padding:4px 11px;border-radius:999px;cursor:pointer;transition:background .14s,color .14s}
|
|
18700
|
+
.mp-viewsw button:hover{color:var(--dsw-alias-label-primary)}
|
|
18701
|
+
.mp-viewsw button.on{background:var(--dsw-alias-brand-primary);color:#fff}
|
|
18702
|
+
.mp-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(228px,1fr));gap:10px}
|
|
18703
|
+
.mp-tgroup{padding:12px 12px 10px;border:1px solid var(--dsw-alias-border-l1);border-radius:14px;
|
|
18704
|
+
background:linear-gradient(180deg,var(--dsw-alias-bg-layer-2),color-mix(in srgb,var(--dsw-alias-bg-layer-2) 88%,var(--dsw-alias-bg-layer-1)));
|
|
18705
|
+
box-shadow:0 1px 2px color-mix(in srgb,var(--dsw-alias-label-primary) 5%,transparent)}
|
|
18706
|
+
.mp-tgroup-head h2{display:flex;align-items:center;gap:7px;margin:0;font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary);letter-spacing:.06em}
|
|
18707
|
+
.mp-tgroup-head h2::before{content:"";flex:none;width:7px;height:7px;border-radius:2px;background:var(--dsw-alias-brand-primary)}
|
|
18708
|
+
.mp-tgroup-head p{margin:3px 0 9px;font-size:11.5px;line-height:1.55;color:var(--dsw-alias-label-secondary)}
|
|
18709
|
+
.mp-ttools{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
|
|
18710
|
+
.mp-tool{display:flex;flex-direction:column;gap:1px;padding:7px 9px;text-align:left;border:1px solid var(--dsw-alias-border-l1);border-radius:9px;
|
|
18711
|
+
background:color-mix(in srgb,var(--dsw-alias-bg-layer-1) 72%,transparent);color:var(--dsw-alias-label-primary);font-family:inherit;cursor:pointer;
|
|
18712
|
+
transition:border-color .14s,background .14s,box-shadow .14s}
|
|
18713
|
+
.mp-tool b{font-size:13px;font-weight:600;letter-spacing:.02em}
|
|
18714
|
+
.mp-tool span{font-size:11px;line-height:1.4;color:var(--dsw-alias-label-secondary)}
|
|
18715
|
+
.mp-tool:hover{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}
|
|
18716
|
+
.mp-tool.on{border-color:transparent;background:var(--dsw-alias-brand-primary);box-shadow:0 8px 18px -12px var(--dsw-alias-brand-primary)}
|
|
18717
|
+
.mp-tool.on b,.mp-tool.on span{color:#fff}
|
|
18718
|
+
.mp-tool.wide{grid-column:1/-1}
|
|
18719
|
+
.mp-tmore{display:none;grid-column:1/-1;align-items:center;justify-content:center;gap:6px;padding:7px;border:1px dashed var(--dsw-alias-border-l1);border-radius:9px;
|
|
18720
|
+
background:transparent;color:var(--dsw-alias-label-secondary);font-family:inherit;font-size:12px;cursor:pointer}
|
|
18721
|
+
.mp-tmore:hover{color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}
|
|
18722
|
+
@container (max-width:560px){
|
|
18723
|
+
.mp-start-top{flex-direction:column;align-items:stretch;gap:8px}
|
|
18724
|
+
.mp-viewsw{margin-left:0;align-self:flex-end}
|
|
18725
|
+
.mp-tgroup:not(.open) .mp-ttools>.mp-tool:nth-child(n+5){display:none}
|
|
18726
|
+
.mp-tmore{display:flex}
|
|
18727
|
+
}
|
|
18728
|
+
.mp-tabs{display:grid;grid-template-columns:repeat(auto-fit,minmax(74px,1fr));gap:6px;margin-bottom:14px;width:100%;max-width:940px}
|
|
18729
|
+
.mp-tabs.hide{display:none}
|
|
18730
|
+
.mp-tab{padding:7px 10px;border-radius:999px;border:1px solid transparent;background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 62%,transparent);color:var(--dsw-alias-label-secondary);cursor:pointer;font-size:13px;white-space:nowrap;
|
|
18731
|
+
transition:background .16s,color .16s,border-color .16s,box-shadow .16s}
|
|
18732
|
+
.mp-tab:hover{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary)}
|
|
18733
|
+
.mp-tab.on{background:var(--dsw-alias-brand-primary);border-color:transparent;color:#fff;font-weight:600;box-shadow:0 8px 18px -12px var(--dsw-alias-brand-primary)}
|
|
17831
18734
|
.mp-field{display:flex;flex-direction:column;gap:5px;font-size:13px;color:var(--dsw-alias-label-secondary);min-width:0}
|
|
17832
18735
|
.mp-input{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);border-radius:9px;padding:7px 11px;font-size:14px;outline:none;width:100%;min-width:0;height:36px;
|
|
17833
18736
|
transition:border-color .14s,box-shadow .14s,background .14s}
|
|
@@ -17929,8 +18832,10 @@ const CSS = `
|
|
|
17929
18832
|
}
|
|
17930
18833
|
@media (max-width:720px){
|
|
17931
18834
|
.mp-wrap{padding:14px 14px 36px}
|
|
17932
|
-
.mp-tabs{display:
|
|
17933
|
-
.mp-
|
|
18835
|
+
.mp-tabs{display:flex;flex-wrap:nowrap;gap:8px;overflow-x:auto;overscroll-behavior-x:contain;margin:0 -14px 12px;padding:2px 14px 6px;scrollbar-width:none}
|
|
18836
|
+
.mp-tabs::-webkit-scrollbar{display:none}
|
|
18837
|
+
.mp-tab{flex:0 0 auto;min-height:44px;padding:10px 16px;font-size:13.5px;text-align:center}
|
|
18838
|
+
.mp-rc{min-height:36px}
|
|
17934
18839
|
.mp-input,.mp-textarea{padding:10px 12px;font-size:16px;min-height:44px;height:auto}
|
|
17935
18840
|
.mp-textarea{min-height:76px}
|
|
17936
18841
|
.mp-quiz-q{padding:9px 10px}
|
|
@@ -17949,7 +18854,8 @@ const CSS = `
|
|
|
17949
18854
|
}
|
|
17950
18855
|
@media (max-width:420px){
|
|
17951
18856
|
.mp-wrap{padding:12px 10px 32px}
|
|
17952
|
-
.mp-
|
|
18857
|
+
.mp-tabs{margin-left:-10px;margin-right:-10px;padding-left:10px;padding-right:10px}
|
|
18858
|
+
.mp-tab{font-size:13px;padding:9px 13px}
|
|
17953
18859
|
}
|
|
17954
18860
|
:where(.mp-btn,.mp-tab,.mp-chip,.mp-hist-item,.mp-hist-clear,.mp-qmopt,.seg button):focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
17955
18861
|
@media (prefers-reduced-motion:reduce){
|
|
@@ -18066,6 +18972,28 @@ function pad(n) { return String(n).padStart(2, '0'); }
|
|
|
18066
18972
|
|
|
18067
18973
|
const QUICK_TABS = ['almanac', 'convert', 'zeri', 'chenggu', 'xiaoliuren', 'star', 'numerology', 'trend', 'fengshui', 'name'];
|
|
18068
18974
|
|
|
18975
|
+
const GROUPS = Array.isArray(window.__MPGroups) ? window.__MPGroups : [];
|
|
18976
|
+
|
|
18977
|
+
const RECENT_KEY = 'mp.recent.tabs';
|
|
18978
|
+
const VIEW_KEY = 'mp.first.view';
|
|
18979
|
+
const RECENT_MAX = 3;
|
|
18980
|
+
|
|
18981
|
+
function storeGet(key) {
|
|
18982
|
+
try { return JSON.parse(window.localStorage.getItem(key) || 'null'); } catch (e) { return null; }
|
|
18983
|
+
}
|
|
18984
|
+
function storeSet(key, val) {
|
|
18985
|
+
try { window.localStorage.setItem(key, JSON.stringify(val)); } catch (e) { /* 存不了不影响使用 */ }
|
|
18986
|
+
}
|
|
18987
|
+
function dayLabel(ts) {
|
|
18988
|
+
const d = new Date(ts);
|
|
18989
|
+
if (Number.isNaN(d.getTime())) return '';
|
|
18990
|
+
const day = (x) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();
|
|
18991
|
+
const diff = Math.round((day(new Date()) - day(d)) / 86400000);
|
|
18992
|
+
if (diff <= 0) return '今天';
|
|
18993
|
+
if (diff === 1) return '昨天';
|
|
18994
|
+
return `${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
18995
|
+
}
|
|
18996
|
+
|
|
18069
18997
|
function nowParts() {
|
|
18070
18998
|
const d = new Date();
|
|
18071
18999
|
return { date: `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`, time: `${pad(d.getHours())}:${pad(d.getMinutes())}` };
|
|
@@ -18214,6 +19142,12 @@ function App() {
|
|
|
18214
19142
|
if (result && result.r) { LAST.r = result.r; LAST.q = askText.trim(); LAST.it = result.it || null; }
|
|
18215
19143
|
}, [result, askText]);
|
|
18216
19144
|
const [hist, setHist] = useState(() => loadHistory());
|
|
19145
|
+
const [view, setView] = useState(() => (storeGet(VIEW_KEY) === 'flat' ? 'flat' : 'group'));
|
|
19146
|
+
const [recent, setRecent] = useState(() => {
|
|
19147
|
+
const v = storeGet(RECENT_KEY);
|
|
19148
|
+
return Array.isArray(v) ? v : [];
|
|
19149
|
+
});
|
|
19150
|
+
const [openGroups, setOpenGroups] = useState({});
|
|
18217
19151
|
const [replayArgs, setReplayArgs] = useState(null);
|
|
18218
19152
|
const [error, setError] = useState('');
|
|
18219
19153
|
const [notice, setNotice] = useState('');
|
|
@@ -18387,15 +19321,19 @@ function App() {
|
|
|
18387
19321
|
});
|
|
18388
19322
|
} catch (e) { trend = null; }
|
|
18389
19323
|
}
|
|
19324
|
+
let caliber = null;
|
|
19325
|
+
if (Engine.caliberCompare) {
|
|
19326
|
+
try { caliber = Engine.caliberCompare(args); } catch (e) { caliber = null; }
|
|
19327
|
+
}
|
|
18390
19328
|
const ask = (needAsk(k) || k === 'qimen')
|
|
18391
19329
|
? { question: needAsk(k) ? question.trim() : '', direction }
|
|
18392
19330
|
: undefined;
|
|
18393
19331
|
const it = Engine.interpret ? Engine.interpret(r, ask) : null;
|
|
18394
|
-
if (it && r.cross && Engine.
|
|
18395
|
-
it.sections = [...(it.sections || []),
|
|
19332
|
+
if (it && r.cross && Engine.crossSection) {
|
|
19333
|
+
it.sections = [...(it.sections || []), Engine.crossSection(r.cross)];
|
|
18396
19334
|
}
|
|
18397
19335
|
const timed = kindOf(k) === 'cast' && (k !== 'meihua' || mh === 'time');
|
|
18398
|
-
setResult({ kind: k, r, it, at: dt, timed, trend });
|
|
19336
|
+
setResult({ kind: k, r, it, at: dt, timed, trend, caliber });
|
|
18399
19337
|
setFx(null); setFit(null); setPastMarks({}); setRectRes(null);
|
|
18400
19338
|
setError(''); setCopied('');
|
|
18401
19339
|
if (k !== 'tarot' && k !== 'mbti') {
|
|
@@ -18437,6 +19375,25 @@ function App() {
|
|
|
18437
19375
|
run(next, v);
|
|
18438
19376
|
};
|
|
18439
19377
|
|
|
19378
|
+
const recordRecent = (k) => {
|
|
19379
|
+
if (!TABS.some((t) => t.k === k)) return;
|
|
19380
|
+
setRecent((prev) => {
|
|
19381
|
+
const list = (prev || []).filter((x) => x && x.tab && x.tab !== k);
|
|
19382
|
+
const next = [{ tab: k, at: Date.now() }].concat(list).slice(0, RECENT_MAX);
|
|
19383
|
+
storeSet(RECENT_KEY, next);
|
|
19384
|
+
return next;
|
|
19385
|
+
});
|
|
19386
|
+
};
|
|
19387
|
+
const changeView = (v) => {
|
|
19388
|
+
const next = v === 'flat' ? 'flat' : 'group';
|
|
19389
|
+
setView(next);
|
|
19390
|
+
storeSet(VIEW_KEY, next);
|
|
19391
|
+
};
|
|
19392
|
+
const activate = (k) => {
|
|
19393
|
+
recordRecent(k);
|
|
19394
|
+
switchTo(k);
|
|
19395
|
+
};
|
|
19396
|
+
|
|
18440
19397
|
const editDate = (value) => {
|
|
18441
19398
|
setDate(value);
|
|
18442
19399
|
if (timeKind !== 'none') setManual((m) => Object.assign({}, m, { [timeKind]: { date: value, time } }));
|
|
@@ -18641,15 +19598,55 @@ function App() {
|
|
|
18641
19598
|
run(k);
|
|
18642
19599
|
}, [replayArgs]);
|
|
18643
19600
|
|
|
19601
|
+
const recentList = (recent || []).filter((x) => x && TABS.some((t) => t.k === x.tab)).slice(0, RECENT_MAX);
|
|
19602
|
+
const tabLabel = (k) => (TABS.find((t) => t.k === k) || {}).label || k;
|
|
19603
|
+
const toolOf = ({ k, label, tip, wide }) => h('button', {
|
|
19604
|
+
key: k, type: 'button', className: 'mp-tool' + (wide ? ' wide' : '') + (tab === k ? ' on' : ''), 'data-tab': k,
|
|
19605
|
+
onClick: () => activate(k),
|
|
19606
|
+
}, h('b', null, label), h('span', null, tip));
|
|
19607
|
+
|
|
18644
19608
|
const children = [
|
|
18645
|
-
h('
|
|
19609
|
+
h('section', { key: 'start', className: 'mp-start', 'aria-label': '选择要算的事' },
|
|
19610
|
+
h('div', { className: 'mp-start-top' },
|
|
19611
|
+
h('div', { className: 'mp-recent', hidden: recentList.length === 0 },
|
|
19612
|
+
h('span', { className: 'mp-recent-lbl' }, '最近用过'),
|
|
19613
|
+
h('span', { className: 'mp-recent-list' }, recentList.map((x) => h('button', {
|
|
19614
|
+
key: x.tab, type: 'button', className: 'mp-rc', onClick: () => activate(x.tab),
|
|
19615
|
+
}, tabLabel(x.tab), h('i', null, dayLabel(x.at)))))),
|
|
19616
|
+
h('div', { className: 'mp-viewsw', role: 'group', 'aria-label': '首屏视图' },
|
|
19617
|
+
h('button', {
|
|
19618
|
+
type: 'button', className: view === 'group' ? 'on' : '',
|
|
19619
|
+
'aria-pressed': view === 'group' ? 'true' : 'false',
|
|
19620
|
+
onClick: () => changeView('group'),
|
|
19621
|
+
}, '分组'),
|
|
19622
|
+
h('button', {
|
|
19623
|
+
type: 'button', className: view === 'flat' ? 'on' : '',
|
|
19624
|
+
'aria-pressed': view === 'flat' ? 'true' : 'false',
|
|
19625
|
+
onClick: () => changeView('flat'),
|
|
19626
|
+
}, '平铺'))),
|
|
19627
|
+
view === 'group' ? h('div', { className: 'mp-groups' },
|
|
19628
|
+
GROUPS.map((g) => {
|
|
19629
|
+
const open = !!openGroups[g.title];
|
|
19630
|
+
const extra = Math.max(0, g.items.length - 4);
|
|
19631
|
+
return h('section', { key: g.title, className: 'mp-tgroup' + (open ? ' open' : '') },
|
|
19632
|
+
h('div', { className: 'mp-tgroup-head' }, h('h2', null, g.title), h('p', null, g.hint)),
|
|
19633
|
+
h('div', { className: 'mp-ttools' },
|
|
19634
|
+
g.items.map(toolOf),
|
|
19635
|
+
extra > 0 ? h('button', {
|
|
19636
|
+
key: 'more', type: 'button', className: 'mp-tmore',
|
|
19637
|
+
'aria-expanded': open ? 'true' : 'false',
|
|
19638
|
+
onClick: () => setOpenGroups((o) => Object.assign({}, o, { [g.title]: !open })),
|
|
19639
|
+
}, open ? '收起' : `还有 ${extra} 个`) : null));
|
|
19640
|
+
})) : null),
|
|
19641
|
+
|
|
19642
|
+
h('div', { key: 'tabs', className: 'mp-tabs' + (view === 'flat' ? '' : ' hide'), role: 'tablist', 'aria-label': '命理体系' }, TABS.map((t) =>
|
|
18646
19643
|
h('button', {
|
|
18647
19644
|
key: t.k,
|
|
18648
19645
|
role: 'tab',
|
|
18649
19646
|
'aria-selected': tab === t.k ? 'true' : 'false',
|
|
18650
19647
|
tabIndex: tab === t.k ? 0 : -1,
|
|
18651
19648
|
className: 'mp-tab' + (tab === t.k ? ' on' : ''),
|
|
18652
|
-
onClick: () =>
|
|
19649
|
+
onClick: () => activate(t.k),
|
|
18653
19650
|
}, t.label))),
|
|
18654
19651
|
|
|
18655
19652
|
h('div', { key: 'head', className: 'mp-panel' },
|
|
@@ -18920,7 +19917,7 @@ function App() {
|
|
|
18920
19917
|
: PP.quickHTML(result.r),
|
|
18921
19918
|
result.it,
|
|
18922
19919
|
{ folded: defaultFolded() },
|
|
18923
|
-
),
|
|
19920
|
+
) + PP.caliberHTML(result.caliber),
|
|
18924
19921
|
},
|
|
18925
19922
|
}) : null,
|
|
18926
19923
|
|