pptx-react-viewer 4.27.0 → 4.30.0

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 (128) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +37 -33
  3. package/dist/{AiChatPanel-3J6XGIJ4.mjs → AiChatPanel-42FL4CPM.mjs} +2 -2
  4. package/dist/AiChatPanel-42FL4CPM.mjs.br +0 -0
  5. package/dist/AiChatPanel-42FL4CPM.mjs.gz +0 -0
  6. package/dist/{AiChatPanel-EGTSK4T5.js → AiChatPanel-6VWCT6NE.js} +10 -10
  7. package/dist/AiChatPanel-6VWCT6NE.js.br +0 -0
  8. package/dist/AiChatPanel-6VWCT6NE.js.gz +0 -0
  9. package/dist/{Model3DScene-2V2GQ6FY.mjs → Model3DScene-EZDCI7TT.mjs} +1 -1
  10. package/dist/Model3DScene-EZDCI7TT.mjs.br +0 -0
  11. package/dist/Model3DScene-EZDCI7TT.mjs.gz +0 -0
  12. package/dist/{Model3DScene-Q3XEZSWV.js → Model3DScene-KYIYYLMY.js} +1 -1
  13. package/dist/Model3DScene-KYIYYLMY.js.br +0 -0
  14. package/dist/Model3DScene-KYIYYLMY.js.gz +0 -0
  15. package/dist/{chunk-QGM4M3NI.js → chunk-DFFCFNK2.js} +2 -0
  16. package/dist/chunk-DFFCFNK2.js.br +0 -0
  17. package/dist/chunk-DFFCFNK2.js.gz +0 -0
  18. package/dist/{chunk-6DZX6EAA.mjs → chunk-GDQSMJQZ.mjs} +2 -1
  19. package/dist/chunk-GDQSMJQZ.mjs.br +0 -0
  20. package/dist/chunk-GDQSMJQZ.mjs.gz +0 -0
  21. package/dist/{chunk-ZK7UEEXE.mjs → chunk-GXMGJ5A3.mjs} +85 -87
  22. package/dist/chunk-GXMGJ5A3.mjs.br +0 -0
  23. package/dist/chunk-GXMGJ5A3.mjs.gz +0 -0
  24. package/dist/{chunk-34AXBLYH.mjs → chunk-KRXS36RB.mjs} +83 -87
  25. package/dist/chunk-KRXS36RB.mjs.br +0 -0
  26. package/dist/chunk-KRXS36RB.mjs.gz +0 -0
  27. package/dist/{chunk-MQCBMO6A.js → chunk-MFGD7XVJ.js} +264 -268
  28. package/dist/chunk-MFGD7XVJ.js.br +0 -0
  29. package/dist/chunk-MFGD7XVJ.js.gz +0 -0
  30. package/dist/chunk-RHNJ4IU2.js +4229 -0
  31. package/dist/chunk-RHNJ4IU2.js.br +0 -0
  32. package/dist/chunk-RHNJ4IU2.js.gz +0 -0
  33. package/dist/{chunk-5RQTZ376.js → chunk-XKV2QDAO.js} +396 -398
  34. package/dist/chunk-XKV2QDAO.js.br +0 -0
  35. package/dist/chunk-XKV2QDAO.js.gz +0 -0
  36. package/dist/chunk-ZIBAN7RL.mjs +3888 -0
  37. package/dist/chunk-ZIBAN7RL.mjs.br +0 -0
  38. package/dist/chunk-ZIBAN7RL.mjs.gz +0 -0
  39. package/dist/i18n.js +1 -1
  40. package/dist/i18n.js.br +2 -2
  41. package/dist/i18n.js.gz +0 -0
  42. package/dist/i18n.mjs +1 -1
  43. package/dist/i18n.mjs.br +0 -0
  44. package/dist/i18n.mjs.gz +0 -0
  45. package/dist/index.d.ts +22 -0
  46. package/dist/index.js +25 -25
  47. package/dist/index.js.br +0 -0
  48. package/dist/index.js.gz +0 -0
  49. package/dist/index.mjs +4 -4
  50. package/dist/index.mjs.br +0 -0
  51. package/dist/index.mjs.gz +0 -0
  52. package/dist/internals.d.ts +11 -1
  53. package/dist/internals.js +82 -82
  54. package/dist/internals.js.br +0 -0
  55. package/dist/internals.js.gz +0 -0
  56. package/dist/internals.mjs +3 -3
  57. package/dist/internals.mjs.br +0 -0
  58. package/dist/internals.mjs.gz +0 -0
  59. package/dist/{three.module-A6ACXOES.mjs → three.module-2R4ADL7W.mjs} +1 -1
  60. package/dist/three.module-2R4ADL7W.mjs.br +0 -0
  61. package/dist/three.module-2R4ADL7W.mjs.gz +0 -0
  62. package/dist/{three.module-IORLGCSX.js → three.module-LS32MK23.js} +1 -1
  63. package/dist/three.module-LS32MK23.js.br +0 -0
  64. package/dist/three.module-LS32MK23.js.gz +0 -0
  65. package/dist/viewer/index.d.ts +22 -0
  66. package/dist/viewer/index.js +20 -20
  67. package/dist/viewer/index.js.br +0 -0
  68. package/dist/viewer/index.js.gz +0 -0
  69. package/dist/viewer/index.mjs +4 -4
  70. package/dist/viewer/index.mjs.br +0 -0
  71. package/dist/viewer/index.mjs.gz +0 -0
  72. package/dist/{y-webrtc-F5IA7T5S.mjs → y-webrtc-6DZI5KUK.mjs} +1 -1
  73. package/dist/y-webrtc-6DZI5KUK.mjs.br +0 -0
  74. package/dist/y-webrtc-6DZI5KUK.mjs.gz +0 -0
  75. package/dist/{y-webrtc-6LID3XZO.js → y-webrtc-OTRGEYOH.js} +5 -5
  76. package/dist/y-webrtc-OTRGEYOH.js.br +0 -0
  77. package/dist/y-webrtc-OTRGEYOH.js.gz +0 -0
  78. package/dist/{y-websocket-HOY2HFMH.js → y-websocket-AWBYMAHL.js} +1 -1
  79. package/dist/y-websocket-AWBYMAHL.js.br +0 -0
  80. package/dist/y-websocket-AWBYMAHL.js.gz +0 -0
  81. package/dist/{y-websocket-VGLBV2HJ.mjs → y-websocket-VAKUVRQT.mjs} +1 -1
  82. package/dist/y-websocket-VAKUVRQT.mjs.br +0 -0
  83. package/dist/y-websocket-VAKUVRQT.mjs.gz +0 -0
  84. package/package.json +4 -3
  85. package/dist/AiChatPanel-3J6XGIJ4.mjs.br +0 -0
  86. package/dist/AiChatPanel-3J6XGIJ4.mjs.gz +0 -0
  87. package/dist/AiChatPanel-EGTSK4T5.js.br +0 -0
  88. package/dist/AiChatPanel-EGTSK4T5.js.gz +0 -0
  89. package/dist/Model3DScene-2V2GQ6FY.mjs.br +0 -0
  90. package/dist/Model3DScene-2V2GQ6FY.mjs.gz +0 -0
  91. package/dist/Model3DScene-Q3XEZSWV.js.br +0 -2
  92. package/dist/Model3DScene-Q3XEZSWV.js.gz +0 -0
  93. package/dist/UTIF-RPFRSSC5.mjs +0 -6400
  94. package/dist/UTIF-RPFRSSC5.mjs.br +0 -0
  95. package/dist/UTIF-RPFRSSC5.mjs.gz +0 -0
  96. package/dist/UTIF-XWCKRN6V.js +0 -6402
  97. package/dist/UTIF-XWCKRN6V.js.br +0 -0
  98. package/dist/UTIF-XWCKRN6V.js.gz +0 -0
  99. package/dist/chunk-34AXBLYH.mjs.br +0 -0
  100. package/dist/chunk-34AXBLYH.mjs.gz +0 -0
  101. package/dist/chunk-5RQTZ376.js.br +0 -0
  102. package/dist/chunk-5RQTZ376.js.gz +0 -0
  103. package/dist/chunk-6DZX6EAA.mjs.br +0 -0
  104. package/dist/chunk-6DZX6EAA.mjs.gz +0 -0
  105. package/dist/chunk-MQCBMO6A.js.br +0 -0
  106. package/dist/chunk-MQCBMO6A.js.gz +0 -0
  107. package/dist/chunk-QGM4M3NI.js.br +0 -0
  108. package/dist/chunk-QGM4M3NI.js.gz +0 -0
  109. package/dist/chunk-TYJZJJZ6.mjs +0 -208183
  110. package/dist/chunk-TYJZJJZ6.mjs.br +0 -0
  111. package/dist/chunk-TYJZJJZ6.mjs.gz +0 -0
  112. package/dist/chunk-WK6JBJCT.js +0 -208548
  113. package/dist/chunk-WK6JBJCT.js.br +0 -0
  114. package/dist/chunk-WK6JBJCT.js.gz +0 -0
  115. package/dist/chunk-ZK7UEEXE.mjs.br +0 -0
  116. package/dist/chunk-ZK7UEEXE.mjs.gz +0 -0
  117. package/dist/three.module-A6ACXOES.mjs.br +0 -0
  118. package/dist/three.module-A6ACXOES.mjs.gz +0 -0
  119. package/dist/three.module-IORLGCSX.js.br +0 -0
  120. package/dist/three.module-IORLGCSX.js.gz +0 -0
  121. package/dist/y-webrtc-6LID3XZO.js.br +0 -0
  122. package/dist/y-webrtc-6LID3XZO.js.gz +0 -0
  123. package/dist/y-webrtc-F5IA7T5S.mjs.br +0 -0
  124. package/dist/y-webrtc-F5IA7T5S.mjs.gz +0 -0
  125. package/dist/y-websocket-HOY2HFMH.js.br +0 -0
  126. package/dist/y-websocket-HOY2HFMH.js.gz +0 -0
  127. package/dist/y-websocket-VGLBV2HJ.mjs.br +0 -0
  128. package/dist/y-websocket-VGLBV2HJ.mjs.gz +0 -0
@@ -0,0 +1,4229 @@
1
+ 'use strict';
2
+
3
+ var chunkDFFCFNK2_js = require('./chunk-DFFCFNK2.js');
4
+ var pptx = require('ooxml-ui/pptx');
5
+ var pptx_star = require('ooxml-core/pptx');
6
+ var clsx = require('clsx');
7
+ var tailwindMerge = require('tailwind-merge');
8
+ var React8 = require('react');
9
+ var lu = require('react-icons/lu');
10
+ var jsxRuntime = require('react/jsx-runtime');
11
+ var i18n = require('ooxml-ui/pptx/i18n');
12
+ var reactI18next = require('react-i18next');
13
+
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
+
16
+ function _interopNamespace(e) {
17
+ if (e && e.__esModule) return e;
18
+ var n = Object.create(null);
19
+ if (e) {
20
+ Object.keys(e).forEach(function (k) {
21
+ if (k !== 'default') {
22
+ var d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: function () { return e[k]; }
26
+ });
27
+ }
28
+ });
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
+ }
33
+
34
+ var pptx_star__namespace = /*#__PURE__*/_interopNamespace(pptx_star);
35
+ var React8__default = /*#__PURE__*/_interopDefault(React8);
36
+
37
+ function getAnimationInitialStyle(preset, nativeAnimation) {
38
+ return pptx.getAnimationInitialStyle(preset, nativeAnimation);
39
+ }
40
+
41
+ // ../core/dist/index.mjs
42
+ var dist_exports = {};
43
+ chunkDFFCFNK2_js.__reExport(dist_exports, pptx_star__namespace);
44
+ function cn(...inputs) {
45
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
46
+ }
47
+ function cloneHistorySnapshot(snapshot) {
48
+ return pptx.cloneHistorySnapshot(snapshot);
49
+ }
50
+ var DEFAULT_CANVAS_WIDTH = 1280;
51
+ var DEFAULT_CANVAS_HEIGHT = 720;
52
+ var MIN_ELEMENT_SIZE = 12;
53
+ var EMU_PER_PX = 9525;
54
+ var DEFAULT_BODY_INSET_TB_PX = 45720 / 9525;
55
+ var DEFAULT_TEXT_COLOR = "#111827";
56
+ var DEFAULT_FILL_COLOR = "#3b82f6";
57
+ var DEFAULT_STROKE_COLOR = "#1f2937";
58
+ var DEFAULT_FONT_FAMILY = '"Segoe UI", "Helvetica Neue", Arial, sans-serif';
59
+ var DEFAULT_TEXT_FONT_SIZE = 24;
60
+ var HYPERLINK_COLOR = "#0563C1";
61
+ var DEFAULT_TABLE_ROWS = 3;
62
+ var DEFAULT_TABLE_COLUMNS = 3;
63
+ var ZOOM_TO_SELECTION_PADDING = 96;
64
+ var GRID_SIZE = 8;
65
+ var SLIDE_NAV_THUMBNAIL_WIDTH = 156;
66
+ var UNGROUPED_SECTION_ID = "__ungrouped__";
67
+ var DEFAULT_SECTION_GROUP_ID = "default";
68
+ var TOOLBAR_SECTIONS = [
69
+ { id: "file", labelKey: "pptx.ribbon.tab.file" },
70
+ { id: "home", labelKey: "pptx.ribbon.tab.home" },
71
+ { id: "insert", labelKey: "pptx.ribbon.tab.insert" },
72
+ { id: "draw", labelKey: "pptx.ribbon.tab.draw" },
73
+ { id: "design", labelKey: "pptx.ribbon.tab.design" },
74
+ { id: "transitions", labelKey: "pptx.ribbon.tab.transitions" },
75
+ { id: "animations", labelKey: "pptx.ribbon.tab.animations" },
76
+ { id: "slideShow", labelKey: "pptx.ribbon.tab.slideShow" },
77
+ { id: "record", labelKey: "pptx.ribbon.tab.record" },
78
+ { id: "review", labelKey: "pptx.ribbon.tab.review" },
79
+ { id: "view", labelKey: "pptx.ribbon.tab.view" },
80
+ { id: "help", labelKey: "pptx.ribbon.tab.help" }
81
+ ];
82
+ var SHORTCUT_REFERENCE_ITEMS = pptx.VIEWER_SHORTCUT_REFERENCE;
83
+ var ANIMATION_PRESET_OPTIONS = [
84
+ { value: "fadeIn", label: "Fade In", i18nKey: "pptx.animation.preset.fadeIn" },
85
+ { value: "flyIn", label: "Fly In", i18nKey: "pptx.animation.preset.flyIn" },
86
+ { value: "zoomIn", label: "Zoom In", i18nKey: "pptx.animation.preset.zoomIn" },
87
+ { value: "fadeOut", label: "Fade Out", i18nKey: "pptx.animation.preset.fadeOut" },
88
+ { value: "flyOut", label: "Fly Out", i18nKey: "pptx.animation.preset.flyOut" },
89
+ { value: "zoomOut", label: "Zoom Out", i18nKey: "pptx.animation.preset.zoomOut" },
90
+ { value: "spin", label: "Spin", i18nKey: "pptx.animation.preset.spin" },
91
+ { value: "pulse", label: "Pulse", i18nKey: "pptx.animation.preset.pulse" },
92
+ { value: "colorWave", label: "Color Wave", i18nKey: "pptx.animation.preset.colorWave" },
93
+ { value: "bounce", label: "Bounce", i18nKey: "pptx.animation.preset.bounce" },
94
+ { value: "flash", label: "Flash", i18nKey: "pptx.animation.preset.flash" },
95
+ { value: "growShrink", label: "Grow/Shrink", i18nKey: "pptx.animation.preset.growShrink" },
96
+ { value: "teeter", label: "Teeter", i18nKey: "pptx.animation.preset.teeter" }
97
+ ];
98
+ var GLYPH_COMPONENTS = {
99
+ square: lu.LuSquare,
100
+ circle: lu.LuCircle,
101
+ database: lu.LuDatabase,
102
+ diamond: lu.LuDiamond,
103
+ minus: lu.LuMinus,
104
+ moveRight: lu.LuMoveRight,
105
+ plus: lu.LuPlus,
106
+ triangle: lu.LuTriangle
107
+ };
108
+ var SHAPE_PRESETS = pptx.SHAPE_PRESET_DEFS.map(
109
+ (def) => ({
110
+ type: def.type,
111
+ label: def.label,
112
+ i18nKey: def.i18nKey,
113
+ icon: React8__default.default.createElement(GLYPH_COMPONENTS[def.glyph], {
114
+ className: def.glyphClass ? `w-3.5 h-3.5 ${def.glyphClass}` : "w-3.5 h-3.5"
115
+ })
116
+ })
117
+ );
118
+ var CONNECTOR_ARROW_OPTIONS = [
119
+ { value: "none", label: "None", i18nKey: "pptx.arrowhead.none" },
120
+ { value: "triangle", label: "Triangle", i18nKey: "pptx.arrowhead.triangle" },
121
+ { value: "stealth", label: "Stealth", i18nKey: "pptx.arrowhead.stealth" },
122
+ { value: "diamond", label: "Diamond", i18nKey: "pptx.arrowhead.diamond" },
123
+ { value: "oval", label: "Oval", i18nKey: "pptx.arrowhead.oval" },
124
+ { value: "arrow", label: "Open Arrow", i18nKey: "pptx.arrowhead.openArrow" }
125
+ ];
126
+ var ARROW_SIZE_OPTIONS = [
127
+ { value: "sm", label: "Small", i18nKey: "pptx.connectorOptions.sizeSmall" },
128
+ { value: "med", label: "Medium", i18nKey: "pptx.connectorOptions.sizeMedium" },
129
+ { value: "lg", label: "Large", i18nKey: "pptx.connectorOptions.sizeLarge" }
130
+ ];
131
+ var STROKE_DASH_OPTIONS = pptx.STROKE_DASH_OPTIONS;
132
+
133
+ // src/viewer/utils/shape-types.tsx
134
+ function getShapeType(shapeType) {
135
+ if (!shapeType) {
136
+ return "rect";
137
+ }
138
+ const normalized = shapeType.toLowerCase();
139
+ if (normalized === "rect") {
140
+ return "rect";
141
+ }
142
+ if (normalized === "roundrect") {
143
+ return "roundRect";
144
+ }
145
+ if (normalized === "ellipse" || normalized === "oval") {
146
+ return "ellipse";
147
+ }
148
+ if (normalized === "cylinder" || normalized === "can") {
149
+ return "cylinder";
150
+ }
151
+ if (normalized === "triangle") {
152
+ return "triangle";
153
+ }
154
+ if (normalized === "rttriangle") {
155
+ return "rtTriangle";
156
+ }
157
+ if (normalized === "diamond") {
158
+ return "diamond";
159
+ }
160
+ if (normalized === "line") {
161
+ return "line";
162
+ }
163
+ if (normalized === "parallelogram") {
164
+ return "parallelogram";
165
+ }
166
+ if (normalized === "trapezoid") {
167
+ return "trapezoid";
168
+ }
169
+ if (normalized === "pentagon") {
170
+ return "pentagon";
171
+ }
172
+ if (normalized === "hexagon") {
173
+ return "hexagon";
174
+ }
175
+ if (normalized === "octagon") {
176
+ return "octagon";
177
+ }
178
+ if (normalized === "chevron") {
179
+ return "chevron";
180
+ }
181
+ if (normalized === "star5") {
182
+ return "star5";
183
+ }
184
+ if (normalized === "star6") {
185
+ return "star6";
186
+ }
187
+ if (normalized === "star8") {
188
+ return "star8";
189
+ }
190
+ if (normalized === "plus") {
191
+ return "plus";
192
+ }
193
+ if (normalized === "heart") {
194
+ return "heart";
195
+ }
196
+ if (normalized === "cloud") {
197
+ return "cloud";
198
+ }
199
+ if (normalized === "sun") {
200
+ return "sun";
201
+ }
202
+ if (normalized === "moon") {
203
+ return "moon";
204
+ }
205
+ if (normalized === "pie") {
206
+ return "pie";
207
+ }
208
+ if (normalized === "plaque") {
209
+ return "plaque";
210
+ }
211
+ if (normalized === "teardrop") {
212
+ return "teardrop";
213
+ }
214
+ if (normalized === "rtarrow" || normalized === "rightarrow") {
215
+ return "rtArrow";
216
+ }
217
+ if (normalized === "leftarrow") {
218
+ return "leftArrow";
219
+ }
220
+ if (normalized === "uparrow") {
221
+ return "upArrow";
222
+ }
223
+ if (normalized === "downarrow") {
224
+ return "downArrow";
225
+ }
226
+ if (normalized.includes("connector")) {
227
+ return "connector";
228
+ }
229
+ if (normalized === "connector") {
230
+ return "connector";
231
+ }
232
+ return "rect";
233
+ }
234
+ function isConnectorOrLineElement(element) {
235
+ if (element.type === "connector") {
236
+ return true;
237
+ }
238
+ if (!(0, dist_exports.hasShapeProperties)(element)) {
239
+ return false;
240
+ }
241
+ const st = getShapeType(element.shapeType);
242
+ return st === "connector" || st === "line" || element.shapeType === "line";
243
+ }
244
+ function getImageMaskStyle(element) {
245
+ if (!(0, dist_exports.hasShapeProperties)(element)) {
246
+ return void 0;
247
+ }
248
+ const geometry = pptx.resolveShapeGeometry(element);
249
+ if (geometry.kind === "borderRadius") {
250
+ return { borderRadius: geometry.radius };
251
+ }
252
+ return geometry.kind === "clipPath" ? { clipPath: geometry.clipPath } : void 0;
253
+ }
254
+ function getImageRenderStyle(element) {
255
+ const fit = pptx.getImageFitStyle(element);
256
+ const counterTransform = pptx.getImageFillCounterTransform(element, Boolean(fit.transform));
257
+ return {
258
+ // A translated/scaled crop, or a rotWithShape=false counter-transform,
259
+ // must be masked by the stationary wrapper, not by the moving/counter-
260
+ // transformed bitmap itself.
261
+ ...fit.transform || counterTransform ? {} : getImageMaskStyle(element) || {},
262
+ ...fit,
263
+ ...counterTransform ? { transform: counterTransform, transformOrigin: "center" } : {}
264
+ };
265
+ }
266
+ function getImageSurfaceMaskStyle(element) {
267
+ const mask = getImageMaskStyle(element);
268
+ return {
269
+ overflow: "hidden",
270
+ borderRadius: mask?.borderRadius,
271
+ clipPath: mask?.clipPath ?? getCropShapeClipPath(element)
272
+ };
273
+ }
274
+ function getImageSurfaceStyle(element) {
275
+ const fill = (0, dist_exports.hasShapeProperties)(element) ? pptx.getComputedFillStyle(element) : void 0;
276
+ return {
277
+ position: "absolute",
278
+ inset: 0,
279
+ ...getImageSurfaceMaskStyle(element),
280
+ backgroundColor: fill?.backgroundColor ?? "transparent",
281
+ backgroundImage: fill?.backgroundImage,
282
+ backgroundRepeat: fill?.backgroundRepeat,
283
+ backgroundSize: fill?.backgroundSize,
284
+ backgroundPosition: fill?.backgroundPosition
285
+ };
286
+ }
287
+ function getCropShapeClipPath(element) {
288
+ if (!(0, dist_exports.isImageLikeElement)(element)) {
289
+ return void 0;
290
+ }
291
+ return pptx.getCropShapeClipPath(element.cropShape, element.width, element.height);
292
+ }
293
+ function getImageTilingStyle(element, nativeSize) {
294
+ return pptx.getImageTilingStyle(element, nativeSize);
295
+ }
296
+
297
+ // src/viewer/utils/geometry-image.ts
298
+ function shouldRenderFallbackLabel(element, isTextElement) {
299
+ if (isTextElement) {
300
+ return false;
301
+ }
302
+ if (element.type === "shape" || element.type === "connector") {
303
+ return false;
304
+ }
305
+ if (element.type === "picture" || element.type === "image") {
306
+ return false;
307
+ }
308
+ if (element.type === "table") {
309
+ return false;
310
+ }
311
+ if (element.type === "media") {
312
+ return false;
313
+ }
314
+ if (element.type === "contentPart") {
315
+ return false;
316
+ }
317
+ if (element.type === "model3d") {
318
+ return false;
319
+ }
320
+ if (element.type === "ole") {
321
+ const previewData = element.previewImageData ?? element.previewImage;
322
+ return !previewData;
323
+ }
324
+ return element.type === "chart" || element.type === "smartArt" || element.type === "unknown";
325
+ }
326
+ function ensureArrayValue(value) {
327
+ if (!value) {
328
+ return [];
329
+ }
330
+ return Array.isArray(value) ? value : [value];
331
+ }
332
+ function buildTrimFragment(element) {
333
+ const start = element.trimStartMs;
334
+ if (start === void 0 || start <= 0) {
335
+ return "";
336
+ }
337
+ return `#t=${(start / 1e3).toFixed(3)}`;
338
+ }
339
+ function useMediaMetadataExtraction(mediaRef, element) {
340
+ const [metadata, setMetadata] = React8.useState(element.metadata);
341
+ React8.useEffect(() => {
342
+ const el = mediaRef.current;
343
+ if (!el) {
344
+ return;
345
+ }
346
+ if (element.metadata?.duration !== void 0) {
347
+ setMetadata(element.metadata);
348
+ return;
349
+ }
350
+ const extract = () => {
351
+ if (!Number.isFinite(el.duration) || el.duration === 0) {
352
+ return;
353
+ }
354
+ const meta = {
355
+ duration: el.duration
356
+ };
357
+ if (el instanceof HTMLVideoElement) {
358
+ if (el.videoWidth > 0) {
359
+ meta.videoWidth = el.videoWidth;
360
+ }
361
+ if (el.videoHeight > 0) {
362
+ meta.videoHeight = el.videoHeight;
363
+ }
364
+ }
365
+ const sourceEl = el.querySelector("source");
366
+ if (sourceEl?.type) {
367
+ meta.codecInfo = sourceEl.type;
368
+ }
369
+ element.metadata = meta;
370
+ setMetadata(meta);
371
+ };
372
+ el.addEventListener("loadedmetadata", extract);
373
+ if (el.readyState >= 1) {
374
+ extract();
375
+ }
376
+ return () => {
377
+ el.removeEventListener("loadedmetadata", extract);
378
+ };
379
+ }, [mediaRef, element]);
380
+ return metadata;
381
+ }
382
+ function CaptionTrackRenderer({
383
+ captionTracks
384
+ }) {
385
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: captionTracks.map((track) => {
386
+ const trackSrc = track.src ?? (track.content ? `data:text/vtt;charset=utf-8,${encodeURIComponent(track.content)}` : void 0);
387
+ if (!trackSrc) {
388
+ return null;
389
+ }
390
+ return /* @__PURE__ */ jsxRuntime.jsx(
391
+ "track",
392
+ {
393
+ kind: track.kind,
394
+ label: track.label,
395
+ srcLang: track.language,
396
+ src: trackSrc,
397
+ default: track.isDefault
398
+ },
399
+ track.id
400
+ );
401
+ }) });
402
+ }
403
+ function VideoWithMetadata({
404
+ element,
405
+ mediaRef,
406
+ onPlay,
407
+ dataUrl,
408
+ trimFragment,
409
+ mediaMimeType,
410
+ posterUrl,
411
+ shouldLoop,
412
+ shouldAutoPlay,
413
+ isFullScreen,
414
+ isPresentationMode,
415
+ showTransport
416
+ }) {
417
+ useMediaMetadataExtraction(mediaRef, element);
418
+ const captionTracks = element.captionTracks ?? [];
419
+ return /* @__PURE__ */ jsxRuntime.jsxs(
420
+ "video",
421
+ {
422
+ ref: mediaRef,
423
+ className: "w-full h-full pointer-events-auto",
424
+ style: isFullScreen ? { objectFit: "cover" } : pptx.getImageFitStyle(element),
425
+ controls: showTransport,
426
+ preload: "metadata",
427
+ playsInline: true,
428
+ autoPlay: shouldAutoPlay,
429
+ muted: shouldAutoPlay && !isPresentationMode,
430
+ poster: posterUrl,
431
+ loop: shouldLoop,
432
+ onPlay,
433
+ crossOrigin: captionTracks.length > 0 ? "anonymous" : void 0,
434
+ children: [
435
+ /* @__PURE__ */ jsxRuntime.jsx("source", { src: `${dataUrl}${trimFragment}`, type: mediaMimeType || "video/mp4" }),
436
+ captionTracks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(CaptionTrackRenderer, { captionTracks })
437
+ ]
438
+ }
439
+ );
440
+ }
441
+ function AudioWithMetadata({
442
+ element,
443
+ mediaRef,
444
+ onPlay,
445
+ dataUrl,
446
+ trimFragment,
447
+ mediaMimeType,
448
+ shouldLoop,
449
+ shouldAutoPlay,
450
+ showTransport
451
+ }) {
452
+ useMediaMetadataExtraction(mediaRef, element);
453
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center p-2 pointer-events-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
454
+ "audio",
455
+ {
456
+ ref: mediaRef,
457
+ className: "w-full",
458
+ controls: showTransport,
459
+ preload: "metadata",
460
+ autoPlay: shouldAutoPlay,
461
+ loop: shouldLoop,
462
+ onPlay,
463
+ children: /* @__PURE__ */ jsxRuntime.jsx("source", { src: `${dataUrl}${trimFragment}`, type: mediaMimeType || "audio/mpeg" })
464
+ }
465
+ ) });
466
+ }
467
+ function PresentationMediaController({
468
+ element,
469
+ isPresentationMode,
470
+ shouldAutoPlay,
471
+ resolvedDataUrl,
472
+ isFullScreen,
473
+ onPlayStateChange,
474
+ children
475
+ }) {
476
+ const { t } = reactI18next.useTranslation();
477
+ const mediaRef = React8.useRef(null);
478
+ const [isMediaPlaying, setIsMediaPlaying] = React8.useState(false);
479
+ const trimStartSec = element.trimStartMs !== void 0 ? element.trimStartMs / 1e3 : 0;
480
+ const hideWhenNotPlaying = isPresentationMode && element.hideWhenNotPlaying === true;
481
+ const { volume: playbackVolume, playbackRate } = pptx.mediaPlaybackAttributes({
482
+ loop: element.loop,
483
+ volume: element.volume,
484
+ playbackSpeed: element.playbackSpeed
485
+ });
486
+ React8.useEffect(() => {
487
+ const el = mediaRef.current;
488
+ if (el) {
489
+ el.volume = playbackVolume;
490
+ }
491
+ }, [playbackVolume]);
492
+ React8.useEffect(() => {
493
+ const el = mediaRef.current;
494
+ if (el) {
495
+ el.playbackRate = playbackRate;
496
+ }
497
+ }, [playbackRate]);
498
+ React8.useEffect(() => {
499
+ const el = mediaRef.current;
500
+ if (!el) {
501
+ return;
502
+ }
503
+ const handlePlay = () => {
504
+ setIsMediaPlaying(true);
505
+ onPlayStateChange?.(true);
506
+ };
507
+ const handlePause = () => {
508
+ setIsMediaPlaying(false);
509
+ onPlayStateChange?.(false);
510
+ };
511
+ const handleEnded = () => {
512
+ setIsMediaPlaying(false);
513
+ onPlayStateChange?.(false);
514
+ };
515
+ el.addEventListener("play", handlePlay);
516
+ el.addEventListener("pause", handlePause);
517
+ el.addEventListener("ended", handleEnded);
518
+ return () => {
519
+ el.removeEventListener("play", handlePlay);
520
+ el.removeEventListener("pause", handlePause);
521
+ el.removeEventListener("ended", handleEnded);
522
+ };
523
+ }, [onPlayStateChange]);
524
+ React8.useEffect(() => {
525
+ const el = mediaRef.current;
526
+ if (!el || !isPresentationMode) {
527
+ return;
528
+ }
529
+ return pptx.scheduleMediaTrimAndFade(el, {
530
+ trimStartMs: element.trimStartMs,
531
+ trimEndMs: element.trimEndMs,
532
+ fadeInDuration: element.fadeInDuration,
533
+ fadeOutDuration: element.fadeOutDuration,
534
+ volume: playbackVolume
535
+ });
536
+ }, [
537
+ isPresentationMode,
538
+ element.trimStartMs,
539
+ element.trimEndMs,
540
+ element.fadeInDuration,
541
+ element.fadeOutDuration,
542
+ playbackVolume
543
+ ]);
544
+ React8.useEffect(() => {
545
+ if (!isPresentationMode || !shouldAutoPlay) {
546
+ return;
547
+ }
548
+ if (element.playAcrossSlides && element.mediaType === "audio") {
549
+ const dataUrl = element.mediaData ?? resolvedDataUrl;
550
+ if (pptx.registerCrossSlideAudio(element, dataUrl)) {
551
+ return;
552
+ }
553
+ }
554
+ const el = mediaRef.current;
555
+ if (!el) {
556
+ return;
557
+ }
558
+ const timer = window.setTimeout(() => {
559
+ if (trimStartSec > 0) {
560
+ el.currentTime = trimStartSec;
561
+ }
562
+ void el.play().catch(() => {
563
+ });
564
+ }, 100);
565
+ return () => window.clearTimeout(timer);
566
+ }, [isPresentationMode, shouldAutoPlay, element, resolvedDataUrl, trimStartSec]);
567
+ const wrapperStyle = hideWhenNotPlaying ? {
568
+ opacity: isMediaPlaying ? 1 : 0,
569
+ transition: "opacity 0.3s ease",
570
+ pointerEvents: isMediaPlaying ? "auto" : "none"
571
+ } : {};
572
+ const handleStopFullScreen = React8.useCallback(() => {
573
+ const el = mediaRef.current;
574
+ if (el && !el.paused) {
575
+ el.pause();
576
+ }
577
+ }, []);
578
+ const noopOnPlay = React8.useCallback(() => {
579
+ }, []);
580
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-full", style: wrapperStyle, children: [
581
+ children({ mediaRef, onPlay: noopOnPlay, isMediaPlaying }),
582
+ pptx.shouldShowMediaFullscreenStopButton({
583
+ fullScreen: isFullScreen,
584
+ presenting: isPresentationMode,
585
+ playing: isMediaPlaying
586
+ }) && /* @__PURE__ */ jsxRuntime.jsx(
587
+ "button",
588
+ {
589
+ type: "button",
590
+ className: "absolute bottom-3 right-3 z-30 rounded-full bg-black/50 hover:bg-black/70 text-white/80 hover:text-white p-2 transition-colors pointer-events-auto",
591
+ onClick: handleStopFullScreen,
592
+ "aria-label": t("pptx.media.stopFullscreenAria"),
593
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1" }) })
594
+ }
595
+ )
596
+ ] });
597
+ }
598
+ function label(key) {
599
+ return key === void 0 ? void 0 : i18n.translationsEn[key];
600
+ }
601
+ function FallbackIcon({
602
+ paths,
603
+ size,
604
+ className
605
+ }) {
606
+ if (paths.length === 0) {
607
+ return null;
608
+ }
609
+ return /* @__PURE__ */ jsxRuntime.jsx(
610
+ "svg",
611
+ {
612
+ width: size,
613
+ height: size,
614
+ viewBox: "0 0 24 24",
615
+ fill: "none",
616
+ stroke: "currentColor",
617
+ strokeWidth: "1.5",
618
+ className,
619
+ children: paths.map((d) => /* @__PURE__ */ jsxRuntime.jsx("path", { d }, d))
620
+ }
621
+ );
622
+ }
623
+ function Badge({
624
+ visual,
625
+ element
626
+ }) {
627
+ if (visual.badge === "none") {
628
+ return null;
629
+ }
630
+ const isMissing = visual.badge === "missing";
631
+ return /* @__PURE__ */ jsxRuntime.jsxs(
632
+ "div",
633
+ {
634
+ className: `absolute inset-0 flex flex-col items-center justify-center ${isMissing ? "gap-1" : ""}`,
635
+ ...{ [pptx.MEDIA_CHROME_ATTRIBUTE]: visual.badge },
636
+ children: [
637
+ /* @__PURE__ */ jsxRuntime.jsx(
638
+ FallbackIcon,
639
+ {
640
+ paths: pptx.mediaFallbackIcon(visual, element.mediaType),
641
+ size: isMissing ? 32 : 48,
642
+ className: isMissing ? "text-white/60" : "text-white/80 drop-shadow-md"
643
+ }
644
+ ),
645
+ isMissing && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-white/60", children: label(pptx.mediaFallbackLabelKey(visual, element.mediaType)) })
646
+ ]
647
+ }
648
+ );
649
+ }
650
+ function Placeholder({
651
+ visual,
652
+ element
653
+ }) {
654
+ if (visual.placeholder === "none") {
655
+ return null;
656
+ }
657
+ const isMissing = visual.placeholder === "missing";
658
+ return /* @__PURE__ */ jsxRuntime.jsxs(
659
+ "div",
660
+ {
661
+ className: `w-full h-full flex flex-col items-center justify-center gap-1 pointer-events-none rounded ${isMissing ? "bg-black/30 border border-dashed border-white/20" : element.mediaType === "audio" ? "bg-black/10" : "bg-black/20"}`,
662
+ ...{ [pptx.MEDIA_CHROME_ATTRIBUTE]: visual.placeholder },
663
+ children: [
664
+ /* @__PURE__ */ jsxRuntime.jsx(
665
+ FallbackIcon,
666
+ {
667
+ paths: pptx.mediaFallbackIcon(visual, element.mediaType),
668
+ size: isMissing ? 36 : element.mediaType === "audio" ? 24 : 32,
669
+ className: isMissing ? "text-white/50" : "text-white/70"
670
+ }
671
+ ),
672
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[10px] ${isMissing ? "text-white/50" : "text-white/70"}`, children: label(pptx.mediaFallbackLabelKey(visual, element.mediaType)) })
673
+ ]
674
+ }
675
+ );
676
+ }
677
+ function renderMediaFallback({
678
+ element,
679
+ posterUrl,
680
+ surface
681
+ }) {
682
+ const visual = pptx.mediaFallbackVisual(surface, {
683
+ hasPoster: Boolean(posterUrl),
684
+ missing: element.mediaMissing === true
685
+ });
686
+ if (visual.poster && posterUrl) {
687
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-full relative pointer-events-none", children: [
688
+ /* @__PURE__ */ jsxRuntime.jsx(
689
+ "img",
690
+ {
691
+ src: posterUrl,
692
+ alt: visual.dimPoster ? i18n.translationsEn["pptx.media.posterAlt"] : i18n.translationsEn["pptx.media.videoPosterAlt"],
693
+ className: `w-full h-full${visual.dimPoster ? " opacity-50" : ""}`,
694
+ style: pptx.getImageFitStyle(element)
695
+ }
696
+ ),
697
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { visual, element })
698
+ ] });
699
+ }
700
+ return /* @__PURE__ */ jsxRuntime.jsx(Placeholder, { visual, element });
701
+ }
702
+ function renderMediaElement(element, mediaDataUrls, options) {
703
+ if (element.type !== "media") {
704
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: i18n.translationsEn["pptx.media.title"] });
705
+ }
706
+ const mediaType = element.mediaType;
707
+ const mediaPath = element.mediaPath;
708
+ const mediaMimeType = element.mediaMimeType;
709
+ const dataUrl = element.mediaData ?? (mediaPath ? mediaDataUrls.get(mediaPath) : void 0);
710
+ const trimFragment = buildTrimFragment(element);
711
+ const posterUrl = element.posterFrameData ?? void 0;
712
+ const shouldLoop = pptx.mediaPlaybackAttributes(element).loop;
713
+ const shouldAutoPlay = options?.autoPlay === true || element.autoPlay === true;
714
+ const isFullScreen = options?.fullScreen === true;
715
+ const isPresentationMode = options?.isPresentationMode === true;
716
+ const showTransport = options?.showTransport ?? !isPresentationMode;
717
+ const surface = {
718
+ presenting: isPresentationMode,
719
+ preview: options?.preview === true
720
+ };
721
+ if (element.mediaMissing) {
722
+ return renderMediaFallback({ element, posterUrl, surface });
723
+ }
724
+ if (mediaType === "video") {
725
+ const onlineVideo = pptx.getOnlineVideoEmbed(element);
726
+ if (onlineVideo) {
727
+ return /* @__PURE__ */ jsxRuntime.jsx(
728
+ "iframe",
729
+ {
730
+ src: onlineVideo.embedUrl,
731
+ title: i18n.translationsEn["pptx.media.onlineVideoTitle"],
732
+ className: "w-full h-full border-0 pointer-events-auto",
733
+ allow: pptx.ONLINE_VIDEO_IFRAME_ALLOW,
734
+ allowFullScreen: true,
735
+ sandbox: pptx.ONLINE_VIDEO_IFRAME_SANDBOX
736
+ }
737
+ );
738
+ }
739
+ if (dataUrl) {
740
+ return /* @__PURE__ */ jsxRuntime.jsx(
741
+ PresentationMediaController,
742
+ {
743
+ element,
744
+ isPresentationMode,
745
+ shouldAutoPlay,
746
+ resolvedDataUrl: dataUrl,
747
+ isFullScreen,
748
+ onPlayStateChange: options?.onPlayStateChange,
749
+ children: ({ mediaRef, onPlay }) => /* @__PURE__ */ jsxRuntime.jsx(
750
+ VideoWithMetadata,
751
+ {
752
+ element,
753
+ mediaRef,
754
+ onPlay,
755
+ dataUrl,
756
+ trimFragment,
757
+ mediaMimeType,
758
+ posterUrl,
759
+ shouldLoop,
760
+ shouldAutoPlay,
761
+ isFullScreen,
762
+ isPresentationMode,
763
+ showTransport
764
+ }
765
+ )
766
+ }
767
+ );
768
+ }
769
+ return renderMediaFallback({ element, posterUrl, surface });
770
+ }
771
+ if (mediaType === "audio") {
772
+ if (dataUrl) {
773
+ return /* @__PURE__ */ jsxRuntime.jsx(
774
+ PresentationMediaController,
775
+ {
776
+ element,
777
+ isPresentationMode,
778
+ shouldAutoPlay,
779
+ resolvedDataUrl: dataUrl,
780
+ isFullScreen: false,
781
+ onPlayStateChange: options?.onPlayStateChange,
782
+ children: ({ mediaRef, onPlay }) => /* @__PURE__ */ jsxRuntime.jsx(
783
+ AudioWithMetadata,
784
+ {
785
+ element,
786
+ mediaRef,
787
+ onPlay,
788
+ dataUrl,
789
+ trimFragment,
790
+ mediaMimeType,
791
+ shouldLoop,
792
+ shouldAutoPlay,
793
+ showTransport
794
+ }
795
+ )
796
+ }
797
+ );
798
+ }
799
+ return renderMediaFallback({ element, posterUrl, surface });
800
+ }
801
+ if (surface.presenting || surface.preview) {
802
+ return null;
803
+ }
804
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: i18n.translationsEn["pptx.media.title"] });
805
+ }
806
+ function getTextStyleForElement(element, fallbackColor) {
807
+ return pptx.buildTextBlockStyle(element, { fallbackColor });
808
+ }
809
+ function getTextLayoutStyle(element) {
810
+ if (!(0, dist_exports.hasTextProperties)(element)) {
811
+ return {};
812
+ }
813
+ const writingMode = pptx.toCssWritingMode(element.textStyle?.textDirection);
814
+ const textOrientation = pptx.toCssTextOrientation(element.textStyle?.textDirection);
815
+ const verticalDirection = pptx.toCssVerticalDirection(element.textStyle?.textDirection);
816
+ const textWrapNone = element.textStyle?.textWrap === "none";
817
+ const shapeAutoFitTextBox = element.textStyle?.autoFitMode === "shrink" && (element.type === "text" || element.locks?.txBox === true);
818
+ const hasParagraphIndents = (0, dist_exports.hasTextProperties)(element) && element.paragraphIndents && element.paragraphIndents.length > 0;
819
+ const paragraphMarginLeft = element.textStyle?.paragraphMarginLeft;
820
+ const paragraphIndent = element.textStyle?.paragraphIndent;
821
+ const marginLeft = !hasParagraphIndents && typeof paragraphMarginLeft === "number" && paragraphMarginLeft !== 0 ? paragraphMarginLeft : void 0;
822
+ const textIndent = !hasParagraphIndents && typeof paragraphIndent === "number" && paragraphIndent !== 0 ? paragraphIndent : void 0;
823
+ const bodyTop = element.textStyle?.bodyInsetTop ?? DEFAULT_BODY_INSET_TB_PX;
824
+ const bodyBottom = element.textStyle?.bodyInsetBottom ?? DEFAULT_BODY_INSET_TB_PX;
825
+ const bodyLayoutStyle = pptx.buildTextBodyLayoutStyle(element);
826
+ return {
827
+ ...bodyLayoutStyle,
828
+ // Body inset only. Paragraph spacing (spcBef/spcAft) is applied
829
+ // per-paragraph by the paragraph renderer, not collapsed here.
830
+ paddingTop: bodyTop,
831
+ paddingBottom: bodyBottom,
832
+ writingMode,
833
+ textOrientation,
834
+ direction: verticalDirection ?? bodyLayoutStyle.direction,
835
+ marginLeft: marginLeft ?? bodyLayoutStyle.marginLeft,
836
+ textIndent,
837
+ ...shapeAutoFitTextBox ? {
838
+ width: textWrapNone ? "max-content" : "100%",
839
+ minWidth: "100%",
840
+ height: "max-content",
841
+ minHeight: "100%",
842
+ whiteSpace: "pre-wrap",
843
+ wordBreak: textWrapNone ? "normal" : "break-word",
844
+ overflow: "visible"
845
+ } : {},
846
+ ...textWrapNone ? {
847
+ whiteSpace: "nowrap",
848
+ overflow: "visible"
849
+ } : {}
850
+ };
851
+ }
852
+ function buildTextBody3DSceneStyle(textStyle, elementSize) {
853
+ return pptx.buildTextBody3DSceneStyle(textStyle, elementSize);
854
+ }
855
+
856
+ // src/viewer/utils/text-warp-css.tsx
857
+ function getTextWarpStyle(textStyle) {
858
+ const preset = textStyle?.textWarpPreset;
859
+ if (!preset || preset === "textNoShape" || preset === "textPlain") {
860
+ return void 0;
861
+ }
862
+ switch (preset) {
863
+ // Arch shapes
864
+ case "textArchUp":
865
+ case "textArchUpPour":
866
+ return {
867
+ transform: "perspective(400px) rotateX(-12deg)",
868
+ transformOrigin: "center bottom"
869
+ };
870
+ case "textArchDown":
871
+ case "textArchDownPour":
872
+ return {
873
+ transform: "perspective(400px) rotateX(12deg)",
874
+ transformOrigin: "center top"
875
+ };
876
+ // Button shapes (concave/convex)
877
+ case "textButton":
878
+ case "textButtonPour":
879
+ return {
880
+ transform: "perspective(500px) rotateX(8deg)",
881
+ transformOrigin: "center top"
882
+ };
883
+ // Chevron / arrow
884
+ case "textChevron":
885
+ case "textChevronInverted":
886
+ return {
887
+ transform: "perspective(600px) rotateY(6deg)",
888
+ transformOrigin: "center center"
889
+ };
890
+ // Circle
891
+ case "textCircle":
892
+ case "textCirclePour":
893
+ return {
894
+ transform: "perspective(350px) rotateX(-5deg) rotateY(5deg)",
895
+ borderRadius: "50%"
896
+ };
897
+ // Slant
898
+ case "textSlantUp":
899
+ return {
900
+ transform: "perspective(500px) rotateY(8deg) skewY(-4deg)",
901
+ transformOrigin: "left center"
902
+ };
903
+ case "textSlantDown":
904
+ return {
905
+ transform: "perspective(500px) rotateY(-8deg) skewY(4deg)",
906
+ transformOrigin: "right center"
907
+ };
908
+ // Fade
909
+ case "textFadeUp":
910
+ return {
911
+ transform: "perspective(400px) rotateX(-10deg)",
912
+ transformOrigin: "center bottom"
913
+ };
914
+ case "textFadeDown":
915
+ return {
916
+ transform: "perspective(400px) rotateX(10deg)",
917
+ transformOrigin: "center top"
918
+ };
919
+ case "textFadeLeft":
920
+ return {
921
+ transform: "perspective(400px) rotateY(10deg)",
922
+ transformOrigin: "right center"
923
+ };
924
+ case "textFadeRight":
925
+ return {
926
+ transform: "perspective(400px) rotateY(-10deg)",
927
+ transformOrigin: "left center"
928
+ };
929
+ // Inflate / Deflate
930
+ case "textInflate":
931
+ case "textInflateBottom":
932
+ case "textInflateTop":
933
+ return {
934
+ transform: "scaleY(1.15) scaleX(1.05)",
935
+ transformOrigin: "center center"
936
+ };
937
+ case "textDeflate":
938
+ case "textDeflateBottom":
939
+ case "textDeflateTop":
940
+ return {
941
+ transform: "scaleY(0.88) scaleX(0.95)",
942
+ transformOrigin: "center center"
943
+ };
944
+ // Wave
945
+ case "textWave1":
946
+ case "textWave2":
947
+ case "textWave4":
948
+ return {
949
+ transform: "perspective(600px) rotateX(-3deg) skewX(3deg)",
950
+ transformOrigin: "center center"
951
+ };
952
+ case "textDoubleWave1":
953
+ return {
954
+ transform: "perspective(600px) rotateX(-2deg) skewX(4deg)",
955
+ transformOrigin: "center center"
956
+ };
957
+ // Triangle / Trapezoid
958
+ case "textTriangle":
959
+ case "textTriangleInverted":
960
+ return {
961
+ transform: "perspective(500px) rotateX(-6deg)",
962
+ transformOrigin: "center bottom"
963
+ };
964
+ // Ring
965
+ case "textRingInside":
966
+ case "textRingOutside":
967
+ return {
968
+ transform: "perspective(350px) rotateX(-4deg) rotateY(4deg)",
969
+ transformOrigin: "center center"
970
+ };
971
+ // Can
972
+ case "textCanUp":
973
+ case "textCanDown":
974
+ return {
975
+ transform: "perspective(400px) rotateX(-6deg)",
976
+ transformOrigin: "center center"
977
+ };
978
+ // Cascade
979
+ case "textCascadeUp":
980
+ return {
981
+ transform: "skewY(-8deg)",
982
+ transformOrigin: "left top"
983
+ };
984
+ case "textCascadeDown":
985
+ return {
986
+ transform: "skewY(8deg)",
987
+ transformOrigin: "left top"
988
+ };
989
+ // Curve
990
+ case "textCurveUp":
991
+ return {
992
+ transform: "perspective(500px) rotateX(-8deg)",
993
+ transformOrigin: "center bottom"
994
+ };
995
+ case "textCurveDown":
996
+ return {
997
+ transform: "perspective(500px) rotateX(8deg)",
998
+ transformOrigin: "center top"
999
+ };
1000
+ // Inflate/Deflate compound variants
1001
+ case "textDeflateInflate":
1002
+ return {
1003
+ transform: "scaleY(0.92) scaleX(1.04)",
1004
+ transformOrigin: "center center"
1005
+ };
1006
+ case "textDeflateInflateDeflate":
1007
+ return {
1008
+ transform: "scaleY(0.85) scaleX(1.06)",
1009
+ transformOrigin: "center center"
1010
+ };
1011
+ // Stop / Octagon
1012
+ case "textStop":
1013
+ return {
1014
+ transform: "scaleX(0.9) scaleY(0.9)",
1015
+ transformOrigin: "center center"
1016
+ };
1017
+ default:
1018
+ return void 0;
1019
+ }
1020
+ }
1021
+ function buildAnimStyle(state) {
1022
+ if (!state) {
1023
+ return void 0;
1024
+ }
1025
+ const style = {};
1026
+ if (state.visible === false) {
1027
+ style.visibility = "hidden";
1028
+ }
1029
+ if (state.cssAnimation) {
1030
+ style.animation = state.cssAnimation;
1031
+ }
1032
+ return Object.keys(style).length > 0 ? style : void 0;
1033
+ }
1034
+ function wrapWithTextBuildAnimation(elementId, paraIndex, renderedSegments, paraRuns, subElementAnimStates, renderPiece) {
1035
+ if (!subElementAnimStates || subElementAnimStates.size === 0) {
1036
+ return renderedSegments;
1037
+ }
1038
+ const paraKey = `${elementId}${pptx.TEXT_BUILD_ID_SEP}p${paraIndex}`;
1039
+ const paraState = subElementAnimStates.get(paraKey);
1040
+ if (paraState) {
1041
+ const style = buildAnimStyle(paraState);
1042
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-anim-id": paraKey, style: { display: "inline", ...style }, children: renderedSegments }, paraKey);
1043
+ }
1044
+ const spec = pptx.buildTextBuildSpec(
1045
+ elementId,
1046
+ paraIndex,
1047
+ paraRuns.map((run) => ({ text: run.text, style: run })),
1048
+ subElementAnimStates
1049
+ );
1050
+ if (!spec?.spans) {
1051
+ return renderedSegments;
1052
+ }
1053
+ return spec.spans.map((span, index) => {
1054
+ const content = span.style && renderPiece ? renderPiece(span.style, span.text, String(index)) : span.text;
1055
+ if (!span.animId) {
1056
+ return /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: content }, `ws-${index}`);
1057
+ }
1058
+ return /* @__PURE__ */ jsxRuntime.jsx(
1059
+ "span",
1060
+ {
1061
+ "data-anim-id": span.animId,
1062
+ style: pptx.textBuildSpanStyle(span),
1063
+ children: content
1064
+ },
1065
+ span.animId
1066
+ );
1067
+ });
1068
+ }
1069
+ function renderUnderlineWords(text, isUnderlineWords, wordDecoration, metric, keyPrefix, inner) {
1070
+ if (!isUnderlineWords || !text) {
1071
+ return inner(text, keyPrefix, metric);
1072
+ }
1073
+ const pieces = pptx.splitWordsForUnderline(text);
1074
+ if (pieces.length === 0) {
1075
+ return inner(text, keyPrefix, metric);
1076
+ }
1077
+ const gapMetric = metric ? {
1078
+ ...metric,
1079
+ nestedStyle: metric.nestedStyle ? pptx.stripUnderlineDecoration(metric.nestedStyle) : void 0
1080
+ } : void 0;
1081
+ return pieces.map((piece, i) => {
1082
+ const key = `${keyPrefix}-u${i}`;
1083
+ const following = pptx.followingText(pieces, i, metric?.following);
1084
+ if (!piece.underline) {
1085
+ return /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: inner(piece.text, key, gapMetric && { ...gapMetric, following }) }, key);
1086
+ }
1087
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: wordDecoration, children: inner(piece.text, key, metric && { ...metric, following }) }, key);
1088
+ });
1089
+ }
1090
+ function makeSegmentPieceRenderer(needsScriptFonts, scriptFonts, baseFontFamily, isUnderlineWords, wordDecoration, metric) {
1091
+ return (text, key, following) => renderUnderlineWords(
1092
+ text,
1093
+ isUnderlineWords,
1094
+ wordDecoration,
1095
+ metric && { ...metric, following },
1096
+ key,
1097
+ (subText, subKey, subMetric) => renderMetricPieces(
1098
+ subText,
1099
+ subMetric,
1100
+ subKey,
1101
+ (pieceText, pieceKey) => renderScriptAwareText(
1102
+ pieceText,
1103
+ needsScriptFonts,
1104
+ scriptFonts,
1105
+ baseFontFamily,
1106
+ pieceKey,
1107
+ subMetric?.nestedStyle
1108
+ )
1109
+ )
1110
+ );
1111
+ }
1112
+ function renderTabbedLine(line, ctx, keyPrefix, renderPiece, nestedStyle, underlineWords = false) {
1113
+ const [lineLayout] = pptx.buildRunTabLines(
1114
+ line,
1115
+ ctx,
1116
+ nestedStyle,
1117
+ void 0,
1118
+ underlineWords
1119
+ );
1120
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-block", whiteSpace: "nowrap" }, children: lineLayout.pieces.map((piece, i) => {
1121
+ const key = `${keyPrefix}-tab-${i}`;
1122
+ return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1123
+ piece.leaderStyle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: piece.leaderStyle, children: piece.leaderText }) : null,
1124
+ piece.words ? piece.words.map((word, w) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: word.style, children: renderPiece(word.text, `${key}-w${w}`) }, `${key}-w${w}`)) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: piece.style, children: renderPiece(piece.text, key) })
1125
+ ] }, key);
1126
+ }) });
1127
+ }
1128
+ function renderEastAsianPieces(text, metric, keyPrefix, inner, baseStyle, following) {
1129
+ const parts = pptx.splitEastAsianBreaks(text, metric.eastAsian, metric.font, following);
1130
+ if (parts.length === 1 && !parts[0].style) {
1131
+ return inner(parts[0].text, keyPrefix);
1132
+ }
1133
+ return parts.map((part, i) => {
1134
+ const key = `${keyPrefix}-e${i}`;
1135
+ return part.style ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...baseStyle ?? metric.nestedStyle, ...part.style }, children: inner(part.text, key) }, key) : /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: inner(part.text, key) }, key);
1136
+ });
1137
+ }
1138
+ function renderMetricPieces(text, metric, keyPrefix, inner) {
1139
+ if (!metric || !text) {
1140
+ return inner(text, keyPrefix);
1141
+ }
1142
+ const pieces = pptx.splitRunForMetrics(text, metric.font);
1143
+ if (pieces.length <= 1) {
1144
+ return renderEastAsianPieces(text, metric, keyPrefix, inner, void 0, metric.following);
1145
+ }
1146
+ return pieces.map((piece, i) => {
1147
+ const key = `${keyPrefix}-w${i}`;
1148
+ const style = {
1149
+ ...metric.nestedStyle,
1150
+ letterSpacing: pptx.pieceLetterSpacing(metric.authoredPx, piece.tracking)
1151
+ };
1152
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style, children: renderEastAsianPieces(
1153
+ piece.text,
1154
+ metric,
1155
+ key,
1156
+ inner,
1157
+ style,
1158
+ pptx.followingText(pieces, i, metric.following)
1159
+ ) }, key);
1160
+ });
1161
+ }
1162
+ function renderScriptAwareText(text, needsScriptFonts, scriptFonts, baseFontFamily, keyPrefix, nestedStyle) {
1163
+ if (!needsScriptFonts || !text) {
1164
+ return text;
1165
+ }
1166
+ const pieces = pptx.splitRunByScriptFont(
1167
+ text,
1168
+ scriptFonts,
1169
+ baseFontFamily,
1170
+ nestedStyle
1171
+ );
1172
+ if (!pieces) {
1173
+ return text;
1174
+ }
1175
+ return pieces.map(
1176
+ (piece, i) => piece.style ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: piece.style, children: piece.text }, `${keyPrefix}-r${i}`) : /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: piece.text }, `${keyPrefix}-r${i}`)
1177
+ );
1178
+ }
1179
+ function renderSegmentContent(elementId, segmentIndex, textValue, lines, needsScriptFonts, scriptFonts, baseFontFamily, findHighlights, tabContext, metric, isUnderlineWords = false, wordDecoration) {
1180
+ const segHl = findHighlights?.get(segmentIndex);
1181
+ const renderLeaf = makeSegmentPieceRenderer(
1182
+ needsScriptFonts,
1183
+ scriptFonts,
1184
+ baseFontFamily,
1185
+ isUnderlineWords,
1186
+ wordDecoration,
1187
+ metric
1188
+ );
1189
+ if (!segHl || segHl.length === 0) {
1190
+ return lines.map((line, lineIndex) => {
1191
+ const lineKey = `${elementId}-seg-${segmentIndex}-line-${lineIndex}`;
1192
+ return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1193
+ tabContext && line.includes(" ") ? renderTabbedLine(
1194
+ line,
1195
+ tabContext,
1196
+ lineKey,
1197
+ renderLeaf,
1198
+ metric?.nestedStyle,
1199
+ isUnderlineWords
1200
+ ) : renderLeaf(line, lineKey, lineIndex < lines.length - 1 ? "\n" : metric?.following),
1201
+ lineIndex < lines.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx("br", {}) : null
1202
+ ] }, lineKey);
1203
+ });
1204
+ }
1205
+ const sorted = [...segHl].sort((a, b) => a.startOffset - b.startOffset);
1206
+ const chunks = [];
1207
+ let cursor = 0;
1208
+ for (const hl of sorted) {
1209
+ if (hl.startOffset > cursor) {
1210
+ chunks.push({
1211
+ text: textValue.slice(cursor, hl.startOffset),
1212
+ highlighted: false,
1213
+ isCurrent: false
1214
+ });
1215
+ }
1216
+ chunks.push({
1217
+ text: textValue.slice(hl.startOffset, hl.startOffset + hl.length),
1218
+ highlighted: true,
1219
+ isCurrent: hl.isCurrent
1220
+ });
1221
+ cursor = hl.startOffset + hl.length;
1222
+ }
1223
+ if (cursor < textValue.length) {
1224
+ chunks.push({
1225
+ text: textValue.slice(cursor),
1226
+ highlighted: false,
1227
+ isCurrent: false
1228
+ });
1229
+ }
1230
+ return chunks.map((chunk, ci) => {
1231
+ const chunkKey = `${elementId}-seg-${segmentIndex}-hl-${ci}`;
1232
+ return chunk.highlighted ? /* @__PURE__ */ jsxRuntime.jsx(
1233
+ "mark",
1234
+ {
1235
+ style: {
1236
+ ...metric?.nestedStyle,
1237
+ backgroundColor: chunk.isCurrent ? "#f97316" : "#facc15",
1238
+ color: "inherit",
1239
+ borderRadius: 2
1240
+ },
1241
+ children: renderLeaf(chunk.text, chunkKey, pptx.followingText(chunks, ci, metric?.following))
1242
+ },
1243
+ chunkKey
1244
+ ) : /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: renderLeaf(chunk.text, chunkKey, pptx.followingText(chunks, ci, metric?.following)) }, chunkKey);
1245
+ });
1246
+ }
1247
+ function renderEquationSegment(elementId, segmentIndex, equationXml, equationNumber, fontSize) {
1248
+ const mathml = pptx.convertOmmlToMathMl(equationXml);
1249
+ const safeMathml = mathml ? pptx.sanitizeMathMl(mathml) : "";
1250
+ const equationContent = safeMathml ? /* @__PURE__ */ jsxRuntime.jsx(
1251
+ "span",
1252
+ {
1253
+ className: "inline-block align-middle",
1254
+ style: {
1255
+ fontFamily: '"Cambria Math", "STIX Two Math", serif'
1256
+ },
1257
+ dangerouslySetInnerHTML: { __html: safeMathml }
1258
+ }
1259
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block px-1 py-0.5 rounded text-xs bg-gray-200/20 text-gray-400 italic", children: i18n.translationsEn["pptx.textSegment.equationFallback"] });
1260
+ if (equationNumber) {
1261
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1262
+ "span",
1263
+ {
1264
+ style: {
1265
+ display: "flex",
1266
+ justifyContent: "space-between",
1267
+ alignItems: "center",
1268
+ width: "100%",
1269
+ fontSize
1270
+ },
1271
+ children: [
1272
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { visibility: "hidden", whiteSpace: "nowrap" }, children: [
1273
+ "(",
1274
+ equationNumber,
1275
+ ")"
1276
+ ] }),
1277
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { textAlign: "center", flex: 1 }, children: equationContent }),
1278
+ /* @__PURE__ */ jsxRuntime.jsxs(
1279
+ "span",
1280
+ {
1281
+ style: {
1282
+ whiteSpace: "nowrap",
1283
+ fontFamily: '"Cambria Math", "STIX Two Math", serif'
1284
+ },
1285
+ children: [
1286
+ "(",
1287
+ equationNumber,
1288
+ ")"
1289
+ ]
1290
+ }
1291
+ )
1292
+ ]
1293
+ },
1294
+ `${elementId}-seg-${segmentIndex}`
1295
+ );
1296
+ }
1297
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: fontSize ? { fontSize } : void 0, children: equationContent }, `${elementId}-seg-${segmentIndex}`);
1298
+ }
1299
+ function renderHyperlink(run, spanNode, key, ctx) {
1300
+ const url = run.hyperlink?.url;
1301
+ const onHyperlinkClick = ctx.onHyperlinkClick;
1302
+ if (!url || !onHyperlinkClick) {
1303
+ return spanNode;
1304
+ }
1305
+ const requireCtrlClick = ctx.requireCtrlClick;
1306
+ const displayUrl = url.startsWith("ppaction://") ? url.replace(/^ppaction:\/\//u, "").split("?")[0] : url;
1307
+ const targetFrame = run.hyperlink?.target;
1308
+ const follow = (modified) => {
1309
+ if (requireCtrlClick && !modified) {
1310
+ return false;
1311
+ }
1312
+ onHyperlinkClick(url, targetFrame);
1313
+ return true;
1314
+ };
1315
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1316
+ "span",
1317
+ {
1318
+ role: "link",
1319
+ tabIndex: 0,
1320
+ className: requireCtrlClick ? "group/link relative" : void 0,
1321
+ style: { cursor: requireCtrlClick ? void 0 : "pointer", pointerEvents: "auto" },
1322
+ title: run.hyperlink?.tooltip,
1323
+ onClick: (e) => {
1324
+ if (!follow(e.ctrlKey || e.metaKey)) {
1325
+ return;
1326
+ }
1327
+ e.stopPropagation();
1328
+ e.preventDefault();
1329
+ },
1330
+ onKeyDown: (e) => {
1331
+ if (e.key !== "Enter" && e.key !== " ") {
1332
+ return;
1333
+ }
1334
+ if (!follow(e.ctrlKey || e.metaKey)) {
1335
+ return;
1336
+ }
1337
+ e.preventDefault();
1338
+ e.stopPropagation();
1339
+ },
1340
+ children: [
1341
+ spanNode,
1342
+ requireCtrlClick && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute left-0 top-full z-[9999] mt-1 max-w-64 opacity-0 transition-opacity duration-150 group-hover/link:opacity-100", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col rounded border border-border bg-popover px-2.5 py-1.5 shadow-lg", children: [
1343
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-foreground", children: displayUrl }),
1344
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 text-[10px] text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(FollowLinkHint, {}) })
1345
+ ] }) })
1346
+ ]
1347
+ },
1348
+ `${key}-link`
1349
+ );
1350
+ }
1351
+ function FollowLinkHint() {
1352
+ const { t } = reactI18next.useTranslation();
1353
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: t("pptx.linkTooltip.followLink") });
1354
+ }
1355
+ function wrapWithTextReflection(run, key, spanNode, spanStyle, baseContent) {
1356
+ if (!run.reflection) {
1357
+ return spanNode;
1358
+ }
1359
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { position: "relative", display: "inline-block" }, children: [
1360
+ spanNode,
1361
+ /* @__PURE__ */ jsxRuntime.jsx(
1362
+ "span",
1363
+ {
1364
+ "aria-hidden": "true",
1365
+ className: "pptx-react-text-reflection",
1366
+ style: run.reflection,
1367
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: spanStyle, children: baseContent })
1368
+ }
1369
+ )
1370
+ ] }, `${key}-reflwrap`);
1371
+ }
1372
+ var BASELINE_FONT_SCALE = 0.65;
1373
+ function renderParagraphRun(run, segment, ctx, keySuffix = "") {
1374
+ const { element, fallbackColor, findHighlights, onHyperlinkClick } = ctx;
1375
+ const segmentIndex = run.segmentIndex ?? 0;
1376
+ const key = `${element.id}-seg-${segmentIndex}${keySuffix}`;
1377
+ if (run.equation) {
1378
+ return renderEquationSegment(
1379
+ element.id,
1380
+ segmentIndex,
1381
+ run.equation.xml,
1382
+ run.equation.number,
1383
+ typeof run.style.fontSize === "string" ? run.style.fontSize : void 0
1384
+ );
1385
+ }
1386
+ const segmentStyle = segment?.style ?? {};
1387
+ const textValue = run.text;
1388
+ const lines = textValue.split("\n");
1389
+ const resolvedSegmentColor = pptx.normalizeHexColor(
1390
+ segmentStyle.color || element.textStyle?.color,
1391
+ run.hyperlink ? HYPERLINK_COLOR : fallbackColor
1392
+ );
1393
+ const rawBaseline = typeof segmentStyle.baseline === "number" ? segmentStyle.baseline : 0;
1394
+ const baselineFraction = rawBaseline === 0 ? 0 : Math.abs(rawBaseline) >= 1e3 ? rawBaseline / 1e5 : rawBaseline / 100;
1395
+ const baselineFontScale = baselineFraction !== 0 ? BASELINE_FONT_SCALE : 1;
1396
+ const rawFontSize = segmentStyle.fontSize || element.textStyle?.fontSize || DEFAULT_TEXT_FONT_SIZE;
1397
+ const baseFontSize = pptx.scaleFontSizeForAutoFit(
1398
+ rawFontSize,
1399
+ pptx.resolveAutoFitFontScale(element.textStyle)
1400
+ );
1401
+ const baselineShift = baselineFraction !== 0 ? `${baselineFraction * baseFontSize}px` : void 0;
1402
+ const fontKerning = pptx.resolveFontKerning(segmentStyle.kerning, baseFontSize);
1403
+ const scriptFallbackWins = Boolean(
1404
+ segmentStyle.scriptFallbackFont && segmentStyle.fontFamilyIsCascadeDefault
1405
+ );
1406
+ const rawFontFamily = segmentStyle.fontFamily || element.textStyle?.fontFamily;
1407
+ const baseFontFamily = scriptFallbackWins ? (0, dist_exports.getSubstituteFontFamily)(segmentStyle.scriptFallbackFont) : rawFontFamily ? (0, dist_exports.getSubstituteFontFamily)(
1408
+ rawFontFamily,
1409
+ (0, dist_exports.parsePanoseString)(segmentStyle.latinFontPanose ?? element.textStyle?.latinFontPanose)
1410
+ ) : DEFAULT_FONT_FAMILY;
1411
+ const scriptFonts = pptx.resolveScriptFontSet(segmentStyle, element.textStyle, baseFontFamily);
1412
+ const needsScriptFonts = pptx.hasDistinctScriptFonts(scriptFonts);
1413
+ const authoredLetterSpacing = pptx.authoredLetterSpacingPx(segmentStyle);
1414
+ const metricFont = {
1415
+ fontFamily: baseFontFamily,
1416
+ fontSizePx: baseFontSize * baselineFontScale,
1417
+ bold: Boolean(segmentStyle.bold),
1418
+ italic: Boolean(segmentStyle.italic)
1419
+ };
1420
+ const nestedStyle = pptx.nestedTextDecorationStyle(run.style);
1421
+ const metricContext = {
1422
+ font: metricFont,
1423
+ authoredPx: authoredLetterSpacing,
1424
+ nestedStyle,
1425
+ // Resolved per run, so a Korean run keeps its Hangul words whole.
1426
+ eastAsian: pptx.eastAsianBreaksForRun(ctx.eastAsianBreaks, segmentStyle.language),
1427
+ following: ctx.eastAsianFollowing
1428
+ };
1429
+ const spanStyle = { ...run.style };
1430
+ spanStyle.color = resolvedSegmentColor;
1431
+ spanStyle.fontSize = baseFontSize * baselineFontScale;
1432
+ spanStyle.fontFamily = baseFontFamily;
1433
+ spanStyle.verticalAlign = baselineShift;
1434
+ spanStyle.fontKerning = fontKerning;
1435
+ spanStyle.letterSpacing = pptx.pieceLetterSpacing(
1436
+ authoredLetterSpacing,
1437
+ pptx.resolveMetricTrackingPx(textValue, metricFont)
1438
+ );
1439
+ const hollow = pptx.hollowTextFillStyle(segmentStyle, {
1440
+ color: resolvedSegmentColor,
1441
+ textStroke: typeof spanStyle.WebkitTextStroke === "string" ? spanStyle.WebkitTextStroke : void 0
1442
+ });
1443
+ if (hollow) {
1444
+ Object.assign(spanStyle, hollow);
1445
+ }
1446
+ const runRtl = segmentStyle.rtl;
1447
+ if (runRtl !== void 0) {
1448
+ spanStyle.direction = runRtl ? "rtl" : "ltr";
1449
+ spanStyle.unicodeBidi = runRtl !== ctx.paragraphRtl ? "bidi-override" : "embed";
1450
+ }
1451
+ const isUnderlineWords = pptx.splitsUnderlineIntoWords(segmentStyle);
1452
+ const wordDecoration = isUnderlineWords ? nestedStyle ?? run.underlineWordPieces?.find((piece) => piece.style)?.style : void 0;
1453
+ if (isUnderlineWords) {
1454
+ const stripped = pptx.stripUnderlineDecoration(spanStyle);
1455
+ spanStyle.textDecoration = stripped.textDecoration;
1456
+ delete spanStyle.textDecorationStyle;
1457
+ delete spanStyle.textDecorationThickness;
1458
+ delete spanStyle.textUnderlineOffset;
1459
+ delete spanStyle.textDecorationColor;
1460
+ }
1461
+ const baseContent = renderSegmentContent(
1462
+ element.id,
1463
+ segmentIndex,
1464
+ textValue,
1465
+ lines,
1466
+ needsScriptFonts,
1467
+ scriptFonts,
1468
+ baseFontFamily,
1469
+ findHighlights,
1470
+ pptx.buildTabContext(
1471
+ element.textStyle?.tabStops,
1472
+ element.textStyle?.defaultTabSize,
1473
+ baseFontSize,
1474
+ baseFontFamily,
1475
+ Boolean(segmentStyle.bold),
1476
+ Boolean(segmentStyle.italic),
1477
+ { language: segmentStyle.language, rtl: ctx.paragraphRtl === true }
1478
+ ),
1479
+ metricContext,
1480
+ isUnderlineWords,
1481
+ wordDecoration
1482
+ );
1483
+ const spanNode = /* @__PURE__ */ jsxRuntime.jsx("span", { "data-seg-idx": segmentIndex, style: spanStyle, children: renderRubyOrText(run, baseContent) }, key);
1484
+ const reflectedNode = wrapWithTextReflection(run, key, spanNode, spanStyle, baseContent);
1485
+ return run.hyperlink && onHyperlinkClick ? renderHyperlink(run, reflectedNode, key, ctx) : reflectedNode;
1486
+ }
1487
+ function renderRubyOrText(run, baseContent) {
1488
+ if (!run.ruby) {
1489
+ return baseContent;
1490
+ }
1491
+ return /* @__PURE__ */ jsxRuntime.jsxs("ruby", { children: [
1492
+ baseContent,
1493
+ /* @__PURE__ */ jsxRuntime.jsx("rp", { children: "(" }),
1494
+ /* @__PURE__ */ jsxRuntime.jsx("rt", { style: run.ruby.style, children: run.ruby.text }),
1495
+ /* @__PURE__ */ jsxRuntime.jsx("rp", { children: ")" })
1496
+ ] });
1497
+ }
1498
+ function renderSeededListRun(seed, runs, segments, context) {
1499
+ const sourceRun = runs.find((candidate) => candidate.segmentIndex === seed.segmentIndex);
1500
+ const segment = sourceRun ? segments[seed.segmentIndex] : { text: seed.text, style: seed.style };
1501
+ const resolvedSegment = {
1502
+ ...segment,
1503
+ style: pptx.withInlineListDecorationDefaults(segment.style, context.element.textStyle)
1504
+ };
1505
+ const decorationCss = pptx.segmentStyleToCss(
1506
+ resolvedSegment,
1507
+ pptx.resolveAutoFitFontScale(context.element.textStyle)
1508
+ );
1509
+ pptx.applyUnderlineVariant(decorationCss, resolvedSegment);
1510
+ const run = sourceRun ? { ...sourceRun, style: { ...sourceRun.style, ...pptx.nestedTextDecorationStyle(decorationCss) } } : {
1511
+ text: seed.text,
1512
+ style: decorationCss,
1513
+ segmentIndex: seed.segmentIndex
1514
+ };
1515
+ const rendered = renderParagraphRun(run, resolvedSegment, context);
1516
+ if (!React8__default.default.isValidElement(rendered)) {
1517
+ return rendered;
1518
+ }
1519
+ return React8__default.default.cloneElement(rendered, {
1520
+ "data-pptx-list-run": seed.token,
1521
+ ...seed.text === "" ? { children: /* @__PURE__ */ jsxRuntime.jsx("br", {}) } : {}
1522
+ });
1523
+ }
1524
+ function renderTextSegments(element, fallbackColor, emptyFallback, findHighlights, onHyperlinkClick, fieldContext, subElementAnimStates, segmentOverrides, requireCtrlClick, placeholderPrompt, inlineListSeed) {
1525
+ if (!(0, dist_exports.hasTextProperties)(element)) {
1526
+ return emptyFallback || null;
1527
+ }
1528
+ const segments = segmentOverrides ?? element.textSegments;
1529
+ if (!segments || segments.length === 0) {
1530
+ if (placeholderPrompt) {
1531
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: placeholderPrompt.style, children: placeholderPrompt.text });
1532
+ }
1533
+ return element.text || emptyFallback || "";
1534
+ }
1535
+ const paragraphs = pptx.buildParagraphs(element, fieldContext, segmentOverrides, {
1536
+ preserveTrailingEmpty: inlineListSeed ? true : void 0,
1537
+ eastAsianRunPieces: false
1538
+ });
1539
+ const ctx = {
1540
+ element,
1541
+ fallbackColor,
1542
+ findHighlights,
1543
+ onHyperlinkClick,
1544
+ requireCtrlClick
1545
+ };
1546
+ return paragraphs.map(
1547
+ (para, paraIndex) => renderParagraph(
1548
+ para,
1549
+ paraIndex,
1550
+ paragraphs.length,
1551
+ segments,
1552
+ ctx,
1553
+ subElementAnimStates,
1554
+ inlineListSeed
1555
+ )
1556
+ );
1557
+ }
1558
+ function joinRunsBySegment(runs) {
1559
+ const out = [];
1560
+ for (const run of runs) {
1561
+ const last = out[out.length - 1];
1562
+ if (last && run.segmentIndex !== void 0 && last.segmentIndex === run.segmentIndex && !last.equation && !run.equation) {
1563
+ last.text += run.text;
1564
+ continue;
1565
+ }
1566
+ out.push({ ...run });
1567
+ }
1568
+ return out;
1569
+ }
1570
+ function renderParagraph(para, paraIndex, paraCount, segments, ctx, subElementAnimStates, inlineListSeed) {
1571
+ const element = ctx.element;
1572
+ const runCtx = {
1573
+ ...ctx,
1574
+ paragraphRtl: para.rtl,
1575
+ eastAsianBreaks: para.eastAsianBreaks
1576
+ };
1577
+ const runs = joinRunsBySegment(para.runs);
1578
+ const listParagraph = inlineListSeed?.paragraphs[paraIndex];
1579
+ const renderedRuns = listParagraph ? listParagraph.runs.map((run) => renderSeededListRun(run, runs, segments, runCtx)) : runs.map(
1580
+ (run, i) => renderParagraphRun(run, segments[run.segmentIndex ?? -1], {
1581
+ ...runCtx,
1582
+ eastAsianFollowing: para.eastAsianBreaks ? pptx.followingText(runs, i) : void 0
1583
+ })
1584
+ );
1585
+ const paraStyle = {
1586
+ // `text-align`, BiDi `direction` / `unicode-bidi` and the kinsoku
1587
+ // line-break rules, resolved by shared from this paragraph's own `a:pPr`.
1588
+ ...para.paragraphStyle
1589
+ };
1590
+ if (para.strutFontSizePx !== void 0) {
1591
+ paraStyle.fontSize = para.strutFontSizePx;
1592
+ }
1593
+ if (para.spaceBeforePx !== void 0) {
1594
+ paraStyle.marginTop = para.spaceBeforePx;
1595
+ }
1596
+ if (para.spaceAfterPx !== void 0) {
1597
+ paraStyle.marginBottom = para.spaceAfterPx;
1598
+ }
1599
+ if (para.lineHeight !== void 0) {
1600
+ paraStyle.lineHeight = para.lineHeight;
1601
+ }
1602
+ if (para.marginLeftPx !== void 0) {
1603
+ if (para.rtl === true) {
1604
+ paraStyle.marginRight = para.marginLeftPx;
1605
+ } else {
1606
+ paraStyle.marginLeft = para.marginLeftPx;
1607
+ }
1608
+ }
1609
+ if (para.textIndentPx !== void 0) {
1610
+ paraStyle.textIndent = para.textIndentPx;
1611
+ }
1612
+ const marker = renderBulletMarker(para, paraIndex, element.id);
1613
+ const wrappedContent = wrapWithTextBuildAnimation(
1614
+ element.id,
1615
+ paraIndex,
1616
+ renderedRuns,
1617
+ runs,
1618
+ subElementAnimStates,
1619
+ // A staged build splits the paragraph but must not flatten it: each piece
1620
+ // is re-rendered through the SAME run renderer, so it keeps its run's
1621
+ // font, size, colour and decoration while it animates.
1622
+ (run, text, pieceKey) => renderParagraphRun(
1623
+ { ...run, text },
1624
+ segments[run.segmentIndex ?? -1],
1625
+ runCtx,
1626
+ `-build-${pieceKey}`
1627
+ )
1628
+ );
1629
+ const needsWrapper = Boolean(listParagraph) || Object.keys(paraStyle).length > 0 || marker !== null;
1630
+ if (!needsWrapper) {
1631
+ return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1632
+ wrappedContent,
1633
+ paraIndex < paraCount - 1 ? /* @__PURE__ */ jsxRuntime.jsx("br", {}) : null
1634
+ ] }, `${element.id}-para-${paraIndex}`);
1635
+ }
1636
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1637
+ "div",
1638
+ {
1639
+ style: paraStyle,
1640
+ "data-pptx-list-paragraph": listParagraph?.token,
1641
+ children: [
1642
+ marker,
1643
+ para.isEmpty && !listParagraph ? /* @__PURE__ */ jsxRuntime.jsx("br", {}) : wrappedContent
1644
+ ]
1645
+ },
1646
+ `${element.id}-para-${paraIndex}`
1647
+ );
1648
+ }
1649
+ function renderBulletMarker(para, paraIndex, elementId) {
1650
+ const picture = para.bulletPicture;
1651
+ if (picture?.src) {
1652
+ return /* @__PURE__ */ jsxRuntime.jsx(
1653
+ "img",
1654
+ {
1655
+ "data-pptx-bullet-marker": true,
1656
+ contentEditable: false,
1657
+ src: picture.src,
1658
+ alt: picture.accessibleLabel,
1659
+ style: {
1660
+ width: picture.sizePx,
1661
+ height: picture.sizePx,
1662
+ display: "inline-block",
1663
+ verticalAlign: "middle",
1664
+ marginInlineEnd: 4,
1665
+ objectFit: "contain"
1666
+ }
1667
+ },
1668
+ `${elementId}-para-${paraIndex}-bullet-img`
1669
+ );
1670
+ }
1671
+ if (para.bulletMarker === void 0) {
1672
+ return null;
1673
+ }
1674
+ return /* @__PURE__ */ jsxRuntime.jsx(
1675
+ "span",
1676
+ {
1677
+ className: "pptx-bullet",
1678
+ "data-pptx-bullet-marker": true,
1679
+ contentEditable: false,
1680
+ style: para.bulletStyle,
1681
+ "aria-label": picture?.accessibleLabel,
1682
+ children: para.bulletMarker
1683
+ },
1684
+ `${elementId}-para-${paraIndex}-bullet`
1685
+ );
1686
+ }
1687
+ function getDuotoneColors(element) {
1688
+ if (!(0, dist_exports.isImageLikeElement)(element)) {
1689
+ return void 0;
1690
+ }
1691
+ return element.imageEffects?.duotone;
1692
+ }
1693
+ function buildLineShadowCss(element) {
1694
+ if (!(0, dist_exports.hasShapeProperties)(element)) {
1695
+ return void 0;
1696
+ }
1697
+ const ss = element.shapeStyle;
1698
+ if (!ss?.lineShadowColor || ss.lineShadowColor === "transparent") {
1699
+ return void 0;
1700
+ }
1701
+ const offsetX = typeof ss.lineShadowOffsetX === "number" ? ss.lineShadowOffsetX : 2;
1702
+ const offsetY = typeof ss.lineShadowOffsetY === "number" ? ss.lineShadowOffsetY : 2;
1703
+ const blur = typeof ss.lineShadowBlur === "number" ? Math.max(0, ss.lineShadowBlur) : 4;
1704
+ const opacity = typeof ss.lineShadowOpacity === "number" ? Math.max(0, Math.min(1, ss.lineShadowOpacity)) : 0.35;
1705
+ return `${Math.round(offsetX)}px ${Math.round(offsetY)}px ${Math.round(blur)}px ${pptx.colorWithOpacity(
1706
+ pptx.normalizeHexColor(ss.lineShadowColor, "#000000"),
1707
+ opacity
1708
+ )}`;
1709
+ }
1710
+ function buildLineGlowFilter(element) {
1711
+ if (!(0, dist_exports.hasShapeProperties)(element)) {
1712
+ return void 0;
1713
+ }
1714
+ const ss = element.shapeStyle;
1715
+ if (!ss?.lineGlowColor || ss.lineGlowColor === "transparent" || !ss.lineGlowRadius) {
1716
+ return void 0;
1717
+ }
1718
+ const glowOpacity = typeof ss.lineGlowOpacity === "number" ? ss.lineGlowOpacity : 0.75;
1719
+ const glowRad = Math.round(Math.max(0, ss.lineGlowRadius));
1720
+ const glowCol = pptx.colorWithOpacity(pptx.normalizeHexColor(ss.lineGlowColor, "#ffff00"), glowOpacity);
1721
+ return `drop-shadow(0 0 ${glowRad}px ${glowCol})`;
1722
+ }
1723
+ function getDagDuotoneFilterId(elementId) {
1724
+ return `dag-duotone-${elementId}`;
1725
+ }
1726
+ function hasDagDuotoneEffect(element) {
1727
+ if (!(0, dist_exports.hasShapeProperties)(element)) {
1728
+ return false;
1729
+ }
1730
+ return Boolean(element.shapeStyle?.dagDuotone);
1731
+ }
1732
+ function renderDagDuotoneSvgFilter(elementId, color1, color2) {
1733
+ const filterId = getDagDuotoneFilterId(elementId);
1734
+ const c1 = pptx.hexToRgbUnit(color1);
1735
+ const c2 = pptx.hexToRgbUnit(color2);
1736
+ const grayscaleMatrix = [
1737
+ 0.2126,
1738
+ 0.7152,
1739
+ 0.0722,
1740
+ 0,
1741
+ 0,
1742
+ 0.2126,
1743
+ 0.7152,
1744
+ 0.0722,
1745
+ 0,
1746
+ 0,
1747
+ 0.2126,
1748
+ 0.7152,
1749
+ 0.0722,
1750
+ 0,
1751
+ 0,
1752
+ 0,
1753
+ 0,
1754
+ 0,
1755
+ 1,
1756
+ 0
1757
+ ].join(" ");
1758
+ return /* @__PURE__ */ jsxRuntime.jsx(
1759
+ "svg",
1760
+ {
1761
+ width: 0,
1762
+ height: 0,
1763
+ style: { position: "absolute", overflow: "hidden" },
1764
+ "aria-hidden": "true",
1765
+ children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", children: [
1766
+ /* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { type: "matrix", values: grayscaleMatrix }),
1767
+ /* @__PURE__ */ jsxRuntime.jsxs("feComponentTransfer", { children: [
1768
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncR", { type: "linear", slope: c2.r - c1.r, intercept: c1.r }),
1769
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncG", { type: "linear", slope: c2.g - c1.g, intercept: c1.g }),
1770
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncB", { type: "linear", slope: c2.b - c1.b, intercept: c1.b })
1771
+ ] })
1772
+ ] }) })
1773
+ }
1774
+ );
1775
+ }
1776
+ function build3DExtrusionData(shape3d, scene3d, fillColor, elementWidth, elementHeight) {
1777
+ return pptx.build3DExtrusionData(
1778
+ shape3d,
1779
+ scene3d,
1780
+ fillColor,
1781
+ elementWidth,
1782
+ elementHeight
1783
+ );
1784
+ }
1785
+ function apply3dEffects(base, scene3d, shape3d, fillColorFallback, elementSize, elementId) {
1786
+ pptx.apply3dEffects(
1787
+ base,
1788
+ scene3d,
1789
+ shape3d,
1790
+ fillColorFallback,
1791
+ elementSize,
1792
+ elementId
1793
+ );
1794
+ }
1795
+
1796
+ // src/viewer/utils/shape-visual-style.ts
1797
+ function rendersCustomVectorPath(element) {
1798
+ return (element.type === "shape" || element.type === "image" || element.type === "picture") && Boolean(element.pathData) && typeof element.pathWidth === "number" && element.pathWidth > 0 && typeof element.pathHeight === "number" && element.pathHeight > 0;
1799
+ }
1800
+ function rendersWedgeCalloutVector(element) {
1801
+ return element.type === "shape" && pptx.isWedgeCalloutPresetShape(element.shapeType);
1802
+ }
1803
+ function getShapeVisualStyle(element, _hasFill, fillColor, _strokeWidth, _strokeColor, animatesFill, animatesStroke, parentGroupFill) {
1804
+ if (element.type === "group") {
1805
+ const fx2 = pptx.getComputedEffectStyle(element);
1806
+ const groupStyle = {};
1807
+ if (fx2.filter) {
1808
+ groupStyle.filter = fx2.filter;
1809
+ }
1810
+ if (fx2.overflowVisible) {
1811
+ groupStyle.overflow = "visible";
1812
+ }
1813
+ return groupStyle;
1814
+ }
1815
+ if (!(0, dist_exports.hasShapeProperties)(element)) {
1816
+ return {};
1817
+ }
1818
+ const ss = element.shapeStyle;
1819
+ const fill = animatesFill ? void 0 : pptx.getComputedFillStyle(element, parentGroupFill);
1820
+ const fx = pptx.getComputedEffectStyle(element);
1821
+ const stroke = pptx.getComputedStrokeStyle(element);
1822
+ const base = {
1823
+ // A gradient fill REPLACES the solid fill, it does not sit on top of it;
1824
+ // the whole precedence lives in shared's `getComputedFillStyle`.
1825
+ backgroundColor: fill?.backgroundColor ?? "transparent",
1826
+ backgroundImage: fill?.backgroundImage,
1827
+ backgroundRepeat: fill?.backgroundRepeat,
1828
+ backgroundSize: fill?.backgroundSize,
1829
+ backgroundPosition: fill?.backgroundPosition,
1830
+ // The container always carries `box-sizing: border-box`, so the default
1831
+ // `background-origin: padding-box` would size the paint 2px smaller than
1832
+ // the shape and make a gradient tile wrap, painting a 1px sliver of its
1833
+ // opposite end along the edge. Paint from the border box instead.
1834
+ backgroundOrigin: "border-box",
1835
+ boxShadow: fx.boxShadow,
1836
+ // Reflection is no longer a single CSS property (`-webkit-box-reflect`
1837
+ // never worked in Firefox): `ElementRenderer` renders a mirrored sibling
1838
+ // node instead, using shared's `getReflectionWrapperStyle` directly (see
1839
+ // `ReflectionOverlay`).
1840
+ filter: fx.filter,
1841
+ opacity: fx.opacity,
1842
+ // Only proxy the DAG blend onto the whole element for the blend-only case:
1843
+ // with an overlay colour, `ShapeEffectOverlay` paints a separate blended
1844
+ // tint layer (shared decides which, and returns only one of the two).
1845
+ mixBlendMode: fx.mixBlendMode,
1846
+ // An unstroked element must occupy EXACTLY its authored box, so the
1847
+ // selection/hover affordance is an `outline` (see `ElementRenderer`) and
1848
+ // the border collapses to 0 rather than to a transparent 1px.
1849
+ borderWidth: stroke.borderWidth,
1850
+ borderColor: animatesStroke ? void 0 : stroke.borderColor,
1851
+ borderStyle: stroke.borderStyle,
1852
+ // Inherited SVG presentation properties: written on the container so the
1853
+ // freeform `<path>` and the stroke overlay both pick them up.
1854
+ strokeLinejoin: stroke.strokeLinejoin,
1855
+ strokeMiterlimit: stroke.strokeMiterlimit,
1856
+ strokeLinecap: stroke.strokeLinecap
1857
+ };
1858
+ Object.assign(
1859
+ base,
1860
+ pptx.getAnimationColorBaseStyle(element, {
1861
+ animatesFill,
1862
+ animatesStroke,
1863
+ parentGroupFill
1864
+ })
1865
+ );
1866
+ if (element.type === "image" || element.type === "picture") {
1867
+ base.borderWidth = 0;
1868
+ base.borderColor = void 0;
1869
+ base.borderStyle = void 0;
1870
+ }
1871
+ apply3dEffects(
1872
+ base,
1873
+ ss?.scene3d,
1874
+ ss?.shape3d,
1875
+ ss?.fillColor ?? fillColor,
1876
+ {
1877
+ width: element.width,
1878
+ height: element.height
1879
+ },
1880
+ element.id
1881
+ );
1882
+ if (rendersCustomVectorPath(element) || rendersWedgeCalloutVector(element) || pptx.isStrokeOnlyPresetElement(element)) {
1883
+ base.backgroundColor = "transparent";
1884
+ base.backgroundImage = void 0;
1885
+ base.borderWidth = void 0;
1886
+ base.borderColor = void 0;
1887
+ base.borderStyle = void 0;
1888
+ }
1889
+ if (animatesFill) {
1890
+ base.backgroundColor = void 0;
1891
+ base.backgroundImage = void 0;
1892
+ }
1893
+ if (rendersWedgeCalloutVector(element)) {
1894
+ return base;
1895
+ }
1896
+ const geometry = pptx.resolveShapeGeometry(element);
1897
+ switch (geometry.kind) {
1898
+ case "bare":
1899
+ return { backgroundColor: "transparent", borderWidth: 0, borderStyle: "none" };
1900
+ case "strokeOnly":
1901
+ return { ...base, backgroundColor: "transparent", backgroundImage: void 0 };
1902
+ case "borderRadius":
1903
+ return { ...base, borderRadius: geometry.radius };
1904
+ case "clipPath":
1905
+ return { ...base, clipPath: geometry.clipPath };
1906
+ case "lineEdge":
1907
+ return {
1908
+ ...base,
1909
+ backgroundColor: "transparent",
1910
+ borderWidth: 0,
1911
+ borderTopWidth: geometry.strokeWidth,
1912
+ borderTopColor: stroke.borderColor,
1913
+ borderTopStyle: stroke.borderStyle ?? "solid"
1914
+ };
1915
+ default:
1916
+ return base;
1917
+ }
1918
+ }
1919
+ function getConnectorPathGeometry(element) {
1920
+ return (0, dist_exports.getConnectorPathGeometry)(element);
1921
+ }
1922
+ var ARROW_SIZE_SCALE = {
1923
+ sm: 0.6,
1924
+ med: 1,
1925
+ lg: 1.5
1926
+ };
1927
+ function renderConnectorMarker(markerId, arrowType, color, arrowWidth, arrowLength) {
1928
+ if (!arrowType || arrowType === "none") {
1929
+ return null;
1930
+ }
1931
+ const wScale = ARROW_SIZE_SCALE[arrowWidth || "med"] ?? 1;
1932
+ const lScale = ARROW_SIZE_SCALE[arrowLength || "med"] ?? 1;
1933
+ const mw = Math.round(8 * lScale);
1934
+ const mh = Math.round(8 * wScale);
1935
+ return /* @__PURE__ */ jsxRuntime.jsx(
1936
+ "marker",
1937
+ {
1938
+ id: markerId,
1939
+ markerWidth: mw,
1940
+ markerHeight: mh,
1941
+ refX: 8,
1942
+ refY: 5,
1943
+ orient: "auto-start-reverse",
1944
+ viewBox: "0 0 10 10",
1945
+ markerUnits: "strokeWidth",
1946
+ children: arrowType === "triangle" ? /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "0,0 10,5 0,10", fill: color }) : arrowType === "stealth" ? /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "0,0 10,5 0,10 3.4,5", fill: color }) : arrowType === "diamond" ? /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "0,5 5,0 10,5 5,10", fill: color }) : arrowType === "oval" ? /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: 5, cy: 5, rx: 4, ry: 3.3, fill: color }) : /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0 0 L10 5 L0 10", fill: "none", stroke: color, strokeWidth: 1.6 })
1947
+ }
1948
+ );
1949
+ }
1950
+ function renderSvgGradientDefs(gradient) {
1951
+ if (!gradient) {
1952
+ return null;
1953
+ }
1954
+ if (gradient.kind === "rectPath") {
1955
+ return /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("pattern", { id: gradient.id, patternUnits: "objectBoundingBox", width: 1, height: 1, children: /* @__PURE__ */ jsxRuntime.jsx("image", { href: gradient.href, x: 0, y: 0, width: 1, height: 1, preserveAspectRatio: "none" }) }) });
1956
+ }
1957
+ const stops = gradient.stops.map((stop, index) => /* @__PURE__ */ jsxRuntime.jsx(
1958
+ "stop",
1959
+ {
1960
+ offset: stop.offset,
1961
+ stopColor: stop.color,
1962
+ stopOpacity: typeof stop.opacity === "number" ? stop.opacity : void 0
1963
+ },
1964
+ index
1965
+ ));
1966
+ return /* @__PURE__ */ jsxRuntime.jsx("defs", { children: gradient.kind === "radial" ? /* @__PURE__ */ jsxRuntime.jsx("radialGradient", { id: gradient.id, cx: gradient.cx, cy: gradient.cy, r: gradient.r, children: stops }) : /* @__PURE__ */ jsxRuntime.jsx(
1967
+ "linearGradient",
1968
+ {
1969
+ id: gradient.id,
1970
+ x1: gradient.x1,
1971
+ y1: gradient.y1,
1972
+ x2: gradient.x2,
1973
+ y2: gradient.y2,
1974
+ children: stops
1975
+ }
1976
+ ) });
1977
+ }
1978
+ function joinStyle(shapeStyle) {
1979
+ const lineJoin = shapeStyle?.lineJoin === "bevel" ? "bevel" : shapeStyle?.lineJoin === "miter" ? "miter" : "round";
1980
+ const miterLimit = lineJoin === "miter" && typeof shapeStyle?.miterLimit === "number" ? Math.max(shapeStyle.miterLimit / 1e5, 1) : void 0;
1981
+ return { lineJoin, miterLimit };
1982
+ }
1983
+ function strokeContext(shapeStyle, strokePaint, strokeWidth, dashArray) {
1984
+ const { lineJoin, miterLimit } = joinStyle(shapeStyle);
1985
+ return {
1986
+ strokePaint,
1987
+ strokeWidth,
1988
+ dashArray,
1989
+ lineCap: pptx.svgLineCap(shapeStyle?.lineCap),
1990
+ lineJoin,
1991
+ miterLimit,
1992
+ offsets: pptx.getCompoundLineOffsets(shapeStyle?.compoundLine, strokeWidth),
1993
+ widths: pptx.getCompoundLineWidths(shapeStyle?.compoundLine, strokeWidth)
1994
+ };
1995
+ }
1996
+ function strokeStrands(d, keyBase, ctx) {
1997
+ return ctx.offsets.map((offset, idx) => /* @__PURE__ */ jsxRuntime.jsx(
1998
+ "path",
1999
+ {
2000
+ d,
2001
+ fill: "none",
2002
+ stroke: ctx.strokePaint,
2003
+ strokeWidth: Math.max(ctx.widths[idx] ?? ctx.strokeWidth, 1),
2004
+ strokeDasharray: ctx.dashArray,
2005
+ strokeLinecap: ctx.lineCap,
2006
+ strokeLinejoin: ctx.lineJoin,
2007
+ strokeMiterlimit: ctx.miterLimit,
2008
+ vectorEffect: "non-scaling-stroke",
2009
+ style: offset !== 0 ? { transform: `translate(0, ${offset}px)` } : void 0
2010
+ },
2011
+ `${keyBase}-s${idx}`
2012
+ ));
2013
+ }
2014
+ function renderCustomGeometryVector(pathData, pathWidth, pathHeight, structuredPaths, shapeStyle, hasFill, fillColor, fillOpacity, strokePaint, strokeWidth, dashArray, animatesFill = false, gradient) {
2015
+ const ctx = strokeContext(shapeStyle, strokePaint, strokeWidth, dashArray);
2016
+ const subpaths = structuredPaths && structuredPaths.length > 0 ? (0, dist_exports.customGeometryPathsToSvgSubpaths)(structuredPaths, pathWidth, pathHeight) : void 0;
2017
+ const needsPerSubpath = subpaths !== void 0 && subpaths.some((sp) => sp.fillMode && sp.fillMode !== "norm" || sp.stroke === false);
2018
+ const gradientPaint = gradient ? pptx.svgGradientFillRef(gradient) : void 0;
2019
+ const nodes = [];
2020
+ if (subpaths && needsPerSubpath) {
2021
+ const paints = pptx.buildSubpathPaints(subpaths, hasFill, fillColor, fillOpacity);
2022
+ paints.forEach((paint, idx) => {
2023
+ if (paint.fill !== "none") {
2024
+ const mode = subpaths[idx]?.fillMode;
2025
+ const useGradient = gradientPaint && (mode === void 0 || mode === "norm");
2026
+ nodes.push(
2027
+ /* @__PURE__ */ jsxRuntime.jsx(
2028
+ "path",
2029
+ {
2030
+ d: paint.d,
2031
+ fill: animatesFill ? "inherit" : useGradient ? gradientPaint : paint.fill,
2032
+ stroke: "none",
2033
+ vectorEffect: "non-scaling-stroke"
2034
+ },
2035
+ `f${idx}`
2036
+ )
2037
+ );
2038
+ }
2039
+ if (paint.stroked && strokeWidth > 0) {
2040
+ nodes.push(...strokeStrands(paint.d, `p${idx}`, ctx));
2041
+ }
2042
+ });
2043
+ } else {
2044
+ if (hasFill) {
2045
+ nodes.push(
2046
+ /* @__PURE__ */ jsxRuntime.jsx(
2047
+ "path",
2048
+ {
2049
+ d: pathData,
2050
+ fill: animatesFill ? "inherit" : gradientPaint ?? pptx.colorWithOpacity(fillColor, fillOpacity),
2051
+ stroke: "none",
2052
+ vectorEffect: "non-scaling-stroke"
2053
+ },
2054
+ "fill"
2055
+ )
2056
+ );
2057
+ }
2058
+ if (strokeWidth > 0) {
2059
+ nodes.push(...strokeStrands(pathData, "agg", ctx));
2060
+ }
2061
+ }
2062
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2063
+ "svg",
2064
+ {
2065
+ viewBox: `0 0 ${pathWidth} ${pathHeight}`,
2066
+ className: "absolute inset-0 w-full h-full pointer-events-none",
2067
+ preserveAspectRatio: "none",
2068
+ children: [
2069
+ animatesFill ? null : renderSvgGradientDefs(gradient),
2070
+ nodes
2071
+ ]
2072
+ }
2073
+ );
2074
+ }
2075
+ function renderVectorShape(element, hasFill, fillColor, strokeWidth, strokeColor, animatesFill, animatesStroke) {
2076
+ if (!(0, dist_exports.hasShapeProperties)(element)) {
2077
+ return null;
2078
+ }
2079
+ const normalizedType = (element.shapeType || "").toLowerCase();
2080
+ const fillPaint = animatesFill ? "inherit" : pptx.colorWithOpacity(fillColor, element.shapeStyle?.fillOpacity);
2081
+ const strokePaint = animatesStroke ? "inherit" : pptx.colorWithOpacity(strokeColor, element.shapeStyle?.strokeOpacity);
2082
+ const dashType = pptx.normalizeStrokeDashType(element.shapeStyle?.strokeDash);
2083
+ const dashArray = pptx.getSvgStrokeDasharray(
2084
+ dashType,
2085
+ Math.max(strokeWidth, 1),
2086
+ element.shapeStyle?.customDashSegments
2087
+ );
2088
+ if (normalizedType === "can" || normalizedType === "cylinder") {
2089
+ const width = Math.max(element.width, 1);
2090
+ const height = Math.max(element.height, 1);
2091
+ const rim = Math.max(Math.min(height * 0.16, 28), 6);
2092
+ const stroke = Math.max(strokeWidth, 1);
2093
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2094
+ "svg",
2095
+ {
2096
+ viewBox: `0 0 ${width} ${height}`,
2097
+ className: "w-full h-full pointer-events-none",
2098
+ preserveAspectRatio: "none",
2099
+ children: [
2100
+ /* @__PURE__ */ jsxRuntime.jsx(
2101
+ "ellipse",
2102
+ {
2103
+ cx: width / 2,
2104
+ cy: rim / 2,
2105
+ rx: width / 2,
2106
+ ry: rim / 2,
2107
+ fill: hasFill ? fillPaint : "none",
2108
+ stroke: strokeWidth > 0 ? strokePaint : "none",
2109
+ strokeWidth: stroke,
2110
+ strokeDasharray: dashArray,
2111
+ vectorEffect: "non-scaling-stroke"
2112
+ }
2113
+ ),
2114
+ /* @__PURE__ */ jsxRuntime.jsx(
2115
+ "rect",
2116
+ {
2117
+ x: 0,
2118
+ y: rim / 2,
2119
+ width,
2120
+ height: Math.max(height - rim, 1),
2121
+ fill: hasFill ? fillPaint : "none",
2122
+ stroke: strokeWidth > 0 ? strokePaint : "none",
2123
+ strokeWidth: stroke,
2124
+ strokeDasharray: dashArray,
2125
+ vectorEffect: "non-scaling-stroke"
2126
+ }
2127
+ ),
2128
+ /* @__PURE__ */ jsxRuntime.jsx(
2129
+ "ellipse",
2130
+ {
2131
+ cx: width / 2,
2132
+ cy: height - rim / 2,
2133
+ rx: width / 2,
2134
+ ry: rim / 2,
2135
+ fill: hasFill ? fillPaint : "none",
2136
+ stroke: strokeWidth > 0 ? strokePaint : "none",
2137
+ strokeWidth: stroke,
2138
+ strokeDasharray: dashArray,
2139
+ vectorEffect: "non-scaling-stroke"
2140
+ }
2141
+ )
2142
+ ]
2143
+ }
2144
+ );
2145
+ }
2146
+ if ((element.type === "shape" || element.type === "image" || element.type === "picture") && element.pathData && element.pathWidth && element.pathHeight && element.pathWidth > 0 && element.pathHeight > 0) {
2147
+ return renderCustomGeometryVector(
2148
+ element.pathData,
2149
+ element.pathWidth,
2150
+ element.pathHeight,
2151
+ element.customGeometryPaths,
2152
+ element.shapeStyle,
2153
+ hasFill,
2154
+ fillColor,
2155
+ element.shapeStyle?.fillOpacity,
2156
+ strokePaint,
2157
+ strokeWidth,
2158
+ dashArray,
2159
+ Boolean(animatesFill),
2160
+ // A freeform's `a:gradFill` needs a real SVG paint server: the
2161
+ // container's `background-image` is suppressed for custom geometry, so
2162
+ // without this the shape fell back to the parser's representative solid
2163
+ // and lost every fade (issue #132).
2164
+ pptx.buildSvgGradientDef(element.shapeStyle, element.id)
2165
+ );
2166
+ }
2167
+ if ((element.type === "image" || element.type === "picture") && strokeWidth > 0 && !pptx.buildStrokeOutline(element)) {
2168
+ const width = Math.max(element.width, 1);
2169
+ const height = Math.max(element.height, 1);
2170
+ const geometry = pptx.getPresetShapeVectorGeometry(
2171
+ element.shapeType || "rect",
2172
+ width,
2173
+ height,
2174
+ element.shapeAdjustments
2175
+ );
2176
+ if (geometry) {
2177
+ return /* @__PURE__ */ jsxRuntime.jsx(
2178
+ "svg",
2179
+ {
2180
+ viewBox: `${geometry.minX} ${geometry.minY} ${geometry.viewWidth} ${geometry.viewHeight}`,
2181
+ className: "w-full h-full pointer-events-none",
2182
+ preserveAspectRatio: "none",
2183
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2184
+ "path",
2185
+ {
2186
+ d: geometry.d,
2187
+ fill: "none",
2188
+ stroke: strokePaint,
2189
+ strokeWidth: strokeWidth * 2,
2190
+ strokeDasharray: dashArray,
2191
+ vectorEffect: "non-scaling-stroke"
2192
+ }
2193
+ )
2194
+ }
2195
+ );
2196
+ }
2197
+ }
2198
+ if (element.type === "shape" && pptx.isWedgeCalloutPresetShape(element.shapeType)) {
2199
+ const width = Math.max(element.width, 1);
2200
+ const height = Math.max(element.height, 1);
2201
+ const geometry = pptx.getPresetShapeVectorGeometry(
2202
+ element.shapeType,
2203
+ width,
2204
+ height,
2205
+ element.shapeAdjustments
2206
+ );
2207
+ if (geometry) {
2208
+ const gradient = pptx.buildSvgGradientDef(element.shapeStyle, element.id);
2209
+ const gradientPaint = gradient ? pptx.svgGradientFillRef(gradient) : void 0;
2210
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2211
+ "svg",
2212
+ {
2213
+ viewBox: `${geometry.minX} ${geometry.minY} ${geometry.viewWidth} ${geometry.viewHeight}`,
2214
+ className: "pointer-events-none",
2215
+ preserveAspectRatio: "none",
2216
+ style: {
2217
+ position: "absolute",
2218
+ left: geometry.minX,
2219
+ top: geometry.minY,
2220
+ width: geometry.viewWidth,
2221
+ height: geometry.viewHeight,
2222
+ overflow: "visible"
2223
+ },
2224
+ children: [
2225
+ animatesFill ? null : renderSvgGradientDefs(gradient),
2226
+ /* @__PURE__ */ jsxRuntime.jsx(
2227
+ "path",
2228
+ {
2229
+ d: geometry.d,
2230
+ fill: hasFill ? animatesFill ? "inherit" : gradientPaint ?? fillPaint : "none",
2231
+ stroke: strokeWidth > 0 ? strokePaint : "none",
2232
+ strokeWidth,
2233
+ strokeDasharray: dashArray,
2234
+ vectorEffect: "non-scaling-stroke"
2235
+ }
2236
+ )
2237
+ ]
2238
+ }
2239
+ );
2240
+ }
2241
+ }
2242
+ if ((0, dist_exports.isCalloutShape)(normalizedType)) {
2243
+ const width = Math.max(element.width, 1);
2244
+ const height = Math.max(element.height, 1);
2245
+ const geometry = (0, dist_exports.getCalloutLeaderLineGeometry)(
2246
+ normalizedType,
2247
+ width,
2248
+ height,
2249
+ element.shapeAdjustments
2250
+ );
2251
+ if (geometry && geometry.points.length >= 2) {
2252
+ const leaderPath = (0, dist_exports.buildCalloutLeaderLineSvgPath)(geometry);
2253
+ const bounds = (0, dist_exports.getCalloutViewBoxBounds)(width, height, geometry);
2254
+ const lineStroke = Math.max(strokeWidth, 1);
2255
+ const offsetLeft = bounds.minX;
2256
+ const offsetTop = bounds.minY;
2257
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2258
+ "svg",
2259
+ {
2260
+ viewBox: `${bounds.minX} ${bounds.minY} ${bounds.viewWidth} ${bounds.viewHeight}`,
2261
+ className: "pointer-events-none",
2262
+ preserveAspectRatio: "none",
2263
+ style: {
2264
+ position: "absolute",
2265
+ left: offsetLeft,
2266
+ top: offsetTop,
2267
+ width: bounds.viewWidth,
2268
+ height: bounds.viewHeight,
2269
+ overflow: "visible"
2270
+ },
2271
+ children: [
2272
+ geometry.hasAccent && /* @__PURE__ */ jsxRuntime.jsx(
2273
+ "line",
2274
+ {
2275
+ x1: 0,
2276
+ y1: 0,
2277
+ x2: width,
2278
+ y2: 0,
2279
+ stroke: strokePaint,
2280
+ strokeWidth: lineStroke,
2281
+ vectorEffect: "non-scaling-stroke"
2282
+ }
2283
+ ),
2284
+ /* @__PURE__ */ jsxRuntime.jsx(
2285
+ "path",
2286
+ {
2287
+ d: leaderPath,
2288
+ fill: "none",
2289
+ stroke: strokePaint,
2290
+ strokeWidth: lineStroke,
2291
+ strokeDasharray: dashArray,
2292
+ strokeLinecap: "round",
2293
+ strokeLinejoin: "round",
2294
+ vectorEffect: "non-scaling-stroke"
2295
+ }
2296
+ )
2297
+ ]
2298
+ }
2299
+ );
2300
+ }
2301
+ }
2302
+ if (element.type === "connector" || getShapeType(element.shapeType) === "connector" || element.shapeType === "line") {
2303
+ const viewWidth = Math.max(element.width, 1);
2304
+ const viewHeight = Math.max(element.height, 1);
2305
+ const { pathData } = getConnectorPathGeometry(element);
2306
+ const markerSeed = element.id.replace(/[^a-zA-Z0-9_-]/gu, "_");
2307
+ const startMarkerId = `${markerSeed}-start-arrow`;
2308
+ const endMarkerId = `${markerSeed}-end-arrow`;
2309
+ const startArrow = element.shapeStyle?.connectorStartArrow;
2310
+ const endArrow = element.shapeStyle?.connectorEndArrow;
2311
+ const startArrowW = element.shapeStyle?.connectorStartArrowWidth;
2312
+ const startArrowL = element.shapeStyle?.connectorStartArrowLength;
2313
+ const endArrowW = element.shapeStyle?.connectorEndArrowWidth;
2314
+ const endArrowL = element.shapeStyle?.connectorEndArrowLength;
2315
+ const compoundLine = element.shapeStyle?.compoundLine;
2316
+ const connectorLineCap = pptx.svgLineCap(element.shapeStyle?.lineCap);
2317
+ const hitTargetWidth = Math.max(strokeWidth * 3, 12);
2318
+ const offsets = pptx.getCompoundLineOffsets(compoundLine, strokeWidth);
2319
+ const widths = pptx.getCompoundLineWidths(compoundLine, strokeWidth);
2320
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2321
+ "svg",
2322
+ {
2323
+ viewBox: `0 0 ${viewWidth} ${viewHeight}`,
2324
+ className: "w-full h-full",
2325
+ preserveAspectRatio: "none",
2326
+ style: { overflow: "visible", pointerEvents: "none" },
2327
+ children: [
2328
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
2329
+ renderConnectorMarker(startMarkerId, startArrow, strokePaint, startArrowW, startArrowL),
2330
+ renderConnectorMarker(endMarkerId, endArrow, strokePaint, endArrowW, endArrowL)
2331
+ ] }),
2332
+ /* @__PURE__ */ jsxRuntime.jsx(
2333
+ "path",
2334
+ {
2335
+ d: pathData,
2336
+ fill: "none",
2337
+ stroke: "transparent",
2338
+ strokeWidth: hitTargetWidth,
2339
+ strokeLinecap: "round",
2340
+ strokeLinejoin: "round",
2341
+ style: { pointerEvents: "stroke" }
2342
+ }
2343
+ ),
2344
+ offsets.map((offset, idx) => /* @__PURE__ */ jsxRuntime.jsx(
2345
+ "path",
2346
+ {
2347
+ d: pathData,
2348
+ fill: "none",
2349
+ stroke: strokePaint,
2350
+ strokeWidth: Math.max(widths[idx] ?? strokeWidth, 1),
2351
+ strokeDasharray: dashArray,
2352
+ strokeLinecap: connectorLineCap,
2353
+ strokeLinejoin: "round",
2354
+ markerStart: idx === 0 && startArrow && startArrow !== "none" ? `url(#${startMarkerId})` : void 0,
2355
+ markerEnd: idx === offsets.length - 1 && endArrow && endArrow !== "none" ? `url(#${endMarkerId})` : void 0,
2356
+ vectorEffect: "non-scaling-stroke",
2357
+ style: {
2358
+ pointerEvents: "none",
2359
+ ...offset !== 0 ? { transform: `translate(0, ${offset}px)` } : {}
2360
+ }
2361
+ },
2362
+ idx
2363
+ ))
2364
+ ]
2365
+ }
2366
+ );
2367
+ }
2368
+ return null;
2369
+ }
2370
+
2371
+ // src/viewer/utils/table-cell-fill.tsx
2372
+ function parseGradientFillCss(gradFill) {
2373
+ if (!gradFill) {
2374
+ return void 0;
2375
+ }
2376
+ const gsLstRaw = gradFill["a:gsLst"];
2377
+ if (!gsLstRaw) {
2378
+ return void 0;
2379
+ }
2380
+ const stops = ensureArrayValue(gsLstRaw["a:gs"]);
2381
+ if (stops.length === 0) {
2382
+ return void 0;
2383
+ }
2384
+ const rawStops = stops.map((gs) => {
2385
+ const pos = Number.parseInt(String(gs["@_pos"] || "0"), 10) / 1e3;
2386
+ const color = pptx.parseDrawingColor(gs) ?? "#888888";
2387
+ const opacity = pptx.parseDrawingColorOpacity(gs);
2388
+ return { position: pos, color, opacity };
2389
+ }).sort((a, b) => a.position - b.position);
2390
+ const stopStrings = rawStops.map((s) => `${pptx.colorWithOpacity(s.color, s.opacity)} ${s.position.toFixed(1)}%`).join(", ");
2391
+ const lin = gradFill["a:lin"];
2392
+ if (lin) {
2393
+ const angRaw = Number.parseInt(String(lin["@_ang"] || "0"), 10);
2394
+ const angleDeg = Math.round((0, dist_exports.ooxmlGradientAngleToCssDegrees)(angRaw / 6e4));
2395
+ return `linear-gradient(${angleDeg}deg, ${stopStrings})`;
2396
+ }
2397
+ const path = gradFill["a:path"];
2398
+ if (path) {
2399
+ const pathType = String(path["@_path"] || "circle");
2400
+ const fillToRectXml = path["a:fillToRect"];
2401
+ const fillToRect = fillToRectXml ? {
2402
+ l: Number.parseInt(String(fillToRectXml["@_l"] || "0"), 10) / 1e5,
2403
+ t: Number.parseInt(String(fillToRectXml["@_t"] || "0"), 10) / 1e5,
2404
+ r: Number.parseInt(String(fillToRectXml["@_r"] || "0"), 10) / 1e5,
2405
+ b: Number.parseInt(String(fillToRectXml["@_b"] || "0"), 10) / 1e5
2406
+ } : void 0;
2407
+ if (pathType === "rect") {
2408
+ return pptx.buildRectPathGradient(rawStops, void 0, fillToRect);
2409
+ }
2410
+ let cx = 50;
2411
+ let cy = 50;
2412
+ if (fillToRect) {
2413
+ const { l, t, r, b } = fillToRect;
2414
+ cx = (l + (1 - r)) / 2 * 100;
2415
+ cy = (t + (1 - b)) / 2 * 100;
2416
+ }
2417
+ const posX = `${Math.round(cx)}%`;
2418
+ const posY = `${Math.round(cy)}%`;
2419
+ if (pathType === "shape") {
2420
+ return `radial-gradient(farthest-side at ${posX} ${posY}, ${stopStrings})`;
2421
+ }
2422
+ return `radial-gradient(circle at ${posX} ${posY}, ${stopStrings})`;
2423
+ }
2424
+ return `linear-gradient(180deg, ${stopStrings})`;
2425
+ }
2426
+ function parsePatternFillCss(pattFill) {
2427
+ if (!pattFill) {
2428
+ return void 0;
2429
+ }
2430
+ const fgColor = pptx.parseDrawingColor(pattFill["a:fgClr"]) ?? "#000000";
2431
+ const bgColor = pptx.parseDrawingColor(pattFill["a:bgClr"]) ?? "#ffffff";
2432
+ const preset = String(pattFill["@_prst"] || "ltDnDiag");
2433
+ switch (preset) {
2434
+ case "ltHorz":
2435
+ case "horz":
2436
+ case "narHorz":
2437
+ case "dkHorz":
2438
+ case "wdUpDiag":
2439
+ return `repeating-linear-gradient(0deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2440
+ case "ltVert":
2441
+ case "vert":
2442
+ case "narVert":
2443
+ case "dkVert":
2444
+ case "wdDnDiag":
2445
+ return `repeating-linear-gradient(90deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2446
+ case "ltDnDiag":
2447
+ case "dnDiag":
2448
+ case "dkDnDiag":
2449
+ return `repeating-linear-gradient(135deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2450
+ case "ltUpDiag":
2451
+ case "upDiag":
2452
+ case "dkUpDiag":
2453
+ return `repeating-linear-gradient(45deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2454
+ case "dashHorz":
2455
+ case "dashVert":
2456
+ case "dashDnDiag":
2457
+ case "dashUpDiag":
2458
+ return `repeating-linear-gradient(135deg, ${bgColor}, ${bgColor} 4px, ${fgColor} 4px, ${fgColor} 6px, ${bgColor} 6px, ${bgColor} 10px)`;
2459
+ case "smCheck":
2460
+ case "lgCheck":
2461
+ return `repeating-conic-gradient(${fgColor} 0% 25%, ${bgColor} 0% 50%) 0 0 / 8px 8px`;
2462
+ case "smGrid":
2463
+ case "lgGrid":
2464
+ return `repeating-linear-gradient(0deg, ${fgColor} 0px, ${fgColor} 1px, transparent 1px, transparent 6px), repeating-linear-gradient(90deg, ${fgColor} 0px, ${fgColor} 1px, transparent 1px, transparent 6px), ${bgColor}`;
2465
+ case "dotGrid":
2466
+ case "pct5":
2467
+ case "pct10":
2468
+ case "pct20":
2469
+ case "pct25":
2470
+ case "pct30":
2471
+ case "pct40":
2472
+ case "pct50":
2473
+ case "pct60":
2474
+ case "pct70":
2475
+ case "pct75":
2476
+ case "pct80":
2477
+ case "pct90":
2478
+ return `radial-gradient(${fgColor} 1px, ${bgColor} 1px) 0 0 / 4px 4px`;
2479
+ case "smConfetti":
2480
+ case "lgConfetti":
2481
+ case "zigZag":
2482
+ case "wave":
2483
+ case "sphere":
2484
+ case "divot":
2485
+ case "shingle":
2486
+ case "weave":
2487
+ case "plaid":
2488
+ case "trellis":
2489
+ return `repeating-linear-gradient(45deg, ${bgColor}, ${bgColor} 2px, ${fgColor} 2px, ${fgColor} 3px)`;
2490
+ case "solidDmnd":
2491
+ case "openDmnd":
2492
+ return `repeating-conic-gradient(${fgColor} 0% 25%, ${bgColor} 0% 50%) 0 0 / 10px 10px`;
2493
+ default:
2494
+ return `repeating-linear-gradient(135deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2495
+ }
2496
+ }
2497
+ function ooxmlDashToCss(dashVal) {
2498
+ if (!dashVal) {
2499
+ return "solid";
2500
+ }
2501
+ switch (dashVal) {
2502
+ case "dot":
2503
+ case "sysDot":
2504
+ return "dotted";
2505
+ case "dash":
2506
+ case "sysDash":
2507
+ case "lgDash":
2508
+ return "dashed";
2509
+ case "dashDot":
2510
+ case "lgDashDot":
2511
+ case "sysDashDot":
2512
+ case "lgDashDotDot":
2513
+ case "sysDashDotDot":
2514
+ return "dashed";
2515
+ case "solid":
2516
+ return "solid";
2517
+ default:
2518
+ return "solid";
2519
+ }
2520
+ }
2521
+ function parseCellBorders(cellProperties) {
2522
+ if (!cellProperties) {
2523
+ return {};
2524
+ }
2525
+ const borderStyle = {};
2526
+ const edges = [
2527
+ { xml: "a:lnL", prefix: "borderLeft" },
2528
+ { xml: "a:lnR", prefix: "borderRight" },
2529
+ { xml: "a:lnT", prefix: "borderTop" },
2530
+ { xml: "a:lnB", prefix: "borderBottom" }
2531
+ ];
2532
+ for (const edge of edges) {
2533
+ const ln = cellProperties[edge.xml];
2534
+ if (!ln) {
2535
+ continue;
2536
+ }
2537
+ const widthEmu = Number.parseInt(String(ln["@_w"] || "0"), 10);
2538
+ const widthPx = Math.max(1, Math.round(widthEmu / 12700));
2539
+ const prstDash = ln["a:prstDash"];
2540
+ const dashVal = prstDash ? String(prstDash["@_val"] || "") : void 0;
2541
+ const cssBorderStyle = ooxmlDashToCss(dashVal);
2542
+ const color = pptx.parseDrawingColor(ln["a:solidFill"]);
2543
+ if (color) {
2544
+ const opacity = pptx.parseDrawingColorOpacity(ln["a:solidFill"]);
2545
+ const key = `${edge.prefix}`;
2546
+ borderStyle[key] = `${widthPx}px ${cssBorderStyle} ${pptx.colorWithOpacity(color, opacity)}`;
2547
+ }
2548
+ }
2549
+ return borderStyle;
2550
+ }
2551
+ function parseCellTextEffects(runProps) {
2552
+ const effectLst = runProps?.["a:effectLst"];
2553
+ if (!effectLst) {
2554
+ return void 0;
2555
+ }
2556
+ const textShadowParts = [];
2557
+ const outerShdw = effectLst["a:outerShdw"];
2558
+ if (outerShdw) {
2559
+ const shdwColor = pptx.parseDrawingColor(outerShdw);
2560
+ if (shdwColor) {
2561
+ const blurRad = Number.parseInt(String(outerShdw["@_blurRad"] || "0"), 10);
2562
+ const blurPx = blurRad > 0 ? Math.round(blurRad / 12700) : 0;
2563
+ const distVal = Number.parseInt(String(outerShdw["@_dist"] || "0"), 10);
2564
+ const dirVal = Number.parseInt(String(outerShdw["@_dir"] || "0"), 10);
2565
+ let offX = 0;
2566
+ let offY = 0;
2567
+ if (distVal > 0) {
2568
+ const angleRad = dirVal / 6e4 * (Math.PI / 180);
2569
+ offX = Math.round(distVal * Math.cos(angleRad) / 12700);
2570
+ offY = Math.round(distVal * Math.sin(angleRad) / 12700);
2571
+ }
2572
+ textShadowParts.push(`${offX}px ${offY}px ${blurPx}px ${shdwColor}`);
2573
+ }
2574
+ }
2575
+ const glow = effectLst["a:glow"];
2576
+ if (glow) {
2577
+ const glowColor = pptx.parseDrawingColor(glow);
2578
+ if (glowColor) {
2579
+ const glowRad = Number.parseInt(String(glow["@_rad"] || "0"), 10);
2580
+ const glowPx = glowRad > 0 ? Math.round(glowRad / 12700) : 2;
2581
+ textShadowParts.push(`0px 0px ${glowPx}px ${glowColor}`);
2582
+ }
2583
+ }
2584
+ return textShadowParts.length > 0 ? textShadowParts.join(", ") : void 0;
2585
+ }
2586
+
2587
+ // src/viewer/utils/table-cell-style.tsx
2588
+ function extractCellText(cellXml) {
2589
+ if (!cellXml) {
2590
+ return "";
2591
+ }
2592
+ const txBody = cellXml["a:txBody"];
2593
+ const paragraphs = ensureArrayValue(txBody?.["a:p"]);
2594
+ const paragraphTexts = [];
2595
+ paragraphs.forEach((paragraph) => {
2596
+ const textParts = [];
2597
+ const runs = ensureArrayValue(paragraph["a:r"]);
2598
+ runs.forEach((run) => {
2599
+ textParts.push((0, dist_exports.xmlText)(run["a:t"]) ?? "");
2600
+ });
2601
+ const fields = ensureArrayValue(paragraph["a:fld"]);
2602
+ fields.forEach((field) => {
2603
+ textParts.push((0, dist_exports.xmlText)(field["a:t"]) ?? "");
2604
+ });
2605
+ paragraphTexts.push(textParts.join(""));
2606
+ });
2607
+ return paragraphTexts.join("\n");
2608
+ }
2609
+ function parseParagraphAlignment(value) {
2610
+ const alignment = String(value || "").toLowerCase();
2611
+ if (alignment === "ctr") {
2612
+ return "center";
2613
+ }
2614
+ if (alignment === "r") {
2615
+ return "right";
2616
+ }
2617
+ if (alignment === "just" || alignment === "justify") {
2618
+ return "justify";
2619
+ }
2620
+ return "left";
2621
+ }
2622
+ function extractTableCellStyle(cellXml, fallbackStyle, schemeColorOverrides) {
2623
+ const { color: _fallbackColor, ...fallbackWithoutColor } = fallbackStyle;
2624
+ const cellStyle = { ...fallbackWithoutColor };
2625
+ const txBody = cellXml["a:txBody"];
2626
+ const paragraphs = ensureArrayValue(txBody?.["a:p"]);
2627
+ const firstParagraph = paragraphs[0];
2628
+ const paragraphProperties = firstParagraph?.["a:pPr"];
2629
+ const runs = ensureArrayValue(firstParagraph?.["a:r"]);
2630
+ const firstRun = runs[0];
2631
+ const runProps = firstRun?.["a:rPr"] || paragraphProperties?.["a:defRPr"];
2632
+ if (runProps?.["@_sz"]) {
2633
+ const pointSize = Number.parseInt(String(runProps["@_sz"]), 10) / 100;
2634
+ if (Number.isFinite(pointSize) && pointSize > 0) {
2635
+ cellStyle.fontSize = pointSize * (96 / 72);
2636
+ }
2637
+ }
2638
+ if (runProps?.["@_b"] !== void 0) {
2639
+ cellStyle.fontWeight = runProps["@_b"] === "1" ? 700 : 400;
2640
+ }
2641
+ if (runProps?.["@_i"] !== void 0) {
2642
+ cellStyle.fontStyle = runProps["@_i"] === "1" ? "italic" : "normal";
2643
+ }
2644
+ if (runProps?.["@_u"] !== void 0) {
2645
+ cellStyle.textDecorationLine = runProps["@_u"] === "sng" ? "underline" : "none";
2646
+ }
2647
+ const runColor = pptx.parseDrawingColor(runProps?.["a:solidFill"], schemeColorOverrides) || pptx.parseDrawingColor(runProps?.["a:highlight"], schemeColorOverrides);
2648
+ if (runColor) {
2649
+ const opacity = pptx.parseDrawingColorOpacity(runProps?.["a:solidFill"]);
2650
+ cellStyle.color = pptx.colorWithOpacity(runColor, opacity);
2651
+ }
2652
+ const fontFamily = runProps?.["a:latin"]?.["@_typeface"] || runProps?.["a:ea"]?.["@_typeface"] || runProps?.["a:cs"]?.["@_typeface"];
2653
+ if (fontFamily) {
2654
+ cellStyle.fontFamily = fontFamily;
2655
+ }
2656
+ if (paragraphProperties?.["@_algn"]) {
2657
+ cellStyle.textAlign = parseParagraphAlignment(paragraphProperties["@_algn"]);
2658
+ }
2659
+ const cellProperties = cellXml["a:tcPr"];
2660
+ const cellFill = pptx.parseDrawingColor(
2661
+ cellProperties?.["a:solidFill"],
2662
+ schemeColorOverrides
2663
+ );
2664
+ if (cellFill) {
2665
+ const opacity = pptx.parseDrawingColorOpacity(
2666
+ cellProperties?.["a:solidFill"]
2667
+ );
2668
+ cellStyle.backgroundColor = pptx.colorWithOpacity(cellFill, opacity);
2669
+ } else {
2670
+ const gradCss = parseGradientFillCss(cellProperties?.["a:gradFill"]);
2671
+ if (gradCss) {
2672
+ cellStyle.background = gradCss;
2673
+ } else {
2674
+ const pattCss = parsePatternFillCss(cellProperties?.["a:pattFill"]);
2675
+ if (pattCss) {
2676
+ cellStyle.background = pattCss;
2677
+ }
2678
+ }
2679
+ }
2680
+ const edgeBorders = parseCellBorders(cellProperties);
2681
+ Object.assign(cellStyle, edgeBorders);
2682
+ if (!cellStyle.borderLeftColor && !cellStyle.borderRightColor && !cellStyle.borderTopColor && !cellStyle.borderBottomColor) {
2683
+ const borderColor = pptx.parseDrawingColor(
2684
+ cellProperties?.["a:lnL"]?.["a:solidFill"],
2685
+ schemeColorOverrides
2686
+ ) || pptx.parseDrawingColor(
2687
+ cellProperties?.["a:lnR"]?.["a:solidFill"],
2688
+ schemeColorOverrides
2689
+ ) || pptx.parseDrawingColor(
2690
+ cellProperties?.["a:lnT"]?.["a:solidFill"],
2691
+ schemeColorOverrides
2692
+ ) || pptx.parseDrawingColor(
2693
+ cellProperties?.["a:lnB"]?.["a:solidFill"],
2694
+ schemeColorOverrides
2695
+ );
2696
+ if (borderColor) {
2697
+ cellStyle.borderColor = borderColor;
2698
+ }
2699
+ }
2700
+ if (cellProperties) {
2701
+ const margin = (key) => Number.parseInt(String(cellProperties[key] ?? ""), 10) / EMU_PER_PX;
2702
+ const marL = margin("@_marL");
2703
+ const marR = margin("@_marR");
2704
+ const marT = margin("@_marT");
2705
+ const marB = margin("@_marB");
2706
+ if (marL >= 0) {
2707
+ cellStyle.paddingLeft = marL;
2708
+ }
2709
+ if (marR >= 0) {
2710
+ cellStyle.paddingRight = marR;
2711
+ }
2712
+ if (marT >= 0) {
2713
+ cellStyle.paddingTop = marT;
2714
+ }
2715
+ if (marB >= 0) {
2716
+ cellStyle.paddingBottom = marB;
2717
+ }
2718
+ }
2719
+ if (cellProperties?.["@_anchor"]) {
2720
+ const anchor = String(cellProperties["@_anchor"]);
2721
+ if (anchor === "ctr") {
2722
+ cellStyle.verticalAlign = "middle";
2723
+ } else if (anchor === "b") {
2724
+ cellStyle.verticalAlign = "bottom";
2725
+ } else {
2726
+ cellStyle.verticalAlign = "top";
2727
+ }
2728
+ }
2729
+ if (cellProperties?.["@_vert"]) {
2730
+ const vert = String(cellProperties["@_vert"]);
2731
+ switch (vert) {
2732
+ case "vert":
2733
+ case "eaVert":
2734
+ case "wordArtVert":
2735
+ case "wordArtVertRtl":
2736
+ cellStyle.writingMode = "vertical-rl";
2737
+ break;
2738
+ case "vert270":
2739
+ case "mongolianVert":
2740
+ cellStyle.writingMode = "vertical-lr";
2741
+ break;
2742
+ }
2743
+ if (vert === "wordArtVert") {
2744
+ cellStyle.textOrientation = "upright";
2745
+ } else if (cellStyle.writingMode) {
2746
+ cellStyle.textOrientation = "mixed";
2747
+ }
2748
+ if (vert === "wordArtVertRtl") {
2749
+ cellStyle.direction = "rtl";
2750
+ }
2751
+ }
2752
+ const textShadow = parseCellTextEffects(runProps);
2753
+ if (textShadow) {
2754
+ cellStyle.textShadow = textShadow;
2755
+ }
2756
+ return cellStyle;
2757
+ }
2758
+ function getTableCellBandStyle(element, rowIndex, cellIndex, rowCount, columnCount, styleCtx) {
2759
+ if (element.type !== "table") {
2760
+ return void 0;
2761
+ }
2762
+ return pptx.getTableCellBandStyle(element.tableData, rowIndex, cellIndex, rowCount, columnCount, {
2763
+ tableStyleMap: styleCtx?.tableStyleMap,
2764
+ colorScheme: styleCtx?.theme?.colorScheme,
2765
+ fontScheme: styleCtx?.theme?.fontScheme
2766
+ });
2767
+ }
2768
+
2769
+ // src/viewer/utils/table-data-parse.tsx
2770
+ function getGraphicDataFromElement(element) {
2771
+ return element.rawXml?.["a:graphic"]?.["a:graphicData"];
2772
+ }
2773
+ function getTableXmlFromElement(element) {
2774
+ return getGraphicDataFromElement(element)?.["a:tbl"];
2775
+ }
2776
+ function parseTableElementData(element, fallbackTextStyle) {
2777
+ const table = getTableXmlFromElement(element);
2778
+ if (!table) {
2779
+ return null;
2780
+ }
2781
+ const rows = ensureArrayValue(table["a:tr"]);
2782
+ if (rows.length === 0) {
2783
+ return null;
2784
+ }
2785
+ const tableGrid = table["a:tblGrid"];
2786
+ const gridColumns = ensureArrayValue(
2787
+ tableGrid?.["a:gridCol"]
2788
+ );
2789
+ const columnWidths = gridColumns.map((column) => {
2790
+ const width = Number.parseInt(String(column?.["@_w"] || ""), 10);
2791
+ return Number.isFinite(width) && width > 0 ? width : 0;
2792
+ });
2793
+ const totalColumnWidth = columnWidths.reduce((sum, width) => sum + width, 0);
2794
+ let columnPercentages = totalColumnWidth > 0 ? columnWidths.map((width) => width / totalColumnWidth * 100) : [];
2795
+ const modelWidths = element.type === "table" ? element.tableData?.columnWidths : void 0;
2796
+ if (modelWidths?.length && modelWidths.length === gridColumns.length && modelWidths.every((width) => Number.isFinite(width) && width >= 0) && Math.abs(modelWidths.reduce((sum, width) => sum + width, 0) - 1) <= Number.EPSILON * modelWidths.length * 4) {
2797
+ columnPercentages = modelWidths.map((width) => width * 100);
2798
+ }
2799
+ const cells = [];
2800
+ rows.forEach((row, rowIndex) => {
2801
+ const rowCells = ensureArrayValue(row["a:tc"]);
2802
+ rowCells.forEach((cell, columnIndex) => {
2803
+ cells.push({
2804
+ rowIndex,
2805
+ columnIndex,
2806
+ text: extractCellText(cell),
2807
+ style: extractTableCellStyle(cell, fallbackTextStyle),
2808
+ rawCell: cell
2809
+ });
2810
+ });
2811
+ });
2812
+ const columnCount = Math.max(
2813
+ columnPercentages.length,
2814
+ rows.reduce((maxCount, row) => {
2815
+ const rowCells = ensureArrayValue(row["a:tc"]);
2816
+ return Math.max(maxCount, rowCells.length);
2817
+ }, 0)
2818
+ );
2819
+ return {
2820
+ rowCount: rows.length,
2821
+ columnCount,
2822
+ rows,
2823
+ columnPercentages,
2824
+ cells
2825
+ };
2826
+ }
2827
+ function renderTableCellContent(cell, fallbackText) {
2828
+ const blocks = cell ? pptx.cellParagraphBlocks(cell) : void 0;
2829
+ if (blocks) {
2830
+ return blocks.map((block, index) => /* @__PURE__ */ jsxRuntime.jsx(
2831
+ "div",
2832
+ {
2833
+ style: { display: "block", ...block.css },
2834
+ children: block.runs.map(renderRun)
2835
+ },
2836
+ `p-${index}`
2837
+ ));
2838
+ }
2839
+ const runs = cell?.textRuns;
2840
+ if (!runs || runs.length === 0) {
2841
+ return fallbackText || " ";
2842
+ }
2843
+ return runs.map(
2844
+ (run, index) => run.isParagraphBreak ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "block", height: 0 } }, `p-${index}`) : renderRun(run, index)
2845
+ );
2846
+ }
2847
+ function renderRun(run, index) {
2848
+ if (run.isLineBreak) {
2849
+ return /* @__PURE__ */ jsxRuntime.jsx("br", {}, `br-${index}`);
2850
+ }
2851
+ return /* @__PURE__ */ jsxRuntime.jsx(
2852
+ "span",
2853
+ {
2854
+ style: { position: "relative", ...pptx.cellRunStyle(run) },
2855
+ children: run.text
2856
+ },
2857
+ `r-${index}`
2858
+ );
2859
+ }
2860
+ function getCellDiagonalBorders(style, tableData, pos, styleCtx) {
2861
+ return pptx.getCellDiagonalBorders(style, tableData, pos, {
2862
+ tableStyleMap: styleCtx?.tableStyleMap,
2863
+ colorScheme: styleCtx?.theme?.colorScheme,
2864
+ fontScheme: styleCtx?.theme?.fontScheme
2865
+ });
2866
+ }
2867
+ function TableCellDiagonalBorders({
2868
+ diag
2869
+ }) {
2870
+ const hasDown = Boolean(diag.diagDownColor && diag.diagDownWidth);
2871
+ const hasUp = Boolean(diag.diagUpColor && diag.diagUpWidth);
2872
+ if (!hasDown && !hasUp) {
2873
+ return null;
2874
+ }
2875
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2876
+ "svg",
2877
+ {
2878
+ "aria-hidden": "true",
2879
+ style: {
2880
+ position: "absolute",
2881
+ inset: 0,
2882
+ width: "100%",
2883
+ height: "100%",
2884
+ pointerEvents: "none",
2885
+ overflow: "visible"
2886
+ },
2887
+ children: [
2888
+ hasDown && /* @__PURE__ */ jsxRuntime.jsx(
2889
+ "line",
2890
+ {
2891
+ x1: "0",
2892
+ y1: "0",
2893
+ x2: "100%",
2894
+ y2: "100%",
2895
+ stroke: diag.diagDownColor,
2896
+ strokeWidth: diag.diagDownWidth
2897
+ }
2898
+ ),
2899
+ hasUp && /* @__PURE__ */ jsxRuntime.jsx(
2900
+ "line",
2901
+ {
2902
+ x1: "0",
2903
+ y1: "100%",
2904
+ x2: "100%",
2905
+ y2: "0",
2906
+ stroke: diag.diagUpColor,
2907
+ strokeWidth: diag.diagUpWidth
2908
+ }
2909
+ )
2910
+ ]
2911
+ }
2912
+ );
2913
+ }
2914
+ function TableCellInput({
2915
+ initialText,
2916
+ style,
2917
+ onCommit,
2918
+ onCancel
2919
+ }) {
2920
+ const inputRef = React8.useRef(null);
2921
+ const committedRef = React8.useRef(false);
2922
+ const onCommitRef = React8.useRef(onCommit);
2923
+ onCommitRef.current = onCommit;
2924
+ React8.useEffect(() => {
2925
+ const el = inputRef.current;
2926
+ if (el) {
2927
+ el.focus();
2928
+ el.select();
2929
+ }
2930
+ }, []);
2931
+ React8.useEffect(() => {
2932
+ const input = inputRef.current;
2933
+ return () => {
2934
+ if (!committedRef.current && input) {
2935
+ onCommitRef.current(input.value);
2936
+ }
2937
+ };
2938
+ }, []);
2939
+ const doCommit = (text) => {
2940
+ if (committedRef.current) {
2941
+ return;
2942
+ }
2943
+ committedRef.current = true;
2944
+ onCommit(text);
2945
+ };
2946
+ const doCancel = () => {
2947
+ committedRef.current = true;
2948
+ onCancel();
2949
+ };
2950
+ return /* @__PURE__ */ jsxRuntime.jsx(
2951
+ "input",
2952
+ {
2953
+ ref: inputRef,
2954
+ type: "text",
2955
+ defaultValue: initialText,
2956
+ className: "w-full bg-transparent outline-none",
2957
+ style: {
2958
+ ...style,
2959
+ padding: 0,
2960
+ margin: 0,
2961
+ border: "none"
2962
+ },
2963
+ onPointerDown: (e) => e.stopPropagation(),
2964
+ onMouseDown: (e) => e.stopPropagation(),
2965
+ onClick: (e) => e.stopPropagation(),
2966
+ onDoubleClick: (e) => e.stopPropagation(),
2967
+ onBlur: (e) => doCommit(e.currentTarget.value),
2968
+ onKeyDown: (e) => {
2969
+ e.stopPropagation();
2970
+ if (e.key === "Escape") {
2971
+ e.preventDefault();
2972
+ doCancel();
2973
+ } else if (e.key === "Enter") {
2974
+ e.preventDefault();
2975
+ doCommit(e.currentTarget.value);
2976
+ } else if (e.key === "Tab") {
2977
+ e.preventDefault();
2978
+ doCommit(e.currentTarget.value);
2979
+ }
2980
+ }
2981
+ }
2982
+ );
2983
+ }
2984
+ function TableResizeOverlay({
2985
+ children,
2986
+ columnWidths,
2987
+ editable,
2988
+ onResizeColumns,
2989
+ onResizeRow
2990
+ }) {
2991
+ const containerRef = React8.useRef(null);
2992
+ const [rowBounds, setRowBounds] = React8.useState([]);
2993
+ const dragRef = React8.useRef(null);
2994
+ const colBoundaries = React8.useMemo(() => pptx.computeColumnBoundaries(columnWidths), [columnWidths]);
2995
+ const measureRows = React8.useCallback(() => {
2996
+ const container = containerRef.current;
2997
+ if (!container) {
2998
+ return;
2999
+ }
3000
+ const table = container.querySelector("table");
3001
+ if (!table) {
3002
+ return;
3003
+ }
3004
+ const trs = table.querySelectorAll("tbody > tr");
3005
+ const bounds = [];
3006
+ let cumHeight = 0;
3007
+ trs.forEach((tr, i) => {
3008
+ cumHeight += tr.offsetHeight;
3009
+ if (i < trs.length - 1) {
3010
+ bounds.push(cumHeight);
3011
+ }
3012
+ });
3013
+ setRowBounds((prev) => {
3014
+ if (prev.length === bounds.length && prev.every((v, i) => v === bounds[i])) {
3015
+ return prev;
3016
+ }
3017
+ return bounds;
3018
+ });
3019
+ }, []);
3020
+ React8.useLayoutEffect(() => {
3021
+ measureRows();
3022
+ });
3023
+ React8.useEffect(() => {
3024
+ const handleMouseMove = (e) => {
3025
+ const drag = dragRef.current;
3026
+ if (!drag) {
3027
+ return;
3028
+ }
3029
+ e.preventDefault();
3030
+ const delta = drag.type === "col" ? e.clientX - drag.startPos : e.clientY - drag.startPos;
3031
+ drag.handleEl.style.transform = drag.type === "col" ? `translateX(${delta}px)` : `translateY(${delta}px)`;
3032
+ };
3033
+ const handleMouseUp = (e) => {
3034
+ const drag = dragRef.current;
3035
+ if (!drag || !containerRef.current) {
3036
+ return;
3037
+ }
3038
+ const rect = containerRef.current.getBoundingClientRect();
3039
+ if (e.clientX !== drag.startPos && drag.type === "col" && drag.initialWidths && onResizeColumns) {
3040
+ const deltaProp = (e.clientX - drag.startPos) / rect.width;
3041
+ onResizeColumns(pptx.computeResizedColumnWidths(drag.initialWidths, drag.index, deltaProp));
3042
+ } else if (e.clientY !== drag.startPos && drag.type === "row" && onResizeRow) {
3043
+ const deltaY = e.clientY - drag.startPos;
3044
+ const newHeight = pptx.computeResizedRowHeight(
3045
+ drag.initialRowHeight ?? pptx.DEFAULT_ROW_HEIGHT,
3046
+ deltaY
3047
+ );
3048
+ onResizeRow(drag.index, newHeight);
3049
+ }
3050
+ drag.handleEl.style.transform = "";
3051
+ document.body.style.cursor = "";
3052
+ document.body.style.userSelect = "";
3053
+ dragRef.current = null;
3054
+ };
3055
+ document.addEventListener("mousemove", handleMouseMove);
3056
+ document.addEventListener("mouseup", handleMouseUp);
3057
+ return () => {
3058
+ document.removeEventListener("mousemove", handleMouseMove);
3059
+ document.removeEventListener("mouseup", handleMouseUp);
3060
+ };
3061
+ }, [onResizeColumns, onResizeRow]);
3062
+ if (!editable) {
3063
+ return children;
3064
+ }
3065
+ const startColDrag = (e, index) => {
3066
+ e.preventDefault();
3067
+ e.stopPropagation();
3068
+ document.body.style.cursor = "col-resize";
3069
+ document.body.style.userSelect = "none";
3070
+ dragRef.current = {
3071
+ type: "col",
3072
+ index,
3073
+ startPos: e.clientX,
3074
+ handleEl: e.currentTarget,
3075
+ initialWidths: [...columnWidths]
3076
+ };
3077
+ };
3078
+ const startRowDrag = (e, index) => {
3079
+ e.preventDefault();
3080
+ e.stopPropagation();
3081
+ const table = containerRef.current?.querySelector("table");
3082
+ const tr = table?.querySelectorAll("tbody > tr")[index];
3083
+ const actualHeight = tr?.offsetHeight ?? pptx.DEFAULT_ROW_HEIGHT;
3084
+ document.body.style.cursor = "row-resize";
3085
+ document.body.style.userSelect = "none";
3086
+ dragRef.current = {
3087
+ type: "row",
3088
+ index,
3089
+ startPos: e.clientY,
3090
+ handleEl: e.currentTarget,
3091
+ initialRowHeight: actualHeight
3092
+ };
3093
+ };
3094
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "relative w-full h-full", children: [
3095
+ children,
3096
+ colBoundaries.map((leftPct, i) => /* @__PURE__ */ jsxRuntime.jsx(
3097
+ "div",
3098
+ {
3099
+ className: "absolute top-0 bottom-0 w-[6px] cursor-col-resize z-10 pointer-events-auto group",
3100
+ style: { left: `calc(${leftPct}% - 3px)` },
3101
+ onMouseDown: (e) => startColDrag(e, i),
3102
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-full mx-auto bg-transparent group-hover:bg-blue-400/60 transition-colors" })
3103
+ },
3104
+ `col-h-${i}`
3105
+ )),
3106
+ rowBounds.map((topPx, i) => /* @__PURE__ */ jsxRuntime.jsx(
3107
+ "div",
3108
+ {
3109
+ className: "absolute left-0 right-0 h-[6px] cursor-row-resize z-10 pointer-events-auto group",
3110
+ style: { top: `${topPx - 3}px` },
3111
+ onMouseDown: (e) => startRowDrag(e, i),
3112
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px w-full my-auto bg-transparent group-hover:bg-blue-400/60 transition-colors" })
3113
+ },
3114
+ `row-h-${i}`
3115
+ ))
3116
+ ] });
3117
+ }
3118
+ function renderTableFromTableData(element, textStyle, options) {
3119
+ const tableData = element.tableData;
3120
+ const rowCount = tableData.rows.length;
3121
+ const columnCount = tableData.columnWidths.length;
3122
+ const selectedCell = options?.selectedCell || null;
3123
+ const isEditable = Boolean(options?.editable) && pptx.canDrillDown(element);
3124
+ const hasCellSelectionHandler = typeof options?.onSelectCell === "function";
3125
+ const sharedCtx = {
3126
+ tableStyleMap: options?.styleCtx?.tableStyleMap,
3127
+ colorScheme: options?.styleCtx?.theme?.colorScheme,
3128
+ fontScheme: options?.styleCtx?.theme?.fontScheme
3129
+ };
3130
+ const cellCss = (cell, rowIndex, cellIndex) => pptx.tableCellCss(
3131
+ tableData,
3132
+ cell,
3133
+ { rowIndex, cellIndex, rowCount, columnCount },
3134
+ sharedCtx,
3135
+ textStyle
3136
+ );
3137
+ const selectionRect = (() => {
3138
+ if (!selectedCell?.selectedCells || selectedCell.selectedCells.length < 2) {
3139
+ return void 0;
3140
+ }
3141
+ const first = selectedCell.selectedCells[0];
3142
+ const last = selectedCell.selectedCells[selectedCell.selectedCells.length - 1];
3143
+ return pptx.computeSelectionRect(first.row, first.col, last.row, last.col, tableData);
3144
+ })();
3145
+ return /* @__PURE__ */ jsxRuntime.jsx(
3146
+ TableResizeOverlay,
3147
+ {
3148
+ columnWidths: tableData.columnWidths,
3149
+ editable: isEditable,
3150
+ onResizeColumns: options?.onResizeColumns,
3151
+ onResizeRow: options?.onResizeRow,
3152
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3153
+ "div",
3154
+ {
3155
+ className: cn(
3156
+ "w-full h-full overflow-hidden",
3157
+ isEditable && hasCellSelectionHandler ? "pointer-events-auto" : "pointer-events-none"
3158
+ ),
3159
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3160
+ "table",
3161
+ {
3162
+ className: "w-full h-full border-collapse table-fixed",
3163
+ style: {
3164
+ fontFamily: pptx.DEFAULT_FONT_FAMILY,
3165
+ // `a:tblPr@rtl` mirrors the column order for RTL decks.
3166
+ ...pptx.tableContainerCss(tableData)
3167
+ },
3168
+ children: [
3169
+ tableData.columnWidths.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: tableData.columnWidths.map((w, ci) => /* @__PURE__ */ jsxRuntime.jsx(
3170
+ "col",
3171
+ {
3172
+ style: { width: `${(w * 100).toFixed(2)}%` }
3173
+ },
3174
+ `${element.id}-col-${ci}`
3175
+ )) }),
3176
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: tableData.rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
3177
+ "tr",
3178
+ {
3179
+ style: row.height ? { height: row.height } : void 0,
3180
+ children: row.cells.map((cell, cellIndex) => {
3181
+ if (cell.hMerge || cell.vMerge) {
3182
+ return null;
3183
+ }
3184
+ const isCellSelected = selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex;
3185
+ const isInMultiSelection = pptx.isCellInRect(rowIndex, cellIndex, selectionRect);
3186
+ const isCellEditing = isCellSelected && selectedCell?.isEditing;
3187
+ const diag = getCellDiagonalBorders(
3188
+ cell.style,
3189
+ tableData,
3190
+ { rowIndex, cellIndex, rowCount, columnCount },
3191
+ options?.styleCtx
3192
+ );
3193
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3194
+ "td",
3195
+ {
3196
+ className: cn(
3197
+ "px-1 py-0.5 align-top",
3198
+ // No border of its own: a side the deck gives no border renders with
3199
+ // none, as PowerPoint does. Editing keeps a faint grid.
3200
+ isEditable && hasCellSelectionHandler ? "border border-blue-200/70 cursor-cell" : null,
3201
+ isCellSelected ? "ring-1 ring-inset ring-blue-500" : null,
3202
+ isInMultiSelection && !isCellSelected ? "bg-blue-500/15 ring-1 ring-inset ring-blue-400/50" : null
3203
+ ),
3204
+ colSpan: cell.gridSpan && cell.gridSpan > 1 ? cell.gridSpan : void 0,
3205
+ rowSpan: cell.rowSpan && cell.rowSpan > 1 ? cell.rowSpan : void 0,
3206
+ style: {
3207
+ ...cellCss(cell, rowIndex, cellIndex),
3208
+ ...diag ? { position: "relative" } : void 0
3209
+ },
3210
+ onClick: (event) => {
3211
+ if (!isEditable || !hasCellSelectionHandler) {
3212
+ return;
3213
+ }
3214
+ event.stopPropagation();
3215
+ if (event.shiftKey && selectedCell) {
3216
+ const rect = pptx.computeSelectionRect(
3217
+ selectedCell.rowIndex,
3218
+ selectedCell.columnIndex,
3219
+ rowIndex,
3220
+ cellIndex,
3221
+ tableData
3222
+ );
3223
+ options?.onSelectCell?.({
3224
+ rowIndex: selectedCell.rowIndex,
3225
+ columnIndex: selectedCell.columnIndex,
3226
+ selectedCells: pptx.rectToCells(rect)
3227
+ });
3228
+ } else {
3229
+ options?.onSelectCell?.({
3230
+ rowIndex,
3231
+ columnIndex: cellIndex
3232
+ });
3233
+ }
3234
+ },
3235
+ onDoubleClick: (event) => {
3236
+ if (!isEditable || !hasCellSelectionHandler) {
3237
+ return;
3238
+ }
3239
+ event.stopPropagation();
3240
+ options?.onSelectCell?.({
3241
+ rowIndex,
3242
+ columnIndex: cellIndex,
3243
+ isEditing: true
3244
+ });
3245
+ },
3246
+ children: [
3247
+ diag ? /* @__PURE__ */ jsxRuntime.jsx(TableCellDiagonalBorders, { diag }) : null,
3248
+ isCellEditing ? /* @__PURE__ */ jsxRuntime.jsx(
3249
+ TableCellInput,
3250
+ {
3251
+ initialText: cell.text ?? "",
3252
+ style: cellCss(cell, rowIndex, cellIndex),
3253
+ onCommit: (text) => {
3254
+ options?.onCommitCellEdit?.(rowIndex, cellIndex, text);
3255
+ },
3256
+ onCancel: () => {
3257
+ options?.onSelectCell?.({
3258
+ rowIndex,
3259
+ columnIndex: cellIndex
3260
+ });
3261
+ }
3262
+ }
3263
+ ) : renderTableCellContent(cell, cell.text || "\xA0")
3264
+ ]
3265
+ },
3266
+ `${element.id}-cell-${rowIndex}-${cellIndex}`
3267
+ );
3268
+ })
3269
+ },
3270
+ `${element.id}-row-${rowIndex}`
3271
+ )) })
3272
+ ]
3273
+ }
3274
+ )
3275
+ }
3276
+ )
3277
+ }
3278
+ );
3279
+ }
3280
+ function renderTableElement(element, textStyle, options) {
3281
+ const parsedTable = parseTableElementData(element, textStyle);
3282
+ if (!parsedTable) {
3283
+ const tableEl2 = element;
3284
+ if (tableEl2.tableData && tableEl2.tableData.rows.length > 0) {
3285
+ return renderTableFromTableData(tableEl2, textStyle, options);
3286
+ }
3287
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: i18n.translationsEn["pptx.table.title"] });
3288
+ }
3289
+ const selectedCell = options?.selectedCell || null;
3290
+ const isEditable = Boolean(options?.editable) && pptx.canDrillDown(element);
3291
+ const hasCellSelectionHandler = typeof options?.onSelectCell === "function";
3292
+ const tableEl = element;
3293
+ const xmlSelectionRect = (() => {
3294
+ if (!selectedCell?.selectedCells || selectedCell.selectedCells.length < 2) {
3295
+ return void 0;
3296
+ }
3297
+ if (!tableEl.tableData) {
3298
+ return void 0;
3299
+ }
3300
+ const first = selectedCell.selectedCells[0];
3301
+ const last = selectedCell.selectedCells[selectedCell.selectedCells.length - 1];
3302
+ return pptx.computeSelectionRect(first.row, first.col, last.row, last.col, tableEl.tableData);
3303
+ })();
3304
+ const schemeOverrides = options?.styleCtx?.theme?.colorScheme ? options.styleCtx.theme.colorScheme : void 0;
3305
+ return /* @__PURE__ */ jsxRuntime.jsx(
3306
+ TableResizeOverlay,
3307
+ {
3308
+ columnWidths: parsedTable.columnPercentages.map((p) => p / 100),
3309
+ editable: isEditable,
3310
+ onResizeColumns: options?.onResizeColumns,
3311
+ onResizeRow: options?.onResizeRow,
3312
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3313
+ "div",
3314
+ {
3315
+ className: cn(
3316
+ "w-full h-full overflow-hidden",
3317
+ isEditable && hasCellSelectionHandler ? "pointer-events-auto" : "pointer-events-none"
3318
+ ),
3319
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3320
+ "table",
3321
+ {
3322
+ className: "w-full h-full border-collapse table-fixed",
3323
+ style: {
3324
+ fontFamily: pptx.DEFAULT_FONT_FAMILY,
3325
+ // `a:tblPr@rtl` mirrors the column order for RTL decks.
3326
+ ...pptx.tableContainerCss(tableEl.tableData)
3327
+ },
3328
+ children: [
3329
+ parsedTable.columnPercentages.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: parsedTable.columnPercentages.map((percentage, columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(
3330
+ "col",
3331
+ {
3332
+ style: { width: `${percentage.toFixed(2)}%` }
3333
+ },
3334
+ `${element.id}-col-${columnIndex}`
3335
+ )) }) : null,
3336
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: parsedTable.rows.map((row, rowIndex) => {
3337
+ const cells = ensureArrayValue(row["a:tc"]);
3338
+ const rowHeightRaw = Number.parseInt(String(row["@_h"] || ""), 10);
3339
+ const rowHeight = Number.isFinite(rowHeightRaw) && rowHeightRaw > 0 ? Math.max(16, rowHeightRaw / EMU_PER_PX) : void 0;
3340
+ return /* @__PURE__ */ jsxRuntime.jsx(
3341
+ "tr",
3342
+ {
3343
+ style: rowHeight ? { height: rowHeight } : void 0,
3344
+ children: cells.map((cell, cellIndex) => {
3345
+ const isHMerged = cell["@_hMerge"] === "1";
3346
+ const isVMerged = cell["@_vMerge"] === "1";
3347
+ if (isHMerged || isVMerged) {
3348
+ return null;
3349
+ }
3350
+ const gridSpanRaw = Number.parseInt(String(cell["@_gridSpan"] || ""), 10);
3351
+ const colSpan = Number.isFinite(gridSpanRaw) && gridSpanRaw > 1 ? gridSpanRaw : void 0;
3352
+ const rowSpanRaw = Number.parseInt(String(cell["@_rowSpan"] || ""), 10);
3353
+ const rSpan = Number.isFinite(rowSpanRaw) && rowSpanRaw > 1 ? rowSpanRaw : void 0;
3354
+ const bandStyle = getTableCellBandStyle(
3355
+ element,
3356
+ rowIndex,
3357
+ cellIndex,
3358
+ parsedTable.rowCount,
3359
+ parsedTable.columnCount,
3360
+ options?.styleCtx
3361
+ );
3362
+ const xmlCellStyle = extractTableCellStyle(cell, textStyle, schemeOverrides);
3363
+ const tdCellOverride = tableEl.tableData?.rows[rowIndex]?.cells[cellIndex]?.style;
3364
+ const diag = getCellDiagonalBorders(
3365
+ tdCellOverride,
3366
+ tableEl.tableData,
3367
+ {
3368
+ rowIndex,
3369
+ cellIndex,
3370
+ rowCount: parsedTable.rowCount,
3371
+ columnCount: parsedTable.columnCount
3372
+ },
3373
+ options?.styleCtx
3374
+ );
3375
+ const mergedStyle = {
3376
+ // Lowest-priority fallback: `xmlCellStyle` never carries a
3377
+ // `color` of its own (see `extractTableCellStyle`), so this
3378
+ // is the only source when neither the table style band nor
3379
+ // an explicit run/cell colour applies.
3380
+ color: textStyle.color,
3381
+ // PowerPoint's line spacing and default margins, as
3382
+ // `tableCellCss` gives the structured-model path.
3383
+ ...pptx.TABLE_CELL_TEXT_DEFAULTS,
3384
+ ...bandStyle,
3385
+ ...xmlCellStyle,
3386
+ ...tdCellOverride ? pptx.cellStyleToCss(tdCellOverride) : void 0,
3387
+ ...diag ? { position: "relative" } : void 0
3388
+ };
3389
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3390
+ "td",
3391
+ {
3392
+ className: cn(
3393
+ "px-1 py-0.5 align-top",
3394
+ // No border of its own: a side the deck gives no border renders
3395
+ // with none, as PowerPoint does. Editing keeps a faint grid.
3396
+ isEditable && hasCellSelectionHandler ? "border border-blue-200/70 cursor-cell" : null,
3397
+ selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex ? "ring-1 ring-inset ring-blue-500" : null,
3398
+ pptx.isCellInRect(rowIndex, cellIndex, xmlSelectionRect) && !(selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex) ? "bg-blue-500/15 ring-1 ring-inset ring-blue-400/50" : null
3399
+ ),
3400
+ colSpan,
3401
+ rowSpan: rSpan,
3402
+ style: mergedStyle,
3403
+ onClick: (event) => {
3404
+ if (!isEditable || !hasCellSelectionHandler) {
3405
+ return;
3406
+ }
3407
+ event.stopPropagation();
3408
+ if (event.shiftKey && selectedCell && tableEl.tableData) {
3409
+ const rect = pptx.computeSelectionRect(
3410
+ selectedCell.rowIndex,
3411
+ selectedCell.columnIndex,
3412
+ rowIndex,
3413
+ cellIndex,
3414
+ tableEl.tableData
3415
+ );
3416
+ options?.onSelectCell?.({
3417
+ rowIndex: selectedCell.rowIndex,
3418
+ columnIndex: selectedCell.columnIndex,
3419
+ selectedCells: pptx.rectToCells(rect)
3420
+ });
3421
+ } else {
3422
+ options?.onSelectCell?.({
3423
+ rowIndex,
3424
+ columnIndex: cellIndex
3425
+ });
3426
+ }
3427
+ },
3428
+ onDoubleClick: (event) => {
3429
+ if (!isEditable || !hasCellSelectionHandler) {
3430
+ return;
3431
+ }
3432
+ event.stopPropagation();
3433
+ options?.onSelectCell?.({
3434
+ rowIndex,
3435
+ columnIndex: cellIndex,
3436
+ isEditing: true
3437
+ });
3438
+ },
3439
+ children: [
3440
+ diag ? /* @__PURE__ */ jsxRuntime.jsx(TableCellDiagonalBorders, { diag }) : null,
3441
+ selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex && selectedCell?.isEditing ? /* @__PURE__ */ jsxRuntime.jsx(
3442
+ TableCellInput,
3443
+ {
3444
+ initialText: extractCellText(cell) ?? "",
3445
+ style: mergedStyle,
3446
+ onCommit: (text) => {
3447
+ options?.onCommitCellEdit?.(rowIndex, cellIndex, text);
3448
+ },
3449
+ onCancel: () => {
3450
+ options?.onSelectCell?.({
3451
+ rowIndex,
3452
+ columnIndex: cellIndex
3453
+ });
3454
+ }
3455
+ }
3456
+ ) : renderTableCellContent(
3457
+ tableEl.tableData?.rows[rowIndex]?.cells[cellIndex],
3458
+ extractCellText(cell) || "\xA0"
3459
+ )
3460
+ ]
3461
+ },
3462
+ `${element.id}-cell-${rowIndex}-${cellIndex}`
3463
+ );
3464
+ })
3465
+ },
3466
+ `${element.id}-row-${rowIndex}`
3467
+ );
3468
+ }) })
3469
+ ]
3470
+ }
3471
+ )
3472
+ }
3473
+ )
3474
+ }
3475
+ );
3476
+ }
3477
+ function renderGradientStops(stops) {
3478
+ return stops.map((stop, i) => /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: stop.offset, stopColor: stop.color, stopOpacity: stop.opacity }, i));
3479
+ }
3480
+ function partAttrs(part) {
3481
+ return part ? pptx.chartPartToAttrs(part) : void 0;
3482
+ }
3483
+ function resolveReactPalette(chartData) {
3484
+ return pptx.resolveChartPalette(chartData);
3485
+ }
3486
+ function buildReactChartViewModel(element) {
3487
+ if (element.type !== "chart" || !element.chartData) {
3488
+ return pptx.buildChartViewModel(element);
3489
+ }
3490
+ const palette = resolveReactPalette(element.chartData), themedElement = {
3491
+ ...element,
3492
+ chartData: { ...element.chartData, colorPalette: palette }
3493
+ };
3494
+ return pptx.buildChartViewModel(themedElement);
3495
+ }
3496
+ function renderPrimitive(prim, key) {
3497
+ switch (prim.kind) {
3498
+ case "rect": {
3499
+ const r = prim;
3500
+ return /* @__PURE__ */ jsxRuntime.jsx(
3501
+ "rect",
3502
+ {
3503
+ x: r.x,
3504
+ y: r.y,
3505
+ width: r.w,
3506
+ height: r.h,
3507
+ fill: r.fill,
3508
+ rx: r.rx ?? 0,
3509
+ opacity: r.opacity ?? 1,
3510
+ ...partAttrs(r.part),
3511
+ children: r.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: r.title }) : null
3512
+ },
3513
+ key
3514
+ );
3515
+ }
3516
+ case "path": {
3517
+ const p = prim;
3518
+ return /* @__PURE__ */ jsxRuntime.jsx(
3519
+ "path",
3520
+ {
3521
+ d: p.d,
3522
+ fill: p.fill,
3523
+ stroke: p.stroke ?? "none",
3524
+ strokeWidth: p.strokeWidth ?? 0,
3525
+ strokeDasharray: p.dashArray,
3526
+ fillOpacity: p.opacity ?? 1,
3527
+ ...partAttrs(p.part),
3528
+ children: p.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: p.title }) : null
3529
+ },
3530
+ key
3531
+ );
3532
+ }
3533
+ case "polyline": {
3534
+ const p = prim;
3535
+ return /* @__PURE__ */ jsxRuntime.jsx(
3536
+ "polyline",
3537
+ {
3538
+ points: p.points,
3539
+ stroke: p.stroke,
3540
+ strokeWidth: p.strokeWidth,
3541
+ strokeDasharray: p.dashArray,
3542
+ fill: p.fill,
3543
+ opacity: p.opacity ?? 1,
3544
+ ...partAttrs(p.part),
3545
+ children: p.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: p.title }) : null
3546
+ },
3547
+ key
3548
+ );
3549
+ }
3550
+ case "circle": {
3551
+ const c = prim;
3552
+ return /* @__PURE__ */ jsxRuntime.jsx(
3553
+ "circle",
3554
+ {
3555
+ cx: c.cx,
3556
+ cy: c.cy,
3557
+ r: c.r,
3558
+ fill: c.fill,
3559
+ stroke: c.stroke,
3560
+ strokeWidth: c.strokeWidth,
3561
+ opacity: c.opacity ?? 1,
3562
+ ...partAttrs(c.part),
3563
+ children: c.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: c.title }) : null
3564
+ },
3565
+ key
3566
+ );
3567
+ }
3568
+ case "line": {
3569
+ const l = prim;
3570
+ return /* @__PURE__ */ jsxRuntime.jsx(
3571
+ "line",
3572
+ {
3573
+ x1: l.x1,
3574
+ y1: l.y1,
3575
+ x2: l.x2,
3576
+ y2: l.y2,
3577
+ stroke: l.stroke,
3578
+ strokeWidth: l.strokeWidth,
3579
+ strokeDasharray: l.dashArray,
3580
+ opacity: l.opacity ?? 1,
3581
+ transform: l.transform,
3582
+ children: l.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: l.title }) : null
3583
+ },
3584
+ key
3585
+ );
3586
+ }
3587
+ case "polygon": {
3588
+ const p = prim;
3589
+ return /* @__PURE__ */ jsxRuntime.jsx(
3590
+ "polygon",
3591
+ {
3592
+ points: p.points,
3593
+ fill: p.fill,
3594
+ stroke: p.stroke,
3595
+ strokeWidth: p.strokeWidth,
3596
+ opacity: p.opacity ?? 1,
3597
+ strokeDasharray: p.dashArray,
3598
+ transform: p.transform,
3599
+ ...partAttrs(p.part),
3600
+ children: p.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: p.title }) : null
3601
+ },
3602
+ key
3603
+ );
3604
+ }
3605
+ case "text":
3606
+ return renderText(prim, key);
3607
+ default:
3608
+ return null;
3609
+ }
3610
+ }
3611
+ function renderText(t, key) {
3612
+ return /* @__PURE__ */ jsxRuntime.jsx(
3613
+ "text",
3614
+ {
3615
+ x: t.x,
3616
+ y: t.y,
3617
+ textAnchor: t.textAnchor,
3618
+ fontSize: t.fontSize,
3619
+ fill: t.fill,
3620
+ fontWeight: t.fontWeight ?? "normal",
3621
+ fontStyle: t.fontStyle ?? "normal",
3622
+ fontFamily: t.fontFamily,
3623
+ dominantBaseline: t.dominantBaseline,
3624
+ opacity: t.opacity ?? 1,
3625
+ transform: t.transform,
3626
+ children: t.text
3627
+ },
3628
+ key
3629
+ );
3630
+ }
3631
+ function renderChartViewModel(elementId, vm, preserveAspectRatio = "none") {
3632
+ const legendItems = pptx.computeChartLegendLayout(vm);
3633
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3634
+ "svg",
3635
+ {
3636
+ className: "w-full h-full pointer-events-none",
3637
+ viewBox: `0 0 ${vm.svgWidth} ${vm.svgHeight}`,
3638
+ preserveAspectRatio,
3639
+ children: [
3640
+ vm.defs && vm.defs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: vm.defs.map(pptx.resolveChartSvgDef).map(
3641
+ (def, i) => def.kind === "linearGradient" ? /* @__PURE__ */ jsxRuntime.jsx(
3642
+ "linearGradient",
3643
+ {
3644
+ id: def.id,
3645
+ x1: def.x1,
3646
+ y1: def.y1,
3647
+ x2: def.x2,
3648
+ y2: def.y2,
3649
+ children: renderGradientStops(def.stops)
3650
+ },
3651
+ `${elementId}-def-${i}`
3652
+ ) : def.kind === "radialGradient" ? /* @__PURE__ */ jsxRuntime.jsx(
3653
+ "radialGradient",
3654
+ {
3655
+ id: def.id,
3656
+ cx: def.cx,
3657
+ cy: def.cy,
3658
+ r: def.r,
3659
+ children: renderGradientStops(def.stops)
3660
+ },
3661
+ `${elementId}-def-${i}`
3662
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
3663
+ "pattern",
3664
+ {
3665
+ id: def.id,
3666
+ patternUnits: def.patternUnits,
3667
+ patternContentUnits: def.patternContentUnits,
3668
+ x: def.x,
3669
+ y: def.y,
3670
+ width: def.width,
3671
+ height: def.height,
3672
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3673
+ "image",
3674
+ {
3675
+ href: def.href,
3676
+ x: 0,
3677
+ y: 0,
3678
+ width: def.width,
3679
+ height: def.height,
3680
+ preserveAspectRatio: def.preserveAspectRatio
3681
+ }
3682
+ )
3683
+ },
3684
+ `${elementId}-def-${i}`
3685
+ )
3686
+ ) }),
3687
+ vm.areaFill && /* @__PURE__ */ jsxRuntime.jsx(
3688
+ "rect",
3689
+ {
3690
+ x: 0,
3691
+ y: 0,
3692
+ width: vm.svgWidth,
3693
+ height: vm.svgHeight,
3694
+ rx: vm.areaRadius,
3695
+ fill: vm.areaFill
3696
+ }
3697
+ ),
3698
+ vm.title && /* @__PURE__ */ jsxRuntime.jsx(
3699
+ "text",
3700
+ {
3701
+ x: vm.titleX,
3702
+ y: vm.titleY,
3703
+ textAnchor: "middle",
3704
+ fontSize: vm.titleStyle?.fontSize ?? 12,
3705
+ fontWeight: vm.titleStyle?.fontWeight ?? 600,
3706
+ fontFamily: vm.titleStyle?.fontFamily,
3707
+ fill: vm.titleStyle?.fill ?? "#1e293b",
3708
+ "data-chart-part": "title",
3709
+ children: vm.titleRunSpans && vm.titleRunSpans.length > 0 ? vm.titleRunSpans.map((run, i) => /* @__PURE__ */ jsxRuntime.jsx(
3710
+ "tspan",
3711
+ {
3712
+ fontSize: run.fontSize,
3713
+ fontWeight: run.fontWeight,
3714
+ fontStyle: run.fontStyle,
3715
+ fontFamily: run.fontFamily,
3716
+ fill: run.fill,
3717
+ children: run.text
3718
+ },
3719
+ `${elementId}-title-run-${i}`
3720
+ )) : vm.title
3721
+ }
3722
+ ),
3723
+ vm.gridlines.map((gl, i) => /* @__PURE__ */ jsxRuntime.jsx(
3724
+ "line",
3725
+ {
3726
+ x1: gl.x1,
3727
+ y1: gl.y1,
3728
+ x2: gl.x2,
3729
+ y2: gl.y2,
3730
+ stroke: gl.stroke,
3731
+ strokeWidth: gl.strokeWidth
3732
+ },
3733
+ `${elementId}-gl-${i}`
3734
+ )),
3735
+ (vm.secondaryGridlines ?? []).map((gl, i) => /* @__PURE__ */ jsxRuntime.jsx(
3736
+ "line",
3737
+ {
3738
+ x1: gl.x1,
3739
+ y1: gl.y1,
3740
+ x2: gl.x2,
3741
+ y2: gl.y2,
3742
+ stroke: gl.stroke,
3743
+ strokeWidth: gl.strokeWidth,
3744
+ strokeDasharray: gl.dashArray,
3745
+ opacity: gl.opacity ?? 1
3746
+ },
3747
+ `${elementId}-sgl-${i}`
3748
+ )),
3749
+ vm.axisLabels.map((lbl, i) => renderText(lbl, `${elementId}-al-${i}`)),
3750
+ (vm.secondaryAxisLabels ?? []).map((lbl, i) => renderText(lbl, `${elementId}-sal-${i}`)),
3751
+ vm.zeroLine && /* @__PURE__ */ jsxRuntime.jsx(
3752
+ "line",
3753
+ {
3754
+ x1: vm.zeroLine.x1,
3755
+ y1: vm.zeroLine.y1,
3756
+ x2: vm.zeroLine.x2,
3757
+ y2: vm.zeroLine.y2,
3758
+ stroke: vm.zeroLine.stroke,
3759
+ strokeWidth: vm.zeroLine.strokeWidth
3760
+ }
3761
+ ),
3762
+ vm.categoryLabels.map((lbl, i) => renderText(lbl, `${elementId}-cl-${i}`)),
3763
+ vm.primitives.map((prim, i) => renderPrimitive(prim, `${elementId}-p-${i}`)),
3764
+ vm.dataLabels.map((dl, i) => renderText(dl, `${elementId}-dl-${i}`)),
3765
+ legendItems.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(
3766
+ "g",
3767
+ {
3768
+ transform: `translate(${item.x.toFixed(1)},${item.y.toFixed(1)})`,
3769
+ children: [
3770
+ item.lineSwatch ? item.lineSwatch.primitives.map(
3771
+ (prim, si) => renderPrimitive(prim, `${elementId}-lg-${i}-sw-${si}`)
3772
+ ) : /* @__PURE__ */ jsxRuntime.jsx("rect", { x: 0, y: -7, width: 10, height: 10, rx: 2, fill: item.color }),
3773
+ /* @__PURE__ */ jsxRuntime.jsx(
3774
+ "text",
3775
+ {
3776
+ x: 13,
3777
+ y: 3,
3778
+ fontSize: item.fontSize,
3779
+ fill: item.fill,
3780
+ fontWeight: item.fontWeight,
3781
+ fontStyle: item.fontStyle,
3782
+ fontFamily: item.fontFamily,
3783
+ children: item.label
3784
+ }
3785
+ )
3786
+ ]
3787
+ },
3788
+ `${elementId}-lg-${i}`
3789
+ ))
3790
+ ]
3791
+ }
3792
+ );
3793
+ }
3794
+ function renderChartElement(element) {
3795
+ if (element.type !== "chart") {
3796
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: i18n.translationsEn["pptx.chart.heading"] });
3797
+ }
3798
+ const chartData = element.chartData;
3799
+ if (!chartData || chartData.series.length === 0) {
3800
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: i18n.translationsEn["pptx.chart.heading"] });
3801
+ }
3802
+ const kind = pptx.resolveChartKind(chartData.chartType ?? "bar");
3803
+ return renderChartViewModel(
3804
+ element.id,
3805
+ buildReactChartViewModel(element),
3806
+ pptx.chartPreserveAspectRatio(kind)
3807
+ );
3808
+ }
3809
+ function buildNotesPdf(pages) {
3810
+ const images = pages.map((page) => {
3811
+ const dataUrl = page.canvas.toDataURL("image/jpeg", 0.92);
3812
+ const base64 = dataUrl.split(",")[1] ?? "";
3813
+ const raw = atob(base64);
3814
+ const bytes2 = new Uint8Array(raw.length);
3815
+ for (let i = 0; i < raw.length; i++) {
3816
+ bytes2[i] = raw.charCodeAt(i);
3817
+ }
3818
+ return { bytes: bytes2, w: page.canvas.width, h: page.canvas.height };
3819
+ });
3820
+ const meta = pages.map((page) => ({
3821
+ notes: page.notes,
3822
+ slideNumber: page.slideNumber
3823
+ }));
3824
+ const bytes = pptx.buildNotesPdfBytes(images, meta);
3825
+ const blob = new Blob([bytes], { type: "application/pdf" });
3826
+ return URL.createObjectURL(blob);
3827
+ }
3828
+ function buildPdfFromTiledImageData(pages) {
3829
+ const bytes = pptx.buildTiledSlidesPdfBytes(pages);
3830
+ const blob = new Blob([bytes], { type: "application/pdf" });
3831
+ return URL.createObjectURL(blob);
3832
+ }
3833
+ var activePreview = null;
3834
+ function startPreviewAnimation(elementId, preset, options) {
3835
+ stopPreviewAnimation();
3836
+ const domEl = document.querySelector(`[data-element-id="${elementId}"]`);
3837
+ const descriptor = pptx.buildPreviewAnimation(preset, {
3838
+ ...options,
3839
+ geometry: domEl ? pptx.measurePreviewGeometry(domEl) : void 0
3840
+ });
3841
+ if (!descriptor) {
3842
+ return;
3843
+ }
3844
+ playDescriptor(elementId, descriptor);
3845
+ }
3846
+ function startMotionPathPreview(elementId, path, options) {
3847
+ stopPreviewAnimation();
3848
+ const domEl = document.querySelector(`[data-element-id="${elementId}"]`);
3849
+ if (!domEl) {
3850
+ return;
3851
+ }
3852
+ const stage = domEl.offsetParent;
3853
+ const descriptor = pptx.buildMotionPathPreview({
3854
+ path,
3855
+ slideWidth: stage?.offsetWidth || DEFAULT_PREVIEW_SLIDE_WIDTH,
3856
+ slideHeight: stage?.offsetHeight || DEFAULT_PREVIEW_SLIDE_HEIGHT,
3857
+ durationMs: options?.durationMs,
3858
+ delayMs: options?.delayMs,
3859
+ timingCurve: options?.timingCurve
3860
+ });
3861
+ if (!descriptor) {
3862
+ return;
3863
+ }
3864
+ playDescriptor(elementId, descriptor);
3865
+ }
3866
+ var DEFAULT_PREVIEW_SLIDE_WIDTH = 1280;
3867
+ var DEFAULT_PREVIEW_SLIDE_HEIGHT = 720;
3868
+ function playDescriptor(elementId, descriptor) {
3869
+ const domEl = document.querySelector(`[data-element-id="${elementId}"]`);
3870
+ if (!domEl) {
3871
+ return;
3872
+ }
3873
+ const styleEl = document.createElement("style");
3874
+ styleEl.textContent = descriptor.keyframesCss;
3875
+ document.head.appendChild(styleEl);
3876
+ const originalAnimation = domEl.style.animation;
3877
+ const originalVisibility = domEl.style.visibility;
3878
+ domEl.style.visibility = "visible";
3879
+ domEl.style.animation = descriptor.cssAnimation;
3880
+ const timeoutId = setTimeout(() => {
3881
+ domEl.style.animation = originalAnimation;
3882
+ domEl.style.visibility = originalVisibility;
3883
+ styleEl.remove();
3884
+ if (activePreview?.elementId === elementId) {
3885
+ activePreview = null;
3886
+ }
3887
+ }, descriptor.durationMs + 100);
3888
+ activePreview = {
3889
+ elementId,
3890
+ timeoutId,
3891
+ styleEl,
3892
+ originalAnimation,
3893
+ originalVisibility
3894
+ };
3895
+ }
3896
+ function stopPreviewAnimation() {
3897
+ if (!activePreview) {
3898
+ return;
3899
+ }
3900
+ clearTimeout(activePreview.timeoutId);
3901
+ activePreview.styleEl.remove();
3902
+ const domEl = document.querySelector(
3903
+ `[data-element-id="${activePreview.elementId}"]`
3904
+ );
3905
+ if (domEl) {
3906
+ domEl.style.animation = activePreview.originalAnimation;
3907
+ domEl.style.visibility = activePreview.originalVisibility;
3908
+ }
3909
+ activePreview = null;
3910
+ }
3911
+
3912
+ Object.defineProperty(exports, "ACTION_BUTTON_PRESETS", {
3913
+ enumerable: true,
3914
+ get: function () { return pptx.ACTION_BUTTON_PRESETS; }
3915
+ });
3916
+ Object.defineProperty(exports, "DEFAULT_COLOR_CHANGE_TOLERANCE", {
3917
+ enumerable: true,
3918
+ get: function () { return pptx.DEFAULT_COLOR_CHANGE_TOLERANCE; }
3919
+ });
3920
+ Object.defineProperty(exports, "INK_REPLAY_KEYFRAMES", {
3921
+ enumerable: true,
3922
+ get: function () { return pptx.INK_REPLAY_KEYFRAMES; }
3923
+ });
3924
+ Object.defineProperty(exports, "MAX_ZOOM_SCALE", {
3925
+ enumerable: true,
3926
+ get: function () { return pptx.MAX_ZOOM_SCALE; }
3927
+ });
3928
+ Object.defineProperty(exports, "MIN_ZOOM_SCALE", {
3929
+ enumerable: true,
3930
+ get: function () { return pptx.MIN_ZOOM_SCALE; }
3931
+ });
3932
+ Object.defineProperty(exports, "SHAPE_QUICK_STYLES", {
3933
+ enumerable: true,
3934
+ get: function () { return pptx.SHAPE_QUICK_STYLES; }
3935
+ });
3936
+ Object.defineProperty(exports, "SLIDE_TRANSITION_OPTIONS", {
3937
+ enumerable: true,
3938
+ get: function () { return pptx.SLIDE_TRANSITION_OPTIONS; }
3939
+ });
3940
+ Object.defineProperty(exports, "TABLE_STYLE_PRESETS", {
3941
+ enumerable: true,
3942
+ get: function () { return pptx.TABLE_STYLE_PRESETS; }
3943
+ });
3944
+ Object.defineProperty(exports, "applyColorChange", {
3945
+ enumerable: true,
3946
+ get: function () { return pptx.applyColorChange; }
3947
+ });
3948
+ Object.defineProperty(exports, "applyFormatToElement", {
3949
+ enumerable: true,
3950
+ get: function () { return pptx.applyFormatToElement; }
3951
+ });
3952
+ Object.defineProperty(exports, "applyReroutedConnectors", {
3953
+ enumerable: true,
3954
+ get: function () { return pptx.applyReroutedConnectors; }
3955
+ });
3956
+ Object.defineProperty(exports, "buildCacheKey", {
3957
+ enumerable: true,
3958
+ get: function () { return pptx.buildCacheKey; }
3959
+ });
3960
+ Object.defineProperty(exports, "buildContentPartStrokes", {
3961
+ enumerable: true,
3962
+ get: function () { return pptx.buildContentPartStrokes; }
3963
+ });
3964
+ Object.defineProperty(exports, "buildCssGradientFromShapeStyle", {
3965
+ enumerable: true,
3966
+ get: function () { return pptx.buildCssGradientFromShapeStyle; }
3967
+ });
3968
+ Object.defineProperty(exports, "buildInkGroupStrokes", {
3969
+ enumerable: true,
3970
+ get: function () { return pptx.buildInkGroupStrokes; }
3971
+ });
3972
+ Object.defineProperty(exports, "buildSaveSlides", {
3973
+ enumerable: true,
3974
+ get: function () { return pptx.buildSaveSlides; }
3975
+ });
3976
+ Object.defineProperty(exports, "canvasToJpegData", {
3977
+ enumerable: true,
3978
+ get: function () { return pptx.canvasToJpegData; }
3979
+ });
3980
+ Object.defineProperty(exports, "clampCropValue", {
3981
+ enumerable: true,
3982
+ get: function () { return pptx.clampCropValue; }
3983
+ });
3984
+ Object.defineProperty(exports, "cloneSlide", {
3985
+ enumerable: true,
3986
+ get: function () { return pptx.cloneSlide; }
3987
+ });
3988
+ Object.defineProperty(exports, "cloneTemplateElementsBySlideId", {
3989
+ enumerable: true,
3990
+ get: function () { return pptx.cloneTemplateElementsBySlideId; }
3991
+ });
3992
+ Object.defineProperty(exports, "colorWithOpacity", {
3993
+ enumerable: true,
3994
+ get: function () { return pptx.colorWithOpacity; }
3995
+ });
3996
+ Object.defineProperty(exports, "comparePresentation", {
3997
+ enumerable: true,
3998
+ get: function () { return pptx.comparePresentation; }
3999
+ });
4000
+ Object.defineProperty(exports, "computeHandoutLayout", {
4001
+ enumerable: true,
4002
+ get: function () { return pptx.computeHandoutLayout; }
4003
+ });
4004
+ Object.defineProperty(exports, "computeSnapToShape", {
4005
+ enumerable: true,
4006
+ get: function () { return pptx.computeSnapToShape; }
4007
+ });
4008
+ Object.defineProperty(exports, "copyFormatFromElement", {
4009
+ enumerable: true,
4010
+ get: function () { return pptx.copyFormatFromElement; }
4011
+ });
4012
+ Object.defineProperty(exports, "formatCommentTimestamp", {
4013
+ enumerable: true,
4014
+ get: function () { return pptx.formatCommentTimestamp; }
4015
+ });
4016
+ Object.defineProperty(exports, "generateNoteLineCount", {
4017
+ enumerable: true,
4018
+ get: function () { return pptx.generateNoteLineCount; }
4019
+ });
4020
+ Object.defineProperty(exports, "getAriaLabel", {
4021
+ enumerable: true,
4022
+ get: function () { return pptx.getAriaLabel; }
4023
+ });
4024
+ Object.defineProperty(exports, "getAriaRole", {
4025
+ enumerable: true,
4026
+ get: function () { return pptx.getAriaRole; }
4027
+ });
4028
+ Object.defineProperty(exports, "getAriaRoleDescription", {
4029
+ enumerable: true,
4030
+ get: function () { return pptx.getAriaRoleDescription; }
4031
+ });
4032
+ Object.defineProperty(exports, "getCachedResult", {
4033
+ enumerable: true,
4034
+ get: function () { return pptx.getCachedResult; }
4035
+ });
4036
+ Object.defineProperty(exports, "getCompoundLineOffsets", {
4037
+ enumerable: true,
4038
+ get: function () { return pptx.getCompoundLineOffsets; }
4039
+ });
4040
+ Object.defineProperty(exports, "getCompoundLineWidths", {
4041
+ enumerable: true,
4042
+ get: function () { return pptx.getCompoundLineWidths; }
4043
+ });
4044
+ Object.defineProperty(exports, "getContentPartReplayStyles", {
4045
+ enumerable: true,
4046
+ get: function () { return pptx.getContentPartReplayStyles; }
4047
+ });
4048
+ Object.defineProperty(exports, "getElementLabel", {
4049
+ enumerable: true,
4050
+ get: function () { return pptx.getElementLabel; }
4051
+ });
4052
+ Object.defineProperty(exports, "getElementTransform", {
4053
+ enumerable: true,
4054
+ get: function () { return pptx.getElementTransform; }
4055
+ });
4056
+ Object.defineProperty(exports, "getElementTransformWithoutRotation", {
4057
+ enumerable: true,
4058
+ get: function () { return pptx.getElementTransformWithoutRotation; }
4059
+ });
4060
+ Object.defineProperty(exports, "getImageEffectsFilter", {
4061
+ enumerable: true,
4062
+ get: function () { return pptx.getImageEffectsFilter; }
4063
+ });
4064
+ Object.defineProperty(exports, "getImageEffectsOpacity", {
4065
+ enumerable: true,
4066
+ get: function () { return pptx.getImageEffectsOpacity; }
4067
+ });
4068
+ Object.defineProperty(exports, "getInkReplayStyles", {
4069
+ enumerable: true,
4070
+ get: function () { return pptx.getInkReplayStyles; }
4071
+ });
4072
+ Object.defineProperty(exports, "getPatternSvg", {
4073
+ enumerable: true,
4074
+ get: function () { return pptx.getPatternSvg; }
4075
+ });
4076
+ Object.defineProperty(exports, "getPrintableArea", {
4077
+ enumerable: true,
4078
+ get: function () { return pptx.getPrintableArea; }
4079
+ });
4080
+ Object.defineProperty(exports, "getShapeAdjustmentHandleDescriptors", {
4081
+ enumerable: true,
4082
+ get: function () { return pptx.getShapeAdjustmentHandleDescriptors; }
4083
+ });
4084
+ Object.defineProperty(exports, "getSvgStrokeDasharray", {
4085
+ enumerable: true,
4086
+ get: function () { return pptx.getSvgStrokeDasharray; }
4087
+ });
4088
+ Object.defineProperty(exports, "getTextCompensationTransform", {
4089
+ enumerable: true,
4090
+ get: function () { return pptx.getTextCompensationTransform; }
4091
+ });
4092
+ Object.defineProperty(exports, "hasCopyableFormat", {
4093
+ enumerable: true,
4094
+ get: function () { return pptx.hasCopyableFormat; }
4095
+ });
4096
+ Object.defineProperty(exports, "isEditableTextElement", {
4097
+ enumerable: true,
4098
+ get: function () { return pptx.isEditableTextElement; }
4099
+ });
4100
+ Object.defineProperty(exports, "isImageTiled", {
4101
+ enumerable: true,
4102
+ get: function () { return pptx.isImageTiled; }
4103
+ });
4104
+ Object.defineProperty(exports, "isPpactionUrl", {
4105
+ enumerable: true,
4106
+ get: function () { return pptx.isPpactionUrl; }
4107
+ });
4108
+ Object.defineProperty(exports, "isTemplateElementId", {
4109
+ enumerable: true,
4110
+ get: function () { return pptx.isTemplateElementId; }
4111
+ });
4112
+ Object.defineProperty(exports, "isUrlSafe", {
4113
+ enumerable: true,
4114
+ get: function () { return pptx.isUrlSafe; }
4115
+ });
4116
+ Object.defineProperty(exports, "makeCloneId", {
4117
+ enumerable: true,
4118
+ get: function () { return pptx.makeCloneId; }
4119
+ });
4120
+ Object.defineProperty(exports, "mergeCells", {
4121
+ enumerable: true,
4122
+ get: function () { return pptx.mergeCells; }
4123
+ });
4124
+ Object.defineProperty(exports, "normalizeHexColor", {
4125
+ enumerable: true,
4126
+ get: function () { return pptx.normalizeHexColor; }
4127
+ });
4128
+ Object.defineProperty(exports, "normalizeStrokeDashType", {
4129
+ enumerable: true,
4130
+ get: function () { return pptx.normalizeStrokeDashType; }
4131
+ });
4132
+ Object.defineProperty(exports, "openNativeEyeDropper", {
4133
+ enumerable: true,
4134
+ get: function () { return pptx.openNativeEyeDropper; }
4135
+ });
4136
+ Object.defineProperty(exports, "parsePpactionUrl", {
4137
+ enumerable: true,
4138
+ get: function () { return pptx.parsePpactionUrl; }
4139
+ });
4140
+ Object.defineProperty(exports, "partitionTemplateElements", {
4141
+ enumerable: true,
4142
+ get: function () { return pptx.partitionTemplateElements; }
4143
+ });
4144
+ Object.defineProperty(exports, "rerouteConnectorsForMovedElements", {
4145
+ enumerable: true,
4146
+ get: function () { return pptx.rerouteConnectorsForMovedElements; }
4147
+ });
4148
+ Object.defineProperty(exports, "safeOpenUrl", {
4149
+ enumerable: true,
4150
+ get: function () { return pptx.safeOpenUrl; }
4151
+ });
4152
+ Object.defineProperty(exports, "sanitizeGradientStops", {
4153
+ enumerable: true,
4154
+ get: function () { return pptx.sanitizeGradientStops; }
4155
+ });
4156
+ Object.defineProperty(exports, "setCachedResult", {
4157
+ enumerable: true,
4158
+ get: function () { return pptx.setCachedResult; }
4159
+ });
4160
+ Object.defineProperty(exports, "splitCell", {
4161
+ enumerable: true,
4162
+ get: function () { return pptx.splitCell; }
4163
+ });
4164
+ Object.defineProperty(exports, "stopAllPersistentAudio", {
4165
+ enumerable: true,
4166
+ get: function () { return pptx.stopAllPersistentAudio; }
4167
+ });
4168
+ Object.defineProperty(exports, "substituteFieldText", {
4169
+ enumerable: true,
4170
+ get: function () { return pptx.substituteFieldText; }
4171
+ });
4172
+ exports.ANIMATION_PRESET_OPTIONS = ANIMATION_PRESET_OPTIONS;
4173
+ exports.ARROW_SIZE_OPTIONS = ARROW_SIZE_OPTIONS;
4174
+ exports.CONNECTOR_ARROW_OPTIONS = CONNECTOR_ARROW_OPTIONS;
4175
+ exports.DEFAULT_CANVAS_HEIGHT = DEFAULT_CANVAS_HEIGHT;
4176
+ exports.DEFAULT_CANVAS_WIDTH = DEFAULT_CANVAS_WIDTH;
4177
+ exports.DEFAULT_FILL_COLOR = DEFAULT_FILL_COLOR;
4178
+ exports.DEFAULT_FONT_FAMILY = DEFAULT_FONT_FAMILY;
4179
+ exports.DEFAULT_SECTION_GROUP_ID = DEFAULT_SECTION_GROUP_ID;
4180
+ exports.DEFAULT_STROKE_COLOR = DEFAULT_STROKE_COLOR;
4181
+ exports.DEFAULT_TABLE_COLUMNS = DEFAULT_TABLE_COLUMNS;
4182
+ exports.DEFAULT_TABLE_ROWS = DEFAULT_TABLE_ROWS;
4183
+ exports.DEFAULT_TEXT_COLOR = DEFAULT_TEXT_COLOR;
4184
+ exports.DEFAULT_TEXT_FONT_SIZE = DEFAULT_TEXT_FONT_SIZE;
4185
+ exports.GRID_SIZE = GRID_SIZE;
4186
+ exports.HYPERLINK_COLOR = HYPERLINK_COLOR;
4187
+ exports.MIN_ELEMENT_SIZE = MIN_ELEMENT_SIZE;
4188
+ exports.SHAPE_PRESETS = SHAPE_PRESETS;
4189
+ exports.SHORTCUT_REFERENCE_ITEMS = SHORTCUT_REFERENCE_ITEMS;
4190
+ exports.SLIDE_NAV_THUMBNAIL_WIDTH = SLIDE_NAV_THUMBNAIL_WIDTH;
4191
+ exports.STROKE_DASH_OPTIONS = STROKE_DASH_OPTIONS;
4192
+ exports.TOOLBAR_SECTIONS = TOOLBAR_SECTIONS;
4193
+ exports.UNGROUPED_SECTION_ID = UNGROUPED_SECTION_ID;
4194
+ exports.ZOOM_TO_SELECTION_PADDING = ZOOM_TO_SELECTION_PADDING;
4195
+ exports.build3DExtrusionData = build3DExtrusionData;
4196
+ exports.buildLineGlowFilter = buildLineGlowFilter;
4197
+ exports.buildLineShadowCss = buildLineShadowCss;
4198
+ exports.buildNotesPdf = buildNotesPdf;
4199
+ exports.buildPdfFromTiledImageData = buildPdfFromTiledImageData;
4200
+ exports.buildReactChartViewModel = buildReactChartViewModel;
4201
+ exports.buildTextBody3DSceneStyle = buildTextBody3DSceneStyle;
4202
+ exports.cloneHistorySnapshot = cloneHistorySnapshot;
4203
+ exports.cn = cn;
4204
+ exports.dist_exports = dist_exports;
4205
+ exports.getAnimationInitialStyle = getAnimationInitialStyle;
4206
+ exports.getConnectorPathGeometry = getConnectorPathGeometry;
4207
+ exports.getCropShapeClipPath = getCropShapeClipPath;
4208
+ exports.getDuotoneColors = getDuotoneColors;
4209
+ exports.getImageRenderStyle = getImageRenderStyle;
4210
+ exports.getImageSurfaceMaskStyle = getImageSurfaceMaskStyle;
4211
+ exports.getImageSurfaceStyle = getImageSurfaceStyle;
4212
+ exports.getImageTilingStyle = getImageTilingStyle;
4213
+ exports.getShapeVisualStyle = getShapeVisualStyle;
4214
+ exports.getTextLayoutStyle = getTextLayoutStyle;
4215
+ exports.getTextStyleForElement = getTextStyleForElement;
4216
+ exports.getTextWarpStyle = getTextWarpStyle;
4217
+ exports.hasDagDuotoneEffect = hasDagDuotoneEffect;
4218
+ exports.isConnectorOrLineElement = isConnectorOrLineElement;
4219
+ exports.renderChartElement = renderChartElement;
4220
+ exports.renderConnectorMarker = renderConnectorMarker;
4221
+ exports.renderDagDuotoneSvgFilter = renderDagDuotoneSvgFilter;
4222
+ exports.renderMediaElement = renderMediaElement;
4223
+ exports.renderTableElement = renderTableElement;
4224
+ exports.renderTextSegments = renderTextSegments;
4225
+ exports.renderVectorShape = renderVectorShape;
4226
+ exports.shouldRenderFallbackLabel = shouldRenderFallbackLabel;
4227
+ exports.startMotionPathPreview = startMotionPathPreview;
4228
+ exports.startPreviewAnimation = startPreviewAnimation;
4229
+ exports.stopPreviewAnimation = stopPreviewAnimation;