pptx-react-viewer 2.9.0 → 2.11.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 (125) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/{AiChatPanel-6W6ZBAGU.mjs → AiChatPanel-EX2TBRJM.mjs} +4 -4
  3. package/dist/AiChatPanel-EX2TBRJM.mjs.br +0 -0
  4. package/dist/AiChatPanel-EX2TBRJM.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-MALC32TM.js → AiChatPanel-PJPSDMN4.js} +23 -23
  6. package/dist/AiChatPanel-PJPSDMN4.js.br +0 -0
  7. package/dist/AiChatPanel-PJPSDMN4.js.gz +0 -0
  8. package/dist/{Model3DScene-57HZ4NVD.mjs → Model3DScene-TTQFV7OS.mjs} +1 -1
  9. package/dist/Model3DScene-TTQFV7OS.mjs.br +0 -0
  10. package/dist/Model3DScene-TTQFV7OS.mjs.gz +0 -0
  11. package/dist/{Model3DScene-76R2YXSO.js → Model3DScene-UCBPTEAY.js} +2 -2
  12. package/dist/Model3DScene-UCBPTEAY.js.br +0 -0
  13. package/dist/Model3DScene-UCBPTEAY.js.gz +0 -0
  14. package/dist/{SurfaceChart3DScene-JGOQNHSU.mjs → SurfaceChart3DScene-5SZCRHZI.mjs} +1 -1
  15. package/dist/{SurfaceChart3DScene-JGOQNHSU.mjs.br → SurfaceChart3DScene-5SZCRHZI.mjs.br} +0 -0
  16. package/dist/SurfaceChart3DScene-5SZCRHZI.mjs.gz +0 -0
  17. package/dist/{SurfaceChart3DScene-2QZZTBV4.js → SurfaceChart3DScene-ADKCYYOQ.js} +2 -2
  18. package/dist/SurfaceChart3DScene-ADKCYYOQ.js.br +0 -0
  19. package/dist/SurfaceChart3DScene-ADKCYYOQ.js.gz +0 -0
  20. package/dist/{chunk-D6SHCB4V.js → chunk-4J7SPY64.js} +338 -324
  21. package/dist/chunk-4J7SPY64.js.br +0 -0
  22. package/dist/chunk-4J7SPY64.js.gz +0 -0
  23. package/dist/{chunk-CD434OFE.mjs → chunk-53NXKDMZ.mjs} +48 -0
  24. package/dist/chunk-53NXKDMZ.mjs.br +0 -0
  25. package/dist/chunk-53NXKDMZ.mjs.gz +0 -0
  26. package/dist/{chunk-L47Y62L6.mjs → chunk-C2UWTH42.mjs} +1168 -118
  27. package/dist/chunk-C2UWTH42.mjs.br +0 -0
  28. package/dist/chunk-C2UWTH42.mjs.gz +0 -0
  29. package/dist/{chunk-6UXRNLHD.js → chunk-E367QIKR.js} +2526 -1738
  30. package/dist/chunk-E367QIKR.js.br +0 -0
  31. package/dist/chunk-E367QIKR.js.gz +0 -0
  32. package/dist/{chunk-4FO4JMTN.mjs → chunk-HK2UERUX.mjs} +17 -3
  33. package/dist/chunk-HK2UERUX.mjs.br +0 -0
  34. package/dist/chunk-HK2UERUX.mjs.gz +0 -0
  35. package/dist/{chunk-IKISUZKE.js → chunk-HMQVOPQH.js} +1210 -118
  36. package/dist/chunk-HMQVOPQH.js.br +0 -0
  37. package/dist/chunk-HMQVOPQH.js.gz +0 -0
  38. package/dist/{chunk-NQLVK23T.mjs → chunk-L2CM5EUD.mjs} +885 -97
  39. package/dist/chunk-L2CM5EUD.mjs.br +0 -0
  40. package/dist/chunk-L2CM5EUD.mjs.gz +0 -0
  41. package/dist/{chunk-34BUZNKO.js → chunk-MM5RMRSP.js} +278 -291
  42. package/dist/chunk-MM5RMRSP.js.br +0 -0
  43. package/dist/chunk-MM5RMRSP.js.gz +0 -0
  44. package/dist/{chunk-2JDWFMIK.js → chunk-N6IHR6PS.js} +48 -0
  45. package/dist/chunk-N6IHR6PS.js.br +0 -0
  46. package/dist/chunk-N6IHR6PS.js.gz +0 -0
  47. package/dist/{chunk-JPTO6P5K.mjs → chunk-RJEY2KZH.mjs} +34 -48
  48. package/dist/chunk-RJEY2KZH.mjs.br +0 -0
  49. package/dist/chunk-RJEY2KZH.mjs.gz +0 -0
  50. package/dist/{chunk-6OLS3EJW.mjs → chunk-UZVRM6LD.mjs} +1 -1
  51. package/dist/chunk-UZVRM6LD.mjs.br +0 -0
  52. package/dist/chunk-UZVRM6LD.mjs.gz +0 -0
  53. package/dist/{chunk-YEM2VOAP.js → chunk-VNP627O5.js} +3 -3
  54. package/dist/chunk-VNP627O5.js.br +0 -0
  55. package/dist/chunk-VNP627O5.js.gz +0 -0
  56. package/dist/i18n.js +4 -4
  57. package/dist/i18n.js.br +0 -0
  58. package/dist/i18n.js.gz +0 -0
  59. package/dist/i18n.mjs +1 -1
  60. package/dist/i18n.mjs.br +0 -0
  61. package/dist/i18n.mjs.gz +0 -0
  62. package/dist/index.d.ts +26 -3
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +36 -36
  65. package/dist/index.js.br +0 -0
  66. package/dist/index.js.gz +0 -0
  67. package/dist/index.mjs +6 -6
  68. package/dist/index.mjs.br +0 -0
  69. package/dist/index.mjs.gz +0 -0
  70. package/dist/internals.d.ts +30 -2
  71. package/dist/internals.d.ts.map +1 -1
  72. package/dist/internals.js +79 -79
  73. package/dist/internals.js.br +0 -0
  74. package/dist/internals.js.gz +0 -0
  75. package/dist/internals.mjs +4 -4
  76. package/dist/internals.mjs.br +0 -0
  77. package/dist/internals.mjs.gz +0 -0
  78. package/dist/pptx-viewer.css +1 -1
  79. package/dist/pptx-viewer.css.br +0 -0
  80. package/dist/pptx-viewer.css.gz +0 -0
  81. package/dist/{useViewerBuildingBlocks-C59NY1qZ.d.ts → useViewerBuildingBlocks-Rqxm0pRS.d.ts} +19 -5
  82. package/dist/useViewerBuildingBlocks-Rqxm0pRS.d.ts.map +1 -0
  83. package/dist/viewer/index.js +22 -22
  84. package/dist/viewer/index.js.br +0 -0
  85. package/dist/viewer/index.js.gz +0 -0
  86. package/dist/viewer/index.mjs +6 -6
  87. package/dist/viewer/index.mjs.br +0 -0
  88. package/dist/viewer/index.mjs.gz +0 -0
  89. package/package.json +1 -1
  90. package/dist/AiChatPanel-6W6ZBAGU.mjs.br +0 -0
  91. package/dist/AiChatPanel-6W6ZBAGU.mjs.gz +0 -0
  92. package/dist/AiChatPanel-MALC32TM.js.br +0 -0
  93. package/dist/AiChatPanel-MALC32TM.js.gz +0 -0
  94. package/dist/Model3DScene-57HZ4NVD.mjs.br +0 -0
  95. package/dist/Model3DScene-57HZ4NVD.mjs.gz +0 -0
  96. package/dist/Model3DScene-76R2YXSO.js.br +0 -0
  97. package/dist/Model3DScene-76R2YXSO.js.gz +0 -0
  98. package/dist/SurfaceChart3DScene-2QZZTBV4.js.br +0 -0
  99. package/dist/SurfaceChart3DScene-2QZZTBV4.js.gz +0 -0
  100. package/dist/SurfaceChart3DScene-JGOQNHSU.mjs.gz +0 -0
  101. package/dist/chunk-2JDWFMIK.js.br +0 -0
  102. package/dist/chunk-2JDWFMIK.js.gz +0 -0
  103. package/dist/chunk-34BUZNKO.js.br +0 -0
  104. package/dist/chunk-34BUZNKO.js.gz +0 -0
  105. package/dist/chunk-4FO4JMTN.mjs.br +0 -0
  106. package/dist/chunk-4FO4JMTN.mjs.gz +0 -0
  107. package/dist/chunk-6OLS3EJW.mjs.br +0 -0
  108. package/dist/chunk-6OLS3EJW.mjs.gz +0 -0
  109. package/dist/chunk-6UXRNLHD.js.br +0 -0
  110. package/dist/chunk-6UXRNLHD.js.gz +0 -0
  111. package/dist/chunk-CD434OFE.mjs.br +0 -0
  112. package/dist/chunk-CD434OFE.mjs.gz +0 -0
  113. package/dist/chunk-D6SHCB4V.js.br +0 -0
  114. package/dist/chunk-D6SHCB4V.js.gz +0 -0
  115. package/dist/chunk-IKISUZKE.js.br +0 -0
  116. package/dist/chunk-IKISUZKE.js.gz +0 -0
  117. package/dist/chunk-JPTO6P5K.mjs.br +0 -0
  118. package/dist/chunk-JPTO6P5K.mjs.gz +0 -0
  119. package/dist/chunk-L47Y62L6.mjs.br +0 -0
  120. package/dist/chunk-L47Y62L6.mjs.gz +0 -0
  121. package/dist/chunk-NQLVK23T.mjs.br +0 -0
  122. package/dist/chunk-NQLVK23T.mjs.gz +0 -0
  123. package/dist/chunk-YEM2VOAP.js.br +0 -0
  124. package/dist/chunk-YEM2VOAP.js.gz +0 -0
  125. package/dist/useViewerBuildingBlocks-C59NY1qZ.d.ts.map +0 -1
@@ -46608,8 +46608,8 @@ function applyImageColorEffects(blip, effects, parseColor, extractOpacity) {
46608
46608
  const rawFrom = child19(change.rawXml, "clrFrom");
46609
46609
  const rawTo = child19(change.rawXml, "clrTo");
46610
46610
  const rawTransparent = rawTo ? (opacity(rawTo, extractOpacity) ?? 1) <= 0 : void 0;
46611
- const unchanged = sameRawColor(rawFrom, change.clrFrom, parseColor) && sameRawColor(rawTo, change.clrTo, parseColor) && (rawTransparent === void 0 || change.clrToTransparent === rawTransparent);
46612
- if (unchanged && change.rawXml) {
46611
+ const unchanged2 = sameRawColor(rawFrom, change.clrFrom, parseColor) && sameRawColor(rawTo, change.clrTo, parseColor) && (rawTransparent === void 0 || change.clrToTransparent === rawTransparent);
46612
+ if (unchanged2 && change.rawXml) {
46613
46613
  setChild6(blip, "clrChange", change.rawXml);
46614
46614
  } else {
46615
46615
  const fromChoice = sameRawColor(rawFrom, change.clrFrom, parseColor) ? extractColorChoiceXml(rawFrom) : buildSrgbColorChoice(change.clrFrom);
@@ -50614,8 +50614,8 @@ var PptxHandlerRuntime14 = class extends PptxHandlerRuntime13 {
50614
50614
  }
50615
50615
  const notesBodyShape = shapes.find((shape) => {
50616
50616
  const placeholder = shape?.["p:nvSpPr"]?.["p:nvPr"]?.["p:ph"];
50617
- const placeholderType = String(placeholder?.["@_type"] || "").trim().toLowerCase();
50618
- return placeholderType === "body";
50617
+ const placeholderType2 = String(placeholder?.["@_type"] || "").trim().toLowerCase();
50618
+ return placeholderType2 === "body";
50619
50619
  }) || shapes.find((shape) => Boolean(shape?.["p:txBody"])) || shapes[0];
50620
50620
  if (!notesBodyShape) {
50621
50621
  return false;
@@ -51453,10 +51453,16 @@ var PptxHandlerRuntime17 = class extends PptxHandlerRuntime16 {
51453
51453
  * survive a save: collapsing them to the plain-text path silently downgrades
51454
51454
  * a field to static text (e.g. a slide-number field becomes a frozen number)
51455
51455
  * or drops the equation, ruby, or bullet.
51456
+ *
51457
+ * `paragraphLevel` (`a:pPr/@lvl`) belongs on this list for the same reason
51458
+ * and used to be missing from it: a nested bullet whose runs all share one
51459
+ * style looked "uniform", so the save path discarded its segments and rebuilt
51460
+ * the paragraph from the flat string, which carries no indent level. Every
51461
+ * such paragraph came back from a round-trip flattened to the top level.
51456
51462
  */
51457
51463
  isStructuralTextSegment(segment) {
51458
51464
  return Boolean(
51459
- segment.fieldType || segment.equationXml || segment.rubyText || segment.bulletInfo
51465
+ segment.fieldType || segment.equationXml || segment.rubyText || segment.bulletInfo || segment.paragraphLevel
51460
51466
  );
51461
51467
  }
51462
51468
  areTextSegmentsUniform(textSegments) {
@@ -86655,6 +86661,43 @@ var EQUATION_TEMPLATES = [
86655
86661
  i18nKey: "pptx.equation.template.trigIdentity"
86656
86662
  }
86657
86663
  ];
86664
+ function purifyFn() {
86665
+ const purify = DOMPurify__default.default;
86666
+ return typeof purify.sanitize === "function" ? purify.sanitize : void 0;
86667
+ }
86668
+ function sanitizeMarkupOrEmpty(markup, config) {
86669
+ const sanitize = purifyFn();
86670
+ return sanitize ? sanitize(markup, config) : "";
86671
+ }
86672
+ function sanitizeMathMl(markup) {
86673
+ const sanitized = sanitizeMarkupOrEmpty(markup, { USE_PROFILES: { mathMl: true, svg: true } });
86674
+ if (/<math(?:\s|>)/iu.test(markup) && !/<math(?:\s|>)/iu.test(sanitized) && sanitized) {
86675
+ return `<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline">${sanitized}</math>`;
86676
+ }
86677
+ return sanitized;
86678
+ }
86679
+ function emptyResult() {
86680
+ return { mathml: "", omml: {} };
86681
+ }
86682
+ function compileLatexEquation(source) {
86683
+ const trimmed = source.trim();
86684
+ if (!trimmed) {
86685
+ return emptyResult();
86686
+ }
86687
+ try {
86688
+ const omml = convertLatexToOmml(trimmed);
86689
+ const raw = convertOmmlToMathMl(omml);
86690
+ return { mathml: raw ? sanitizeMathMl(raw) : "", omml };
86691
+ } catch {
86692
+ return emptyResult();
86693
+ }
86694
+ }
86695
+ function latexToMathMl(source) {
86696
+ return compileLatexEquation(source).mathml;
86697
+ }
86698
+ function compileEquationTemplateMathMl() {
86699
+ return EQUATION_TEMPLATES.map((tmpl) => latexToMathMl(tmpl.latex));
86700
+ }
86658
86701
  var ACCENT1 = "#4472C4";
86659
86702
  var ACCENT2 = "#ED7D31";
86660
86703
  var ACCENT3 = "#A5A5A5";
@@ -87110,6 +87153,14 @@ function resolveDataPointExplosion(series, pointIndex) {
87110
87153
  const point = findDataPoint(series, pointIndex);
87111
87154
  return point?.explosion ?? series.explosion ?? 0;
87112
87155
  }
87156
+ function resolveDataPointMarker(series, pointIndex) {
87157
+ const point = findDataPoint(series, pointIndex)?.marker;
87158
+ return {
87159
+ symbol: point?.symbol ?? series.marker?.symbol,
87160
+ size: point?.size ?? series.marker?.size,
87161
+ fill: point?.spPr?.fillColor ?? series.marker?.spPr?.fillColor
87162
+ };
87163
+ }
87113
87164
  function addChartSeries(data) {
87114
87165
  return chartDataAddSeries(data, {
87115
87166
  name: `Series ${data.series.length + 1}`,
@@ -87997,13 +88048,16 @@ function buildMarkerPrimitive(input) {
87997
88048
  return { kind: "circle", cx, cy, r, fill, part };
87998
88049
  }
87999
88050
  }
88000
- function pushMarker(out, series, cx, cy, fill, defaultRadius2, part, opacity2) {
88051
+ function pushMarker(out, series, pointIndex, cx, cy, fill, defaultRadius2, part, opacity2) {
88052
+ const marker = resolveDataPointMarker(series, pointIndex);
88001
88053
  const m = buildMarkerPrimitive({
88002
- symbol: series.marker?.symbol,
88003
- size: series.marker?.size,
88054
+ symbol: marker.symbol,
88055
+ size: marker.size,
88004
88056
  cx,
88005
88057
  cy,
88006
- fill,
88058
+ // A marker fill (series or per-point) wins over the plot fill, which is
88059
+ // what the line/area body is drawn with.
88060
+ fill: marker.fill ?? fill,
88007
88061
  defaultRadius: defaultRadius2,
88008
88062
  part
88009
88063
  });
@@ -88083,6 +88137,7 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
88083
88137
  pushMarker(
88084
88138
  primitives,
88085
88139
  series,
88140
+ idx,
88086
88141
  pt.x,
88087
88142
  pt.y,
88088
88143
  resolveDataPointFill(series, idx, c) ?? c,
@@ -88154,6 +88209,7 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
88154
88209
  pushMarker(
88155
88210
  primitives,
88156
88211
  series,
88212
+ idx,
88157
88213
  pt.x,
88158
88214
  pt.y,
88159
88215
  resolveDataPointFill(series, idx, c) ?? c,
@@ -88197,6 +88253,7 @@ function buildScatter(chartData, layout, range) {
88197
88253
  pushMarker(
88198
88254
  primitives,
88199
88255
  series,
88256
+ vi,
88200
88257
  dot.cx,
88201
88258
  dot.cy,
88202
88259
  resolveDataPointFill(series, vi, c) ?? c,
@@ -93666,6 +93723,10 @@ function applyFlyDirection(effect, subtype) {
93666
93723
  const suffix = `${edge.charAt(0).toUpperCase()}${edge.slice(1)}`;
93667
93724
  return `${prefix}${suffix}`;
93668
93725
  }
93726
+ function slideOffset(percent2, axis) {
93727
+ const fallback = axis === "w" ? "1280px" : "720px";
93728
+ return `calc(var(--pptx-slide-${axis}, ${fallback}) * ${(percent2 / 100).toFixed(4)})`;
93729
+ }
93669
93730
  function buildDynamicKeyframe(anim, uid) {
93670
93731
  if (anim.motionPath) {
93671
93732
  const name = `pptx-tl-motion-${uid}`;
@@ -93676,8 +93737,8 @@ function buildDynamicKeyframe(anim, uid) {
93676
93737
  const lines = [];
93677
93738
  for (let i = 0; i < points3.length; i++) {
93678
93739
  const pct = Math.round(i / (points3.length - 1) * 100);
93679
- const tx = points3[i].x.toFixed(2);
93680
- const ty = points3[i].y.toFixed(2);
93740
+ const tx = slideOffset(points3[i].x, "w");
93741
+ const ty = slideOffset(points3[i].y, "h");
93681
93742
  if (anim.motionPathRotateAuto) {
93682
93743
  const next = i < points3.length - 1 ? points3[i + 1] : points3[i];
93683
93744
  const prev = i > 0 ? points3[i - 1] : points3[i];
@@ -93685,10 +93746,10 @@ function buildDynamicKeyframe(anim, uid) {
93685
93746
  const dy = i < points3.length - 1 ? next.y - points3[i].y : points3[i].y - prev.y;
93686
93747
  const angleDeg = Math.atan2(dy, dx) * (180 / Math.PI);
93687
93748
  lines.push(
93688
- ` ${pct}% { transform: translate(${tx}%, ${ty}%) rotate(${angleDeg.toFixed(2)}deg); }`
93749
+ ` ${pct}% { transform: translate(${tx}, ${ty}) rotate(${angleDeg.toFixed(2)}deg); }`
93689
93750
  );
93690
93751
  } else {
93691
- lines.push(` ${pct}% { transform: translate(${tx}%, ${ty}%); }`);
93752
+ lines.push(` ${pct}% { transform: translate(${tx}, ${ty}); }`);
93692
93753
  }
93693
93754
  }
93694
93755
  return {
@@ -94823,6 +94884,422 @@ var TimelineEngine = class _TimelineEngine {
94823
94884
  }
94824
94885
  }
94825
94886
  };
94887
+ var PRESET_TO_EFFECT = {
94888
+ fadeIn: "fadeIn",
94889
+ flyIn: "flyInBottom",
94890
+ zoomIn: "zoomIn",
94891
+ fadeOut: "fadeOut",
94892
+ flyOut: "flyOutBottom",
94893
+ zoomOut: "zoomOut",
94894
+ spin: "spin",
94895
+ pulse: "pulse",
94896
+ colorWave: "colorWave",
94897
+ bounce: "bounce",
94898
+ flash: "flash"
94899
+ };
94900
+ var DIRECTION_FLY_MAP = {
94901
+ fromLeft: { flyIn: "flyInLeft", flyOut: "flyOutLeft" },
94902
+ fromRight: { flyIn: "flyInRight", flyOut: "flyOutRight" },
94903
+ fromTop: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94904
+ fromBottom: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
94905
+ fromTopLeft: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94906
+ fromTopRight: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94907
+ fromBottomLeft: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
94908
+ fromBottomRight: { flyIn: "flyInBottom", flyOut: "flyOutBottom" }
94909
+ };
94910
+ function resolvePreviewEffect(preset, direction) {
94911
+ if ((preset === "flyIn" || preset === "flyOut") && direction) {
94912
+ const dirMap = DIRECTION_FLY_MAP[direction];
94913
+ if (dirMap) {
94914
+ return preset === "flyIn" ? dirMap.flyIn : dirMap.flyOut;
94915
+ }
94916
+ }
94917
+ return PRESET_TO_EFFECT[preset];
94918
+ }
94919
+ function timingCurveToCss(curve, cubicBezierValues) {
94920
+ if (cubicBezierValues) {
94921
+ const parts = cubicBezierValues.split(",").map((s) => s.trim());
94922
+ if (parts.length === 4 && parts.every((p) => !Number.isNaN(Number(p)))) {
94923
+ return `cubic-bezier(${parts.join(", ")})`;
94924
+ }
94925
+ }
94926
+ switch (curve) {
94927
+ case "ease":
94928
+ return "ease";
94929
+ case "ease-in":
94930
+ return "ease-in";
94931
+ case "ease-out":
94932
+ return "ease-out";
94933
+ case "linear":
94934
+ return "linear";
94935
+ default:
94936
+ return "ease";
94937
+ }
94938
+ }
94939
+ function buildPreviewAnimation(preset, options) {
94940
+ if (preset === "none") {
94941
+ return void 0;
94942
+ }
94943
+ const effectName = resolvePreviewEffect(preset, options?.direction);
94944
+ if (!effectName) {
94945
+ return void 0;
94946
+ }
94947
+ const keyframeName = `pptx-${effectName}`;
94948
+ const keyframesCss = getEffectKeyframes(effectName);
94949
+ if (!keyframesCss) {
94950
+ return void 0;
94951
+ }
94952
+ const duration = options?.durationMs ?? 600;
94953
+ const easing = timingCurveToCss(options?.timingCurve, options?.cubicBezier);
94954
+ return {
94955
+ keyframeName,
94956
+ keyframesCss,
94957
+ cssAnimation: `${keyframeName} ${duration}ms ${easing} 0ms 1 normal both`,
94958
+ durationMs: duration
94959
+ };
94960
+ }
94961
+ var EDITABLE = /* @__PURE__ */ new Set(["M", "L", "C", "Z", "m", "l", "c", "z"]);
94962
+ var ARITY = { m: 2, l: 2, c: 6, z: 0 };
94963
+ function scanPath(path) {
94964
+ const tokens = path.match(/[A-Za-z]|-?\d*\.?\d+(?:[eE][-+]?\d+)?/gu);
94965
+ if (!tokens) {
94966
+ return void 0;
94967
+ }
94968
+ const segments = [];
94969
+ let i = 0;
94970
+ let cmd = "";
94971
+ while (i < tokens.length) {
94972
+ if (/^[A-Za-z]$/u.test(tokens[i])) {
94973
+ cmd = tokens[i];
94974
+ i++;
94975
+ if (!EDITABLE.has(cmd)) {
94976
+ return void 0;
94977
+ }
94978
+ if (cmd === "Z" || cmd === "z") {
94979
+ segments.push({ cmd, coords: [] });
94980
+ }
94981
+ continue;
94982
+ }
94983
+ const arity = ARITY[cmd.toLowerCase()];
94984
+ if (!arity) {
94985
+ return void 0;
94986
+ }
94987
+ const coords = [];
94988
+ for (let n = 0; n < arity; n++) {
94989
+ const value = Number(tokens[i++]);
94990
+ if (!Number.isFinite(value)) {
94991
+ return void 0;
94992
+ }
94993
+ coords.push(value);
94994
+ }
94995
+ segments.push({ cmd, coords });
94996
+ if (cmd === "M") {
94997
+ cmd = "L";
94998
+ } else if (cmd === "m") {
94999
+ cmd = "l";
95000
+ }
95001
+ }
95002
+ return segments.length > 0 ? segments : void 0;
95003
+ }
95004
+ function formatPath(segments) {
95005
+ return segments.map(
95006
+ (segment) => segment.coords.length === 0 ? segment.cmd : `${segment.cmd} ${segment.coords.map((n) => trimNumber(n)).join(" ")}`
95007
+ ).join(" ");
95008
+ }
95009
+ function trimNumber(value) {
95010
+ return String(Number(value.toFixed(4)));
95011
+ }
95012
+ function motionPathFractionPoints(path) {
95013
+ return parseMotionPathPoints(path).map((point) => ({ x: point.x / 100, y: point.y / 100 }));
95014
+ }
95015
+ function toPixels(point, frame2) {
95016
+ return {
95017
+ x: frame2.originX + point.x * frame2.slideWidth,
95018
+ y: frame2.originY + point.y * frame2.slideHeight
95019
+ };
95020
+ }
95021
+ function motionPathToSvgD(path, frame2) {
95022
+ const points3 = motionPathFractionPoints(path).map((point) => toPixels(point, frame2));
95023
+ if (points3.length === 0) {
95024
+ return "";
95025
+ }
95026
+ const head = `M ${trimNumber(frame2.originX)} ${trimNumber(frame2.originY)}`;
95027
+ const rest = points3.map((point) => `L ${trimNumber(point.x)} ${trimNumber(point.y)}`);
95028
+ return [head, ...rest].join(" ");
95029
+ }
95030
+ function motionPathEndPixel(path, frame2) {
95031
+ const points3 = motionPathFractionPoints(path);
95032
+ const last = points3.length > 0 ? points3[points3.length - 1] : void 0;
95033
+ return last ? toPixels(last, frame2) : { x: frame2.originX, y: frame2.originY };
95034
+ }
95035
+ function setMotionPathEnd(path, x, y) {
95036
+ const segments = scanPath(path);
95037
+ if (!segments) {
95038
+ return path;
95039
+ }
95040
+ let lastIndex = -1;
95041
+ for (let i = segments.length - 1; i >= 0; i--) {
95042
+ if (segments[i].coords.length > 0) {
95043
+ lastIndex = i;
95044
+ break;
95045
+ }
95046
+ }
95047
+ if (lastIndex < 0 || segments.some((segment) => segment.cmd === "Z" || segment.cmd === "z")) {
95048
+ return path;
95049
+ }
95050
+ const last = segments[lastIndex];
95051
+ if (last.cmd === last.cmd.toLowerCase()) {
95052
+ return path;
95053
+ }
95054
+ const coords = [...last.coords];
95055
+ const endX = coords[coords.length - 2];
95056
+ const endY = coords[coords.length - 1];
95057
+ const dx = x - endX;
95058
+ const dy = y - endY;
95059
+ coords[coords.length - 2] = x;
95060
+ coords[coords.length - 1] = y;
95061
+ if (last.cmd === "C") {
95062
+ coords[2] += dx;
95063
+ coords[3] += dy;
95064
+ }
95065
+ const next = segments.map(
95066
+ (segment, index) => index === lastIndex ? { ...last, coords } : segment
95067
+ );
95068
+ return formatPath(next);
95069
+ }
95070
+ function isEditableMotionPath(path) {
95071
+ const segments = scanPath(path);
95072
+ if (!segments) {
95073
+ return false;
95074
+ }
95075
+ return !segments.some((segment) => segment.cmd === "Z" || segment.cmd === "z");
95076
+ }
95077
+ function buildMotionPathKeyframes(args) {
95078
+ const points3 = motionPathFractionPoints(args.path);
95079
+ if (points3.length < 2) {
95080
+ return void 0;
95081
+ }
95082
+ const frames = points3.map((point, index) => {
95083
+ const percent2 = Math.round(index / (points3.length - 1) * 100);
95084
+ const x = trimNumber(point.x * args.slideWidth);
95085
+ const y = trimNumber(point.y * args.slideHeight);
95086
+ return ` ${percent2}% { transform: translate(${x}px, ${y}px); }`;
95087
+ });
95088
+ return {
95089
+ keyframeName: args.keyframeName,
95090
+ css: `@keyframes ${args.keyframeName} {
95091
+ ${frames.join("\n")}
95092
+ }`
95093
+ };
95094
+ }
95095
+ var K = 0.5523;
95096
+ var RX = 0.125;
95097
+ var RY = 0.2222;
95098
+ var CIRCLE = [
95099
+ "M 0 0",
95100
+ `C ${-K * RX} 0 ${-RX} ${-RY + K * RY} ${-RX} ${-RY}`,
95101
+ `C ${-RX} ${-RY - K * RY} ${-K * RX} ${ -2 * RY} 0 ${ -2 * RY}`,
95102
+ `C ${K * RX} ${ -2 * RY} ${RX} ${-RY - K * RY} ${RX} ${-RY}`,
95103
+ `C ${RX} ${-RY + K * RY} ${K * RX} 0 0 0`
95104
+ ].join(" ").replace(/(\d\.\d{4})\d+/gu, "$1");
95105
+ var MOTION_PATH_PRESETS2 = [
95106
+ // -- Lines ---------------------------------------------------------------
95107
+ { id: "lineRight", family: "lines", path: "M 0 0 L 0.25 0" },
95108
+ { id: "lineLeft", family: "lines", path: "M 0 0 L -0.25 0" },
95109
+ { id: "lineDown", family: "lines", path: "M 0 0 L 0 0.25" },
95110
+ { id: "lineUp", family: "lines", path: "M 0 0 L 0 -0.25" },
95111
+ { id: "lineDiagonalUpRight", family: "lines", path: "M 0 0 L 0.25 -0.25" },
95112
+ { id: "lineDiagonalDownRight", family: "lines", path: "M 0 0 L 0.25 0.25" },
95113
+ { id: "lineDiagonalUpLeft", family: "lines", path: "M 0 0 L -0.25 -0.25" },
95114
+ { id: "lineDiagonalDownLeft", family: "lines", path: "M 0 0 L -0.25 0.25" },
95115
+ // -- Arcs ----------------------------------------------------------------
95116
+ {
95117
+ id: "arcUp",
95118
+ family: "arcs",
95119
+ path: "M 0 0 C 0 -0.1227 0.0559 -0.2222 0.125 -0.2222 C 0.1941 -0.2222 0.25 -0.1227 0.25 0"
95120
+ },
95121
+ {
95122
+ id: "arcDown",
95123
+ family: "arcs",
95124
+ path: "M 0 0 C 0 0.1227 0.0559 0.2222 0.125 0.2222 C 0.1941 0.2222 0.25 0.1227 0.25 0"
95125
+ },
95126
+ {
95127
+ id: "arcRight",
95128
+ family: "arcs",
95129
+ path: "M 0 0 C 0.069 0 0.125 0.0995 0.125 0.2222 C 0.125 0.3449 0.069 0.4444 0 0.4444"
95130
+ },
95131
+ {
95132
+ id: "arcLeft",
95133
+ family: "arcs",
95134
+ path: "M 0 0 C -0.069 0 -0.125 0.0995 -0.125 0.2222 C -0.125 0.3449 -0.069 0.4444 0 0.4444"
95135
+ },
95136
+ // -- Turns ---------------------------------------------------------------
95137
+ { id: "turnUp", family: "turns", path: "M 0 0 L 0.25 0 L 0.25 -0.25" },
95138
+ { id: "turnDown", family: "turns", path: "M 0 0 L 0.25 0 L 0.25 0.25" },
95139
+ { id: "turnRight", family: "turns", path: "M 0 0 L 0 0.25 L 0.25 0.25" },
95140
+ { id: "turnLeft", family: "turns", path: "M 0 0 L 0 0.25 L -0.25 0.25" },
95141
+ {
95142
+ id: "sCurve",
95143
+ family: "turns",
95144
+ path: "M 0 0 C 0.0833 -0.1111 0.1667 0.1111 0.25 0"
95145
+ },
95146
+ {
95147
+ id: "zigzag",
95148
+ family: "turns",
95149
+ path: "M 0 0 L 0.0625 -0.1111 L 0.125 0 L 0.1875 -0.1111 L 0.25 0"
95150
+ },
95151
+ // -- Shapes --------------------------------------------------------------
95152
+ { id: "circle", family: "shapes", path: CIRCLE },
95153
+ { id: "square", family: "shapes", path: "M 0 0 L 0.125 0 L 0.125 -0.2222 L 0 -0.2222 Z" },
95154
+ { id: "triangle", family: "shapes", path: "M 0 0 L 0.0625 -0.2222 L 0.125 0 Z" },
95155
+ {
95156
+ id: "diamond",
95157
+ family: "shapes",
95158
+ path: "M 0 0 L 0.0625 -0.1111 L 0.125 0 L 0.0625 0.1111 Z"
95159
+ },
95160
+ {
95161
+ id: "hexagon",
95162
+ family: "shapes",
95163
+ path: "M 0 0 L 0.0417 -0.1111 L 0.125 -0.1111 L 0.1667 0 L 0.125 0.1111 L 0.0417 0.1111 Z"
95164
+ },
95165
+ // -- Loops ---------------------------------------------------------------
95166
+ {
95167
+ id: "loopDeLoop",
95168
+ family: "loops",
95169
+ path: "M 0 0 C 0.0625 0 0.0972 -0.2222 0.1667 -0.2222 C 0.2361 -0.2222 0.2708 0 0.1667 0 L 0.3333 0"
95170
+ },
95171
+ {
95172
+ id: "figureEight",
95173
+ family: "loops",
95174
+ path: "M 0 0 C -0.0833 0 -0.0833 -0.2222 0 -0.2222 C 0.0833 -0.2222 0.0833 0 0.1667 0 C 0.25 0 0.25 -0.2222 0.1667 -0.2222 C 0.0833 -0.2222 0.0833 0 0 0"
95175
+ },
95176
+ {
95177
+ id: "spiral",
95178
+ family: "loops",
95179
+ path: "M 0 0 C 0.0417 0 0.0417 -0.0741 0 -0.0741 C -0.0625 -0.0741 -0.0625 -0.1852 0 -0.1852 C 0.0833 -0.1852 0.0833 -0.3333 0 -0.3333"
95180
+ }
95181
+ ];
95182
+ var MOTION_PATH_FAMILIES = [
95183
+ "lines",
95184
+ "arcs",
95185
+ "turns",
95186
+ "shapes",
95187
+ "loops"
95188
+ ];
95189
+ function motionPathFamilyLabelKey(family) {
95190
+ return `pptx.animation.motionPath.family.${family}`;
95191
+ }
95192
+ function motionPathPresetLabelKey(presetId) {
95193
+ return `pptx.animation.motionPath.preset.${presetId}`;
95194
+ }
95195
+ function motionPathPresetById(presetId) {
95196
+ return MOTION_PATH_PRESETS2.find((preset) => preset.id === presetId);
95197
+ }
95198
+ function motionPathPresetsByFamily(family) {
95199
+ return MOTION_PATH_PRESETS2.filter((preset) => preset.family === family);
95200
+ }
95201
+ function motionPathPresetIdForPath(path) {
95202
+ if (!path) {
95203
+ return void 0;
95204
+ }
95205
+ const normalized = path.trim().replace(/\s+/gu, " ");
95206
+ return MOTION_PATH_PRESETS2.find(
95207
+ (preset) => preset.path.trim().replace(/\s+/gu, " ") === normalized
95208
+ )?.id;
95209
+ }
95210
+ var DEFAULT_MOTION_PATH_PRESET_ID = "lineRight";
95211
+ var DEFAULT_MOTION_PATH_DURATION_MS = 2e3;
95212
+ var DEFAULT_TRIGGER2 = "onClick";
95213
+ function motionPathFor(animations, elementId) {
95214
+ return animations.find((animation) => animation.elementId === elementId)?.motionPath;
95215
+ }
95216
+ function setMotionPath(animations, elementId, path) {
95217
+ const index = animations.findIndex((animation) => animation.elementId === elementId);
95218
+ if (index >= 0) {
95219
+ return animations.map(
95220
+ (animation, i) => i === index ? {
95221
+ ...animation,
95222
+ motionPath: path,
95223
+ motionPathEditMode: animation.motionPathEditMode ?? "relative",
95224
+ durationMs: animation.durationMs ?? DEFAULT_MOTION_PATH_DURATION_MS
95225
+ } : animation
95226
+ );
95227
+ }
95228
+ return [
95229
+ ...animations,
95230
+ {
95231
+ elementId,
95232
+ motionPath: path,
95233
+ motionPathEditMode: "relative",
95234
+ durationMs: DEFAULT_MOTION_PATH_DURATION_MS,
95235
+ order: animations.length,
95236
+ trigger: DEFAULT_TRIGGER2
95237
+ }
95238
+ ];
95239
+ }
95240
+ function applyMotionPathPreset(animations, elementId, presetId) {
95241
+ const preset = motionPathPresetById(presetId);
95242
+ if (!preset) {
95243
+ return [...animations];
95244
+ }
95245
+ return setMotionPath(animations, elementId, preset.path);
95246
+ }
95247
+ function clearMotionPath(animations, elementId) {
95248
+ const index = animations.findIndex((animation) => animation.elementId === elementId);
95249
+ if (index < 0) {
95250
+ return [...animations];
95251
+ }
95252
+ const current = animations[index];
95253
+ const stillHasEffect = Boolean(current.entrance || current.emphasis || current.exit);
95254
+ if (!stillHasEffect) {
95255
+ return animations.filter((animation) => animation.elementId !== elementId).map((animation, i) => ({ ...animation, order: i }));
95256
+ }
95257
+ return animations.map(
95258
+ (animation, i) => i === index ? {
95259
+ ...animation,
95260
+ motionPath: void 0,
95261
+ motionPathEditMode: void 0,
95262
+ motionPtsTypes: void 0
95263
+ } : animation
95264
+ );
95265
+ }
95266
+ function motionPathNativeAnimations(slide) {
95267
+ const native = slide.nativeAnimations ?? [];
95268
+ const alreadyNative = new Set(
95269
+ native.filter((animation) => animation.motionPath).map((animation) => animation.targetId)
95270
+ );
95271
+ return (slide.animations ?? []).filter((animation) => Boolean(animation.motionPath) && !alreadyNative.has(animation.elementId)).map((animation) => ({
95272
+ targetId: animation.elementId,
95273
+ trigger: animation.trigger ?? DEFAULT_TRIGGER2,
95274
+ triggerShapeId: animation.triggerShapeId,
95275
+ presetClass: "path",
95276
+ durationMs: animation.durationMs ?? DEFAULT_MOTION_PATH_DURATION_MS,
95277
+ delayMs: animation.delayMs ?? 0,
95278
+ motionPath: animation.motionPath,
95279
+ motionPathEditMode: animation.motionPathEditMode ?? "relative"
95280
+ }));
95281
+ }
95282
+ function buildMotionPathPreview(args) {
95283
+ const keyframeName = `pptx-motion-preview-${args.uid ?? 0}`;
95284
+ const keyframes = buildMotionPathKeyframes({
95285
+ path: args.path,
95286
+ slideWidth: args.slideWidth,
95287
+ slideHeight: args.slideHeight,
95288
+ keyframeName
95289
+ });
95290
+ if (!keyframes) {
95291
+ return void 0;
95292
+ }
95293
+ const durationMs = args.durationMs ?? DEFAULT_MOTION_PATH_DURATION_MS;
95294
+ const delayMs = args.delayMs ?? 0;
95295
+ const easing = timingCurveToCss(args.timingCurve);
95296
+ return {
95297
+ keyframeName,
95298
+ keyframesCss: keyframes.css,
95299
+ cssAnimation: `${keyframeName} ${durationMs}ms ${easing} ${delayMs}ms 1 normal both`,
95300
+ durationMs
95301
+ };
95302
+ }
94826
95303
  function buildSegmentCounts(slide, nativeAnims) {
94827
95304
  const segmentCounts = /* @__PURE__ */ new Map();
94828
95305
  for (const anim of nativeAnims) {
@@ -94855,7 +95332,7 @@ var PresentationAnimationController = class _PresentationAnimationController {
94855
95332
  * id list (base element ids + text-build sub-element ids) to track.
94856
95333
  */
94857
95334
  static fromSlide(slide) {
94858
- const nativeAnims = slide.nativeAnimations ?? [];
95335
+ const nativeAnims = [...slide.nativeAnimations ?? [], ...motionPathNativeAnimations(slide)];
94859
95336
  const segmentCounts = buildSegmentCounts(slide, nativeAnims);
94860
95337
  const expandedAnims = segmentCounts.size > 0 ? expandTextBuildAnimations(nativeAnims, segmentCounts) : nativeAnims;
94861
95338
  const engine = TimelineEngine.fromAnimations(expandedAnims);
@@ -94976,79 +95453,75 @@ var PresentationAnimationController = class _PresentationAnimationController {
94976
95453
  return ids;
94977
95454
  }
94978
95455
  };
94979
- var PRESET_TO_EFFECT = {
94980
- fadeIn: "fadeIn",
94981
- flyIn: "flyInBottom",
94982
- zoomIn: "zoomIn",
94983
- fadeOut: "fadeOut",
94984
- flyOut: "flyOutBottom",
94985
- zoomOut: "zoomOut",
94986
- spin: "spin",
94987
- pulse: "pulse",
94988
- colorWave: "colorWave",
94989
- bounce: "bounce",
94990
- flash: "flash"
94991
- };
94992
- var DIRECTION_FLY_MAP = {
94993
- fromLeft: { flyIn: "flyInLeft", flyOut: "flyOutLeft" },
94994
- fromRight: { flyIn: "flyInRight", flyOut: "flyOutRight" },
94995
- fromTop: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94996
- fromBottom: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
94997
- fromTopLeft: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94998
- fromTopRight: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94999
- fromBottomLeft: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
95000
- fromBottomRight: { flyIn: "flyInBottom", flyOut: "flyOutBottom" }
95001
- };
95002
- function resolvePreviewEffect(preset, direction) {
95003
- if ((preset === "flyIn" || preset === "flyOut") && direction) {
95004
- const dirMap = DIRECTION_FLY_MAP[direction];
95005
- if (dirMap) {
95006
- return preset === "flyIn" ? dirMap.flyIn : dirMap.flyOut;
95007
- }
95008
- }
95009
- return PRESET_TO_EFFECT[preset];
95010
- }
95011
- function timingCurveToCss(curve, cubicBezierValues) {
95012
- if (cubicBezierValues) {
95013
- const parts = cubicBezierValues.split(",").map((s) => s.trim());
95014
- if (parts.length === 4 && parts.every((p) => !Number.isNaN(Number(p)))) {
95015
- return `cubic-bezier(${parts.join(", ")})`;
95456
+ function applyMediaCommandVerb(el, parsed) {
95457
+ const safePlay = () => {
95458
+ void el.play().catch(() => {
95459
+ });
95460
+ };
95461
+ const safeSeek = (seconds) => {
95462
+ try {
95463
+ el.currentTime = seconds;
95464
+ } catch {
95016
95465
  }
95017
- }
95018
- switch (curve) {
95019
- case "ease":
95020
- return "ease";
95021
- case "ease-in":
95022
- return "ease-in";
95023
- case "ease-out":
95024
- return "ease-out";
95025
- case "linear":
95026
- return "linear";
95466
+ };
95467
+ switch (parsed.verb) {
95468
+ case "playFrom":
95469
+ safeSeek(parsed.seekSeconds ?? 0);
95470
+ safePlay();
95471
+ return true;
95472
+ case "play":
95473
+ safePlay();
95474
+ return true;
95475
+ case "pause":
95476
+ el.pause();
95477
+ return true;
95478
+ case "stop":
95479
+ el.pause();
95480
+ safeSeek(0);
95481
+ return true;
95482
+ case "togglePlay":
95483
+ if (el.paused) {
95484
+ safePlay();
95485
+ } else {
95486
+ el.pause();
95487
+ }
95488
+ return true;
95027
95489
  default:
95028
- return "ease";
95490
+ return false;
95029
95491
  }
95030
95492
  }
95031
- function buildPreviewAnimation(preset, options) {
95032
- if (preset === "none") {
95493
+ function findMediaElementByElementId(targetId, root) {
95494
+ if (typeof HTMLMediaElement === "undefined") {
95033
95495
  return void 0;
95034
95496
  }
95035
- const effectName = resolvePreviewEffect(preset, options?.direction);
95036
- if (!effectName) {
95497
+ const scope = root ?? (typeof document === "undefined" ? null : document);
95498
+ if (!scope) {
95037
95499
  return void 0;
95038
95500
  }
95039
- const keyframeName = `pptx-${effectName}`;
95040
- const keyframesCss = getEffectKeyframes(effectName);
95041
- if (!keyframesCss) {
95042
- return void 0;
95501
+ for (const wrapper of scope.querySelectorAll("[data-element-id]")) {
95502
+ if (wrapper.dataset["elementId"] !== targetId) {
95503
+ continue;
95504
+ }
95505
+ if (wrapper instanceof HTMLMediaElement) {
95506
+ return wrapper;
95507
+ }
95508
+ const media = wrapper.querySelector("video, audio");
95509
+ if (media instanceof HTMLMediaElement) {
95510
+ return media;
95511
+ }
95043
95512
  }
95044
- const duration = options?.durationMs ?? 600;
95045
- const easing = timingCurveToCss(options?.timingCurve, options?.cubicBezier);
95046
- return {
95047
- keyframeName,
95048
- keyframesCss,
95049
- cssAnimation: `${keyframeName} ${duration}ms ${easing} 0ms 1 normal both`,
95050
- durationMs: duration
95051
- };
95513
+ return void 0;
95514
+ }
95515
+ function runMediaCommand(command, resolve) {
95516
+ const el = resolve(command.targetId);
95517
+ if (!el) {
95518
+ return false;
95519
+ }
95520
+ const parsed = parseMediaCommand(command.command);
95521
+ if (!parsed) {
95522
+ return false;
95523
+ }
95524
+ return applyMediaCommandVerb(el, parsed);
95052
95525
  }
95053
95526
  var CAMERA_PRESET_MAP = {
95054
95527
  orthographicFront: { rotateX: 0, rotateY: 0, rotateZ: 0 },
@@ -96511,6 +96984,110 @@ function deleteTableColumn(tableData, colIdx) {
96511
96984
  const newWidths = normalizeWidths(tableData.columnWidths.filter((_, i) => i !== colIdx));
96512
96985
  return { ...tableData, rows: newRows, columnWidths: newWidths };
96513
96986
  }
96987
+ function setCellText(element, rowIndex, colIndex, text2) {
96988
+ const tableData = element.tableData;
96989
+ if (!tableData) {
96990
+ return element;
96991
+ }
96992
+ const rows = tableData.rows.map((row, ri) => {
96993
+ if (ri !== rowIndex) {
96994
+ return row;
96995
+ }
96996
+ return {
96997
+ ...row,
96998
+ cells: row.cells.map((cell, ci) => ci === colIndex ? { ...cell, text: text2 } : cell)
96999
+ };
97000
+ });
97001
+ return { ...element, tableData: { ...tableData, rows } };
97002
+ }
97003
+ function buildTableDataGrid(element) {
97004
+ const tableData = element.tableData;
97005
+ const sourceRows = tableData?.rows ?? [];
97006
+ const colCount = tableData?.columnWidths.length ?? 0;
97007
+ const colIndices = Array.from({ length: colCount }, (_unused, index) => index);
97008
+ const rows = sourceRows.map((row, rowIndex) => ({
97009
+ rowIndex,
97010
+ cells: colIndices.map((colIndex) => ({
97011
+ rowIndex,
97012
+ colIndex,
97013
+ text: row.cells[colIndex]?.text ?? ""
97014
+ }))
97015
+ }));
97016
+ return {
97017
+ rowCount: sourceRows.length,
97018
+ colCount,
97019
+ colIndices,
97020
+ rows,
97021
+ canRemoveRow: sourceRows.length > 1,
97022
+ canRemoveColumn: colCount > 1
97023
+ };
97024
+ }
97025
+ function withTableData(element, transform) {
97026
+ const tableData = element.tableData;
97027
+ if (!tableData) {
97028
+ return element;
97029
+ }
97030
+ const next = transform(tableData);
97031
+ if (next === tableData) {
97032
+ return element;
97033
+ }
97034
+ const updated = { ...element, tableData: next };
97035
+ if (element.rawXml) {
97036
+ const rawXml = rebuildTableStructureInRawXml(element, next);
97037
+ if (rawXml) {
97038
+ updated.rawXml = rawXml;
97039
+ }
97040
+ }
97041
+ return updated;
97042
+ }
97043
+ function setTableElementCellText(element, rowIndex, colIndex, text2) {
97044
+ const updated = setCellText(element, rowIndex, colIndex, text2);
97045
+ if (updated === element || !element.rawXml) {
97046
+ return updated;
97047
+ }
97048
+ const rawXml = updateCellTextInRawXml(element, rowIndex, colIndex, text2);
97049
+ return rawXml ? { ...updated, rawXml } : updated;
97050
+ }
97051
+ function insertTableElementRow(element, rowIdx, position2) {
97052
+ return withTableData(element, (data) => insertTableRow(data, rowIdx, position2));
97053
+ }
97054
+ function removeTableElementRow(element, rowIdx) {
97055
+ return withTableData(element, (data) => deleteTableRow(data, rowIdx));
97056
+ }
97057
+ function insertTableElementColumn(element, colIdx, position2) {
97058
+ return withTableData(element, (data) => insertTableColumn(data, colIdx, position2));
97059
+ }
97060
+ function removeTableElementColumn(element, colIdx) {
97061
+ return withTableData(element, (data) => deleteTableColumn(data, colIdx));
97062
+ }
97063
+ function appendTableElementRow(element) {
97064
+ const rowCount = element.tableData?.rows.length ?? 0;
97065
+ if (rowCount === 0) {
97066
+ return element;
97067
+ }
97068
+ return insertTableElementRow(element, rowCount - 1, "below");
97069
+ }
97070
+ function removeLastTableElementRow(element) {
97071
+ const rowCount = element.tableData?.rows.length ?? 0;
97072
+ if (rowCount === 0) {
97073
+ return element;
97074
+ }
97075
+ return removeTableElementRow(element, rowCount - 1);
97076
+ }
97077
+ function appendTableElementColumn(element) {
97078
+ const colCount = element.tableData?.columnWidths.length ?? 0;
97079
+ if (colCount === 0) {
97080
+ return element;
97081
+ }
97082
+ return insertTableElementColumn(element, colCount - 1, "right");
97083
+ }
97084
+ function removeLastTableElementColumn(element) {
97085
+ const colCount = element.tableData?.columnWidths.length ?? 0;
97086
+ if (colCount === 0) {
97087
+ return element;
97088
+ }
97089
+ return removeTableElementColumn(element, colCount - 1);
97090
+ }
96514
97091
  function computeMergeCellRight(td, rowIndex, columnIndex) {
96515
97092
  const row = td.rows[rowIndex];
96516
97093
  if (!row) {
@@ -97984,14 +98561,43 @@ function computeAutoFitTextStyle(input) {
97984
98561
  }
97985
98562
  return result;
97986
98563
  }
98564
+ var MAX_GROUP_DEPTH2 = 64;
97987
98565
  function isLinkedTextBox(element) {
97988
98566
  return hasTextProperties(element) && element.linkedTxbxId !== void 0;
97989
98567
  }
98568
+ function flattenForChainResolution(elements) {
98569
+ if (!elements.some((el) => el.type === "group")) {
98570
+ return elements;
98571
+ }
98572
+ const flat = [];
98573
+ const seen = /* @__PURE__ */ new Set();
98574
+ const walk2 = (list, depth) => {
98575
+ for (const el of list) {
98576
+ if (el.type !== "group") {
98577
+ flat.push(el);
98578
+ continue;
98579
+ }
98580
+ if (seen.has(el)) {
98581
+ continue;
98582
+ }
98583
+ seen.add(el);
98584
+ flat.push(el);
98585
+ if (depth < MAX_GROUP_DEPTH2) {
98586
+ walk2(el.children ?? [], depth + 1);
98587
+ }
98588
+ }
98589
+ };
98590
+ walk2(elements, 0);
98591
+ return flat;
98592
+ }
97990
98593
  function getOverflowSegments(element, slideElements) {
97991
98594
  if (!slideElements || slideElements.length === 0) {
97992
98595
  return void 0;
97993
98596
  }
97994
- return getLinkedTextBoxSegments(element, slideElements);
98597
+ if (!isLinkedTextBox(element)) {
98598
+ return void 0;
98599
+ }
98600
+ return getLinkedTextBoxSegments(element, flattenForChainResolution(slideElements));
97995
98601
  }
97996
98602
  function resolveParagraphRtl(paraSegments, elementRtl) {
97997
98603
  for (const entry2 of paraSegments) {
@@ -98771,21 +99377,6 @@ function buildTextRunFilterChain(style) {
98771
99377
  }
98772
99378
  return parts.length > 0 ? parts.join(" ") : void 0;
98773
99379
  }
98774
- function purifyFn() {
98775
- const purify = DOMPurify__default.default;
98776
- return typeof purify.sanitize === "function" ? purify.sanitize : void 0;
98777
- }
98778
- function sanitizeMarkupOrEmpty(markup, config) {
98779
- const sanitize = purifyFn();
98780
- return sanitize ? sanitize(markup, config) : "";
98781
- }
98782
- function sanitizeMathMl(markup) {
98783
- const sanitized = sanitizeMarkupOrEmpty(markup, { USE_PROFILES: { mathMl: true, svg: true } });
98784
- if (/<math(?:\s|>)/iu.test(markup) && !/<math(?:\s|>)/iu.test(sanitized) && sanitized) {
98785
- return `<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline">${sanitized}</math>`;
98786
- }
98787
- return sanitized;
98788
- }
98789
99380
  function resolveParagraphStrutFontSize(segments, bodyFontSize) {
98790
99381
  let largest;
98791
99382
  for (const segment of segments) {
@@ -106900,6 +107491,488 @@ function mapPresentationKey(input, buffer = createPresentationKeyBuffer()) {
106900
107491
  }
106901
107492
  return { action: "none" };
106902
107493
  }
107494
+ var READING_VIEW_ATTR = "data-pptx-reading-view";
107495
+ var READING_VIEW_COUNTER_ATTR = "data-pptx-reading-view-counter";
107496
+ var READING_VIEW_STAGE_ATTR = "data-pptx-reading-view-stage";
107497
+ var CLOSED_READING_VIEW = { open: false, slideIndex: 0 };
107498
+ function openReadingView(slideIndex, slideCount) {
107499
+ return { open: true, slideIndex: clampIndex(slideIndex, slideCount) };
107500
+ }
107501
+ function mapReadingViewKey(input, buffer) {
107502
+ const mapped = mapPresentationKey(input, buffer);
107503
+ switch (mapped.action) {
107504
+ case "next":
107505
+ return { command: "next" };
107506
+ case "previous":
107507
+ return { command: "previous" };
107508
+ case "first":
107509
+ return { command: "first" };
107510
+ case "last":
107511
+ return { command: "last" };
107512
+ case "goto":
107513
+ return { command: "goto", slideIndex: mapped.slideNumber - 1 };
107514
+ case "end":
107515
+ return { command: "exit" };
107516
+ default:
107517
+ return { command: "none" };
107518
+ }
107519
+ }
107520
+ function handleReadingViewKey(input, buffer) {
107521
+ const command = mapReadingViewKey(input, buffer);
107522
+ if (command.command !== "none") {
107523
+ return { command, swallow: true, preventDefault: true };
107524
+ }
107525
+ const isChord = Boolean(input.ctrlKey || input.metaKey || input.altKey);
107526
+ return { command, swallow: !isChord, preventDefault: false };
107527
+ }
107528
+ function applyReadingViewCommand(state, command, slideCount) {
107529
+ if (!state.open || slideCount <= 0) {
107530
+ return state.open ? CLOSED_READING_VIEW : state;
107531
+ }
107532
+ const last = slideCount - 1;
107533
+ switch (command.command) {
107534
+ case "next":
107535
+ return state.slideIndex >= last ? CLOSED_READING_VIEW : { open: true, slideIndex: state.slideIndex + 1 };
107536
+ case "previous":
107537
+ return { open: true, slideIndex: Math.max(0, state.slideIndex - 1) };
107538
+ case "first":
107539
+ return { open: true, slideIndex: 0 };
107540
+ case "last":
107541
+ return { open: true, slideIndex: last };
107542
+ case "goto":
107543
+ return { open: true, slideIndex: clampIndex(command.slideIndex, slideCount) };
107544
+ case "exit":
107545
+ return CLOSED_READING_VIEW;
107546
+ default:
107547
+ return state;
107548
+ }
107549
+ }
107550
+ function canGoPrevious(state) {
107551
+ return state.open && state.slideIndex > 0;
107552
+ }
107553
+ function canGoNext(state, slideCount) {
107554
+ return state.open && slideCount > 0;
107555
+ }
107556
+ function readingViewFitScale(canvas, viewport, padding = 0) {
107557
+ const available = {
107558
+ width: viewport.width - padding * 2,
107559
+ height: viewport.height - padding * 2
107560
+ };
107561
+ if (canvas.width <= 0 || canvas.height <= 0 || available.width <= 0 || available.height <= 0) {
107562
+ return 0;
107563
+ }
107564
+ return Math.min(available.width / canvas.width, available.height / canvas.height);
107565
+ }
107566
+ function clampIndex(index, slideCount) {
107567
+ if (!Number.isFinite(index) || slideCount <= 0) {
107568
+ return 0;
107569
+ }
107570
+ return Math.min(Math.max(Math.trunc(index), 0), slideCount - 1);
107571
+ }
107572
+ var OUTLINE_VIEW_ATTR = "data-pptx-outline-view";
107573
+ var OUTLINE_ROW_ATTR = "data-pptx-outline-row";
107574
+ var OUTLINE_SLIDE_ATTR = "data-pptx-outline-slide";
107575
+ var OUTLINE_LEVEL_ATTR = "data-pptx-outline-level";
107576
+ var MAX_PARAGRAPH_LEVEL = 8;
107577
+ var TITLE_PH_TYPES = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
107578
+ var CHROME_PH_TYPES = /* @__PURE__ */ new Set(["ftr", "hdr", "dt", "sldnum"]);
107579
+ var OUTLINE_TITLE_ELEMENT_NAME = "Title";
107580
+ function placeholderType(element) {
107581
+ const ph = element.rawXml?.["p:nvSpPr"]?.["p:nvPr"]?.["p:ph"];
107582
+ if (!ph) {
107583
+ return void 0;
107584
+ }
107585
+ const type = typeof ph["@_type"] === "string" ? ph["@_type"].trim().toLowerCase() : "";
107586
+ return type.length > 0 ? type : "body";
107587
+ }
107588
+ function isTextBearing(element) {
107589
+ return hasTextProperties(element);
107590
+ }
107591
+ function elementHasText(element) {
107592
+ if (!hasTextProperties(element)) {
107593
+ return false;
107594
+ }
107595
+ if (typeof element.text === "string" && element.text.trim().length > 0) {
107596
+ return true;
107597
+ }
107598
+ return (element.textSegments ?? []).some((segment) => segment.text.trim().length > 0);
107599
+ }
107600
+ function resolveSlideOutlineElements(slide) {
107601
+ const elements = (slide.elements ?? []).filter(isTextBearing);
107602
+ const placeholderTitle = elements.find((element) => {
107603
+ const type = placeholderType(element);
107604
+ return type !== void 0 && TITLE_PH_TYPES.has(type);
107605
+ });
107606
+ const placeholderBody = elements.filter((element) => {
107607
+ const type = placeholderType(element);
107608
+ return type !== void 0 && !TITLE_PH_TYPES.has(type) && !CHROME_PH_TYPES.has(type);
107609
+ });
107610
+ if (placeholderTitle || placeholderBody.length > 0) {
107611
+ return { title: placeholderTitle ?? null, body: placeholderBody };
107612
+ }
107613
+ const named = elements.find(
107614
+ (element) => (element.name ?? "").trim().toLowerCase() === OUTLINE_TITLE_ELEMENT_NAME.toLowerCase()
107615
+ );
107616
+ const withText = elements.filter(elementHasText);
107617
+ const title = named ?? withText[0] ?? null;
107618
+ return { title, body: withText.filter((element) => element !== title) };
107619
+ }
107620
+ function isBulletMarker(segment) {
107621
+ const bullet = segment.bulletInfo;
107622
+ if (!bullet) {
107623
+ return false;
107624
+ }
107625
+ const marker = bullet.char ? `${bullet.char} ` : bullet.imageRelId || bullet.imageDataUrl ? "\u{1F4CE} " : bullet.autoNumType ? void 0 : "\u2022 ";
107626
+ return marker ? segment.text === marker : bullet.paragraphIndex !== void 0;
107627
+ }
107628
+ function isParagraphSeparator(segment) {
107629
+ return Boolean(segment.isParagraphBreak) || segment.text === "\n" && !segment.isLineBreak;
107630
+ }
107631
+ function groupElementParagraphs(element) {
107632
+ const withText = hasTextProperties(element) ? element : void 0;
107633
+ const segments = withText?.textSegments;
107634
+ if (!segments || segments.length === 0) {
107635
+ const style = { ...withText?.textStyle ?? {} };
107636
+ return (withText?.text ?? "").split("\n").map((text2) => ({
107637
+ content: [{ text: text2, style: { ...style } }]
107638
+ }));
107639
+ }
107640
+ const groups = [{ content: [] }];
107641
+ for (const segment of segments) {
107642
+ if (isParagraphSeparator(segment)) {
107643
+ groups.push({ content: [] });
107644
+ continue;
107645
+ }
107646
+ const current = groups[groups.length - 1];
107647
+ if (current.content.length === 0 && current.marker === void 0 && isBulletMarker(segment)) {
107648
+ current.marker = segment;
107649
+ continue;
107650
+ }
107651
+ current.content.push(segment);
107652
+ }
107653
+ return groups;
107654
+ }
107655
+ function paragraphGroupText(group) {
107656
+ return group.content.map((segment) => segment.isLineBreak ? " " : segment.text).join("");
107657
+ }
107658
+ function paragraphGroupLevel(group) {
107659
+ const first = group.marker ?? group.content[0];
107660
+ const level = first?.paragraphLevel;
107661
+ return typeof level === "number" && level > 0 ? Math.min(level, MAX_PARAGRAPH_LEVEL) : 0;
107662
+ }
107663
+ function readElementParagraphs(element) {
107664
+ const groups = groupElementParagraphs(element);
107665
+ const paragraphs = groups.map((group) => ({
107666
+ text: paragraphGroupText(group),
107667
+ level: paragraphGroupLevel(group)
107668
+ }));
107669
+ let last = paragraphs.length - 1;
107670
+ while (last >= 0 && paragraphs[last].text.length === 0) {
107671
+ last -= 1;
107672
+ }
107673
+ return paragraphs.slice(0, last + 1);
107674
+ }
107675
+ function outlineRowKey(slideId, elementId, paragraphIndex) {
107676
+ return `${slideId}|${elementId ?? "\0new-title"}|${paragraphIndex}`;
107677
+ }
107678
+ function pushElementRows(rows, element, kind, slide, slideIndex) {
107679
+ for (const [paragraphIndex, paragraph] of readElementParagraphs(element).entries()) {
107680
+ rows.push({
107681
+ key: outlineRowKey(slide.id, element.id, paragraphIndex),
107682
+ slideIndex,
107683
+ slideId: slide.id,
107684
+ kind,
107685
+ elementId: element.id,
107686
+ paragraphIndex,
107687
+ // A title always sits in the leftmost column; body text is pushed one
107688
+ // column right of it, so authored level 0 reads as outline level 1.
107689
+ level: kind === "title" ? 0 : paragraph.level + 1,
107690
+ text: paragraph.text
107691
+ });
107692
+ }
107693
+ }
107694
+ function buildOutline(slides) {
107695
+ const rows = [];
107696
+ for (const [slideIndex, slide] of slides.entries()) {
107697
+ const { title, body } = resolveSlideOutlineElements(slide);
107698
+ const before = rows.length;
107699
+ if (title) {
107700
+ pushElementRows(rows, title, "title", slide, slideIndex);
107701
+ }
107702
+ if (rows.length === before) {
107703
+ rows.push({
107704
+ key: outlineRowKey(slide.id, title?.id ?? null, 0),
107705
+ slideIndex,
107706
+ slideId: slide.id,
107707
+ kind: "title",
107708
+ elementId: title?.id ?? null,
107709
+ paragraphIndex: 0,
107710
+ level: 0,
107711
+ text: ""
107712
+ });
107713
+ }
107714
+ for (const element of body) {
107715
+ pushElementRows(rows, element, "body", slide, slideIndex);
107716
+ }
107717
+ }
107718
+ return rows;
107719
+ }
107720
+ function findOutlineRow(rows, key) {
107721
+ return rows.find((row) => row.key === key);
107722
+ }
107723
+ var PASTE_OFFSET_PX = 20;
107724
+ function generateElementId() {
107725
+ return `el-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
107726
+ }
107727
+ function makeCloneId(intoTemplate, sourceId) {
107728
+ if (!intoTemplate) {
107729
+ return generateElementId();
107730
+ }
107731
+ if (sourceId.startsWith("master-")) {
107732
+ return `master-${generateElementId()}`;
107733
+ }
107734
+ return `layout-${generateElementId()}`;
107735
+ }
107736
+ function buildElementClipboardPayload(element, isTemplate) {
107737
+ return { element: structuredClone(element), isTemplate };
107738
+ }
107739
+ function cloneElementForPaste(element, options = {}) {
107740
+ const clone3 = structuredClone(element);
107741
+ clone3.id = makeCloneId(options.intoTemplate ?? false, element.id);
107742
+ clone3.x += options.offsetX ?? PASTE_OFFSET_PX;
107743
+ clone3.y += options.offsetY ?? PASTE_OFFSET_PX;
107744
+ return clone3;
107745
+ }
107746
+ function mapOutlineKey(input, rowKey) {
107747
+ const none = { edit: null, preventDefault: false };
107748
+ if (input.ctrlKey || input.metaKey) {
107749
+ return none;
107750
+ }
107751
+ if (input.key === "Tab" && !input.altKey) {
107752
+ return {
107753
+ edit: { type: "indent", key: rowKey, delta: input.shiftKey ? -1 : 1 },
107754
+ preventDefault: true
107755
+ };
107756
+ }
107757
+ if (input.altKey && input.shiftKey && (input.key === "ArrowRight" || input.key === "ArrowLeft")) {
107758
+ return {
107759
+ edit: { type: "indent", key: rowKey, delta: input.key === "ArrowRight" ? 1 : -1 },
107760
+ preventDefault: true
107761
+ };
107762
+ }
107763
+ if (input.key === "Enter" && !input.shiftKey && !input.altKey) {
107764
+ return { edit: { type: "insertAfter", key: rowKey }, preventDefault: true };
107765
+ }
107766
+ return none;
107767
+ }
107768
+ function withLevel(segments, level) {
107769
+ return segments.map((segment, index) => {
107770
+ if (index > 0) {
107771
+ return segment;
107772
+ }
107773
+ const next = { ...segment };
107774
+ if (level > 0) {
107775
+ next.paragraphLevel = Math.min(level, MAX_PARAGRAPH_LEVEL);
107776
+ } else {
107777
+ delete next.paragraphLevel;
107778
+ }
107779
+ return next;
107780
+ });
107781
+ }
107782
+ function rebuildParagraph(group, donor, text2, elementStyle) {
107783
+ if (group && paragraphGroupText(group) === text2) {
107784
+ return [...group.marker ? [group.marker] : [], ...group.content];
107785
+ }
107786
+ const source = group ?? donor;
107787
+ const marker = source?.marker ? [source.marker] : [];
107788
+ const content = remapTextToSegments(text2, source?.content, elementStyle);
107789
+ return [...marker, ...content];
107790
+ }
107791
+ function writeElementParagraphs(element, paragraphs) {
107792
+ const groups = groupElementParagraphs(element);
107793
+ const donor = groups[groups.length - 1];
107794
+ const style = hasTextProperties(element) ? element.textStyle : void 0;
107795
+ const segments = [];
107796
+ for (const [index, paragraph] of paragraphs.entries()) {
107797
+ if (index > 0) {
107798
+ const previous = segments[segments.length - 1];
107799
+ segments.push({
107800
+ text: "\n",
107801
+ style: { ...previous?.style ?? style ?? {} },
107802
+ isParagraphBreak: true
107803
+ });
107804
+ }
107805
+ segments.push(
107806
+ ...withLevel(rebuildParagraph(groups[index], donor, paragraph.text, style), paragraph.level)
107807
+ );
107808
+ }
107809
+ return {
107810
+ ...element,
107811
+ text: paragraphs.map((paragraph) => paragraph.text).join("\n"),
107812
+ textSegments: segments
107813
+ };
107814
+ }
107815
+ var DEFAULT_CANVAS = { width: 960, height: 540 };
107816
+ function createTitleElement(text2, options) {
107817
+ const canvas = options.canvas ?? DEFAULT_CANVAS;
107818
+ return {
107819
+ type: "text",
107820
+ id: options.idGenerator ? options.idGenerator() : generateElementId(),
107821
+ name: OUTLINE_TITLE_ELEMENT_NAME,
107822
+ x: Math.round(canvas.width * 0.06),
107823
+ y: Math.round(canvas.height * 0.08),
107824
+ width: Math.round(canvas.width * 0.88),
107825
+ height: Math.round(canvas.height * 0.17),
107826
+ text: text2,
107827
+ textStyle: { fontSize: 36, bold: true },
107828
+ textSegments: [{ text: text2, style: { fontSize: 36, bold: true } }]
107829
+ };
107830
+ }
107831
+ function renumber(slides) {
107832
+ return slides.map((slide, index) => ({ ...slide, slideNumber: index + 1 }));
107833
+ }
107834
+ function unchanged(slides, row) {
107835
+ return {
107836
+ slides,
107837
+ changed: false,
107838
+ focusKey: row?.key ?? null,
107839
+ activeSlideIndex: row?.slideIndex ?? 0
107840
+ };
107841
+ }
107842
+ function replaceElement(slides, slideIndex, elementId, next) {
107843
+ return slides.map(
107844
+ (slide, index) => index === slideIndex ? {
107845
+ ...slide,
107846
+ elements: (slide.elements ?? []).map(
107847
+ (element) => element.id === elementId ? next : element
107848
+ )
107849
+ } : slide
107850
+ );
107851
+ }
107852
+ function editParagraphs(slides, row, mutate) {
107853
+ const slide = slides[row.slideIndex];
107854
+ const element = (slide?.elements ?? []).find((candidate) => candidate.id === row.elementId);
107855
+ if (!element) {
107856
+ return null;
107857
+ }
107858
+ const paragraphs = readElementParagraphs(element);
107859
+ while (paragraphs.length <= row.paragraphIndex) {
107860
+ paragraphs.push({ text: "", level: 0 });
107861
+ }
107862
+ const next = mutate(paragraphs);
107863
+ if (!next) {
107864
+ return null;
107865
+ }
107866
+ return {
107867
+ slides: replaceElement(
107868
+ slides,
107869
+ row.slideIndex,
107870
+ element.id,
107871
+ writeElementParagraphs(element, next)
107872
+ ),
107873
+ changed: true,
107874
+ focusKey: row.key,
107875
+ activeSlideIndex: row.slideIndex
107876
+ };
107877
+ }
107878
+ function oneLine(text2) {
107879
+ return text2.replace(/[\r\n]+/g, " ");
107880
+ }
107881
+ function applySetText(slides, row, raw, options) {
107882
+ const text2 = oneLine(raw);
107883
+ if (row.elementId === null) {
107884
+ if (text2.length === 0) {
107885
+ return unchanged([...slides], row);
107886
+ }
107887
+ const element = createTitleElement(text2, options);
107888
+ const next = slides.map(
107889
+ (slide, index) => index === row.slideIndex ? { ...slide, elements: [element, ...slide.elements ?? []] } : slide
107890
+ );
107891
+ return {
107892
+ slides: next,
107893
+ changed: true,
107894
+ focusKey: outlineRowKey(row.slideId, element.id, 0),
107895
+ activeSlideIndex: row.slideIndex
107896
+ };
107897
+ }
107898
+ const result = editParagraphs(slides, row, (paragraphs) => {
107899
+ if (paragraphs[row.paragraphIndex].text === text2) {
107900
+ return null;
107901
+ }
107902
+ const next = [...paragraphs];
107903
+ next[row.paragraphIndex] = { ...next[row.paragraphIndex], text: text2 };
107904
+ return next;
107905
+ });
107906
+ return result ?? unchanged([...slides], row);
107907
+ }
107908
+ function applyIndent(slides, row, delta) {
107909
+ if (row.kind !== "body" || row.elementId === null || delta === 0) {
107910
+ return unchanged([...slides], row);
107911
+ }
107912
+ const result = editParagraphs(slides, row, (paragraphs) => {
107913
+ const current = paragraphs[row.paragraphIndex];
107914
+ const level = Math.min(Math.max(current.level + (delta > 0 ? 1 : -1), 0), MAX_PARAGRAPH_LEVEL);
107915
+ if (level === current.level) {
107916
+ return null;
107917
+ }
107918
+ const next = [...paragraphs];
107919
+ next[row.paragraphIndex] = { ...current, level };
107920
+ return next;
107921
+ });
107922
+ return result ?? unchanged([...slides], row);
107923
+ }
107924
+ function applyInsertAfter(slides, row, options) {
107925
+ if (row.kind === "title") {
107926
+ const slide = {
107927
+ id: makeSlideId(options.idGenerator),
107928
+ rId: "",
107929
+ slideNumber: row.slideIndex + 2,
107930
+ elements: []
107931
+ };
107932
+ const next = renumber([
107933
+ ...slides.slice(0, row.slideIndex + 1),
107934
+ slide,
107935
+ ...slides.slice(row.slideIndex + 1)
107936
+ ]);
107937
+ return {
107938
+ slides: next,
107939
+ changed: true,
107940
+ focusKey: outlineRowKey(slide.id, null, 0),
107941
+ activeSlideIndex: row.slideIndex + 1
107942
+ };
107943
+ }
107944
+ const result = editParagraphs(slides, row, (paragraphs) => {
107945
+ const next = [...paragraphs];
107946
+ next.splice(row.paragraphIndex + 1, 0, {
107947
+ text: "",
107948
+ level: paragraphs[row.paragraphIndex].level
107949
+ });
107950
+ return next;
107951
+ });
107952
+ if (!result) {
107953
+ return unchanged([...slides], row);
107954
+ }
107955
+ return {
107956
+ ...result,
107957
+ focusKey: outlineRowKey(row.slideId, row.elementId, row.paragraphIndex + 1)
107958
+ };
107959
+ }
107960
+ function applyOutlineEdit(slides, edit, options = {}) {
107961
+ const row = findOutlineRow(buildOutline(slides), edit.key);
107962
+ if (!row) {
107963
+ return unchanged([...slides]);
107964
+ }
107965
+ switch (edit.type) {
107966
+ case "setText":
107967
+ return applySetText(slides, row, edit.text, options);
107968
+ case "indent":
107969
+ return applyIndent(slides, row, edit.delta);
107970
+ case "insertAfter":
107971
+ return applyInsertAfter(slides, row, options);
107972
+ default:
107973
+ return unchanged([...slides], row);
107974
+ }
107975
+ }
106903
107976
  var NUDGE_SMALL = 1;
106904
107977
  var NUDGE_LARGE = 10;
106905
107978
  var GUARD_DEFAULTS = {
@@ -108924,29 +109997,6 @@ var COMMON_FONTS = [
108924
109997
  "Tw Cen MT",
108925
109998
  "Verdana"
108926
109999
  ];
108927
- var PASTE_OFFSET_PX = 20;
108928
- function generateElementId() {
108929
- return `el-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
108930
- }
108931
- function makeCloneId(intoTemplate, sourceId) {
108932
- if (!intoTemplate) {
108933
- return generateElementId();
108934
- }
108935
- if (sourceId.startsWith("master-")) {
108936
- return `master-${generateElementId()}`;
108937
- }
108938
- return `layout-${generateElementId()}`;
108939
- }
108940
- function buildElementClipboardPayload(element, isTemplate) {
108941
- return { element: structuredClone(element), isTemplate };
108942
- }
108943
- function cloneElementForPaste(element, options = {}) {
108944
- const clone3 = structuredClone(element);
108945
- clone3.id = makeCloneId(options.intoTemplate ?? false, element.id);
108946
- clone3.x += options.offsetX ?? PASTE_OFFSET_PX;
108947
- clone3.y += options.offsetY ?? PASTE_OFFSET_PX;
108948
- return clone3;
108949
- }
108950
110000
  var DEFAULT_PREVIEW_ELEMENT_CAP = 500;
108951
110001
  function buildPreviewElements(slide, templateElements = [], options) {
108952
110002
  const cap = options?.cap ?? DEFAULT_PREVIEW_ELEMENT_CAP;
@@ -112595,6 +113645,7 @@ exports.DEFAULT_BROADCAST_SERVER_URL = DEFAULT_BROADCAST_SERVER_URL;
112595
113645
  exports.DEFAULT_COLOR_CHANGE_TOLERANCE = DEFAULT_COLOR_CHANGE_TOLERANCE;
112596
113646
  exports.DEFAULT_COLOR_MAP = DEFAULT_COLOR_MAP;
112597
113647
  exports.DEFAULT_INSERT_CHART_TYPE = DEFAULT_INSERT_CHART_TYPE;
113648
+ exports.DEFAULT_MOTION_PATH_PRESET_ID = DEFAULT_MOTION_PATH_PRESET_ID;
112598
113649
  exports.DEFAULT_QUICK_ACCESS_COMMAND_IDS = DEFAULT_QUICK_ACCESS_COMMAND_IDS;
112599
113650
  exports.DEFAULT_ROW_HEIGHT = DEFAULT_ROW_HEIGHT;
112600
113651
  exports.DEFAULT_VIEWER_OPTIONS = DEFAULT_VIEWER_OPTIONS;
@@ -112621,11 +113672,16 @@ exports.MATERIAL_PRESETS = MATERIAL_PRESETS;
112621
113672
  exports.MAX_ZOOM_SCALE = MAX_ZOOM_SCALE;
112622
113673
  exports.MIN_ZOOM_SCALE = MIN_ZOOM_SCALE;
112623
113674
  exports.MOBILE_BREAKPOINT = MOBILE_BREAKPOINT;
113675
+ exports.MOTION_PATH_FAMILIES = MOTION_PATH_FAMILIES;
112624
113676
  exports.NOTES_FONT_SIZE_DEFAULT = NOTES_FONT_SIZE_DEFAULT;
112625
113677
  exports.NOTES_FONT_SIZE_MAX = NOTES_FONT_SIZE_MAX;
112626
113678
  exports.NOTES_FONT_SIZE_MIN = NOTES_FONT_SIZE_MIN;
112627
113679
  exports.NOTES_FONT_SIZE_STEP = NOTES_FONT_SIZE_STEP;
112628
113680
  exports.NUM = NUM;
113681
+ exports.OUTLINE_LEVEL_ATTR = OUTLINE_LEVEL_ATTR;
113682
+ exports.OUTLINE_ROW_ATTR = OUTLINE_ROW_ATTR;
113683
+ exports.OUTLINE_SLIDE_ATTR = OUTLINE_SLIDE_ATTR;
113684
+ exports.OUTLINE_VIEW_ATTR = OUTLINE_VIEW_ATTR;
112629
113685
  exports.PATTERN_OPTIONS = PATTERN_OPTIONS;
112630
113686
  exports.PRESENTATION_CHANNEL_NAME = PRESENTATION_CHANNEL_NAME;
112631
113687
  exports.PRESENTATION_HASH = PRESENTATION_HASH;
@@ -112637,6 +113693,9 @@ exports.PptxHandler = PptxHandler;
112637
113693
  exports.PptxMarkdownConverter = PptxMarkdownConverter;
112638
113694
  exports.PresentationAnimationController = PresentationAnimationController;
112639
113695
  exports.QUICK_ACCESS_COMMAND_CATALOG = QUICK_ACCESS_COMMAND_CATALOG;
113696
+ exports.READING_VIEW_ATTR = READING_VIEW_ATTR;
113697
+ exports.READING_VIEW_COUNTER_ATTR = READING_VIEW_COUNTER_ATTR;
113698
+ exports.READING_VIEW_STAGE_ATTR = READING_VIEW_STAGE_ATTR;
112640
113699
  exports.RULER_FONT_SIZE = RULER_FONT_SIZE;
112641
113700
  exports.RULER_THICKNESS = RULER_THICKNESS;
112642
113701
  exports.SECTION_HEADING = SECTION_HEADING;
@@ -112681,6 +113740,8 @@ exports.addSmartArtNodeAsChild = addSmartArtNodeAsChild;
112681
113740
  exports.addTagToCollections = addTagToCollections;
112682
113741
  exports.alignElements = alignElements;
112683
113742
  exports.appendPresentationInkPoint = appendPresentationInkPoint;
113743
+ exports.appendTableElementColumn = appendTableElementColumn;
113744
+ exports.appendTableElementRow = appendTableElementRow;
112684
113745
  exports.apply3dEffects = apply3dEffects;
112685
113746
  exports.applyAcceptAllSlides = applyAcceptAllSlides;
112686
113747
  exports.applyAcceptSlide = applyAcceptSlide;
@@ -112689,7 +113750,10 @@ exports.applyChartBuildReveal = applyChartBuildReveal;
112689
113750
  exports.applyColorChange = applyColorChange;
112690
113751
  exports.applyDuotone = applyDuotone;
112691
113752
  exports.applyFormatToElement = applyFormatToElement;
113753
+ exports.applyMotionPathPreset = applyMotionPathPreset;
113754
+ exports.applyOutlineEdit = applyOutlineEdit;
112692
113755
  exports.applyPreferenceToOptions = applyPreferenceToOptions;
113756
+ exports.applyReadingViewCommand = applyReadingViewCommand;
112693
113757
  exports.applyRehearsalTimings = applyRehearsalTimings;
112694
113758
  exports.applyReroutedConnectors = applyReroutedConnectors;
112695
113759
  exports.applyResize = applyResize;
@@ -112719,9 +113783,11 @@ exports.buildInitialGuides = buildInitialGuides;
112719
113783
  exports.buildInnerShadowCssFromShapeStyle = buildInnerShadowCssFromShapeStyle;
112720
113784
  exports.buildJoinCollaborationConfig = buildJoinCollaborationConfig;
112721
113785
  exports.buildMorphTransitionPlan = buildMorphTransitionPlan;
113786
+ exports.buildMotionPathPreview = buildMotionPathPreview;
112722
113787
  exports.buildMultiLayerShadowCss = buildMultiLayerShadowCss;
112723
113788
  exports.buildNotesHtml = buildNotesHtml;
112724
113789
  exports.buildNotesPdfBytes = buildNotesPdfBytes;
113790
+ exports.buildOutline = buildOutline;
112725
113791
  exports.buildOutlineHtml = buildOutlineHtml;
112726
113792
  exports.buildPatternFillCss = buildPatternFillCss;
112727
113793
  exports.buildPresentationAudienceUrl = buildPresentationAudienceUrl;
@@ -112739,6 +113805,7 @@ exports.buildSmartArtPresetData = buildSmartArtPresetData;
112739
113805
  exports.buildStrokeOutline = buildStrokeOutline;
112740
113806
  exports.buildSummaryZoomView = buildSummaryZoomView;
112741
113807
  exports.buildSvgGradientDef = buildSvgGradientDef;
113808
+ exports.buildTableDataGrid = buildTableDataGrid;
112742
113809
  exports.buildTextBlockStyle = buildTextBlockStyle;
112743
113810
  exports.buildTextBody3DSceneStyle = buildTextBody3DSceneStyle;
112744
113811
  exports.buildTextBuildSpec = buildTextBuildSpec;
@@ -112750,6 +113817,8 @@ exports.buildThemeColorGrid = buildThemeColorGrid;
112750
113817
  exports.buildThemeColorMap = buildThemeColorMap;
112751
113818
  exports.buildUserFontFaceStyles = buildUserFontFaceStyles;
112752
113819
  exports.canCommitActionType = canCommitActionType;
113820
+ exports.canGoNext = canGoNext;
113821
+ exports.canGoPrevious = canGoPrevious;
112753
113822
  exports.canvasToJpegData = canvasToJpegData;
112754
113823
  exports.cell3DBevelCss = cell3DBevelCss;
112755
113824
  exports.chartDataChangeType = chartDataChangeType;
@@ -112763,6 +113832,7 @@ exports.clampZoomScale = clampZoomScale;
112763
113832
  exports.clearAllLocalViewerData = clearAllLocalViewerData;
112764
113833
  exports.clearAudienceContent = clearAudienceContent;
112765
113834
  exports.clearLocalAwareness = clearLocalAwareness;
113835
+ exports.clearMotionPath = clearMotionPath;
112766
113836
  exports.clearStoredViewerPrefs = clearStoredViewerPrefs;
112767
113837
  exports.cloneElementForPaste = cloneElementForPaste;
112768
113838
  exports.cloneHistorySnapshot = cloneHistorySnapshot;
@@ -112773,6 +113843,8 @@ exports.collectMediaElements = collectMediaElements;
112773
113843
  exports.collectUsedFonts = collectUsedFonts;
112774
113844
  exports.colorWithOpacity = colorWithOpacity;
112775
113845
  exports.comparePresentation = comparePresentation;
113846
+ exports.compileEquationTemplateMathMl = compileEquationTemplateMathMl;
113847
+ exports.compileLatexEquation = compileLatexEquation;
112776
113848
  exports.computeAllNotesPages = computeAllNotesPages;
112777
113849
  exports.computeColumnBoundaries = computeColumnBoundaries;
112778
113850
  exports.computeEntranceAnimationDelay = computeEntranceAnimationDelay;
@@ -112839,6 +113911,7 @@ exports.extractPathPoints = extractPathPoints;
112839
113911
  exports.filterCommands = filterCommands;
112840
113912
  exports.filterRenderedElements = filterRenderedElements;
112841
113913
  exports.findChartPartTarget = findChartPartTarget;
113914
+ exports.findMediaElementByElementId = findMediaElementByElementId;
112842
113915
  exports.findSmartArtNodeText = findSmartArtNodeText;
112843
113916
  exports.flattenTagCollections = flattenTagCollections;
112844
113917
  exports.formatAxisValue = formatAxisValue;
@@ -112923,6 +113996,7 @@ exports.groupElements = groupElements;
112923
113996
  exports.groupIntoParagraphs = groupIntoParagraphs;
112924
113997
  exports.groupSlidesBySection = groupSlidesBySection;
112925
113998
  exports.guidePxToEmu = guidePxToEmu;
113999
+ exports.handleReadingViewKey = handleReadingViewKey;
112926
114000
  exports.hasCopyableFormat = hasCopyableFormat;
112927
114001
  exports.hasDistinctScriptFonts = hasDistinctScriptFonts;
112928
114002
  exports.hasPressureVariation = hasPressureVariation;
@@ -112935,6 +114009,7 @@ exports.isActionHidden = isActionHidden;
112935
114009
  exports.isBrowserOpenableMime = isBrowserOpenableMime;
112936
114010
  exports.isCalloutShape = isCalloutShape;
112937
114011
  exports.isCellInRect = isCellInRect;
114012
+ exports.isEditableMotionPath = isEditableMotionPath;
112938
114013
  exports.isEditableTextElement = isEditableTextElement;
112939
114014
  exports.isEditorTextInputTarget = isEditorTextInputTarget;
112940
114015
  exports.isElementActionable = isElementActionable;
@@ -112960,6 +114035,7 @@ exports.loadAudienceContent = loadAudienceContent;
112960
114035
  exports.makeCloneId = makeCloneId;
112961
114036
  exports.makeSlideId = makeSlideId;
112962
114037
  exports.mapEditorKey = mapEditorKey;
114038
+ exports.mapOutlineKey = mapOutlineKey;
112963
114039
  exports.mapPresentationKey = mapPresentationKey;
112964
114040
  exports.mayLeaveSlideShow = mayLeaveSlideShow;
112965
114041
  exports.mergeAdditiveSelection = mergeAdditiveSelection;
@@ -112970,6 +114046,13 @@ exports.mergeSlideTransition = mergeSlideTransition;
112970
114046
  exports.mobileElapsedSince = mobileElapsedSince;
112971
114047
  exports.mobileSlideCounter = mobileSlideCounter;
112972
114048
  exports.morphOptionToMode = morphOptionToMode;
114049
+ exports.motionPathEndPixel = motionPathEndPixel;
114050
+ exports.motionPathFamilyLabelKey = motionPathFamilyLabelKey;
114051
+ exports.motionPathFor = motionPathFor;
114052
+ exports.motionPathPresetIdForPath = motionPathPresetIdForPath;
114053
+ exports.motionPathPresetLabelKey = motionPathPresetLabelKey;
114054
+ exports.motionPathPresetsByFamily = motionPathPresetsByFamily;
114055
+ exports.motionPathToSvgD = motionPathToSvgD;
112973
114056
  exports.mountModel3D = mountModel3D;
112974
114057
  exports.mountSurfaceChart3D = mountSurfaceChart3D;
112975
114058
  exports.movePresenterPointer = movePresenterPointer;
@@ -112988,11 +114071,11 @@ exports.ooxmlDashToCssBorderStyle = ooxmlDashToCssBorderStyle;
112988
114071
  exports.ooxmlGradientAngleToCssDegrees = ooxmlGradientAngleToCssDegrees;
112989
114072
  exports.openNativeEyeDropper = openNativeEyeDropper;
112990
114073
  exports.openPptxFile = openPptxFile;
114074
+ exports.openReadingView = openReadingView;
112991
114075
  exports.openUrlInNewTab = openUrlInNewTab;
112992
114076
  exports.paletteColor = paletteColor;
112993
114077
  exports.parseDrawingColor = parseDrawingColor;
112994
114078
  exports.parseDrawingColorOpacity = parseDrawingColorOpacity;
112995
- exports.parseMediaCommand = parseMediaCommand;
112996
114079
  exports.parsePpactionUrl = parsePpactionUrl;
112997
114080
  exports.pickSupportedMimeType = pickSupportedMimeType;
112998
114081
  exports.placeAudienceWindow = placeAudienceWindow;
@@ -113014,6 +114097,7 @@ exports.readBackstageRecentFile = readBackstageRecentFile;
113014
114097
  exports.readSlidesFromYDoc = readSlidesFromYDoc;
113015
114098
  exports.readStoredViewerPrefs = readStoredViewerPrefs;
113016
114099
  exports.readViewportMetrics = readViewportMetrics;
114100
+ exports.readingViewFitScale = readingViewFitScale;
113017
114101
  exports.rebuildDrawingShapesIfCleared = rebuildDrawingShapesIfCleared;
113018
114102
  exports.rebuildTableStructureInRawXml = rebuildTableStructureInRawXml;
113019
114103
  exports.reconcileSlidesInYDoc = reconcileSlidesInYDoc;
@@ -113023,8 +114107,12 @@ exports.registerCollaborationTeardown = registerCollaborationTeardown;
113023
114107
  exports.remapTextToSegments = remapTextToSegments;
113024
114108
  exports.removeChartCategory = removeChartCategory;
113025
114109
  exports.removeChartSeries = removeChartSeries;
114110
+ exports.removeLastTableElementColumn = removeLastTableElementColumn;
114111
+ exports.removeLastTableElementRow = removeLastTableElementRow;
113026
114112
  exports.removeQuickAccessCommand = removeQuickAccessCommand;
113027
114113
  exports.removeSmartArtNode = removeSmartArtNode;
114114
+ exports.removeTableElementColumn = removeTableElementColumn;
114115
+ exports.removeTableElementRow = removeTableElementRow;
113028
114116
  exports.renameSection = renameSection;
113029
114117
  exports.reorderSmartArtNode = reorderSmartArtNode;
113030
114118
  exports.rerouteConnectorsForMovedElements = rerouteConnectorsForMovedElements;
@@ -113057,6 +114145,7 @@ exports.resolveViewerAddinRows = resolveViewerAddinRows;
113057
114145
  exports.restoreSegmentSelection = restoreSegmentSelection;
113058
114146
  exports.revealedSmartArtNodeCount = revealedSmartArtNodeCount;
113059
114147
  exports.rulerDragToGuidePosition = rulerDragToGuidePosition;
114148
+ exports.runMediaCommand = runMediaCommand;
113060
114149
  exports.safeOpenUrl = safeOpenUrl;
113061
114150
  exports.sanitizeColor = sanitizeColor;
113062
114151
  exports.sanitizeDownloadFilename = sanitizeDownloadFilename;
@@ -113084,8 +114173,11 @@ exports.setChartDataPointMarker = setChartDataPointMarker;
113084
114173
  exports.setChartSeriesChartType = setChartSeriesChartType;
113085
114174
  exports.setChartSeriesMarker = setChartSeriesMarker;
113086
114175
  exports.setDuotoneCachedResult = setDuotoneCachedResult;
114176
+ exports.setMotionPath = setMotionPath;
114177
+ exports.setMotionPathEnd = setMotionPathEnd;
113087
114178
  exports.setPendingSelectionRestore = setPendingSelectionRestore;
113088
114179
  exports.setSmartArtNodeStyle = setSmartArtNodeStyle;
114180
+ exports.setTableElementCellText = setTableElementCellText;
113089
114181
  exports.shadeColor2 = shadeColor2;
113090
114182
  exports.shouldAutoFollowBroadcaster = shouldAutoFollowBroadcaster;
113091
114183
  exports.shouldCommitSmartArtNodeText = shouldCommitSmartArtNodeText;