guanwei 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +5 -2
- package/README.md +6 -3
- package/dist/assets/{index-C7ql6zvs.js → index-DmdGzBy9.js} +25 -25
- package/dist/assets/index-DmdGzBy9.js.map +1 -0
- package/dist/assets/index-hLV3S-Cj.css +1 -0
- package/dist/index.html +2 -2
- package/package.json +2 -2
- package/scripts/release.sh +15 -0
- package/server/src/data/db.json +210 -0
- package/server/src/data/guanwei.db +0 -0
- package/server/src/index.ts +28 -5
- package/server/src/routes/tarot.ts +4 -4
- package/server/src/routes/users.ts +42 -7
- package/server/src/services/divineStore.ts +1 -5
- package/server/src/services/promptBuilder.ts +2 -2
- package/server/src/types/index.ts +2 -104
- package/shared/core/data/ganzhi.ts +1 -1
- package/shared/core/data/gua64.ts +1 -1
- package/{src → shared/core}/data/lifeContext.ts +2 -8
- package/shared/core/data/liuren.ts +1 -1
- package/shared/core/data/qimen.ts +1 -1
- package/{src → shared/core}/data/spreads.ts +1 -1
- package/{src → shared/core}/data/tarotCards.ts +1 -1
- package/shared/core/data/xiaoliuren.ts +1 -1
- package/shared/core/data/ziwei.ts +1 -1
- package/shared/core/data/zodiac.ts +1 -1
- package/shared/core/engine/bazi.ts +0 -1
- package/shared/core/engine/calendar.ts +2 -2
- package/{server/src/utils → shared/core/engine}/semanticAnalyzer.ts +9 -46
- package/{server/src/utils → shared/core/engine}/tarotEngine.ts +6 -6
- package/shared/core/engine/ziwei.ts +3 -2
- package/shared/core/engine/ziweiInterpret.ts +0 -3
- package/shared/core/types.ts +157 -0
- package/src/App.tsx +1 -1
- package/src/arts/registry.ts +1 -1
- package/src/components/QuestionFields.tsx +0 -1
- package/src/components/ReportView.tsx +0 -1
- package/src/components/TimeShichenInput.tsx +1 -0
- package/src/components/arts/BaziArt.tsx +0 -10
- package/src/components/arts/LiurenArt.tsx +1 -1
- package/src/components/arts/LiuyaoArt.tsx +0 -1
- package/src/components/arts/MeihuaArt.tsx +0 -1
- package/src/components/arts/QimenArt.tsx +0 -1
- package/src/components/arts/TarotArt.tsx +2 -2
- package/src/components/arts/XiaoliurenArt.tsx +1 -2
- package/src/components/arts/ZiweiArt.tsx +2 -15
- package/src/data/arts.ts +1 -1
- package/src/index.css +2 -74
- package/src/pages/AuthPage.tsx +4 -6
- package/src/pages/DemoPage.tsx +1 -2
- package/src/pages/HistoryPage.tsx +10 -9
- package/src/pages/ModulePage.tsx +6 -32
- package/src/services/api.ts +4 -4
- package/src/stores/useDivinationStore.ts +1 -1
- package/src/types/index.ts +2 -104
- package/tailwind.config.js +0 -35
- package/tsconfig.json +5 -5
- package/dist/assets/index-C7ql6zvs.js.map +0 -1
- package/dist/assets/index-DQx62TUr.css +0 -1
- package/server/src/data/lifeContext.ts +0 -423
- package/server/src/data/spreads.ts +0 -255
- package/server/src/data/tarotCards.ts +0 -2353
- package/src/components/Navigation.tsx +0 -80
- package/src/components/TarotCard.tsx +0 -129
- package/src/pages/AstrologyPage.tsx +0 -33
- package/src/pages/BaZiPage.tsx +0 -33
- package/src/pages/Home.tsx +0 -179
- package/src/pages/SpreadEditor.tsx +0 -230
- package/src/pages/SpreadLibrary.tsx +0 -199
- package/src/pages/SpreadLibraryPage.tsx +0 -17
- package/src/pages/TarotPage.tsx +0 -738
- package/src/pages/ZiWeiPage.tsx +0 -33
- package/src/utils/semanticAnalyzer.ts +0 -555
- package/src/utils/tarotEngine.ts +0 -849
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&family=Ma+Shan+Zheng&family=Zhi+Mang+Xing&family=Noto+Sans+SC:wght@300;400;500;700&display=swap";@import"https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@300;400;500;600;700&family=Ma+Shan+Zheng&family=Zhi+Mang+Xing&display=swap";*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}html{scroll-behavior:smooth;overflow-x:hidden}body{overflow-x:hidden}::-webkit-scrollbar{width:6px}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-full{height:100%}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.resize{resize:both}.items-center{align-items:center}.justify-center{justify-content:center}.break-all{word-break:break-all}.border{border-width:1px}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.underline{text-decoration-line:underline}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}@keyframes fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes typing-cursor{0%,to{opacity:1}50%{opacity:0}}@media print{body{background:#fff!important}header,footer,nav,aside,.site-head,.site-nav,.back-link,.module-hero,.mh-intro,.mh-row,.altar-panel,.fit-card,.fit-note,.btn-row,.ai-streaming,.ai-error,.result-placeholder,.disclaimer,.d-title,.motes,.ink-vein,.bamboo,.cal-grid,.profile-card,.no-print{display:none!important}main{display:block!important;padding:0!important}.wrap{max-width:none!important;padding:0!important}.altar{display:block!important}.altar-result{width:100%!important;max-width:none!important}.report-view{color:#000!important;background:#fff!important}.report-view .result-card{-moz-column-break-inside:auto;break-inside:auto;border:1px solid #ddd!important;background:#fff!important;box-shadow:none!important;color:#000!important;margin-bottom:6mm}.report-view .result-card h3{-moz-column-break-after:avoid;break-after:avoid}.report-view .domain-cell,.report-view li,.report-view .traits-grid .trait{-moz-column-break-inside:avoid;break-inside:avoid}.report-view .result-title{-moz-column-break-after:avoid;break-after:avoid}.report-view .result-text,.report-view p,.report-view li,.report-view h3{color:#000!important}.report-view .domain-name{color:#555!important}@page{margin:12mm}}@keyframes pulse-soft{0%,to{opacity:.55}50%{opacity:1}}:root{--paper: #F5F1E7;--paper-deep: #EDE8D9;--paper-dim: #E4DECC;--ink: #37342C;--ink-soft: #6B675C;--ink-faint: #97917F;--line: rgba(55,52,44,.16);--line-soft: rgba(55,52,44,.1);--celadon: #96A88F;--celadon-deep: #5F7660;--celadon-tint: #E3E8DC;--crab: #7C9792;--crab-tint: #DCE4E0;--rice: #D9CDAC;--rice-tint: #EDE5CE;--cinnabar: #A5402D;--cinnabar-deep:#8C3526;--cinnabar-tint:#F3E3DC;--white-paper: #FBF9F3;--font-song: "Noto Serif SC","Songti SC","Source Han Serif SC","SimSun","STSong",serif;--font-kai: "Ma Shan Zheng","Kaiti SC","KaiTi","STKaiti","Noto Serif SC",serif;--font-zm: "Zhi Mang Xing","Ma Shan Zheng","Kaiti SC",serif;--fs-xs: .75rem;--fs-sm: .875rem;--fs-base:1.05rem;--fs-lg: 1.35rem;--fs-xl: clamp(1.6rem, 3.2vw, 2.2rem);--fs-2xl: clamp(2.2rem, 5.5vw, 3.6rem);--fs-3xl: clamp(3rem, 9vw, 6rem);--fs-display: clamp(4.2rem, 14vw, 10rem);--sp-1:.5rem;--sp-2:1rem;--sp-3:1.5rem;--sp-4:2rem;--sp-5:3rem;--sp-6:4.5rem;--sp-7:6.5rem;--sp-8:9rem;--r-sm:2px;--r-md:4px;--r-lg:8px;--shadow-paper: 0 1px 2px rgba(55,52,44,.06), 0 10px 30px -18px rgba(55,52,44,.18);--ease-out: cubic-bezier(.22,1,.36,1);--ease-ink: cubic-bezier(.5,0,.1,1);--dur-fast: .22s;--dur-mid: .6s;--dur-slow: 1.2s}*{margin:0;padding:0;box-sizing:border-box}html{scroll-behavior:smooth}body{font-family:var(--font-song);color:var(--ink);background:var(--paper);font-size:var(--fs-base);line-height:1.85;-webkit-font-smoothing:antialiased;overflow-x:hidden}::-moz-selection{background:var(--cinnabar);color:var(--paper)}::selection{background:var(--cinnabar);color:var(--paper)}img,svg{display:block;max-width:100%}a{color:inherit;text-decoration:none}button{font-family:inherit;cursor:pointer;background:none;border:none;color:inherit}input,select,textarea{font-family:inherit;color:inherit}#paper-grain{position:fixed;top:0;right:0;bottom:0;left:0;z-index:-2;pointer-events:none;background:radial-gradient(120% 90% at 12% 0%,rgba(255,255,255,.55),transparent 55%),radial-gradient(100% 80% at 100% 100%,rgba(198,188,160,.22),transparent 60%)}#paper-grain:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;background-image:repeating-linear-gradient(0deg,rgba(55,52,44,.016) 0 1px,transparent 1px 3px),repeating-linear-gradient(90deg,rgba(55,52,44,.012) 0 1px,transparent 1px 5px);opacity:.5}#mountains{position:fixed;left:0;right:0;bottom:0;height:38vh;z-index:-1;pointer-events:none;opacity:.5}.wrap{max-width:1200px;margin:0 auto;padding:0 clamp(1.25rem,4vw,3rem)}.site-head{position:sticky;top:0;z-index:50;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:linear-gradient(180deg,#f5f1e7eb,#f5f1e7b8);border-bottom:1px solid var(--line-soft)}.head-inner{display:flex;align-items:center;justify-content:space-between;padding-block:.8rem;gap:1rem}.brand{display:flex;align-items:baseline;gap:.6rem;flex-shrink:0}.brand .seal{align-self:center;font-family:var(--font-kai);font-size:.72rem;letter-spacing:.12em;color:var(--cinnabar);border:1.5px solid var(--cinnabar);padding:.28rem .34rem;line-height:1;border-radius:2px}.brand .name{font-family:var(--font-kai);font-size:1.45rem;letter-spacing:.32em;color:var(--ink)}.brand .sub{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.3em;white-space:nowrap}.nav-links{display:flex;align-items:center;gap:clamp(.6rem,2vw,1.6rem);flex-wrap:wrap;justify-content:flex-end}.nav-links a{font-size:var(--fs-sm);letter-spacing:.18em;color:var(--ink-soft);padding:.3rem 0;position:relative;transition:color var(--dur-fast) var(--ease-out)}.nav-links a:after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--cinnabar);transform:scaleX(0);transform-origin:right;transition:transform var(--dur-mid) var(--ease-out)}.nav-links a:hover{color:var(--ink)}.nav-links a:hover:after{transform:scaleX(1);transform-origin:left}.nav-links a.active{color:var(--cinnabar)}.view{display:none;animation:viewIn .9s var(--ease-out) both}.view.active{display:block}@keyframes viewIn{0%{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}.hero{position:relative;min-height:calc(100vh - 76px);display:flex;flex-direction:column;justify-content:center;padding-block:var(--sp-6)}.hero-kicker{display:flex;align-items:center;gap:1rem;font-size:var(--fs-sm);letter-spacing:.5em;color:var(--ink-faint);margin-bottom:var(--sp-3)}.hero-kicker:before{content:"";width:3.5rem;height:1px;background:var(--ink-faint)}.hero-title{font-family:var(--font-kai);font-size:var(--fs-display);letter-spacing:.12em;line-height:1.05;color:var(--ink);text-shadow:0 2px 30px rgba(255,255,255,.6)}.hero-title .accent{color:var(--celadon-deep);font-family:var(--font-zm)}.hero-line{margin-top:var(--sp-4);font-size:var(--fs-lg);color:var(--ink-soft);max-width:34ch;line-height:2;letter-spacing:.08em}.hero-line em{font-style:normal;color:var(--cinnabar)}.hero-desc{margin-top:var(--sp-3);max-width:52ch;color:var(--ink-faint);font-size:var(--fs-sm);letter-spacing:.14em;line-height:2.1}.hero-actions{margin-top:var(--sp-5);display:flex;gap:1rem;flex-wrap:wrap}.btn-seal{position:relative;padding:.85rem 2.2rem;font-family:var(--font-kai);font-size:1.05rem;letter-spacing:.35em;color:var(--cinnabar);border:1.5px solid var(--cinnabar);border-radius:2px;transition:all var(--dur-mid) var(--ease-out);overflow:hidden;display:inline-block;cursor:pointer}.btn-seal:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;background:var(--cinnabar);transform:scaleY(0);transform-origin:top;transition:transform var(--dur-mid) var(--ease-out)}.btn-seal:hover:before{transform:scaleY(1)}.btn-seal.btn-ghost{color:var(--ink-soft);border-color:var(--ink-soft)}.btn-seal.btn-ghost:before{background:var(--ink-soft)}.btn-seal.btn-ghost:hover{color:var(--paper)}.hero-vert{position:absolute;right:clamp(1rem,4vw,3rem);top:50%;transform:translateY(-50%);writing-mode:vertical-rl;font-family:var(--font-kai);font-size:var(--fs-sm);letter-spacing:.6em;color:var(--ink-faint);opacity:.75;display:flex;gap:2.2rem}.hero-vert span{white-space:nowrap}.scroll-hint{position:absolute;bottom:2.4rem;left:50%;transform:translate(-50%);writing-mode:vertical-rl;font-size:var(--fs-xs);letter-spacing:.5em;color:var(--ink-faint);display:flex;align-items:center;gap:.6rem;animation:floatHint 3.2s var(--ease-ink) infinite}.scroll-hint:after{content:"";width:1px;height:3rem;background:linear-gradient(180deg,var(--ink-faint),transparent)}.section-head{margin-bottom:var(--sp-5)}.section-eyebrow{display:flex;align-items:center;gap:1rem;font-size:var(--fs-sm);letter-spacing:.5em;color:var(--ink-faint)}.section-eyebrow:before{content:"";width:2.5rem;height:1px;background:var(--ink-faint)}.section-title{font-family:var(--font-kai);font-size:var(--fs-2xl);letter-spacing:.2em;margin-top:.8rem;color:var(--ink)}.section-note{margin-top:.6rem;color:var(--ink-faint);font-size:var(--fs-sm);letter-spacing:.12em}.arts-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.2rem,2.5vw,2rem)}@media(max-width:900px){.arts-grid{grid-template-columns:repeat(2,1fr)}}@media(max-width:560px){.arts-grid{grid-template-columns:1fr}}.art-card{position:relative;background:linear-gradient(175deg,var(--white-paper),var(--paper) 70%,var(--paper-deep));border:1px solid var(--line);border-radius:var(--r-md);padding:var(--sp-4) var(--sp-3);cursor:pointer;transition:transform var(--dur-mid) var(--ease-out),box-shadow var(--dur-mid) var(--ease-out),border-color var(--dur-mid);overflow:hidden;min-height:240px;display:flex;flex-direction:column;text-decoration:none;color:inherit}.art-card:before{content:"";position:absolute;top:0;left:1.5rem;right:1.5rem;height:1px;background:linear-gradient(90deg,transparent,var(--celadon),transparent)}.art-card:after{content:"";position:absolute;inset:auto -30% -55% -30%;height:90%;background:radial-gradient(ellipse at center,rgba(150,168,143,.16),transparent 65%);opacity:0;transition:opacity var(--dur-slow) var(--ease-ink)}.art-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-paper);border-color:var(--celadon)}.art-card:hover:after{opacity:1}.art-card:focus-visible{outline:2px solid var(--celadon-deep);outline-offset:2px}.art-num{font-family:var(--font-kai);font-size:var(--fs-sm);color:var(--ink-faint);letter-spacing:.3em;display:flex;align-items:center;gap:.5rem}.art-num:after{content:"";flex:1;height:1px;background:var(--line-soft)}.art-symbol{margin:var(--sp-2) 0 var(--sp-2);font-family:var(--font-zm);font-size:var(--fs-2xl);color:var(--celadon-deep);line-height:1;text-align:center;width:3.4rem;height:3.4rem;margin-left:auto;margin-right:auto;display:flex;align-items:center;justify-content:center;border:1px solid var(--line-soft);border-radius:50%;background:radial-gradient(circle at 35% 30%,var(--celadon-tint),transparent 70%)}.art-name{font-family:var(--font-kai);font-size:var(--fs-xl);letter-spacing:.24em;text-align:center;color:var(--ink)}.art-poem{text-align:center;color:var(--ink-faint);font-size:var(--fs-sm);letter-spacing:.18em;margin-top:.6rem}.art-enter{margin-top:auto;padding-top:var(--sp-2);text-align:center;font-size:var(--fs-xs);letter-spacing:.4em;color:var(--ink-faint);transition:color var(--dur-fast)}.art-card:hover .art-enter{color:var(--cinnabar)}.about{background:var(--paper-deep);border-block:1px solid var(--line-soft)}.about-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-4)}@media(max-width:860px){.about-grid{grid-template-columns:1fr}}.about-item{padding-right:var(--sp-3)}.about-item h3{font-family:var(--font-kai);font-size:1.1rem;letter-spacing:.2em;display:flex;align-items:center;gap:.7rem;color:var(--ink)}.about-item h3:before{content:"·";color:var(--cinnabar);font-size:1.4rem}.about-item p{margin-top:.7rem;font-size:var(--fs-sm);color:var(--ink-soft);line-height:2.1;letter-spacing:.06em}.module-hero{padding:var(--sp-7) 0 var(--sp-5);position:relative}.module-kicker{display:flex;align-items:center;gap:1rem;font-size:var(--fs-sm);letter-spacing:.4em;color:var(--ink-faint)}.module-kicker:before{content:"";width:2.5rem;height:1px;background:var(--ink-faint)}.module-title-row{display:flex;align-items:flex-end;gap:var(--sp-3);flex-wrap:wrap;margin-top:1rem}.module-title{font-family:var(--font-kai);font-size:var(--fs-2xl);letter-spacing:.18em;color:var(--ink)}.module-title .cn{display:block;font-family:var(--font-zm);font-size:var(--fs-3xl);color:var(--celadon-deep);letter-spacing:.1em}.module-poem{font-family:var(--font-kai);color:var(--ink-soft);font-size:var(--fs-lg);letter-spacing:.3em;padding-bottom:.5rem}.module-intro{margin-top:var(--sp-2);max-width:62ch;color:var(--ink-soft);font-size:var(--fs-sm);letter-spacing:.08em;line-height:2.2}.module-intro .source{color:var(--ink-faint);font-size:var(--fs-xs)}.altar{display:grid;grid-template-columns:340px 1fr;gap:var(--sp-5);align-items:start}@media(max-width:960px){.altar{grid-template-columns:1fr}}.altar-panel{background:linear-gradient(175deg,var(--white-paper),var(--paper-deep));border:1px solid var(--line);border-radius:var(--r-lg);padding:var(--sp-4);position:sticky;top:88px}@media(max-width:960px){.altar-panel{position:static}}.panel-title{font-family:var(--font-kai);font-size:1.1rem;letter-spacing:.25em;display:flex;align-items:center;gap:.6rem;color:var(--ink);padding-bottom:var(--sp-2);border-bottom:1px solid var(--line-soft)}.panel-title:before{content:"◇";color:var(--celadon-deep);font-size:.8rem}.field{margin-top:var(--sp-3)}.field label{display:block;font-size:var(--fs-sm);letter-spacing:.2em;color:var(--ink-soft);margin-bottom:.4rem}.field .hint{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.08em;margin-top:.3rem}.field-row{display:grid;grid-template-columns:1fr 1fr;gap:.8rem}.input-line{width:100%;padding:.6rem .8rem;background:#fbf9f399;border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--fs-base);transition:border-color var(--dur-fast),box-shadow var(--dur-fast)}.input-line:focus{outline:none;border-color:var(--celadon-deep);box-shadow:0 0 0 3px #5f76601f}select.input-line{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--ink-soft) 50%),linear-gradient(135deg,var(--ink-soft) 50%,transparent 50%);background-position:calc(100% - 18px) 50%,calc(100% - 13px) 50%;background-size:5px 5px;background-repeat:no-repeat}.btn-divine{margin-top:var(--sp-4);width:100%;padding:1rem;background:var(--celadon-deep);color:var(--paper);font-family:var(--font-kai);font-size:1.15rem;letter-spacing:.5em;text-indent:.5em;border-radius:var(--r-sm);transition:background var(--dur-mid) var(--ease-out),transform var(--dur-mid);cursor:pointer}.btn-divine:hover{background:var(--cinnabar);transform:translateY(-1px)}.btn-divine:disabled{opacity:.5;cursor:wait}.btn-divine .small{display:block;font-size:var(--fs-xs);letter-spacing:.3em;font-family:var(--font-song);color:#fbf9f3bf;margin-top:.15rem}.altar-result{min-height:320px}.result-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:320px;gap:.8rem;color:var(--ink-faint);border:1px dashed var(--line);border-radius:var(--r-lg);padding:var(--sp-4);text-align:center}.result-placeholder .glyph{font-family:var(--font-zm);font-size:3.4rem;color:var(--rice)}.result-placeholder p{letter-spacing:.3em;font-size:var(--fs-sm)}.result-card{background:linear-gradient(175deg,var(--white-paper),var(--paper-deep));border:1px solid var(--line);border-radius:var(--r-lg);padding:var(--sp-4);margin-bottom:var(--sp-3);animation:viewIn .8s var(--ease-out) both}.result-card h3{font-family:var(--font-kai);font-size:1.1rem;letter-spacing:.2em;color:var(--celadon-deep);display:flex;align-items:center;gap:.6rem;padding-bottom:.8rem;margin-bottom:var(--sp-2);border-bottom:1px solid var(--line-soft)}.result-card h3:before{content:"◆";font-size:.8rem}.result-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--sp-2)}.result-cell{padding:.9rem;background:#fbf9f38c;border:1px solid var(--line-soft);border-radius:var(--r-sm)}.result-cell .k{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.25em}.result-cell .v{font-size:1.15rem;color:var(--ink);margin-top:.2rem;letter-spacing:.08em;font-weight:500}.result-cell .v.big{font-size:1.5rem;font-family:var(--font-kai)}.result-cell .v.hot{color:var(--cinnabar)}.result-cell .v.cool{color:var(--celadon-deep)}.result-text{color:var(--ink-soft);font-size:var(--fs-sm);line-height:2.2;letter-spacing:.04em;margin-top:.5rem}.report-view,.report-view p,.report-view li,.report-view h3,.result-text,.result-text p,.result-text li{font-family:system-ui,-apple-system,PingFang SC,Hiragino Sans GB,Microsoft YaHei,sans-serif}.result-text strong{color:var(--ink);font-weight:600}.result-text .tag-hot{color:var(--cinnabar);font-weight:500}.result-text .tag-cool{color:var(--celadon-deep);font-weight:500}.result-text p+p{margin-top:.6rem}.wx-fire{color:var(--cinnabar)}.wx-wood{color:#5e7a4e}.wx-water{color:#3e5f7a}.wx-metal{color:#8c7a4e}.wx-earth{color:#7a6a4a}.disclaimer{margin-top:var(--sp-5);display:flex;gap:1rem;align-items:flex-start;padding:var(--sp-3);background:var(--cinnabar-tint);border:1px solid rgba(165,64,45,.25);border-radius:var(--r-md);font-size:var(--fs-sm);color:#7a3b2c;line-height:2}.disclaimer .seal-mini{flex-shrink:0;font-family:var(--font-kai);color:var(--cinnabar);border:1px solid var(--cinnabar);padding:.3rem .4rem;font-size:.7rem;letter-spacing:.2em;border-radius:2px;margin-top:.15rem}.disclaimer strong{color:var(--cinnabar-deep)}.site-foot{border-top:1px solid var(--line-soft);padding:var(--sp-5) 0 var(--sp-4);margin-top:var(--sp-6)}.foot-inner{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);flex-wrap:wrap}.foot-brand{display:flex;align-items:center;gap:.8rem;font-family:var(--font-kai);letter-spacing:.3em;color:var(--ink-soft)}.foot-brand .seal{color:var(--cinnabar);border:1.5px solid var(--cinnabar);padding:.24rem .3rem;font-size:.66rem;border-radius:2px}.foot-meta{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.1em;line-height:2}.pill{display:inline-block;padding:.15rem .7rem;border:1px solid var(--line);border-radius:99px;font-size:var(--fs-xs);color:var(--ink-soft);letter-spacing:.15em;margin:.15rem .3rem .15rem 0;background:#fbf9f380}.pill.hot{color:var(--cinnabar);border-color:#a5402d59}.pill.cool{color:var(--celadon-deep);border-color:#5f766059}.center{text-align:center}.mt-1{margin-top:var(--sp-1)}.mt-2{margin-top:var(--sp-2)}.mt-3{margin-top:var(--sp-3)}.mt-4{margin-top:var(--sp-4)}.mt-5{margin-top:var(--sp-5)}.small{font-size:var(--fs-sm)}.tiny{font-size:var(--fs-xs)}.cinnabar{color:var(--cinnabar)}.celadon{color:var(--celadon-deep)}.muted{color:var(--ink-faint)}.fade-up{animation:fadeUp 1s var(--ease-out) both}@keyframes fadeUp{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}.delay-1{animation-delay:.12s}.delay-2{animation-delay:.24s}.delay-3{animation-delay:.36s}.separator{display:flex;align-items:center;gap:1rem;color:var(--ink-faint);font-size:var(--fs-xs);letter-spacing:.5em;margin:var(--sp-4) 0}.separator:before,.separator:after{content:"";flex:1;height:1px;background:var(--line-soft)}.back-link{display:inline-flex;align-items:center;gap:.5rem;font-size:var(--fs-sm);letter-spacing:.2em;color:var(--ink-faint);transition:color var(--dur-fast);margin-bottom:var(--sp-3)}.back-link:hover{color:var(--cinnabar)}@media(max-width:760px){.hero-vert{display:none}.art-card{min-height:200px}.brand .sub{display:none}.module-title-row{flex-direction:column;align-items:flex-start;gap:.6rem}.nav-links{gap:.6rem}}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}.coins{display:flex;gap:1rem;justify-content:center;flex-wrap:wrap}.coin{width:74px;height:74px;border-radius:50%;background:radial-gradient(circle at 32% 28%,#d8c9a0,#a8905e 60%,#8a7448);border:3px solid #6E5B38;box-shadow:inset 0 -6px 12px #3c2d1466,inset 0 4px 8px #fffadc80,0 6px 14px #37342c40;display:flex;align-items:center;justify-content:center;font-family:var(--font-kai);font-size:1.2rem;color:#5c4a26;position:relative}.coin:before{content:"〒";position:absolute;font-size:2rem;color:#5c4a26d9}.coin .face{position:relative;z-index:1;text-align:center;line-height:1.15;font-size:.68rem;letter-spacing:.05em}.yao-row{display:flex;align-items:center;gap:1rem;justify-content:center;padding:.55rem 0;border-bottom:1px dotted var(--line-soft)}.yao-label{width:3.2rem;font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.2em;text-align:right;font-variant-numeric:tabular-nums}.yao-glyph{font-size:2rem;line-height:1;letter-spacing:.2em}.yao-move{color:var(--cinnabar);font-size:var(--fs-xs);letter-spacing:.2em}.yao-move .dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--cinnabar);display:inline-block;margin-left:.3rem}.qimen-grid{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;max-width:560px;margin:0 auto;background:var(--paper-deep)}.qm-cell{aspect-ratio:1;border:1px solid var(--line-soft);padding:.7rem;position:relative;background:linear-gradient(160deg,#fbf9f3b3,#ede8d980)}.qm-cell .qm-name{font-family:var(--font-kai);font-size:1.05rem;color:var(--celadon-deep);letter-spacing:.15em}.qm-cell .qm-items{font-size:.72rem;color:var(--ink-soft);line-height:1.7;letter-spacing:.05em;margin-top:.3rem}.qm-cell .qm-star{font-size:.68rem;color:var(--ink-faint)}.ziwei-grid{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;max-width:640px;margin:0 auto}.zw-cell{border:1px solid var(--line-soft);padding:.55rem;min-height:96px;background:#fbf9f38c}.zw-cell.center{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.2rem;background:var(--paper-deep)}.zw-cell .zw-name{font-family:var(--font-kai);font-size:.8rem;color:var(--celadon-deep);letter-spacing:.1em;display:flex;justify-content:space-between}.zw-cell .zw-stars{font-size:.62rem;color:var(--ink-soft);line-height:1.8;letter-spacing:.04em}.liuren-stage{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:var(--sp-2)}.liuren-item{padding:1rem;background:#fbf9f38c;border:1px solid var(--line-soft);border-radius:var(--r-sm)}.liuren-item .k{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.3em}.liuren-item .v{font-size:1.2rem;margin-top:.3rem;letter-spacing:.2em;font-family:var(--font-kai)}.motes{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;overflow:hidden;z-index:0}.mote{position:absolute;font-family:var(--font-zm);color:var(--ink-faint);opacity:.2;letter-spacing:.1em;animation:moteFloat var(--mote-duration,10s) ease-in-out infinite;animation-delay:var(--mote-delay,0s);-webkit-user-select:none;-moz-user-select:none;user-select:none;text-shadow:0 1px 6px rgba(255,255,255,.5)}@keyframes moteFloat{0%,to{transform:translateY(0) translate(0);opacity:.16}50%{transform:translateY(-52px) translate(var(--mote-drift,-12px));opacity:.34}}#mountains{animation:inkDrift 90s ease-in-out infinite alternate}@keyframes inkDrift{0%{transform:translate(0) scale(1)}to{transform:translate(-22px) scale(1.03)}}.mist{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;overflow:hidden;z-index:0}.mist:before,.mist:after{content:"";position:absolute;top:12%;width:60vw;height:34vh;background:radial-gradient(ellipse at center,rgba(150,168,143,.13),transparent 65%);filter:blur(10px);animation:mistDrift 34s ease-in-out infinite alternate}.mist:before{left:-20vw;animation-delay:-8s}.mist:after{right:-22vw;top:26%;width:52vw;animation-delay:-20s}@keyframes mistDrift{0%{transform:translate(0)}to{transform:translate(9vw)}}.hero-glow{position:absolute;width:34vw;height:34vw;border-radius:50%;pointer-events:none;filter:blur(60px);opacity:.5;animation:glowBreath 8s ease-in-out infinite}.hero-glow--left{left:-8vw;top:-6vw;background:radial-gradient(circle,rgba(150,168,143,.22),transparent 70%)}.hero-glow--right{right:-10vw;bottom:-8vw;background:radial-gradient(circle,rgba(124,151,146,.18),transparent 70%);animation-delay:-4s}@keyframes glowBreath{0%,to{opacity:.35;transform:scale(1)}50%{opacity:.6;transform:scale(1.06)}}@media(prefers-reduced-motion:reduce){.mote,#mountains,.mist:before,.mist:after,.hero-glow{animation:none!important}}.tarot-stage{display:flex;justify-content:center;padding:var(--sp-4) 0;position:relative}.tarot-fan{display:flex;justify-content:center;gap:2px;transform:rotate(-4deg)}.tarot-card{width:96px;height:156px;flex-shrink:0;background:linear-gradient(160deg,#f7f2e4,#e6dcbe 70%,#d6c9a4);border:1px solid #C9B98F;border-radius:6px;box-shadow:0 8px 20px -10px #37342c66,inset 0 0 0 4px #c9b98f59;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:transform var(--dur-mid) var(--ease-out);position:relative}.tarot-card:before{content:"✦";font-size:1.4rem;color:#a58d5e}.tarot-card:hover{transform:translateY(-10px) rotate(0)}.tarot-card.picked{transform:translateY(-14px) rotate(0)}.tarot-card .card-inner{position:absolute;top:0;right:0;bottom:0;left:0;padding:.5rem;display:flex;flex-direction:column;align-items:center;justify-content:space-between;background:linear-gradient(170deg,#fdfaf1,#efe6cc);border-radius:5px;opacity:0;transition:opacity var(--dur-mid)}.tarot-card.revealed .card-inner{opacity:1}.card-inner .cn{font-family:var(--font-kai);font-size:1.05rem;color:var(--ink);letter-spacing:.1em}.card-inner .en{font-size:.52rem;color:var(--ink-faint);letter-spacing:.14em}.card-inner .sigil{font-size:1.6rem;color:var(--cinnabar)}.btn-seal:before{z-index:0}.btn-seal>*{position:relative;z-index:1}.btn-seal:hover>*{color:var(--paper)}.btn-seal.btn-ghost:hover>*{color:var(--paper)}#ink-vein{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:-1;overflow:hidden}#ink-vein .vein-lines{position:absolute;top:0;right:0;bottom:0;left:0;opacity:.05;background-image:repeating-linear-gradient(115deg,transparent 0 38px,rgba(55,52,44,.5) 38px 39px),repeating-linear-gradient(25deg,transparent 0 58px,rgba(55,52,44,.35) 58px 59px);animation:veinFlow 140s linear infinite}@keyframes veinFlow{0%{background-position:0 0,0 0}to{background-position:120px 60px,-80px 40px}}#ink-vein .vein-poem{position:absolute;right:1.6rem;top:50%;transform:translateY(-50%);writing-mode:vertical-rl;font-family:var(--font-kai);font-size:var(--fs-sm);letter-spacing:.9em;color:var(--ink-faint);opacity:.34;-webkit-user-select:none;-moz-user-select:none;user-select:none;animation:poemBreath 9s ease-in-out infinite;white-space:nowrap}@keyframes poemBreath{0%,to{opacity:.22}50%{opacity:.42}}#ink-vein .vein-seal{position:absolute;right:2.2rem;bottom:6.5rem;font-family:var(--font-kai);font-size:.6rem;letter-spacing:.2em;color:var(--cinnabar);opacity:.4;border:1px solid rgba(165,64,45,.5);padding:.3rem .34rem;border-radius:2px;animation:poemBreath 7s ease-in-out infinite;animation-delay:-3s}@media(max-width:860px){#ink-vein .vein-poem,#ink-vein .vein-seal{display:none}}.has-sub{position:relative}.sub-menu{position:absolute;top:calc(100% + .4rem);left:50%;transform:translate(-50%) translateY(-6px);min-width:9.5rem;padding:.5rem 0;background:var(--white-paper);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-paper);opacity:0;visibility:hidden;transition:all var(--dur-mid) var(--ease-out);z-index:60}.has-sub:hover .sub-menu,.has-sub:focus-within .sub-menu{opacity:1;visibility:visible;transform:translate(-50%) translateY(0)}.sub-menu a{display:block;padding:.42rem 1.2rem;font-size:var(--fs-sm);letter-spacing:.2em;color:var(--ink-soft);text-align:left;white-space:nowrap}.sub-menu a:hover{color:var(--cinnabar);background:var(--cinnabar-tint)}.song-select{position:relative;width:100%}.song-select .trigger{width:100%;padding:.6rem .8rem;display:flex;align-items:center;justify-content:space-between;gap:.6rem;background:#fbf9f399;border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--fs-base);color:var(--ink);cursor:pointer;text-align:left;transition:border-color var(--dur-fast),box-shadow var(--dur-fast)}.song-select .trigger:hover{border-color:var(--celadon)}.song-select.open .trigger{border-color:var(--celadon-deep);box-shadow:0 0 0 3px #5f76601f}.song-select .trigger:after{content:"";width:7px;height:7px;flex-shrink:0;border-right:1.5px solid var(--ink-soft);border-bottom:1.5px solid var(--ink-soft);transform:rotate(45deg) translateY(-2px);transition:transform var(--dur-fast)}.song-select.open .trigger:after{transform:rotate(225deg) translateY(1px)}.song-select .panel{position:absolute;top:calc(100% + .35rem);left:0;right:0;max-height:240px;overflow-y:auto;background:var(--white-paper);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-paper);z-index:70;padding:.35rem 0;animation:viewIn .25s var(--ease-out) both}.song-select .panel button{display:block;width:100%;padding:.5rem .9rem;text-align:left;font-size:var(--fs-sm);letter-spacing:.1em;color:var(--ink-soft);transition:background var(--dur-fast),color var(--dur-fast)}.song-select .panel button:hover{background:var(--celadon-tint);color:var(--ink)}.song-select .panel button.sel{color:var(--celadon-deep);font-weight:600}.song-select .panel button.sel:before{content:"◆ ";font-size:.62rem}.song-dialog-mask{position:fixed;top:0;right:0;bottom:0;left:0;background:#37342c59;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;z-index:200;animation:fadeUp .3s var(--ease-out) both}.song-dialog{width:min(420px,90vw);padding:var(--sp-4);background:linear-gradient(175deg,var(--white-paper),var(--paper-deep));border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-paper);animation:viewIn .35s var(--ease-out) both}.song-dialog .dlg-title{font-family:var(--font-kai);font-size:1.15rem;letter-spacing:.25em;color:var(--ink);display:flex;align-items:center;gap:.6rem;padding-bottom:var(--sp-2);border-bottom:1px solid var(--line-soft);margin-bottom:var(--sp-3)}.song-dialog .dlg-title:before{content:"❖";color:var(--cinnabar);font-size:.9rem}.song-dialog .dlg-body{color:var(--ink-soft);font-size:var(--fs-sm);line-height:2.1;letter-spacing:.05em}.song-dialog .dlg-actions{display:flex;gap:.8rem;justify-content:flex-end;margin-top:var(--sp-4)}.casting-glyph{animation:castSpin 2.4s var(--ease-ink) infinite}@keyframes castSpin{0%{transform:rotate(0) scale(1);opacity:.7}50%{transform:rotate(180deg) scale(1.08);opacity:1}to{transform:rotate(360deg) scale(1);opacity:.7}}.casting-ring{position:relative;width:4.4rem;height:4.4rem;border-radius:50%;margin:0 auto .8rem;border:1px dashed var(--celadon);animation:ringExpand 2.4s var(--ease-ink) infinite}@keyframes ringExpand{0%{transform:scale(.75);opacity:.5}50%{transform:scale(1);opacity:1}to{transform:scale(.75);opacity:.5}}.stagger>*{animation:fadeUp .7s var(--ease-out) both}.stagger>*:nth-child(1){animation-delay:.05s}.stagger>*:nth-child(2){animation-delay:.16s}.stagger>*:nth-child(3){animation-delay:.27s}.stagger>*:nth-child(4){animation-delay:.38s}.stagger>*:nth-child(5){animation-delay:.49s}.bazi-pan{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-2);max-width:640px;margin:0 auto}.bz-pillar{background:#fbf9f38c;border:1px solid var(--line-soft);border-radius:var(--r-sm);padding:.9rem .5rem;text-align:center;position:relative;overflow:hidden;transition:border-color var(--dur-mid),transform var(--dur-mid)}.bz-pillar:hover{border-color:var(--celadon);transform:translateY(-2px)}.bz-pillar .p-name{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.3em;margin-bottom:.5rem}.bz-pillar .p-gan{font-family:var(--font-kai);font-size:2rem;line-height:1.15;display:block}.bz-pillar .p-zhi{font-family:var(--font-kai);font-size:2rem;line-height:1.15;display:block;margin-top:.15rem}.bz-pillar .p-wx{font-size:var(--fs-xs);margin-top:.4rem;letter-spacing:.2em}.bz-pillar .p-shishen{font-size:var(--fs-xs);color:var(--celadon-deep);margin-top:.2rem;letter-spacing:.1em}.bz-pillar .p-nayin{font-size:.62rem;color:var(--ink-faint);margin-top:.3rem;letter-spacing:.08em;border-top:1px dotted var(--line-soft);padding-top:.35rem}.bz-pillar.day-pillar{border-color:var(--cinnabar);background:linear-gradient(175deg,#f3e3dc80,#fbf9f399);box-shadow:0 0 0 1px #a5402d26}.bz-pillar.day-pillar .p-name{color:var(--cinnabar)}.bz-pillar .p-zhu{position:absolute;top:.35rem;right:.5rem;font-size:.6rem;color:var(--ink-faint);letter-spacing:.15em}.zw-cell{transition:background var(--dur-mid),box-shadow var(--dur-mid)}.zw-cell.ming-cell{background:linear-gradient(175deg,#f3e3dc8c,#fbf9f380);box-shadow:inset 0 0 0 1px #a5402d40}.zw-cell .zw-stars .star-name{display:inline-block;padding:.06rem .22rem;border-radius:2px;margin-right:.14rem}.zw-cell .zw-stars .star-name.star-hot{color:var(--cinnabar);background:#a5402d14}.zw-cell .zw-stars .star-name.star-cool{color:var(--celadon-deep);background:#5f766014}.tarot-slot{display:flex;flex-direction:column;align-items:center;gap:.5rem}.tarot-slot .slot-label{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.25em;text-align:center;max-width:110px;line-height:1.6}.tarot-fan .tarot-card.face-down:after{content:"";position:absolute;top:6px;right:6px;bottom:6px;left:6px;border:1px solid rgba(165,92,62,.35);border-radius:3px}@media(prefers-reduced-motion:reduce){#ink-vein .vein-lines,#ink-vein .vein-poem,.casting-glyph,.casting-ring{animation:none!important}}.btn-seal{isolation:isolate}.btn-seal:before{z-index:-1;transform-origin:top}.btn-seal:hover{color:var(--paper)}.btn-seal .sb-label{position:relative;z-index:1}.btn-seal:hover .sb-label{color:var(--paper)}.arts-sub{padding:.6rem .4rem .8rem}.sub-group{margin-bottom:.3rem}.sub-group-name{font-size:.62rem;letter-spacing:.35em;color:var(--ink-faint);padding:.35rem .9rem .2rem;border-bottom:1px dotted var(--line-soft);margin-bottom:.2rem}.sub-group a{display:flex;align-items:baseline;gap:.55rem;font-size:var(--fs-sm);letter-spacing:.18em;color:var(--ink-soft);padding:.4rem .9rem;border-radius:var(--r-sm)}.sub-group a:hover{color:var(--cinnabar);background:var(--cinnabar-tint)}.sub-group .sub-glyph{font-family:var(--font-zm);color:var(--celadon-deep);font-size:.95rem}.sub-group .sub-poem{margin-left:auto;font-size:.6rem;color:var(--ink-faint);letter-spacing:.1em;white-space:nowrap}.user-menu .user-chip{display:flex;align-items:center;gap:.45rem;padding:.28rem .7rem .28rem .32rem;border:1px solid var(--line);border-radius:99px;background:#fbf9f3b3;cursor:pointer;transition:border-color var(--dur-fast),box-shadow var(--dur-fast)}.user-menu .user-chip:hover{border-color:var(--celadon);box-shadow:0 0 0 3px #5f76601a}.user-menu .user-seal{width:1.7rem;height:1.7rem;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--celadon-deep);color:var(--paper);font-family:var(--font-kai);font-size:.85rem;flex-shrink:0}.user-menu .user-name{font-size:var(--fs-sm);letter-spacing:.12em;color:var(--ink);max-width:5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.user-menu .user-caret{font-size:.62rem;color:var(--ink-faint)}.user-menu .sub-menu a{padding:.5rem 1.2rem}.side-anchor{position:fixed;left:1.4rem;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:.9rem;z-index:30}.side-anchor button{display:flex;align-items:center;gap:.5rem;font-size:var(--fs-xs);letter-spacing:.25em;color:var(--ink-faint);writing-mode:vertical-rl;transition:color var(--dur-fast);cursor:pointer;padding:.15rem 0}.side-anchor .dot{width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.5;flex-shrink:0}.side-anchor button:hover{color:var(--ink)}.side-anchor button.active{color:var(--cinnabar)}.side-anchor button.active .dot{opacity:1;box-shadow:0 0 0 3px #a5402d26}@media(max-width:1100px){.side-anchor{display:none}}.song-search .panel{width:100%}.song-search .ss-search{padding:.5rem .7rem .35rem}.song-search .ss-input{width:100%;padding:.42rem .6rem;background:#fbf9f3cc;border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--fs-sm)}.song-search .ss-input:focus{outline:none;border-color:var(--celadon-deep)}.song-search .ss-list{max-height:220px;overflow-y:auto;padding:.2rem 0}.song-search .ss-empty{padding:.8rem;text-align:center;color:var(--ink-faint);font-size:var(--fs-xs);letter-spacing:.2em}.song-select .trigger:after{display:none}.song-select .trigger .chev{flex-shrink:0;color:var(--ink-faint);transition:transform var(--dur-fast)}.song-select.open .trigger .chev{transform:rotate(180deg);color:var(--celadon-deep)}.song-select .trigger{line-height:1.6}.song-select .panel{left:0;right:0}.user-menu .sub-menu{right:0;left:auto;transform:none;min-width:8.5rem}.user-menu:hover .sub-menu{transform:none}.cal-input{position:relative}.cal-field{display:flex;gap:.4rem;align-items:center}.cal-field .input-line{flex:1}.cal-field input.cal-error{border-color:var(--cinnabar)}.cal-toggle{display:flex;align-items:center;justify-content:center;width:2.3rem;height:2.3rem;flex-shrink:0;border:1px solid var(--line);border-radius:var(--r-sm);background:#fbf9f399;color:var(--ink-soft);cursor:pointer;transition:border-color var(--dur-fast),color var(--dur-fast)}.cal-toggle:hover{border-color:var(--celadon);color:var(--celadon-deep)}.cal-panel{position:absolute;top:calc(100% + .35rem);left:0;z-index:70;width:min(290px,90vw);padding:.7rem;background:var(--white-paper);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-paper);animation:viewIn .25s var(--ease-out) both}.cal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.cal-title{font-family:var(--font-kai);font-size:.95rem;letter-spacing:.15em;color:var(--ink)}.cal-nav{display:flex;padding:.25rem;color:var(--ink-faint);cursor:pointer;border-radius:var(--r-sm)}.cal-nav:hover{color:var(--cinnabar);background:var(--cinnabar-tint)}.cal-week{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;font-size:.62rem;color:var(--ink-faint);letter-spacing:.1em;margin-bottom:.2rem}.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.cal-grid button{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:var(--fs-sm);color:var(--ink-soft);border-radius:var(--r-sm);cursor:pointer;transition:background var(--dur-fast),color var(--dur-fast)}.cal-grid button:hover{background:var(--celadon-tint);color:var(--ink)}.cal-grid button.sel{background:var(--celadon-deep);color:var(--paper);font-weight:600}.song-search .ss-custom{width:100%;padding:.6rem .9rem;text-align:center;font-size:var(--fs-sm);color:var(--celadon-deep);letter-spacing:.1em;cursor:pointer}.song-search .ss-custom:hover{background:var(--celadon-tint)}.song-select .trigger .chev,.song-search .trigger .chev{width:16px;height:16px;stroke-width:2.4}.nav-links .has-sub>a .chev-mini{width:14px;height:14px;stroke-width:2.2;vertical-align:-2px}.user-menu .user-caret{display:inline-flex;width:14px;height:14px}.user-menu .user-caret svg{width:14px;height:14px;stroke-width:2.2}.song-select .panel button,.song-select .trigger span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.song-select{min-width:0}.song-select .trigger{min-height:2.55rem}.song-select .panel{min-width:100%;width:-moz-max-content;width:max-content;max-width:16rem}.song-select .panel button{font-size:var(--fs-sm)}.altar-panel{position:sticky;top:84px;max-height:calc(100vh - 108px);overflow-y:auto;scrollbar-width:thin}.altar-panel::-webkit-scrollbar{width:4px}.altar-panel::-webkit-scrollbar-thumb{background:var(--celadon);border-radius:2px}@media(max-width:960px){.altar-panel{position:static;max-height:none;overflow:visible}}.altar-result{padding-bottom:var(--sp-2)}.bamboo-art{position:absolute;right:1rem;top:50%;transform:translateY(-50%);width:min(300px,30vw);pointer-events:none;opacity:.85}.bamboo-art svg{width:100%;height:auto;filter:drop-shadow(0 6px 18px rgba(95,118,96,.12))}.page-decor{position:relative}.page-decor .wrap{position:relative;z-index:1}@media(max-width:900px){.bamboo-art{display:none}}.nav-links a{white-space:nowrap}.nav-links .has-sub>a{display:inline-flex;align-items:center;gap:.28rem}.nav-links .has-sub>a .chev-mini{flex-shrink:0}.tarot-fan{transform:none;align-items:flex-start;gap:.9rem}.tarot-slot{width:104px}.tarot-slot .tarot-card{margin:0 auto}.tarot-slot .slot-label{min-height:2.6em;display:flex;align-items:flex-start;justify-content:center}.tarot-stage .tarot-fan.wrap-fan{max-width:640px}.center-actions{display:flex;gap:.8rem;justify-content:center;align-items:center;flex-wrap:wrap}.today-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);align-items:stretch}.today-grid .result-card{display:flex;flex-direction:column;margin-bottom:0;min-height:220px}.today-grid .result-card .result-text{flex:1}@media(max-width:860px){.today-grid{grid-template-columns:1fr}}.scroll-hint{transition:opacity .6s var(--ease-out),visibility .6s}.zw-palace-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:var(--sp-2);margin-top:var(--sp-3)}.zw-palace-cell{padding:.7rem .8rem;background:#fbf9f38c;border:1px solid var(--line-soft);border-radius:var(--r-sm);transition:border-color var(--dur-mid),background var(--dur-mid)}.zw-palace-cell:hover{border-color:var(--celadon)}.zw-palace-cell.is-ming{background:linear-gradient(175deg,#f3e3dc8c,#fbf9f380);border-color:#a5402d59}.zw-palace-cell.empty{opacity:.55}.zp-head{display:flex;align-items:baseline;gap:.4rem;border-bottom:1px dotted var(--line-soft);padding-bottom:.3rem;margin-bottom:.35rem}.zp-name{font-family:var(--font-kai);font-size:.92rem;color:var(--celadon-deep);letter-spacing:.12em}.zp-zhi{font-size:.66rem;color:var(--ink-faint)}.zp-ming{margin-left:auto;font-size:.6rem;color:var(--cinnabar);border:1px solid rgba(165,64,45,.4);padding:0 .3rem;border-radius:2px}.zp-stars{font-size:.72rem;color:var(--ink-soft);line-height:1.7;letter-spacing:.06em;min-height:1.7em}.zp-theme{font-size:.62rem;color:var(--ink-faint);letter-spacing:.15em;margin-top:.2rem}.hero{padding-bottom:calc(var(--sp-6) + 2.2rem)}.scroll-hint{position:absolute;bottom:1.1rem;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.55rem;font-size:var(--fs-xs);letter-spacing:.35em;color:var(--ink-faint);writing-mode:horizontal-tb;animation:floatHintX 3s var(--ease-ink) infinite;z-index:2}.scroll-hint svg{width:14px;height:14px;animation:hintBounce 1.6s ease-in-out infinite}@keyframes floatHintX{0%,to{transform:translate(-50%) translateY(0)}50%{transform:translate(-50%) translateY(7px)}}@keyframes hintBounce{0%,to{transform:translateY(0)}50%{transform:translateY(3px)}}.scroll-hint.hidden{opacity:0;visibility:hidden}.btn-row{display:flex;gap:.8rem;align-items:center;flex-wrap:wrap}.btn-row .btn-seal,.btn-row a.btn-seal{display:inline-flex;align-items:center;justify-content:center}.dlg-actions,.center-actions{align-items:center}.report-list{margin:0;padding-left:1.2rem;color:var(--ink-soft);font-size:var(--fs-sm);line-height:2.1;letter-spacing:.04em}.report-list li::marker{color:var(--celadon-deep)}.trait-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--sp-2)}.trait-cell{padding:.9rem;background:#fbf9f38c;border:1px solid var(--line-soft);border-radius:var(--r-sm);border-top:2px solid var(--celadon)}.trait-name{font-family:var(--font-kai);font-size:.98rem;color:var(--celadon-deep);letter-spacing:.15em;margin-bottom:.3rem}.trait-desc{font-size:var(--fs-sm);color:var(--ink-soft);line-height:1.9}.timeline{position:relative;padding-left:1.4rem}.timeline:before{content:"";position:absolute;left:.32rem;top:.3rem;bottom:.3rem;width:1px;background:var(--line)}.tl-item{position:relative;padding-bottom:var(--sp-3)}.tl-marker{position:absolute;left:-1.4rem;top:.25rem;width:.66rem;height:.66rem;border-radius:50%;background:var(--paper);border:2px solid var(--celadon-deep);display:flex;align-items:center;justify-content:center}.tl-item:first-child .tl-marker{background:var(--celadon-deep)}.tl-head{display:flex;align-items:baseline;gap:.6rem}.tl-head strong{font-family:var(--font-kai);font-size:.95rem;color:var(--ink);letter-spacing:.12em}.tl-age{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.15em}.tl-summary{font-size:var(--fs-sm);color:var(--ink-soft);line-height:2;margin-top:.2rem}.domain-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:var(--sp-2)}.domain-cell{padding:.9rem;background:#fbf9f38c;border:1px solid var(--line-soft);border-radius:var(--r-sm)}.domain-name{font-family:var(--font-kai);font-size:.9rem;color:var(--cinnabar);letter-spacing:.25em;margin-bottom:.4rem;border-bottom:1px dotted var(--line-soft);padding-bottom:.3rem}.domain-cell p{font-size:var(--fs-sm);color:var(--ink-soft);line-height:1.95;margin-top:.2rem}.fit-note{padding:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-3);background:var(--rice-tint);border:1px solid rgba(217,205,172,.6);border-left:3px solid var(--rice);border-radius:var(--r-md);font-size:var(--fs-sm);color:var(--ink-soft);line-height:2}.fit-note strong{color:var(--ink);letter-spacing:.15em}.fit-note .fit-suggest{color:var(--cinnabar);margin-top:.3rem}.fit-card.fit-partial{border-left-color:var(--rice)}.fit-card.fit-bad{border-left-color:var(--cinnabar)}.fit-card.fit-ok{border-left-color:var(--celadon)}.scroll-hint.inline-hint{position:static;transform:none;margin-top:2.2rem;writing-mode:horizontal-tb;animation:none}.scroll-hint.inline-hint svg{width:15px;height:15px;animation:hintBounce 1.6s ease-in-out infinite}.hero{padding-bottom:var(--sp-6)}.ai-streaming{border:1px dashed var(--celadon);border-radius:var(--r-md);padding:var(--sp-3);background:#e3e8dc40}.ai-stream-head{display:flex;align-items:center;gap:.6rem}.ai-spinner{width:15px;height:15px;border-radius:50%;flex-shrink:0;border:2px solid var(--celadon);border-top-color:transparent;animation:castSpin 1s linear infinite}.ai-stream-body{margin-top:.7rem;max-height:260px;overflow-y:auto;padding:.6rem .8rem;background:#fbf9f3b3;border-radius:var(--r-sm);scrollbar-width:thin}.ai-error{border:1px solid rgba(165,64,45,.3);border-radius:var(--r-md);padding:var(--sp-3);background:#f3e3dc4d}.shichen-chip{display:inline-flex;align-items:center;justify-content:center;padding:.4rem .9rem;flex-shrink:0;white-space:nowrap;background:var(--celadon-tint);border:1px solid var(--celadon);border-radius:var(--r-sm);font-size:var(--fs-xs);color:var(--celadon-deep);letter-spacing:.15em}.profile-card{display:flex;align-items:center;gap:1rem;cursor:pointer;padding:1rem 1.2rem;background:linear-gradient(175deg,var(--white-paper),var(--paper-deep));border:1px solid var(--line);border-radius:var(--r-md);transition:border-color var(--dur-mid),box-shadow var(--dur-mid),transform var(--dur-mid)}.profile-card:hover{border-color:var(--celadon);box-shadow:var(--shadow-paper);transform:translateY(-2px)}.profile-card.primary{border-left:3px solid var(--cinnabar)}.pc-badge{flex-shrink:0;width:2rem;height:2rem;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--cinnabar);color:var(--paper);font-family:var(--font-kai);font-size:.85rem}.pc-badge.sample{background:var(--celadon-deep)}.pc-body{flex:1;min-width:0}.pc-title{font-family:var(--font-kai);font-size:.98rem;color:var(--ink);letter-spacing:.12em;margin-bottom:.2rem}.pc-info{font-size:var(--fs-xs);color:var(--ink-faint);letter-spacing:.06em;line-height:1.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pc-action{flex-shrink:0;font-size:var(--fs-xs);color:var(--celadon-deep);letter-spacing:.2em}.module-hero.compact{padding:var(--sp-3) 0 var(--sp-2)}.mh-row{display:flex;align-items:baseline;gap:1.2rem;flex-wrap:wrap}.mh-row .back-link{margin-bottom:0;flex-shrink:0}.mh-row .module-title{margin-top:0;font-size:var(--fs-xl);display:flex;align-items:baseline;gap:.9rem;letter-spacing:.14em}.mh-row .module-title .cn{font-size:clamp(1.5rem,3vw,2.2rem);display:inline}.mh-row .mh-sub{font-family:var(--font-kai);font-size:var(--fs-sm);color:var(--ink-faint);letter-spacing:.25em;white-space:nowrap}.mh-row .mh-kicker{margin-left:auto;font-size:var(--fs-xs);letter-spacing:.3em;color:var(--ink-faint);white-space:nowrap}@media(max-width:640px){.mh-row .mh-kicker{white-space:normal;letter-spacing:.15em;line-height:1.6;max-width:16em;text-align:right}}.mh-intro{margin-top:.4rem;max-width:72ch}.mh-intro summary{cursor:pointer;font-size:var(--fs-xs);letter-spacing:.25em;color:var(--celadon-deep);list-style:none;display:inline-flex;align-items:center;gap:.4rem;-webkit-user-select:none;-moz-user-select:none;user-select:none}.mh-intro summary:before{content:"▸";font-size:.7rem;transition:transform var(--dur-fast)}.mh-intro[open] summary:before{transform:rotate(90deg)}.mh-intro p{font-size:var(--fs-sm);color:var(--ink-soft);line-height:2;margin-top:.5rem}
|
package/dist/index.html
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>观微 · 玄学问道 —— 九术参详,观微知著</title>
|
|
8
8
|
<meta name="description" content="以纸墨留白为骨,融四柱八字、紫微斗数、奇门遁甲、梅花易数、六爻、大六壬、小六壬、星盘、塔罗九术于一体。观微知著,以术问道。" />
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-DmdGzBy9.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="/assets/index-hLV3S-Cj.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guanwei",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
@@ -91,6 +91,6 @@
|
|
|
91
91
|
"url": "git+https://github.com/RubyCcll/guanwei.git"
|
|
92
92
|
},
|
|
93
93
|
"engines": {
|
|
94
|
-
"node": ">=
|
|
94
|
+
"node": ">=22.5.0"
|
|
95
95
|
}
|
|
96
96
|
}
|
package/scripts/release.sh
CHANGED
|
@@ -44,9 +44,24 @@ if ! grep -q "^## \[${NEW_VER}\]" CHANGELOG.md; then
|
|
|
44
44
|
read -rp " 已补好?回车继续: " _
|
|
45
45
|
fi
|
|
46
46
|
|
|
47
|
+
# 2.5 防 tag 错位:提交后 HEAD 的 package.json 版本号必须等于目标版本(否则 tag 会落到错误 commit)
|
|
48
|
+
echo "2.5️⃣ 校验 HEAD 版本号 === ${NEW_VER}(防 v1.1.0 式 tag 错位)..."
|
|
49
|
+
HEAD_VER="$(node -e "console.log(require('./package.json').version)")"
|
|
50
|
+
if [[ "$HEAD_VER" != "$NEW_VER" ]]; then
|
|
51
|
+
echo " ⚠️ 当前工作区 package.json 版本为 ${HEAD_VER},目标为 ${NEW_VER}"
|
|
52
|
+
echo " (若刚跑过步骤 1 的版本升级但尚未提交,继续即可;提交后 tag 前将再次校验)"
|
|
53
|
+
fi
|
|
54
|
+
|
|
47
55
|
echo "3️⃣ 提交 + 打 tag + 推送 git"
|
|
48
56
|
git add package.json package-lock.json server/package.json server/package-lock.json CHANGELOG.md
|
|
49
57
|
git commit -m "chore: 版本升级 ${NEW_VER}"
|
|
58
|
+
# 提交后再次校验:确保 tag 一定落在版本号已落地的 commit 上
|
|
59
|
+
HEAD_VER="$(node -e "console.log(require('./package.json').version)")"
|
|
60
|
+
if [[ "$HEAD_VER" != "$NEW_VER" ]]; then
|
|
61
|
+
echo " ❌ 提交后 HEAD 版本为 ${HEAD_VER},目标 ${NEW_VER}——版本号未落地,拒绝打 tag"
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
echo " ✅ 版本号一致,打 tag v${NEW_VER}"
|
|
50
65
|
git tag "v${NEW_VER}"
|
|
51
66
|
git push origin main
|
|
52
67
|
git push origin "v${NEW_VER}"
|
package/server/src/data/db.json
CHANGED
|
@@ -12075,6 +12075,216 @@
|
|
|
12075
12075
|
}
|
|
12076
12076
|
}
|
|
12077
12077
|
]
|
|
12078
|
+
},
|
|
12079
|
+
{
|
|
12080
|
+
"username": "联调7035",
|
|
12081
|
+
"passHash": "h7a11ca53",
|
|
12082
|
+
"createdAt": 1787462187089,
|
|
12083
|
+
"profile": {
|
|
12084
|
+
"birthDate": "1996-09-09",
|
|
12085
|
+
"birthHourIndex": 5,
|
|
12086
|
+
"gender": "男",
|
|
12087
|
+
"location": null
|
|
12088
|
+
},
|
|
12089
|
+
"samples": [],
|
|
12090
|
+
"records": [
|
|
12091
|
+
{
|
|
12092
|
+
"artId": "bazi",
|
|
12093
|
+
"createdAt": 1,
|
|
12094
|
+
"result": {
|
|
12095
|
+
"dayGZ": "壬申"
|
|
12096
|
+
}
|
|
12097
|
+
}
|
|
12098
|
+
]
|
|
12099
|
+
},
|
|
12100
|
+
{
|
|
12101
|
+
"username": "联调6052",
|
|
12102
|
+
"passHash": "h7a11ca53",
|
|
12103
|
+
"createdAt": 1787463476120,
|
|
12104
|
+
"profile": {
|
|
12105
|
+
"birthDate": "1996-09-09",
|
|
12106
|
+
"birthHourIndex": 5,
|
|
12107
|
+
"gender": "男",
|
|
12108
|
+
"location": null
|
|
12109
|
+
},
|
|
12110
|
+
"samples": [],
|
|
12111
|
+
"records": [
|
|
12112
|
+
{
|
|
12113
|
+
"artId": "bazi",
|
|
12114
|
+
"createdAt": 1,
|
|
12115
|
+
"result": {
|
|
12116
|
+
"dayGZ": "壬申"
|
|
12117
|
+
}
|
|
12118
|
+
}
|
|
12119
|
+
]
|
|
12120
|
+
},
|
|
12121
|
+
{
|
|
12122
|
+
"username": "联调4217",
|
|
12123
|
+
"passHash": "scrypt$5d770ea33c351c28afc8ee563d5712a2$7d00490154d70d549eba3a28d0a94a8cf2b4b23fa2fcde990200e850566993779a3854ed20858039690fb21a59ac814942947d95d4bad8f4ae328317d3e35137",
|
|
12124
|
+
"createdAt": 1787463514296,
|
|
12125
|
+
"profile": {
|
|
12126
|
+
"birthDate": "1996-09-09",
|
|
12127
|
+
"birthHourIndex": 5,
|
|
12128
|
+
"gender": "男",
|
|
12129
|
+
"location": null
|
|
12130
|
+
},
|
|
12131
|
+
"samples": [],
|
|
12132
|
+
"records": [
|
|
12133
|
+
{
|
|
12134
|
+
"artId": "bazi",
|
|
12135
|
+
"createdAt": 1,
|
|
12136
|
+
"result": {
|
|
12137
|
+
"dayGZ": "壬申"
|
|
12138
|
+
}
|
|
12139
|
+
}
|
|
12140
|
+
]
|
|
12141
|
+
},
|
|
12142
|
+
{
|
|
12143
|
+
"username": "联调3642",
|
|
12144
|
+
"passHash": "scrypt$e68ed2ead08e6da65060e6a7eaa44d4f$494bf83f166632db29cc3d85b334b5a7e64bec70949721cf3ef77c71b3e2b4f2b6a9abf6fe3bf8371ab506df450ead79ba01bda5005beaba47fdc269b9492c64",
|
|
12145
|
+
"createdAt": 1787464003708,
|
|
12146
|
+
"profile": {
|
|
12147
|
+
"birthDate": "1996-09-09",
|
|
12148
|
+
"birthHourIndex": 5,
|
|
12149
|
+
"gender": "男",
|
|
12150
|
+
"location": null
|
|
12151
|
+
},
|
|
12152
|
+
"samples": [],
|
|
12153
|
+
"records": [
|
|
12154
|
+
{
|
|
12155
|
+
"artId": "bazi",
|
|
12156
|
+
"createdAt": 1,
|
|
12157
|
+
"result": {
|
|
12158
|
+
"dayGZ": "壬申"
|
|
12159
|
+
}
|
|
12160
|
+
}
|
|
12161
|
+
]
|
|
12162
|
+
},
|
|
12163
|
+
{
|
|
12164
|
+
"username": "联调7150",
|
|
12165
|
+
"passHash": "scrypt$a691ebce2d89d81489e7209925cda9ed$4f9aaf62d714d4ce7bc8f1df2566461161bd8ad32bad88d23680534bede52d3a99efd28897ddbd75eedcf5eb08bc7b748020cc3d242acc8966c96d52fbf53c0d",
|
|
12166
|
+
"createdAt": 1787464067260,
|
|
12167
|
+
"profile": {
|
|
12168
|
+
"birthDate": "1996-09-09",
|
|
12169
|
+
"birthHourIndex": 5,
|
|
12170
|
+
"gender": "男",
|
|
12171
|
+
"location": null
|
|
12172
|
+
},
|
|
12173
|
+
"samples": [],
|
|
12174
|
+
"records": [
|
|
12175
|
+
{
|
|
12176
|
+
"artId": "bazi",
|
|
12177
|
+
"createdAt": 1,
|
|
12178
|
+
"result": {
|
|
12179
|
+
"dayGZ": "壬申"
|
|
12180
|
+
}
|
|
12181
|
+
}
|
|
12182
|
+
]
|
|
12183
|
+
},
|
|
12184
|
+
{
|
|
12185
|
+
"username": "联调7275",
|
|
12186
|
+
"passHash": "scrypt$5f91de795c181fe55ef00de36e94e7b8$5d3bd0f8d7097ea4fac56be03934a4a8638642c784f82d066d7b4b582669024c9d38ae82e19d7ab73781a7ab80130858b03a7490f979e04d7ed72294079571e6",
|
|
12187
|
+
"createdAt": 1787468567400,
|
|
12188
|
+
"profile": {
|
|
12189
|
+
"birthDate": "1996-09-09",
|
|
12190
|
+
"birthHourIndex": 5,
|
|
12191
|
+
"gender": "男",
|
|
12192
|
+
"location": null
|
|
12193
|
+
},
|
|
12194
|
+
"samples": [],
|
|
12195
|
+
"records": [
|
|
12196
|
+
{
|
|
12197
|
+
"artId": "bazi",
|
|
12198
|
+
"createdAt": 1,
|
|
12199
|
+
"result": {
|
|
12200
|
+
"dayGZ": "壬申"
|
|
12201
|
+
}
|
|
12202
|
+
}
|
|
12203
|
+
]
|
|
12204
|
+
},
|
|
12205
|
+
{
|
|
12206
|
+
"username": "联调9581",
|
|
12207
|
+
"passHash": "scrypt$16272308b8058bf6ccbe9d3a2ed81a4d$52177ab888d594c6da154cf421557b10d8ab4fd170ee975cbfa432309bdd41cd0fb07c1a58f7d239662e7d36d035db3ce62bc9c50aeb36c0355779a8cf38fac5",
|
|
12208
|
+
"createdAt": 1787468589681,
|
|
12209
|
+
"profile": {
|
|
12210
|
+
"birthDate": "1996-09-09",
|
|
12211
|
+
"birthHourIndex": 5,
|
|
12212
|
+
"gender": "男",
|
|
12213
|
+
"location": null
|
|
12214
|
+
},
|
|
12215
|
+
"samples": [],
|
|
12216
|
+
"records": [
|
|
12217
|
+
{
|
|
12218
|
+
"artId": "bazi",
|
|
12219
|
+
"createdAt": 1,
|
|
12220
|
+
"result": {
|
|
12221
|
+
"dayGZ": "壬申"
|
|
12222
|
+
}
|
|
12223
|
+
}
|
|
12224
|
+
]
|
|
12225
|
+
},
|
|
12226
|
+
{
|
|
12227
|
+
"username": "联调4768",
|
|
12228
|
+
"passHash": "scrypt$64a1be5442280ced0d57d277dfa9fa0b$edefd31c07e15fa626de318a85515d008228d6bf52c7ecf530a6afafc950ebc52fc329ed2970616d2a8c625449310e2aff70065048bbf2669813f54a093ce60e",
|
|
12229
|
+
"createdAt": 1787569754918,
|
|
12230
|
+
"profile": {
|
|
12231
|
+
"birthDate": "1996-09-09",
|
|
12232
|
+
"birthHourIndex": 5,
|
|
12233
|
+
"gender": "男",
|
|
12234
|
+
"location": null
|
|
12235
|
+
},
|
|
12236
|
+
"samples": [],
|
|
12237
|
+
"records": [
|
|
12238
|
+
{
|
|
12239
|
+
"artId": "bazi",
|
|
12240
|
+
"createdAt": 1,
|
|
12241
|
+
"result": {
|
|
12242
|
+
"dayGZ": "壬申"
|
|
12243
|
+
}
|
|
12244
|
+
}
|
|
12245
|
+
]
|
|
12246
|
+
},
|
|
12247
|
+
{
|
|
12248
|
+
"username": "联调8774",
|
|
12249
|
+
"passHash": "scrypt$7dd369064a2bc5127e968c5c3c79eab0$1bfb59fb2da2ca7565b1be2744acb56feb132c9c5b2d41a8e74e1e36378c871bac4786656c572295a7c3004948d1adc3d98d2f7110bf7c3b2045f68853693c79",
|
|
12250
|
+
"createdAt": 1787569838889,
|
|
12251
|
+
"profile": {
|
|
12252
|
+
"birthDate": "1996-09-09",
|
|
12253
|
+
"birthHourIndex": 5,
|
|
12254
|
+
"gender": "男",
|
|
12255
|
+
"location": null
|
|
12256
|
+
},
|
|
12257
|
+
"samples": [],
|
|
12258
|
+
"records": [
|
|
12259
|
+
{
|
|
12260
|
+
"artId": "bazi",
|
|
12261
|
+
"createdAt": 1,
|
|
12262
|
+
"result": {
|
|
12263
|
+
"dayGZ": "壬申"
|
|
12264
|
+
}
|
|
12265
|
+
}
|
|
12266
|
+
]
|
|
12267
|
+
},
|
|
12268
|
+
{
|
|
12269
|
+
"username": "联调9959",
|
|
12270
|
+
"passHash": "scrypt$fe9baf0e3feea172dd83fc4dd90bddee$11783ba55e4dc083fe442e185577c7e86d89cd8e51a2049f337045e60ab8a230acdceadcbca899aba2b900bc3e0a1c9ce6682190dd34a74133e330d3d83ba7fe",
|
|
12271
|
+
"createdAt": 1787569870216,
|
|
12272
|
+
"profile": {
|
|
12273
|
+
"birthDate": "1996-09-09",
|
|
12274
|
+
"birthHourIndex": 5,
|
|
12275
|
+
"gender": "男",
|
|
12276
|
+
"location": null
|
|
12277
|
+
},
|
|
12278
|
+
"samples": [],
|
|
12279
|
+
"records": [
|
|
12280
|
+
{
|
|
12281
|
+
"artId": "bazi",
|
|
12282
|
+
"createdAt": 1,
|
|
12283
|
+
"result": {
|
|
12284
|
+
"dayGZ": "壬申"
|
|
12285
|
+
}
|
|
12286
|
+
}
|
|
12287
|
+
]
|
|
12078
12288
|
}
|
|
12079
12289
|
]
|
|
12080
12290
|
}
|
|
Binary file
|
package/server/src/index.ts
CHANGED
|
@@ -3,15 +3,38 @@ import path from 'path';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
|
|
5
5
|
// 轻量 .env 加载(无第三方依赖)
|
|
6
|
+
// 支持:# 注释行、空行、KEY=value(可带双引号/单引号,内嵌转义 \n \t \" \\ 与注释剥离)
|
|
6
7
|
(() => {
|
|
7
8
|
try {
|
|
8
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
10
|
const envFile = path.join(__dirname, '..', '.env');
|
|
10
11
|
const content = fs.readFileSync(envFile, 'utf-8');
|
|
11
|
-
content.split(
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
14
|
-
|
|
12
|
+
for (const rawLine of content.split(/\r?\n/)) {
|
|
13
|
+
const line = rawLine.trim();
|
|
14
|
+
if (!line || line.startsWith('#')) continue; // 空行 / 注释行
|
|
15
|
+
const eq = line.indexOf('=');
|
|
16
|
+
if (eq <= 0) continue; // 无等号 → 跳过
|
|
17
|
+
const key = line.slice(0, eq).trim();
|
|
18
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue; // 非法键名 → 跳过
|
|
19
|
+
if (process.env[key] !== undefined) continue; // 环境变量优先,不覆盖
|
|
20
|
+
let val = line.slice(eq + 1).trim();
|
|
21
|
+
// 行内注释剥离(引号外的 # 视为注释起点)
|
|
22
|
+
if (!val.startsWith('"') && !val.startsWith("'")) {
|
|
23
|
+
const hash = val.indexOf(' #');
|
|
24
|
+
if (hash >= 0) val = val.slice(0, hash);
|
|
25
|
+
}
|
|
26
|
+
// 引号包裹 → 整体剥引号 + 处理转义(仅双引号内做转义展开)
|
|
27
|
+
const q = val.startsWith('"') ? '"' : val.startsWith("'") ? "'" : null;
|
|
28
|
+
if (q && val.endsWith(q) && val.length >= 2) {
|
|
29
|
+
val = val.slice(1, -1);
|
|
30
|
+
if (q === '"') {
|
|
31
|
+
val = val.replace(/\\n/g, '\n').replace(/\\t/g, '\t').replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
val = val.trim();
|
|
35
|
+
}
|
|
36
|
+
process.env[key] = val;
|
|
37
|
+
}
|
|
15
38
|
console.log('· 已加载 .env(LLM_PROVIDER=' + (process.env.LLM_PROVIDER || '未配置') + ')');
|
|
16
39
|
} catch { /* 无 .env 时忽略 */ }
|
|
17
40
|
})();
|
|
@@ -60,7 +83,7 @@ app.use('/api', hourRouter);
|
|
|
60
83
|
|
|
61
84
|
app.listen(PORT, () => {
|
|
62
85
|
console.log(`
|
|
63
|
-
🎴
|
|
86
|
+
🎴 观微后端服务已启动
|
|
64
87
|
|
|
65
88
|
地址: http://localhost:${PORT}
|
|
66
89
|
健康检查: http://localhost:${PORT}/api/health
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { tarotCards } from '
|
|
3
|
-
import { defaultSpreads } from '
|
|
4
|
-
import { drawCards, generateInterpretation } from '
|
|
5
|
-
import { analyzeQuestion } from '
|
|
2
|
+
import { tarotCards } from '../../../shared/core/data/tarotCards.js';
|
|
3
|
+
import { defaultSpreads } from '../../../shared/core/data/spreads.js';
|
|
4
|
+
import { drawCards, generateInterpretation } from '../../../shared/core/engine/tarotEngine.js';
|
|
5
|
+
import { analyzeQuestion } from '../../../shared/core/engine/semanticAnalyzer.js';
|
|
6
6
|
import type { QuestionCategory, Spread } from '../types/index.js';
|
|
7
7
|
|
|
8
8
|
const router = Router();
|
|
@@ -2,11 +2,18 @@
|
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import path from 'path';
|
|
5
|
+
import crypto from 'crypto';
|
|
5
6
|
import { fileURLToPath } from 'url';
|
|
6
7
|
|
|
7
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
9
|
const DB_FILE = path.join(__dirname, '..', 'data', 'db.json');
|
|
9
10
|
|
|
11
|
+
function scryptAsync(pw: string, salt: Buffer, keylen: number): Promise<Buffer> {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
crypto.scrypt(pw, salt, keylen, (err, key) => err ? reject(err) : resolve(key));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
interface DbUser {
|
|
11
18
|
username: string;
|
|
12
19
|
passHash: string;
|
|
@@ -28,11 +35,31 @@ function saveDb(db: Db): void {
|
|
|
28
35
|
fs.writeFileSync(DB_FILE, JSON.stringify(db, null, 2));
|
|
29
36
|
}
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
// 密码哈希:scrypt(带随机盐,防彩虹表/暴力破解)。
|
|
39
|
+
// 格式:scrypt$<saltHex>$<hashHex>;登录时对存量旧哈希(djb2 前缀 'h')做兼容校验,命中即升级为 scrypt。
|
|
40
|
+
const SCRYPT_N = 16384, SCRYPT_R = 8, SCRYPT_P = 1, SCRYPT_KEYLEN = 64;
|
|
41
|
+
|
|
42
|
+
async function hashPassword(pw: string): Promise<string> {
|
|
43
|
+
const salt = crypto.randomBytes(16);
|
|
44
|
+
const key = await scryptAsync(pw, salt, SCRYPT_KEYLEN);
|
|
45
|
+
return 'scrypt$' + salt.toString('hex') + '$' + key.toString('hex');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function verifyPassword(pw: string, stored: string): Promise<boolean> {
|
|
49
|
+
if (!stored) return false;
|
|
50
|
+
if (stored.startsWith('scrypt$')) {
|
|
51
|
+
const parts = stored.split('$');
|
|
52
|
+
if (parts.length !== 3) return false;
|
|
53
|
+
const salt = Buffer.from(parts[1], 'hex');
|
|
54
|
+
const expected = Buffer.from(parts[2], 'hex');
|
|
55
|
+
const key = await scryptAsync(pw, salt, expected.length);
|
|
56
|
+
return key.length === expected.length && crypto.timingSafeEqual(key, expected);
|
|
57
|
+
}
|
|
58
|
+
// 旧格式(djb2 变体):仅做兼容校验,命中后由调用方升级
|
|
32
59
|
let h = 5381;
|
|
33
60
|
const s = 'guanwei::' + pw;
|
|
34
61
|
for (let i = 0; i < s.length; i++) h = ((h << 5) + h + s.charCodeAt(i)) >>> 0;
|
|
35
|
-
return 'h' + h.toString(16);
|
|
62
|
+
return 'h' + h.toString(16) === stored;
|
|
36
63
|
}
|
|
37
64
|
|
|
38
65
|
const router = Router();
|
|
@@ -51,7 +78,7 @@ function upsertUser(username: string): DbUser {
|
|
|
51
78
|
return user;
|
|
52
79
|
}
|
|
53
80
|
|
|
54
|
-
router.post('/register', (req, res) => {
|
|
81
|
+
router.post('/register', async (req, res) => {
|
|
55
82
|
const { username, password, profile } = req.body;
|
|
56
83
|
const name = String(username || '').trim();
|
|
57
84
|
if (name.length < 2) return res.status(400).json({ error: '名号至少二字' });
|
|
@@ -61,25 +88,33 @@ router.post('/register', (req, res) => {
|
|
|
61
88
|
if (existing) {
|
|
62
89
|
// 云同步自动建档的占位账号(无密语)可被正式注册升级
|
|
63
90
|
if (!existing.passHash) {
|
|
64
|
-
existing.passHash =
|
|
91
|
+
existing.passHash = await hashPassword(String(password));
|
|
65
92
|
if (profile) existing.profile = { ...existing.profile, ...profile };
|
|
66
93
|
saveDb(db);
|
|
67
94
|
return res.json({ ok: true, upgraded: true, user: { username: existing.username, profile: existing.profile, samples: existing.samples } });
|
|
68
95
|
}
|
|
69
96
|
return res.status(400).json({ error: '此名号已有人用' });
|
|
70
97
|
}
|
|
71
|
-
const user: DbUser = { username: name, passHash:
|
|
98
|
+
const user: DbUser = { username: name, passHash: await hashPassword(String(password)), createdAt: Date.now(), profile: profile || {}, samples: [], records: [] };
|
|
72
99
|
db.users.push(user);
|
|
73
100
|
saveDb(db);
|
|
74
101
|
res.json({ ok: true, user: { username: user.username, profile: user.profile, samples: user.samples } });
|
|
75
102
|
});
|
|
76
103
|
|
|
77
104
|
// 登录
|
|
78
|
-
router.post('/login', (req, res) => {
|
|
105
|
+
router.post('/login', async (req, res) => {
|
|
79
106
|
const { username, password } = req.body;
|
|
80
107
|
const db = loadDb();
|
|
81
108
|
const user = db.users.find(u => u.username === String(username || '').trim());
|
|
82
|
-
if (!user
|
|
109
|
+
if (!user) return res.status(401).json({ error: '名号或密语未合' });
|
|
110
|
+
const ok = await verifyPassword(String(password || ''), user.passHash);
|
|
111
|
+
if (!ok) return res.status(401).json({ error: '名号或密语未合' });
|
|
112
|
+
// 旧哈希命中 → 升级为 scrypt 存储
|
|
113
|
+
if (user.passHash && !user.passHash.startsWith('scrypt$')) {
|
|
114
|
+
user.passHash = await hashPassword(String(password));
|
|
115
|
+
saveDb(db);
|
|
116
|
+
console.log(`[users] 密码哈希已升级为 scrypt: ${user.username}`);
|
|
117
|
+
}
|
|
83
118
|
res.json({ ok: true, user: { username: user.username, profile: user.profile, samples: user.samples } });
|
|
84
119
|
});
|
|
85
120
|
|
|
@@ -30,11 +30,7 @@ export function getDb(): DatabaseSync {
|
|
|
30
30
|
report_quality TEXT,
|
|
31
31
|
status TEXT NOT NULL DEFAULT 'divined',
|
|
32
32
|
created_at INTEGER NOT NULL,
|
|
33
|
-
updated_at INTEGER NOT NULL
|
|
34
|
-
plan_tier TEXT NOT NULL DEFAULT 'free',
|
|
35
|
-
quota_key TEXT,
|
|
36
|
-
quota_consumed INTEGER NOT NULL DEFAULT 1,
|
|
37
|
-
billing_meta TEXT
|
|
33
|
+
updated_at INTEGER NOT NULL
|
|
38
34
|
);
|
|
39
35
|
CREATE INDEX IF NOT EXISTS idx_div_user_time ON divinations(username, created_at DESC);
|
|
40
36
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// 提示词构建:9
|
|
1
|
+
// 提示词构建:9 术角色 persona(单轮注入,多 Agent 编排规划中)+ 两套报告 Schema 模板 + 档案注入
|
|
2
2
|
import type { ChatMessage } from './llmProvider';
|
|
3
3
|
import { agentOf } from './skills';
|
|
4
4
|
import { chartBrief } from './chartBrief';
|
|
@@ -89,7 +89,7 @@ function lifeEventsNote(profile?: unknown): string {
|
|
|
89
89
|
return '【命主已知人生经历 · 解读校准】以下为命主本人确认的人生事件,解读必须与此相符:\n' + clean.join('\n') + '\n要求:① 凡解读涉及这些年份(或与之相邻的大运流年)时,必须呼应对应事件(如该年患病手术,则论健康/流年时须呼应);② 严禁写出与已知经历相矛盾的内容(如已知 2024 年重大健康事件,就不得断言该年平安无事);③ 已知经历未覆盖的年份正常论命,不得为了呼应而编造具体事件细节。';
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
//
|
|
92
|
+
// 角色化解读版:9 术 persona(单轮注入)+ 档案 + 排盘结果 → 结构化解读报告
|
|
93
93
|
export function buildReportMessages(
|
|
94
94
|
artId: string,
|
|
95
95
|
question: string,
|