@lemonppt/renderer 0.2.0 → 0.2.2

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 (72) hide show
  1. package/dist/client/client-render.js +65 -5401
  2. package/dist/client/editor-script.js +3355 -0
  3. package/dist/client/theme-echarts.js +65 -25
  4. package/dist/client-render.d.ts +1 -7
  5. package/dist/client-render.d.ts.map +1 -1
  6. package/dist/client-render.js +1 -11
  7. package/dist/client-render.js.map +1 -1
  8. package/dist/editor-script.d.ts +1 -1
  9. package/dist/editor-script.d.ts.map +1 -1
  10. package/dist/editor-script.js +80 -77
  11. package/dist/editor-script.js.map +1 -1
  12. package/dist/export-pdf.js +1 -1
  13. package/dist/export-pdf.js.map +1 -1
  14. package/dist/export-pptx.d.ts +1132 -2
  15. package/dist/export-pptx.d.ts.map +1 -1
  16. package/dist/export-pptx.js +1208 -19525
  17. package/dist/export-pptx.js.map +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/render-editor-data.d.ts +21 -0
  23. package/dist/render-editor-data.d.ts.map +1 -0
  24. package/dist/render-editor-data.js +1068 -0
  25. package/dist/render-editor-data.js.map +1 -0
  26. package/dist/render.d.ts +0 -2
  27. package/dist/render.d.ts.map +1 -1
  28. package/dist/render.js +7 -323
  29. package/dist/render.js.map +1 -1
  30. package/dist/theme01-pptx.d.ts +12 -0
  31. package/dist/theme01-pptx.d.ts.map +1 -0
  32. package/dist/theme01-pptx.js +2954 -0
  33. package/dist/theme01-pptx.js.map +1 -0
  34. package/dist/theme02-pptx.d.ts +5 -0
  35. package/dist/theme02-pptx.d.ts.map +1 -0
  36. package/dist/theme02-pptx.js +1063 -0
  37. package/dist/theme02-pptx.js.map +1 -0
  38. package/dist/theme03-pptx.d.ts +5 -0
  39. package/dist/theme03-pptx.d.ts.map +1 -0
  40. package/dist/theme03-pptx.js +3279 -0
  41. package/dist/theme03-pptx.js.map +1 -0
  42. package/dist/theme04-pptx.d.ts +6 -0
  43. package/dist/theme04-pptx.d.ts.map +1 -0
  44. package/dist/theme04-pptx.js +5496 -0
  45. package/dist/theme04-pptx.js.map +1 -0
  46. package/dist/theme05-pptx.d.ts +5 -0
  47. package/dist/theme05-pptx.d.ts.map +1 -0
  48. package/dist/theme05-pptx.js +3152 -0
  49. package/dist/theme05-pptx.js.map +1 -0
  50. package/dist/theme06-pptx.d.ts +124 -0
  51. package/dist/theme06-pptx.d.ts.map +1 -0
  52. package/dist/theme06-pptx.js +8154 -0
  53. package/dist/theme06-pptx.js.map +1 -0
  54. package/dist/theme07-pptx.d.ts +49 -0
  55. package/dist/theme07-pptx.d.ts.map +1 -0
  56. package/dist/theme07-pptx.js +2579 -0
  57. package/dist/theme07-pptx.js.map +1 -0
  58. package/dist/theme08-pptx.d.ts +19 -0
  59. package/dist/theme08-pptx.d.ts.map +1 -0
  60. package/dist/theme08-pptx.js +1411 -0
  61. package/dist/theme08-pptx.js.map +1 -0
  62. package/dist/theme09-pptx.d.ts +18 -0
  63. package/dist/theme09-pptx.d.ts.map +1 -0
  64. package/dist/theme09-pptx.js +1513 -0
  65. package/dist/theme09-pptx.js.map +1 -0
  66. package/dist/theme10-pptx.d.ts +18 -0
  67. package/dist/theme10-pptx.d.ts.map +1 -0
  68. package/dist/theme10-pptx.js +2889 -0
  69. package/dist/theme10-pptx.js.map +1 -0
  70. package/package.json +7 -6
  71. package/templates/editor.html +580 -0
  72. package/templates/editor.js +222 -0
@@ -0,0 +1,1063 @@
1
+ // lemonPPT - AI-powered presentation generation
2
+ // Copyright (c) 2026 lemonforme
3
+ // SPDX-License-Identifier: AGPL-3.0-or-later
4
+ //
5
+ // theme02 深色霓虹科技风 — PPTX 版式专属渲染器(从 export-pptx.ts 抽出)。
6
+ // 共享基础设施(全局 helper + 通用渲染器 + 类型 + theme02 局部 helper/const)从 export-pptx.ts 导入;
7
+ // theme01 通用渲染器从 theme01-pptx.ts 复用。注册通过 registerTheme02Renderers 回调注入。
8
+ import { addKicker, addTitle, COLORS, FONTS, addTheme02Card, renderInsightPanel, renderTableOfContentsV1, renderImageV1, renderTestimonialV1, renderProcessV1, T2_CHART, addImageMaybe, renderTheme01MetricBig, renderChartFunnel, renderTheme01ChartDonut, renderChartHeatmap, renderChartRadar, renderChartGauge, renderStatsV1, renderTeamV1, renderTimelineV1, renderFeatureV1, renderTheme01GalleryV1, renderPricingV1, renderTheme01RoadmapV1, renderSwotV1, renderFaqV1, renderTheme01FilmstripV1, renderPartnersV1, renderPestV1, renderTheme01TableV1, renderTheme01TagsV1 } from './export-pptx.js';
9
+ import { renderChartV1, renderContentV1, renderCoverV1, renderClosing, renderComparisonV1 } from './export-pptx.js';
10
+ function renderTheme02ChapterV1(slide, props) {
11
+ if (props.kicker)
12
+ addKicker(slide, props.kicker);
13
+ if (props.title)
14
+ addTitle(slide, props.title);
15
+ if (props.number) {
16
+ slide.addText(props.number, {
17
+ x: 0.8, y: 2.4, w: 8.4, h: 1.0,
18
+ fontSize: 72, color: COLORS.accent, bold: true, align: 'left',
19
+ fontFace: FONTS.mono,
20
+ });
21
+ }
22
+ if (props.subtitle) {
23
+ slide.addText(props.subtitle, {
24
+ x: 0.8, y: props.number ? 3.6 : 2.4, w: 8.4, h: 0.8,
25
+ fontSize: 22, color: COLORS.secondary, align: 'left', valign: 'top',
26
+ fontFace: FONTS.body,
27
+ });
28
+ }
29
+ }
30
+ function renderTheme02ChapterV2(slide, props) {
31
+ addTheme02Card(slide, 0.8, 1.0, 8.4, 3.8, 0.2);
32
+ if (props.kicker)
33
+ addKicker(slide, props.kicker, 0.8, 1.2);
34
+ if (props.number) {
35
+ slide.addText(props.number, {
36
+ x: 0.8, y: 1.8, w: 8.4, h: 1.4,
37
+ fontSize: 96, color: COLORS.accent, bold: true, align: 'center',
38
+ fontFace: FONTS.mono,
39
+ });
40
+ }
41
+ if (props.title) {
42
+ slide.addText(props.title, {
43
+ x: 0.8, y: props.number ? 3.3 : 1.8, w: 8.4, h: 0.9,
44
+ fontSize: 48, color: COLORS.primary, bold: true, align: 'center', valign: 'top',
45
+ fontFace: FONTS.heading,
46
+ });
47
+ }
48
+ if (props.subtitle) {
49
+ slide.addText(props.subtitle, {
50
+ x: 1.2, y: props.title ? 4.3 : 3.0, w: 7.6, h: 0.6,
51
+ fontSize: 20, color: COLORS.secondary, align: 'center', valign: 'top',
52
+ fontFace: FONTS.body,
53
+ });
54
+ }
55
+ }
56
+ function renderTheme02QuoteV2(slide, props) {
57
+ addTheme02Card(slide, 0.9, 1.4, 8.2, 3.2, 0.15);
58
+ slide.addText(`“${props.quote}”`, {
59
+ x: 1.1, y: 1.7, w: 7.8, h: 2.0,
60
+ fontSize: 32, color: COLORS.primary, bold: true, align: 'center', valign: 'middle',
61
+ fontFace: FONTS.heading,
62
+ });
63
+ const attribution = [props.author, props.role, props.source].filter(Boolean).join(' · ');
64
+ if (attribution) {
65
+ slide.addText(attribution, {
66
+ x: 1.1, y: 3.85, w: 7.8, h: 0.4,
67
+ fontSize: 16, color: COLORS.secondary, align: 'center',
68
+ fontFace: FONTS.mono,
69
+ });
70
+ }
71
+ }
72
+ function renderTheme02NumberShowcaseV1(slide, props) {
73
+ addTheme02Card(slide, 1.2, 1.1, 7.6, 3.8, 0.2);
74
+ if (props.kicker)
75
+ addKicker(slide, props.kicker, 0.8, 1.0);
76
+ if (props.title) {
77
+ slide.addText(props.title, {
78
+ x: 0.8, y: 1.5, w: 8.4, h: 0.7,
79
+ fontSize: 36, color: COLORS.primary, bold: true, align: 'center', valign: 'top',
80
+ fontFace: FONTS.heading,
81
+ });
82
+ }
83
+ const valueY = props.title ? 2.35 : 1.7;
84
+ slide.addText(props.value ?? '', {
85
+ x: 0.8, y: valueY, w: 8.4, h: 1.5,
86
+ fontSize: 80, color: COLORS.accent, bold: true, align: 'center', valign: 'top',
87
+ fontFace: FONTS.mono,
88
+ });
89
+ if (props.unit) {
90
+ slide.addText(props.unit, {
91
+ x: 0.8, y: valueY + 1.35, w: 8.4, h: 0.35,
92
+ fontSize: 22, color: COLORS.secondary, align: 'center',
93
+ fontFace: FONTS.mono,
94
+ });
95
+ }
96
+ if (props.description) {
97
+ slide.addText(props.description, {
98
+ x: 1.2, y: props.unit ? valueY + 1.85 : valueY + 1.55, w: 7.6, h: 0.7,
99
+ fontSize: 18, color: COLORS.secondary, align: 'center', valign: 'top',
100
+ fontFace: FONTS.body,
101
+ });
102
+ }
103
+ if (props.footnote) {
104
+ slide.addText(props.footnote, {
105
+ x: 0.8, y: 5.35, w: 8.4, h: 0.25,
106
+ fontSize: 11, color: COLORS.secondary, align: 'center',
107
+ fontFace: FONTS.mono,
108
+ });
109
+ }
110
+ }
111
+ function renderTheme02ChartV1(slide, props) {
112
+ const adapted = {
113
+ ...props,
114
+ type: props.type === 'area' ? 'line' : props.type,
115
+ };
116
+ renderChartV1(slide, adapted);
117
+ }
118
+ function renderTheme02ContentV1(slide, props) {
119
+ renderContentV1(slide, {
120
+ kicker: props.kicker,
121
+ title: props.title ?? '',
122
+ points: props.bullets || [],
123
+ });
124
+ }
125
+ function renderTheme02DeltaV1(slide, props) {
126
+ const hasInsight = props.showInsight !== false && !!props.insight && (!!props.insight.value || !!props.insight.label || !!props.insight.description);
127
+ const mainW = hasInsight ? 6.8 : 8.4;
128
+ const startX = 0.8;
129
+ if (props.kicker)
130
+ addKicker(slide, props.kicker, startX);
131
+ if (props.title)
132
+ addTitle(slide, props.title, startX, 1.3, mainW);
133
+ if (props.subtitle) {
134
+ slide.addText(props.subtitle, {
135
+ x: startX, y: 2.05, w: mainW, h: 0.35,
136
+ fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top',
137
+ fontFace: FONTS.body,
138
+ });
139
+ }
140
+ const items = (props.items || []).slice(0, 6);
141
+ if (items.length === 0) {
142
+ slide.addText('(暂无对照数据)', {
143
+ x: 2, y: 3.2, w: 6, h: 0.8,
144
+ fontSize: 18, color: COLORS.secondary, align: 'center', valign: 'middle',
145
+ fontFace: FONTS.body,
146
+ });
147
+ return;
148
+ }
149
+ const cols = Math.min(items.length, 3);
150
+ const rows = Math.ceil(items.length / cols);
151
+ const cardW = (mainW - 0.25 * (cols - 1)) / cols;
152
+ const cardH = rows === 1 ? 2.6 : 1.25;
153
+ const startY = 2.5;
154
+ items.forEach((item, index) => {
155
+ const col = index % cols;
156
+ const row = Math.floor(index / cols);
157
+ const x = startX + col * (cardW + 0.25);
158
+ const y = startY + row * (cardH + 0.25);
159
+ const previous = Number(item.previous) || 0;
160
+ const current = Number(item.current) || 0;
161
+ const delta = previous > 0 ? ((current - previous) / previous) * 100 : 0;
162
+ const positive = delta >= 0;
163
+ addTheme02Card(slide, x, y, cardW, cardH, 0.1);
164
+ slide.addText(item.label || '', {
165
+ x: x + 0.12, y: y + 0.1, w: cardW - 0.24, h: 0.35,
166
+ fontSize: 14, color: COLORS.secondary, align: 'left', valign: 'top',
167
+ fontFace: FONTS.body,
168
+ });
169
+ slide.addText(`${current}${item.unit ? ` ${item.unit}` : ''}`, {
170
+ x: x + 0.12, y: y + 0.5, w: cardW - 0.24, h: 0.45,
171
+ fontSize: 24, color: positive ? COLORS.accent : 'FF6B6B', bold: true, align: 'left', valign: 'top',
172
+ fontFace: FONTS.heading,
173
+ });
174
+ slide.addText(`${positive ? '+' : ''}${delta.toFixed(1)}%`, {
175
+ x: x + 0.12, y: y + 1.0, w: cardW - 0.24, h: 0.3,
176
+ fontSize: 12, color: positive ? COLORS.accent : 'FF6B6B', align: 'left', valign: 'top',
177
+ fontFace: FONTS.mono,
178
+ });
179
+ });
180
+ if (props.footnote) {
181
+ slide.addText(props.footnote, {
182
+ x: startX, y: 5.75, w: mainW, h: 0.25,
183
+ fontSize: 11, color: COLORS.secondary, align: 'left',
184
+ fontFace: FONTS.mono,
185
+ });
186
+ }
187
+ if (hasInsight) {
188
+ renderInsightPanel(slide, props.insight, 8.0, 2.3, 2.4, 3.2);
189
+ }
190
+ }
191
+ function renderTheme02TableOfContentsV1(slide, props) {
192
+ renderTableOfContentsV1(slide, {
193
+ title: props.title ?? '目录',
194
+ kicker: props.subtitle,
195
+ items: (props.items || []).map((item) => item.title),
196
+ });
197
+ }
198
+ function renderTheme02ImageV1(slide, props) {
199
+ renderImageV1(slide, {
200
+ title: props.title ?? '',
201
+ subtitle: props.subtitle,
202
+ imageUrl: props.image,
203
+ });
204
+ if (props.caption) {
205
+ slide.addText(props.caption, {
206
+ x: 0.8, y: 5.25, w: 8.4, h: 0.3,
207
+ fontSize: 11, color: COLORS.secondary, align: 'left',
208
+ fontFace: FONTS.mono,
209
+ });
210
+ }
211
+ }
212
+ function renderTheme02QuoteV1(slide, props) {
213
+ renderTestimonialV1(slide, {
214
+ quote: props.quote,
215
+ author: props.author,
216
+ role: props.role,
217
+ avatarUrl: props.avatar,
218
+ });
219
+ }
220
+ function renderTheme02BentoV1(slide, props) {
221
+ const hasInsight = props.showInsight !== false && !!props.insight && (!!props.insight.value || !!props.insight.label || !!props.insight.description);
222
+ const mainW = hasInsight ? 6.8 : 8.4;
223
+ const startX = 0.8;
224
+ if (props.kicker)
225
+ addKicker(slide, props.kicker, startX);
226
+ if (props.title)
227
+ addTitle(slide, props.title, startX, 1.3, mainW);
228
+ if (props.subtitle) {
229
+ slide.addText(props.subtitle, {
230
+ x: startX, y: 2.05, w: mainW, h: 0.35,
231
+ fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top',
232
+ fontFace: FONTS.body,
233
+ });
234
+ }
235
+ const items = (props.items || []).slice(0, 6);
236
+ if (items.length === 0) {
237
+ slide.addText('(暂无数据)', {
238
+ x: 2, y: 3.2, w: 6, h: 0.8,
239
+ fontSize: 18, color: COLORS.secondary, align: 'center', valign: 'middle',
240
+ fontFace: FONTS.body,
241
+ });
242
+ return;
243
+ }
244
+ const cardW = (mainW - 0.4) / 2;
245
+ const positions = [
246
+ { x: startX, y: 2.5, w: cardW, h: 1.3 },
247
+ { x: startX + cardW + 0.2, y: 2.5, w: cardW, h: 1.3 },
248
+ { x: startX, y: 4.0, w: cardW, h: 1.3 },
249
+ { x: startX + cardW + 0.2, y: 4.0, w: cardW, h: 1.3 },
250
+ { x: startX, y: 5.5, w: cardW, h: 1.3 },
251
+ { x: startX + cardW + 0.2, y: 5.5, w: cardW, h: 1.3 },
252
+ ];
253
+ items.forEach((item, index) => {
254
+ const pos = positions[index];
255
+ if (!pos)
256
+ return;
257
+ addTheme02Card(slide, pos.x, pos.y, pos.w, pos.h, 0.1);
258
+ const valueText = `${item.value}${item.unit ? ` ${item.unit}` : ''}`;
259
+ slide.addText(valueText, {
260
+ x: pos.x + 0.12, y: pos.y + 0.12, w: pos.w - 0.24, h: 0.45,
261
+ fontSize: 24, color: COLORS.primary, bold: true, align: 'left', valign: 'top',
262
+ fontFace: FONTS.heading,
263
+ });
264
+ slide.addText(item.label, {
265
+ x: pos.x + 0.12, y: pos.y + 0.62, w: pos.w - 0.24, h: 0.35,
266
+ fontSize: 12, color: COLORS.secondary, align: 'left', valign: 'top',
267
+ fontFace: FONTS.body,
268
+ });
269
+ });
270
+ if (hasInsight) {
271
+ renderInsightPanel(slide, props.insight, 8.0, 2.3, 2.4, 3.2);
272
+ }
273
+ }
274
+ function renderTheme02ProcessV1(slide, props) {
275
+ const steps = (props.steps || []).map((s) => s.title || '').filter(Boolean);
276
+ renderProcessV1(slide, {
277
+ kicker: props.kicker,
278
+ title: props.title,
279
+ steps,
280
+ });
281
+ }
282
+ function renderTheme02ProgressV1(slide, props) {
283
+ if (props.kicker)
284
+ addKicker(slide, props.kicker);
285
+ if (props.title)
286
+ addTitle(slide, props.title);
287
+ if (props.subtitle) {
288
+ slide.addText(props.subtitle, {
289
+ x: 0.8, y: 2.05, w: 8.4, h: 0.35,
290
+ fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top',
291
+ fontFace: FONTS.body,
292
+ });
293
+ }
294
+ const items = (props.items || []).slice(0, 6);
295
+ if (items.length === 0) {
296
+ slide.addText('(暂无进度数据)', {
297
+ x: 2, y: 3.2, w: 6, h: 0.8,
298
+ fontSize: 18, color: COLORS.secondary, align: 'center', valign: 'middle',
299
+ fontFace: FONTS.body,
300
+ });
301
+ return;
302
+ }
303
+ let y = 2.5;
304
+ items.forEach((item) => {
305
+ const value = Number(item.value) || 0;
306
+ const max = Number(item.max) || 100;
307
+ const pct = max > 0 ? Math.min(100, (value / max) * 100) : 0;
308
+ slide.addText(item.label || '', {
309
+ x: 0.8, y, w: 5.0, h: 0.3,
310
+ fontSize: 14, color: COLORS.primary, align: 'left', valign: 'top',
311
+ fontFace: FONTS.body,
312
+ });
313
+ slide.addText(`${value}${item.unit ? ` ${item.unit}` : ''} (${pct.toFixed(1)}%)`, {
314
+ x: 5.8, y, w: 3.4, h: 0.3,
315
+ fontSize: 14, color: COLORS.accent, bold: true, align: 'right', valign: 'top',
316
+ fontFace: FONTS.mono,
317
+ });
318
+ slide.addShape('rect', {
319
+ x: 0.8, y: y + 0.35, w: 8.4, h: 0.12,
320
+ fill: { color: COLORS.light },
321
+ });
322
+ slide.addShape('rect', {
323
+ x: 0.8, y: y + 0.35, w: 8.4 * (pct / 100), h: 0.12,
324
+ fill: { color: COLORS.accent },
325
+ });
326
+ y += 0.65;
327
+ });
328
+ }
329
+ function renderTheme02FeatureV2(slide, props) {
330
+ const x = 0.8;
331
+ const w = 8.4;
332
+ if (props.kicker)
333
+ addKicker(slide, props.kicker, x);
334
+ if (props.title)
335
+ addTitle(slide, props.title, x, 1.25, w);
336
+ if (props.subtitle)
337
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.4, fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
338
+ const features = (props.features || []).slice(0, 6);
339
+ if (features.length === 0)
340
+ return;
341
+ const cols = 3;
342
+ const rows = Math.ceil(features.length / cols);
343
+ const cardW = (w - 0.4 * (cols - 1)) / cols;
344
+ const cardH = rows >= 2 ? 1.25 : 2.2;
345
+ const startY = 2.55;
346
+ features.forEach((f, i) => {
347
+ const c = i % cols;
348
+ const r = Math.floor(i / cols);
349
+ const cx = x + c * (cardW + 0.4);
350
+ const cy = startY + r * (cardH + 0.28);
351
+ addTheme02Card(slide, cx, cy, cardW, cardH, 0.12);
352
+ let ty = cy + 0.16;
353
+ if (f.icon) {
354
+ slide.addText(f.icon, { x: cx + 0.22, y: ty, w: cardW - 0.44, h: 0.38, fontSize: 22, align: 'left', valign: 'top', fontFace: FONTS.body });
355
+ ty += 0.44;
356
+ }
357
+ slide.addText(f.title || '', { x: cx + 0.22, y: ty, w: cardW - 0.44, h: 0.36, fontSize: 15, bold: true, color: COLORS.primary, align: 'left', valign: 'top', fontFace: FONTS.heading });
358
+ ty += 0.38;
359
+ if (f.desc)
360
+ slide.addText(f.desc, { x: cx + 0.22, y: ty, w: cardW - 0.44, h: cardH - (ty - cy) - 0.12, fontSize: 11, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
361
+ });
362
+ }
363
+ function renderTheme02ChecklistV1(slide, props) {
364
+ const x = 0.8;
365
+ const w = 8.4;
366
+ if (props.kicker)
367
+ addKicker(slide, props.kicker, x);
368
+ if (props.title)
369
+ addTitle(slide, props.title, x, 1.25, w);
370
+ if (props.subtitle)
371
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.4, fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
372
+ const items = (props.items || []).slice(0, 8);
373
+ if (items.length === 0)
374
+ return;
375
+ let y = 2.65;
376
+ const rowH = Math.min(0.5, (5.05 - 2.65) / items.length);
377
+ items.forEach((it) => {
378
+ slide.addText('✓', { x, y, w: 0.42, h: rowH, fontSize: 18, bold: true, color: COLORS.accent, align: 'center', valign: 'middle', fontFace: FONTS.body });
379
+ slide.addText(it.text || '', { x: x + 0.55, y, w: w - 0.55, h: rowH, fontSize: 16, bold: true, color: COLORS.primary, align: 'left', valign: 'middle', fontFace: FONTS.heading });
380
+ if (it.note && items.length <= 5)
381
+ slide.addText(it.note, { x: x + 0.55, y: y + rowH - 0.22, w: w - 0.55, h: 0.2, fontSize: 11, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
382
+ y += rowH + 0.05;
383
+ });
384
+ }
385
+ function renderTheme02StepsV1(slide, props) {
386
+ const x = 0.8;
387
+ const w = 8.4;
388
+ if (props.kicker)
389
+ addKicker(slide, props.kicker, x);
390
+ if (props.title)
391
+ addTitle(slide, props.title, x, 1.25, w);
392
+ if (props.subtitle)
393
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.4, fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
394
+ const steps = (props.steps || []).slice(0, 6);
395
+ if (steps.length === 0)
396
+ return;
397
+ const cols = 3;
398
+ const rows = Math.ceil(steps.length / cols);
399
+ const cardW = (w - 0.4 * (cols - 1)) / cols;
400
+ const cardH = rows >= 2 ? 1.4 : 2.4;
401
+ const startY = 2.6;
402
+ steps.forEach((s, i) => {
403
+ const c = i % cols;
404
+ const r = Math.floor(i / cols);
405
+ const cx = x + c * (cardW + 0.4);
406
+ const cy = startY + r * (cardH + 0.28);
407
+ addTheme02Card(slide, cx, cy, cardW, cardH, 0.12);
408
+ slide.addText(String(i + 1), { x: cx + 0.2, y: cy + 0.16, w: 0.6, h: 0.5, fontSize: 22, bold: true, color: COLORS.accent, align: 'left', valign: 'top', fontFace: FONTS.heading });
409
+ slide.addText(s.title || '', { x: cx + 0.2, y: cy + 0.72, w: cardW - 0.4, h: 0.4, fontSize: 15, bold: true, color: COLORS.primary, align: 'left', valign: 'top', fontFace: FONTS.heading });
410
+ if (s.desc)
411
+ slide.addText(s.desc, { x: cx + 0.2, y: cy + 1.12, w: cardW - 0.4, h: cardH - 1.2, fontSize: 11, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
412
+ });
413
+ }
414
+ function renderTheme02CardGridV1(slide, props) {
415
+ const x = 0.8;
416
+ const w = 8.4;
417
+ if (props.kicker)
418
+ addKicker(slide, props.kicker, x);
419
+ if (props.title)
420
+ addTitle(slide, props.title, x, 1.25, w);
421
+ if (props.subtitle)
422
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.4, fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
423
+ const cards = (props.cards || []).slice(0, 9);
424
+ if (cards.length === 0)
425
+ return;
426
+ const cols = 3;
427
+ const rows = Math.ceil(cards.length / cols);
428
+ const cardW = (w - 0.36 * (cols - 1)) / cols;
429
+ const cardH = (5.05 - 2.55) / rows - 0.28;
430
+ const startY = 2.55;
431
+ cards.forEach((cd, i) => {
432
+ const c = i % cols;
433
+ const r = Math.floor(i / cols);
434
+ const cx = x + c * (cardW + 0.36);
435
+ const cy = startY + r * (cardH + 0.28);
436
+ addTheme02Card(slide, cx, cy, cardW, cardH, 0.12);
437
+ let ty = cy + 0.16;
438
+ if (cd.tag) {
439
+ slide.addText(cd.tag, { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.26, fontSize: 11, bold: true, color: COLORS.accent, align: 'left', valign: 'top', fontFace: FONTS.mono });
440
+ ty += 0.32;
441
+ }
442
+ slide.addText(cd.title || '', { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.4, fontSize: 15, bold: true, color: COLORS.primary, align: 'left', valign: 'top', fontFace: FONTS.heading });
443
+ ty += 0.42;
444
+ if (cd.desc)
445
+ slide.addText(cd.desc, { x: cx + 0.2, y: ty, w: cardW - 0.4, h: cardH - (ty - cy) - 0.12, fontSize: 11, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
446
+ });
447
+ }
448
+ function renderTheme02HighlightV1(slide, props) {
449
+ const x = 0.8;
450
+ const w = 8.4;
451
+ if (props.kicker)
452
+ slide.addText(props.kicker, { x, y: 1.5, w, h: 0.4, fontSize: 14, bold: true, color: COLORS.accent, align: 'center', valign: 'top', fontFace: FONTS.mono });
453
+ if (props.title)
454
+ slide.addText(props.title, { x, y: 2.0, w, h: 0.4, fontSize: 18, bold: true, color: COLORS.secondary, align: 'center', valign: 'top', fontFace: FONTS.heading });
455
+ if (props.statement)
456
+ slide.addText(props.statement, { x: x + 0.4, y: 2.5, w: w - 0.8, h: 1.8, fontSize: 30, bold: true, color: COLORS.primary, align: 'center', valign: 'middle', fontFace: FONTS.heading });
457
+ if (props.footnote)
458
+ slide.addText(props.footnote, { x, y: 4.5, w, h: 0.4, fontSize: 14, color: COLORS.secondary, align: 'center', valign: 'top', fontFace: FONTS.body });
459
+ }
460
+ function renderTheme02ComparisonV2(slide, props) {
461
+ const x = 0.8;
462
+ const w = 8.4;
463
+ if (props.kicker)
464
+ addKicker(slide, props.kicker, x);
465
+ if (props.title)
466
+ addTitle(slide, props.title, x, 1.2, w);
467
+ if (props.subtitle)
468
+ slide.addText(props.subtitle, { x, y: 1.95, w, h: 0.4, fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
469
+ const cols = (props.columns || []).slice(0, 2);
470
+ if (cols.length === 0)
471
+ return;
472
+ const colW = (w - 0.4) / 2;
473
+ const startY = 2.5;
474
+ const colH = 2.4;
475
+ cols.forEach((col, i) => {
476
+ const cx = x + i * (colW + 0.4);
477
+ addTheme02Card(slide, cx, startY, colW, colH, 0.12);
478
+ slide.addText(col.title || '', { x: cx + 0.25, y: startY + 0.2, w: colW - 0.5, h: 0.4, fontSize: 18, bold: true, color: i === 1 ? COLORS.accent : COLORS.primary, align: 'left', valign: 'top', fontFace: FONTS.heading });
479
+ const points = (col.points || []).slice(0, 6);
480
+ let py = startY + 0.75;
481
+ const ph = (colH - 0.95) / Math.max(points.length, 1);
482
+ points.forEach((p) => {
483
+ slide.addText('• ' + p, { x: cx + 0.25, y: py, w: colW - 0.5, h: ph, fontSize: 13, color: COLORS.primary, align: 'left', valign: 'top', fontFace: FONTS.body });
484
+ py += ph;
485
+ });
486
+ });
487
+ }
488
+ function renderTheme02MatrixV1(slide, props) {
489
+ const x = 0.8;
490
+ const w = 8.4;
491
+ if (props.kicker)
492
+ addKicker(slide, props.kicker, x);
493
+ if (props.title)
494
+ addTitle(slide, props.title, x, 1.2, w);
495
+ if (props.subtitle)
496
+ slide.addText(props.subtitle, { x, y: 1.95, w, h: 0.35, fontSize: 15, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
497
+ const startY = 2.5;
498
+ const gridH = 2.4;
499
+ const gridW = w - 0.5;
500
+ const qColors = ['00E5B0', 'FFD166', '00B4FF', 'FF6B6B'];
501
+ const quads = props.quadrants || [];
502
+ for (let qi = 0; qi < 4; qi++) {
503
+ const c = qi % 2;
504
+ const r = Math.floor(qi / 2);
505
+ const qx = x + 0.5 + c * (gridW / 2 + 0.1);
506
+ const qy = startY + r * (gridH / 2 + 0.12);
507
+ addTheme02Card(slide, qx, qy, gridW / 2 - 0.05, gridH / 2 - 0.06, 0.1);
508
+ const q = quads[qi];
509
+ if (q) {
510
+ slide.addText(q.title || '', { x: qx + 0.18, y: qy + 0.12, w: gridW / 2 - 0.36, h: 0.35, fontSize: 15, bold: true, color: qColors[qi] || COLORS.accent, align: 'left', valign: 'top', fontFace: FONTS.heading });
511
+ if (q.desc)
512
+ slide.addText(q.desc, { x: qx + 0.18, y: qy + 0.5, w: gridW / 2 - 0.36, h: gridH / 2 - 0.6, fontSize: 11, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
513
+ }
514
+ }
515
+ if (props.axisY)
516
+ slide.addText(props.axisY, { x: x - 0.05, y: startY + gridH / 2 - 0.2, w: 0.5, h: 0.4, fontSize: 12, color: COLORS.secondary, align: 'center', valign: 'middle', fontFace: FONTS.mono });
517
+ if (props.axisX)
518
+ slide.addText(props.axisX, { x: x + 0.5, y: startY + gridH + 0.02, w: gridW, h: 0.3, fontSize: 12, color: COLORS.secondary, align: 'center', valign: 'top', fontFace: FONTS.mono });
519
+ }
520
+ function renderTheme02StatGridV1(slide, props) {
521
+ const x = 0.8;
522
+ const w = 8.4;
523
+ if (props.kicker)
524
+ addKicker(slide, props.kicker, x);
525
+ if (props.title)
526
+ addTitle(slide, props.title, x, 1.25, w);
527
+ if (props.subtitle)
528
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.4, fontSize: 16, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.body });
529
+ const stats = (props.stats || []).slice(0, 8);
530
+ if (stats.length === 0)
531
+ return;
532
+ const cols = 4;
533
+ const rows = Math.ceil(stats.length / cols);
534
+ const cardW = (w - 0.36 * (cols - 1)) / cols;
535
+ const cardH = (5.05 - 2.55) / rows - 0.26;
536
+ const startY = 2.55;
537
+ stats.forEach((s, i) => {
538
+ const c = i % cols;
539
+ const r = Math.floor(i / cols);
540
+ const cx = x + c * (cardW + 0.36);
541
+ const cy = startY + r * (cardH + 0.26);
542
+ addTheme02Card(slide, cx, cy, cardW, cardH, 0.1);
543
+ let ty = cy + 0.16;
544
+ const valStr = (s.value || '') + (s.unit ? ' ' + s.unit : '');
545
+ slide.addText(valStr, { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.5, fontSize: 26, bold: true, color: COLORS.accent, align: 'left', valign: 'top', fontFace: FONTS.heading });
546
+ ty += 0.55;
547
+ if (s.label)
548
+ slide.addText(s.label, { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.3, fontSize: 12, color: COLORS.primary, align: 'left', valign: 'top', fontFace: FONTS.body });
549
+ ty += 0.32;
550
+ if (s.delta)
551
+ slide.addText(s.delta, { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.3, fontSize: 12, bold: true, color: COLORS.secondary, align: 'left', valign: 'top', fontFace: FONTS.mono });
552
+ });
553
+ }
554
+ function renderTheme02CoverV3(slide, props) {
555
+ const x = 0.8;
556
+ const w = 8.4;
557
+ if (props.kicker)
558
+ slide.addText(props.kicker, { x, y: 1.7, w, h: 0.4, fontSize: 14, bold: true, color: COLORS.accent, align: 'center', valign: 'top', fontFace: FONTS.mono });
559
+ if (props.title)
560
+ slide.addText(props.title, { x, y: 2.2, w, h: 1.6, fontSize: 44, bold: true, color: COLORS.primary, align: 'center', valign: 'middle', fontFace: FONTS.heading });
561
+ if (props.subtitle)
562
+ slide.addText(props.subtitle, { x: x + 0.5, y: 3.9, w: w - 1, h: 0.8, fontSize: 18, color: COLORS.secondary, align: 'center', valign: 'top', fontFace: FONTS.body });
563
+ if (props.date)
564
+ slide.addText(props.date, { x, y: 4.8, w, h: 0.4, fontSize: 13, color: COLORS.secondary, align: 'center', valign: 'top', fontFace: FONTS.mono });
565
+ }
566
+ function renderTheme02ClosingV2(slide, props) {
567
+ const x = 0.8;
568
+ const w = 8.4;
569
+ if (props.kicker)
570
+ slide.addText(props.kicker, { x, y: 1.9, w, h: 0.4, fontSize: 14, bold: true, color: COLORS.accent, align: 'center', valign: 'top', fontFace: FONTS.mono });
571
+ if (props.title)
572
+ slide.addText(props.title, { x, y: 2.4, w, h: 1.4, fontSize: 40, bold: true, color: COLORS.primary, align: 'center', valign: 'middle', fontFace: FONTS.heading });
573
+ if (props.subtitle)
574
+ slide.addText(props.subtitle, { x: x + 0.5, y: 3.9, w: w - 1, h: 0.8, fontSize: 18, color: COLORS.secondary, align: 'center', valign: 'top', fontFace: FONTS.body });
575
+ if (props.cta) {
576
+ const ctaW = 3.2;
577
+ slide.addText(props.cta, { x: (10 - ctaW) / 2, y: 4.85, w: ctaW, h: 0.5, fontSize: 16, bold: true, color: COLORS.white, fill: { color: COLORS.accent }, align: 'center', valign: 'middle', fontFace: FONTS.heading });
578
+ }
579
+ }
580
+ function renderTheme02ChartBarV1(slide, props) {
581
+ const x = 0.8;
582
+ const w = 8.4;
583
+ if (props.kicker)
584
+ addKicker(slide, props.kicker, x);
585
+ if (props.title)
586
+ addTitle(slide, props.title, x, 1.25, w);
587
+ if (props.subtitle)
588
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
589
+ const labels = props.labels || [];
590
+ const series = (props.series || []).slice(0, 3);
591
+ if (labels.length === 0 || series.length === 0)
592
+ return;
593
+ slide.addChart('bar', series.map((s) => ({ name: s.name || '', labels, values: (s.values || []) })), {
594
+ x, y: 2.5, w, h: 2.9, chartColors: T2_CHART,
595
+ showValue: true, dataLabelColor: COLORS.primary, dataLabelFontSize: 9,
596
+ catAxisLabelColor: COLORS.secondary, valAxisLabelColor: COLORS.secondary,
597
+ catAxisLabelFontFace: FONTS.body, valAxisLabelFontFace: FONTS.body,
598
+ });
599
+ }
600
+ function renderTheme02ChartLineV1(slide, props) {
601
+ const x = 0.8;
602
+ const w = 8.4;
603
+ if (props.kicker)
604
+ addKicker(slide, props.kicker, x);
605
+ if (props.title)
606
+ addTitle(slide, props.title, x, 1.25, w);
607
+ if (props.subtitle)
608
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
609
+ const labels = props.labels || [];
610
+ const series = (props.series || []).slice(0, 4);
611
+ if (labels.length === 0 || series.length === 0)
612
+ return;
613
+ slide.addChart('line', series.map((s) => ({ name: s.name || '', labels, values: (s.values || []) })), {
614
+ x, y: 2.5, w, h: 2.9, chartColors: T2_CHART,
615
+ lineDataSymbol: 'circle', lineDataSymbolSize: 6,
616
+ catAxisLabelColor: COLORS.secondary, valAxisLabelColor: COLORS.secondary,
617
+ catAxisLabelFontFace: FONTS.body, valAxisLabelFontFace: FONTS.body,
618
+ });
619
+ }
620
+ function renderTheme02ChartAreaV1(slide, props) {
621
+ const x = 0.8;
622
+ const w = 8.4;
623
+ if (props.kicker)
624
+ addKicker(slide, props.kicker, x);
625
+ if (props.title)
626
+ addTitle(slide, props.title, x, 1.25, w);
627
+ if (props.subtitle)
628
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
629
+ const labels = props.labels || [];
630
+ const series = (props.series || []).slice(0, 3);
631
+ if (labels.length === 0 || series.length === 0)
632
+ return;
633
+ slide.addChart('area', series.map((s) => ({ name: s.name || '', labels, values: (s.values || []) })), {
634
+ x, y: 2.5, w, h: 2.9, chartColors: T2_CHART,
635
+ catAxisLabelColor: COLORS.secondary, valAxisLabelColor: COLORS.secondary,
636
+ catAxisLabelFontFace: FONTS.body, valAxisLabelFontFace: FONTS.body,
637
+ });
638
+ }
639
+ function renderTheme02ChartStackV1(slide, props) {
640
+ const x = 0.8;
641
+ const w = 8.4;
642
+ if (props.kicker)
643
+ addKicker(slide, props.kicker, x);
644
+ if (props.title)
645
+ addTitle(slide, props.title, x, 1.25, w);
646
+ if (props.subtitle)
647
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
648
+ const labels = props.labels || [];
649
+ const series = (props.series || []).slice(0, 4);
650
+ if (labels.length === 0 || series.length === 0)
651
+ return;
652
+ slide.addChart('bar', series.map((s) => ({ name: s.name || '', labels, values: (s.values || []) })), {
653
+ x, y: 2.5, w, h: 2.9, chartColors: T2_CHART, barDir: 'bar', barGrouping: 'percentStacked',
654
+ showValue: true, dataLabelColor: COLORS.white, dataLabelFontSize: 9,
655
+ catAxisLabelColor: COLORS.secondary, valAxisLabelColor: COLORS.secondary,
656
+ catAxisLabelFontFace: FONTS.body, valAxisLabelFontFace: FONTS.body,
657
+ });
658
+ }
659
+ function renderTheme02KpiStripV1(slide, props) {
660
+ const x = 0.8;
661
+ const w = 8.4;
662
+ if (props.kicker)
663
+ addKicker(slide, props.kicker, x);
664
+ if (props.title)
665
+ addTitle(slide, props.title, x, 1.25, w);
666
+ if (props.subtitle)
667
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.4, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
668
+ const items = (props.items || []).slice(0, 5);
669
+ if (items.length === 0)
670
+ return;
671
+ const cols = items.length;
672
+ const cardW = (w - 0.3 * (cols - 1)) / cols;
673
+ const startY = 2.6;
674
+ const cardH = 2.2;
675
+ items.forEach((it, i) => {
676
+ const cx = x + i * (cardW + 0.3);
677
+ addTheme02Card(slide, cx, startY, cardW, cardH, 0.12);
678
+ let ty = startY + 0.2;
679
+ const valStr = (it.value || '') + (it.unit ? ' ' + it.unit : '');
680
+ slide.addText(valStr, { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.6, fontSize: 28, bold: true, color: COLORS.accent, align: 'left', fontFace: FONTS.heading });
681
+ ty += 0.62;
682
+ if (it.label)
683
+ slide.addText(it.label || '', { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.3, fontSize: 12, color: COLORS.primary, align: 'left', fontFace: FONTS.body });
684
+ ty += 0.32;
685
+ if (it.delta)
686
+ slide.addText(it.delta || '', { x: cx + 0.2, y: ty, w: cardW - 0.4, h: 0.3, fontSize: 12, bold: true, color: COLORS.secondary, align: 'left', fontFace: FONTS.mono });
687
+ });
688
+ }
689
+ function renderTheme02BigStatV1(slide, props) {
690
+ const x = 0.8;
691
+ const w = 8.4;
692
+ if (props.kicker)
693
+ slide.addText(props.kicker, { x, y: 1.5, w, h: 0.4, fontSize: 14, bold: true, color: COLORS.accent, align: 'center', fontFace: FONTS.mono });
694
+ if (props.title)
695
+ slide.addText(props.title, { x, y: 2.0, w, h: 0.4, fontSize: 18, bold: true, color: COLORS.secondary, align: 'center', fontFace: FONTS.heading });
696
+ const valStr = (props.value || '') + (props.unit ? ' ' + props.unit : '');
697
+ if (valStr)
698
+ slide.addText(valStr, { x: x + 0.5, y: 2.5, w: w - 1, h: 1.4, fontSize: 60, bold: true, color: COLORS.primary, align: 'center', valign: 'middle', fontFace: FONTS.heading });
699
+ let ty = 4.0;
700
+ if (props.label)
701
+ slide.addText(props.label, { x, y: ty, w, h: 0.35, fontSize: 16, color: COLORS.primary, align: 'center', fontFace: FONTS.body });
702
+ ty += 0.4;
703
+ if (props.delta)
704
+ slide.addText(props.delta, { x, y: ty, w, h: 0.3, fontSize: 14, bold: true, color: COLORS.accent, align: 'center', fontFace: FONTS.mono });
705
+ ty += 0.35;
706
+ if (props.footnote)
707
+ slide.addText(props.footnote, { x, y: ty, w, h: 0.3, fontSize: 12, color: COLORS.secondary, align: 'center', fontFace: FONTS.body });
708
+ }
709
+ function renderTheme02CycleV1(slide, props) {
710
+ const x = 0.8;
711
+ const w = 8.4;
712
+ if (props.kicker)
713
+ addKicker(slide, props.kicker, x);
714
+ if (props.title)
715
+ addTitle(slide, props.title, x, 1.25, w);
716
+ if (props.subtitle)
717
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
718
+ const steps = (props.steps || []).slice(0, 6);
719
+ if (steps.length === 0)
720
+ return;
721
+ const n = steps.length;
722
+ const cardW = (w - 0.3 * (n - 1)) / n;
723
+ const startY = 2.6;
724
+ const cardH = 2.0;
725
+ steps.forEach((s, i) => {
726
+ const cx = x + i * (cardW + 0.3);
727
+ addTheme02Card(slide, cx, startY, cardW, cardH, 0.12);
728
+ slide.addText(String(i + 1), { x: cx + 0.2, y: startY + 0.16, w: 0.6, h: 0.5, fontSize: 22, bold: true, color: COLORS.accent, fontFace: FONTS.heading });
729
+ slide.addText(s.title || '', { x: cx + 0.2, y: startY + 0.7, w: cardW - 0.4, h: 0.4, fontSize: 14, bold: true, color: COLORS.primary, fontFace: FONTS.heading });
730
+ if (s.desc)
731
+ slide.addText(s.desc || '', { x: cx + 0.2, y: startY + 1.1, w: cardW - 0.4, h: cardH - 1.2, fontSize: 11, color: COLORS.secondary, fontFace: FONTS.body });
732
+ });
733
+ slide.addText('↻ 闭环循环', { x, y: startY + cardH + 0.2, w, h: 0.3, fontSize: 13, color: COLORS.accent, align: 'center', fontFace: FONTS.mono });
734
+ }
735
+ function renderTheme02SwimlaneV1(slide, props) {
736
+ const x = 0.8;
737
+ const w = 8.4;
738
+ if (props.kicker)
739
+ addKicker(slide, props.kicker, x);
740
+ if (props.title)
741
+ addTitle(slide, props.title, x, 1.25, w);
742
+ if (props.subtitle)
743
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
744
+ const phases = (props.phases || []).slice(0, 5);
745
+ const lanes = (props.lanes || []).slice(0, 4);
746
+ if (phases.length === 0 || lanes.length === 0)
747
+ return;
748
+ const startY = 2.55;
749
+ const nameW = 1.4;
750
+ const gridX = x + nameW;
751
+ const gridW = w - nameW;
752
+ const colW = gridW / phases.length;
753
+ const laneH = Math.min(0.9, (5.0 - startY) / lanes.length);
754
+ phases.forEach((p, i) => slide.addText(p, { x: gridX + i * colW, y: startY, w: colW, h: 0.35, fontSize: 12, bold: true, color: COLORS.accent, align: 'center', fontFace: FONTS.heading }));
755
+ let ly = startY + 0.4;
756
+ lanes.forEach((lane) => {
757
+ slide.addText(lane.name || '', { x, y: ly, w: nameW, h: laneH, fontSize: 12, bold: true, color: COLORS.primary, align: 'left', valign: 'middle', fontFace: FONTS.heading });
758
+ (lane.items || []).slice(0, phases.length).forEach((it, i) => {
759
+ slide.addText(it || '', { x: gridX + i * colW + 0.1, y: ly, w: colW - 0.2, h: laneH, fontSize: 11, color: COLORS.secondary, align: 'center', valign: 'middle', fontFace: FONTS.body });
760
+ });
761
+ ly += laneH;
762
+ });
763
+ }
764
+ function renderTheme02PyramidV1(slide, props) {
765
+ const x = 0.8;
766
+ const w = 8.4;
767
+ if (props.kicker)
768
+ addKicker(slide, props.kicker, x);
769
+ if (props.title)
770
+ addTitle(slide, props.title, x, 1.25, w);
771
+ if (props.subtitle)
772
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
773
+ const levels = (props.levels || []).slice(0, 5);
774
+ if (levels.length === 0)
775
+ return;
776
+ const startY = 2.6;
777
+ const totalH = 2.4;
778
+ const bandH = totalH / levels.length;
779
+ const denom = Math.max(levels.length - 1, 1);
780
+ levels.forEach((lv, i) => {
781
+ const topW = w * (0.5 + 0.5 * (i / denom));
782
+ const cx = x + (w - topW) / 2;
783
+ const cy = startY + i * bandH;
784
+ slide.addShape('rect', { x: cx, y: cy, w: topW, h: bandH * 0.92, fill: { color: T2_CHART[i % T2_CHART.length] }, line: { color: COLORS.border, width: 1 } });
785
+ slide.addText(lv.title || '', { x: cx, y: cy, w: topW, h: bandH * 0.92, fontSize: 14, bold: true, color: COLORS.white, align: 'center', valign: 'middle', fontFace: FONTS.heading });
786
+ });
787
+ }
788
+ function renderTheme02OrgChartV1(slide, props) {
789
+ const x = 0.8;
790
+ const w = 8.4;
791
+ if (props.kicker)
792
+ addKicker(slide, props.kicker, x);
793
+ if (props.title)
794
+ addTitle(slide, props.title, x, 1.25, w);
795
+ if (props.subtitle)
796
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
797
+ const root = props.root;
798
+ const children = (props.children || []).slice(0, 5);
799
+ if (!root)
800
+ return;
801
+ const cx = x + w / 2;
802
+ const rootW = 3.0;
803
+ const rootH = 1.0;
804
+ const rootY = 2.5;
805
+ addTheme02Card(slide, cx - rootW / 2, rootY, rootW, rootH, 0.12);
806
+ slide.addText(root.title || '', { x: cx - rootW / 2, y: rootY + 0.12, w: rootW, h: 0.4, fontSize: 16, bold: true, color: COLORS.primary, align: 'center', fontFace: FONTS.heading });
807
+ if (root.sub)
808
+ slide.addText(root.sub, { x: cx - rootW / 2, y: rootY + 0.52, w: rootW, h: 0.35, fontSize: 11, color: COLORS.secondary, align: 'center', fontFace: FONTS.body });
809
+ if (children.length) {
810
+ const childY = rootY + rootH + 0.6;
811
+ const childW = (w - 0.3 * (children.length - 1)) / children.length;
812
+ const childH = 1.2;
813
+ children.forEach((c, i) => {
814
+ const ccx = x + i * (childW + 0.3);
815
+ addTheme02Card(slide, ccx, childY, childW, childH, 0.12);
816
+ slide.addText(c.title || '', { x: ccx, y: childY + 0.12, w: childW, h: 0.4, fontSize: 14, bold: true, color: COLORS.primary, align: 'center', fontFace: FONTS.heading });
817
+ if (c.sub)
818
+ slide.addText(c.sub, { x: ccx, y: childY + 0.52, w: childW, h: 0.5, fontSize: 11, color: COLORS.secondary, align: 'center', valign: 'top', fontFace: FONTS.body });
819
+ });
820
+ }
821
+ }
822
+ function renderTheme02FlowV1(slide, props) {
823
+ const x = 0.8;
824
+ const w = 8.4;
825
+ if (props.kicker)
826
+ addKicker(slide, props.kicker, x);
827
+ if (props.title)
828
+ addTitle(slide, props.title, x, 1.25, w);
829
+ if (props.subtitle)
830
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
831
+ const steps = (props.steps || []).slice(0, 5);
832
+ if (steps.length === 0)
833
+ return;
834
+ const arrowW = 0.4;
835
+ const n = steps.length;
836
+ const cardW = (w - arrowW * (n - 1)) / n;
837
+ const startY = 2.7;
838
+ const cardH = 1.9;
839
+ steps.forEach((s, i) => {
840
+ const cx = x + i * (cardW + arrowW);
841
+ addTheme02Card(slide, cx, startY, cardW, cardH, 0.12);
842
+ slide.addText(String(i + 1), { x: cx + 0.2, y: startY + 0.16, w: 0.6, h: 0.5, fontSize: 22, bold: true, color: COLORS.accent, fontFace: FONTS.heading });
843
+ slide.addText(s.title || '', { x: cx + 0.2, y: startY + 0.7, w: cardW - 0.4, h: 0.4, fontSize: 14, bold: true, color: COLORS.primary, fontFace: FONTS.heading });
844
+ if (s.desc)
845
+ slide.addText(s.desc || '', { x: cx + 0.2, y: startY + 1.1, w: cardW - 0.4, h: cardH - 1.2, fontSize: 11, color: COLORS.secondary, fontFace: FONTS.body });
846
+ if (i < n - 1)
847
+ slide.addText('→', { x: cx + cardW, y: startY, w: arrowW, h: cardH, fontSize: 24, bold: true, color: COLORS.accent, align: 'center', valign: 'middle', fontFace: FONTS.body });
848
+ });
849
+ }
850
+ function renderTheme02TableV2(slide, props) {
851
+ const x = 0.8;
852
+ const w = 8.4;
853
+ if (props.kicker)
854
+ addKicker(slide, props.kicker, x);
855
+ if (props.title)
856
+ addTitle(slide, props.title, x, 1.25, w);
857
+ if (props.subtitle)
858
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.35, fontSize: 16, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
859
+ const columns = (props.columns || []).slice(0, 5);
860
+ const rows = (props.rows || []).slice(0, 8);
861
+ if (columns.length === 0)
862
+ return;
863
+ const startY = 2.55;
864
+ const colW = w / columns.length;
865
+ const headerH = 0.4;
866
+ const rowH = Math.min(0.42, (5.0 - startY - headerH) / Math.max(rows.length, 1));
867
+ columns.forEach((c, i) => slide.addText(c, { x: x + i * colW, y: startY, w: colW, h: headerH, fontSize: 13, bold: true, color: COLORS.accent, align: 'left', valign: 'middle', fontFace: FONTS.heading }));
868
+ slide.addShape('rect', { x, y: startY + headerH, w, h: 0.02, fill: { color: COLORS.border } });
869
+ let ry = startY + headerH;
870
+ rows.forEach((row, r) => {
871
+ if (r % 2 === 1)
872
+ slide.addShape('rect', { x, y: ry, w, h: rowH, fill: { color: COLORS.surfaceElevated } });
873
+ columns.forEach((_, i) => slide.addText((row && row[i]) || '', { x: x + i * colW + 0.05, y: ry, w: colW - 0.1, h: rowH, fontSize: 11, color: COLORS.primary, align: 'left', valign: 'middle', fontFace: FONTS.body }));
874
+ ry += rowH;
875
+ });
876
+ }
877
+ function renderTheme02ImageSplitV1(slide, props) {
878
+ const x = 0.8;
879
+ const w = 8.4;
880
+ const textW = 4.0;
881
+ const imgX = x + textW + 0.4;
882
+ const imgW = w - textW - 0.4;
883
+ if (props.kicker)
884
+ addKicker(slide, props.kicker, x);
885
+ if (props.title)
886
+ addTitle(slide, props.title, x, 1.25, textW);
887
+ if (props.subtitle)
888
+ slide.addText(props.subtitle, { x, y: 2.05, w: textW, h: 0.6, fontSize: 16, color: COLORS.secondary, fontFace: FONTS.body });
889
+ const bullets = (props.bullets || []).slice(0, 5);
890
+ let by = 2.8;
891
+ bullets.forEach((b) => { slide.addText('✓ ' + b, { x, y: by, w: textW, h: 0.45, fontSize: 14, color: COLORS.primary, fontFace: FONTS.body }); by += 0.5; });
892
+ if (props.image)
893
+ addImageMaybe(slide, props.image, imgX, 2.0, imgW, 3.2);
894
+ else {
895
+ slide.addShape('rect', { x: imgX, y: 2.0, w: imgW, h: 3.2, fill: { color: COLORS.surfaceElevated }, line: { color: COLORS.border, width: 1 } });
896
+ slide.addText('图片占位', { x: imgX, y: 2.0, w: imgW, h: 3.2, fontSize: 14, color: COLORS.secondary, align: 'center', valign: 'middle', fontFace: FONTS.body });
897
+ }
898
+ }
899
+ function renderTheme02ImageGridV2(slide, props) {
900
+ const x = 0.8;
901
+ const w = 8.4;
902
+ if (props.kicker)
903
+ addKicker(slide, props.kicker, x);
904
+ if (props.title)
905
+ addTitle(slide, props.title, x, 1.25, w);
906
+ if (props.subtitle)
907
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.3, fontSize: 16, color: COLORS.secondary, fontFace: FONTS.body });
908
+ const imgs = (props.images || []).slice(0, 4);
909
+ const caps = (props.captions || []).slice(0, 4);
910
+ const tileW = (w - 0.3) / 2;
911
+ const tileH = 1.4;
912
+ const startY = 2.5;
913
+ imgs.forEach((im, i) => {
914
+ const tx = x + (i % 2) * (tileW + 0.3);
915
+ const ty = startY + Math.floor(i / 2) * (tileH + 0.3);
916
+ if (im)
917
+ addImageMaybe(slide, im, tx, ty, tileW, tileH);
918
+ else {
919
+ slide.addShape('rect', { x: tx, y: ty, w: tileW, h: tileH, fill: { color: COLORS.surfaceElevated }, line: { color: COLORS.border, width: 1 } });
920
+ slide.addText('图片占位', { x: tx, y: ty, w: tileW, h: tileH, fontSize: 12, color: COLORS.secondary, align: 'center', valign: 'middle', fontFace: FONTS.body });
921
+ }
922
+ if (caps[i])
923
+ slide.addText(caps[i], { x: tx, y: ty + tileH + 0.02, w: tileW, h: 0.28, fontSize: 11, color: COLORS.secondary, align: 'left', fontFace: FONTS.body });
924
+ });
925
+ }
926
+ function renderTheme02SpotlightV1(slide, props) {
927
+ const x = 0.8;
928
+ const w = 8.4;
929
+ if (props.image)
930
+ addImageMaybe(slide, props.image, 0, 0, 10, 5.625);
931
+ else
932
+ slide.addShape('rect', { x: 0, y: 0, w: 10, h: 5.625, fill: { color: COLORS.surfaceElevated } });
933
+ slide.addShape('rect', { x: 0, y: 0, w: 10, h: 5.625, fill: { color: '080A0E', transparency: 45 } });
934
+ if (props.kicker)
935
+ slide.addText(props.kicker, { x, y: 1.5, w, h: 0.4, fontSize: 14, bold: true, color: COLORS.accent, align: 'center', fontFace: FONTS.mono });
936
+ if (props.title)
937
+ slide.addText(props.title, { x, y: 2.1, w, h: 1.0, fontSize: 40, bold: true, color: COLORS.white, align: 'center', valign: 'middle', fontFace: FONTS.heading });
938
+ if (props.subtitle)
939
+ slide.addText(props.subtitle, { x: x + 0.5, y: 3.3, w: w - 1, h: 0.8, fontSize: 18, color: COLORS.white, align: 'center', fontFace: FONTS.body });
940
+ if (props.caption)
941
+ slide.addText(props.caption, { x, y: 5.0, w, h: 0.3, fontSize: 12, color: COLORS.white, align: 'center', fontFace: FONTS.mono });
942
+ }
943
+ function renderTheme02ChapterV3(slide, props) {
944
+ const x = 0.8;
945
+ const w = 8.4;
946
+ if (props.number)
947
+ slide.addText(props.number, { x, y: 1.6, w, h: 1.6, fontSize: 96, bold: true, color: COLORS.accent, align: 'center', valign: 'middle', fontFace: FONTS.heading });
948
+ if (props.kicker)
949
+ slide.addText(props.kicker, { x, y: 3.3, w, h: 0.4, fontSize: 14, bold: true, color: COLORS.secondary, align: 'center', fontFace: FONTS.mono });
950
+ if (props.title)
951
+ slide.addText(props.title, { x, y: 3.75, w, h: 0.6, fontSize: 32, bold: true, color: COLORS.primary, align: 'center', fontFace: FONTS.heading });
952
+ slide.addShape('rect', { x: x + w / 2 - 1.0, y: 4.5, w: 2.0, h: 0.02, fill: { color: COLORS.accent } });
953
+ if (props.subtitle)
954
+ slide.addText(props.subtitle, { x, y: 4.65, w, h: 0.4, fontSize: 15, color: COLORS.secondary, align: 'center', fontFace: FONTS.body });
955
+ }
956
+ function renderTheme02SectionDividerV1(slide, props) {
957
+ const x = 0.8;
958
+ const w = 8.4;
959
+ if (props.index)
960
+ slide.addText(props.index, { x, y: 1.9, w, h: 0.4, fontSize: 14, bold: true, color: COLORS.accent, align: 'center', fontFace: FONTS.mono });
961
+ if (props.kicker)
962
+ slide.addText(props.kicker, { x, y: 2.35, w, h: 0.4, fontSize: 13, bold: true, color: COLORS.secondary, align: 'center', fontFace: FONTS.mono });
963
+ if (props.title)
964
+ slide.addText(props.title, { x, y: 2.8, w, h: 0.8, fontSize: 36, bold: true, color: COLORS.primary, align: 'center', fontFace: FONTS.heading });
965
+ slide.addShape('rect', { x: x + w / 2 - 1.2, y: 3.7, w: 2.4, h: 0.02, fill: { color: COLORS.accent } });
966
+ if (props.subtitle)
967
+ slide.addText(props.subtitle, { x, y: 3.9, w, h: 0.5, fontSize: 16, color: COLORS.secondary, align: 'center', fontFace: FONTS.body });
968
+ }
969
+ function renderTheme02LogoWallV1(slide, props) {
970
+ const x = 0.8;
971
+ const w = 8.4;
972
+ if (props.kicker)
973
+ addKicker(slide, props.kicker, x);
974
+ if (props.title)
975
+ addTitle(slide, props.title, x, 1.25, w);
976
+ if (props.subtitle)
977
+ slide.addText(props.subtitle, { x, y: 2.05, w, h: 0.3, fontSize: 16, color: COLORS.secondary, fontFace: FONTS.body });
978
+ const logos = (props.logos || []).slice(0, 8);
979
+ if (logos.length === 0)
980
+ return;
981
+ const cols = 4;
982
+ const rows = Math.ceil(logos.length / cols);
983
+ const cardW = (w - 0.3 * (cols - 1)) / cols;
984
+ const cardH = Math.min(1.1, (5.0 - 2.5) / rows - 0.2);
985
+ logos.forEach((lg, i) => {
986
+ const cx = x + (i % cols) * (cardW + 0.3);
987
+ const cy = 2.55 + Math.floor(i / cols) * (cardH + 0.25);
988
+ addTheme02Card(slide, cx, cy, cardW, cardH, 0.12);
989
+ slide.addText(lg.name || '', { x: cx + 0.15, y: cy + 0.18, w: cardW - 0.3, h: 0.4, fontSize: 15, bold: true, color: COLORS.primary, align: 'center', fontFace: FONTS.heading });
990
+ if (lg.sub)
991
+ slide.addText(lg.sub, { x: cx + 0.15, y: cy + 0.58, w: cardW - 0.3, h: 0.3, fontSize: 11, color: COLORS.secondary, align: 'center', fontFace: FONTS.body });
992
+ });
993
+ }
994
+ export function registerTheme02Renderers(registerPptxLayoutRenderer) {
995
+ registerPptxLayoutRenderer('theme02_cover_v1', renderCoverV1);
996
+ registerPptxLayoutRenderer('theme02_cover_v2', renderCoverV1);
997
+ registerPptxLayoutRenderer('theme02_chapter_v1', renderTheme02ChapterV1);
998
+ registerPptxLayoutRenderer('theme02_chapter_v2', renderTheme02ChapterV2);
999
+ registerPptxLayoutRenderer('theme02_metric_big', renderTheme01MetricBig);
1000
+ registerPptxLayoutRenderer('theme02_number_showcase_v1', renderTheme02NumberShowcaseV1);
1001
+ registerPptxLayoutRenderer('theme02_chart_v1', renderTheme02ChartV1);
1002
+ registerPptxLayoutRenderer('theme02_chart_funnel', renderChartFunnel);
1003
+ registerPptxLayoutRenderer('theme02_chart_donut', renderTheme01ChartDonut);
1004
+ registerPptxLayoutRenderer('theme02_chart_heatmap', renderChartHeatmap);
1005
+ registerPptxLayoutRenderer('theme02_chart_radar', renderChartRadar);
1006
+ registerPptxLayoutRenderer('theme02_chart_gauge', renderChartGauge);
1007
+ registerPptxLayoutRenderer('theme02_content_v1', renderTheme02ContentV1);
1008
+ registerPptxLayoutRenderer('theme02_delta_v1', renderTheme02DeltaV1);
1009
+ registerPptxLayoutRenderer('theme02_closing_v1', renderClosing);
1010
+ registerPptxLayoutRenderer('theme02_table_of_contents_v1', renderTheme02TableOfContentsV1);
1011
+ registerPptxLayoutRenderer('theme02_metrics_v1', renderStatsV1);
1012
+ registerPptxLayoutRenderer('theme02_team_v1', renderTeamV1);
1013
+ registerPptxLayoutRenderer('theme02_timeline_v1', renderTimelineV1);
1014
+ registerPptxLayoutRenderer('theme02_comparison_v1', renderComparisonV1);
1015
+ registerPptxLayoutRenderer('theme02_image_v1', renderTheme02ImageV1);
1016
+ registerPptxLayoutRenderer('theme02_quote_v1', renderTheme02QuoteV1);
1017
+ registerPptxLayoutRenderer('theme02_quote_v2', renderTheme02QuoteV2);
1018
+ registerPptxLayoutRenderer('theme02_bento_v1', renderTheme02BentoV1);
1019
+ registerPptxLayoutRenderer('theme02_feature_v1', renderFeatureV1);
1020
+ registerPptxLayoutRenderer('theme02_gallery_v1', renderTheme01GalleryV1);
1021
+ registerPptxLayoutRenderer('theme02_pricing_v1', renderPricingV1);
1022
+ registerPptxLayoutRenderer('theme02_process_v1', renderTheme02ProcessV1);
1023
+ registerPptxLayoutRenderer('theme02_progress_v1', renderTheme02ProgressV1);
1024
+ registerPptxLayoutRenderer('theme02_roadmap_v1', renderTheme01RoadmapV1);
1025
+ registerPptxLayoutRenderer('theme02_swot_v1', renderSwotV1);
1026
+ registerPptxLayoutRenderer('theme02_faq_v1', renderFaqV1);
1027
+ registerPptxLayoutRenderer('theme02_filmstrip_v1', renderTheme01FilmstripV1);
1028
+ registerPptxLayoutRenderer('theme02_partners_v1', renderPartnersV1);
1029
+ registerPptxLayoutRenderer('theme02_pest_v1', renderPestV1);
1030
+ registerPptxLayoutRenderer('theme02_stats_v1', renderStatsV1);
1031
+ registerPptxLayoutRenderer('theme02_table_v1', renderTheme01TableV1);
1032
+ registerPptxLayoutRenderer('theme02_tags_v1', renderTheme01TagsV1);
1033
+ registerPptxLayoutRenderer('theme02_testimonial_v1', renderTestimonialV1);
1034
+ registerPptxLayoutRenderer('theme02_feature_v2', renderTheme02FeatureV2);
1035
+ registerPptxLayoutRenderer('theme02_checklist_v1', renderTheme02ChecklistV1);
1036
+ registerPptxLayoutRenderer('theme02_steps_v1', renderTheme02StepsV1);
1037
+ registerPptxLayoutRenderer('theme02_card_grid_v1', renderTheme02CardGridV1);
1038
+ registerPptxLayoutRenderer('theme02_highlight_v1', renderTheme02HighlightV1);
1039
+ registerPptxLayoutRenderer('theme02_comparison_v2', renderTheme02ComparisonV2);
1040
+ registerPptxLayoutRenderer('theme02_matrix_v1', renderTheme02MatrixV1);
1041
+ registerPptxLayoutRenderer('theme02_stat_grid_v1', renderTheme02StatGridV1);
1042
+ registerPptxLayoutRenderer('theme02_cover_v3', renderTheme02CoverV3);
1043
+ registerPptxLayoutRenderer('theme02_closing_v2', renderTheme02ClosingV2);
1044
+ registerPptxLayoutRenderer('theme02_chart_bar_v1', renderTheme02ChartBarV1);
1045
+ registerPptxLayoutRenderer('theme02_chart_line_v1', renderTheme02ChartLineV1);
1046
+ registerPptxLayoutRenderer('theme02_chart_area_v1', renderTheme02ChartAreaV1);
1047
+ registerPptxLayoutRenderer('theme02_chart_stack_v1', renderTheme02ChartStackV1);
1048
+ registerPptxLayoutRenderer('theme02_kpi_strip_v1', renderTheme02KpiStripV1);
1049
+ registerPptxLayoutRenderer('theme02_big_stat_v1', renderTheme02BigStatV1);
1050
+ registerPptxLayoutRenderer('theme02_cycle_v1', renderTheme02CycleV1);
1051
+ registerPptxLayoutRenderer('theme02_swimlane_v1', renderTheme02SwimlaneV1);
1052
+ registerPptxLayoutRenderer('theme02_pyramid_v1', renderTheme02PyramidV1);
1053
+ registerPptxLayoutRenderer('theme02_org_chart_v1', renderTheme02OrgChartV1);
1054
+ registerPptxLayoutRenderer('theme02_flow_v1', renderTheme02FlowV1);
1055
+ registerPptxLayoutRenderer('theme02_table_v2', renderTheme02TableV2);
1056
+ registerPptxLayoutRenderer('theme02_image_split_v1', renderTheme02ImageSplitV1);
1057
+ registerPptxLayoutRenderer('theme02_image_grid_v2', renderTheme02ImageGridV2);
1058
+ registerPptxLayoutRenderer('theme02_spotlight_v1', renderTheme02SpotlightV1);
1059
+ registerPptxLayoutRenderer('theme02_chapter_v3', renderTheme02ChapterV3);
1060
+ registerPptxLayoutRenderer('theme02_section_divider_v1', renderTheme02SectionDividerV1);
1061
+ registerPptxLayoutRenderer('theme02_logo_wall_v1', renderTheme02LogoWallV1);
1062
+ }
1063
+ //# sourceMappingURL=theme02-pptx.js.map