@topmindspace/tms-skills 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.en.md +3 -3
- package/README.md +3 -3
- package/package.json +1 -1
- package/top-ppt-html/README.en.md +2 -2
- package/top-ppt-html/README.md +1 -1
- package/top-ppt-html/SKILL.md +2 -2
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +122 -48
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +122 -48
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +122 -48
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +126 -52
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.model.json +3 -3
- package/top-ppt-html/assets/pptx-export.js +118 -45
- package/top-ppt-html/assets/style-gallery.html +19 -3
- package/top-ppt-html/assets/templates/architecture.html +122 -48
- package/top-ppt-html/assets/templates/engine.css +3 -2
- package/top-ppt-html/assets/templates/presentation.html +122 -48
- package/top-ppt-html/assets/templates/research.html +122 -48
- package/top-ppt-html/package-lock.json +2 -2
- package/top-ppt-html/package.json +1 -1
- package/top-ppt-html/references/chart-decision-tree.md +26 -25
- package/top-ppt-html/references/components-atoms.md +5 -4
- package/top-ppt-html/references/content-rules.md +3 -1
- package/top-ppt-html/references/failure-modes.md +29 -3
- package/top-ppt-html/references/layouts-combo.md +1 -1
- package/top-ppt-html/references/modes.md +1 -1
- package/top-ppt-html/references/page-type-matrix.md +10 -6
- package/top-ppt-html/references/pptx-export.md +3 -3
- package/top-ppt-html/scripts/build_pptx.js +101 -42
- package/top-ppt-html/scripts/cross_verify.py +84 -1
- package/top-ppt-html/scripts/extract_model.py +5 -0
- package/top-ppt-html/scripts/layout-constants.json +42 -2
- package/top-ppt-html/scripts/lib_layout_regions.js +6 -3
- package/top-ppt-html/scripts/model-schema.json +1 -0
- package/top-ppt-html/scripts/render_from_model.py +133 -17
- package/top-ppt-html/scripts/sync_runtime.py +19 -3
- package/top-ppt-html/scripts/test_feedback_gates.py +73 -0
- package/top-ppt-html/scripts/validate_pptx.py +148 -0
- package/top-ppt-html/scripts/validate_report.py +24 -0
|
@@ -815,8 +815,9 @@ color:var(--accent);font-variant-numeric:tabular-nums;line-height:1;min-width:2.
|
|
|
815
815
|
.agenda__a:hover .agenda__go{color:var(--accent);transform:translateX(4px)}
|
|
816
816
|
.agenda__go svg{width:20px;height:20px;display:block}
|
|
817
817
|
@media (min-width:900px){
|
|
818
|
-
|
|
819
|
-
.agenda--2col
|
|
818
|
+
/* R4:列优先(先左列后右列),与 PPTX Agenda 列填充一致——grid 行优先会打乱阅读顺序 */
|
|
819
|
+
.agenda--2col{display:block;column-count:2;column-gap:clamp(20px,3vw,48px)}
|
|
820
|
+
.agenda--2col .agenda__i{break-inside:avoid;border-top:1px solid var(--border-soft)}}
|
|
820
821
|
/* ── 页码指示(翻页导航) ── */
|
|
821
822
|
.pager{position:fixed;right:clamp(10px,1.6vw,26px);top:50%;transform:translateY(-50%);
|
|
822
823
|
z-index:60;display:flex;flex-direction:column;align-items:center;gap:10px}
|
|
@@ -958,7 +959,7 @@ background:var(--surface-2);border-radius:6px;padding:2px 7px;color:var(--text)}
|
|
|
958
959
|
<section class="band band--fit" id="cover">
|
|
959
960
|
<div class="wrap">
|
|
960
961
|
<div class="shead rv">
|
|
961
|
-
<div class="t-eyebrow">产品介绍 · 2026-09-26 · v0.1.
|
|
962
|
+
<div class="t-eyebrow">产品介绍 · 2026-09-26 · v0.1.18</div>
|
|
962
963
|
<h1 class="t-display shead__title">TopMind × tms-skills</h1>
|
|
963
964
|
<p class="t-lead shead__desc">HTML + PPT 双交付 · 为正式商务演示而生</p>
|
|
964
965
|
</div>
|
|
@@ -1005,7 +1006,7 @@ background:var(--surface-2);border-radius:6px;padding:2px 7px;color:var(--text)}
|
|
|
1005
1006
|
<div class="card"><div class="card__hd"><div class="card__ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M8 13h8M8 17h6"/></svg></div><h3 class="t-h3">当前主技能</h3></div>
|
|
1006
1007
|
<ul class="ul"><li><strong>top-ppt-html。</strong>正式场合演示文稿</li><li><strong>HTML + PPTX。</strong>同源模型 · 双交付</li></ul></div>
|
|
1007
1008
|
</div>
|
|
1008
|
-
<div class="footnote">包名 @topmindspace/tms-skills · 当前线 0.1.
|
|
1009
|
+
<div class="footnote">包名 @topmindspace/tms-skills · 当前线 0.1.18(latest)</div>
|
|
1009
1010
|
<div class="sowhat rv"><span class="sowhat__v">安装器与技能同仓同 tag——装一次,版本线对齐。</span></div>
|
|
1010
1011
|
</div>
|
|
1011
1012
|
</section>
|
|
@@ -1888,7 +1889,7 @@ window.REPORT_MODEL = {
|
|
|
1888
1889
|
"theme": "light",
|
|
1889
1890
|
"title": "TopMind × tms-skills",
|
|
1890
1891
|
"subtitle": "HTML + PPT 双交付 · 为正式商务演示而生",
|
|
1891
|
-
"meta": "产品介绍 · 2026-09-26 · v0.1.
|
|
1892
|
+
"meta": "产品介绍 · 2026-09-26 · v0.1.18",
|
|
1892
1893
|
"agenda": [
|
|
1893
1894
|
[
|
|
1894
1895
|
"01",
|
|
@@ -2048,7 +2049,7 @@ window.REPORT_MODEL = {
|
|
|
2048
2049
|
]
|
|
2049
2050
|
}
|
|
2050
2051
|
],
|
|
2051
|
-
"footnote": "包名 @topmindspace/tms-skills · 当前线 0.1.
|
|
2052
|
+
"footnote": "包名 @topmindspace/tms-skills · 当前线 0.1.18(latest)",
|
|
2052
2053
|
"soWhat": "安装器与技能同仓同 tag——装一次,版本线对齐。"
|
|
2053
2054
|
},
|
|
2054
2055
|
{
|
|
@@ -2443,7 +2444,7 @@ window.REPORT_MODEL = {
|
|
|
2443
2444
|
|
|
2444
2445
|
/* __TOPPPT_RUNTIME_START__ */
|
|
2445
2446
|
/* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
|
|
2446
|
-
/* __TOPPPT_RUNTIME_SHA__:
|
|
2447
|
+
/* __TOPPPT_RUNTIME_SHA__:73cff2ca1dbc78a8 */
|
|
2447
2448
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2448
2449
|
* TopPPT HTML· 浏览器端 PPTX 预览运行时
|
|
2449
2450
|
* 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
|
|
@@ -2602,6 +2603,15 @@ function regionOf(pageType, slotId, opts) {
|
|
|
2602
2603
|
return { x: MX, y: P.heroY || 2.9, w: CW * (P.heroW || 0.52), h: P.heroH || 1.6,
|
|
2603
2604
|
dividerX: P.dividerX, metricY0: P.metricY0, metricRowH: P.metricRowH };
|
|
2604
2605
|
}
|
|
2606
|
+
/* R3:kpi 支撑指标列——落在 dividerX 右侧(默认全宽返回会压住 hero) */
|
|
2607
|
+
if (type === 'kpi' && slot === 'metrics') {
|
|
2608
|
+
var dxK = P.dividerX != null ? P.dividerX : 0.56;
|
|
2609
|
+
return {
|
|
2610
|
+
x: MX + CW * dxK + 0.35, y: P.metricY0 || 2.95,
|
|
2611
|
+
w: CW * (1 - dxK) - 0.5,
|
|
2612
|
+
h: Math.max(0.6, bottomDefault - (P.metricY0 || 2.95)),
|
|
2613
|
+
};
|
|
2614
|
+
}
|
|
2605
2615
|
if (type === 'comparison' && (slot === 'left' || slot === 'primary' || slot === 'right')) {
|
|
2606
2616
|
var cg = P.panelGap || 0.4, pw = (CW - cg) / 2;
|
|
2607
2617
|
if (slot === 'right') return { x: MX + pw + cg, y: P.panelY || 2.55, w: pw, h: P.panelH || 3.4 };
|
|
@@ -2634,15 +2644,22 @@ function regionOf(pageType, slotId, opts) {
|
|
|
2634
2644
|
}
|
|
2635
2645
|
if (type === 'image' && slot === 'primary') {
|
|
2636
2646
|
var iy2 = Math.max(P.y || 2.3, opts.top || 0);
|
|
2637
|
-
|
|
2647
|
+
/* R2:有图注时图片不得越过 contentBottomWithNote(图注落注释带,属 annotation self) */
|
|
2648
|
+
var iBottom = (opts.bottom != null) ? opts.bottom
|
|
2649
|
+
: (opts.caption ? (L.contentBottomWithNote || 6.4) : bottomDefault);
|
|
2650
|
+
return { x: MX, y: iy2, w: CW, h: Math.max(1.2, Math.min(P.h || 4.2, iBottom - iy2)) };
|
|
2638
2651
|
}
|
|
2639
2652
|
if ((type === 'halftable') && (slot === 'left' || slot === 'primary')) {
|
|
2640
2653
|
var rs = PT.research || {};
|
|
2641
|
-
|
|
2654
|
+
var ht = opts.top != null ? opts.top : topDefault;
|
|
2655
|
+
var hb = opts.bottom != null ? opts.bottom : bottomDefault;
|
|
2656
|
+
return { x: MX, y: ht, w: CW * (rs.halfTableW || 0.52), h: Math.max(1, hb - ht) };
|
|
2642
2657
|
}
|
|
2643
2658
|
if ((type === 'halftable') && (slot === 'right' || slot === 'secondary')) {
|
|
2644
2659
|
var rs2 = PT.research || {};
|
|
2645
|
-
|
|
2660
|
+
var ht2 = opts.top != null ? opts.top : topDefault;
|
|
2661
|
+
var hb2 = opts.bottom != null ? opts.bottom : bottomDefault;
|
|
2662
|
+
return { x: MX + CW * (rs2.halfChartX || 0.57), y: ht2, w: CW * (rs2.halfChartW || 0.43), h: Math.max(1, hb2 - ht2) };
|
|
2646
2663
|
}
|
|
2647
2664
|
if (type === 'matrix' && slot === 'primary') {
|
|
2648
2665
|
var rm = PT.research || {};
|
|
@@ -2663,7 +2680,7 @@ function regionOf(pageType, slotId, opts) {
|
|
|
2663
2680
|
/* __TOPPPT_SCHEMA_START__ */
|
|
2664
2681
|
/* ── 由 scripts/sync_runtime.py 从 scripts/model-schema.json 注入 · 禁止手改 ── */
|
|
2665
2682
|
/* DSL schema 单源:浏览器端 validateModel 与 scripts/extract_model.py 消费同一份定义 */
|
|
2666
|
-
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"]}}};
|
|
2683
|
+
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"],"mutualExclusionHint":"verdict 与 soWhat 互斥:二者共用 annotation 结论条槽位,同页双填必叠印。comparison 页填 verdict 时不要再填 soWhat(渲染器已自动二选一,但模型侧应只给一个)。","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"]}}};
|
|
2667
2684
|
/* __TOPPPT_SCHEMA_END__ */
|
|
2668
2685
|
|
|
2669
2686
|
var _mode = 'presentation'; /* 当前模式(slidesOf 里按 model.mode 设置) */
|
|
@@ -2954,6 +2971,15 @@ function footnoteLine(sh, text, S) {
|
|
|
2954
2971
|
sh.push(txSp(R.x, R.y, R.w, R.h,
|
|
2955
2972
|
[[{ t: text, sz: 9.5, col: S.faint, font: S.font }]]));
|
|
2956
2973
|
}
|
|
2974
|
+
/* R2:sec.note 与 sec.footnote 共用注释带末行(footnoteY=6.72)。
|
|
2975
|
+
note.y=6.55 会压进 so-what 带(6.05–6.67)——同页二者必须合并为一行。 */
|
|
2976
|
+
function noteOrFootnote(sh, sec, S) {
|
|
2977
|
+
var parts = [];
|
|
2978
|
+
if (sec && sec.note) parts.push(String(sec.note));
|
|
2979
|
+
if (sec && sec.footnote) parts.push(String(sec.footnote));
|
|
2980
|
+
if (!parts.length) return;
|
|
2981
|
+
footnoteLine(sh, parts.join(' · '), S);
|
|
2982
|
+
}
|
|
2957
2983
|
/* 待核实清单条(accent 强调色标注 · 与 build_pptx.js / HTML .flagbar 同源) */
|
|
2958
2984
|
function flagBar(sh, items, S, yTop) {
|
|
2959
2985
|
var F = PT.flagbar || { hdH: 0.26, rowH: 0.24, maxRows: 3, gap: 0.12 };
|
|
@@ -3142,7 +3168,9 @@ function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
3142
3168
|
: [{ name: '数值', values: ec.values || [] }];
|
|
3143
3169
|
var nb = Math.max(1, labels.length);
|
|
3144
3170
|
var ns = Math.max(1, series.length);
|
|
3145
|
-
|
|
3171
|
+
/* R2:类目标签带必须含在 h 内(原 baseY+0.08 画在图区外,会压进 so-what/来源行) */
|
|
3172
|
+
var labelH = 0.36;
|
|
3173
|
+
var baseY = y + Math.max(0.6, h - labelH), plotW = w, step = plotW / nb;
|
|
3146
3174
|
var cluster = Math.min(1.1, step * (ns > 1 ? 0.78 : 0.55));
|
|
3147
3175
|
var bw = cluster / ns;
|
|
3148
3176
|
var all = [];
|
|
@@ -3151,26 +3179,27 @@ function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
3151
3179
|
});
|
|
3152
3180
|
var vmax = ec.max || Math.max.apply(null, all.concat([1]));
|
|
3153
3181
|
var top = all.length ? Math.max.apply(null, all) : 0;
|
|
3182
|
+
var plotH = Math.max(0.35, baseY - y);
|
|
3154
3183
|
sh.push(shape('rect', x, baseY, plotW, 0.02, S.line));
|
|
3155
3184
|
series.forEach(function (se, si) {
|
|
3156
3185
|
var vals = se.values || [];
|
|
3157
3186
|
var col = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
3158
3187
|
vals.forEach(function (v, i) {
|
|
3159
3188
|
var num = Number(v) || 0;
|
|
3160
|
-
var hh = Math.max(0.05, num / vmax * (
|
|
3189
|
+
var hh = Math.max(0.05, num / vmax * (plotH - 0.35));
|
|
3161
3190
|
var bx = x + i * step + (step - cluster) / 2 + si * bw;
|
|
3162
3191
|
var hot = ns === 1 && num === top;
|
|
3163
3192
|
sh.push(shape('roundRect', bx, baseY - hh, Math.max(0.04, bw * 0.92), hh,
|
|
3164
3193
|
hot ? (dcols ? dcols[i % 5] : S.accent) : col, { adj: 6000 }));
|
|
3165
3194
|
if (ns === 1) {
|
|
3166
|
-
sh.push(txSp(bx - 0.3, baseY - hh - 0.
|
|
3195
|
+
sh.push(txSp(bx - 0.3, baseY - hh - 0.36, bw + 0.6, 0.30,
|
|
3167
3196
|
[[{ t: valText(num, ec.unit), sz: 12.5, b: 1, col: hot ? S.accent : S.body, font: S.font }]], { align: 'ctr' }));
|
|
3168
3197
|
}
|
|
3169
3198
|
});
|
|
3170
3199
|
});
|
|
3171
3200
|
labels.forEach(function (lb, i) {
|
|
3172
3201
|
var lx = x + i * step;
|
|
3173
|
-
sh.push(txSp(lx, baseY + 0.
|
|
3202
|
+
sh.push(txSp(lx, baseY + 0.06, step, labelH - 0.08,
|
|
3174
3203
|
[[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
3175
3204
|
});
|
|
3176
3205
|
/* Multi-series legend along top of plot (keeps category labels; avoids blank chart). */
|
|
@@ -3193,7 +3222,10 @@ function lineShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
3193
3222
|
var all = [];
|
|
3194
3223
|
series.forEach(function (se) { (se.values || []).forEach(function (v) { all.push(Number(v) || 0); }); });
|
|
3195
3224
|
var vmax = ec.max || Math.max.apply(null, all.concat([1]));
|
|
3196
|
-
|
|
3225
|
+
/* R2:类目标签带含在 h 内,禁画到图区外压 so-what */
|
|
3226
|
+
var labelH = 0.36;
|
|
3227
|
+
var baseY = y + Math.max(0.6, h - labelH);
|
|
3228
|
+
var plotH = Math.max(0.35, baseY - y - 0.2);
|
|
3197
3229
|
sh.push(shape('rect', x, baseY, w, 0.02, S.line));
|
|
3198
3230
|
var stepX = n > 1 ? w / (n - 1) : 0;
|
|
3199
3231
|
series.forEach(function (se, si) {
|
|
@@ -3213,7 +3245,7 @@ function lineShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
3213
3245
|
});
|
|
3214
3246
|
labels.forEach(function (lb, i) {
|
|
3215
3247
|
var px = x + (n > 1 ? i * stepX : w / 2);
|
|
3216
|
-
sh.push(txSp(px - 0.5, baseY + 0.
|
|
3248
|
+
sh.push(txSp(px - 0.5, baseY + 0.06, 1.0, labelH - 0.08,
|
|
3217
3249
|
[[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
3218
3250
|
});
|
|
3219
3251
|
}
|
|
@@ -3665,25 +3697,44 @@ function slidesOf(model, S) {
|
|
|
3665
3697
|
c.push(txSp(MX, CV.subtitleY, CW - 1, CV.subtitleH, [[{ t: model.subtitle || '', sz: 18, col: S.soft, font: S.font }]]));
|
|
3666
3698
|
slides.push(c);
|
|
3667
3699
|
|
|
3668
|
-
/* Agenda(>8
|
|
3700
|
+
/* Agenda(>8 条自动双列;>12 条自动分页;长标题截断+全称入 notes;列优先与 HTML 一致) */
|
|
3669
3701
|
var items = model.agenda || [];
|
|
3670
3702
|
if (items.length) {
|
|
3671
|
-
var
|
|
3672
|
-
|
|
3673
|
-
var
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
var
|
|
3680
|
-
var
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3703
|
+
var ROWS_PER_PAGE = 12;
|
|
3704
|
+
var agPages = [];
|
|
3705
|
+
for (var ai = 0; ai < items.length; ai += ROWS_PER_PAGE) agPages.push(items.slice(ai, ai + ROWS_PER_PAGE));
|
|
3706
|
+
agPages.forEach(function (pageItems, pi) {
|
|
3707
|
+
var ag = [];
|
|
3708
|
+
var sub = agPages.length > 1 ? '(' + (pi + 1) + '/' + agPages.length + ')' : '';
|
|
3709
|
+
head(ag, 'AGENDA', '报告大纲' + sub);
|
|
3710
|
+
var colN = pageItems.length > 8 ? 2 : 1;
|
|
3711
|
+
var perCol = Math.ceil(pageItems.length / colN) || 1;
|
|
3712
|
+
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP - 0.25) / Math.max(1, perCol));
|
|
3713
|
+
var numSz = rowH >= 0.85 ? 30 : (rowH >= 0.65 ? 22 : 18);
|
|
3714
|
+
var tSz = rowH >= 0.85 ? 16 : 14, dSz = rowH >= 0.85 ? 12 : 11;
|
|
3715
|
+
var agNotes = [];
|
|
3716
|
+
pageItems.forEach(function (it, i) {
|
|
3717
|
+
var col = Math.floor(i / perCol), row = i % perCol;
|
|
3718
|
+
var x = MX + col * (CW / colN), y = CONTENT_TOP + row * rowH;
|
|
3719
|
+
var titleBoxW = CW / colN - 1.15;
|
|
3720
|
+
var rawTitle = String(it[1] || '');
|
|
3721
|
+
var titleEstW = estTextH(rawTitle, titleBoxW, tSz, 1.2);
|
|
3722
|
+
var maxTitleH = rowH * 0.55;
|
|
3723
|
+
var title = rawTitle;
|
|
3724
|
+
if (titleEstW > maxTitleH) {
|
|
3725
|
+
var maxChars = Math.max(10, Math.floor(rawTitle.length * (maxTitleH / titleEstW)));
|
|
3726
|
+
if (rawTitle.length > maxChars) {
|
|
3727
|
+
title = rawTitle.slice(0, maxChars - 1) + '…';
|
|
3728
|
+
agNotes.push('条目 ' + it[0] + ' 全称:' + rawTitle);
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
ag.push(txSp(x, y, 0.9, Math.min(0.9, rowH), [[{ t: it[0], sz: numSz, b: 1, col: S.accent, font: S.font }]]));
|
|
3732
|
+
ag.push(txSp(x + 1.0, y + 0.03, titleBoxW, Math.min(0.95, rowH),
|
|
3733
|
+
[[{ t: title, sz: tSz, b: 1, col: S.ink, font: S.font }],
|
|
3734
|
+
[{ t: it[2] || '', sz: dSz, col: S.body, font: S.font }]], { lineSpacing: tSz + 5 }));
|
|
3735
|
+
});
|
|
3736
|
+
slides.push(ag);
|
|
3685
3737
|
});
|
|
3686
|
-
slides.push(ag);
|
|
3687
3738
|
}
|
|
3688
3739
|
|
|
3689
3740
|
/* 章节页 */
|
|
@@ -3769,12 +3820,13 @@ function slidesOf(model, S) {
|
|
|
3769
3820
|
{ t: p[1], sz: fz - 1, col: S.body, font: S.font }]]));
|
|
3770
3821
|
});
|
|
3771
3822
|
});
|
|
3823
|
+
/* R2:verdict 与 soWhat 共用 annotation 槽位——只画一个(verdict 优先) */
|
|
3772
3824
|
if (sec.verdict) {
|
|
3773
3825
|
var vR = regOf('exhibit', 'annotation') || { x: MX, y: PT.exhibit.soWhatY, w: CW, h: 0.62 };
|
|
3774
|
-
sh.push(shape('rect', vR.x, vR.y, vR.w, vR.h, S.accent));
|
|
3826
|
+
sh.push(shape('rect', vR.x, vR.y, vR.w, vR.h, S.accent, { name: 'tr:soWhat' }));
|
|
3775
3827
|
sh.push(txSp(vR.x + 0.22, vR.y + 0.06, vR.w - 0.44, vR.h - 0.12,
|
|
3776
3828
|
[[{ t: '结论 ', sz: 11, b: 1, col: S.onAccent, font: S.font, spc: 150 },
|
|
3777
|
-
{ t: sec.verdict, sz: 12.5, b: 1, col: S.onAccent, font: S.font }]], { anchor: 'ctr' }));
|
|
3829
|
+
{ t: sec.verdict, sz: 12.5, b: 1, col: S.onAccent, font: S.font }]], { anchor: 'ctr', name: 'tr:soWhat' }));
|
|
3778
3830
|
}
|
|
3779
3831
|
} else if (type === 'quote') {
|
|
3780
3832
|
var Q = PT.quote;
|
|
@@ -3807,7 +3859,6 @@ function slidesOf(model, S) {
|
|
|
3807
3859
|
} else if (type === 'donut') {
|
|
3808
3860
|
var dcn = sec.chart || {};
|
|
3809
3861
|
if (dcn.labels && dcn.values) donutChart(sh, dcn, S, dcn.colors || donutColors(model.style, S, model.theme), bodyBottom);
|
|
3810
|
-
if (sec.note) sh.push(txSp(MX, PT.note.y, CW, PT.note.h, [[{ t: sec.note, sz: 11, col: S.faint, font: S.font }]]));
|
|
3811
3862
|
} else if (type === 'heatmap') {
|
|
3812
3863
|
var H = PT.heatmap;
|
|
3813
3864
|
var hR = regOf('heatmap', 'primary', { bottom: bodyBottom }) || { x: MX, y: H.y, w: CW, h: bodyBottom - H.y };
|
|
@@ -3954,7 +4005,7 @@ function slidesOf(model, S) {
|
|
|
3954
4005
|
} else if (type === 'bar') {
|
|
3955
4006
|
var ch = sec.chart || {};
|
|
3956
4007
|
var dcols2 = (ch.colors || dataColors(model.style, model.theme));
|
|
3957
|
-
var botY = chartBottom(!!sec.soWhat, !!sec.footnote
|
|
4008
|
+
var botY = chartBottom(!!sec.soWhat, !!(sec.footnote || sec.note)) - 0.05;
|
|
3958
4009
|
var isHBar = ch.type === 'hbar';
|
|
3959
4010
|
var bRR = regOf('bar', isHBar ? 'hbar' : 'primary', { bottom: botY }) ||
|
|
3960
4011
|
{ x: isHBar ? MX : MX + PT.bar.chartX, y: isHBar ? PT.bar.hbarY0 : PT.bar.chartY,
|
|
@@ -3981,13 +4032,12 @@ function slidesOf(model, S) {
|
|
|
3981
4032
|
} else {
|
|
3982
4033
|
chartBlockShapes(sh, ch, S, bx, bRR.y, bw, Math.max(1.5, bRR.h), dcols2);
|
|
3983
4034
|
}
|
|
3984
|
-
if (sec.note) sh.push(txSp(MX, PT.note.y, CW, PT.note.h, [[{ t: sec.note, sz: 11, col: S.faint, font: S.font }]]));
|
|
3985
4035
|
} else if (type === 'twocol' || type === 'threecol') {
|
|
3986
4036
|
var ps2 = sec.paragraphs || [];
|
|
3987
4037
|
var nCol = (type === 'threecol') ? 3 : 2;
|
|
3988
4038
|
var gapC = (type === 'threecol') ? PT.research.col3Gap : PT.twocol.colGap;
|
|
3989
|
-
|
|
3990
|
-
|
|
4039
|
+
/* R3:多栏均分用版心全宽(regOf('twocol') 返回单栏宽,当总宽会压扁三栏) */
|
|
4040
|
+
var tcR = { x: MX, y: bodyY, w: CW, h: bodyBottom - bodyY };
|
|
3991
4041
|
var gC = cols(tcR.w, nCol, gapC);
|
|
3992
4042
|
var perC = Math.ceil(ps2.length / nCol);
|
|
3993
4043
|
var availC = tcR.h;
|
|
@@ -4183,7 +4233,7 @@ function slidesOf(model, S) {
|
|
|
4183
4233
|
var dStart = dgR.y;
|
|
4184
4234
|
var dEnd = dgR.y + dgR.h;
|
|
4185
4235
|
var nLay = Math.max(1, lys.length);
|
|
4186
|
-
var lh2 = Math.max(0.
|
|
4236
|
+
var lh2 = Math.max(0.5, Math.min(D.maxLayerH, (dEnd - dStart) / nLay - D.layerGap));
|
|
4187
4237
|
lys.forEach(function (lay, li) {
|
|
4188
4238
|
var y9 = dStart + li * (lh2 + D.layerGap);
|
|
4189
4239
|
var focus = lay[2] === 'focus';
|
|
@@ -4199,9 +4249,26 @@ function slidesOf(model, S) {
|
|
|
4199
4249
|
var ntt = isRec(nd) ? nd.t : nd;
|
|
4200
4250
|
var nds = isRec(nd) ? (nd.d || '') : '';
|
|
4201
4251
|
sh.push(shape('roundRect', x10, y9, nw2, lh2, ndacc ? S.soft : S.surface, { adj: 4000, line: S.line }));
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4252
|
+
/* R1: 注解不得「浮回」标题上。标题顶对齐,注解钳在标题下边;空间不足降级单框混排。 */
|
|
4253
|
+
var padXn = 0.12, padYn = 0.10;
|
|
4254
|
+
var innerWn = nw2 - padXn * 2;
|
|
4255
|
+
var titleHn = 0.32, noteHn = 0.34, gapTNn = 0.04;
|
|
4256
|
+
var needHn = titleHn + gapTNn + (nds ? noteHn : 0) + padYn * 2;
|
|
4257
|
+
if (!nds || lh2 >= needHn) {
|
|
4258
|
+
var tYn = y9 + padYn;
|
|
4259
|
+
sh.push(txSp(x10 + padXn, nds ? tYn : y9 + lh2 / 2 - 0.18, innerWn, titleHn,
|
|
4260
|
+
[[{ t: ntt, sz: nds ? 11 : 12.5, b: 1, col: ndacc ? S.accent : S.ink, font: S.font }]],
|
|
4261
|
+
{ anchor: 'ctr' }));
|
|
4262
|
+
if (nds) {
|
|
4263
|
+
var nYn = Math.max(tYn + titleHn + gapTNn, y9 + lh2 - padYn - noteHn);
|
|
4264
|
+
sh.push(txSp(x10 + padXn, nYn, innerWn, Math.min(noteHn, y9 + lh2 - padYn - nYn),
|
|
4265
|
+
[[{ t: nds, sz: 10, col: S.faint, font: S.font }]], { anchor: 't' }));
|
|
4266
|
+
}
|
|
4267
|
+
} else {
|
|
4268
|
+
sh.push(txSp(x10 + padXn, y9 + padYn * 0.5, innerWn, lh2 - padYn,
|
|
4269
|
+
[[{ t: ntt, sz: 11, b: 1, col: ndacc ? S.accent : S.ink, font: S.font }],
|
|
4270
|
+
[{ t: nds, sz: 9, col: S.faint, font: S.font }]], { anchor: 't', lineSpacing: 12 }));
|
|
4271
|
+
}
|
|
4205
4272
|
});
|
|
4206
4273
|
if (li < lys.length - 1) {
|
|
4207
4274
|
var cy2 = y9 + lh2 + D.layerGap / 2;
|
|
@@ -4211,10 +4278,14 @@ function slidesOf(model, S) {
|
|
|
4211
4278
|
}
|
|
4212
4279
|
});
|
|
4213
4280
|
if (sec.legend) {
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4281
|
+
/* R2:图例进图区底部(与 HTML .arch__legend 同源),禁用 PH-0.62 固定偏移 */
|
|
4282
|
+
var lgH2 = 0.28;
|
|
4283
|
+
var lgY2 = Math.max(dStart, bodyBottom - lgH2 - 0.02);
|
|
4284
|
+
var nLg2 = Math.max(1, sec.legend.length);
|
|
4285
|
+
var step2 = Math.min(2.4, CW / nLg2);
|
|
4286
|
+
sec.legend.forEach(function (lg2, li2) {
|
|
4287
|
+
sh.push(txSp(MX + CW - nLg2 * step2 + li2 * step2, lgY2, step2 - 0.05, lgH2,
|
|
4288
|
+
[[{ t: '● ' + lg2, sz: 10, col: S.faint, font: S.font }]]));
|
|
4218
4289
|
});
|
|
4219
4290
|
}
|
|
4220
4291
|
} else if (type === 'exhibit') {
|
|
@@ -4271,8 +4342,10 @@ function slidesOf(model, S) {
|
|
|
4271
4342
|
}
|
|
4272
4343
|
}
|
|
4273
4344
|
/* research 通用可选件:so-what 结论条 + 页脚来源行 + 待核实条(共用同一槽位) */
|
|
4274
|
-
|
|
4275
|
-
if (sec.
|
|
4345
|
+
/* R2:verdict 已占 annotation 槽位时跳过 soWhat,禁止同槽双条叠印 */
|
|
4346
|
+
if (sec.soWhat && !sec.verdict) soWhatBar(sh, sec.soWhat, S);
|
|
4347
|
+
/* R2:note 与 footnote 共用注释带末行(禁 note.y=6.55 压 so-what) */
|
|
4348
|
+
noteOrFootnote(sh, sec, S);
|
|
4276
4349
|
if (flagH) flagBar(sh, flagItems, S, flagY);
|
|
4277
4350
|
slides.push(sh);
|
|
4278
4351
|
});
|
|
@@ -4442,9 +4515,10 @@ function validateModel(model) {
|
|
|
4442
4515
|
}
|
|
4443
4516
|
var agMax = (M.model && M.model.agendaComfortMax) || 16;
|
|
4444
4517
|
if ((model.agenda || []).length > agMax) {
|
|
4445
|
-
warnings.push('agenda ' + model.agenda.length + ' 条超出单页舒适上限 ' + agMax + '
|
|
4518
|
+
warnings.push('agenda ' + model.agenda.length + ' 条超出单页舒适上限 ' + agMax + ',将自动分页');
|
|
4446
4519
|
}
|
|
4447
|
-
var
|
|
4520
|
+
var agPageCount = hasAgenda ? Math.ceil(model.agenda.length / 12) : 0;
|
|
4521
|
+
var pages = 1 + agPageCount + secs.length + 1; /* 封面+大纲(可多页)+章节+收尾 */
|
|
4448
4522
|
return { ok: missing.length === 0, missing: missing, warnings: warnings, pages: pages };
|
|
4449
4523
|
}
|
|
4450
4524
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"theme": "light",
|
|
5
5
|
"title": "TopMind × tms-skills",
|
|
6
6
|
"subtitle": "HTML + PPT 双交付 · 为正式商务演示而生",
|
|
7
|
-
"meta": "产品介绍 · 2026-09-26 · v0.1.
|
|
7
|
+
"meta": "产品介绍 · 2026-09-26 · v0.1.18",
|
|
8
8
|
"agenda": [
|
|
9
9
|
[
|
|
10
10
|
"01",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
]
|
|
165
165
|
}
|
|
166
166
|
],
|
|
167
|
-
"footnote": "包名 @topmindspace/tms-skills · 当前线 0.1.
|
|
167
|
+
"footnote": "包名 @topmindspace/tms-skills · 当前线 0.1.18(latest)",
|
|
168
168
|
"soWhat": "安装器与技能同仓同 tag——装一次,版本线对齐。"
|
|
169
169
|
},
|
|
170
170
|
{
|
|
@@ -555,4 +555,4 @@
|
|
|
555
555
|
]
|
|
556
556
|
]
|
|
557
557
|
}
|
|
558
|
-
}
|
|
558
|
+
}
|