dsh-metaphysics 0.62.4 → 0.63.0
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 +101 -1
- package/client.almanac.js +49 -49
- package/client.chart.js +222 -0
- package/client.chenggu.js +57 -57
- package/client.convert.js +50 -50
- package/client.daliuren.js +124 -107
- package/client.fengshui.js +44 -44
- package/client.js +390 -281
- package/client.liuyao.js +123 -106
- package/client.mbti.js +50 -50
- package/client.name.js +70 -70
- package/client.numerology.js +50 -50
- package/client.qimen.js +115 -98
- package/client.star.js +51 -51
- package/client.tarot.js +115 -98
- package/client.xiaoliuren.js +51 -51
- package/client.zeri.js +49 -49
- package/engine/bazi.js +71 -2
- package/engine/citations-fuwen.js +222 -0
- package/engine/citations.js +129 -5
- package/engine/diff.js +1 -1
- package/engine/geju.js +333 -2
- package/engine/index.js +29 -1
- package/engine/interpret-knowledge.js +10 -10
- package/engine/interpret.js +78 -6
- package/engine/qimen.js +9 -0
- package/engine/structure.js +218 -0
- package/engine/xiaoliuren.js +6 -2
- package/package.json +1 -1
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +1099 -56
- package/client.bazi.js +0 -205
- package/client.hepan.js +0 -204
- package/client.trend.js +0 -196
- package/client.ziwei.js +0 -205
package/engine/geju.js
CHANGED
|
@@ -136,6 +136,15 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
136
136
|
if (!use) use = hui || base;
|
|
137
137
|
const usedBy = exposedKey ? '透干' : (hui ? '会支' : '本气');
|
|
138
138
|
const exposedPos = exposedKey ? { year: '年', month: '月', hour: '时' }[exposedKey] : null;
|
|
139
|
+
// 评分元数据:只给下面 patternScoreOf 用,不参与取格本身
|
|
140
|
+
const metaOf = (c, by, key) => ({
|
|
141
|
+
stem: c.stem,
|
|
142
|
+
god: c.god,
|
|
143
|
+
pos: c.pos,
|
|
144
|
+
usedBy: by,
|
|
145
|
+
exposedKey: key || null,
|
|
146
|
+
exposedPos: key ? { year: '年', month: '月', hour: '时' }[key] : null,
|
|
147
|
+
});
|
|
139
148
|
|
|
140
149
|
// 建禄只认日干的禄位;戊土辰月、己土未月这类「本气比肩但不在禄位」的杂气月不再冒称建禄
|
|
141
150
|
if (base.god === '比肩' && LUSHEN_BRANCH[dayStem] === monthBranch) {
|
|
@@ -143,6 +152,7 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
143
152
|
name: '建禄格',
|
|
144
153
|
kind: '月令格',
|
|
145
154
|
evidence: `月令${monthBranch}为日干${dayStem}之禄(本气${base.stem}比肩),身坐禄地`,
|
|
155
|
+
...metaOf(base, '本气', null),
|
|
146
156
|
};
|
|
147
157
|
}
|
|
148
158
|
if (base.god === '劫财') {
|
|
@@ -151,15 +161,17 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
151
161
|
name: isYangStem(dayStem) ? '阳刃格' : '月刃格',
|
|
152
162
|
kind: '月令格',
|
|
153
163
|
evidence: `月令${monthBranch}为日干${dayStem}之刃(本气${base.stem}劫财)${isYangStem(dayStem) ? '' : ',阴干统称月刃'}`,
|
|
164
|
+
...metaOf(base, '本气', null),
|
|
154
165
|
};
|
|
155
166
|
}
|
|
156
|
-
return { name: '月劫格', kind: '月令格', evidence: `月令${monthBranch}本气${base.stem}
|
|
167
|
+
return { name: '月劫格', kind: '月令格', evidence: `月令${monthBranch}本气${base.stem}为劫财`, ...metaOf(base, '本气', null) };
|
|
157
168
|
}
|
|
158
169
|
if (usedBy === '本气' && base.god === '比肩') {
|
|
159
170
|
return {
|
|
160
171
|
name: '比肩格',
|
|
161
172
|
kind: '月令格',
|
|
162
173
|
evidence: `月令${monthBranch}藏${hidden.join('')},本气${base.stem}为比肩,但${dayStem}禄在${LUSHEN_BRANCH[dayStem]}、不在${monthBranch},属杂气月比肩当权`,
|
|
174
|
+
...metaOf(base, '本气', null),
|
|
163
175
|
};
|
|
164
176
|
}
|
|
165
177
|
// 子平十六:「透乙则用月劫」——杂气月由透干或会支取到劫财时,仍作月劫论
|
|
@@ -169,6 +181,7 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
169
181
|
name: '月劫格',
|
|
170
182
|
kind: '月令格',
|
|
171
183
|
evidence: `月令${monthBranch}藏${hidden.join('')},${use.pos}${use.stem}(劫财)${via},劫财为用,作月劫论`,
|
|
184
|
+
...metaOf(use, usedBy, exposedKey),
|
|
172
185
|
};
|
|
173
186
|
}
|
|
174
187
|
const name = `${use.god}格`;
|
|
@@ -180,7 +193,146 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
180
193
|
} else {
|
|
181
194
|
ex = `月令${monthBranch}藏${hidden.join('')},本气${base.stem}(${base.god})未透干,以月令本气取格`;
|
|
182
195
|
}
|
|
183
|
-
return { name, kind: '月令格', evidence: ex };
|
|
196
|
+
return { name, kind: '月令格', evidence: ex, ...metaOf(use, usedBy, exposedKey) };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ── 成格评分(炳祥高级第 16 课口径)───────────────────────────
|
|
200
|
+
// 只读评分:基础分按取格档位,再减「透干被合 30」「用神太弱 20」,60 分为及格线。
|
|
201
|
+
// 不改 name / evidence / geju 三态,也不参与旺衰与喜忌。
|
|
202
|
+
const ZHUANQI_BRANCHES = ['子', '午', '卯', '酉'];
|
|
203
|
+
const BASE_BY_TIER = {
|
|
204
|
+
专气透: 90,
|
|
205
|
+
本气透: 70,
|
|
206
|
+
中气透: 50,
|
|
207
|
+
余气透: 20,
|
|
208
|
+
同五行透: 5,
|
|
209
|
+
会支取用: 60,
|
|
210
|
+
月令不透: 40,
|
|
211
|
+
};
|
|
212
|
+
const HE_PENALTY = 30;
|
|
213
|
+
const WEAK_PENALTY = 20;
|
|
214
|
+
const PATTERN_PASS = 60;
|
|
215
|
+
const OUTER_PATTERNS = ['建禄格', '阳刃格', '月刃格', '月劫格'];
|
|
216
|
+
|
|
217
|
+
/** 天干五合:找与 stem 相合的另一干(合而不化也算) */
|
|
218
|
+
function stemHeWith(stem, pillars) {
|
|
219
|
+
for (const key of ['year', 'month', 'day', 'hour']) {
|
|
220
|
+
const p = pillars[key];
|
|
221
|
+
if (!p || !p.stem || p.stem === stem) continue;
|
|
222
|
+
if (STEM_HE[stem + p.stem] || STEM_HE[p.stem + stem]) {
|
|
223
|
+
return { pillar: POS_LABEL[key], key, stem: p.stem };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** 用神太弱:无本气通根,且(被天干克 或 全局占比 <18%) */
|
|
230
|
+
function patternWeakWith(pattern, pillars, wuxing = {}) {
|
|
231
|
+
const stem = pattern.stem;
|
|
232
|
+
const el = STEM_ELEMENT[stem];
|
|
233
|
+
const hasBaseRoot = ['year', 'month', 'day', 'hour'].some((key) => {
|
|
234
|
+
const p = pillars[key];
|
|
235
|
+
if (!p) return false;
|
|
236
|
+
return (HIDDEN[p.branch] || [])[0] === stem;
|
|
237
|
+
});
|
|
238
|
+
const total = Object.values(wuxing).reduce((n, v) => n + (Number(v) || 0), 0);
|
|
239
|
+
const pct = total > 0 ? Math.round(((Number(wuxing[el]) || 0) / total) * 1000) / 10 : 0;
|
|
240
|
+
const overcome = ['year', 'month', 'day', 'hour'].some((key) => {
|
|
241
|
+
const p = pillars[key];
|
|
242
|
+
if (!p || !p.stem || p.stem === stem) return false;
|
|
243
|
+
const otherEl = STEM_ELEMENT[p.stem];
|
|
244
|
+
return otherEl && OVERCOMES[otherEl] === el;
|
|
245
|
+
});
|
|
246
|
+
const weak = !hasBaseRoot && (pct < 18 || overcome);
|
|
247
|
+
const reasons = [
|
|
248
|
+
hasBaseRoot ? `有本气通根(${stem})` : '四支无本气通根',
|
|
249
|
+
`全局 ${pct}%`,
|
|
250
|
+
overcome ? '且被天干克' : '',
|
|
251
|
+
].filter(Boolean);
|
|
252
|
+
return {
|
|
253
|
+
weak,
|
|
254
|
+
pct,
|
|
255
|
+
hasBaseRoot,
|
|
256
|
+
overcome,
|
|
257
|
+
detail: reasons.join(','),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* 月令格成格评分。
|
|
263
|
+
* @param {object} pattern monthPattern() 的返回(需 stamp / pos / usedBy)
|
|
264
|
+
* @param {object} pillars 四柱
|
|
265
|
+
* @param {string} dayStem 日干
|
|
266
|
+
* @param {string} monthBranch 月支
|
|
267
|
+
* @param {object} wuxing 五行分值
|
|
268
|
+
*/
|
|
269
|
+
export function patternScoreOf(pattern, pillars, dayStem, monthBranch, wuxing = {}) {
|
|
270
|
+
if (!pattern) return null;
|
|
271
|
+
if (pattern.kind !== '月令格' || OUTER_PATTERNS.includes(pattern.name)) {
|
|
272
|
+
return {
|
|
273
|
+
applicable: false,
|
|
274
|
+
base: null,
|
|
275
|
+
baseLabel: null,
|
|
276
|
+
deductions: [],
|
|
277
|
+
score: null,
|
|
278
|
+
pass: null,
|
|
279
|
+
grade: null,
|
|
280
|
+
threshold: PATTERN_PASS,
|
|
281
|
+
detail: `${pattern.name}属外格(建禄/羊刃/月劫),课程不按正八格的透干档位计成格分,故不套 −30 / −20。`,
|
|
282
|
+
method: '只评正八格月令格;建禄/羊刃/月劫属外格,不评分',
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const zhi = pattern.monthBranch || monthBranch;
|
|
287
|
+
let baseLabel;
|
|
288
|
+
if (pattern.usedBy === '透干') {
|
|
289
|
+
if (ZHUANQI_BRANCHES.includes(zhi) && pattern.pos === '本气') baseLabel = '专气透';
|
|
290
|
+
else baseLabel = `${pattern.pos}透`;
|
|
291
|
+
} else if (pattern.usedBy === '会支') {
|
|
292
|
+
baseLabel = '会支取用';
|
|
293
|
+
} else {
|
|
294
|
+
// 月令本气未透:若同五行异阴阳之干透出,按课里「同五行透」档(<10%)计
|
|
295
|
+
const baseEl = STEM_ELEMENT[pattern.stem];
|
|
296
|
+
const sameEl = ['year', 'month', 'hour']
|
|
297
|
+
.map((k) => pillars[k] && pillars[k].stem)
|
|
298
|
+
.find((s) => s && s !== pattern.stem && STEM_ELEMENT[s] === baseEl);
|
|
299
|
+
baseLabel = sameEl ? '同五行透' : '月令不透';
|
|
300
|
+
}
|
|
301
|
+
const base = BASE_BY_TIER[baseLabel] ?? 40;
|
|
302
|
+
|
|
303
|
+
const deductions = [];
|
|
304
|
+
const he = pattern.usedBy === '透干' ? stemHeWith(pattern.stem, pillars) : null;
|
|
305
|
+
if (he) {
|
|
306
|
+
deductions.push({
|
|
307
|
+
reason: '透干被合',
|
|
308
|
+
points: HE_PENALTY,
|
|
309
|
+
detail: `${pattern.stem}与${he.pillar}干${he.stem}五合(合而不化也按被合论)`,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
const weak = patternWeakWith(pattern, pillars, wuxing);
|
|
313
|
+
if (weak.weak) {
|
|
314
|
+
deductions.push({ reason: '用神太弱', points: WEAK_PENALTY, detail: weak.detail });
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const deducted = deductions.reduce((n, d) => n + d.points, 0);
|
|
318
|
+
const score = Math.max(0, base - deducted);
|
|
319
|
+
const pass = score >= PATTERN_PASS;
|
|
320
|
+
const detail = `基础分 ${base}(${baseLabel})`
|
|
321
|
+
+ `${deductions.length ? `,${deductions.map((d) => `${d.reason} −${d.points}(${d.detail})`).join(',')}` : ',无减项'}`
|
|
322
|
+
+ `,成格分 ${score}/100,${pass ? `过 ${PATTERN_PASS} 分线,按课里作成格论` : `不及 ${PATTERN_PASS} 分线,按课里作不成格论`}。`;
|
|
323
|
+
|
|
324
|
+
return {
|
|
325
|
+
applicable: true,
|
|
326
|
+
base,
|
|
327
|
+
baseLabel,
|
|
328
|
+
deductions,
|
|
329
|
+
score,
|
|
330
|
+
pass,
|
|
331
|
+
grade: pass ? '成格' : '不成格',
|
|
332
|
+
threshold: PATTERN_PASS,
|
|
333
|
+
detail,
|
|
334
|
+
method: '基础分按取格档位(专气透 90 / 本气透 70 / 中气透 50 / 余气透 20 / 同五行透 5 / 会支取用 60 / 月令不透 40);透干被合 −30、用神太弱 −20;60 分及格。只读标注,不改取格与既有三态。',
|
|
335
|
+
};
|
|
184
336
|
}
|
|
185
337
|
|
|
186
338
|
// ── 特殊格 / 组合 ────────────────────────────────────────────
|
|
@@ -344,6 +496,170 @@ export function tongguanOf(favor = [], avoid = [], wuxing = {}) {
|
|
|
344
496
|
return null;
|
|
345
497
|
}
|
|
346
498
|
|
|
499
|
+
// ── 病药(炳祥高级第 6 课口径)───────────────────────────────
|
|
500
|
+
// 只做只读标注:病=最强忌神,药=能克忌神的喜神(其次取泄),不改喜忌结论。
|
|
501
|
+
// 门槛按课里:正格忌神 >35%、从格 >15%;从格能量放大,10% ≈ 正格 30-40%。
|
|
502
|
+
const BING_THRESHOLD = { 正格: 35, 从格: 15 };
|
|
503
|
+
|
|
504
|
+
export function bingyaoOf({ dayStem, strength, wuxing = {}, yongshen = {}, geju = [] }) {
|
|
505
|
+
const roles = elementRoles(dayStem);
|
|
506
|
+
const roleName = (el) => (el === roles.me ? '比劫' : el === roles.inMe ? '印'
|
|
507
|
+
: el === roles.shi ? '食伤' : el === roles.cai ? '财' : '官杀');
|
|
508
|
+
const w = (el) => Math.round((Number(wuxing[el]) || 0) * 10) / 10;
|
|
509
|
+
const total = Object.values(wuxing).reduce((n, v) => n + (Number(v) || 0), 0);
|
|
510
|
+
const pctOf = (el) => (total > 0 ? Math.round((w(el) / total) * 1000) / 10 : 0);
|
|
511
|
+
const desc = (x) => `${x.element}(${x.role}·${x.pct}%)`;
|
|
512
|
+
|
|
513
|
+
const cong = (geju || []).find((g) => g.kind === '从格');
|
|
514
|
+
const threshold = cong ? BING_THRESHOLD.从格 : BING_THRESHOLD.正格;
|
|
515
|
+
|
|
516
|
+
// 从格的喜忌与扶抑相反。现有 yongshenOf 只按旺衰给扶抑喜忌,没有吃 geju,
|
|
517
|
+
// 这里在病药层单列一份反转后的喜忌,避免把从格的喜神当忌神;不改 yongshen 本身。
|
|
518
|
+
let favorEls = yongshen.favor || [];
|
|
519
|
+
let avoidEls = yongshen.avoid || [];
|
|
520
|
+
let source = '扶抑喜忌';
|
|
521
|
+
if (cong) {
|
|
522
|
+
// 按从格类型分:从财/从杀忌印比;从儿忌印与官杀(比劫生食伤不忌);从强忌财官食伤。
|
|
523
|
+
if (cong.name === '从强格') {
|
|
524
|
+
favorEls = [roles.inMe, roles.me];
|
|
525
|
+
avoidEls = [roles.cai, roles.guan, roles.shi];
|
|
526
|
+
} else if (cong.name === '从儿格') {
|
|
527
|
+
favorEls = [roles.shi, roles.cai];
|
|
528
|
+
avoidEls = [roles.inMe, roles.guan];
|
|
529
|
+
} else if (cong.name === '从杀格') {
|
|
530
|
+
favorEls = [roles.guan, roles.cai];
|
|
531
|
+
avoidEls = [roles.me, roles.inMe];
|
|
532
|
+
} else {
|
|
533
|
+
favorEls = [roles.cai, roles.guan, roles.shi];
|
|
534
|
+
avoidEls = [roles.me, roles.inMe];
|
|
535
|
+
}
|
|
536
|
+
source = '从格反转';
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const sick = avoidEls
|
|
540
|
+
.map((el) => ({ element: el, role: roleName(el), pct: pctOf(el) }))
|
|
541
|
+
.sort((a, b) => b.pct - a.pct)[0] || null;
|
|
542
|
+
|
|
543
|
+
const base = {
|
|
544
|
+
threshold,
|
|
545
|
+
isCong: !!cong,
|
|
546
|
+
congName: cong ? cong.name : null,
|
|
547
|
+
favorSource: source,
|
|
548
|
+
sick: sick || null,
|
|
549
|
+
remedy: null,
|
|
550
|
+
level: '无病',
|
|
551
|
+
method: '病=最强忌神;正格 >35%、从格 >15% 才算病;从格先按喜忌反转取忌;药优先取克忌神的喜神,其次取泄;只作标注,不改喜忌',
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
if (!sick || sick.pct <= threshold) {
|
|
555
|
+
return {
|
|
556
|
+
...base,
|
|
557
|
+
detail: sick
|
|
558
|
+
? `忌神最重为${desc(sick)},未过${cong ? '从格' : '正格'} ${threshold}% 门槛,按炳祥口径作无病论。`
|
|
559
|
+
: `本盘无忌神可论,按炳祥口径作无病论。`,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const favor = favorEls
|
|
564
|
+
.map((el) => ({ element: el, role: roleName(el), pct: pctOf(el) }))
|
|
565
|
+
.filter((x) => x.pct > 0)
|
|
566
|
+
.sort((a, b) => b.pct - a.pct);
|
|
567
|
+
const over = (a, b) => OVERCOMES[a] === b; // a 克 b
|
|
568
|
+
|
|
569
|
+
let remedy = null;
|
|
570
|
+
let mode = null;
|
|
571
|
+
let note = '';
|
|
572
|
+
|
|
573
|
+
if (sick.role === '印') {
|
|
574
|
+
// 印为忌:财克印最优,但财力须 ≥ 食伤的 50%;不足则只能用食伤硬抗(安慰剂)。
|
|
575
|
+
const cai = favor.find((f) => f.role === '财');
|
|
576
|
+
const shi = favor.find((f) => f.role === '食伤');
|
|
577
|
+
if (cai && pctOf(roles.cai) >= pctOf(roles.shi) * 0.5) {
|
|
578
|
+
remedy = cai;
|
|
579
|
+
mode = '财克印';
|
|
580
|
+
} else if (shi && pctOf(roles.shi) >= 1) {
|
|
581
|
+
remedy = shi;
|
|
582
|
+
mode = '食伤硬抗(安慰剂)';
|
|
583
|
+
note = `财力${pctOf(roles.cai)}% 不足食伤的 50%(食伤${pctOf(roles.shi)}%),按课里只能以食伤硬抗。`;
|
|
584
|
+
} else {
|
|
585
|
+
note = `财、食伤都不足以制印(财${pctOf(roles.cai)}%、食伤${pctOf(roles.shi)}%),按课里属有病无药。`;
|
|
586
|
+
}
|
|
587
|
+
} else {
|
|
588
|
+
// 克 > 泄:先找克忌神的喜神,再退而取「忌神所生」的喜神(泄其势)。
|
|
589
|
+
const ke = favor.find((f) => over(f.element, sick.element));
|
|
590
|
+
if (ke) {
|
|
591
|
+
remedy = ke;
|
|
592
|
+
mode = '克';
|
|
593
|
+
} else {
|
|
594
|
+
const xie = favor.find((f) => GENERATES[sick.element] === f.element);
|
|
595
|
+
if (xie) {
|
|
596
|
+
remedy = xie;
|
|
597
|
+
mode = '泄';
|
|
598
|
+
note = `喜神中无克${sick.element}者,退取${xie.element}泄其势(课里「克 > 泄」,泄力次之)。`;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const level = remedy ? '有病有药' : '有病无药';
|
|
604
|
+
const detail = [
|
|
605
|
+
`病为${desc(sick)},已过${cong ? `从格(${cong.name})` : '正格'} ${threshold}% 门槛。`,
|
|
606
|
+
remedy
|
|
607
|
+
? `药取${desc(remedy)},以「${mode}」制病${remedy.pct < sick.pct ? `;药力弱于病(${remedy.pct}% < ${sick.pct}%)` : ''}。`
|
|
608
|
+
: `喜神中无可制之药,按炳祥口径属有病无药。`,
|
|
609
|
+
note,
|
|
610
|
+
].filter(Boolean).join('');
|
|
611
|
+
|
|
612
|
+
return { ...base, level, remedy, mode, detail };
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// ── 闲神(炳祥高级第 9 课口径)───────────────────────────────
|
|
616
|
+
// 狭义闲神=食伤与官杀中较弱的那一个;4% 最佳、<10% 合格、>=10% 显忌。
|
|
617
|
+
// 显性(该五行透干)×3 只用于文案排序,不改分值,也不参与旺衰/喜忌。
|
|
618
|
+
export function xianshenOf({ dayStem, wuxing = {}, pillars = {}, yongshen = {} }) {
|
|
619
|
+
const roles = elementRoles(dayStem);
|
|
620
|
+
const w = (el) => Math.round((Number(wuxing[el]) || 0) * 10) / 10;
|
|
621
|
+
const total = Object.values(wuxing).reduce((n, v) => n + (Number(v) || 0), 0);
|
|
622
|
+
const pctOf = (el) => (total > 0 ? Math.round((w(el) / total) * 1000) / 10 : 0);
|
|
623
|
+
|
|
624
|
+
const candidates = [
|
|
625
|
+
{ role: '食伤', element: roles.shi },
|
|
626
|
+
{ role: '官杀', element: roles.guan },
|
|
627
|
+
].map((x) => ({ ...x, pct: pctOf(x.element) }));
|
|
628
|
+
const idle = candidates.sort((a, b) => a.pct - b.pct)[0];
|
|
629
|
+
const band = idle.pct <= 4 ? '最佳' : idle.pct < 10 ? '合格' : '显忌';
|
|
630
|
+
|
|
631
|
+
const stems = ['year', 'month', 'day', 'hour']
|
|
632
|
+
.map((k) => pillars[k] && pillars[k].stem)
|
|
633
|
+
.filter(Boolean);
|
|
634
|
+
const visible = stems.some((s) => STEM_ELEMENT[s] === idle.element);
|
|
635
|
+
const favorRoles = yongshen.favorRoles || [];
|
|
636
|
+
const avoidRoles = yongshen.avoidRoles || [];
|
|
637
|
+
const stance = favorRoles.includes(idle.role) ? '喜' : avoidRoles.includes(idle.role) ? '忌' : '中性';
|
|
638
|
+
|
|
639
|
+
const level = band === '显忌' ? '闲神显忌' : band === '最佳' ? '闲神得位' : '闲神合格';
|
|
640
|
+
const detail = [
|
|
641
|
+
`狭义闲神取${idle.element}(${idle.role},全局 ${idle.pct}%),是食伤与官杀中较弱的一个。`,
|
|
642
|
+
band === '最佳'
|
|
643
|
+
? '4% 上下,正是课里说的最佳区间。'
|
|
644
|
+
: band === '合格'
|
|
645
|
+
? '不足 10%,按课里算合格,不作显忌。'
|
|
646
|
+
: '超过 10%,课里按忌神论:不是大凶,是别扭、乱使劲、干了很多事没结果。',
|
|
647
|
+
visible ? `此神透干(显性),按课里「显性 ×3」在文案里优先提示;分值不改。` : '此神未透干,属暗闲神,影响更轻。',
|
|
648
|
+
`在现有喜忌里为${stance}。`,
|
|
649
|
+
].join('');
|
|
650
|
+
|
|
651
|
+
return {
|
|
652
|
+
idle,
|
|
653
|
+
band,
|
|
654
|
+
level,
|
|
655
|
+
visible,
|
|
656
|
+
stance,
|
|
657
|
+
displayWeight: Math.round(idle.pct * (visible ? 3 : 1) * 10) / 10,
|
|
658
|
+
detail,
|
|
659
|
+
method: '闲神=食伤与官杀中较弱者;4% 最佳 / <10% 合格 / >=10% 显忌;显性 ×3 只作文案排序,不改分值与喜忌',
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
|
|
347
663
|
// ── 用神 / 喜忌 ──────────────────────────────────────────────
|
|
348
664
|
|
|
349
665
|
|
|
@@ -546,16 +862,31 @@ export function scoreLuck(ganzhi, frame) {
|
|
|
546
862
|
export function analyzeBaziFrame({ pillars, dayStem, monthBranch, strength, wuxing }) {
|
|
547
863
|
const gods = godStats(pillars, dayStem);
|
|
548
864
|
const month = monthPattern(pillars, dayStem, monthBranch);
|
|
865
|
+
// 成格评分:只给月令格挂分,外格返回 applicable:false;随后续 specialPatterns 一起回传
|
|
866
|
+
const patternScore = patternScoreOf(month, pillars, dayStem, monthBranch, wuxing);
|
|
867
|
+
if (patternScore && patternScore.applicable) {
|
|
868
|
+
month.score = patternScore.score;
|
|
869
|
+
month.scoreDetail = patternScore;
|
|
870
|
+
}
|
|
549
871
|
const special = specialPatterns(pillars, dayStem, monthBranch, strength, wuxing, gods);
|
|
550
872
|
const geju = [month, ...special];
|
|
551
873
|
const yongshen = yongshenOf(dayStem, monthBranch, strength, wuxing, Object.values(pillars).map((p) => p.branch));
|
|
874
|
+
// 病药:只读标注,复用上面的喜忌,不改结论
|
|
875
|
+
const bingyao = bingyaoOf({ dayStem, strength, wuxing, yongshen, geju });
|
|
876
|
+
// 闲神:只读标注
|
|
877
|
+
const xianshen = xianshenOf({ dayStem, wuxing, pillars, yongshen });
|
|
552
878
|
return {
|
|
553
879
|
geju,
|
|
554
880
|
primary: month,
|
|
555
881
|
primaryName: month.name,
|
|
556
882
|
godStats: gods,
|
|
557
883
|
yongshen,
|
|
884
|
+
bingyao,
|
|
885
|
+
xianshen,
|
|
886
|
+
patternScore,
|
|
558
887
|
dayStem,
|
|
559
888
|
monthBranch,
|
|
889
|
+
// 八大地支结构:静态结构 + 宫位权重,仅作标注,不参与取格与喜忌
|
|
890
|
+
structure: strength.branchStructure || null,
|
|
560
891
|
};
|
|
561
892
|
}
|
package/engine/index.js
CHANGED
|
@@ -110,6 +110,13 @@ function baziText(r) {
|
|
|
110
110
|
const jiao = r.dayun.jiao && r.dayun.jiao.at
|
|
111
111
|
? `;交运 ${r.dayun.jiao.at}(${r.dayun.jiao.frame},距${r.dayun.jiao.from.name} ${r.dayun.jiao.spanDays} 天,三日折一年)`
|
|
112
112
|
: '';
|
|
113
|
+
// 起运岁精确值(截断到年月日时):上面 startAge 是四舍五入到月的口语写法,两者同源、并列给出。
|
|
114
|
+
// 第三方对拍里截断到月 23/23 全中、四舍五入只有 15/23——差别就在这串日时上,所以必须看得见。
|
|
115
|
+
const sae = r.dayun.startAgeExact;
|
|
116
|
+
const startAgeExactLine = sae && Number.isInteger(sae.years)
|
|
117
|
+
? `起运岁(精确):${sae.years} 年 ${sae.months} 个月 ${sae.days} 天 ${sae.hours} 小时`
|
|
118
|
+
+ `(${sae.caliber};上面「${r.dayun.startAge.years}岁${r.dayun.startAge.months}个月」是四舍五入到月,两者同源)`
|
|
119
|
+
: '';
|
|
113
120
|
// 阈值 20 分钟:与 NAOJ 历要项对拍实测,本引擎节气最多偏早 13.5 分钟(Meeus 低精度上限约 14 分钟)
|
|
114
121
|
const near = r.jieqi.nearBoundaryMinutes < 20
|
|
115
122
|
? `\n⚠ 出生时刻距「节」仅 ${r.jieqi.nearBoundaryMinutes} 分钟,而节气时刻本身有最多约 14 分钟的偏差,月柱与年柱建议人工复核。`
|
|
@@ -142,6 +149,22 @@ function baziText(r) {
|
|
|
142
149
|
(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})` : ''),
|
|
143
150
|
`十神权重:${Object.entries(r.frame.godStats.groups).map(([k, v]) => `${k}${v}`).join(' ')}`,
|
|
144
151
|
] : [];
|
|
152
|
+
// 八大地支结构(炳祥课静态口径):算得出但没有输出通道的字段等于没做,这里补一行摘要。
|
|
153
|
+
// 只报「哪几支成党、异类是哪支、静态从格概率」,与上面旺衰分是两套并列口径,不互相覆盖。
|
|
154
|
+
// 三柱模式第四支是正午占位:照实标「占位」,不把它说成实有的时支。
|
|
155
|
+
const bs = r.strength && r.strength.branchStructure;
|
|
156
|
+
const bsCols = bs ? bs.branches.map((b) => `${b.label}${b.branch}${b.camp}${bs.placeholderHour && b.key === 'hour' ? '·占位' : ''}`).join('、') : '';
|
|
157
|
+
// 注意 bs.word 本身已含三柱说明(bazi.js 的 hourUnknown 分支会改写它),这里不重复追加
|
|
158
|
+
const bsTail = bs && !bs.placeholderHour && !bs.complete ? ' 时柱暂缺,只列三支' : '';
|
|
159
|
+
const branchStructureLine = bs
|
|
160
|
+
? `地支结构:${bs.placeholderHour ? '三支+占位' : '四支'} ${bs.code}(${bsCols}) `
|
|
161
|
+
+ `${bs.word}${bs.congProb != null ? `(静态从格 ${bs.congRange})` : ''}${bsTail}`
|
|
162
|
+
: '';
|
|
163
|
+
// 暗合:另列不并入合冲刑害。只出现一对时按课里口径「可忽略」,所以照实写出来但不升级为断语。
|
|
164
|
+
const anhe = (r.relations && Array.isArray(r.relations.anhe)) ? r.relations.anhe : [];
|
|
165
|
+
const anheLine = anhe.length
|
|
166
|
+
? `暗合:${anhe.join(' ')}(另列,不并入上面的合冲刑害;${anhe.length === 1 ? '只一对,按口径可忽略' : `共 ${anhe.length} 对`})`
|
|
167
|
+
: '';
|
|
145
168
|
const hourMissing = r.hourUnknown === true || !P.hour;
|
|
146
169
|
return [
|
|
147
170
|
`【四柱】${P.year.ganzhi} ${P.month.ganzhi} ${P.day.ganzhi}${P.hour ? ` ${P.hour.ganzhi}` : '(时柱暂缺)'}`,
|
|
@@ -151,14 +174,17 @@ function baziText(r) {
|
|
|
151
174
|
`五行:${wuxing}`,
|
|
152
175
|
...(palaces ? [palaces] : []),
|
|
153
176
|
`日主强弱:${r.strength.level}(${r.strength.score}) ${r.strength.detail}`,
|
|
177
|
+
...(branchStructureLine ? [branchStructureLine] : []),
|
|
154
178
|
...gejuLine,
|
|
155
179
|
`天干关系:${(r.relations && r.relations.stems.length) ? r.relations.stems.join(' ') : '—'}`,
|
|
156
180
|
`地支关系:${(r.relations && r.relations.branches.length) ? r.relations.branches.join(' ') : '—'}`,
|
|
181
|
+
...(anheLine ? [anheLine] : []),
|
|
157
182
|
shenshaLine,
|
|
158
183
|
`真太阳时:${r.solarTime.trueSolarText}(${r.input.geo ? r.input.geo.note + ';' : ''}${r.solarTime.note}) 晚子时:${r.input.lateZi ? '23:00 后算次日' : '23:00 后仍算当日'}`,
|
|
159
184
|
`节气:上一节 ${r.jieqi.previous.name} ${r.jieqi.previous.time} 下一节 ${r.jieqi.next.name} ${r.jieqi.next.time}`,
|
|
160
185
|
...(renyuanLine ? [renyuanLine] : []),
|
|
161
186
|
`大运:${r.dayun.rule}(${r.dayun.direction}),${r.dayun.startAge.years}岁${r.dayun.startAge.months}个月起运${jiao}`,
|
|
187
|
+
...(startAgeExactLine ? [startAgeExactLine] : []),
|
|
162
188
|
` ${dayun}`,
|
|
163
189
|
`流年:${r.liunian.slice(0, 10).map((l) => `${l.year}${l.ganzhi}(${l.stemTenGod})${l.luck ? `·${l.luck.tier}` : ''}`).join(' ')}`,
|
|
164
190
|
(() => {
|
|
@@ -1785,8 +1811,10 @@ function chengguText(r) {
|
|
|
1785
1811
|
|
|
1786
1812
|
/** 小六壬文本 */
|
|
1787
1813
|
function xiaoliurenText(r) {
|
|
1814
|
+
// 所问从顶层读(引擎把 question 挂顶层,不进 meta——meta 要能被句柄完整复现)
|
|
1815
|
+
const q = r.question || (r.meta && r.meta.question) || null;
|
|
1788
1816
|
return [
|
|
1789
|
-
`【小六壬·${r.meta.mode}】${
|
|
1817
|
+
`【小六壬·${r.meta.mode}】${q ? `所问:${q}` : ''}`,
|
|
1790
1818
|
r.meta.originText,
|
|
1791
1819
|
`落宫:${r.steps.join(' → ')}`,
|
|
1792
1820
|
`断语:${r.result.palace}(${r.result.luck}) ${r.result.text}`,
|
|
@@ -446,36 +446,36 @@ export const KNOWLEDGE = [
|
|
|
446
446
|
system: 'qimen', dims: ['overall'],
|
|
447
447
|
gist: '冬至后阳遁、夏至后阴遁,局数由节气与三元定。',
|
|
448
448
|
detail: '一年分阴阳两遁,各九局;局数取决于当前节气与上中下三元(符头定元)。取局流派有拆补、超神接气、置闰三种,同一时刻可能排出不同局数——这不是算错,是流派差异。',
|
|
449
|
-
source: '
|
|
449
|
+
source: '《烟波钓叟歌》;拆补与置闰见《奇门遁甲统宗》;符头定三元与二十四节气局数见《奇门遁甲元灵经》卷一;超神接气与阳遁仪顺奇逆见《奇门遁甲秘笈大全》总序',
|
|
450
450
|
status: 'variant',
|
|
451
|
-
note: '
|
|
451
|
+
note: '三种取局法在节气交接前后差异最明显,本插件同时实现三种,可在参数里指定。元灵经卷一「阴阳各局」的二十四节气三元局数与引擎表逐格相符(24/24),三元符头「甲己干加子午卯酉为上元」亦与引擎定局口径同;秘笈总序「符速节迟…用超神之法,节先符后…行节气之方」正是超神与接气两名的由来。',
|
|
452
452
|
},
|
|
453
453
|
{
|
|
454
454
|
id: 'qimen-jixing',
|
|
455
455
|
system: 'qimen', dims: ['overall', 'work'],
|
|
456
456
|
gist: '六仪落刑宫叫击刑,是宫位条件不是判决。',
|
|
457
457
|
detail: '六仪按所配地支相刑:甲子戊落震三(子刑卯)、甲戌己落坤二(戌刑未)、甲申庚落艮八(申刑寅)、甲午辛落离九(午自刑)、甲辰壬落巽四(辰自刑)、甲寅癸落巽四(寅刑巳)。天盘六仪落到自己那一宫即击刑,取象是受制、掣肘、旧账翻出来,多用来量这个符号本身使不使得上力。',
|
|
458
|
-
source: '
|
|
458
|
+
source: '《烟波钓叟歌》刑格注;《奇门遁甲统宗》;六仪配旬首见《奇门遁甲元灵经》卷一,落宫表见《奇门遁甲秘笈大全》卷十五·六仪刑击格',
|
|
459
459
|
status: 'variant',
|
|
460
|
-
note: '
|
|
460
|
+
note: '有流派只论天盘六仪击刑,也有把地盘一并算的;本插件只判天盘,且只作宫位条件,不自动断用神受制。秘笈卷十五「甲子戊直符加三宫,甲戌己值符加二宫,甲申庚加八宫,甲午辛加九宫,甲辰壬加四宫,甲寅癸值符加四宫」与引擎六格逐一相符。',
|
|
461
461
|
},
|
|
462
462
|
{
|
|
463
463
|
id: 'qimen-rumu',
|
|
464
464
|
system: 'qimen', dims: ['overall'],
|
|
465
465
|
gist: '天盘干落墓宫叫入墓:三奇与六仪各按五行墓库判。',
|
|
466
466
|
detail: '按五行墓库推,乙、丁两个阴干从《玄机赋》逆行取墓说:乙墓戌(乾六)、丙墓戌(乾六)、丁墓丑(艮八);六仪中戊墓戌(乾六)、己庚墓丑(艮八)、辛壬墓辰(巽四)、癸墓未(坤二)。天盘干落到自己的墓宫即入墓。取象是收束、藏起来、事情压住不动;好坏要看所问之事——问收藏、问了结,入墓未必是坏事。',
|
|
467
|
-
source: '
|
|
467
|
+
source: '《奇门遁甲统宗》三奇入墓条;阴干逆行取墓见其中「玄机赋」;三奇入墓歌见《奇门遁甲秘笈大全》卷十五(同卷时墓格只戊、壬、丙三句与本盘相符,辛、乙两句相异);五行墓库见《五行大义》',
|
|
468
468
|
status: 'variant',
|
|
469
|
-
note: '各家对入墓范围说法不一:有只论三奇,也有把六仪、八门、九星一并论墓的;本插件判天盘三奇与六仪,八门、九星暂不入墓。墓宫取法同样有异说——通行另有一说按五行墓库直取(乙 木墓未、丁 火墓戌),本盘依《玄机赋》阴干逆行说(乙墓戌、丁墓丑),与引擎 qimen.js 的 RU_MU
|
|
469
|
+
note: '各家对入墓范围说法不一:有只论三奇,也有把六仪、八门、九星一并论墓的;本插件判天盘三奇与六仪,八门、九星暂不入墓。墓宫取法同样有异说——通行另有一说按五行墓库直取(乙 木墓未、丁 火墓戌),本盘依《玄机赋》阴干逆行说(乙墓戌、丁墓丑),与引擎 qimen.js 的 RU_MU 表同源。秘笈卷十五「三奇入墓歌」作乙丙临乾、丁临艮,与本盘三奇同;但同卷「时墓格」作辛丑墓艮、乙未墓坤,与本盘辛墓辰巽、乙墓戌乾不同,「奇墓格」又作乙到临坤——一书之内三说并存,照录并列,不拿它改引擎表。',
|
|
470
470
|
},
|
|
471
471
|
{
|
|
472
472
|
id: 'qimen-ganying',
|
|
473
473
|
system: 'qimen', dims: ['overall', 'work'],
|
|
474
474
|
gist: '十干克应看天盘干加地盘干:同宫两干相遇,先取成象,再与门星神合看。',
|
|
475
475
|
detail: '十干克应把天盘干与地盘干的组合收成 100 组,每组一个格名与一段取象。例如甲加丙「青龙返首」主大吉大利,甲加庚「值符飞宫」主吉事不成,乙加辛「青龙逃走」主失财逃亡。它回答的是「这两股气碰在一起像什么」,不单独回答「事情成不成」;同一组落在不同门、星、神与旺衰下,轻重会变。',
|
|
476
|
-
source: '《奇门十干应克》通行 100
|
|
476
|
+
source: '《奇门十干应克》通行 100 组表;《奇门遁甲元灵经》卷二「天盘加地盘吉凶」存甲、乙、丙三组异文;格名与取象另见《奇门遁甲秘笈大全》总序',
|
|
477
477
|
status: 'variant',
|
|
478
|
-
note: '100
|
|
478
|
+
note: '100 组表各家措辞不一,本插件取通行表;元灵经只存三组(各 9 条,三组都缺「加戊」,页面到丙加癸为止)且文字不同,两本并列、不合并。元灵经甲加甲「吉凶不定,惟看门如何。门吉则吉,门凶则凶」正是本卡「先取成象、再与门星神合看」的原文依据;同格异文如青龙返首(总序作「反首」)、乙加辛青龙逃走三处断语各别(财物废坠/主财失逃亡/奴仆拐带六畜皆伤)。已录原文只证这几组与这一层口径,不证 100 组表全文。十干克应只作取象,不自动折吉凶。',
|
|
479
479
|
},
|
|
480
480
|
{
|
|
481
481
|
id: 'qimen-wangshuai',
|
|
@@ -490,9 +490,9 @@ export const KNOWLEDGE = [
|
|
|
490
490
|
system: 'qimen', dims: ['overall', 'work'],
|
|
491
491
|
gist: '旺衰是助力,不单独定吉凶:门旺而宫克门仍受制。',
|
|
492
492
|
detail: '月令旺衰只回答「这个符号自身有多少气」,不回答「事情成不成」。取象时要和宫位关系叠起来看:门旺但同宫门克宫(门迫),力量被宫位掣肘;门囚但宫生门,仍得宫助。星同理,旺星落宫若被克,也难全其用。',
|
|
493
|
-
source: '
|
|
493
|
+
source: '《奇门遁甲统宗》;《烟波钓叟歌》门宫生克注;「门尅宫为迫,宫尅门为制,门生宫为和,宫生门为义」见《奇门遁甲秘笈大全》卷十五·迫制和义格,八门迫宫见同卷门迫歌;休门到离为迫见《奇门遁甲元灵经》卷二·八门值事',
|
|
494
494
|
status: 'variant',
|
|
495
|
-
note: '
|
|
495
|
+
note: '有流派按时令而非月令论门星旺衰,也有以落宫五行当令者;本插件统一按月支五行判,并在解读里明确只作强度参考。门宫四类关系(迫/制/和/义)与引擎 gatePalaceRelation 一一对应,门迫歌八格全是门克宫、逐格对拍相符;古籍在迫制之后直接下吉凶(「吉门被迫吉不就,凶门被迫祸重重」),本插件只取落宫条件,不自动折吉凶。',
|
|
496
496
|
},
|
|
497
497
|
{
|
|
498
498
|
id: 'qimen-gan-shengke',
|
package/engine/interpret.js
CHANGED
|
@@ -345,7 +345,7 @@ function baziInterpret(r) {
|
|
|
345
345
|
`**用神**:喜${join(favor) || '—'}(${join(ys.favorRoles || []) || '—'}),忌${join(avoid) || '—'}(${join(ys.avoidRoles || []) || '—'})。${neutral.length ? `(${join(neutral.map((n) => n.element))} 近零,按中性偏忌看)` : ''}${frameToneOf(level, favorRolesByWeight)}`,
|
|
346
346
|
`**格局**:${primary}(${pick(frame.primary, 'evidence', '')})${(Array.isArray(frame.geju) ? frame.geju : []).filter((g) => g.name && g.name !== primary).length
|
|
347
347
|
? `,另有${frame.geju.map((g) => g.name).filter((n) => n && n !== primary).join('、')}`
|
|
348
|
-
: ''}。`,
|
|
348
|
+
: ''}${frame.patternScore && frame.patternScore.applicable ? `。成格评分 ${frame.patternScore.score}/100(${frame.patternScore.grade})` : ''}。`,
|
|
349
349
|
].join('\n');
|
|
350
350
|
|
|
351
351
|
const portraitText = [
|
|
@@ -428,7 +428,12 @@ function baziInterpret(r) {
|
|
|
428
428
|
const jiaoLine = r.dayun && r.dayun.jiao && r.dayun.jiao.at
|
|
429
429
|
? `起运交运时刻 ${r.dayun.jiao.at}(${r.dayun.jiao.frame};三日折一年,距${r.dayun.jiao.from.name} ${r.dayun.jiao.spanDays} 天)。每步大运在同月同日同时刻换,逐年日期见下方大运表「交运」列。\n`
|
|
430
430
|
: '';
|
|
431
|
-
|
|
431
|
+
// 精确起运岁:与「几岁几个月」的口语写法并列。对上第三方排盘时差的就是日、时这两位。
|
|
432
|
+
const sae = r.dayun && r.dayun.startAgeExact;
|
|
433
|
+
const exactLine = sae && Number.isInteger(sae.years)
|
|
434
|
+
? `起运岁精确值:${sae.years} 年 ${sae.months} 个月 ${sae.days} 天 ${sae.hours} 小时(${sae.caliber})。与摘要「${r.dayun.startAge.years}岁${r.dayun.startAge.months}个月」同源:后者四舍五入到月,差一个月的边界常出在这里——第三方给到日/时的,按这一行核对。\n`
|
|
435
|
+
: '';
|
|
436
|
+
return `${jiaoLine}${exactLine}当前大运:${pick(cur, 'ganzhi', '—')}(${curSpan})。后续两步:${nextTwo}。\n近五年流年:${years || '—'}。\n读法:大运管"这十年的大环境",流年管"今年的具体天气";两者打架时,以能否动到用神为准。`;
|
|
432
437
|
})(),
|
|
433
438
|
},
|
|
434
439
|
{ key: 'years', label: '流年时间轴', text: yearsText },
|
|
@@ -503,20 +508,87 @@ function baziInterpret(r) {
|
|
|
503
508
|
}] : []),
|
|
504
509
|
{
|
|
505
510
|
key: 'geju', label: '格局依据',
|
|
506
|
-
text: (Array.isArray(frame.geju) ? frame.geju : []).map((g) =>
|
|
507
|
-
`${g.name}(${g.kind}${g.status ? `·${g.status}` : ''}):${g.evidence}${Array.isArray(g.breaks) && g.breaks.length ? `;破:${g.breaks.join(';')}` : ''}`).join(';') || '未取到格局'
|
|
511
|
+
text: ((Array.isArray(frame.geju) ? frame.geju : []).map((g) =>
|
|
512
|
+
`${g.name}(${g.kind}${g.status ? `·${g.status}` : ''}):${g.evidence}${Array.isArray(g.breaks) && g.breaks.length ? `;破:${g.breaks.join(';')}` : ''}`).join(';') || '未取到格局')
|
|
513
|
+
+ (frame.patternScore ? `\n成格评分:${frame.patternScore.detail}` : ''),
|
|
508
514
|
},
|
|
515
|
+
...(frame.bingyao ? [{
|
|
516
|
+
key: 'bingyao', label: '病药',
|
|
517
|
+
text: `【${frame.bingyao.level}】${frame.bingyao.detail}\n口径:${frame.bingyao.method}`,
|
|
518
|
+
}] : []),
|
|
519
|
+
...(frame.xianshen ? [{
|
|
520
|
+
key: 'xianshen', label: '闲神',
|
|
521
|
+
text: `【${frame.xianshen.level}】${frame.xianshen.detail}\n口径:${frame.xianshen.method}`,
|
|
522
|
+
}] : []),
|
|
523
|
+
// 八大地支结构:与旺衰分并列的第二套静态视图。算出来却没人看得见的字段等于没做,
|
|
524
|
+
// 所以这里单独给一节,写清「它是什么、跟上面旺衰分的区别、能不能据此断从格」。
|
|
525
|
+
...(r.strength && r.strength.branchStructure ? [{
|
|
526
|
+
key: 'structure', label: '地支结构',
|
|
527
|
+
text: (() => {
|
|
528
|
+
const b = r.strength.branchStructure;
|
|
529
|
+
const cols = b.branches.map((x) => `${x.label}支${x.branch}(${x.support}·${x.camp} 档 ${x.weight} 分${b.placeholderHour && x.key === 'hour' ? '·占位' : ''})`).join(';');
|
|
530
|
+
const odd = b.odd && b.odd.length ? `异类:${b.odd.map((x) => `${x.label}支${x.branch}(${x.weight} 分)`).join('、')}。` : '四支二对二或同党,无异类。';
|
|
531
|
+
const bal = b.balance || {};
|
|
532
|
+
return `【${b.code}】${b.detail}\n`
|
|
533
|
+
+ `逐支:${cols}\n`
|
|
534
|
+
+ `${odd}${b.halfSupported && b.halfSupported.length ? `半得地:${b.halfSupported.join('、')}(按 0.2–0.5 折算,不计入身强阵营)。` : ''}\n`
|
|
535
|
+
+ `地支 身强 ${bal.branch ? bal.branch.A : '—'} : 身弱 ${bal.branch ? bal.branch.B : '—'},加天干后 ${bal.total ? `${bal.total.A}:${bal.total.B}` : '—'}(宫位权重年 11 / 月 36 / 日 27 / 时 16)。\n`
|
|
536
|
+
+ `${b.word}${b.congProb != null ? `——静态从格概率 ${b.congRange}。` : '。'}\n`
|
|
537
|
+
+ `口径:${b.method}\n`
|
|
538
|
+
+ `与「日主强弱」的关系:这是并列的第二套静态视图,不改上面的旺衰评分,也不参与取格与喜忌——两者是同一组四支的两种读法,不是先后两步。\n`
|
|
539
|
+
+ `边界:${b.note}`;
|
|
540
|
+
})(),
|
|
541
|
+
}] : []),
|
|
542
|
+
// 暗合:另列不并。这一条最容易被人当成「合」读进旺衰,所以把边界写在节里。
|
|
543
|
+
...(r.relations && Array.isArray(r.relations.anhe) && r.relations.anhe.length ? [{
|
|
544
|
+
key: 'anhe', label: '暗合',
|
|
545
|
+
text: `${r.relations.anhe.join('\n')}\n`
|
|
546
|
+
+ `口径:${r.relations.anheNote || '暗合只作取象,不参与旺衰与格局。'}\n`
|
|
547
|
+
+ `边界:暗合与上面的「地支关系」(三合、三会、六合、六冲、刑、害)是两条线,本插件不把它们合并计分;`
|
|
548
|
+
+ `${r.relations.anhe.length === 1 ? '本盘只出现一对,按课里口径可以直接忽略。' : `本盘共 ${r.relations.anhe.length} 对,可作取象参考,但仍不折旺衰。`}`,
|
|
549
|
+
}] : []),
|
|
550
|
+
(() => {
|
|
551
|
+
const ss = r.shensha;
|
|
552
|
+
const cols = { year: '年', month: '月', day: '日', hour: '时' };
|
|
553
|
+
if (!ss || !Array.isArray(ss.groups) || !ss.groups.length) {
|
|
554
|
+
return {
|
|
555
|
+
key: 'shensha', label: '神煞',
|
|
556
|
+
text: '本盘未见常用神煞。按炳祥课里的口径,神煞是枝叶,只作锦上添花,不单独定吉凶;真正的吉凶仍看格局、旺衰与行运。',
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
const names = Array.isArray(ss.names) ? ss.names : [];
|
|
560
|
+
const rows = ss.groups.map((g) => `${g.cat}:${(g.items || []).map((it) => {
|
|
561
|
+
const where = (it.pillars || []).map((k) => cols[k] || k).join('、');
|
|
562
|
+
return `${it.name}${where ? `(${where})` : ''}`;
|
|
563
|
+
}).join('、')}`).join(';');
|
|
564
|
+
const core = ['驿马', '羊刃', '桃花', '华盖'].filter((n) => names.includes(n));
|
|
565
|
+
const hasTianyi = names.includes('天乙贵人');
|
|
566
|
+
return {
|
|
567
|
+
key: 'shensha', label: '神煞',
|
|
568
|
+
text: `命中神煞:${rows}。\n`
|
|
569
|
+
+ '按炳祥课里的口径,真正拿来取象的只有驿马、羊刃、桃花、华盖四颗'
|
|
570
|
+
+ `${core.length ? `,本盘见 ${core.join('、')}` : ',本盘这四颗都未见'}`
|
|
571
|
+
+ ';其余一律只作锦上添花。'
|
|
572
|
+
+ (hasTianyi
|
|
573
|
+
? '天乙贵人尤其是添头:课里给的口径是「无贵人概率 5/6⁴ < 50%,单独断贵人准确率 <30%」,不能拿来定吉凶。'
|
|
574
|
+
: '天乙贵人即使出现也只是添头:课里统计其单独断贵人准确率 <30%,不能拿来定吉凶。')
|
|
575
|
+
+ '\n神煞永远是枝叶:它只提示「像不像」,不决定「成不成」。吉凶仍以格局、旺衰、喜忌与行运为主,神煞不参与本盘的旺衰与格局判定。',
|
|
576
|
+
};
|
|
577
|
+
})(),
|
|
509
578
|
...(Array.isArray(r.classics) && r.classics.length ? [{
|
|
510
579
|
key: 'classics', label: '古籍原文',
|
|
511
580
|
text: r.classics.map((e) => `《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》「${e.quote}」——${e.plain}`).join('\n'),
|
|
512
581
|
}] : []),
|
|
513
582
|
{
|
|
514
583
|
key: 'quant', label: '量化口径',
|
|
515
|
-
text: `本报告的量化只到「档位」:事业看十神权重(${topName} ${top[0]?.[1] ?? '—'})、财富看财星权重(${groups['财'] ?? 0})、感情看配偶星权重(${spouseKey} ${groups[spouseKey] ?? 0});大运/流年用「大吉 / 吉 / 平 /
|
|
584
|
+
text: `本报告的量化只到「档位」:事业看十神权重(${topName} ${top[0]?.[1] ?? '—'})、财富看财星权重(${groups['财'] ?? 0})、感情看配偶星权重(${spouseKey} ${groups[spouseKey] ?? 0});大运/流年用「大吉 / 吉 / 平 / 忌」四档。不换算金额、不给健康诊断——那需要地域、家庭、行业与体检数据,命盘本身推不出来。`
|
|
585
|
+
+ (r.strength?.weightPct
|
|
586
|
+
? `\n宫位权重(炳祥课里干 2/5/0/3、支 11/36/27/16 的百分比视图):${r.strength.weightPct.detail}。这组数只说明四柱各占多少,不改上面的旺衰评分。`
|
|
587
|
+
: ''),
|
|
516
588
|
},
|
|
517
589
|
{
|
|
518
590
|
key: 'limits', label: '未纳入',
|
|
519
|
-
text: '
|
|
591
|
+
text: '本盘没有计算:流月与流日、神煞的分值折算(解读侧只按课里口径作降权提示,不折成分值)、地支藏干的动态引化(合冲后再论)。取用按「调候优先、扶抑校验」;调候由月令与全局寒暖燥湿判定,并按《穷通宝鉴》120 格给出用神顺序(整理表口径,原文摘句照录,异文处已标 note);各派取法仍有分歧;真太阳时未含历史时区与夏令时。把这些补上会改变"强弱"的边际判断,所以这里只给方向,不下断语。',
|
|
520
592
|
},
|
|
521
593
|
];
|
|
522
594
|
|