dsh-metaphysics 0.50.1 → 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 +57 -9
- package/README.md +11 -9
- package/client.js +516 -36
- package/docs/assets/dsh-metaphysics-group.jpg +0 -0
- package/engine/bazi.js +11 -1
- package/engine/classics.js +13 -0
- package/engine/diff.js +301 -197
- package/engine/geju.js +29 -9
- package/engine/index.js +90 -6
- package/engine/interpret-knowledge.js +5 -5
- package/engine/interpret-plain.js +4 -1
- package/engine/interpret.js +8 -5
- package/index.js +12 -2
- package/package.json +2 -2
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +572 -35
- 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.50.
|
|
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
|
|
|
@@ -2919,6 +3190,16 @@ const CLASSICS = [
|
|
|
2919
3190
|
plain: '大运以生月为起点,最怕与流年(太岁)冲克:原文说岁运冲月为祸,又把「岁运与日柱相对」叫返吟、「岁运压日」叫伏吟。这两句是按「对日柱」说的,与本插件「干支相同为伏吟、天克地冲为反吟」不是同一套定义(本插件取后者);末句「不利六亲、破财」是旧说的重话,只作变动提示,不作断语。',
|
|
2920
3191
|
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7539.html',
|
|
2921
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
|
+
},
|
|
2922
3203
|
];
|
|
2923
3204
|
|
|
2924
3205
|
const BY_ID = CLASSICS.reduce((m, e) => { m[e.id] = e; return m; }, {});
|
|
@@ -3285,11 +3566,15 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3285
3566
|
const me = roles.me;
|
|
3286
3567
|
const weak = strength.level === '身弱' || strength.level === '偏弱';
|
|
3287
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 = { 比劫: '帮身', 印: '生身', 食伤: '泄秀', 财: '耗', 官杀: '制' };
|
|
3288
3572
|
|
|
3289
3573
|
const baseFavor = weak ? [roles.inMe, me] : strong ? [roles.shi, roles.cai, roles.guan] : [roles.inMe, me, roles.shi];
|
|
3290
3574
|
const baseAvoid = weak ? [roles.shi, roles.cai, roles.guan] : strong ? [me, roles.inMe] : [roles.guan, roles.cai];
|
|
3291
3575
|
let favor = baseFavor.slice();
|
|
3292
3576
|
let avoid = baseAvoid.slice();
|
|
3577
|
+
const disputed = [];
|
|
3293
3578
|
|
|
3294
3579
|
const climate = judgeClimate({ monthBranch, dayStem, wuxing, branches });
|
|
3295
3580
|
const qt = qtOf(dayStem, monthBranch);
|
|
@@ -3298,27 +3583,39 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3298
3583
|
const needEl = climate.need.element;
|
|
3299
3584
|
if (!favor.includes(needEl)) favor.unshift(needEl);
|
|
3300
3585
|
avoid = avoid.filter((e) => e !== needEl);
|
|
3301
|
-
|
|
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
|
+
}
|
|
3302
3598
|
}
|
|
3303
3599
|
|
|
3304
|
-
const roleName = (el) => (el === me ? '比劫' : el === roles.inMe ? '印'
|
|
3305
|
-
: el === roles.shi ? '食伤' : el === roles.cai ? '财' : '官杀');
|
|
3306
3600
|
const expand = {
|
|
3307
3601
|
比劫: ['比肩', '劫财'], 印: ['正印', '偏印'], 食伤: ['食神', '伤官'],
|
|
3308
3602
|
财: ['正财', '偏财'], 官杀: ['正官', '七杀'],
|
|
3309
3603
|
};
|
|
3310
3604
|
const favorTenGods = Array.from(new Set(favor.flatMap((el) => expand[roleName(el)] || [])));
|
|
3311
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)] || [])));
|
|
3312
3607
|
const tongguan = tongguanOf(favor, avoid, wuxing);
|
|
3313
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('、');
|
|
3314
3613
|
const detail = [
|
|
3315
3614
|
`日主${dayStem}${me},${strength.level}(${strength.score} 分):`,
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
: '身中和,先取调候与通关,喜忌随大运流年动态变化。',
|
|
3321
|
-
`调候:${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) ? '(有争议)' : ''}` : ',气候平和'}。`,
|
|
3322
3619
|
qt ? `穷通宝鉴:${qt.month}${dayStem}${me},用神${qt.yong.join('、')}(首取${qt.primary})。` : '',
|
|
3323
3620
|
tongguan
|
|
3324
3621
|
? `通关:忌${tongguan.foe}克用${tongguan.use},五行以${tongguan.bridge}为关;局中${tongguan.level === '可通'
|
|
@@ -3338,10 +3635,12 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3338
3635
|
level: strength.level,
|
|
3339
3636
|
favor,
|
|
3340
3637
|
avoid,
|
|
3638
|
+
disputed,
|
|
3341
3639
|
favorRoles: favor.map(roleName),
|
|
3342
3640
|
avoidRoles: avoid.map(roleName),
|
|
3343
3641
|
favorTenGods,
|
|
3344
3642
|
avoidTenGods,
|
|
3643
|
+
disputedTenGods,
|
|
3345
3644
|
tiaohou: { ...climate, ...arb, element: climate.need ? climate.need.element : null },
|
|
3346
3645
|
climate,
|
|
3347
3646
|
qt,
|
|
@@ -3928,6 +4227,15 @@ function buildBazi(input) {
|
|
|
3928
4227
|
} else if (tianKeDiChong(w.ganzhi, l.ganzhi)) {
|
|
3929
4228
|
signals.push({ type: '运年反吟', target: `第${w.step}步大运`, detail: `大运${w.ganzhi}与流年${l.ganzhi}天克地冲` });
|
|
3930
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
|
+
}
|
|
3931
4239
|
}
|
|
3932
4240
|
for (const key of ['year', 'month', 'day', 'hour']) {
|
|
3933
4241
|
const g = pillars[key].ganzhi;
|
|
@@ -3941,7 +4249,7 @@ function buildBazi(input) {
|
|
|
3941
4249
|
l.suiyun = {
|
|
3942
4250
|
dayun: active.map((w) => ({ step: w.step, ganzhi: w.ganzhi })),
|
|
3943
4251
|
signals,
|
|
3944
|
-
note: '
|
|
4252
|
+
note: '只标干支重复与天克地冲这类变动信号,不判吉凶;大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列;大运与本命四柱的伏吟/反吟整步大运都在,逐年重复列出',
|
|
3945
4253
|
};
|
|
3946
4254
|
}
|
|
3947
4255
|
|
|
@@ -11225,6 +11533,9 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
11225
11533
|
const ys = (r.frame && r.frame.yongshen) || {};
|
|
11226
11534
|
const favor = join(ys.favor);
|
|
11227
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
|
+
: '';
|
|
11228
11539
|
const strength = STRENGTH_PLAIN[st.level] || '力量偏中性';
|
|
11229
11540
|
const tiaohou = ys.tiaohou && ys.tiaohou.note ? `另外,${ys.tiaohou.note},所以「暖一点、亮一点」的环境通常更舒服。` : '';
|
|
11230
11541
|
const sy = (r.liunian || []).find((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
@@ -11233,7 +11544,7 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
11233
11544
|
: '';
|
|
11234
11545
|
return `你的命局属于「${s(st.level, '中性')}」:${strength}。` +
|
|
11235
11546
|
`${favor ? `能补${favor}的环境(行业、方位、作息、相处的人)会让你省力;${avoid ? `而${avoid}偏重的场合容易空耗,能绕就绕。` : ''}` : ''}` +
|
|
11236
|
-
tiaohou + syPlain;
|
|
11547
|
+
dis + tiaohou + syPlain;
|
|
11237
11548
|
}
|
|
11238
11549
|
if (r.system === 'ziwei') {
|
|
11239
11550
|
const body = r.body || {};
|
|
@@ -11368,10 +11679,10 @@ const KNOWLEDGE = [
|
|
|
11368
11679
|
id: 'bazi-yueling-siquan',
|
|
11369
11680
|
system: 'bazi', dims: ['overall', 'career'],
|
|
11370
11681
|
gist: '月令不是「一个月」,是当月最有权的那一个字。',
|
|
11371
|
-
detail: '月令藏干按本气、中气、余气分日用事,本气当权的时间最长。所以判旺衰先看日主在月令是得令还是失令——得令者未看全局,已有三分底气。本插件按 30
|
|
11372
|
-
source: '
|
|
11682
|
+
detail: '月令藏干按本气、中气、余气分日用事,本气当权的时间最长。所以判旺衰先看日主在月令是得令还是失令——得令者未看全局,已有三分底气。本插件按 30 日表算出「生在本月第几日、哪一干当权」,给的是月内轮值这一层细节;旺衰与取格仍以月令本气、透干与会支为主,不随轮值改判。三命通会卷二·论人元司事另列一套日数(寅月五日/五日/二十日),与本插件取的通行表不同;原文并列,不改判。',
|
|
11683
|
+
source: '《子平真诠》论用神;人元司权分日之说见《渊海子平》;三命通会卷二·论人元司事(典藏网 7529)另列一套日数',
|
|
11373
11684
|
status: 'variant',
|
|
11374
|
-
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18 等多说);本插件固定通行 30 日表(如寅月戊7丙7甲16),节当日为第 1 日,第 31
|
|
11685
|
+
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18 等多说);本插件固定通行 30 日表(如寅月戊7丙7甲16),节当日为第 1 日,第 31 日以后按本气算、不硬分摊。三命通会此本寅月作 5/5/20、卯月作 7/23,与通行表不同,两表各照原样。司权表与本柱藏干表口径不同(子月壬、卯月甲、午月丙、酉月庚、亥月戊只出现在司权表里),两表各照原样;取格不随轮值改判。',
|
|
11375
11686
|
},
|
|
11376
11687
|
{
|
|
11377
11688
|
id: 'bazi-tonggen-tougan',
|
|
@@ -11419,10 +11730,10 @@ const KNOWLEDGE = [
|
|
|
11419
11730
|
id: 'bazi-suiyun',
|
|
11420
11731
|
system: 'bazi', dims: ['overall', 'career'],
|
|
11421
11732
|
gist: '大运管十年基调,流年管当年触发。',
|
|
11422
|
-
detail: '
|
|
11733
|
+
detail: '大运像换了条路,流年像这条路上某一段的天气。岁运并临(当值大运与流年干支相同)、运年反吟(大运与流年天克地冲)、大运伏吟(大运与原局某柱干支相同)、大运反吟(大运与原局某柱天克地冲)、流年伏吟(流年与原局某柱干支相同)、流年反吟(流年与原局某柱天克地冲),是传统上标记「变动较大」的年份,属于提示而非断语。本插件逐年标出六类信号:当值大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列;大运与本命四柱的伏吟/反吟整步大运都在,会连续多年重复列出;只标干支重复与对冲,不折分数。原文里「返吟」指岁运与日柱相对、「伏吟」指岁运压日,与本插件「干支相同为伏吟、天克地冲为反吟」不是同一套定义,两者并列、不合并。',
|
|
11423
11734
|
source: '《三命通会》卷二·总论岁运(https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7539.html);岁运并临之说出自《渊海子平》',
|
|
11424
11735
|
status: 'variant',
|
|
11425
|
-
note: '
|
|
11736
|
+
note: '「岁运并临主大凶」是流传最广也最被滥用的说法,本插件只作变动提示,不断吉凶;大运与本命四柱的伏吟/反吟会连续多年出现,不逐年加重;四柱十神层面的引化也未叠入。',
|
|
11426
11737
|
},
|
|
11427
11738
|
{
|
|
11428
11739
|
id: 'bazi-liuqin',
|
|
@@ -12350,6 +12661,7 @@ function baziInterpret(r) {
|
|
|
12350
12661
|
const level = pick(st, 'level', '中和');
|
|
12351
12662
|
const favor = Array.isArray(ys.favor) ? ys.favor : [];
|
|
12352
12663
|
const avoid = Array.isArray(ys.avoid) ? ys.avoid : [];
|
|
12664
|
+
const disputed = Array.isArray(ys.disputed) ? ys.disputed : [];
|
|
12353
12665
|
const primary = pick(frame, 'primaryName', '未取定');
|
|
12354
12666
|
const gender = pick(r.input, 'gender', '');
|
|
12355
12667
|
const isMale = gender === 'male';
|
|
@@ -12564,11 +12876,13 @@ function baziInterpret(r) {
|
|
|
12564
12876
|
const nextSeg = ry.next ? `,第 ${ry.next.from} 日起交 ${ry.next.stem}${ry.next.element}` : '';
|
|
12565
12877
|
const outside = ry.inHidden ? '' : ` 表里的 ${ry.active} 不在本柱藏干表中(属余气口径),两表各照原样,不互相改写。`;
|
|
12566
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}` : '';
|
|
12567
12881
|
return {
|
|
12568
12882
|
key: 'renyuan', label: '人元司权',
|
|
12569
12883
|
text: `生于${ry.month}月第 ${ry.day} 日(从${ry.term ? ry.term.name : '节'}起算,节当日为第 1 日,日差按本盘所用时刻所在日计):这一日由 **${ry.active}${ry.activeElement}** 司权,第 ${ry.segment.from}–${ry.segment.to} 日属它${nextSeg}。\n`
|
|
12570
12884
|
+ '月令这一个月里,余气、中气、本气轮值,不是整月同一个五行当值——所以「月令是什么」,还要看生在第几日。\n'
|
|
12571
|
-
+
|
|
12885
|
+
+ `**口径**:本插件固定通行 30 日表(${table});另有 7/7/16、9/3/18 等分法,三命通会此本又作 5/5/20(见下原文),各家不一。分日只作解释层的一层细节,**不改取格**:取格仍按本气、透干与会支判定。${outside}${beyond}` + src,
|
|
12572
12886
|
};
|
|
12573
12887
|
})()] : []),
|
|
12574
12888
|
{
|
|
@@ -12600,8 +12914,8 @@ function baziInterpret(r) {
|
|
|
12600
12914
|
const stem = (l.suiyun.dayun || []).map((d) => `第${d.step}步${d.ganzhi}`).join('、');
|
|
12601
12915
|
return `${l.year} ${l.ganzhi}(${stem || '未到起运'}):${l.suiyun.signals.map((s) => s.detail).join(';')}`;
|
|
12602
12916
|
}).join('\n') +
|
|
12603
|
-
'\n
|
|
12604
|
-
: '
|
|
12917
|
+
'\n读法:岁运并临、运年反吟、大运与流年的伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。大运与本命四柱的伏吟/反吟整步大运都在,会连续多年出现,不当成逐年加重。' + src
|
|
12918
|
+
: '近十年没有岁运并临、运年反吟或大运/流年伏吟、反吟。「岁运并临主大凶」这类说法流传很广,本插件只把它当变动提示,没有命中就不作额外解读。',
|
|
12605
12919
|
};
|
|
12606
12920
|
})(),
|
|
12607
12921
|
{
|
|
@@ -12637,7 +12951,7 @@ function baziInterpret(r) {
|
|
|
12637
12951
|
...(cli ? [{
|
|
12638
12952
|
key: 'climate', label: '寒暖燥湿',
|
|
12639
12953
|
text: `${cli.narration}${cli.need
|
|
12640
|
-
? `调候取${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) ? '调候所忌在扶抑里为喜,两说并存' : '与扶抑同向'}`
|
|
12641
12955
|
: '气候平和,调候不作主取'}。`,
|
|
12642
12956
|
}] : []),
|
|
12643
12957
|
...(ys.qt ? [{
|
|
@@ -13788,7 +14102,7 @@ const BUILDERS = {
|
|
|
13788
14102
|
const { interpretQimen } = __mods['qimen-interpret'];
|
|
13789
14103
|
const { buildAnswer, buildPlain, buildGlossary, buildFollowups, dimensionPlain } = __mods['interpret-plain'];
|
|
13790
14104
|
const { knowledgeFor, caveatsFor, STATUS_LABEL } = __mods['interpret-knowledge'];
|
|
13791
|
-
const { CLASSIC_BOOKS, suiyunClassicOf } = __mods.classics;
|
|
14105
|
+
const { CLASSIC_BOOKS, suiyunClassicOf, classicOf } = __mods.classics;
|
|
13792
14106
|
|
|
13793
14107
|
function enrichPlain(result, r, ask) {
|
|
13794
14108
|
if (!result) return result;
|
|
@@ -14494,7 +14808,8 @@ const { buildStar } = __mods.star;
|
|
|
14494
14808
|
const { buildNumerology } = __mods.numerology;
|
|
14495
14809
|
const { buildMbti, mbtiPaper } = __mods.mbti;
|
|
14496
14810
|
const { buildConvert } = __mods.convert;
|
|
14497
|
-
const { classicsFor, classicsText, suiyunClassicOf, CLASSIC_BOOKS } = __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;
|
|
14498
14813
|
const { buildTrend } = __mods.trend;
|
|
14499
14814
|
const { buildFengshui } = __mods.fengshui;
|
|
14500
14815
|
const { buildName } = __mods.name;
|
|
@@ -14585,15 +14900,21 @@ function baziText(r) {
|
|
|
14585
14900
|
`${g.cat}|` + g.items.map((i) => `${i.name}(${i.pillars.map((k) => SHORT[k]).join('')})`).join('、')).join(';')
|
|
14586
14901
|
: '神煞:—';
|
|
14587
14902
|
const ry = r.renyuan;
|
|
14903
|
+
const rySrc = classicOf('smt-renyuan');
|
|
14588
14904
|
const renyuanLine = ry
|
|
14589
|
-
? `人元:${ry.month}月第${ry.day}日,${ry.active}${ry.activeElement}司权(${ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' ')})${ry.beyond ? ';已过 30 日表,按本气算' : ''}`
|
|
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('、')}`
|
|
14590
14910
|
: '';
|
|
14911
|
+
const disEls = new Set(ysd.map((d) => d.element));
|
|
14591
14912
|
const gejuLine = r.frame ? [
|
|
14592
14913
|
`格局:${r.frame.primary ? `${r.frame.primary.name}(${r.frame.primary.evidence})` : '—'}`,
|
|
14593
14914
|
` ${r.frame.geju.map((g) => `${g.name}[${g.kind}]`).join(' ')}`,
|
|
14594
|
-
`用神:喜${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}`,
|
|
14595
14916
|
` ${r.frame.yongshen.detail}`,
|
|
14596
|
-
`寒暖:${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) ? '(有争议)' : ''}` : ''}` : '—'}` +
|
|
14597
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})` : ''),
|
|
14598
14919
|
`十神权重:${Object.entries(r.frame.godStats.groups).map(([k, v]) => `${k}${v}`).join(' ')}`,
|
|
14599
14920
|
] : [];
|
|
@@ -14616,8 +14937,8 @@ function baziText(r) {
|
|
|
14616
14937
|
`流年:${r.liunian.slice(0, 10).map((l) => `${l.year}${l.ganzhi}(${l.stemTenGod})${l.luck ? `·${l.luck.tier}` : ''}`).join(' ')}`,
|
|
14617
14938
|
(() => {
|
|
14618
14939
|
const hits = r.liunian.filter((l) => l.suiyun && l.suiyun.signals && l.suiyun.signals.length);
|
|
14619
|
-
if (!hits.length) return '
|
|
14620
|
-
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})` : ''}`;
|
|
14621
14942
|
const e = suiyunClassicOf(r);
|
|
14622
14943
|
const src = e ? `|古籍见《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》` : '';
|
|
14623
14944
|
return '岁运提示(只标干支变动,不判吉凶):' + hits
|
|
@@ -14882,6 +15203,10 @@ function compute(args = {}) {
|
|
|
14882
15203
|
if (ct) r.summary = `${r.summary}\n【古籍】\n${ct}`;
|
|
14883
15204
|
const syc = suiyunClassicOf(r);
|
|
14884
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
|
+
}
|
|
14885
15210
|
}
|
|
14886
15211
|
if (r && r.precision && r.precision.level === 'approx' && r.summary) {
|
|
14887
15212
|
r.summary = `⚠ ${r.precision.note}\n${r.summary}`;
|
|
@@ -14988,6 +15313,64 @@ function interpretText(i) {
|
|
|
14988
15313
|
return out.join('\n');
|
|
14989
15314
|
}
|
|
14990
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
|
+
|
|
14991
15374
|
const JU_METHODS = ['chaibu', 'chaoshen', 'zhirun'];
|
|
14992
15375
|
const TAROT_COUNTS = [1, 3, 5];
|
|
14993
15376
|
const LATE_ZI_MODES = ['same-day', 'next-day'];
|
|
@@ -15582,6 +15965,15 @@ function renderText(result) {
|
|
|
15582
15965
|
if (extra) parts.push(extra);
|
|
15583
15966
|
}
|
|
15584
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
|
+
}
|
|
15585
15977
|
if (result.followup) {
|
|
15586
15978
|
const f = result.followup;
|
|
15587
15979
|
parts.push(`【追问】${f.question}\n${f.answer}${f.evidence && f.evidence.length ? `\n 依据:${f.evidence.join(';')} 置信度:${f.confidence}` : ''}`);
|
|
@@ -15600,12 +15992,12 @@ function renderText(result) {
|
|
|
15600
15992
|
return parts.filter(Boolean).join('\n\n');
|
|
15601
15993
|
}
|
|
15602
15994
|
|
|
15603
|
-
return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAddress, resolveAddress, buildBazi, buildLiuyao, tossLines, followup, askPrompt, pastSignals, verifyFit, rectifyBirth, crossCheck, crossText, crossSection, buildAlmanac, buildZeri, buildChenggu, buildXiaoliuren, buildStar, buildNumerology, buildConvert, buildTrend, buildFengshui, buildName, parseDateTime, compute, interpretText, renderText };
|
|
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 };
|
|
15604
15996
|
})();
|
|
15605
15997
|
|
|
15606
15998
|
const Engine = __mods.index;
|
|
15607
15999
|
window.Engine = Engine;
|
|
15608
|
-
window.__MP_VER = '0.50.
|
|
16000
|
+
window.__MP_VER = '0.50.5';
|
|
15609
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":"按八字选字"}]}];
|
|
15610
16002
|
(function () {
|
|
15611
16003
|
const NEED_ASK = { liuyao: true, meihua: true, daliuren: true, tarot: true };
|
|
@@ -15637,7 +16029,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15637
16029
|
|
|
15638
16030
|
(function () {
|
|
15639
16031
|
const CSS = `
|
|
15640
|
-
.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;
|
|
15641
16033
|
--line:#c8c1b2;--dimline:#b9b2a4;--hair:#e9e2d3;
|
|
15642
16034
|
--bg:#f6f1e6;--card:#fffdf8;--band:#fbf7ee;--hover:#f3ede1;--hover2:#ece5d6;
|
|
15643
16035
|
--tri:#f3e8cd;--soul:#fae4dc;--sel:#fceee7;--link:#f9ece0;
|
|
@@ -15650,7 +16042,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
15650
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;
|
|
15651
16043
|
border-radius:12px;overflow:hidden;box-shadow:var(--shadow);container-type:inline-size}
|
|
15652
16044
|
@media screen and (prefers-color-scheme:dark){
|
|
15653
|
-
.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;
|
|
15654
16046
|
--line:#514a3e;--dimline:#5f5849;--hair:#2f2b23;
|
|
15655
16047
|
--bg:#12110c;--card:#211f18;--band:#282419;--hover:#2e2a1f;--hover2:#383322;
|
|
15656
16048
|
--tri:#332913;--soul:#3a231c;--sel:#43271f;--link:#33241c;
|
|
@@ -16112,6 +16504,49 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
16112
16504
|
.mp-cross-cell{font-size:12.5px;line-height:1.75;color:var(--ink2)}
|
|
16113
16505
|
.mp-cross-cell b{display:block;font-size:10.5px;letter-spacing:.1em;color:var(--muted);font-weight:600;margin-bottom:1px}
|
|
16114
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
|
+
}
|
|
16115
16550
|
.mp-tables{border-top:1px solid var(--line);padding:12px 16px 4px;background:var(--card)}
|
|
16116
16551
|
.mp-table-wrap{margin-bottom:12px}
|
|
16117
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}
|
|
@@ -17694,12 +18129,16 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17694
18129
|
const ys = fr.yongshen ? `
|
|
17695
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>
|
|
17696
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
|
+
: ''}
|
|
17697
18135
|
<div class="pp-tl pp-dim">${esc(fr.yongshen.detail)}</div>` : '';
|
|
17698
18136
|
const cli = r.climate || (fr.yongshen && fr.yongshen.climate) || null;
|
|
17699
18137
|
const cliCard = cli ? (() => {
|
|
17700
18138
|
const pct = Math.max(2, Math.min(98, Math.round(((Number(cli.temp) || 0) + 3) / 6 * 100)));
|
|
17701
18139
|
const need = cli.need ? `<em>调候取</em><b>${esc(cli.need.stem + cli.need.element)}</b>` : '<em>气候平和</em>';
|
|
17702
|
-
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>' : ''}` : '';
|
|
17703
18142
|
const ev = (cli.evidence || []).length ? `<em>依据</em><span>${esc(cli.evidence.join('、'))}</span>` : '';
|
|
17704
18143
|
const pri = cli.priority === '调候优先' ? '<span class="mp-cli-p">调候优先</span>' : '<span class="mp-cli-p">扶抑为主</span>';
|
|
17705
18144
|
const qt = r.frame && r.frame.yongshen && r.frame.yongshen.qt;
|
|
@@ -17733,7 +18172,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17733
18172
|
const syc = r.suiyunClassic;
|
|
17734
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>` : '';
|
|
17735
18174
|
const syRow = sy.length ? `<div class="pp-tl pp-dim">岁运提示(只标干支变动,不判吉凶)</div><div class="pp-chips">${sy.map((l) =>
|
|
17736
|
-
`<span class="pp-chip" title="${esc(`${l.suiyun.signals.map((x) => x.detail).join(';')}|${l.suiyun.note || ''}`)}">${l.year} ${esc(l.suiyun.signals.map((x) => `${x.type}${x.type.startsWith('流年') && x.target ? `·${x.target}` : ''}`).join('/'))}</span>`).join('')}</div>${sySrc}` : '';
|
|
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}` : '';
|
|
17737
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>` : '';
|
|
17738
18177
|
const ssGroups = (r.shensha && r.shensha.groups) || [];
|
|
17739
18178
|
const ssx = ssGroups.length ? `
|
|
@@ -17878,6 +18317,43 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
17878
18317
|
return (html || '') + pp.interpretHTML(it, opt);
|
|
17879
18318
|
};
|
|
17880
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
|
+
|
|
17881
18357
|
pp.almanacHTML = function (r) {
|
|
17882
18358
|
if (!r || !r.meta) return pp.quickHTML(r);
|
|
17883
18359
|
const g = r.ganzhi || {};
|
|
@@ -18845,6 +19321,10 @@ function App() {
|
|
|
18845
19321
|
});
|
|
18846
19322
|
} catch (e) { trend = null; }
|
|
18847
19323
|
}
|
|
19324
|
+
let caliber = null;
|
|
19325
|
+
if (Engine.caliberCompare) {
|
|
19326
|
+
try { caliber = Engine.caliberCompare(args); } catch (e) { caliber = null; }
|
|
19327
|
+
}
|
|
18848
19328
|
const ask = (needAsk(k) || k === 'qimen')
|
|
18849
19329
|
? { question: needAsk(k) ? question.trim() : '', direction }
|
|
18850
19330
|
: undefined;
|
|
@@ -18853,7 +19333,7 @@ function App() {
|
|
|
18853
19333
|
it.sections = [...(it.sections || []), Engine.crossSection(r.cross)];
|
|
18854
19334
|
}
|
|
18855
19335
|
const timed = kindOf(k) === 'cast' && (k !== 'meihua' || mh === 'time');
|
|
18856
|
-
setResult({ kind: k, r, it, at: dt, timed, trend });
|
|
19336
|
+
setResult({ kind: k, r, it, at: dt, timed, trend, caliber });
|
|
18857
19337
|
setFx(null); setFit(null); setPastMarks({}); setRectRes(null);
|
|
18858
19338
|
setError(''); setCopied('');
|
|
18859
19339
|
if (k !== 'tarot' && k !== 'mbti') {
|
|
@@ -19437,7 +19917,7 @@ function App() {
|
|
|
19437
19917
|
: PP.quickHTML(result.r),
|
|
19438
19918
|
result.it,
|
|
19439
19919
|
{ folded: defaultFolded() },
|
|
19440
|
-
),
|
|
19920
|
+
) + PP.caliberHTML(result.caliber),
|
|
19441
19921
|
},
|
|
19442
19922
|
}) : null,
|
|
19443
19923
|
|