@topmindspace/tms-skills 0.1.3 → 0.1.5

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +6 -6
  3. package/package.json +2 -2
  4. package/top-ppt-html/README.md +5 -5
  5. package/top-ppt-html/SKILL.md +15 -12
  6. package/top-ppt-html/agents/openai.yaml +2 -2
  7. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +72 -27
  8. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +72 -27
  9. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +72 -27
  10. package/top-ppt-html/assets/pptx-export.js +69 -25
  11. package/top-ppt-html/assets/style-gallery.html +1 -1
  12. package/top-ppt-html/assets/templates/architecture.html +70 -25
  13. package/top-ppt-html/assets/templates/presentation.html +70 -25
  14. package/top-ppt-html/assets/templates/research.html +70 -25
  15. package/top-ppt-html/package-lock.json +2 -2
  16. package/top-ppt-html/package.json +2 -2
  17. package/top-ppt-html/references/default-surface.md +1 -1
  18. package/top-ppt-html/references/modes.md +1 -1
  19. package/top-ppt-html/references/playbook.md +9 -8
  20. package/top-ppt-html/references/pptx-export.md +1 -1
  21. package/top-ppt-html/references/presentation-craft.md +4 -3
  22. package/top-ppt-html/references/tech-design.md +1 -1
  23. package/top-ppt-html/scripts/audit_skill.py +11 -0
  24. package/top-ppt-html/scripts/build_pptx.js +24 -10
  25. package/top-ppt-html/scripts/cross_verify.py +1 -1
  26. package/top-ppt-html/scripts/negative_tests.py +65 -9
  27. package/top-ppt-html/scripts/quality_gate.py +30 -19
  28. package/top-ppt-html/scripts/render_from_model.py +1 -1
  29. package/top-ppt-html/scripts/sync_runtime.py +10 -4
  30. package/top-ppt-html/scripts/test_feedback_gates.py +180 -0
  31. package/top-ppt-html/scripts/validate_pptx.py +157 -0
  32. package/top-ppt-html/scripts/validate_report.py +31 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,42 @@
1
+ ## 0.1.5 — 2026-09-25
2
+
3
+ ### top-ppt-html · defect close-out
4
+
5
+ - **P0 D1**:环图右栏可见标题去掉作者约束「禁止叠在弧上」→ 读者向「构成明细」。
6
+ - **P0 D2**:`sync_runtime.py` 注入 `/* __TOPPPT_RUNTIME_SHA__:<16hex> */`(源 = `assets/pptx-export.js`);`validate_report` 缺戳/漂移 FAIL;负例 N19。
7
+ - **P1 D3**:`cross_verify.NUMERIC_TOKEN` 增补 YB|ZB|EB|PB 与 kWh|Gbps。
8
+ - **P1 D4**:CI 轻量生成 `dist/regression` 样张 + `python-pptx`,使 N4/N5/N7 真正跑通(非全量 regression)。
9
+ - **P2**:package-lock 对齐 0.1.5;README/PUBLISHING 2.x 弃用改为事实陈述;`deprecate-npm-2x.sh` 精简为 `@2.x` one-shot + verify;双版本口径(包 semver vs schema `0.1`)写入 SKILL/tech-design。
10
+ - **术语**:全库「甲板」→ 演示文稿/样页等(保留英文 trigger `deck`)。
11
+
12
+ ### Installer
13
+
14
+ - `@topmindspace/tms-skills` → **0.1.5**(整仓同 tag)。
15
+
16
+ ## 0.1.4 — 2026-09-25
17
+
18
+ ### top-ppt-html · craft + quality + docs + perf close-out
19
+
20
+ - **P0 效率 / agent 工作流**(usage-feedback):
21
+ - 默认交付 **仅 B 通道 PPTX**(`build_pptx.js`);A 通道(`pptx-export.js` / `gen_channel_a.js`)限预览与 `cross_verify` / 回归。
22
+ - `extract_snippet` 强制 + **整读大 L2 = FAIL / 不合格**(SKILL + playbook);`audit_skill` 新增对应门禁。
23
+ - `quality_gate` 对互不依赖子进程(HTML strict / PPTX strict / evals)**并行**执行。
24
+ - Fast / 轻量路径强化 **HTML-first**;PPTX 显式 opt-in(用户要 PPT 或交付含 PPTX)。
25
+ - **未削弱**红线:反截断、图表多样性(`minTypes.presentation=4` / registry)、Mode A 大气正式工艺、Gate 0 语义。
26
+ - **质量 / 规范**:对齐 SKILL frontmatter、双 `package.json`、README 钉版本、PUBLISHING、安装说明;跑通 check / audit / feedback gates。
27
+ - **docs 工艺改写**:定位强调优雅·美观·大气·演讲/正式场合;版式/排版/色彩/内容组织 + 质检与高保真导出;L0 仍瘦、L2 按需。
28
+ - **此前 #7(validator / engine)**:`shape_bounds` 读 `p:xfrm`、`TEXT_OVERFLOW_VERTICAL`、`ANNOTATION_BAND_OVERLAP`、`FONT_SIZE_NOT_SNAPPED`、多系列 vbar、streamgraph 图例内收、image caption `capYImg`——随本版一并发布。
29
+
30
+ ### Installer
31
+
32
+ - `@topmindspace/tms-skills` → **0.1.4**(整仓同 tag)。
33
+
34
+ ### Intentional leftovers
35
+
36
+ - 不引入 Claude-only `when_to_use` / 跨端风险 `allowed-tools`(同 0.1.3)。
37
+ - `skills-ref validate` 仍为可选,非发布硬依赖。
38
+ - layout-constants / model-schema 事实源版本线仍为 `0.1`(patch 记在 package / metadata)。
39
+
1
40
  ## 0.1.3 — 2026-09-24
2
41
 
3
42
  ### top-ppt-html · QA close-out + docs
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # tms-skills
2
2
 
3
- **TopMindspace 智能体技能 monorepo** — 可安装的智能体技能集合,当前包含 **top-ppt-html**。
3
+ **TopMindspace 智能体技能 monorepo** — 可安装的智能体技能集合,当前包含 **top-ppt-html**(优雅、大气、正式场合演讲/汇报演示文稿)。
4
4
 
5
5
  让 idea 飞,好想法被看见。
6
6
 
@@ -8,9 +8,9 @@
8
8
 
9
9
  | 技能 | 版本 | 做什么 |
10
10
  |------|------|--------|
11
- | [`top-ppt-html`](./top-ppt-html/) | 0.1.3 | 报告 / 演示 / 信息架构图:单文件 HTML + 版式保真的可编辑 16:9 PPTX |
11
+ | [`top-ppt-html`](./top-ppt-html/) | 0.1.5 | 优雅大气的正式场合演讲/汇报演示文稿:单文件 HTML + 版式保真可编辑 16:9 PPTX |
12
12
 
13
- 安装器包 [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) 亦为 **0.1.3**(整仓发版:安装器与当前技能同 tag;未来多技能仍可各自演进,默认随仓库 release)。
13
+ 安装器包 [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) 亦为 **0.1.5**(整仓发版:安装器与当前技能同 tag;未来多技能仍可各自演进,默认随仓库 release)。
14
14
 
15
15
  更多技能以仓库根目录下的技能目录加入(每个目录含 `SKILL.md`)。
16
16
 
@@ -19,9 +19,9 @@
19
19
  两条通道,装出来同一套技能。**npm = 钉版本快照**;**GitHub = 跟仓库 HEAD**。
20
20
 
21
21
 
22
- > **警告 / Warning**:不要安装 `@topmindspace/tms-skills@^2`。npm 上残留的 **2.0.0–2.1.1** 是仓库重置前的过时线;当前线是 **0.1.x**(`latest` 亦指向 0.1.x)。维护者登录 npm 后可运行 `scripts/deprecate-npm-2x.sh` 标记弃用。
22
+ > **警告 / Warning**:不要安装 `@topmindspace/tms-skills@^2`。npm 上的 **2.0.0–2.1.1** 已弃用(仓库重置前的过时线);当前线是 **0.1.x**(`latest` 指向 0.1.x)。请安装 `@topmindspace/tms-skills@0.1.x`。
23
23
  >
24
- > Do **not** install `^2`. Versions 2.0.0–2.1.1 are obsolete after the repo reset; use **0.1.x**. Maintainers with npm auth should run `scripts/deprecate-npm-2x.sh`.
24
+ > Do **not** install `^2`. Versions **2.0.0–2.1.1 are deprecated**; use **0.1.x** (`latest` tracks 0.1.x).
25
25
 
26
26
 
27
27
  ### npm(推荐)
@@ -30,7 +30,7 @@
30
30
  npx @topmindspace/tms-skills list
31
31
  npx @topmindspace/tms-skills install top-ppt-html
32
32
  npx @topmindspace/tms-skills install top-ppt-html --to ./.claude/skills
33
- npx @topmindspace/tms-skills@0.1.3 install top-ppt-html # 钉版本
33
+ npx @topmindspace/tms-skills@0.1.5 install top-ppt-html # 钉版本
34
34
  ```
35
35
 
36
36
  ### GitHub 直装
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topmindspace/tms-skills",
3
- "version": "0.1.3",
4
- "description": "TopMindspace 智能体技能 monorepo — 通过 npm / GitHub npx 安装技能(top-ppt-html 等)。",
3
+ "version": "0.1.5",
4
+ "description": "TopMindspace 智能体技能 monorepo — 通过 npm / GitHub npx 安装技能(top-ppt-html:优雅大气正式场合演讲/汇报演示文稿等)。",
5
5
  "license": "MIT",
6
6
  "author": "TopMindspace",
7
7
  "repository": {
@@ -1,9 +1,9 @@
1
1
  # TopPPT HTML
2
2
 
3
- **让 idea 飞,好想法被看见。** 一套面向 AI 智能体的商务报告生成技能:把想法、调研、分析、架构方案,变成**专业级的 HTML 报告 + 版式保真的可编辑 PPTX**。
3
+ **让 idea 飞,好想法被看见。** 面向**演讲与正式场合**的高品质演示文稿技能:把主张、调研、分析、架构方案,生成为**优雅、美观、大气**的可翻页 HTML + **版式保真可编辑 PPTX**。核心工艺是版式、排版、色彩与内容组织——克制图标/图表配文,而非 gadget 堆砌或咨询 dump 默认。
4
4
 
5
5
  - 技能标识:`top-ppt-html`(安装/打包目录名与此一致);品牌名:**TopPPT HTML**
6
- - 版本:**v0.1.3**(与 `@topmindspace/tms-skills@0.1.3` 同 tag)
6
+ - 版本:**v0.1.5**(与 `@topmindspace/tms-skills@0.1.5` 同 tag)
7
7
  - **智能体入口**:`SKILL.md` → `references/playbook.md`(L1)→ L2 按需
8
8
  - **人类维护者**:本 README(安装 / 命令 / 目录);勿把本文件当生成规范
9
9
 
@@ -78,11 +78,11 @@ npm install # 依 package.json 安装 pptxgenjs(^4)
78
78
  ```
79
79
  听意图 → Gate 0 参考图 → 六项问询 → 路径判定(轻量默认 / 完整走 outline-design.md 七步法)
80
80
  → scaffold_report.py 起骨架(勿整读/复制模板)→ **只填 window.REPORT_MODEL** → `render_from_model.py --inplace`
81
- → validate_report.py --strict 全 PASS → 交付
82
- →(含 PPTX 时)extract_model.py → build_pptx.js --model → validate_pptx.py --strict 0/0
81
+ → validate_report.py --strict 全 PASS → 交付(默认 HTML)
82
+ →(用户要 PPTX 时 · **仅 B 通道**)extract_model.py → build_pptx.js --model → validate_pptx.py --strict 0/0
83
83
  ```
84
84
 
85
- **渐进式披露三档**(详见 `SKILL.md` 阶段路由表):`L0` = `SKILL.md`(路由 + 门禁 + 铁律,加载即用);`L1` = `references/playbook.md`(**唯一常读入口**:模式契约 / 页型选型 / 组合版式矩阵 / 图表选型决策树 / 内容规则 / 配色 / 校验命令);`L2` = 深度规范,**只在命中条件时读、读完即停**;**取码优先 `extract_snippet.py`**(`components.md`/`charts.md` 为逻辑索引,自动路由到 `components-atoms` / `layouts-*` / `charts-basic` / `charts-extended` / `charts-discipline` 等物理文件)。
85
+ **渐进式披露三档**(详见 `SKILL.md` 阶段路由表):`L0` = `SKILL.md`(路由 + 门禁 + 铁律,加载即用);`L1` = `references/playbook.md`(**唯一常读入口**:模式契约 / 页型选型 / 组合版式矩阵 / 图表选型决策树 / 内容规则 / 配色 / 校验命令);`L2` = 深度规范,**只在命中条件时读、读完即停**;**取码必须 `extract_snippet.py`**(整读大 L2 = FAIL);`components.md`/`charts.md` 为逻辑索引,自动路由到物理拆分文件。
86
86
 
87
87
  ## 三、目录结构
88
88
 
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  name: top-ppt-html
3
- description: "Use when 用户要做报告、演示、汇报、PPT、slides、deck、路演,或写研究报告、分析报告、咨询报告、白皮书、调研、评测、对标、经营分析、复盘、项目汇报、商务/HTML/网页报告,或做架构图、拓扑图、流程图、泳道图、方案图,或把材料做成可视化报告并导出 HTML/PPT/PPTX,或优化排版/版式/配色/图文布局,或要快速模式/fast/直接生成/一键出稿/少问一句。TopPPT HTML:零外链可翻页 HTML(亮暗双主题)+ 版式保真可编辑 16:9 PPTX;三模式(A 演示·每屏一主张 / B 研究·咨询密排 / C 架构·图为王)× 9 风格。Do NOT use for 纯代码工程、非报告类网页或应用开发、视频/图片生成、直接改写已有 Word/PPT 源文件本身。"
3
+ description: "Use when 用户要做报告、演示、汇报、PPT、slides、deck、路演,或写研究报告、分析报告、咨询报告、白皮书、调研、评测、对标、经营分析、复盘、项目汇报、商务/HTML/网页报告,或做架构图、拓扑图、流程图、泳道图、方案图,或把材料做成可视化报告并导出 HTML/PPT/PPTX,或优化排版/版式/配色/图文布局,或要快速模式/fast/直接生成/一键出稿/少问一句。TopPPT HTML:优雅大气的正式场合演讲/汇报演示文稿——零外链可翻页 HTML(亮暗双主题)+ 版式保真可编辑 16:9 PPTX;核心=版式·排版·色彩·内容组织;三模式(A 演示·每屏一主张 / B 研究·咨询密排 / C 架构·图为王)× 9 风格。Do NOT use for 纯代码工程、非报告类网页或应用开发、视频/图片生成、直接改写已有 Word/PPT 源文件本身。"
4
4
  license: MIT
5
5
  compatibility: "Python 3 stdlib for HTML generation; Node >=18 + pptxgenjs for PPTX; optional playwright for browser regression / theme captures."
6
6
  metadata:
7
- version: "0.1.3"
7
+ version: "0.1.5"
8
8
  author: TopMindspace
9
9
  ---
10
10
  # TopPPT HTML
11
11
 
12
- **让 idea 飞,好想法被看见。** 一套技能、三种模式、两种交付:**单文件 HTML 报告**(可翻页、可演示、header 自带工具栏)+ **版式保真的原生可编辑 PPTX**(智能体精导唯一交付通道)。两者同源于一个内容模型 `REPORT_MODEL`。设计对齐 Material Design 3,执行克制(Google/Apple 风);研究模式对齐咨询机构(McKinsey/BCG)的密度与论证结构,但**克制优先**——不加多余的页头标签、页脚信息与装饰。
12
+ **让 idea 飞,好想法被看见。** 面向**演讲与正式场合**的优雅、大气的演示文稿——非 gadget 堆砌、非咨询 dump 默认。三种模式、两种交付:**单文件 HTML**(可翻页演示)+ **版式保真可编辑 PPTX**(**B 通道** `build_pptx.js` 为唯一交付;**A 通道**仅预览/`cross_verify`)。同源 `REPORT_MODEL`。设计对齐 MD3,执行克制;研究模式可对齐咨询密度,但**克制优先**——少装饰、一屏一重心。
13
13
 
14
14
  ## Gate 0 · 先给参考图(**标准模式**硬门禁)
15
15
 
@@ -23,7 +23,6 @@ metadata:
23
23
 
24
24
  **标准模式**:跳过参考图直接问询 = 不合格。**Fast Mode**(下节)豁免 Gate 0 与六项。
25
25
 
26
-
27
26
  ## Fast Mode · 快速模式(用户显式 opt-in)
28
27
 
29
28
  触发词任一即进入(**跳过 Gate 0 与六项问询**):`快速模式` / `fast` / `直接生成` / `一键出稿` / `fast mode` / `少问一句`。
@@ -34,9 +33,9 @@ metadata:
34
33
  | style | B→mckinsey · A→business-blue · C→graphite-dark | |
35
34
  | theme | light(graphite→dark) | |
36
35
  | 篇幅 | A=10 / B=12 / C=6 | |
37
- | format | html only(用户要 PPT→html+pptx) | |
36
+ | format | **html only**(默认;**仅当用户要 PPT / 交付含 PPTX 才开** B 通道) | |
38
37
 
39
- 流程:一行宣布「Fast 选用:…」→ **最小大纲**(`outline-design.md`「轻量最小集」)→ playbook §二轻量链(骨架→模型单写→回填→strict→`quality_gate --deliver`;可选 pptx)。路径轻量;末可附 `assets/style-gallery.html`。开场声明「已跳过参考图」。**标准模式**仍强制 Gate 0 + 六项。
38
+ 流程:一行宣布「Fast 选用:…」→ **最小大纲**(`outline-design.md`「轻量最小集」)→ playbook §二轻量链(骨架→模型单写→回填→strict→`quality_gate --deliver`;**PPTX 显式 opt-in**)。路径轻量;末可附 `assets/style-gallery.html`。开场声明「已跳过参考图」。**标准模式**仍强制 Gate 0 + 六项。
40
39
 
41
40
  ## 唯一入口流程
42
41
 
@@ -56,7 +55,7 @@ metadata:
56
55
  2. **篇幅**——A 8–15 页(图文 V1–V4,简单图禁全幅)/ B 12–25 页 / C 1–3 张图共 6–8 页;有材料按材料量推荐。
57
56
  3. **风格(始终选择)**——默认商务蓝;B 推荐麦肯锡/墨绿/暖沙金;C 推荐石墨深灰/商务蓝/彩色;拿不准给 Gate 0 参考图。
58
57
  4. **亮暗主题(始终确认)**——浅色默认(打印/外发)/ 深色(沉浸/发布会/大屏);石墨深灰出厂深色;双主题经 `REPORT_MODEL.theme` 贯穿 HTML 与导出。
59
- 5. **交付格式**——仅 HTML(默认)/ HTML+PPTX(正式汇报、需协作修改时推荐)。
58
+ 5. **交付格式**——仅 HTML(默认)/ HTML+PPTX(用户要可编辑演示文稿时;PPTX 走 **B 通道**)。
60
59
  6. **参考图确认**——复述 Gate 0 路径,确认用户已看到。
61
60
 
62
61
  **载体**:优先结构化选项卡一次收集,否则对话文本一次列全。此后形式层面不再反复确认(内容层面按需一次大纲确认,见下)。
@@ -84,7 +83,7 @@ metadata:
84
83
 
85
84
  > 披露分层(机器可读):`L0=SKILL.md` · `L1=references/playbook.md` · `L2=按需`
86
85
  >
87
- > **纪律**:L0+L1 是默认全部所需;**只在命中"何时读"时才打开 L2,读完即执行、不预读下一份**。需要代码时**一律先走节级取码** `extract_snippet.py`(`--list` 查全量路由;`--task 任务名 / --chart 图表类型 / --page-type 页型 / --file 文件 --section 节号`),逻辑名 `components.md` / `charts.md` 自动路由到物理拆分文件。
86
+ > **纪律**:L0+L1 是默认全部所需;**只在命中"何时读"时才打开 L2,读完即执行、不预读下一份**。需要代码时**一律** `extract_snippet.py`(`--list` / `--task` / `--chart` / `--page-type` / `--file --section`)。**整读大 L2 文件 = FAIL / 不合格**(禁令清单见下与 playbook §十)。
88
87
 
89
88
  **L2 一览**(命中条件与逐任务只读清单的**详表以 playbook §十为准**,此处仅索引):
90
89
 
@@ -94,7 +93,7 @@ metadata:
94
93
  - 配色/主题/字阶 → `styles.md` + `design-system.md` · 写作 → `content-rules.md` · 图标语义 → `icons.md`
95
94
  - PPTX 精导 → `references/pptx-export.md` · 深度高保真 → `references/high-fidelity.md` · 修复顺序 → `references/failure-modes.md` · 技能维护 → `references/tech-design.md`
96
95
 
97
- **操作方式**:定模式/页型/组合/图 → 只读 `playbook.md`;取代码 → **必须** `extract_snippet.py`。**禁止整读**:`layouts-combo` / `components-atoms` / `charts-basic` / `charts-extended` / `content-rules` 全文 / `pptx-export` / 模式模板 HTML(走 scaffold)。详表 playbook §十。同阶段不重读。
96
+ **操作方式**:定模式/页型/组合/图 → 只读 `playbook.md`;取代码 → **必须** `extract_snippet.py`。**整读下列文件 = FAIL**:`layouts-combo` / `components-atoms` / `charts-basic` / `charts-extended` / `content-rules` 全文 / `pptx-export` / 模式模板 HTML(走 scaffold)。详表 playbook §十。同阶段不重读。
98
97
 
99
98
  ## 铁律(12 条 · 交付硬门禁)
100
99
 
@@ -116,9 +115,13 @@ metadata:
116
115
  ## 交付物与验收
117
116
 
118
117
  - **HTML**:单文件零外链、可翻页可演示、每页一屏高;header 工具栏(T 亮暗 / 9 风格即切 / P 预览 / H 指引 / F 全屏 / B 折叠)。
119
- - **PPTX**:16:9 全原生形状/文本框/表格(`pictures=0` 可编辑);带数据图表为原生数据图表,非原生附数据表;lead/soWhat/口径/来源写入演讲者备注;按 `REPORT_MODEL.theme` 导出亮/暗版。
120
- - **验收**:HTML strict 0 FAIL / 0 WARN;带 PPTX 加验 PPTX 严格模式 0/0;未通过时末尾给**定向修复指引**。
121
- - **交付说明**:`quality_gate.py` 加 `--deliver`(含 PPTX 时带 `--pptx/--model`)自动生成七要素(路径/字节数/模式/风格/篇幅/格式/校验+引用),缺一即 gate FAIL——不要手拼。
118
+ - **PPTX(B 通道交付)**:`extract_model` → `build_pptx.js` → `validate_pptx --strict`;16:9 全原生可编辑。**A 通道不交付**(仅预览 / `cross_verify`;细则 playbook §九)。
119
+ - **验收**:HTML strict 0/0;含 PPTX 再加 PPTX 0/0;失败给**定向修复指引**。
120
+ - **交付说明**:`quality_gate.py --deliver`(含 PPTX 带 `--pptx/--model`;子门禁并行)出七要素,缺一 FAIL——勿手拼。
121
+
122
+ ## 版本口径
123
+
124
+ 包 semver(现 0.1.5)≠ 布局 schema 线(layout-constants / model-schema 的 version,现 `0.1`);patch 不抬 schema。
122
125
 
123
126
  ## 环境依赖
124
127
 
@@ -1,5 +1,5 @@
1
1
  # Codex / ChatGPT Skills UI metadata (optional)
2
2
  display_name: "TopPPT HTML"
3
- short_description: "Reports, decks, and architecture diagrams as single-file HTML + editable 16:9 PPTX."
4
- default_prompt: "Generate a professional presentation or research report as HTML (and optional PPTX)."
3
+ short_description: "Elegant, atmospheric formal decks for speeches — HTML + editable 16:9 PPTX."
4
+ default_prompt: "Generate an elegant formal presentation or report as HTML (PPTX on request via B-channel)."
5
5
  allow_implicit_invocation: true
@@ -1976,6 +1976,7 @@ window.REPORT_MODEL = {
1976
1976
 
1977
1977
  /* __TOPPPT_RUNTIME_START__ */
1978
1978
  /* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
1979
+ /* __TOPPPT_RUNTIME_SHA__:68c55206c33160af */
1979
1980
  /* ═══════════════════════════════════════════════════════════════════════════
1980
1981
  * TopPPT HTML· 浏览器端 PPTX 预览运行时
1981
1982
  * 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
@@ -2057,11 +2058,11 @@ var STYLE_DATA_COLORS = {"business-blue":["1a73e8","3526bb","21a199","b77148","9
2057
2058
  var STYLE_DATA_COLORS_DARK = {"business-blue":["8ab4f8","7966e0","88e7e5","d4ad91","cbce83"],"apple-mono":["f5f5f7","2997ff","2dd4bf","ff9f0a","bf5af2"],"mckinsey":["7fb2e5","6f6bdb","8ce3d8","d1a694","cbc586"],"brand-red":["ff5a66","e09e66","e788cb","91d4c2","83b4ce"],"warm-sand":["d9b36a","c2d571","df9391","97b5ce","8e89c7"],"deep-teal":["4fc3b0","7aaecd","97d8a4","c99cac","c29c8f"],"graphite-dark":["4da3ff","6c66e0","88e7dc","d4a691","cec983"],"indigo-violet":["a5a4f0","a967e0","89c3e7","d3c792","aece83"],"spectrum":["8ba0f8","9066e0","88d6e7","d4ba91","bdce83"]};
2058
2059
  var GRID = {"columns":12,"gutter":0.16,"colW":0.8644,"x":[0.6,1.6244,2.6488,3.6732,4.6976,5.722,6.7464,7.7708,8.7952,9.8196,10.844,11.8684,12.733],"y":[2.35,3.27,4.19,5.11,6.03,6.9],"safe":{"top":0.4,"bottom":0.4,"left":0.6,"right":0.6}};
2059
2060
  var TYPO = {"levels":[{"id":"C0","name":"封面/章节幕标题","role":"coverTitle","usage":"封面主标题、章节幕标题"},{"id":"T1","name":"页码/章节徽章","role":"caption","usage":"页码徽章、章节编号"},{"id":"T2","name":"页面主标题/结论标题","role":"h1","usage":"每页顶部结论句(research 行动标题)"},{"id":"T3","name":"副标题/语境说明","role":"lead","usage":"主标题下方导语"},{"id":"T4","name":"模块标题/图表标题","role":"h2","usage":"卡片标题、图表标题、面板标题"},{"id":"T5","name":"证据编号/轻量标签","role":"micro","usage":"Exhibit 编号、状态标签"},{"id":"T6","name":"证据块标题/小节标题","role":"h2","usage":"分栏小标题、证据块标题"},{"id":"T7","name":"正文解释段落","role":"body","usage":"证据解释、管理解读正文、表格正文"},{"id":"T8","name":"结论条文字","role":"body","usage":"so-what 结论条、核心结论框"},{"id":"T9","name":"SO WHAT 标签","role":"caption","usage":"so-what 标签行"},{"id":"T10","name":"SO WHAT 正文/业务含义","role":"body","usage":"so-what 正文、行动含义、表格行动项"},{"id":"T11","name":"图表轴/图例/刻度/微标签","role":"micro","usage":"坐标轴、图例、刻度、单位(禁用于表格正文与完整短句)"},{"id":"T12","name":"图表数据标签","role":"caption","usage":"折线点值、柱形标签、百分比标注"},{"id":"T13","name":"关键 KPI 大数字","role":"h1","usage":"KPI 大数字、hero 数值"},{"id":"T14","name":"注释/口径/来源/页脚","role":"micro","usage":"footnote、来源行、页脚、小页码"}],"tableSemanticRule":{"body":["T7","T10"],"microAllowed":["T11"],"microForbiddenFor":["表格正文","行动项","风险项","解释句","建议句","长项目符号","完整短句"]}};
2060
- var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"溢出处置优先级:① 优化内容(列表化/精炼/合并/拆页/换组合版式)→ ② 调整容器尺寸与行宽 → ③ 有限度缩小字号(见 fontShrink)→ ④ 仍装不下则拆页。禁止无限缩字号硬塞,也禁止把「精简」当第一手段砍掉决策必需信息。","fontShrink":{"ladder":[15,14,13.5,13,12.5,12,11.5,11,10.5,10,9.5,9,8.5],"maxShrinkSteps":4,"floorPt":{"presentation":10,"research":9,"architecture":10},"preferContentFirst":true,"warnBelow":9.5},"continuousTextRule":"语义连续的一句话 / so-what 主句 / 结论句 / 表格单元格正文不得拆成多个独立文本框(避免异常空格、断句、基线漂移);局部加粗高亮必须用同一文本框内富文本。"};
2061
+ var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"溢出处置优先级(禁静默截断):① 重构承载(列表/卡片/表/图/组合版式)→ ② 拆页/分章(议程→主张→证据卡→明细;01a/01b;信息须完整)→ ③ 换布局形态(V1–V4/多列/卡栅格)→ ④ 有限 fontShrink(阶梯内、模式 floor 以上、最多 4 档)→ ⑤ 禁止:静默截断、砍 so-what/证据/口径、为审美稀疏删决策必需信息。单页字数预算是预警不是删字许可证。","fontShrink":{"ladder":[15,14,13.5,13,12.5,12,11.5,11,10.5,10,9.5,9,8.5],"maxShrinkSteps":4,"floorPt":{"presentation":10,"research":9,"architecture":10},"preferContentFirst":true,"warnBelow":9.5},"continuousTextRule":"语义连续的一句话 / so-what 主句 / 结论句 / 表格单元格正文不得拆成多个独立文本框(避免异常空格、断句、基线漂移);局部加粗高亮必须用同一文本框内富文本。"};
2061
2062
  var REG = {"bar":{"html":"svg-bars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160}},"hbar":{"html":"svg-hbars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":100}},"stack":{"html":"svg-stack","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160},"nativeOpt":{"barGrouping":"stacked"}},"stackline":{"html":"svg-stackline","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":40},"nativeOpt":{"barGrouping":"percentStacked"}},"line":{"html":"svg-line","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"dualline":{"html":"svg-dualline","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"area":{"html":"svg-area","pptx":"native","nativeType":"area","dataTable":"notes","min":{"vbHeightMin":160}},"donut":{"html":"svg-donut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"multidonut":{"html":"svg-mdonut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"pie":{"html":"svg-pie","pptx":"native","nativeType":"pie","dataTable":"notes","min":{"pxWidthMin":140}},"radar":{"html":"svg-radar","pptx":"native","nativeType":"radar","dataTable":"notes","min":{"pxWidthMin":220}},"scatter":{"html":"svg-scatter","pptx":"native","nativeType":"scatter","dataTable":"notes","min":{"vbHeightMin":180}},"bubble":{"html":"svg-bubble","pptx":"native","nativeType":"bubble","dataTable":"notes","min":{"vbHeightMin":180}},"waterfall":{"html":"svg-wf","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":170},"nativeTrick":"stacked+hiddenBase+connector"},"gauge":{"html":"svg-gauge","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":180},"nativeTrick":"doughnut+firstSliceAng+hiddenRemainder"},"pareto":{"html":"svg-pareto","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":180},"nativeTrick":"multiType+bar+line"},"gantt":{"html":"svg-gantt","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":130},"path":{"forbidPresetShapes":true}},"vsbar":{"html":"svg-vsbar","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"progress":{"html":"svg-progress","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"sparkline":{"html":"svg-spark","pptx":"shape","dataTable":"off","min":{"vbHeightMin":20},"path":{"forbidPresetShapes":true}},"funnel":{"html":"svg-funnel","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"minSamplePoints":8,"forbidPresetShapes":true}},"treemap":{"html":"svg-treemap","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":170},"path":{"forbidPresetShapes":true}},"marimekko":{"html":"svg-marimekko","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"boxplot":{"html":"svg-boxplot","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"network":{"html":"svg-network","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"forbidPresetShapes":true}},"sankey":{"html":"svg-sankey","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"minSamplePoints":16,"trackBothEdges":true,"forbidPresetShapes":true}},"streamgraph":{"html":"svg-stream","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"minSamplePoints":24,"trackBothEdges":true,"forbidPresetShapes":true}},"slope":{"html":"svg-slope","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"dumbbell":{"html":"svg-dumbbell","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"lollipop":{"html":"svg-lollipop","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"dotplot":{"html":"svg-dotplot","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":120},"path":{"forbidPresetShapes":true}},"bulletchart":{"html":"svg-bullet","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"waffle":{"html":"svg-waffle","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"radialbar":{"html":"svg-radialbar","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":200},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"rose":{"html":"svg-rose","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":180},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"candlestick":{"html":"svg-candle","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}}};
2062
2063
  var DEEP = {"triggers":["高保真","1:1","一比一","精确还原","按图还原","正式交付","不能偏移","像素级","严格对照","逐页验收"],"complexCharts":["sankey","streamgraph","treemap","marimekko","boxplot","network","rose","radialbar","candlestick","funnel"],"checks":{"anchors":true,"containerOverflow":true,"renderCompare":true,"manifest":true},"renderCompare":{"engine":"soffice","fallback":"powerpoint-com","skipIfMissing":true,"dpi":96}};
2063
2064
  var IMG = {"layouts":["full","half","bleed","grid","compare","wall"],"multiLayouts":["grid","compare","wall"],"fitEnum":["cover","contain"],"fitDefault":"cover","formats":["png","jpeg","jpg","webp","svg"],"ratioDefault":{"full":"3:1","half":"4:3","bleed":"21:9","grid":"4:3","compare":"4:3","wall":"1:1"},"ratioCssClass":{"full":"media--r3-1","half":"media--r4-3","bleed":"media--r21-9","grid":"media--r4-3","compare":"media--r4-3","wall":"media--r1-1"},"recommendedSizePx":{"full":"2400×800","half":"1400×1050","bleed":"2560×1100","grid":"900×675","compare":"1400×1050","wall":"480×480"},"maxInlineBytes":1572864,"maxTotalInlineBytes":8388608,"maxPerPage":6,"placeholderLabel":"配图占位","placeholderHintPrefix":"建议 ","placeholderHintSuffix":"px","zeroExternal":true,"qualityRule":"位图优先提供 ≥2× 显示尺寸;截图用 16:9 或 4:3 锁定比例;数据图不要用截图(应用内联 SVG 图表,可随主题变色)。"};
2064
- var LAYOUT_SLOTS = {"version":"9.1","pageTypes":{"points":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".grid.g-2 / .card / .ul","pptx":"points columns","minUnits":1},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar / footnoteLine"}]},"metrics":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".metric","pptx":"metric row","minUnits":4},{"id":"annotation","role":"annotation","required":false,"html":"口径行 / .sowhat","pptx":"footnoteLine / soWhatBar"}]},"kpi":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"hero","role":"primary","required":true,"html":".t-metric hero","pptx":"hero number"},{"id":"metrics","role":"secondary","required":false,"html":".metric","pptx":"support metrics"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar"}]},"exhibit":{"mode":["research","presentation"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead / .exhibit__hd","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart] / .exhibit","pptx":"nativeChart | shapeChart","channel":"registry"},{"id":"secondary","role":"secondary","required":false,"html":"要点列表","pptx":"side bullets"},{"id":"annotation","role":"annotation","required":true,"html":".exhibit__src / .sowhat","pptx":"footnoteLine / soWhatBar / notes"}]},"split":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"left","role":"primary","required":true,"html":"左区(points/table/image/chart)","pptx":"left zone"},{"id":"right","role":"secondary","required":true,"html":"右区(points/table/image/chart)","pptx":"right zone"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar"}]},"table":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".tbl-wrap table","pptx":"addTable","maxRows":{"presentation":8,"research":16}},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar / footnoteLine"}]},"bar":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart]","pptx":"nativeChart | shapeChart","channel":"registry"},{"id":"annotation","role":"annotation","required":true,"html":"note / dataTable","pptx":"footnoteLine / notes / inline table"}]},"donut":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=donut]","pptx":"addChart doughnut"},{"id":"annotation","role":"annotation","required":false,"html":"中心合计 / 图例 / .note","pptx":"center label / legend / notes"}]},"twocol":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".cols-2","pptx":"two text columns"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"threecol":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".cols-3","pptx":"three text columns"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"halftable":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"左表","pptx":"addTable left"},{"id":"secondary","role":"secondary","required":true,"html":"右图","pptx":"chart right"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"matrix":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".matrix","pptx":"matrix cells"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"comparison":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"left","role":"primary","required":true,"html":"左面板","pptx":"left panel"},{"id":"right","role":"secondary","required":true,"html":"右面板","pptx":"right panel"},{"id":"annotation","role":"annotation","required":false,"html":"verdict / .sowhat","pptx":"verdict bar"}]},"quote":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"金句正文","pptx":"quote text"}]},"timeline":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".tl","pptx":"timeline axis"}]},"steps":{"mode":["presentation","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".steps","pptx":"step row"}]},"cards":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".card grid","pptx":"card grid"}]},"heatmap":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".heat","pptx":"heat cells"}]},"bullet":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".bul","pptx":"bullet rows"}]},"pyramid":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".pyr","pptx":"pyramid layers"}]},"image":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".media*","pptx":"imageLayoutShapes"}]},"diagram":{"mode":["architecture","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".arch / layers","pptx":"layered nodes + edges","maxNodes":24,"maxLayers":4},{"id":"annotation","role":"annotation","required":false,"html":".arch__legend / .note","pptx":"legend chips / notes"}]},"lane":{"mode":["architecture","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".lane","pptx":"lanes + steps"}]},"sankey":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=sankey]","pptx":"infoSankey","maxNodes":12},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"treemap":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=treemap]","pptx":"infoTreemap"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"boxplot":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=boxplot]","pptx":"infoBoxplot"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"network":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=network]","pptx":"infoNetwork"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"marimekko":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=marimekko]","pptx":"infoMarimekko"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"streamgraph":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=streamgraph]","pptx":"infoStreamgraph"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]}}};
2065
+ var LAYOUT_SLOTS = {"version":"0.1","pageTypes":{"points":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".grid.g-2 / .card / .ul","pptx":"points columns","minUnits":1},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar / footnoteLine"}]},"metrics":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".metric","pptx":"metric row","minUnits":4},{"id":"annotation","role":"annotation","required":false,"html":"口径行 / .sowhat","pptx":"footnoteLine / soWhatBar"}]},"kpi":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"hero","role":"primary","required":true,"html":".t-metric hero","pptx":"hero number"},{"id":"metrics","role":"secondary","required":false,"html":".metric","pptx":"support metrics"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar"}]},"exhibit":{"mode":["research","presentation"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead / .exhibit__hd","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart] / .exhibit","pptx":"nativeChart | shapeChart","channel":"registry"},{"id":"secondary","role":"secondary","required":false,"html":"要点列表","pptx":"side bullets"},{"id":"annotation","role":"annotation","required":true,"html":".exhibit__src / .sowhat","pptx":"footnoteLine / soWhatBar / notes"}]},"split":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"left","role":"primary","required":true,"html":"左区(points/table/image/chart)","pptx":"left zone"},{"id":"right","role":"secondary","required":true,"html":"右区(points/table/image/chart)","pptx":"right zone"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar"}]},"table":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".tbl-wrap table","pptx":"addTable","maxRows":{"presentation":8,"research":16}},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar / footnoteLine"}]},"bar":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart]","pptx":"nativeChart | shapeChart","channel":"registry"},{"id":"annotation","role":"annotation","required":true,"html":"note / dataTable","pptx":"footnoteLine / notes / inline table"}]},"donut":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=donut]","pptx":"addChart doughnut"},{"id":"annotation","role":"annotation","required":false,"html":"中心合计 / 图例 / .note","pptx":"center label / legend / notes"}]},"twocol":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".cols-2","pptx":"two text columns"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"threecol":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".cols-3","pptx":"three text columns"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"halftable":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"左表","pptx":"addTable left"},{"id":"secondary","role":"secondary","required":true,"html":"右图","pptx":"chart right"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"matrix":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".matrix","pptx":"matrix cells"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"comparison":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"left","role":"primary","required":true,"html":"左面板","pptx":"left panel"},{"id":"right","role":"secondary","required":true,"html":"右面板","pptx":"right panel"},{"id":"annotation","role":"annotation","required":false,"html":"verdict / .sowhat","pptx":"verdict bar"}]},"quote":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"金句正文","pptx":"quote text"}]},"timeline":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".tl","pptx":"timeline axis"}]},"steps":{"mode":["presentation","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".steps","pptx":"step row"}]},"cards":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".card grid","pptx":"card grid"}]},"heatmap":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".heat","pptx":"heat cells"}]},"bullet":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".bul","pptx":"bullet rows"}]},"pyramid":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".pyr","pptx":"pyramid layers"}]},"image":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".media*","pptx":"imageLayoutShapes"}]},"diagram":{"mode":["architecture","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".arch / layers","pptx":"layered nodes + edges","maxNodes":24,"maxLayers":4},{"id":"annotation","role":"annotation","required":false,"html":".arch__legend / .note","pptx":"legend chips / notes"}]},"lane":{"mode":["architecture","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".lane","pptx":"lanes + steps"}]},"sankey":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=sankey]","pptx":"infoSankey","maxNodes":12},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"treemap":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=treemap]","pptx":"infoTreemap"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"boxplot":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=boxplot]","pptx":"infoBoxplot"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"network":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=network]","pptx":"infoNetwork"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"marimekko":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=marimekko]","pptx":"infoMarimekko"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"streamgraph":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=streamgraph]","pptx":"infoStreamgraph"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]}}};
2065
2066
 
2066
2067
  /* regionOf(pageType, slotId, opts) — 页型布局区域 IR(与 scripts/lib_layout_regions.js 同源) */
2067
2068
  function regionOf(pageType, slotId, opts) {
@@ -2195,7 +2196,7 @@ function regionOf(pageType, slotId, opts) {
2195
2196
  /* __TOPPPT_SCHEMA_START__ */
2196
2197
  /* ── 由 scripts/sync_runtime.py 从 scripts/model-schema.json 注入 · 禁止手改 ── */
2197
2198
  /* DSL schema 单源:浏览器端 validateModel 与 scripts/extract_model.py 消费同一份定义 */
2198
- var MODEL_SCHEMA = {"version":"9.1","modes":["presentation","research","architecture"],"model":{"required":["title","sections:array","closing.title","closing.points:array"],"optional":["mode","style","theme","subtitle","meta","agenda:array"],"agendaMin":{"presentation":3,"research":3,"architecture":0},"sectionsMin":1,"sectionsRecommended":3,"agendaComfortMax":16},"commonSectionFields":["eyebrow","title","lead","soWhat","footnote","flags","image","exhibitNo","layoutPreset"],"flagsHint":"flags = 待核实/待二次修改条目字符串数组(如 '2027 增速 xx%(口径未定)');渲染为 accent 强调色标注行,提示用户核对。","imageHint":"image = 素材图片/配图占位对象。三选一必填:src(用户图,data: 内联或相对路径,零外链铁律禁 http(s))|items(多图版式:grid/compare/wall,元素 {src?, alt?, caption?, placeholder?})|placeholder:true(无图时出配图占位,原生形状渲染、pictures 不增)。其余可选:layout(full/half/bleed/grid/compare/wall,见 layout-constants.json imageSpec.layouts)、fit(cover 默认 / contain)、caption、alt、hint、ratio。","imageLayoutHint":"layout 与 HTML 版式对应:full=版心全宽图|half=左图右注(points 为右栏注解)|bleed=通栏出血|grid=多图网格(items 2/3/4/6 张)|compare=双图 A/B 对比(items 2 张)|wall=Logo 墙(items 3–12 张小图)。占位符标签文本由双引擎按 imageSpec 拼同一串,保证 A/B 通道逐页文本一致。","chartTypes":["bar","hbar","stack","stackline","line","dualline","area","donut","multidonut","pie","radar","scatter","bubble","waterfall","gauge","pareto","funnel","gantt","vsbar","progress","sparkline","slope","dumbbell","lollipop","dotplot","bulletchart","waffle","radialbar","rose","candlestick"],"chartTypesHint":"chart.type 可取值 = 本表(30 类:16 原生 + 14 形状还原)。其余 6 类复杂信息图(sankey/treemap/boxplot/network/marimekko/streamgraph)是**专属页型**而非 chart.type——它们要按列/段/节点等结构化载荷表达,故走 sections[].type。不变量:charts.registry.types == chartTypes ∪ 上述 6 类页型(sync_runtime.py 校验)。","chartDataTable":{"enum":["notes","inline","appendix","off"],"default":"notes","rule":"非原生图表(registry.pptx=shape)的 dataTable 不得为 off;缺失时按 registry 默认值补齐。"},"pageTypes":{"points":{"label":"要点列表页","modes":["presentation","research","architecture"],"required":["points:array"],"optional":["metrics:array"]},"metrics":{"label":"指标带页(4–6 个核心数字)","modes":["presentation","research"],"required":["metrics:array"]},"kpi":{"label":"大数指标页(hero 大数字 + 支撑指标行)","modes":["presentation","research"],"required":["hero:array"],"optional":["metrics:array"]},"table":{"label":"对比表页","modes":["presentation","research","architecture"],"required":["table.head:array","table.rows:array"],"optional":["table.colW:array"]},"timeline":{"label":"时间线 / 路线页","modes":["presentation","research"],"required":["phases:array"]},"steps":{"label":"步骤条页(N 步横排 + 箭头,可分组)","modes":["presentation","research","architecture"],"required":["steps:array"],"optional":["groups:array","note"]},"bar":{"label":"图表页(chart.type 见 chartTypes;native 通道走原生数据图表,shape 通道走高保真形状还原 + 数据表)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.start:array","chart.target:array","chart.dataTable","note"]},"donut":{"label":"环形图页(原生 pie 楔形 + 图例)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.unit","chart.centerLabel","chart.colors:array","chart.dataTable","note"]},"heatmap":{"label":"热力矩阵页(行 × 列 + 强度色阶)","modes":["presentation","research"],"required":["rowHeads:array","colHeads:array","cells:array"],"optional":["unit","scaleLabel:array","note"]},"bullet":{"label":"达成对比页(实际 vs 目标条)","modes":["presentation","research"],"required":["items:array"],"optional":["unit","max","note"]},"pyramid":{"label":"金字塔页(层级递进,顶层最窄)","modes":["presentation","research","architecture"],"required":["levels:array"],"optional":["note"]},"image":{"label":"素材图片页(full/half/bleed/grid/compare/wall,效果与位置锁定;支持配图占位)","modes":["presentation","research","architecture"],"required":["anyof:image.src:str|image.items:array|image.placeholder"],"optional":["image.caption","image.alt","image.layout","image.fit","image.ratio","image.hint","points:array","note"]},"cards":{"label":"卡片网格页(cards 元素须为 {title, points:[[k,v]…]},不接受元组)","modes":["presentation","research"],"required":["cards:array"],"optional":["columns"]},"split":{"label":"双区组合页(left / right 各可为 要点|图表|表格|图片:type = points(默认)| table | image | 图表类型名;图表/表格字段直接挂在对应侧)","modes":["presentation","research"],"required":["anyof:left.points:array|left.type:str"],"optional":["left.cap","left.image","left.labels:array","left.values:array","left.series:array","left.points:array","left.max","left.unit","left.colors:array","left.dataTable","left.head:array","left.rows:array","left.colW:array","right.type","right.cap","right.image","right.labels:array","right.values:array","right.series:array","right.points:array","right.max","right.unit","right.colors:array","right.dataTable","right.head:array","right.rows:array","right.colW:array"]},"comparison":{"label":"对比页(左右双栏 + 可选结论条)","modes":["presentation","research"],"required":["left.title","left.points:array","right.title","right.points:array"],"optional":["verdict"]},"quote":{"label":"引用 / 金句页(深色全幅)","modes":["presentation","research"],"required":["quote","author"],"optional":["context"]},"diagram":{"label":"分层架构页(architecture 模式走全幅几何)","modes":["presentation","research","architecture"],"required":["layers:array"],"optional":["legend:array"]},"exhibit":{"label":"Exhibit 编号图表页(research R2)","modes":["research"],"required":["chart.labels:array","chart.values:array"],"optional":["exhibitNo","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"twocol":{"label":"双栏论证页(research R1)","modes":["research"],"required":["paragraphs:array"]},"threecol":{"label":"三栏证据页(research R6)","modes":["research"],"required":["paragraphs:array"]},"halftable":{"label":"半表半图页(research R7)","modes":["research"],"required":["table.head:array","table.rows:array","chart.labels:array","chart.values:array"],"optional":["table.colW:array","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"matrix":{"label":"矩阵图页(research R8)","modes":["research"],"required":["rowHeads:array","colHeads:array","cells:array"]},"lane":{"label":"泳道页(architecture A2)","modes":["architecture"],"required":["lanes:array"]},"sankey":{"label":"桑基图页(节点-流带,流向与流量)","modes":["research","architecture"],"required":["flows:array"],"optional":["unit","chart.dataTable","note"]},"treemap":{"label":"树图页(面积编码的层级构成)","modes":["research","architecture"],"required":["items:array"],"optional":["unit","chart.dataTable","note"]},"boxplot":{"label":"箱线图页(分布对比:min/q1/median/q3/max)","modes":["research","architecture"],"required":["groups:array"],"optional":["unit","chart.dataTable","note"]},"network":{"label":"关系网络页(节点-边拓扑)","modes":["research","architecture"],"required":["nodes:array","edges:array"],"optional":["chart.dataTable","note"]},"marimekko":{"label":"马赛克图页(列宽 × 列高双重编码)","modes":["research","architecture"],"required":["cols:array","cells:array"],"optional":["unit","chart.dataTable","note"]},"streamgraph":{"label":"流带图页(时间上的构成演变)","modes":["research","architecture"],"required":["series:array"],"optional":["labels:array","chart.dataTable","note"]}}};
2199
+ var MODEL_SCHEMA = {"version":"0.1","modes":["presentation","research","architecture"],"model":{"required":["title","sections:array","closing.title","closing.points:array"],"optional":["mode","style","theme","subtitle","meta","agenda:array"],"agendaMin":{"presentation":3,"research":3,"architecture":0},"sectionsMin":1,"sectionsRecommended":3,"agendaComfortMax":16},"commonSectionFields":["eyebrow","title","lead","soWhat","footnote","flags","image","exhibitNo","layoutPreset"],"flagsHint":"flags = 待核实/待二次修改条目字符串数组(如 '2027 增速 xx%(口径未定)');渲染为 accent 强调色标注行,提示用户核对。","imageHint":"image = 素材图片/配图占位对象。三选一必填:src(用户图,data: 内联或相对路径,零外链铁律禁 http(s))|items(多图版式:grid/compare/wall,元素 {src?, alt?, caption?, placeholder?})|placeholder:true(无图时出配图占位,原生形状渲染、pictures 不增)。其余可选:layout(full/half/bleed/grid/compare/wall,见 layout-constants.json imageSpec.layouts)、fit(cover 默认 / contain)、caption、alt、hint、ratio。","imageLayoutHint":"layout 与 HTML 版式对应:full=版心全宽图|half=左图右注(points 为右栏注解)|bleed=通栏出血|grid=多图网格(items 2/3/4/6 张)|compare=双图 A/B 对比(items 2 张)|wall=Logo 墙(items 3–12 张小图)。占位符标签文本由双引擎按 imageSpec 拼同一串,保证 A/B 通道逐页文本一致。","chartTypes":["bar","hbar","stack","stackline","line","dualline","area","donut","multidonut","pie","radar","scatter","bubble","waterfall","gauge","pareto","funnel","gantt","vsbar","progress","sparkline","slope","dumbbell","lollipop","dotplot","bulletchart","waffle","radialbar","rose","candlestick"],"chartTypesHint":"chart.type 可取值 = 本表(30 类:16 原生 + 14 形状还原)。其余 6 类复杂信息图(sankey/treemap/boxplot/network/marimekko/streamgraph)是**专属页型**而非 chart.type——它们要按列/段/节点等结构化载荷表达,故走 sections[].type。不变量:charts.registry.types == chartTypes ∪ 上述 6 类页型(sync_runtime.py 校验)。","chartDataTable":{"enum":["notes","inline","appendix","off"],"default":"notes","rule":"非原生图表(registry.pptx=shape)的 dataTable 不得为 off;缺失时按 registry 默认值补齐。"},"pageTypes":{"points":{"label":"要点列表页","modes":["presentation","research","architecture"],"required":["points:array"],"optional":["metrics:array"]},"metrics":{"label":"指标带页(4–6 个核心数字)","modes":["presentation","research"],"required":["metrics:array"]},"kpi":{"label":"大数指标页(hero 大数字 + 支撑指标行)","modes":["presentation","research"],"required":["hero:array"],"optional":["metrics:array"]},"table":{"label":"对比表页","modes":["presentation","research","architecture"],"required":["table.head:array","table.rows:array"],"optional":["table.colW:array"]},"timeline":{"label":"时间线 / 路线页","modes":["presentation","research"],"required":["phases:array"]},"steps":{"label":"步骤条页(N 步横排 + 箭头,可分组)","modes":["presentation","research","architecture"],"required":["steps:array"],"optional":["groups:array","note"]},"bar":{"label":"图表页(chart.type 见 chartTypes;native 通道走原生数据图表,shape 通道走高保真形状还原 + 数据表)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.start:array","chart.target:array","chart.dataTable","note"]},"donut":{"label":"环形图页(原生 pie 楔形 + 图例)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.unit","chart.centerLabel","chart.colors:array","chart.dataTable","note"]},"heatmap":{"label":"热力矩阵页(行 × 列 + 强度色阶)","modes":["presentation","research"],"required":["rowHeads:array","colHeads:array","cells:array"],"optional":["unit","scaleLabel:array","note"]},"bullet":{"label":"达成对比页(实际 vs 目标条)","modes":["presentation","research"],"required":["items:array"],"optional":["unit","max","note"]},"pyramid":{"label":"金字塔页(层级递进,顶层最窄)","modes":["presentation","research","architecture"],"required":["levels:array"],"optional":["note"]},"image":{"label":"素材图片页(full/half/bleed/grid/compare/wall,效果与位置锁定;支持配图占位)","modes":["presentation","research","architecture"],"required":["anyof:image.src:str|image.items:array|image.placeholder"],"optional":["image.caption","image.alt","image.layout","image.fit","image.ratio","image.hint","points:array","note"]},"cards":{"label":"卡片网格页(cards 元素须为 {title, points:[[k,v]…]},不接受元组)","modes":["presentation","research"],"required":["cards:array"],"optional":["columns"]},"split":{"label":"双区组合页(left / right 各可为 要点|图表|表格|图片:type = points(默认)| table | image | 图表类型名;图表/表格字段直接挂在对应侧)","modes":["presentation","research"],"required":["anyof:left.points:array|left.type:str"],"optional":["left.cap","left.image","left.labels:array","left.values:array","left.series:array","left.points:array","left.max","left.unit","left.colors:array","left.dataTable","left.head:array","left.rows:array","left.colW:array","right.type","right.cap","right.image","right.labels:array","right.values:array","right.series:array","right.points:array","right.max","right.unit","right.colors:array","right.dataTable","right.head:array","right.rows:array","right.colW:array"]},"comparison":{"label":"对比页(左右双栏 + 可选结论条)","modes":["presentation","research"],"required":["left.title","left.points:array","right.title","right.points:array"],"optional":["verdict"]},"quote":{"label":"引用 / 金句页(深色全幅)","modes":["presentation","research"],"required":["quote","author"],"optional":["context"]},"diagram":{"label":"分层架构页(architecture 模式走全幅几何)","modes":["presentation","research","architecture"],"required":["layers:array"],"optional":["legend:array"]},"exhibit":{"label":"Exhibit 编号图表页(research R2)","modes":["research"],"required":["chart.labels:array","chart.values:array"],"optional":["exhibitNo","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"twocol":{"label":"双栏论证页(research R1)","modes":["research"],"required":["paragraphs:array"]},"threecol":{"label":"三栏证据页(research R6)","modes":["research"],"required":["paragraphs:array"]},"halftable":{"label":"半表半图页(research R7)","modes":["research"],"required":["table.head:array","table.rows:array","chart.labels:array","chart.values:array"],"optional":["table.colW:array","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"matrix":{"label":"矩阵图页(research R8)","modes":["research"],"required":["rowHeads:array","colHeads:array","cells:array"]},"lane":{"label":"泳道页(architecture A2)","modes":["architecture"],"required":["lanes:array"]},"sankey":{"label":"桑基图页(节点-流带,流向与流量)","modes":["research","architecture"],"required":["flows:array"],"optional":["unit","chart.dataTable","note"]},"treemap":{"label":"树图页(面积编码的层级构成)","modes":["research","architecture"],"required":["items:array"],"optional":["unit","chart.dataTable","note"]},"boxplot":{"label":"箱线图页(分布对比:min/q1/median/q3/max)","modes":["research","architecture"],"required":["groups:array"],"optional":["unit","chart.dataTable","note"]},"network":{"label":"关系网络页(节点-边拓扑)","modes":["research","architecture"],"required":["nodes:array","edges:array"],"optional":["chart.dataTable","note"]},"marimekko":{"label":"马赛克图页(列宽 × 列高双重编码)","modes":["research","architecture"],"required":["cols:array","cells:array"],"optional":["unit","chart.dataTable","note"]},"streamgraph":{"label":"流带图页(时间上的构成演变)","modes":["research","architecture"],"required":["series:array"],"optional":["labels:array","chart.dataTable","note"]}}};
2199
2200
  /* __TOPPPT_SCHEMA_END__ */
2200
2201
 
2201
2202
  var _mode = 'presentation'; /* 当前模式(slidesOf 里按 model.mode 设置) */
@@ -2254,6 +2255,16 @@ function modeFloorPtA(mode) {
2254
2255
  var m = String(mode || 'presentation');
2255
2256
  return (floors[m] != null) ? floors[m] : 10;
2256
2257
  }
2258
+ function snapFont(pt, ladder, floor) {
2259
+ var lad = (ladder || FONT_LADDER).filter(function (v) { return v >= (floor == null ? 0 : floor); });
2260
+ if (!lad.length) return floor == null ? pt : Math.max(floor, pt);
2261
+ var best = lad[0], bd = Math.abs(lad[0] - pt);
2262
+ for (var i = 1; i < lad.length; i++) {
2263
+ var d = Math.abs(lad[i] - pt);
2264
+ if (d < bd) { bd = d; best = lad[i]; }
2265
+ }
2266
+ return best;
2267
+ }
2257
2268
  function fitFont(items, widthIn, availIn, opts) {
2258
2269
  opts = opts || {};
2259
2270
  var max = (opts.max == null) ? 99 : opts.max, lf = opts.lineFactor || 1.45;
@@ -2598,7 +2609,7 @@ function imageLayoutShapes(sh, S, layout, img, items, points, isPh, fit, y0, y1)
2598
2609
  sh.push(shape('rect', rxI, lyI + rowHI / 2 - 0.06, 0.12, 0.12, S.accent));
2599
2610
  sh.push(txSp(rxI + 0.26, lyI, rwI - 0.3, rowHI - 0.04,
2600
2611
  [[{ t: (pt[0] || '') + ' ', sz: fzI, b: 1, col: S.ink, font: S.font },
2601
- { t: pt[1] || '', sz: fzI - 1, col: S.body, font: S.font }]], { anchor: 't' }));
2612
+ { t: pt[1] || '', sz: snapFont(fzI - 1), col: S.body, font: S.font }]], { anchor: 't' }));
2602
2613
  });
2603
2614
  capY = iy + Math.max(ihh, ih * 0.5);
2604
2615
  } else if (layout === 'bleed') {
@@ -2647,24 +2658,55 @@ function hbarRows(sh, ec, S, y0, y1, dcols, x0, w) {
2647
2658
  }
2648
2659
  /* 竖柱 / 堆叠柱 */
2649
2660
  function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
2650
- var labels = ec.labels || [], values = ec.values || [];
2661
+ /* Multi-series aware (mirrors lineShapes): ec.series[{name,values}] or single ec.values. */
2662
+ var labels = ec.labels || [];
2663
+ var series = (ec.series && ec.series.length)
2664
+ ? ec.series
2665
+ : [{ name: '数值', values: ec.values || [] }];
2651
2666
  var nb = Math.max(1, labels.length);
2667
+ var ns = Math.max(1, series.length);
2652
2668
  var baseY = y + h, plotW = w, step = plotW / nb;
2653
- var bw = Math.min(1.1, step * 0.55);
2654
- var vmax = ec.max || Math.max.apply(null, values.concat([1]));
2655
- var top = values.length ? Math.max.apply(null, values) : 0;
2669
+ var cluster = Math.min(1.1, step * (ns > 1 ? 0.78 : 0.55));
2670
+ var bw = cluster / ns;
2671
+ var all = [];
2672
+ series.forEach(function (se) {
2673
+ (se.values || []).forEach(function (v) { all.push(Number(v) || 0); });
2674
+ });
2675
+ var vmax = ec.max || Math.max.apply(null, all.concat([1]));
2676
+ var top = all.length ? Math.max.apply(null, all) : 0;
2656
2677
  sh.push(shape('rect', x, baseY, plotW, 0.02, S.line));
2657
- values.forEach(function (v, i) {
2658
- var hh = Math.max(0.05, v / vmax * (h - 0.5));
2659
- var bx = x + i * step + (step - bw) / 2;
2660
- var hot = v === top;
2661
- var dc = dcols ? dcols[i % 5] : null;
2662
- sh.push(shape('roundRect', bx, baseY - hh, bw, hh, dc || (hot ? S.accent : S.faint), { adj: 6000 }));
2663
- sh.push(txSp(bx - 0.3, baseY - hh - 0.4, bw + 0.6, 0.32,
2664
- [[{ t: valText(v, ec.unit), sz: 12.5, b: 1, col: hot ? S.accent : S.body, font: S.font }]], { align: 'ctr' }));
2665
- sh.push(txSp(bx - 0.3, baseY + 0.08, bw + 0.6, 0.32,
2666
- [[{ t: labels[i], sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
2678
+ series.forEach(function (se, si) {
2679
+ var vals = se.values || [];
2680
+ var col = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
2681
+ vals.forEach(function (v, i) {
2682
+ var num = Number(v) || 0;
2683
+ var hh = Math.max(0.05, num / vmax * (h - 0.5));
2684
+ var bx = x + i * step + (step - cluster) / 2 + si * bw;
2685
+ var hot = ns === 1 && num === top;
2686
+ sh.push(shape('roundRect', bx, baseY - hh, Math.max(0.04, bw * 0.92), hh,
2687
+ hot ? (dcols ? dcols[i % 5] : S.accent) : col, { adj: 6000 }));
2688
+ if (ns === 1) {
2689
+ sh.push(txSp(bx - 0.3, baseY - hh - 0.4, bw + 0.6, 0.32,
2690
+ [[{ t: valText(num, ec.unit), sz: 12.5, b: 1, col: hot ? S.accent : S.body, font: S.font }]], { align: 'ctr' }));
2691
+ }
2692
+ });
2667
2693
  });
2694
+ labels.forEach(function (lb, i) {
2695
+ var lx = x + i * step;
2696
+ sh.push(txSp(lx, baseY + 0.08, step, 0.32,
2697
+ [[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
2698
+ });
2699
+ /* Multi-series legend along top of plot (keeps category labels; avoids blank chart). */
2700
+ if (ns > 1) {
2701
+ var lx2 = x;
2702
+ series.forEach(function (se, si) {
2703
+ var col2 = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
2704
+ sh.push(shape('rect', lx2, y, 0.12, 0.12, col2));
2705
+ sh.push(txSp(lx2 + 0.16, y - 0.02, 1.4, 0.24,
2706
+ [[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]]));
2707
+ lx2 += 1.6;
2708
+ });
2709
+ }
2668
2710
  }
2669
2711
  /* 折线 / 双折线 / 面积 */
2670
2712
  function lineShapes(sh, ec, S, x, y, w, h, dcols) {
@@ -3071,8 +3113,11 @@ function infoApprox(sh, sec, S, y0, y1) {
3071
3113
  totals.push(tt);
3072
3114
  }
3073
3115
  var maxTot = Math.max.apply(null, totals.concat([1]));
3074
- var plotH3 = P.y1 - P.y0;
3075
- var cyMid = (P.y0 + P.y1) / 2;
3116
+ /* Reserve legend INSIDE the plot box so 6-series pages do not crush the annotation band. */
3117
+ var legH = Math.min(1.2, Math.max(0.28, series.length * 0.22 + 0.08));
3118
+ var plotBottom = P.y1 - legH;
3119
+ var plotH3 = Math.max(0.6, plotBottom - P.y0);
3120
+ var cyMid = P.y0 + plotH3 / 2;
3076
3121
  var base = totals.map(function (tv) { return cyMid - tv / maxTot * plotH3 / 2; });
3077
3122
  series.forEach(function (se, si) {
3078
3123
  var upper = base.map(function (bv, i3) { return bv + (values[si][i3] || 0) / maxTot * plotH3 / 2; });
@@ -3082,12 +3127,12 @@ function infoApprox(sh, sec, S, y0, y1) {
3082
3127
  sh.push(shape('rect', MX + i4 * stepX, (base[i4] + base[i4 + 1]) / 2, stepX, hgt, palette[si % palette.length]));
3083
3128
  }
3084
3129
  base = upper;
3085
- sh.push(shape('rect', MX, P.y1 + 0.06 + si * 0.26, 0.12, 0.12, palette[si % palette.length]));
3086
- sh.push(txSp(MX + 0.16, P.y1 + si * 0.26, 1.5, 0.26,
3130
+ sh.push(shape('rect', MX, plotBottom + 0.04 + si * 0.2, 0.12, 0.12, palette[si % palette.length]));
3131
+ sh.push(txSp(MX + 0.16, plotBottom + 0.02 + si * 0.2, 1.5, 0.2,
3087
3132
  [[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]], { anchor: 'ctr' }));
3088
3133
  });
3089
3134
  labels.forEach(function (lb, i5) {
3090
- sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4, P.y1 - 0.02, 0.8, 0.24,
3135
+ sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4, plotBottom - 0.22, 0.8, 0.2,
3091
3136
  [[{ t: String(lb), sz: 9.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
3092
3137
  });
3093
3138
  }
@@ -3279,8 +3324,8 @@ function slidesOf(model, S) {
3279
3324
  var iy = iR.y;
3280
3325
  var capH2 = img.caption ? 0.32 : 0;
3281
3326
  var ih = Math.max(1.2, iR.h);
3282
- imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
3283
- if (img.caption) sh.push(txSp(MX, iy + ih + 0.04, CW, capH2, [[{ t: img.caption, sz: 10.5, col: S.faint, font: S.font }]]));
3327
+ var capYImg = imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
3328
+ if (img.caption) sh.push(txSp(MX, capYImg + 0.04, CW, capH2, [[{ t: img.caption, sz: 10.5, col: S.faint, font: S.font }]]));
3284
3329
  } else if (type === 'donut') {
3285
3330
  var dcn = sec.chart || {};
3286
3331
  if (dcn.labels && dcn.values) donutChart(sh, dcn, S, dcn.colors || donutColors(model.style, S, model.theme));
@@ -3597,7 +3642,7 @@ function slidesOf(model, S) {
3597
3642
  sh.push(shape('rect', x, ly2 + rowHP / 2 - 0.06, 0.12, 0.12, S.accent));
3598
3643
  sh.push(txSp(x + 0.28, ly2, w - 0.4, rowHP - 0.04,
3599
3644
  [[{ t: pt[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
3600
- { t: pt[1], sz: fzP - 1, col: S.body, font: S.font }]]));
3645
+ { t: pt[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
3601
3646
  });
3602
3647
  };
3603
3648
  if (lt2 === 'table') {
@@ -3718,7 +3763,7 @@ function slidesOf(model, S) {
3718
3763
  sh.push(shape('rect', ptsR.x, y11 + rowHPt / 2 - P2.markSize / 2, P2.markSize, P2.markSize, S.accent));
3719
3764
  sh.push(txSp(ptsR.x + 0.32, y11, textW, rowHPt - 0.04,
3720
3765
  [[{ t: p[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
3721
- { t: p[1], sz: fzP - 1, col: S.body, font: S.font }]]));
3766
+ { t: p[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
3722
3767
  });
3723
3768
  if (hasM) {
3724
3769
  var gx2 = PW - MX - nm2 * mw2;