const NUM_CLR={ 1:{top:[232,160,160],front:[196,122,120],right:[168,96,96]}, 2:{top:[240,200,160],front:[232,168,124],right:[208,144,96]}, 3:{top:[238,208,128],front:[224,184,88],right:[200,152,64]}, 4:{top:[160,216,112],front:[112,173,71],right:[88,136,48]}, 5:{top:[144,200,240],front:[91,155,213],right:[64,120,176]}, 6:{top:[240,168,176],front:[212,135,142],right:[176,104,112]}, 7:{top:[184,168,216],front:[139,122,181],right:[104,88,152]}, 8:{top:[160,144,128],front:[107,91,78],right:[80,64,48]}, 9:{top:[244,236,224],front:[232,220,200],right:[208,192,168]}, }; // ===== Dimetric 投影 + Z 轴旋转 —— 底座天然水平 ===== let rotZ = -0.55; // Z 轴旋转角(弧度) let dragActive=false, dragPX=0; let currentFreq={}; function proj(x,y,z,rz) { // Z 轴旋转 + 45° dimetric 投影 const cr=Math.cos(rz), sr=Math.sin(rz); const xr=x*cr-y*sr, yr=x*sr+y*cr; return { sx:yr-xr, sy:-(xr+yr)+z*0.7, depth:-(xr+yr)+z }; } function faceVis(face, rz) { const cr=Math.cos(rz), sr=Math.sin(rz); switch(face) { case 'right': return cr+sr>0; case 'left': return cr+sr<0; case 'front': return cr-sr>0; case 'back': return cr-sr<0; case 'top': return true; case 'bottom':return false; } } function faceCorns(cx,cy,cz,hs,face) { const h=hs; switch(face) { case 'top': return [[cx-h,cy-h,cz+h],[cx+h,cy-h,cz+h],[cx+h,cy+h,cz+h],[cx-h,cy+h,cz+h]]; case 'bottom': return [[cx-h,cy-h,cz-h],[cx+h,cy-h,cz-h],[cx+h,cy+h,cz-h],[cx-h,cy+h,cz-h]]; case 'front': return [[cx-h,cy+h,cz-h],[cx+h,cy+h,cz-h],[cx+h,cy+h,cz+h],[cx-h,cy+h,cz+h]]; case 'back': return [[cx-h,cy-h,cz-h],[cx+h,cy-h,cz-h],[cx+h,cy-h,cz+h],[cx-h,cy-h,cz+h]]; case 'right': return [[cx+h,cy-h,cz-h],[cx+h,cy+h,cz-h],[cx+h,cy+h,cz+h],[cx+h,cy-h,cz+h]]; case 'left': return [[cx-h,cy-h,cz-h],[cx-h,cy+h,cz-h],[cx-h,cy+h,cz+h],[cx-h,cy-h,cz+h]]; } } function renderScene(canvas, freq, rz) { const dpr=window.devicePixelRatio||1; const mob=window.innerWidth<=600; const CS=mob?20:26; const STEP=CS*2+(mob?2:4); const DH=CS*2+(mob?1:2); const PAD=mob?30:40; const cols={}; for(let n=1;n<=9;n++){ const row=2-Math.floor((n-1)/3), col=(n-1)%3; cols[n]={wx:(col-1)*STEP,wy:(row-1)*STEP}; } // 计算包围盒 let mnX=Infinity,mxX=-Infinity,mnY=Infinity,mxY=-Infinity; for(let n=1;n<=9;n++){ const {wx,wy}=cols[n]; const layers=Math.max(1,freq[n]||1); for(let l=0;l{const p=proj(c[0],c[1],c[2],rz);mnX=Math.min(mnX,p.sx);mxX=Math.max(mxX,p.sx);mnY=Math.min(mnY,p.sy);mxY=Math.max(mxY,p.sy);}); } } // 底座平台包围盒 const bw=STEP*2+CS*2+16, bz=-CS-3; [[-bw,-bw,bz],[bw,-bw,bz],[bw,bw,bz],[-bw,bw,bz]].forEach(c=>{ const p=proj(c[0],c[1],c[2],rz);mnX=Math.min(mnX,p.sx);mxX=Math.max(mxX,p.sx);mnY=Math.min(mnY,p.sy);mxY=Math.max(mxY,p.sy); }); const viewW=Math.max(mxX-mnX+PAD*2,mob?300:400); const viewH=Math.max(mxY-mnY+PAD*2,mob?320:420); canvas.width=Math.ceil(viewW*dpr);canvas.height=Math.ceil(viewH*dpr); canvas.style.width=Math.ceil(viewW)+'px';canvas.style.height=Math.ceil(viewH)+'px'; const ctx=canvas.getContext('2d');ctx.scale(dpr,dpr);ctx.clearRect(0,0,viewW,viewH); const centerX=(mxX+mnX)/2, ox=viewW/2-centerX, oy=viewH-PAD-mxY; const faces=[]; const AF=['top','bottom','front','back','right','left']; // 底座平台(厚块) (()=>{ const bt=mob?4:5, bzTop=-CS-2, bzBot=bzTop-bt; const bclr=[170,155,135]; [ {t:'top', c:[[-bw,-bw,bzTop],[bw,-bw,bzTop],[bw,bw,bzTop],[-bw,bw,bzTop]],clr:bclr}, {t:'front', c:[[-bw,bw,bzBot],[bw,bw,bzBot],[bw,bw,bzTop],[-bw,bw,bzTop]],clr:bclr.map(v=>Math.floor(v*0.85))}, {t:'right', c:[[bw,-bw,bzBot],[bw,bw,bzBot],[bw,bw,bzTop],[bw,-bw,bzTop]],clr:bclr.map(v=>Math.floor(v*0.7))}, ].forEach(fb=>{ const pts=fb.c.map(c=>proj(c[0],c[1],c[2],rz)); const avgZ=pts.reduce((s,p)=>s+p.depth,0)/4; const projPts=pts.map(p=>[ox+p.sx,oy-p.sy]); faces.push({z:avgZ,proj:projPts,color:fb.clr,isTop:fb.t==='top',num:0}); }); })(); // 方块面 for(let n=1;n<=9;n++){ const {wx,wy}=cols[n]; const layers=Math.max(1,freq[n]||1); const clr=NUM_CLR[n]; const fc={top:clr.top,bottom:clr.top,front:clr.front,back:clr.front,right:clr.right,left:clr.right}; for(let l=0;lproj(c[0],c[1],c[2],rz)); const avgZ=pts.reduce((s,p)=>s+p.depth,0)/4; const projPts=pts.map(p=>[ox+p.sx,oy-p.sy]); const cnt=proj(wx,wy,wz+CS,rz); faces.push({z:avgZ,proj:projPts,color:fc[face],isTop:face==='top',num:n,cx:ox+cnt.sx,cy:oy-cnt.sy}); } } } faces.sort((a,b)=>a.z-b.z); const alpha=0.82; for(const f of faces){ const [r,g,b]=f.color; ctx.fillStyle=`rgba(${r},${g},${b},${alpha})`; ctx.beginPath();ctx.moveTo(f.proj[0][0],f.proj[0][1]); for(let i=1;i<4;i++)ctx.lineTo(f.proj[i][0],f.proj[i][1]); ctx.closePath();ctx.fill(); if(f.isTop&&f.num){ ctx.fillStyle='rgba(255,255,255,0.92)'; const fs=mob?11:14;ctx.font=`bold ${fs}px Georgia,"Noto Serif SC",serif`; ctx.textAlign='center';ctx.textBaseline='middle'; ctx.shadowColor='rgba(0,0,0,0.25)';ctx.shadowBlur=2; ctx.fillText(f.num,f.cx,f.cy); ctx.shadowColor='transparent';ctx.shadowBlur=0; } } // 底部 2D 横条 (()=>{ const bh=mob?18:22,by=viewH-bh; const grad=ctx.createLinearGradient(0,by,0,viewH); grad.addColorStop(0,'rgba(180,165,145,0.5)'); grad.addColorStop(0.3,'rgba(160,145,125,0.35)'); grad.addColorStop(1,'rgba(140,125,105,0.1)'); ctx.fillStyle=grad;ctx.fillRect(0,by,viewW,bh); ctx.strokeStyle='rgba(140,125,105,0.45)';ctx.lineWidth=1; ctx.beginPath();ctx.moveTo(0,by);ctx.lineTo(viewW,by);ctx.stroke(); })(); } function drawScene(){ const canvas=document.querySelector('#scene3d canvas'); if(!canvas)return; renderScene(canvas,currentFreq,rotZ); } function setupRotation(){ const el=document.querySelector('#scene3d');if(!el)return; function getX(e){return e.touches&&e.touches.length?e.touches[0].clientX:e.clientX} function onStart(e){dragActive=true;dragPX=getX(e);e.preventDefault()} function onMove(e){ if(!dragActive)return; const cx=getX(e),dx=cx-dragPX;dragPX=cx; rotZ+=dx*0.008;drawScene();e.preventDefault(); } function onEnd(){dragActive=false} el.addEventListener('mousedown',onStart); el.addEventListener('touchstart',onStart,{passive:false}); window.addEventListener('mousemove',onMove); window.addEventListener('touchmove',onMove,{passive:false}); window.addEventListener('mouseup',onEnd); window.addEventListener('touchend',onEnd); } // ===== 解读模块生成器 ===== const GUA64=['','乾为天','天泽履','天火同人','天雷无妄','天风姤','天水讼','天山遁','天地否','泽天夬','兑为泽','泽火革','泽雷随','泽风大过','泽水困','泽山咸','泽地萃','火天大有','火泽睽','离为火','火雷噬嗑','火风鼎','火水未济','火山旅','火地晋','雷天大壮','雷泽归妹','雷火丰','震为雷','雷风恒','雷水解','雷山小过','雷地豫','风天小畜','风泽中孚','风火家人','风雷益','巽为风','风水涣','风山渐','风地观','水天需','水泽节','水火既济','水雷屯','水风井','坎为水','水山蹇','水地比','山天大畜','山泽损','山火贲','山雷颐','山风蛊','山水蒙','艮为山','山地剥','地天泰','地泽临','地火明夷','地雷复','地风升','地水师','地山谦','坤为地']; const GUA64_DESC={'乾为天':'刚健中正,纯阳之卦。运势旺盛,宜主动进取。','坤为地':'柔顺包容,厚德载物。耐心守成,终得善果。','水雷屯':'万事起头难。创业维艰,宜稳扎稳打。','山水蒙':'蒙昧初开。宜虚心求教,不可自作聪明。','水天需':'等待时机。耐心守候,时机未到不可强求。','天水讼':'争执诉讼之象。退一步海阔天空。','地水师':'统兵出征。纪律严明,以正制邪。','水地比':'亲附和合。广结善缘,必得助力。','地天泰':'天地交泰。万事亨通,上下和合。','天地否':'闭塞不通。宜隐忍守正,静待时机。','天火同人':'志同道合。同心协力可成大事。','火天大有':'丰收大有。顺天应时,财源广进。','雷天大壮':'强盛壮大。力量充沛但切忌恃强凌弱。','火地晋':'旭日东升。逐步晋升,光明在前。','地火明夷':'光明受损。韬光养晦,等待天明。','风火家人':'家庭和乐。修身齐家,家和万事兴。','火泽睽':'乖离不合。求同存异,小事可成。','水山蹇':'艰难险阻。退守求稳,不可强闯。','雷水解':'困难解除。柳暗花明,危机化解。','山泽损':'损下益上。有舍有得,吃亏是福。','风雷益':'增益有利。抓住机遇,积极作为。','泽天夬':'决断果断。当断则断,不受其乱。','天风姤':'不期而遇。随缘而处,不可强求。','泽地萃':'聚集荟萃。人气旺盛,利于合作。','地风升':'步步高升。循序渐进,终达目标。','泽水困':'困顿之象。坚守正道,终可脱困。','水风井':'修德养民。滋养根本,源远流长。','泽火革':'变革之时。顺势而变,除旧布新。','火风鼎':'鼎新革故。稳固根基,创新求变。','震为雷':'震动警醒。临危不乱,化险为夷。','艮为山':'知止不殆。适可而止,安守本分。','风山渐':'循序渐进。按部就班,水到渠成。','雷泽归妹':'婚嫁之象。以诚相待,终成眷属。','雷火丰':'丰盛之时。月满则亏,知足常乐。','火山旅':'行旅之象。随遇而安,莫问归期。','巽为风':'柔顺渗透。以柔克刚,润物无声。','兑为泽':'喜悦沟通。以和为贵,广结善缘。','风水涣':'涣散离散。聚拢人心,凝聚力量。','水泽节':'节制有度。合理规划,量力而行。','风泽中孚':'诚信感召。以诚待人,金石为开。','雷山小过':'小有过失。宜下不宜上,宜小不宜大。','水火既济':'事已成就。居安思危,防微杜渐。','火水未济':'未竟之业。持之以恒,终将成功。','地山谦':'谦逊受益。虚怀若谷,众望所归。','雷地豫':'安乐愉悦。居安思危,不可懈怠。','泽雷随':'随顺时势。灵活应变,顺势而为。','山风蛊':'蛊坏整治。拨乱反正,振弊起衰。','地泽临':'居高临下。亲近下属,恩威并施。','风地观':'观览体察。审时度势,明察秋毫。','火雷噬嗑':'咬合刑罚。明断是非,刚正不阿。','山火贲':'文饰美化。返璞归真,内在为重。','山地剥':'剥落凋零。守正待时,顺势而为。','地雷复':'一阳来复。否极泰来,新生在望。','天雷无妄':'真实无妄。顺其自然,不妄作为。','山天大畜':'蓄积力量。厚积薄发,大器晚成。','山雷颐':'颐养之道。养生养德,自求口实。','泽风大过':'过度之象。刚柔相济,中庸为贵。','坎为水':'重重险难。坚守诚信,终可出险。','离为火':'光明依附。柔顺中正,照亮四方。'}; function meihuaHTML(y,m,d){ const dz=['子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥']; const dzNum={子:1,丑:2,寅:3,卯:4,辰:5,巳:6,午:7,未:8,申:9,酉:10,戌:11,亥:12}; const tg=['甲','乙','丙','丁','戊','己','庚','辛','壬','癸']; const guaName=['','乾 ☰','兑 ☱','离 ☲','震 ☳','巽 ☴','坎 ☵','艮 ☶','坤 ☷']; const guaEle=['','金','金','火','木','木','水','土','土']; const ndz=dz[(y-4)%12],ntg=tg[(y-4)%10],nDZ=dzNum[ndz]; const upNum=nDZ%8||8,downNum=(m+d)%8||8,dongY=(nDZ+m+d)%6||6; const benGuaIdx=(upNum-1)*8+downNum; const benName=GUA64[benGuaIdx]||(guaName[upNum]+'+'+guaName[downNum]); const varUp=dongY<=3?upNum:((upNum^5)||8),varDown=dongY<=3?((downNum^5)||8):downNum; const varIdx=(varUp-1)*8+varDown; const varName=GUA64[varIdx]||(guaName[varUp]+'+'+guaName[varDown]); const desc=GUA64_DESC[benName]||'卦象已显,静心体悟其中玄机。'; const dongYaoNames=['初爻','二爻','三爻','四爻','五爻','上爻']; const ue=guaEle[upNum],de=guaEle[downNum]; const shengKe={'金':'木','木':'土','土':'水','水':'火','火':'金'}; let tiYong; if(upNum===downNum)tiYong='体用比和,万事顺遂'; else if(shengKe[ue]===de)tiYong='体克用,事可成但需费心力'; else if(shengKe[de]===ue)tiYong='用克体,宜守不宜攻,等待时机'; else tiYong='体用相生,遇贵人之象,万事可成'; return `
✦ ${benName} ✦
${ntg}${ndz}年 · 上卦${guaName[upNum]} 下卦${guaName[downNum]} · 动在${dongYaoNames[dongY-1]}
▸ 本卦:${benName}
${desc}

▸ 变卦:${varName}
${GUA64_DESC[varName]||'变动已生,观其变化而知吉凶。'}

▸ 体用生克
上卦属${ue}·下卦属${de} — ${tiYong}
`; } const XLR_NAMES=['','大安','留连','速喜','赤口','小吉','空亡']; const XLR_DESC={'大安':'大吉。光明正大,平安顺遂。求财向东南,凡事安稳。','留连':'凶。事难成就,去者未归。宜静不宜动,急则生变。','速喜':'大吉。喜事将至,向南吉利,行人有信至。','赤口':'凶。口舌是非,宜守不宜攻,失物难寻。','小吉':'大吉。好事将近,路遇贵人,向西南吉利。','空亡':'大凶。谋事落空,宜静待时机,强求反遭祸。'}; function xiaoLiuRenHTML(y,m,d){ const mo=m>12?m-12:m,shi=7;let pos=1; for(let i=1;i✦ 小六壬 掌诀:${name} ✦
月上起日,日上起时(午时)→ 最终落位
${name}
${XLR_DESC[name]}

▸ 六掌速查
大安 · 留连 · 速喜 · 赤口 · 小吉 · 空亡
`; } function daLiuRenHTML(y,m,d){ const dz=['子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥']; const ydz=dz[(y-4)%12],yueJiangMap={1:'子',2:'亥',3:'戌',4:'酉',5:'申',6:'未',7:'午',8:'巳',9:'辰',10:'卯',11:'寅',12:'丑'}; return `
✦ 大六壬 课式概要 ✦
${y}年(${ydz}年)· ${m}月 月将${yueJiangMap[m]||'午'} · 占时午
▸ 简介
六壬为三式之首,以月将加占时起天地盘,排四课发三传断吉凶。演算极精(12天将+12神煞+遁干),此处展示基础课式。

▸ 天地盘
地盘:子丑寅卯辰巳午未申酉戌亥(固定)
天盘:月将加临占时之上,顺布十二辰


▸ 四课
第一课日干阳神 · 第二课日干阴神 · 第三课日支阳神 · 第四课日支阴神

▸ 三传
初传(发用·起始)→ 中传(移易·过程)→ 末传(归计·结局)

▸ 九宗门
贼克·比用·涉害·遥克·昴星·别责·八专·伏吟·反吟

※ 完整排盘需配合具体时辰与日干支,建议请六壬师详断。
`; } function qiMenHTML(y,m,d){ const dz=['子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥']; const tg=['甲','乙','丙','丁','戊','己','庚','辛','壬','癸']; const mingGongMap={1:'丑',2:'寅',3:'卯',4:'辰',5:'巳',6:'午',7:'未',8:'申',9:'酉',10:'戌',11:'亥',12:'子'}; return `
✦ 奇门遁甲 命盘概要 ✦
${tg[(y-4)%10]}${dz[(y-4)%12]}年 · 命宫:${mingGongMap[m]||'午'}
▸ 简介
奇门合天(九星)、地(九宫)、人(八门)、神(八神)四层于一体。排盘需节气+时辰+用局,极为精密。

▸ 地盘九宫
戴九履一·左三右七·二四为肩·六八为足·五居中央
坎一水·坤二土·震三木·巽四木·中五土·乾六金·兑七金·艮八土·离九火


▸ 八门(人事)
开门(吉)·休门(吉)·生门(吉)·伤门(凶)·杜门(平)·景门(平)·死门(凶)·惊门(凶)

▸ 九星(天时)
天蓬·天任·天冲·天辅·天英·天芮·天柱·天心·天禽

※ 全面排盘需根据具体时辰和节气确定阳遁/阴遁几局,建议请奇门师详断。
`; } const ZODIAC=[ {name:'摩羯座',emoji:'♑',elem:'土',from:[12,22],to:[1,19],trait:'坚韧务实,目标明确,大器晚成',lucky:'深绿·黑'}, {name:'水瓶座',emoji:'♒',elem:'风',from:[1,20],to:[2,18],trait:'独立创新,思维超前,人道主义',lucky:'蓝·银'}, {name:'双鱼座',emoji:'♓',elem:'水',from:[2,19],to:[3,20],trait:'浪漫敏感,富有同情心,艺术天赋',lucky:'紫·海蓝'}, {name:'白羊座',emoji:'♈',elem:'火',from:[3,21],to:[4,19],trait:'热情勇敢,行动力强,开拓先锋',lucky:'红·金'}, {name:'金牛座',emoji:'♉',elem:'土',from:[4,20],to:[5,20],trait:'稳健可靠,审美出众,坚定执着',lucky:'粉·绿'}, {name:'双子座',emoji:'♊',elem:'风',from:[5,21],to:[6,21],trait:'机智灵活,善于沟通,双面魅力',lucky:'黄·银'}, {name:'巨蟹座',emoji:'♋',elem:'水',from:[6,22],to:[7,22],trait:'温柔顾家,情感丰富,保护欲强',lucky:'白·银'}, {name:'狮子座',emoji:'♌',elem:'火',from:[7,23],to:[8,22],trait:'自信大方,领导力强,光芒四射',lucky:'金·橙'}, {name:'处女座',emoji:'♍',elem:'土',from:[8,23],to:[9,22],trait:'细致严谨,追求完美,服务精神',lucky:'灰·米'}, {name:'天秤座',emoji:'♎',elem:'风',from:[9,23],to:[10,23],trait:'优雅公正,善于平衡,社交达人',lucky:'粉·蓝'}, {name:'天蝎座',emoji:'♏',elem:'水',from:[10,24],to:[11,22],trait:'深沉敏锐,意志坚定,极致深情',lucky:'深红·黑'}, {name:'射手座',emoji:'♐',elem:'火',from:[11,23],to:[12,21],trait:'乐观自由,探索精神,哲学思维',lucky:'紫·深蓝'}, ]; function xingZuoHTML(y,m,d){ let z=ZODIAC.find(x=>(m===x.from[0]&&d>=x.from[1])||(m===x.to[0]&&d<=x.to[1])); if(!z){if((m===12&&d>=22)||(m===1&&d<=19))z=ZODIAC[0];else if(m===1)z=ZODIAC[1];else z=ZODIAC.find(x=>m===x.from[0]&&d✦ ${z.emoji} ${z.name} ✦
${z.elem}象星座 · 幸运色:${z.lucky}
${z.emoji}
▸ 性格特质
${z.trait}

▸ 元素能量
${et[z.elem]}

▸ 十二星座
${ZODIAC.map(x=>`${x.emoji}`).join(' ')}
`; } const BAGUA=[ {name:'乾 ☰',xiang:'天',elem:'金',clr:'#d4c5a0',txt:'#8b7355',desc:'刚健·创造'}, {name:'兑 ☱',xiang:'泽',elem:'金',clr:'#e8d5c8',txt:'#a08070',desc:'喜悦·沟通'}, {name:'离 ☲',xiang:'火',elem:'火',clr:'#e8c8c0',txt:'#b06050',desc:'光明·智慧'}, {name:'震 ☳',xiang:'雷',elem:'木',clr:'#c8d8b0',txt:'#5a7a3a',desc:'行动·震动'}, {name:'巽 ☴',xiang:'风',elem:'木',clr:'#b8d0b8',txt:'#4a7a4a',desc:'渗透·柔顺'}, {name:'坎 ☵',xiang:'水',elem:'水',clr:'#a8c8d8',txt:'#3a6a8a',desc:'险陷·智慧'}, {name:'艮 ☶',xiang:'山',elem:'土',clr:'#d0c8b0',txt:'#7a6a4a',desc:'静止·坚守'}, {name:'坤 ☷',xiang:'地',elem:'土',clr:'#e0d8c0',txt:'#8a7a5a',desc:'柔顺·包容'}, ]; function wuXingHTML(y,m,d){ const yElem=['金','水','木','火','土'][Math.floor(((y-4)%10)/2)]; const mElem=['木','木','土','火','火','土','金','金','土','水','水','土'][m-1]; const dElem=['木','火','土','金','水'][d%5]; const ec={金:'#d4c5a0',水:'#a8c8d8',木:'#b8d0b8',火:'#e8c8c0',土:'#e0d8c0'}; return `
✦ 五行八卦 能量图谱 ✦
年柱${yElem} · 月柱${mElem} · 日柱${dElem}
▸ 五行
${['金','水','木','火','土'].map(e=>`${e}`).join('')}
金(义)·水(智)·木(仁)·火(礼)·土(信)
相生:金→水→木→火→土→金
相克:金→木→土→水→火→金


▸ 八卦
${BAGUA.map(b=>`
${b.name}
${b.elem}·${b.xiang}
${b.desc}
`).join('')}
八卦歌诀:乾三连·坤六断·震仰盂·艮覆碗·离中虚·坎中满·兑上缺·巽下断
`; } // ===== Tab 切换 ===== function initTabs(){ const nav=document.querySelector('.tabs-nav'); if(!nav)return; nav.addEventListener('click',e=>{ const btn=e.target.closest('.tab-btn'); if(!btn)return; const tab=btn.dataset.tab; nav.querySelectorAll('.tab-btn').forEach(b=>b.classList.remove('active')); btn.classList.add('active'); document.querySelectorAll('.tab-panel').forEach(p=>p.classList.remove('active')); const panel=document.getElementById(tab+'-panel'); if(panel)panel.classList.add('active'); }); } function update(v,y,m,d){ document.getElementById('valR').textContent=v.R; document.getElementById('valQ').textContent=v.Q; document.getElementById('valP').textContent=v.P; document.getElementById('valO').textContent=v.O; document.getElementById('valM').textContent=v.M; document.getElementById('valN').textContent=v.N; document.getElementById('valI').textContent=v.I; document.getElementById('valJ').textContent=v.J; document.getElementById('valK').textContent=v.K; document.getElementById('valL').textContent=v.L; document.getElementById('valU').textContent=v.U; document.getElementById('valT').textContent=v.T; document.getElementById('valS').textContent=v.S; document.getElementById('valX').textContent=v.X; document.getElementById('valV').textContent=v.V; document.getElementById('valW').textContent=v.W; document.getElementById('dateD').textContent=String(d).padStart(2,'0'); document.getElementById('dateM').textContent=String(m).padStart(2,'0'); document.getElementById('dateY').textContent=y; const allNums=[0,1,2,3,4,5,6,7,8,9]; const inner=new Set([v.O,v.M,v.N,v.I,v.J,v.K,v.L]); const present=new Set([...inner,v.Q,v.P,v.R,v.T,v.S,v.U,v.V,v.W,v.X,v.AB[0],v.AB[1],v.CD[0],v.CD[1],v.EF[0],v.EF[1],v.GH[0],v.GH[1]]); const miss={inner:allNums.filter(n=>!inner.has(n)),outer:allNums.filter(n=>![v.Q,v.P,v.R,v.T,v.S,v.U,v.V,v.W,v.X].includes(n)),both:allNums.filter(n=>!present.has(n))}; const n=NUM[v.O]||{}; const freq={}; for(let i=1;i<=9;i++)freq[i]=0; const allVals=[v.O,v.M,v.N,v.I,v.J,v.K,v.L,v.Q,v.P,v.R,v.T,v.S,v.U,v.V,v.W,v.X, v.AB[0],v.AB[1],v.CD[0],v.CD[1],v.EF[0],v.EF[1],v.GH[0],v.GH[1]]; allVals.forEach(x=>{if(x>=1&&x<=9)freq[x]++;}); currentFreq=freq; const freqArr=Object.entries(freq).sort((a,b)=>b[1]-a[1]); const most=freqArr[0],least=freqArr.filter(([,c])=>c===freqArr[freqArr.length-1][1]); let freeHtml=`
`; freeHtml+=`
${v.O}号人
`; freeHtml+=`
${n.title||''}
`; freeHtml+=`
${n.desc||''}
`; freeHtml+=`
`; let premiumHtml=``; premiumHtml+=`
`; premiumHtml+=`✦ 天赋优势:${n.pos||''}
✦ 人生课题:${n.neg||''}
✦ 五行属性:${n.elem||''}
✦ 适合职业:${n.job||''}
`; premiumHtml+=`
`; premiumHtml+=`
✦ 数字能量图谱 ✦
`; premiumHtml+=`
你的生命三角共汇聚了 ${allVals.filter(x=>x>=1).length} 个能量数字
`; premiumHtml+=`
↻ 左右旋转
`; premiumHtml+=`
🔥 能量最强:${most[0]}(出现 ${most[1]} 次),是你生命中最闪耀的特质
`; if(least.length>0)premiumHtml+=`
💧 能量最弱:${least.map(([n])=>`${n}`).join('、')}(仅 ${least[0][1]} 次),值得你用心浇灌
`; premiumHtml+=`
`; premiumHtml+=`
✦ 三角内外——真实自我与外界眼光 ✦
`; premiumHtml+=`
`; premiumHtml+=`
▸ 三角内部:代表你内在真实的自我——潜意识的驱动、与生俱来的性格特质、不为人知的内心世界。
`; premiumHtml+=`
▸ 三角外部:代表外界对你的认知——你在工作、家庭、社交中呈现出的样子,以及他人眼中的你。
`; premiumHtml+=`
▸ 下方基因(父母遗传):代表来自父亲和母亲的先天遗传基因,是你性格的底层土壤。
`; premiumHtml+=`
`; premiumHtml+=`
✦ 性格密码深度解读 ✦
`; premiumHtml+=`
`; premiumHtml+=`
潜意识码:${v.I}${v.J}${v.K}${v.L}
`; premiumHtml+=`
你内心深处的真实驱动力,最本能的反应模式。四个数字分别主宰:思维、情感、行动、人际。
`; premiumHtml+=`
内心码:${v.M}${v.N}
`; premiumHtml+=`
深层情感模式与核心价值观。理性行动 vs 感性人际——两者的平衡就是你面对压力时的姿态。
`; premiumHtml+=`
坐镇码:${v.I}${v.M}${v.O}
`; premiumHtml+=`
性格核心轴线:潜意识→内心→主性格。三环相扣,是你从内驱力到外在呈现的完整链条,也是你最稳定的底色。
`; premiumHtml+=`
父亲基因:${v.EF.join('')} ${v.GH.join('')} · 母亲基因:${v.AB.join('')} ${v.CD.join('')}
`; premiumHtml+=`
父亲基因 ← 年份 ${v.EF.join('')}${v.GH.join('')})承载家族传承与事业基因
母亲基因 ← 月${v.CD.join('')} 日${v.AB.join('')})影响情感模式与人际底色
`; premiumHtml+=`
`; premiumHtml+=`
✦ 数字缺失与能量过剩 ✦
`; premiumHtml+=`
`; if(miss.both.length>0){premiumHtml+=`
⚠ 缺失数字
`;miss.both.forEach(n=>{premiumHtml+=`
· 缺${n}:${MISS_MSG[n]||''}
`;});} else premiumHtml+=`
✦ 你的数字分布完整,能量均衡。
`; const over=[];for(let i=1;i<=9;i++){if(freq[i]>=4&&!miss.both.includes(i))over.push(i);} if(over.length>0){premiumHtml+=`
⚡ 能量过剩
`;over.forEach(n=>{premiumHtml+=`
· 多${n}(×${freq[n]}):${MISS_STRONG[n]||''}
`;});} premiumHtml+=`
`; const joints=[['I','J'],['J','M'],['M','I'],['K','L'],['L','N'],['N','K'],['M','O'],['O','N'],['M','N'],['Q','P'],['Q','O'],['P','O']].map(([a,b])=>{const k=''+v[a]+v[b];const jk=Object.keys(JOINT).find(x=>x.startsWith(k));return {code:k,label:jk?JOINT[jk]:'—'};}); premiumHtml+=`
`; premiumHtml+=`
✦ 12组人生联合码 ✦
`; premiumHtml+=`
相邻数字组合,解密你不同人生阶段的内在剧本
`; const ages=[ {label:'21—40岁 · 工作和朋友',codes:joints.slice(0,4),desc:'由潜意识码主导,反映你在职场上升期和社交圈中的表现模式。'+(v.I+v.J+v.M>=10?'能量较强,事业心旺盛,社交活跃。':'能量内敛,更注重深度而非广度。')}, {label:'41—60岁 · 儿女和下属',codes:joints.slice(4,8),desc:'由内心码和主性格主导,体现你对下一代和下级的培养方式及中年价值观。'+(v.K+v.L+v.N>=10?'有较强的责任感和支配欲。':'倾向于给予空间,放手让他人成长。')}, {label:'61岁至晚年 · 晚年和家庭',codes:joints.slice(8,12),desc:'由外心码主导,展现你晚年的生活智慧和家庭关系的最终呈现。'+(v.M+v.N+v.O>=10?'晚年活跃,持续发挥影响力。':'晚年宁静,享受内在平和。')}, ]; ages.forEach(ag=>{ premiumHtml+=`
${ag.label}
`; premiumHtml+=`
${ag.desc}
`; premiumHtml+=`
`; ag.codes.forEach(jc=>{premiumHtml+=`
${jc.code} ${jc.label}
`;}); premiumHtml+=`
`; }); const paid=localStorage.getItem('jiema_paid'); const lockEl=document.getElementById('missingBlock'); if(paid){ lockEl.innerHTML=freeHtml+premiumHtml; }else{ lockEl.innerHTML=freeHtml+'
'+premiumHtml+'
'; const lock=document.getElementById('shuziLock'); Array.from(lock.children).forEach(c=>c.classList.add('blur')); const cover=document.createElement('div');cover.className='cover'; cover.innerHTML='
🔒 解锁你的完整数字报告
天赋优势 · 能量分布 · 性格编码 · 12组联合码
'; const btn=document.createElement('button');btn.className='lk-btn';btn.textContent='¥39.9 立即解锁 →'; btn.addEventListener('click',unlockShuzi);cover.appendChild(btn);lock.appendChild(cover); } setTimeout(()=>{ const canvas=document.querySelector('#scene3d canvas'); if(canvas){renderScene(canvas,freq,rotZ);setupRotation();} },30); document.getElementById('missingMsg').textContent=''; document.getElementById('codesBlock').innerHTML=''; document.getElementById('jointBlock').innerHTML=''; const tipEl=document.getElementById('tip'); ['valR','valQ','valP','valO','valM','valN','valI','valJ','valK','valL','valU','valT','valS','valX','valV','valW'].forEach(id=>{ const el=document.getElementById(id);if(!el)return;el.style.cursor='pointer'; const k=id.replace('val',''); el.onpointerenter=()=>{const f=tips[k]?tips[k](v):'';tipEl.innerHTML=f||k;tipEl.classList.add('on')}; el.onpointermove=e=>{tipEl.style.left=(e.clientX+14)+'px';tipEl.style.top=(e.clientY-10)+'px'}; }); // 填充其他解读面板 document.getElementById('meihua-panel').innerHTML=meihuaHTML(y,m,d); document.getElementById('xiaoliuren-panel').innerHTML=xiaoLiuRenHTML(y,m,d); document.getElementById('daliuren-panel').innerHTML=daLiuRenHTML(y,m,d); document.getElementById('qimen-panel').innerHTML=qiMenHTML(y,m,d); document.getElementById('xingzuo-panel').innerHTML=xingZuoHTML(y,m,d); document.getElementById('wuxing-panel').innerHTML=wuXingHTML(y,m,d); } function unlockShuzi(){localStorage.setItem("jiema_paid","1");const l=document.getElementById("shuziLock");l.querySelectorAll(".blur").forEach(c=>c.classList.remove("blur"));l.classList.add("unlocked");} function go(){const y=+document.getElementById('inY').value,m=+document.getElementById('inM').value,d=+document.getElementById('inD').value;if(!y||!m||!d)return;update(calc(y,m,d),y,m,d)} document.getElementById('goBtn').addEventListener('click',go); document.querySelectorAll('.input-row input').forEach(i=>i.addEventListener('keydown',e=>{if(e.key==='Enter')go()})); setTimeout(go,150); initTabs(); // URL 参数预填(从 jiema.html 跳转过来) (function(){ const p=new URLSearchParams(location.search); const y=p.get('y'),m=p.get('m'),d=p.get('d'); if(y&&m&&d){ document.getElementById('inY').value=y; document.getElementById('inM').value=m; document.getElementById('inD').value=d; setTimeout(go,200); } })();