pptx-react-viewer 3.1.2 → 3.1.4

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 (154) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/{AiChatPanel-UCFQIWOQ.mjs → AiChatPanel-ITCVRVKP.mjs} +3 -3
  3. package/dist/AiChatPanel-ITCVRVKP.mjs.br +0 -0
  4. package/dist/AiChatPanel-ITCVRVKP.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-4EYZDQXM.js → AiChatPanel-TO5PHBGW.js} +23 -23
  6. package/dist/AiChatPanel-TO5PHBGW.js.br +0 -0
  7. package/dist/AiChatPanel-TO5PHBGW.js.gz +0 -0
  8. package/dist/{Area3DChartScene-YBMC6NKY.js → Area3DChartScene-2UNQ3J3V.js} +2 -2
  9. package/dist/Area3DChartScene-2UNQ3J3V.js.br +0 -0
  10. package/dist/Area3DChartScene-2UNQ3J3V.js.gz +0 -0
  11. package/dist/{Area3DChartScene-PMYXO4MR.mjs → Area3DChartScene-7PHPDOTG.mjs} +1 -1
  12. package/dist/Area3DChartScene-7PHPDOTG.mjs.br +0 -0
  13. package/dist/Area3DChartScene-7PHPDOTG.mjs.gz +0 -0
  14. package/dist/{Bar3DChartScene-CEOI6SU6.mjs → Bar3DChartScene-BLPUHYRZ.mjs} +1 -1
  15. package/dist/Bar3DChartScene-BLPUHYRZ.mjs.br +0 -0
  16. package/dist/Bar3DChartScene-BLPUHYRZ.mjs.gz +0 -0
  17. package/dist/{Bar3DChartScene-75DCA2ZA.js → Bar3DChartScene-MC5S3AGT.js} +2 -2
  18. package/dist/Bar3DChartScene-MC5S3AGT.js.br +0 -0
  19. package/dist/Bar3DChartScene-MC5S3AGT.js.gz +0 -0
  20. package/dist/{Line3DChartScene-STGX6N6V.js → Line3DChartScene-JVVZRIDD.js} +2 -2
  21. package/dist/Line3DChartScene-JVVZRIDD.js.br +0 -0
  22. package/dist/Line3DChartScene-JVVZRIDD.js.gz +0 -0
  23. package/dist/{Line3DChartScene-EZZKWUZR.mjs → Line3DChartScene-L5B4YFG3.mjs} +1 -1
  24. package/dist/Line3DChartScene-L5B4YFG3.mjs.br +0 -0
  25. package/dist/Line3DChartScene-L5B4YFG3.mjs.gz +0 -0
  26. package/dist/{Model3DScene-FGQJKWL6.mjs → Model3DScene-6TNWS5LV.mjs} +1 -1
  27. package/dist/Model3DScene-6TNWS5LV.mjs.br +0 -0
  28. package/dist/Model3DScene-6TNWS5LV.mjs.gz +0 -0
  29. package/dist/{Model3DScene-DWRD63FH.js → Model3DScene-LRDNQNKJ.js} +2 -2
  30. package/dist/Model3DScene-LRDNQNKJ.js.br +0 -0
  31. package/dist/Model3DScene-LRDNQNKJ.js.gz +0 -0
  32. package/dist/{PieChart3DScene-R3Y7OVVO.js → PieChart3DScene-PZWZCXHX.js} +2 -2
  33. package/dist/PieChart3DScene-PZWZCXHX.js.br +0 -0
  34. package/dist/PieChart3DScene-PZWZCXHX.js.gz +0 -0
  35. package/dist/{PieChart3DScene-DH6RSJO6.mjs → PieChart3DScene-XXAIVP4I.mjs} +1 -1
  36. package/dist/PieChart3DScene-XXAIVP4I.mjs.br +0 -0
  37. package/dist/PieChart3DScene-XXAIVP4I.mjs.gz +0 -0
  38. package/dist/{SurfaceChart3DScene-BMBU5RKI.mjs → SurfaceChart3DScene-CRUGJSCY.mjs} +1 -1
  39. package/dist/SurfaceChart3DScene-CRUGJSCY.mjs.br +1 -0
  40. package/dist/SurfaceChart3DScene-CRUGJSCY.mjs.gz +0 -0
  41. package/dist/{SurfaceChart3DScene-UM5HA3VO.js → SurfaceChart3DScene-UBQV3ZN2.js} +2 -2
  42. package/dist/SurfaceChart3DScene-UBQV3ZN2.js.br +0 -0
  43. package/dist/SurfaceChart3DScene-UBQV3ZN2.js.gz +0 -0
  44. package/dist/UTIF-LAD5QYGQ.mjs +6400 -0
  45. package/dist/UTIF-LAD5QYGQ.mjs.br +0 -0
  46. package/dist/UTIF-LAD5QYGQ.mjs.gz +0 -0
  47. package/dist/UTIF-POYWAAGO.js +6402 -0
  48. package/dist/UTIF-POYWAAGO.js.br +0 -0
  49. package/dist/UTIF-POYWAAGO.js.gz +0 -0
  50. package/dist/{chunk-VLLZ3QL2.mjs → chunk-57MGKBJ4.mjs} +284 -81
  51. package/dist/chunk-57MGKBJ4.mjs.br +0 -0
  52. package/dist/chunk-57MGKBJ4.mjs.gz +0 -0
  53. package/dist/{chunk-4VVOTEQ4.mjs → chunk-A2UAUSJM.mjs} +114 -8
  54. package/dist/chunk-A2UAUSJM.mjs.br +0 -0
  55. package/dist/chunk-A2UAUSJM.mjs.gz +0 -0
  56. package/dist/{chunk-W3J6SNVE.mjs → chunk-BPWSJLLG.mjs} +158 -29
  57. package/dist/chunk-BPWSJLLG.mjs.br +0 -0
  58. package/dist/chunk-BPWSJLLG.mjs.gz +0 -0
  59. package/dist/{chunk-YNUYFR2T.js → chunk-LGVNUG3G.js} +3 -3
  60. package/dist/chunk-LGVNUG3G.js.br +0 -0
  61. package/dist/chunk-LGVNUG3G.js.gz +0 -0
  62. package/dist/{chunk-WVIKFMNS.js → chunk-LXYDXLKZ.js} +511 -405
  63. package/dist/chunk-LXYDXLKZ.js.br +0 -0
  64. package/dist/chunk-LXYDXLKZ.js.gz +0 -0
  65. package/dist/{chunk-O5DKWJDK.mjs → chunk-QOLYY7E3.mjs} +1 -1
  66. package/dist/chunk-QOLYY7E3.mjs.br +0 -0
  67. package/dist/chunk-QOLYY7E3.mjs.gz +0 -0
  68. package/dist/{chunk-2HLDBQH7.js → chunk-T2QG2HD5.js} +302 -171
  69. package/dist/chunk-T2QG2HD5.js.br +0 -0
  70. package/dist/chunk-T2QG2HD5.js.gz +0 -0
  71. package/dist/{chunk-MQEG5GOV.js → chunk-T44LBKF6.js} +1373 -1170
  72. package/dist/chunk-T44LBKF6.js.br +0 -0
  73. package/dist/chunk-T44LBKF6.js.gz +0 -0
  74. package/dist/{chunk-S546O4W2.mjs → chunk-XIHK52SB.mjs} +1526 -342
  75. package/dist/chunk-XIHK52SB.mjs.br +0 -0
  76. package/dist/chunk-XIHK52SB.mjs.gz +0 -0
  77. package/dist/{chunk-7ZQ2FZXE.js → chunk-YDEEINER.js} +1529 -344
  78. package/dist/chunk-YDEEINER.js.br +0 -0
  79. package/dist/chunk-YDEEINER.js.gz +0 -0
  80. package/dist/index.d.ts +139 -3
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +49 -49
  83. package/dist/index.js.br +0 -0
  84. package/dist/index.js.gz +0 -0
  85. package/dist/index.mjs +5 -5
  86. package/dist/index.mjs.br +0 -0
  87. package/dist/index.mjs.gz +0 -0
  88. package/dist/internals.d.ts +139 -3
  89. package/dist/internals.d.ts.map +1 -1
  90. package/dist/internals.js +78 -78
  91. package/dist/internals.js.br +0 -0
  92. package/dist/internals.js.gz +0 -0
  93. package/dist/internals.mjs +3 -3
  94. package/dist/internals.mjs.br +0 -0
  95. package/dist/internals.mjs.gz +0 -0
  96. package/dist/pptx-viewer.css +1 -1
  97. package/dist/pptx-viewer.css.br +0 -0
  98. package/dist/pptx-viewer.css.gz +0 -0
  99. package/dist/viewer/index.d.ts +139 -3
  100. package/dist/viewer/index.js +26 -26
  101. package/dist/viewer/index.js.br +0 -0
  102. package/dist/viewer/index.js.gz +0 -0
  103. package/dist/viewer/index.mjs +5 -5
  104. package/dist/viewer/index.mjs.br +0 -0
  105. package/dist/viewer/index.mjs.gz +0 -0
  106. package/package.json +2 -2
  107. package/dist/AiChatPanel-4EYZDQXM.js.br +0 -0
  108. package/dist/AiChatPanel-4EYZDQXM.js.gz +0 -0
  109. package/dist/AiChatPanel-UCFQIWOQ.mjs.br +0 -0
  110. package/dist/AiChatPanel-UCFQIWOQ.mjs.gz +0 -0
  111. package/dist/Area3DChartScene-PMYXO4MR.mjs.br +0 -0
  112. package/dist/Area3DChartScene-PMYXO4MR.mjs.gz +0 -0
  113. package/dist/Area3DChartScene-YBMC6NKY.js.br +0 -0
  114. package/dist/Area3DChartScene-YBMC6NKY.js.gz +0 -0
  115. package/dist/Bar3DChartScene-75DCA2ZA.js.br +0 -0
  116. package/dist/Bar3DChartScene-75DCA2ZA.js.gz +0 -0
  117. package/dist/Bar3DChartScene-CEOI6SU6.mjs.br +0 -0
  118. package/dist/Bar3DChartScene-CEOI6SU6.mjs.gz +0 -0
  119. package/dist/Line3DChartScene-EZZKWUZR.mjs.br +0 -0
  120. package/dist/Line3DChartScene-EZZKWUZR.mjs.gz +0 -0
  121. package/dist/Line3DChartScene-STGX6N6V.js.br +0 -0
  122. package/dist/Line3DChartScene-STGX6N6V.js.gz +0 -0
  123. package/dist/Model3DScene-DWRD63FH.js.br +0 -0
  124. package/dist/Model3DScene-DWRD63FH.js.gz +0 -0
  125. package/dist/Model3DScene-FGQJKWL6.mjs.br +0 -0
  126. package/dist/Model3DScene-FGQJKWL6.mjs.gz +0 -0
  127. package/dist/PieChart3DScene-DH6RSJO6.mjs.br +0 -0
  128. package/dist/PieChart3DScene-DH6RSJO6.mjs.gz +0 -0
  129. package/dist/PieChart3DScene-R3Y7OVVO.js.br +0 -0
  130. package/dist/PieChart3DScene-R3Y7OVVO.js.gz +0 -0
  131. package/dist/SurfaceChart3DScene-BMBU5RKI.mjs.br +0 -0
  132. package/dist/SurfaceChart3DScene-BMBU5RKI.mjs.gz +0 -0
  133. package/dist/SurfaceChart3DScene-UM5HA3VO.js.br +0 -0
  134. package/dist/SurfaceChart3DScene-UM5HA3VO.js.gz +0 -0
  135. package/dist/chunk-2HLDBQH7.js.br +0 -0
  136. package/dist/chunk-2HLDBQH7.js.gz +0 -0
  137. package/dist/chunk-4VVOTEQ4.mjs.br +0 -0
  138. package/dist/chunk-4VVOTEQ4.mjs.gz +0 -0
  139. package/dist/chunk-7ZQ2FZXE.js.br +0 -0
  140. package/dist/chunk-7ZQ2FZXE.js.gz +0 -0
  141. package/dist/chunk-MQEG5GOV.js.br +0 -0
  142. package/dist/chunk-MQEG5GOV.js.gz +0 -0
  143. package/dist/chunk-O5DKWJDK.mjs.br +0 -0
  144. package/dist/chunk-O5DKWJDK.mjs.gz +0 -0
  145. package/dist/chunk-S546O4W2.mjs.br +0 -0
  146. package/dist/chunk-S546O4W2.mjs.gz +0 -0
  147. package/dist/chunk-VLLZ3QL2.mjs.br +0 -0
  148. package/dist/chunk-VLLZ3QL2.mjs.gz +0 -0
  149. package/dist/chunk-W3J6SNVE.mjs.br +0 -0
  150. package/dist/chunk-W3J6SNVE.mjs.gz +0 -0
  151. package/dist/chunk-WVIKFMNS.js.br +0 -0
  152. package/dist/chunk-WVIKFMNS.js.gz +0 -0
  153. package/dist/chunk-YNUYFR2T.js.br +0 -0
  154. package/dist/chunk-YNUYFR2T.js.gz +0 -0
@@ -7028,6 +7028,7 @@ var SLIDE_FIELD_KIND = {
7028
7028
  elements: "nested",
7029
7029
  backgroundColor: "scalar",
7030
7030
  backgroundImage: "scalar",
7031
+ backgroundImageProperties: "complex",
7031
7032
  backgroundGradient: "scalar",
7032
7033
  backgroundPattern: "complex",
7033
7034
  backgroundShadeToTitle: "scalar",
@@ -17836,6 +17837,31 @@ function parseDrawingHueDegrees(value) {
17836
17837
  }
17837
17838
  return parsed / 6e4;
17838
17839
  }
17840
+ var TEXT_ORIENTATION_IDENTITY = [1, 0, 0, 1];
17841
+ function isTextOrientationMatrix(value) {
17842
+ return Array.isArray(value) && value.length === 4 && value.every((entry2) => typeof entry2 === "number" && Number.isFinite(entry2));
17843
+ }
17844
+ function multiplyTextOrientationMatrices(left, right) {
17845
+ return [
17846
+ left[0] * right[0] + left[2] * right[1],
17847
+ left[1] * right[0] + left[3] * right[1],
17848
+ left[0] * right[2] + left[2] * right[3],
17849
+ left[1] * right[2] + left[3] * right[3]
17850
+ ];
17851
+ }
17852
+ function getElementOrientationMatrix(element) {
17853
+ const radians = (Number(element.rotation) || 0) * Math.PI / 180;
17854
+ const cosine = Math.cos(radians);
17855
+ const sine = Math.sin(radians);
17856
+ const rotation = [cosine, sine, -sine, cosine];
17857
+ const flip = [
17858
+ element.flipHorizontal ? -1 : 1,
17859
+ 0,
17860
+ 0,
17861
+ element.flipVertical ? -1 : 1
17862
+ ];
17863
+ return multiplyTextOrientationMatrices(rotation, flip);
17864
+ }
17839
17865
  function parseBoolean(value) {
17840
17866
  if (value === true || value === "1" || value === "true") {
17841
17867
  return true;
@@ -19667,6 +19693,21 @@ function serializePlaceholderLevelStyle(style, existing) {
19667
19693
  if (style.indent !== void 0) {
19668
19694
  attrEdits.indent = String(Math.round(style.indent * EMU_PER_PX));
19669
19695
  }
19696
+ if (style.defaultTabSize !== void 0) {
19697
+ attrEdits.defTabSz = String(Math.round(style.defaultTabSize * EMU_PER_PX));
19698
+ }
19699
+ if (style.eaLineBreak !== void 0) {
19700
+ attrEdits.eaLnBrk = style.eaLineBreak ? "1" : "0";
19701
+ }
19702
+ if (style.latinLineBreak !== void 0) {
19703
+ attrEdits.latinLnBrk = style.latinLineBreak ? "1" : "0";
19704
+ }
19705
+ if (style.fontAlignment !== void 0) {
19706
+ attrEdits.fontAlgn = style.fontAlignment;
19707
+ }
19708
+ if (style.hangingPunctuation !== void 0) {
19709
+ attrEdits.hangingPunct = style.hangingPunctuation ? "1" : "0";
19710
+ }
19670
19711
  const childEdits = /* @__PURE__ */ new Map();
19671
19712
  if (style.lineSpacing !== void 0) {
19672
19713
  childEdits.set("a:lnSpc", {
@@ -27003,7 +27044,7 @@ function parseRunFontElements(rPr) {
27003
27044
  const latin = rPr["a:latin"];
27004
27045
  const eastAsian = rPr["a:ea"];
27005
27046
  const complexScript = rPr["a:cs"];
27006
- const chosenTypeface = latin?.["@_typeface"] || eastAsian?.["@_typeface"] || complexScript?.["@_typeface"];
27047
+ const chosenTypeface = latin?.["@_typeface"];
27007
27048
  if (typeof chosenTypeface === "string" && chosenTypeface.trim().length > 0) {
27008
27049
  result.fontFamily = chosenTypeface.trim();
27009
27050
  }
@@ -35381,6 +35422,13 @@ var FONT_SUBSTITUTION_MAP = {
35381
35422
  NSimSun: ["Noto Serif CJK SC", "STSong", "serif"],
35382
35423
  FangSong: ["Noto Serif CJK SC", "STFangsong", "serif"],
35383
35424
  KaiTi: ["Noto Serif CJK SC", "STKaiti", "serif"],
35425
+ DengXian: ["Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", "sans-serif"],
35426
+ \u7B49\u7EBF: ["DengXian", "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", "sans-serif"],
35427
+ \u5B8B\u4F53: ["SimSun", "Songti SC", "STSong", "Noto Serif CJK SC", "serif"],
35428
+ \u65B0\u5B8B\u4F53: ["NSimSun", "Songti SC", "STSong", "Noto Serif CJK SC", "serif"],
35429
+ \u9ED1\u4F53: ["SimHei", "Heiti SC", "STHeiti", "PingFang SC", "Noto Sans CJK SC", "sans-serif"],
35430
+ \u4EFF\u5B8B: ["FangSong", "STFangsong", "Songti SC", "Noto Serif CJK SC", "serif"],
35431
+ \u6977\u4F53: ["KaiTi", "Kaiti SC", "STKaiti", "Noto Serif CJK SC", "serif"],
35384
35432
  Batang: ["Noto Serif CJK KR", "AppleMyungjo", "serif"],
35385
35433
  Dotum: ["Noto Sans CJK KR", "AppleGothic", "sans-serif"],
35386
35434
  Gulim: ["Noto Sans CJK KR", "AppleGothic", "sans-serif"],
@@ -43102,7 +43150,12 @@ function parseTimeTargetElement(tgtEl) {
43102
43150
  const rawXml = tgtEl;
43103
43151
  const shape = tgtEl["p:spTgt"];
43104
43152
  if (shape?.["@_spid"] !== void 0) {
43105
- return { type: "shape", shapeId: String(shape["@_spid"]), rawXml };
43153
+ return {
43154
+ type: "shape",
43155
+ shapeId: String(shape["@_spid"]),
43156
+ ...shape["p:bg"] !== void 0 ? { backgroundOnly: true } : {},
43157
+ rawXml
43158
+ };
43106
43159
  }
43107
43160
  if (tgtEl["p:sldTgt"] !== void 0) {
43108
43161
  return { type: "slide", rawXml };
@@ -43269,7 +43322,11 @@ function extractColorAnimation(childTnList) {
43269
43322
  if (animClrNodes.length === 0) {
43270
43323
  return void 0;
43271
43324
  }
43272
- const node = animClrNodes[0];
43325
+ const components = animClrNodes.map(extractSingleColorAnimation);
43326
+ const primary = components[0];
43327
+ return components.length > 1 ? { ...primary, components } : primary;
43328
+ }
43329
+ function extractSingleColorAnimation(node) {
43273
43330
  const clrSpc = String(node["@_clrSpc"] || "rgb").toLowerCase();
43274
43331
  const colorSpace = clrSpc === "hsl" ? "hsl" : "rgb";
43275
43332
  const dir = String(node["@_dir"] || "").toLowerCase();
@@ -43277,7 +43334,9 @@ function extractColorAnimation(childTnList) {
43277
43334
  const path = node["@_path"] !== void 0 ? String(node["@_path"]) : void 0;
43278
43335
  const fromColor = extractColorValue(node["p:from"]);
43279
43336
  const toColor = extractColorValue(node["p:to"]);
43280
- const byColor = extractHslDeltaOrColorValue(node["p:by"], colorSpace);
43337
+ const byContainer = node["p:by"];
43338
+ const byColor = extractHslDeltaOrColorValue(byContainer, colorSpace);
43339
+ const hslDelta = colorSpace === "hsl" ? extractHslDelta(byContainer) : void 0;
43281
43340
  const targetAttribute = extractAttrNameFromCBhvr(node["p:cBhvr"]);
43282
43341
  return {
43283
43342
  colorSpace,
@@ -43286,9 +43345,21 @@ function extractColorAnimation(childTnList) {
43286
43345
  fromColor,
43287
43346
  toColor,
43288
43347
  byColor,
43348
+ hslDelta,
43289
43349
  targetAttribute
43290
43350
  };
43291
43351
  }
43352
+ function extractHslDelta(colorContainer) {
43353
+ const hsl = colorContainer?.["p:hsl"];
43354
+ if (!hsl) {
43355
+ return void 0;
43356
+ }
43357
+ return {
43358
+ hue: Number(hsl["@_h"] ?? 0) / 6e4,
43359
+ saturation: Number(hsl["@_s"] ?? 0) / 1e3,
43360
+ lightness: Number(hsl["@_l"] ?? 0) / 1e3
43361
+ };
43362
+ }
43292
43363
  function extractHslDeltaOrColorValue(colorContainer, colorSpace) {
43293
43364
  if (!colorContainer) {
43294
43365
  return void 0;
@@ -43611,6 +43682,9 @@ function extractChildMotionValues(childTnList) {
43611
43682
  const motionPathRotateAuto = void 0;
43612
43683
  let motionPathEditMode;
43613
43684
  let motionPtsTypes;
43685
+ let motionPathRotationAngle;
43686
+ let motionPathRotationCenterX;
43687
+ let motionPathRotationCenterY;
43614
43688
  let rotationBy;
43615
43689
  let rotationFrom;
43616
43690
  let rotationTo;
@@ -43628,6 +43702,9 @@ function extractChildMotionValues(childTnList) {
43628
43702
  motionPathRotateAuto,
43629
43703
  motionPathEditMode,
43630
43704
  motionPtsTypes,
43705
+ motionPathRotationAngle,
43706
+ motionPathRotationCenterX,
43707
+ motionPathRotationCenterY,
43631
43708
  rotationBy,
43632
43709
  rotationFrom,
43633
43710
  rotationTo,
@@ -43651,6 +43728,25 @@ function extractChildMotionValues(childTnList) {
43651
43728
  if (motionNode["@_ptsTypes"] !== void 0) {
43652
43729
  motionPtsTypes = String(motionNode["@_ptsTypes"]);
43653
43730
  }
43731
+ if (motionNode["@_rAng"] !== void 0) {
43732
+ const parsed = Number.parseInt(String(motionNode["@_rAng"]), 10);
43733
+ if (Number.isFinite(parsed)) {
43734
+ motionPathRotationAngle = parsed / 6e4;
43735
+ }
43736
+ }
43737
+ const rotationCenter = motionNode["p:rCtr"];
43738
+ if (rotationCenter?.["@_x"] !== void 0) {
43739
+ const parsed = Number.parseInt(String(rotationCenter["@_x"]), 10);
43740
+ if (Number.isFinite(parsed)) {
43741
+ motionPathRotationCenterX = parsed / 1e3;
43742
+ }
43743
+ }
43744
+ if (rotationCenter?.["@_y"] !== void 0) {
43745
+ const parsed = Number.parseInt(String(rotationCenter["@_y"]), 10);
43746
+ if (Number.isFinite(parsed)) {
43747
+ motionPathRotationCenterY = parsed / 1e3;
43748
+ }
43749
+ }
43654
43750
  }
43655
43751
  }
43656
43752
  const rotationNodes = ensureArray8(childTnList["p:animRot"]);
@@ -43705,6 +43801,9 @@ function extractChildMotionValues(childTnList) {
43705
43801
  motionPathRotateAuto,
43706
43802
  motionPathEditMode,
43707
43803
  motionPtsTypes,
43804
+ motionPathRotationAngle,
43805
+ motionPathRotationCenterX,
43806
+ motionPathRotationCenterY,
43708
43807
  rotationBy,
43709
43808
  rotationFrom,
43710
43809
  rotationTo,
@@ -44495,6 +44594,7 @@ var PptxSlideLoaderService = class {
44495
44594
  const ownBackgroundColor = params.extractBackgroundColor(slideXmlObj);
44496
44595
  const ownBackgroundGradient = params.extractBackgroundGradient(slideXmlObj);
44497
44596
  let ownBackgroundImage;
44597
+ let backgroundImageProperties;
44498
44598
  const [
44499
44599
  backgroundColor,
44500
44600
  backgroundGradient,
@@ -44509,7 +44609,12 @@ var PptxSlideLoaderService = class {
44509
44609
  (async () => {
44510
44610
  const own = await params.extractBackgroundImage(slideXmlObj, path);
44511
44611
  ownBackgroundImage = own;
44512
- return own || params.getLayoutBackgroundImage(path);
44612
+ if (own) {
44613
+ backgroundImageProperties = params.extractBackgroundImageProperties(slideXmlObj);
44614
+ return own;
44615
+ }
44616
+ backgroundImageProperties = await params.getLayoutBackgroundImageProperties(path);
44617
+ return params.getLayoutBackgroundImage(path);
44513
44618
  })(),
44514
44619
  params.extractSlideNotes(path),
44515
44620
  params.extractSlideComments(path),
@@ -44577,6 +44682,7 @@ var PptxSlideLoaderService = class {
44577
44682
  backgroundColor,
44578
44683
  backgroundGradient: backgroundGradient || void 0,
44579
44684
  backgroundImage,
44685
+ backgroundImageProperties,
44580
44686
  transition,
44581
44687
  animations,
44582
44688
  animationTimelineAnchors,
@@ -45178,7 +45284,7 @@ var TIME_NODE_EVENTS = /* @__PURE__ */ new Set(["onBegin", "onEnd", "begin", "en
45178
45284
  function createGroupContext() {
45179
45285
  return { parCounter: { next: 0 } };
45180
45286
  }
45181
- function conditionsStartAutomatically(cTn) {
45287
+ function conditionsStartAutomatically(cTn, mainSequence) {
45182
45288
  if (!cTn) {
45183
45289
  return true;
45184
45290
  }
@@ -45194,6 +45300,14 @@ function conditionsStartAutomatically(cTn) {
45194
45300
  const event = condition["@_evt"] === void 0 ? void 0 : String(condition["@_evt"]);
45195
45301
  const hasTimeNode = condition["p:tn"] !== void 0 || condition["@_tn"] !== void 0;
45196
45302
  if (event !== void 0 && TIME_NODE_EVENTS.has(event) && hasTimeNode) {
45303
+ const timeNode = condition["p:tn"];
45304
+ const targetTimeNodeId = timeNode?.["@_val"] ?? condition["@_tn"];
45305
+ if (mainSequence !== void 0 && targetTimeNodeId !== void 0 && String(targetTimeNodeId) === mainSequence.id) {
45306
+ if (mainSequence.autoStart) {
45307
+ return true;
45308
+ }
45309
+ continue;
45310
+ }
45197
45311
  return true;
45198
45312
  }
45199
45313
  if (event !== void 0) {
@@ -45212,11 +45326,33 @@ function isMainSequence(cTn) {
45212
45326
  function isEffectNode(cTn) {
45213
45327
  return cTn !== void 0 && cTn["@_presetClass"] !== void 0;
45214
45328
  }
45329
+ function extractWrapperStartDelayMs(cTn) {
45330
+ if (!cTn) {
45331
+ return void 0;
45332
+ }
45333
+ const directDelay = readTimingAttr(cTn["@_delay"]);
45334
+ if (directDelay !== void 0 && directDelay >= 0) {
45335
+ return directDelay;
45336
+ }
45337
+ const stCondLst = cTn["p:stCondLst"];
45338
+ if (!stCondLst) {
45339
+ return void 0;
45340
+ }
45341
+ let smallest;
45342
+ for (const condition of ensureArray8(stCondLst["p:cond"])) {
45343
+ const delay = readTimingAttr(condition["@_delay"]);
45344
+ if (delay !== void 0 && delay >= 0 && (smallest === void 0 || delay < smallest)) {
45345
+ smallest = delay;
45346
+ }
45347
+ }
45348
+ return smallest;
45349
+ }
45215
45350
  function childGroupContext(parent, cTn, options) {
45216
45351
  if (options.isClickLevelGroup) {
45217
45352
  return {
45218
- groupAutoStart: conditionsStartAutomatically(cTn),
45353
+ groupAutoStart: conditionsStartAutomatically(cTn, options.mainSequence),
45219
45354
  parGroupIndex: parent.parGroupIndex,
45355
+ parGroupDelayMs: parent.parGroupDelayMs,
45220
45356
  parCounter: parent.parCounter,
45221
45357
  // The innermost enclosing `p:seq`'s attrs are unrelated to click-level
45222
45358
  // grouping; carry them through rather than dropping them here.
@@ -45228,15 +45364,74 @@ function childGroupContext(parent, cTn, options) {
45228
45364
  if (isEffectNode(cTn)) {
45229
45365
  return parent;
45230
45366
  }
45367
+ const localDelayMs = extractWrapperStartDelayMs(cTn);
45231
45368
  return {
45232
45369
  groupAutoStart: parent.groupAutoStart,
45233
45370
  parGroupIndex: parent.parCounter.next++,
45371
+ parGroupDelayMs: localDelayMs === void 0 ? parent.parGroupDelayMs : (parent.parGroupDelayMs ?? 0) + localDelayMs,
45234
45372
  parCounter: parent.parCounter,
45235
45373
  seqConcurrent: parent.seqConcurrent,
45236
45374
  seqNextAction: parent.seqNextAction,
45237
45375
  seqPrevAction: parent.seqPrevAction
45238
45376
  };
45239
45377
  }
45378
+ function extractAttributeAnimations(childTnList) {
45379
+ if (!childTnList) {
45380
+ return void 0;
45381
+ }
45382
+ const components = [];
45383
+ for (const node of ensureArray8(childTnList["p:anim"])) {
45384
+ const attrName = extractAttrNameFromCBhvr(node["p:cBhvr"]);
45385
+ const keyframes = extractKeyframes(node);
45386
+ if (!attrName || !keyframes || keyframes.length === 0) {
45387
+ continue;
45388
+ }
45389
+ const behavior = node["p:cBhvr"];
45390
+ const cTn = behavior?.["p:cTn"];
45391
+ components.push({
45392
+ attrName,
45393
+ keyframes,
45394
+ durationMs: readTimingAttr(cTn?.["@_dur"]),
45395
+ delayMs: cTn ? extractStartConditionDelayMs(cTn) : void 0
45396
+ });
45397
+ }
45398
+ return components.length > 0 ? components : void 0;
45399
+ }
45400
+ var PRIMARY_BEHAVIOUR_FAMILIES = [
45401
+ ["p:animMotion", "p:animRot", "p:animScale"],
45402
+ ["p:animClr"],
45403
+ ["p:animEffect"],
45404
+ ["p:anim"]
45405
+ ];
45406
+ function isEnabled(value) {
45407
+ return value === true || value === 1 || value === "1" || value === "true";
45408
+ }
45409
+ function extractChildAutoReverseTiming(cTn, toArray5) {
45410
+ const childTnLst = cTn["p:childTnLst"];
45411
+ if (!childTnLst) {
45412
+ return void 0;
45413
+ }
45414
+ for (const family of PRIMARY_BEHAVIOUR_FAMILIES) {
45415
+ const behaviours = family.flatMap((tag) => toArray5(childTnLst[tag]));
45416
+ if (behaviours.length === 0) {
45417
+ continue;
45418
+ }
45419
+ const timings = behaviours.map((behaviour) => {
45420
+ const common = behaviour["p:cBhvr"];
45421
+ const inner = common?.["p:cTn"];
45422
+ return {
45423
+ autoReverse: isEnabled(inner?.["@_autoRev"]),
45424
+ durationMs: readTimingAttr(inner?.["@_dur"])
45425
+ };
45426
+ });
45427
+ const durationMs = timings[0]?.durationMs;
45428
+ if (durationMs !== void 0 && timings.every((timing) => timing.autoReverse && timing.durationMs === durationMs)) {
45429
+ return { autoReverse: true, durationMs };
45430
+ }
45431
+ return void 0;
45432
+ }
45433
+ return void 0;
45434
+ }
45240
45435
  var defaultLookup = new PptxXmlLookupService();
45241
45436
  function resolveSlideTimingNode(slideRoot) {
45242
45437
  const direct = slideRoot?.["p:timing"];
@@ -45427,7 +45622,8 @@ var PptxNativeAnimationService = class {
45427
45622
  const presetClass = cTn["@_presetClass"];
45428
45623
  const presetId = cTn["@_presetID"] ? Number.parseInt(String(cTn["@_presetID"]), 10) : void 0;
45429
45624
  const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
45430
- const durationMs = readTimingAttr(cTn["@_dur"]) ?? extractChildBehaviourDurationMs(cTn, ensureArray8);
45625
+ const childAutoReverseTiming = extractChildAutoReverseTiming(cTn, ensureArray8);
45626
+ const durationMs = readTimingAttr(cTn["@_dur"]) ?? childAutoReverseTiming?.durationMs ?? extractChildBehaviourDurationMs(cTn, ensureArray8);
45431
45627
  const delayMs = readTimingAttr(cTn["@_delay"]) ?? extractStartConditionDelayMs(cTn);
45432
45628
  const accel = parseTimingPercentFraction(cTn["@_accel"]);
45433
45629
  const decel = parseTimingPercentFraction(cTn["@_decel"]);
@@ -45475,6 +45671,7 @@ var PptxNativeAnimationService = class {
45475
45671
  const textTarget = this.extractTextTargetFromCTn(cTn);
45476
45672
  const keyframes = extractChildKeyframes(childTnList2);
45477
45673
  const keyframeAttrName = extractChildKeyframeAttrName(childTnList2);
45674
+ const attributeAnimations = extractAttributeAnimations(childTnList2);
45478
45675
  const roundTripAttrs = captureRoundTripCTnAttrs(cTn);
45479
45676
  const afterEffectFlag = extractAfterEffect(cTn);
45480
45677
  const timingAttrs = extractCTnTimingAttrs(cTn);
@@ -45502,6 +45699,9 @@ var PptxNativeAnimationService = class {
45502
45699
  motionPathRotateAuto: childMotion.motionPathRotateAuto,
45503
45700
  motionPathEditMode: childMotion.motionPathEditMode,
45504
45701
  motionPtsTypes: childMotion.motionPtsTypes,
45702
+ motionPathRotationAngle: childMotion.motionPathRotationAngle,
45703
+ motionPathRotationCenterX: childMotion.motionPathRotationCenterX,
45704
+ motionPathRotationCenterY: childMotion.motionPathRotationCenterY,
45505
45705
  rotationBy: childMotion.rotationBy,
45506
45706
  rotationFrom: childMotion.rotationFrom,
45507
45707
  rotationTo: childMotion.rotationTo,
@@ -45514,8 +45714,9 @@ var PptxNativeAnimationService = class {
45514
45714
  scaleZoomContents: childMotion.scaleZoomContents,
45515
45715
  keyframes: keyframes ?? void 0,
45516
45716
  attrName: keyframeAttrName,
45717
+ attributeAnimations,
45517
45718
  repeatCount: repeatInfo.repeatCount,
45518
- autoReverse: repeatInfo.autoReverse,
45719
+ autoReverse: repeatInfo.autoReverse ?? childAutoReverseTiming?.autoReverse,
45519
45720
  soundRId: soundInfo.soundRId,
45520
45721
  stopSound: soundInfo.stopSound,
45521
45722
  startConditions: startConditions ?? void 0,
@@ -45530,6 +45731,7 @@ var PptxNativeAnimationService = class {
45530
45731
  afterEffect: afterEffectFlag,
45531
45732
  groupAutoStart: group2.groupAutoStart,
45532
45733
  parGroupIndex: group2.parGroupIndex,
45734
+ parGroupDelayMs: group2.parGroupDelayMs,
45533
45735
  effectFilter
45534
45736
  });
45535
45737
  }
@@ -45540,12 +45742,17 @@ var PptxNativeAnimationService = class {
45540
45742
  const sequences = ensureArray8(childTnList["p:seq"]);
45541
45743
  const exclusives = ensureArray8(childTnList["p:excl"]);
45542
45744
  for (const parallel of parallels) {
45745
+ const mainSequenceId = cTn["@_id"];
45543
45746
  this.walkTimingTree(
45544
45747
  parallel,
45545
45748
  animations,
45546
45749
  trigger,
45547
45750
  childGroupContext(group2, parallel["p:cTn"], {
45548
- isClickLevelGroup: isClickLevel
45751
+ isClickLevelGroup: isClickLevel,
45752
+ mainSequence: isClickLevel && mainSequenceId !== void 0 ? {
45753
+ autoStart: group2.seqConcurrent === true && group2.seqNextAction === "seek",
45754
+ id: String(mainSequenceId)
45755
+ } : void 0
45549
45756
  })
45550
45757
  );
45551
45758
  }
@@ -45736,6 +45943,9 @@ var PptxNativeAnimationService = class {
45736
45943
  if (!triggerShapeId) {
45737
45944
  continue;
45738
45945
  }
45946
+ const endSync = seqCTn?.["p:endSync"];
45947
+ const runtimeTrigger = endSync?.["p:rtn"];
45948
+ const restartable = String(runtimeTrigger?.["@_val"] ?? "") === "all";
45739
45949
  const interactiveAnims = [];
45740
45950
  const seqAttrs = extractSeqAttrs(seq);
45741
45951
  this.walkTimingTree(seq, interactiveAnims, "onShapeClick", {
@@ -45744,7 +45954,11 @@ var PptxNativeAnimationService = class {
45744
45954
  });
45745
45955
  for (const anim of interactiveAnims) {
45746
45956
  anim.triggerShapeId = triggerShapeId;
45747
- anim.trigger = "onShapeClick";
45957
+ anim.interactiveSequence = true;
45958
+ anim.interactiveRestart = restartable;
45959
+ if (anim.trigger === "onClick") {
45960
+ anim.trigger = "onShapeClick";
45961
+ }
45748
45962
  animations.push(anim);
45749
45963
  }
45750
45964
  }
@@ -47224,6 +47438,15 @@ function buildMotionPathNode(anim, allocateId) {
47224
47438
  }
47225
47439
  }
47226
47440
  };
47441
+ if (anim.motionPathRotationAngle !== void 0) {
47442
+ motionNode["@_rAng"] = String(Math.round(anim.motionPathRotationAngle * 6e4));
47443
+ }
47444
+ if (anim.motionPathRotationCenterX !== void 0 || anim.motionPathRotationCenterY !== void 0) {
47445
+ motionNode["p:rCtr"] = {
47446
+ "@_x": String(Math.round((anim.motionPathRotationCenterX ?? 0) * 1e3)),
47447
+ "@_y": String(Math.round((anim.motionPathRotationCenterY ?? 0) * 1e3))
47448
+ };
47449
+ }
47227
47450
  const effectCTn = {
47228
47451
  "@_id": String(effectId),
47229
47452
  "@_presetID": "0",
@@ -47395,6 +47618,8 @@ function wrapInInteractiveSequence(effectNodes, triggerShapeId, allocateId) {
47395
47618
  }
47396
47619
  function buildMainSequenceNode(mainSeqId, children11) {
47397
47620
  const node = {
47621
+ "@_concurrent": "1",
47622
+ "@_nextAc": "seek",
47398
47623
  "p:cTn": {
47399
47624
  "@_id": String(mainSeqId),
47400
47625
  "@_dur": "indefinite",
@@ -51006,10 +51231,6 @@ function scaleElementSubtree(el, scaleX, scaleY) {
51006
51231
  el.y *= scaleY;
51007
51232
  el.width *= scaleX;
51008
51233
  el.height *= scaleY;
51009
- const avgScale = (Math.abs(scaleX) + Math.abs(scaleY)) / 2;
51010
- if (hasShapeProperties(el) && el.shapeStyle?.strokeWidth) {
51011
- el.shapeStyle.strokeWidth *= avgScale;
51012
- }
51013
51234
  if (el.type === "group") {
51014
51235
  for (const nested of el.children) {
51015
51236
  scaleElementSubtree(nested, scaleX, scaleY);
@@ -51023,10 +51244,6 @@ function transformGroupChild(el, t) {
51023
51244
  el.y = t.parentY + relativeY * t.scaleY;
51024
51245
  el.width *= t.scaleX;
51025
51246
  el.height *= t.scaleY;
51026
- const avgScale = (Math.abs(t.scaleX) + Math.abs(t.scaleY)) / 2;
51027
- if (hasShapeProperties(el) && el.shapeStyle?.strokeWidth) {
51028
- el.shapeStyle.strokeWidth *= avgScale;
51029
- }
51030
51247
  if (el.type === "group") {
51031
51248
  for (const nested of el.children) {
51032
51249
  scaleElementSubtree(nested, t.scaleX, t.scaleY);
@@ -56433,6 +56650,32 @@ function parseMasterColorMap(node) {
56433
56650
  }
56434
56651
  return Object.keys(result).length > 0 ? result : void 0;
56435
56652
  }
56653
+ var HEX_COLOR = /^#?[0-9a-f]{6}$/iu;
56654
+ function resolveToken2(value, resolveThemeColor) {
56655
+ if (!value || HEX_COLOR.test(value)) {
56656
+ return value;
56657
+ }
56658
+ return resolveThemeColor(value) ?? value;
56659
+ }
56660
+ function resolveColorAnimation(animation, resolveThemeColor) {
56661
+ return {
56662
+ ...animation,
56663
+ fromColor: resolveToken2(animation.fromColor, resolveThemeColor),
56664
+ toColor: resolveToken2(animation.toColor, resolveThemeColor),
56665
+ byColor: resolveToken2(animation.byColor, resolveThemeColor),
56666
+ components: animation.components?.map(
56667
+ (component) => resolveColorAnimation(component, resolveThemeColor)
56668
+ )
56669
+ };
56670
+ }
56671
+ function resolveNativeAnimationThemeColors(animations, resolveThemeColor) {
56672
+ return animations.map(
56673
+ (animation) => animation.colorAnimation ? {
56674
+ ...animation,
56675
+ colorAnimation: resolveColorAnimation(animation.colorAnimation, resolveThemeColor)
56676
+ } : animation
56677
+ );
56678
+ }
56436
56679
  function getXmlShapeIdFromXml(rawXml) {
56437
56680
  if (!rawXml) {
56438
56681
  return void 0;
@@ -59422,7 +59665,42 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
59422
59665
  }
59423
59666
  };
59424
59667
  var CAN_USE_BLOB_URLS = typeof globalThis.URL?.createObjectURL === "function" && typeof globalThis.Blob !== "undefined";
59668
+ async function decodeTiffToPngBlob(bytes) {
59669
+ if (typeof document === "undefined") {
59670
+ return void 0;
59671
+ }
59672
+ const imported = await import('./UTIF-POYWAAGO.js');
59673
+ const decoder = "default" in imported ? imported.default : imported;
59674
+ const page = decoder.decode(bytes)[0];
59675
+ if (!page) {
59676
+ return void 0;
59677
+ }
59678
+ decoder.decodeImage(bytes, page);
59679
+ const width = Number(page.width);
59680
+ const height = Number(page.height);
59681
+ if (!Number.isFinite(width) || width <= 0 || !Number.isFinite(height) || height <= 0) {
59682
+ return void 0;
59683
+ }
59684
+ const rgba = new Uint8ClampedArray(decoder.toRGBA8(page));
59685
+ const canvas = document.createElement("canvas");
59686
+ canvas.width = width;
59687
+ canvas.height = height;
59688
+ const context = canvas.getContext("2d");
59689
+ if (!context) {
59690
+ return void 0;
59691
+ }
59692
+ const imageData = context.createImageData(width, height);
59693
+ imageData.data.set(rgba);
59694
+ context.putImageData(imageData, 0, 0);
59695
+ return await new Promise((resolve2) => {
59696
+ canvas.toBlob((blob) => resolve2(blob ?? void 0), "image/png");
59697
+ });
59698
+ }
59425
59699
  var PptxHandlerRuntime7 = class extends PptxHandlerRuntime6 {
59700
+ /** Forward declaration implemented later in the runtime inheritance chain. */
59701
+ resolveThemeColor(_schemeKey) {
59702
+ return void 0;
59703
+ }
59426
59704
  /**
59427
59705
  * Convert raw image bytes to a URL suitable for <img src>.
59428
59706
  * Uses Blob URLs in browsers (avoids 33% base64 overhead),
@@ -59489,6 +59767,18 @@ var PptxHandlerRuntime7 = class extends PptxHandlerRuntime6 {
59489
59767
  }
59490
59768
  return void 0;
59491
59769
  }
59770
+ if (ext === "tif" || ext === "tiff") {
59771
+ const binaryBuffer = await imageFile.async("arraybuffer");
59772
+ const pngBlob = await decodeTiffToPngBlob(binaryBuffer);
59773
+ if (pngBlob) {
59774
+ const converted = this.createImageUrl(await pngBlob.arrayBuffer(), "image/png");
59775
+ this.imageDataCache.set(imagePath, converted);
59776
+ return converted;
59777
+ }
59778
+ const imageData2 = this.createImageUrl(binaryBuffer, this.getImageMimeType(imagePath));
59779
+ this.imageDataCache.set(imagePath, imageData2);
59780
+ return imageData2;
59781
+ }
59492
59782
  const imageBytes = await imageFile.async("arraybuffer");
59493
59783
  const imageData = this.createImageUrl(imageBytes, this.getImageMimeType(imagePath));
59494
59784
  this.imageDataCache.set(imagePath, imageData);
@@ -59587,10 +59877,14 @@ var PptxHandlerRuntime7 = class extends PptxHandlerRuntime6 {
59587
59877
  * anything.
59588
59878
  */
59589
59879
  parseNativeAnimations(slideXml3, slidePath) {
59590
- const animations = this.nativeAnimationService.parseNativeAnimations(slideXml3);
59591
- if (!animations) {
59880
+ const parsedAnimations = this.nativeAnimationService.parseNativeAnimations(slideXml3);
59881
+ if (!parsedAnimations) {
59592
59882
  return void 0;
59593
59883
  }
59884
+ const animations = resolveNativeAnimationThemeColors(
59885
+ parsedAnimations,
59886
+ (token2) => this.resolveThemeColor(token2)
59887
+ );
59594
59888
  for (const anim of animations) {
59595
59889
  if (anim.soundRId) {
59596
59890
  anim.soundPath = this.resolveRelationshipTarget(slidePath, anim.soundRId);
@@ -63092,7 +63386,7 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime5 extends PptxHandlerRuntime
63092
63386
  const latinTypefaceToken = xmlAttr(latin, "typeface");
63093
63387
  const eaTypefaceToken = xmlAttr(eastAsian, "typeface");
63094
63388
  const csTypefaceToken = xmlAttr(complexScript, "typeface");
63095
- const chosenTypeface = latinTypefaceToken || eaTypefaceToken || csTypefaceToken;
63389
+ const chosenTypeface = latinTypefaceToken;
63096
63390
  const resolvedTypeface = this.resolveThemeTypeface(chosenTypeface);
63097
63391
  if (resolvedTypeface) {
63098
63392
  style.fontFamily = resolvedTypeface;
@@ -73989,6 +74283,7 @@ var PptxHandlerRuntime57 = class _PptxHandlerRuntime24 extends PptxHandlerRuntim
73989
74283
  const rEmbed = xmlAttr(blip, "r:embed");
73990
74284
  const rLink = xmlAttr(blip, "r:link");
73991
74285
  const crop = this.readImageCropFromBlipFill(blipFill);
74286
+ const imageEffects = this.extractImageEffects(blip);
73992
74287
  const tileNode = blipFill?.["a:tile"];
73993
74288
  const tileProps = {};
73994
74289
  if (tileNode) {
@@ -74048,6 +74343,7 @@ var PptxHandlerRuntime57 = class _PptxHandlerRuntime24 extends PptxHandlerRuntim
74048
74343
  }
74049
74344
  const styleNode = shape["p:style"] || inheritedPlaceholder?.shape?.["p:style"] || inheritedPlaceholder?.picture?.["p:style"];
74050
74345
  const sifCNvPr = xmlPath(shape, "p:nvSpPr", "p:cNvPr");
74346
+ const sifElementName = xmlAttr(sifCNvPr, "name")?.trim() || void 0;
74051
74347
  const sifSlideRels = this.slideRelsMap.get(slidePath);
74052
74348
  const { actionClick: sifActionClick, actionHover: sifActionHover } = this.parseElementActions(
74053
74349
  sifCNvPr,
@@ -74063,6 +74359,7 @@ var PptxHandlerRuntime57 = class _PptxHandlerRuntime24 extends PptxHandlerRuntim
74063
74359
  height,
74064
74360
  imageData,
74065
74361
  imagePath,
74362
+ imageEffects: imageEffects || void 0,
74066
74363
  ...crop,
74067
74364
  ...tileProps,
74068
74365
  shapeType,
@@ -74078,6 +74375,7 @@ var PptxHandlerRuntime57 = class _PptxHandlerRuntime24 extends PptxHandlerRuntim
74078
74375
  flipHorizontal,
74079
74376
  flipVertical,
74080
74377
  rawXml: shape,
74378
+ name: sifElementName,
74081
74379
  actionClick: sifActionClick,
74082
74380
  actionHover: sifActionHover
74083
74381
  };
@@ -74280,6 +74578,21 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
74280
74578
  if (textStyle.align === void 0 && levelStyle.alignment !== void 0) {
74281
74579
  textStyle.align = levelStyle.alignment;
74282
74580
  }
74581
+ if (textStyle.defaultTabSize === void 0 && levelStyle.defaultTabSize !== void 0) {
74582
+ textStyle.defaultTabSize = levelStyle.defaultTabSize;
74583
+ }
74584
+ if (textStyle.eaLineBreak === void 0 && levelStyle.eaLineBreak !== void 0) {
74585
+ textStyle.eaLineBreak = levelStyle.eaLineBreak;
74586
+ }
74587
+ if (textStyle.latinLineBreak === void 0 && levelStyle.latinLineBreak !== void 0) {
74588
+ textStyle.latinLineBreak = levelStyle.latinLineBreak;
74589
+ }
74590
+ if (textStyle.fontAlignment === void 0 && levelStyle.fontAlignment !== void 0) {
74591
+ textStyle.fontAlignment = levelStyle.fontAlignment;
74592
+ }
74593
+ if (textStyle.hangingPunctuation === void 0 && levelStyle.hangingPunctuation !== void 0) {
74594
+ textStyle.hangingPunctuation = levelStyle.hangingPunctuation;
74595
+ }
74283
74596
  }
74284
74597
  };
74285
74598
  var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
@@ -74930,17 +75243,10 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime26 extends PptxHandlerRuntim
74930
75243
  ctx.slideRelationshipMap,
74931
75244
  false
74932
75245
  );
74933
- const endParagraphStyle = this.extractTextRunStyle(
74934
- p?.["a:endParaRPr"],
74935
- paraAlign,
74936
- ctx.slideRelationshipMap,
74937
- false
74938
- );
74939
75246
  const mergedDefaultRunStyle = {
74940
75247
  ...ctx.bodyDefaultRunStyle,
74941
75248
  ...inheritedLevelStyle,
74942
75249
  ...bodyLevelStyle,
74943
- ...endParagraphStyle,
74944
75250
  ...defaultRunStyle
74945
75251
  };
74946
75252
  if (mergedDefaultRunStyle.color === void 0 && ctx.styleFontRefColor !== void 0) {
@@ -75805,6 +76111,7 @@ var PptxHandlerRuntime64 = class _PptxHandlerRuntime28 extends PptxHandlerRuntim
75805
76111
  isLinked: mediaReference.isLinked,
75806
76112
  posterFramePath,
75807
76113
  posterFrameData,
76114
+ ...this.readImageCropFromBlipFill(posterBlipFill),
75808
76115
  // Real PowerPoint media is `p:pic`-shaped even though the
75809
76116
  // `media` type buckets as `p:graphicFrame`, so its locks live
75810
76117
  // in `a:picLocks`. The writer resolves the same container from
@@ -76508,6 +76815,23 @@ var PptxHandlerRuntime66 = class _PptxHandlerRuntime30 extends PptxHandlerRuntim
76508
76815
  el.height = parseEmuInt(ext["@_cy"]) / _PptxHandlerRuntime30.EMU_PER_PX;
76509
76816
  }
76510
76817
  }
76818
+ applyAncestorGroupTextTransform(children11, groupTransform) {
76819
+ for (const child252 of children11) {
76820
+ if (child252.type === "group") {
76821
+ this.applyAncestorGroupTextTransform(child252.children, groupTransform);
76822
+ continue;
76823
+ }
76824
+ if (!hasTextProperties(child252)) {
76825
+ continue;
76826
+ }
76827
+ const existing = child252.textStyle?.ancestorGroupTransform;
76828
+ const nestedTransform = isTextOrientationMatrix(existing) ? existing : TEXT_ORIENTATION_IDENTITY;
76829
+ child252.textStyle = {
76830
+ ...child252.textStyle,
76831
+ ancestorGroupTransform: multiplyTextOrientationMatrices(groupTransform, nestedTransform)
76832
+ };
76833
+ }
76834
+ }
76511
76835
  /**
76512
76836
  * Push a group fill down to every descendant whose own fill is `a:grpFill`
76513
76837
  * ("inherit from my group").
@@ -76636,6 +76960,16 @@ var PptxHandlerRuntime66 = class _PptxHandlerRuntime30 extends PptxHandlerRuntim
76636
76960
  if (hasGroupFill && grpFillStyle.fillMode !== "group") {
76637
76961
  this.applyGroupFillInheritance(children11, grpFillStyle);
76638
76962
  }
76963
+ if (raw.rotation || raw.flipHorizontal || raw.flipVertical) {
76964
+ this.applyAncestorGroupTextTransform(
76965
+ children11,
76966
+ getElementOrientationMatrix({
76967
+ rotation: raw.rotation,
76968
+ flipHorizontal: raw.flipHorizontal,
76969
+ flipVertical: raw.flipVertical
76970
+ })
76971
+ );
76972
+ }
76639
76973
  for (const child252 of children11) {
76640
76974
  child252.x -= parentX;
76641
76975
  child252.y -= parentY;
@@ -76931,6 +77265,52 @@ var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
76931
77265
  }
76932
77266
  };
76933
77267
  var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
77268
+ /**
77269
+ * Preserve the visual properties authored on a background `a:blipFill`.
77270
+ *
77271
+ * The decoded image URL alone is not enough to reproduce PowerPoint: crop,
77272
+ * stretch/tile placement and blip effects such as `a:alphaModFix` live next
77273
+ * to the relationship id and otherwise disappear during slide assembly.
77274
+ */
77275
+ extractBackgroundImageProperties(slideXml3, rootElement = "p:sld") {
77276
+ try {
77277
+ const blipFill = xmlPath(slideXml3, rootElement, "p:cSld", "p:bg", "p:bgPr", "a:blipFill");
77278
+ const blip = xmlChild(blipFill, "a:blip");
77279
+ if (!blipFill || !blip) {
77280
+ return void 0;
77281
+ }
77282
+ const properties = {
77283
+ ...this.readImageCropFromBlipFill(blipFill)
77284
+ };
77285
+ const imageEffects = this.extractImageEffects(blip);
77286
+ if (imageEffects) {
77287
+ properties.imageEffects = imageEffects;
77288
+ }
77289
+ const tileNode = xmlChild(blipFill, "a:tile");
77290
+ if (tileNode) {
77291
+ const txRaw = Number.parseInt(String(tileNode["@_tx"] ?? ""), 10);
77292
+ const tyRaw = Number.parseInt(String(tileNode["@_ty"] ?? ""), 10);
77293
+ const sxRaw = Number.parseInt(String(tileNode["@_sx"] ?? ""), 10);
77294
+ const syRaw = Number.parseInt(String(tileNode["@_sy"] ?? ""), 10);
77295
+ properties.tileOffsetX = Number.isFinite(txRaw) ? txRaw / 9525 : 0;
77296
+ properties.tileOffsetY = Number.isFinite(tyRaw) ? tyRaw / 9525 : 0;
77297
+ properties.tileScaleX = Number.isFinite(sxRaw) ? sxRaw / 1e5 : 1;
77298
+ properties.tileScaleY = Number.isFinite(syRaw) ? syRaw / 1e5 : 1;
77299
+ const flip = String(tileNode["@_flip"] ?? "none").trim();
77300
+ if (flip === "x" || flip === "y" || flip === "xy" || flip === "none") {
77301
+ properties.tileFlip = flip;
77302
+ }
77303
+ const alignment = String(tileNode["@_algn"] ?? "tl").trim();
77304
+ if (alignment.length > 0) {
77305
+ properties.tileAlignment = alignment;
77306
+ }
77307
+ }
77308
+ return Object.keys(properties).length > 0 ? properties : void 0;
77309
+ } catch (error) {
77310
+ console.warn("Failed to extract background image properties:", error);
77311
+ return void 0;
77312
+ }
77313
+ }
76934
77314
  async extractBackgroundImage(slideXml3, slidePath, rootElement = "p:sld") {
76935
77315
  try {
76936
77316
  const blip = xmlPath(
@@ -77199,6 +77579,26 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
77199
77579
  }
77200
77580
  return void 0;
77201
77581
  }
77582
+ async getMasterBackgroundImageProperties(layoutPath) {
77583
+ const layoutRels = this.slideRelsMap.get(layoutPath);
77584
+ if (!layoutRels) {
77585
+ return void 0;
77586
+ }
77587
+ for (const [, target] of layoutRels.entries()) {
77588
+ if (!target.includes("slideMaster")) {
77589
+ continue;
77590
+ }
77591
+ const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
77592
+ const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
77593
+ try {
77594
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
77595
+ return masterXmlObj ? this.extractBackgroundImageProperties(masterXmlObj, "p:sldMaster") : void 0;
77596
+ } catch {
77597
+ return void 0;
77598
+ }
77599
+ }
77600
+ return void 0;
77601
+ }
77202
77602
  async getLayoutBackgroundImage(slidePath) {
77203
77603
  const slideRels = this.slideRelsMap.get(slidePath);
77204
77604
  if (!slideRels) {
@@ -77213,7 +77613,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
77213
77613
  if (layoutXmlObj) {
77214
77614
  const layoutRelsPath = partRelsPath(layoutPath);
77215
77615
  await this.loadSlideRelationships(layoutPath, layoutRelsPath);
77216
- const bg = this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
77616
+ const bg = await this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
77217
77617
  if (bg) {
77218
77618
  return bg;
77219
77619
  }
@@ -77226,6 +77626,36 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
77226
77626
  }
77227
77627
  return void 0;
77228
77628
  }
77629
+ async getLayoutBackgroundImageProperties(slidePath) {
77630
+ const slideRels = this.slideRelsMap.get(slidePath);
77631
+ if (!slideRels) {
77632
+ return void 0;
77633
+ }
77634
+ for (const [, target] of slideRels.entries()) {
77635
+ if (!target.includes("slideLayout")) {
77636
+ continue;
77637
+ }
77638
+ const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
77639
+ const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
77640
+ try {
77641
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
77642
+ if (!layoutXmlObj) {
77643
+ return void 0;
77644
+ }
77645
+ const layoutRelsPath = partRelsPath(layoutPath);
77646
+ await this.loadSlideRelationships(layoutPath, layoutRelsPath);
77647
+ const layoutImage = await this.extractBackgroundImage(
77648
+ layoutXmlObj,
77649
+ layoutPath,
77650
+ "p:sldLayout"
77651
+ );
77652
+ return layoutImage ? this.extractBackgroundImageProperties(layoutXmlObj, "p:sldLayout") : this.getMasterBackgroundImageProperties(layoutPath);
77653
+ } catch {
77654
+ return void 0;
77655
+ }
77656
+ }
77657
+ return void 0;
77658
+ }
77229
77659
  async getLayoutBackgroundColor(slidePath) {
77230
77660
  const slideRels = this.slideRelsMap.get(slidePath);
77231
77661
  if (!slideRels) {
@@ -77651,6 +78081,29 @@ var PptxHandlerRuntime71 = class _PptxHandlerRuntime31 extends PptxHandlerRuntim
77651
78081
  style.indent = indent / _PptxHandlerRuntime31.EMU_PER_PX;
77652
78082
  }
77653
78083
  }
78084
+ const defaultTabSizeRaw = levelProps["@_defTabSz"];
78085
+ if (defaultTabSizeRaw !== void 0) {
78086
+ const defaultTabSize = Number.parseInt(String(defaultTabSizeRaw), 10);
78087
+ if (Number.isFinite(defaultTabSize)) {
78088
+ style.defaultTabSize = defaultTabSize / _PptxHandlerRuntime31.EMU_PER_PX;
78089
+ }
78090
+ }
78091
+ const eaLineBreak = this.parseOptionalBooleanAttr(levelProps["@_eaLnBrk"]);
78092
+ if (eaLineBreak !== void 0) {
78093
+ style.eaLineBreak = eaLineBreak;
78094
+ }
78095
+ const latinLineBreak = this.parseOptionalBooleanAttr(levelProps["@_latinLnBrk"]);
78096
+ if (latinLineBreak !== void 0) {
78097
+ style.latinLineBreak = latinLineBreak;
78098
+ }
78099
+ const fontAlignment = String(levelProps["@_fontAlgn"] ?? "").trim();
78100
+ if (fontAlignment.length > 0) {
78101
+ style.fontAlignment = fontAlignment;
78102
+ }
78103
+ const hangingPunctuation = this.parseOptionalBooleanAttr(levelProps["@_hangingPunct"]);
78104
+ if (hangingPunctuation !== void 0) {
78105
+ style.hangingPunctuation = hangingPunctuation;
78106
+ }
77654
78107
  const lnSpc = levelProps["a:lnSpc"];
77655
78108
  if (lnSpc) {
77656
78109
  const multiplier = this.parseLineSpacingMultiplier(lnSpc);
@@ -78226,6 +78679,7 @@ var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
78226
78679
  await this.loadSlideRelationships(partPath, `${partDirectory}/_rels/${fileName}.rels`);
78227
78680
  }
78228
78681
  part.backgroundImage = await this.extractBackgroundImage(data, partPath, rootTag2);
78682
+ part.backgroundImageProperties = this.extractBackgroundImageProperties(data, rootTag2);
78229
78683
  this.unwrapAlternateContent(spTree);
78230
78684
  const previousClrMapOverride = this.currentSlideClrMapOverride;
78231
78685
  if (rootTag2 === "p:sldLayout") {
@@ -79250,6 +79704,7 @@ var PptxHandlerRuntime79 = class extends PptxHandlerRuntime78 {
79250
79704
  * scheme fill style list.
79251
79705
  *
79252
79706
  * Per the OOXML spec:
79707
+ * - idx 0 or 1000 → no fill
79253
79708
  * - idx 1-3 → fillStyleLst[idx-1]
79254
79709
  * - idx 1001-1003 → bgFillStyleLst[idx-1001]
79255
79710
  *
@@ -79266,6 +79721,12 @@ var PptxHandlerRuntime79 = class extends PptxHandlerRuntime78 {
79266
79721
  if (overrideColorXml) {
79267
79722
  style.fillRefColorXml = overrideColorXml;
79268
79723
  }
79724
+ if (idx === 0 || idx === 1e3) {
79725
+ style.fillMode = "none";
79726
+ style.fillColor = "transparent";
79727
+ style.fillOpacity = 0;
79728
+ return;
79729
+ }
79269
79730
  if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme) {
79270
79731
  style.fillMode = "theme";
79271
79732
  style.fillColor = this.parseColor(refNode);
@@ -80407,33 +80868,109 @@ function extractDrawingShapeFill(spPr, deps) {
80407
80868
  }
80408
80869
  return result;
80409
80870
  }
80410
- function extractDrawingShapeTextStyle(txBody, deps) {
80871
+ function drawingTextEmuAttribute(node, name, emuPerPx) {
80872
+ if (!node || node[`@_${name}`] === void 0) {
80873
+ return void 0;
80874
+ }
80875
+ const value = Number.parseInt(String(node[`@_${name}`]), 10);
80876
+ return Number.isFinite(value) ? value / emuPerPx : void 0;
80877
+ }
80878
+ function drawingTextBoolean(value) {
80879
+ return value === true || value === 1 || value === "1" || value === "true";
80880
+ }
80881
+ function extractDrawingShapeTextStyle(txBody, deps, emuPerPx) {
80411
80882
  let fontSize;
80412
80883
  let fontColor;
80884
+ let fontFamily;
80885
+ let fontWeight;
80886
+ let fontStyle;
80887
+ let lineHeight;
80888
+ let lineHeightRatio;
80889
+ let lineSpacingAfter;
80890
+ let lineSpacingAfterRatio;
80413
80891
  if (!txBody) {
80414
80892
  return { fontSize, fontColor };
80415
80893
  }
80894
+ const bodyPr = deps.getChild(txBody, "bodyPr");
80416
80895
  const paragraphs = deps.getChildren(txBody, "p");
80417
80896
  for (const p of paragraphs) {
80897
+ const pPr = deps.getChild(p, "pPr");
80898
+ const lineSpacing = deps.getChild(pPr, "lnSpc");
80899
+ const lineSpacingPercent = deps.getChild(lineSpacing, "spcPct");
80900
+ const lineSpacingPoints = deps.getChild(lineSpacing, "spcPts");
80901
+ const spacingAfter = deps.getChild(pPr, "spcAft");
80902
+ const spacingAfterPercent = deps.getChild(spacingAfter, "spcPct");
80903
+ const spacingAfterPoints = deps.getChild(spacingAfter, "spcPts");
80904
+ if (lineHeightRatio === void 0 && lineSpacingPercent?.["@_val"] !== void 0) {
80905
+ const raw = Number.parseInt(String(lineSpacingPercent["@_val"]), 10);
80906
+ if (Number.isFinite(raw) && raw > 0) {
80907
+ lineHeightRatio = raw / 1e5;
80908
+ }
80909
+ }
80910
+ if (lineHeight === void 0 && lineSpacingPoints?.["@_val"] !== void 0) {
80911
+ const raw = Number.parseInt(String(lineSpacingPoints["@_val"]), 10);
80912
+ if (Number.isFinite(raw) && raw > 0) {
80913
+ lineHeight = raw / 100 * (96 / 72);
80914
+ }
80915
+ }
80916
+ if (lineSpacingAfterRatio === void 0 && spacingAfterPercent?.["@_val"] !== void 0) {
80917
+ const raw = Number.parseInt(String(spacingAfterPercent["@_val"]), 10);
80918
+ if (Number.isFinite(raw) && raw >= 0) {
80919
+ lineSpacingAfterRatio = raw / 1e5;
80920
+ }
80921
+ }
80922
+ if (lineSpacingAfter === void 0 && spacingAfterPoints?.["@_val"] !== void 0) {
80923
+ const raw = Number.parseInt(String(spacingAfterPoints["@_val"]), 10);
80924
+ if (Number.isFinite(raw) && raw >= 0) {
80925
+ lineSpacingAfter = raw / 100 * (96 / 72);
80926
+ }
80927
+ }
80418
80928
  const runs = deps.getChildren(p, "r");
80419
80929
  for (const r of runs) {
80420
80930
  const rPr = deps.getChild(r, "rPr");
80421
- if (rPr && !fontSize) {
80931
+ if (rPr) {
80422
80932
  const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
80423
- if (Number.isFinite(szRaw) && szRaw > 0) {
80424
- fontSize = szRaw / 100;
80933
+ if (fontSize === void 0 && Number.isFinite(szRaw) && szRaw > 0) {
80934
+ fontSize = szRaw / 100 * (96 / 72);
80935
+ }
80936
+ fontColor ??= deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
80937
+ const eastAsian = deps.getChild(rPr, "ea");
80938
+ const latin = deps.getChild(rPr, "latin");
80939
+ const complexScript = deps.getChild(rPr, "cs");
80940
+ fontFamily ??= String(
80941
+ eastAsian?.["@_typeface"] || latin?.["@_typeface"] || complexScript?.["@_typeface"] || ""
80942
+ ).trim() || void 0;
80943
+ if (fontWeight === void 0 && rPr["@_b"] !== void 0) {
80944
+ fontWeight = drawingTextBoolean(rPr["@_b"]) ? 700 : 400;
80945
+ }
80946
+ if (fontStyle === void 0 && rPr["@_i"] !== void 0) {
80947
+ fontStyle = drawingTextBoolean(rPr["@_i"]) ? "italic" : "normal";
80425
80948
  }
80426
- fontColor = deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
80427
80949
  }
80428
- if (fontSize) {
80950
+ if (fontSize !== void 0 && fontFamily !== void 0 && fontColor !== void 0) {
80429
80951
  break;
80430
80952
  }
80431
80953
  }
80432
- if (fontSize) {
80954
+ if (fontSize !== void 0 && fontFamily !== void 0 && fontColor !== void 0) {
80433
80955
  break;
80434
80956
  }
80435
80957
  }
80436
- return { fontSize, fontColor };
80958
+ return {
80959
+ fontSize,
80960
+ fontColor,
80961
+ fontFamily,
80962
+ fontWeight,
80963
+ fontStyle,
80964
+ lineHeight,
80965
+ lineHeightRatio,
80966
+ lineSpacingAfter,
80967
+ lineSpacingAfterRatio,
80968
+ textInsetLeft: drawingTextEmuAttribute(bodyPr, "lIns", emuPerPx),
80969
+ textInsetTop: drawingTextEmuAttribute(bodyPr, "tIns", emuPerPx),
80970
+ textInsetRight: drawingTextEmuAttribute(bodyPr, "rIns", emuPerPx),
80971
+ textInsetBottom: drawingTextEmuAttribute(bodyPr, "bIns", emuPerPx),
80972
+ textVerticalAnchor: String(bodyPr?.["@_anchor"] || "").trim() || void 0
80973
+ };
80437
80974
  }
80438
80975
  function resolveSmartArtTextStyles(paragraphs, resolve2) {
80439
80976
  for (const paragraph of paragraphs ?? []) {
@@ -80573,10 +81110,13 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
80573
81110
  const width = Math.round(parseInt(String(ext["@_cx"] || "0"), 10) / emuPerPx);
80574
81111
  const height = Math.round(parseInt(String(ext["@_cy"] || "0"), 10) / emuPerPx);
80575
81112
  const rotation = xfrm?.["@_rot"] ? parseInt(String(xfrm["@_rot"]), 10) / 6e4 : void 0;
81113
+ const flipHorizontal = ["1", "true"].includes(String(xfrm?.["@_flipH"] ?? "").toLowerCase());
81114
+ const flipVertical = ["1", "true"].includes(String(xfrm?.["@_flipV"] ?? "").toLowerCase());
80576
81115
  const skewX = xfrm?.["@_skewX"] ? parseInt(String(xfrm["@_skewX"]), 10) / 6e4 : void 0;
80577
81116
  const skewY = xfrm?.["@_skewY"] ? parseInt(String(xfrm["@_skewY"]), 10) / 6e4 : void 0;
80578
81117
  const prstGeom = this.xmlLookupService.getChildByLocalName(spPr, "prstGeom");
80579
81118
  const custGeom = this.xmlLookupService.getChildByLocalName(spPr, "custGeom");
81119
+ const shapeAdjustments = prstGeom ? this.parseGeometryAdjustments(prstGeom) : void 0;
80580
81120
  let shapeType = prstGeom ? String(prstGeom["@_prst"] || "rect") : "rect";
80581
81121
  let customGeometry = {};
80582
81122
  if (custGeom) {
@@ -80614,10 +81154,15 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
80614
81154
  this.collectLocalTextValues(txBody, "t", textValues2);
80615
81155
  }
80616
81156
  const text2 = textValues2.join("").trim() || void 0;
80617
- const { fontSize, fontColor } = extractDrawingShapeTextStyle(
80618
- txBody,
80619
- this.drawingShapeStyleDeps()
80620
- );
81157
+ const textStyle = extractDrawingShapeTextStyle(txBody, this.drawingShapeStyleDeps(), emuPerPx);
81158
+ const { fontSize, fontColor } = textStyle;
81159
+ const txXfrm = this.xmlLookupService.getChildByLocalName(sp, "txXfrm");
81160
+ const txOff = this.xmlLookupService.getChildByLocalName(txXfrm, "off");
81161
+ const txExt = this.xmlLookupService.getChildByLocalName(txXfrm, "ext");
81162
+ const textFrameX = drawingTextEmuAttribute(txOff, "x", emuPerPx);
81163
+ const textFrameY = drawingTextEmuAttribute(txOff, "y", emuPerPx);
81164
+ const textFrameWidth = drawingTextEmuAttribute(txExt, "cx", emuPerPx);
81165
+ const textFrameHeight = drawingTextEmuAttribute(txExt, "cy", emuPerPx);
80621
81166
  const paragraphs = txBody ? resolveSmartArtTextStyles(
80622
81167
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
80623
81168
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -80641,16 +81186,22 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime35 extends PptxHandlerRuntim
80641
81186
  width,
80642
81187
  height,
80643
81188
  rotation,
81189
+ flipHorizontal,
81190
+ flipVertical,
80644
81191
  skewX,
80645
81192
  skewY,
81193
+ shapeAdjustments,
80646
81194
  ...fill,
80647
81195
  fillColor: fill.fillColor ?? void 0,
80648
81196
  strokeColor: strokeColor ?? void 0,
80649
81197
  strokeWidth,
80650
81198
  text: structuredText,
80651
81199
  textSegments,
80652
- fontSize,
80653
- fontColor,
81200
+ ...textStyle,
81201
+ textFrameX,
81202
+ textFrameY,
81203
+ textFrameWidth,
81204
+ textFrameHeight,
80654
81205
  ...customGeometry
80655
81206
  };
80656
81207
  }
@@ -82947,7 +83498,9 @@ var PptxHandlerRuntime93 = class _PptxHandlerRuntime37 extends PptxHandlerRuntim
82947
83498
  extractBackgroundGradient: (slideXml3) => this.extractBackgroundGradient(slideXml3),
82948
83499
  getLayoutBackgroundGradient: (slidePath) => this.getLayoutBackgroundGradient(slidePath),
82949
83500
  extractBackgroundImage: (slideXml3, slidePath) => this.extractBackgroundImage(slideXml3, slidePath),
83501
+ extractBackgroundImageProperties: (slideXml3, rootElement) => this.extractBackgroundImageProperties(slideXml3, rootElement),
82950
83502
  getLayoutBackgroundImage: (slidePath) => this.getLayoutBackgroundImage(slidePath),
83503
+ getLayoutBackgroundImageProperties: (slidePath) => this.getLayoutBackgroundImageProperties(slidePath),
82951
83504
  rememberSlideBackgroundOrigin: (slidePath, origin) => rememberSlideBackgroundOrigin(this, slidePath, origin),
82952
83505
  extractSlideNotes: (slidePath) => this.extractSlideNotes(slidePath),
82953
83506
  extractSlideComments: (slidePath) => this.extractSlideComments(slidePath),
@@ -99587,8 +100140,8 @@ function buildCustomGeometryClipPath(pathData, pathWidth, pathHeight, elemWidth,
99587
100140
  return `path('${out.join(" ")}')`;
99588
100141
  }
99589
100142
  function getResolvedShapeClipPath(element, width, height) {
99590
- const w = typeof width === "number" ? width : element.width;
99591
- const h = typeof height === "number" ? height : element.height;
100143
+ const w = element.width;
100144
+ const h = element.height;
99592
100145
  const custom = element;
99593
100146
  if (custom.pathData && custom.pathWidth && custom.pathHeight) {
99594
100147
  const customClip = buildCustomGeometryClipPath(
@@ -100506,6 +101059,33 @@ function resolveComputedFill(ss, element) {
100506
101059
  }
100507
101060
  return {};
100508
101061
  }
101062
+ function isTextOrientationMatrix2(value) {
101063
+ return Array.isArray(value) && value.length === 4 && value.every((entry2) => typeof entry2 === "number" && Number.isFinite(entry2));
101064
+ }
101065
+ function multiplyTextOrientationMatrices2(left, right) {
101066
+ return [
101067
+ left[0] * right[0] + left[2] * right[1],
101068
+ left[1] * right[0] + left[3] * right[1],
101069
+ left[0] * right[2] + left[2] * right[3],
101070
+ left[1] * right[2] + left[3] * right[3]
101071
+ ];
101072
+ }
101073
+ function getElementOrientationMatrix2(element) {
101074
+ const radians = (Number(element.rotation) || 0) * Math.PI / 180;
101075
+ const cosine = Math.cos(radians);
101076
+ const sine = Math.sin(radians);
101077
+ const rotation = [cosine, sine, -sine, cosine];
101078
+ const flip = [
101079
+ element.flipHorizontal ? -1 : 1,
101080
+ 0,
101081
+ 0,
101082
+ element.flipVertical ? -1 : 1
101083
+ ];
101084
+ return multiplyTextOrientationMatrices2(rotation, flip);
101085
+ }
101086
+ function textOrientationAngleScore(matrix) {
101087
+ return Math.abs(Math.atan2(matrix[1], matrix[0]));
101088
+ }
100509
101089
  function normalizeStrokeDashType(value) {
100510
101090
  const normalized = String(value || "").trim().toLowerCase();
100511
101091
  if (!normalized) {
@@ -100607,12 +101187,37 @@ function getElementTransformWithoutRotation(element) {
100607
101187
  }
100608
101188
  function getTextCompensationTransform(element) {
100609
101189
  const transforms = [];
100610
- if (element.flipHorizontal) {
101190
+ const normalizedRotation = ((Number(element.rotation) || 0) % 360 + 360) % 360;
101191
+ const swapFlipAxis = normalizedRotation > 90 && normalizedRotation < 270 && element.flipHorizontal !== element.flipVertical;
101192
+ const compensateHorizontal = swapFlipAxis ? element.flipVertical : element.flipHorizontal;
101193
+ const compensateVertical = swapFlipAxis ? element.flipHorizontal : element.flipVertical;
101194
+ if (compensateHorizontal) {
100611
101195
  transforms.push("scaleX(-1)");
100612
101196
  }
100613
- if (element.flipVertical) {
101197
+ if (compensateVertical) {
100614
101198
  transforms.push("scaleY(-1)");
100615
101199
  }
101200
+ const ancestorGroupTransform = "textStyle" in element ? element.textStyle?.ancestorGroupTransform : void 0;
101201
+ if (isTextOrientationMatrix2(ancestorGroupTransform)) {
101202
+ const localCompensation = [
101203
+ compensateHorizontal ? -1 : 1,
101204
+ 0,
101205
+ 0,
101206
+ compensateVertical ? -1 : 1
101207
+ ];
101208
+ const visibleTransform = multiplyTextOrientationMatrices2(
101209
+ multiplyTextOrientationMatrices2(ancestorGroupTransform, getElementOrientationMatrix2(element)),
101210
+ localCompensation
101211
+ );
101212
+ const determinant = visibleTransform[0] * visibleTransform[3] - visibleTransform[1] * visibleTransform[2];
101213
+ if (determinant < -1e-6) {
101214
+ const horizontalCandidate = multiplyTextOrientationMatrices2(visibleTransform, [-1, 0, 0, 1]);
101215
+ const verticalCandidate = multiplyTextOrientationMatrices2(visibleTransform, [1, 0, 0, -1]);
101216
+ transforms.push(
101217
+ textOrientationAngleScore(horizontalCandidate) <= textOrientationAngleScore(verticalCandidate) ? "scaleX(-1)" : "scaleY(-1)"
101218
+ );
101219
+ }
101220
+ }
100616
101221
  return transforms.length > 0 ? transforms.join(" ") : void 0;
100617
101222
  }
100618
101223
  function parseDrawingPercent2(value) {
@@ -100806,6 +101411,7 @@ function getOuterShadowCss(style, context) {
100806
101411
  if (!style?.shadowColor || style.shadowColor === "transparent") {
100807
101412
  return void 0;
100808
101413
  }
101414
+ const usesOoxmlDefaults = style.outerShadowXml !== void 0;
100809
101415
  let offsetX;
100810
101416
  let offsetY;
100811
101417
  if (typeof style.shadowAngle === "number" && typeof style.shadowDistance === "number") {
@@ -100814,11 +101420,12 @@ function getOuterShadowCss(style, context) {
100814
101420
  offsetX = Math.cos(angleRad) * style.shadowDistance;
100815
101421
  offsetY = Math.sin(angleRad) * style.shadowDistance;
100816
101422
  } else {
100817
- offsetX = typeof style.shadowOffsetX === "number" && Number.isFinite(style.shadowOffsetX) ? style.shadowOffsetX : 4;
100818
- offsetY = typeof style.shadowOffsetY === "number" && Number.isFinite(style.shadowOffsetY) ? style.shadowOffsetY : 4;
101423
+ offsetX = typeof style.shadowOffsetX === "number" && Number.isFinite(style.shadowOffsetX) ? style.shadowOffsetX : usesOoxmlDefaults ? 0 : 4;
101424
+ offsetY = typeof style.shadowOffsetY === "number" && Number.isFinite(style.shadowOffsetY) ? style.shadowOffsetY : usesOoxmlDefaults ? 0 : 4;
100819
101425
  }
100820
- const blur = typeof style.shadowBlur === "number" && Number.isFinite(style.shadowBlur) ? Math.max(0, style.shadowBlur) : 6;
100821
- const opacity2 = typeof style.shadowOpacity === "number" && Number.isFinite(style.shadowOpacity) ? clampUnitInterval22(style.shadowOpacity) : 0.35;
101426
+ const rawBlur = typeof style.shadowBlur === "number" && Number.isFinite(style.shadowBlur) ? Math.max(0, style.shadowBlur) : usesOoxmlDefaults ? 0 : 6;
101427
+ const blur = usesOoxmlDefaults ? rawBlur / 2 : rawBlur;
101428
+ const opacity2 = typeof style.shadowOpacity === "number" && Number.isFinite(style.shadowOpacity) ? clampUnitInterval22(style.shadowOpacity) : usesOoxmlDefaults ? 1 : 0.35;
100822
101429
  const spread = getShadowScaleSpread(style.shadowScaleX, style.shadowScaleY, blur);
100823
101430
  const color2 = colorWithOpacity2(
100824
101431
  normalizeHexColor2(style.shadowColor, DEFAULT_SHADOW_COLOR),
@@ -100827,6 +101434,48 @@ function getOuterShadowCss(style, context) {
100827
101434
  const geometry = `${Math.round(offsetX)}px ${Math.round(offsetY)}px ${Math.round(blur)}px`;
100828
101435
  return spread === 0 ? `${geometry} ${color2}` : `${geometry} ${spread}px ${color2}`;
100829
101436
  }
101437
+ function getCompositeOuterShadowFilterCss(style, context) {
101438
+ if (!style) {
101439
+ return void 0;
101440
+ }
101441
+ const usesOoxmlDefaults = style.outerShadowXml !== void 0;
101442
+ const shadows = style.shadows && style.shadows.length > 0 ? style.shadows : style.shadowColor && style.shadowColor !== "transparent" ? [
101443
+ {
101444
+ angle: style.shadowAngle,
101445
+ distance: style.shadowDistance,
101446
+ offsetX: style.shadowOffsetX,
101447
+ offsetY: style.shadowOffsetY,
101448
+ blur: style.shadowBlur,
101449
+ color: style.shadowColor,
101450
+ opacity: style.shadowOpacity
101451
+ }
101452
+ ] : [];
101453
+ const parts = [];
101454
+ for (const shadow of shadows) {
101455
+ if (!shadow.color || shadow.color === "transparent") {
101456
+ continue;
101457
+ }
101458
+ let offsetX;
101459
+ let offsetY;
101460
+ if (typeof shadow.angle === "number" && typeof shadow.distance === "number") {
101461
+ const angle = style.shadowRotateWithShape === false && typeof context?.rotation === "number" ? shadow.angle - context.rotation : shadow.angle;
101462
+ const angleRad = angle * Math.PI / 180;
101463
+ offsetX = Math.cos(angleRad) * shadow.distance;
101464
+ offsetY = Math.sin(angleRad) * shadow.distance;
101465
+ } else {
101466
+ offsetX = typeof shadow.offsetX === "number" && Number.isFinite(shadow.offsetX) ? shadow.offsetX : usesOoxmlDefaults ? 0 : 4;
101467
+ offsetY = typeof shadow.offsetY === "number" && Number.isFinite(shadow.offsetY) ? shadow.offsetY : usesOoxmlDefaults ? 0 : 4;
101468
+ }
101469
+ const rawBlur = typeof shadow.blur === "number" && Number.isFinite(shadow.blur) ? Math.max(0, shadow.blur) : usesOoxmlDefaults ? 0 : 6;
101470
+ const blur = usesOoxmlDefaults ? rawBlur / 2 : rawBlur;
101471
+ const opacity2 = typeof shadow.opacity === "number" && Number.isFinite(shadow.opacity) ? clampUnitInterval22(shadow.opacity) : usesOoxmlDefaults ? 1 : 0.35;
101472
+ const color2 = colorWithOpacity2(normalizeHexColor2(shadow.color, DEFAULT_SHADOW_COLOR), opacity2);
101473
+ parts.push(
101474
+ `drop-shadow(${Math.round(offsetX)}px ${Math.round(offsetY)}px ${Math.round(blur)}px ${color2})`
101475
+ );
101476
+ }
101477
+ return parts.length > 0 ? parts.join(" ") : void 0;
101478
+ }
100830
101479
  function getShadowScaleSpread(scaleX, scaleY, blur) {
100831
101480
  const sx = typeof scaleX === "number" && Number.isFinite(scaleX) ? scaleX / 1e5 : 1;
100832
101481
  const sy = typeof scaleY === "number" && Number.isFinite(scaleY) ? scaleY / 1e5 : 1;
@@ -100995,7 +101644,7 @@ function getEffectFilterCss(style, elementId) {
100995
101644
  const parts = [];
100996
101645
  if (style.glowColor && style.glowColor !== "transparent" && style.glowRadius) {
100997
101646
  const glowOpacity = typeof style.glowOpacity === "number" ? style.glowOpacity : 0.75;
100998
- const glowRad = Math.round(Math.max(0, style.glowRadius));
101647
+ const glowRad = Math.max(0, style.glowRadius / 2);
100999
101648
  const glowCol = colorWithOpacity2(
101000
101649
  normalizeHexColor2(style.glowColor, DEFAULT_GLOW_COLOR),
101001
101650
  glowOpacity
@@ -101076,7 +101725,9 @@ function getComputedEffectStyle(element, options = {}) {
101076
101725
  return result;
101077
101726
  }
101078
101727
  const paintsLineEffectsItself = element.type === "connector" || getShapeType("shapeType" in element ? element.shapeType : void 0) === "connector";
101079
- const boxShadow = getBoxShadowCss(
101728
+ const shadowsCompositePixels = element.type === "group" || element.type === "text" || element.type === "image" || element.type === "picture";
101729
+ const compositeShadow = shadowsCompositePixels ? getCompositeOuterShadowFilterCss(style, { rotation: element.rotation }) : void 0;
101730
+ const boxShadow = shadowsCompositePixels ? void 0 : getBoxShadowCss(
101080
101731
  style,
101081
101732
  { includeGlow: options.includeGlowBoxShadow },
101082
101733
  { rotation: element.rotation }
@@ -101090,7 +101741,7 @@ function getComputedEffectStyle(element, options = {}) {
101090
101741
  }
101091
101742
  const filter = getEffectFilterCss(style, element.id);
101092
101743
  const lineGlow = paintsLineEffectsItself ? void 0 : getLineGlowFilterCss(style);
101093
- const filterParts = [filter, lineGlow].filter(
101744
+ const filterParts = [compositeShadow, filter, lineGlow].filter(
101094
101745
  (part) => part !== void 0 && part !== ""
101095
101746
  );
101096
101747
  if (filterParts.length > 0) {
@@ -101236,6 +101887,55 @@ function outlinePathData(clipPath, width, height) {
101236
101887
  }
101237
101888
  return rect2;
101238
101889
  }
101890
+ var WEDGE_CALLOUT_PRESET_NAMES = /* @__PURE__ */ new Set([
101891
+ "wedgerectcallout",
101892
+ "wedgeroundrectcallout",
101893
+ "wedgeellipsecallout"
101894
+ ]);
101895
+ function isWedgeCalloutPresetShape(shapeType) {
101896
+ return typeof shapeType === "string" && WEDGE_CALLOUT_PRESET_NAMES.has(shapeType.toLowerCase());
101897
+ }
101898
+ function clipPathPolygonPoints(clipPath, width, height) {
101899
+ const asPolygon = /^polygon\((.*)\)$/su.exec(clipPath.trim());
101900
+ if (!asPolygon) {
101901
+ return [];
101902
+ }
101903
+ const toPx2 = (token2, extent) => token2.endsWith("%") ? Number.parseFloat(token2) / 100 * extent : Number.parseFloat(token2);
101904
+ return asPolygon[1].split(",").map((pair) => pair.trim().split(/\s+/u)).filter((parts) => parts.length === 2).map(([rawX, rawY]) => [toPx2(rawX, width), toPx2(rawY, height)]).filter(([x, y]) => Number.isFinite(x) && Number.isFinite(y));
101905
+ }
101906
+ function getPresetShapeVectorGeometry(shapeType, width, height, adjustments) {
101907
+ const normalizedWidth = Math.max(Number.isFinite(width) ? width : 0, 1);
101908
+ const normalizedHeight = Math.max(Number.isFinite(height) ? height : 0, 1);
101909
+ const clipPath = getResolvedShapeClipPathFor(
101910
+ shapeType,
101911
+ normalizedWidth,
101912
+ normalizedHeight,
101913
+ adjustments
101914
+ );
101915
+ const d = outlinePathData(clipPath, normalizedWidth, normalizedHeight);
101916
+ if (!d) {
101917
+ return void 0;
101918
+ }
101919
+ let minX = 0;
101920
+ let minY = 0;
101921
+ let maxX = normalizedWidth;
101922
+ let maxY = normalizedHeight;
101923
+ for (const [x, y] of clipPath ? clipPathPolygonPoints(clipPath, normalizedWidth, normalizedHeight) : []) {
101924
+ minX = Math.min(minX, x);
101925
+ minY = Math.min(minY, y);
101926
+ maxX = Math.max(maxX, x);
101927
+ maxY = Math.max(maxY, y);
101928
+ }
101929
+ return {
101930
+ d,
101931
+ minX,
101932
+ minY,
101933
+ maxX,
101934
+ maxY,
101935
+ viewWidth: Math.max(maxX - minX, 1),
101936
+ viewHeight: Math.max(maxY - minY, 1)
101937
+ };
101938
+ }
101239
101939
  function outlineStrands(compoundLine, strokeWidth) {
101240
101940
  const offsets = getCompoundLineOffsets(compoundLine, strokeWidth);
101241
101941
  if (offsets.length <= 1) {
@@ -113231,6 +113931,7 @@ var KEYFRAME_DEFINITIONS = {
113231
113931
  function getEffectKeyframes(effect) {
113232
113932
  return KEYFRAME_DEFINITIONS[effect] ?? "";
113233
113933
  }
113934
+ var HEX_COLOR2 = /^#?[0-9a-f]{6}$/iu;
113234
113935
  function hexToRgb4(hex4) {
113235
113936
  const cleaned = hex4.replace(/^#/u, "");
113236
113937
  const val2 = parseInt(cleaned, 16);
@@ -113345,48 +114046,145 @@ function resolveCssProperties(attrName) {
113345
114046
  }
113346
114047
  return ATTR_NAME_TO_CSS_PROPERTIES[attrName] ?? ["color"];
113347
114048
  }
113348
- function resolveColorAnimationTargets(targetAttribute) {
113349
- const cssProperties = resolveCssProperties(targetAttribute);
114049
+ function resolveColorAnimationTargets(animationOrAttribute) {
114050
+ const attributes = typeof animationOrAttribute === "string" || animationOrAttribute === void 0 ? [animationOrAttribute] : colorAnimationComponents(animationOrAttribute).map(
114051
+ (component) => component.targetAttribute
114052
+ );
113350
114053
  const targets = [];
113351
- if (cssProperties.includes("fill")) {
113352
- targets.push("fill");
113353
- }
113354
- if (cssProperties.includes("stroke")) {
113355
- targets.push("stroke");
114054
+ for (const attribute2 of attributes) {
114055
+ const cssProperties = resolveCssProperties(attribute2);
114056
+ if (cssProperties.includes("fill") && !targets.includes("fill")) {
114057
+ targets.push("fill");
114058
+ }
114059
+ if (cssProperties.includes("stroke") && !targets.includes("stroke")) {
114060
+ targets.push("stroke");
114061
+ }
113356
114062
  }
113357
114063
  return targets;
113358
114064
  }
113359
- function buildColorAnimationKeyframes(colorAnim, keyframeName, steps = 10) {
113360
- const { colorSpace, direction, fromColor, toColor, byColor, targetAttribute } = colorAnim;
114065
+ var ANIMATION_COLOR_BASE_PROPERTIES = {
114066
+ color: "--pptx-animation-color-base",
114067
+ fill: "--pptx-animation-fill-base",
114068
+ stroke: "--pptx-animation-stroke-base"
114069
+ };
114070
+ function colorAnimationComponents(colorAnim) {
114071
+ return colorAnim.components && colorAnim.components.length > 0 ? colorAnim.components : [colorAnim];
114072
+ }
114073
+ function clampPercent(value) {
114074
+ return Math.max(0, Math.min(100, value));
114075
+ }
114076
+ function applyHslDelta(fromColor, delta, progress) {
114077
+ const fromRgb = hexToRgb4(fromColor);
114078
+ const fromHsl = rgbToHsl2(fromRgb.r, fromRgb.g, fromRgb.b);
114079
+ const hue = ((fromHsl.h + delta.hue * progress) % 360 + 360) % 360;
114080
+ const saturation = clampPercent(fromHsl.s + delta.saturation * progress);
114081
+ const lightness = clampPercent(fromHsl.l + delta.lightness * progress);
114082
+ const rgb = hslToRgb2(hue, saturation, lightness);
114083
+ return rgbToHex3(rgb.r, rgb.g, rgb.b);
114084
+ }
114085
+ function cssNumber(value) {
114086
+ const rounded = Math.round(value * 1e6) / 1e6;
114087
+ return String(Object.is(rounded, -0) ? 0 : rounded);
114088
+ }
114089
+ function baseColorForProperty(property) {
114090
+ if (property === "fill" || property === "background-color" || property === "backgroundColor") {
114091
+ return `var(${ANIMATION_COLOR_BASE_PROPERTIES.fill}, currentColor)`;
114092
+ }
114093
+ if (property === "stroke" || property === "border-color" || property === "borderColor") {
114094
+ return `var(${ANIMATION_COLOR_BASE_PROPERTIES.stroke}, currentColor)`;
114095
+ }
114096
+ return `var(${ANIMATION_COLOR_BASE_PROPERTIES.color}, currentColor)`;
114097
+ }
114098
+ function relativeHslColor(property, delta, progress) {
114099
+ const hue = cssNumber(delta.hue * progress);
114100
+ const saturation = cssNumber(delta.saturation * progress);
114101
+ const lightness = cssNumber(delta.lightness * progress);
114102
+ return `hsl(from ${baseColorForProperty(property)} calc(h + ${hue}) calc(s + ${saturation}) calc(l + ${lightness}) / alpha)`;
114103
+ }
114104
+ function absoluteComponentColor(component, progress) {
114105
+ const { colorSpace, direction, fromColor, toColor, byColor } = component;
113361
114106
  let effectiveFrom;
113362
114107
  let effectiveTo;
113363
114108
  if (fromColor && toColor) {
114109
+ if (!HEX_COLOR2.test(fromColor) || !HEX_COLOR2.test(toColor)) {
114110
+ return void 0;
114111
+ }
113364
114112
  effectiveFrom = fromColor;
113365
114113
  effectiveTo = toColor;
113366
114114
  } else if (fromColor && byColor) {
114115
+ if (!HEX_COLOR2.test(fromColor) || !HEX_COLOR2.test(byColor)) {
114116
+ return void 0;
114117
+ }
113367
114118
  const fromRgb = hexToRgb4(fromColor);
113368
114119
  const byRgb = hexToRgb4(byColor);
113369
114120
  effectiveFrom = fromColor;
113370
114121
  effectiveTo = rgbToHex3(fromRgb.r + byRgb.r, fromRgb.g + byRgb.g, fromRgb.b + byRgb.b);
113371
114122
  } else if (toColor) {
114123
+ if (!HEX_COLOR2.test(toColor)) {
114124
+ return void 0;
114125
+ }
113372
114126
  effectiveFrom = "#000000";
113373
114127
  effectiveTo = toColor;
113374
114128
  } else {
113375
114129
  return void 0;
113376
114130
  }
113377
- const cssProperties = resolveCssProperties(targetAttribute);
114131
+ return interpolateColor(effectiveFrom, effectiveTo, progress, colorSpace, direction);
114132
+ }
114133
+ function buildColorAnimationKeyframes(colorAnim, keyframeName2, steps = 10) {
114134
+ const components = colorAnimationComponents(colorAnim);
114135
+ if (!components.some(
114136
+ (component) => component.hslDelta !== void 0 || component.toColor !== void 0 || component.fromColor !== void 0 && component.byColor !== void 0
114137
+ )) {
114138
+ return void 0;
114139
+ }
113378
114140
  const lines = [];
114141
+ let hasDeclarations = false;
113379
114142
  const actualSteps = Math.max(2, steps);
113380
114143
  for (let i = 0; i <= actualSteps; i++) {
113381
114144
  const t = i / actualSteps;
113382
114145
  const pct = Math.round(t * 100);
113383
- const color2 = interpolateColor(effectiveFrom, effectiveTo, t, colorSpace, direction);
113384
- const decls = cssProperties.map((prop) => `${prop}: ${color2};`).join(" ");
114146
+ const declarations = [];
114147
+ for (const component of components) {
114148
+ const cssProperties = resolveCssProperties(component.targetAttribute);
114149
+ if (component.hslDelta) {
114150
+ if (component.fromColor && !HEX_COLOR2.test(component.fromColor)) {
114151
+ continue;
114152
+ }
114153
+ for (const property of cssProperties) {
114154
+ const color22 = component.fromColor ? applyHslDelta(component.fromColor, component.hslDelta, t) : relativeHslColor(property, component.hslDelta, t);
114155
+ declarations.push(`${property}: ${color22};`);
114156
+ hasDeclarations = true;
114157
+ }
114158
+ continue;
114159
+ }
114160
+ const color2 = absoluteComponentColor(component, t);
114161
+ if (color2) {
114162
+ declarations.push(...cssProperties.map((property) => `${property}: ${color2};`));
114163
+ hasDeclarations = true;
114164
+ }
114165
+ }
114166
+ const decls = declarations.join(" ");
113385
114167
  lines.push(` ${pct}% { ${decls} }`);
113386
114168
  }
113387
- return `@keyframes ${keyframeName} {
114169
+ return hasDeclarations ? `@keyframes ${keyframeName2} {
113388
114170
  ${lines.join("\n")}
113389
- }`;
114171
+ }` : void 0;
114172
+ }
114173
+ function getAnimationColorBaseStyle(element, options = {}) {
114174
+ if (!hasShapeProperties(element) || !options.animatesFill && !options.animatesStroke) {
114175
+ return {};
114176
+ }
114177
+ const style = {};
114178
+ if (options.animatesFill) {
114179
+ const fill = getComputedFillStyle(element, options.parentGroupFill);
114180
+ style[ANIMATION_COLOR_BASE_PROPERTIES.fill] = fill?.backgroundColor ?? element.shapeStyle?.fillColor ?? "currentColor";
114181
+ }
114182
+ if (options.animatesStroke) {
114183
+ const stroke = getComputedStrokeStyle(element);
114184
+ style[ANIMATION_COLOR_BASE_PROPERTIES.stroke] = stroke.borderColor ?? element.shapeStyle?.strokeColor ?? "currentColor";
114185
+ }
114186
+ style[ANIMATION_COLOR_BASE_PROPERTIES.color] = (hasTextProperties(element) ? element.textStyle?.color : void 0) ?? "currentColor";
114187
+ return style;
113390
114188
  }
113391
114189
  function resolveChartBuildMode(token2) {
113392
114190
  switch (token2) {
@@ -113553,6 +114351,141 @@ function revealedSmartArtNodeCount(nodes, build) {
113553
114351
  }
113554
114352
  return revealedStageCount(build.progress, nodes.length);
113555
114353
  }
114354
+ var ATTRIBUTE_KINDS = {
114355
+ opacity: "opacity",
114356
+ ppt_h: "scaleY",
114357
+ ppt_w: "scaleX",
114358
+ ppt_x: "translateX",
114359
+ ppt_y: "translateY",
114360
+ "style.opacity": "opacity",
114361
+ "style.rotation": "rotation"
114362
+ };
114363
+ var SELF_REFERENCE_RE = /^#?ppt_([whxy])(?:([+-])(\d*\.?\d+))?$/iu;
114364
+ function clamp0122(value) {
114365
+ return Math.max(0, Math.min(1, value));
114366
+ }
114367
+ function numericValue(keyframe) {
114368
+ const parsed = Number(keyframe.value);
114369
+ return Number.isFinite(parsed) ? parsed : void 0;
114370
+ }
114371
+ function parseSelfReference(keyframe, expectedAxis) {
114372
+ const token2 = String(keyframe.value).replaceAll(" ", "").toLowerCase();
114373
+ const match = SELF_REFERENCE_RE.exec(token2);
114374
+ if (!match || match[1] !== expectedAxis) {
114375
+ return void 0;
114376
+ }
114377
+ const magnitude = match[3] === void 0 ? 0 : Number(match[3]);
114378
+ if (!Number.isFinite(magnitude)) {
114379
+ return void 0;
114380
+ }
114381
+ return { offset: match[2] === "-" ? -magnitude : magnitude };
114382
+ }
114383
+ function parseValue(kind, keyframe) {
114384
+ if (kind === "rotation") {
114385
+ return numericValue(keyframe);
114386
+ }
114387
+ if (kind === "opacity") {
114388
+ const value = numericValue(keyframe);
114389
+ return value === void 0 ? void 0 : clamp0122(value);
114390
+ }
114391
+ if (kind === "scaleX" || kind === "scaleY") {
114392
+ const numeric = numericValue(keyframe);
114393
+ if (numeric === 0) {
114394
+ return 0;
114395
+ }
114396
+ const axis2 = kind === "scaleX" ? "w" : "h";
114397
+ const reference2 = parseSelfReference(keyframe, axis2);
114398
+ return reference2?.offset === 0 ? 1 : void 0;
114399
+ }
114400
+ const axis = kind === "translateX" ? "x" : "y";
114401
+ const reference = parseSelfReference(keyframe, axis);
114402
+ return reference === void 0 ? void 0 : reference.offset * 100;
114403
+ }
114404
+ function parseComponent(component, effectDurationMs) {
114405
+ const kind = ATTRIBUTE_KINDS[component.attrName];
114406
+ if (!kind) {
114407
+ return void 0;
114408
+ }
114409
+ const stops = [];
114410
+ for (const keyframe of component.keyframes) {
114411
+ if (typeof keyframe.tm !== "number" || !Number.isFinite(keyframe.tm)) {
114412
+ return void 0;
114413
+ }
114414
+ const value = parseValue(kind, keyframe);
114415
+ if (value === void 0) {
114416
+ return void 0;
114417
+ }
114418
+ stops.push({ progress: clamp0122(keyframe.tm / 1e5), value });
114419
+ }
114420
+ if (stops.length < 2) {
114421
+ return void 0;
114422
+ }
114423
+ stops.sort((left, right) => left.progress - right.progress);
114424
+ return {
114425
+ delayMs: component.delayMs ?? 0,
114426
+ durationMs: component.durationMs ?? effectDurationMs,
114427
+ kind,
114428
+ stops
114429
+ };
114430
+ }
114431
+ function valueAt(component, progress, effectDurationMs) {
114432
+ const elapsedMs = progress * effectDurationMs - component.delayMs;
114433
+ const localProgress = clamp0122(elapsedMs / Math.max(1, component.durationMs));
114434
+ const first = component.stops[0];
114435
+ const last = component.stops[component.stops.length - 1];
114436
+ if (localProgress <= first.progress) {
114437
+ return first.value;
114438
+ }
114439
+ if (localProgress >= last.progress) {
114440
+ return last.value;
114441
+ }
114442
+ for (let index = 1; index < component.stops.length; index += 1) {
114443
+ const right = component.stops[index];
114444
+ const left = component.stops[index - 1];
114445
+ if (localProgress <= right.progress) {
114446
+ const span = Math.max(Number.EPSILON, right.progress - left.progress);
114447
+ const ratio = (localProgress - left.progress) / span;
114448
+ return left.value + (right.value - left.value) * ratio;
114449
+ }
114450
+ }
114451
+ return last.value;
114452
+ }
114453
+ function createAttributeTransformModel(anim) {
114454
+ const effectDurationMs = Math.max(1, anim.durationMs ?? 1e3);
114455
+ const supportedComponents = (anim.attributeAnimations ?? []).filter(
114456
+ (component) => ATTRIBUTE_KINDS[component.attrName] !== void 0
114457
+ );
114458
+ const components = supportedComponents.map(
114459
+ (component) => parseComponent(component, effectDurationMs)
114460
+ );
114461
+ const parsedComponents = components.filter(
114462
+ (component) => component !== void 0
114463
+ );
114464
+ if (parsedComponents.length !== supportedComponents.length) {
114465
+ return void 0;
114466
+ }
114467
+ if (parsedComponents.length === 0) {
114468
+ return void 0;
114469
+ }
114470
+ const progressSet = /* @__PURE__ */ new Set([0, 1]);
114471
+ for (const component of parsedComponents) {
114472
+ for (const stop of component.stops) {
114473
+ progressSet.add(
114474
+ clamp0122((component.delayMs + stop.progress * component.durationMs) / effectDurationMs)
114475
+ );
114476
+ }
114477
+ }
114478
+ return {
114479
+ progresses: [...progressSet].sort((left, right) => left - right),
114480
+ stateAt(progress) {
114481
+ const state = {};
114482
+ for (const component of parsedComponents) {
114483
+ state[component.kind] = valueAt(component, progress, effectDurationMs);
114484
+ }
114485
+ return state;
114486
+ }
114487
+ };
114488
+ }
113556
114489
  var BEZIER_SAMPLES = 8;
113557
114490
  function cubicAt(p0, c1, c2, p3, t) {
113558
114491
  const mt = 1 - t;
@@ -113638,119 +114571,150 @@ function parseMotionPathPoints(motionPath) {
113638
114571
  }
113639
114572
  return points3;
113640
114573
  }
113641
- function buildAbsoluteRotationKeyframe(anim, namePrefix, uid) {
113642
- if (anim.rotationBy !== void 0) {
113643
- return void 0;
114574
+ function slideOffset(percent3, axis) {
114575
+ const fallback = axis === "w" ? "1280px" : "720px";
114576
+ return `calc(var(--pptx-slide-${axis}, ${fallback}) * ${(percent3 / 100).toFixed(4)})`;
114577
+ }
114578
+ function hasRotation(anim) {
114579
+ return anim.rotationBy !== void 0 || anim.rotationFrom !== void 0 || anim.rotationTo !== void 0;
114580
+ }
114581
+ function hasScale(anim) {
114582
+ return anim.scaleByX !== void 0 || anim.scaleByY !== void 0 || anim.scaleFromX !== void 0 || anim.scaleFromY !== void 0 || anim.scaleToX !== void 0 || anim.scaleToY !== void 0;
114583
+ }
114584
+ function hasAuthoredTransform(anim) {
114585
+ return Boolean(anim.motionPath) || hasRotation(anim) || hasScale(anim) || createAttributeTransformModel(anim) !== void 0;
114586
+ }
114587
+ function rotationAt(anim, progress) {
114588
+ const from = anim.rotationFrom ?? 0;
114589
+ const to = anim.rotationTo ?? (anim.rotationBy !== void 0 ? from + anim.rotationBy : from);
114590
+ return from + (to - from) * progress;
114591
+ }
114592
+ function scaleAt(anim, axis, progress) {
114593
+ const from = axis === "x" ? anim.scaleFromX ?? 1 : anim.scaleFromY ?? 1;
114594
+ const authoredTo = axis === "x" ? anim.scaleToX : anim.scaleToY;
114595
+ const by = axis === "x" ? anim.scaleByX : anim.scaleByY;
114596
+ const to = authoredTo ?? (by !== void 0 ? from * by : from);
114597
+ return from + (to - from) * progress;
114598
+ }
114599
+ function opacityAt(anim, progress) {
114600
+ if (anim.presetClass === "entr") {
114601
+ return progress;
113644
114602
  }
113645
- if (anim.rotationFrom === void 0 && anim.rotationTo === void 0) {
113646
- return void 0;
114603
+ if (anim.presetClass === "exit") {
114604
+ return 1 - progress;
113647
114605
  }
113648
- const from = anim.rotationFrom ?? anim.rotationTo ?? 0;
113649
- const to = anim.rotationTo ?? anim.rotationFrom ?? 0;
113650
- const name = `${namePrefix}-${uid}`;
114606
+ return void 0;
114607
+ }
114608
+ function formatNumber(value, fractionDigits = 4) {
114609
+ return String(Number(value.toFixed(fractionDigits)));
114610
+ }
114611
+ function tangentAngle(points3, index) {
114612
+ const point = points3[index];
114613
+ const next = index < points3.length - 1 ? points3[index + 1] : point;
114614
+ const previous = index > 0 ? points3[index - 1] : point;
114615
+ const dx = index < points3.length - 1 ? next.x - point.x : point.x - previous.x;
114616
+ const dy = index < points3.length - 1 ? next.y - point.y : point.y - previous.y;
114617
+ return Math.atan2(dy, dx) * (180 / Math.PI);
114618
+ }
114619
+ function rotateMotionPathPoints(points3, anim) {
114620
+ const angle = anim.motionPathRotationAngle ?? 0;
114621
+ if (!Number.isFinite(angle) || angle === 0) {
114622
+ return [...points3];
114623
+ }
114624
+ const radians = angle * Math.PI / 180;
114625
+ const cosine = Math.cos(radians);
114626
+ const sine = Math.sin(radians);
114627
+ const centerX = anim.motionPathRotationCenterX ?? 0;
114628
+ const centerY = anim.motionPathRotationCenterY ?? 0;
114629
+ return points3.map((point) => {
114630
+ const x = point.x - centerX;
114631
+ const y = point.y - centerY;
114632
+ return {
114633
+ x: centerX + x * cosine - y * sine,
114634
+ y: centerY + x * sine + y * cosine
114635
+ };
114636
+ });
114637
+ }
114638
+ function pointAt(points3, progress) {
114639
+ if (points3.length < 2) {
114640
+ return { x: 0, y: 0 };
114641
+ }
114642
+ const position2 = progress * (points3.length - 1);
114643
+ const leftIndex = Math.floor(position2);
114644
+ const rightIndex = Math.min(points3.length - 1, leftIndex + 1);
114645
+ const ratio = position2 - leftIndex;
114646
+ const left = points3[leftIndex];
114647
+ const right = points3[rightIndex];
113651
114648
  return {
113652
- keyframeName: name,
113653
- css: `@keyframes ${name} {
113654
- from { transform: rotate(${from}deg); }
113655
- to { transform: rotate(${to}deg); }
113656
- }`
114649
+ x: left.x + (right.x - left.x) * ratio,
114650
+ y: left.y + (right.y - left.y) * ratio
113657
114651
  };
113658
114652
  }
113659
- function buildAbsoluteScaleKeyframe(anim, namePrefix, uid) {
113660
- if (anim.scaleByX !== void 0 || anim.scaleByY !== void 0) {
113661
- return void 0;
114653
+ function keyframeName(anim, prefixes, uid, hasAttributeAnimation) {
114654
+ const motion = Boolean(anim.motionPath);
114655
+ const rotation = hasRotation(anim);
114656
+ const scale = hasScale(anim);
114657
+ if (hasAttributeAnimation || Number(motion) + Number(rotation) + Number(scale) > 1) {
114658
+ return `${prefixes.transform}-${uid}`;
113662
114659
  }
113663
- if (anim.scaleFromX === void 0 && anim.scaleFromY === void 0 && anim.scaleToX === void 0 && anim.scaleToY === void 0) {
113664
- return void 0;
114660
+ if (motion) {
114661
+ return `${prefixes.motion}-${uid}`;
113665
114662
  }
113666
- const fromX = anim.scaleFromX ?? 1;
113667
- const fromY = anim.scaleFromY ?? 1;
113668
- const toX = anim.scaleToX ?? fromX;
113669
- const toY = anim.scaleToY ?? fromY;
113670
- const name = `${namePrefix}-${uid}`;
113671
- return {
113672
- keyframeName: name,
113673
- css: `@keyframes ${name} {
113674
- from { transform: scale(${fromX}, ${fromY}); }
113675
- to { transform: scale(${toX}, ${toY}); }
113676
- }`
113677
- };
113678
- }
113679
- function clamp0122(value) {
113680
- return Math.max(0, Math.min(1, value));
114663
+ if (rotation) {
114664
+ return `${anim.rotationBy === void 0 ? prefixes.rotationAbsolute : prefixes.rotationRelative}-${uid}`;
114665
+ }
114666
+ return `${anim.scaleByX === void 0 && anim.scaleByY === void 0 ? prefixes.scaleAbsolute : prefixes.scaleRelative}-${uid}`;
113681
114667
  }
113682
- var KNOWN_OPACITY_ATTR_NAMES = /* @__PURE__ */ new Set(["style.opacity", "opacity"]);
113683
- function buildOpacityTavKeyframe(anim, namePrefix, uid) {
113684
- if (anim.presetClass !== "emph") {
114668
+ function buildTransformKeyframes(anim, uid, prefixes) {
114669
+ const rotation = hasRotation(anim);
114670
+ const scale = hasScale(anim);
114671
+ const attributeModel = createAttributeTransformModel(anim);
114672
+ const parsedPoints = anim.motionPath ? rotateMotionPathPoints(parseMotionPathPoints(anim.motionPath), anim) : [];
114673
+ const points3 = parsedPoints.length >= 2 ? parsedPoints : [];
114674
+ if (points3.length === 0 && !rotation && !scale && !attributeModel) {
113685
114675
  return void 0;
113686
114676
  }
113687
- if (anim.attrName !== void 0 && !KNOWN_OPACITY_ATTR_NAMES.has(anim.attrName)) {
113688
- return void 0;
114677
+ const progressSet = new Set(attributeModel?.progresses ?? [0, 1]);
114678
+ for (let index = 0; index < points3.length; index += 1) {
114679
+ progressSet.add(index / (points3.length - 1));
113689
114680
  }
113690
- const frames = anim.keyframes;
113691
- if (!frames || frames.length < 2) {
113692
- return void 0;
113693
- }
113694
- const stops = [];
113695
- for (const kf of frames) {
113696
- if (typeof kf.tm !== "number" || !Number.isFinite(kf.tm)) {
113697
- return void 0;
114681
+ const progresses = [...progressSet].sort((left, right) => left - right);
114682
+ const lines = progresses.map((progress) => {
114683
+ const point = pointAt(points3, progress);
114684
+ const attributeState = attributeModel?.stateAt(progress);
114685
+ const declarations = [];
114686
+ const opacity2 = attributeState?.opacity ?? opacityAt(anim, progress);
114687
+ if (opacity2 !== void 0) {
114688
+ declarations.push(`opacity: ${formatNumber(opacity2)};`);
113698
114689
  }
113699
- if (kf.valueType !== "flt" && kf.valueType !== "int") {
113700
- return void 0;
114690
+ const transforms = [];
114691
+ if (points3.length > 0) {
114692
+ transforms.push(`translate(${slideOffset(point.x, "w")}, ${slideOffset(point.y, "h")})`);
113701
114693
  }
113702
- const opacity2 = Number(kf.value);
113703
- if (!Number.isFinite(opacity2) || opacity2 < 0 || opacity2 > 1) {
113704
- return void 0;
114694
+ if (attributeState?.translateX !== void 0 || attributeState?.translateY !== void 0) {
114695
+ transforms.push(
114696
+ `translate(${slideOffset(attributeState.translateX ?? 0, "w")}, ${slideOffset(attributeState.translateY ?? 0, "h")})`
114697
+ );
113705
114698
  }
113706
- stops.push({ pct: clamp0122(kf.tm / 1e5) * 100, opacity: opacity2 });
113707
- }
113708
- stops.sort((a, b) => a.pct - b.pct);
113709
- const name = `${namePrefix}-${uid}`;
113710
- const lines = stops.map((s) => ` ${Number(s.pct.toFixed(2))}% { opacity: ${s.opacity}; }`);
113711
- return { keyframeName: name, css: `@keyframes ${name} {
113712
- ${lines.join("\n")}
113713
- }` };
113714
- }
113715
- var KNOWN_COLOR_ATTR_NAMES = /* @__PURE__ */ new Set([
113716
- "fillcolor",
113717
- "fill.color",
113718
- "style.color",
113719
- "stroke.color"
113720
- ]);
113721
- var HEX_COLOR_RE = /^#[0-9a-f]{6}$/iu;
113722
- function buildColorTavKeyframe(anim, namePrefix, uid) {
113723
- if (anim.colorAnimation) {
113724
- return void 0;
113725
- }
113726
- if (!anim.attrName || !KNOWN_COLOR_ATTR_NAMES.has(anim.attrName)) {
113727
- return void 0;
113728
- }
113729
- const frames = anim.keyframes;
113730
- if (!frames || frames.length < 2) {
113731
- return void 0;
113732
- }
113733
- const stops = [];
113734
- for (const kf of frames) {
113735
- if (typeof kf.tm !== "number" || !Number.isFinite(kf.tm)) {
113736
- return void 0;
114699
+ if (rotation || points3.length > 0 && anim.motionPathRotateAuto || attributeState?.rotation !== void 0) {
114700
+ const pointIndex = Math.round(progress * Math.max(0, points3.length - 1));
114701
+ const pathRotation = anim.motionPathRotateAuto ? tangentAngle(points3, pointIndex) : 0;
114702
+ const angle = pathRotation + (attributeState?.rotation ?? rotationAt(anim, progress));
114703
+ transforms.push(
114704
+ `rotate(${anim.motionPathRotateAuto ? angle.toFixed(2) : formatNumber(angle, 2)}deg)`
114705
+ );
113737
114706
  }
113738
- if (kf.valueType !== "clr") {
113739
- return void 0;
114707
+ if (scale || attributeState?.scaleX !== void 0 || attributeState?.scaleY !== void 0) {
114708
+ transforms.push(
114709
+ `scale(${formatNumber(attributeState?.scaleX ?? scaleAt(anim, "x", progress))}, ${formatNumber(attributeState?.scaleY ?? scaleAt(anim, "y", progress))})`
114710
+ );
113740
114711
  }
113741
- const color2 = String(kf.value);
113742
- if (!HEX_COLOR_RE.test(color2)) {
113743
- return void 0;
114712
+ if (transforms.length > 0) {
114713
+ declarations.push(`transform: ${transforms.join(" ")};`);
113744
114714
  }
113745
- stops.push({ pct: clamp0122(kf.tm / 1e5) * 100, color: color2.toLowerCase() });
113746
- }
113747
- stops.sort((a, b) => a.pct - b.pct);
113748
- const cssProperties = resolveCssProperties(anim.attrName);
113749
- const name = `${namePrefix}-${uid}`;
113750
- const lines = stops.map((s) => {
113751
- const decls = cssProperties.map((prop) => `${prop}: ${s.color};`).join(" ");
113752
- return ` ${Number(s.pct.toFixed(2))}% { ${decls} }`;
114715
+ return ` ${formatNumber(progress * 100, 2)}% { ${declarations.join(" ")} }`;
113753
114716
  });
114717
+ const name = keyframeName(anim, prefixes, uid, attributeModel !== void 0);
113754
114718
  return { keyframeName: name, css: `@keyframes ${name} {
113755
114719
  ${lines.join("\n")}
113756
114720
  }` };
@@ -113795,71 +114759,18 @@ function applyFlyDirection(effect, subtype) {
113795
114759
  const suffix = `${edge.charAt(0).toUpperCase()}${edge.slice(1)}`;
113796
114760
  return `${prefix}${suffix}`;
113797
114761
  }
113798
- function slideOffset(percent3, axis) {
113799
- const fallback = axis === "w" ? "1280px" : "720px";
113800
- return `calc(var(--pptx-slide-${axis}, ${fallback}) * ${(percent3 / 100).toFixed(4)})`;
113801
- }
114762
+ var TIMELINE_TRANSFORM_PREFIXES = {
114763
+ motion: "pptx-tl-motion",
114764
+ rotationAbsolute: "pptx-tl-rotateAbs",
114765
+ rotationRelative: "pptx-tl-rotate",
114766
+ scaleAbsolute: "pptx-tl-scaleAbs",
114767
+ scaleRelative: "pptx-tl-scale",
114768
+ transform: "pptx-tl-transform"
114769
+ };
113802
114770
  function buildDynamicKeyframe(anim, uid) {
113803
- if (anim.motionPath) {
113804
- const name = `pptx-tl-motion-${uid}`;
113805
- const points3 = parseMotionPathPoints(anim.motionPath);
113806
- if (points3.length < 2) {
113807
- return void 0;
113808
- }
113809
- const lines = [];
113810
- for (let i = 0; i < points3.length; i++) {
113811
- const pct = Math.round(i / (points3.length - 1) * 100);
113812
- const tx = slideOffset(points3[i].x, "w");
113813
- const ty = slideOffset(points3[i].y, "h");
113814
- if (anim.motionPathRotateAuto) {
113815
- const next = i < points3.length - 1 ? points3[i + 1] : points3[i];
113816
- const prev = i > 0 ? points3[i - 1] : points3[i];
113817
- const dx = i < points3.length - 1 ? next.x - points3[i].x : points3[i].x - prev.x;
113818
- const dy = i < points3.length - 1 ? next.y - points3[i].y : points3[i].y - prev.y;
113819
- const angleDeg = Math.atan2(dy, dx) * (180 / Math.PI);
113820
- lines.push(
113821
- ` ${pct}% { transform: translate(${tx}, ${ty}) rotate(${angleDeg.toFixed(2)}deg); }`
113822
- );
113823
- } else {
113824
- lines.push(` ${pct}% { transform: translate(${tx}, ${ty}); }`);
113825
- }
113826
- }
113827
- return {
113828
- keyframeName: name,
113829
- css: `@keyframes ${name} {
113830
- ${lines.join("\n")}
113831
- }`
113832
- };
113833
- }
113834
- if (anim.rotationBy !== void 0) {
113835
- const name = `pptx-tl-rotate-${uid}`;
113836
- return {
113837
- keyframeName: name,
113838
- css: `@keyframes ${name} {
113839
- from { transform: rotate(0deg); }
113840
- to { transform: rotate(${anim.rotationBy}deg); }
113841
- }`
113842
- };
113843
- }
113844
- const absoluteRotate = buildAbsoluteRotationKeyframe(anim, "pptx-tl-rotateAbs", uid);
113845
- if (absoluteRotate) {
113846
- return absoluteRotate;
113847
- }
113848
- if (anim.scaleByX !== void 0 || anim.scaleByY !== void 0) {
113849
- const name = `pptx-tl-scale-${uid}`;
113850
- const sx = anim.scaleByX ?? 1;
113851
- const sy = anim.scaleByY ?? 1;
113852
- return {
113853
- keyframeName: name,
113854
- css: `@keyframes ${name} {
113855
- from { transform: scale(1); }
113856
- to { transform: scale(${sx}, ${sy}); }
113857
- }`
113858
- };
113859
- }
113860
- const absoluteScale = buildAbsoluteScaleKeyframe(anim, "pptx-tl-scaleAbs", uid);
113861
- if (absoluteScale) {
113862
- return absoluteScale;
114771
+ const transform = buildTransformKeyframes(anim, uid, TIMELINE_TRANSFORM_PREFIXES);
114772
+ if (transform) {
114773
+ return transform;
113863
114774
  }
113864
114775
  if (anim.colorAnimation) {
113865
114776
  const name = `pptx-tl-color-${uid}`;
@@ -113928,6 +114839,85 @@ function finalizeClickGroup(steps, options) {
113928
114839
  }
113929
114840
  return group2;
113930
114841
  }
114842
+ function clamp013(value) {
114843
+ return Math.max(0, Math.min(1, value));
114844
+ }
114845
+ var KNOWN_OPACITY_ATTR_NAMES = /* @__PURE__ */ new Set(["style.opacity", "opacity"]);
114846
+ function buildOpacityTavKeyframe(anim, namePrefix, uid) {
114847
+ if (anim.presetClass !== "emph") {
114848
+ return void 0;
114849
+ }
114850
+ if (anim.attrName !== void 0 && !KNOWN_OPACITY_ATTR_NAMES.has(anim.attrName)) {
114851
+ return void 0;
114852
+ }
114853
+ const frames = anim.keyframes;
114854
+ if (!frames || frames.length < 2) {
114855
+ return void 0;
114856
+ }
114857
+ const stops = [];
114858
+ for (const kf of frames) {
114859
+ if (typeof kf.tm !== "number" || !Number.isFinite(kf.tm)) {
114860
+ return void 0;
114861
+ }
114862
+ if (kf.valueType !== "flt" && kf.valueType !== "int") {
114863
+ return void 0;
114864
+ }
114865
+ const opacity2 = Number(kf.value);
114866
+ if (!Number.isFinite(opacity2) || opacity2 < 0 || opacity2 > 1) {
114867
+ return void 0;
114868
+ }
114869
+ stops.push({ pct: clamp013(kf.tm / 1e5) * 100, opacity: opacity2 });
114870
+ }
114871
+ stops.sort((a, b) => a.pct - b.pct);
114872
+ const name = `${namePrefix}-${uid}`;
114873
+ const lines = stops.map((s) => ` ${Number(s.pct.toFixed(2))}% { opacity: ${s.opacity}; }`);
114874
+ return { keyframeName: name, css: `@keyframes ${name} {
114875
+ ${lines.join("\n")}
114876
+ }` };
114877
+ }
114878
+ var KNOWN_COLOR_ATTR_NAMES = /* @__PURE__ */ new Set([
114879
+ "fillcolor",
114880
+ "fill.color",
114881
+ "style.color",
114882
+ "stroke.color"
114883
+ ]);
114884
+ var HEX_COLOR_RE = /^#[0-9a-f]{6}$/iu;
114885
+ function buildColorTavKeyframe(anim, namePrefix, uid) {
114886
+ if (anim.colorAnimation) {
114887
+ return void 0;
114888
+ }
114889
+ if (!anim.attrName || !KNOWN_COLOR_ATTR_NAMES.has(anim.attrName)) {
114890
+ return void 0;
114891
+ }
114892
+ const frames = anim.keyframes;
114893
+ if (!frames || frames.length < 2) {
114894
+ return void 0;
114895
+ }
114896
+ const stops = [];
114897
+ for (const kf of frames) {
114898
+ if (typeof kf.tm !== "number" || !Number.isFinite(kf.tm)) {
114899
+ return void 0;
114900
+ }
114901
+ if (kf.valueType !== "clr") {
114902
+ return void 0;
114903
+ }
114904
+ const color2 = String(kf.value);
114905
+ if (!HEX_COLOR_RE.test(color2)) {
114906
+ return void 0;
114907
+ }
114908
+ stops.push({ pct: clamp013(kf.tm / 1e5) * 100, color: color2.toLowerCase() });
114909
+ }
114910
+ stops.sort((a, b) => a.pct - b.pct);
114911
+ const cssProperties = resolveCssProperties(anim.attrName);
114912
+ const name = `${namePrefix}-${uid}`;
114913
+ const lines = stops.map((s) => {
114914
+ const decls = cssProperties.map((prop) => `${prop}: ${s.color};`).join(" ");
114915
+ return ` ${Number(s.pct.toFixed(2))}% { ${decls} }`;
114916
+ });
114917
+ return { keyframeName: name, css: `@keyframes ${name} {
114918
+ ${lines.join("\n")}
114919
+ }` };
114920
+ }
113931
114921
  function applySpeedToDuration(speedPct, baseDurationMs) {
113932
114922
  if (speedPct === void 0 || !Number.isFinite(speedPct) || speedPct <= 0) {
113933
114923
  return baseDurationMs;
@@ -113957,10 +114947,13 @@ function shouldHoldEndState(anim) {
113957
114947
  }
113958
114948
  function resolveEffectTiming(anim, baseDurationMs) {
113959
114949
  const durationMs = applySpeedToDuration(anim.speedPct, baseDurationMs);
113960
- const iterationCount = resolveIterationCount(anim.repeatCount, anim.repeatDurMs, durationMs);
114950
+ const authoredIterations = resolveIterationCount(anim.repeatCount, anim.repeatDurMs, durationMs);
114951
+ const iterationCount = anim.autoReverse && anim.repeatDurMs === void 0 ? authoredIterations * 2 : authoredIterations;
114952
+ const activeDurationMs = Number.isFinite(iterationCount) ? durationMs * iterationCount : durationMs;
113961
114953
  return {
113962
114954
  durationMs,
113963
114955
  iterationCount,
114956
+ activeDurationMs,
113964
114957
  holdEndState: shouldHoldEndState(anim)
113965
114958
  };
113966
114959
  }
@@ -114211,7 +115204,8 @@ function emitStaggeredPieces(anim, kind, counts, output, newClickStepPerParagrap
114211
115204
  ...isFirstStep ? {} : {
114212
115205
  triggerDelayMs: void 0,
114213
115206
  startConditions: void 0,
114214
- parGroupIndex: void 0
115207
+ parGroupIndex: void 0,
115208
+ parGroupDelayMs: void 0
114215
115209
  },
114216
115210
  buildType: void 0,
114217
115211
  iterate: void 0
@@ -114259,6 +115253,7 @@ function expandSingleBuildAnimation(anim, buildType, counts, output) {
114259
115253
  triggerDelayMs: void 0,
114260
115254
  startConditions: void 0,
114261
115255
  parGroupIndex: void 0,
115256
+ parGroupDelayMs: void 0,
114262
115257
  buildType: void 0,
114263
115258
  buildReverse: void 0,
114264
115259
  buildAdvAutoMs: void 0,
@@ -114280,7 +115275,8 @@ function joinPreviousFields() {
114280
115275
  trigger: "withPrevious",
114281
115276
  triggerDelayMs: void 0,
114282
115277
  startConditions: void 0,
114283
- parGroupIndex: void 0
115278
+ parGroupIndex: void 0,
115279
+ parGroupDelayMs: void 0
114284
115280
  };
114285
115281
  }
114286
115282
  function expandParagraphRange(anim, targetId, start, end, output) {
@@ -114481,13 +115477,13 @@ function applyAfterAnimationFromEditorList(nativeAnimations, editorAnimations) {
114481
115477
  };
114482
115478
  });
114483
115479
  }
114484
- function buildAfterAnimationDimKeyframes(color2, keyframeName) {
114485
- return `@keyframes ${keyframeName} {
115480
+ function buildAfterAnimationDimKeyframes(color2, keyframeName2) {
115481
+ return `@keyframes ${keyframeName2} {
114486
115482
  100% { color: ${color2}; }
114487
115483
  }`;
114488
115484
  }
114489
- function appendDimAnimation(cssAnimation, keyframeName, startDelayMs) {
114490
- return `${cssAnimation}, ${keyframeName} 1ms linear ${Math.max(0, startDelayMs)}ms 1 forwards`;
115485
+ function appendDimAnimation(cssAnimation, keyframeName2, startDelayMs) {
115486
+ return `${cssAnimation}, ${keyframeName2} 1ms linear ${Math.max(0, startDelayMs)}ms 1 forwards`;
114491
115487
  }
114492
115488
  function resolveAfterAnimationStepFields(anim, cssAnimation, baseHoldEndState, dimStartDelayMs, dimKeyframeName) {
114493
115489
  if (anim.afterAnimationAction === "dimToColor" && anim.afterAnimationColor) {
@@ -114636,12 +115632,39 @@ function parseMediaCommand(commandString) {
114636
115632
  }
114637
115633
  return void 0;
114638
115634
  }
114639
- function clamp013(value) {
115635
+ var COLOR_KEYFRAME = /^pptx-tl-(?:color|tavclr)-/u;
115636
+ var TRANSFORM_KEYFRAME = /^pptx-tl-(?:motion|rotate(?:Abs)?|scale(?:Abs)?|transform)-/u;
115637
+ function sameOptionalValue(left, right) {
115638
+ return left === right;
115639
+ }
115640
+ function hasIndependentColourAndTransform(left, right) {
115641
+ return COLOR_KEYFRAME.test(left.keyframeName) && TRANSFORM_KEYFRAME.test(right.keyframeName) || TRANSFORM_KEYFRAME.test(left.keyframeName) && COLOR_KEYFRAME.test(right.keyframeName);
115642
+ }
115643
+ function canComposeParallelSteps(left, right) {
115644
+ return hasIndependentColourAndTransform(left, right) && left.elementId !== "" && left.elementId === right.elementId && left.cssAnimation !== "" && right.cssAnimation !== "" && left.delayMs === right.delayMs && left.durationMs === right.durationMs && left.presetClass === right.presetClass && left.fillMode === right.fillMode && sameOptionalValue(left.holdEndState, right.holdEndState) && sameOptionalValue(left.hideAfterEffect, right.hideAfterEffect) && sameOptionalValue(left.pendingHideOnNextClick, right.pendingHideOnNextClick) && sameOptionalValue(left.seqConcurrent, right.seqConcurrent) && sameOptionalValue(left.seqNextAction, right.seqNextAction) && sameOptionalValue(left.seqPrevAction, right.seqPrevAction) && !left.command && !right.command && !left.build && !right.build && !left.soundPath && !right.soundPath && !left.stopSound && !right.stopSound && !left.restart && !right.restart && left.exclGroupId === void 0 && right.exclGroupId === void 0;
115645
+ }
115646
+ function composeParallelSteps(left, right) {
115647
+ const colorTargets = [.../* @__PURE__ */ new Set([...left.colorTargets ?? [], ...right.colorTargets ?? []])];
115648
+ return {
115649
+ ...left,
115650
+ cssAnimation: `${left.cssAnimation}, ${right.cssAnimation}`,
115651
+ colorTargets: colorTargets.length > 0 ? colorTargets : void 0
115652
+ };
115653
+ }
115654
+ var BACKGROUND_ANIMATION_ID_SUFFIX = "::pptx-bg";
115655
+ function resolveAnimationTargetId(animation) {
115656
+ const targetId = animation.targetId ?? "";
115657
+ if (targetId && animation.target?.type === "shape" && animation.target.backgroundOnly === true) {
115658
+ return `${targetId}${BACKGROUND_ANIMATION_ID_SUFFIX}`;
115659
+ }
115660
+ return targetId;
115661
+ }
115662
+ function clamp014(value) {
114640
115663
  return Math.max(0, Math.min(1, value));
114641
115664
  }
114642
115665
  function cssEasingForAnimation(anim) {
114643
- const accel = anim.accel !== void 0 && anim.accel > 0 ? clamp013(anim.accel) : 0;
114644
- const decel = anim.decel !== void 0 && anim.decel > 0 ? clamp013(anim.decel) : 0;
115666
+ const accel = anim.accel !== void 0 && anim.accel > 0 ? clamp014(anim.accel) : 0;
115667
+ const decel = anim.decel !== void 0 && anim.decel > 0 ? clamp014(anim.decel) : 0;
114645
115668
  if (accel === 0 && decel === 0) {
114646
115669
  return "ease";
114647
115670
  }
@@ -114650,11 +115673,11 @@ function cssEasingForAnimation(anim) {
114650
115673
  return `cubic-bezier(${x1}, 0, ${x2}, 1)`;
114651
115674
  }
114652
115675
  function stepColorTargets(anim, tavColorApplied) {
114653
- const targetAttribute = anim.colorAnimation?.targetAttribute ?? (tavColorApplied ? anim.attrName : void 0);
114654
- if (!targetAttribute) {
115676
+ const colorSource = anim.colorAnimation ?? (tavColorApplied ? anim.attrName : void 0);
115677
+ if (!colorSource) {
114655
115678
  return void 0;
114656
115679
  }
114657
- const targets = resolveColorAnimationTargets(targetAttribute);
115680
+ const targets = resolveColorAnimationTargets(colorSource);
114658
115681
  return targets.length > 0 ? targets : void 0;
114659
115682
  }
114660
115683
  function fallbackEffectForClass(presetClass) {
@@ -114676,17 +115699,22 @@ function buildTimeline(nativeAnimations) {
114676
115699
  entranceElementIds: /* @__PURE__ */ new Set(),
114677
115700
  keyframesCss: "",
114678
115701
  interactiveSequences: /* @__PURE__ */ new Map(),
115702
+ restartableInteractiveSequences: /* @__PURE__ */ new Set(),
114679
115703
  hoverSequences: /* @__PURE__ */ new Map()
114680
115704
  };
114681
115705
  }
114682
115706
  const regularAnims = [];
114683
115707
  const interactiveAnims = /* @__PURE__ */ new Map();
115708
+ const restartableInteractiveSequences = /* @__PURE__ */ new Set();
114684
115709
  const hoverAnims = [];
114685
115710
  for (const anim of nativeAnimations) {
114686
- if (anim.trigger === "onShapeClick" && anim.triggerShapeId) {
115711
+ if ((anim.interactiveSequence === true || anim.trigger === "onShapeClick") && anim.triggerShapeId) {
114687
115712
  const existing = interactiveAnims.get(anim.triggerShapeId) ?? [];
114688
115713
  existing.push(anim);
114689
115714
  interactiveAnims.set(anim.triggerShapeId, existing);
115715
+ if (anim.interactiveRestart === true) {
115716
+ restartableInteractiveSequences.add(anim.triggerShapeId);
115717
+ }
114690
115718
  } else if (anim.trigger === "onHover" && anim.targetId) {
114691
115719
  hoverAnims.push(anim);
114692
115720
  } else {
@@ -114699,6 +115727,7 @@ function buildTimeline(nativeAnimations) {
114699
115727
  const dynamicBlocks = [];
114700
115728
  let dynamicUid = 0;
114701
115729
  let currentGroup = [];
115730
+ let currentGroupLastParallelIndex;
114702
115731
  let currentGroupIsClick = false;
114703
115732
  let currentGroupAutoStart = false;
114704
115733
  let subGroupIndex;
@@ -114706,8 +115735,11 @@ function buildTimeline(nativeAnimations) {
114706
115735
  for (const anim of regularAnims) {
114707
115736
  const expandedSteps = expandIterateAnimation(anim);
114708
115737
  for (const singleAnim of expandedSteps) {
114709
- let effect = resolveEffect(singleAnim);
114710
- let dynamic = effect ? void 0 : buildDynamicKeyframe(singleAnim, dynamicUid++);
115738
+ let dynamic = hasAuthoredTransform(singleAnim) ? buildDynamicKeyframe(singleAnim, dynamicUid++) : void 0;
115739
+ let effect = dynamic ? void 0 : resolveEffect(singleAnim);
115740
+ if (!effect && !dynamic) {
115741
+ dynamic = buildDynamicKeyframe(singleAnim, dynamicUid++);
115742
+ }
114711
115743
  if (effect === "transparency" || !effect) {
114712
115744
  const tavOpacity = buildOpacityTavKeyframe(singleAnim, "pptx-tl-tav", dynamicUid);
114713
115745
  if (tavOpacity) {
@@ -114754,7 +115786,7 @@ function buildTimeline(nativeAnimations) {
114754
115786
  if (dynamic) {
114755
115787
  dynamicBlocks.push(dynamic.css);
114756
115788
  }
114757
- const elementId = isCommand ? "" : singleAnim.targetId ?? "";
115789
+ const elementId = isCommand ? "" : resolveAnimationTargetId(singleAnim);
114758
115790
  const effective = resolveAnimationStart(singleAnim);
114759
115791
  const trigger = effective.trigger;
114760
115792
  const baseDuration = isCommand ? 0 : singleAnim.durationMs ?? defaultDuration(singleAnim.presetClass);
@@ -114768,7 +115800,7 @@ function buildTimeline(nativeAnimations) {
114768
115800
  const triggerDelay = 0;
114769
115801
  const presetClass = isCommand ? "emph" : singleAnim.presetClass ?? "entr";
114770
115802
  const fill = fillModeForClass(singleAnim.presetClass);
114771
- const timing = isCommand ? { durationMs: 0, iterationCount: 1, holdEndState: false } : resolveEffectTiming(singleAnim, baseDuration);
115803
+ const timing = isCommand ? { durationMs: 0, iterationCount: 1, activeDurationMs: 0, holdEndState: false } : resolveEffectTiming(singleAnim, baseDuration);
114772
115804
  const duration = timing.durationMs;
114773
115805
  const iterCount = timing.iterationCount;
114774
115806
  const direction = singleAnim.autoReverse ? "alternate" : "normal";
@@ -114786,17 +115818,18 @@ function buildTimeline(nativeAnimations) {
114786
115818
  clickGroups.push(group2);
114787
115819
  }
114788
115820
  currentGroup = [];
115821
+ currentGroupLastParallelIndex = void 0;
114789
115822
  currentGroupIsClick = isOnClick || isFirstAnimation;
114790
115823
  currentGroupAutoStart = singleAnim.groupAutoStart === true && !effective.requiresInteraction;
114791
115824
  subGroupIndex = singleAnim.parGroupIndex;
114792
- subGroupStartMs = 0;
115825
+ subGroupStartMs = singleAnim.parGroupDelayMs ?? 0;
114793
115826
  }
114794
115827
  const prevStep = currentGroup.length > 0 ? currentGroup[currentGroup.length - 1] : void 0;
114795
115828
  let delayMs;
114796
- if (singleAnim.parGroupIndex !== void 0 && prevStep) {
115829
+ if (singleAnim.parGroupIndex !== void 0) {
114797
115830
  if (singleAnim.parGroupIndex !== subGroupIndex) {
114798
115831
  subGroupIndex = singleAnim.parGroupIndex;
114799
- subGroupStartMs = trigger === "withPrevious" ? prevStep.delayMs : prevStep.delayMs + prevStep.durationMs;
115832
+ subGroupStartMs = singleAnim.parGroupDelayMs ?? (prevStep ? trigger === "withPrevious" ? prevStep.delayMs : prevStep.delayMs + prevStep.durationMs : 0);
114800
115833
  }
114801
115834
  delayMs = subGroupStartMs + animDelay + triggerDelay;
114802
115835
  } else if (trigger === "withPrevious" && prevStep) {
@@ -114813,19 +115846,19 @@ function buildTimeline(nativeAnimations) {
114813
115846
  singleAnim,
114814
115847
  baseCssAnimation,
114815
115848
  timing.holdEndState,
114816
- delayMs + duration,
115849
+ delayMs + timing.activeDurationMs,
114817
115850
  `pptx-tl-dim-${dynamicUid++}`
114818
115851
  );
114819
115852
  if (afterFields.dimKeyframeBlock) {
114820
115853
  dynamicBlocks.push(afterFields.dimKeyframeBlock);
114821
115854
  }
114822
- currentGroup.push({
115855
+ const step = {
114823
115856
  elementId,
114824
115857
  cssAnimation: afterFields.cssAnimation,
114825
115858
  keyframeName: keyframe,
114826
115859
  trigger,
114827
115860
  delayMs,
114828
- durationMs: duration,
115861
+ durationMs: timing.activeDurationMs,
114829
115862
  fillMode: fill,
114830
115863
  presetClass,
114831
115864
  soundPath: singleAnim.soundPath,
@@ -114841,7 +115874,14 @@ function buildTimeline(nativeAnimations) {
114841
115874
  seqNextAction: singleAnim.seqNextAction,
114842
115875
  seqPrevAction: singleAnim.seqPrevAction,
114843
115876
  exclGroupId: singleAnim.exclGroupId
114844
- });
115877
+ };
115878
+ const previousParallelStep = currentGroup[currentGroup.length - 1];
115879
+ if (singleAnim.parGroupIndex !== void 0 && singleAnim.parGroupIndex === currentGroupLastParallelIndex && previousParallelStep && canComposeParallelSteps(previousParallelStep, step)) {
115880
+ currentGroup[currentGroup.length - 1] = composeParallelSteps(previousParallelStep, step);
115881
+ } else {
115882
+ currentGroup.push(step);
115883
+ }
115884
+ currentGroupLastParallelIndex = singleAnim.parGroupIndex;
114845
115885
  }
114846
115886
  }
114847
115887
  if (currentGroup.length > 0) {
@@ -114884,6 +115924,7 @@ function buildTimeline(nativeAnimations) {
114884
115924
  entranceElementIds: entranceIds,
114885
115925
  keyframesCss: keyframeBlocks.join("\n\n"),
114886
115926
  interactiveSequences,
115927
+ restartableInteractiveSequences,
114887
115928
  hoverSequences
114888
115929
  };
114889
115930
  }
@@ -114908,9 +115949,15 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
114908
115949
  for (const [shapeId, anims] of animsByKey) {
114909
115950
  const seqGroups = [];
114910
115951
  let seqGroup = [];
115952
+ let seqGroupLastParallelIndex;
115953
+ let subGroupIndex;
115954
+ let subGroupStartMs = 0;
114911
115955
  for (const anim of anims) {
114912
- let effect = resolveEffect(anim);
114913
- let dynamic = effect ? void 0 : buildDynamicKeyframe(anim, dynamicUid++);
115956
+ let dynamic = hasAuthoredTransform(anim) ? buildDynamicKeyframe(anim, dynamicUid++) : void 0;
115957
+ let effect = dynamic ? void 0 : resolveEffect(anim);
115958
+ if (!effect && !dynamic) {
115959
+ dynamic = buildDynamicKeyframe(anim, dynamicUid++);
115960
+ }
114914
115961
  if (effect === "transparency" || !effect) {
114915
115962
  const tavOpacity = buildOpacityTavKeyframe(anim, "pptx-tl-tav", dynamicUid);
114916
115963
  if (tavOpacity) {
@@ -114942,14 +115989,14 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
114942
115989
  if (dynamic) {
114943
115990
  dynamicBlocks.push(dynamic.css);
114944
115991
  }
114945
- const elementId = isCommand ? "" : anim.targetId ?? "";
115992
+ const elementId = isCommand ? "" : resolveAnimationTargetId(anim);
114946
115993
  const seqTrigger = anim.trigger ?? "onShapeClick";
114947
115994
  const baseDuration = isCommand ? 0 : anim.durationMs ?? defaultDuration(anim.presetClass);
114948
115995
  const animDelay = Math.max(anim.delayMs ?? 0, anim.triggerDelayMs ?? 0);
114949
115996
  const triggerDelay = 0;
114950
115997
  const presetClass = isCommand ? "emph" : anim.presetClass ?? "entr";
114951
115998
  const fill = fillModeForClass(anim.presetClass);
114952
- const timing = isCommand ? { durationMs: 0, iterationCount: 1, holdEndState: false } : resolveEffectTiming(anim, baseDuration);
115999
+ const timing = isCommand ? { durationMs: 0, iterationCount: 1, activeDurationMs: 0, holdEndState: false } : resolveEffectTiming(anim, baseDuration);
114953
116000
  const duration = timing.durationMs;
114954
116001
  const iterCount = timing.iterationCount;
114955
116002
  const direction = anim.autoReverse ? "alternate" : "normal";
@@ -114961,13 +116008,18 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
114961
116008
  seqGroups.push(finalizeClickGroup(seqGroup));
114962
116009
  seqGroup = [];
114963
116010
  }
116011
+ const prevStep = seqGroup.length > 0 ? seqGroup[seqGroup.length - 1] : void 0;
114964
116012
  let delayMs;
114965
- if (seqTrigger === "withPrevious" && seqGroup.length > 0) {
114966
- const prev = seqGroup[seqGroup.length - 1];
114967
- delayMs = prev.delayMs + animDelay + triggerDelay;
114968
- } else if ((seqTrigger === "afterPrevious" || seqTrigger === "afterDelay") && seqGroup.length > 0) {
114969
- const prev = seqGroup[seqGroup.length - 1];
114970
- delayMs = prev.delayMs + prev.durationMs + animDelay + triggerDelay;
116013
+ if (anim.parGroupIndex !== void 0) {
116014
+ if (anim.parGroupIndex !== subGroupIndex) {
116015
+ subGroupIndex = anim.parGroupIndex;
116016
+ subGroupStartMs = anim.parGroupDelayMs ?? (prevStep ? seqTrigger === "withPrevious" ? prevStep.delayMs : prevStep.delayMs + prevStep.durationMs : 0);
116017
+ }
116018
+ delayMs = subGroupStartMs + animDelay + triggerDelay;
116019
+ } else if (seqTrigger === "withPrevious" && prevStep) {
116020
+ delayMs = prevStep.delayMs + animDelay + triggerDelay;
116021
+ } else if ((seqTrigger === "afterPrevious" || seqTrigger === "afterDelay") && prevStep) {
116022
+ delayMs = prevStep.delayMs + prevStep.durationMs + animDelay + triggerDelay;
114971
116023
  } else {
114972
116024
  delayMs = animDelay + triggerDelay;
114973
116025
  }
@@ -114978,19 +116030,19 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
114978
116030
  anim,
114979
116031
  baseCssAnimation,
114980
116032
  timing.holdEndState,
114981
- delayMs + duration,
116033
+ delayMs + timing.activeDurationMs,
114982
116034
  `pptx-tl-dim-${dynamicUid++}`
114983
116035
  );
114984
116036
  if (afterFields.dimKeyframeBlock) {
114985
116037
  dynamicBlocks.push(afterFields.dimKeyframeBlock);
114986
116038
  }
114987
- seqGroup.push({
116039
+ const step = {
114988
116040
  elementId,
114989
116041
  cssAnimation: afterFields.cssAnimation,
114990
116042
  keyframeName: keyframe,
114991
116043
  trigger: seqTrigger,
114992
116044
  delayMs,
114993
- durationMs: duration,
116045
+ durationMs: timing.activeDurationMs,
114994
116046
  fillMode: fill,
114995
116047
  presetClass,
114996
116048
  soundPath: anim.soundPath,
@@ -115006,7 +116058,14 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
115006
116058
  seqNextAction: anim.seqNextAction,
115007
116059
  seqPrevAction: anim.seqPrevAction,
115008
116060
  exclGroupId: anim.exclGroupId
115009
- });
116061
+ };
116062
+ const previousParallelStep = seqGroup[seqGroup.length - 1];
116063
+ if (anim.parGroupIndex !== void 0 && anim.parGroupIndex === seqGroupLastParallelIndex && previousParallelStep && canComposeParallelSteps(previousParallelStep, step)) {
116064
+ seqGroup[seqGroup.length - 1] = composeParallelSteps(previousParallelStep, step);
116065
+ } else {
116066
+ seqGroup.push(step);
116067
+ }
116068
+ seqGroupLastParallelIndex = anim.parGroupIndex;
115010
116069
  }
115011
116070
  if (seqGroup.length > 0) {
115012
116071
  seqGroups.push(finalizeClickGroup(seqGroup));
@@ -115358,14 +116417,20 @@ var TimelineEngine = class _TimelineEngine {
115358
116417
  advanceInteractive(triggerShapeId, nowMs = Date.now()) {
115359
116418
  const groups = this.timeline.interactiveSequences.get(triggerShapeId);
115360
116419
  const currentIdx = this.interactiveGroupIndexes.get(triggerShapeId) ?? -1;
115361
- const result = this.advanceSequenceGroup(
116420
+ let result = this.advanceSequenceGroup(
115362
116421
  groups,
115363
116422
  currentIdx,
115364
116423
  this.interactiveGroupStartedAtMs.get(triggerShapeId),
115365
116424
  nowMs
115366
116425
  );
115367
116426
  if (result === "exhausted") {
115368
- return null;
116427
+ if (!this.timeline.restartableInteractiveSequences?.has(triggerShapeId)) {
116428
+ return null;
116429
+ }
116430
+ result = this.advanceSequenceGroup(groups, -1, void 0, nowMs);
116431
+ if (result === "exhausted") {
116432
+ return null;
116433
+ }
115369
116434
  }
115370
116435
  if (result === "blocked") {
115371
116436
  return EMPTY_CLICK_GROUP;
@@ -115563,7 +116628,7 @@ function buildPreviewAnimation(preset, options) {
115563
116628
  if (!effectName) {
115564
116629
  return void 0;
115565
116630
  }
115566
- const keyframeName = `pptx-${effectName}`;
116631
+ const keyframeName2 = `pptx-${effectName}`;
115567
116632
  const keyframesCss = getEffectKeyframes(effectName);
115568
116633
  if (!keyframesCss) {
115569
116634
  return void 0;
@@ -115571,9 +116636,9 @@ function buildPreviewAnimation(preset, options) {
115571
116636
  const duration = options?.durationMs ?? 600;
115572
116637
  const easing = timingCurveToCss(options?.timingCurve, options?.cubicBezier);
115573
116638
  return {
115574
- keyframeName,
116639
+ keyframeName: keyframeName2,
115575
116640
  keyframesCss,
115576
- cssAnimation: `${keyframeName} ${duration}ms ${easing} 0ms 1 normal both`,
116641
+ cssAnimation: `${keyframeName2} ${duration}ms ${easing} 0ms 1 normal both`,
115577
116642
  durationMs: duration
115578
116643
  };
115579
116644
  }
@@ -115895,16 +116960,19 @@ function motionPathNativeAnimations(slide) {
115895
116960
  durationMs: animation.durationMs ?? DEFAULT_MOTION_PATH_DURATION_MS,
115896
116961
  delayMs: animation.delayMs ?? 0,
115897
116962
  motionPath: animation.motionPath,
115898
- motionPathEditMode: animation.motionPathEditMode ?? "relative"
116963
+ motionPathEditMode: animation.motionPathEditMode ?? "relative",
116964
+ motionPathRotationAngle: animation.motionPathRotationAngle,
116965
+ motionPathRotationCenterX: animation.motionPathRotationCenterX,
116966
+ motionPathRotationCenterY: animation.motionPathRotationCenterY
115899
116967
  }));
115900
116968
  }
115901
116969
  function buildMotionPathPreview(args) {
115902
- const keyframeName = `pptx-motion-preview-${args.uid ?? 0}`;
116970
+ const keyframeName2 = `pptx-motion-preview-${args.uid ?? 0}`;
115903
116971
  const keyframes = buildMotionPathKeyframes({
115904
116972
  path: args.path,
115905
116973
  slideWidth: args.slideWidth,
115906
116974
  slideHeight: args.slideHeight,
115907
- keyframeName
116975
+ keyframeName: keyframeName2
115908
116976
  });
115909
116977
  if (!keyframes) {
115910
116978
  return void 0;
@@ -115913,9 +116981,9 @@ function buildMotionPathPreview(args) {
115913
116981
  const delayMs = args.delayMs ?? 0;
115914
116982
  const easing = timingCurveToCss(args.timingCurve);
115915
116983
  return {
115916
- keyframeName,
116984
+ keyframeName: keyframeName2,
115917
116985
  keyframesCss: keyframes.css,
115918
- cssAnimation: `${keyframeName} ${durationMs}ms ${easing} ${delayMs}ms 1 normal both`,
116986
+ cssAnimation: `${keyframeName2} ${durationMs}ms ${easing} ${delayMs}ms 1 normal both`,
115919
116987
  durationMs
115920
116988
  };
115921
116989
  }
@@ -115962,8 +117030,9 @@ var PresentationAnimationController = class _PresentationAnimationController {
115962
117030
  const engine = TimelineEngine.fromAnimations(expandedAnims);
115963
117031
  const elementIds = slide.elements.map((element) => element.id);
115964
117032
  for (const anim of expandedAnims) {
115965
- if (anim.targetId && anim.targetId.includes(TEXT_BUILD_ID_SEP)) {
115966
- elementIds.push(anim.targetId);
117033
+ const targetId = resolveAnimationTargetId(anim);
117034
+ if (targetId.includes(TEXT_BUILD_ID_SEP)) {
117035
+ elementIds.push(targetId);
115967
117036
  }
115968
117037
  }
115969
117038
  return new _PresentationAnimationController(engine, elementIds);
@@ -116892,8 +117961,8 @@ function apply3dEffects(base, scene3d, shape3d, fillColorFallback) {
116892
117961
  if (perspective) {
116893
117962
  base.perspective = perspective;
116894
117963
  }
116895
- const hasRotation = rotateX !== 0 || rotateY !== 0 || rotateZ !== 0;
116896
- if (hasRotation) {
117964
+ const hasRotation2 = rotateX !== 0 || rotateY !== 0 || rotateZ !== 0;
117965
+ if (hasRotation2) {
116897
117966
  const transforms = [];
116898
117967
  if (rotateX !== 0) {
116899
117968
  transforms.push(`rotateX(${rotateX}deg)`);
@@ -116918,7 +117987,7 @@ function apply3dEffects(base, scene3d, shape3d, fillColorFallback) {
116918
117987
  const zTranslate = `translateZ(${halfDepth}px)`;
116919
117988
  base.transform = base.transform ? `${base.transform} ${zTranslate}` : zTranslate;
116920
117989
  }
116921
- if (hasRotation || perspective || shape3d) {
117990
+ if (hasRotation2 || perspective || shape3d) {
116922
117991
  base.willChange = "transform";
116923
117992
  base.transformStyle = "preserve-3d";
116924
117993
  }
@@ -118970,7 +120039,7 @@ function getImageFitStyle(el) {
118970
120039
  height: "100%",
118971
120040
  objectFit: "fill"
118972
120041
  };
118973
- if (!isImageLikeElement(el)) {
120042
+ if (!isImageLikeElement(el) && el.type !== "media") {
118974
120043
  return uncropped;
118975
120044
  }
118976
120045
  const { placement, crop } = imageFitTransformParts(el);
@@ -118991,7 +120060,7 @@ function getImageFitStyle(el) {
118991
120060
  }
118992
120061
  var IDENTITY_TRANSFORM_PAIR = "translate(0%, 0%) scale(1, 1)";
118993
120062
  function imageFitTransformParts(el) {
118994
- if (!isImageLikeElement(el)) {
120063
+ if (!isImageLikeElement(el) && el.type !== "media") {
118995
120064
  return { placement: "", crop: "" };
118996
120065
  }
118997
120066
  const frLeft = el.fillRectLeft ?? 0;
@@ -125588,8 +126657,8 @@ function buildTextBody3DSceneStyle(textStyle) {
125588
126657
  if (!perspective && (rotateX !== 0 || rotateY !== 0 || rotateZ !== 0)) {
125589
126658
  perspective = "800px";
125590
126659
  }
125591
- const hasRotation = rotateX !== 0 || rotateY !== 0 || rotateZ !== 0;
125592
- const hasScene = hasRotation || Boolean(perspective);
126660
+ const hasRotation2 = rotateX !== 0 || rotateY !== 0 || rotateZ !== 0;
126661
+ const hasScene = hasRotation2 || Boolean(perspective);
125593
126662
  if (!hasScene) {
125594
126663
  return void 0;
125595
126664
  }
@@ -125597,7 +126666,7 @@ function buildTextBody3DSceneStyle(textStyle) {
125597
126666
  if (perspective) {
125598
126667
  style.perspective = perspective;
125599
126668
  }
125600
- if (hasRotation) {
126669
+ if (hasRotation2) {
125601
126670
  const transforms = [];
125602
126671
  if (rotateX !== 0) {
125603
126672
  transforms.push(`rotateX(${rotateX}deg)`);
@@ -126437,7 +127506,8 @@ function buildParagraphs(element, fieldContext, segmentOverrides) {
126437
127506
  paragraphIndents?.[paraIndex],
126438
127507
  firstSeg?.paragraphLevel
126439
127508
  );
126440
- const bulletStyle = buildBulletMarkerStyle(bullet, firstSeg, fontScale, indent.textIndentPx);
127509
+ const textIndentPx = indent.textIndentPx !== void 0 && (indent.textIndentPx >= 0 || indent.marginLeftPx !== void 0 || bullet !== void 0) ? indent.textIndentPx : void 0;
127510
+ const bulletStyle = buildBulletMarkerStyle(bullet, firstSeg, fontScale, textIndentPx);
126441
127511
  const spacing = resolveParagraphSpacing({
126442
127512
  paraProps: propsCarrier?.paragraphProperties,
126443
127513
  bodyStyle,
@@ -126478,7 +127548,7 @@ function buildParagraphs(element, fieldContext, segmentOverrides) {
126478
127548
  bulletPicture: bullet?.picture,
126479
127549
  bulletStyle,
126480
127550
  marginLeftPx: indent.marginLeftPx,
126481
- textIndentPx: indent.textIndentPx,
127551
+ textIndentPx,
126482
127552
  lineHeight: spacing.lineHeight,
126483
127553
  spaceBeforePx: spacing.spaceBeforePx,
126484
127554
  spaceAfterPx: spacing.spaceAfterPx,
@@ -129391,21 +130461,9 @@ function solveShapeAdjustments(solvers, localX, localY) {
129391
130461
  }
129392
130462
  var SHAPE_ADJUSTMENT_MIN = 0;
129393
130463
  var SHAPE_ADJUSTMENT_MAX = 5e4;
129394
- var DEFAULT_ROUND_RECT_ADJUSTMENT = 16667;
129395
130464
  function clampShapeAdjustmentValue(value) {
129396
130465
  return Math.max(SHAPE_ADJUSTMENT_MIN, Math.min(SHAPE_ADJUSTMENT_MAX, Math.round(value)));
129397
130466
  }
129398
- function getRoundRectAdjustmentValue(element) {
129399
- const adjustment = element.shapeAdjustments?.adj;
129400
- if (typeof adjustment === "number" && Number.isFinite(adjustment)) {
129401
- return clampShapeAdjustmentValue(adjustment);
129402
- }
129403
- return DEFAULT_ROUND_RECT_ADJUSTMENT;
129404
- }
129405
- function getRoundRectRadiusPx2(element) {
129406
- const normalizedAdjustment = getRoundRectAdjustmentValue(element) / SHAPE_ADJUSTMENT_MAX;
129407
- return Math.min(Math.max(element.width, 1), Math.max(element.height, 1)) * 0.5 * normalizedAdjustment;
129408
- }
129409
130467
  function getShapeAdjustmentHandleDescriptors(element) {
129410
130468
  if (!hasShapeProperties(element) || element.type === "connector") {
129411
130469
  return [];
@@ -130177,6 +131235,7 @@ var COMPLEX_SLIDE_FIELDS = {
130177
131235
  activeXControls: "_ax",
130178
131236
  legacyVmlElements: "_lvml",
130179
131237
  backgroundPattern: "_bp",
131238
+ backgroundImageProperties: "_bip",
130180
131239
  modernCommentPart: "_mc",
130181
131240
  headerFooterFlags: "_hff",
130182
131241
  slideSynchronization: "_sync"
@@ -136160,13 +137219,59 @@ function buildPieChart3DDataForElement(element, options) {
136160
137219
  const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: pieSeries.values.length }, (_, i) => String(i + 1));
136161
137220
  return buildPieChart3DData(chartData, categoryLabels, options);
136162
137221
  }
136163
- var AVERAGE_ADVANCE_RATIO = 0.5;
137222
+ function estimatedGlyphAdvanceRatio(glyph) {
137223
+ if (/\p{Mark}/u.test(glyph)) {
137224
+ return 0;
137225
+ }
137226
+ if (/\s/u.test(glyph)) {
137227
+ return 0.33;
137228
+ }
137229
+ if (/[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Extended_Pictographic}]/u.test(
137230
+ glyph
137231
+ )) {
137232
+ return 1;
137233
+ }
137234
+ if (/[A-Z]/u.test(glyph)) {
137235
+ return 0.65;
137236
+ }
137237
+ if (/[a-z0-9]/u.test(glyph)) {
137238
+ return 0.55;
137239
+ }
137240
+ if (/[,.;:!?()\u005b\u005d{}'"`\-_/\\]/u.test(glyph)) {
137241
+ return 0.35;
137242
+ }
137243
+ return 0.6;
137244
+ }
137245
+ function estimatedTextWidth(glyphs, fontSize) {
137246
+ return glyphs.reduce((sum, glyph) => sum + estimatedGlyphAdvanceRatio(glyph) * fontSize, 0);
137247
+ }
137248
+ var HANGING_PUNCTUATION_RE = /^[\u3001\u3002\uff0c\uff0e\uff01\uff1f\uff1b\uff1a\u3009\u300b\u300d\u300f\u3011\u3015\u3017\u3019\u301b\uff09\uff3d\uff5d\u2019\u201d\u00bb\u203a]$/u;
137249
+ var BREAKABLE_GLYPH_RE = /^[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Extended_Pictographic}]$/u;
137250
+ function estimatedWrapUnits(text2) {
137251
+ const units = [];
137252
+ let unbreakableRun = "";
137253
+ const flushRun = () => {
137254
+ if (unbreakableRun.length > 0) {
137255
+ units.push(unbreakableRun);
137256
+ unbreakableRun = "";
137257
+ }
137258
+ };
137259
+ for (const glyph of Array.from(text2)) {
137260
+ if (/\s/u.test(glyph) || BREAKABLE_GLYPH_RE.test(glyph)) {
137261
+ flushRun();
137262
+ units.push(glyph);
137263
+ } else {
137264
+ unbreakableRun += glyph;
137265
+ }
137266
+ }
137267
+ flushRun();
137268
+ return units;
137269
+ }
136164
137270
  function wrapTextByEstimatedWidth(text2, maxWidth, fontSize, options = {}) {
136165
137271
  if (!text2 || text2.trim().length === 0) {
136166
137272
  return [];
136167
137273
  }
136168
- const charactersPerLine = Math.floor(maxWidth / Math.max(fontSize * AVERAGE_ADVANCE_RATIO, 1));
136169
- if (charactersPerLine <= 0) {
137274
+ if (!(maxWidth > 0) || !(fontSize > 0)) {
136170
137275
  return [];
136171
137276
  }
136172
137277
  const lines = [];
@@ -136178,18 +137283,31 @@ function wrapTextByEstimatedWidth(text2, maxWidth, fontSize, options = {}) {
136178
137283
  continue;
136179
137284
  }
136180
137285
  let current = "";
136181
- for (const word of paragraph.split(/\s+/u)) {
136182
- if (current.length === 0) {
136183
- current = word;
136184
- } else if (current.length + 1 + word.length <= charactersPerLine) {
136185
- current += ` ${word}`;
136186
- } else {
136187
- lines.push(current);
136188
- current = word;
137286
+ let pendingWhitespace = false;
137287
+ for (const unit of estimatedWrapUnits(paragraph)) {
137288
+ if (/^\s+$/u.test(unit)) {
137289
+ pendingWhitespace = current.length > 0;
137290
+ continue;
137291
+ }
137292
+ const separator = pendingWhitespace && current.length > 0 ? " " : "";
137293
+ const candidate = `${current}${separator}${unit}`;
137294
+ if (current.length === 0 || estimatedTextWidth(Array.from(candidate), fontSize) <= maxWidth) {
137295
+ current = candidate;
137296
+ pendingWhitespace = false;
137297
+ continue;
137298
+ }
137299
+ if (HANGING_PUNCTUATION_RE.test(unit)) {
137300
+ current += unit;
137301
+ pendingWhitespace = false;
137302
+ continue;
136189
137303
  }
136190
- }
136191
- if (current.length > 0) {
136192
137304
  lines.push(current);
137305
+ current = unit;
137306
+ pendingWhitespace = false;
137307
+ }
137308
+ const completed = current.trimEnd();
137309
+ if (completed.length > 0) {
137310
+ lines.push(completed);
136193
137311
  }
136194
137312
  }
136195
137313
  return lines;
@@ -136201,7 +137319,7 @@ function centeredSvgTextLines(text2, fontSize, options = {}) {
136201
137319
  if (lines.length === 0) {
136202
137320
  return [{ text: "", y: centerY }];
136203
137321
  }
136204
- const lineHeight = fontSize * LINE_HEIGHT_RATIO;
137322
+ const lineHeight = options.lineHeight ?? fontSize * (options.lineHeightRatio ?? LINE_HEIGHT_RATIO);
136205
137323
  const blockTop = centerY - lines.length * lineHeight / 2;
136206
137324
  return lines.map((line22, index) => ({
136207
137325
  text: line22,
@@ -136248,6 +137366,12 @@ function buildChromeStyle(chrome) {
136248
137366
  return s;
136249
137367
  }
136250
137368
  var TEXT_WIDTH_FRACTION = 0.82;
137369
+ var CJK_SMARTART_TEXT_RE = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
137370
+ var CJK_SMARTART_LINE_HEIGHT_RATIO = 1.33;
137371
+ var DEFAULT_SMARTART_LINE_HEIGHT_RATIO = 1.2;
137372
+ function drawingTextBaseLineHeightRatio(text2) {
137373
+ return CJK_SMARTART_TEXT_RE.test(text2 ?? "") ? CJK_SMARTART_LINE_HEIGHT_RATIO : DEFAULT_SMARTART_LINE_HEIGHT_RATIO;
137374
+ }
136251
137375
  function underlyingFill(shape, shapes, index) {
136252
137376
  const centerX = shape.x + shape.width / 2;
136253
137377
  const centerY = shape.y + shape.height / 2;
@@ -136272,17 +137396,27 @@ function computeDrawingViewBox(shapes) {
136272
137396
  let maxX = -Infinity;
136273
137397
  let maxY = -Infinity;
136274
137398
  for (const s of shapes) {
136275
- if (s.x < minX) {
136276
- minX = s.x;
137399
+ const shapeMinX = Math.min(s.x, s.textFrameX ?? s.x);
137400
+ const shapeMinY = Math.min(s.y, s.textFrameY ?? s.y);
137401
+ const shapeMaxX = Math.max(
137402
+ s.x + s.width,
137403
+ (s.textFrameX ?? s.x) + (s.textFrameWidth ?? s.width)
137404
+ );
137405
+ const shapeMaxY = Math.max(
137406
+ s.y + s.height,
137407
+ (s.textFrameY ?? s.y) + (s.textFrameHeight ?? s.height)
137408
+ );
137409
+ if (shapeMinX < minX) {
137410
+ minX = shapeMinX;
136277
137411
  }
136278
- if (s.y < minY) {
136279
- minY = s.y;
137412
+ if (shapeMinY < minY) {
137413
+ minY = shapeMinY;
136280
137414
  }
136281
- if (s.x + s.width > maxX) {
136282
- maxX = s.x + s.width;
137415
+ if (shapeMaxX > maxX) {
137416
+ maxX = shapeMaxX;
136283
137417
  }
136284
- if (s.y + s.height > maxY) {
136285
- maxY = s.y + s.height;
137418
+ if (shapeMaxY > maxY) {
137419
+ maxY = shapeMaxY;
136286
137420
  }
136287
137421
  }
136288
137422
  if (!Number.isFinite(minX)) {
@@ -136326,10 +137460,23 @@ function resolveShapeKind(shape, hasImage) {
136326
137460
  return "image";
136327
137461
  }
136328
137462
  const normalized = (shape.shapeType ?? "").trim().toLowerCase();
136329
- if (normalized === "chevron" || normalized === "homeplate") {
136330
- return "polygon";
137463
+ if (normalized === "ellipse" || normalized === "oval") {
137464
+ return "ellipse";
137465
+ }
137466
+ const identityPresets = /* @__PURE__ */ new Set(["rect", "flowchartprocess", "roundrect"]);
137467
+ return identityPresets.has(normalized) || normalized.length === 0 ? "rect" : "path";
137468
+ }
137469
+ function drawingShapeTransform(shape, cx, cy) {
137470
+ const transforms = [];
137471
+ if (shape.rotation) {
137472
+ transforms.push(`rotate(${shape.rotation} ${cx} ${cy})`);
137473
+ }
137474
+ if (shape.flipHorizontal || shape.flipVertical) {
137475
+ transforms.push(
137476
+ `translate(${cx} ${cy}) scale(${shape.flipHorizontal ? -1 : 1} ${shape.flipVertical ? -1 : 1}) translate(${-cx} ${-cy})`
137477
+ );
136331
137478
  }
136332
- return getShapeType(shape.shapeType) === "ellipse" ? "ellipse" : "rect";
137479
+ return transforms.length > 0 ? transforms.join(" ") : void 0;
136333
137480
  }
136334
137481
  function projectDrawingShapes(elementId, shapes, viewBox, palette, style) {
136335
137482
  const { minX, minY } = viewBox;
@@ -136344,12 +137491,38 @@ function projectDrawingShapes(elementId, shapes, viewBox, palette, style) {
136344
137491
  const cx = relX + shape.width / 2;
136345
137492
  const cy = relY + shape.height / 2;
136346
137493
  const stroke = shape.strokeColor ?? (sw > 0 ? "rgba(255,255,255,0.3)" : "none");
136347
- const transform = shape.rotation !== void 0 ? `rotate(${shape.rotation} ${cx} ${cy})` : void 0;
137494
+ const transform = drawingShapeTransform(shape, cx, cy);
137495
+ const presetGeometry = kind === "path" ? getPresetShapeVectorGeometry(
137496
+ shape.shapeType,
137497
+ shape.width,
137498
+ shape.height,
137499
+ shape.shapeAdjustments
137500
+ ) : void 0;
136348
137501
  const fontSize = shape.fontSize ?? Math.max(8, Math.min(14, shape.height * 0.2));
137502
+ const hasTextFrame = Number.isFinite(shape.textFrameX) && Number.isFinite(shape.textFrameY) && Number.isFinite(shape.textFrameWidth) && Number.isFinite(shape.textFrameHeight) && (shape.textFrameWidth ?? 0) > 0 && (shape.textFrameHeight ?? 0) > 0;
137503
+ const textFrameX = (hasTextFrame ? shape.textFrameX : shape.x) - minX;
137504
+ const textFrameY = (hasTextFrame ? shape.textFrameY : shape.y) - minY;
137505
+ const textFrameWidth = hasTextFrame ? shape.textFrameWidth : shape.width;
137506
+ const textFrameHeight = hasTextFrame ? shape.textFrameHeight : shape.height;
137507
+ const textInsetLeft = shape.textInsetLeft ?? 0;
137508
+ const textInsetRight = shape.textInsetRight ?? 0;
137509
+ const textInsetTop = shape.textInsetTop ?? 0;
137510
+ const textInsetBottom = shape.textInsetBottom ?? 0;
137511
+ const textContentWidth = Math.max(1, textFrameWidth - textInsetLeft - textInsetRight);
137512
+ const textContentHeight = Math.max(1, textFrameHeight - textInsetTop - textInsetBottom);
137513
+ const textCenterX = textFrameX + textInsetLeft + textContentWidth / 2;
137514
+ const textCenterY = textFrameY + textInsetTop + textContentHeight / 2;
137515
+ const textWrapWidth = hasTextFrame ? textContentWidth : shape.width * TEXT_WIDTH_FRACTION;
137516
+ const authoredLineHeightRatio = shape.lineHeightRatio ?? 1;
137517
+ const lineHeightRatio = drawingTextBaseLineHeightRatio(shape.text) * authoredLineHeightRatio + (shape.lineSpacingAfterRatio ?? 0);
137518
+ const lineHeight = shape.lineHeight !== void 0 || shape.lineSpacingAfter !== void 0 ? (shape.lineHeight ?? fontSize * drawingTextBaseLineHeightRatio(shape.text) * authoredLineHeightRatio) + (shape.lineSpacingAfter ?? 0) : void 0;
136349
137519
  return {
136350
137520
  key: `${elementId}-dsp-${shape.id}-${i}`,
136351
137521
  kind,
136352
- ...kind === "polygon" ? { points: chevronPoints(relX, relY, shape.width, shape.height) } : {},
137522
+ ...presetGeometry ? {
137523
+ pathData: presetGeometry.d,
137524
+ pathTransform: [transform, `translate(${relX} ${relY})`].filter(Boolean).join(" ")
137525
+ } : {},
136353
137526
  ...gradient ? { gradient } : {},
136354
137527
  x: relX,
136355
137528
  y: relY,
@@ -136364,13 +137537,20 @@ function projectDrawingShapes(elementId, shapes, viewBox, palette, style) {
136364
137537
  transform,
136365
137538
  imageUrl: shape.fillImageUrl,
136366
137539
  textLines: shape.text ? centeredSvgTextLines(shape.text, fontSize, {
136367
- maxWidth: shape.width * TEXT_WIDTH_FRACTION,
136368
- centerY: cy
137540
+ maxWidth: textWrapWidth,
137541
+ centerY: textCenterY,
137542
+ lineHeight,
137543
+ lineHeightRatio
136369
137544
  }) : [],
136370
- textX: cx,
136371
- textY: cy,
137545
+ textX: textCenterX,
137546
+ textY: textCenterY,
137547
+ textWidth: textContentWidth,
137548
+ textHeight: textContentHeight,
136372
137549
  fontColor: shape.fontColor ?? drawingShapeLabelColor(shape, shapes, i, fill),
136373
- fontSize
137550
+ fontSize,
137551
+ fontFamily: shape.fontFamily ? getSubstituteFontFamily(shape.fontFamily) : void 0,
137552
+ fontWeight: shape.fontWeight,
137553
+ fontStyle: shape.fontStyle
136374
137554
  };
136375
137555
  });
136376
137556
  }
@@ -136520,7 +137700,7 @@ function resolveSlideSizeSelection(input) {
136520
137700
  }
136521
137701
  var EXPORT_ASSEMBLING_PERCENT = 95;
136522
137702
  var EXPORT_DONE_PERCENT = 100;
136523
- function clampPercent(value) {
137703
+ function clampPercent2(value) {
136524
137704
  if (Number.isNaN(value)) {
136525
137705
  return 0;
136526
137706
  }
@@ -136530,13 +137710,13 @@ function slideProgressPercent(current, total, span = 90) {
136530
137710
  if (total <= 0) {
136531
137711
  return 0;
136532
137712
  }
136533
- return clampPercent(current / total * span);
137713
+ return clampPercent2(current / total * span);
136534
137714
  }
136535
137715
  function recordProgressPercent(current, total) {
136536
137716
  if (total <= 0) {
136537
137717
  return 45;
136538
137718
  }
136539
- return clampPercent(45 + current / total * 45);
137719
+ return clampPercent2(45 + current / total * 45);
136540
137720
  }
136541
137721
  function slideStatusLabel(verb, current, total) {
136542
137722
  return `${verb} slide ${current + 1} of ${total}...`;
@@ -142744,7 +143924,8 @@ function masterViewParts(document2, target) {
142744
143924
  masterIndex: target.masterIndex,
142745
143925
  elements: master.elements ?? [],
142746
143926
  backgroundColor: master.backgroundColor,
142747
- backgroundImage: master.backgroundImage
143927
+ backgroundImage: master.backgroundImage,
143928
+ backgroundImageProperties: master.backgroundImageProperties
142748
143929
  };
142749
143930
  const layout = target.layoutIndex === null ? void 0 : master.layouts?.[target.layoutIndex];
142750
143931
  if (!layout || target.layoutIndex === null) {
@@ -142759,7 +143940,8 @@ function masterViewParts(document2, target) {
142759
143940
  layoutIndex: target.layoutIndex,
142760
143941
  elements: layout.elements ?? [],
142761
143942
  backgroundColor: layout.backgroundColor ?? master.backgroundColor,
142762
- backgroundImage: layout.backgroundImage ?? master.backgroundImage
143943
+ backgroundImage: layout.backgroundImage ?? master.backgroundImage,
143944
+ backgroundImageProperties: layout.backgroundImage ? layout.backgroundImageProperties : master.backgroundImageProperties
142763
143945
  }
142764
143946
  ];
142765
143947
  }
@@ -142770,7 +143952,8 @@ function auxiliaryParts(kind, part) {
142770
143952
  path: part.path,
142771
143953
  elements: part.elements ?? [],
142772
143954
  backgroundColor: part.backgroundColor,
142773
- backgroundImage: part.backgroundImage
143955
+ backgroundImage: part.backgroundImage,
143956
+ backgroundImageProperties: part.backgroundImageProperties
142774
143957
  }
142775
143958
  ] : [];
142776
143959
  }
@@ -142789,7 +143972,8 @@ function masterViewPseudoSlide(document2, target) {
142789
143972
  slideNumber: 0,
142790
143973
  elements: parts.flatMap((part) => [...part.elements]),
142791
143974
  backgroundColor: primary.backgroundColor,
142792
- backgroundImage: primary.backgroundImage
143975
+ backgroundImage: primary.backgroundImage,
143976
+ backgroundImageProperties: primary.backgroundImageProperties
142793
143977
  };
142794
143978
  }
142795
143979
  function masterViewElements(document2, target) {
@@ -145907,7 +147091,7 @@ function buildPrintHtmlDocument(options) {
145907
147091
  </html>`;
145908
147092
  }
145909
147093
  function openPendingPrintWindow(preparingLabel) {
145910
- const printWindow = window.open("", "_blank", "noopener,noreferrer");
147094
+ const printWindow = window.open("", "_blank");
145911
147095
  if (!printWindow) {
145912
147096
  return null;
145913
147097
  }
@@ -146298,7 +147482,7 @@ exports.chartPreserveAspectRatio = chartPreserveAspectRatio;
146298
147482
  exports.clampCropValue = clampCropValue;
146299
147483
  exports.clampNotesFontSize = clampNotesFontSize;
146300
147484
  exports.clampOptionNumber = clampOptionNumber;
146301
- exports.clampPercent = clampPercent;
147485
+ exports.clampPercent2 = clampPercent2;
146302
147486
  exports.clampSorterZoom = clampSorterZoom;
146303
147487
  exports.clampTransitionNumber = clampTransitionNumber;
146304
147488
  exports.clampUnitInterval = clampUnitInterval2;
@@ -146437,6 +147621,7 @@ exports.generateNibMarks = generateNibMarks;
146437
147621
  exports.generateNoteLineCount = generateNoteLineCount;
146438
147622
  exports.generatePressureCircles = generatePressureCircles;
146439
147623
  exports.generateTicks = generateTicks;
147624
+ exports.getAnimationColorBaseStyle = getAnimationColorBaseStyle;
146440
147625
  exports.getAnimationInitialStyle = getAnimationInitialStyle;
146441
147626
  exports.getAriaLabel = getAriaLabel;
146442
147627
  exports.getAriaRole = getAriaRole;
@@ -146481,9 +147666,8 @@ exports.getOverflowSegments = getOverflowSegments;
146481
147666
  exports.getPatternSvg = getPatternSvg;
146482
147667
  exports.getPendingSelectionRestore = getPendingSelectionRestore;
146483
147668
  exports.getPresetShapeClipPath = getPresetShapeClipPath;
147669
+ exports.getPresetShapeVectorGeometry = getPresetShapeVectorGeometry;
146484
147670
  exports.getPrintableArea = getPrintableArea;
146485
- exports.getResolvedShapeClipPath = getResolvedShapeClipPath;
146486
- exports.getRoundRectRadiusPx2 = getRoundRectRadiusPx2;
146487
147671
  exports.getSessionTabId = getSessionTabId;
146488
147672
  exports.getShapeAdjustmentHandleDescriptors = getShapeAdjustmentHandleDescriptors;
146489
147673
  exports.getShapeConnectionSites = getShapeConnectionSites;
@@ -146541,6 +147725,7 @@ exports.isStrokeOnlyPresetElement = isStrokeOnlyPresetElement;
146541
147725
  exports.isSupportedPresentationFile = isSupportedPresentationFile;
146542
147726
  exports.isTemplateElementId = isTemplateElementId3;
146543
147727
  exports.isUrlSafe = isUrlSafe;
147728
+ exports.isWedgeCalloutPresetShape = isWedgeCalloutPresetShape;
146544
147729
  exports.lastShowSlideIndex = lastShowSlideIndex;
146545
147730
  exports.listAutosaveSnapshots = listAutosaveSnapshots;
146546
147731
  exports.listBackstageRecentFiles = listBackstageRecentFiles;