YVES28 commited on
Commit
e665390
·
verified ·
1 Parent(s): 0ed3ced

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. README.md +27 -5
  2. index.html +559 -18
README.md CHANGED
@@ -1,10 +1,32 @@
1
  ---
2
- title: Learningos
3
- emoji: 🏆
4
- colorFrom: green
5
- colorTo: yellow
6
  sdk: static
 
 
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: LearningOS V3.0 儿童学习能力 AI 操作系统
3
+ emoji: 🧠
4
+ colorFrom: blue
5
+ colorTo: blue
6
  sdk: static
7
+ sdk_version: static
8
+ app_file: index.html
9
  pinned: false
10
  ---
11
 
12
+ # LearningOS V3.0 — 儿童学习能力 AI 操作系统(原型演示 / Static)
13
+
14
+ 基于儿童神经发育科学 + AI 主动智能体 + 多模态行为分析 + 标准化学习能力评估体系 + 数字化干预,
15
+ 打造覆盖 **AI筛查—能力评估—智能解释—个性化干预—家庭管理—医疗协同—科研数据库** 的
16
+ 儿童学习脑健康数字生态平台原型。
17
+
18
+ > ⚠️ **合规与知识产权声明**
19
+ > 本 Space 为**演示原型**。其中全部测评题目、任务、常模与算法均为平台**自研原创演示内容**,
20
+ > **不包含、不引用任何受版权保护的国际量表(如 WIAT-III / WISC-V)原题或英文常模**。
21
+ > 国际经典量表仅作为平台在评估维度划分与结果解释架构上的**学术参考框架**。
22
+ > 本应用输出**不构成任何临床或教育诊断结论**。
23
+
24
+ ## 功能闭环
25
+ 1. **AI 筛查**:家长/教师 8 项行为问卷 → 风险预警
26
+ 2. **能力评估**:自研分测验(阅读/数学/语言/书写/执行功能)→ 组合分标准分
27
+ 3. **学习数字孪生**:10 维能力雷达 + 成长时间轴 + 6 个月趋势投影
28
+ 4. **智能解释 LearningGPT**:可解释地追溯底层认知因素,支持问答
29
+ 5. **个性化干预**:自适应干预引擎(ZPD 动态调参)
30
+ 6. **报告导出**:面向医/教/家三端的报告(可下载 .md / 打印 PDF)
31
+
32
+ 纯前端实现(HTML/CSS/JS + Plotly.js),无需后端,可静态托管。
index.html CHANGED
@@ -1,19 +1,560 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>LearningOS V3.0 · 儿童学习能力 AI 操作系统</title>
7
+ <script src="https://cdn.plot.ly/plotly-2.35.2.min.js" charset="utf-8"></script>
8
+ <style>
9
+ :root{
10
+ --blue:#2E86DE; --blue-d:#1f5fa8; --bg:#f5f8fc; --card:#fff;
11
+ --line:#e2e8f0; --text:#1f2d3d; --muted:#6b7a8d; --red:#E74C3C; --green:#27ae60;
12
+ }
13
+ *{box-sizing:border-box}
14
+ body{margin:0;font-family:-apple-system,"PingFang SC","Microsoft YaHei",Segoe UI,Roboto,sans-serif;
15
+ background:var(--bg);color:var(--text);line-height:1.6}
16
+ header{background:linear-gradient(135deg,var(--blue),var(--blue-d));color:#fff;padding:18px 24px}
17
+ header h1{margin:0;font-size:20px}
18
+ header p{margin:4px 0 0;font-size:13px;opacity:.9}
19
+ .tabs{display:flex;flex-wrap:wrap;background:#fff;border-bottom:1px solid var(--line)}
20
+ .tab{padding:12px 16px;cursor:pointer;font-size:14px;color:var(--muted);border-bottom:3px solid transparent}
21
+ .tab.active{color:var(--blue);border-bottom-color:var(--blue);font-weight:600}
22
+ .page{display:none;padding:20px 24px;max-width:980px;margin:0 auto}
23
+ .page.active{display:block}
24
+ .card{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:16px 18px;margin-bottom:16px;
25
+ box-shadow:0 1px 3px rgba(0,0,0,.04)}
26
+ h2{font-size:18px;margin:0 0 10px}
27
+ h3{font-size:15px;margin:14px 0 6px;color:var(--blue-d)}
28
+ label{display:block;font-size:13px;margin:10px 0 4px;color:var(--text)}
29
+ .row{display:flex;gap:14px;flex-wrap:wrap}
30
+ .row > *{flex:1;min-width:200px}
31
+ button{background:var(--blue);color:#fff;border:none;padding:10px 18px;border-radius:8px;
32
+ font-size:14px;cursor:pointer;margin-top:10px}
33
+ button:hover{background:var(--blue-d)}
34
+ button.ghost{background:#fff;color:var(--blue);border:1px solid var(--blue)}
35
+ .opt{display:flex;gap:8px;flex-wrap:wrap;margin:6px 0}
36
+ .opt label{margin:0;padding:6px 12px;border:1px solid var(--line);border-radius:20px;cursor:pointer;font-size:13px}
37
+ .opt input{display:none}
38
+ .opt input:checked + span{font-weight:600}
39
+ .opt label:has(input:checked){background:var(--blue);color:#fff;border-color:var(--blue)}
40
+ input[type=number],textarea,select{width:100%;padding:8px 10px;border:1px solid var(--line);border-radius:8px;font-size:14px}
41
+ .pill{display:inline-block;padding:2px 10px;border-radius:12px;font-size:12px;background:#eef4fb;color:var(--blue)}
42
+ .warn{color:var(--red);font-weight:600}
43
+ .ok{color:var(--green);font-weight:600}
44
+ .muted{color:var(--muted);font-size:13px}
45
+ .plot{width:100%;height:440px}
46
+ details{border:1px solid var(--line);border-radius:8px;padding:8px 12px;margin:10px 0;background:#fff}
47
+ summary{cursor:pointer;font-weight:600;font-size:14px}
48
+ .banner{background:#fff7e6;border:1px solid #ffe1a8;color:#8a5a00;padding:10px 14px;border-radius:8px;font-size:13px;margin-bottom:14px}
49
+ .qcard{border:1px solid var(--line);border-radius:8px;padding:10px 12px;margin:8px 0}
50
+ pre{white-space:pre-wrap;word-break:break-word;background:#f8fafc;border:1px solid var(--line);padding:12px;border-radius:8px;font-size:13px}
51
+ table{width:100%;border-collapse:collapse;font-size:13px;margin-top:6px}
52
+ th,td{border:1px solid var(--line);padding:6px 8px;text-align:left}
53
+ th{background:#f1f6fc}
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <header>
58
+ <h1>🧠 LearningOS V3.0 — 儿童学习能力 AI 操作系统(原型演示)</h1>
59
+ <p>AI筛查 · 能力评估 · 学习数字孪生 · 智能解释(LearningGPT) · 个性化干预 · 报告导出</p>
60
+ </header>
61
+
62
+ <div class="tabs" id="tabs">
63
+ <div class="tab active" data-t="home">🏠 概览</div>
64
+ <div class="tab" data-t="screen">🔍 AI 筛查</div>
65
+ <div class="tab" data-t="assess">📝 能力评估</div>
66
+ <div class="tab" data-t="twin">👤 学习数字孪生</div>
67
+ <div class="tab" data-t="explain">🤖 智能解释</div>
68
+ <div class="tab" data-t="intervene">🎯 个性化干预</div>
69
+ <div class="tab" data-t="report">📤 报告导出</div>
70
+ </div>
71
+
72
+ <!-- 概览 -->
73
+ <div class="page active" id="home">
74
+ <div class="banner">⚠️ 本应用为<b>演示原型</b>:题目、常模、算法均为平台自研原创演示内容,<b>不构成任何临床或教育诊断结论</b>。WIAT-III/WISC-V 仅作为维度设计的学术参考框架。</div>
75
+ <div class="card">
76
+ <h2>平台定位</h2>
77
+ <p>基于儿童神经发育科学 + AI 主动智能体 + 多模态行为分析 + 标准化学习能力评估体系 + 数字化干预,
78
+ 打造覆盖 <b>AI筛查—能力评估—智能解释—个性化干预—家庭管理—医疗协同—科研数据库</b> 的儿童学习脑健康数字生态平台。</p>
79
+ <h3>可体验的完整闭环</h3>
80
+ <ol>
81
+ <li><b>AI 筛查</b>:家长/教师 8 项行为问卷 → 风险预警</li>
82
+ <li><b>能力评估</b>:自研分测验(阅读/数学/语言/书写/执行功能)→ 组合分标准分</li>
83
+ <li><b>学习数字孪生</b>:10 维能力雷达 + 成长时间轴 + 6 个月趋势投影</li>
84
+ <li><b>智能解释 LearningGPT</b>:可解释地追溯底层认知因素,支持问答</li>
85
+ <li><b>个性化干预</b>:自适应干预引擎(ZPD 动态调参)</li>
86
+ <li><b>报告导出</b>:面向医/教/家三端的报告</li>
87
+ </ol>
88
+ <button id="demoBtn">🚀 一键加载演示档案(快速体验)</button>
89
+ <button class="ghost" id="resetBtn">🧹 清空并重新开始</button>
90
+ <p class="muted" id="homeStatus">尚未生成画像,请先完成筛查与评估,或点击一键演示。</p>
91
+ </div>
92
+ </div>
93
+
94
+ <!-- AI 筛查 -->
95
+ <div class="page" id="screen">
96
+ <div class="card">
97
+ <h2>AI 筛查(家长/教师版)</h2>
98
+ <p class="muted">请按孩子近一个月的真实表现评分:1=从不,5=总是</p>
99
+ <div id="screenItems"></div>
100
+ <button id="saveScreen">保存筛查结果</button>
101
+ <div id="screenOut" class="muted"></div>
102
+ </div>
103
+ </div>
104
+
105
+ <!-- 能力评估 -->
106
+ <div class="page" id="assess">
107
+ <div class="card">
108
+ <h2>能力评估(自研分测验)</h2>
109
+ <p class="muted">完成以下任务,系统将计算分测验 → 组合分标准分(均值100 / 标准差15)。</p>
110
+
111
+ <details open><summary>📖 阅读理解</summary>
112
+ <p id="rcPassage" class="muted"></p>
113
+ <div id="rcQuestions"></div>
114
+ </details>
115
+
116
+ <details open><summary>🔢 数学计算</summary>
117
+ <div id="mcQuestions"></div>
118
+ </details>
119
+
120
+ <details open><summary>🧩 数学应用</summary>
121
+ <div id="maQuestions"></div>
122
+ </details>
123
+
124
+ <details open><summary>🔤 词汇</summary>
125
+ <div id="vocQuestions"></div>
126
+ </details>
127
+
128
+ <details open><summary>✏️ 句子结构</summary>
129
+ <div id="sentQuestions"></div>
130
+ </details>
131
+
132
+ <details><summary>🔡 字词识读(自评)</summary>
133
+ <label>能流利识读以下 16 个字的数量:<span id="wrVal">12</span></label>
134
+ <input type="range" id="wordReading" min="0" max="16" value="12" />
135
+ <p class="muted" id="wrChars"></p>
136
+ </details>
137
+
138
+ <details><summary>✍️ 书写流畅(自评)</summary>
139
+ <label>抄写参考句耗时(秒)</label>
140
+ <input type="number" id="writtenSec" value="45" />
141
+ <p class="muted" id="wfPrompt"></p>
142
+ </details>
143
+
144
+ <details><summary>🟥 Stroop 抑制控制(自评)</summary>
145
+ <p class="muted" id="stroopDemo"></p>
146
+ <label>正确点击数 (0-10):<span id="scVal">8</span></label>
147
+ <input type="range" id="stroopCorrect" min="0" max="10" value="8" />
148
+ <label>平均反应时 (ms)</label>
149
+ <input type="number" id="stroopRt" value="900" />
150
+ </details>
151
+
152
+ <details><summary>🎯 CPT 持续注意(自评)</summary>
153
+ <p class="muted" id="cptDemo"></p>
154
+ <label>漏点 X 的次数 (0-4):<span id="coVal">1</span></label>
155
+ <input type="range" id="cptOmis" min="0" max="4" value="1" />
156
+ <label>误点非 X 的次数 (0-10):<span id="ccVal">1</span></label>
157
+ <input type="range" id="cptComm" min="0" max="10" value="1" />
158
+ </details>
159
+
160
+ <button id="submitAssess">📊 提交并生成能力画像</button>
161
+ <div id="assessOut"></div>
162
+ </div>
163
+ </div>
164
+
165
+ <!-- 数字孪生 -->
166
+ <div class="page" id="twin">
167
+ <div class="card">
168
+ <h2>学习数字孪生 (Learning Digital Twin)</h2>
169
+ <label><input type="checkbox" id="intervene" checked /> 已启动自适应干预(影响未来斜率)</label>
170
+ <div class="row">
171
+ <div><div id="radar" class="plot"></div></div>
172
+ <div><div id="timeline" class="plot"></div></div>
173
+ </div>
174
+ <button id="refreshTwin">🔄 刷新数字孪生</button>
175
+ <p class="muted" id="twinHint"></p>
176
+ </div>
177
+ </div>
178
+
179
+ <!-- 智能解释 -->
180
+ <div class="page" id="explain">
181
+ <div class="card">
182
+ <h2>智能解释 · LearningGPT(可解释 AI)</h2>
183
+ <div id="exSummary"></div>
184
+ <hr/>
185
+ <label>向 LearningGPT 提问(如:为什么孩子阅读理解下降?)</label>
186
+ <textarea id="exQuestion" rows="2" placeholder="输入您关心的问题…"></textarea>
187
+ <button id="askBtn">💡 获取解释</button>
188
+ <div id="exAnswer" style="margin-top:10px"></div>
189
+ </div>
190
+ </div>
191
+
192
+ <!-- 个性化干预 -->
193
+ <div class="page" id="intervene">
194
+ <div class="card">
195
+ <h2>个性化干预(自适应干预引擎)</h2>
196
+ <button id="ivBtn">🔄 生成/刷新干预方案</button>
197
+ <div id="ivPlan" style="margin-top:10px"></div>
198
+ </div>
199
+ </div>
200
+
201
+ <!-- 报告导出 -->
202
+ <div class="page" id="report">
203
+ <div class="card">
204
+ <h2>报告导出(医/教/家三端)</h2>
205
+ <button id="rpBtn">📄 生成报告</button>
206
+ <button class="ghost" id="rpDownload">⬇️ 下载报告 (.md)</button>
207
+ <button class="ghost" id="rpPrint">🖨️ 打印 / 另存 PDF</button>
208
+ <div id="rpMD" style="margin-top:12px"></div>
209
+ </div>
210
+ </div>
211
+
212
+ <script>
213
+ /* ===================== 数据与常模(自研原创演示) ===================== */
214
+ const SS_MEAN=100, SS_SD=15, SCALED_MEAN=10, SCALED_SD=3;
215
+ const AGE_BANDS=["4-6岁(幼小衔接)","7-9岁(小学低段)","10-12岁(小学高段)","13-15岁(初中)"];
216
+
217
+ const DIMENSIONS=[
218
+ ["info","基础信息",false],["neuro","神经发育",true],["cognitive","认知能力",true],
219
+ ["language","语言沟通",true],["reading","阅读素养",true],["math","数学计算",true],
220
+ ["executive","执行功能",true],["family","家庭环境",false],["school","学校表现",false],
221
+ ["ai_history","AI训练历史",false]
222
+ ];
223
+
224
+ const COMPOSITES={
225
+ reading:{name:"阅读素养 (Reading)",subtests:["word_reading","reading_comp"]},
226
+ math:{name:"数学能力 (Math)",subtests:["math_calc","math_applied"]},
227
+ written:{name:"书写表达 (Written)",subtests:["written_fluency"]},
228
+ oral:{name:"口头语言 (Oral Language)",subtests:["vocabulary","sentence"]},
229
+ executive:{name:"执行功能/注意力 (Executive)",subtests:["stroop","cpt"]}
230
+ };
231
+
232
+ const ITEMS={
233
+ reading_comp:{
234
+ passage:"小猫和小狗是好朋友。一天,它们一起去公园玩球。小狗把球抛得很高,小猫跳起来接住了。回家的路上,下起了小雨,它们躲进树叶下,开心地笑了。",
235
+ questions:[
236
+ {q:"谁把球抛得很高?",options:["小猫","小狗","小鸟"],answer:1},
237
+ {q:"它们为什么躲起来?",options:["累了","下雨了","天黑了"],answer:1},
238
+ {q:"这个故事主要讲什么?",options:["两个朋友玩耍","下雨天真好","接球比赛"],answer:0}
239
+ ]},
240
+ math_calc:{problems:[
241
+ {q:"12 + 7 = ?",answer:19},{q:"35 - 18 = ?",answer:17},{q:"6 × 8 = ?",answer:48},
242
+ {q:"72 ÷ 9 = ?",answer:8},{q:"45 + 29 = ?",answer:74}]},
243
+ math_applied:{questions:[
244
+ {q:"小明有8颗糖,妈妈又给了5颗,他现在有几颗?",options:["12","13","14"],answer:1},
245
+ {q:"一盒铅笔有12支,平均分给3个同学,每人几支?",options:["3","4","6"],answer:1}]},
246
+ vocabulary:{questions:[
247
+ {q:"「迅速」的意思最接近?",options:["快速","缓慢","安静"],answer:0},
248
+ {q:"「美丽」的意思最接近?",options:["好看","难看","高大"],answer:0},
249
+ {q:"「寒冷」的意思最接近?",options:["冷","热","甜"],answer:0},
250
+ {q:"「巨大」的意思最接近?",options:["大","小","轻"],answer:0}]},
251
+ sentence:{questions:[
252
+ {q:"下列哪个句子语序正确?",options:["我吃饭了","饭吃了我","吃了饭我"],answer:0},
253
+ {q:"「因为…所以…」使用正确的是?",options:["因为下雨,所以比赛取消","因为比赛取消,所以下雨","下雨因为,所以取消"],answer:0},
254
+ {q:"量词使用正确的是?",options:["一只猫","一条猫","一个猫"],answer:0}]},
255
+ word_reading:{chars:["蝴","蝶","螃","蟹","蘑","菇","蜻","蜓","鸬","鹚","鼹","鼠","蜈","蚣","蝙","蝠"]},
256
+ written_fluency:{prompt:"今天天气真好,我们去公园放风筝。",ref:16},
257
+ stroop:{stimuli:[["红","绿"],["蓝","红"],["绿","蓝"],["黄","红"],["红","蓝"],["绿","黄"],["蓝","绿"],["黄","绿"],["红","黄"],["绿","红"]],colors:["红","绿","蓝","黄"]},
258
+ cpt:{sequence:["K","J","F","X","L","S","D","X","P","A","X","M","R","T","X","B","N","X","C","V"],target:"X"}
259
+ };
260
+
261
+ const SCREENING=[
262
+ {q:"写作业时容易分心、走神",domain:"attention"},
263
+ {q:"阅读时经常跳行、漏字或重复读",domain:"reading"},
264
+ {q:"记不住多步口头指令",domain:"executive"},
265
+ {q:"完成功课极慢,明显超出同龄人",domain:"speed"},
266
+ {q:"数学计算常因粗心出错",domain:"math"},
267
+ {q:"字迹潦草、握笔姿势别扭",domain:"written"},
268
+ {q:"遇到挫折容易情绪波动",domain:"emotion"},
269
+ {q:"与同伴交往存在困难",domain:"social"}
270
+ ];
271
+ const SCREEN_DOMAINS=["attention","reading","executive","speed","math","written","emotion","social"];
272
+ const DOMAIN_CN={attention:"注意力",reading:"阅读",executive:"执行功能",speed:"加工速度",math:"数学",written:"书写",emotion:"情绪",social:"社交"};
273
+
274
+ const FACTOR_MAP={
275
+ reading:{low_word_high_comp:["工作记忆负载 (Working Memory Load)","字词识读尚可但阅读理解偏弱,提示信息保持与整合环节负载阶段性超载,而非识字能力本身倒退。"],
276
+ general:["阅读流畅性与解码效率","阅读相关分测验整体处于临界区间,建议优先排查视觉-语音转换与眼动回视模式。"]},
277
+ math:["计算策略表型与程序性知识","数学分测验偏低,常见瓶颈为计算策略固化与工作记忆在多位��算中的负载。"],
278
+ written:["精细动作与加工速度","书写流畅性偏弱,通常与手部精细动作协调及视觉-动作整合速度相关。"],
279
+ oral:["词汇提取与句法工作记忆","口头语言分测验反映词汇量与句法工作记忆,偏低时影响课堂理解与表达。"],
280
+ executive:["抑制控制与持续注意","执行功能/注意力分测验提示抑制控制或持续注意存在波动,易表现为分心与冲动。"]
281
+ };
282
+
283
+ const MODULE_CATALOG={
284
+ "工作记忆负载 (Working Memory Load)":{module:"工作记忆双任务训练",modality:"Child APP · 游戏化(数字广度+视觉矩阵)",freq:"每周 4 次",dur:"每次 12 分钟",goal:"提升信息保持与整合容量,缓解阅读理解加工瓶颈"},
285
+ "阅读流畅性与解码效率":{module:"眼动-语音整合训练",modality:"Child APP · 眼动追踪+跟读",freq:"每周 5 次",dur:"每次 10 分钟",goal:"降低回视概率、提升阅读流畅性"},
286
+ "计算策略表型与程序性知识":{module:"计算策略多样化训练",modality:"Child APP · 分步解题+策略提示",freq:"每周 4 次",dur:"每次 15 分钟",goal:"丰富计算策略、降低程序性错误"},
287
+ "精细动作与加工速度":{module:"书写自动化训练",modality:"Child APP · 压感笔迹+抄写节奏",freq:"每周 3 次",dur:"每次 10 分钟",goal:"提升书写速率与视觉-动作整合"},
288
+ "词汇提取与句法工作记忆":{module:"语义网络拓展训练",modality:"Child APP · 词汇联想+造句",freq:"每周 3 次",dur:"每次 12 分钟",goal:"扩充词汇量与句法工作记忆"},
289
+ "抑制控制与持续注意":{module:"Go/No-Go 与持续注意训练",modality:"Child APP · 反应抑制+信号检测",freq:"每周 5 次",dur:"每次 8 分钟",goal:"提升抑制控制与持续注意力时长"}
290
+ };
291
+
292
+ /* ===================== 工具函数 ===================== */
293
+ const clamp=(v,lo=1,hi=19)=>Math.max(lo,Math.min(hi,v));
294
+ function classifySS(ss){if(ss>=115)return"高于平均";if(ss>=85)return"平均水平";if(ss>=70)return"临界偏低";return"显著偏低";}
295
+ function scaledFromCorrect(correct,total){if(total<=0)return 10;const center=total/2;return clamp(Math.round(SCALED_MEAN+(correct-center)/center*SCALED_SD));}
296
+ function compositeSS(list){if(!list.length)return 100;const avg=list.reduce((a,b)=>a+b,0)/list.length;return Math.round(SS_MEAN+(avg-SCALED_MEAN)*(SS_SD/SCALED_SD));}
297
+ function readingFactor(profile){
298
+ const sub=profile.sub_scaled||{};const wr=sub.word_reading,rc=sub.reading_comp;const rd=FACTOR_MAP.reading;
299
+ if(wr!=null&&rc!=null&&wr-rc>=2)return rd.low_word_high_comp;return rd.general;
300
+ }
301
+ function factorOf(key,profile){
302
+ const f=FACTOR_MAP[key];
303
+ if(Array.isArray(f))return f;
304
+ if(f&&typeof f==="object")return readingFactor(profile);
305
+ return ["待评估因素",""];
306
+ }
307
+
308
+ /* ===================== 状态 ===================== */
309
+ let state={profile:null,screening:{},meta:{name:"待测儿童",age_band:AGE_BANDS[1]}};
310
+
311
+ /* ===================== 页面切换 ===================== */
312
+ document.querySelectorAll('.tab').forEach(t=>t.onclick=()=>{
313
+ document.querySelectorAll('.tab').forEach(x=>x.classList.remove('active'));
314
+ document.querySelectorAll('.page').forEach(x=>x.classList.remove('active'));
315
+ t.classList.add('active');
316
+ document.getElementById(t.dataset.t).classList.add('active');
317
+ if(t.dataset.t==="twin")refreshTwin();
318
+ });
319
+
320
+ /* ===================== 构建评估 UI ===================== */
321
+ function buildAssessUI(){
322
+ document.getElementById('rcPassage').textContent="短文:"+ITEMS.reading_comp.passage;
323
+ const rc=document.getElementById('rcQuestions');
324
+ ITEMS.reading_comp.questions.forEach((q,i)=>{
325
+ rc.appendChild(qCard(`阅读 ${i+1}. ${q.q}`,q.options,`rc${i}`));
326
+ });
327
+ const mc=document.getElementById('mcQuestions');
328
+ ITEMS.math_calc.problems.forEach((p,i)=>{
329
+ const d=document.createElement('div');d.className='qcard';
330
+ d.innerHTML=`<label>计算 ${i+1}. ${p.q}</label><input type="number" id="mc${i}" />`;
331
+ mc.appendChild(d);
332
+ });
333
+ const ma=document.getElementById('maQuestions');
334
+ ITEMS.math_applied.questions.forEach((q,i)=>ma.appendChild(qCard(`应用 ${i+1}. ${q.q}`,q.options,`ma${i}`)));
335
+ const voc=document.getElementById('vocQuestions');
336
+ ITEMS.vocabulary.questions.forEach((q,i)=>voc.appendChild(qCard(`词汇 ${i+1}. ${q.q}`,q.options,`voc${i}`)));
337
+ const sent=document.getElementById('sentQuestions');
338
+ ITEMS.sentence.questions.forEach((q,i)=>sent.appendChild(qCard(`句子 ${i+1}. ${q.q}`,q.options,`sent${i}`)));
339
+ document.getElementById('wrChars').textContent="演示字表:"+ITEMS.word_reading.chars.join("、");
340
+ document.getElementById('wfPrompt').textContent="参考句:"+ITEMS.written_fluency.prompt;
341
+ document.getElementById('stroopDemo').textContent="演示刺激(字≠墨色),需点击墨色:"+
342
+ ITEMS.stroop.stimuli.map(s=>`${s[0]}(墨:${s[1]})`).join("、");
343
+ document.getElementById('cptDemo').textContent="刺激序列(出现 X 需点击):"+ITEMS.cpt.sequence.join(" ");
344
+ // 滑块实时数值
345
+ bindRange('wordReading','wrVal');bindRange('stroopCorrect','scVal');
346
+ bindRange('cptOmis','coVal');bindRange('cptComm','ccVal');
347
+ }
348
+ function qCard(title,options,name){
349
+ const d=document.createElement('div');d.className='qcard';
350
+ let html=`<label>${title}</label><div class="opt">`;
351
+ options.forEach((o,i)=>{html+=`<label><input type="radio" name="${name}" value="${i}"><span>${o}</span></label>`;});
352
+ html+='</div>';d.innerHTML=html;return d;
353
+ }
354
+ function bindRange(id,lab){const el=document.getElementById(id);el.oninput=()=>document.getElementById(lab).textContent=el.value;}
355
+
356
+ /* ===================== 筛查 UI ===================== */
357
+ function buildScreenUI(){
358
+ const box=document.getElementById('screenItems');
359
+ SCREENING.forEach((it,i)=>{
360
+ const d=document.createElement('div');d.className='qcard';
361
+ let opts='';for(let v=1;v<=5;v++)opts+=`<label><input type="radio" name="scr${i}" value="${v}" ${v===3?'checked':''}><span>${v}</span></label>`;
362
+ d.innerHTML=`<label>${i+1}. ${it.q}</label><div class="opt">${opts}</div>`;
363
+ box.appendChild(d);
364
+ });
365
+ }
366
+
367
+ /* ===================== 评分 ===================== */
368
+ function getRadio(name){const el=document.querySelector(`input[name="${name}"]:checked`);return el?parseInt(el.value):null;}
369
+ function scoreScreening(){
370
+ const ratings={};
371
+ SCREENING.forEach((it,i)=>{const v=getRadio(`scr${i}`);if(v)ratings[it.domain]=ratings[it.domain]||[];if(v)ratings[it.domain].push(v);});
372
+ const out={};
373
+ SCREEN_DOMAINS.forEach(dom=>{const vals=ratings[dom]||[];const avg=vals.length?vals.reduce((a,b)=>a+b,0)/vals.length:0;out[dom]={avg:Math.round(avg*100)/100,flag:avg>=4};});
374
+ return out;
375
+ }
376
+ function buildProfile(responses){
377
+ const sub={};
378
+ // 阅读
379
+ const rcA=ITEMS.reading_comp.questions.map(q=>q.answer);
380
+ sub.reading_comp=scaledFromCorrect(rcA.filter((a,i)=>a===responses.rc[i]).length,rcA.length);
381
+ sub.word_reading=scaledFromCorrect(responses.wordReading,16);
382
+ // 数学
383
+ const mcA=ITEMS.math_calc.problems.map(p=>String(p.answer));
384
+ const mcCorrect=mcA.filter((a,i)=>String(responses.mc[i])===a).length;
385
+ let sCalc=scaledFromCorrect(mcCorrect,5);
386
+ const per=responses.mcTime/5;if(per<4)sCalc=clamp(sCalc+1);else if(per>9)sCalc=clamp(sCalc-1);
387
+ sub.math_calc=sCalc;
388
+ const maA=ITEMS.math_applied.questions.map(q=>q.answer);
389
+ sub.math_applied=scaledFromCorrect(maA.filter((a,i)=>a===responses.ma[i]).length,maA.length);
390
+ // 词汇/句子
391
+ const vocA=ITEMS.vocabulary.questions.map(q=>q.answer);
392
+ sub.vocabulary=scaledFromCorrect(vocA.filter((a,i)=>a===responses.voc[i]).length,vocA.length);
393
+ const sentA=ITEMS.sentence.questions.map(q=>q.answer);
394
+ sub.sentence=scaledFromCorrect(sentA.filter((a,i)=>a===responses.sent[i]).length,sentA.length);
395
+ // 书写
396
+ const elapsed=responses.writtenSec||45;const cpm=16/(elapsed/60);
397
+ sub.written_fluency=clamp(Math.round(SCALED_MEAN+(cpm-22)/22*SCALED_SD*3));
398
+ // Stroop / CPT
399
+ sub.stroop=clamp(13-responses.stroopErrors*2-(responses.stroopRt>1500?1:0));
400
+ sub.cpt=clamp(13-(responses.cptOmis+responses.cptComm)*2);
401
+
402
+ const composites={};
403
+ for(const k in COMPOSITES){const scales=COMPOSITES[k].subtests.map(s=>sub[s]);const ss=compositeSS(scales);
404
+ composites[k]={name:COMPOSITES[k].name,ss,level:classifySS(ss),subtests:Object.fromEntries(COMPOSITES[k].subtests.map(s=>[s,sub[s]]))};}
405
+ const dim={};DIMENSIONS.forEach(d=>dim[d[0]]=null);
406
+ dim.reading=composites.reading.ss;dim.math=composites.math.ss;dim.language=composites.oral.ss;
407
+ dim.executive=composites.executive.ss;dim.cognitive=Math.round((composites.written.ss+composites.executive.ss)/2);
408
+ dim.neuro=dim.cognitive;dim.family=72;dim.school=68;dim.ai_history=25;dim.info=100;
409
+ return {meta:state.meta,sub_scaled:sub,composites,dim_scores:dim,screening:state.screening};
410
+ }
411
+ function demoProfile(){
412
+ const base={reading:78,math:96,written:92,oral:104,executive:88};
413
+ const composites={};
414
+ for(const k in base){const ss=Math.max(60,Math.min(130,base[k]+(Math.random()*12-6)|0));composites[k]={name:COMPOSITES[k].name,ss,level:classifySS(ss)};}
415
+ const dim={};DIMENSIONS.forEach(d=>dim[d[0]]=null);
416
+ dim.reading=composites.reading.ss;dim.math=composites.math.ss;dim.language=composites.oral.ss;
417
+ dim.executive=composites.executive.ss;dim.cognitive=composites.written.ss;dim.neuro=composites.written.ss;
418
+ dim.family=72;dim.school=68;dim.ai_history=25;dim.info=100;
419
+ const scr={};SCREEN_DOMAINS.forEach(d=>{const avg=Math.round((2+Math.random()*2.6)*100)/100;scr[d]={avg,flag:avg>=4};});
420
+ scr.reading={avg:4.3,flag:true};scr.attention={avg:4.1,flag:true};
421
+ return {meta:{name:"演示儿童",age_band:AGE_BANDS[1],demo:true},sub_scaled:{},composites,dim_scores:dim,screening:scr};
422
+ }
423
+
424
+ /* ===================== 数字孪生 ===================== */
425
+ function ssToIndex(ss){return Math.max(0,Math.min(100,(ss-60)/(130-60)*100));}
426
+ function normalizedDims(p){const d=p.dim_scores||{};const o={};DIMENSIONS.forEach(([k,_,ab])=>{const v=d[k];if(v==null){o[k]=50;return;}o[k]=ab?ssToIndex(v):Math.max(0,Math.min(100,v));});return o;}
427
+ function refreshTwin(){
428
+ if(!state.profile||!state.profile.composites){document.getElementById('twinHint').textContent="请先生成能力画像(评估页或一键演示)。";return;}
429
+ const nd=normalizedDims(state.profile);
430
+ const labels=DIMENSIONS.map(d=>d[1]);const vals=DIMENSIONS.map(d=>nd[d[0]]);
431
+ Plotly.newPlot('radar',[{type:'scatterpolar',r:[...vals,vals[0]],theta:[...labels,labels[0]],fill:'toself',
432
+ name:'当前能力画像',line:{color:'#2E86DE'},fillcolor:'rgba(46,134,222,0.25)'},
433
+ {type:'scatterpolar',r:Array(labels.length+1).fill(65),theta:[...labels,labels[0]],name:'同龄参考',line:{color:'#888',dash:'dot'}}],
434
+ {polar:{radialaxis:{visible:true,range:[0,100]}},showlegend:true,height:430,
435
+ margin:{l:40,r:40,t:30,b:30},legend:{orientation:'h',y:-0.15}});
436
+ // 时间轴
437
+ const intervene=document.getElementById('intervene').checked;
438
+ const abilityKeys=DIMENSIONS.filter(d=>d[2]).map(d=>d[0]);
439
+ const base=abilityKeys.reduce((a,k)=>a+nd[k],0)/abilityKeys.length;
440
+ const scr=state.profile.screening||{};const readingFlag=scr.reading&&scr.reading.flag;
441
+ const aiHist=state.profile.dim_scores.ai_history||25;
442
+ let drift=0.15;if(aiHist>=40)drift+=0.25;if(readingFlag&&!intervene)drift-=0.35;if(intervene)drift+=0.45;
443
+ const past=[];let val=base;for(let i=12;i>0;i--){val+=0.2+(Math.random()*2-1)*1.2;past.push(Math.round(val*10)/10);}
444
+ const future=[];val=base;for(let i=1;i<=26;i++){val+=drift+(Math.random()*2-1)*0.6;future.push(Math.max(0,Math.min(100,val)));}
445
+ const weeks=[];for(let i=-12;i<0;i++)weeks.push(i);weeks.push(0);for(let i=1;i<=26;i++)weeks.push(i);
446
+ const series=[...past,base,...future];const upper=[],lower=[];
447
+ weeks.forEach(w=>{const band=w<=0?1.5:1.5+w*0.25;upper.push(Math.min(100,series[weeks.indexOf(w)]+band));lower.push(Math.max(0,series[weeks.indexOf(w)]-band));});
448
+ const traces=[
449
+ {x:weeks,y:upper,mode:'lines',line:{width:0},showlegend:false,hoverinfo:'skip'},
450
+ {x:weeks,y:lower,mode:'lines',line:{width:0},fill:'tonexty',fillcolor:'rgba(46,134,222,0.15)',name:'不确定区间',hoverinfo:'skip'}
451
+ ];
452
+ weeks.forEach((w,i)=>{const phase=w<0?'历史':(w===0?'当前':'预测');if(!traces.find(t=>t.name===phase))traces.push({x:[weeks[i]],y:[series[i]],mode:'lines+markers',name:phase,line:{color:{历史:'#95A5A6',当前:'#E74C3C',预测:'#2E86DE'}[phase],width:3},marker:{size:5}});else{const t=traces.find(t=>t.name===phase);t.x.push(weeks[i]);t.y.push(series[i]);}});
453
+ Plotly.newPlot('timeline',traces,{title:`学习成长时间轴 · 6个月预测斜率≈${drift>=0?'+':''}${drift.toFixed(2)}/周${intervene?' · 已启动自适应干预':' · 未干预'}`,
454
+ xaxis:{title:'周(负数=过去,正数=未来)'},yaxis:{title:'综合能力指数',range:[0,100]},height:430,
455
+ legend:{orientation:'h',y:-0.25},margin:{l:40,r:40,t:50,b:40}});
456
+ document.getElementById('twinHint').textContent="数字孪生已更新。";
457
+ }
458
+
459
+ /* ===================== 解释 ===================== */
460
+ function analyze(p){
461
+ const comps=p.composites||{};const scr=p.screening||{};const findings=[];const risks=[];const strengths=[];
462
+ for(const k in comps){const c=comps[k];if(c.ss<85){const[fname,fdesc]=factorOf(k,p);findings.push({dimension:c.name,ss:c.ss,level:c.level,factor:fname,detail:fdesc});risks.push(c.name);}else if(c.ss>=110)strengths.push(c.name);}
463
+ const flags=SCREEN_DOMAINS.filter(d=>scr[d]&&scr[d].flag).map(d=>DOMAIN_CN[d]);
464
+ const n=findings.length;
465
+ const overall=n===0?"当前各项能力处于平均水平或更高,未见明显偏低组合分,建议保持规律随访与能力拓展。":`共发现 ${n} 项能力组合分处于临界/显著偏低区间,主要关注:${risks.join("、")}。`;
466
+ let summary=`【总体结论】${overall}\n\n【能力组合分】\n`;
467
+ for(const k in comps)summary+=`· ${comps[k].name}:标准分 ${comps[k].ss}(${comps[k].level})\n`;
468
+ summary+=`\n【筛查预警】${flags.length?'存在:'+flags.join("、"):'无明显预警信号'}\n`;
469
+ summary+=`【相对优势】${strengths.length?strengths.join("、"):'暂未显现明显优势项'}`;
470
+ return {overall,findings,risks,strengths,flags,summary};
471
+ }
472
+ function explainQuestion(p,q){
473
+ if(!q)return "请输入您关心的问题。";
474
+ const a=analyze(p);const comps=p.composites||{};let target=null;
475
+ if(/阅读|理解|识字|读书/.test(q))target="reading";
476
+ else if(/数学|计算|应用题/.test(q))target="math";
477
+ else if(/写字|书写|字迹|握笔/.test(q))target="written";
478
+ else if(/注意|分心|专注|走神|冲动/.test(q))target="executive";
479
+ else if(/语言|表达|说话|词汇/.test(q))target="oral";
480
+ if(!target)return "我结合孩子的多模态能力画像为您解读:\n\n"+a.overall+"\n\n您可以就具体维度继续追问,例如:「为什么孩子阅读理解下降?」「数学计算总粗心怎么办?」「注意力为什么不持久?」";
481
+ const c=comps[target]||{};const[fname,fdesc]=factorOf(target,p);
482
+ return `关于您提到的「${COMPOSITES[target].name}」问题:\n\n系统追踪到该维度标准分为 **${c.ss}(${c.level})**。\n底层认知因素指向 **${fname}**:${fdesc}\n\n💡 建议:基于上述机制,可优先安排针对性的认知训练模块(如工作记忆/抑制控制/加工速度训练),并在家庭端降低任务时长、提升即时反馈频率,使孩子始终处于最优学习发展区(ZPD)。`;
483
+ }
484
+
485
+ /* ===================== 干预 ===================== */
486
+ function recommend(p){
487
+ const a=analyze(p);const aiHist=(p.dim_scores||{}).ai_history||25;const mods=[];const seen=new Set();
488
+ a.findings.forEach(f=>{const factor=f.factor;if(MODULE_CATALOG[factor]&&!seen.has(factor)){seen.add(factor);const m={...MODULE_CATALOG[factor]};
489
+ if(aiHist>=40)m.adapt="既往完成度高,初始难度上调一档,步进更快";
490
+ else if(aiHist<20)m.adapt="训练史较短,从基础档起步,强化即时反馈与激励";
491
+ else m.adapt="维持标准难度曲线,按实时表现动态变频";
492
+ m.target=f.dimension;mods.push(m);}});
493
+ if(!mods.length)mods.push({module:"能力拓展与预防训练",modality:"Child APP · 综合游戏化挑战",freq:"每周 2 次",dur:"每次 10 分钟",goal:"巩固优势、预防能力滑坡",adapt:"无显著风险,维持拓展性训练",target:"综合"});
494
+ return mods;
495
+ }
496
+ function planHTML(p){
497
+ const mods=recommend(p);let h='<h3>个性化干预方案(自适应)</h3>';
498
+ mods.forEach((m,i)=>{h+=`<p><b>${i+1}. ${m.module}</b> → 目标维度:${m.target}</p>
499
+ <p class="muted">干预形态:${m.modality} | 频次/时长:${m.freq} · ${m.dur}</p>
500
+ <p class="muted">训练目标:${m.goal}</p><p class="muted">自适应策略:${m.adapt}</p>`;});
501
+ return h;
502
+ }
503
+
504
+ /* ===================== 报告 ===================== */
505
+ function genMarkdown(p){
506
+ const meta=p.meta||{};const a=analyze(p);const d=p.dim_scores||{};const scr=p.screening||{};
507
+ let md=`# 儿童学习能力评估与干预报告(LearningOS V3.0 原型)\n\n`;
508
+ md+=`## 一、基本信息\n- 姓名/代号:${meta.name||'—'}\n- 年龄段:${meta.age_band||'—'}\n- 报告性质:演示原型(非诊断)\n\n`;
509
+ md+=`## 二、能力组合分(Subtests → Composites)\n| 组合分 | 标准分 | 等级 |\n| --- | --- | --- |\n`;
510
+ for(const k in p.composites)md+=`| ${p.composites[k].name} | ${p.composites[k].ss} | ${p.composites[k].level} |\n`;
511
+ md+=`\n## 三、学习数字孪生 · 十维画像\n| 维度 | 指数/分值 |\n| --- | --- |\n`;
512
+ DIMENSIONS.forEach(dm=>md+=`| ${dm[1]} | ${d[dm[0]]??'—'} |\n`);
513
+ md+=`\n## 四、AI 筛查预警\n| 维度 | 平均分(1-5) | 状态 |\n| --- | --- | --- |\n`;
514
+ SCREEN_DOMAINS.forEach(dom=>{const v=scr[dom];md+=`| ${DOMAIN_CN[dom]} | ${v?v.avg:'—'} | ${v&&v.flag?'⚠️ 预警':'正常'} |\n`;});
515
+ md+=`\n## 五、智能解释(LearningGPT)\n${a.summary}\n\n## 六、个性化干预方案\n`;
516
+ recommend(p).forEach((m,i)=>{md+=`### ${i+1}. ${m.module} → ${m.target}\n- 形态:${m.modality}\n- 频次/时长:${m.freq} · ${m.dur}\n- 目标:${m.goal}\n- 自适应:${m.adapt}\n`;});
517
+ md+=`\n---\n> ⚠️ 本报告显示范性原型输出,所用题目、常模与算法均为平台自研演示内容,不构成任何临床诊断或教育鉴定结论。WIAT-III/WISC-V 仅作为维度设计的学术参考框架。`;
518
+ return md;
519
+ }
520
+
521
+ /* ===================== 事件绑定 ===================== */
522
+ function syncAll(p,statusText){
523
+ if(!p||!p.composites){document.getElementById('twinHint').textContent="请先生成能力画像。";
524
+ document.getElementById('exSummary').textContent="请先生成能力画像。";document.getElementById('ivPlan').textContent="请先生成能力画像。";return;}
525
+ document.getElementById('exSummary').textContent=analyze(p).summary;
526
+ document.getElementById('ivPlan').innerHTML=planHTML(p);refreshTwin();
527
+ }
528
+ document.getElementById('demoBtn').onclick=()=>{state.profile=demoProfile();document.getElementById('homeStatus').textContent="✅ 已加载演示档案,请前往『学习数字孪生 / 智能解释 / 个性化干预 / 报告导出』查看。";syncAll(state.profile);};
529
+ document.getElementById('resetBtn').onclick=()=>{state.profile=null;document.getElementById('homeStatus').textContent="已清空,请重新评估。";syncAll(null);};
530
+ document.getElementById('saveScreen').onclick=()=>{state.screening=scoreScreening();let h='<h3>筛查结果</h3>';SCREEN_DOMAINS.forEach(d=>{const v=state.screening[d];h+=`<p>${DOMAIN_CN[d]}:均分 ${v.avg} → ${v.flag?'<span class="warn">⚠️ 预警</span>':'<span class="ok">✅ 正常</span>'}</p>`;});document.getElementById('screenOut').innerHTML=h;};
531
+ document.getElementById('submitAssess').onclick=()=>{
532
+ const responses={rc:ITEMS.reading_comp.questions.map((_,i)=>getRadio(`rc${i}`)),
533
+ mc:ITEMS.math_calc.problems.map((_,i)=>document.getElementById(`mc${i}`).value),mcTime:30,
534
+ ma:ITEMS.math_applied.questions.map((_,i)=>getRadio(`ma${i}`)),
535
+ voc:ITEMS.vocabulary.questions.map((_,i)=>getRadio(`voc${i}`)),
536
+ sent:ITEMS.sentence.questions.map((_,i)=>getRadio(`sent${i}`)),
537
+ wordReading:parseInt(document.getElementById('wordReading').value),
538
+ writtenSec:parseFloat(document.getElementById('writtenSec').value)||45,
539
+ stroopErrors:10-parseInt(document.getElementById('stroopCorrect').value),
540
+ stroopRt:parseFloat(document.getElementById('stroopRt').value)||900,
541
+ cptOmis:parseInt(document.getElementById('cptOmis').value),
542
+ cptComm:parseInt(document.getElementById('cptComm').value)};
543
+ state.profile=buildProfile(responses);
544
+ let h='<h3>✅ 能力画像已生成(组合分标准分,均值100/标准差15)</h3><ul>';
545
+ for(const k in state.profile.composites)h+=`<li><b>${state.profile.composites[k].name}</b>:${state.profile.composites[k].ss}(${state.profile.composites[k].level})</li>`;
546
+ h+='</ul>';document.getElementById('assessOut').innerHTML=h;syncAll(state.profile);
547
+ };
548
+ document.getElementById('refreshTwin').onclick=refreshTwin;
549
+ document.getElementById('askBtn').onclick=()=>{if(!state.profile){document.getElementById('exAnswer').textContent="请先生成能力画像再提问。";return;}document.getElementById('exAnswer').textContent=explainQuestion(state.profile,document.getElementById('exQuestion').value);};
550
+ document.getElementById('ivBtn').onclick=()=>{if(!state.profile){document.getElementById('ivPlan').textContent="请先生成能力画像。";return;}document.getElementById('ivPlan').innerHTML=planHTML(state.profile);};
551
+ let lastMD="";
552
+ document.getElementById('rpBtn').onclick=()=>{if(!state.profile){document.getElementById('rpMD').textContent="请先生成能力画像。";return;}lastMD=genMarkdown(state.profile);document.getElementById('rpMD').textContent=lastMD;};
553
+ document.getElementById('rpDownload').onclick=()=>{if(!lastMD)lastMD=genMarkdown(state.profile);const blob=new Blob([lastMD],{type:'text/markdown'});const a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='LearningOS_报告.md';a.click();};
554
+ document.getElementById('rpPrint').onclick=()=>{const w=window.open();w.document.write('<pre>'+genMarkdown(state.profile).replace(/</g,'&lt;')+'</pre>');w.document.close();w.print();};
555
+
556
+ /* ===================== 初始化 ===================== */
557
+ buildAssessUI();buildScreenUI();
558
+ </script>
559
+ </body>
560
  </html>