pptx-react-viewer 1.25.4 → 1.25.5

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 (98) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/{Model3DScene-DZFYJPUH.mjs → Model3DScene-XVYOISVJ.mjs} +2 -2
  3. package/dist/Model3DScene-XVYOISVJ.mjs.br +0 -0
  4. package/dist/Model3DScene-XVYOISVJ.mjs.gz +0 -0
  5. package/dist/{Model3DScene-SP6WOKSX.js → Model3DScene-Y5ABLO7K.js} +3 -3
  6. package/dist/Model3DScene-Y5ABLO7K.js.br +0 -0
  7. package/dist/Model3DScene-Y5ABLO7K.js.gz +0 -0
  8. package/dist/{SurfaceChart3DScene-54BRNPQ5.mjs → SurfaceChart3DScene-RXZADECL.mjs} +2 -2
  9. package/dist/SurfaceChart3DScene-RXZADECL.mjs.br +0 -0
  10. package/dist/SurfaceChart3DScene-RXZADECL.mjs.gz +0 -0
  11. package/dist/{SurfaceChart3DScene-GISPZ4C2.js → SurfaceChart3DScene-WMY5JTW4.js} +3 -3
  12. package/dist/SurfaceChart3DScene-WMY5JTW4.js.br +0 -0
  13. package/dist/SurfaceChart3DScene-WMY5JTW4.js.gz +0 -0
  14. package/dist/{chunk-5VYVKFMS.js → chunk-7CSBUYRN.js} +808 -808
  15. package/dist/chunk-7CSBUYRN.js.br +0 -0
  16. package/dist/chunk-7CSBUYRN.js.gz +0 -0
  17. package/dist/{chunk-7FE27DDH.js → chunk-E55Q4AC7.js} +556 -476
  18. package/dist/chunk-E55Q4AC7.js.br +0 -0
  19. package/dist/chunk-E55Q4AC7.js.gz +0 -0
  20. package/dist/{chunk-P72VQ7WE.mjs → chunk-F4WPQRZU.mjs} +96 -16
  21. package/dist/chunk-F4WPQRZU.mjs.br +0 -0
  22. package/dist/chunk-F4WPQRZU.mjs.gz +0 -0
  23. package/dist/{chunk-UYNOPUSG.mjs → chunk-FOMF7POV.mjs} +1658 -353
  24. package/dist/chunk-FOMF7POV.mjs.br +0 -0
  25. package/dist/chunk-FOMF7POV.mjs.gz +0 -0
  26. package/dist/{chunk-VUC3UPLM.mjs → chunk-FVQDRA5N.mjs} +1044 -108
  27. package/dist/chunk-FVQDRA5N.mjs.br +0 -0
  28. package/dist/chunk-FVQDRA5N.mjs.gz +0 -0
  29. package/dist/{chunk-FWF2SP6N.js → chunk-IPYAN574.js} +1660 -352
  30. package/dist/chunk-IPYAN574.js.br +0 -0
  31. package/dist/chunk-IPYAN574.js.gz +0 -0
  32. package/dist/{chunk-TPG2WKHQ.mjs → chunk-L4ZADJOM.mjs} +6 -6
  33. package/dist/chunk-L4ZADJOM.mjs.br +0 -0
  34. package/dist/chunk-L4ZADJOM.mjs.gz +0 -0
  35. package/dist/{chunk-6F4WVHS3.js → chunk-TEN35NUX.js} +1077 -141
  36. package/dist/chunk-TEN35NUX.js.br +0 -0
  37. package/dist/chunk-TEN35NUX.js.gz +0 -0
  38. package/dist/{dist-QU6JIDAF.js → dist-755SJ3ZH.js} +574 -562
  39. package/dist/dist-755SJ3ZH.js.br +0 -0
  40. package/dist/dist-755SJ3ZH.js.gz +0 -0
  41. package/dist/dist-FFWP5NQZ.mjs +2 -0
  42. package/dist/dist-FFWP5NQZ.mjs.br +0 -0
  43. package/dist/dist-FFWP5NQZ.mjs.gz +0 -0
  44. package/dist/hooks-unstable.d.ts +243 -4
  45. package/dist/hooks-unstable.d.ts.map +1 -1
  46. package/dist/hooks-unstable.js +78 -78
  47. package/dist/hooks-unstable.js.br +0 -0
  48. package/dist/hooks-unstable.js.gz +0 -0
  49. package/dist/hooks-unstable.mjs +3 -3
  50. package/dist/hooks-unstable.mjs.br +0 -0
  51. package/dist/hooks-unstable.mjs.gz +0 -0
  52. package/dist/{index-DWvM1PBB.d.ts → index-J6IuHQ2_.d.ts} +21 -4
  53. package/dist/index-J6IuHQ2_.d.ts.map +1 -0
  54. package/dist/index.d.ts +223 -1
  55. package/dist/index.js +33 -33
  56. package/dist/index.js.br +0 -0
  57. package/dist/index.js.gz +0 -0
  58. package/dist/index.mjs +4 -4
  59. package/dist/index.mjs.br +0 -0
  60. package/dist/index.mjs.gz +0 -0
  61. package/dist/viewer/index.d.ts +223 -1
  62. package/dist/viewer/index.js +20 -20
  63. package/dist/viewer/index.js.br +0 -0
  64. package/dist/viewer/index.js.gz +0 -0
  65. package/dist/viewer/index.mjs +4 -4
  66. package/dist/viewer/index.mjs.br +0 -0
  67. package/dist/viewer/index.mjs.gz +0 -0
  68. package/package.json +1 -1
  69. package/dist/Model3DScene-DZFYJPUH.mjs.br +0 -0
  70. package/dist/Model3DScene-DZFYJPUH.mjs.gz +0 -0
  71. package/dist/Model3DScene-SP6WOKSX.js.br +0 -0
  72. package/dist/Model3DScene-SP6WOKSX.js.gz +0 -0
  73. package/dist/SurfaceChart3DScene-54BRNPQ5.mjs.br +0 -0
  74. package/dist/SurfaceChart3DScene-54BRNPQ5.mjs.gz +0 -0
  75. package/dist/SurfaceChart3DScene-GISPZ4C2.js.br +0 -0
  76. package/dist/SurfaceChart3DScene-GISPZ4C2.js.gz +0 -0
  77. package/dist/chunk-5VYVKFMS.js.br +0 -0
  78. package/dist/chunk-5VYVKFMS.js.gz +0 -0
  79. package/dist/chunk-6F4WVHS3.js.br +0 -0
  80. package/dist/chunk-6F4WVHS3.js.gz +0 -0
  81. package/dist/chunk-7FE27DDH.js.br +0 -0
  82. package/dist/chunk-7FE27DDH.js.gz +0 -0
  83. package/dist/chunk-FWF2SP6N.js.br +0 -0
  84. package/dist/chunk-FWF2SP6N.js.gz +0 -0
  85. package/dist/chunk-P72VQ7WE.mjs.br +0 -0
  86. package/dist/chunk-P72VQ7WE.mjs.gz +0 -0
  87. package/dist/chunk-TPG2WKHQ.mjs.br +0 -0
  88. package/dist/chunk-TPG2WKHQ.mjs.gz +0 -0
  89. package/dist/chunk-UYNOPUSG.mjs.br +0 -0
  90. package/dist/chunk-UYNOPUSG.mjs.gz +0 -0
  91. package/dist/chunk-VUC3UPLM.mjs.br +0 -0
  92. package/dist/chunk-VUC3UPLM.mjs.gz +0 -0
  93. package/dist/dist-QNYKM7YS.mjs +0 -2
  94. package/dist/dist-QNYKM7YS.mjs.br +0 -0
  95. package/dist/dist-QNYKM7YS.mjs.gz +0 -0
  96. package/dist/dist-QU6JIDAF.js.br +0 -0
  97. package/dist/dist-QU6JIDAF.js.gz +0 -0
  98. package/dist/index-DWvM1PBB.d.ts.map +0 -1
@@ -1,4 +1,4 @@
1
- import { MIN_ELEMENT_SIZE, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hasShapeProperties, hasTextProperties, createChartElement, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, hslToRgb, PRESET_COLOR_MAP, isImageLikeElement, stripXmlOrderSuffix, orderedXmlKey, applyDrawingColorTransforms } from './chunk-UYNOPUSG.mjs';
1
+ import { MIN_ELEMENT_SIZE, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hasShapeProperties, hasTextProperties, createChartElement, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, hslToRgb, PRESET_COLOR_MAP, isImageLikeElement, stripXmlOrderSuffix, orderedXmlKey, createBuiltinVariables, resolveCoordinate, applyDrawingColorTransforms } from './chunk-FOMF7POV.mjs';
2
2
  import DOMPurify from 'dompurify';
3
3
 
4
4
  var defaultThemeColors = {
@@ -556,7 +556,27 @@ function buildReflectedGradientStops(stops) {
556
556
  }));
557
557
  return [...forward, ...reversed];
558
558
  }
559
- function buildGradientCss(gradient) {
559
+ function normalizeDegrees(deg) {
560
+ return (deg % 360 + 360) % 360;
561
+ }
562
+ function adjustLinearGradientAngle(angle, gradient, context) {
563
+ if (!context) {
564
+ return angle;
565
+ }
566
+ let result = angle;
567
+ const { width, height, rotation } = context;
568
+ if (gradient.fillGradientScaled !== false && typeof width === "number" && typeof height === "number" && width > 0 && height > 0 && width !== height) {
569
+ const rad = result * Math.PI / 180;
570
+ result = normalizeDegrees(
571
+ Math.atan2(height * Math.sin(rad), width * Math.cos(rad)) * 180 / Math.PI
572
+ );
573
+ }
574
+ if (gradient.fillGradientRotWithShape === false && typeof rotation === "number") {
575
+ result = normalizeDegrees(result - rotation);
576
+ }
577
+ return result;
578
+ }
579
+ function buildGradientCss(gradient, context) {
560
580
  if (!gradient || gradient.fillMode !== "gradient") {
561
581
  return void 0;
562
582
  }
@@ -578,9 +598,10 @@ function buildGradientCss(gradient) {
578
598
  return buildCirclePathGradient(stops, fp, ftr);
579
599
  }
580
600
  const normalizedAngle = typeof gradient.fillGradientAngle === "number" && Number.isFinite(gradient.fillGradientAngle) ? gradient.fillGradientAngle : 90;
601
+ const effectiveAngle = adjustLinearGradientAngle(normalizedAngle, gradient, context);
581
602
  const flip = gradient.fillGradientFlip;
582
603
  const linearStops = flip && flip !== "none" ? buildReflectedGradientStops(stops) : stops;
583
- return `linear-gradient(${Math.round(normalizedAngle)}deg, ${linearStops.map(toCssGradientStop).join(", ")})`;
604
+ return `linear-gradient(${Math.round(effectiveAngle)}deg, ${linearStops.map(toCssGradientStop).join(", ")})`;
584
605
  }
585
606
  var buildCssGradientFromShapeStyle = buildGradientCss;
586
607
  function getPatternSvg(preset, fg, bg) {
@@ -4173,6 +4194,10 @@ function resolveDataPointFill(series, pointIndex, fallbackColor) {
4173
4194
  function resolveVaryColorFill(series, pointIndex, paletteColor3) {
4174
4195
  return findDataPoint(series, pointIndex)?.spPr?.fillColor ?? paletteColor3;
4175
4196
  }
4197
+ function resolveDataPointExplosion(series, pointIndex) {
4198
+ const point = findDataPoint(series, pointIndex);
4199
+ return point?.explosion ?? series.explosion ?? 0;
4200
+ }
4176
4201
  function clamp3(value, min, max) {
4177
4202
  return Math.min(Math.max(value, min), max);
4178
4203
  }
@@ -4545,34 +4570,59 @@ function categoryTotals(series, catCount) {
4545
4570
  (_, ci) => series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0)
4546
4571
  );
4547
4572
  }
4573
+ function blendToWhite(color) {
4574
+ const match = /^#?([0-9a-f]{6})$/iu.exec(color.trim());
4575
+ if (!match) {
4576
+ return color;
4577
+ }
4578
+ const value = Number.parseInt(match[1], 16);
4579
+ const mix = (channel) => Math.round(channel + (255 - channel) * 0.5);
4580
+ const r = mix(value >> 16 & 255);
4581
+ const g = mix(value >> 8 & 255);
4582
+ const b = mix(value & 255);
4583
+ return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0").toUpperCase()}`;
4584
+ }
4585
+ function invertNegativeFill(series, pointIndex, value, baseFill) {
4586
+ if (value >= 0) {
4587
+ return baseFill;
4588
+ }
4589
+ const point = series.dataPoints?.find((p) => p.idx === pointIndex);
4590
+ const invert = point?.invertIfNegative ?? series.invertIfNegative ?? false;
4591
+ return invert ? blendToWhite(baseFill) : baseFill;
4592
+ }
4548
4593
  function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, grouping, sourceIndices2) {
4549
4594
  const primitives = [];
4550
4595
  const dataLabels = [];
4551
4596
  const series = chartData.series;
4552
4597
  const palette = chartData.colorPalette;
4553
4598
  const showLabels = chartData.style?.hasDataLabels;
4599
+ const varyColorsSingle = chartData.varyColors === true && series.length === 1;
4554
4600
  if (grouping === "clustered") {
4555
4601
  const seriesCount = Math.max(series.length, 1);
4556
4602
  const barGroupWidth2 = layout.plotWidth / Math.max(catCount, 1);
4557
- const singleBarWidth = barGroupWidth2 * 0.7 / seriesCount;
4558
- const groupOffset = (barGroupWidth2 - singleBarWidth * seriesCount) / 2;
4603
+ const singleBarWidth = chartData.barGapWidth !== void 0 ? barGroupWidth2 / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100) : barGroupWidth2 * 0.7 / seriesCount;
4604
+ const overlap = chartData.barOverlap ?? 0;
4605
+ const step = singleBarWidth * (1 - overlap / 100);
4606
+ const clusterWidth = singleBarWidth + step * (seriesCount - 1);
4607
+ const groupOffset = (barGroupWidth2 - clusterWidth) / 2;
4559
4608
  for (let displayIndex = 0; displayIndex < catCount; displayIndex++) {
4560
4609
  const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
4561
4610
  for (let si = 0; si < series.length; si++) {
4562
4611
  const val2 = series[si].values[sourceIndex] ?? 0;
4563
- const x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + singleBarWidth * si;
4612
+ const x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + step * si;
4564
4613
  const activeRange = secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange;
4565
4614
  const zeroY = valueToY2(0, activeRange, layout.plotTop, layout.plotBottom);
4566
4615
  const valY = valueToY2(val2, activeRange, layout.plotTop, layout.plotBottom);
4567
4616
  const y = Math.min(zeroY, valY);
4568
4617
  const h = Math.max(Math.abs(zeroY - valY), 1);
4618
+ const baseFill = varyColorsSingle ? resolveVaryColorFill(series[si], sourceIndex, paletteColor2(sourceIndex, palette)) : resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4569
4619
  primitives.push({
4570
4620
  kind: "rect",
4571
4621
  x,
4572
4622
  y,
4573
4623
  w: singleBarWidth,
4574
4624
  h,
4575
- fill: resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette),
4625
+ fill: invertNegativeFill(series[si], sourceIndex, val2, baseFill),
4576
4626
  rx: 1,
4577
4627
  part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4578
4628
  });
@@ -4603,6 +4653,8 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4603
4653
  if (r.seriesIndex !== void 0 && r.pointIndex !== void 0) {
4604
4654
  const sourcePointIndex = sourceIndices2[r.pointIndex] ?? r.pointIndex;
4605
4655
  fill = resolveDataPointFill(series[r.seriesIndex], sourcePointIndex, r.fill) ?? r.fill;
4656
+ const value = series[r.seriesIndex].values[sourcePointIndex] ?? 0;
4657
+ fill = invertNegativeFill(series[r.seriesIndex], sourcePointIndex, value, fill);
4606
4658
  part = { role: "dataPoint", seriesIndex: r.seriesIndex, pointIndex: sourcePointIndex };
4607
4659
  }
4608
4660
  primitives.push({ kind: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill, rx: 1, part });
@@ -4636,13 +4688,14 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4636
4688
  const topY = valueToY2(top, primaryRange, layout.plotTop, layout.plotBottom);
4637
4689
  const y = Math.min(baseY, topY);
4638
4690
  const h = Math.max(Math.abs(baseY - topY), 0.5);
4691
+ const pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4639
4692
  primitives.push({
4640
4693
  kind: "rect",
4641
4694
  x,
4642
4695
  y,
4643
4696
  w: barW,
4644
4697
  h,
4645
- fill: resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette),
4698
+ fill: invertNegativeFill(series[si], sourceIndex, rawVal, pctBaseFill),
4646
4699
  part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4647
4700
  });
4648
4701
  if (showLabels && Math.abs(val2) > 0) {
@@ -4691,6 +4744,139 @@ function pushClusteredStackedLabels(series, sourceIndices2, catCount, layout, ra
4691
4744
  }
4692
4745
  }
4693
4746
  }
4747
+ function smoothLinePath(points) {
4748
+ if (points.length === 0) {
4749
+ return "";
4750
+ }
4751
+ if (points.length === 1) {
4752
+ return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
4753
+ }
4754
+ if (points.length === 2) {
4755
+ return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)} L${points[1].x.toFixed(2)},${points[1].y.toFixed(2)}`;
4756
+ }
4757
+ let d = `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
4758
+ for (let i = 0; i < points.length - 1; i++) {
4759
+ const p0 = points[i - 1] ?? points[i];
4760
+ const p1 = points[i];
4761
+ const p2 = points[i + 1];
4762
+ const p3 = points[i + 2] ?? p2;
4763
+ const cp1x = p1.x + (p2.x - p0.x) / 6;
4764
+ const cp1y = p1.y + (p2.y - p0.y) / 6;
4765
+ const cp2x = p2.x - (p3.x - p1.x) / 6;
4766
+ const cp2y = p2.y - (p3.y - p1.y) / 6;
4767
+ d += ` C${cp1x.toFixed(2)},${cp1y.toFixed(2)} ${cp2x.toFixed(2)},${cp2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
4768
+ }
4769
+ return d;
4770
+ }
4771
+ function markerRadius(size, defaultRadius2) {
4772
+ if (size === void 0 || !Number.isFinite(size) || size <= 0) {
4773
+ return defaultRadius2;
4774
+ }
4775
+ return size / 2;
4776
+ }
4777
+ function polygonPoints(vertices) {
4778
+ return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
4779
+ }
4780
+ function starVertices(cx, cy, r) {
4781
+ const inner = r * 0.5;
4782
+ const out = [];
4783
+ for (let i = 0; i < 10; i++) {
4784
+ const radius = i % 2 === 0 ? r : inner;
4785
+ const angle = -Math.PI / 2 + Math.PI * i / 5;
4786
+ out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
4787
+ }
4788
+ return out;
4789
+ }
4790
+ function buildMarkerPrimitive(input) {
4791
+ const { symbol, cx, cy, fill, part } = input;
4792
+ if (symbol === "none") {
4793
+ return null;
4794
+ }
4795
+ const r = markerRadius(input.size, input.defaultRadius);
4796
+ const stroke = fill;
4797
+ switch (symbol) {
4798
+ case "square":
4799
+ return { kind: "rect", x: cx - r, y: cy - r, w: r * 2, h: r * 2, fill, part };
4800
+ case "dash":
4801
+ return { kind: "rect", x: cx - r, y: cy - r * 0.32, w: r * 2, h: r * 0.64, fill, part };
4802
+ case "diamond":
4803
+ return {
4804
+ kind: "polygon",
4805
+ points: polygonPoints([
4806
+ [cx, cy - r],
4807
+ [cx + r, cy],
4808
+ [cx, cy + r],
4809
+ [cx - r, cy]
4810
+ ]),
4811
+ fill,
4812
+ stroke,
4813
+ strokeWidth: 0,
4814
+ part
4815
+ };
4816
+ case "triangle":
4817
+ return {
4818
+ kind: "polygon",
4819
+ points: polygonPoints([
4820
+ [cx, cy - r],
4821
+ [cx + r * 0.9, cy + r * 0.75],
4822
+ [cx - r * 0.9, cy + r * 0.75]
4823
+ ]),
4824
+ fill,
4825
+ stroke,
4826
+ strokeWidth: 0,
4827
+ part
4828
+ };
4829
+ case "star":
4830
+ return {
4831
+ kind: "polygon",
4832
+ points: polygonPoints(starVertices(cx, cy, r)),
4833
+ fill,
4834
+ stroke,
4835
+ strokeWidth: 0,
4836
+ part
4837
+ };
4838
+ case "plus":
4839
+ return {
4840
+ kind: "path",
4841
+ d: `M${(cx - r).toFixed(2)},${cy.toFixed(2)} L${(cx + r).toFixed(2)},${cy.toFixed(2)} M${cx.toFixed(2)},${(cy - r).toFixed(2)} L${cx.toFixed(2)},${(cy + r).toFixed(2)}`,
4842
+ fill: "none",
4843
+ stroke,
4844
+ strokeWidth: Math.max(1, r * 0.4),
4845
+ part
4846
+ };
4847
+ case "x":
4848
+ return {
4849
+ kind: "path",
4850
+ d: `M${(cx - r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx + r).toFixed(2)},${(cy + r).toFixed(2)} M${(cx + r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx - r).toFixed(2)},${(cy + r).toFixed(2)}`,
4851
+ fill: "none",
4852
+ stroke,
4853
+ strokeWidth: Math.max(1, r * 0.4),
4854
+ part
4855
+ };
4856
+ case "dot":
4857
+ return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, part };
4858
+ default:
4859
+ return { kind: "circle", cx, cy, r, fill, part };
4860
+ }
4861
+ }
4862
+ function pushMarker(out, series, cx, cy, fill, defaultRadius2, part, opacity) {
4863
+ const m = buildMarkerPrimitive({
4864
+ symbol: series.marker?.symbol,
4865
+ size: series.marker?.size,
4866
+ cx,
4867
+ cy,
4868
+ fill,
4869
+ defaultRadius: defaultRadius2,
4870
+ part
4871
+ });
4872
+ if (!m) {
4873
+ return;
4874
+ }
4875
+ if (opacity !== void 0) {
4876
+ m.opacity = opacity;
4877
+ }
4878
+ out.push(m);
4879
+ }
4694
4880
  function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, sourceIndices2, xPositions) {
4695
4881
  const primitives = [];
4696
4882
  const dataLabels = [];
@@ -4709,24 +4895,36 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
4709
4895
  })
4710
4896
  );
4711
4897
  const c = seriesColor2(series, si, chartData.colorPalette);
4712
- primitives.push({
4713
- kind: "polyline",
4714
- points: linePointsToSvgString(pts),
4715
- stroke: c,
4716
- strokeWidth: 2.4,
4717
- fill: "none",
4718
- part: { role: "series", seriesIndex: si }
4719
- });
4898
+ const seriesPart = { role: "series", seriesIndex: si };
4899
+ primitives.push(
4900
+ series.smooth ? {
4901
+ kind: "path",
4902
+ d: smoothLinePath(pts),
4903
+ stroke: c,
4904
+ strokeWidth: 2.4,
4905
+ fill: "none",
4906
+ part: seriesPart
4907
+ } : {
4908
+ kind: "polyline",
4909
+ points: linePointsToSvgString(pts),
4910
+ stroke: c,
4911
+ strokeWidth: 2.4,
4912
+ fill: "none",
4913
+ part: seriesPart
4914
+ }
4915
+ );
4720
4916
  pts.forEach((pt, displayIndex) => {
4721
- const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
4722
- primitives.push({
4723
- kind: "circle",
4724
- cx: pt.x,
4725
- cy: pt.y,
4726
- r: 2.5,
4727
- fill: resolveDataPointFill(series, sourceIndex, c) ?? c,
4728
- part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4729
- });
4917
+ const idx = sourceIndices2[displayIndex] ?? displayIndex;
4918
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
4919
+ pushMarker(
4920
+ primitives,
4921
+ series,
4922
+ pt.x,
4923
+ pt.y,
4924
+ resolveDataPointFill(series, idx, c) ?? c,
4925
+ 2.5,
4926
+ part
4927
+ );
4730
4928
  });
4731
4929
  if (showLabels) {
4732
4930
  displayValues.forEach((val2, displayIndex) => {
@@ -4787,19 +4985,17 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
4787
4985
  part: { role: "series", seriesIndex: si }
4788
4986
  });
4789
4987
  pts.forEach((pt, displayIndex) => {
4790
- const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
4791
- primitives.push({
4792
- kind: "circle",
4793
- cx: pt.x,
4794
- cy: pt.y,
4795
- r: 2,
4796
- fill: resolveDataPointFill(series, sourceIndex, c) ?? c,
4797
- part: {
4798
- role: "dataPoint",
4799
- seriesIndex: si,
4800
- pointIndex: sourceIndex
4801
- }
4802
- });
4988
+ const idx = sourceIndices2[displayIndex] ?? displayIndex;
4989
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
4990
+ pushMarker(
4991
+ primitives,
4992
+ series,
4993
+ pt.x,
4994
+ pt.y,
4995
+ resolveDataPointFill(series, idx, c) ?? c,
4996
+ 2,
4997
+ part
4998
+ );
4803
4999
  });
4804
5000
  if (showLabels) {
4805
5001
  displayValues.forEach((val2, displayIndex) => {
@@ -4833,15 +5029,17 @@ function buildScatter(chartData, layout, range) {
4833
5029
  const c = seriesColor2(series, si, chartData.colorPalette);
4834
5030
  const dots = computeScatterDots(series.values, maxXIndex, layout, range, xValues);
4835
5031
  dots.forEach((dot, vi) => {
4836
- primitives.push({
4837
- kind: "circle",
4838
- cx: dot.cx,
4839
- cy: dot.cy,
4840
- r: 4,
4841
- fill: resolveDataPointFill(series, vi, c) ?? c,
4842
- opacity: 0.85,
4843
- part: { role: "dataPoint", seriesIndex: si, pointIndex: vi }
4844
- });
5032
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: vi };
5033
+ pushMarker(
5034
+ primitives,
5035
+ series,
5036
+ dot.cx,
5037
+ dot.cy,
5038
+ resolveDataPointFill(series, vi, c) ?? c,
5039
+ 4,
5040
+ part,
5041
+ 0.85
5042
+ );
4845
5043
  });
4846
5044
  if (showLabels) {
4847
5045
  series.values.forEach((val2, vi) => {
@@ -4910,7 +5108,124 @@ function buildBubbles(chartData, layout, range) {
4910
5108
  }
4911
5109
  return { primitives, dataLabels };
4912
5110
  }
4913
- function categoryX(displayIndex, count, layout, spacing) {
5111
+ function categoryX(index, catCount, layout, options) {
5112
+ const explicit = options.xPositions?.[index];
5113
+ if (explicit !== void 0) {
5114
+ return explicit;
5115
+ }
5116
+ if (options.mode === "bar") {
5117
+ const slot = layout.plotWidth / Math.max(catCount, 1);
5118
+ return layout.plotLeft + slot * index + slot / 2;
5119
+ }
5120
+ const maxIdx = Math.max(catCount - 1, 1);
5121
+ return layout.plotLeft + index / maxIdx * layout.plotWidth;
5122
+ }
5123
+ function dashFor(dashStyle) {
5124
+ if (!dashStyle || dashStyle === "solid") {
5125
+ return void 0;
5126
+ }
5127
+ return dashStyle === "dot" || dashStyle === "sysDot" ? "1 2" : "4 3";
5128
+ }
5129
+ function computeDropLinePrimitives(chartData, layout, range, catCount, options) {
5130
+ const style = chartData.dropLines;
5131
+ if (!style) {
5132
+ return [];
5133
+ }
5134
+ const baselineY = valueToY2(range.min, range, layout.plotTop, layout.plotBottom);
5135
+ const dashArray2 = dashFor(style.dashStyle);
5136
+ const out = [];
5137
+ for (const series of chartData.series) {
5138
+ series.values.forEach((val2, vi) => {
5139
+ const x = categoryX(vi, catCount, layout, options);
5140
+ out.push({
5141
+ kind: "line",
5142
+ x1: x,
5143
+ y1: valueToY2(val2, range, layout.plotTop, layout.plotBottom),
5144
+ x2: x,
5145
+ y2: baselineY,
5146
+ stroke: style.color ?? "#94a3b8",
5147
+ strokeWidth: style.width ?? 0.8,
5148
+ dashArray: dashArray2
5149
+ });
5150
+ });
5151
+ }
5152
+ return out;
5153
+ }
5154
+ function computeHiLowLinePrimitives(chartData, layout, range, catCount, options) {
5155
+ const style = chartData.hiLowLines;
5156
+ if (!style || chartData.series.length < 2) {
5157
+ return [];
5158
+ }
5159
+ const dashArray2 = dashFor(style.dashStyle);
5160
+ const out = [];
5161
+ for (let vi = 0; vi < catCount; vi++) {
5162
+ let high = Number.NEGATIVE_INFINITY;
5163
+ let low = Number.POSITIVE_INFINITY;
5164
+ for (const series of chartData.series) {
5165
+ const v = series.values[vi];
5166
+ if (v !== void 0) {
5167
+ high = Math.max(high, v);
5168
+ low = Math.min(low, v);
5169
+ }
5170
+ }
5171
+ if (!Number.isFinite(high) || !Number.isFinite(low)) {
5172
+ continue;
5173
+ }
5174
+ const x = categoryX(vi, catCount, layout, options);
5175
+ out.push({
5176
+ kind: "line",
5177
+ x1: x,
5178
+ y1: valueToY2(high, range, layout.plotTop, layout.plotBottom),
5179
+ x2: x,
5180
+ y2: valueToY2(low, range, layout.plotTop, layout.plotBottom),
5181
+ stroke: style.color ?? "#334155",
5182
+ strokeWidth: style.width ?? 1,
5183
+ dashArray: dashArray2
5184
+ });
5185
+ }
5186
+ return out;
5187
+ }
5188
+ function computeUpDownBarPrimitives(chartData, layout, range, catCount, options) {
5189
+ const bars = chartData.upDownBars;
5190
+ if (!bars || chartData.series.length < 2) {
5191
+ return [];
5192
+ }
5193
+ const first = chartData.series[0];
5194
+ const last = chartData.series[chartData.series.length - 1];
5195
+ const slot = layout.plotWidth / Math.max(catCount, 1);
5196
+ const gapWidth = bars.gapWidth ?? 150;
5197
+ const barW = Math.max(slot / (1 + Math.max(gapWidth, 0) / 100), 1);
5198
+ const upFill = bars.upBars?.fillColor ?? "#e2e8f0";
5199
+ const downFill = bars.downBars?.fillColor ?? "#334155";
5200
+ const out = [];
5201
+ for (let vi = 0; vi < catCount; vi++) {
5202
+ const firstVal = first.values[vi];
5203
+ const lastVal = last.values[vi];
5204
+ if (firstVal === void 0 || lastVal === void 0) {
5205
+ continue;
5206
+ }
5207
+ const firstY = valueToY2(firstVal, range, layout.plotTop, layout.plotBottom);
5208
+ const lastY = valueToY2(lastVal, range, layout.plotTop, layout.plotBottom);
5209
+ const x = categoryX(vi, catCount, layout, options) - barW / 2;
5210
+ out.push({
5211
+ kind: "rect",
5212
+ x,
5213
+ y: Math.min(firstY, lastY),
5214
+ w: barW,
5215
+ h: Math.max(Math.abs(firstY - lastY), 1),
5216
+ fill: lastVal >= firstVal ? upFill : downFill
5217
+ });
5218
+ }
5219
+ return out;
5220
+ }
5221
+ function computeHelperLinePrimitives(chartData, layout, range, catCount, options) {
5222
+ return [
5223
+ ...computeUpDownBarPrimitives(chartData, layout, range, catCount, options),
5224
+ ...computeDropLinePrimitives(chartData, layout, range, catCount, options),
5225
+ ...computeHiLowLinePrimitives(chartData, layout, range, catCount, options)
5226
+ ];
5227
+ }
5228
+ function categoryX2(displayIndex, count, layout, spacing) {
4914
5229
  if (spacing === "bar") {
4915
5230
  return layout.plotLeft + layout.plotWidth / Math.max(count, 1) * (displayIndex + 0.5);
4916
5231
  }
@@ -4941,8 +5256,8 @@ function buildMultiLevelCategoryLabels(categoryLabels, categoryLevels, sourceInd
4941
5256
  if (!group.text || group.start % skip !== 0) {
4942
5257
  return [];
4943
5258
  }
4944
- const startX = categoryX(group.start, sourceIndices2.length, layout, spacing);
4945
- const endX = categoryX(group.end, sourceIndices2.length, layout, spacing);
5259
+ const startX = categoryX2(group.start, sourceIndices2.length, layout, spacing);
5260
+ const endX = categoryX2(group.end, sourceIndices2.length, layout, spacing);
4946
5261
  return [
4947
5262
  {
4948
5263
  kind: "text",
@@ -4997,13 +5312,13 @@ function buildTickMarks(axis, sourceCount, layout, spacing, axisY) {
4997
5312
  }
4998
5313
  const majorSkip = Math.max(1, axis.tickMarkSkip ?? 1);
4999
5314
  for (let displayIndex = 0; displayIndex < sourceCount; displayIndex += majorSkip) {
5000
- const x = categoryX(displayIndex, sourceCount, layout, spacing);
5315
+ const x = categoryX2(displayIndex, sourceCount, layout, spacing);
5001
5316
  const major = tickLine(x, y, axis.majorTickMark, topAxis, 4, axis);
5002
5317
  if (major) {
5003
5318
  result.push(major);
5004
5319
  }
5005
5320
  if (axis.minorTickMark !== void 0 && displayIndex + majorSkip < sourceCount) {
5006
- const nextX = categoryX(displayIndex + majorSkip, sourceCount, layout, spacing);
5321
+ const nextX = categoryX2(displayIndex + majorSkip, sourceCount, layout, spacing);
5007
5322
  const minor = tickLine((x + nextX) / 2, y, axis.minorTickMark, topAxis, 2.5, axis);
5008
5323
  if (minor) {
5009
5324
  result.push(minor);
@@ -5281,7 +5596,7 @@ function buildCartesianHorizontalAxis(chartData, categoryLabels, layout, kind, p
5281
5596
  catAxisStyle,
5282
5597
  sourceIndices: sourceIndices2,
5283
5598
  xPositions: datePlan?.xPositions ?? categoryPlan?.sourceIndices.map(
5284
- (_sourceIndex, displayIndex) => categoryX(displayIndex, categoryPlan.sourceIndices.length, layout, catAxisStyle)
5599
+ (_sourceIndex, displayIndex) => categoryX2(displayIndex, categoryPlan.sourceIndices.length, layout, catAxisStyle)
5285
5600
  ),
5286
5601
  labels: [
5287
5602
  ...datePlan?.labels ?? categoryPlan?.labels ?? buildCategoryLabels(categoryLabels, layout, catAxisStyle),
@@ -5296,7 +5611,7 @@ function buildCartesianHorizontalAxis(chartData, categoryLabels, layout, kind, p
5296
5611
  }
5297
5612
  var DEFAULT_COLOR3 = "#334155";
5298
5613
  var CAP_HALF_WIDTH = 4;
5299
- function categoryX2(value, count, layout, mode) {
5614
+ function categoryX3(value, count, layout, mode) {
5300
5615
  if (mode === "bar") {
5301
5616
  const slot = layout.plotWidth / Math.max(count, 1);
5302
5617
  return layout.plotLeft + slot * value + slot / 2;
@@ -5403,7 +5718,7 @@ function computeErrorBarPrimitives(chartData, catCount, layout, range, mode = "l
5403
5718
  const categoryMapper = (value) => positionedCategoryX(
5404
5719
  value,
5405
5720
  options.xPositions,
5406
- (index) => categoryX2(index, indexes.length || catCount, layout, seriesMode)
5721
+ (index) => categoryX3(index, indexes.length || catCount, layout, seriesMode)
5407
5722
  );
5408
5723
  const toPixel = xValues.numeric ? (value) => numericX(value, xRange, layout) : categoryMapper;
5409
5724
  const x = toPixel(baseXValue);
@@ -5977,7 +6292,15 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
5977
6292
  } else {
5978
6293
  plot = buildBubbles(chartData, layout, primaryRange);
5979
6294
  }
5980
- const primitives = [...plot.primitives, ...horizontalAxis.tickMarks];
6295
+ const helperLines = kind === "line" || kind === "area" ? computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, {
6296
+ mode: "line",
6297
+ xPositions: horizontalAxis.xPositions
6298
+ }) : [];
6299
+ const primitives = [
6300
+ ...helperLines,
6301
+ ...plot.primitives,
6302
+ ...horizontalAxis.tickMarks
6303
+ ];
5981
6304
  const overlays = [
5982
6305
  ...computeTrendlinePrimitives(
5983
6306
  displayChartData,
@@ -6103,6 +6426,10 @@ function buildComboViewModel(element, chartData, categoryLabels) {
6103
6426
  );
6104
6427
  const primitives = [];
6105
6428
  const dataLabels = [];
6429
+ const helperOpts = { mode: "line", xPositions: horizontalAxis.xPositions };
6430
+ primitives.push(
6431
+ ...computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, helperOpts)
6432
+ );
6106
6433
  const barSeries = chartData.series.slice(0, 1);
6107
6434
  if (barSeries[0]) {
6108
6435
  const barRange = rangeForSeries(0, primaryRange, secondaryRange, secondaryIndexes);
@@ -8510,16 +8837,30 @@ function computePieLayout(elementWidth, elementHeight, chartData, isDoughnut) {
8510
8837
  const cx = size / 2;
8511
8838
  const cy = titleOffset + (size - titleOffset - legendOffset) / 2;
8512
8839
  const outerR = Math.max((size - titleOffset - legendOffset) * 0.42, 0);
8513
- const innerR = isDoughnut ? outerR * 0.55 : 0;
8840
+ const holeRatio = isDoughnut && chartData.doughnutHoleSize !== void 0 ? Math.min(Math.max(chartData.doughnutHoleSize, 10), 90) / 100 : 0.55;
8841
+ const innerR = isDoughnut ? outerR * holeRatio : 0;
8514
8842
  return { cx, cy, outerR, innerR, size };
8515
8843
  }
8516
- function computePieSlices(values, cx, cy, outerR, innerR) {
8844
+ function computePieSlices(values, cx, cy, outerR, innerR, options) {
8517
8845
  const total = values.reduce((s, v) => s + Math.abs(v), 0) || 1;
8518
- let cumAngle = -Math.PI / 2;
8519
- return values.map((val2) => {
8846
+ let cumAngle = options?.startAngle ?? -Math.PI / 2;
8847
+ return values.map((val2, i) => {
8520
8848
  const sliceAngle = Math.abs(val2) / total * Math.PI * 2;
8521
8849
  const startAngle = cumAngle;
8522
8850
  cumAngle += sliceAngle;
8851
+ const explosion = options?.explosions?.[i] ?? 0;
8852
+ if (explosion > 0) {
8853
+ const mid = (startAngle + cumAngle) / 2;
8854
+ const offset = outerR * (explosion / 100);
8855
+ return computePieSlicePath(
8856
+ cx + Math.cos(mid) * offset,
8857
+ cy + Math.sin(mid) * offset,
8858
+ outerR,
8859
+ innerR,
8860
+ startAngle,
8861
+ cumAngle
8862
+ );
8863
+ }
8523
8864
  return computePieSlicePath(cx, cy, outerR, innerR, startAngle, cumAngle);
8524
8865
  });
8525
8866
  }
@@ -8714,7 +9055,9 @@ function buildPieViewModel(element, chartData, categoryLabels, isDoughnut) {
8714
9055
  const svgHeight = Math.max(size, 60);
8715
9056
  const pieSeries = chartData.series[0];
8716
9057
  const values = pieSeries?.values ?? [];
8717
- const slices = computePieSlices(values, cx, cy, outerR, innerR);
9058
+ const startAngle = -Math.PI / 2 + (chartData.firstSliceAngle ?? 0) * Math.PI / 180;
9059
+ const explosions = pieSeries ? values.map((_v, i) => resolveDataPointExplosion(pieSeries, i)) : void 0;
9060
+ const slices = computePieSlices(values, cx, cy, outerR, innerR, { startAngle, explosions });
8718
9061
  const primitives = slices.map(
8719
9062
  ({ d }, i) => ({
8720
9063
  kind: "path",
@@ -9859,6 +10202,29 @@ function getAnimationInitialStyle(preset, nativeAnimation) {
9859
10202
  }
9860
10203
  return {};
9861
10204
  }
10205
+ function cssEasingForAnimation(anim) {
10206
+ const hasAccel = anim.accel !== void 0 && anim.accel > 0;
10207
+ const hasDecel = anim.decel !== void 0 && anim.decel > 0;
10208
+ if (hasAccel && hasDecel) {
10209
+ return "ease-in-out";
10210
+ }
10211
+ if (hasAccel) {
10212
+ return "ease-in";
10213
+ }
10214
+ if (hasDecel) {
10215
+ return "ease-out";
10216
+ }
10217
+ return "ease";
10218
+ }
10219
+ function fallbackEffectForClass(presetClass) {
10220
+ if (presetClass === "entr") {
10221
+ return "fadeIn";
10222
+ }
10223
+ if (presetClass === "exit") {
10224
+ return "fadeOut";
10225
+ }
10226
+ return void 0;
10227
+ }
9862
10228
  function buildTimeline(nativeAnimations) {
9863
10229
  if (nativeAnimations.length === 0) {
9864
10230
  return {
@@ -9893,10 +10259,13 @@ function buildTimeline(nativeAnimations) {
9893
10259
  for (const anim of regularAnims) {
9894
10260
  const expandedSteps = expandIterateAnimation(anim);
9895
10261
  for (const singleAnim of expandedSteps) {
9896
- const effect = resolveEffect(singleAnim);
10262
+ let effect = resolveEffect(singleAnim);
9897
10263
  const dynamic = effect ? void 0 : buildDynamicKeyframe(singleAnim, dynamicUid++);
9898
10264
  if (!effect && !dynamic) {
9899
- continue;
10265
+ effect = fallbackEffectForClass(singleAnim.presetClass);
10266
+ if (!effect) {
10267
+ continue;
10268
+ }
9900
10269
  }
9901
10270
  const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
9902
10271
  if (effect) {
@@ -9942,7 +10311,8 @@ function buildTimeline(nativeAnimations) {
9942
10311
  delayMs = animDelay + triggerDelay;
9943
10312
  }
9944
10313
  const iterStr = iterCount === Infinity ? "infinite" : String(iterCount);
9945
- const cssAnimation = `${keyframe} ${duration}ms ease ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10314
+ const easing = cssEasingForAnimation(singleAnim);
10315
+ const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
9946
10316
  currentGroup.push({
9947
10317
  elementId,
9948
10318
  cssAnimation,
@@ -10025,10 +10395,13 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
10025
10395
  const seqGroups = [];
10026
10396
  let seqGroup = [];
10027
10397
  for (const anim of anims) {
10028
- const effect = resolveEffect(anim);
10398
+ let effect = resolveEffect(anim);
10029
10399
  const dynamic = effect ? void 0 : buildDynamicKeyframe(anim, dynamicUid++);
10030
10400
  if (!effect && !dynamic) {
10031
- continue;
10401
+ effect = fallbackEffectForClass(anim.presetClass);
10402
+ if (!effect) {
10403
+ continue;
10404
+ }
10032
10405
  }
10033
10406
  const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
10034
10407
  if (effect) {
@@ -10065,7 +10438,8 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
10065
10438
  delayMs = animDelay + triggerDelay;
10066
10439
  }
10067
10440
  const iterStr = iterCount === Infinity ? "infinite" : String(iterCount);
10068
- const cssAnimation = `${keyframe} ${duration}ms ease ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10441
+ const easing = cssEasingForAnimation(anim);
10442
+ const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10069
10443
  seqGroup.push({
10070
10444
  elementId,
10071
10445
  cssAnimation,
@@ -14141,6 +14515,23 @@ function getConnectionSites(width, height) {
14141
14515
  // left center
14142
14516
  ];
14143
14517
  }
14518
+ function getShapeConnectionSites(shape) {
14519
+ const geo = shape;
14520
+ const cxn = geo.customGeometryConnectionSites;
14521
+ if (!cxn || cxn.length === 0) {
14522
+ return getConnectionSites(shape.width, shape.height);
14523
+ }
14524
+ const pathW = geo.pathWidth && geo.pathWidth > 0 ? geo.pathWidth : shape.width;
14525
+ const pathH = geo.pathHeight && geo.pathHeight > 0 ? geo.pathHeight : shape.height;
14526
+ const vars = createBuiltinVariables({ w: pathW, h: pathH });
14527
+ const scaleX = pathW > 0 ? shape.width / pathW : 1;
14528
+ const scaleY = pathH > 0 ? shape.height / pathH : 1;
14529
+ return cxn.map((site, index) => ({
14530
+ x: resolveCoordinate(site.posX, vars) * scaleX,
14531
+ y: resolveCoordinate(site.posY, vars) * scaleY,
14532
+ index
14533
+ }));
14534
+ }
14144
14535
  function rerouteConnectorsForMovedElements(elements, movedElementIds) {
14145
14536
  if (movedElementIds.size === 0) {
14146
14537
  return [];
@@ -14184,7 +14575,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14184
14575
  if (!startShape) {
14185
14576
  return null;
14186
14577
  }
14187
- const sites = getConnectionSites(startShape.width, startShape.height);
14578
+ const sites = getShapeConnectionSites(startShape);
14188
14579
  const siteIndex = startConn.connectionSiteIndex ?? 0;
14189
14580
  const site = sites[siteIndex] ?? sites[0];
14190
14581
  sx = startShape.x + site.x;
@@ -14200,7 +14591,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14200
14591
  if (!endShape) {
14201
14592
  return null;
14202
14593
  }
14203
- const sites = getConnectionSites(endShape.width, endShape.height);
14594
+ const sites = getShapeConnectionSites(endShape);
14204
14595
  const siteIndex = endConn.connectionSiteIndex ?? 0;
14205
14596
  const site = sites[siteIndex] ?? sites[0];
14206
14597
  ex = endShape.x + site.x;
@@ -14209,12 +14600,16 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14209
14600
  ex = connector.x + connector.width;
14210
14601
  ey = connector.y + connector.height;
14211
14602
  }
14603
+ const flipHorizontal = ex < sx;
14604
+ const flipVertical = ey < sy;
14212
14605
  return {
14213
14606
  id: connector.id,
14214
14607
  x: Math.min(sx, ex),
14215
14608
  y: Math.min(sy, ey),
14216
14609
  width: Math.abs(ex - sx) || 1,
14217
- height: Math.abs(ey - sy) || 1
14610
+ height: Math.abs(ey - sy) || 1,
14611
+ flipHorizontal,
14612
+ flipVertical
14218
14613
  };
14219
14614
  }
14220
14615
  function applyReroutedConnectors(elements, rerouted) {
@@ -14230,13 +14625,20 @@ function applyReroutedConnectors(elements, rerouted) {
14230
14625
  if (!update) {
14231
14626
  return el;
14232
14627
  }
14233
- return {
14628
+ const next = {
14234
14629
  ...el,
14235
14630
  x: update.x,
14236
14631
  y: update.y,
14237
14632
  width: update.width,
14238
14633
  height: update.height
14239
14634
  };
14635
+ if (update.flipHorizontal !== void 0) {
14636
+ next.flipHorizontal = update.flipHorizontal;
14637
+ }
14638
+ if (update.flipVertical !== void 0) {
14639
+ next.flipVertical = update.flipVertical;
14640
+ }
14641
+ return next;
14240
14642
  });
14241
14643
  }
14242
14644
  function getCompoundLineOffsets(compoundLine, strokeWidth) {
@@ -15770,7 +16172,308 @@ var INSTANT = {
15770
16172
  };
15771
16173
  var DEFAULT_TRANSITION_DURATION_MS = 1e3;
15772
16174
  var EASE = "ease-in-out";
15773
- var SLIDE_TRANSITION_KEYFRAMES = `
16175
+ var P14_TRANSITION_KEYFRAMES = `
16176
+ /* \u2500\u2500 Conveyor (translate X with staggered timing) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16177
+ @keyframes pptx-tr-conveyor-in-from-right {
16178
+ from { transform: translateX(100%) rotateY(-30deg); }
16179
+ 60% { transform: translateX(20%) rotateY(-10deg); }
16180
+ to { transform: translateX(0) rotateY(0deg); }
16181
+ }
16182
+ @keyframes pptx-tr-conveyor-out-to-left {
16183
+ from { transform: translateX(0) rotateY(0deg); }
16184
+ 40% { transform: translateX(-20%) rotateY(10deg); }
16185
+ to { transform: translateX(-100%) rotateY(30deg); }
16186
+ }
16187
+ @keyframes pptx-tr-conveyor-in-from-left {
16188
+ from { transform: translateX(-100%) rotateY(30deg); }
16189
+ 60% { transform: translateX(-20%) rotateY(10deg); }
16190
+ to { transform: translateX(0) rotateY(0deg); }
16191
+ }
16192
+ @keyframes pptx-tr-conveyor-out-to-right {
16193
+ from { transform: translateX(0) rotateY(0deg); }
16194
+ 40% { transform: translateX(20%) rotateY(-10deg); }
16195
+ to { transform: translateX(100%) rotateY(-30deg); }
16196
+ }
16197
+
16198
+ /* \u2500\u2500 Doors (clip-path from center split) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16199
+ @keyframes pptx-tr-doors-horz {
16200
+ from { clip-path: inset(0 50%); }
16201
+ to { clip-path: inset(0 0); }
16202
+ }
16203
+ @keyframes pptx-tr-doors-vert {
16204
+ from { clip-path: inset(50% 0); }
16205
+ to { clip-path: inset(0 0); }
16206
+ }
16207
+
16208
+ /* \u2500\u2500 Ferris (rotate elements around center) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16209
+ @keyframes pptx-tr-ferris-in-from-right {
16210
+ from { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
16211
+ to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16212
+ }
16213
+ @keyframes pptx-tr-ferris-out-to-left {
16214
+ from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16215
+ to { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
16216
+ }
16217
+ @keyframes pptx-tr-ferris-in-from-left {
16218
+ from { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
16219
+ to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16220
+ }
16221
+ @keyframes pptx-tr-ferris-out-to-right {
16222
+ from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16223
+ to { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
16224
+ }
16225
+
16226
+ /* \u2500\u2500 Flash (bright flash opacity burst) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16227
+ @keyframes pptx-tr-flash-white {
16228
+ 0% { opacity: 1; }
16229
+ 30% { opacity: 0; }
16230
+ 50% { opacity: 0; }
16231
+ 100% { opacity: 1; }
16232
+ }
16233
+ @keyframes pptx-tr-flash-in {
16234
+ 0% { opacity: 0; }
16235
+ 50% { opacity: 0; }
16236
+ 70% { opacity: 1; }
16237
+ 100% { opacity: 1; }
16238
+ }
16239
+
16240
+ /* \u2500\u2500 Flythrough (scale + translate Z-axis feel) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16241
+ @keyframes pptx-tr-flythrough-in {
16242
+ from { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
16243
+ to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16244
+ }
16245
+ @keyframes pptx-tr-flythrough-out {
16246
+ from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16247
+ to { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
16248
+ }
16249
+ @keyframes pptx-tr-flythrough-reverse-in {
16250
+ from { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
16251
+ to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16252
+ }
16253
+ @keyframes pptx-tr-flythrough-reverse-out {
16254
+ from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16255
+ to { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
16256
+ }
16257
+
16258
+ /* \u2500\u2500 Gallery (translate with perspective) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16259
+ @keyframes pptx-tr-gallery-in-from-right {
16260
+ from { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
16261
+ to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16262
+ }
16263
+ @keyframes pptx-tr-gallery-out-to-left {
16264
+ from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16265
+ to { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
16266
+ }
16267
+ @keyframes pptx-tr-gallery-in-from-left {
16268
+ from { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
16269
+ to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16270
+ }
16271
+ @keyframes pptx-tr-gallery-out-to-right {
16272
+ from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16273
+ to { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
16274
+ }
16275
+
16276
+ /* \u2500\u2500 Glitter (particle dissolve effect) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16277
+ @keyframes pptx-tr-glitter-in {
16278
+ from { opacity: 0; filter: brightness(1.5) contrast(1.3) blur(2px); }
16279
+ 60% { opacity: 0.7; filter: brightness(1.2) contrast(1.1) blur(1px); }
16280
+ to { opacity: 1; filter: brightness(1) contrast(1) blur(0); }
16281
+ }
16282
+
16283
+ /* \u2500\u2500 Honeycomb (hexagonal reveal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16284
+ @keyframes pptx-tr-honeycomb-in {
16285
+ from {
16286
+ clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%);
16287
+ opacity: 0;
16288
+ }
16289
+ to {
16290
+ clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
16291
+ opacity: 1;
16292
+ }
16293
+ }
16294
+ @keyframes pptx-tr-honeycomb-out {
16295
+ from { opacity: 1; }
16296
+ to { opacity: 0; filter: blur(2px); }
16297
+ }
16298
+
16299
+ /* \u2500\u2500 Pan (large-scale translate) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16300
+ @keyframes pptx-tr-pan-from-right {
16301
+ from { transform: translateX(100%); }
16302
+ to { transform: translateX(0); }
16303
+ }
16304
+ @keyframes pptx-tr-pan-to-left {
16305
+ from { transform: translateX(0); }
16306
+ to { transform: translateX(-100%); }
16307
+ }
16308
+ @keyframes pptx-tr-pan-from-left {
16309
+ from { transform: translateX(-100%); }
16310
+ to { transform: translateX(0); }
16311
+ }
16312
+ @keyframes pptx-tr-pan-to-right {
16313
+ from { transform: translateX(0); }
16314
+ to { transform: translateX(100%); }
16315
+ }
16316
+ @keyframes pptx-tr-pan-from-bottom {
16317
+ from { transform: translateY(100%); }
16318
+ to { transform: translateY(0); }
16319
+ }
16320
+ @keyframes pptx-tr-pan-to-top {
16321
+ from { transform: translateY(0); }
16322
+ to { transform: translateY(-100%); }
16323
+ }
16324
+ @keyframes pptx-tr-pan-from-top {
16325
+ from { transform: translateY(-100%); }
16326
+ to { transform: translateY(0); }
16327
+ }
16328
+ @keyframes pptx-tr-pan-to-bottom {
16329
+ from { transform: translateY(0); }
16330
+ to { transform: translateY(100%); }
16331
+ }
16332
+ `;
16333
+ var P14_TRANSITION_KEYFRAMES_2 = `
16334
+ /* \u2500\u2500 Prism (3D rotation via perspective transform) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16335
+ @keyframes pptx-tr-prism-in-from-right {
16336
+ from { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
16337
+ to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16338
+ }
16339
+ @keyframes pptx-tr-prism-out-to-left {
16340
+ from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16341
+ to { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
16342
+ }
16343
+ @keyframes pptx-tr-prism-in-from-left {
16344
+ from { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
16345
+ to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16346
+ }
16347
+ @keyframes pptx-tr-prism-out-to-right {
16348
+ from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16349
+ to { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
16350
+ }
16351
+ @keyframes pptx-tr-prism-in-from-bottom {
16352
+ from { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
16353
+ to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16354
+ }
16355
+ @keyframes pptx-tr-prism-out-to-top {
16356
+ from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16357
+ to { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
16358
+ }
16359
+ @keyframes pptx-tr-prism-in-from-top {
16360
+ from { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
16361
+ to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16362
+ }
16363
+ @keyframes pptx-tr-prism-out-to-bottom {
16364
+ from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16365
+ to { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
16366
+ }
16367
+
16368
+ /* \u2500\u2500 Reveal (slide away reveal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16369
+ @keyframes pptx-tr-reveal-out-to-right {
16370
+ from { transform: translateX(0); }
16371
+ to { transform: translateX(100%); }
16372
+ }
16373
+ @keyframes pptx-tr-reveal-out-to-left {
16374
+ from { transform: translateX(0); }
16375
+ to { transform: translateX(-100%); }
16376
+ }
16377
+ @keyframes pptx-tr-reveal-in {
16378
+ from { opacity: 0.5; }
16379
+ to { opacity: 1; }
16380
+ }
16381
+
16382
+ /* \u2500\u2500 Ripple (expanding ring clip-path) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16383
+ @keyframes pptx-tr-ripple-in {
16384
+ from { clip-path: circle(0% at 50% 50%); opacity: 0.5; }
16385
+ 30% { clip-path: circle(20% at 50% 50%); opacity: 0.7; }
16386
+ 60% { clip-path: circle(50% at 50% 50%); opacity: 0.9; }
16387
+ to { clip-path: circle(75% at 50% 50%); opacity: 1; }
16388
+ }
16389
+
16390
+ /* \u2500\u2500 Shred (fragmented clip-path pieces) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16391
+ @keyframes pptx-tr-shred-strips-in {
16392
+ from { clip-path: inset(0 100% 0 0); opacity: 0; }
16393
+ 30% { clip-path: inset(0 60% 0 0); opacity: 0.5; }
16394
+ to { clip-path: inset(0); opacity: 1; }
16395
+ }
16396
+ @keyframes pptx-tr-shred-rectangles-in {
16397
+ from { clip-path: inset(50%); opacity: 0; }
16398
+ 40% { clip-path: inset(20%); opacity: 0.6; }
16399
+ to { clip-path: inset(0); opacity: 1; }
16400
+ }
16401
+ @keyframes pptx-tr-shred-out {
16402
+ from { opacity: 1; }
16403
+ to { opacity: 0; filter: blur(2px); }
16404
+ }
16405
+
16406
+ /* \u2500\u2500 Switch (flip/rotate swap) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16407
+ @keyframes pptx-tr-switch-in-from-right {
16408
+ from { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
16409
+ to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16410
+ }
16411
+ @keyframes pptx-tr-switch-out-to-left {
16412
+ from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16413
+ to { transform: perspective(800px) rotateY(180deg); opacity: 0; }
16414
+ }
16415
+ @keyframes pptx-tr-switch-in-from-left {
16416
+ from { transform: perspective(800px) rotateY(180deg); opacity: 0; }
16417
+ to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16418
+ }
16419
+ @keyframes pptx-tr-switch-out-to-right {
16420
+ from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16421
+ to { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
16422
+ }
16423
+
16424
+ /* \u2500\u2500 Vortex (rotate + scale spiral) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16425
+ @keyframes pptx-tr-vortex-in {
16426
+ from { transform: rotate(720deg) scale(0); opacity: 0; }
16427
+ to { transform: rotate(0deg) scale(1); opacity: 1; }
16428
+ }
16429
+ @keyframes pptx-tr-vortex-out {
16430
+ from { transform: rotate(0deg) scale(1); opacity: 1; }
16431
+ to { transform: rotate(-720deg) scale(0); opacity: 0; }
16432
+ }
16433
+
16434
+ /* \u2500\u2500 Warp (skew distortion) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16435
+ @keyframes pptx-tr-warp-in {
16436
+ from { transform: scale(0.3) skewX(30deg) skewY(15deg); opacity: 0; }
16437
+ 50% { transform: scale(0.8) skewX(-5deg) skewY(-3deg); opacity: 0.7; }
16438
+ to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
16439
+ }
16440
+ @keyframes pptx-tr-warp-out {
16441
+ from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
16442
+ 50% { transform: scale(0.8) skewX(5deg) skewY(3deg); opacity: 0.7; }
16443
+ to { transform: scale(0.3) skewX(-30deg) skewY(-15deg); opacity: 0; }
16444
+ }
16445
+ @keyframes pptx-tr-warp-reverse-in {
16446
+ from { transform: scale(3) skewX(-20deg) skewY(-10deg); opacity: 0; filter: blur(4px); }
16447
+ to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
16448
+ }
16449
+ @keyframes pptx-tr-warp-reverse-out {
16450
+ from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
16451
+ to { transform: scale(3) skewX(20deg) skewY(10deg); opacity: 0; filter: blur(4px); }
16452
+ }
16453
+
16454
+ /* \u2500\u2500 WheelReverse (reverse wheel rotation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16455
+ @keyframes pptx-tr-wheel-reverse-in {
16456
+ from { clip-path: circle(0% at 50% 50%); transform: rotate(180deg); }
16457
+ to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
16458
+ }
16459
+
16460
+ /* \u2500\u2500 Window (scale from center with border) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16461
+ @keyframes pptx-tr-window-horz {
16462
+ from { clip-path: inset(0 50%); }
16463
+ to { clip-path: inset(0 0); }
16464
+ }
16465
+ @keyframes pptx-tr-window-vert {
16466
+ from { clip-path: inset(50% 0); }
16467
+ to { clip-path: inset(0 0); }
16468
+ }
16469
+ @keyframes pptx-tr-window-out {
16470
+ from { opacity: 1; transform: scale(1); }
16471
+ to { opacity: 0; transform: scale(0.9); }
16472
+ }
16473
+ `;
16474
+ var P14_TRANSITION_KEYFRAMES_ALL = `${P14_TRANSITION_KEYFRAMES}
16475
+ ${P14_TRANSITION_KEYFRAMES_2}`;
16476
+ var CORE_SLIDE_TRANSITION_KEYFRAMES = `
15774
16477
  /* \u2500\u2500 Fade \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
15775
16478
  @keyframes pptx-tr-fade-in {
15776
16479
  from { opacity: 0; }
@@ -16033,8 +16736,243 @@ var SLIDE_TRANSITION_KEYFRAMES = `
16033
16736
  to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
16034
16737
  }
16035
16738
  `;
16739
+ var SLIDE_TRANSITION_KEYFRAMES = `${CORE_SLIDE_TRANSITION_KEYFRAMES}
16740
+ ${P14_TRANSITION_KEYFRAMES_ALL}`;
16741
+ function resolveLR(direction) {
16742
+ if (direction === "l" || direction === "r") {
16743
+ return direction;
16744
+ }
16745
+ return "l";
16746
+ }
16747
+ function resolveP14Orientation(direction, orient) {
16748
+ if (orient === "horz" || orient === "vert") {
16749
+ return orient;
16750
+ }
16751
+ if (direction === "horz" || direction === "vert") {
16752
+ return direction;
16753
+ }
16754
+ return "horz";
16755
+ }
16756
+ function resolveCardinal(direction) {
16757
+ switch (direction) {
16758
+ case "l":
16759
+ return "left";
16760
+ case "r":
16761
+ return "right";
16762
+ case "u":
16763
+ return "up";
16764
+ case "d":
16765
+ return "down";
16766
+ default:
16767
+ return "left";
16768
+ }
16769
+ }
16770
+ function directionalPair(direction, prefix, dur, ease) {
16771
+ const dir = resolveCardinal(direction);
16772
+ const opposites = {
16773
+ left: ["to-left", "from-right"],
16774
+ right: ["to-right", "from-left"],
16775
+ up: ["to-top", "from-bottom"],
16776
+ down: ["to-bottom", "from-top"]
16777
+ };
16778
+ const [outSuffix, inSuffix] = opposites[dir];
16779
+ return {
16780
+ outgoing: `${prefix}-${outSuffix} ${dur} ${ease} forwards`,
16781
+ incoming: `${prefix}-${inSuffix} ${dur} ${ease} forwards`,
16782
+ outgoingOnTop: false
16783
+ };
16784
+ }
16785
+ function cardinalOutInPair(direction, prefix, dur, ease) {
16786
+ const dir = resolveCardinal(direction);
16787
+ const map = {
16788
+ left: ["out-to-left", "in-from-right"],
16789
+ right: ["out-to-right", "in-from-left"],
16790
+ up: ["out-to-top", "in-from-bottom"],
16791
+ down: ["out-to-bottom", "in-from-top"]
16792
+ };
16793
+ const [outSuffix, inSuffix] = map[dir];
16794
+ return {
16795
+ outgoing: `${prefix}-${outSuffix} ${dur} ${ease} forwards`,
16796
+ incoming: `${prefix}-${inSuffix} ${dur} ${ease} forwards`,
16797
+ outgoingOnTop: false
16798
+ };
16799
+ }
16800
+ function getP14TransitionAnimations(type, durationMs, direction, orient) {
16801
+ const dur = `${durationMs}ms`;
16802
+ const ease = EASE;
16803
+ switch (type) {
16804
+ case "conveyor": {
16805
+ const lr = resolveLR(direction);
16806
+ if (lr === "l") {
16807
+ return {
16808
+ outgoing: `pptx-tr-conveyor-out-to-left ${dur} ${ease} forwards`,
16809
+ incoming: `pptx-tr-conveyor-in-from-right ${dur} ${ease} forwards`,
16810
+ outgoingOnTop: false
16811
+ };
16812
+ }
16813
+ return {
16814
+ outgoing: `pptx-tr-conveyor-out-to-right ${dur} ${ease} forwards`,
16815
+ incoming: `pptx-tr-conveyor-in-from-left ${dur} ${ease} forwards`,
16816
+ outgoingOnTop: false
16817
+ };
16818
+ }
16819
+ case "doors": {
16820
+ const o = resolveP14Orientation(direction, orient);
16821
+ return {
16822
+ outgoing: "none",
16823
+ incoming: o === "vert" ? `pptx-tr-doors-vert ${dur} ${ease} forwards` : `pptx-tr-doors-horz ${dur} ${ease} forwards`,
16824
+ outgoingOnTop: false
16825
+ };
16826
+ }
16827
+ case "ferris": {
16828
+ const lr = resolveLR(direction);
16829
+ if (lr === "l") {
16830
+ return {
16831
+ outgoing: `pptx-tr-ferris-out-to-left ${dur} ${ease} forwards`,
16832
+ incoming: `pptx-tr-ferris-in-from-right ${dur} ${ease} forwards`,
16833
+ outgoingOnTop: false
16834
+ };
16835
+ }
16836
+ return {
16837
+ outgoing: `pptx-tr-ferris-out-to-right ${dur} ${ease} forwards`,
16838
+ incoming: `pptx-tr-ferris-in-from-left ${dur} ${ease} forwards`,
16839
+ outgoingOnTop: false
16840
+ };
16841
+ }
16842
+ case "flash":
16843
+ return {
16844
+ outgoing: `pptx-tr-flash-white ${dur} ${ease} forwards`,
16845
+ incoming: `pptx-tr-flash-in ${dur} ${ease} forwards`,
16846
+ outgoingOnTop: true
16847
+ };
16848
+ case "flythrough": {
16849
+ const isOut = direction === "out";
16850
+ if (isOut) {
16851
+ return {
16852
+ outgoing: `pptx-tr-flythrough-reverse-out ${dur} ${ease} forwards`,
16853
+ incoming: `pptx-tr-flythrough-reverse-in ${dur} ${ease} forwards`,
16854
+ outgoingOnTop: true
16855
+ };
16856
+ }
16857
+ return {
16858
+ outgoing: `pptx-tr-flythrough-out ${dur} ${ease} forwards`,
16859
+ incoming: `pptx-tr-flythrough-in ${dur} ${ease} forwards`,
16860
+ outgoingOnTop: true
16861
+ };
16862
+ }
16863
+ case "gallery": {
16864
+ const lr = resolveLR(direction);
16865
+ if (lr === "l") {
16866
+ return {
16867
+ outgoing: `pptx-tr-gallery-out-to-left ${dur} ${ease} forwards`,
16868
+ incoming: `pptx-tr-gallery-in-from-right ${dur} ${ease} forwards`,
16869
+ outgoingOnTop: false
16870
+ };
16871
+ }
16872
+ return {
16873
+ outgoing: `pptx-tr-gallery-out-to-right ${dur} ${ease} forwards`,
16874
+ incoming: `pptx-tr-gallery-in-from-left ${dur} ${ease} forwards`,
16875
+ outgoingOnTop: false
16876
+ };
16877
+ }
16878
+ case "glitter":
16879
+ return {
16880
+ outgoing: `pptx-tr-fade-out ${dur} ${ease} forwards`,
16881
+ incoming: `pptx-tr-glitter-in ${dur} ${ease} forwards`,
16882
+ outgoingOnTop: true
16883
+ };
16884
+ case "honeycomb":
16885
+ return {
16886
+ outgoing: `pptx-tr-honeycomb-out ${dur} ${ease} forwards`,
16887
+ incoming: `pptx-tr-honeycomb-in ${dur} ${ease} forwards`,
16888
+ outgoingOnTop: true
16889
+ };
16890
+ case "pan":
16891
+ return directionalPair(direction, "pptx-tr-pan", dur, ease);
16892
+ case "prism":
16893
+ return cardinalOutInPair(direction, "pptx-tr-prism", dur, ease);
16894
+ case "reveal": {
16895
+ const lr = resolveLR(direction);
16896
+ return {
16897
+ outgoing: lr === "l" ? `pptx-tr-reveal-out-to-left ${dur} ${ease} forwards` : `pptx-tr-reveal-out-to-right ${dur} ${ease} forwards`,
16898
+ incoming: `pptx-tr-reveal-in ${dur} ${ease} forwards`,
16899
+ outgoingOnTop: true
16900
+ };
16901
+ }
16902
+ case "ripple":
16903
+ return {
16904
+ outgoing: "none",
16905
+ incoming: `pptx-tr-ripple-in ${dur} ${ease} forwards`,
16906
+ outgoingOnTop: false
16907
+ };
16908
+ case "shred": {
16909
+ const pattern = direction === "rectangles" ? "rectangles" : "strips";
16910
+ return {
16911
+ outgoing: `pptx-tr-shred-out ${dur} ${ease} forwards`,
16912
+ incoming: pattern === "rectangles" ? `pptx-tr-shred-rectangles-in ${dur} ${ease} forwards` : `pptx-tr-shred-strips-in ${dur} ${ease} forwards`,
16913
+ outgoingOnTop: true
16914
+ };
16915
+ }
16916
+ case "switch": {
16917
+ const lr = resolveLR(direction);
16918
+ if (lr === "l") {
16919
+ return {
16920
+ outgoing: `pptx-tr-switch-out-to-left ${dur} ${ease} forwards`,
16921
+ incoming: `pptx-tr-switch-in-from-right ${dur} ${ease} forwards`,
16922
+ outgoingOnTop: false
16923
+ };
16924
+ }
16925
+ return {
16926
+ outgoing: `pptx-tr-switch-out-to-right ${dur} ${ease} forwards`,
16927
+ incoming: `pptx-tr-switch-in-from-left ${dur} ${ease} forwards`,
16928
+ outgoingOnTop: false
16929
+ };
16930
+ }
16931
+ case "vortex":
16932
+ return {
16933
+ outgoing: `pptx-tr-vortex-out ${dur} ${ease} forwards`,
16934
+ incoming: `pptx-tr-vortex-in ${dur} ${ease} forwards`,
16935
+ outgoingOnTop: true
16936
+ };
16937
+ case "warp": {
16938
+ const isOut = direction === "out";
16939
+ if (isOut) {
16940
+ return {
16941
+ outgoing: `pptx-tr-warp-reverse-out ${dur} ${ease} forwards`,
16942
+ incoming: `pptx-tr-warp-reverse-in ${dur} ${ease} forwards`,
16943
+ outgoingOnTop: true
16944
+ };
16945
+ }
16946
+ return {
16947
+ outgoing: `pptx-tr-warp-out ${dur} ${ease} forwards`,
16948
+ incoming: `pptx-tr-warp-in ${dur} ${ease} forwards`,
16949
+ outgoingOnTop: true
16950
+ };
16951
+ }
16952
+ case "wheelReverse":
16953
+ return {
16954
+ outgoing: "none",
16955
+ incoming: `pptx-tr-wheel-reverse-in ${dur} ${ease} forwards`,
16956
+ outgoingOnTop: false
16957
+ };
16958
+ case "window": {
16959
+ const o = resolveP14Orientation(direction, orient);
16960
+ return {
16961
+ outgoing: `pptx-tr-window-out ${dur} ${ease} forwards`,
16962
+ incoming: o === "vert" ? `pptx-tr-window-vert ${dur} ${ease} forwards` : `pptx-tr-window-horz ${dur} ${ease} forwards`,
16963
+ outgoingOnTop: true
16964
+ };
16965
+ }
16966
+ default:
16967
+ return void 0;
16968
+ }
16969
+ }
16036
16970
  function getSlideTransitionAnimations(type, durationMs, direction, orient, spokes) {
16037
16971
  const dur = `${durationMs}ms`;
16972
+ const p14 = getP14TransitionAnimations(type, durationMs, direction, orient);
16973
+ if (p14) {
16974
+ return p14;
16975
+ }
16038
16976
  switch (type) {
16039
16977
  case "none":
16040
16978
  case "cut":
@@ -16236,31 +17174,13 @@ function getSlideTransitionAnimations(type, durationMs, direction, orient, spoke
16236
17174
  const randomType = RANDOM_ELIGIBLE_TYPES[Math.floor(Math.random() * RANDOM_ELIGIBLE_TYPES.length)];
16237
17175
  return getSlideTransitionAnimations(randomType, durationMs, direction, orient);
16238
17176
  }
16239
- // ── Exotic / 3-D transitions approximated with the closest well-tested
16240
- // 2-D CSS behaviour (delegates to an existing case rather than emitting a
16241
- // plain fade). A faithful per-effect keyframe set is available via
16242
- // `getP14TransitionAnimations`.
16243
- case "pan":
16244
- case "gallery":
16245
- case "conveyor":
16246
- return getSlideTransitionAnimations("push", durationMs, direction, orient);
16247
- case "reveal":
16248
- return getSlideTransitionAnimations("wipe", durationMs, direction, orient);
16249
- case "doors":
16250
- return getSlideTransitionAnimations("split", durationMs, direction, orient);
16251
- case "switch":
16252
- case "flythrough":
16253
- case "ferris":
16254
- case "prism":
16255
- return getSlideTransitionAnimations("zoom", durationMs, direction, orient);
16256
- case "ripple":
16257
- case "honeycomb":
16258
- case "glitter":
16259
- case "shred":
16260
- return getSlideTransitionAnimations("dissolve", durationMs, direction, orient);
16261
- case "flash":
16262
- return getSlideTransitionAnimations("fade", durationMs, direction, orient);
16263
- // Fallback (unknown / not-yet-mapped type) — symmetrical cross-fade.
17177
+ // The exotic / 3-D transition family (conveyor/doors/ferris/flash/
17178
+ // flythrough/gallery/glitter/honeycomb/pan/prism/reveal/ripple/shred/
17179
+ // switch/vortex/warp/wheelReverse/window) is handled faithfully above via
17180
+ // `getP14TransitionAnimations` and never reaches this switch.
17181
+ // Fallback (unknown / not-yet-mapped type, e.g. the p15 cinematic set:
17182
+ // cube/flip/rotate/orbit/fracture/peelOff/pageCurl*/airplane/origami)
17183
+ // — symmetrical cross-fade.
16264
17184
  default:
16265
17185
  return {
16266
17186
  outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
@@ -16985,30 +17905,46 @@ function computeTargetLayout(nodes, box, palette, style, elementId) {
16985
17905
  family: "target"
16986
17906
  };
16987
17907
  }
16988
- function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout) {
17908
+ function interpolateSmartArtPalette(palette, count, method, hueDirection) {
17909
+ if (count <= 0 || palette.length === 0) {
17910
+ return [];
17911
+ }
17912
+ if (palette.length < 2 || count <= palette.length) {
17913
+ return Array.from({ length: count }, (_, i) => palette[i % palette.length]);
17914
+ }
17915
+ const segments = palette.length - 1;
17916
+ return Array.from({ length: count }, (_, i) => {
17917
+ const pos = i / (count - 1) * segments;
17918
+ const lower = Math.min(Math.floor(pos), segments - 1);
17919
+ const frac = pos - lower;
17920
+ return interpolateColor(palette[lower], palette[lower + 1], frac, "hsl", hueDirection);
17921
+ });
17922
+ }
17923
+ function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout, interpolation) {
16989
17924
  const flat = flattenNodes(nodes);
16990
17925
  const family = resolveLayoutFamily(nodes, resolvedLayoutType, layout);
17926
+ const pal = interpolation?.method === "span" ? interpolateSmartArtPalette(palette, flat.length, "span", interpolation.hueDirection) : palette;
16991
17927
  switch (family) {
16992
17928
  case "list":
16993
- return computeListLayout(flat, box, palette, style, elementId);
17929
+ return computeListLayout(flat, box, pal, style, elementId);
16994
17930
  case "process":
16995
- return computeProcessLayout(flat, box, palette, style, elementId);
17931
+ return computeProcessLayout(flat, box, pal, style, elementId);
16996
17932
  case "cycle":
16997
- return computeCycleLayout(flat, box, palette, style, elementId);
17933
+ return computeCycleLayout(flat, box, pal, style, elementId);
16998
17934
  case "hierarchy":
16999
- return computeHierarchyLayout(nodes, box, palette, style, elementId);
17935
+ return computeHierarchyLayout(nodes, box, pal, style, elementId);
17000
17936
  case "matrix":
17001
- return computeMatrixLayout(flat, box, palette, style, elementId);
17937
+ return computeMatrixLayout(flat, box, pal, style, elementId);
17002
17938
  case "radial":
17003
- return computeRadialLayout(flat, box, palette, style, elementId);
17939
+ return computeRadialLayout(flat, box, pal, style, elementId);
17004
17940
  case "pyramid":
17005
- return computePyramidLayout(flat, box, palette, style, elementId);
17941
+ return computePyramidLayout(flat, box, pal, style, elementId);
17006
17942
  case "venn":
17007
- return computeVennLayout(flat, box, palette, style, elementId);
17943
+ return computeVennLayout(flat, box, pal, style, elementId);
17008
17944
  case "funnel":
17009
- return computeFunnelLayout(flat, box, palette, style, elementId);
17945
+ return computeFunnelLayout(flat, box, pal, style, elementId);
17010
17946
  case "target":
17011
- return computeTargetLayout(flat, box, palette, style, elementId);
17947
+ return computeTargetLayout(flat, box, pal, style, elementId);
17012
17948
  }
17013
17949
  }
17014
17950
  function parseViewBox(viewBox) {