Files
digital-psychology/xingjing_app.html
T

1538 lines
145 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
<title>星镜</title>
<style>
html{overflow-y:auto;-webkit-overflow-scrolling:touch}
:root{
--pri:#E54D42; --blue:#4A90E2; --teal:#0D9488; --gold:#C8923A;
--text:#333; --sub:#999; --bg-start:#FFD1C7; --bg-end:#FFC8B5; --dark:#1a1a2e;
}
*{box-sizing:border-box;margin:0;padding:0}
body{
font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei","Helvetica Neue",sans-serif;
background:linear-gradient(180deg,var(--bg-start) 0%,var(--bg-end) 40%,#fff5f0 100%);
color:var(--text);max-width:430px;margin:0 auto;min-height:100vh;
-webkit-font-smoothing:antialiased;overflow-x:hidden;
overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.topbar{
display:flex;align-items:center;justify-content:center;gap:8px;
padding:10px 16px 6px;position:sticky;top:0;z-index:20;
background:linear-gradient(180deg,var(--bg-start) 0%,rgba(255,209,199,0.7) 100%);
-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
}
.topbar .tbt{font-size:15px;font-weight:700;color:var(--text);flex:1;text-align:center}
.topbar .back-btn{
width:32px;height:32px;border-radius:50%;border:none;background:rgba(255,255,255,0.6);
font-size:16px;cursor:pointer;display:none;align-items:center;justify-content:center;
flex-shrink:0;color:var(--text);
}
.topbar .back-btn.show{display:flex}
.topbar img{height:22px;flex-shrink:0}
.page{display:none;padding:0 16px 85px;animation:fadeIn 0.25s}
.page.active{display:block}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.nav{
position:fixed;bottom:0;left:50%;transform:translateX(-50%);
width:100%;max-width:430px;background:#fff;display:flex;justify-content:space-around;
padding:4px 0 calc(6px + env(safe-area-inset-bottom,0));
border-top:1px solid #f0f0f0;z-index:100;box-shadow:0 -2px 8px rgba(0,0,0,0.03);
}
.nav-item{display:flex;flex-direction:column;align-items:center;gap:1px;font-size:9px;color:var(--sub);cursor:pointer;line-height:1;transition:color 0.15s}
.nav-item .ni{font-size:17px}
.nav-item.active{color:var(--pri)}
.card{background:#fff;border-radius:14px;padding:16px;margin-bottom:10px;box-shadow:0 2px 8px rgba(0,0,0,0.04)}
.card-sm{padding:12px;border-radius:12px}
.card-title{font-size:15px;font-weight:700;margin-bottom:4px}
.card-sub{font-size:11px;color:var(--sub);line-height:1.5}
.hero-card{
background:linear-gradient(135deg,var(--dark),#16213e,#0f3460);
border-radius:18px;padding:24px 18px 20px;margin-bottom:12px;color:#fff;position:relative;overflow:hidden;
}
.hero-card .h-stars{position:absolute;inset:0;pointer-events:none}
.hero-card .h-stars span{position:absolute;background:#fff;border-radius:50%;animation:twinkle 3s ease-in-out infinite}
.hero-card .h-stars span:nth-child(1){width:3px;height:3px;top:12%;left:20%}
.hero-card .h-stars span:nth-child(2){width:2px;height:2px;top:25%;right:22%}
.hero-card .h-stars span:nth-child(3){width:3px;height:3px;top:50%;left:65%}
.hero-card .h-stars span:nth-child(4){width:2px;height:2px;bottom:30%;left:15%}
.hero-card .h-stars span:nth-child(5){width:3px;height:3px;bottom:20%;right:30%}
@keyframes twinkle{0%,100%{opacity:0.2}50%{opacity:1}}
.hero-card .hzodiac{margin-bottom:4px}
.hero-card .hlabel{font-size:11px;opacity:0.6;margin-bottom:2px}
/* Dunhuang zodiac badge */
.zodiac-dh{display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:50%;background:#F5E6D3;border:2px solid;font-size:22px;font-weight:700;line-height:1;box-shadow:0 2px 8px rgba(0,0,0,0.1);flex-shrink:0}
.hero-card .zodiac-dh{width:56px;height:56px;font-size:26px;border-width:2.5px;margin:0 auto}
.result-hero .zodiac-dh{width:64px;height:64px;font-size:30px;border-width:3px;margin:0 auto}
.zodiac-dh.fire{border-color:#C04030;color:#8B2020;background:#FDF2EC}
.zodiac-dh.earth{border-color:#A0855B;color:#6B4F3A;background:#F8F2EA}
.zodiac-dh.air{border-color:#5B8FA8;color:#3A6070;background:#F0F5F8}
.zodiac-dh.water{border-color:#6B5B95;color:#4A3570;background:#F2F0F8}
#pAvatar .zodiac-dh{width:56px;height:56px;font-size:26px;box-shadow:none}
.hist-item .zodiac-dh{width:40px;height:40px;font-size:18px}
.hero-card .hsign{font-size:24px;font-weight:800}
.hero-card .hdate{font-size:11px;opacity:0.5;margin-top:2px}
.hero-card .haction{display:inline-block;margin-top:12px;padding:8px 20px;background:rgba(255,255,255,0.15);color:#fff;border-radius:20px;font-size:13px;font-weight:600;cursor:pointer;transition:transform 0.15s}
.hero-card .haction:active{transform:scale(0.95)}
.input-row{display:flex;gap:6px;align-items:center;margin-bottom:8px;flex-wrap:wrap}
.input-row input,.input-row select{padding:10px 8px;border:1.5px solid #e8e0d8;border-radius:10px;font-size:14px;outline:none;background:#fdfaf7;text-align:center;flex:1;min-width:0}
.input-row input:focus,.input-row select:focus{border-color:var(--pri)}
.input-row .lbl{font-size:12px;color:var(--sub);white-space:nowrap}
.btn{display:inline-block;padding:10px 20px;border:none;border-radius:22px;font-size:13px;font-weight:600;cursor:pointer;transition:transform 0.15s}
.btn:active{transform:scale(0.96)}
.btn-pri{background:var(--pri);color:#fff;box-shadow:0 3px 10px rgba(229,77,66,.2)}
.btn-outline{background:#fff;color:var(--pri);border:1.5px solid var(--pri)}
.btn-sm{padding:6px 14px;font-size:11px}
.btn-block{display:block;width:100%;text-align:center}
.quiz-q{margin-bottom:14px}
.quiz-q .q-num{font-size:10px;color:var(--sub);margin-bottom:2px}
.quiz-q .q-text{font-size:15px;font-weight:600;margin-bottom:8px;line-height:1.4}
.quiz-opt{display:block;width:100%;padding:12px 14px;margin-bottom:6px;background:#fafafa;border:1.5px solid #eee;border-radius:12px;font-size:13px;text-align:left;cursor:pointer;transition:all 0.15s;line-height:1.4}
.quiz-opt:active,.quiz-opt.sel{background:#FFF5F0;border-color:var(--pri);color:var(--pri)}
.result-hero{background:linear-gradient(135deg,var(--dark),#16213e,#0f3460);border-radius:18px;padding:28px 20px;text-align:center;color:#fff;margin-bottom:12px}
.result-hero .rzodiac{margin-bottom:6px}
.result-hero .rsign{font-size:22px;font-weight:800;margin-bottom:2px}
.result-hero .rmbti{font-size:13px;opacity:0.7;margin-bottom:8px}
.result-tag{display:inline-block;padding:3px 10px;border-radius:20px;font-size:10px;margin:2px;background:rgba(255,255,255,0.12);color:rgba(255,255,255,0.85)}
.elem-bar{display:flex;align-items:center;gap:6px;margin-bottom:4px;font-size:11px}
.elem-bar .el{width:40px;text-align:right;color:var(--sub)}
.elem-bar .eb{flex:1;height:8px;border-radius:4px;background:#eee;overflow:hidden}
.elem-bar .ebf{height:100%;border-radius:4px;transition:width 0.6s}
.elem-bar .ev{width:28px;text-align:right;font-weight:600;font-size:10px}
.dim-row{display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:11px}
.dim-row .dl{width:24px;text-align:right;color:var(--sub);font-weight:600}
.dim-row .dbar{flex:1;height:18px;background:#f5f5f5;border-radius:9px;position:relative;overflow:hidden}
.dim-row .dfill{height:100%;border-radius:9px;transition:width 0.8s;display:flex;align-items:center;padding-left:8px;color:#fff;font-size:9px;font-weight:600}
.dim-row .dr{width:24px;font-weight:600;font-size:10px}
#chartCanvas{display:block;width:100%;border-radius:16px;background:var(--dark);cursor:grab}
#chartCanvas:active{cursor:grabbing}
.chart-info{text-align:center;padding:10px;font-size:12px;color:var(--sub);background:#fff;border-radius:12px;margin-top:8px;box-shadow:0 2px 6px rgba(0,0,0,0.03)}
.chart-info .pn{font-weight:700;color:var(--pri);font-size:14px}
.horo-card{background:linear-gradient(135deg,#fff8f0,#fff5f0);border-radius:14px;padding:14px;margin-bottom:10px;border:1px solid rgba(229,77,66,0.08)}
.horo-card .hday{font-size:11px;color:var(--sub)}
.horo-card .hmsg{font-size:13px;font-weight:600;color:var(--text);margin:4px 0;line-height:1.5}
.horo-card .hstars{color:#FFD700;font-size:12px}
.quick-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px}
.quick-item{background:#fff;border-radius:12px;padding:16px 12px;text-align:center;box-shadow:0 2px 6px rgba(0,0,0,0.03);cursor:pointer;transition:transform 0.15s}
.quick-item:active{transform:scale(0.96)}
.quick-item .qi{font-size:26px;margin-bottom:4px}
.quick-item .qt{font-size:12px;font-weight:600;color:var(--text)}
.quick-item .qd{font-size:10px;color:var(--sub);margin-top:2px}
.feed-tabs{display:flex;gap:8px;margin-bottom:10px;overflow-x:auto}
.feed-tab{padding:6px 14px;border-radius:20px;font-size:11px;white-space:nowrap;background:#fff;color:var(--sub);cursor:pointer;transition:all 0.15s;border:1px solid #eee}
.feed-tab.active{background:var(--pri);color:#fff;border-color:var(--pri)}
.feed-item{background:#fff;border-radius:14px;margin-bottom:10px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.04)}
.feed-item .f-thumb{position:relative;height:180px;display:flex;align-items:center;justify-content:center;cursor:pointer}
.feed-item .f-thumb .play-btn{width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,0.2);display:flex;align-items:center;justify-content:center;font-size:16px;color:#fff}
.feed-item .f-thumb .f-dur{position:absolute;bottom:8px;right:8px;background:rgba(0,0,0,0.6);color:#fff;font-size:10px;padding:2px 6px;border-radius:4px}
.feed-item .f-avatar{position:absolute;bottom:8px;left:8px;width:28px;height:28px;border-radius:50%;background:rgba(255,255,255,0.3);display:flex;align-items:center;justify-content:center;font-size:14px}
.feed-item .f-info{padding:12px}
.feed-item .f-info .f-title{font-size:13px;font-weight:600;margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.feed-item .f-info .f-meta{font-size:10px;color:var(--sub);display:flex;gap:10px}
.feed-item .f-tags{display:flex;gap:5px;padding:0 12px 8px;flex-wrap:wrap}
.feed-tag{font-size:9px;padding:2px 7px;border-radius:10px;background:#FFF5F0;color:var(--pri)}
.video-overlay{position:fixed;inset:0;z-index:200;background:#000;display:none;flex-direction:column;justify-content:center;align-items:center}
.video-overlay.on{display:flex}
.video-overlay .v-canvas{display:block;width:100%;max-width:430px}
.video-overlay .v-close{position:absolute;top:16px;right:16px;z-index:210;width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,0.12);color:#fff;border:none;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center}
.video-overlay .v-progress{position:absolute;bottom:40px;left:50%;transform:translateX(-50%);width:70%;max-width:280px;height:3px;background:rgba(255,255,255,0.15);border-radius:3px;z-index:210}
.video-overlay .v-progress .v-bar{height:100%;background:var(--pri);border-radius:3px;transition:width 0.1s linear}
.video-overlay .v-watermark{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-20deg);color:rgba(255,255,255,0.06);font-size:32px;font-weight:800;pointer-events:none;z-index:205;white-space:nowrap}
.tier-card{background:#fff;border-radius:14px;padding:16px;margin-bottom:8px;box-shadow:0 2px 8px rgba(0,0,0,0.04);position:relative;overflow:hidden}
.tier-card.pro{border:2px solid var(--gold)}
.tier-card.pro::after{content:"推荐";position:absolute;top:0;right:0;background:var(--gold);color:#fff;font-size:10px;padding:3px 10px;border-radius:0 12px 0 12px;font-weight:600}
.tier-card .t-name{font-size:15px;font-weight:700;margin-bottom:2px}
.tier-card .t-price{font-size:20px;font-weight:800;color:var(--pri);margin-bottom:6px}
.tier-card .t-price .unit{font-size:12px;font-weight:400}
.tier-card .t-feat{font-size:11px;color:var(--sub);line-height:1.8}
.badge-row{display:flex;gap:8px;overflow-x:auto;padding:4px 0;margin-bottom:6px}
.badge-item{flex-shrink:0;width:56px;text-align:center;font-size:9px;color:var(--sub)}
.badge-item .bi{width:44px;height:44px;border-radius:50%;margin:0 auto 4px;display:flex;align-items:center;justify-content:center;font-size:20px}
.badge-item .bi.locked{background:#f0f0f0;filter:grayscale(1);opacity:0.5}
.hist-item{display:flex;align-items:center;gap:10px;padding:12px;background:#fff;border-radius:12px;margin-bottom:8px;box-shadow:0 1px 4px rgba(0,0,0,0.03);cursor:pointer}
.hist-item .hi{flex-shrink:0;display:flex;align-items:center}
.hist-item .hc{flex:1;min-width:0}
.hist-item .hc .hn{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hist-item .hc .hd{font-size:10px;color:var(--sub)}
.toast{position:fixed;top:60px;left:50%;transform:translateX(-50%);z-index:300;background:var(--dark);color:#fff;padding:10px 20px;border-radius:20px;font-size:13px;opacity:0;transition:opacity 0.3s;pointer-events:none}
.toast.show{opacity:1}
/* Purchase modal - simple overlay kept for membership */
.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;z-index:250;background:rgba(0,0,0,0.5);display:none;align-items:center;justify-content:center}
.modal-overlay.on{display:flex}
.modal-box{background:#fff;border-radius:16px;padding:24px;width:calc(100% - 48px);max-width:360px;text-align:center}
.modal-box .m-icon{font-size:40px;margin-bottom:6px}
.modal-box .m-title{font-size:17px;font-weight:700;margin-bottom:4px}
.modal-box .m-desc{font-size:12px;color:var(--sub);margin-bottom:14px;line-height:1.6}
.sec-head{font-size:14px;font-weight:700;margin:14px 0 8px;display:flex;align-items:center;gap:6px}
.sec-head .dot{width:6px;height:6px;border-radius:50%;background:var(--pri);flex-shrink:0}
.scroll-x{display:flex;gap:10px;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}
.scroll-x::-webkit-scrollbar{display:none}
/* Back button container */
.back-row{display:flex;align-items:center;gap:6px;margin-bottom:10px}
.back-row .bk{cursor:pointer;font-size:13px;color:var(--pri);font-weight:600;display:flex;align-items:center;gap:2px}
/* ═══ SCHULTE 3D CUBE ═══ */
.cube-scene{perspective:900px;width:300px;height:300px;margin:20px auto;position:relative}
.cube-scene.paused .cube{animation-play-state:paused}
.cube{width:100%;height:100%;position:relative;transform-style:preserve-3d;transform:rotateX(-15deg) rotateY(25deg)}
.cube-face{position:absolute;width:300px;height:300px;border-radius:10px;backface-visibility:hidden}
.cube-front{transform:translateZ(150px);background:linear-gradient(135deg,#1a1a2e,#16213e)}
.cube-back{transform:rotateY(180deg) translateZ(150px);background:linear-gradient(135deg,#16213e,#0f3460)}
.cube-left{transform:rotateY(-90deg) translateZ(150px);background:linear-gradient(135deg,#0f3460,#1a1a2e)}
.cube-right{transform:rotateY(90deg) translateZ(150px);background:linear-gradient(135deg,#1a1a2e,#2d1b69)}
.cube-top{transform:rotateX(90deg) translateZ(150px);background:linear-gradient(135deg,#2d1b69,#16213e)}
.cube-bottom{transform:rotateX(-90deg) translateZ(150px);background:linear-gradient(135deg,#16213e,#1a1a2e)}
.cube-face .deco-face{font-size:32px;opacity:.2;text-align:center;line-height:1.3;pointer-events:none;position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.cube-grid{position:absolute;top:0;left:0;width:300px;height:300px;border-radius:10px;display:grid;grid-template-columns:repeat(5,1fr);grid-template-rows:repeat(5,1fr);gap:2px;padding:4px;z-index:10;background:rgba(26,26,46,.85);box-shadow:0 0 30px rgba(0,0,0,.4),inset 0 0 20px rgba(0,0,0,.2);perspective:400px}
.cube-grid .cs{display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:800;border-radius:6px;cursor:pointer;transition:transform .15s,box-shadow .15s;user-select:none;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,.92);color:var(--text);box-shadow:0 4px 14px rgba(0,0,0,.15);animation:cellFloat 3s ease-in-out infinite;transform-style:preserve-3d}
@keyframes cellFloat{0%,100%{transform:translateY(0) scale(1);box-shadow:0 4px 12px rgba(0,0,0,.18)}50%{transform:translateY(-12px) scale(1.06);box-shadow:0 18px 32px rgba(0,0,0,.42)}}
.cube-grid .cs:active{transform:scale(.9)!important;animation:none}
.cube-grid .cs.done{background:rgba(255,255,255,.12);color:transparent;box-shadow:none;pointer-events:none;opacity:0;animation:none}
.cube-grid .cs.next{animation:cellFloat 3s ease-in-out infinite,csPulse .8s ease-in-out infinite}
@keyframes csPulse{0%,100%{box-shadow:0 0 8px rgba(229,77,66,.3)}50%{box-shadow:0 0 24px rgba(229,77,66,.85)}}
.schulte-info{text-align:center;padding:8px 0;color:var(--sub);font-size:12px}
.schulte-timer{font-size:28px;font-weight:800;color:var(--pri);text-align:center;margin:8px 0}
.schulte-best{font-size:11px;color:var(--sub);text-align:center}
.schulte-cta{display:block;margin:10px auto;width:160px}
.schulte-result{text-align:center;padding:20px 0}
.schulte-result .sr-time{font-size:36px;font-weight:800;color:var(--pri)}
.schulte-result .sr-rank{font-size:13px;color:var(--sub);margin-top:4px}
/* Synastry tabs */
.syn-tab{flex:1;padding:8px 4px;border:none;border-radius:20px;background:#f0f0f0;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s;color:var(--sub)}
.syn-tab.active{background:var(--pri);color:#fff;box-shadow:0 2px 8px rgba(229,77,66,.2)}
</style>
</head>
<body>
<div class="topbar" id="topbar">
<button class="back-btn" id="backBtn" onclick="goBack()"></button>
<img src="logo.png" alt="愈心谷"><span class="tbt">星镜</span>
<div style="width:32px;flex-shrink:0"></div>
</div>
<!-- ═══════ PAGE: 首页 ═══════ -->
<div class="page active" id="page-home">
<div class="hero-card" id="homeHero">
<div class="h-stars"><span></span><span></span><span></span><span></span><span></span></div>
<div class="hlabel" id="hlMonth">今日星象</div>
<div class="hzodiac" id="hzEmoji">🔭</div>
<div class="hsign" id="hzSign">探索你的星盘</div>
<div class="hdate" id="hzDate">发现内在的宇宙</div>
<div class="haction" onclick="goTest()">✦ 开始星盘测试</div>
</div>
<div class="horo-card" id="horoCard">
<div class="hday"></div><div class="hstars">★★★★☆</div><div class="hmsg"></div>
<div style="font-size:10px;color:var(--sub);margin-top:6px">💛 幸运色:<span id="hlColor"></span> · 幸运数字:<span id="hlNum"></span></div>
</div>
<div class="quick-grid">
<div class="quick-item" onclick="goTest()"><div class="qi">🔮</div><div class="qt">星盘测试</div><div class="qd">生辰排盘 · 性格解读</div></div>
<div class="quick-item" onclick="switchTab('chart')"><div class="qi"></div><div class="qt">动态星盘</div><div class="qd">行星运转 · 实时动画</div></div>
<div class="quick-item" onclick="switchTab('community')"><div class="qi"></div><div class="qt">视频社区</div><div class="qd">达人解读 · 热门内容</div></div>
<div class="quick-item" onclick="switchTab('report')"><div class="qi">🎬</div><div class="qt">我的报告</div><div class="qd">历史记录 · 视频回放</div></div>
<div class="quick-item" onclick="openSchulte()"><div class="qi">🧊</div><div class="qt">舒尔特训练</div><div class="qd">3D魔方 · 前额叶激活</div></div>
<div class="quick-item" onclick="openSynastry()"><div class="qi">💫</div><div class="qt">合盘配对</div><div class="qd">双人星盘 · 缘分契合度</div></div>
</div>
<div class="sec-head"><span class="dot"></span>热门解读</div>
<div class="scroll-x" id="trendingRow"></div>
</div>
<!-- ═══════ PAGE: 测试-输入出生 ═══════ -->
<div class="page" id="page-test-birth">
<div class="back-row"><span class="bk" onclick="goHome()">← 返回首页</span></div>
<div class="card" style="text-align:center">
<div style="font-size:36px;margin-bottom:6px">🔭</div>
<div class="card-title">输入出生信息</div>
<div class="card-sub">解锁专属星盘与性格解读</div>
</div>
<div class="card">
<div class="input-row">
<input type="number" id="tYear" placeholder="1990" style="flex:1.2"><span class="lbl"></span>
<select id="tMonth" style="flex:0.9"><option value=""></option></select>
<select id="tDay" style="flex:0.9"><option value=""></option></select>
</div>
<div class="input-row">
<select id="tHour" style="flex:1"><option value="">时辰</option></select>
<span class="lbl"></span>
</div>
<div class="input-row">
<select id="tProv" style="flex:1" onchange="onProvChange()"><option value="">省份</option></select>
<select id="tCity" style="flex:1" onchange="onCityChange()"><option value="">市区</option></select>
<select id="tDist" style="flex:1"><option value="">县/区</option></select>
</div>
<button class="btn btn-pri btn-block" onclick="startQuiz()" style="margin-top:8px">下一步 →</button>
</div>
</div>
<!-- ═══════ PAGE: 测试-答题 ═══════ -->
<div class="page" id="page-test-quiz">
<div class="back-row"><span class="bk" onclick="goTest()">← 返回修改</span></div>
<div style="text-align:center;margin-bottom:8px">
<span style="font-size:11px;color:var(--sub)" id="quizHint"></span>
<div style="font-size:12px;color:var(--sub);margin-top:2px"><span id="qNow">1</span> / <span id="qTotal">10</span></div>
<div style="height:4px;background:#eee;border-radius:2px;overflow:hidden;margin-top:4px">
<div id="qBar" style="height:100%;background:var(--pri);border-radius:2px;transition:width 0.3s;width:10%"></div>
</div>
</div>
<div id="quizCard"></div>
</div>
<!-- ═══════ PAGE: 测试-结果 ═══════ -->
<div class="page" id="page-test-result">
<div class="back-row"><span class="bk" onclick="goHome()">← 返回首页</span></div>
<div id="resultContent"></div>
</div>
<!-- ═══════ PAGE: 星盘 ═══════ -->
<div class="page" id="page-chart">
<div style="text-align:center;padding:8px 0 4px;font-size:12px;color:var(--sub)" id="chartHint">点击行星查看详情</div>
<canvas id="chartCanvas"></canvas>
<div class="chart-info" id="chartInfo">
<span style="cursor:pointer;color:var(--pri);font-weight:600" onclick="toggleChartMode()" id="chartToggle">◎ 实时天象</span>
<span style="margin-left:8px;font-size:11px;color:var(--sub)">拖拽旋转 · 双指缩放 · 点击行星</span>
</div>
</div>
<!-- ═══════ PAGE: 报告 ═══════ -->
<div class="page" id="page-report">
<div class="sec-head"><span class="dot"></span>测试历史</div>
<div id="historyList"></div>
</div>
<!-- ═══════ PAGE: 社区 ═══════ -->
<div class="page" id="page-community">
<div class="feed-tabs" id="feedTabs"></div>
<div id="feedList"></div>
</div>
<!-- ═══════ PAGE: 我的 ═══════ -->
<div class="page" id="page-profile">
<div class="card" style="text-align:center">
<div style="width:56px;height:56px;border-radius:50%;margin:0 auto 8px;display:flex;align-items:center;justify-content:center" id="pAvatar"><span class="zodiac-dh earth" style="width:56px;height:56px;font-size:26px"></span></div>
<div class="card-title" id="pSign">探索者</div><div class="card-sub" id="pDetail">完成测试解锁完整档案</div>
</div>
<div class="sec-head"><span class="dot"></span>成就徽章</div>
<div class="badge-row" id="badgeRow"></div>
<div class="sec-head"><span class="dot"></span>会员订阅</div>
<div class="tier-card"><div class="t-name">免费版</div><div class="t-price">¥0<span class="unit"> /月</span></div><div class="t-feat">✓ 基础排盘 &nbsp; ✓ 30秒带水印报告 &nbsp; ✓ 每日运势 &nbsp; ✓ 社区浏览</div></div>
<div class="tier-card pro" onclick="openPurchase()"><div class="t-name">星镜会员</div><div class="t-price">¥24<span class="unit"> /月</span> <span style="font-size:11px;color:var(--sub);text-decoration:line-through">首月¥9.9</span></div><div class="t-feat">✓ 无水印完整视频报告 &nbsp; ✓ 高清3D星盘 &nbsp; ✓ AI数字人多风格 &nbsp; ✓ 专属课程库 &nbsp; ✓ 不限次数生成</div><button class="btn btn-pri btn-block btn-sm" style="margin-top:8px">立即开通</button></div>
<div class="tier-card" onclick="openPurchase()"><div class="t-name">年度会员</div><div class="t-price">¥168<span class="unit"> /年</span> <span style="font-size:11px;color:var(--teal)">省 ¥120</span></div><div class="t-feat">✓ 包含全部月会员权益 + 年度专属深度报告</div><button class="btn btn-outline btn-block btn-sm" style="margin-top:6px">开通年度</button></div>
<div class="sec-head"><span class="dot"></span>预约达人咨询</div>
<div class="card card-sm" style="margin-bottom:16px">
<select style="width:100%;padding:10px;border:1.5px solid #e8e0d8;border-radius:10px;font-size:13px;margin-bottom:8px;background:#fdfaf7"><option>选择咨询类型</option><option>视频一对一 · ¥199/30min</option><option>预制短视频解读 · ¥99/次</option><option>语音咨询 · ¥129/30min</option><option>图文咨询 · ¥49/次</option></select>
<textarea placeholder="简述你想咨询的问题..." style="width:100%;padding:10px;border:1.5px solid #e8e0d8;border-radius:10px;font-size:13px;resize:none;min-height:64px;font-family:inherit;background:#fdfaf7"></textarea>
<button class="btn btn-pri btn-block btn-sm" style="margin-top:8px" onclick="showToast('预约请求已提交,达人将在24小时内回复')">提交预约</button>
</div>
</div>
<!-- ═══════ PAGE: 舒尔特 ═══════ -->
<div class="page" id="page-schulte">
<div class="back-row"><span class="bk" onclick="goHome()">← 返回首页</span></div>
<div class="card" style="text-align:center;margin-bottom:12px">
<div style="font-size:28px">🧊</div>
<div class="card-title">舒尔特前额叶训练</div>
<div class="card-sub" id="schulteSub">按顺序点击 1→25,训练专注力与反应速度</div>
</div>
<div class="cube-scene" id="cubeScene">
<div class="cube" id="cubeEl">
<div class="cube-face cube-front"><div class="deco-face"><br>愈心谷</div></div>
<div class="cube-face cube-back"><div class="deco-face"><br>专注<br>前额叶</div></div>
<div class="cube-face cube-left"><div class="deco-face"><br>反应<br>速度</div></div>
<div class="cube-face cube-right"><div class="deco-face"><br>注意力</div></div>
<div class="cube-face cube-top"><div class="deco-face"><br>视觉<br>搜索</div></div>
<div class="cube-face cube-bottom"><div class="deco-face"><br>记忆</div></div>
</div>
<div class="cube-grid" id="cubeFront"></div>
</div>
<div class="schulte-timer" id="schulteTimer">00:00.0</div>
<div class="schulte-best" id="schulteBest"></div>
<button class="btn btn-pri schulte-cta" id="schulteBtn" onclick="startSchulte()">开始训练</button>
<div class="schulte-info">拖拽旋转 · 点击数字按序消除</div>
</div>
<!-- ═══════ PAGE: 合盘 ═══════ -->
<div class="page" id="page-synastry">
<div class="back-row"><span class="bk" onclick="goHome()">← 返回首页</span></div>
<div class="card" style="text-align:center">
<div style="font-size:36px" id="synIcon">💫</div>
<div class="card-title" id="synTitle">双人合盘 · 缘分配对</div>
<div class="card-sub" id="synSub">输入两人的出生信息,解锁星座契合度分析</div>
</div>
<div style="display:flex;gap:4px;margin-bottom:10px" id="synTabs">
<button class="syn-tab active" onclick="setSynMode('romance')" id="synTabRomance">❤️ 两性合盘</button>
<button class="syn-tab" onclick="setSynMode('friendship')" id="synTabFriend">🤝 缘分配对</button>
<button class="syn-tab" onclick="setSynMode('family')" id="synTabFamily">🏠 家庭合盘</button>
</div>
<div style="display:flex;gap:4px;margin-bottom:10px" id="synChartTabs">
<button class="syn-tab active" onclick="setSynChart('compare')">◎ 比较盘</button>
<button class="syn-tab" onclick="setSynChart('composite')">◉ 组合盘</button>
<button class="syn-tab" onclick="setSynChart('marksAB')">👁 马盘 A→B</button>
<button class="syn-tab" onclick="setSynChart('marksBA')">👁 马盘 B→A</button>
</div>
<div style="margin-bottom:8px">
<div class="card card-sm" style="background:linear-gradient(135deg,#fff5f5,#fff);border-left:3px solid #E54D42">
<div style="font-size:11px;color:var(--pri);font-weight:700;margin-bottom:6px" id="synLabel1">👤 你</div>
<div class="input-row"><input type="number" id="s1Year" placeholder="1990" style="flex:1.2"><span class="lbl"></span><select id="s1Month" style="flex:0.9"><option value=""></option></select><select id="s1Day" style="flex:0.9"><option value=""></option></select></div>
</div>
<div class="card card-sm" style="background:linear-gradient(135deg,#f5f0ff,#fff);border-left:3px solid #7B68EE;margin-top:8px">
<div style="font-size:11px;color:#7B68EE;font-weight:700;margin-bottom:6px;display:flex;align-items:center;gap:6px">
<span id="synLabel2">👤 TA</span>
<select id="synFamilyRel" style="display:none;padding:3px 6px;border:1px solid #7B68EE;border-radius:8px;font-size:11px;background:#fdfaf7;color:#7B68EE">
<option>父亲</option><option>母亲</option><option>兄弟</option><option>姐妹</option><option>子女</option><option>祖父母</option><option>其他家人</option>
</select>
</div>
<div class="input-row"><input type="number" id="s2Year" placeholder="1995" style="flex:1.2"><span class="lbl"></span><select id="s2Month" style="flex:0.9"><option value=""></option></select><select id="s2Day" style="flex:0.9"><option value=""></option></select></div>
</div>
</div>
<button class="btn btn-pri btn-block" onclick="runSynastry()" style="margin-bottom:12px" id="synBtn">💫 开始合盘分析</button>
<div id="synastryResult"></div>
</div>
<!-- ═══════ BOTTOM NAV ═══════ -->
<div class="nav" id="bottomNav">
<div class="nav-item active" onclick="switchTab('home')"><span class="ni"></span>首页</div>
<div class="nav-item" onclick="switchTab('chart')"><span class="ni"></span>星盘</div>
<div class="nav-item" onclick="switchTab('report')"><span class="ni"></span>报告</div>
<div class="nav-item" onclick="switchTab('community')"><span class="ni"></span>社区</div>
<div class="nav-item" onclick="switchTab('profile')"><span class="ni"></span>我的</div>
</div>
<!-- ═══════ VIDEO OVERLAY ═══════ -->
<div class="video-overlay" id="videoOverlay">
<button class="v-close" onclick="stopVideo()"></button>
<canvas class="v-canvas" id="videoCanvas"></canvas>
<div class="v-progress"><div class="v-bar" id="vBar" style="width:0%"></div></div>
<div class="v-watermark" id="vWatermark">星镜 · 预览版</div>
</div>
<div class="toast" id="toast"></div>
<div class="modal-overlay" id="purchaseModal">
<div class="modal-box">
<div class="m-icon"></div><div class="m-title">开通星镜会员</div>
<div class="m-desc">解锁无水印完整视频报告、高清3D星盘、专属课程等全部权益。<br>首月仅需 ¥9.9</div>
<button class="btn btn-pri btn-block" onclick="doPurchase()">¥9.9 立即开通</button>
<button class="btn btn-outline btn-block btn-sm" style="margin-top:6px" onclick="closePurchase()">暂不需要</button>
</div>
</div>
<script>
// ═══════ DATA ═══════
var ZODIAC=[
{name:'摩羯座',dh:'羯',el:'土',trait:'坚韧·务实·野心',color:'#8B7355',range:[[1,1,1,19],[12,22,12,31]]},
{name:'水瓶座',dh:'瓶',el:'风',trait:'独立·创新·博爱',color:'#4A90E2',range:[[1,20,2,18]]},
{name:'双鱼座',dh:'鱼',el:'水',trait:'敏感·梦幻·共情',color:'#7B68EE',range:[[2,19,3,20]]},
{name:'白羊座',dh:'羊',el:'火',trait:'勇敢·冲动·开创',color:'#E54D42',range:[[3,21,4,19]]},
{name:'金牛座',dh:'牛',el:'土',trait:'稳重·固执·审美',color:'#5CB85C',range:[[4,20,5,20]]},
{name:'双子座',dh:'子',el:'风',trait:'多变·聪明·好奇',color:'#F5A623',range:[[5,21,6,21]]},
{name:'巨蟹座',dh:'蟹',el:'水',trait:'温柔·念旧·顾家',color:'#C0C0C0',range:[[6,22,7,22]]},
{name:'狮子座',dh:'狮',el:'火',trait:'自信·慷慨·领袖',color:'#FFD700',range:[[7,23,8,22]]},
{name:'处女座',dh:'女',el:'土',trait:'细致·完美·服务',color:'#8B8B83',range:[[8,23,9,22]]},
{name:'天秤座',dh:'秤',el:'风',trait:'优雅·平衡·犹豫',color:'#FF69B4',range:[[9,23,10,23]]},
{name:'天蝎座',dh:'蝎',el:'水',trait:'深刻·神秘·执着',color:'#8B0000',range:[[10,24,11,22]]},
{name:'射手座',dh:'射',el:'火',trait:'乐观·自由·冒险',color:'#FF6347',range:[[11,23,12,21]]}
];
var ZODIAC_ICON={"摩羯座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjVFNkQzIiBzdHJva2U9IiNBMEE1NUIiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiNDNEE4N0MiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzZCNEYzQSIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMjAgMzhjMi00IDYtOCAxMi04czEwIDQgMTIgOCIvPgo8cGF0aCBkPSJNMjUgMzBjMS0yIDMtNCA3LTNjMyAxIDUgMyA1IDMiLz4KPHBhdGggZD0iTTE4IDQyYzIgNCA2IDggOCAxNGMxIDMgMCA1LTIgNiIvPgo8cGF0aCBkPSJNNDYgNDJjLTIgNC02IDgtOCAxNGMtMSAzIDAgNSAyIDYiLz4KPC9nPgo8Y2lyY2xlIGN4PSIzMiIgY3k9IjIyIiByPSIyIiBmaWxsPSIjNkI0RjNBIi8+Cjwvc3ZnPg==","水瓶座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjBGNUY4IiBzdHJva2U9IiM1QjhGQTgiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiM3QkFGQzgiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzNBNjA3MCIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMjIgMTRjMCAyIDIgNCA1IDRoMTBjMyAwIDUtMiA1LTQiLz4KPHBhdGggZD0iTTI0IDE4djEwYzAgNi0yIDEwLTQgMTRjMiAyIDQgNCA2IDRoMTJjMiAwIDQtMiA2LTRjLTItNC00LTgtNC0xNFYxOCIvPgo8cGF0aCBkPSJNMjggMzBjMi0yIDQtNCA4LTNjMyAxIDQgMyA0IDNNMjcgMzZjMi0yIDUtMyA4LTJNMjUgNDJjMi0yIDUtMyA4LTIiLz4KPC9nPgo8L3N2Zz4=","双鱼座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjJGMEY4IiBzdHJva2U9IiM2QjVCOTUiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiM4QjdCQjUiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzRBMzU3MCIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMjIgMjJjNi00IDE0LTIgMTYgNmMyIDgtNCAxNC0xMCAxNHMtMTAtNi04LTE0Ii8+CjxjaXJjbGUgY3g9IjIwIiBjeT0iMjAiIHI9IjEuNSIgZmlsbD0iIzRBMzU3MCIvPgo8cGF0aCBkPSJNNDIgNDJjLTYgNC0xNCAyLTE2LTZjLTItOCA0LTE0IDEwLTE0czEwIDYgOCAxNCIvPgo8Y2lyY2xlIGN4PSI0NCIgY3k9IjQ0IiByPSIxLjUiIGZpbGw9IiM0QTM1NzAiLz4KPHBhdGggZD0iTTMwIDM0YzEtMiAzLTIgNCAwIi8+CjwvZz4KPC9zdmc+","白羊座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRkRGMkVDIiBzdHJva2U9IiNDMDQwMzAiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiNEMDYwNTAiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzhCMjAyMCIgc3Ryb2tlLXdpZHRoPSIyLjIiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+CjxwYXRoIGQ9Ik0xNiAzNmMyLTggNi0xNCAxNC0xNmMzLTEgNiAwIDggMiIvPgo8cGF0aCBkPSJNNDggMzZjLTItOC02LTE0LTE0LTE2Yy0zLTEtNiAwLTggMiIvPgo8cGF0aCBkPSJNMTggMzhjNC0xMiA4LTE0IDE0LTEyYzYgMiA4IDggOCA4TTQ2IDM4Yy00LTEyLTgtMTQtMTQtMTJjLTYgMi04IDgtOCA4Ii8+CjwvZz4KPHBhdGggZD0iTTI4IDQwYzAtMiAyLTQgNC00czQgMiA0IDQiIHN0cm9rZT0iIzhCMjAyMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIGZpbGw9Im5vbmUiLz4KPC9zdmc+","金牛座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjhGMkVBIiBzdHJva2U9IiNBMDg1NUIiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiNDNEE4N0MiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzZCNEYzQSIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMjYgMjBjMi02IDgtOCAxMi02YzIgMSA0IDMgNCA2Ii8+CjxwYXRoIGQ9Ik0xOCAyOGMwIDQgMiA4IDYgMTBsNCAxMGMxIDIgMiAzIDQgM3MzLTEgNC0zbDQtMTBjNC0yIDYtNiA2LTEwIi8+CjxjaXJjbGUgY3g9IjI0IiBjeT0iMjQiIHI9IjIiIGZpbGw9IiM2QjRGM0EiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyNCIgcj0iMiIgZmlsbD0iIzZCNEYzQSIvPgo8cGF0aCBkPSJNMjggMzRoOCIvPgo8L2c+Cjwvc3ZnPg==","双子座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjBGNUY4IiBzdHJva2U9IiM1QjhGQTgiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiM3QkFGQzgiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzNBNjA3MCIgc3Ryb2tlLXdpZHRoPSIxLjgiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+CjxwYXRoIGQ9Ik0yMiAxNGMwIDQgMiA2IDUgNnM1LTIgNS02Ii8+CjxwYXRoIGQ9Ik0yMiAyMHYyMGMwIDYgMiAxMCA0IDEyIi8+CjxwYXRoIGQ9Ik0zMCAxNGMwIDQgMiA2IDUgNnM1LTIgNS02Ii8+CjxwYXRoIGQ9Ik0zMCAyMHYyMGMwIDYgMiAxMCA0IDEyIi8+CjxwYXRoIGQ9Ik0yNCAyOGMxLTIgMy0zIDUtMk0zMiAyOGMxLTIgMy0zIDUtMiIvPgo8L2c+CjxjaXJjbGUgY3g9IjI0IiBjeT0iMTQiIHI9IjMiIGZpbGw9IiMzQTYwNzAiLz4KPGNpcmNsZSBjeD0iMzIiIGN5PSIxNCIgcj0iMyIgZmlsbD0iIzNBNjA3MCIvPgo8L3N2Zz4=","巨蟹座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjJGMEY4IiBzdHJva2U9IiM2QjVCOTUiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiM4QjdCQjUiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzRBMzU3MCIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMTYgMjhjNC00IDgtNCAxMi0yYzItMyA1LTMgOCAwYzMtMyA2LTMgMTAtMiIvPgo8cGF0aCBkPSJNMTQgMzRjNCA2IDggMTAgMTggMTBzMTQtNCAxOC0xMCIvPgo8cGF0aCBkPSJNMjQgNDRjMyA0IDYgNiA4IDZzNS0yIDgtNiIvPgo8cGF0aCBkPSJNMTggMzR2LTZNNDYgMzR2LTYiLz4KPC9nPgo8Y2lyY2xlIGN4PSIxOCIgY3k9IjIyIiByPSIyIiBmaWxsPSIjNEEzNTcwIi8+CjxjaXJjbGUgY3g9IjQ2IiBjeT0iMjIiIHI9IjIiIGZpbGw9IiM0QTM1NzAiLz4KPC9zdmc+","狮子座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRkRGMkVDIiBzdHJva2U9IiNDMDQwMzAiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiNEMDYwNTAiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzhCMjAyMCIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMzIgMTJjLTYgMi0xMCA2LTEyIDEwYy0xIDItMSA0IDAgNmMyIDYgNiAxMCAxMiAxMmM2LTIgMTAtNiAxMi0xMmMxLTIgMS00IDAtNmMtMi00LTYtOC0xMi0xMHoiLz4KPHBhdGggZD0iTTI4IDIyYzEtMiAzLTMgNC0yczEgMyAwIDQiLz4KPHBhdGggZD0iTTM2IDIyYy0xLTItMy0zLTQtMnMtMSAzIDAgNCIvPgo8cGF0aCBkPSJNMzAgMjhjMC0xIDEtMSAyIDBjMSAxIDEgMSAyIDAiLz4KPC9nPgo8L3N2Zz4=","处女座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjhGMkVBIiBzdHJva2U9IiNBMDg1NUIiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiNDNEE4N0MiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzZCNEYzQSIgc3Ryb2tlLXdpZHRoPSIxLjgiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+CjxwYXRoIGQ9Ik0zMiAxMmMwIDQtMiA2LTUgNiIvPgo8cGF0aCBkPSJNMzIgMTh2MTJjMCA4LTIgMTItNCAxNmMyIDIgNCA0IDggNHM2LTIgOC00Yy0yLTQtNC04LTQtMTZWMTgiLz4KPHBhdGggZD0iTTIyIDQ2bDQtNGw0IDQiLz4KPHBhdGggZD0iTTQyIDQ2bC00LTRsLTQgNCIvPgo8cGF0aCBkPSJNMjggMjBsMiAxNCIvPgo8cGF0aCBkPSJNMzYgMjBsLTIgMTQiLz4KPC9nPgo8Y2lyY2xlIGN4PSIyNyIgY3k9IjEyIiByPSIzIiBmaWxsPSIjNkI0RjNBIi8+Cjwvc3ZnPg==","天秤座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjBGNUY4IiBzdHJva2U9IiM1QjhGQTgiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiM3QkFGQzgiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzNBNjA3MCIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMTYgMThoMzIiLz4KPHBhdGggZD0iTTMyIDE4djgiLz4KPHBhdGggZD0iTTE4IDI2bC0yIDhjMCAyIDEgNCAzIDRzMy0yIDMtNGMwIDIgMSA0IDMgNHMzLTItMy00YzAgMiAxIDQgMyA0czMtMiAzLTRsLTItOCIvPgo8cGF0aCBkPSJNMjAgNDJjNCA2IDggMTAgMTIgMTBzOC00IDEyLTEwIi8+CjwvZz4KPC9zdmc+","天蝎座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRjJGMEY4IiBzdHJva2U9IiM2QjVCOTUiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiM4QjdCQjUiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzRBMzU3MCIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPgo8cGF0aCBkPSJNMjggMTZjLTQgMC02IDQtNiA4YzAgMyAxIDUgMyA2Ii8+CjxwYXRoIGQ9Ik0zNiAxNmM0IDAgNiA0IDYgOGMwIDMtMSA1LTMgNiIvPgo8cGF0aCBkPSJNMjIgMzBjLTIgNC00IDEwLTIgMTRjMiA1IDYgOCAxMiA4czEwLTMgMTItOGMyLTQgMC0xMC0yLTE0Ii8+CjxwYXRoIGQ9Ik0zMiAzMHYyMiIvPgo8cGF0aCBkPSJNMjYgNDhjMyAzIDYgNCA4IDJjMy0zIDMtNiAxLTEwTTM4IDQ4Yy0zIDMtNiA0LTggMmMtMy0zLTMtNi0xLTEwIi8+CjwvZz4KPC9zdmc+","射手座":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjMwIiBmaWxsPSIjRkRGMkVDIiBzdHJva2U9IiNDMDQwMzAiIHN0cm9rZS13aWR0aD0iMi41Ii8+CjxjaXJjbGUgY3g9IjMyIiBjeT0iMzIiIHI9IjI4IiBmaWxsPSJub25lIiBzdHJva2U9IiNEMDYwNTAiIHN0cm9rZS13aWR0aD0iMC41Ii8+CjxnIHN0cm9rZT0iIzhCMjAyMCIgc3Ryb2tlLXdpZHRoPSIyLjIiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+CjxwYXRoIGQ9Ik0xOCA0NmMyLTggNi0xOCAxNi0zMGM0IDQgOCA2IDEyIDZjMiAwIDQtMSA0LTIiLz4KPHBhdGggZD0iTTM0IDE2YzYgMiAxMCA2IDEyIDEyIi8+CjxwYXRoIGQ9Ik00NiAyOGwtNCA4bC04LTQiLz4KPC9nPgo8cGF0aCBkPSJNMjggNDBjMCA2IDIgMTAgNCAxMmMyLTIgNC02IDQtMTIiIHN0cm9rZT0iIzhCMjAyMCIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KPC9zdmc+"};
function zodiacBadge(z){return '<span class="zodiac-dh '+(z.el==='火'?'fire':z.el==='土'?'earth':z.el==='风'?'air':'water')+'"><img src="'+ZODIAC_ICON[z.name]+'" width="32" height="32" alt="'+z.name+'" style="width:100%;height:100%;border-radius:50%"></span>';}
var HOURS=['子时 23-1','丑时 1-3','寅时 3-5','卯时 5-7','辰时 7-9','巳时 9-11','午时 11-13','未时 13-15','申时 15-17','酉时 17-19','戌时 19-21','亥时 21-23'];
var CITIES=['北京','上海','广州','深圳','成都','杭州','武汉','南京','西安','重庆','长沙','其他'];
var REGIONS={
'北京':{'北京':['东城','西城','朝阳','海淀','丰台','石景山','通州','大兴','顺义','昌平','房山','门头沟','平谷','怀柔','密云','延庆']},
'上海':{'上海':['黄浦','徐汇','长宁','静安','普陀','虹口','杨浦','浦东','闵行','宝山','嘉定','松江','金山','青浦','奉贤','崇明']},
'天津':{'天津':['和平','河东','河西','南开','河北','红桥','滨海','东丽','西青','津南','北辰','武清','宝坻','宁河','静海','蓟州']},
'重庆':{'重庆':['渝中','江北','沙坪坝','九龙坡','南岸','大渡口','北碚','渝北','巴南','万州','涪陵','黔江','长寿','江津','合川','永川','南川','綦江','大足','璧山','铜梁','潼南','荣昌','开州','梁平','武隆','城口','丰都','垫江','忠县','云阳','奉节','巫山','巫溪','石柱','秀山','酉阳','彭水']},
'广东':{'广州':['越秀','天河','海珠','荔湾','白云','黄埔','番禺','花都','南沙','从化','增城'],'深圳':['福田','罗湖','南山','盐田','宝安','龙岗','龙华','坪山','光明'],'珠海':['香洲','斗门','金湾'],'汕头':['金平','龙湖','濠江','潮阳','潮南','澄海','南澳'],'佛山':['禅城','南海','顺德','三水','高明'],'韶关':['浈江','武江','曲江','乐昌','南雄','始兴','仁化','翁源','新丰','乳源'],'湛江':['赤坎','霞山','坡头','麻章','廉江','雷州','吴川','遂溪','徐闻'],'肇庆':['端州','鼎湖','高要','四会','广宁','怀集','封开','德庆'],'江门':['蓬江','江海','新会','台山','开平','鹤山','恩平'],'茂名':['茂南','电白','高州','化州','信宜'],'惠州':['惠城','惠阳','博罗','惠东','龙门'],'梅州':['梅江','梅县','兴宁','大埔','丰顺','五华','平远','蕉岭'],'汕尾':['城区','陆丰','海丰','陆河'],'河源':['源城','紫金','龙川','连平','和平','东源'],'阳江':['江城','阳东','阳春','阳西'],'清远':['清城','清新','英德','连州','佛冈','阳山','连山','连南'],'东莞':['莞城','南城','东城','万江','虎门','长安','厚街','寮步','大朗','塘厦','凤岗','常平'],'中山':['石岐','东区','西区','南区','小榄','古镇','三乡','坦洲','南朗'],'潮州':['湘桥','潮安','饶平'],'揭阳':['榕城','揭东','普宁','惠来','揭西'],'云浮':['云城','云安','罗定','新兴','郁南']},
'江苏':{'南京':['玄武','秦淮','建邺','鼓楼','栖霞','雨花台','江宁','浦口','六合','溧水','高淳'],'苏州':['姑苏','虎丘','吴中','相城','吴江','常熟','张家港','昆山','太仓'],'无锡':['梁溪','锡山','惠山','滨湖','新吴','江阴','宜兴'],'常州':['天宁','钟楼','新北','武进','金坛','溧阳'],'镇江':['京口','润州','丹徒','丹阳','扬中','句容'],'南通':['崇川','通州','海门','启东','如皋','海安','如东'],'扬州':['广陵','邗江','江都','仪征','高邮','宝应'],'泰州':['海陵','高港','姜堰','兴化','靖江','泰兴'],'盐城':['亭湖','盐都','大丰','东台','响水','滨海','阜宁','射阳','建湖'],'淮安':['清江浦','淮安','淮阴','洪泽','涟水','盱眙','金湖'],'连云港':['连云','海州','赣榆','东海','灌云','灌南'],'徐州':['鼓楼','云龙','贾汪','泉山','铜山','新沂','邳州','丰县','沛县','睢宁'],'宿迁':['宿城','宿豫','沭阳','泗阳','泗洪']},
'浙江':{'杭州':['上城','拱墅','西湖','滨江','萧山','余杭','临平','钱塘','富阳','临安','桐庐','淳安','建德'],'宁波':['海曙','江北','北仑','镇海','鄞州','奉化','余姚','慈溪','象山','宁海'],'温州':['鹿城','龙湾','瓯海','洞头','瑞安','乐清','永嘉','平阳','苍南','文成','泰顺'],'嘉兴':['南湖','秀洲','海宁','平湖','桐乡','嘉善','海盐'],'湖州':['吴兴','南浔','德清','长兴','安吉'],'绍兴':['越城','柯桥','上虞','诸暨','嵊州','新昌'],'金华':['婺城','金东','兰溪','义乌','东阳','永康','武义','浦江','磐安'],'衢州':['柯城','衢江','江山','常山','开化','龙游'],'舟山':['定海','普陀','岱山','嵊泗'],'台州':['椒江','黄岩','路桥','温岭','临海','玉环','三门','天台','仙居'],'丽水':['莲都','龙泉','青田','缙云','遂昌','松阳','云和','庆元','景宁']},
'山东':{'济南':['历下','市中','槐荫','天桥','历城','长清','章丘','济阳','莱芜','钢城','平阴','商河'],'青岛':['市南','市北','黄岛','崂山','李沧','城阳','即墨','胶州','平度','莱西'],'淄博':['淄川','张店','博山','临淄','周村','桓台','高青','沂源'],'枣庄':['市中','薛城','峄城','台儿庄','山亭','滕州'],'东营':['东营','河口','垦利','利津','广饶'],'烟台':['芝罘','福山','牟平','莱山','蓬莱','龙口','莱阳','莱州','招远','栖霞','海阳'],'潍坊':['潍城','寒亭','坊子','奎文','青州','诸城','寿光','安丘','高密','昌邑','临朐','昌乐'],'济宁':['任城','兖州','曲阜','邹城','微山','鱼台','金乡','嘉祥','汶上','泗水','梁山'],'泰安':['泰山','岱岳','新泰','肥城','宁阳','东平'],'威海':['环翠','文登','荣成','乳山'],'日照':['东港','岚山','五莲','莒县'],'临沂':['兰山','罗庄','河东','沂南','郯城','沂水','兰陵','费县','平邑','莒南','蒙阴','临沭'],'德州':['德城','陵城','乐陵','禹城','宁津','庆云','临邑','齐河','平原','夏津','武城'],'聊城':['东昌府','茌平','临清','阳谷','莘县','东阿','冠县','高唐'],'滨州':['滨城','沾化','邹平','惠民','阳信','无棣','博兴'],'菏泽':['牡丹','定陶','曹县','单县','成武','巨野','郓城','鄄城','东明']},
'河南':{'郑州':['中原','二七','管城','金水','上街','惠济','巩义','荥阳','新密','新郑','登封','中牟'],'开封':['龙亭','顺河','鼓楼','禹王台','祥符','杞县','通许','尉氏','兰考'],'洛阳':['老城','西工','瀍河','涧西','偃师','孟津','新安','栾川','嵩县','汝阳','宜阳','洛宁','伊川'],'平顶山':['新华','卫东','石龙','湛河','舞钢','汝州','宝丰','叶县','鲁山','郏县'],'安阳':['文峰','北关','殷都','龙安','林州','安阳','汤阴','滑县','内黄'],'鹤壁':['鹤山','山城','淇滨','浚县','淇县'],'新乡':['红旗','卫滨','凤泉','牧野','卫辉','辉县','新乡','获嘉','原阳','延津','封丘','长垣'],'焦作':['解放','中站','马村','山阳','沁阳','孟州','修武','博爱','武陟','温县'],'濮阳':['华龙','清丰','南乐','范县','台前','濮阳'],'许昌':['魏都','建安','禹州','长葛','鄢陵','襄城'],'漯河':['源汇','郾城','召陵','舞阳','临颍'],'三门峡':['湖滨','陕州','义马','灵宝','渑池','卢氏'],'南阳':['宛城','卧龙','邓州','南召','方城','西峡','镇平','内乡','淅川','社旗','唐河','新野','桐柏'],'商丘':['梁园','睢阳','永城','民权','睢县','宁陵','柘城','虞城','夏邑'],'信阳':['浉河','平桥','罗山','光山','新县','商城','固始','潢川','淮滨','息县'],'周口':['川汇','淮阳','项城','扶沟','西华','商水','沈丘','郸城','太康','鹿邑'],'驻马店':['驿城','西平','上蔡','平舆','正阳','确山','泌阳','汝南','遂平','新蔡'],'济源':['济源']},
'河北':{'石家庄':['长安','桥西','新华','井陉','裕华','藁城','鹿泉','栾城','正定','行唐','灵寿','高邑','深泽','赞皇','无极','平山','元氏','赵县','晋州','新乐'],'唐山':['路南','路北','古冶','开平','丰南','丰润','曹妃甸','遵化','迁安','滦州','滦南','乐亭','迁西','玉田'],'秦皇岛':['海港','山海关','北戴河','抚宁','昌黎','卢龙','青龙'],'邯郸':['邯山','丛台','复兴','峰峰','肥乡','永年','武安','临漳','成安','大名','涉县','磁县','邱县','鸡泽','广平','馆陶','魏县','曲周'],'邢台':['襄都','信都','任泽','南和','南宫','沙河','临城','内丘','柏乡','隆尧','宁晋','巨鹿','新河','广宗','平乡','威县','清河','临西'],'保定':['竞秀','莲池','满城','清苑','徐水','涿州','定州','安国','高碑店','涞水','阜平','定兴','唐县','高阳','容城','涞源','望都','安新','易县','曲阳','蠡县','顺平','博野','雄县'],'张家口':['桥东','桥西','宣化','下花园','万全','崇礼','张北','康保','沽源','尚义','蔚县','阳原','怀安','怀来','涿鹿','赤城'],'承德':['双桥','双滦','鹰手营子','平泉','承德','兴隆','滦平','隆化','丰宁','宽城','围场'],'沧州':['新华','运河','泊头','任丘','黄骅','河间','沧县','青县','东光','海兴','盐山','肃宁','南皮','吴桥','献县','孟村'],'廊坊':['安次','广阳','霸州','三河','固安','永清','香河','大城','文安','大厂'],'衡水':['桃城','冀州','深州','枣强','武邑','武强','饶阳','安平','故城','景县','阜城']},
'四川':{'成都':['锦江','青羊','金牛','武侯','成华','龙泉驿','青白江','新都','温江','双流','郫都','新津','都江堰','彭州','邛崃','崇州','简阳','金堂','大邑','蒲江'],'绵阳':['涪城','游仙','安州','江油','三台','盐亭','梓潼','平武','北川'],'自贡':['自流井','贡井','大安','沿滩','荣县','富顺'],'攀枝花':['东区','西区','仁和','米易','盐边'],'泸州':['江阳','纳溪','龙马潭','泸县','合江','叙永','古蔺'],'德阳':['旌阳','罗江','广汉','什邡','绵竹','中江'],'广元':['利州','昭化','朝天','旺苍','青川','剑阁','苍溪'],'遂宁':['船山','安居','射洪','蓬溪','大英'],'内江':['市中','东兴','隆昌','威远','资中'],'乐山':['市中','沙湾','五通桥','金口河','峨眉山','犍为','井研','夹江','沐川','峨边','马边'],'南充':['顺庆','高坪','嘉陵','阆中','南部','营山','蓬安','仪陇','西充'],'眉山':['东坡','彭山','仁寿','洪雅','丹棱','青神'],'宜宾':['翠屏','南溪','叙州','江安','长宁','高县','珙县','筠连','兴文','屏山'],'广安':['广安','前锋','华蓥','岳池','武胜','邻水'],'达州':['通川','达川','万源','宣汉','开江','大竹','渠县'],'雅安':['雨城','名山','荥经','汉源','石棉','天全','芦山','宝兴'],'巴中':['巴州','恩阳','通江','南江','平昌'],'资阳':['雁江','安岳','乐至'],'凉山':['西昌','会理','木里','盐源','德昌','会东','宁南','普格','布拖','金阳','昭觉','喜德','冕宁','越西','甘洛','美姑','雷波'],'甘孜':['康定','泸定','丹巴','九龙','雅江','道孚','炉霍','甘孜','新龙','德格','白玉','石渠','色达','理塘','巴塘','乡城','稻城','得荣'],'阿坝':['马尔康','汶川','理县','茂县','松潘','九寨沟','金川','小金','黑水','壤塘','阿坝','若尔盖','红原']},
'湖北':{'武汉':['江岸','江汉','硚口','汉阳','武昌','青山','洪山','东西湖','汉南','蔡甸','江夏','黄陂','新洲'],'黄石':['黄石港','西塞山','下陆','铁山','大冶','阳新'],'十堰':['茅箭','张湾','郧阳','丹江口','郧西','竹山','竹溪','房县'],'宜昌':['西陵','伍家岗','点军','猇亭','夷陵','宜都','当阳','枝江','远安','兴山','秭归','长阳','五峰'],'襄阳':['襄城','樊城','襄州','老河口','枣阳','宜城','南漳','谷城','保康'],'鄂州':['鄂城','华容','梁子湖'],'荆门':['东宝','掇刀','钟祥','京山','沙洋'],'孝感':['孝南','应城','安陆','汉川','孝昌','大悟','云梦'],'荆州':['沙市','荆州','石首','洪湖','松滋','监利','公安','江陵'],'黄冈':['黄州','麻城','武穴','团风','红安','罗田','英山','浠水','蕲春','黄梅'],'咸宁':['咸安','赤壁','嘉鱼','通城','崇阳','通山'],'随州':['曾都','广水','随县'],'恩施':['恩施','利川','建始','巴东','宣恩','咸丰','来凤','鹤峰'],'仙桃':['仙桃'],'潜江':['潜江'],'天门':['天门']},
'湖南':{'长沙':['芙蓉','天心','岳麓','开福','雨花','望城','浏阳','宁乡','长沙'],'株洲':['天元','荷塘','芦淞','石峰','渌口','醴陵','攸县','茶陵','炎陵'],'湘潭':['雨湖','岳塘','湘乡','韶山','湘潭'],'衡阳':['珠晖','雁峰','石鼓','蒸湘','南岳','耒阳','常宁','衡阳','衡南','衡山','衡东','祁东'],'邵阳':['双清','大祥','北塔','武冈','邵东','新邵','邵阳','隆回','洞口','绥宁','新宁','城步'],'岳阳':['岳阳楼','云溪','君山','汨罗','临湘','岳阳','华容','湘阴','平江'],'常德':['武陵','鼎城','津市','安乡','汉寿','澧县','临澧','桃源','石门'],'张家界':['永定','武陵源','慈利','桑植'],'益阳':['资阳','赫山','沅江','南县','桃江','安化'],'郴州':['北湖','苏仙','资兴','桂阳','宜章','永兴','嘉禾','临武','汝城','桂东','安仁'],'永州':['零陵','冷水滩','祁阳','东安','双牌','道县','江永','宁远','蓝山','新田','江华'],'怀化':['鹤城','洪江','中方','沅陵','辰溪','溆浦','会同','麻阳','新晃','芷江','靖州','通道'],'娄底':['娄星','冷水江','涟源','双峰','新化'],'湘西':['吉首','泸溪','凤凰','花垣','保靖','古丈','永顺','龙山']},
'福建':{'福州':['鼓楼','台江','仓山','马尾','晋安','长乐','福清','闽侯','连江','罗源','闽清','永泰','平潭'],'厦门':['思明','湖里','集美','海沧','同安','翔安'],'莆田':['城厢','涵江','荔城','秀屿','仙游'],'三明':['三元','沙县','永安','明溪','清流','宁化','大田','尤溪','将乐','泰宁','建宁'],'泉州':['鲤城','丰泽','洛江','泉港','石狮','晋江','南安','惠安','安溪','永春','德化','金门'],'漳州':['芗城','龙文','龙海','长泰','云霄','漳浦','诏安','东山','南靖','平和','华安'],'南平':['延平','建阳','邵武','武夷山','建瓯','顺昌','浦城','光泽','松溪','政和'],'龙岩':['新罗','永定','漳平','长汀','上杭','武平','连城'],'宁德':['蕉城','福安','福鼎','霞浦','古田','屏南','寿宁','周宁','柘荣']},
'安徽':{'合肥':['瑶海','庐阳','蜀山','包河','巢湖','长丰','肥东','肥西','庐江'],'芜湖':['镜湖','鸠江','弋江','湾沚','繁昌','无为','南陵'],'蚌埠':['龙子湖','蚌山','禹会','淮上','怀远','五河','固镇'],'淮南':['大通','田家庵','谢家集','八公山','潘集','凤台','寿县'],'马鞍山':['花山','雨山','博望','当涂','含山','和县'],'淮北':['杜集','相山','烈山','濉溪'],'铜陵':['铜官','义安','郊区','枞阳'],'安庆':['迎江','大观','宜秀','桐城','怀宁','潜山','太湖','宿松','望江','岳西'],'黄山':['屯溪','黄山','徽州','歙县','休宁','黟县','祁门'],'滁州':['琅琊','南谯','天长','明光','来安','全椒','定远','凤阳'],'阜阳':['颍州','颍东','颍泉','界首','临泉','太和','阜南','颍上'],'宿州':['埇桥','砀山','萧县','灵璧','泗县'],'六安':['金安','裕安','叶集','霍邱','舒城','金寨','霍山'],'亳州':['谯城','涡阳','蒙城','利辛'],'池州':['贵池','东至','石台','青阳'],'宣城':['宣州','宁国','广德','郎溪','泾县','绩溪','旌德']},
'江西':{'南昌':['东湖','西湖','青云谱','青山湖','新建','红谷滩','南昌','进贤','安义'],'景德镇':['昌江','珠山','乐平','浮梁'],'萍乡':['安源','湘东','莲花','上栗','芦溪'],'九江':['濂溪','浔阳','柴桑','瑞昌','共青城','庐山','武宁','修水','永修','德安','都昌','湖口','彭泽'],'新余':['渝水','分宜'],'鹰潭':['月湖','余江','贵溪'],'赣州':['章贡','南康','赣县','瑞金','信丰','大余','上犹','崇义','安远','定南','全南','宁都','于都','兴国','会昌','寻乌','石城','龙南'],'吉安':['吉州','青原','井冈山','吉安','吉水','峡江','新干','永丰','泰和','遂川','万安','安福','永新'],'宜春':['袁州','丰城','樟树','高安','奉新','万载','上高','宜丰','靖安','铜鼓'],'抚州':['临川','东乡','南城','黎川','南丰','崇仁','乐安','宜黄','金溪','资溪','广昌'],'上饶':['信州','广丰','广信','德兴','玉山','铅山','横峰','弋阳','余干','鄱阳','万年','婺源']},
'辽宁':{'沈阳':['和平','沈河','大东','皇姑','铁西','苏家屯','浑南','沈北','于洪','辽中','新民','康平','法库'],'大连':['中山','西岗','沙河口','甘井子','旅顺口','金州','普兰店','瓦房店','庄河','长海'],'鞍山':['铁东','铁西','立山','千山','海城','台安','岫岩'],'抚顺':['新抚','东洲','望花','顺城','抚顺','新宾','清原'],'本溪':['平山','溪湖','明山','南芬','本溪','桓仁'],'丹东':['元宝','振兴','振安','东港','凤城','宽甸'],'锦州':['古塔','凌河','太和','凌海','北镇','黑山','义县'],'营口':['站前','西市','鲅鱼圈','老边','盖州','大石桥'],'阜新':['海州','新邱','太平','清河门','细河','彰武','阜新'],'辽阳':['白塔','文圣','宏伟','弓长岭','太子河','灯塔','辽阳'],'盘锦':['双台子','兴隆台','大洼','盘山'],'铁岭':['银州','清河','调兵山','开原','铁岭','西丰','昌图'],'朝阳':['双塔','龙城','北票','凌源','朝阳','建平','喀左'],'葫芦岛':['连山','龙港','南票','兴城','绥中','建昌']},
'陕西':{'西安':['新城','碑林','莲湖','灞桥','未央','雁塔','阎良','临潼','长安','高陵','鄠邑','蓝田','周至'],'铜川':['王益','印台','耀州','宜君'],'宝鸡':['渭滨','金台','陈仓','凤翔','岐山','扶风','眉县','陇县','千阳','麟游','凤县','太白'],'咸阳':['秦都','杨陵','渭城','兴平','三原','泾阳','乾县','礼泉','永寿','长武','旬邑','淳化','武功','彬州'],'渭南':['临渭','华州','韩城','华阴','潼关','大荔','合阳','澄城','蒲城','白水','富平'],'延安':['宝塔','安塞','子长','延长','延川','志丹','吴起','甘泉','富县','洛川','宜川','黄龙','黄陵'],'汉中':['汉台','南郑','城固','洋县','西乡','勉县','宁强','略阳','镇巴','留坝','佛坪'],'榆林':['榆阳','横山','神木','府谷','靖边','定边','绥德','米脂','佳县','吴堡','清涧','子洲'],'安康':['汉滨','旬阳','汉阴','石泉','宁陕','紫阳','岚皋','平利','镇坪','白河'],'商洛':['商州','洛南','丹凤','商南','山阳','镇安','柞水']},
'山西':{'太原':['杏花岭','迎泽','小店','尖草坪','万柏林','晋源','古交','清徐','阳曲','娄烦'],'大同':['平城','云冈','新荣','云州','阳高','天镇','广灵','灵丘','浑源','左云'],'阳泉':['城区','矿区','郊区','平定','盂县'],'长治':['潞州','上党','屯留','潞城','襄垣','平顺','黎城','壶关','长子','武乡','沁县','沁源'],'晋城':['城区','泽州','高平','沁水','阳城','陵川'],'朔州':['朔城','平鲁','怀仁','山阴','应县','右玉'],'晋中':['榆次','太谷','介休','榆社','左权','和顺','昔阳','寿阳','祁县','平遥','灵石'],'运城':['盐湖','永济','河津','临猗','万荣','闻喜','稷山','新绛','绛县','垣曲','夏县','平陆','芮城'],'忻州':['忻府','原平','定襄','五台','代县','繁峙','宁武','静乐','神池','五寨','岢岚','河曲','保德','偏关'],'临汾':['尧都','侯马','霍州','曲沃','翼城','襄汾','洪洞','古县','安泽','浮山','吉县','乡宁','大宁','隰县','永和','蒲县','汾西'],'吕梁':['离石','孝义','汾阳','文水','交城','兴县','临县','柳林','石楼','岚县','方山','中阳','交口']},
'黑龙江':{'哈尔滨':['道里','南岗','道外','平房','松北','香坊','呼兰','阿城','双城','尚志','五常','依兰','方正','宾县','巴彦','木兰','通河','延寿'],'齐齐哈尔':['龙沙','建华','铁锋','昂昂溪','富拉尔基','碾子山','梅里斯','讷河','龙江','依安','泰来','甘南','富裕','克山','克东','拜泉'],'鸡西':['鸡冠','恒山','滴道','梨树','城子河','麻山','虎林','密山','鸡东'],'鹤岗':['向阳','工农','南山','兴安','东山','兴山','萝北','绥滨'],'双鸭山':['尖山','岭东','四方台','宝山','集贤','友谊','宝清','饶河'],'大庆':['萨尔图','龙凤','让胡路','红岗','大同','肇州','肇源','林甸','杜尔伯特'],'伊春':['伊美','乌翠','友好','金林','铁力','嘉荫','汤旺','丰林','大箐山','南岔'],'佳木斯':['前进','向阳','东风','郊区','同江','富锦','桦南','桦川','汤原','抚远'],'七台河':['新兴','桃山','茄子河','勃利'],'牡丹江':['东安','阳明','爱民','西安','绥芬河','海林','宁安','穆棱','东宁','林口'],'黑河':['爱辉','北安','五大连池','嫩江','逊克','孙吴'],'绥化':['北林','安达','肇东','海伦','望奎','兰西','青冈','庆安','明水','绥棱'],'大兴安岭':['加格达奇','漠河','呼玛','塔河']},
'吉林':{'长春':['南关','宽城','朝阳','二道','绿园','双阳','九台','榆树','德惠','公主岭','农安'],'吉林':['昌邑','龙潭','船营','丰满','永吉','蛟河','桦甸','舒兰','磐石'],'四平':['铁西','铁东','双辽','梨树','伊通'],'辽源':['龙山','西安','东丰','东辽'],'通化':['东昌','二道江','梅河口','集安','通化','辉南','柳河'],'白山':['浑江','江源','临江','抚松','靖宇','长白'],'松原':['宁江','扶余','长岭','乾安','前郭'],'白城':['洮北','洮南','大安','镇赉','通榆'],'延边':['延吉','图们','敦化','珲春','龙井','和龙','汪清','安图']},
'云南':{'昆明':['五华','盘龙','官渡','西山','东川','呈贡','安宁','晋宁','富民','宜良','嵩明','石林','禄劝','寻甸'],'曲靖':['麒麟','沾益','马龙','宣威','陆良','师宗','罗平','富源','会泽'],'玉溪':['红塔','江川','澄江','通海','华宁','易门','峨山','新平','元江'],'保山':['隆阳','腾冲','施甸','龙陵','昌宁'],'昭通':['昭阳','鲁甸','巧家','盐津','大关','永善','绥江','镇雄','彝良','威信','水富'],'丽江':['古城','玉龙','永胜','华坪','宁蒗'],'普洱':['思茅','宁洱','墨江','景东','景谷','镇沅','江城','孟连','澜沧','西盟'],'临沧':['临翔','凤庆','云县','永德','镇康','双江','耿马','沧源'],'楚雄':['楚雄','禄丰','双柏','牟定','南华','姚安','大姚','永仁','元谋','武定'],'红河':['蒙自','个旧','开远','弥勒','建水','石屏','泸西','元阳','红河','绿春','金平','屏边','河口'],'文山':['文山','砚山','西畴','麻栗坡','马关','丘北','广南','富宁'],'西双版纳':['景洪','勐海','勐腊'],'大理':['大理','祥云','宾川','弥渡','永平','云龙','洱源','剑川','鹤庆','漾濞','南涧','巍山'],'德宏':['芒市','瑞丽','梁河','盈江','陇川'],'怒江':['泸水','福贡','贡山','兰坪'],'迪庆':['香格里拉','德钦','维西']},
'贵州':{'贵阳':['南明','云岩','花溪','乌当','白云','观山湖','清镇','开阳','息烽','修文'],'六盘水':['钟山','水城','六枝','盘州'],'遵义':['红花岗','汇川','播州','赤水','仁怀','桐梓','绥阳','正安','道真','务川','凤冈','湄潭','余庆','习水'],'安顺':['西秀','平坝','普定','镇宁','关岭','紫云'],'毕节':['七星关','大方','黔西','金沙','织金','纳雍','威宁','赫章'],'铜仁':['碧江','万山','江口','玉屏','石阡','思南','印江','德江','沿河','松桃'],'黔西南':['兴义','兴仁','普安','晴隆','贞丰','望谟','册亨','安龙'],'黔东南':['凯里','黄平','施秉','三穗','镇远','岑巩','天柱','锦屏','剑河','台江','黎平','榕江','从江','雷山','麻江','丹寨'],'黔南':['都匀','福泉','荔波','贵定','瓮安','独山','平塘','罗甸','长顺','龙里','惠水','三都']},
'广西':{'南宁':['兴宁','青秀','江南','西乡塘','良庆','邕宁','武鸣','横州','隆安','马山','上林','宾阳'],'柳州':['城中','鱼峰','柳南','柳北','柳江','柳城','鹿寨','融安','融水','三江'],'桂林':['秀峰','叠彩','象山','七星','雁山','临桂','阳朔','灵川','全州','兴安','永福','灌阳','龙胜','资源','平乐','荔浦','恭城'],'梧州':['万秀','长洲','龙圩','岑溪','苍梧','藤县','蒙山'],'北海':['海城','银海','铁山港','合浦'],'防城港':['港口','防城','东兴','上思'],'钦州':['钦南','钦北','灵山','浦北'],'贵港':['港北','港南','覃塘','桂平','平南'],'玉林':['玉州','福绵','北流','容县','陆川','博白','兴业'],'百色':['右江','田阳','靖西','田东','德保','那坡','凌云','乐业','田林','西林','隆林'],'贺州':['八步','平桂','昭平','钟山','富川'],'河池':['金城江','宜州','南丹','天峨','凤山','东兰','罗城','环江','巴马','都安','大化'],'来宾':['兴宾','合山','忻城','象州','武宣','金秀'],'崇左':['江州','凭祥','扶绥','宁明','龙州','大新','天等']},
'海南':{'海口':['秀英','龙华','琼山','美兰'],'三亚':['海棠','吉阳','天涯','崖州'],'三沙':['三沙'],'儋州':['儋州'],'五指山':['五指山'],'琼海':['琼海'],'文昌':['文昌'],'万宁':['万宁'],'东方':['东方'],'定安':['定安'],'屯昌':['屯昌'],'澄迈':['澄迈'],'临高':['临高'],'白沙':['白沙'],'昌江':['昌江'],'乐东':['乐东'],'陵水':['陵水'],'保亭':['保亭'],'琼中':['琼中']},
'甘肃':{'兰州':['城关','七里河','西固','安宁','红古','永登','皋兰','榆中'],'嘉峪关':['嘉峪关'],'金昌':['金川','永昌'],'白银':['白银','平川','靖远','会宁','景泰'],'天水':['秦州','麦积','清水','秦安','甘谷','武山','张家川'],'武威':['凉州','民勤','古浪','天祝'],'张掖':['甘州','民乐','临泽','高台','山丹','肃南'],'平凉':['崆峒','华亭','泾川','灵台','崇信','庄浪','静宁'],'酒泉':['肃州','玉门','敦煌','金塔','瓜州','肃北','阿克塞'],'庆阳':['西峰','庆城','环县','华池','合水','正宁','宁县','镇原'],'定西':['安定','通渭','陇西','渭源','临洮','漳县','岷县'],'陇南':['武都','成县','文县','宕昌','康县','西和','礼县','徽县','两当'],'临夏':['临夏','临夏县','康乐','永靖','广河','和政','东乡','积石山'],'甘南':['合作','临潭','卓尼','舟曲','迭部','玛曲','碌曲','夏河']},
'内蒙古':{'呼和浩特':['新城','回民','玉泉','赛罕','托克托','和林格尔','清水河','武川','土默特左'],'包头':['昆都仑','青山','东河','九原','石拐','白云鄂博','固阳','土默特右','达尔罕茂明安'],'乌海':['海勃湾','海南','乌达'],'赤峰':['红山','元宝山','松山','阿鲁科尔沁','巴林左','巴林右','林西','克什克腾','翁牛特','喀喇沁','宁城','敖汉'],'通辽':['科尔沁','霍林郭勒','科尔沁左翼中','科尔沁左翼后','开鲁','库伦','奈曼','扎鲁特'],'鄂尔多斯':['东胜','康巴什','达拉特','准格尔','鄂托克前','鄂托克','杭锦','乌审','伊金霍洛'],'呼伦贝尔':['海拉尔','扎赉诺尔','满洲里','牙克石','扎兰屯','额尔古纳','根河','阿荣旗','莫力达瓦','鄂伦春','鄂温克','陈巴尔虎','新巴尔虎左','新巴尔虎右'],'巴彦淖尔':['临河','五原','磴口','乌拉特前','乌拉特中','乌拉特后','杭锦后'],'乌兰察布':['集宁','丰镇','卓资','化德','商都','兴和','凉城','察哈尔右翼前','察哈尔右翼中','察哈尔右翼后','四子王'],'兴安盟':['乌兰浩特','阿尔山','科尔沁右翼前','科尔沁右翼中','扎赉特','突泉'],'锡林郭勒':['锡林浩特','二连浩特','阿巴嘎','苏尼特左','苏尼特右','东乌珠穆沁','西乌珠穆沁','太仆寺','镶黄','正镶白','正蓝','多伦'],'阿拉善':['阿拉善左','阿拉善右','额济纳']},
'新疆':{'乌鲁木齐':['天山','沙依巴克','新市','水磨沟','头屯河','达坂城','米东','乌鲁木齐'],'克拉玛依':['克拉玛依','独山子','白碱滩','乌尔禾'],'吐鲁番':['高昌','鄯善','托克逊'],'哈密':['伊州','巴里坤','伊吾'],'昌吉':['昌吉','阜康','呼图壁','玛纳斯','奇台','吉木萨尔','木垒'],'博州':['博乐','阿拉山口','精河','温泉'],'巴州':['库尔勒','轮台','尉犁','若羌','且末','焉耆','和静','和硕','博湖'],'阿克苏':['阿克苏','温宿','库车','沙雅','新和','拜城','乌什','阿瓦提','柯坪'],'克州':['阿图什','阿克陶','阿合奇','乌恰'],'喀什':['喀什','疏附','疏勒','英吉沙','泽普','莎车','叶城','麦盖提','岳普湖','伽师','巴楚','塔什库尔干'],'和田':['和田','和田县','墨玉','皮山','洛浦','策勒','于田','民丰'],'伊犁':['伊宁','奎屯','霍尔果斯','伊宁县','察布查尔','霍城','巩留','新源','昭苏','特克斯','尼勒克'],'塔城':['塔城','乌苏','额敏','沙湾','托里','裕民','和布克赛尔'],'阿勒泰':['阿勒泰','布尔津','富蕴','福海','哈巴河','青河','吉木乃'],'石河子':['石河子']},
'西藏':{'拉萨':['城关','堆龙德庆','达孜','林周','当雄','尼木','曲水','墨竹工卡'],'日喀则':['桑珠孜','南木林','江孜','定日','萨迦','拉孜','昂仁','谢通门','白朗','仁布','康马','定结','仲巴','亚东','吉隆','聂拉木','萨嘎','岗巴'],'昌都':['卡若','江达','贡觉','类乌齐','丁青','察雅','八宿','左贡','芒康','洛隆','边坝'],'林芝':['巴宜','工布江达','米林','墨脱','波密','察隅','朗县'],'山南':['乃东','扎囊','贡嘎','桑日','琼结','曲松','措美','洛扎','加查','隆子','错那','浪卡子'],'那曲':['色尼','嘉黎','比如','聂荣','安多','申扎','索县','班戈','巴青','尼玛','双湖'],'阿里':['普兰','札达','噶尔','日土','革吉','改则','措勤']},
'青海':{'西宁':['城东','城中','城西','城北','湟中','湟源','大通'],'海东':['乐都','平安','民和','互助','化隆','循化'],'海北':['海晏','祁连','刚察','门源'],'黄南':['同仁','尖扎','泽库','河南'],'海南':['共和','同德','贵德','兴海','贵南'],'果洛':['玛沁','班玛','甘德','达日','久治','玛多'],'玉树':['玉树','杂多','称多','治多','囊谦','曲麻莱'],'海西':['德令哈','格尔木','茫崖','乌兰','都兰','天峻']},
'宁夏':{'银川':['兴庆','西夏','金凤','永宁','贺兰','灵武'],'石嘴山':['大武口','惠农','平罗'],'吴忠':['利通','红寺堡','青铜峡','盐池','同心'],'固原':['原州','西吉','隆德','泾源','彭阳'],'中卫':['沙坡头','中宁','海原']},
'香港':{'香港':['中西区','湾仔','东区','南区','油尖旺','深水埗','九龙城','黄大仙','观塘','荃湾','屯门','元朗','北区','大埔','沙田','西贡','离岛']},
'澳门':{'澳门':['澳门半岛','氹仔','路环']},
'台湾':{'台北':['中正','大同','中山','松山','大安','万华','信义','士林','北投','内湖','南港','文山'],'新北':['板桥','三重','中和','永和','新庄','新店','土城','芦洲','汐止','树林','淡水'],'桃园':['桃园','中坜','平镇','八德','杨梅','芦竹','大溪'],'台中':['中区','东区','南区','西区','北区','北屯','西屯','南屯','大里','太平','丰原'],'台南':['中西','东区','南区','北区','安平','安南','永康','新营'],'高雄':['苓雅','前镇','三民','新兴','前金','盐埕','鼓山','左营','楠梓','凤山','冈山'],'基隆':['仁爱','信义','中正','中山','安乐','暖暖','七堵'],'新竹':['东区','北区','香山','竹北'],'嘉义':['东区','西区'],'苗栗':['苗栗','头份','竹南'],'彰化':['彰化','员林'],'南投':['南投','埔里','草屯'],'云林':['斗六','虎尾'],'屏东':['屏东','潮州'],'宜兰':['宜兰','罗东'],'花莲':['花莲'],'台东':['台东'],'澎湖':['马公']}
};
var QUIZ=[
{q:'周末你更倾向于怎样度过?',d:'探索社交能量来源',opts:['宅家看书看剧,享受独处时光','约上好友聚会,热闹才开心','一个人去户外徒步探索','看心情,随时切换']},
{q:'做重要决定时,你更依赖什么?',d:'揭示决策模式',opts:['逻辑分析和客观事实','直觉和内心感受','多方征求意见后再定','综合考虑,权衡利弊']},
{q:'面对突如其来的变化,第一反应?',d:'测试应变模式',opts:['立即调整计划,快速适应','先有点慌,然后慢慢接受','感到兴奋,喜欢新鲜感','冷静分析,找到最优应对']},
{q:'在团队中你通常扮演什么角色?',d:'了解协作风格',opts:['组织者和领导者','创意提供者','执行者和细节把控者','协调者和氛围维护者']},
{q:'朋友形容你最多的是什么?',d:'外部认知画像',opts:['理性、冷静、靠谱','热情、阳光、有趣','温柔、体贴、细腻','独立、自由、有主见']},
{q:'你更容易被什么打动?',d:'情感触发点',opts:['一段感人的故事','一个精妙的创意','一处绝美的风景','一个实实在在的帮助']},
{q:'面对压力时通常怎么做?',d:'压力应对机制',opts:['制定详细计划,一步步解决','找人倾诉,释放情绪','暂时逃避,给自己缓冲时间','运动或做事来转移注意力']},
{q:'情绪更像哪种自然现象?',d:'情绪波动模式',opts:['深海——表面平静,内在丰富','火焰——来得快去得也快','潮汐——有规律地起伏','山峦——稳定不易波动']},
{q:'理想中的生活状态?',d:'人生价值取向',opts:['稳步上升,一切在掌控中','充满惊喜和可能性','宁静平和,岁月静好','自由自在,不被束缚']},
{q:'亲密关系中最看重什么?',d:'关系需求模式',opts:['深度的灵魂共鸣和理解','浪漫和激情,保持新鲜感','稳定的陪伴和安全感','共同成长,互相成就']}
];
var PLANETS=[
{name:'太阳',r:0,s:0,size:14,color:'#FFD700',glow:'rgba(255,215,0,0.3)',desc:'核心自我 · 生命力',orbitDays:365.25},
{name:'月亮',r:34,s:0.015,size:8,color:'#C0C0C0',glow:'rgba(192,192,192,0.2)',desc:'情绪反应 · 潜意识',orbitDays:27.32},
{name:'水星',r:52,s:0.025,size:5,color:'#B8860B',glow:'rgba(184,134,11,0.15)',desc:'思维方式 · 沟通',orbitDays:87.97},
{name:'金星',r:68,s:0.018,size:7,color:'#FF69B4',glow:'rgba(255,105,180,0.2)',desc:'爱情观念 · 审美',orbitDays:224.7},
{name:'火星',r:82,s:0.012,size:6,color:'#E54D42',glow:'rgba(229,77,66,0.2)',desc:'行动模式 · 欲望',orbitDays:686.98},
{name:'木星',r:98,s:0.008,size:11,color:'#F5A623',glow:'rgba(245,166,35,0.2)',desc:'幸运领域 · 成长',orbitDays:4332.59},
{name:'土星',r:114,s:0.006,size:10,color:'#8B8B83',glow:'rgba(139,139,131,0.15)',desc:'责任课题 · 考验',orbitDays:10759.22}
];
var CHART_MODE='live'; // 'live' or 'birth'
var BIRTH_ANGLES=null;
var REF_DATE=new Date(2000,0,1,12,0,0).getTime();
var CHART_ZI=[];function chartPreloadIcons(){ZODIAC.forEach(function(z,i){var img=new Image();img.src=ZODIAC_ICON[z.name];CHART_ZI[i]=img;});}
chartPreloadIcons();
var CHART_INTRO=-1;
var CHART_PAIRS=[];
var CHART_TIMER=null;
var CHART_REVEALED=[];
var CHART_CUR_START=0;
var CHART_LINE_DUR=3000;
var CHART_FROZEN_NOW=0;
var CHART_DONE=false; // prevent auto-restart after first play
function getPlanetAngles(birth){
if(!birth)return null;
var bd=new Date(birth.year,birth.month-1,birth.day,12,0,0).getTime();
var days=(bd-REF_DATE)/86400000;
var angles=[];
PLANETS.forEach(function(p,i){
if(p.orbitDays){
var baseAngle=p.baseAngle||0;
angles.push(((days/p.orbitDays)%1)*Math.PI*2+baseAngle);
}else{angles.push(0);}
});
return angles;
}
var FEED_CAT=['推荐','星盘解读','性格分析','合盘配对','运势播报','心理成长'];
var FEED=[
{c:0,t:'天蝎座不为人知的五个秘密',a:'星语师小鹿',d:'2:34',v:'12.8万',tags:['天蝎座','深度'],bg1:'#1a1a2e',bg2:'#8B0000',icon:'🦂'},
{c:0,t:'MBTI测试结果反转!我居然不是INTJ',a:'心理探长',d:'1:52',v:'8.3万',tags:['性格测试','反转'],bg1:'#16213e',bg2:'#0f3460',icon:'🧠'},
{c:1,t:'教你三分钟看懂自己的本命星盘',a:'占星小课堂',d:'3:15',v:'25.6万',tags:['星盘入门','教程'],bg1:'#0f3460',bg2:'#1a1a2e',icon:'🌟'},
{c:2,t:'双人合盘大揭秘:你们真的合适吗',a:'星空对话',d:'3:16',v:'20.1万',tags:['合盘','感情'],bg1:'#2d1b69',bg2:'#1a1a2e',icon:'💫'},
{c:1,t:'十二上升星座的外貌气质全解析',a:'星座美学',d:'4:02',v:'18.3万',tags:['上升星座','外貌'],bg1:'#1a1a2e',bg2:'#2d1b69',icon:'✨'},
{c:3,t:'水逆期生存指南:避开这三个坑',a:'星座大叔',d:'2:08',v:'9.7万',tags:['水逆','避坑'],bg1:'#0f3460',bg2:'#16213e',icon:'⚠️'},
{c:4,t:'2026下半年十二星座运势总览',a:'星空预言家',d:'5:30',v:'33.2万',tags:['运势','年度'],bg1:'#1a1a2e',bg2:'#0f3460',icon:'🔮'},
{c:5,t:'如何走出焦虑:占星视角的情绪管理',a:'心灵星座',d:'2:45',v:'11.5万',tags:['焦虑','情绪管理'],bg1:'#16213e',bg2:'#2d1b69',icon:'💆'},
{c:0,t:'金星落在十二星座的爱情模式',a:'恋爱占星师',d:'4:20',v:'16.7万',tags:['金星','爱情'],bg1:'#2d1b69',bg2:'#1a1a2e',icon:'💕'},
{c:2,t:'INTJ和ENFP为什么是天生一对',a:'人格解码',d:'2:55',v:'7.2万',tags:['性格配对','MBTI'],bg1:'#0f3460',bg2:'#16213e',icon:'🎭'},
{c:1,t:'冥王星换座:未来二十年大变局',a:'深度占星',d:'6:10',v:'28.9万',tags:['冥王星','时代'],bg1:'#1a1a2e',bg2:'#8B0000',icon:'🌑'},
{c:4,t:'本周十二星座注意事项',a:'每周星运',d:'3:40',v:'14.1万',tags:['周运','提醒'],bg1:'#16213e',bg2:'#0f3460',icon:'📅'}
];
var HOROSCOPES=[
{msg:'今天的星象提示你:相信直觉。某个看似偶然的相遇可能带来重要转机。',color:'珊瑚粉',num:7},
{msg:'创造力格外活跃,把灵感记录下来。月亮与海王星的互动让直觉变得敏锐。',color:'薰衣草紫',num:3},
{msg:'保持耐心是今天的关键词,好事值得等待。火星给你带来额外行动力。',color:'琥珀橙',num:9},
{msg:'适合整理和规划的一天,为未来播下种子。木星的幸运光环正照耀着你。',color:'薄荷绿',num:5},
{msg:'勇敢迈出第一步,宇宙会回应你的勇气。金星与木星的相位带来好运。',color:'天空蓝',num:8},
{msg:'给自己一些独处的时间,倾听内心的声音。今日适合冥想和自我关怀。',color:'玫瑰金',num:2},
{msg:'一个久违的朋友可能会联系你,珍惜这份重逢。水星顺行带来沟通顺畅。',color:'暖黄色',num:6},
{msg:'处理事务时多一份耐心,今天适合完成搁置已久的计划。',color:'雾蓝色',num:4}
];
var TRENDING=[
{t:'十二上升星座全解',d:'外貌·气质·第一印象',i:'✨'},
{t:'月亮星座看原生家庭',d:'童年模式如何影响你',i:'🌙'},
{t:'金星星座看爱情',d:'你的爱情语言是什么',i:'💕'},
{t:'火星星座看行动力',d:'驱动你的内在引擎',i:'🔥'}
];
// ═══════ STATE ═══════
var S={tab:'home',quizIdx:0,answers:[],birth:null,sign:null,feedCat:0,isMember:false,history:[],navHistory:[]};
// ═══════ INIT ═══════
(function init(){
var h=localStorage.getItem('xj_history');
S.history=h?JSON.parse(h):[];
// Migrate old signEmoji → signBadge
S.history.forEach(function(r){if(!r.signBadge&&r.signEmoji){var z=ZODIAC.find(function(zz){return zz.name===r.signName});if(z)r.signBadge=zodiacBadge(z);}});
if(S.history.length>0){var last=S.history[S.history.length-1];S.sign=ZODIAC.find(function(z){return z.name===last.signName});S.birth=last.birth;BIRTH_ANGLES=getPlanetAngles(S.birth);CHART_MODE='birth';}
S.isMember=localStorage.getItem('xj_member')==='1';
renderHome();renderFeedTabs();renderFeed();renderHistory();renderProfile();
setTimeout(function(){drawChart()},200);
var today=new Date();var seed=(today.getFullYear()*10000+(today.getMonth()+1)*100+today.getDate())%HOROSCOPES.length;
var ho=HOROSCOPES[seed];
document.querySelector('#horoCard .hday').textContent=today.getFullYear()+'年'+(today.getMonth()+1)+'月'+today.getDate()+'日 · 今日运势';
document.querySelector('#horoCard .hmsg').textContent=ho.msg;
document.getElementById('hlColor').textContent=ho.color;
document.getElementById('hlNum').textContent=ho.num;
var m=today.getMonth()+1,d=today.getDate();
document.getElementById('hlMonth').textContent=m+'月'+d+'日 · 今日星象';
var cz=getZodiac(m,d);
document.getElementById('hzEmoji').innerHTML=zodiacBadge(cz);
document.getElementById('hzSign').textContent=cz.name+'季';
document.getElementById('hzDate').textContent=cz.trait;
renderTrending();
setupTestInputs();
})();
function setupTestInputs(){
var ms=document.getElementById('tMonth');if(!ms||ms.options.length>1)return;
for(var i=1;i<=12;i++){var o=document.createElement('option');o.value=i;o.text=i+'月';ms.appendChild(o);}
var ds=document.getElementById('tDay');for(var i=1;i<=31;i++){var o=document.createElement('option');o.value=i;o.text=i+'日';ds.appendChild(o);}
var hs=document.getElementById('tHour');HOURS.forEach(function(h,i){var o=document.createElement('option');o.value=i;o.text=h;hs.appendChild(o);});
var ps=document.getElementById('tProv');
Object.keys(REGIONS).forEach(function(p){var o=document.createElement('option');o.value=p;o.text=p;ps.appendChild(o);});
}
function onProvChange(){
var p=document.getElementById('tProv').value;
var cs=document.getElementById('tCity');cs.innerHTML='<option value="">市区</option>';
var ds=document.getElementById('tDist');ds.innerHTML='<option value="">县/区</option>';
if(p&&REGIONS[p]){Object.keys(REGIONS[p]).forEach(function(c){var o=document.createElement('option');o.value=c;o.text=c;cs.appendChild(o);});}
}
function onCityChange(){
var p=document.getElementById('tProv').value;
var c=document.getElementById('tCity').value;
var ds=document.getElementById('tDist');ds.innerHTML='<option value="">县/区</option>';
if(p&&c&&REGIONS[p]&&REGIONS[p][c]){REGIONS[p][c].forEach(function(d){var o=document.createElement('option');o.value=d;o.text=d;ds.appendChild(o);});}
}
// ═══════ NAVIGATION ═══════
var MAIN_TABS=['home','chart','report','community','profile'];
function showPage(id,title,showBack,showNav){
document.querySelectorAll('.page').forEach(function(p){p.classList.remove('active')});
document.getElementById('page-'+id).classList.add('active');
S.tab=id;
// Topbar
document.querySelector('#topbar .tbt').textContent=title;
var backBtn=document.getElementById('backBtn');
if(showBack){backBtn.classList.add('show')}else{backBtn.classList.remove('show')}
// Bottom nav
var nav=document.getElementById('bottomNav');
nav.style.display=showNav?'flex':'none';
// Highlight nav item
document.querySelectorAll('.nav-item').forEach(function(n){n.classList.remove('active')});
if(showNav){
var idx=MAIN_TABS.indexOf(id);
if(idx>=0)document.querySelectorAll('.nav-item')[idx].classList.add('active');
}
S.navHistory.push({id:id,title:title,showBack:showBack,showNav:showNav});
}
function switchTab(tab){
var titles={home:'星镜',chart:'星镜 · 星盘',report:'星镜 · 报告',community:'星镜 · 社区',profile:'星镜 · 我的'};
showPage(tab,titles[tab],false,true);
if(tab==='chart'){setTimeout(function(){drawChart();startChartIntro();},100);}
if(tab==='home')renderHome();
}
function goTest(){
S.quizIdx=0;S.answers=[];
setupTestInputs();
showPage('test-birth','星镜 · 测试',true,false);
}
function goHome(){
showPage('home','星镜',false,true);
renderHome();
}
function openSchulte(){
showPage('schulte','星镜 · 舒尔特',true,false);
initSchulteBest();
if(schulteState.running){clearInterval(schulteState.timer);schulteState.timer=null;}
schulteState.running=false;schulteState.next=1;
document.getElementById('schulteTimer').textContent='00:00.0';
document.getElementById('schulteBtn').textContent='开始训练';
document.getElementById('schulteSub').textContent='按顺序点击 1→25,训练专注力与反应速度';
var scene=document.getElementById('cubeScene');scene.classList.remove('paused');
var cube=document.getElementById('cubeEl');cube.style.transform='rotateX(-15deg) rotateY(25deg)';
buildSchulteGrid();
}
function goBack(){
if(S.navHistory.length<=1){goHome();return;}
S.navHistory.pop(); // remove current
var prev=S.navHistory[S.navHistory.length-1];
if(!prev){goHome();return;}
showPage(prev.id,prev.title,prev.showBack,prev.showNav);
if(prev.id==='home')renderHome();
if(prev.id==='chart')setTimeout(function(){drawChart()},100);
}
// ═══════ ZODIAC ═══════
function getZodiac(m,d){
for(var i=0;i<ZODIAC.length;i++){var z=ZODIAC[i];for(var j=0;j<z.range.length;j++){var r=z.range[j];if((m===r[0]&&d>=r[1])||(m===r[2]&&d<=r[3]))return z;}}
return ZODIAC[0];
}
// ═══════ TEST FLOW ═══════
function startQuiz(){
var y=parseInt(document.getElementById('tYear').value);
var m=parseInt(document.getElementById('tMonth').value);
var d=parseInt(document.getElementById('tDay').value);
if(!y||!m||!d){showToast('请填写完整的出生年月日');return;}
if(y<1900||y>2026){showToast('请输入有效的出生年份');return;}
S.birth={year:y,month:m,day:d};
S.sign=getZodiac(m,d);
S.quizIdx=0;S.answers=[];
showPage('test-quiz','星镜 · 答题',true,false);
renderQuizCard();
}
function renderQuizCard(){
var q=QUIZ[S.quizIdx];
document.getElementById('quizHint').textContent=q.d;
document.getElementById('qNow').textContent=S.quizIdx+1;
document.getElementById('qBar').style.width=((S.quizIdx+1)/QUIZ.length*100)+'%';
var h='<div class="quiz-q"><div class="q-text">'+q.q+'</div>';
q.opts.forEach(function(o,i){h+='<button class="quiz-opt" onclick="pickAnswer('+i+')">'+o+'</button>';});
h+='</div>';
document.getElementById('quizCard').innerHTML=h;
}
function pickAnswer(idx){
S.answers.push(idx);S.quizIdx++;
if(S.quizIdx>=QUIZ.length){showResult();}else{renderQuizCard();}
}
function showResult(){
showPage('test-result','星镜 · 解读',true,false);
if(S.birth){BIRTH_ANGLES=getPlanetAngles(S.birth);CHART_MODE='birth';updateChartToggle();}
var sign=S.sign,a=S.answers;
var dims=[
{name:'开放性',val:Math.max(20,(a[1]===3||a[8]===3?60:20)+20+(a[1]===3?20:0)),color:'#4A90E2',left:'传统',right:'好奇'},
{name:'尽责性',val:Math.max(20,(a[6]===0||a[0]===0?55:20)+20+(a[6]===0?25:0)),color:'#5CB85C',left:'随性',right:'自律'},
{name:'外向性',val:Math.max(20,(a[0]===1||a[3]===0?60:20)+20+(a[3]===0?20:0)),color:'#F5A623',left:'内向',right:'外向'},
{name:'宜人性',val:Math.max(20,(a[4]===2||a[9]===2?55:20)+20+(a[9]===2?20:0)),color:'#FF69B4',left:'独立',right:'共情'},
{name:'情绪性',val:Math.max(20,(a[7]===1||a[2]===1?50:25)+25+(a[7]===1?25:0)),color:'#E54D42',left:'稳定',right:'敏感'}
];
var mbti='';
mbti+=(a[0]===0||a[0]===2?'I':'E');mbti+=(a[1]===0||a[1]===3?'T':'F');
mbti+=(a[6]===0?'J':'P');mbti+=(a[5]===1||a[8]===3?'N':'S');
var elScore={:25,:25,:25,:25};
if(sign.el==='火')elScore.+=20;else if(sign.el==='土')elScore.+=20;else if(sign.el==='风')elScore.+=20;else elScore.+=20;
elScore.+=a[0]===1?10:a[0]===3?5:0;elScore.+=a[6]===0?10:a[3]===2?5:0;
elScore.+=a[1]===0?10:a[5]===3?5:0;elScore.+=a[9]===0?10:a[4]===2?5:0;
var total=elScore.+elScore.+elScore.+elScore.;
var els=[{name:'火',pct:Math.round(elScore./total*100),color:'#E54D42'},{name:'土',pct:Math.round(elScore./total*100),color:'#5CB85C'},{name:'风',pct:Math.round(elScore./total*100),color:'#4A90E2'},{name:'水',pct:Math.round(elScore./total*100),color:'#7B68EE'}];
var style=a[8]===0?'稳步前行型':a[8]===1?'探索冒险型':a[8]===2?'宁静致远型':'自由奔放型';
var emotion=a[7]===0?'深沉内敛':a[7]===1?'热烈奔放':a[7]===2?'起伏有致':'稳定平和';
var love=a[9]===0?'灵魂共鸣型':a[9]===1?'浪漫激情型':a[9]===2?'温暖陪伴型':'成长伙伴型';
var h='';
h+='<div class="result-hero"><div class="rzodiac">'+zodiacBadge(sign)+'</div><div class="rsign">'+sign.name+'</div><div class="rmbti">'+mbti+' · '+style+'</div><div>';
h+='<span class="result-tag">'+sign.el+'象</span><span class="result-tag">'+emotion+'</span><span class="result-tag">'+love+'</span></div></div>';
h+='<div class="card card-sm"><div class="card-title">四大元素能量分布</div>';
els.forEach(function(e){h+='<div class="elem-bar"><span class="el">'+e.name+'</span><div class="eb"><div class="ebf" style="width:'+e.pct+'%;background:'+e.color+'"></div></div><span class="ev">'+e.pct+'%</span></div>';});
h+='</div>';
h+='<div class="card card-sm"><div class="card-title">人格五维度画像</div>';
dims.forEach(function(d){h+='<div class="dim-row"><span class="dl">'+d.left+'</span><div class="dbar"><div class="dfill" style="width:'+d.val+'%;background:'+d.color+'">'+d.name+'</div></div><span class="dr">'+d.right+'</span></div>';});
h+='</div>';
h+='<div class="card card-sm"><div class="card-title">性格综述</div><div class="card-sub">你是一个<strong>'+sign.name+'</strong>'+sign.trait+'。属于<strong>'+sign.el+'象星座</strong>,风格偏向<strong>'+style+'</strong>。情感方面表现为<strong>'+emotion+'</strong>,在亲密关系中最看重<strong>'+love.replace('型','')+'</strong>。</div></div>';
h+='<button class="btn btn-pri btn-block" onclick="playVideoReport()">▶ 播放专属视频报告</button>';
h+='<button class="btn btn-outline btn-block btn-sm" onclick="switchTab(\'chart\')" style="margin-top:6px">◎ 查看动态星盘</button>';
document.getElementById('resultContent').innerHTML=h;
var entry={signName:sign.name,signBadge:zodiacBadge(sign),mbti:mbti,style:style,birth:S.birth,el:sign.el,date:new Date().toISOString().slice(0,10),els:els,dims:dims};
S.history.push(entry);localStorage.setItem('xj_history',JSON.stringify(S.history));
renderHistory();renderProfile();
}
// ═══════ HOME ═══════
function renderHome(){
if(S.sign){document.getElementById('hzEmoji').innerHTML=zodiacBadge(S.sign);document.getElementById('hzSign').textContent=S.sign.name;document.getElementById('hzDate').textContent=S.sign.trait;}
}
function renderTrending(){
var h='';TRENDING.forEach(function(it){h+='<div style="flex-shrink:0;width:130px;background:#fff;border-radius:12px;padding:14px 12px;text-align:center;box-shadow:0 2px 6px rgba(0,0,0,0.03);cursor:pointer" onclick="showToast(\'即将上线\')"><div style="font-size:28px;margin-bottom:4px">'+it.i+'</div><div style="font-size:12px;font-weight:600">'+it.t+'</div><div style="font-size:10px;color:var(--sub)">'+it.d+'</div></div>';});
document.getElementById('trendingRow').innerHTML=h;
}
// ═══════ CHART ═══════
var chartAngle=0,chartZoom=1,chartDragging=false,chartLastX=0,chartPinchDist=0;
function drawChart(){
var canvas=document.getElementById('chartCanvas');if(!canvas)return;
var ctx=canvas.getContext('2d'),dpr=window.devicePixelRatio||1;
var w=canvas.parentElement.clientWidth-32;if(w<10)return;
var s=Math.min(w,380);canvas.width=s*dpr;canvas.height=s*dpr;canvas.style.width=s+'px';canvas.style.height=s+'px';ctx.scale(dpr,dpr);
var cx=s/2,cy=s/2,mr=s/2-16;
function render(){
ctx.clearRect(0,0,s,s);ctx.fillStyle='#0a0a1a';ctx.fillRect(0,0,s,s);
ctx.save();ctx.translate(cx,cy);ctx.scale(chartZoom,chartZoom);ctx.rotate(chartAngle);
var seed=42;
for(var i=0;i<80;i++){seed=(seed*16807)%2147483647;var sr=12+((seed%1000)/1000)*(mr-12),sa=((seed%6283)/1000);ctx.fillStyle='rgba(255,255,255,'+(0.15+Math.sin(Date.now()/2500+i*0.7)*0.12)+')';ctx.beginPath();ctx.arc(Math.cos(sa)*sr,Math.sin(sa)*sr,0.5+Math.random()*0.6,0,Math.PI*2);ctx.fill();}
ctx.strokeStyle='rgba(255,255,255,0.06)';ctx.lineWidth=1;ctx.beginPath();ctx.arc(0,0,mr,0,Math.PI*2);ctx.stroke();ctx.beginPath();ctx.arc(0,0,mr-4,0,Math.PI*2);ctx.stroke();
for(var i=0;i<12;i++){var a=i/12*Math.PI*2-Math.PI/2;ctx.strokeStyle='rgba(255,255,255,0.03)';ctx.lineWidth=0.5;ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(Math.cos(a)*mr,Math.sin(a)*mr);ctx.stroke();}
// Draw zodiac icons around the wheel
var isz=16;
for(var i=0;i<12;i++){
var a=i/12*Math.PI*2-Math.PI/2;
var ix=Math.cos(a)*(mr-14),iy=Math.sin(a)*(mr-14);
ctx.save();ctx.translate(ix,iy);
ctx.globalAlpha=0.7;
if(CHART_ZI[i]&&CHART_ZI[i].complete)ctx.drawImage(CHART_ZI[i],-isz,-isz,isz*2,isz*2);
ctx.restore();
}
PLANETS.forEach(function(p){if(p.r>0){ctx.strokeStyle='rgba(255,255,255,0.03)';ctx.lineWidth=0.5;ctx.beginPath();ctx.arc(0,0,p.r,0,Math.PI*2);ctx.stroke();}});
var now=Date.now()/1000;
if(CHART_MODE==='birth'&&BIRTH_ANGLES){now=0;}
// Freeze time during intro so planets match locked pairs
if(CHART_INTRO>=0){if(CHART_FROZEN_NOW===0)CHART_FROZEN_NOW=now;now=CHART_FROZEN_NOW;}
var pos=[];
PLANETS.forEach(function(p,i){
var angle;
if(CHART_MODE==='birth'&&BIRTH_ANGLES){angle=BIRTH_ANGLES[i]||0;}
else{angle=(p.r>0)?(now*p.s+i*0.8):0;}
pos.push({x:Math.cos(angle)*p.r,y:Math.sin(angle)*p.r});
});
// Build pairs only once per intro (lock during animation)
if(CHART_INTRO<0||CHART_PAIRS.length===0){
CHART_PAIRS=[];
var seen={};
// Step 1: proximity-based pairs
for(var i=0;i<pos.length;i++){for(var j=i+1;j<pos.length;j++){
var dx=pos[j].x-pos[i].x,dy=pos[j].y-pos[i].y;
if(Math.hypot(dx,dy)<100){var key=i+','+j;seen[key]=true;CHART_PAIRS.push({a:i,b:j,ax:pos[i].x,ay:pos[i].y,bx:pos[j].x,by:pos[j].y,order:Math.min(PLANETS[i].r,PLANETS[j].r)});}
}}
// Step 2: guarantee every planet has at least 1 line (closest neighbour)
for(var i=0;i<pos.length;i++){
var has=false;for(var pi=0;pi<CHART_PAIRS.length;pi++){if(CHART_PAIRS[pi].a===i||CHART_PAIRS[pi].b===i){has=true;break;}}
if(!has){
var bestJ=-1,bestDist=Infinity;
for(var j=0;j<pos.length;j++){if(j===i)continue;var dd=Math.hypot(pos[j].x-pos[i].x,pos[j].y-pos[i].y);if(dd<bestDist){bestDist=dd;bestJ=j;}}
if(bestJ>=0){
var aa=Math.min(i,bestJ),bb=Math.max(i,bestJ),key=aa+','+bb;
if(!seen[key]){seen[key]=true;CHART_PAIRS.push({a:aa,b:bb,ax:pos[aa].x,ay:pos[aa].y,bx:pos[bb].x,by:pos[bb].y,order:Math.min(PLANETS[aa].r,PLANETS[bb].r)});}
}
}
}
CHART_PAIRS.sort(function(p,q){return p.order-q.order;});
}
// Draw aspect lines with animation
var introDone=(CHART_INTRO<0&&CHART_REVEALED.length>0);
for(var pi=0;pi<CHART_PAIRS.length;pi++){
var pr=CHART_PAIRS[pi];
var isRevealed=CHART_REVEALED.indexOf(pi)>=0;
var isCurrent=(CHART_INTRO>=0&&pi===CHART_INTRO);
if(!isRevealed&&!isCurrent)continue;
var alpha, lw;
if(isCurrent){alpha=0.8;lw=1.8;}
else if(introDone){alpha=0.35;lw=0.6;}
else{alpha=0.3;lw=0.5;}
ctx.strokeStyle='rgba(255,255,255,'+alpha+')';ctx.lineWidth=lw;
ctx.beginPath();
if(isCurrent){
var elapsed=Date.now()-CHART_CUR_START;
var t=Math.min(1,elapsed/CHART_LINE_DUR);
// ease-out
t=1-Math.pow(1-t,3);
ctx.moveTo(pr.ax,pr.ay);
ctx.lineTo(pr.ax+(pr.bx-pr.ax)*t,pr.ay+(pr.by-pr.ay)*t);
}else{
ctx.moveTo(pr.ax,pr.ay);ctx.lineTo(pr.bx,pr.by);
}
ctx.stroke();
}
// Highlight active zodiac sign
if(CHART_INTRO>=0&&CHART_INTRO<CHART_PAIRS.length){
var ap=CHART_PAIRS[CHART_INTRO];
var midAngle=Math.atan2((ap.ay+ap.by)/2,(ap.ax+ap.bx)/2);
var zi=Math.floor(((midAngle+Math.PI/2+Math.PI*2)%(Math.PI*2))/(Math.PI*2)*12);
var za=zi/12*Math.PI*2-Math.PI/2;
ctx.fillStyle='rgba(255,255,255,0.7)';
var hz=22;
ctx.save();ctx.translate(Math.cos(za)*(mr-10),Math.sin(za)*(mr-10));
if(CHART_ZI[zi]&&CHART_ZI[zi].complete)ctx.drawImage(CHART_ZI[zi],-hz,-hz,hz*2,hz*2);
ctx.restore();
}
// Post-intro: highlight current sun zodiac sign with glow + enlarged icon
if(CHART_DONE){
var activeZi;
if(CHART_MODE==='birth'&&S.sign){activeZi=ZODIAC.indexOf(S.sign);}
else{var cz2=getZodiac(new Date().getMonth()+1,new Date().getDate());activeZi=ZODIAC.indexOf(cz2);}
if(activeZi>=0){
var activeA=activeZi/12*Math.PI*2-Math.PI/2;
var pulse=1+Math.sin(Date.now()/1200)*0.08;
var az=18*pulse;
var ag=ctx.createRadialGradient(Math.cos(activeA)*(mr-10),Math.sin(activeA)*(mr-10),az*0.5,Math.cos(activeA)*(mr-10),Math.sin(activeA)*(mr-10),az*2);
ag.addColorStop(0,'rgba(255,215,0,0.4)');ag.addColorStop(0.5,'rgba(255,180,0,0.15)');ag.addColorStop(1,'rgba(255,180,0,0)');
ctx.fillStyle=ag;ctx.beginPath();ctx.arc(Math.cos(activeA)*(mr-10),Math.sin(activeA)*(mr-10),az*2,0,Math.PI*2);ctx.fill();
ctx.save();ctx.translate(Math.cos(activeA)*(mr-10),Math.sin(activeA)*(mr-10));
ctx.globalAlpha=0.95;
if(CHART_ZI[activeZi]&&CHART_ZI[activeZi].complete)ctx.drawImage(CHART_ZI[activeZi],-az,-az,az*2,az*2);
ctx.restore();
// Show name below the icon
ctx.fillStyle='rgba(255,255,255,0.8)';ctx.font='bold 10px sans-serif';ctx.textAlign='center';
ctx.fillText(ZODIAC[activeZi].name,Math.cos(activeA)*(mr-10),Math.sin(activeA)*(mr-10)+az+10);
}
}
PLANETS.forEach(function(p,i){var angle;if(CHART_MODE==='birth'&&BIRTH_ANGLES){angle=BIRTH_ANGLES[i]||0;}else{angle=(p.r>0)?(now*p.s+i*0.8):0;}var px=Math.cos(angle)*p.r,py=Math.sin(angle)*p.r;var g=ctx.createRadialGradient(px,py,0,px,py,p.size*1.8);g.addColorStop(0,p.glow);g.addColorStop(1,'rgba(0,0,0,0)');ctx.fillStyle=g;ctx.beginPath();ctx.arc(px,py,p.size*1.8,0,Math.PI*2);ctx.fill();ctx.fillStyle=p.color;ctx.beginPath();ctx.arc(px,py,p.size,0,Math.PI*2);ctx.fill();ctx.fillStyle='rgba(255,255,255,0.5)';ctx.font='8px sans-serif';ctx.textAlign='center';ctx.fillText(p.name,px,py-p.size-5);});
var sg=ctx.createRadialGradient(0,0,0,0,0,15);sg.addColorStop(0,'#FFF8DC');sg.addColorStop(0.4,'#FFD700');sg.addColorStop(1,'rgba(255,215,0,0)');ctx.fillStyle=sg;ctx.beginPath();ctx.arc(0,0,15,0,Math.PI*2);ctx.fill();ctx.fillStyle='#FFD700';ctx.beginPath();ctx.arc(0,0,7,0,Math.PI*2);ctx.fill();
ctx.restore();
}
render();
canvas.onclick=function(e){var rect=canvas.getBoundingClientRect();var mx=e.clientX-rect.left-cx,my=e.clientY-rect.top-cy;var cos=Math.cos(-chartAngle),sin=Math.sin(-chartAngle);var rx=mx*cos-my*sin,ry=mx*sin+my*cos;var found=-1;PLANETS.forEach(function(p,i){var a;if(CHART_MODE==='birth'&&BIRTH_ANGLES){a=BIRTH_ANGLES[i]||0;}else{var now2=Date.now()/1000;a=(p.r>0)?(now2*p.s+i*0.8):0;}var px=Math.cos(a)*p.r,py=Math.sin(a)*p.r;if(Math.hypot(rx-px,ry-py)<p.size*2.5)found=i;});if(Math.hypot(rx,ry)<14)found=0;if(found>=0){var p=PLANETS[found];document.getElementById('chartInfo').innerHTML='<span class="pn">'+p.name+'</span> · '+p.desc;document.getElementById('chartHint').textContent='已选中:'+p.name;}};
canvas.addEventListener('mousedown',function(e){chartDragging=true;chartLastX=e.clientX;});
canvas.addEventListener('mousemove',function(e){if(!chartDragging)return;chartAngle+=(e.clientX-chartLastX)*0.005;chartLastX=e.clientX;render();});
canvas.addEventListener('mouseup',function(){chartDragging=false;});canvas.addEventListener('mouseleave',function(){chartDragging=false;});
canvas.addEventListener('touchstart',function(e){if(e.touches.length===1){chartDragging=true;chartLastX=e.touches[0].clientX;}if(e.touches.length===2){chartPinchDist=Math.hypot(e.touches[0].clientX-e.touches[1].clientX,e.touches[0].clientY-e.touches[1].clientY);}},{passive:false});
canvas.addEventListener('touchmove',function(e){if(e.touches.length===1&&chartDragging){chartAngle+=(e.touches[0].clientX-chartLastX)*0.005;chartLastX=e.touches[0].clientX;render();}if(e.touches.length===2){e.preventDefault();var d=Math.hypot(e.touches[0].clientX-e.touches[1].clientX,e.touches[0].clientY-e.touches[1].clientY);chartZoom=Math.max(0.5,Math.min(2,chartZoom*(d/chartPinchDist)));chartPinchDist=d;render();}},{passive:false});
canvas.addEventListener('touchend',function(){chartDragging=false;});
if(!canvas._anim){canvas._anim=true;function anim(){render();requestAnimationFrame(anim);}anim();}
}
function toggleChartMode(){
if(!S.birth){showToast('请先完成星盘测试');return;}
CHART_MODE=CHART_MODE==='birth'?'live':'birth';
CHART_DONE=false; // allow replay
updateChartToggle();
startChartIntro();
drawChart();
}
function updateChartToggle(){
var el=document.getElementById('chartToggle');
if(!el)return;
if(!S.birth){el.textContent='◎ 实时天象';return;}
if(CHART_MODE==='birth'){
var d=S.birth;el.textContent='📅 '+d.year+'.'+d.month+'.'+d.day+' 本命盘';
}else{el.textContent='◎ 实时天象';}
}
function startChartIntro(){
if(CHART_DONE)return; // play once only
if(CHART_TIMER){clearInterval(CHART_TIMER);CHART_TIMER=null;}
CHART_INTRO=-1;CHART_PAIRS=[];CHART_REVEALED=[];CHART_FROZEN_NOW=0;
// Wait for first render to fill CHART_PAIRS, then start
setTimeout(function(){
if(CHART_PAIRS.length===0)return;
CHART_INTRO=0;CHART_CUR_START=Date.now();
updateIntroText(0);
CHART_TIMER=setInterval(function(){
// Current line done, move to revealed
CHART_REVEALED.push(CHART_INTRO);
CHART_INTRO++;
if(CHART_INTRO>=CHART_PAIRS.length){
CHART_INTRO=-1;clearInterval(CHART_TIMER);CHART_TIMER=null;CHART_DONE=true;
updateIntroDone();return;
}
CHART_CUR_START=Date.now();
updateIntroText(CHART_INTRO);
},CHART_LINE_DUR);
},200);
}
function updateIntroText(idx){
var pr=CHART_PAIRS[idx];
var na=PLANETS[pr.a].name,nb=PLANETS[pr.b].name;
var key=pr.a<pr.b?pr.a+'-'+pr.b:pr.b+'-'+pr.a;
var meanings={
'0-1':'意识与潜意识的对话,内外自我的和谐',
'0-2':'思维模式的自我表达,语言与创造力',
'0-3':'魅力与价值感,如何被世界所爱',
'0-4':'意志力转化为行动,勇气与进取',
'0-5':'自信与机遇,生命中的贵人方向',
'0-6':'责任塑造人格,成熟与自律之路',
'1-2':'感性与理性的平衡,直觉与逻辑',
'1-3':'情感需求与爱的表达方式',
'1-4':'情绪驱动行为,内在感受的出口',
'1-5':'情感丰盈与内心安全感',
'1-6':'情绪克制与内在成熟度',
'2-3':'沟通中的温度,语言的艺术魅力',
'2-4':'思维果敢,言之有物的力量',
'2-5':'智慧的高度,宏观视野与哲学思考',
'2-6':'严谨的逻辑,深入本质的洞察力',
'3-4':'爱与欲望的张力,吸引力法则',
'3-5':'幸运眷顾,美好事物的吸引力',
'3-6':'感情中的承诺与长久关系',
'4-5':'行动带来扩张,勇气与成长',
'4-6':'克制中的力量,持久与耐力',
'5-6':'理想与现实的平衡,成长与沉淀'
};
var meaning=meanings[key]||(na+'与'+nb+'的相位互动');
document.getElementById('chartHint').textContent='✦ '+na+' ↔ '+nb;
document.getElementById('chartInfo').innerHTML='<span style="color:var(--pri);font-weight:600">第'+(idx+1)+'/'+CHART_PAIRS.length+'条</span> <span style="font-size:11px;color:var(--sub)">'+meaning+'</span>';
}
function updateIntroDone(){
document.getElementById('chartHint').textContent='全部 '+CHART_PAIRS.length+' 条相位连线已完成';
document.getElementById('chartInfo').innerHTML='<span style="cursor:pointer;color:var(--pri);font-weight:600" onclick="toggleChartMode()" id="chartToggle"></span><span style="margin-left:8px;font-size:11px;color:var(--sub)">拖拽旋转 · 双指缩放 · 点击行星</span>';
updateChartToggle();
}
// ═══════ VIDEO ═══════
var videoTimer=null;
function playVideoReport(){
if(!S.sign){showToast('请先完成测试');return;}
var overlay=document.getElementById('videoOverlay');overlay.classList.add('on');
var canvas=document.getElementById('videoCanvas'),ctx=canvas.getContext('2d'),dpr=window.devicePixelRatio||1;
var w=Math.min(430,window.innerWidth),h=window.innerHeight;
canvas.width=w*dpr;canvas.height=h*dpr;canvas.style.width=w+'px';canvas.style.height=h+'px';ctx.scale(dpr,dpr);
var wm=document.getElementById('vWatermark');wm.style.display=S.isMember?'none':'block';
var sign=S.sign,fps=30,totalFrames=30*fps,frame=0;
var signImg=new Image();signImg.src=ZODIAC_ICON[sign.name];
var scenes=[
{start:0,end:3,texts:[{t:0,text:'星镜',x:w/2,y:h*0.15,fs:40,fc:'#fff'}]},
{start:3,end:8,imgs:[{t:0,img:signImg,x:w/2,y:h*0.28,s:120}],texts:[{t:0,text:sign.name,x:w/2,y:h*0.43,fs:26,fc:'#fff'},{t:1.5,text:sign.trait,x:w/2,y:h*0.50,fs:13,fc:'rgba(255,255,255,0.7)'}]},
{start:8,end:20,texts:[{t:0,text:sign.el+'象星座',x:w/2,y:h*0.22,fs:20,fc:sign.color},{t:2,text:'天赋特质',x:w/2,y:h*0.35,fs:15,fc:'rgba(255,255,255,0.5)'},{t:3,text:sign.trait.split('·')[0],x:w/2,y:h*0.44,fs:18,fc:'#fff'},{t:5.5,text:sign.trait.split('·')[1],x:w/2,y:h*0.52,fs:16,fc:'#fff'},{t:8,text:sign.trait.split('·')[2],x:w/2,y:h*0.60,fs:16,fc:'#fff'},{t:10.5,text:'开启视频解读 · 了解更多',x:w/2,y:h*0.72,fs:12,fc:'rgba(255,255,255,0.4)'}]},
{start:20,end:26,texts:[{t:0,text:'开通星镜会员',x:w/2,y:h*0.35,fs:18,fc:'#fff'},{t:1.5,text:'解锁无水印完整视频报告',x:w/2,y:h*0.44,fs:13,fc:'rgba(255,255,255,0.8)'},{t:3,text:'首月仅 ¥9.9',x:w/2,y:h*0.56,fs:20,fc:'#FFD700'}]},
{start:26,end:30,imgs:[{t:0,img:signImg,x:w/2,y:h*0.32,s:64}],texts:[{t:0,text:'星镜',x:w/2,y:h*0.48,fs:20,fc:'#fff'},{t:1.5,text:'让每一次自我探索,都成为可播放的电影',x:w/2,y:h*0.56,fs:11,fc:'rgba(255,255,255,0.5)'}]}
];
var stars=[];for(var i=0;i<80;i++)stars.push({x:Math.random()*w,y:Math.random()*h,r:Math.random()*1.5+0.5,a:Math.random(),sp:Math.random()*0.02+0.005});
function drawFrame(){
ctx.fillStyle='#0a0a1a';ctx.fillRect(0,0,w,h);var t=frame/fps;
stars.forEach(function(s){s.a+=s.sp;ctx.fillStyle='rgba(255,255,255,'+(0.3+Math.sin(s.a)*0.4)+')';ctx.beginPath();ctx.arc(s.x,s.y,s.r,0,Math.PI*2);ctx.fill();});
for(var si=0;si<scenes.length;si++){var sc=scenes[si];if(t>=sc.start&&t<=sc.end){var st=t-sc.start;
// Draw images
if(sc.imgs)sc.imgs.forEach(function(ix){if(st>=ix.t&&ix.img.complete&&ix.img.naturalWidth>0){var alpha=Math.min(1,(st-ix.t)/0.5);ctx.globalAlpha=alpha;ctx.drawImage(ix.img,ix.x-ix.s/2,ix.y-ix.s/2,ix.s,ix.s);ctx.globalAlpha=1;}});
// Draw texts
if(sc.texts)sc.texts.forEach(function(tx){if(st>=tx.t){var alpha=Math.min(1,(st-tx.t)/0.5);ctx.fillStyle=tx.fc.replace(/rgba\\((\\d+),(\\d+),(\\d+),([\\d.]+)\\)/,function(_,r,g,b,a2){return'rgba('+r+','+g+','+b+','+(alpha*parseFloat(a2)).toFixed(2)+')';});ctx.font='bold '+tx.fs+'px -apple-system,sans-serif';ctx.textAlign='center';ctx.fillText(tx.text,tx.x,tx.y);}});
}}
frame++;document.getElementById('vBar').style.width=(frame/totalFrames*100)+'%';
if(frame>=totalFrames){clearInterval(videoTimer);videoTimer=null;return;}
}
if(videoTimer)clearInterval(videoTimer);
frame=0;document.getElementById('vBar').style.width='0%';drawFrame();
videoTimer=setInterval(drawFrame,1000/fps);
}
function stopVideo(){if(videoTimer){clearInterval(videoTimer);videoTimer=null;}document.getElementById('videoOverlay').classList.remove('on');}
// ═══════ FEED ═══════
function renderFeedTabs(){var h='';FEED_CAT.forEach(function(c,i){h+='<span class="feed-tab'+(i===S.feedCat?' active':'')+'" onclick="switchFeedCat('+i+')">'+c+'</span>';});document.getElementById('feedTabs').innerHTML=h;}
function switchFeedCat(i){S.feedCat=i;renderFeedTabs();renderFeed();}
function renderFeed(){var list=FEED.filter(function(f){return S.feedCat===0||f.c===S.feedCat||f.c===0});var h='';list.forEach(function(f){h+='<div class="feed-item" onclick="showToast(\'视频播放中...\')"><div class="f-thumb" style="background:linear-gradient(135deg,'+f.bg1+','+f.bg2+')"><div class="play-btn">▶</div><div class="f-dur">'+f.d+'</div><div class="f-avatar">'+f.icon+'</div></div><div class="f-info"><div class="f-title">'+f.t+'</div><div class="f-meta"><span>'+f.a+'</span><span>'+f.v+' 次观看</span></div></div><div class="f-tags">';f.tags.forEach(function(t){h+='<span class="feed-tag">#'+t+'</span>';});h+='</div></div>';});document.getElementById('feedList').innerHTML=h;}
// ═══════ HISTORY ═══════
function renderHistory(){
var list=document.getElementById('historyList');
if(S.history.length===0){list.innerHTML='<div class="card" style="text-align:center"><div style="font-size:36px;margin-bottom:6px">🎬</div><div class="card-title">还没有测试记录</div><div class="card-sub">完成星盘测试后,你的专属报告将保存在这里</div><button class="btn btn-pri btn-sm" style="margin-top:10px" onclick="goTest()">开始测试 →</button></div>';return;}
var h='';for(var i=S.history.length-1;i>=0;i--){var r=S.history[i];h+='<div class="hist-item" onclick="replayHistory('+i+')"><div class="hi">'+r.signBadge+'</div><div class="hc"><div class="hn">'+r.signName+' · '+r.mbti+'</div><div class="hd">'+r.date+' · '+r.style+' · '+r.el+'象星座</div></div><div style="font-size:11px;color:var(--pri)">▶</div></div>';}list.innerHTML=h;}
function replayHistory(idx){var r=S.history[idx];S.sign=ZODIAC.find(function(z){return z.name===r.signName});S.birth=r.birth;playVideoReport();}
// ═══════ PROFILE ═══════
function renderProfile(){
if(S.history.length>0){var last=S.history[S.history.length-1];document.getElementById('pAvatar').innerHTML=last.signBadge;document.getElementById('pSign').textContent=last.signName+' · '+last.mbti;document.getElementById('pDetail').textContent=last.style+' · '+last.el+'象星座 · 已完成'+S.history.length+'次测试';}
var badges=[{name:'初识星盘',icon:'🔭',unlock:S.history.length>=1},{name:'探索者',icon:'🌟',unlock:S.history.length>=2},{name:'星象达人',icon:'🌙',unlock:S.history.length>=3},{name:'深度玩家',icon:'✨',unlock:S.history.length>=5},{name:'会员专属',icon:'👑',unlock:S.isMember}];
var h='';badges.forEach(function(b){h+='<div class="badge-item"><div class="bi'+(b.unlock?'':' locked')+'" style="background:'+(b.unlock?'#FFF5F0':'#f0f0f0')+'">'+b.icon+'</div>'+b.name+'</div>';});document.getElementById('badgeRow').innerHTML=h;
}
// ═══════ PURCHASE ═══════
function openPurchase(){document.getElementById('purchaseModal').classList.add('on');}
function closePurchase(){document.getElementById('purchaseModal').classList.remove('on');}
function doPurchase(){S.isMember=true;localStorage.setItem('xj_member','1');showToast('购买成功!欢迎加入星镜会员 🎉');closePurchase();renderProfile();}
// ═══════ UTILS ═══════
function showToast(msg){var t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');setTimeout(function(){t.classList.remove('show')},2000);}
window.addEventListener('resize',function(){if(S.tab==='chart')drawChart();});
document.getElementById('purchaseModal').addEventListener('click',function(e){if(e.target===this)closePurchase();});
// ═══════ SYNASTRY ═══════
var synMode='romance';
function setSynMode(m){
synMode=m;
document.querySelectorAll('.syn-tab').forEach(function(t){t.classList.remove('active');});
document.getElementById('synTab'+{romance:'Romance',friendship:'Friend',family:'Family'}[m]).classList.add('active');
var cfg={romance:{icon:'❤️',title:'两性合盘',sub:'分析两人的情感模式、吸引力与亲密关系契合度',l1:'👤 你',l2:'💕 伴侣',btn:'❤️ 开始两性合盘'},
friendship:{icon:'🤝',title:'缘分配对',sub:'输入两人的出生信息,解锁星座契合度分析',l1:'👤 你',l2:'👤 TA',btn:'💫 开始合盘分析'},
family:{icon:'🏠',title:'家庭合盘',sub:'分析亲子、手足或家庭成员的星座互动与相处模式',l1:'👤 我',l2:'👨‍👩‍👧 家人',btn:'🏠 开始家庭合盘'}}[m];
document.getElementById('synIcon').textContent=cfg.icon;
document.getElementById('synTitle').textContent='双人合盘 · '+cfg.title;
document.getElementById('synSub').textContent=cfg.sub;
document.getElementById('synLabel1').textContent=cfg.l1;
document.getElementById('synLabel2').textContent=cfg.l2;
document.getElementById('synBtn').textContent=cfg.btn;
// Show family relationship selector only in family mode
var relSel=document.getElementById('synFamilyRel');if(relSel)relSel.style.display=m==='family'?'inline-block':'none';
document.getElementById('synastryResult').innerHTML='';
}
var synChartType='compare';
function setSynChart(t){
synChartType=t;
document.querySelectorAll('#synChartTabs .syn-tab').forEach(function(b){b.classList.remove('active');});
var idx={compare:0,composite:1,marksAB:2,marksBA:3}[t];
document.querySelectorAll('#synChartTabs .syn-tab')[idx].classList.add('active');
}
// ═══ Synastry wheel drawing engine ═══
function drawSynastryWheel(cvid,birth1,birth2){
var cv=document.getElementById(cvid);if(!cv)return;
var ctx=cv.getContext('2d'),dpr=window.devicePixelRatio||1;
var w=340,h=340;cv.width=w*dpr;cv.height=h*dpr;cv.style.width='100%';cv.style.maxWidth=w+'px';cv.style.height='auto';ctx.scale(dpr,dpr);
var cx=w/2,cy=h/2;
var ang1=birth1?getPlanetAngles(birth1):null;
var ang2=birth2?getPlanetAngles(birth2):null;
if(!ang1||!ang2)return;
var zSigns=['♑','♒','♓','♈','♉','♊','♋','♌','♍','♎','♏','♐'];
var zNames=['摩羯','水瓶','双鱼','白羊','金牛','双子','巨蟹','狮子','处女','天秤','天蝎','射手'];
var pColors=['#FFD700','#C0C0C0','#B8860B','#FF69B4','#E54D42','#F5A623','#8B8B83'];
var pNames=['日','月','水','金','火','木','土'];
// Aspect detection helper
function getAspect(deg){
deg=((deg%360)+360)%360;
if(deg<=8||deg>=352)return{t:'合',c:'#FFD700',w:2.5,o:0};
if(deg>=172&&deg<=188)return{t:'冲',c:'#E54D42',w:2,o:180};
if(deg>=114&&deg<=126)return{t:'拱',c:'#4A90E2',w:1.8,o:120};
if(deg>=84&&deg<=96)return{t:'刑',c:'#FF6347',w:1.5,o:90};
if(deg>=54&&deg<=66)return{t:'六合',c:'#5CB85C',w:1.5,o:60};
return null;
}
// Compute composite midpoints
var compAng=[];
for(var i=0;i<7;i++){
var diff=ang2[i]-ang1[i];
if(diff>Math.PI)diff-=Math.PI*2;if(diff<-Math.PI)diff+=Math.PI*2;
compAng.push((ang1[i]+diff/2+Math.PI*2)%(Math.PI*2));
}
function render(){
ctx.clearRect(0,0,w,h);
ctx.fillStyle='#0a0a1a';ctx.fillRect(0,0,w,h);
if(synChartType==='compare'){
// === COMPARISON CHART: dual rings ===
var ir=80,or=125,zr=155;
// Zodiac ring
for(var i=0;i<12;i++){var a=i/12*Math.PI*2-Math.PI/2;ctx.strokeStyle='rgba(255,255,255,.08)';ctx.lineWidth=.5;ctx.beginPath();ctx.arc(cx,cy,zr-12,a,a+Math.PI/6);ctx.stroke();}
// Sector lines
for(var i=0;i<12;i++){var a=i/12*Math.PI*2-Math.PI/2;ctx.strokeStyle='rgba(255,255,255,.06)';ctx.beginPath();ctx.moveTo(cx+Math.cos(a)*(zr-12),cy+Math.sin(a)*(zr-12));ctx.lineTo(cx+Math.cos(a)*zr,cy+Math.sin(a)*zr);ctx.stroke();}
// Zodiac labels
for(var i=0;i<12;i++){var a=(i+.5)/12*Math.PI*2-Math.PI/2;ctx.fillStyle='rgba(255,255,255,.35)';ctx.font='9px sans-serif';ctx.textAlign='center';ctx.fillText(zSigns[i],cx+Math.cos(a)*(zr-6),cy+Math.sin(a)*(zr-6)+3);}
// Rings
ctx.strokeStyle='rgba(255,255,255,.1)';ctx.lineWidth=1;ctx.beginPath();ctx.arc(cx,cy,ir,0,Math.PI*2);ctx.stroke();ctx.beginPath();ctx.arc(cx,cy,or,0,Math.PI*2);ctx.stroke();
// Inner ring = Person A's planets
var pos1=[],pos2=[];
for(var i=0;i<7;i++){var a=ang1[i];var px=cx+Math.cos(a)*ir,py=cy+Math.sin(a)*ir;pos1.push({x:px,y:py,a:a});ctx.fillStyle=pColors[i];ctx.beginPath();ctx.arc(px,py,5,0,Math.PI*2);ctx.fill();ctx.fillStyle='#fff';ctx.font='bold 7px sans-serif';ctx.textAlign='center';ctx.fillText(pNames[i],px,py+2);}
// Outer ring = Person B's planets
for(var i=0;i<7;i++){var a=ang2[i];var px=cx+Math.cos(a)*or,py=cy+Math.sin(a)*or;pos2.push({x:px,y:py,a:a});ctx.fillStyle=pColors[i];ctx.beginPath();ctx.arc(px,py,5,0,Math.PI*2);ctx.fill();ctx.strokeStyle='rgba(255,255,255,.5)';ctx.lineWidth=1;ctx.stroke();ctx.fillStyle='#fff';ctx.font='bold 7px sans-serif';ctx.textAlign='center';ctx.fillText(pNames[i],px,py+2);}
// Aspect lines between rings
for(var i=0;i<7;i++){for(var j=0;j<7;j++){
var da=((ang2[j]-ang1[i])%(Math.PI*2)+Math.PI*2)%(Math.PI*2);
var asp=getAspect(da/Math.PI*180);
if(asp){
ctx.strokeStyle=asp.c;ctx.lineWidth=asp.w;ctx.globalAlpha=.45;
ctx.beginPath();ctx.moveTo(pos1[i].x,pos1[i].y);ctx.lineTo(pos2[j].x,pos2[j].y);ctx.stroke();
ctx.globalAlpha=1;
}
}}
// Legend
ctx.fillStyle='rgba(255,255,255,.6)';ctx.font='9px sans-serif';ctx.fillText('内圈:你 · 外圈:TA',cx,cy+or+16);
}else{
// === SINGLE-RING CHARTS: composite / marks ===
var sr=125,zr=sr+28;
var angles;var title='';
if(synChartType==='composite'){angles=compAng;title='组合中点盘';}
else if(synChartType==='marksAB'){angles=ang2.map(function(a,i){return(a+ang1[i]*.38)%(Math.PI*2);});title='马盘 A→BA眼中的B';}
else{angles=ang1.map(function(a,i){return(a+ang2[i]*.38)%(Math.PI*2);});title='马盘 B→AB眼中的A';}
// Zodiac sectors
for(var i=0;i<12;i++){var a=i/12*Math.PI*2-Math.PI/2;ctx.strokeStyle='rgba(255,255,255,.08)';ctx.lineWidth=.5;ctx.beginPath();ctx.arc(cx,cy,sr+10,a,a+Math.PI/6);ctx.stroke();}
for(var i=0;i<12;i++){var a=i/12*Math.PI*2-Math.PI/2;ctx.strokeStyle='rgba(255,255,255,.06)';ctx.beginPath();ctx.moveTo(cx+Math.cos(a)*(sr+10),cy+Math.sin(a)*(sr+10));ctx.lineTo(cx+Math.cos(a)*zr,cy+Math.sin(a)*zr);ctx.stroke();}
for(var i=0;i<12;i++){var a=(i+.5)/12*Math.PI*2-Math.PI/2;ctx.fillStyle='rgba(255,255,255,.35)';ctx.font='9px sans-serif';ctx.textAlign='center';ctx.fillText(zSigns[i],cx+Math.cos(a)*(zr-6),cy+Math.sin(a)*(zr-6)+3);}
// Planet ring
ctx.strokeStyle='rgba(255,255,255,.15)';ctx.lineWidth=1.5;ctx.beginPath();ctx.arc(cx,cy,sr,0,Math.PI*2);ctx.stroke();
// Planets
var poses=[];
for(var i=0;i<7;i++){var a=angles[i];var px=cx+Math.cos(a)*sr,py=cy+Math.sin(a)*sr;poses.push({x:px,y:py,a:a});ctx.fillStyle=pColors[i];ctx.beginPath();ctx.arc(px,py,6,0,Math.PI*2);ctx.fill();ctx.strokeStyle='rgba(255,255,255,.3)';ctx.lineWidth=1;ctx.stroke();ctx.fillStyle='#fff';ctx.font='bold 7px sans-serif';ctx.textAlign='center';ctx.fillText(pNames[i],px,py+2);}
// Inner aspects
for(var i=0;i<7;i++){for(var j=i+1;j<7;j++){
var da=((angles[j]-angles[i])%(Math.PI*2)+Math.PI*2)%(Math.PI*2);
var asp=getAspect(da/Math.PI*180);
if(asp){
ctx.strokeStyle=asp.c;ctx.lineWidth=asp.w;ctx.globalAlpha=.5;
ctx.beginPath();ctx.moveTo(poses[i].x,poses[i].y);ctx.lineTo(poses[j].x,poses[j].y);ctx.stroke();
ctx.globalAlpha=1;
}
}}
ctx.fillStyle='rgba(255,255,255,.5)';ctx.font='10px sans-serif';ctx.textAlign='center';ctx.fillText(title,cx,cy+zr+6);
}
}
render();
}
function openSynastry(){
showPage('synastry','星镜 · 合盘',true,false);
setupSynastryInputs();
setSynMode(synMode);
}
function setupSynastryInputs(){
['s1','s2'].forEach(function(p){
var ms=document.getElementById(p+'Month');if(!ms||ms.options.length>1)return;
for(var i=1;i<=12;i++){var o=document.createElement('option');o.value=i;o.text=i+'月';ms.appendChild(o);}
var ds=document.getElementById(p+'Day');for(var i=1;i<=31;i++){var o=document.createElement('option');o.value=i;o.text=i+'日';ds.appendChild(o);}
});
}
function runSynastry(){
var y1=parseInt(document.getElementById('s1Year').value),m1=parseInt(document.getElementById('s1Month').value),d1=parseInt(document.getElementById('s1Day').value);
var y2=parseInt(document.getElementById('s2Year').value),m2=parseInt(document.getElementById('s2Month').value),d2=parseInt(document.getElementById('s2Day').value);
if(!y1||!m1||!d1||!y2||!m2||!d2){showToast('请填写两人的完整出生日期');return;}
var familyRel='家人';var relSel=document.getElementById('synFamilyRel');if(relSel&&relSel.style.display!=='none')familyRel=relSel.value;
var z1=getZodiac(m1,d1),z2=getZodiac(m2,d2);
// Element & sign compat
var elCompat={火火:75,土土:80,风风:78,水水:82,火土:45,土火:45,火风:88,风火:88,火水:35,水火:35,土风:55,风土:55,土水:72,水土:72,风水:60,水风:60};
var elScore=elCompat[z1.el+z2.el]||50;
var zCompat={摩羯:['金牛',55],水瓶:['双子',60],双鱼:['巨蟹',65],白羊:['狮子',70],金牛:['处女',68],双子:['天秤',72],巨蟹:['天蝎',75],狮子:['射手',70],处女:['摩羯',65],天秤:['水瓶',68],天蝎:['双鱼',78],射手:['白羊',72]};
var zScore=50;var zm=zCompat[z1.name];if(zm&&zm[0]===z2.name)zScore=zm[1];
var zm2=zCompat[z2.name];if(zm2&&zm2[0]===z1.name)zScore=Math.max(zScore,zm2[1]);
// === Planet aspect analysis (测测-style) ===
var pairs=[
{a:'太阳',b:'太阳',icon:'☀☀',cat:'吸引力',d:'核心自我的共鸣'},
{a:'太阳',b:'月亮',icon:'☀☽',cat:'情感深度',d:'意识与潜意识的互动'},
{a:'金星',b:'火星',icon:'♀♂',cat:'激情火花',d:'爱与欲望的磁场'},
{a:'水星',b:'水星',icon:'☿☿',cat:'沟通',d:'思维频率的匹配'},
{a:'月亮',b:'月亮',icon:'☽☽',cat:'心灵默契',d:'情绪安全感的共振'},
{a:'金星',b:'金星',icon:'♀♀',cat:'吸引力',d:'爱情语言的契合'},
{a:'火星',b:'火星',icon:'♂♂',cat:'激情火花',d:'行动力与欲望碰撞'},
{a:'月亮',b:'金星',icon:'☽♀',cat:'情感深度',d:'情绪滋养与爱的表达'},
{a:'太阳',b:'水星',icon:'☀☿',cat:'沟通',d:'自我表达与言语理解'},
{a:'木星',b:'土星',icon:'♃♄',cat:'关系持久',d:'理想与现实的平衡'}
];
var planetAspects=[],dims={吸引力:0,沟通:0,情感深度:0,关系持久:0,激情火花:0,心灵默契:0},dc={吸引力:0,沟通:0,情感深度:0,关系持久:0,激情火花:0,心灵默契:0};
pairs.forEach(function(p){
var s=elCompat[z1.el+z2.el]||50;
if(p.a==='金星'&&p.b==='火星')s=z1.el+z2.el==='火风'||z1.el+z2.el==='风火'?88:z1.el+z2.el==='水火'||z1.el+z2.el==='火水'?40:z1.el+z2.el==='土水'||z1.el+z2.el==='水土'?70:s;
if(p.a==='太阳'&&p.b==='月亮')s=z1.name===z2.name?85:z1.el+z2.el==='火风'?82:z1.el+z2.el==='水土'?75:s;
if(p.a==='水星'&&p.b==='水星')s=z1.el+z2.el==='风风'?90:z1.el+z2.el==='火风'?78:z1.el+z2.el==='土水'?65:s;
if(p.a==='月亮'&&p.b==='月亮')s=z1.el+z2.el==='水水'?88:z1.el+z2.el==='土土'?82:z1.el+z2.el==='火火'?55:s;
if(p.a==='金星'&&p.b==='金星')s=z1.el+z2.el==='土土'?82:z1.el+z2.el==='风风'?78:z1.el+z2.el==='水水'?75:s;
if(p.a==='火星'&&p.b==='火星')s=z1.el+z2.el==='火火'?85:z1.el+z2.el==='风风'?62:z1.el+z2.el==='土土'?55:s;
if(p.a==='月亮'&&p.b==='金星')s=z1.el+z2.el==='水土'?80:z1.el+z2.el==='水水'?78:z1.el+z2.el==='火风'?72:s;
if(p.a==='太阳'&&p.b==='水星')s=z1.el+z2.el==='风风'?85:z1.el+z2.el==='火风'?76:z1.el+z2.el==='水土'?68:s;
if(p.a==='木星'&&p.b==='土星')s=z1.el+z2.el==='土土'?85:z1.el+z2.el==='风风'?70:z1.el+z2.el==='火火'?50:s;
s=Math.max(25,Math.min(95,s+Math.round((Math.random()-0.5)*10)));
var stars=s>=85?'★★★★★':s>=70?'★★★★☆':s>=55?'★★★☆☆':s>=35?'★★☆☆☆':'★☆☆☆☆';
var it='';var zn1=z1.name,zn2=z2.name;
if(p.a==='太阳'&&p.b==='太阳')it=s>=75?zn1+'与'+zn2+'的核心人格高度共振,彼此理解对方的本质需求。':s>=50?'两人有各自独立的人格魅力,需要花时间理解彼此的处事方式。':'两个独立的灵魂,互相尊重比互相改变更重要。';
else if(p.a==='太阳'&&p.b==='月亮')it=s>=75?zn1+'的自我表达能温柔包裹'+zn2+'的情绪世界,给予充分的安全感。':s>=50?'理性与感性需要磨合,但正是这种差异让你们更完整。':'自我与情绪的冲突可能让彼此疲惫,学会换位是关键。';
else if(p.a==='金星'&&p.b==='火星')it=s>=75?'吸引力爆棚!你们的磁场天然共振,初次见面就有强烈的好感。':s>=50?'有不错的情愫流动,多创造独处机会让火花升温。':'感情的节奏不太同步,需要更多耐心等待对方跟上。';
else if(p.a==='水星'&&p.b==='水星')it=s>=75?'沟通丝滑顺畅,能聊到天亮也不累。你们的脑回路在同一条线上。':s>=50?'大部分话题能聊得来,偶尔的思维碰撞反而是调味剂。':'沟通风格差异明显,多确认双方的真正意图减少误会。';
else if(p.a==='月亮'&&p.b==='月亮')it=s>=75?'情绪共鸣极深,不用说出口就能感知对方的心情变化。':s>=50?'情绪节奏基本同步,偶尔不同频也能快速调整。':'情绪表达方式不同,需要更明确地告诉对方你的感受。';
else if(p.a==='金星'&&p.b==='金星')it=s>=75?'爱情观高度一致,你们享受浪漫的方式是如此相似。':s>=50?'对爱的理解有交集也有差异,互补让关系更丰富。':'表达爱的方式不太一样,别用自己的标准衡量对方的付出。';
else if(p.a==='火星'&&p.b==='火星')it=s>=75?'行动力超强的一对,一起做事效率翻倍,激情四射。':s>=50?'做事的节奏不同但可以互补,一快一慢相得益彰。':'都很有主见,处理冲突时学会退一步海阔天空。';
else if(p.a==='月亮'&&p.b==='金星')it=s>=75?'情感的滋养与爱的表达完美对接,在一起就是治愈。':s>=50?'情感上可以互相支持,多表达欣赏让对方感受到被爱。':'情感需求与爱的表达方式有落差,坦诚沟通胜过猜测。';
else if(p.a==='太阳'&&p.b==='水星')it=s>=75?zn1+'的表达能被'+zn2+'精准理解,交流毫无障碍。':s>=50?'多数情况下能顺畅交流,偶尔的误解无伤大雅。':'思维频道不完全一致,说清楚比让对方猜更重要。';
else if(p.a==='木星'&&p.b==='土星')it=s>=75?'理想与现实达到美妙平衡,一个负责想象一个负责落地。':s>=50?'乐观与务实需要磨合,但分工明确后会很稳定。':'自由与约束的张力较大,找到共同的目标是关键。';
planetAspects.push({icon:p.icon,label:p.a+' × '+p.b,cat:p.cat,score:s,stars:stars,desc:it});
if(dims[p.cat]!==undefined){dims[p.cat]+=s;dc[p.cat]++;}
});
Object.keys(dims).forEach(function(k){dims[k]=Math.round(dims[k]/dc[k]);});
var total=Math.round(dims.吸引力*0.22+dims.沟通*0.16+dims.情感深度*0.18+dims.关系持久*0.14+dims.激情火花*0.16+dims.心灵默契*0.14);
total=Math.min(98,Math.max(30,total));
// Mode config
var modeCfg={
romance:{title:'两性吸引力',icon:'❤️',heroBg:'linear-gradient(135deg,#3d0a2e,#2d1b69,#16213e)',
levels:[{max:48,l:'火花未燃',e:'🌱'},{max:65,l:'温柔吸引',e:'🌷'},{max:80,l:'热烈奔赴',e:'🔥'},{max:98,l:'灵魂伴侣',e:'💞'}],
keywords:['亲密','默契','吸引','成长','信任','守护'],
strength:z1.name+'与'+z2.name+'的相遇有一种天然的磁场。'+z1.el+'象与'+z2.el+'象的能量搭配'+(elScore>=75?'非常和谐':'富有张力')+',你们的组合在人群中总是特别的存在。',
watch:z1.el===z2.el?'同元素让你们容易理解彼此,但也可能陷入相同的盲点。尝试跳出舒适圈,给关系注入新鲜感。':'不同元素的碰撞是你们最大的财富,也可能是摩擦的来源。学会欣赏差异而非试图改变对方。',
advice:'保持每周一次深度对话,不聊日常琐事只谈心。'+z1.name+'可以多主动表达感受,'+z2.name+'需要给对方留出独处的空间。记住:最好的关系是两个完整的人并肩前行,而非两个半人拼凑。'},
friendship:{title:'缘分契合度',icon:'🤝',heroBg:'linear-gradient(135deg,#2d1b69,#16213e,#0f3460)',
levels:[{max:45,l:'有缘无分',e:'🌊'},{max:60,l:'淡淡默契',e:'🌸'},{max:75,l:'灵魂共鸣',e:'🔥'},{max:98,l:'天作之合',e:'💫'}],
keywords:['志趣','理解','成长','互补','共鸣','自由'],
strength:z1.name+''+z1.trait.split('·')[0]+')与'+z2.name+''+z2.trait.split('·')[0]+')的组合有一种天然的舒适感。在一起时可以自在地做自己,无需刻意迎合。',
watch:'两人的节奏偶尔会错位——一个想冲锋时另一个想休整。尊重各自的生命节拍,不必强求同步。尊重各自的边界是长久友谊的基础。',
advice:'一起培养一个共同爱好,让它成为你们友谊的锚点。'+z1.name+'可以多分享你的思考,'+z2.name+'可以带对方体验新鲜事物。友谊最好的样子是互相照亮而非彼此消耗。'},
family:{title:'家庭和谐度',icon:'🏠',heroBg:'linear-gradient(135deg,#1a3a2e,#16213e,#0f3460)',
levels:[{max:50,l:'需要磨合',e:'🏡'},{max:68,l:'和睦相处',e:'🌿'},{max:82,l:'互相扶持',e:'🌟'},{max:98,l:'家和万事兴',e:'🌈'}],
keywords:['包容','支持','理解','关怀','传承','温暖'],
strength:'你和'+familyRel+''+z2.name+')之间有一种超越言语的亲情纽带。'+z1.el+'象与'+z2.el+'象的能量在家庭中'+(elScore>=70?'相辅相成':'需要更多磨合')+'。',
watch:z1.el===z2.el?'同元素的家人容易有相似的处事方式,但注意不要让固有模式限制彼此。多一点变通,少一点固执。':'不同元素的家人意味着多元的能量,理解对方的不同表达方式是和谐的关键。',
advice:'定期安排家庭聚会或视频通话,仪式感是家庭关系的润滑剂。'+z1.name+'可以多倾听,'+z2.name+'可以多表达。家人之间的爱不需要理由,但需要经营。'}
}[synMode];
var level=modeCfg.levels[0];for(var i=0;i<modeCfg.levels.length;i++){if(total<=modeCfg.levels[i].max){level=modeCfg.levels[i];break;}}
// === Build result HTML ===
var h='';
h+='<div class="result-hero" style="background:'+modeCfg.heroBg+'">';
h+='<div style="display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:8px">';
h+='<span>'+zodiacBadge(z1)+'</span><span style="font-size:20px;color:rgba(255,255,255,.5)">✕</span><span>'+zodiacBadge(z2)+'</span></div>';
h+='<div style="font-size:15px;opacity:.7;margin-bottom:2px">'+modeCfg.icon+' '+modeCfg.title+'</div>';
h+='<div style="font-size:48px;font-weight:900;color:#FFD700;margin:8px 0">'+total+'<span style="font-size:16px;opacity:.7">%</span></div>';
h+='<div style="font-size:17px;font-weight:700;margin-bottom:10px">'+level.l+' '+level.e+'</div>';
h+='<canvas id="synRadar" width="240" height="240" style="margin:4px auto;display:block;max-width:100%"></canvas>';
h+='</div>';
// Chart type tabs (result area)
h+='<div style="display:flex;gap:4px;margin-bottom:10px">';
h+='<button class="syn-tab'+(synChartType==='compare'?' active':'')+'" onclick="synChartType=\'compare\';drawSynastryWheel(\'synWheel\',{year:'+y1+',month:'+m1+',day:'+d1+'},{year:'+y2+',month:'+m2+',day:'+d2+'});refreshSynTabs()">◎ 比较盘</button>';
h+='<button class="syn-tab'+(synChartType==='composite'?' active':'')+'" onclick="synChartType=\'composite\';drawSynastryWheel(\'synWheel\',{year:'+y1+',month:'+m1+',day:'+d1+'},{year:'+y2+',month:'+m2+',day:'+d2+'});refreshSynTabs()">◉ 组合盘</button>';
h+='<button class="syn-tab'+(synChartType==='marksAB'?' active':'')+'" onclick="synChartType=\'marksAB\';drawSynastryWheel(\'synWheel\',{year:'+y1+',month:'+m1+',day:'+d1+'},{year:'+y2+',month:'+m2+',day:'+d2+'});refreshSynTabs()">👁 马盘 A→B</button>';
h+='<button class="syn-tab'+(synChartType==='marksBA'?' active':'')+'" onclick="synChartType=\'marksBA\';drawSynastryWheel(\'synWheel\',{year:'+y1+',month:'+m1+',day:'+d1+'},{year:'+y2+',month:'+m2+',day:'+d2+'});refreshSynTabs()">👁 马盘 B→A</button>';
h+='</div>';
// Synastry wheel canvas
h+='<canvas id="synWheel" width="340" height="340" style="display:block;max-width:100%;margin:0 auto 10px;border-radius:12px;background:#0a0a1a"></canvas>';
// Aspect detail table
h+='<div class="card card-sm"><div class="card-title">📐 相位详情表</div>';
// Compute aspects for the selected chart type
(function(){
var ang1=getPlanetAngles({year:y1,month:m1,day:d1});
var ang2=getPlanetAngles({year:y2,month:m2,day:d2});
var pNames=['日','月','水','金','火','木','土'];
var aspNames={:'黄',:'红',:'蓝',:'橙',六合:'绿'};
var aspColors={:'#FFD700',:'#E54D42',:'#4A90E2',:'#FF6347',六合:'#5CB85C'};
var aspects=[];
for(var i=0;i<7;i++){for(var j=0;j<7;j++){
var da=((ang2[j]-ang1[i])%(Math.PI*2)+Math.PI*2)%(Math.PI*2);
var deg=da/Math.PI*180;
var t=null;
deg=((deg%360)+360)%360;
if(deg<=8||deg>=352)t='合';else if(deg>=172&&deg<=188)t='冲';else if(deg>=114&&deg<=126)t='拱';else if(deg>=84&&deg<=96)t='刑';else if(deg>=54&&deg<=66)t='六合';
if(t)aspects.push({a:PLANETS[i].name,b:PLANETS[j].name,t:t,c:aspColors[t],deg:Math.round(deg),orb:Math.round(Math.abs(deg-(t==='合'?0:t==='冲'?180:t==='拱'?120:t==='刑'?90:60)))});
}}
// Sort: conjunctions first, then by orb
aspects.sort(function(x,y){var o={:0,:1,:2,:3,六合:4};return(o[x.t]-o[y.t])||(x.orb-y.orb);});
aspects.slice(0,8).forEach(function(a){
h+='<div style="display:flex;align-items:center;gap:6px;padding:4px 0;border-bottom:1px solid #f5f5f5;font-size:11px">';
h+='<span style="font-weight:700;min-width:56px">'+a.a+' × '+a.b+'</span>';
h+='<span style="display:inline-block;width:20px;height:20px;line-height:20px;text-align:center;border-radius:50%;background:'+a.c+';color:#fff;font-size:9px;font-weight:700">'+a.t+'</span>';
h+='<span style="color:var(--sub)">'+a.deg+'°</span>';
h+='<span style="color:var(--sub);font-size:9px;margin-left:auto">容许 '+a.orb+'°</span>';
h+='</div>';
});
if(aspects.length===0)h+='<div style="color:var(--sub);font-size:11px">暂无显著的托勒密相位</div>';
})();
h+='</div>';
// Six dimensions
h+='<div class="card card-sm"><div class="card-title">🔮 六维解析</div>';
var dOrder=['吸引力','激情火花','情感深度','沟通','心灵默契','关系持久'];
var dColors={吸引力:'#E54D42',激情火花:'#FF6347',情感深度:'#7B68EE',沟通:'#4A90E2',心灵默契:'#FF69B4',关系持久:'#5CB85C'};
dOrder.forEach(function(d){
h+='<div class="elem-bar"><span class="el" style="width:56px;text-align:left;font-size:10px">'+d+'</span><div class="eb"><div class="ebf" style="width:'+dims[d]+'%;background:'+dColors[d]+'"></div></div><span style="font-size:10px;color:var(--sub);font-weight:700">'+dims[d]+'%</span></div>';
});
h+='</div>';
// Planet aspect details
h+='<div class="card card-sm"><div class="card-title">⭐ 行星相位解读</div>';
planetAspects.slice(0,6).forEach(function(a){
var alpha=a.score>=80?1:a.score>=60?.85:.7;
h+='<div style="margin-bottom:10px;opacity:'+alpha+'">';
h+='<div style="display:flex;align-items:center;gap:6px;margin-bottom:2px"><span style="font-size:15px">'+a.icon+'</span><span style="font-size:12px;font-weight:700">'+a.label+'</span><span style="font-size:10px;color:#FFD700">'+a.stars+'</span><span style="font-size:10px;color:var(--sub);margin-left:auto">'+a.score+'%</span></div>';
h+='<div style="font-size:11px;color:var(--sub);line-height:1.5">'+a.desc+'</div></div>';
});
h+='</div>';
// Keywords
h+='<div class="card card-sm"><div class="card-title">💫 关系关键词</div>';
h+='<div style="display:flex;flex-wrap:wrap;gap:6px;margin-top:4px">';
modeCfg.keywords.forEach(function(k){h+='<span style="padding:4px 12px;background:#FFF5F0;color:var(--pri);border-radius:16px;font-size:11px;font-weight:600">#'+k+'</span>';});
h+='</div></div>';
// Sections
h+='<div class="card card-sm"><div class="card-title">✅ 关系优势</div><div class="card-sub">'+modeCfg.strength+'</div></div>';
h+='<div class="card card-sm"><div class="card-title">⚠️ 需要注意</div><div class="card-sub">'+modeCfg.watch+'</div></div>';
h+='<div class="card card-sm"><div class="card-title">💌 给你们的建议</div><div class="card-sub">'+modeCfg.advice+'</div></div>';
h+='<button class="btn btn-outline btn-block btn-sm" onclick="openSynastry()" style="margin-bottom:16px">重新合盘</button>';
document.getElementById('synastryResult').innerHTML=h;
// Draw radar chart
setTimeout(function(){
var cv=document.getElementById('synRadar');if(!cv)return;
var ctx=cv.getContext('2d'),w=cv.width,h=cv.height,cx=w/2,cy=h/2,r=80;
ctx.clearRect(0,0,w,h);
for(var i=1;i<=4;i++){ctx.beginPath();ctx.arc(cx,cy,r*i/4,0,Math.PI*2);ctx.strokeStyle='rgba(255,255,255,'+(.06+.04*i)+')';ctx.lineWidth=.8;ctx.stroke();}
var labels=['吸引力','激情','情感','沟通','默契','持久'];
var vals=[dims.吸引力,dims.激情火花,dims.情感深度,dims.沟通,dims.心灵默契,dims.关系持久];
var clrs=['#E54D42','#FF6347','#7B68EE','#4A90E2','#FF69B4','#5CB85C'];
// Axes
for(var i=0;i<6;i++){var a=-Math.PI/2+i/6*Math.PI*2;ctx.beginPath();ctx.moveTo(cx,cy);ctx.lineTo(cx+Math.cos(a)*r,cy+Math.sin(a)*r);ctx.strokeStyle='rgba(255,255,255,.06)';ctx.stroke();}
// Data polygon
ctx.beginPath();
for(var i=0;i<6;i++){var a=-Math.PI/2+i/6*Math.PI*2;var vr=vals[i]/100*r;var px=cx+Math.cos(a)*vr,py=cy+Math.sin(a)*vr;if(i===0)ctx.moveTo(px,py);else ctx.lineTo(px,py);}
ctx.closePath();var g=ctx.createRadialGradient(cx,cy,0,cx,cy,r);g.addColorStop(0,'rgba(255,215,0,.28)');g.addColorStop(1,'rgba(255,100,50,.04)');ctx.fillStyle=g;ctx.fill();ctx.strokeStyle='rgba(255,215,0,.65)';ctx.lineWidth=2;ctx.stroke();
// Dots & labels
for(var i=0;i<6;i++){var a=-Math.PI/2+i/6*Math.PI*2;var vr=vals[i]/100*r;var px=cx+Math.cos(a)*vr,py=cy+Math.sin(a)*vr;ctx.fillStyle=clrs[i];ctx.beginPath();ctx.arc(px,py,4,0,Math.PI*2);ctx.fill();ctx.fillStyle='#FFD700';ctx.beginPath();ctx.arc(px,py,2.2,0,Math.PI*2);ctx.fill();var lx=cx+Math.cos(a)*(r+22),ly=cy+Math.sin(a)*(r+22);ctx.fillStyle='rgba(255,255,255,.65)';ctx.font='9px sans-serif';ctx.textAlign='center';ctx.fillText(labels[i],lx,ly+3);}
},100);
// Draw synastry wheel
setTimeout(function(){drawSynastryWheel('synWheel',{year:y1,month:m1,day:d1},{year:y2,month:m2,day:d2});},150);
}
// Tab refresh helper for result-area chart tabs
function refreshSynTabs(){
var tabs=document.querySelectorAll('#synastryResult .syn-tab');
tabs.forEach(function(t){t.classList.remove('active');});
var idx={compare:0,composite:1,marksAB:2,marksBA:3}[synChartType];
if(tabs[idx])tabs[idx].classList.add('active');
}
// ═══════ SCHULTE ═══════
var schulteState={running:false,next:1,nums:[],startTime:0,timer:null,best:parseFloat(localStorage.getItem('schulte_best')||'0')};
function initSchulteBest(){
var el=document.getElementById('schulteBest');
el.textContent=schulteState.best>0?'历史最佳:'+(schulteState.best/1000).toFixed(1)+'s':'';
}
initSchulteBest();
function shuffleSchulte(){
var arr=[];for(var i=1;i<=25;i++)arr.push(i);
for(var i=arr.length-1;i>0;i--){var j=Math.floor(Math.random()*(i+1));var t=arr[i];arr[i]=arr[j];arr[j]=t;}
return arr;
}
function buildSchulteGrid(){
if(schulteState.nums.length===0)schulteState.nums=shuffleSchulte();
var front=document.getElementById('cubeFront');
front.innerHTML='';
for(var i=0;i<25;i++){
var cell=document.createElement('div');cell.className='cs';
cell.textContent=schulteState.nums[i];
cell.setAttribute('data-num',schulteState.nums[i]);
cell.style.animationDelay=((i%5)*0.12+(Math.floor(i/5)*0.08))+'s';
cell.onclick=function(){schulteClick(this);};
front.appendChild(cell);
}
}
function schulteClick(el){
if(!schulteState.running)return;
var n=parseInt(el.getAttribute('data-num'));
if(n!==schulteState.next)return; // wrong order, ignore
el.classList.add('done');
schulteState.next++;
if(schulteState.next>25){finishSchulte();return;}
// Highlight next target
var front=document.getElementById('cubeFront');
var cells=front.querySelectorAll('.cs');
for(var i=0;i<cells.length;i++){
var cn=parseInt(cells[i].getAttribute('data-num'));
cells[i].classList.toggle('next',cn===schulteState.next);
}
}
function startSchulte(){
if(schulteState.running)return;
var scene=document.getElementById('cubeScene');
scene.classList.add('paused'); // freeze rotation while playing
schulteState.running=true;schulteState.next=1;
schulteState.nums=shuffleSchulte();
schulteState.startTime=performance.now();
buildSchulteGrid();
// Mark first number as next
var front=document.getElementById('cubeFront');
var cells=front.querySelectorAll('.cs');
for(var i=0;i<cells.length;i++){
var cn=parseInt(cells[i].getAttribute('data-num'));
cells[i].classList.toggle('next',cn===1);
}
document.getElementById('schulteBtn').textContent='训练中...';
document.getElementById('schulteSub').textContent='点击数字 1→2→3...→25,越快越好';
// Start timer display
updateSchulteTimer();
schulteState.timer=setInterval(updateSchulteTimer,100);
}
function updateSchulteTimer(){
if(!schulteState.running)return;
var elapsed=(performance.now()-schulteState.startTime);
document.getElementById('schulteTimer').textContent=(elapsed/1000).toFixed(1)+'s';
}
function finishSchulte(){
schulteState.running=false;
clearInterval(schulteState.timer);schulteState.timer=null;
var elapsed=performance.now()-schulteState.startTime;
document.getElementById('schulteTimer').textContent=(elapsed/1000).toFixed(1)+'s';
var scene=document.getElementById('cubeScene');
scene.classList.remove('paused');
document.getElementById('schulteBtn').textContent='再来一次';
document.getElementById('schulteSub').textContent='完成!前额叶激活 ✓ 专注力训练 ✓';
// Save best
if(schulteState.best===0||elapsed<schulteState.best){
schulteState.best=elapsed;
localStorage.setItem('schulte_best',elapsed);
document.getElementById('schulteBest').textContent='🎉 新纪录!最佳:'+(elapsed/1000).toFixed(1)+'s';
}else{
document.getElementById('schulteBest').textContent='最佳:'+(schulteState.best/1000).toFixed(1)+'s | 本次:'+(elapsed/1000).toFixed(1)+'s';
}
// Show result rank hint
var s=elapsed/1000;
var rank=s<25?'⚡ 反应极快':s<40?'🔥 优秀':s<60?'👍 良好':s<90?'📖 正常':'🌱 继续加油';
document.getElementById('schulteSub').textContent+=' · '+rank;
// Reset cube position
var cube=document.getElementById('cubeEl');
cube.style.transform='rotateX(-15deg) rotateY(25deg)';
}
// Cube drag rotate
(function(){
var scene=document.getElementById('cubeScene');
var cube=document.getElementById('cubeEl');
var dragging=false,lastX=0,rotY=25,rotX=-15;
scene.addEventListener('mousedown',function(e){if(schulteState.running)return;dragging=true;lastX=e.clientX;});
scene.addEventListener('mousemove',function(e){if(!dragging)return;rotY+=(e.clientX-lastX)*0.5;lastX=e.clientX;cube.style.transform='rotateX('+rotX+'deg) rotateY('+rotY+'deg)';});
scene.addEventListener('mouseup',function(){dragging=false;});
scene.addEventListener('mouseleave',function(){dragging=false;});
scene.addEventListener('touchstart',function(e){if(schulteState.running||e.touches.length!==1)return;dragging=true;lastX=e.touches[0].clientX;},{passive:true});
scene.addEventListener('touchmove',function(e){if(!dragging)return;rotY+=(e.touches[0].clientX-lastX)*0.5;lastX=e.touches[0].clientX;cube.style.transform='rotateX('+rotX+'deg) rotateY('+rotY+'deg)';},{passive:true});
scene.addEventListener('touchend',function(){dragging=false;});
})();
</script>
</body>
</html>