/** * 梅花易数证据链架构 * 参考 mingyu 项目的 evidence 模式,为排盘结果增加结构化证据链 * * 核心原则: * - 每个 fact 必须有具体的 limitation(不能是泛泛免责) * - 证据链是增强层,不破坏现有排盘流程 * - 支持/约束/反证三位一体 */ import { WUXING_SHENG, WUXING_KE, getTrigramByNumber } from './trigrams.js'; import type { HuaResult } from './analysis.js'; import { getTraditionalText } from './tradition.js'; // ═══════════════════════════════════════════ // 类型定义 // ═══════════════════════════════════════════ /** 证据阶段键 */ export type MeihuaStageKey = 'origin' | 'process' | 'result'; /** MeihuaFact 基础接口 — 所有 fact 的公共字段 */ export interface MeihuaFact { key: string; status: string; promptText: string; sources: string[]; limitation: string; } /** 卦象结构事实 */ export interface HexagramStructureFact extends MeihuaFact { stage: MeihuaStageKey; label: '主卦' | '互卦' | '变卦'; hexagramName: string; symbol: string; upperTrigram: string; lowerTrigram: string; nature: string; judgment: string; } /** 阶段体用事实 */ export interface StageEvidence extends MeihuaFact { stage: MeihuaStageKey; label: string; hexagramName: string; ti: { name: string; element: string; seasonState: string }; yong: { name: string; element: string; seasonState: string }; relation: string; support: string[]; constraints: string[]; basis: string; } /** 阶段推进事实(主→互→变的体用关系变化) */ export interface TransitionFact extends MeihuaFact { fromStageKey: string; toStageKey: string; fromStage: MeihuaStageKey; toStage: MeihuaStageKey; fromRelation: string; toRelation: string; } /** 反证事实 */ export interface CounterEvidenceFact extends MeihuaFact { ownerStageKey: string; stage: MeihuaStageKey; type: '体用关系限制' | '体卦月令限制' | '用卦月令限制' | '现实复核限制'; detail: string; } /** 应期事实 */ export interface TimingFact extends MeihuaFact { order: number; type: '动爻层位' | '月建旺衰' | '体卦状态' | '原应期条件'; rawText?: string; } /** 传统文本事实(卦辞/爻辞) */ export interface TraditionalTextFact extends MeihuaFact { stage: '主卦' | '互卦' | '变卦'; hexagram: string; kind: '卦辞' | '爻辞' | '用辞'; yaoPosition?: number; applicability: '当前卦辞辅助' | '当前动爻辅助' | '未发动背景' | '特殊用辞背景'; originalText: string; traditionalSignals: string[]; topicTags: string[]; } /** 完整的证据链分析结果 */ export interface MeihuaEvidenceAnalysis { key: 'meihua:evidence'; status: '已计算'; // 卦象结构 hexagramFacts: HexagramStructureFact[]; // 阶段体用 stages: StageEvidence[]; // 阶段推进 transitionFacts: TransitionFact[]; // 反证 counterEvidenceFacts: CounterEvidenceFact[]; counterSummary: { status: '有明确反证' | '未见明确反证'; detail: string }; // 应期 timingFacts: TimingFact[]; // 传统文本 traditionalFacts: TraditionalTextFact[]; // 汇总 summary: { factCount: number; stageCount: number; transitionCount: number; counterCount: number; traditionalCount: number; timingCount: number; }; // 全局限制 limitations: string[]; // 原始 prompt 文本 promptText: string; } // ═══════════════════════════════════════════ // 限制声明常量(每个类型的具体约束) // ═══════════════════════════════════════════ const STAGE_FACT_LIMITATION = '阶段体用事实只描述主卦、互卦或变卦中的体用五行关系与月令旺衰;阶段标签、支持或限制不得直接解释为现实起因、过程、结果、吉凶或成功率' as const; const HEXAGRAM_FACT_LIMITATION = '主互变卦象事实只记录当前上下经卦、卦名与卦符;不得由卦名或阶段位置直接推断现实事件、人物、吉凶、成败或应期' as const; const TRANSITION_FACT_LIMITATION = '阶段推进事实只比较相邻已记录阶段的体用关系变化;不得把卦内先后直接写成现实事件必然按同样顺序发生,跨阶段缺口时更不得补造中间过程' as const; const COUNTER_FACT_LIMITATION = '反证事实只表示某一阶段存在泄耗、受克、休囚死或待现实复核等限制;不得把单项反证直接写成现实失败、灾祸、伤病、损失或必然结果' as const; const COUNTER_SUMMARY_LIMITATION = '反证汇总只说明当前阶段核验是否发现明确限制;未见明确反证不代表现实风险为零,也不得按反证数量换算吉凶总分或成功率' as const; const TIMING_FACT_LIMITATION = '应期事实只提供动爻层位、体用生克、月令旺衰与现实条件的相对触发;不得把爻位、卦数、阶段数量或旺衰换算唯一日期,也不证明事件必然发生' as const; const TRADITIONAL_FACT_LIMITATION = '卦辞与爻辞是《周易》传统取象原文,只用于当前主互变结构和动爻层位的辅助解释,不证明现实吉凶、婚育、疾病、伤亡、诉讼、财物得失、人物意图或固定时间结果' as const; const SUMMARY_FACT_LIMITATION = '梅花证据汇总只统计起卦、主互变卦象、体用、推进、传统文本、反证与应期事实的覆盖情况;不得按数量生成吉凶总分、成功率、人物意图或唯一日期' as const; // ═══════════════════════════════════════════ // 辅助函数 // ═══════════════════════════════════════════ function unique(values: string[]): string[] { return Array.from(new Set(values.filter(Boolean))); } /** 判断旺相休囚死 */ function getSeasonState(element: string, season: string): string { const s = season; // 旺 if ((s.includes('春') && element === '木') || (s.includes('夏') && element === '火') || (s.includes('秋') && element === '金') || (s.includes('冬') && element === '水') || (s.includes('末') && element === '土')) return '旺'; // 相(被旺者所生) if ((s.includes('春') && element === '火') || (s.includes('夏') && element === '土') || (s.includes('秋') && element === '水') || (s.includes('冬') && element === '木') || (s.includes('末') && element === '金')) return '相'; // 休(生旺者) if ((s.includes('春') && element === '水') || (s.includes('夏') && element === '木') || (s.includes('秋') && element === '土') || (s.includes('冬') && element === '金') || (s.includes('末') && element === '火')) return '休'; // 囚(克旺者) if ((s.includes('春') && element === '金') || (s.includes('夏') && element === '水') || (s.includes('秋') && element === '木') || (s.includes('冬') && element === '土') || (s.includes('末') && element === '火')) return '囚'; // 死(被旺者所克,或被克者) return '死'; } /** 体用关系 → 支持/约束 */ function relationEvidence(relation: string): { support: string[]; constraints: string[] } { switch (relation) { case '用生体': return { support: ['外来助力生扶体卦'], constraints: [] }; case '比和': return { support: ['体用同五行,关系同气'], constraints: ['仍须结合旺衰与现实条件'] }; case '体克用': return { support: ['体卦对用卦具有制约能力'], constraints: ['主动推进可能伴随消耗'] }; case '体生用': return { support: ['体卦向事项一方投入'], constraints: ['体卦存在泄耗'] }; case '用克体': return { support: [], constraints: ['外部事项对体卦形成压力'] }; default: return { support: [], constraints: ['现有资料不足以确定五行关系'] }; } } /** 旺衰 → 支持/约束 */ function stateEvidence(role: '体' | '用', state: string): { support: string[]; constraints: string[] } { if (state === '旺' || state === '相') return { support: [`${role}卦得月令${state}`], constraints: [] }; if (state === '休' || state === '囚' || state === '死') return { support: [], constraints: [`${role}卦月令${state}`] }; return { support: [], constraints: [] }; } /** 判断五行关系(返回简化标签) */ function getRelationLabel(tiElement: string, yongElement: string): string { if (tiElement === yongElement) return '比和'; if (WUXING_SHENG[yongElement] === tiElement) return '用生体'; if (WUXING_SHENG[tiElement] === yongElement) return '体生用'; if (WUXING_KE[yongElement] === tiElement) return '用克体'; if (WUXING_KE[tiElement] === yongElement) return '体克用'; return '关系未定'; } /** 传统文本信号分类 */ function classifyTraditionalSignals(text: string): string[] { const riskText = text.replace(/无咎|无悔|悔亡|无不利/g, ''); return unique([ /吉|亨|利|无咎|悔亡|无悔|无不利/.test(text) ? '传统有利或通达标签' : '', /凶|厉|吝|悔|咎|灾|不利|无攸利/.test(riskText) ? '传统风险或受限标签' : '', /贞|永贞/.test(text) ? '守正与持续条件标签' : '', /往|征|涉|行|进|退|出|入/.test(text) ? '行动与进退标签' : '', ]); } /** 传统文本主题分类 */ function classifyTraditionalTopics(text: string): string[] { return unique([ /女|妇|婚|归妹|孕|夫|妻/.test(text) ? '关系与婚育类象' : '', /死|疾|病|灾|伤|血|丧|亡/.test(text) ? '健康伤亡与损失类象' : '', /讼|狱|刑|伐|师|寇|攻/.test(text) ? '争议、刑罚与攻守类象' : '', /财|资|获|得|食|畜|货/.test(text) ? '资源与得失类象' : '', /年|月|日|岁|旬|三年|八月/.test(text) ? '传统时间措辞' : '', /王|君子|大人|小人|侯/.test(text) ? '身份与角色类象' : '', ]); } // ═══════════════════════════════════════════ // 证据链生成函数 // ═══════════════════════════════════════════ /** * 为排盘结果生成完整证据链 * @param result calculateHua() 的返回值 * @param input 原始输入(用于获取起卦参数) */ export function buildEvidence(result: HuaResult): MeihuaEvidenceAnalysis { const season = result.wangShuai.season; const dongYao = result.dongYao; const tiElement = result.wuxingAnalysis.tiElement; const yongElement = result.wuxingAnalysis.yongElement; // ── 1. 卦象结构事实 ── const hexagramFacts = buildHexagramFacts(result); // ── 2. 阶段体用事实 ── const stages = buildStageEvidence(result, season); // ── 3. 阶段推进事实 ── const transitionFacts = buildTransitionFacts(stages); // ── 4. 反证 ── const counterEvidenceFacts = buildCounterEvidence(stages); const counterSummary = { status: counterEvidenceFacts.length > 0 ? '有明确反证' as const : '未见明确反证' as const, detail: counterEvidenceFacts.length > 0 ? `发现${counterEvidenceFacts.length}条反证:${counterEvidenceFacts.map(f => f.detail).join(';')}` : '当前盘面未见明确反证', limitation: COUNTER_SUMMARY_LIMITATION, }; // ── 5. 应期 ── const timingFacts = buildTimingFacts(result, season); // ── 6. 传统文本 ── const traditionalFacts = buildTraditionalFacts(result, dongYao); // ── 7. 汇总 ── const factCount = hexagramFacts.length + stages.length + transitionFacts.length + counterEvidenceFacts.length + timingFacts.length + traditionalFacts.length; const summary = { factCount, stageCount: stages.length, transitionCount: transitionFacts.length, counterCount: counterEvidenceFacts.length, traditionalCount: traditionalFacts.length, timingCount: timingFacts.length, limitation: SUMMARY_FACT_LIMITATION, }; // ── 全局限制 ── const limitations = [ '梅花易数证据链仅描述卦象结构、体用五行关系与月令旺衰,不证明现实吉凶、成败、概率或固定应期', '传统卦辞爻辞是《周易》原文辅助,不直接对应现实事件、人物、婚育、疾病、伤亡或诉讼', '反证与支持仅反映盘面五行生克状态,不代表现实中的必然结果或风险为零', '应期分析只提供相对触发条件,不得换算为绝对日期或时间节点', ]; // ── promptText ── const promptText = [ ...hexagramFacts.map(f => f.promptText), ...stages.map(f => f.promptText), ...transitionFacts.map(f => f.promptText), ...counterEvidenceFacts.map(f => f.promptText), counterSummary.detail, ...timingFacts.map(f => f.promptText), ...traditionalFacts.map(f => f.promptText), ].join('\n'); return { key: 'meihua:evidence', status: '已计算', hexagramFacts, stages, transitionFacts, counterEvidenceFacts, counterSummary, timingFacts, traditionalFacts, summary, limitations, promptText, }; } // ── 子生成器 ── function buildHexagramFacts(result: HuaResult): HexagramStructureFact[] { const defs = [ { stage: 'origin' as MeihuaStageKey, label: '主卦' as const, hex: result.mainHexagram.hexagram, upperName: result.mainHexagram.upper.name, lowerName: result.mainHexagram.lower.name }, { stage: 'process' as MeihuaStageKey, label: '互卦' as const, hex: result.mutualHexagram, upperName: result.mutualHexagram.upper.name, lowerName: result.mutualHexagram.lower.name }, { stage: 'result' as MeihuaStageKey, label: '变卦' as const, hex: result.changedHexagram, upperName: result.changedHexagram.upper.name, lowerName: result.changedHexagram.lower.name }, ]; return defs.map(({ stage, label, hex, upperName, lowerName }) => ({ key: `meihua:hexagram:${stage}`, status: '已记录', stage, label, hexagramName: hex.name, symbol: hex.symbol, upperTrigram: upperName, lowerTrigram: lowerName, nature: hex.nature, judgment: hex.judgment, promptText: `${label}${hex.name}${hex.symbol},上${upperName}下${lowerName},${hex.judgment}`, sources: ['先天八卦取数', '六十四卦结构'], limitation: HEXAGRAM_FACT_LIMITATION, })); } function buildStageEvidence(result: HuaResult, season: string): StageEvidence[] { const tiPos = result.tiGua.position; const yongPos = result.yongGua.position; // 主卦体用 const mainTiName = result.tiGua.trigram.name; const mainYongName = result.yongGua.trigram.name; const mainRelation = getRelationLabel(result.tiGua.trigram.element, result.yongGua.trigram.element); // 互卦体用:体卦位置不变,互卦对应位置 const mutualTiNum = tiPos === 'upper' ? result.mutualHexagram.upper : result.mutualHexagram.lower; const mutualYongNum = yongPos === 'upper' ? result.mutualHexagram.upper : result.mutualHexagram.lower; const mutualTi = getTrigramByNumber(mutualTiNum); const mutualYong = getTrigramByNumber(mutualYongNum); const mutualRelation = getRelationLabel(mutualTi.element, mutualYong.element); // 变卦体用 const changedTiNum = tiPos === 'upper' ? result.changedHexagram.upper : result.changedHexagram.lower; const changedYongNum = yongPos === 'upper' ? result.changedHexagram.upper : result.changedHexagram.lower; const changedTi = getTrigramByNumber(changedTiNum); const changedYong = getTrigramByNumber(changedYongNum); const changedRelation = getRelationLabel(changedTi.element, changedYong.element); const defs = [ { stage: 'origin' as MeihuaStageKey, label: '主卦', hexName: result.mainHexagram.hexagram.name, ti: { name: mainTiName, element: result.tiGua.trigram.element }, yong: { name: mainYongName, element: result.yongGua.trigram.element }, relation: mainRelation, basis: `动爻第${result.dongYao}爻在${result.dongYao <= 3 ? '下卦' : '上卦'},${result.dongYao <= 3 ? '上卦' : '下卦'}为体`, }, { stage: 'process' as MeihuaStageKey, label: '互卦', hexName: result.mutualHexagram.name, ti: { name: mutualTi.name, element: mutualTi.element }, yong: { name: mutualYong.name, element: mutualYong.element }, relation: mutualRelation, basis: '体卦位置与主卦一致,互卦取主卦2/3/4爻为下卦、3/4/5爻为上卦', }, { stage: 'result' as MeihuaStageKey, label: '变卦', hexName: result.changedHexagram.name, ti: { name: changedTi.name, element: changedTi.element }, yong: { name: changedYong.name, element: changedYong.element }, relation: changedRelation, basis: '体卦位置与主卦一致,变卦由动爻阴阳互换所得', }, ]; return defs.map(({ stage, label, hexName, ti, yong, relation, basis }) => { const relEv = relationEvidence(relation); const tiState = getSeasonState(ti.element, season); const yongState = getSeasonState(yong.element, season); const tiEv = stateEvidence('体', tiState); const yongEv = stateEvidence('用', yongState); const support = [...relEv.support, ...tiEv.support, ...yongEv.support]; const constraints = [...relEv.constraints, ...tiEv.constraints, ...yongEv.constraints]; const promptText = `${label}${hexName}:体卦${ti.name}${ti.element}(月令${tiState}),用卦${yong.name}${yong.element}(月令${yongState}),关系${relation};依据:${basis};支持:${support.join('、') || '未见额外增强'};限制:${constraints.join('、') || '未见明确盘内限制'}`; return { key: `meihua:stage:${stage}`, status: '已计算', stage, label, hexagramName: hexName, ti: { ...ti, seasonState: tiState }, yong: { ...yong, seasonState: yongState }, relation, support, constraints, basis, promptText, sources: ['动爻所在经卦定体用规则', '主卦、互卦、变卦上下经卦五行', `月建${season}与五行旺相休囚死关系`], limitation: STAGE_FACT_LIMITATION, }; }); } function buildTransitionFacts(stages: StageEvidence[]): TransitionFact[] { const transitions: TransitionFact[] = []; for (let i = 0; i < stages.length - 1; i++) { const from = stages[i]; const to = stages[i + 1]; const changed = from.relation !== to.relation; transitions.push({ key: `meihua:transition:${from.stage}-${to.stage}`, status: '连续', fromStageKey: from.key, toStageKey: to.key, fromStage: from.stage, toStage: to.stage, fromRelation: from.relation, toRelation: to.relation, promptText: `${from.label}→${to.label}:体用关系由「${from.relation}」${changed ? '变为' : '保持'}「${to.relation}」${changed ? ',存在变化' : ',关系稳定'}`, sources: ['阶段体用关系比较'], limitation: TRANSITION_FACT_LIMITATION, }); } return transitions; } function buildCounterEvidence(stages: StageEvidence[]): CounterEvidenceFact[] { const counters: CounterEvidenceFact[] = []; for (const stage of stages) { // 体卦受克 if (stage.relation === '用克体') { counters.push({ key: `meihua:counter:${stage.stage}:用克体`, ownerStageKey: stage.key, stage: stage.stage, type: '体用关系限制', status: '已触发', detail: `${stage.label}体卦${stage.ti.name}${stage.ti.element}受用卦${stage.yong.name}${stage.yong.element}克制`, promptText: `反证:${stage.label}体卦${stage.ti.name}受用卦${stage.yong.name}克制,存在外来压力`, sources: ['五行克关系'], limitation: COUNTER_FACT_LIMITATION, }); } // 体生用(泄耗) if (stage.relation === '体生用') { counters.push({ key: `meihua:counter:${stage.stage}:体生用`, ownerStageKey: stage.key, stage: stage.stage, type: '体用关系限制', status: '已触发', detail: `${stage.label}体卦${stage.ti.name}${stage.ti.element}生用卦${stage.yong.name}${stage.yong.element},体卦泄耗`, promptText: `反证:${stage.label}体卦${stage.ti.name}生用卦${stage.yong.name},体卦存在泄耗`, sources: ['五行生关系'], limitation: COUNTER_FACT_LIMITATION, }); } // 体卦休囚死 if (['休', '囚', '死'].includes(stage.ti.seasonState)) { counters.push({ key: `meihua:counter:${stage.stage}:体卦${stage.ti.seasonState}`, ownerStageKey: stage.key, stage: stage.stage, type: '体卦月令限制', status: '已触发', detail: `${stage.label}体卦${stage.ti.name}${stage.ti.element}月令${stage.ti.seasonState},不得时`, promptText: `反证:${stage.label}体卦${stage.ti.name}月令${stage.ti.seasonState},体卦不得时`, sources: ['月令旺衰'], limitation: COUNTER_FACT_LIMITATION, }); } } return counters; } function buildTimingFacts(result: HuaResult, season: string): TimingFact[] { const facts: TimingFact[] = []; const tiElement = result.tiGua.trigram.element; // 动爻层位 facts.push({ key: 'meihua:timing:dongYao', order: 1, type: '动爻层位', status: '已计算', rawText: `动爻第${result.dongYao}爻`, promptText: `应期参考:动爻第${result.dongYao}爻(${result.dongYao <= 3 ? '下卦' : '上卦'}),动爻所在经卦为用卦`, sources: ['动爻位置'], limitation: TIMING_FACT_LIMITATION, }); // 月建旺衰 facts.push({ key: 'meihua:timing:season', order: 2, type: '月建旺衰', status: '已计算', rawText: season, promptText: `应期参考:当令${season},体卦${tiElement}${result.wangShuai.tiWang ? '旺' : '衰'}`, sources: ['月令旺衰'], limitation: TIMING_FACT_LIMITATION, }); // 体卦状态 const tiState = getSeasonState(tiElement, season); facts.push({ key: 'meihua:timing:tiState', order: 3, type: '体卦状态', status: '已计算', rawText: `体卦${result.tiGua.trigram.name}${tiElement}月令${tiState}`, promptText: `应期参考:体卦${result.tiGua.trigram.name}${tiElement}月令${tiState},${tiState === '旺' || tiState === '相' ? '体旺则应期近' : '体衰则应期远或需待旺时'}`, sources: ['体卦月令状态'], limitation: TIMING_FACT_LIMITATION, }); return facts; } function buildTraditionalFacts(result: HuaResult, dongYao: number): TraditionalTextFact[] { const stages = [ { stage: '主卦' as const, upperNum: result.mainHexagram.upper.number, lowerNum: result.mainHexagram.lower.number, hexName: result.mainHexagram.hexagram.name, judgment: result.mainHexagram.hexagram.judgment }, { stage: '互卦' as const, upperNum: result.mutualHexagram.upper as number, lowerNum: result.mutualHexagram.lower as number, hexName: result.mutualHexagram.name, judgment: result.mutualHexagram.judgment }, { stage: '变卦' as const, upperNum: result.changedHexagram.upper as number, lowerNum: result.changedHexagram.lower as number, hexName: result.changedHexagram.name, judgment: result.changedHexagram.judgment }, ]; const facts: TraditionalTextFact[] = []; for (const { stage, upperNum, lowerNum, hexName, judgment } of stages) { const text = getTraditionalText(upperNum, lowerNum); if (!text) continue; // 卦辞 const judgmentSignals = classifyTraditionalSignals(judgment); const judgmentTopics = classifyTraditionalTopics(judgment); facts.push({ key: `${stage}:${hexName}:卦辞`, status: '已映射', stage, hexagram: hexName, kind: '卦辞', applicability: '当前卦辞辅助', originalText: judgment, promptText: `${stage}${hexName}卦辞「${judgment}」包含${judgmentSignals.join('、') || '未见明确标签'},涉及${judgmentTopics.join('、') || '通用处境类象'};只作为该阶段卦象的传统分类辅助`, traditionalSignals: judgmentSignals, topicTags: judgmentTopics, sources: ['《周易》卦辞', '六十四卦原文资料'], limitation: TRADITIONAL_FACT_LIMITATION, }); // 爻辞 for (let i = 0; i < text.yaoCi.length; i++) { const yaoPosition = i + 1; const isMoving = stage === '主卦' && yaoPosition === dongYao; const yaoText = text.yaoCi[i]; const yaoSignals = classifyTraditionalSignals(yaoText); const yaoTopics = classifyTraditionalTopics(yaoText); facts.push({ key: `${stage}:${hexName}:爻辞:${yaoPosition}`, status: '已映射', stage, hexagram: hexName, kind: '爻辞', yaoPosition, applicability: isMoving ? '当前动爻辅助' : '未发动背景', originalText: yaoText, promptText: `${stage}${hexName}第${yaoPosition}爻「${yaoText}」包含${yaoSignals.join('、') || '未见明确标签'},涉及${yaoTopics.join('、') || '通用处境类象'};${isMoving ? '当前爻位已发动,可作为动爻层位的传统辅助' : '当前爻位未发动,不作为独立判断依据'}`, traditionalSignals: yaoSignals, topicTags: yaoTopics, sources: ['《周易》爻辞', '六十四卦逐爻原文资料'], limitation: TRADITIONAL_FACT_LIMITATION, }); } // 用辞(乾坤) if (text.yongCi) { const yongSignals = classifyTraditionalSignals(text.yongCi); const yongTopics = classifyTraditionalTopics(text.yongCi); facts.push({ key: `${stage}:${hexName}:用辞`, status: '已映射', stage, hexagram: hexName, kind: '用辞', applicability: '特殊用辞背景', originalText: text.yongCi, promptText: `${stage}${hexName}用辞「${text.yongCi}」包含${yongSignals.join('、') || '未见明确标签'},涉及${yongTopics.join('、') || '通用处境类象'};本次采用单动爻起卦,不满足六爻皆变的特殊用辞条件`, traditionalSignals: yongSignals, topicTags: yongTopics, sources: ['《周易》乾坤用九用六', '六十四卦特殊用辞资料'], limitation: TRADITIONAL_FACT_LIMITATION, }); } } return facts; }