dsh-metaphysics 0.34.0 → 0.38.2
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 +103 -3
- package/README.md +342 -309
- package/client.js +1137 -137
- package/docs/assets/dsh-metaphysics-group.png +0 -0
- package/engine/bazi.js +48 -2
- package/engine/classics.js +123 -7
- package/engine/followup.js +58 -0
- package/engine/index.js +54 -15
- package/engine/interpret-knowledge.js +50 -4
- package/engine/interpret-plain.js +46 -3
- package/engine/interpret.js +78 -1
- package/engine/liuyao.js +145 -0
- package/engine/ziwei.js +119 -13
- package/locale/zh.json +1 -1
- package/package.json +16 -14
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +1213 -167
package/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({
|
|
2
2
|
id: 'dsh-metaphysics',
|
|
3
|
+
version: '0.38.2',
|
|
3
4
|
factory(require) {
|
|
4
5
|
const React = (function () {
|
|
5
6
|
try { return require('react'); } catch (e) { return globalThis.React; }
|
|
@@ -2514,6 +2515,7 @@ __mods.classics = (function () {
|
|
|
2514
2515
|
const CLASSIC_BOOKS = {
|
|
2515
2516
|
ziping: { name: '子平真诠', author: '清·沈孝瞻', base: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/' },
|
|
2516
2517
|
ditian: { name: '滴天髓', author: '明·京图(通行本)', base: 'https://www.diancang.xyz/xuanxuewushu/ditiansui/' },
|
|
2518
|
+
sanming: { name: '三命通会', author: '明·万民英', base: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/' },
|
|
2517
2519
|
};
|
|
2518
2520
|
|
|
2519
2521
|
const CLASSICS = [
|
|
@@ -2617,6 +2619,26 @@ const CLASSICS = [
|
|
|
2617
2619
|
plain: '月令用神为主,但必须配气候参看;同样的格局,生在得时的气候里事半功倍,逆着气候就费劲。',
|
|
2618
2620
|
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53634.html',
|
|
2619
2621
|
},
|
|
2622
|
+
{
|
|
2623
|
+
id: 'zp-chengbai',
|
|
2624
|
+
book: 'ziping',
|
|
2625
|
+
chapter: '九、论用神成败救应',
|
|
2626
|
+
scene: '格局',
|
|
2627
|
+
tags: [],
|
|
2628
|
+
quote: '成中有败,必是带忌;败中有成,全凭救应。',
|
|
2629
|
+
plain: '成格不等于一路顺:成中带忌(官逢财又逢伤、官被合之类)就打了折;败格也未必无救——印来解伤、合来清煞,败中还能转成。',
|
|
2630
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53629.html',
|
|
2631
|
+
},
|
|
2632
|
+
{
|
|
2633
|
+
id: 'zp-bianhua',
|
|
2634
|
+
book: 'ziping',
|
|
2635
|
+
chapter: '十、论用神变化',
|
|
2636
|
+
scene: '格局',
|
|
2637
|
+
tags: [],
|
|
2638
|
+
quote: '故若丁生亥月,本为正官,支全卯未,则化为印。己生申月,本属伤官。藏庚透壬,则化为财。凡此之类皆用神之变化也。',
|
|
2639
|
+
plain: '用神本从月令取,但月令藏干不一:丁生亥月本为正官,支会卯未就化为印;己生申月本属伤官,庚藏壬透就化为财。起点相同,合化一变,取用也跟着变(原文只说变化之由,不断定某盘必化)。',
|
|
2640
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53630.html',
|
|
2641
|
+
},
|
|
2620
2642
|
{
|
|
2621
2643
|
id: 'dt-hannuan',
|
|
2622
2644
|
book: 'ditian',
|
|
@@ -2707,6 +2729,76 @@ const CLASSICS = [
|
|
|
2707
2729
|
plain: '看精神不能偏执一端,要在损益之间求其中。',
|
|
2708
2730
|
url: 'https://www.diancang.xyz/xuanxuewushu/ditiansui/153091.html',
|
|
2709
2731
|
},
|
|
2732
|
+
{
|
|
2733
|
+
id: 'smt-zhenguan',
|
|
2734
|
+
book: 'sanming',
|
|
2735
|
+
chapter: '卷五·论正官',
|
|
2736
|
+
scene: '格局',
|
|
2737
|
+
tags: ['正官'],
|
|
2738
|
+
quote: '正官者,乃甲见辛、乙见庚之例。阴阳配合,相制有用,成其道也。故正官为六格之首,止许一位,多则不宜。',
|
|
2739
|
+
plain: '正官取「克我而阴阳相配」,有制而能成用;六格以正官居首,只宜一位,多见就杂。',
|
|
2740
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7582.html',
|
|
2741
|
+
},
|
|
2742
|
+
{
|
|
2743
|
+
id: 'smt-zhengcai',
|
|
2744
|
+
book: 'sanming',
|
|
2745
|
+
chapter: '卷六·论正财',
|
|
2746
|
+
scene: '格局',
|
|
2747
|
+
tags: ['财'],
|
|
2748
|
+
quote: '正财者,乃甲见己、乙见戊之例。受我克制,为我之妻,譬人娶妻,妻赍财嫁我,我必精神康强,而后可享用,若衰微不振,虽妻财丰厚,但能目视,终不得用。',
|
|
2749
|
+
plain: '正财是我克制之物,古人以「娶妻带财」作比:自身精神康强才受用得起,身弱不振,财再厚也只是看着。',
|
|
2750
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7645.html',
|
|
2751
|
+
},
|
|
2752
|
+
{
|
|
2753
|
+
id: 'smt-yinshou',
|
|
2754
|
+
book: 'sanming',
|
|
2755
|
+
chapter: '卷六·论印绶',
|
|
2756
|
+
scene: '格局',
|
|
2757
|
+
tags: ['印'],
|
|
2758
|
+
quote: '印绶者,乃五行生我之名。如甲乙在亥子月,丙丁在寅卯月之类,乃我气之源,为生气,为父母,能护我官星,使无伤克',
|
|
2759
|
+
plain: '印是生我之气,像源头与父母:它能护住官星,使官不受伤克;反过来说,印重就怕财来破。',
|
|
2760
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7655.html',
|
|
2761
|
+
},
|
|
2762
|
+
{
|
|
2763
|
+
id: 'smt-shishen',
|
|
2764
|
+
book: 'sanming',
|
|
2765
|
+
chapter: '卷六·论食神',
|
|
2766
|
+
scene: '格局',
|
|
2767
|
+
tags: ['食神'],
|
|
2768
|
+
quote: '凡命遇财煞之地,食神旺相,煞被食制,不敢为祸,财被食生,充裕不竭,故食神一名寿星,一名爵星,良有以也。',
|
|
2769
|
+
plain: '食神旺,一头制煞、一头生财:煞被制住不敢为祸,财被生起不至枯竭;所以食神又叫寿星、爵星。',
|
|
2770
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7663.html',
|
|
2771
|
+
},
|
|
2772
|
+
{
|
|
2773
|
+
id: 'smt-shangguan',
|
|
2774
|
+
book: 'sanming',
|
|
2775
|
+
chapter: '卷六·论伤官',
|
|
2776
|
+
scene: '格局',
|
|
2777
|
+
tags: ['伤官'],
|
|
2778
|
+
quote: '伤官虽凶,乃我所生,自家之物,伤尽则能生财,财旺则能生官,造化展转有情。',
|
|
2779
|
+
plain: '伤官虽称凶,却是我自己生出来的:伤尽(柱中不见官星)反能生财,财旺再生官,辗转还是有情。',
|
|
2780
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7662.html',
|
|
2781
|
+
},
|
|
2782
|
+
{
|
|
2783
|
+
id: 'smt-yangren',
|
|
2784
|
+
book: 'sanming',
|
|
2785
|
+
chapter: '卷六·论阳刃',
|
|
2786
|
+
scene: '格局',
|
|
2787
|
+
tags: ['阳刃', '劫财'],
|
|
2788
|
+
quote: '阳者,阴阳之阳,刃者,刀刃之刃,即禄前一位,言旺越其分,故险。',
|
|
2789
|
+
plain: '阳刃指禄前一位,旺过了本分,所以险;甲丙戊庚壬五阳干才有刃,阴干见伤官同论。',
|
|
2790
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7671.html',
|
|
2791
|
+
},
|
|
2792
|
+
{
|
|
2793
|
+
id: 'smt-jianlu',
|
|
2794
|
+
book: 'sanming',
|
|
2795
|
+
chapter: '卷六·论建禄',
|
|
2796
|
+
scene: '格局',
|
|
2797
|
+
tags: ['建禄', '比肩', '月劫'],
|
|
2798
|
+
quote: '凡命月令建禄,难招祖业,必主平生见财不聚,却病少寿长,行运再见比肩,克妻妨父损子',
|
|
2799
|
+
plain: '月令建禄是日主临官之地,身旺而财官难取:古说难承祖业、见财不聚,但病少寿长;再走比肩运,古书说克妻妨父损子(属于旧说的重话,本插件只记原文、不作断语)。',
|
|
2800
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7672.html',
|
|
2801
|
+
},
|
|
2710
2802
|
];
|
|
2711
2803
|
|
|
2712
2804
|
const BY_ID = CLASSICS.reduce((m, e) => { m[e.id] = e; return m; }, {});
|
|
@@ -2737,7 +2829,15 @@ function tagOf(gejuName) {
|
|
|
2737
2829
|
return GEJU_KEY[bare + '格'] || bare;
|
|
2738
2830
|
}
|
|
2739
2831
|
|
|
2740
|
-
function
|
|
2832
|
+
function pick(tag, book) {
|
|
2833
|
+
return CLASSICS.find((e) => e.scene === '格局' && e.tags.includes(tag) && (!book || e.book === book)) || null;
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
function chapterTitle(e) {
|
|
2837
|
+
return e.chapter.replace(/^.*[、·]/, '').replace(/^论/, '');
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
function classicsFor(r, limit = 5) {
|
|
2741
2841
|
if (!r) return [];
|
|
2742
2842
|
const out = [];
|
|
2743
2843
|
const seen = new Set();
|
|
@@ -2750,8 +2850,10 @@ function classicsFor(r, limit = 4) {
|
|
|
2750
2850
|
for (const g of gejuList) {
|
|
2751
2851
|
if (!g || (g.kind && g.kind !== '月令格')) continue;
|
|
2752
2852
|
const tag = tagOf(g.name);
|
|
2753
|
-
const
|
|
2754
|
-
if (
|
|
2853
|
+
const primary = pick(tag, 'ziping') || pick(tag);
|
|
2854
|
+
if (primary) push(primary, `你的月令格局是「${g.name}」,故取${CLASSIC_BOOKS[primary.book].name}「${chapterTitle(primary)}」一条`);
|
|
2855
|
+
const alt = CLASSICS.find((e) => e.scene === '格局' && e.tags.includes(tag) && (!primary || e.book !== primary.book));
|
|
2856
|
+
if (alt) push(alt, `同是「${g.name}」,${CLASSIC_BOOKS[alt.book].name}「${chapterTitle(alt)}」另有取法,可对照读`);
|
|
2755
2857
|
}
|
|
2756
2858
|
const cli = r.climate || (r.frame && r.frame.yongshen && (r.frame.yongshen.climate || r.frame.yongshen.tiaohou));
|
|
2757
2859
|
if (cli && cli.kind && cli.kind !== '平和') {
|
|
@@ -2761,7 +2863,15 @@ function classicsFor(r, limit = 4) {
|
|
|
2761
2863
|
push(classicOf('zp-qihou'), '气候与月令用神要互参,故取子平真诠「用神配气候」一条');
|
|
2762
2864
|
if (hot) push(classicOf('dt-hannuan'), '本盘偏热,寒暖一条正对');
|
|
2763
2865
|
}
|
|
2764
|
-
|
|
2866
|
+
const huagi = gejuList.find((g) => g && g.kind === '化气格');
|
|
2867
|
+
const combo = gejuList.find((g) => g && g.kind === '组合');
|
|
2868
|
+
if (huagi) {
|
|
2869
|
+
push(classicOf('zp-bianhua'), `本盘列有「${huagi.name}」:用神由月令合化而变,总纲一位改取${CLASSIC_BOOKS.ziping.name}论用神变化`);
|
|
2870
|
+
} else if (combo) {
|
|
2871
|
+
push(classicOf('zp-chengbai'), `本盘另有「${combo.name}」组合:成格还要看带忌与救应,总纲一位改取${CLASSIC_BOOKS.ziping.name}论用神成败救应`);
|
|
2872
|
+
} else {
|
|
2873
|
+
push(classicOf('zp-yongshen'), '用神从月令取、四吉顺用四凶逆用,是通用总纲');
|
|
2874
|
+
}
|
|
2765
2875
|
return out;
|
|
2766
2876
|
}
|
|
2767
2877
|
|
|
@@ -3367,9 +3477,12 @@ function buildBazi(input) {
|
|
|
3367
3477
|
};
|
|
3368
3478
|
|
|
3369
3479
|
const dayun = [];
|
|
3480
|
+
const dayunWindows = [];
|
|
3370
3481
|
for (let i = 1; i <= 8; i++) {
|
|
3371
3482
|
const idx = (((monthIdx + (forward ? i : -i)) % 60) + 60) % 60;
|
|
3372
3483
|
const g = ganzhiName(idx);
|
|
3484
|
+
const fromJd = partsToJd(addYearsClamped(jiaoParts, (i - 1) * 10));
|
|
3485
|
+
const toJd = partsToJd(addYearsClamped(jiaoParts, i * 10));
|
|
3373
3486
|
dayun.push({
|
|
3374
3487
|
step: i,
|
|
3375
3488
|
startAge: startAgeYears + (i - 1) * 10,
|
|
@@ -3378,9 +3491,10 @@ function buildBazi(input) {
|
|
|
3378
3491
|
branch: g.branch,
|
|
3379
3492
|
stemTenGod: tenGod(dayStem, g.stem),
|
|
3380
3493
|
nayin: nayin(idx),
|
|
3381
|
-
fromDate: formatJd(
|
|
3382
|
-
toDate: formatJd(
|
|
3494
|
+
fromDate: formatJd(fromJd),
|
|
3495
|
+
toDate: formatJd(toJd),
|
|
3383
3496
|
});
|
|
3497
|
+
dayunWindows.push({ step: i, ganzhi: g.name, fromJd, toJd });
|
|
3384
3498
|
}
|
|
3385
3499
|
|
|
3386
3500
|
const thisYear = Number(input.nowYear) || new Date().getFullYear();
|
|
@@ -3521,6 +3635,45 @@ function buildBazi(input) {
|
|
|
3521
3635
|
l.luck = scoreLuck(l.ganzhi, frame);
|
|
3522
3636
|
}
|
|
3523
3637
|
|
|
3638
|
+
const NATAL_LABEL = { year: '年柱', month: '月柱', day: '日柱', hour: '时柱' };
|
|
3639
|
+
const stemOvercomes = (a, b) => OVERCOMES[STEM_ELEMENT[a]] === STEM_ELEMENT[b];
|
|
3640
|
+
const tianKeDiChong = (a, b) => {
|
|
3641
|
+
if (typeof a !== 'string' || typeof b !== 'string' || a.length < 2 || b.length < 2) return false;
|
|
3642
|
+
if (!(a[0] in STEM_ELEMENT) || !(b[0] in STEM_ELEMENT)) return false;
|
|
3643
|
+
return (stemOvercomes(a[0], b[0]) || stemOvercomes(b[0], a[0])) && hasPair(BRANCH_CHONG, a[1], b[1]);
|
|
3644
|
+
};
|
|
3645
|
+
const lichunJd = (y) => {
|
|
3646
|
+
const t = termWindow(y, { jieOnly: true }).find((x) => x.index === 2 && jdToParts(x.jd).year === y);
|
|
3647
|
+
return t ? t.jd : partsToJd({ year: y, month: 2, day: 4 });
|
|
3648
|
+
};
|
|
3649
|
+
for (const l of liunian) {
|
|
3650
|
+
const yStart = lichunJd(l.year);
|
|
3651
|
+
const yEnd = lichunJd(l.year + 1);
|
|
3652
|
+
const active = dayunWindows.filter((w) => w.fromJd < yEnd && w.toJd > yStart);
|
|
3653
|
+
const signals = [];
|
|
3654
|
+
for (const w of active) {
|
|
3655
|
+
if (w.ganzhi === l.ganzhi) {
|
|
3656
|
+
signals.push({ type: '岁运并临', target: `第${w.step}步大运`, detail: `大运与流年同为${l.ganzhi}` });
|
|
3657
|
+
} else if (tianKeDiChong(w.ganzhi, l.ganzhi)) {
|
|
3658
|
+
signals.push({ type: '运年反吟', target: `第${w.step}步大运`, detail: `大运${w.ganzhi}与流年${l.ganzhi}天克地冲` });
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
for (const key of ['year', 'month', 'day', 'hour']) {
|
|
3662
|
+
const g = pillars[key].ganzhi;
|
|
3663
|
+
if (!g) continue;
|
|
3664
|
+
if (l.ganzhi === g) {
|
|
3665
|
+
signals.push({ type: '流年伏吟', target: NATAL_LABEL[key], detail: `流年${l.ganzhi}与${NATAL_LABEL[key]}同干支` });
|
|
3666
|
+
} else if (tianKeDiChong(l.ganzhi, g)) {
|
|
3667
|
+
signals.push({ type: '流年反吟', target: NATAL_LABEL[key], detail: `流年${l.ganzhi}与${NATAL_LABEL[key]}${g}天克地冲` });
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
l.suiyun = {
|
|
3671
|
+
dayun: active.map((w) => ({ step: w.step, ganzhi: w.ganzhi })),
|
|
3672
|
+
signals,
|
|
3673
|
+
note: '只标干支重复与天克地冲这类变动信号,不判吉凶;大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列',
|
|
3674
|
+
};
|
|
3675
|
+
}
|
|
3676
|
+
|
|
3524
3677
|
const p = jdToParts(jd);
|
|
3525
3678
|
|
|
3526
3679
|
const mStemIdx = STEMS.indexOf(pillars.month.stem);
|
|
@@ -4220,7 +4373,136 @@ function yongshenStrength(result, useGod, opts = {}) {
|
|
|
4220
4373
|
};
|
|
4221
4374
|
}
|
|
4222
4375
|
|
|
4223
|
-
|
|
4376
|
+
function hexagramStrength(result, opts = {}) {
|
|
4377
|
+
const rows = (result && result.ben && Array.isArray(result.ben.lines))
|
|
4378
|
+
? result.ben.lines
|
|
4379
|
+
: (result && Array.isArray(result.lines) ? result.lines : []);
|
|
4380
|
+
if (!rows.length) return null;
|
|
4381
|
+
const monthBranch = opts.monthBranch || null;
|
|
4382
|
+
const dayBranch = opts.dayBranch || (result.dayGanZhi ? result.dayGanZhi.branch : null);
|
|
4383
|
+
if (!monthBranch && !dayBranch) return null;
|
|
4384
|
+
const monthElement = monthBranch ? zhiElementOf(monthBranch) : null;
|
|
4385
|
+
const dayElement = dayBranch ? zhiElementOf(dayBranch) : null;
|
|
4386
|
+
const kong = Array.isArray(result.xunKong)
|
|
4387
|
+
? result.xunKong
|
|
4388
|
+
: (typeof result.xunKong === 'string' ? result.xunKong.split('') : []);
|
|
4389
|
+
const shiPos = result.ben ? result.ben.shi : null;
|
|
4390
|
+
const yingPos = result.ben ? result.ben.ying : null;
|
|
4391
|
+
|
|
4392
|
+
const lines = rows.map((l) => {
|
|
4393
|
+
const element = l.element || zhiElementOf(l.branch);
|
|
4394
|
+
const monthChong = !!(monthBranch && CHONG_OF[l.branch] === monthBranch);
|
|
4395
|
+
const dayChong = !!(dayBranch && CHONG_OF[l.branch] === dayBranch);
|
|
4396
|
+
const monthState = monthStateOf(element, monthElement);
|
|
4397
|
+
const dayRelation = dayRelationOf(element, dayElement);
|
|
4398
|
+
const isEmpty = kong.includes(l.branch);
|
|
4399
|
+
return {
|
|
4400
|
+
position: l.position,
|
|
4401
|
+
name: l.name,
|
|
4402
|
+
branch: l.branch,
|
|
4403
|
+
element,
|
|
4404
|
+
liuqin: l.liuqin ?? null,
|
|
4405
|
+
shi: l.position === shiPos,
|
|
4406
|
+
ying: l.position === yingPos,
|
|
4407
|
+
moving: !!l.moving,
|
|
4408
|
+
kong: isEmpty,
|
|
4409
|
+
monthState,
|
|
4410
|
+
monthSay: MONTH_STATE_SAY[monthState] || '',
|
|
4411
|
+
monthChong,
|
|
4412
|
+
dayRelation,
|
|
4413
|
+
daySay: DAY_RELATION_SAY[dayRelation] || '',
|
|
4414
|
+
dayChong,
|
|
4415
|
+
chongTag: monthChong ? '月破'
|
|
4416
|
+
: dayChong ? (isEmpty ? '冲空' : (l.moving ? '逢日辰冲' : '暗动')) : '',
|
|
4417
|
+
};
|
|
4418
|
+
});
|
|
4419
|
+
|
|
4420
|
+
const counts = {};
|
|
4421
|
+
for (const st of MONTH_STATE_ORDER) counts[st] = lines.filter((l) => l.monthState === st).length;
|
|
4422
|
+
|
|
4423
|
+
const labels = [];
|
|
4424
|
+
for (const st of MONTH_STATE_ORDER) if (counts[st]) labels.push(`全卦${st}${counts[st]}爻`);
|
|
4425
|
+
const shiLine = lines.find((l) => l.shi) || null;
|
|
4426
|
+
const yingLine = lines.find((l) => l.ying) || null;
|
|
4427
|
+
if (shiLine && shiLine.monthState !== 'unknown') labels.push(`世爻月建${shiLine.monthState}`);
|
|
4428
|
+
if (yingLine && yingLine.monthState !== 'unknown') labels.push(`应爻月建${yingLine.monthState}`);
|
|
4429
|
+
const tagCount = (tag) => lines.filter((l) => l.chongTag === tag).length;
|
|
4430
|
+
for (const tag of ['月破', '暗动', '冲空', '逢日辰冲']) {
|
|
4431
|
+
const n = tagCount(tag);
|
|
4432
|
+
if (n) labels.push(`${tag}${n}爻`);
|
|
4433
|
+
}
|
|
4434
|
+
|
|
4435
|
+
return {
|
|
4436
|
+
month: monthBranch ? { branch: monthBranch, element: monthElement } : null,
|
|
4437
|
+
day: dayBranch ? { branch: dayBranch, element: dayElement } : null,
|
|
4438
|
+
lines,
|
|
4439
|
+
counts,
|
|
4440
|
+
strongest: lines.filter((l) => l.monthState === '旺').map((l) => l.position),
|
|
4441
|
+
weakest: lines.filter((l) => l.monthState === '死' || l.monthChong).map((l) => l.position),
|
|
4442
|
+
shi: shiLine ? { position: shiLine.position, branch: shiLine.branch, monthState: shiLine.monthState, dayRelation: shiLine.dayRelation } : null,
|
|
4443
|
+
ying: yingLine ? { position: yingLine.position, branch: yingLine.branch, monthState: yingLine.monthState, dayRelation: yingLine.dayRelation } : null,
|
|
4444
|
+
labels,
|
|
4445
|
+
note: '月建主这一段的旺衰、日辰管当天的扶克,六爻逐一给状态;判定与用神旺衰同一套,只多了世应与动爻标记。只报状态、不折分数,也不单独断吉凶。',
|
|
4446
|
+
};
|
|
4447
|
+
}
|
|
4448
|
+
|
|
4449
|
+
const JIN_VERDICT = { 旺: '后劲足', 相: '后劲足', 休: '后劲有限', 囚: '后劲有限', 死: '进得虚' };
|
|
4450
|
+
const TUI_VERDICT = { 旺: '退得缓', 相: '退得缓', 休: '退得实', 囚: '退得实', 死: '退得实' };
|
|
4451
|
+
|
|
4452
|
+
function jinTuiPower(result, opts = {}) {
|
|
4453
|
+
const items = result && result.body && Array.isArray(result.body.jinTui) ? result.body.jinTui : [];
|
|
4454
|
+
if (!items.length) return null;
|
|
4455
|
+
const rows = result && result.ben && Array.isArray(result.ben.lines) ? result.ben.lines : [];
|
|
4456
|
+
const monthBranch = opts.monthBranch || null;
|
|
4457
|
+
const dayBranch = opts.dayBranch || (result && result.dayGanZhi ? result.dayGanZhi.branch : null);
|
|
4458
|
+
const monthElement = monthBranch ? zhiElementOf(monthBranch) : null;
|
|
4459
|
+
const dayElement = dayBranch ? zhiElementOf(dayBranch) : null;
|
|
4460
|
+
const kong = Array.isArray(result && result.xunKong)
|
|
4461
|
+
? result.xunKong
|
|
4462
|
+
: (result && typeof result.xunKong === 'string' ? result.xunKong.split('') : []);
|
|
4463
|
+
|
|
4464
|
+
const lines = items.map((x) => {
|
|
4465
|
+
const line = rows[x.position - 1] || null;
|
|
4466
|
+
const element = (line && line.element) || zhiElementOf(x.from);
|
|
4467
|
+
const monthState = monthStateOf(element, monthElement);
|
|
4468
|
+
const monthChong = !!(monthBranch && CHONG_OF[x.from] === monthBranch);
|
|
4469
|
+
const dayChong = !!(dayBranch && CHONG_OF[x.from] === dayBranch);
|
|
4470
|
+
const dayRelation = dayRelationOf(element, dayElement);
|
|
4471
|
+
const isEmpty = kong.includes(x.from);
|
|
4472
|
+
const verdict = !monthBranch ? '只报趋势'
|
|
4473
|
+
: monthChong ? '月破失据'
|
|
4474
|
+
: ((x.type === '进' ? JIN_VERDICT : TUI_VERDICT)[monthState] || '未定');
|
|
4475
|
+
const monthSay = monthBranch
|
|
4476
|
+
? `月建${monthBranch}(${monthElement})对${element}为${monthState}`
|
|
4477
|
+
: '缺月建,只看日辰';
|
|
4478
|
+
const daySay = dayRelation === 'unknown' ? '' : `日辰${dayBranch}(${dayElement})${dayRelation}`;
|
|
4479
|
+
const extra = [monthChong ? '又遭月破' : '', isEmpty ? '旬空待填' : '', dayChong ? '逢日辰冲' : ''].filter(Boolean);
|
|
4480
|
+
return {
|
|
4481
|
+
position: x.position,
|
|
4482
|
+
from: x.from,
|
|
4483
|
+
to: x.to,
|
|
4484
|
+
type: x.type,
|
|
4485
|
+
element,
|
|
4486
|
+
monthState,
|
|
4487
|
+
monthChong,
|
|
4488
|
+
dayRelation,
|
|
4489
|
+
dayChong,
|
|
4490
|
+
kong: isEmpty,
|
|
4491
|
+
verdict,
|
|
4492
|
+
say: `${x.from}→${x.to}(${x.type}):${monthSay}${daySay ? `,${daySay}` : ''}${extra.length ? `,${extra.join('、')}` : ''} → ${verdict}`,
|
|
4493
|
+
};
|
|
4494
|
+
});
|
|
4495
|
+
|
|
4496
|
+
return {
|
|
4497
|
+
month: monthBranch ? { branch: monthBranch, element: monthElement } : null,
|
|
4498
|
+
day: dayBranch ? { branch: dayBranch, element: dayElement } : null,
|
|
4499
|
+
lines,
|
|
4500
|
+
labels: lines.map((l) => `${l.position}爻化${l.type}·${l.verdict}`),
|
|
4501
|
+
note: '进退只说这一爻往哪边走;力重是把它放回月建日辰,看有没有托着——得令则进得动、退得慢,失令则进得虚、退得实,月破压过一切。仍不直接定吉凶:用神化进为喜,忌神化进反而是忌。',
|
|
4502
|
+
};
|
|
4503
|
+
}
|
|
4504
|
+
|
|
4505
|
+
return { jinTuiOf, hexBody, bodyRelations, bodyLabels, HEXAGRAM_COUNT, hexagramFromBits, YONGSHEN_RULES, yongshenOf, tossLines, buildLiuyao, zhiElementOf, monthStateOf, dayRelationOf, yongshenStrength, hexagramStrength, jinTuiPower };
|
|
4224
4506
|
})();
|
|
4225
4507
|
|
|
4226
4508
|
__mods.ziwei = (function () {
|
|
@@ -4697,6 +4979,7 @@ function buildZiwei(input) {
|
|
|
4697
4979
|
shensha: '长生、博士随大限顺逆;将前、岁前恒顺行;天伤恒在交友、天使恒在疾厄',
|
|
4698
4980
|
masters: '命主按命宫地支,身主按生年地支',
|
|
4699
4981
|
liunian: '流年命宫取该年地支宫;三方四正为本宫与 +4/+8/+6;并给该年所属大限与小限',
|
|
4982
|
+
flyComposite: '三方四正取本宫、对宫与两个三合宫共四宫,四宫宫干各化禄权科忌共 16 条,按落宫归堆标会聚(双忌会、禄忌同宫、三化会、自化);只描会照,不折吉凶',
|
|
4700
4983
|
changqu: '昌曲落宫只由时支决定,故与丑未的关系(夹/三合/同宫/无关)是结构性结论;absorb 的「清/杂」是启发式标记,依据昌曲化忌与会煞,不是断语',
|
|
4701
4984
|
},
|
|
4702
4985
|
};
|
|
@@ -4705,13 +4988,15 @@ function buildZiwei(input) {
|
|
|
4705
4988
|
chart.daxianList = daxianList(chart);
|
|
4706
4989
|
chart.fly = flyStars(chart);
|
|
4707
4990
|
chart.flyChains = flyChains(chart, { from: '命宫' });
|
|
4991
|
+
chart.flyComposite = flyComposite(chart, { from: '命宫' });
|
|
4708
4992
|
enrichLiunian(chart);
|
|
4709
4993
|
chart.flow = flowOf(chart, input.asOf);
|
|
4710
4994
|
chart.patternSummary = {
|
|
4711
4995
|
count: chart.patterns.length,
|
|
4712
4996
|
good: chart.patterns.filter((p) => p.tone === 'good').map((p) => p.name),
|
|
4997
|
+
neutral: chart.patterns.filter((p) => p.tone === 'neutral').map((p) => p.name),
|
|
4713
4998
|
bad: chart.patterns.filter((p) => p.tone === 'bad').map((p) => p.name),
|
|
4714
|
-
note: '
|
|
4999
|
+
note: '格局只描述结构,不作吉凶断语;同一命盘可并存吉格、中性结构与忌格',
|
|
4715
5000
|
};
|
|
4716
5001
|
return chart;
|
|
4717
5002
|
}
|
|
@@ -4751,7 +5036,7 @@ function detectPatterns(chart) {
|
|
|
4751
5036
|
|
|
4752
5037
|
const lu = starBranchOf(chart, '禄存');
|
|
4753
5038
|
const ma = starBranchOf(chart, '天马');
|
|
4754
|
-
if (lu >= 0 && ma >= 0 && (lu === ma || fix(lu - ma) === 6)) add('禄马交驰', `禄存在${
|
|
5039
|
+
if (lu >= 0 && ma >= 0 && (lu === ma || fix(lu - ma) === 6)) add('禄马交驰', `禄存在${BRANCHES[lu]},天马在${BRANCHES[ma]}`);
|
|
4755
5040
|
|
|
4756
5041
|
const huo = starBranchOf(chart, '火星');
|
|
4757
5042
|
const ling = starBranchOf(chart, '铃星');
|
|
@@ -4759,11 +5044,8 @@ function detectPatterns(chart) {
|
|
|
4759
5044
|
if (fix(soulIdx - 1) === ling && fix(soulIdx + 1) === huo) add('火铃夹命', '铃星与火星夹命');
|
|
4760
5045
|
|
|
4761
5046
|
const ji = chart.palaces.find((p) => p.stars.some((s) => s.mutagen === '忌'));
|
|
4762
|
-
if (ji) {
|
|
4763
|
-
|
|
4764
|
-
if (fix(jb - 1) === starBranchOf(chart, '擎羊') && fix(jb + 1) === starBranchOf(chart, '陀罗')) {
|
|
4765
|
-
add('羊陀夹忌', `化忌在${ji.branch},擎羊陀罗夹之`);
|
|
4766
|
-
}
|
|
5047
|
+
if (ji && lu >= 0 && BRANCHES.indexOf(ji.branch) === lu) {
|
|
5048
|
+
add('羊陀夹忌', `化忌与禄存在${ji.branch}同宫,擎羊陀罗夹之`);
|
|
4767
5049
|
}
|
|
4768
5050
|
|
|
4769
5051
|
const lctw = ['铃星', '文昌', '陀罗', '武曲'].map((n) => starBranchOf(chart, n));
|
|
@@ -4782,7 +5064,9 @@ function detectPatterns(chart) {
|
|
|
4782
5064
|
const jia = (a, b) => {
|
|
4783
5065
|
const ba = starBranchOf(chart, a);
|
|
4784
5066
|
const bb = starBranchOf(chart, b);
|
|
4785
|
-
|
|
5067
|
+
if (ba < 0 || bb < 0) return false;
|
|
5068
|
+
return (fix(ba + 1) === soulIdx && fix(bb - 1) === soulIdx)
|
|
5069
|
+
|| (fix(bb + 1) === soulIdx && fix(ba - 1) === soulIdx);
|
|
4786
5070
|
};
|
|
4787
5071
|
const mutagensIn = (indices) => {
|
|
4788
5072
|
const set = new Set();
|
|
@@ -4813,7 +5097,7 @@ function detectPatterns(chart) {
|
|
|
4813
5097
|
if (jia('左辅', '右弼')) add('左右夹命', '左辅、右弼夹命宫');
|
|
4814
5098
|
if (jia('文昌', '文曲')) add('昌曲夹命', '文昌、文曲夹命宫');
|
|
4815
5099
|
if (jia('天魁', '天钺')) add('魁钺夹命', '天魁、天钺夹命宫');
|
|
4816
|
-
if (jia('擎羊', '陀罗')) add('羊陀夹命',
|
|
5100
|
+
if (jia('擎羊', '陀罗')) add('羊陀夹命', `禄存在${BRANCHES[soulIdx]}守命,擎羊陀罗前后夹之`);
|
|
4817
5101
|
|
|
4818
5102
|
const muts = mutagensIn(sanfang);
|
|
4819
5103
|
if (muts.has('禄') && muts.has('权') && muts.has('科')) add('三奇嘉会', '化禄、化权、化科会于命宫三方四正');
|
|
@@ -4826,9 +5110,10 @@ function detectPatterns(chart) {
|
|
|
4826
5110
|
const lianzhen = starBranchOf(chart, '廉贞');
|
|
4827
5111
|
const tianxiang = starBranchOf(chart, '天相');
|
|
4828
5112
|
const qingyang = starBranchOf(chart, '擎羊');
|
|
4829
|
-
if (lianzhen >= 0 &&
|
|
4830
|
-
&&
|
|
4831
|
-
|
|
5113
|
+
if (lianzhen >= 0 && tianxiang >= 0 && qingyang >= 0
|
|
5114
|
+
&& lianzhen === tianxiang && qingyang === tianxiang && tianxiang === soulIdx
|
|
5115
|
+
&& (tianxiang === 0 || tianxiang === 6)) {
|
|
5116
|
+
add('刑囚夹印', `廉贞天相同守命宫${BRANCHES[tianxiang]},擎羊同宫`);
|
|
4832
5117
|
}
|
|
4833
5118
|
if (near.has('贪狼') && (near.has('火星') || near.has('铃星'))) {
|
|
4834
5119
|
add('火贪铃贪', `贪狼与${near.has('火星') ? '火星' : '铃星'}会于命宫三方四正`);
|
|
@@ -4949,6 +5234,97 @@ function flyChains(chart, { from = '命宫', maxSteps = 12 } = {}) {
|
|
|
4949
5234
|
return out;
|
|
4950
5235
|
}
|
|
4951
5236
|
|
|
5237
|
+
const PALACE_SUFFIX = (p) => `${p}${String(p).endsWith('宫') ? '' : '宫'}`;
|
|
5238
|
+
|
|
5239
|
+
function flyComposite(chart, { from = '命宫' } = {}) {
|
|
5240
|
+
const palaces = chart.palaces || [];
|
|
5241
|
+
const src = palaces.find((p) => p.palace === from) || palaces[0];
|
|
5242
|
+
if (!src) return null;
|
|
5243
|
+
const names = Array.isArray(src.sanfang) && src.sanfang.length
|
|
5244
|
+
? [...new Set(src.sanfang)].slice(0, 4)
|
|
5245
|
+
: [src.palace];
|
|
5246
|
+
|
|
5247
|
+
const sources = [];
|
|
5248
|
+
for (const name of names) {
|
|
5249
|
+
const p = palaces.find((x) => x.palace === name);
|
|
5250
|
+
if (!p) continue;
|
|
5251
|
+
sources.push({
|
|
5252
|
+
palace: p.palace,
|
|
5253
|
+
branch: p.branch,
|
|
5254
|
+
stem: p.stem,
|
|
5255
|
+
flies: FLY_TYPES.map((type) => {
|
|
5256
|
+
const star = flyStarOf(p.stem, type);
|
|
5257
|
+
const b = star ? starBranchOf(chart, star) : -1;
|
|
5258
|
+
const target = b >= 0 ? palaces.find((x) => x.branch === BRANCHES[b]) : null;
|
|
5259
|
+
return {
|
|
5260
|
+
type,
|
|
5261
|
+
star,
|
|
5262
|
+
to: target ? target.palace : null,
|
|
5263
|
+
toBranch: target ? target.branch : null,
|
|
5264
|
+
self: !!(target && target.palace === p.palace),
|
|
5265
|
+
};
|
|
5266
|
+
}),
|
|
5267
|
+
});
|
|
5268
|
+
}
|
|
5269
|
+
|
|
5270
|
+
const targets = [];
|
|
5271
|
+
for (const p of palaces) {
|
|
5272
|
+
const incoming = [];
|
|
5273
|
+
for (const s of sources) {
|
|
5274
|
+
for (const f of s.flies) {
|
|
5275
|
+
if (f.to === p.palace) {
|
|
5276
|
+
incoming.push({ from: s.palace, fromBranch: s.branch, fromStem: s.stem, type: f.type, star: f.star, self: f.self });
|
|
5277
|
+
}
|
|
5278
|
+
}
|
|
5279
|
+
}
|
|
5280
|
+
if (!incoming.length) continue;
|
|
5281
|
+
targets.push({
|
|
5282
|
+
palace: p.palace,
|
|
5283
|
+
branch: p.branch,
|
|
5284
|
+
incoming,
|
|
5285
|
+
types: [...new Set(incoming.map((x) => x.type))],
|
|
5286
|
+
count: incoming.length,
|
|
5287
|
+
});
|
|
5288
|
+
}
|
|
5289
|
+
targets.sort((a, b) => b.count - a.count || BRANCHES.indexOf(a.branch) - BRANCHES.indexOf(b.branch));
|
|
5290
|
+
|
|
5291
|
+
const jiAt = (t) => t.incoming.filter((x) => x.type === '忌').length;
|
|
5292
|
+
const groups = {
|
|
5293
|
+
doubleJi: targets.filter((t) => jiAt(t) >= 2),
|
|
5294
|
+
luJi: targets.filter((t) => t.types.includes('禄') && t.types.includes('忌')),
|
|
5295
|
+
tripleHua: targets.filter((t) => t.types.length >= 3),
|
|
5296
|
+
selfHua: targets.filter((t) => t.incoming.some((x) => x.self)),
|
|
5297
|
+
};
|
|
5298
|
+
|
|
5299
|
+
const labels = [];
|
|
5300
|
+
for (const t of groups.doubleJi) labels.push(`${['', '', '双忌', '三忌', '四忌'][jiAt(t)] || `${jiAt(t)}忌`}会${PALACE_SUFFIX(t.palace)}`);
|
|
5301
|
+
for (const t of groups.luJi) labels.push(`禄忌同宫${PALACE_SUFFIX(t.palace)}`);
|
|
5302
|
+
const HUA_NUM = { 3: '三化会', 4: '四化会' };
|
|
5303
|
+
for (const t of groups.tripleHua) labels.push(`${HUA_NUM[t.types.length] || `${t.types.length}化会`}${PALACE_SUFFIX(t.palace)}`);
|
|
5304
|
+
for (const t of groups.selfHua) labels.push(`${PALACE_SUFFIX(t.palace)}自化`);
|
|
5305
|
+
|
|
5306
|
+
const byType = {};
|
|
5307
|
+
for (const type of FLY_TYPES) {
|
|
5308
|
+
byType[type] = sources
|
|
5309
|
+
.map((s) => {
|
|
5310
|
+
const f = s.flies.find((x) => x.type === type);
|
|
5311
|
+
return f && f.to ? { from: s.palace, star: f.star, to: f.to, self: f.self } : null;
|
|
5312
|
+
})
|
|
5313
|
+
.filter(Boolean);
|
|
5314
|
+
}
|
|
5315
|
+
|
|
5316
|
+
return {
|
|
5317
|
+
from: src.palace,
|
|
5318
|
+
sanfang: sources.map((s) => s.palace),
|
|
5319
|
+
sources,
|
|
5320
|
+
targets,
|
|
5321
|
+
groups,
|
|
5322
|
+
byType,
|
|
5323
|
+
labels,
|
|
5324
|
+
note: '三方四正取本宫、对宫与两个三合宫共四宫,四宫宫干各化禄权科忌共 16 条飞化,按落宫归堆;只在落宫相同(会照)时标会聚,单条飞出不另立标签。只描会照与方向,不折吉凶,也未叠大限流年四化。',
|
|
5325
|
+
};
|
|
5326
|
+
}
|
|
5327
|
+
|
|
4952
5328
|
function enrichLiunian(chart) {
|
|
4953
5329
|
for (const ln of chart.liunian) {
|
|
4954
5330
|
const stem = ln.ganzhi[0];
|
|
@@ -5051,7 +5427,7 @@ function flowOf(chart, asOf) {
|
|
|
5051
5427
|
};
|
|
5052
5428
|
}
|
|
5053
5429
|
|
|
5054
|
-
return { PALACE_NAMES, BRIGHTNESS, MUTAGEN, LUCUN, KUI_YUE, MING_ZHU, SHEN_ZHU, triadOf, HUO_START, LING_START, TIANMA, XIANCHI, HUAGAI, JIANGXING, GUCHEN, GUASU, posuIndex, XIAOXIAN_START, CHANGSHENG_NAMES, BOSHI_NAMES, JIANGQIAN_NAMES, SUIQI_NAMES, CHANGSHENG_START, hourBranchIndex, ziweiTianfuIndex, xiaoxianAge, buildZiwei, detectPatterns, daxianList, FLY_TYPES, flyStarOf, flyStars, flyChain, flyChains, enrichLiunian, asOfParts, flowOf };
|
|
5430
|
+
return { PALACE_NAMES, BRIGHTNESS, MUTAGEN, LUCUN, KUI_YUE, MING_ZHU, SHEN_ZHU, triadOf, HUO_START, LING_START, TIANMA, XIANCHI, HUAGAI, JIANGXING, GUCHEN, GUASU, posuIndex, XIAOXIAN_START, CHANGSHENG_NAMES, BOSHI_NAMES, JIANGQIAN_NAMES, SUIQI_NAMES, CHANGSHENG_START, hourBranchIndex, ziweiTianfuIndex, xiaoxianAge, buildZiwei, detectPatterns, PATTERN_TONE, daxianList, FLY_TYPES, flyStarOf, flyStars, flyChain, flyChains, flyComposite, enrichLiunian, asOfParts, flowOf };
|
|
5055
5431
|
})();
|
|
5056
5432
|
|
|
5057
5433
|
__mods.tarot = (function () {
|
|
@@ -9463,6 +9839,40 @@ function useStrengthPlain(st) {
|
|
|
9463
9839
|
return `${when}对这件事有帮有压,一半的力要自己挣——结果更看你怎么走。`;
|
|
9464
9840
|
}
|
|
9465
9841
|
|
|
9842
|
+
function jinTuiPlain(r) {
|
|
9843
|
+
const jp = r && r.jinTuiPower;
|
|
9844
|
+
if (!jp || !Array.isArray(jp.lines) || !jp.lines.length) return '';
|
|
9845
|
+
const sayOf = (l) => (l.verdict === '后劲足' ? '时令托着,后劲足'
|
|
9846
|
+
: l.verdict === '后劲有限' ? '时令不太托,后劲有限'
|
|
9847
|
+
: l.verdict === '进得虚' ? '时令最背,进也是虚进'
|
|
9848
|
+
: l.verdict === '退得缓' ? '时令还托着,退得慢'
|
|
9849
|
+
: l.verdict === '退得实' ? '时令也不托,退得实'
|
|
9850
|
+
: l.verdict === '月破失据' ? '又正好逢月破,进退都站不稳'
|
|
9851
|
+
: '缺月建,先只当方向看');
|
|
9852
|
+
return `动爻的进退还要看时令:${jp.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type},${sayOf(l)}`).join(';')}。`;
|
|
9853
|
+
}
|
|
9854
|
+
|
|
9855
|
+
function hexStrengthPlain(hs) {
|
|
9856
|
+
if (!hs || !hs.counts) return '';
|
|
9857
|
+
const up = (hs.counts.旺 || 0) + (hs.counts.相 || 0);
|
|
9858
|
+
const down = (hs.counts.囚 || 0) + (hs.counts.死 || 0);
|
|
9859
|
+
const when = hs.month && hs.month.branch ? `按${hs.month.branch}月这段时令看` : '按起卦这天看';
|
|
9860
|
+
const shi = hs.shi && hs.shi.monthState !== 'unknown' ? `代表你的世爻在${hs.shi.monthState}` : '';
|
|
9861
|
+
if (up >= 4 && down === 0) return `${when},整张卦六爻的气多数是顺的,${shi},眼下算是好推的时候。`;
|
|
9862
|
+
if (down >= 4 && up === 0) return `${when},整张卦六爻的气多数被压着,${shi},这几天更适合等而不是冲。`;
|
|
9863
|
+
return `${when},整张卦六爻有顺有逆(旺相 ${up} 爻、囚死 ${down} 爻)${shi ? `,${shi}` : ''},成不成要看具体哪一爻在动。`;
|
|
9864
|
+
}
|
|
9865
|
+
|
|
9866
|
+
function flyCompositePlain(fc) {
|
|
9867
|
+
if (!fc || !Array.isArray(fc.targets)) return '';
|
|
9868
|
+
const hub = fc.targets.find((t) => t.count >= 2);
|
|
9869
|
+
const self = fc.groups && fc.groups.selfHua && fc.groups.selfHua.length
|
|
9870
|
+
? '其中有的宫自己化出去又落回自己,容易表现为「想得多、落得少」。'
|
|
9871
|
+
: '';
|
|
9872
|
+
if (!hub) return `把命宫连同对宫、两个三合宫一起看,四股力飞出去没有挤到同一处,这几件事之间牵连不深。${self}`;
|
|
9873
|
+
return `把命宫连同对宫与两个三合宫一起看,${hub.incoming.length} 股力最后挤在「${String(hub.palace).replace(/宫$/, '')}」这件事上——这件事会把好几个方面的劲都吸过来。${self}`;
|
|
9874
|
+
}
|
|
9875
|
+
|
|
9466
9876
|
function bodyPlainOf(labels) {
|
|
9467
9877
|
const keyOf = (l) => Object.keys(PLAIN_BODY).find((k) => l === k || l.startsWith(`${k} `)) || '';
|
|
9468
9878
|
const primary = labels.find((l) => keyOf(l));
|
|
@@ -9525,6 +9935,7 @@ function buildAnswer(r, ask, ctx = {}) {
|
|
|
9525
9935
|
`${bureau.name ? `、${bureau.name}` : ''}${md ? `,命主${md}` : ''}` +
|
|
9526
9936
|
`${body.lands ? `,身宫落在「${body.lands}」——这张盘的重心在这件事上` : ''}。`,
|
|
9527
9937
|
plainFly,
|
|
9938
|
+
flyCompositePlain(r.flyComposite),
|
|
9528
9939
|
`具体到你问的这件事,重点看${where}。`,
|
|
9529
9940
|
].filter(Boolean).join('');
|
|
9530
9941
|
}
|
|
@@ -9539,7 +9950,7 @@ function buildAnswer(r, ask, ctx = {}) {
|
|
|
9539
9950
|
head + `先说结论:本卦是${s(ben.name, '—')}` +
|
|
9540
9951
|
`${ben.palace ? `(${ben.palace})` : ''}` +
|
|
9541
9952
|
`${moving.length ? `,第 ${moving.join('、')} 爻动,变为${s(bian.name, '—')}` : ',六爻安静没有动爻'}。` +
|
|
9542
|
-
`${plainBody}${usePlainOf(r.useGod)}${useStrengthPlain(r.useGodStrength)}`,
|
|
9953
|
+
`${plainBody}${usePlainOf(r.useGod)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
9543
9954
|
'断卦的落点在「世爻」(代表你)和「动爻」(事情的推动点),下面「看盘顺序」就按这个次序展开。',
|
|
9544
9955
|
].join('');
|
|
9545
9956
|
}
|
|
@@ -9556,9 +9967,13 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
9556
9967
|
const avoid = join(ys.avoid);
|
|
9557
9968
|
const strength = STRENGTH_PLAIN[st.level] || '力量偏中性';
|
|
9558
9969
|
const tiaohou = ys.tiaohou && ys.tiaohou.note ? `另外,${ys.tiaohou.note},所以「暖一点、亮一点」的环境通常更舒服。` : '';
|
|
9970
|
+
const sy = (r.liunian || []).find((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
9971
|
+
const syPlain = sy
|
|
9972
|
+
? `再往后看,${sy.year} 年${sy.ganzhi}是${sy.suiyun.signals.map((x) => x.type).join('、')}——传统上把它当作「变化感强一点」的提示,既不是好消息也不是坏消息,遇上时多留个心眼就好。`
|
|
9973
|
+
: '';
|
|
9559
9974
|
return `你的命局属于「${s(st.level, '中性')}」:${strength}。` +
|
|
9560
9975
|
`${favor ? `能补${favor}的环境(行业、方位、作息、相处的人)会让你省力;${avoid ? `而${avoid}偏重的场合容易空耗,能绕就绕。` : ''}` : ''}` +
|
|
9561
|
-
tiaohou;
|
|
9976
|
+
tiaohou + syPlain;
|
|
9562
9977
|
}
|
|
9563
9978
|
if (r.system === 'ziwei') {
|
|
9564
9979
|
const soul = r.soul || {};
|
|
@@ -9571,6 +9986,7 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
9571
9986
|
`紫微看的是「你与环境怎么互动」。命宫落${s(soul.branch, '—')}宫,说明你做事的第一反应是从这个宫位的气质出发` +
|
|
9572
9987
|
`${body.lands ? `;身宫在「${body.lands}」,意味着真正让你上心的,是${body.lands}这件事` : ''}。`,
|
|
9573
9988
|
plainFly,
|
|
9989
|
+
flyCompositePlain(r.flyComposite),
|
|
9574
9990
|
].filter(Boolean).join('');
|
|
9575
9991
|
}
|
|
9576
9992
|
if (r.system === 'liuyao') {
|
|
@@ -9580,7 +9996,7 @@ function buildPlain(r, ask, ctx = {}) {
|
|
|
9580
9996
|
const plainBody = bodyPlainOf(labels);
|
|
9581
9997
|
return `${s(ben.name, '这一卦')}讲的是一个「${moving.length ? '正在动、还会变' : '暂时不动、先看清'}」的局面——` +
|
|
9582
9998
|
`${moving.length ? '有动爻,说明事情还有转圜空间,不是死局。' : '六爻安静,说明当下更该观察而不是硬推。'}` +
|
|
9583
|
-
`${plainBody}${usePlainOf(r.useGod)}${useStrengthPlain(r.useGodStrength)}`;
|
|
9999
|
+
`${plainBody}${usePlainOf(r.useGod)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
9584
10000
|
}
|
|
9585
10001
|
return '';
|
|
9586
10002
|
}
|
|
@@ -9721,10 +10137,10 @@ const KNOWLEDGE = [
|
|
|
9721
10137
|
id: 'bazi-suiyun',
|
|
9722
10138
|
system: 'bazi', dims: ['overall', 'career'],
|
|
9723
10139
|
gist: '大运管十年基调,流年管当年触发。',
|
|
9724
|
-
detail: '
|
|
10140
|
+
detail: '大运像换了条路,流年像这条路上某一段的天气。岁运并临(当值大运与流年干支相同)、运年反吟(大运与流年天克地冲)、流年伏吟(流年与原局某柱干支相同)与流年反吟(流年与原局某柱天克地冲),是传统上标记「变动较大」的年份,属于提示而非断语。本插件逐年标出四类信号:当值大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列;只标干支重复与对冲,不折分数。',
|
|
9725
10141
|
source: '岁运并临、伏吟反吟见《三命通会》《渊海子平》',
|
|
9726
10142
|
status: 'variant',
|
|
9727
|
-
note: '
|
|
10143
|
+
note: '「岁运并临主大凶」是流传最广也最被滥用的说法,本插件只作变动提示,不断吉凶;大运与原局之间的伏吟反吟未逐年标注,四柱十神层面的引化也未叠入。',
|
|
9728
10144
|
},
|
|
9729
10145
|
{
|
|
9730
10146
|
id: 'bazi-liuqin',
|
|
@@ -9753,6 +10169,34 @@ const KNOWLEDGE = [
|
|
|
9753
10169
|
status: 'settled',
|
|
9754
10170
|
},
|
|
9755
10171
|
|
|
10172
|
+
{
|
|
10173
|
+
id: 'bazi-sanming-duizhao',
|
|
10174
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
10175
|
+
gist: '同一个格,子平真诠讲怎么用,三命通会讲怎么取。',
|
|
10176
|
+
detail: '两书不是谁替代谁:子平真诠以月令取用神、论顺逆成败,重「用」;三命通会按十神逐格立论,重「取」与「忌」。同看正官格,前者问财印护官、伤煞混杂,后者先说「止许一位,多则不宜」。本插件把两条并列,不合并成一句断语。',
|
|
10177
|
+
source: '《子平真诠》论正官等篇;《三命通会》卷五、卷六论十神',
|
|
10178
|
+
status: 'variant',
|
|
10179
|
+
note: '两书成书年代与流派不同,用语有出入;本插件照录通行本,不做校勘改字,也不替两家调和。',
|
|
10180
|
+
},
|
|
10181
|
+
{
|
|
10182
|
+
id: 'bazi-geju-chengbai',
|
|
10183
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
10184
|
+
gist: '格有成有败:成中带忌会打折,败中有救还能转成。',
|
|
10185
|
+
detail: '月令取到格只是起点。成格要看有没有带忌——官逢财又逢伤、官透而被合、财旺生官又逢伤,都会把成格打折;败格也看有没有救应——印来解伤、合来清煞、劫来解财,败中可转。所以判格不能只报一个格名。',
|
|
10186
|
+
source: '《子平真诠》九、论用神成败救应',
|
|
10187
|
+
status: 'variant',
|
|
10188
|
+
note: '各家对成格条件与带忌轻重的排序不同(有先看刑冲、有先看合化),本插件只把原文与成败方向并列摆出,不逐盘判成破。',
|
|
10189
|
+
},
|
|
10190
|
+
{
|
|
10191
|
+
id: 'bazi-huagi-bianhua',
|
|
10192
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
10193
|
+
gist: '月令用神会因合化而变:同一个起点,取用可以不同。',
|
|
10194
|
+
detail: '用神本从月令取,但月令藏干不一,透出的字不同、支会合局不同,取用就跟着变:丁生亥月本为正官,支全卯未化为印;己生申月本属伤官,藏庚透壬化为财。所以看到化气格,要回头核对月令与合局,不能只按本气定格。',
|
|
10195
|
+
source: '《子平真诠》十、论用神变化;化气条件各家另论',
|
|
10196
|
+
status: 'variant',
|
|
10197
|
+
note: '化气格成立条件各家宽严不一(是否要求月令为化神、日主是否允许有根),本插件只列条件、附原文,不据此断定化气已成。',
|
|
10198
|
+
},
|
|
10199
|
+
|
|
9756
10200
|
{
|
|
9757
10201
|
id: 'ziwei-sanfang',
|
|
9758
10202
|
system: 'ziwei', dims: ['overall', 'career'],
|
|
@@ -9812,7 +10256,16 @@ const KNOWLEDGE = [
|
|
|
9812
10256
|
detail: '生年四化是先天带的,飞星四化是宫位自己去找的:每一宫的宫干定出禄权科忌四颗星,那几颗星落在哪一宫,就是这一宫的力气往哪边使。所以同一个「化忌」,从命宫飞出去和从财帛飞出去,说的是两件事。',
|
|
9813
10257
|
source: '《紫微斗数全书》四化篇;中州派宫干四化传法',
|
|
9814
10258
|
status: 'variant',
|
|
9815
|
-
note: '
|
|
10259
|
+
note: '飞星派(如钦天四化)把宫干四化当主线,三合派只作辅助;庚干四化各派另有异说,本插件取中州派常用表。飞星串连与三方四正复合飞化现已给出,但未叠大限流年四化。',
|
|
10260
|
+
},
|
|
10261
|
+
{
|
|
10262
|
+
id: 'ziwei-sanfang-fei',
|
|
10263
|
+
system: 'ziwei', dims: ['overall', 'career'],
|
|
10264
|
+
gist: '三方四正一起飞,看四股力会到哪一宫。',
|
|
10265
|
+
detail: '单宫飞化只看本宫宫干把四化送去哪里;三方四正复合飞化把本宫、对宫与两个三合宫共四宫的宫干四化同时摊开,约 16 条,按落宫归堆,落到同一宫的就是会照。会在一处的化越多,那一宫被牵动的力道越集中;两忌以上会宫、禄忌同宫、三化以上会宫、宫干化出又落回本宫(自化),是这一层最常取的几种情形。',
|
|
10266
|
+
source: '《紫微斗数全书》四化篇;飞星派三方四正同飞说',
|
|
10267
|
+
status: 'variant',
|
|
10268
|
+
note: '飞星派对「三方四正一起飞」是否成立、会照要不要折成分数,各家口径不一;本插件只做落宫归堆与会照标记,不折分数,也未叠大限流年四化。',
|
|
9816
10269
|
},
|
|
9817
10270
|
{
|
|
9818
10271
|
id: 'ziwei-jichuanji',
|
|
@@ -9866,6 +10319,15 @@ const KNOWLEDGE = [
|
|
|
9866
10319
|
status: 'variant',
|
|
9867
10320
|
note: '月破、暗动、冲空三者各家取法不完全一致(有派别把日冲动爻也叫暗动,有派别只认旺相之爻暗动);本插件按「月建冲=月破、日冲静爻=暗动、日冲旬空=冲空」这一套给标签,并注明用了哪一支月建。',
|
|
9868
10321
|
},
|
|
10322
|
+
{
|
|
10323
|
+
id: 'liuyao-quanggu-shuai',
|
|
10324
|
+
system: 'liuyao', dims: ['overall', 'work'],
|
|
10325
|
+
gist: '全卦逐爻看月建,才看得出气聚在哪一头。',
|
|
10326
|
+
detail: '月建管这一段时令的旺衰、日辰管当天的扶克,落到全部六爻逐爻判定:每爻都出月令五态(旺相休囚死)与日辰五关系,并标月破、暗动、冲空。世爻、应爻、动爻与旬空另标,五态分布能看出气是聚在世应还是散在旁爻——用神只是其中一处落点,不看全卦容易把一处当全局。',
|
|
10327
|
+
source: '《增删卜易》月建章、日辰章;《卜筮正宗》六爻旺衰论',
|
|
10328
|
+
status: 'variant',
|
|
10329
|
+
note: '各家对月破、暗动、冲空的取法不完全一致,是否给六爻折力重(分数)分歧更大;本插件只给状态标签与五态分布,不折分数。',
|
|
10330
|
+
},
|
|
9869
10331
|
{
|
|
9870
10332
|
id: 'liuyao-yingqi',
|
|
9871
10333
|
system: 'liuyao', dims: ['overall', 'career'],
|
|
@@ -9931,7 +10393,7 @@ const KNOWLEDGE = [
|
|
|
9931
10393
|
id: 'liuyao-jintui-yong',
|
|
9932
10394
|
system: 'liuyao', dims: ['overall', 'work'],
|
|
9933
10395
|
gist: '化进化退要看是用神还是忌神,还要叠月建日辰。',
|
|
9934
|
-
detail: '
|
|
10396
|
+
detail: '进神退神本身只说明这一爻的向外趋势:用神化进为得力,忌神化进则为患加剧;用神化退是力衰,忌神化退反而是解脱。传统还要看它在本月令衰旺、有没有日辰生扶,空亡或受克时进者未必能进。本插件把进退与爻位标出来,再按月建五态给一档力重——得令则进得动、退得慢,失令则进得虚、退得实,月破压过一切;只给档位,不折成加权分数,吉凶仍落在用神与忌神那一层判。',
|
|
9935
10397
|
source: '《增删卜易》进神退神章、用神章',
|
|
9936
10398
|
status: 'variant',
|
|
9937
10399
|
note: '土之进退次序各家说法不完全一致,有以丑→辰→未→戌为进、也有只取辰戌丑未相对者;本插件按丑辰未戌成环处理,并用《增删卜易》卦例中「未土化戌土为进」「戌土化未土为退」对拍。',
|
|
@@ -10356,6 +10818,19 @@ function baziInterpret(r) {
|
|
|
10356
10818
|
return `${jiaoLine}当前大运:${pick(cur, 'ganzhi', '—')}(${curSpan})。后续两步:${nextTwo}。\n近五年流年:${years || '—'}。\n读法:大运管"这十年的大环境",流年管"今年的具体天气";两者打架时,以能否动到用神为准。`;
|
|
10357
10819
|
})(),
|
|
10358
10820
|
},
|
|
10821
|
+
(() => {
|
|
10822
|
+
const hits = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
10823
|
+
return {
|
|
10824
|
+
key: 'suiyun', label: '岁运提示',
|
|
10825
|
+
text: hits.length
|
|
10826
|
+
? hits.map((l) => {
|
|
10827
|
+
const stem = (l.suiyun.dayun || []).map((d) => `第${d.step}步${d.ganzhi}`).join('、');
|
|
10828
|
+
return `${l.year} ${l.ganzhi}(${stem || '未到起运'}):${l.suiyun.signals.map((s) => s.detail).join(';')}`;
|
|
10829
|
+
}).join('\n') +
|
|
10830
|
+
'\n读法:岁运并临、运年反吟与流年伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。'
|
|
10831
|
+
: '近十年没有岁运并临、运年反吟或流年伏吟/反吟。「岁运并临主大凶」这类说法流传很广,本插件只把它当变动提示,没有命中就不作额外解读。',
|
|
10832
|
+
};
|
|
10833
|
+
})(),
|
|
10359
10834
|
{
|
|
10360
10835
|
key: 'checks', label: '交叉校验',
|
|
10361
10836
|
text: (() => {
|
|
@@ -10685,6 +11160,38 @@ function ziweiInterpret(r) {
|
|
|
10685
11160
|
}
|
|
10686
11161
|
}
|
|
10687
11162
|
|
|
11163
|
+
{
|
|
11164
|
+
const fc = r.flyComposite;
|
|
11165
|
+
const word = (p) => `${p}${String(p).endsWith('宫') ? '' : '宫'}`;
|
|
11166
|
+
if (fc && Array.isArray(fc.sources) && fc.sources.length >= 2) {
|
|
11167
|
+
const hubs = fc.targets.filter((t) => t.count >= 2);
|
|
11168
|
+
const hubText = hubs.length
|
|
11169
|
+
? hubs.slice(0, 5).map((t) => `${word(t.palace)}收了 ${t.incoming.map((x) => `${word(x.from)}化${x.type}${x.star}`).join('、')}`).join(';')
|
|
11170
|
+
: '四宫化出去之后没有落在同一宫,力是散开的';
|
|
11171
|
+
const readings = [];
|
|
11172
|
+
if (fc.groups.doubleJi.length) {
|
|
11173
|
+
readings.push(`${fc.groups.doubleJi.map((t) => word(t.palace)).join('、')}收到两个以上的忌——同一件事被反复牵动,传统看作那一宫的事务容易拖着不放`);
|
|
11174
|
+
}
|
|
11175
|
+
if (fc.groups.luJi.length) {
|
|
11176
|
+
readings.push(`${fc.groups.luJi.map((t) => word(t.palace)).join('、')}禄忌同宫:好处与在意的地方绑在一起,越想要的东西越容易反复`);
|
|
11177
|
+
}
|
|
11178
|
+
if (fc.groups.tripleHua.length) {
|
|
11179
|
+
readings.push(`${fc.groups.tripleHua.map((t) => word(t.palace)).join('、')}三化以上会宫:那一宫同时被几种力牵住,常常是这张盘最忙的地方`);
|
|
11180
|
+
}
|
|
11181
|
+
if (fc.groups.selfHua.length) {
|
|
11182
|
+
readings.push(`${fc.groups.selfHua.map((t) => word(t.palace)).join('、')}自化:宫干化出去又落回自己,表现为力气绕回原处`);
|
|
11183
|
+
}
|
|
11184
|
+
sections.push({
|
|
11185
|
+
key: 'flyComposite',
|
|
11186
|
+
label: '三方四正飞化',
|
|
11187
|
+
text: `上一节是命宫一条线往下追;这一节把命宫连同对宫与两个三合宫(${fc.sanfang.join('、')})一起飞:四宫各化禄权科忌,共 16 条飞化(星未上盘的只记星不记落宫),按落宫归堆。` +
|
|
11188
|
+
`${hubText}。` +
|
|
11189
|
+
`${readings.length ? `${readings.join(';')}。` : ''}` +
|
|
11190
|
+
`读法上,会在一处的化越多,那一宫被牵动的力道越集中;落单的飞化只说明方向,不单独取象。这一层同样只描会照与方向,不折吉凶,也没有叠大限与流年四化。`,
|
|
11191
|
+
});
|
|
11192
|
+
}
|
|
11193
|
+
}
|
|
11194
|
+
|
|
10688
11195
|
if (r.flow) {
|
|
10689
11196
|
const f = r.flow;
|
|
10690
11197
|
const at = (p) => `${p.ganzhi || '—'}${p.palace ? `落${p.palace}` : ''}`;
|
|
@@ -10843,6 +11350,10 @@ function liuyaoInterpret(r, ask) {
|
|
|
10843
11350
|
const tuiYao = (bd.jinTui || []).filter((x) => x.type === '退');
|
|
10844
11351
|
if (jinYao.length) bodyText.push(`化进神(第${jinYao.map((x) => x.position).join('、')}爻:${jinYao.map((x) => `${x.from}→${x.to}`).join('、')}):变出的地支与本爻同五行、且顺着往前一步,传统读作「进」——这一爻代表的人或事有后劲,往前走比退回去顺。`);
|
|
10845
11352
|
if (tuiYao.length) bodyText.push(`化退神(第${tuiYao.map((x) => x.position).join('、')}爻:${tuiYao.map((x) => `${x.from}→${x.to}`).join('、')}):变出的地支与本爻同五行、却倒着退一步,传统读作「退」——这一爻代表的人或事渐渐退气,别按原来的势头去推。`);
|
|
11353
|
+
const jp = r.jinTuiPower;
|
|
11354
|
+
if (jp && Array.isArray(jp.lines) && jp.lines.length) {
|
|
11355
|
+
bodyText.push(`进退的力重(放回月建日辰看):${jp.lines.map((l) => `第${l.position}爻${l.say}`).join(';')}。进退只管方向,走不走得动看时令托不托着;用神化进为喜,忌神化进反而是忌。`);
|
|
11356
|
+
}
|
|
10846
11357
|
bodyText.push('这些标签只说明卦体的动势,不直接定吉凶:同一支六冲,近病问的是速愈、久病问的是凶险;同一爻化进,也得看用神旺不旺、有没有月建日辰托着。');
|
|
10847
11358
|
sections.push({ key: 'body', label: '卦体关系', text: bodyText.join('\n') });
|
|
10848
11359
|
}
|
|
@@ -10899,9 +11410,35 @@ function liuyaoInterpret(r, ask) {
|
|
|
10899
11410
|
sections.push({ key: 'yongshen', label: '用神落位与卦体', text: useText.join('\n') });
|
|
10900
11411
|
}
|
|
10901
11412
|
|
|
11413
|
+
{
|
|
11414
|
+
const hs = r.hexStrength;
|
|
11415
|
+
if (hs && Array.isArray(hs.lines) && hs.lines.length) {
|
|
11416
|
+
const head = hs.month && hs.month.branch
|
|
11417
|
+
? `月建 ${hs.month.branch}(${hs.month.element})`
|
|
11418
|
+
: '没有月建(未给起卦时间)';
|
|
11419
|
+
const day = hs.day && hs.day.branch ? `日辰 ${hs.day.branch}(${hs.day.element})` : '日辰 —';
|
|
11420
|
+
const rows = hs.lines.map((l) => {
|
|
11421
|
+
const who = l.shi ? '(世)' : l.ying ? '(应)' : '';
|
|
11422
|
+
const flags = `${l.moving ? '·动' : ''}${l.kong ? '·旬空' : ''}`;
|
|
11423
|
+
return `${l.position}爻${l.liuqin ? l.liuqin : ''}${l.branch}${l.element}${who}${flags}:月建${l.monthState},${l.dayRelation}${l.chongTag ? `,${l.chongTag}` : ''}`;
|
|
11424
|
+
});
|
|
11425
|
+
const order = ['旺', '相', '休', '囚', '死'];
|
|
11426
|
+
const dist = order.filter((k) => hs.counts[k]).map((k) => `${k}${hs.counts[k]}`).join('、');
|
|
11427
|
+
const shi = hs.shi ? `世爻在${hs.shi.position}爻(月建${hs.shi.monthState},${hs.shi.dayRelation})` : '';
|
|
11428
|
+
const ying = hs.ying ? `应爻在${hs.ying.position}爻(月建${hs.ying.monthState},${hs.ying.dayRelation})` : '';
|
|
11429
|
+
sections.push({
|
|
11430
|
+
key: 'hexStrength',
|
|
11431
|
+
label: '全卦逐爻旺衰',
|
|
11432
|
+
text: `整张卦按${head}、${day}逐爻过一遍:${rows.join(';')}。五态分布:${dist}——${[shi, ying].filter(Boolean).join(',')}。` +
|
|
11433
|
+
`气旺的爻对应的事推进起来省力,气弱或遭月破的爻对应的事宜缓;这只是六爻全貌,用神那几爻的细节仍以上一节为准,两处不冲突时再看动爻把哪一头带动。` +
|
|
11434
|
+
`判定与用神旺衰同一套(月令五态、日辰五关系、月破/暗动/冲空),只报状态,不折成分数。`,
|
|
11435
|
+
});
|
|
11436
|
+
}
|
|
11437
|
+
}
|
|
11438
|
+
|
|
10902
11439
|
sections.push({
|
|
10903
11440
|
key: 'limits', label: '未纳入',
|
|
10904
|
-
text: '
|
|
11441
|
+
text: '本卦没有计算:用神两现时该取哪一爻的权重、伏神出伏的应期。化进/化退的力重只按月建五态给「得令/失令」这类档位,不折成加权分数,也不叠动变连环;这些都会改变"旺不旺"的判断,所以这里只给取象与方向。',
|
|
10905
11442
|
});
|
|
10906
11443
|
|
|
10907
11444
|
const dimensions = [
|
|
@@ -11592,7 +12129,54 @@ function followup(r, question) {
|
|
|
11592
12129
|
return { question: q, ...result };
|
|
11593
12130
|
}
|
|
11594
12131
|
|
|
11595
|
-
|
|
12132
|
+
const SYSTEM_LABEL = {
|
|
12133
|
+
bazi: '八字(四柱)',
|
|
12134
|
+
ziwei: '紫微斗数',
|
|
12135
|
+
liuyao: '六爻',
|
|
12136
|
+
meihua: '梅花易数',
|
|
12137
|
+
daliuren: '大六壬',
|
|
12138
|
+
qimen: '奇门遁甲',
|
|
12139
|
+
tarot: '塔罗',
|
|
12140
|
+
hepan: '合盘',
|
|
12141
|
+
chenggu: '称骨',
|
|
12142
|
+
almanac: '黄历',
|
|
12143
|
+
zeri: '择日',
|
|
12144
|
+
star: '星座',
|
|
12145
|
+
numerology: '生命数字',
|
|
12146
|
+
mbti: '十六型人格',
|
|
12147
|
+
trend: '人生 K 线',
|
|
12148
|
+
fengshui: '风水',
|
|
12149
|
+
name: '起名',
|
|
12150
|
+
convert: '公农历互转',
|
|
12151
|
+
};
|
|
12152
|
+
|
|
12153
|
+
function askPrompt(r, opts = {}) {
|
|
12154
|
+
const label = SYSTEM_LABEL[r && r.system] || (r && r.system) || '未知体系';
|
|
12155
|
+
const asked = String((opts && opts.question) || '').trim();
|
|
12156
|
+
const question = asked || '请先总览这张盘,指出最值得注意的一两处,并说明各自的依据。';
|
|
12157
|
+
const limit = Number.isFinite(opts && opts.maxChars) && opts.maxChars >= 400 ? opts.maxChars : 3000;
|
|
12158
|
+
const raw = String((r && r.summary) || '').trim();
|
|
12159
|
+
const truncated = raw.length > limit;
|
|
12160
|
+
const summary = truncated ? `${raw.slice(0, limit)}…(摘要已截断)` : raw;
|
|
12161
|
+
|
|
12162
|
+
const lines = [
|
|
12163
|
+
'【命理追问】下面这张盘是命理插件刚排好的,请就着它回答我的问题;不用重新排盘,盘面字段已经够用。',
|
|
12164
|
+
`体系:${label}`,
|
|
12165
|
+
`所问:${question}`,
|
|
12166
|
+
'',
|
|
12167
|
+
'——盘面摘要——',
|
|
12168
|
+
summary || '(这张盘没有摘要字段,请先让我重新排一次。)',
|
|
12169
|
+
'',
|
|
12170
|
+
'——回答要求——',
|
|
12171
|
+
'1) 尽量引用到具体的柱、宫或爻,再说判断,别只给结论;',
|
|
12172
|
+
'2) 盘面里没有依据的地方直接说「这盘里看不出来」,不要补外部假设;',
|
|
12173
|
+
'3) 用概率和倾向的说法,别给绝对化的断言,也别把传统说法当成事实。',
|
|
12174
|
+
];
|
|
12175
|
+
const text = lines.join('\n');
|
|
12176
|
+
return { text, question, system: (r && r.system) || '', label, chars: text.length, truncated };
|
|
12177
|
+
}
|
|
12178
|
+
|
|
12179
|
+
return { followup, askPrompt };
|
|
11596
12180
|
})();
|
|
11597
12181
|
|
|
11598
12182
|
__mods.crosscheck = (function () {
|
|
@@ -11882,7 +12466,7 @@ return { matchEvent, rectifyBirth, RECTIFY_KINDS };
|
|
|
11882
12466
|
|
|
11883
12467
|
__mods.index = (function () {
|
|
11884
12468
|
const { buildBazi } = __mods.bazi;
|
|
11885
|
-
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength } = __mods.liuyao;
|
|
12469
|
+
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, hexagramStrength, jinTuiPower } = __mods.liuyao;
|
|
11886
12470
|
const { buildZiwei, BRIGHTNESS, flowOf, asOfParts } = __mods.ziwei;
|
|
11887
12471
|
const { drawTarot } = __mods.tarot;
|
|
11888
12472
|
const { buildMeihua } = __mods.meihua;
|
|
@@ -11894,7 +12478,7 @@ const { geocodeAddress, resolveAddress } = __mods.geo;
|
|
|
11894
12478
|
const { toJDN, ganzhiName, dayGanzhiIndex } = __mods.calendar;
|
|
11895
12479
|
const { randomOf, isSeed } = __mods.random;
|
|
11896
12480
|
const { interpret, DIRECTIONS, DIRECTION_DEFAULT } = __mods.interpret;
|
|
11897
|
-
const { followup } = __mods.followup;
|
|
12481
|
+
const { followup, askPrompt } = __mods.followup;
|
|
11898
12482
|
const { crossCheck, crossText } = __mods.crosscheck;
|
|
11899
12483
|
const { pastSignals, verifyFit } = __mods.verify;
|
|
11900
12484
|
const { rectifyBirth } = __mods.rectify;
|
|
@@ -12007,6 +12591,13 @@ function baziText(r) {
|
|
|
12007
12591
|
`大运:${r.dayun.rule}(${r.dayun.direction}),${r.dayun.startAge.years}岁${r.dayun.startAge.months}个月起运${jiao}`,
|
|
12008
12592
|
` ${dayun}`,
|
|
12009
12593
|
`流年:${r.liunian.slice(0, 10).map((l) => `${l.year}${l.ganzhi}(${l.stemTenGod})${l.luck ? `·${l.luck.tier}` : ''}`).join(' ')}`,
|
|
12594
|
+
(() => {
|
|
12595
|
+
const hits = r.liunian.filter((l) => l.suiyun && l.suiyun.signals && l.suiyun.signals.length);
|
|
12596
|
+
if (!hits.length) return '岁运提示:近十年无岁运并临、运年反吟或流年伏吟/反吟(只标干支,不判吉凶)';
|
|
12597
|
+
const label = (s) => `${s.type}${s.type.startsWith('流年') && s.target ? `(${s.target})` : ''}`;
|
|
12598
|
+
return '岁运提示(只标干支变动,不判吉凶):' + hits
|
|
12599
|
+
.map((l) => `${l.year}${l.ganzhi} ${l.suiyun.signals.map(label).join('/')}`).join(';');
|
|
12600
|
+
})(),
|
|
12010
12601
|
'(格局、用神、行运吉凶为扶抑+简化调候的量化提示,非断语。)',
|
|
12011
12602
|
].join('\n') + near;
|
|
12012
12603
|
}
|
|
@@ -12044,6 +12635,17 @@ function ziweiText(r) {
|
|
|
12044
12635
|
const text = ['禄', '权', '科', '忌'].map(one).filter(Boolean).join(' ');
|
|
12045
12636
|
return text ? `【命宫飞星】${text}` : '';
|
|
12046
12637
|
})();
|
|
12638
|
+
const flyCompositeLine = (() => {
|
|
12639
|
+
const fc = r.flyComposite;
|
|
12640
|
+
if (!fc || !Array.isArray(fc.sources) || !fc.sources.length) return '';
|
|
12641
|
+
const groups = fc.labels.length ? fc.labels.join(' · ') : '无同宫会聚';
|
|
12642
|
+
const detail = ['禄', '权', '科', '忌'].map((t) => {
|
|
12643
|
+
const list = ((fc.byType && fc.byType[t]) || []).filter((x) => !x.self);
|
|
12644
|
+
const tos = [...new Set(list.map((x) => String(x.to).replace(/宫$/, '')))];
|
|
12645
|
+
return tos.length ? `${t}→${tos.join('/')}` : '';
|
|
12646
|
+
}).filter(Boolean).join(' ');
|
|
12647
|
+
return `【三方四正飞化】${fc.sanfang.join('·')}:${groups}${detail ? ` ${detail}` : ''}`;
|
|
12648
|
+
})();
|
|
12047
12649
|
return [
|
|
12048
12650
|
`【农历】${lunarText}(月首 ${r.lunar.monthStart}) 时支:${r.hourBranch} 年干支:${r.yearGanzhi}`,
|
|
12049
12651
|
`【时刻】${r.solarTime ? `${r.solarTime.civilText} → 真太阳时 ${r.solarTime.trueSolarText}${r.input.geo ? '(' + r.input.geo.note + ')' : ''}` : ''}`,
|
|
@@ -12053,6 +12655,7 @@ function ziweiText(r) {
|
|
|
12053
12655
|
`【昌曲】文昌${r.changqu.wenchang.branch}(${r.changqu.wenchang.palace}${r.changqu.wenchang.mutagen ? '·化' + r.changqu.wenchang.mutagen : ''}) 文曲${r.changqu.wenqu.branch}(${r.changqu.wenqu.palace}${r.changqu.wenqu.mutagen ? '·化' + r.changqu.wenqu.mutagen : ''})`,
|
|
12054
12656
|
` ${r.changqu.relation} 入命三方:${r.changqu.inSoulSanfang ? '是' : '否'} 吸收面:${r.changqu.absorb.label}(${r.changqu.absorb.reason})`,
|
|
12055
12657
|
flyLine,
|
|
12658
|
+
flyCompositeLine,
|
|
12056
12659
|
'十二宫:',
|
|
12057
12660
|
...rows,
|
|
12058
12661
|
'大限(按起运年龄排序,前 8 限,宫干四化落宫):',
|
|
@@ -12060,7 +12663,7 @@ function ziweiText(r) {
|
|
|
12060
12663
|
'流年(前 6 年,完整 12 年在结构化数据里):',
|
|
12061
12664
|
...liunian,
|
|
12062
12665
|
`【格局】${patterns}`,
|
|
12063
|
-
r.patternSummary ? `【结构统计】吉格 ${r.patternSummary.good.length}、忌格 ${r.patternSummary.bad.length};${r.patternSummary.note}` : '',
|
|
12666
|
+
r.patternSummary ? `【结构统计】吉格 ${r.patternSummary.good.length}、中性 ${r.patternSummary.neutral.length}、忌格 ${r.patternSummary.bad.length};${r.patternSummary.note}` : '',
|
|
12064
12667
|
r.lunar.note ? `注:${r.lunar.note}` : '',
|
|
12065
12668
|
].filter(Boolean).join('\n');
|
|
12066
12669
|
}
|
|
@@ -12205,6 +12808,17 @@ function liuyaoText(r) {
|
|
|
12205
12808
|
} else {
|
|
12206
12809
|
out.push('用神:未取(未指明所问之事;用「询问方向」指定后即按六亲取用)');
|
|
12207
12810
|
}
|
|
12811
|
+
const hexSt = r.hexStrength;
|
|
12812
|
+
if (hexSt && Array.isArray(hexSt.labels) && hexSt.labels.length) {
|
|
12813
|
+
const m = hexSt.month && hexSt.month.branch
|
|
12814
|
+
? `月建 ${hexSt.month.branch}(${hexSt.month.element}) `
|
|
12815
|
+
: '无月建(未给起卦时间) ';
|
|
12816
|
+
out.push(`全卦旺衰:${m}${hexSt.labels.join(' · ')}`);
|
|
12817
|
+
}
|
|
12818
|
+
const jt = r.jinTuiPower;
|
|
12819
|
+
if (jt && Array.isArray(jt.lines) && jt.lines.length) {
|
|
12820
|
+
out.push(`进退力重:${jt.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type}·${l.verdict}`).join(' · ')}`);
|
|
12821
|
+
}
|
|
12208
12822
|
return out.filter(Boolean).join('\n');
|
|
12209
12823
|
}
|
|
12210
12824
|
|
|
@@ -12485,17 +13099,21 @@ function computeRaw(args = {}) {
|
|
|
12485
13099
|
throw fail('E_LINES', e && e.message ? e.message : e);
|
|
12486
13100
|
}
|
|
12487
13101
|
const ug = yongshenOf(result, { direction: args.direction, gender: args.gender });
|
|
12488
|
-
if (ug.liuqin)
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
monthBranch = null;
|
|
12497
|
-
}
|
|
13102
|
+
if (ug.liuqin) result.useGod = ug;
|
|
13103
|
+
let monthBranch = null;
|
|
13104
|
+
if (stamp) {
|
|
13105
|
+
try {
|
|
13106
|
+
const snap = buildSnapshot({ year: stamp.year, month: stamp.month, day: stamp.day, hour: stamp.hour, minute: stamp.minute });
|
|
13107
|
+
monthBranch = (snap.monthGanZhi || '')[1] || null;
|
|
13108
|
+
} catch {
|
|
13109
|
+
monthBranch = null;
|
|
12498
13110
|
}
|
|
13111
|
+
}
|
|
13112
|
+
const hexStrength = hexagramStrength(result, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
13113
|
+
if (hexStrength) result.hexStrength = hexStrength;
|
|
13114
|
+
const jtPower = jinTuiPower(result, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
13115
|
+
if (jtPower) result.jinTuiPower = jtPower;
|
|
13116
|
+
if (ug.liuqin) {
|
|
12499
13117
|
const strength = yongshenStrength(result, ug, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
12500
13118
|
if (strength) result.useGodStrength = strength;
|
|
12501
13119
|
}
|
|
@@ -12881,11 +13499,12 @@ function renderText(result) {
|
|
|
12881
13499
|
return parts.filter(Boolean).join('\n\n');
|
|
12882
13500
|
}
|
|
12883
13501
|
|
|
12884
|
-
return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAddress, resolveAddress, buildBazi, buildLiuyao, tossLines, followup, pastSignals, verifyFit, rectifyBirth, crossCheck, crossText, buildAlmanac, buildZeri, buildChenggu, buildXiaoliuren, buildStar, buildNumerology, buildConvert, buildTrend, buildFengshui, buildName, parseDateTime, compute, interpretText, renderText };
|
|
13502
|
+
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 };
|
|
12885
13503
|
})();
|
|
12886
13504
|
|
|
12887
13505
|
const Engine = __mods.index;
|
|
12888
13506
|
window.Engine = Engine;
|
|
13507
|
+
window.__MP_VER = '0.38.2';
|
|
12889
13508
|
(function () {
|
|
12890
13509
|
const NEED_ASK = { liuyao: true, meihua: true, daliuren: true, tarot: true };
|
|
12891
13510
|
const needAsk = (kind) => !!NEED_ASK[kind];
|
|
@@ -12916,25 +13535,28 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
12916
13535
|
|
|
12917
13536
|
(function () {
|
|
12918
13537
|
const CSS = `
|
|
12919
|
-
.pp,.mp-it{--ink:#1b1b1b;--ink2:#3f3a33;--muted:#6f6a60;--label:#8a8378;--faint:#a9a296;
|
|
13538
|
+
.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;
|
|
12920
13539
|
--line:#c8c1b2;--dimline:#b9b2a4;--hair:#e9e2d3;
|
|
12921
13540
|
--bg:#f6f1e6;--card:#fffdf8;--band:#fbf7ee;--hover:#f3ede1;--hover2:#ece5d6;
|
|
12922
13541
|
--tri:#f3e8cd;--soul:#fae4dc;--sel:#fceee7;--link:#f9ece0;
|
|
12923
13542
|
--red:#b3261e;--red-rgb:179,38,30;--lu:#1f6f3f;--lu-rgb:31,111,63;
|
|
12924
13543
|
--quan:#8a5a00;--quan-rgb:138,90,0;--ke:#1f4e79;--ke-rgb:31,78,121;--ji:#b3261e;
|
|
12925
13544
|
--br-good:#4c7a5c;--br-bad:#9c5b56;--on-accent:#fff;--wx-metal:#8a6b1f;
|
|
12926
|
-
--tg-bi:#4a6f8a;--tg-shi:#4c7a5c;--tg-cai:#8a6b1f;--tg-guan:#9c5b56;--tg-yin:#6d5f83
|
|
13545
|
+
--tg-bi:#4a6f8a;--tg-shi:#4c7a5c;--tg-cai:#8a6b1f;--tg-guan:#9c5b56;--tg-yin:#6d5f83;
|
|
13546
|
+
--ink3:#8a8378;--fx:"Kaiti SC",KaiTi,"STKaiti","Songti SC",serif;--sans:system-ui,-apple-system,"Microsoft YaHei",sans-serif;--kai:"Kaiti SC",KaiTi,"STKaiti",serif;
|
|
13547
|
+
--shadow:0 1px 2px rgba(35,28,18,.05),0 18px 40px -30px rgba(35,28,18,.42)}
|
|
12927
13548
|
.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;
|
|
12928
|
-
container-type:inline-size}
|
|
13549
|
+
border-radius:12px;overflow:hidden;box-shadow:var(--shadow);container-type:inline-size}
|
|
12929
13550
|
@media screen and (prefers-color-scheme:dark){
|
|
12930
|
-
.pp,.mp-it{--ink:#eae5d9;--ink2:#d5cfc2;--muted:#aca598;--label:#a49c8e;--faint:#928b7e;
|
|
13551
|
+
.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;
|
|
12931
13552
|
--line:#514a3e;--dimline:#5f5849;--hair:#2f2b23;
|
|
12932
13553
|
--bg:#12110c;--card:#211f18;--band:#282419;--hover:#2e2a1f;--hover2:#383322;
|
|
12933
13554
|
--tri:#332913;--soul:#3a231c;--sel:#43271f;--link:#33241c;
|
|
12934
13555
|
--red:#f08569;--red-rgb:240,133,105;--lu:#74c795;--lu-rgb:116,199,149;
|
|
12935
13556
|
--quan:#e2a95c;--quan-rgb:226,169,92;--ke:#86bcea;--ke-rgb:134,188,234;--ji:#f08569;
|
|
12936
13557
|
--br-good:#79c79a;--br-bad:#e09a8c;--on-accent:#14130f;--wx-metal:#dcb273;
|
|
12937
|
-
--tg-bi:#93b7cf;--tg-shi:#8fbb9d;--tg-cai:#d3ae62;--tg-guan:#d98d84;--tg-yin:#b4a4d0
|
|
13558
|
+
--tg-bi:#93b7cf;--tg-shi:#8fbb9d;--tg-cai:#d3ae62;--tg-guan:#d98d84;--tg-yin:#b4a4d0;
|
|
13559
|
+
--ink3:#8b8478;--shadow:0 1px 2px rgba(0,0,0,.5),0 18px 40px -30px rgba(0,0,0,.9)}
|
|
12938
13560
|
}
|
|
12939
13561
|
.pp *{box-sizing:border-box}
|
|
12940
13562
|
.pp-grid{display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(4,minmax(150px,auto));gap:0;border:1px solid var(--line)}
|
|
@@ -13024,6 +13646,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13024
13646
|
|
|
13025
13647
|
.pp-cell{cursor:pointer;transition:background .14s ease,box-shadow .14s ease;outline:none}
|
|
13026
13648
|
.pp-cell:hover{background:var(--hover)}
|
|
13649
|
+
.pp-cell:focus-visible{box-shadow:inset 0 0 0 2px var(--red)}
|
|
13027
13650
|
.pp-cell.pp-sel{background:var(--sel);box-shadow:inset 0 0 0 2px rgba(var(--red-rgb),.5)}
|
|
13028
13651
|
.pp-cell.pp-link{background:var(--link);box-shadow:inset 0 0 0 1.5px rgba(var(--red-rgb),.22)}
|
|
13029
13652
|
.pp-detail{display:none;border-top:1px solid var(--line);background:var(--card);padding:11px 14px 13px;font-family:system-ui,sans-serif}
|
|
@@ -13079,7 +13702,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13079
13702
|
.mp-trig{display:inline-block;width:14px;height:10px;vertical-align:-1px;margin-right:4px;color:currentColor}
|
|
13080
13703
|
|
|
13081
13704
|
.mp-hy-wrap{display:flex;gap:22px;flex-wrap:wrap;align-items:flex-start}
|
|
13082
|
-
.mp-hy-box{border:1px solid var(--line);background:var(--card);padding:12px 16px 14px;min-width:250px}
|
|
13705
|
+
.mp-hy-box{border:1px solid var(--line);border-radius:10px;background:var(--card);padding:12px 16px 14px;min-width:250px}
|
|
13083
13706
|
.mp-hy-h{display:flex;align-items:baseline;gap:8px;margin-bottom:10px;font-family:system-ui,sans-serif}
|
|
13084
13707
|
.mp-hy-h b{color:var(--red);font-size:14px}
|
|
13085
13708
|
.mp-hy-h span{color:var(--muted);font-size:12px}
|
|
@@ -13098,7 +13721,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13098
13721
|
.mp-mh{padding:16px}
|
|
13099
13722
|
.mp-mh-head{font-size:13px;color:var(--muted);margin-bottom:12px}
|
|
13100
13723
|
.mp-mh-main{display:flex;gap:18px;flex-wrap:wrap;align-items:flex-start}
|
|
13101
|
-
.mp-hexbox{border:1px solid var(--line);background:var(--card);padding:12px 15px 13px}
|
|
13724
|
+
.mp-hexbox{border:1px solid var(--line);border-radius:10px;background:var(--card);padding:12px 15px 13px}
|
|
13102
13725
|
.mp-hexbox.hb-mini{min-width:118px}
|
|
13103
13726
|
.mp-hexbox .hb-h{display:flex;justify-content:space-between;gap:10px;font-size:12px;letter-spacing:.14em;color:var(--muted);font-family:system-ui,sans-serif;margin-bottom:5px}
|
|
13104
13727
|
.mp-hexbox .hb-n{font-size:17px;font-weight:700;color:var(--red);margin-bottom:8px;letter-spacing:.04em}
|
|
@@ -13268,7 +13891,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13268
13891
|
.mp-tt{padding:16px}
|
|
13269
13892
|
.mp-tt-head{font-size:12.5px;color:var(--muted);margin-bottom:12px;letter-spacing:.04em}
|
|
13270
13893
|
.mp-tt-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(172px,1fr));gap:10px}
|
|
13271
|
-
.mp-tt-card{border:1px solid var(--line);background:var(--card);padding:13px 14px;display:flex;flex-direction:column;gap:7px;min-height:168px}
|
|
13894
|
+
.mp-tt-card{border:1px solid var(--line);border-radius:10px;background:var(--card);padding:13px 14px;display:flex;flex-direction:column;gap:7px;min-height:168px}
|
|
13272
13895
|
.mp-tt-card.tt-rev{background:var(--band);border-style:dashed}
|
|
13273
13896
|
.mp-tt-pos{font-size:12px;color:var(--muted);letter-spacing:.14em}
|
|
13274
13897
|
.mp-tt-name{font-size:19px;font-weight:700;color:var(--red);letter-spacing:.04em}
|
|
@@ -13288,11 +13911,12 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13288
13911
|
.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}
|
|
13289
13912
|
.mp-tt-ta:focus{border-color:var(--red)}
|
|
13290
13913
|
|
|
13291
|
-
.mp-it{margin-top:14px;border:1px solid var(--line);background:var(--bg);color:var(--ink);
|
|
13914
|
+
.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);
|
|
13292
13915
|
font-family:"Songti SC","SimSun","Microsoft YaHei",serif;font-size:13px;line-height:1.75}
|
|
13293
13916
|
.mp-it *{box-sizing:border-box}
|
|
13294
13917
|
.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}
|
|
13295
13918
|
.mp-it-head:hover{background:var(--band)}
|
|
13919
|
+
.mp-it-head:focus-visible{outline:2px solid var(--red);outline-offset:-3px}
|
|
13296
13920
|
.mp-it-arrow{flex:none;font-size:12px;line-height:1;color:var(--red);transition:transform .16s ease}
|
|
13297
13921
|
.mp-it.folded .mp-it-arrow{transform:rotate(-90deg)}
|
|
13298
13922
|
.mp-it.folded .mp-it-wrap{display:none}
|
|
@@ -13367,7 +13991,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13367
13991
|
.mp-tables{border-top:1px solid var(--line);padding:12px 16px 4px;background:var(--card)}
|
|
13368
13992
|
.mp-table-wrap{margin-bottom:12px}
|
|
13369
13993
|
.mp-table-h{font-size:12px;font-weight:700;letter-spacing:.1em;color:var(--lu);margin-bottom:5px;font-family:system-ui,sans-serif}
|
|
13370
|
-
.mp-table-scroll{overflow-x:auto;border:1px solid var(--line);border-radius:
|
|
13994
|
+
.mp-table-scroll{overflow-x:auto;border:1px solid var(--line);border-radius:8px}
|
|
13371
13995
|
.mp-table{width:100%;border-collapse:collapse;font-size:12px;line-height:1.6;color:var(--ink2);font-family:system-ui,sans-serif}
|
|
13372
13996
|
.mp-table th,.mp-table td{padding:5px 9px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line);white-space:nowrap}
|
|
13373
13997
|
.mp-table th{background:var(--band);color:var(--label);font-weight:600;font-size:11px;letter-spacing:.06em}
|
|
@@ -13433,15 +14057,17 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13433
14057
|
.mp-qt-y b.first{color:var(--ji);border-bottom:2px solid var(--ji);padding-bottom:1px}
|
|
13434
14058
|
.mp-qt-q{margin-top:6px;font-size:12.5px;line-height:1.8;color:var(--ink2);font-family:var(--fx)}
|
|
13435
14059
|
.mp-qt-q span{display:block;font-size:11px;color:var(--ink3);font-family:var(--sans);margin-top:2px}
|
|
13436
|
-
.mp-cl{margin-top:
|
|
13437
|
-
|
|
13438
|
-
.mp-cl-h
|
|
14060
|
+
.mp-cl{margin-top:12px;padding:10px 12px 8px;border-left:2px solid var(--quan);border-radius:0 8px 8px 0;
|
|
14061
|
+
background:color-mix(in srgb,var(--band) 72%,transparent)}
|
|
14062
|
+
.mp-cl-h{display:flex;gap:8px;align-items:baseline;font-size:12.5px;margin-bottom:7px}
|
|
14063
|
+
.mp-cl-h b{color:var(--ink);letter-spacing:.06em}
|
|
13439
14064
|
.mp-cl-h span{color:var(--ink3);font-size:11.5px}
|
|
13440
|
-
.mp-cl-e{padding:
|
|
14065
|
+
.mp-cl-e{padding:8px 0;border-top:1px dashed var(--hair)}
|
|
13441
14066
|
.mp-cl-e:first-of-type{border-top:0;padding-top:0}
|
|
13442
|
-
.mp-cl-t b{font-family:var(--fx);font-size:13px;color:var(--lu);font-weight:600}
|
|
13443
|
-
.mp-cl-q{font-family:var(--fx);font-size:
|
|
13444
|
-
|
|
14067
|
+
.mp-cl-t b{font-family:var(--fx);font-size:13px;color:var(--lu);font-weight:600;letter-spacing:.03em}
|
|
14068
|
+
.mp-cl-q{font-family:var(--fx);font-size:14px;line-height:2;color:var(--ink);margin-top:3px;letter-spacing:.02em;
|
|
14069
|
+
padding-left:1.05em;text-indent:-1.05em}
|
|
14070
|
+
.mp-cl-p{font-size:12px;line-height:1.9;color:var(--ink2);margin-top:3px}
|
|
13445
14071
|
@media print{.mp-cl{break-inside:avoid}}
|
|
13446
14072
|
@media print{.mp-cli{break-inside:avoid}}
|
|
13447
14073
|
.mp-nm{margin:12px 16px;border:1px solid var(--line);border-radius:8px;background:var(--card);padding:12px 14px;font-family:system-ui,sans-serif}
|
|
@@ -13471,30 +14097,48 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13471
14097
|
.mp-nm-c em{font-style:normal;font-size:11.5px;line-height:1.7;color:var(--muted);font-family:var(--sans)}
|
|
13472
14098
|
@media print{.mp-nm{break-inside:avoid}}
|
|
13473
14099
|
.mp-quick-pre{margin:0;white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:1.9;color:var(--ink2)}
|
|
13474
|
-
.mp-mb{margin:12px 16px;border:1px solid var(--line);border-radius:
|
|
13475
|
-
.mp-mb-h{display:flex;align-items:
|
|
13476
|
-
|
|
13477
|
-
.mp-mb-
|
|
13478
|
-
.mp-mb-
|
|
13479
|
-
.mp-mb-
|
|
13480
|
-
.mp-mb-
|
|
13481
|
-
.mp-mb-
|
|
13482
|
-
.mp-mb-
|
|
13483
|
-
.mp-mb-
|
|
13484
|
-
.mp-mb-
|
|
13485
|
-
.mp-mb-
|
|
13486
|
-
.mp-mb-
|
|
13487
|
-
.mp-mb-
|
|
13488
|
-
.mp-mb-
|
|
13489
|
-
.mp-mb-
|
|
13490
|
-
.mp-mb-
|
|
13491
|
-
.mp-mb-
|
|
13492
|
-
.mp-mb-
|
|
13493
|
-
.mp-mb-
|
|
13494
|
-
.mp-mb-
|
|
13495
|
-
.mp-mb-
|
|
13496
|
-
.mp-mb-
|
|
13497
|
-
|
|
14100
|
+
.mp-mb{margin:12px 16px;border:1px solid var(--line);border-radius:12px;background:var(--card);box-shadow:var(--shadow);overflow:hidden;font-family:var(--sans)}
|
|
14101
|
+
.mp-mb-h{display:flex;flex-direction:row;align-items:center;gap:14px;flex-wrap:wrap;padding:15px 18px 14px;
|
|
14102
|
+
background:linear-gradient(135deg,var(--sel),var(--band) 64%,var(--card));border-bottom:1px solid var(--hair)}
|
|
14103
|
+
.mp-mb-code{font-family:var(--fx);font-size:32px;font-weight:700;line-height:1;letter-spacing:.12em;color:var(--ink)}
|
|
14104
|
+
.mp-mb-meta{display:flex;flex-direction:column;gap:3px;min-width:0}
|
|
14105
|
+
.mp-mb-meta b{font-size:14.5px;font-weight:600;color:var(--ink);letter-spacing:.04em}
|
|
14106
|
+
.mp-mb-meta i{font-style:normal;font-size:12px;line-height:1.5;color:var(--muted)}
|
|
14107
|
+
.mp-mb-count{margin-left:auto;padding:3px 10px;border:1px solid var(--line);border-radius:999px;background:var(--card);color:var(--muted);font-size:11.5px;white-space:nowrap}
|
|
14108
|
+
.mp-mb-body{padding:14px 18px 16px}
|
|
14109
|
+
.mp-mb-dims{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
|
|
14110
|
+
.mp-mb-dim{border:1px solid var(--hair);border-radius:10px;background:var(--band);padding:9px 11px 10px}
|
|
14111
|
+
.mp-mb-dh{display:flex;align-items:baseline;gap:6px;font-size:11.5px;color:var(--muted)}
|
|
14112
|
+
.mp-mb-dh b{font-family:var(--fx);font-size:17px;font-weight:600;line-height:1.1;letter-spacing:.08em;color:var(--faint)}
|
|
14113
|
+
.mp-mb-dh b.on{color:var(--ink)}
|
|
14114
|
+
.mp-mb-dh em{font-style:normal;margin:0 auto;font-size:11.5px;letter-spacing:.06em}
|
|
14115
|
+
.mp-mb-bar{position:relative;height:7px;border-radius:4px;background:var(--hair);margin:7px 0 6px;overflow:hidden}
|
|
14116
|
+
.mp-mb-bar::after{content:"";position:absolute;left:50%;top:-1px;bottom:-1px;width:1px;background:color-mix(in srgb,var(--line) 70%,transparent)}
|
|
14117
|
+
.mp-mb-bar em{position:absolute;top:0;bottom:0;background:linear-gradient(90deg,var(--quan),color-mix(in srgb,var(--quan) 55%,var(--card)));border-radius:4px}
|
|
14118
|
+
.mp-mb-bar.l em{left:0}
|
|
14119
|
+
.mp-mb-bar.r em{right:0;background:linear-gradient(270deg,var(--quan),color-mix(in srgb,var(--quan) 55%,var(--card)))}
|
|
14120
|
+
.mp-mb-df{font-size:11.5px;color:var(--ink2);font-variant-numeric:tabular-nums}
|
|
14121
|
+
.mp-mb-ds{margin-top:2px;font-size:11.5px;line-height:1.7;color:var(--muted)}
|
|
14122
|
+
.mp-mb-sec{margin-top:11px;font-size:12.5px;line-height:1.85;color:var(--ink2)}
|
|
14123
|
+
.mp-mb-sec em{display:inline-block;margin-right:7px;padding:0 7px;border:1px solid var(--hair);border-radius:5px;background:var(--band);color:var(--muted);font-size:11px;font-style:normal;letter-spacing:.08em}
|
|
14124
|
+
.mp-mb-two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:11px}
|
|
14125
|
+
.mp-mb-two>div{border:1px solid var(--hair);border-left:3px solid var(--br-good);border-radius:8px;background:var(--card);padding:8px 10px;font-size:12.5px;line-height:1.8;color:var(--ink2)}
|
|
14126
|
+
.mp-mb-two>div+div{border-left-color:var(--br-bad)}
|
|
14127
|
+
.mp-mb-two b{display:block;margin-bottom:2px;font-size:11.5px;font-weight:600;letter-spacing:.08em;color:var(--br-good)}
|
|
14128
|
+
.mp-mb-two>div+div b{color:var(--br-bad)}
|
|
14129
|
+
.mp-mb-fn{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}
|
|
14130
|
+
.mp-mb-fn span{font-size:11.5px;border:1px solid var(--line);border-radius:999px;background:var(--card);padding:2px 9px;color:var(--ink2)}
|
|
14131
|
+
.mp-mb-fn span.lead{border-color:var(--quan);background:color-mix(in srgb,var(--quan) 9%,var(--card));color:var(--quan);font-weight:600}
|
|
14132
|
+
.mp-mb-fn span b{font-weight:600;margin-right:4px}
|
|
14133
|
+
.mp-mb-note{margin:12px 18px 14px;padding-top:10px;font-size:11px;line-height:1.7;color:var(--muted);border-top:1px solid var(--hair)}
|
|
14134
|
+
.mp-mb-paper{margin:12px 16px;border:1px solid var(--line);border-radius:12px;background:var(--card);box-shadow:var(--shadow);overflow:hidden;font-family:var(--sans)}
|
|
14135
|
+
.mp-mb-paper ol{counter-reset:q;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px 20px;
|
|
14136
|
+
margin:0;padding:12px 18px 14px;list-style:none;font-size:12.5px;line-height:1.7;color:var(--ink2)}
|
|
14137
|
+
.mp-mb-paper li{counter-increment:q;position:relative;padding:0 0 6px 26px;border-bottom:1px dashed var(--hair)}
|
|
14138
|
+
.mp-mb-paper li::before{content:counter(q);position:absolute;left:0;top:1px;display:flex;align-items:center;justify-content:center;
|
|
14139
|
+
width:19px;height:19px;border:1px solid var(--hair);border-radius:50%;background:var(--band);color:var(--muted);font-size:10.5px;font-variant-numeric:tabular-nums}
|
|
14140
|
+
.mp-mb-paper .mp-mb-note{margin:0 18px 14px}
|
|
14141
|
+
@media (max-width:640px){.mp-mb-dims,.mp-mb-two,.mp-mb-paper ol{grid-template-columns:1fr}.mp-mb-code{font-size:26px}.mp-mb-body{padding:12px 14px 14px}.mp-mb-h{padding:13px 14px 12px}}
|
|
13498
14142
|
@media print{.mp-mb{break-inside:avoid}}
|
|
13499
14143
|
.mp-al{margin:12px 16px;border:1px solid var(--line);border-radius:8px;background:var(--card);padding:12px 14px;font-family:system-ui,sans-serif}
|
|
13500
14144
|
.mp-al-h{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;border-bottom:1px solid var(--hair);padding-bottom:8px;margin-bottom:9px}
|
|
@@ -13889,6 +14533,14 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13889
14533
|
}).join('');
|
|
13890
14534
|
return chips ? `<div class="pp-chips">${chips}</div>` : '';
|
|
13891
14535
|
})() : '';
|
|
14536
|
+
const flyCompositeHTML = r.flyComposite && Array.isArray(r.flyComposite.labels) && r.flyComposite.labels.length
|
|
14537
|
+
? `<div class="pp-chips">${r.flyComposite.labels.map((l) => {
|
|
14538
|
+
const cls = /忌/.test(l) ? 'warn' : /自化/.test(l) ? '' : 'ok';
|
|
14539
|
+
const palaceOf = (x) => String(x).replace(/^.*?会/, '').replace(/^禄忌同宫/, '').replace(/自化$/, '');
|
|
14540
|
+
const hit = (r.flyComposite.targets || []).find((t) => t.palace === palaceOf(l));
|
|
14541
|
+
const tip = hit ? hit.incoming.map((x) => `${x.from}化${x.type}${x.star}`).join('、') : r.flyComposite.note;
|
|
14542
|
+
return `<span class="pp-chip ${cls}" title="${esc(tip)}">三方四正 ${esc(l)}</span>`;
|
|
14543
|
+
}).join('')}</div>` : '';
|
|
13892
14544
|
|
|
13893
14545
|
const fl = r.flow;
|
|
13894
14546
|
const flowHTML = fl ? (() => {
|
|
@@ -13918,7 +14570,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
13918
14570
|
${body('ben', soulIdx, 'ben')}
|
|
13919
14571
|
${body('da', dxIdx, 'da')}
|
|
13920
14572
|
${body('ln', lnIdx, 'ln')}
|
|
13921
|
-
</div>${flowHTML}${chips}${flyHTML}${pats}${dxs}${lnHit}`;
|
|
14573
|
+
</div>${flowHTML}${chips}${flyHTML}${flyCompositeHTML}${pats}${dxs}${lnHit}`;
|
|
13922
14574
|
};
|
|
13923
14575
|
|
|
13924
14576
|
function starLine(list) {
|
|
@@ -14100,12 +14752,29 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
14100
14752
|
return `<span class="pp-chip ${cls}">${esc(l)}</span>`;
|
|
14101
14753
|
}).join('')}</div>`
|
|
14102
14754
|
: '';
|
|
14755
|
+
const jp = r.jinTuiPower && Array.isArray(r.jinTuiPower.labels) ? r.jinTuiPower : null;
|
|
14756
|
+
const jinRow = jp && jp.labels.length
|
|
14757
|
+
? `<div class="pp-chips">${jp.labels.map((l) => {
|
|
14758
|
+
const cls = /后劲足|退得缓/.test(l) ? 'ok' : /有限|进得虚|退得实|月破|未定/.test(l) ? 'warn' : '';
|
|
14759
|
+
return `<span class="pp-chip ${cls}">${esc(l)}</span>`;
|
|
14760
|
+
}).join('')}</div>`
|
|
14761
|
+
: '';
|
|
14762
|
+
const hs = r.hexStrength && Array.isArray(r.hexStrength.labels) ? r.hexStrength : null;
|
|
14763
|
+
const hexRow = hs && hs.labels.length
|
|
14764
|
+
? `<div class="pp-chips">${hs.labels.map((l) => {
|
|
14765
|
+
const cls = /死|囚|月破|冲空/.test(l) ? 'warn'
|
|
14766
|
+
: /旺|相/.test(l) ? 'ok' : '';
|
|
14767
|
+
return `<span class="pp-chip ${cls}">${esc(l)}</span>`;
|
|
14768
|
+
}).join('')}</div>`
|
|
14769
|
+
: '';
|
|
14103
14770
|
return `<div class="pp" style="padding:14px">
|
|
14104
14771
|
<div class="mp-mh-head">起卦 ${r.cast.notation.join('、')}(自下而上) 日辰 ${r.dayGanZhi.name}</div>
|
|
14105
14772
|
<div class="mp-hy-wrap">${ben}${bian}</div>
|
|
14106
14773
|
${bodyRow}
|
|
14107
14774
|
${useRow}
|
|
14108
14775
|
${strengthRow}
|
|
14776
|
+
${jinRow}
|
|
14777
|
+
${hexRow}
|
|
14109
14778
|
</div>`;
|
|
14110
14779
|
};
|
|
14111
14780
|
|
|
@@ -14794,8 +15463,13 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
14794
15463
|
}).join('');
|
|
14795
15464
|
const ln = (r.liunian && r.liunian.length) ? `<div class="pp-chips">${r.liunian.slice(0, 8).map((l) => {
|
|
14796
15465
|
const lk = l.luck || null;
|
|
14797
|
-
|
|
15466
|
+
const sy = (l.suiyun && Array.isArray(l.suiyun.signals)) ? l.suiyun.signals : [];
|
|
15467
|
+
const syTip = sy.length ? `|${sy.map((x) => x.detail).join(';')}` : '';
|
|
15468
|
+
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>`;
|
|
14798
15469
|
}).join('')}</div>` : '';
|
|
15470
|
+
const sy = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
15471
|
+
const syRow = sy.length ? `<div class="pp-tl pp-dim">岁运提示(只标干支变动,不判吉凶)</div><div class="pp-chips">${sy.map((l) =>
|
|
15472
|
+
`<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>` : '';
|
|
14799
15473
|
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>` : '';
|
|
14800
15474
|
const ssGroups = (r.shensha && r.shensha.groups) || [];
|
|
14801
15475
|
const ssx = ssGroups.length ? `
|
|
@@ -14815,14 +15489,14 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
14815
15489
|
${(Array.isArray(r.classics) && r.classics.length) ? `<section class="mp-cl" aria-label="古籍原文">
|
|
14816
15490
|
<div class="mp-cl-h"><b>古籍原文</b><span>照录通行本,释义为白话自撰</span></div>
|
|
14817
15491
|
${r.classics.map((e) => `<div class="mp-cl-e">
|
|
14818
|
-
<div class="mp-cl-t"><b>${esc((
|
|
15492
|
+
<div class="mp-cl-t"><b>${esc(({ ziping: '子平真诠', ditian: '滴天髓', sanming: '三命通会' }[e.book] || e.book) + '·' + e.chapter)}</b></div>
|
|
14819
15493
|
<div class="mp-cl-q">「${esc(e.quote)}」</div>
|
|
14820
15494
|
<div class="mp-cl-p">${esc(e.plain)}</div>
|
|
14821
15495
|
</div>`).join('')}
|
|
14822
15496
|
</section>` : ''}
|
|
14823
15497
|
${sect('五行与十神', `<div class="pp-chips">${wx}</div>${gods}`)}
|
|
14824
15498
|
${sect('大运', `${pp.curveHTML(r)}<div class="pp-chips">${dy}</div>`)}
|
|
14825
|
-
${ln ? sect('流年', ln) : ''}
|
|
15499
|
+
${ln ? sect('流年', ln + syRow) : ''}
|
|
14826
15500
|
${r.palaces ? sect('胎元与命身宫', `<div class="pp-chips">
|
|
14827
15501
|
<span class="pp-chip" title="${r.palaces.taiyuan.note}">胎元 ${r.palaces.taiyuan.ganzhi}</span>
|
|
14828
15502
|
<span class="pp-chip" title="${r.palaces.minggong.note}">命宫 ${r.palaces.minggong.ganzhi}</span>
|
|
@@ -14959,7 +15633,10 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
14959
15633
|
if (r.needAnswers && Array.isArray(r.questions)) {
|
|
14960
15634
|
const items = r.questions.map((q) => `<li>${esc(q.text)}</li>`).join('');
|
|
14961
15635
|
return `<section class="mp-mb-paper" aria-label="十六型人格问卷">
|
|
14962
|
-
<div class="mp-mb-h"
|
|
15636
|
+
<div class="mp-mb-h">
|
|
15637
|
+
<span class="mp-mb-meta"><b>十六型人格问卷</b><i>${r.total} 题 · 每题 1 完全不像 / 5 很像我</i></span>
|
|
15638
|
+
<span class="mp-mb-count">填完分数再看结果</span>
|
|
15639
|
+
</div>
|
|
14963
15640
|
<ol>${items}</ol>
|
|
14964
15641
|
<div class="mp-mb-note">${esc(r.note || '')}</div>
|
|
14965
15642
|
</section>`;
|
|
@@ -14968,32 +15645,35 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, geocodeAd
|
|
|
14968
15645
|
const pct = Math.round((d.pct || 0) * 100);
|
|
14969
15646
|
const leftOn = d.picked === d.left;
|
|
14970
15647
|
const width = Math.max(2, pct);
|
|
14971
|
-
const bar = leftOn
|
|
14972
|
-
? `<em class="on" style="left:0;width:${width}%"></em>`
|
|
14973
|
-
: `<em class="on" style="right:0;width:${width}%"></em>`;
|
|
14974
15648
|
const say = leftOn ? d.leftSay : d.rightSay;
|
|
14975
15649
|
return `<div class="mp-mb-dim">
|
|
14976
|
-
<b class="${leftOn ? 'on' : ''}">${esc(d.left)}</b>
|
|
14977
|
-
<div class="mp-mb-bar"
|
|
14978
|
-
<
|
|
14979
|
-
<
|
|
15650
|
+
<div class="mp-mb-dh"><b class="${leftOn ? 'on' : ''}">${esc(d.left)}</b><em>${esc(d.name)}</em><b class="${leftOn ? '' : 'on'}">${esc(d.right)}</b></div>
|
|
15651
|
+
<div class="mp-mb-bar ${leftOn ? 'l' : 'r'}"><em style="width:${width}%"></em></div>
|
|
15652
|
+
<div class="mp-mb-df">取 ${esc(d.picked)} · ${esc(d.strength)} ${pct}%</div>
|
|
15653
|
+
<div class="mp-mb-ds">${esc(say)}</div>
|
|
14980
15654
|
</div>`;
|
|
14981
15655
|
}).join('');
|
|
14982
15656
|
const p = r.profile || {};
|
|
14983
|
-
const stack = (p.stack || []).map((f) => `<span>${esc(f.code)}
|
|
15657
|
+
const stack = (p.stack || []).map((f, i) => `<span class="${i === 0 ? 'lead' : ''}"><b>${esc(f.code)}</b>${esc(f.say)}</span>`).join('');
|
|
14984
15658
|
return `<section class="mp-mb" aria-label="十六型人格结果">
|
|
14985
|
-
<div class="mp-mb-h"
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
15659
|
+
<div class="mp-mb-h">
|
|
15660
|
+
<span class="mp-mb-code">${esc(r.type || '')}</span>
|
|
15661
|
+
<span class="mp-mb-meta"><b>${esc(p.title || '')}</b><i>${esc(p.keywords || '')}</i></span>
|
|
15662
|
+
<span class="mp-mb-count">已答 ${r.answered || 0}/${r.total || 0} 题</span>
|
|
15663
|
+
</div>
|
|
15664
|
+
<div class="mp-mb-body">
|
|
15665
|
+
<div class="mp-mb-dims">${dims}</div>
|
|
15666
|
+
<div class="mp-mb-sec"><em>一句</em>${esc(p.oneLine || '')}</div>
|
|
15667
|
+
<div class="mp-mb-two">
|
|
15668
|
+
<div><b>优势</b>${(p.strengths || []).map((s) => esc(s)).join(';')}</div>
|
|
15669
|
+
<div><b>留意</b>${(p.blindspots || []).map((s) => esc(s)).join(';')}</div>
|
|
15670
|
+
</div>
|
|
15671
|
+
${stack ? `<div class="mp-mb-sec"><em>认知功能</em>主导 ${esc((p.stack[0] || {}).code || '')} → 依次展开</div><div class="mp-mb-fn">${stack}</div>` : ''}
|
|
15672
|
+
<div class="mp-mb-sec"><em>工作</em>${esc(p.work || '')}</div>
|
|
15673
|
+
<div class="mp-mb-sec"><em>关系</em>${esc(p.love || '')}</div>
|
|
15674
|
+
<div class="mp-mb-sec"><em>学习</em>${esc(p.study || '')}</div>
|
|
15675
|
+
<div class="mp-mb-sec"><em>课题</em>${esc(p.growth || '')}</div>
|
|
14991
15676
|
</div>
|
|
14992
|
-
${stack ? `<div class="mp-mb-sec"><em>认知功能</em>主导 ${esc((p.stack[0] || {}).code || '')} → 依次展开</div><div class="mp-mb-fn">${stack}</div>` : ''}
|
|
14993
|
-
<div class="mp-mb-sec"><em>工作</em>${esc(p.work || '')}</div>
|
|
14994
|
-
<div class="mp-mb-sec"><em>关系</em>${esc(p.love || '')}</div>
|
|
14995
|
-
<div class="mp-mb-sec"><em>学习</em>${esc(p.study || '')}</div>
|
|
14996
|
-
<div class="mp-mb-sec"><em>课题</em>${esc(p.growth || '')}</div>
|
|
14997
15677
|
<div class="mp-mb-note">${esc(r.note || '')}</div>
|
|
14998
15678
|
</section>`;
|
|
14999
15679
|
};
|
|
@@ -15151,7 +15831,8 @@ const PP = window.__PP;
|
|
|
15151
15831
|
const CSS = `
|
|
15152
15832
|
.mp-wrap{height:100%;overflow:auto;padding:20px 24px 40px;color:var(--dsw-alias-label-primary);font-size:14px}
|
|
15153
15833
|
.mp-wrap>*{max-width:940px;margin-left:auto;margin-right:auto}
|
|
15154
|
-
.mp-panel{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:
|
|
15834
|
+
.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;
|
|
15835
|
+
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)}
|
|
15155
15836
|
.mp-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px 14px;align-items:end}
|
|
15156
15837
|
.mp-lbl{display:block;height:18px;line-height:18px;font-size:12.5px;color:var(--dsw-alias-label-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
15157
15838
|
.mp-checks{display:flex;gap:20px;flex-wrap:wrap;margin-top:13px;font-size:12.5px;color:var(--dsw-alias-label-secondary)}
|
|
@@ -15159,17 +15840,50 @@ const CSS = `
|
|
|
15159
15840
|
.mp-askblock{margin-top:14px;display:flex;flex-direction:column;gap:5px}
|
|
15160
15841
|
.mp-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:14px}
|
|
15161
15842
|
.mp-tabs{display:inline-flex;gap:4px;margin-bottom:14px;flex-wrap:wrap;padding:4px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:11px;width:100%;max-width:940px}
|
|
15162
|
-
.mp-tab{padding:7px 15px;border-radius:
|
|
15163
|
-
.mp-tab:hover{background:var(--dsw-alias-bg-layer-
|
|
15164
|
-
.mp-tab.on{background:var(--dsw-alias-brand-primary);color:#fff}
|
|
15843
|
+
.mp-tab{padding:7px 15px;border-radius:9px;border:none;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;font-size:13.5px;transition:background .14s,color .14s,box-shadow .14s}
|
|
15844
|
+
.mp-tab:hover{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}
|
|
15845
|
+
.mp-tab.on{background:var(--dsw-alias-brand-primary);color:#fff;box-shadow:0 8px 18px -12px var(--dsw-alias-brand-primary)}
|
|
15165
15846
|
.mp-field{display:flex;flex-direction:column;gap:5px;font-size:13px;color:var(--dsw-alias-label-secondary);min-width:0}
|
|
15166
|
-
.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:
|
|
15167
|
-
|
|
15168
|
-
.mp-
|
|
15169
|
-
.mp-
|
|
15847
|
+
.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;
|
|
15848
|
+
transition:border-color .14s,box-shadow .14s,background .14s}
|
|
15849
|
+
.mp-input:hover{border-color:color-mix(in srgb,var(--dsw-alias-border-l1) 45%,var(--dsw-alias-brand-primary))}
|
|
15850
|
+
.mp-input:focus{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}
|
|
15851
|
+
.mp-textarea{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:8px 11px;font-size:14px;outline:none;width:100%;min-width:0;resize:vertical;line-height:1.5;font-family:inherit;
|
|
15852
|
+
transition:border-color .14s,box-shadow .14s}
|
|
15853
|
+
.mp-textarea:hover{border-color:color-mix(in srgb,var(--dsw-alias-border-l1) 45%,var(--dsw-alias-brand-primary))}
|
|
15854
|
+
.mp-textarea:focus{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}
|
|
15170
15855
|
.mp-textarea.invalid{border-color:var(--dsw-alias-state-error-primary)}
|
|
15171
|
-
.mp-
|
|
15172
|
-
.mp-
|
|
15856
|
+
.mp-quiz-wrap{grid-column:1 / -1;display:flex;flex-direction:column;gap:6px}
|
|
15857
|
+
.mp-quiz-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
|
15858
|
+
.mp-quiz-bar{flex:1 1 160px;min-width:110px;height:6px;border:1px solid var(--dsw-alias-border-l1);border-radius:999px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}
|
|
15859
|
+
.mp-quiz-bar i{display:block;height:100%;border-radius:999px;background:var(--dsw-alias-brand-primary);transition:width .18s ease}
|
|
15860
|
+
.mp-quiz-count{font-size:12px;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
15861
|
+
.mp-quiz-list{display:flex;flex-direction:column;gap:8px;margin-top:8px}
|
|
15862
|
+
.mp-quiz-q{padding:10px 12px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-1)}
|
|
15863
|
+
.mp-quiz-qt{display:flex;gap:8px;align-items:baseline;font-size:13px;line-height:1.6;color:var(--dsw-alias-label-primary)}
|
|
15864
|
+
.mp-quiz-qt b{flex:none;padding-top:1px;font:600 11px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.04em;color:var(--dsw-alias-brand-primary)}
|
|
15865
|
+
.mp-quiz-opts{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;margin-top:8px}
|
|
15866
|
+
.mp-quiz-o{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:6px 4px;border:1px solid var(--dsw-alias-border-l1);border-radius:8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:center;
|
|
15867
|
+
transition:border-color .14s,background .14s,color .14s}
|
|
15868
|
+
.mp-quiz-o input{position:absolute;inset:0;margin:0;opacity:0;cursor:pointer}
|
|
15869
|
+
.mp-quiz-o b{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums}
|
|
15870
|
+
.mp-quiz-o span{font-size:11px;line-height:1.3}
|
|
15871
|
+
.mp-quiz-o:hover{border-color:var(--dsw-alias-brand-primary)}
|
|
15872
|
+
.mp-quiz-o.on{border-color:transparent;background:var(--dsw-alias-brand-primary)}
|
|
15873
|
+
.mp-quiz-o.on b,.mp-quiz-o.on span{color:#fff}
|
|
15874
|
+
.mp-quiz-o:focus-within{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
15875
|
+
.mp-quiz-nav{display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap}
|
|
15876
|
+
.mp-quiz-btn{padding:6px 14px;border-radius:8px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-primary);font-family:inherit;font-size:12.5px;cursor:pointer;min-height:32px}
|
|
15877
|
+
.mp-quiz-btn:hover:not(:disabled){border-color:var(--dsw-alias-brand-primary)}
|
|
15878
|
+
.mp-quiz-btn:disabled{opacity:.42;cursor:not-allowed}
|
|
15879
|
+
.mp-quiz-btn.primary{border-color:transparent;background:var(--dsw-alias-brand-primary);color:#fff;font-weight:600}
|
|
15880
|
+
.mp-quiz-hint{margin-left:auto;font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.6}
|
|
15881
|
+
.mp-btn{padding:8px 22px;border-radius:9px;border:none;background:var(--dsw-alias-brand-primary);color:#fff;cursor:pointer;font-size:14px;font-weight:600;min-width:132px;
|
|
15882
|
+
box-shadow:0 10px 20px -14px var(--dsw-alias-brand-primary);transition:transform .14s,filter .14s,box-shadow .14s}
|
|
15883
|
+
.mp-btn:hover{filter:brightness(1.06);transform:translateY(-1px)}
|
|
15884
|
+
.mp-btn:active{transform:none;filter:brightness(.98)}
|
|
15885
|
+
.mp-btn.ghost{background:transparent;border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);box-shadow:none}
|
|
15886
|
+
.mp-btn.ghost:hover{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);filter:none}
|
|
15173
15887
|
.mp-seg{display:flex;width:100%;border:1px solid var(--dsw-alias-border-l1);border-radius:8px;overflow:hidden;height:36px}
|
|
15174
15888
|
.mp-seg button{flex:1;padding:0 8px;background:transparent;border:none;color:var(--dsw-alias-label-secondary);font-size:13px;cursor:pointer}
|
|
15175
15889
|
.mp-seg button.on{background:var(--dsw-alias-brand-primary);color:#fff}
|
|
@@ -15195,7 +15909,8 @@ const CSS = `
|
|
|
15195
15909
|
.mp-hist-item b{font-weight:600}
|
|
15196
15910
|
.mp-hist-item span{color:var(--dsw-alias-label-secondary)}
|
|
15197
15911
|
.mp-hist-item i{font-style:normal;color:var(--dsw-alias-label-secondary);opacity:.7;font-size:11px}.mp-hint{font-size:12.5px;color:var(--dsw-alias-label-secondary);line-height:1.7;margin:0 0 14px;padding-left:2px}
|
|
15198
|
-
.mp-card{margin-top:18px;padding:16px 18px;border-radius:
|
|
15912
|
+
.mp-card{margin-top:18px;padding:16px 18px;border-radius:16px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);
|
|
15913
|
+
box-shadow:0 1px 2px color-mix(in srgb,var(--dsw-alias-label-primary) 5%,transparent),0 18px 40px -32px color-mix(in srgb,var(--dsw-alias-label-primary) 42%,transparent)}
|
|
15199
15914
|
.mp-flat{margin-top:16px;padding:0;border:none;background:transparent;border-radius:0}
|
|
15200
15915
|
.mp-dim{color:var(--dsw-alias-label-secondary)}
|
|
15201
15916
|
.mp-err{margin-top:16px;padding:9px 14px;border-radius:8px;border-left:3px solid var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);color:var(--dsw-alias-state-error-primary);font-size:13px}
|
|
@@ -15233,6 +15948,11 @@ const CSS = `
|
|
|
15233
15948
|
.mp-tab{padding:9px 4px;font-size:13.5px;text-align:center}
|
|
15234
15949
|
.mp-input,.mp-textarea{padding:10px 12px;font-size:16px;min-height:44px;height:auto}
|
|
15235
15950
|
.mp-textarea{min-height:76px}
|
|
15951
|
+
.mp-quiz-q{padding:9px 10px}
|
|
15952
|
+
.mp-quiz-o{padding:8px 3px;min-height:50px}
|
|
15953
|
+
.mp-quiz-o span{font-size:10px}
|
|
15954
|
+
.mp-quiz-btn{flex:1 1 auto;min-height:44px}
|
|
15955
|
+
.mp-quiz-hint{flex-basis:100%;margin-left:0}
|
|
15236
15956
|
.mp-actions{margin-top:12px}
|
|
15237
15957
|
.mp-btn{width:100%;padding:12px;font-size:15px;min-height:46px;min-width:0}
|
|
15238
15958
|
.mp-hint,.mp-auto,.mp-cast{font-size:12.5px}
|
|
@@ -15246,10 +15966,81 @@ const CSS = `
|
|
|
15246
15966
|
.mp-wrap{padding:12px 10px 32px}
|
|
15247
15967
|
.mp-tab{font-size:13px;padding:8px 2px}
|
|
15248
15968
|
}
|
|
15969
|
+
: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}
|
|
15970
|
+
@media (prefers-reduced-motion:reduce){
|
|
15971
|
+
*,*::before,*::after{transition-duration:.001ms!important;animation-duration:.001ms!important}
|
|
15972
|
+
}
|
|
15249
15973
|
`;
|
|
15250
15974
|
|
|
15251
15975
|
const { useState, useEffect } = React;
|
|
15252
15976
|
|
|
15977
|
+
const MBTI_PER_PAGE = 4;
|
|
15978
|
+
const MBTI_MIN = 12;
|
|
15979
|
+
let MBTI_INFO = null;
|
|
15980
|
+
function mbtiInfo() {
|
|
15981
|
+
if (MBTI_INFO) return MBTI_INFO;
|
|
15982
|
+
let p = null;
|
|
15983
|
+
try { p = Engine.compute({ system: 'mbti' }); } catch (e) { p = null; }
|
|
15984
|
+
const questions = (p && p.questions) || [];
|
|
15985
|
+
MBTI_INFO = { total: (p && p.total) || questions.length, questions, scale: (p && p.scale) || {} };
|
|
15986
|
+
return MBTI_INFO;
|
|
15987
|
+
}
|
|
15988
|
+
|
|
15989
|
+
function MbtiQuiz(props) {
|
|
15990
|
+
const { answers, page, onPick, onPage, onSubmit, onClear } = props;
|
|
15991
|
+
const info = mbtiInfo();
|
|
15992
|
+
const pages = Math.max(1, Math.ceil(info.total / MBTI_PER_PAGE));
|
|
15993
|
+
const start = page * MBTI_PER_PAGE;
|
|
15994
|
+
const slice = info.questions.slice(start, start + MBTI_PER_PAGE);
|
|
15995
|
+
const answered = answers.filter((v) => v != null).length;
|
|
15996
|
+
const pct = info.total ? Math.round((answered / info.total) * 100) : 0;
|
|
15997
|
+
const last = page >= pages - 1;
|
|
15998
|
+
const ready = answered >= MBTI_MIN;
|
|
15999
|
+
return h('div', { className: 'mp-quiz' },
|
|
16000
|
+
h('div', { className: 'mp-quiz-top' },
|
|
16001
|
+
h('div', { className: 'mp-quiz-bar', 'aria-hidden': 'true' }, h('i', { style: { width: pct + '%' } })),
|
|
16002
|
+
h('span', { className: 'mp-quiz-count' }, `第 ${page + 1} / ${pages} 页 · 已答 ${answered} / ${info.total}`)),
|
|
16003
|
+
h('div', { className: 'mp-quiz-list' }, slice.map((q, k) => {
|
|
16004
|
+
const i = start + k;
|
|
16005
|
+
return h('div', { key: q.id || i, className: 'mp-quiz-q' },
|
|
16006
|
+
h('div', { className: 'mp-quiz-qt' }, h('b', null, String(i + 1).padStart(2, '0')), h('span', null, q.text)),
|
|
16007
|
+
h('div', { className: 'mp-quiz-opts', role: 'radiogroup', 'aria-label': `第 ${i + 1} 题` },
|
|
16008
|
+
[1, 2, 3, 4, 5].map((n) => h('label', { key: n, className: 'mp-quiz-o' + (answers[i] === n ? ' on' : '') },
|
|
16009
|
+
h('input', {
|
|
16010
|
+
type: 'radio', name: `mpmbq${i}`, value: String(n), checked: answers[i] === n,
|
|
16011
|
+
onChange: () => onPick(i, n),
|
|
16012
|
+
}),
|
|
16013
|
+
h('b', null, String(n)),
|
|
16014
|
+
h('span', null, info.scale[n] || '')))));
|
|
16015
|
+
})),
|
|
16016
|
+
h('div', { className: 'mp-quiz-nav' },
|
|
16017
|
+
h('button', { className: 'mp-quiz-btn', disabled: page <= 0, onClick: () => onPage(-1) }, '上一页'),
|
|
16018
|
+
last ? null : h('button', { className: 'mp-quiz-btn', onClick: () => onPage(1) }, '下一页'),
|
|
16019
|
+
h('button', { className: 'mp-quiz-btn primary', disabled: !ready, onClick: onSubmit }, '看结果'),
|
|
16020
|
+
h('button', { className: 'mp-quiz-btn', onClick: onClear }, '清空'),
|
|
16021
|
+
h('span', { className: 'mp-quiz-hint' }, ready
|
|
16022
|
+
? `已够 ${MBTI_MIN} 题,可以看结果;答完 ${info.total} 题会更准。`
|
|
16023
|
+
: `答满 ${MBTI_MIN} 题可先看结果(还差 ${MBTI_MIN - answered} 题)。`)),
|
|
16024
|
+
);
|
|
16025
|
+
}
|
|
16026
|
+
|
|
16027
|
+
class PanelGuard extends (React.Component || Object) {
|
|
16028
|
+
constructor(props) { super(props); this.state = { err: null }; }
|
|
16029
|
+
static getDerivedStateFromError(err) { return { err }; }
|
|
16030
|
+
componentDidCatch(err, info) { console.error('[metaphysics] 面板渲染异常', err, info); }
|
|
16031
|
+
render() {
|
|
16032
|
+
if (!this.state.err) return this.props.children;
|
|
16033
|
+
const e = this.state.err;
|
|
16034
|
+
const stack = String((e && e.stack) || '').split('\n').slice(0, 14).join('\n');
|
|
16035
|
+
return h('div', { className: 'mp-wrap' }, h('div', { className: 'mp-panel' },
|
|
16036
|
+
h('div', { className: 'mp-lbl' }, '命理面板渲染出错——把下面这段发给我'),
|
|
16037
|
+
h('pre', { style: { whiteSpace: 'pre-wrap', fontSize: 12, lineHeight: 1.5, maxHeight: 320, overflow: 'auto', margin: '8px 0' } },
|
|
16038
|
+
String((e && e.message) || e) + '\n\n' + stack),
|
|
16039
|
+
h('div', { className: 'mp-lbl' }, '环境:__PP ' + (typeof PP) + ' · Engine ' + (typeof window.Engine) + ' · React ' + (typeof React) + ' · 版本 ' + (typeof PP === 'object' && PP && (window.__MP_VER || '?'))),
|
|
16040
|
+
));
|
|
16041
|
+
}
|
|
16042
|
+
}
|
|
16043
|
+
|
|
15253
16044
|
function PanelIcon(props) {
|
|
15254
16045
|
const size = props && props.size ? props.size : 20;
|
|
15255
16046
|
const active = props && props.active;
|
|
@@ -15280,7 +16071,7 @@ const TABS = [
|
|
|
15280
16071
|
{ k: 'xiaoliuren', label: '小六壬', timeLabel: '起课时刻', hint: '小六壬用农历月/日/时掐指,也可用三个随机数起课。' },
|
|
15281
16072
|
{ k: 'star', label: '星座', timeLabel: '', hint: '星座按公历日期给出太阳星座与当日基调;同日同星座结果固定。' },
|
|
15282
16073
|
{ k: 'numerology', label: '生命数字', timeLabel: '', hint: '生命数字按公历生日归约出生命路径数、生日数与态度数。' },
|
|
15283
|
-
{ k: 'mbti', label: '人格', timeLabel: '', hint: '
|
|
16074
|
+
{ k: 'mbti', label: '人格', timeLabel: '', hint: '十六型人格是 24 道自我报告题的 MBTI 风格测算:4 题一页,按 1–5 打分,答满 12 题即可看结果;只作自我参照,不是官方量表。' },
|
|
15284
16075
|
{ k: 'trend', label: '人生K线', timeLabel: '出生时刻', hint: '人生 K 线按大运与流年十神给逐年运势分,画成走势图。' },
|
|
15285
16076
|
{ k: 'fengshui', label: '风水', timeLabel: '', hint: '风水看八宅命卦、大游年四吉四凶与流年九宫飞星;也可按坐向看门主灶倾向。' },
|
|
15286
16077
|
{ k: 'name', label: '起名', timeLabel: '', hint: '起名按八字喜用匹配字库五行,可评估现有名字或生成候选名。' },
|
|
@@ -15308,6 +16099,85 @@ const kindOf = (t) => TIME_KIND[t] || 'none';
|
|
|
15308
16099
|
const Core = window.__MPCore || {};
|
|
15309
16100
|
const needAsk = Core.needAsk || ((t) => false);
|
|
15310
16101
|
|
|
16102
|
+
const COMPOSER = { ref: null, seats: [], keys: '', injectType: '', spec: '', errs: [], regs: 0, mounted: 0 };
|
|
16103
|
+
const LAST = { r: null, q: '' };
|
|
16104
|
+
|
|
16105
|
+
function bridgeDiagText() {
|
|
16106
|
+
const bits = [];
|
|
16107
|
+
bits.push('inputActions ' + (COMPOSER.ref ? '已拿到' : '未拿到'));
|
|
16108
|
+
bits.push('渲染 ' + COMPOSER.mounted + ' 次');
|
|
16109
|
+
bits.push('注册 ' + COMPOSER.regs + ' 次');
|
|
16110
|
+
bits.push('inject ' + (COMPOSER.injectType || '?'));
|
|
16111
|
+
bits.push('槽位 ' + (COMPOSER.spec || '?'));
|
|
16112
|
+
if (COMPOSER.errs.length) bits.push('错误:' + COMPOSER.errs.join(' / '));
|
|
16113
|
+
return '桥自检:' + bits.join(';');
|
|
16114
|
+
}
|
|
16115
|
+
|
|
16116
|
+
function noteRegError(e) {
|
|
16117
|
+
if (COMPOSER.errs.length >= 3) return;
|
|
16118
|
+
const s = e && e.message ? String(e.message) : String(e);
|
|
16119
|
+
COMPOSER.errs.push(s.slice(0, 90));
|
|
16120
|
+
}
|
|
16121
|
+
function bridgeActions(props) {
|
|
16122
|
+
if (!props) return null;
|
|
16123
|
+
const a = props.inputActions;
|
|
16124
|
+
if (a && typeof a.setDraft === 'function' && typeof a.submit === 'function') return a;
|
|
16125
|
+
const b = props.actions && props.actions.input;
|
|
16126
|
+
if (b && typeof b.setDraft === 'function' && typeof b.submit === 'function') return b;
|
|
16127
|
+
return null;
|
|
16128
|
+
}
|
|
16129
|
+
|
|
16130
|
+
function useBridge(props, name) {
|
|
16131
|
+
const actions = bridgeActions(props);
|
|
16132
|
+
useEffect(() => {
|
|
16133
|
+
if (COMPOSER.seats.indexOf(name) < 0) COMPOSER.seats.push(name);
|
|
16134
|
+
COMPOSER.keys = props ? Object.keys(props).join(',') : '';
|
|
16135
|
+
if (actions) {
|
|
16136
|
+
COMPOSER.ref = actions;
|
|
16137
|
+
try { window.__MPComposer = actions; } catch (e) { /* 非浏览器环境忽略 */ }
|
|
16138
|
+
}
|
|
16139
|
+
return () => { if (COMPOSER.ref === actions) COMPOSER.ref = null; };
|
|
16140
|
+
}, [actions, name]);
|
|
16141
|
+
return actions;
|
|
16142
|
+
}
|
|
16143
|
+
|
|
16144
|
+
function askTextForLast() {
|
|
16145
|
+
const r = LAST.r;
|
|
16146
|
+
if (!r) return '';
|
|
16147
|
+
try {
|
|
16148
|
+
const p = Engine.askPrompt ? Engine.askPrompt(r, { question: LAST.q }) : null;
|
|
16149
|
+
return (p && p.text) || String(r.summary || '');
|
|
16150
|
+
} catch (e) { return String(r.summary || ''); }
|
|
16151
|
+
}
|
|
16152
|
+
|
|
16153
|
+
function ComposerBridge(props) {
|
|
16154
|
+
COMPOSER.mounted += 1;
|
|
16155
|
+
const actions = useBridge(props, 'input.right');
|
|
16156
|
+
if (!actions) {
|
|
16157
|
+
return h('span', { className: 'mp-chip warn', title: '命理:已占住输入框槽位,但没拿到 inputActions;把这句话告诉作者' }, '命理·未就绪');
|
|
16158
|
+
}
|
|
16159
|
+
return h('button', {
|
|
16160
|
+
type: 'button', className: 'mp-chip ok',
|
|
16161
|
+
title: LAST.r ? '把上一张盘的摘要和问题发进对话窗' : '先在侧栏「命理」里排一张盘',
|
|
16162
|
+
onClick: () => { const t = askTextForLast(); if (t) sendToComposer(t); },
|
|
16163
|
+
}, '命理·问');
|
|
16164
|
+
}
|
|
16165
|
+
|
|
16166
|
+
function ComposerProbe(props) {
|
|
16167
|
+
COMPOSER.mounted += 1;
|
|
16168
|
+
useBridge(props, 'composer.dock');
|
|
16169
|
+
return null;
|
|
16170
|
+
}
|
|
16171
|
+
|
|
16172
|
+
function sendToComposer(text) {
|
|
16173
|
+
let ia = COMPOSER.ref;
|
|
16174
|
+
if (!ia) { try { ia = window.__MPComposer || null; } catch (e) { ia = null; } }
|
|
16175
|
+
if (!ia || typeof ia.setDraft !== 'function' || typeof ia.submit !== 'function') return false;
|
|
16176
|
+
ia.setDraft(text);
|
|
16177
|
+
ia.submit();
|
|
16178
|
+
return true;
|
|
16179
|
+
}
|
|
16180
|
+
|
|
15311
16181
|
function App() {
|
|
15312
16182
|
const [tab, setTab] = useState('ziwei');
|
|
15313
16183
|
const [date, setDate] = useState('1990-05-12');
|
|
@@ -15325,6 +16195,7 @@ function App() {
|
|
|
15325
16195
|
const [qLateZi, setQLateZi] = useState('same-day');
|
|
15326
16196
|
const [crossOn, setCrossOn] = useState(false);
|
|
15327
16197
|
const [askText, setAskText] = useState('');
|
|
16198
|
+
const [chatNote, setChatNote] = useState('');
|
|
15328
16199
|
const [fx, setFx] = useState(null);
|
|
15329
16200
|
const [pastMarks, setPastMarks] = useState({});
|
|
15330
16201
|
const [fit, setFit] = useState(null);
|
|
@@ -15338,7 +16209,8 @@ function App() {
|
|
|
15338
16209
|
const [leapMonth, setLeapMonth] = useState(false);
|
|
15339
16210
|
const [xlrMode, setXlrMode] = useState('time');
|
|
15340
16211
|
const [num1, setNum1] = useState(''); const [num2, setNum2] = useState(''); const [num3, setNum3] = useState('');
|
|
15341
|
-
const [
|
|
16212
|
+
const [mbAns, setMbAns] = useState(() => new Array(mbtiInfo().total).fill(null));
|
|
16213
|
+
const [mbPage, setMbPage] = useState(0);
|
|
15342
16214
|
const [toAge, setToAge] = useState('60');
|
|
15343
16215
|
const [fsMode, setFsMode] = useState('natal');
|
|
15344
16216
|
const [sitting, setSitting] = useState('子');
|
|
@@ -15350,6 +16222,9 @@ function App() {
|
|
|
15350
16222
|
const [onlineGeo, setOnlineGeo] = useState(false);
|
|
15351
16223
|
const [lines, setLines] = useState('');
|
|
15352
16224
|
const [result, setResult] = useState(null);
|
|
16225
|
+
useEffect(() => {
|
|
16226
|
+
if (result && result.r) { LAST.r = result.r; LAST.q = askText.trim(); }
|
|
16227
|
+
}, [result, askText]);
|
|
15353
16228
|
const [hist, setHist] = useState(() => loadHistory());
|
|
15354
16229
|
const [replayArgs, setReplayArgs] = useState(null);
|
|
15355
16230
|
const [error, setError] = useState('');
|
|
@@ -15371,7 +16246,7 @@ function App() {
|
|
|
15371
16246
|
|| tab === 'chenggu' || tab === 'trend' || tab === 'fengshui' || tab === 'name';
|
|
15372
16247
|
const timeKind = kindOf(tab);
|
|
15373
16248
|
const usesTimeInput = !(tab === 'meihua' && mhMode === 'number');
|
|
15374
|
-
const showDate = tab !== 'tarot' && usesTimeInput;
|
|
16249
|
+
const showDate = tab !== 'tarot' && tab !== 'mbti' && usesTimeInput;
|
|
15375
16250
|
const showTime = showDate && timeKind !== 'date';
|
|
15376
16251
|
const showDT = showTime;
|
|
15377
16252
|
|
|
@@ -15381,6 +16256,7 @@ function App() {
|
|
|
15381
16256
|
const dt = override ? override : { date, time };
|
|
15382
16257
|
const genderV = over && over.gender ? over.gender : gender;
|
|
15383
16258
|
const addressV = over && typeof over.address === 'string' ? over.address : address;
|
|
16259
|
+
setNotice(''); // 上一次的提示(如「先答满 12 题」)不该跟着新结果一起留下
|
|
15384
16260
|
try {
|
|
15385
16261
|
const datetime = `${dt.date}T${dt.time}`;
|
|
15386
16262
|
const args = { system: k };
|
|
@@ -15427,7 +16303,8 @@ function App() {
|
|
|
15427
16303
|
}
|
|
15428
16304
|
if (k === 'mbti') {
|
|
15429
16305
|
delete args.datetime;
|
|
15430
|
-
const nums =
|
|
16306
|
+
const nums = mbAns.slice();
|
|
16307
|
+
while (nums.length && nums[nums.length - 1] == null) nums.pop();
|
|
15431
16308
|
if (nums.length) args.answers = nums;
|
|
15432
16309
|
}
|
|
15433
16310
|
if (k === 'trend') { args.gender = genderV; args.toAge = Number(toAge) || 60; args.trueSolar = trueSolar; args.lateZi = lateZi; }
|
|
@@ -15528,7 +16405,7 @@ function App() {
|
|
|
15528
16405
|
setResult({ kind: k, r, it, at: dt, timed, trend });
|
|
15529
16406
|
setFx(null); setFit(null); setPastMarks({}); setRectRes(null);
|
|
15530
16407
|
setError(''); setCopied('');
|
|
15531
|
-
if (k !== 'tarot') {
|
|
16408
|
+
if (k !== 'tarot' && k !== 'mbti') {
|
|
15532
16409
|
const entry = {
|
|
15533
16410
|
kind: k, date, time, gender, address,
|
|
15534
16411
|
lines: k === 'liuyao' ? lines : '',
|
|
@@ -15554,6 +16431,12 @@ function App() {
|
|
|
15554
16431
|
const k = kindOf(next);
|
|
15555
16432
|
setTab(next);
|
|
15556
16433
|
setError('');
|
|
16434
|
+
if (next === 'mbti') {
|
|
16435
|
+
setNotice('');
|
|
16436
|
+
if (mbAns.filter((v) => v != null).length >= MBTI_MIN) run(next);
|
|
16437
|
+
else setResult(null);
|
|
16438
|
+
return;
|
|
16439
|
+
}
|
|
15557
16440
|
if (k === 'none') { run(next); return; } // 塔罗不看时间,直接抽牌(与 web-ui 一致)
|
|
15558
16441
|
const v = manual[k] || (k === 'cast' ? nowParts() : { date: SAMPLE.date, time: SAMPLE.time });
|
|
15559
16442
|
setDate(v.date);
|
|
@@ -15579,6 +16462,15 @@ function App() {
|
|
|
15579
16462
|
};
|
|
15580
16463
|
|
|
15581
16464
|
const go = () => {
|
|
16465
|
+
if (tab === 'mbti') {
|
|
16466
|
+
const n = mbAns.filter((v) => v != null).length;
|
|
16467
|
+
if (n < MBTI_MIN) {
|
|
16468
|
+
setNotice(`先答满 ${MBTI_MIN} 题再看结果(现答 ${n} 题,还差 ${MBTI_MIN - n} 题)。`);
|
|
16469
|
+
return;
|
|
16470
|
+
}
|
|
16471
|
+
run(tab);
|
|
16472
|
+
return;
|
|
16473
|
+
}
|
|
15582
16474
|
if (timeKind !== 'none' && !manual[timeKind]) {
|
|
15583
16475
|
const t = nowParts();
|
|
15584
16476
|
setDate(t.date);
|
|
@@ -15651,6 +16543,21 @@ function App() {
|
|
|
15651
16543
|
} catch (e) { setFx({ question: askText.trim(), ok: false, answer: '追问失败:' + (e && e.message ? e.message : e), evidence: [], confidence: '弱' }); }
|
|
15652
16544
|
};
|
|
15653
16545
|
|
|
16546
|
+
const askInChat = () => {
|
|
16547
|
+
if (!result || !result.r) return;
|
|
16548
|
+
try {
|
|
16549
|
+
const p = Engine.askPrompt ? Engine.askPrompt(result.r, { question: askText.trim() }) : null;
|
|
16550
|
+
const text = p && p.text ? p.text : String(result.r.summary || '');
|
|
16551
|
+
if (sendToComposer(text)) { setChatNote('已发到对话窗,往下看回复。'); return; }
|
|
16552
|
+
const diag = '(' + bridgeDiagText() + ')';
|
|
16553
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
16554
|
+
navigator.clipboard.writeText(text).then(
|
|
16555
|
+
() => setChatNote('对话输入框还没就绪' + diag + ',已复制提问;粘进对话窗回车即可。'),
|
|
16556
|
+
() => setChatNote('对话输入框还没就绪' + diag + ',复制也没成功;先点「复制文字结果」再贴。'));
|
|
16557
|
+
} else { setChatNote('对话输入框还没就绪' + diag + ';先点「复制文字结果」再贴进对话窗。'); }
|
|
16558
|
+
} catch (e) { setChatNote('发到对话窗失败:' + (e && e.message ? e.message : e)); }
|
|
16559
|
+
};
|
|
16560
|
+
|
|
15654
16561
|
const downloadReport = () => {
|
|
15655
16562
|
if (!result || !result.r) return;
|
|
15656
16563
|
try {
|
|
@@ -15874,10 +16781,27 @@ function App() {
|
|
|
15874
16781
|
className: 'mp-input', type: 'number', min: 1, max: 99, value: num3,
|
|
15875
16782
|
onChange: (e) => setNum3(e.target.value),
|
|
15876
16783
|
})) : null,
|
|
15877
|
-
tab === 'mbti' ?
|
|
15878
|
-
className: 'mp-
|
|
15879
|
-
|
|
15880
|
-
|
|
16784
|
+
tab === 'mbti' ? h('div', { className: 'mp-quiz-wrap' },
|
|
16785
|
+
h('div', { className: 'mp-lbl' }, '十六型人格问卷 · 4 题一页,按 1(完全不像)到 5(很像我)打分'),
|
|
16786
|
+
h(MbtiQuiz, {
|
|
16787
|
+
answers: mbAns,
|
|
16788
|
+
page: mbPage,
|
|
16789
|
+
onPick: (i, n) => setMbAns((prev) => {
|
|
16790
|
+
const next = prev.slice();
|
|
16791
|
+
next[i] = n;
|
|
16792
|
+
return next;
|
|
16793
|
+
}),
|
|
16794
|
+
onPage: (d) => setMbPage((p) => Math.max(0, Math.min(
|
|
16795
|
+
p + d,
|
|
16796
|
+
Math.max(0, Math.ceil(mbtiInfo().total / MBTI_PER_PAGE) - 1),
|
|
16797
|
+
))),
|
|
16798
|
+
onSubmit: go,
|
|
16799
|
+
onClear: () => {
|
|
16800
|
+
setMbAns(new Array(mbtiInfo().total).fill(null));
|
|
16801
|
+
setMbPage(0);
|
|
16802
|
+
setResult(null);
|
|
16803
|
+
},
|
|
16804
|
+
})) : null,
|
|
15881
16805
|
tab === 'trend' ? field('算到几岁', h('input', {
|
|
15882
16806
|
className: 'mp-input', type: 'number', min: 10, max: 100, value: toAge,
|
|
15883
16807
|
onChange: (e) => setToAge(e.target.value),
|
|
@@ -15926,7 +16850,7 @@ function App() {
|
|
|
15926
16850
|
onChange: (e) => { setQuestion(e.target.value); setAskInvalid(false); },
|
|
15927
16851
|
onBlur: (e) => refreshInterpret(undefined, e.target.value),
|
|
15928
16852
|
})) : null,
|
|
15929
|
-
h('div', { key: 'actions', className: 'mp-actions' },
|
|
16853
|
+
tab === 'mbti' ? null : h('div', { key: 'actions', className: 'mp-actions' },
|
|
15930
16854
|
h('button', {
|
|
15931
16855
|
className: 'mp-btn ghost', style: { fontSize: 12, padding: '5px 12px', marginRight: 8 },
|
|
15932
16856
|
onClick: openSample, title: '用固定示例盘看完整报告(不改动你已填的数据)',
|
|
@@ -15958,9 +16882,13 @@ function App() {
|
|
|
15958
16882
|
notice ? h('div', { key: 'ntc', className: 'mp-note', role: 'status' }, notice) : null,
|
|
15959
16883
|
|
|
15960
16884
|
(!result && !error) ? h('div', { key: 'empty', className: 'mp-empty' },
|
|
15961
|
-
h('b', null, tab === 'ziwei'
|
|
15962
|
-
: tab === 'tarot' ? '写下想问的事,点「抽牌」'
|
|
15963
|
-
|
|
16885
|
+
h('b', null, tab === 'ziwei' || tab === 'bazi' ? '填好出生信息,点「排盘」'
|
|
16886
|
+
: tab === 'tarot' ? '写下想问的事,点「抽牌」'
|
|
16887
|
+
: tab === 'mbti' ? '按 1–5 给题目打分,答满 12 题就能看结果'
|
|
16888
|
+
: '写下所问之事,点「起卦」'),
|
|
16889
|
+
tab === 'ziwei' || tab === 'bazi' ? '出生日期、时刻与性别即可;出生地只影响真太阳时。'
|
|
16890
|
+
: tab === 'mbti' ? '4 题一页,答案只在本地参与计算,不会上传。'
|
|
16891
|
+
: '起卦时刻已自动取当下,也可以手动改。') : null,
|
|
15964
16892
|
|
|
15965
16893
|
result ? h('div', {
|
|
15966
16894
|
key: 'card',
|
|
@@ -16003,14 +16931,20 @@ function App() {
|
|
|
16003
16931
|
onClick: downloadCard, title: '生成 PNG 摘要卡(一页读懂 + 首张表),适合直接分享',
|
|
16004
16932
|
}, '存为摘要长图')) : null,
|
|
16005
16933
|
|
|
16006
|
-
result ? h('div', { key: 'ask', className: 'mp-askbox' },
|
|
16934
|
+
result ? h('div', { key: 'ask', className: 'mp-askbox', style: { flexWrap: 'wrap' } },
|
|
16007
16935
|
h('input', {
|
|
16008
16936
|
className: 'mp-input', value: askText, maxLength: 120,
|
|
16009
16937
|
placeholder: '追问:如 2027 年事业怎么样(回车提交)',
|
|
16010
16938
|
onChange: (e) => setAskText(e.target.value),
|
|
16011
16939
|
onKeyDown: (e) => { if (e.key === 'Enter') doAsk(); },
|
|
16012
16940
|
}),
|
|
16013
|
-
h('button', { className: 'mp-btn ghost', style: { fontSize: 12, padding: '5px 12px' }, onClick: doAsk }, '追问')
|
|
16941
|
+
h('button', { className: 'mp-btn ghost', style: { fontSize: 12, padding: '5px 12px' }, onClick: doAsk }, '追问'),
|
|
16942
|
+
h('button', {
|
|
16943
|
+
className: 'mp-btn ghost', style: { fontSize: 12, padding: '5px 12px', marginLeft: 8 },
|
|
16944
|
+
onClick: askInChat, title: '把这张盘的摘要和你的问题一起发进 DSH 对话窗,由对话里的模型接着答',
|
|
16945
|
+
}, '问进对话'),
|
|
16946
|
+
(COMPOSER.ref ? null : h('div', { key: 'bridgediag', className: 'mp-note', style: { marginTop: 6, fontSize: 11, flexBasis: '100%' } }, bridgeDiagText())),
|
|
16947
|
+
chatNote ? h('div', { key: 'chatnote', className: 'mp-note', style: { marginTop: 6, fontSize: 12, flexBasis: '100%' } }, chatNote) : null) : null,
|
|
16014
16948
|
|
|
16015
16949
|
fx ? h('div', { key: 'fx', className: 'mp-fx', dangerouslySetInnerHTML: { __html: PP.followupHTML(fx) } }) : null,
|
|
16016
16950
|
|
|
@@ -16094,6 +17028,25 @@ function safeApply(ctx) {
|
|
|
16094
17028
|
return;
|
|
16095
17029
|
}
|
|
16096
17030
|
|
|
17031
|
+
try {
|
|
17032
|
+
COMPOSER.injectType = typeof slots.inject;
|
|
17033
|
+
const sp = typeof slots.spec === 'function' ? slots.spec('conversation.input.right') : null;
|
|
17034
|
+
COMPOSER.spec = sp ? sp.kind + '/' + sp.scope : '未声明';
|
|
17035
|
+
} catch (e) {
|
|
17036
|
+
COMPOSER.spec = '取声明失败';
|
|
17037
|
+
noteRegError(e);
|
|
17038
|
+
}
|
|
17039
|
+
const tryReg = (options, component) => {
|
|
17040
|
+
try {
|
|
17041
|
+
const d = slots.register(options, component);
|
|
17042
|
+
COMPOSER.regs += 1;
|
|
17043
|
+
return d;
|
|
17044
|
+
} catch (e) {
|
|
17045
|
+
noteRegError(e);
|
|
17046
|
+
return null;
|
|
17047
|
+
}
|
|
17048
|
+
};
|
|
17049
|
+
|
|
16097
17050
|
const waitFor = (key, install) => {
|
|
16098
17051
|
try {
|
|
16099
17052
|
if (typeof slots.inject === 'function') {
|
|
@@ -16107,12 +17060,59 @@ function safeApply(ctx) {
|
|
|
16107
17060
|
}
|
|
16108
17061
|
};
|
|
16109
17062
|
|
|
16110
|
-
waitFor('sidebar.panellist', () =>
|
|
16111
|
-
{ name: 'sidebar.panellist', id: 'metaphysics', order: 20, label: () => '命理' },
|
|
17063
|
+
waitFor('sidebar.panellist', () => tryReg(
|
|
17064
|
+
{ name: 'sidebar.panellist', id: 'metaphysics', order: 20, label: () => '命理 v' + (window.__MP_VER || '') },
|
|
16112
17065
|
PanelIcon,
|
|
16113
17066
|
));
|
|
16114
17067
|
|
|
16115
|
-
waitFor('main', () =>
|
|
17068
|
+
waitFor('main', () => tryReg({ name: 'main', key: 'metaphysics' }, (p) => h(PanelGuard, null, h(App, p))));
|
|
17069
|
+
|
|
17070
|
+
const sessionSeat = (key, install) => {
|
|
17071
|
+
const run = () => {
|
|
17072
|
+
try { slots.inject(key, install); }
|
|
17073
|
+
catch (e) {
|
|
17074
|
+
console.error('[metaphysics] 槽位注册失败:' + key, e);
|
|
17075
|
+
try { install(); } catch (e2) { console.error('[metaphysics] 直接注册也失败:' + key, e2); }
|
|
17076
|
+
}
|
|
17077
|
+
};
|
|
17078
|
+
try {
|
|
17079
|
+
if (typeof ctx.effect === 'function') ctx.effect(run, 'metaphysics: ' + key);
|
|
17080
|
+
else run();
|
|
17081
|
+
} catch (e) {
|
|
17082
|
+
console.error('[metaphysics] effect 包裹失败:' + key, e);
|
|
17083
|
+
run();
|
|
17084
|
+
}
|
|
17085
|
+
};
|
|
17086
|
+
|
|
17087
|
+
sessionSeat('conversation.input.right', () => tryReg(
|
|
17088
|
+
{ name: 'conversation.input.right', id: 'metaphysics-ask', order: 40 },
|
|
17089
|
+
ComposerBridge,
|
|
17090
|
+
));
|
|
17091
|
+
|
|
17092
|
+
sessionSeat('conversation.composer.dock', () => tryReg(
|
|
17093
|
+
{ name: 'conversation.composer.dock', id: 'metaphysics-dock', order: 60 },
|
|
17094
|
+
ComposerProbe,
|
|
17095
|
+
));
|
|
17096
|
+
|
|
17097
|
+
let seatTries = 0;
|
|
17098
|
+
const trySeatNow = () => {
|
|
17099
|
+
if (COMPOSER.ref) return;
|
|
17100
|
+
seatTries += 1;
|
|
17101
|
+
const tag = '-' + seatTries;
|
|
17102
|
+
tryReg({ name: 'conversation.input.right', id: 'metaphysics-ask' + tag, order: 40 }, ComposerBridge);
|
|
17103
|
+
tryReg({ name: 'conversation.composer.dock', id: 'metaphysics-dock' + tag, order: 60 }, ComposerProbe);
|
|
17104
|
+
};
|
|
17105
|
+
let seatTriesLeft = 20;
|
|
17106
|
+
const seatRetry = () => {
|
|
17107
|
+
if (COMPOSER.ref || seatTriesLeft <= 0) return;
|
|
17108
|
+
seatTriesLeft -= 1;
|
|
17109
|
+
trySeatNow();
|
|
17110
|
+
setTimeout(seatRetry, 700);
|
|
17111
|
+
};
|
|
17112
|
+
try { setTimeout(seatRetry, 700); } catch (e) { /* 无计时器环境 */ }
|
|
17113
|
+
try {
|
|
17114
|
+
document.addEventListener('pointerdown', () => trySeatNow(), { once: true, capture: true });
|
|
17115
|
+
} catch (e) { /* 非 DOM 环境 */ }
|
|
16116
17116
|
}
|
|
16117
17117
|
|
|
16118
17118
|
return {
|