pptx-react-viewer 2.19.6 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +1 -1
  3. package/dist/{AiChatPanel-IWC2BJH4.js → AiChatPanel-KOKEVIOQ.js} +24 -24
  4. package/dist/AiChatPanel-KOKEVIOQ.js.br +0 -0
  5. package/dist/AiChatPanel-KOKEVIOQ.js.gz +0 -0
  6. package/dist/{AiChatPanel-2VR6UFFK.mjs → AiChatPanel-S5UYFWT2.mjs} +4 -4
  7. package/dist/AiChatPanel-S5UYFWT2.mjs.br +0 -0
  8. package/dist/AiChatPanel-S5UYFWT2.mjs.gz +0 -0
  9. package/dist/{Model3DScene-ATRIORJV.js → Model3DScene-T5372GIJ.js} +2 -2
  10. package/dist/Model3DScene-T5372GIJ.js.br +0 -0
  11. package/dist/Model3DScene-T5372GIJ.js.gz +0 -0
  12. package/dist/{Model3DScene-E4T6KAJF.mjs → Model3DScene-T6QOOVLN.mjs} +1 -1
  13. package/dist/Model3DScene-T6QOOVLN.mjs.br +0 -0
  14. package/dist/Model3DScene-T6QOOVLN.mjs.gz +0 -0
  15. package/dist/{chunk-IWCBDKPX.mjs → chunk-2T7J57AC.mjs} +1 -1
  16. package/dist/chunk-2T7J57AC.mjs.br +0 -0
  17. package/dist/chunk-2T7J57AC.mjs.gz +0 -0
  18. package/dist/{chunk-MVKRI3CZ.js → chunk-6CPUGAK7.js} +2 -0
  19. package/dist/chunk-6CPUGAK7.js.br +0 -0
  20. package/dist/{chunk-MVKRI3CZ.js.gz → chunk-6CPUGAK7.js.gz} +0 -0
  21. package/dist/{chunk-2N2Z7WG2.js → chunk-AFAAKYYB.js} +1093 -1254
  22. package/dist/chunk-AFAAKYYB.js.br +0 -0
  23. package/dist/chunk-AFAAKYYB.js.gz +0 -0
  24. package/dist/{chunk-FTUGCQVY.js → chunk-BW3ZS73U.js} +178 -172
  25. package/dist/chunk-BW3ZS73U.js.br +0 -0
  26. package/dist/chunk-BW3ZS73U.js.gz +0 -0
  27. package/dist/{chunk-3BK53XWF.js → chunk-J56DMNSD.js} +746 -483
  28. package/dist/chunk-J56DMNSD.js.br +0 -0
  29. package/dist/chunk-J56DMNSD.js.gz +0 -0
  30. package/dist/{chunk-SQJBFMEX.mjs → chunk-MZOZNBRO.mjs} +2 -0
  31. package/dist/chunk-MZOZNBRO.mjs.br +0 -0
  32. package/dist/{chunk-SQJBFMEX.mjs.gz → chunk-MZOZNBRO.mjs.gz} +0 -0
  33. package/dist/{chunk-RQWZ7J3Z.mjs → chunk-QLELFH7A.mjs} +728 -480
  34. package/dist/chunk-QLELFH7A.mjs.br +0 -0
  35. package/dist/chunk-QLELFH7A.mjs.gz +0 -0
  36. package/dist/{chunk-YEEOYPFO.js → chunk-SAKMXLW2.js} +382 -379
  37. package/dist/chunk-SAKMXLW2.js.br +0 -0
  38. package/dist/chunk-SAKMXLW2.js.gz +0 -0
  39. package/dist/{chunk-KPNZXUKK.js → chunk-T7OUKBWK.js} +3 -3
  40. package/dist/chunk-T7OUKBWK.js.br +0 -0
  41. package/dist/chunk-T7OUKBWK.js.gz +0 -0
  42. package/dist/{chunk-667ZAXQN.mjs → chunk-U2UIJRSW.mjs} +25 -19
  43. package/dist/chunk-U2UIJRSW.mjs.br +0 -0
  44. package/dist/chunk-U2UIJRSW.mjs.gz +0 -0
  45. package/dist/{chunk-NHN6XKJV.mjs → chunk-XWCN4TGE.mjs} +67 -228
  46. package/dist/chunk-XWCN4TGE.mjs.br +0 -0
  47. package/dist/chunk-XWCN4TGE.mjs.gz +0 -0
  48. package/dist/{chunk-VU4RQSTI.mjs → chunk-YMNURZ22.mjs} +6 -3
  49. package/dist/chunk-YMNURZ22.mjs.br +0 -0
  50. package/dist/chunk-YMNURZ22.mjs.gz +0 -0
  51. package/dist/i18n.js +4 -4
  52. package/dist/i18n.js.br +0 -0
  53. package/dist/i18n.js.gz +0 -0
  54. package/dist/i18n.mjs +1 -1
  55. package/dist/i18n.mjs.br +0 -0
  56. package/dist/i18n.mjs.gz +0 -0
  57. package/dist/index.js +47 -47
  58. package/dist/index.js.br +0 -0
  59. package/dist/index.js.gz +0 -0
  60. package/dist/index.mjs +6 -6
  61. package/dist/index.mjs.br +0 -0
  62. package/dist/index.mjs.gz +0 -0
  63. package/dist/internals.js +79 -79
  64. package/dist/internals.js.br +0 -0
  65. package/dist/internals.js.gz +0 -0
  66. package/dist/internals.mjs +4 -4
  67. package/dist/internals.mjs.br +0 -0
  68. package/dist/internals.mjs.gz +0 -0
  69. package/dist/pptx-viewer.css +1 -1
  70. package/dist/pptx-viewer.css.br +0 -0
  71. package/dist/pptx-viewer.css.gz +0 -0
  72. package/dist/viewer/index.js +27 -27
  73. package/dist/viewer/index.js.br +0 -0
  74. package/dist/viewer/index.js.gz +0 -0
  75. package/dist/viewer/index.mjs +6 -6
  76. package/dist/viewer/index.mjs.br +0 -0
  77. package/dist/viewer/index.mjs.gz +0 -0
  78. package/package.json +1 -1
  79. package/dist/AiChatPanel-2VR6UFFK.mjs.br +0 -0
  80. package/dist/AiChatPanel-2VR6UFFK.mjs.gz +0 -0
  81. package/dist/AiChatPanel-IWC2BJH4.js.br +0 -0
  82. package/dist/AiChatPanel-IWC2BJH4.js.gz +0 -0
  83. package/dist/Model3DScene-ATRIORJV.js.br +0 -0
  84. package/dist/Model3DScene-ATRIORJV.js.gz +0 -0
  85. package/dist/Model3DScene-E4T6KAJF.mjs.br +0 -0
  86. package/dist/Model3DScene-E4T6KAJF.mjs.gz +0 -0
  87. package/dist/chunk-2N2Z7WG2.js.br +0 -0
  88. package/dist/chunk-2N2Z7WG2.js.gz +0 -0
  89. package/dist/chunk-3BK53XWF.js.br +0 -0
  90. package/dist/chunk-3BK53XWF.js.gz +0 -0
  91. package/dist/chunk-667ZAXQN.mjs.br +0 -0
  92. package/dist/chunk-667ZAXQN.mjs.gz +0 -0
  93. package/dist/chunk-FTUGCQVY.js.br +0 -0
  94. package/dist/chunk-FTUGCQVY.js.gz +0 -0
  95. package/dist/chunk-IWCBDKPX.mjs.br +0 -0
  96. package/dist/chunk-IWCBDKPX.mjs.gz +0 -0
  97. package/dist/chunk-KPNZXUKK.js.br +0 -0
  98. package/dist/chunk-KPNZXUKK.js.gz +0 -0
  99. package/dist/chunk-MVKRI3CZ.js.br +0 -0
  100. package/dist/chunk-NHN6XKJV.mjs.br +0 -0
  101. package/dist/chunk-NHN6XKJV.mjs.gz +0 -0
  102. package/dist/chunk-RQWZ7J3Z.mjs.br +0 -0
  103. package/dist/chunk-RQWZ7J3Z.mjs.gz +0 -0
  104. package/dist/chunk-SQJBFMEX.mjs.br +0 -0
  105. package/dist/chunk-VU4RQSTI.mjs.br +0 -0
  106. package/dist/chunk-VU4RQSTI.mjs.gz +0 -0
  107. package/dist/chunk-YEEOYPFO.js.br +0 -0
  108. package/dist/chunk-YEEOYPFO.js.gz +0 -0
@@ -20973,9 +20973,9 @@ function applyDrawingColorTransforms(baseColor, colorNode) {
20973
20973
  }
20974
20974
  const tint3 = parseDrawingPercent(getVal("a:tint"));
20975
20975
  if (tint3 !== void 0) {
20976
- r += (255 - r) * tint3;
20977
- g += (255 - g) * tint3;
20978
- b += (255 - b) * tint3;
20976
+ r = 255 - (255 - r) * tint3;
20977
+ g = 255 - (255 - g) * tint3;
20978
+ b = 255 - (255 - b) * tint3;
20979
20979
  }
20980
20980
  const hslKeys = [
20981
20981
  "a:hue",
@@ -27501,7 +27501,7 @@ function guidToKey(guid) {
27501
27501
  }
27502
27502
  const key2 = new Uint8Array(KEY_LENGTH);
27503
27503
  for (let i = 0; i < KEY_LENGTH; i++) {
27504
- key2[i] = parseInt(stripped.substring(i * 2, i * 2 + 2), 16);
27504
+ key2[KEY_LENGTH - 1 - i] = parseInt(stripped.substring(i * 2, i * 2 + 2), 16);
27505
27505
  }
27506
27506
  return key2;
27507
27507
  }
@@ -27582,9 +27582,9 @@ function addSmartArtNode(data, text2, afterNodeId) {
27582
27582
  };
27583
27583
  const nodes = [...data.nodes];
27584
27584
  if (afterNodeId) {
27585
- const siblingIndex = nodes.findIndex((n) => n.id === afterNodeId);
27586
- if (siblingIndex >= 0) {
27587
- nodes.splice(siblingIndex + 1, 0, newNode);
27585
+ const siblingIndex2 = nodes.findIndex((n) => n.id === afterNodeId);
27586
+ if (siblingIndex2 >= 0) {
27587
+ nodes.splice(siblingIndex2 + 1, 0, newNode);
27588
27588
  } else {
27589
27589
  nodes.push(newNode);
27590
27590
  }
@@ -56165,11 +56165,6 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
56165
56165
  if (requestedSourcePath && this.slideMap.has(requestedSourcePath) && requestedSourcePath.startsWith("ppt/slides/slide")) {
56166
56166
  return requestedSourcePath;
56167
56167
  }
56168
- for (const slidePath of this.slideMap.keys()) {
56169
- if (slidePath.startsWith("ppt/slides/slide")) {
56170
- return slidePath;
56171
- }
56172
- }
56173
56168
  return void 0;
56174
56169
  }
56175
56170
  async loadSlideRelationships(slidePath, relsPath) {
@@ -56209,8 +56204,7 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
56209
56204
  }
56210
56205
  const cSld = pSld["p:cSld"];
56211
56206
  if (!cSld["p:spTree"]) {
56212
- const emptySlide = this.createEmptySlideXml();
56213
- const emptyTree = emptySlide["p:sld"]?.["p:cSld"]?.["p:spTree"];
56207
+ const emptySlide = this.createEmptySlideXml(), emptyTree = emptySlide["p:sld"]?.["p:cSld"]?.["p:spTree"];
56214
56208
  if (emptyTree) {
56215
56209
  cSld["p:spTree"] = emptyTree;
56216
56210
  }
@@ -59009,13 +59003,32 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
59009
59003
  const nvPr = xmlPath(raw, "p:nvSpPr", "p:nvPr") ?? xmlPath(raw, "p:nvPicPr", "p:nvPr") ?? xmlPath(raw, "p:nvGraphicFramePr", "p:nvPr");
59010
59004
  return this.readPlaceholderInfoFromNvPr(nvPr);
59011
59005
  }
59006
+ /**
59007
+ * Whether a placeholder element is still an untouched prompt ("Click to
59008
+ * add text") rather than real user content. Only `type: 'text'`
59009
+ * placeholders can be untouched this way: `createEmptyPlaceholderElement`
59010
+ * only ever fabricates that kind, and any other kind (picture, table,
59011
+ * chart, ...) implies the user already put something in it.
59012
+ */
59013
+ isUntouchedPlaceholderPrompt(element) {
59014
+ if (element.type !== "text") {
59015
+ return false;
59016
+ }
59017
+ if (element.text && element.text.trim().length > 0) {
59018
+ return false;
59019
+ }
59020
+ return !element.textSegments?.some((segment) => segment.text.trim().length > 0);
59021
+ }
59012
59022
  // ── Layout placeholder extraction ───────────────────────────────────
59013
59023
  /**
59014
- * Extract all placeholders from a layout's `p:spTree`, returning
59015
- * their placeholder info and their transform (position/size in EMU).
59024
+ * Extract placeholder info + transform (position/size in EMU) for every
59025
+ * placeholder shape in a `p:spTree`. Shared by layout and master
59026
+ * extraction so a layout slot that omits `a:xfrm` (common: only the first
59027
+ * placeholder of a family typically carries one, the rest inherit
59028
+ * position/size from the matching master placeholder) can be resolved
59029
+ * against the same shape of the master.
59016
59030
  */
59017
- extractLayoutPlaceholders(layoutXml) {
59018
- const spTree = xmlPath(layoutXml, "p:sldLayout", "p:cSld", "p:spTree");
59031
+ extractPlaceholderSlotsFromSpTree(spTree) {
59019
59032
  if (!spTree) {
59020
59033
  return [];
59021
59034
  }
@@ -59043,6 +59056,103 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
59043
59056
  }
59044
59057
  return result;
59045
59058
  }
59059
+ /**
59060
+ * Resolve a layout's slideMaster path from its `.rels` map. Mirrors
59061
+ * `PptxHandlerRuntimeLoadPipeline.findMasterPathForLayout` under a
59062
+ * distinct name: that mixin sits higher in the chain and is not yet
59063
+ * available at this level, and reusing its exact name here would collide
59064
+ * across the mixin chain (TypeScript requires consistent member
59065
+ * visibility for same-named members across the whole prototype chain).
59066
+ */
59067
+ resolveMasterPathForNewLayout(layoutPath) {
59068
+ const layoutRels = this.slideRelsMap.get(layoutPath);
59069
+ if (!layoutRels) {
59070
+ return void 0;
59071
+ }
59072
+ for (const [, target] of layoutRels.entries()) {
59073
+ if (target.includes("slideMaster")) {
59074
+ const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
59075
+ if (target.startsWith("..")) {
59076
+ const segments = (layoutDir + target).split("/");
59077
+ const stack = [];
59078
+ for (const seg of segments) {
59079
+ if (seg === "..") {
59080
+ stack.pop();
59081
+ } else if (seg && seg !== ".") {
59082
+ stack.push(seg);
59083
+ }
59084
+ }
59085
+ return stack.join("/");
59086
+ }
59087
+ return `ppt/${stripParentDirSegments(target)}`;
59088
+ }
59089
+ }
59090
+ return void 0;
59091
+ }
59092
+ /**
59093
+ * Find the master placeholder slot a layout slot inherits its geometry
59094
+ * from when the layout shape itself carries no `a:xfrm`. Prefers an idx
59095
+ * match (the common case: layout and master share idx for ordinary
59096
+ * title/body placeholders); falls back to a type match (with the
59097
+ * ctrTitle->title / subTitle->body aliasing `placeholderMatches` also
59098
+ * applies) since idx is not guaranteed to line up for every family.
59099
+ */
59100
+ findMasterSlotForLayoutSlot(masterSlots, layoutPhInfo) {
59101
+ if (layoutPhInfo.idx !== void 0) {
59102
+ const byIdx = masterSlots.find((slot) => slot.phInfo.idx === layoutPhInfo.idx);
59103
+ if (byIdx) {
59104
+ return byIdx;
59105
+ }
59106
+ }
59107
+ if (!layoutPhInfo.type) {
59108
+ return void 0;
59109
+ }
59110
+ const aliasedType = layoutPhInfo.type === "ctrtitle" ? "title" : layoutPhInfo.type === "subtitle" ? "body" : layoutPhInfo.type;
59111
+ return masterSlots.find(
59112
+ (slot) => slot.phInfo.type === layoutPhInfo.type || slot.phInfo.type === aliasedType
59113
+ );
59114
+ }
59115
+ /**
59116
+ * Extract all placeholders from a layout's `p:spTree`, returning their
59117
+ * placeholder info and transform (position/size in EMU). A slot whose
59118
+ * layout shape has no `a:xfrm` (inheriting position/size from the master
59119
+ * instead) resolves its geometry against the matching master placeholder
59120
+ * rather than reporting an all-zero transform.
59121
+ */
59122
+ extractLayoutPlaceholders(layoutXml, layoutPath) {
59123
+ const spTree = xmlPath(layoutXml, "p:sldLayout", "p:cSld", "p:spTree");
59124
+ const slots = this.extractPlaceholderSlotsFromSpTree(spTree);
59125
+ if (slots.length === 0 || !layoutPath) {
59126
+ return slots;
59127
+ }
59128
+ const needsMasterGeometry = slots.some((slot) => slot.cxEmu <= 0 || slot.cyEmu <= 0);
59129
+ if (!needsMasterGeometry) {
59130
+ return slots;
59131
+ }
59132
+ const masterPath = this.resolveMasterPathForNewLayout(layoutPath);
59133
+ const masterXml = masterPath ? this.masterXmlMap.get(masterPath) : void 0;
59134
+ const masterSpTree = xmlPath(masterXml, "p:sldMaster", "p:cSld", "p:spTree");
59135
+ const masterSlots = this.extractPlaceholderSlotsFromSpTree(masterSpTree);
59136
+ if (masterSlots.length === 0) {
59137
+ return slots;
59138
+ }
59139
+ return slots.map((slot) => {
59140
+ if (slot.cxEmu > 0 && slot.cyEmu > 0) {
59141
+ return slot;
59142
+ }
59143
+ const masterSlot = this.findMasterSlotForLayoutSlot(masterSlots, slot.phInfo);
59144
+ if (!masterSlot || masterSlot.cxEmu <= 0 || masterSlot.cyEmu <= 0) {
59145
+ return slot;
59146
+ }
59147
+ return {
59148
+ ...slot,
59149
+ xEmu: masterSlot.xEmu,
59150
+ yEmu: masterSlot.yEmu,
59151
+ cxEmu: masterSlot.cxEmu,
59152
+ cyEmu: masterSlot.cyEmu
59153
+ };
59154
+ });
59155
+ }
59046
59156
  // ── Core layout switching logic ─────────────────────────────────────
59047
59157
  /**
59048
59158
  * Re-map slide elements to a new layout's placeholders.
@@ -59059,7 +59169,10 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
59059
59169
  * @returns The updated elements array.
59060
59170
  */
59061
59171
  remapElementsToNewLayout(elements2, newLayoutXml, newLayoutPath) {
59062
- const targets = this.extractLayoutPlaceholders(newLayoutXml).map((slot) => ({ ...slot, matched: false }));
59172
+ const targets = this.extractLayoutPlaceholders(newLayoutXml, newLayoutPath).map((slot) => ({
59173
+ ...slot,
59174
+ matched: false
59175
+ }));
59063
59176
  const resultElements = [];
59064
59177
  for (const element of elements2) {
59065
59178
  const phInfo = this.getElementPlaceholderInfo(element);
@@ -59104,7 +59217,7 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
59104
59217
  retargetPlaceholder(updatedElement.rawXml, resolvedLayoutPh.phInfo);
59105
59218
  }
59106
59219
  resultElements.push(updatedElement);
59107
- } else {
59220
+ } else if (!this.isUntouchedPlaceholderPrompt(element)) {
59108
59221
  resultElements.push(element);
59109
59222
  }
59110
59223
  }
@@ -68831,6 +68944,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime18 extends PptxHandlerRuntim
68831
68944
  this.zip.file(relsPath, this.builder.build(relsData));
68832
68945
  }
68833
68946
  };
68947
+ var SPECIAL_PLACEHOLDER_TYPES = /* @__PURE__ */ new Set(["dt", "ftr", "hdr", "sldnum"]);
68834
68948
  var PptxHandlerRuntime52 = class _PptxHandlerRuntime19 extends PptxHandlerRuntime51 {
68835
68949
  /**
68836
68950
  * Parse media data (video/audio path and MIME type) from graphic frame data.
@@ -69059,6 +69173,9 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime19 extends PptxHandlerRuntim
69059
69173
  if (source.type && target.type && !typesMatch) {
69060
69174
  return false;
69061
69175
  }
69176
+ if (source.type && SPECIAL_PLACEHOLDER_TYPES.has(source.type) && !target.type || target.type && SPECIAL_PLACEHOLDER_TYPES.has(target.type) && !source.type) {
69177
+ return false;
69178
+ }
69062
69179
  const bothHaveExplicitIdx = source.idx !== void 0 && target.idx !== void 0;
69063
69180
  if (!bothHaveExplicitIdx && source.type && !target.type) {
69064
69181
  return false;
@@ -97138,6 +97255,15 @@ function resolveDataPointMarker(series, pointIndex) {
97138
97255
  fill: point?.spPr?.fillColor ?? series.marker?.spPr?.fillColor
97139
97256
  };
97140
97257
  }
97258
+ var LEGEND_ITEM_WIDTH = 80;
97259
+ var LEGEND_ITEM_HEIGHT = 14;
97260
+ function computeChartLegendLayout(vm) {
97261
+ const vertical = vm.legendAnchor === "start";
97262
+ return vm.legend.map((entry2, i) => {
97263
+ const x = vertical ? vm.legendX : vm.legendX - vm.legend.length * LEGEND_ITEM_WIDTH / 2 + i * LEGEND_ITEM_WIDTH, y = vertical ? vm.legendY + i * LEGEND_ITEM_HEIGHT : vm.legendY;
97264
+ return { x, y, color: entry2.color, label: entry2.label };
97265
+ });
97266
+ }
97141
97267
  function schemaLabel(keys, token2, translate) {
97142
97268
  if (token2 === void 0) {
97143
97269
  return "";
@@ -97780,47 +97906,24 @@ function blendToWhite(color2) {
97780
97906
  if (!match) {
97781
97907
  return color2;
97782
97908
  }
97783
- const value = Number.parseInt(match[1], 16);
97784
- const mix = (channel) => Math.round(channel + (255 - channel) * 0.5);
97785
- const r = mix(value >> 16 & 255);
97786
- const g = mix(value >> 8 & 255);
97787
- const b = mix(value & 255);
97909
+ const value = Number.parseInt(match[1], 16), mix = (channel) => Math.round(channel + (255 - channel) * 0.5), r = mix(value >> 16 & 255), g = mix(value >> 8 & 255), b = mix(value & 255);
97788
97910
  return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0").toUpperCase()}`;
97789
97911
  }
97790
97912
  function invertNegativeFill(series, pointIndex, value, baseFill) {
97791
97913
  if (value >= 0) {
97792
97914
  return baseFill;
97793
97915
  }
97794
- const point = series.dataPoints?.find((p) => p.idx === pointIndex);
97795
- const invert = point?.invertIfNegative ?? series.invertIfNegative ?? false;
97916
+ const point = series.dataPoints?.find((p) => p.idx === pointIndex), invert = point?.invertIfNegative ?? series.invertIfNegative ?? false;
97796
97917
  return invert ? blendToWhite(baseFill) : baseFill;
97797
97918
  }
97798
97919
  function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, grouping, sourceIndices2) {
97799
- const primitives = [];
97800
- const dataLabels = [];
97801
- const series = chartData.series;
97802
- const palette = chartData.colorPalette;
97803
- const showLabels = chartData.style?.hasDataLabels;
97804
- const varyColorsSingle = chartData.varyColors === true && series.length === 1;
97920
+ const primitives = [], dataLabels = [], series = chartData.series, palette = chartData.colorPalette, showLabels = chartData.style?.hasDataLabels, varyColorsSingle = chartData.varyColors === true && series.length === 1;
97805
97921
  if (grouping === "clustered") {
97806
- const seriesCount = Math.max(series.length, 1);
97807
- const barGroupWidth2 = layout.plotWidth / Math.max(catCount, 1);
97808
- const singleBarWidth = chartData.barGapWidth !== void 0 ? barGroupWidth2 / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100) : barGroupWidth2 * 0.7 / seriesCount;
97809
- const overlap = chartData.barOverlap ?? 0;
97810
- const step = singleBarWidth * (1 - overlap / 100);
97811
- const clusterWidth = singleBarWidth + step * (seriesCount - 1);
97812
- const groupOffset = (barGroupWidth2 - clusterWidth) / 2;
97922
+ const seriesCount = Math.max(series.length, 1), barGroupWidth2 = layout.plotWidth / Math.max(catCount, 1), singleBarWidth = chartData.barGapWidth !== void 0 ? barGroupWidth2 / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100) : barGroupWidth2 * 0.7 / seriesCount, overlap = chartData.barOverlap ?? 0, step = singleBarWidth * (1 - overlap / 100), clusterWidth = singleBarWidth + step * (seriesCount - 1), groupOffset = (barGroupWidth2 - clusterWidth) / 2;
97813
97923
  for (let displayIndex = 0; displayIndex < catCount; displayIndex++) {
97814
97924
  const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
97815
97925
  for (let si = 0; si < series.length; si++) {
97816
- const val2 = series[si].values[sourceIndex] ?? 0;
97817
- const x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + step * si;
97818
- const activeRange = secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange;
97819
- const zeroY = valueToY2(0, activeRange, layout.plotTop, layout.plotBottom);
97820
- const valY = valueToY2(val2, activeRange, layout.plotTop, layout.plotBottom);
97821
- const y = Math.min(zeroY, valY);
97822
- const h = Math.max(Math.abs(zeroY - valY), 1);
97823
- const baseFill = varyColorsSingle ? resolveVaryColorFill(series[si], sourceIndex, paletteColor2(sourceIndex, palette)) : resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
97926
+ const val2 = series[si].values[sourceIndex] ?? 0, x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + step * si, activeRange = secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange, zeroY = valueToY2(0, activeRange, layout.plotTop, layout.plotBottom), valY = valueToY2(val2, activeRange, layout.plotTop, layout.plotBottom), y = Math.min(zeroY, valY), h = Math.max(Math.abs(zeroY - valY), 1), baseFill = varyColorsSingle ? resolveVaryColorFill(series[si], sourceIndex, paletteColor2(sourceIndex, palette)) : resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
97824
97927
  primitives.push({
97825
97928
  kind: "rect",
97826
97929
  x,
@@ -97829,7 +97932,13 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
97829
97932
  h,
97830
97933
  fill: invertNegativeFill(series[si], sourceIndex, val2, baseFill),
97831
97934
  rx: 1,
97832
- part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
97935
+ part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex },
97936
+ title: buildMarkTooltip(
97937
+ series[si].name,
97938
+ chartData.categories[sourceIndex],
97939
+ val2,
97940
+ series[si].numberFormat
97941
+ )
97833
97942
  });
97834
97943
  if (showLabels) {
97835
97944
  const text2 = buildDataLabelText({
@@ -97858,19 +97967,23 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
97858
97967
  const displaySeries2 = series.map((entry2) => ({
97859
97968
  ...entry2,
97860
97969
  values: sourceIndices2.map((sourceIndex) => entry2.values[sourceIndex] ?? 0)
97861
- }));
97862
- const rects = computeStackedBarRects(displaySeries2, catCount, layout, primaryRange, palette);
97970
+ })), rects = computeStackedBarRects(displaySeries2, catCount, layout, primaryRange, palette);
97863
97971
  for (const r of rects) {
97864
- let fill = r.fill;
97865
- let part;
97972
+ let fill = r.fill, part, title;
97866
97973
  if (r.seriesIndex !== void 0 && r.pointIndex !== void 0) {
97867
97974
  const sourcePointIndex = sourceIndices2[r.pointIndex] ?? r.pointIndex;
97868
97975
  fill = resolveDataPointFill(series[r.seriesIndex], sourcePointIndex, r.fill) ?? r.fill;
97869
97976
  const value = series[r.seriesIndex].values[sourcePointIndex] ?? 0;
97870
97977
  fill = invertNegativeFill(series[r.seriesIndex], sourcePointIndex, value, fill);
97871
97978
  part = { role: "dataPoint", seriesIndex: r.seriesIndex, pointIndex: sourcePointIndex };
97979
+ title = buildMarkTooltip(
97980
+ series[r.seriesIndex].name,
97981
+ chartData.categories[sourcePointIndex],
97982
+ value,
97983
+ series[r.seriesIndex].numberFormat
97984
+ );
97872
97985
  }
97873
- primitives.push({ kind: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill, rx: 1, part });
97986
+ primitives.push({ kind: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill, rx: 1, part, title });
97874
97987
  }
97875
97988
  if (showLabels) {
97876
97989
  pushClusteredStackedLabels(
@@ -97885,31 +97998,15 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
97885
97998
  }
97886
97999
  return { primitives, dataLabels };
97887
98000
  }
97888
- const barGroupWidth = layout.plotWidth / Math.max(catCount, 1);
97889
- const barW = barGroupWidth * 0.6;
97890
- const barOffset = (barGroupWidth - barW) / 2;
97891
- const displaySeries = series.map((entry2) => ({
98001
+ const barGroupWidth = layout.plotWidth / Math.max(catCount, 1), barW = barGroupWidth * 0.6, barOffset = (barGroupWidth - barW) / 2, displaySeries = series.map((entry2) => ({
97892
98002
  ...entry2,
97893
98003
  values: sourceIndices2.map((sourceIndex) => entry2.values[sourceIndex] ?? 0)
97894
- }));
97895
- const totals = categoryTotals(displaySeries, catCount);
98004
+ })), totals = categoryTotals(displaySeries, catCount);
97896
98005
  for (let ci = 0; ci < catCount; ci++) {
97897
- let posRunning = 0;
97898
- let negRunning = 0;
98006
+ let posRunning = 0, negRunning = 0;
97899
98007
  const catTotal = totals[ci] || 1;
97900
98008
  for (let si = 0; si < series.length; si++) {
97901
- const sourceIndex = sourceIndices2[ci] ?? ci;
97902
- const rawVal = series[si].values[sourceIndex] ?? 0;
97903
- const val2 = catTotal > 0 ? rawVal / catTotal * 100 : 0;
97904
- const isNeg = val2 < 0;
97905
- const base = isNeg ? negRunning : posRunning;
97906
- const top = base + val2;
97907
- const x = layout.plotLeft + barGroupWidth * ci + barOffset;
97908
- const baseY = valueToY2(base, primaryRange, layout.plotTop, layout.plotBottom);
97909
- const topY = valueToY2(top, primaryRange, layout.plotTop, layout.plotBottom);
97910
- const y = Math.min(baseY, topY);
97911
- const h = Math.max(Math.abs(baseY - topY), 0.5);
97912
- const pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
98009
+ const sourceIndex = sourceIndices2[ci] ?? ci, rawVal = series[si].values[sourceIndex] ?? 0, val2 = catTotal > 0 ? rawVal / catTotal * 100 : 0, isNeg = val2 < 0, base = isNeg ? negRunning : posRunning, top = base + val2, x = layout.plotLeft + barGroupWidth * ci + barOffset, baseY = valueToY2(base, primaryRange, layout.plotTop, layout.plotBottom), topY = valueToY2(top, primaryRange, layout.plotTop, layout.plotBottom), y = Math.min(baseY, topY), h = Math.max(Math.abs(baseY - topY), 0.5), pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
97913
98010
  primitives.push({
97914
98011
  kind: "rect",
97915
98012
  x,
@@ -97917,7 +98014,13 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
97917
98014
  w: barW,
97918
98015
  h,
97919
98016
  fill: invertNegativeFill(series[si], sourceIndex, rawVal, pctBaseFill),
97920
- part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
98017
+ part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex },
98018
+ title: buildMarkTooltip(
98019
+ series[si].name,
98020
+ chartData.categories[sourceIndex],
98021
+ rawVal,
98022
+ series[si].numberFormat
98023
+ )
97921
98024
  });
97922
98025
  if (showLabels && Math.abs(val2) > 0) {
97923
98026
  dataLabels.push({
@@ -97941,19 +98044,11 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
97941
98044
  return { primitives, dataLabels };
97942
98045
  }
97943
98046
  function pushClusteredStackedLabels(chartData, series, sourceIndices2, catCount, layout, range, dataLabels) {
97944
- const barGroupWidth = layout.plotWidth / catCount;
97945
- const seriesCount = Math.max(series.length, 1);
97946
- const singleBarWidth = barGroupWidth * 0.7 / seriesCount;
97947
- const groupOffset = (barGroupWidth - singleBarWidth * seriesCount) / 2;
98047
+ const barGroupWidth = layout.plotWidth / catCount, seriesCount = Math.max(series.length, 1), singleBarWidth = barGroupWidth * 0.7 / seriesCount, groupOffset = (barGroupWidth - singleBarWidth * seriesCount) / 2;
97948
98048
  for (let ci = 0; ci < catCount; ci++) {
97949
98049
  const sourceIndex = sourceIndices2[ci] ?? ci;
97950
98050
  for (let si = 0; si < series.length; si++) {
97951
- const val2 = series[si].values[sourceIndex] ?? 0;
97952
- const x = layout.plotLeft + barGroupWidth * ci + groupOffset + singleBarWidth * si + singleBarWidth / 2;
97953
- const zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom);
97954
- const valY = valueToY2(val2, range, layout.plotTop, layout.plotBottom);
97955
- const labelY = val2 >= 0 ? Math.min(zeroY, valY) - 4 : Math.max(zeroY, valY) + 10;
97956
- const text2 = buildDataLabelText({
98051
+ const val2 = series[si].values[sourceIndex] ?? 0, x = layout.plotLeft + barGroupWidth * ci + groupOffset + singleBarWidth * si + singleBarWidth / 2, zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom), valY = valueToY2(val2, range, layout.plotTop, layout.plotBottom), labelY = val2 >= 0 ? Math.min(zeroY, valY) - 4 : Math.max(zeroY, valY) + 10, text2 = buildDataLabelText({
97957
98052
  chartData,
97958
98053
  series: series[si],
97959
98054
  pointIndex: sourceIndex,
@@ -98145,9 +98240,12 @@ function buildMarkerPrimitive(input) {
98145
98240
  return { kind: "circle", cx, cy, r, fill, part };
98146
98241
  }
98147
98242
  }
98148
- function pushMarker(out, series, pointIndex, cx, cy, fill, defaultRadius2, part, opacity2) {
98149
- const marker = resolveDataPointMarker(series, pointIndex);
98150
- const m = buildMarkerPrimitive({
98243
+ function xyMarkTooltip(seriesName, xVal, yVal, numberFormat) {
98244
+ const y = formatAxisValue2(yVal, numberFormat), coords = xVal !== void 0 ? `(${formatAxisValue2(xVal)}, ${y})` : y;
98245
+ return seriesName.length > 0 ? `${seriesName}: ${coords}` : coords;
98246
+ }
98247
+ function pushMarker(out, series, pointIndex, cx, cy, fill, defaultRadius2, part, opacity2, title) {
98248
+ const marker = resolveDataPointMarker(series, pointIndex), m = buildMarkerPrimitive({
98151
98249
  symbol: marker.symbol,
98152
98250
  size: marker.size,
98153
98251
  cx,
@@ -98164,34 +98262,180 @@ function pushMarker(out, series, pointIndex, cx, cy, fill, defaultRadius2, part,
98164
98262
  if (opacity2 !== void 0) {
98165
98263
  m.opacity = opacity2;
98166
98264
  }
98265
+ if (title !== void 0) {
98266
+ m.title = title;
98267
+ }
98167
98268
  out.push(m);
98168
98269
  }
98169
- function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, sourceIndices2, xPositions) {
98170
- const primitives = [];
98171
- const dataLabels = [];
98172
- const showLabels = chartData.style?.hasDataLabels;
98270
+ function seriesXValues(chartData, series) {
98271
+ if (series.xValues && series.xValues.length > 0) {
98272
+ return series.xValues;
98273
+ }
98274
+ const fromCategories = chartData.categories.map(Number);
98275
+ return fromCategories.length > 0 ? fromCategories : void 0;
98276
+ }
98277
+ function scatterDrawsLine(chartData, series) {
98278
+ if (series.lineNoFill === true) {
98279
+ return false;
98280
+ }
98281
+ const style = chartData.scatterStyle;
98282
+ return style === "line" || style === "lineMarker" || style === "smooth" || style === "smoothMarker";
98283
+ }
98284
+ function buildScatter(chartData, layout, range) {
98285
+ const primitives = [], dataLabels = [], showLabels = chartData.style?.hasDataLabels, allIndices = chartData.series.flatMap((s) => s.values.map((_, i) => i)), maxXIndex = Math.max(1, ...allIndices), perSeriesX = chartData.series.map((series) => seriesXValues(chartData, series)), xDomain = computeScatterXDomain(perSeriesX), smoothStyle = chartData.scatterStyle === "smooth" || chartData.scatterStyle === "smoothMarker";
98173
98286
  for (let si = 0; si < chartData.series.length; si++) {
98174
- const series = chartData.series[si];
98287
+ const series = chartData.series[si], c = seriesColor2(series, si, chartData.colorPalette), dots = computeScatterDots(series.values, maxXIndex, layout, range, perSeriesX[si], xDomain);
98288
+ if (scatterDrawsLine(chartData, series) && dots.length >= 2) {
98289
+ const points3 = dots.map((dot) => ({ x: dot.cx, y: dot.cy })), seriesPart = { role: "series", seriesIndex: si };
98290
+ primitives.push(
98291
+ series.smooth ?? smoothStyle ? {
98292
+ kind: "path",
98293
+ d: smoothLinePath(points3),
98294
+ stroke: c,
98295
+ strokeWidth: 2.4,
98296
+ fill: "none",
98297
+ part: seriesPart
98298
+ } : {
98299
+ kind: "polyline",
98300
+ points: linePointsToSvgString(points3),
98301
+ stroke: c,
98302
+ strokeWidth: 2.4,
98303
+ fill: "none",
98304
+ part: seriesPart
98305
+ }
98306
+ );
98307
+ }
98308
+ dots.forEach((dot, vi) => {
98309
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: vi };
98310
+ pushMarker(
98311
+ primitives,
98312
+ series,
98313
+ vi,
98314
+ dot.cx,
98315
+ dot.cy,
98316
+ resolveDataPointFill(series, vi, c) ?? c,
98317
+ 4,
98318
+ part,
98319
+ 0.85,
98320
+ xyMarkTooltip(
98321
+ series.name,
98322
+ perSeriesX[si]?.[vi],
98323
+ series.values[vi] ?? 0,
98324
+ series.numberFormat
98325
+ )
98326
+ );
98327
+ });
98328
+ if (showLabels) {
98329
+ series.values.forEach((val2, vi) => {
98330
+ const dot = dots[vi], text2 = buildDataLabelText({ chartData, series, pointIndex: vi, value: val2 });
98331
+ if (!dot || text2 === void 0) {
98332
+ return;
98333
+ }
98334
+ dataLabels.push({
98335
+ kind: "text",
98336
+ x: dot.cx,
98337
+ y: dot.cy - 6,
98338
+ text: text2,
98339
+ fontSize: DEFAULT_CHART_DATA_LABEL_PX,
98340
+ fill: "#334155",
98341
+ textAnchor: "middle"
98342
+ });
98343
+ });
98344
+ }
98345
+ }
98346
+ return { primitives, dataLabels };
98347
+ }
98348
+ function buildBubbles(chartData, layout, range) {
98349
+ const primitives = [], dataLabels = [], showLabels = chartData.style?.hasDataLabels, allIndices = chartData.series.flatMap((s) => s.values.map((_, i) => i)), maxXIndex = Math.max(1, ...allIndices), perSeriesX = chartData.series.map((series) => seriesXValues(chartData, series)), xDomain = computeScatterXDomain(perSeriesX), allSizes = chartData.series.flatMap((series) => series.bubbleSizes ?? []), maxBubble = allSizes.length > 0 ? Math.max(1, ...allSizes.map(Math.abs)) : 1, medianRadius = Math.min(layout.plotWidth, layout.plotHeight) * 0.04;
98350
+ for (let si = 0; si < chartData.series.length; si++) {
98351
+ const series = chartData.series[si], c = seriesColor2(series, si, chartData.colorPalette), dots = computeScatterDots(series.values, maxXIndex, layout, range, perSeriesX[si], xDomain);
98352
+ dots.forEach((dot, vi) => {
98353
+ const r = computeBubbleRadius(series.bubbleSizes?.[vi], maxBubble, medianRadius), size = series.bubbleSizes?.[vi], label = size !== void 0 ? `${xyMarkTooltip(series.name, perSeriesX[si]?.[vi], series.values[vi] ?? 0, series.numberFormat)}, size ${formatAxisValue2(size)}` : xyMarkTooltip(
98354
+ series.name,
98355
+ perSeriesX[si]?.[vi],
98356
+ series.values[vi] ?? 0,
98357
+ series.numberFormat
98358
+ );
98359
+ primitives.push({
98360
+ kind: "circle",
98361
+ cx: dot.cx,
98362
+ cy: dot.cy,
98363
+ r,
98364
+ fill: resolveDataPointFill(series, vi, c) ?? c,
98365
+ opacity: 0.6,
98366
+ part: { role: "dataPoint", seriesIndex: si, pointIndex: vi },
98367
+ title: label
98368
+ });
98369
+ });
98370
+ if (showLabels) {
98371
+ series.values.forEach((val2, vi) => {
98372
+ const dot = dots[vi], text2 = buildDataLabelText({ chartData, series, pointIndex: vi, value: val2 });
98373
+ if (!dot || text2 === void 0) {
98374
+ return;
98375
+ }
98376
+ dataLabels.push({
98377
+ kind: "text",
98378
+ x: dot.cx,
98379
+ y: dot.cy - 10,
98380
+ text: text2,
98381
+ fontSize: DEFAULT_CHART_DATA_LABEL_PX,
98382
+ fill: "#334155",
98383
+ textAnchor: "middle"
98384
+ });
98385
+ });
98386
+ }
98387
+ }
98388
+ return { primitives, dataLabels };
98389
+ }
98390
+ function categoryAbsTotals(seriesValues, catCount) {
98391
+ return Array.from(
98392
+ { length: catCount },
98393
+ (_, ci) => seriesValues.reduce((sum, values) => sum + Math.abs(values[ci] ?? 0), 0)
98394
+ );
98395
+ }
98396
+ function computeStackedSeriesPlots(seriesValues, catCount, percent3) {
98397
+ const totals = percent3 ? categoryAbsTotals(seriesValues, catCount) : void 0, posRunning = new Array(catCount).fill(0), negRunning = new Array(catCount).fill(0);
98398
+ return seriesValues.map((values) => {
98399
+ const cumulative = [], base = [], own = [];
98400
+ for (let ci = 0; ci < catCount; ci++) {
98401
+ const raw = values[ci] ?? 0, total = totals?.[ci] ?? 0, val2 = percent3 ? total > 0 ? raw / total * 100 : 0 : raw, isNeg = val2 < 0, from = isNeg ? negRunning[ci] : posRunning[ci], to = from + val2;
98402
+ base.push(from);
98403
+ cumulative.push(to);
98404
+ own.push(val2);
98405
+ if (isNeg) {
98406
+ negRunning[ci] = to;
98407
+ } else {
98408
+ posRunning[ci] = to;
98409
+ }
98410
+ }
98411
+ return { cumulative, base, own };
98412
+ });
98413
+ }
98414
+ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, sourceIndices2, xPositions, stacking = "clustered") {
98415
+ const primitives = [], dataLabels = [], showLabels = chartData.style?.hasDataLabels, isStackedMode = stacking !== "clustered", isPercent = stacking === "percentStacked", resolved = chartData.series.map((series) => {
98175
98416
  if (series.values.length === 0) {
98176
- continue;
98417
+ return void 0;
98177
98418
  }
98178
- const activeRange = secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange;
98179
- const rawValues = sourceIndices2.map((sourceIndex) => series.values[sourceIndex] ?? 0);
98180
- const displayBlanks = sourceIndices2.map((sourceIndex) => series.blanks?.[sourceIndex] ?? false);
98181
- const { values: displayValues, visible } = resolveBlankDisplay(
98419
+ const rawValues = sourceIndices2.map((sourceIndex) => series.values[sourceIndex] ?? 0), displayBlanks = sourceIndices2.map((sourceIndex) => series.blanks?.[sourceIndex] ?? false), { values: displayValues, visible } = resolveBlankDisplay(
98182
98420
  rawValues,
98183
98421
  displayBlanks,
98184
98422
  chartData.chartChrome?.dispBlanksAs
98185
98423
  );
98186
- const pts = computeLinePoints(displayValues, catCount, layout, activeRange).map(
98187
- (point, index) => ({
98188
- ...point,
98189
- x: xPositions?.[index] ?? point.x
98190
- })
98191
- );
98192
- const c = seriesColor2(series, si, chartData.colorPalette);
98193
- const seriesPart = { role: "series", seriesIndex: si };
98194
- const allVisible = visible.every(Boolean);
98424
+ return { displayValues, visible };
98425
+ }), stackedPlots = isStackedMode ? computeStackedSeriesPlots(
98426
+ resolved.map((entry2) => entry2?.displayValues ?? []),
98427
+ catCount,
98428
+ isPercent
98429
+ ) : void 0;
98430
+ for (let si = 0; si < chartData.series.length; si++) {
98431
+ const series = chartData.series[si], entry2 = resolved[si];
98432
+ if (!entry2) {
98433
+ continue;
98434
+ }
98435
+ const { displayValues, visible } = entry2, activeRange = isStackedMode ? primaryRange : secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange, plotValues = stackedPlots ? stackedPlots[si].cumulative : displayValues, pts = computeLinePoints(plotValues, catCount, layout, activeRange).map((point, index) => ({
98436
+ ...point,
98437
+ x: xPositions?.[index] ?? point.x
98438
+ })), c = seriesColor2(series, si, chartData.colorPalette), seriesPart = { role: "series", seriesIndex: si }, allVisible = visible.every(Boolean);
98195
98439
  if (allVisible) {
98196
98440
  primitives.push(
98197
98441
  series.smooth ? {
@@ -98229,8 +98473,7 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
98229
98473
  if (!visible[displayIndex]) {
98230
98474
  return;
98231
98475
  }
98232
- const idx = sourceIndices2[displayIndex] ?? displayIndex;
98233
- const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
98476
+ const idx = sourceIndices2[displayIndex] ?? displayIndex, part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
98234
98477
  pushMarker(
98235
98478
  primitives,
98236
98479
  series,
@@ -98239,19 +98482,45 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
98239
98482
  pt.y,
98240
98483
  resolveDataPointFill(series, idx, c) ?? c,
98241
98484
  2.5,
98242
- part
98485
+ part,
98486
+ void 0,
98487
+ buildMarkTooltip(
98488
+ series.name,
98489
+ chartData.categories[idx],
98490
+ series.values[idx] ?? 0,
98491
+ series.numberFormat
98492
+ )
98243
98493
  );
98244
98494
  });
98245
98495
  if (showLabels) {
98246
- displayValues.forEach((val2, displayIndex) => {
98496
+ const labelValues = stackedPlots ? stackedPlots[si].own : displayValues;
98497
+ labelValues.forEach((val2, displayIndex) => {
98247
98498
  const pt = pts[displayIndex];
98499
+ if (!pt || !visible[displayIndex]) {
98500
+ return;
98501
+ }
98502
+ if (isPercent) {
98503
+ if (val2 === 0) {
98504
+ return;
98505
+ }
98506
+ dataLabels.push({
98507
+ kind: "text",
98508
+ x: pt.x,
98509
+ y: pt.y - 7,
98510
+ text: `${Math.round(val2)}%`,
98511
+ fontSize: DEFAULT_CHART_DATA_LABEL_PX,
98512
+ fill: "#334155",
98513
+ textAnchor: "middle"
98514
+ });
98515
+ return;
98516
+ }
98248
98517
  const text2 = buildDataLabelText({
98249
98518
  chartData,
98250
98519
  series,
98251
98520
  pointIndex: sourceIndices2[displayIndex] ?? displayIndex,
98252
98521
  value: val2
98253
98522
  });
98254
- if (!pt || !visible[displayIndex] || text2 === void 0) {
98523
+ if (text2 === void 0) {
98255
98524
  return;
98256
98525
  }
98257
98526
  dataLabels.push({
@@ -98268,26 +98537,41 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
98268
98537
  }
98269
98538
  return { primitives, dataLabels };
98270
98539
  }
98271
- function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositions) {
98272
- const primitives = [];
98273
- const dataLabels = [];
98274
- const showLabels = chartData.style?.hasDataLabels;
98275
- const baselineY = valueToY2(0, range, layout.plotTop, layout.plotBottom);
98540
+ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositions, stacking = "clustered") {
98541
+ const primitives = [], dataLabels = [], showLabels = chartData.style?.hasDataLabels, isStackedMode = stacking !== "clustered", isPercent = stacking === "percentStacked", baselineY = valueToY2(0, range, layout.plotTop, layout.plotBottom), allDisplayValues = chartData.series.map(
98542
+ (series) => series.values.length === 0 ? void 0 : sourceIndices2.map((sourceIndex) => series.values[sourceIndex] ?? 0)
98543
+ ), stackedPlots = isStackedMode ? computeStackedSeriesPlots(
98544
+ allDisplayValues.map((values) => values ?? []),
98545
+ catCount,
98546
+ isPercent
98547
+ ) : void 0;
98276
98548
  for (let si = 0; si < chartData.series.length; si++) {
98277
- const series = chartData.series[si];
98278
- if (series.values.length === 0) {
98549
+ const series = chartData.series[si], displayValues = allDisplayValues[si];
98550
+ if (!displayValues) {
98279
98551
  continue;
98280
98552
  }
98281
- const displayValues = sourceIndices2.map((sourceIndex) => series.values[sourceIndex] ?? 0);
98282
- const pts = computeLinePoints(displayValues, catCount, layout, range).map((point, index) => ({
98553
+ const plot = stackedPlots?.[si], topValues = plot ? plot.cumulative : displayValues, pts = computeLinePoints(topValues, catCount, layout, range).map((point, index) => ({
98283
98554
  ...point,
98284
98555
  x: xPositions?.[index] ?? point.x
98285
- }));
98286
- const c = seriesColor2(series, si, chartData.colorPalette);
98287
- const lineStr = linePointsToSvgString(pts);
98288
- const firstPt = pts[0];
98289
- const lastPt = pts[pts.length - 1];
98290
- if (firstPt && lastPt) {
98556
+ })), c = seriesColor2(series, si, chartData.colorPalette), lineStr = linePointsToSvgString(pts), firstPt = pts[0], lastPt = pts[pts.length - 1];
98557
+ if (plot) {
98558
+ const baseStr = linePointsToSvgString(
98559
+ [
98560
+ ...computeLinePoints(plot.base, catCount, layout, range).map((point, index) => ({
98561
+ ...point,
98562
+ x: xPositions?.[index] ?? point.x
98563
+ }))
98564
+ ].reverse()
98565
+ );
98566
+ primitives.push({
98567
+ kind: "polyline",
98568
+ points: `${lineStr} ${baseStr}`,
98569
+ stroke: "none",
98570
+ strokeWidth: 0,
98571
+ fill: c,
98572
+ part: { role: "series", seriesIndex: si }
98573
+ });
98574
+ } else if (firstPt && lastPt) {
98291
98575
  primitives.push({
98292
98576
  kind: "polyline",
98293
98577
  points: `${firstPt.x.toFixed(2)},${baselineY.toFixed(2)} ${lineStr} ${lastPt.x.toFixed(2)},${baselineY.toFixed(2)}`,
@@ -98307,8 +98591,7 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
98307
98591
  part: { role: "series", seriesIndex: si }
98308
98592
  });
98309
98593
  pts.forEach((pt, displayIndex) => {
98310
- const idx = sourceIndices2[displayIndex] ?? displayIndex;
98311
- const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
98594
+ const idx = sourceIndices2[displayIndex] ?? displayIndex, part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
98312
98595
  pushMarker(
98313
98596
  primitives,
98314
98597
  series,
@@ -98317,19 +98600,45 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
98317
98600
  pt.y,
98318
98601
  resolveDataPointFill(series, idx, c) ?? c,
98319
98602
  2,
98320
- part
98603
+ part,
98604
+ void 0,
98605
+ buildMarkTooltip(
98606
+ series.name,
98607
+ chartData.categories[idx],
98608
+ series.values[idx] ?? 0,
98609
+ series.numberFormat
98610
+ )
98321
98611
  );
98322
98612
  });
98323
98613
  if (showLabels) {
98324
- displayValues.forEach((val2, displayIndex) => {
98614
+ const labelValues = plot ? plot.own : displayValues;
98615
+ labelValues.forEach((val2, displayIndex) => {
98325
98616
  const pt = pts[displayIndex];
98617
+ if (!pt) {
98618
+ return;
98619
+ }
98620
+ if (isPercent) {
98621
+ if (val2 === 0) {
98622
+ return;
98623
+ }
98624
+ dataLabels.push({
98625
+ kind: "text",
98626
+ x: pt.x,
98627
+ y: pt.y - 6,
98628
+ text: `${Math.round(val2)}%`,
98629
+ fontSize: DEFAULT_CHART_DATA_LABEL_PX,
98630
+ fill: "#334155",
98631
+ textAnchor: "middle"
98632
+ });
98633
+ return;
98634
+ }
98326
98635
  const text2 = buildDataLabelText({
98327
98636
  chartData,
98328
98637
  series,
98329
98638
  pointIndex: sourceIndices2[displayIndex] ?? displayIndex,
98330
98639
  value: val2
98331
98640
  });
98332
- if (!pt || text2 === void 0) {
98641
+ if (text2 === void 0) {
98333
98642
  return;
98334
98643
  }
98335
98644
  dataLabels.push({
@@ -98346,151 +98655,6 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
98346
98655
  }
98347
98656
  return { primitives, dataLabels };
98348
98657
  }
98349
- function seriesXValues(chartData, series) {
98350
- if (series.xValues && series.xValues.length > 0) {
98351
- return series.xValues;
98352
- }
98353
- const fromCategories = chartData.categories.map(Number);
98354
- return fromCategories.length > 0 ? fromCategories : void 0;
98355
- }
98356
- function scatterDrawsLine(chartData, series) {
98357
- if (series.lineNoFill === true) {
98358
- return false;
98359
- }
98360
- const style = chartData.scatterStyle;
98361
- return style === "line" || style === "lineMarker" || style === "smooth" || style === "smoothMarker";
98362
- }
98363
- function buildScatter(chartData, layout, range) {
98364
- const primitives = [];
98365
- const dataLabels = [];
98366
- const showLabels = chartData.style?.hasDataLabels;
98367
- const allIndices = chartData.series.flatMap((s) => s.values.map((_, i) => i));
98368
- const maxXIndex = Math.max(1, ...allIndices);
98369
- const perSeriesX = chartData.series.map((series) => seriesXValues(chartData, series));
98370
- const xDomain = computeScatterXDomain(perSeriesX);
98371
- const smoothStyle = chartData.scatterStyle === "smooth" || chartData.scatterStyle === "smoothMarker";
98372
- for (let si = 0; si < chartData.series.length; si++) {
98373
- const series = chartData.series[si];
98374
- const c = seriesColor2(series, si, chartData.colorPalette);
98375
- const dots = computeScatterDots(
98376
- series.values,
98377
- maxXIndex,
98378
- layout,
98379
- range,
98380
- perSeriesX[si],
98381
- xDomain
98382
- );
98383
- if (scatterDrawsLine(chartData, series) && dots.length >= 2) {
98384
- const points3 = dots.map((dot) => ({ x: dot.cx, y: dot.cy }));
98385
- const seriesPart = { role: "series", seriesIndex: si };
98386
- primitives.push(
98387
- series.smooth ?? smoothStyle ? {
98388
- kind: "path",
98389
- d: smoothLinePath(points3),
98390
- stroke: c,
98391
- strokeWidth: 2.4,
98392
- fill: "none",
98393
- part: seriesPart
98394
- } : {
98395
- kind: "polyline",
98396
- points: linePointsToSvgString(points3),
98397
- stroke: c,
98398
- strokeWidth: 2.4,
98399
- fill: "none",
98400
- part: seriesPart
98401
- }
98402
- );
98403
- }
98404
- dots.forEach((dot, vi) => {
98405
- const part = { role: "dataPoint", seriesIndex: si, pointIndex: vi };
98406
- pushMarker(
98407
- primitives,
98408
- series,
98409
- vi,
98410
- dot.cx,
98411
- dot.cy,
98412
- resolveDataPointFill(series, vi, c) ?? c,
98413
- 4,
98414
- part,
98415
- 0.85
98416
- );
98417
- });
98418
- if (showLabels) {
98419
- series.values.forEach((val2, vi) => {
98420
- const dot = dots[vi];
98421
- const text2 = buildDataLabelText({ chartData, series, pointIndex: vi, value: val2 });
98422
- if (!dot || text2 === void 0) {
98423
- return;
98424
- }
98425
- dataLabels.push({
98426
- kind: "text",
98427
- x: dot.cx,
98428
- y: dot.cy - 6,
98429
- text: text2,
98430
- fontSize: DEFAULT_CHART_DATA_LABEL_PX,
98431
- fill: "#334155",
98432
- textAnchor: "middle"
98433
- });
98434
- });
98435
- }
98436
- }
98437
- return { primitives, dataLabels };
98438
- }
98439
- function buildBubbles(chartData, layout, range) {
98440
- const primitives = [];
98441
- const dataLabels = [];
98442
- const showLabels = chartData.style?.hasDataLabels;
98443
- const allIndices = chartData.series.flatMap((s) => s.values.map((_, i) => i));
98444
- const maxXIndex = Math.max(1, ...allIndices);
98445
- const perSeriesX = chartData.series.map((series) => seriesXValues(chartData, series));
98446
- const xDomain = computeScatterXDomain(perSeriesX);
98447
- const allSizes = chartData.series.flatMap((series) => series.bubbleSizes ?? []);
98448
- const maxBubble = allSizes.length > 0 ? Math.max(1, ...allSizes.map(Math.abs)) : 1;
98449
- const medianRadius = Math.min(layout.plotWidth, layout.plotHeight) * 0.04;
98450
- for (let si = 0; si < chartData.series.length; si++) {
98451
- const series = chartData.series[si];
98452
- const c = seriesColor2(series, si, chartData.colorPalette);
98453
- const dots = computeScatterDots(
98454
- series.values,
98455
- maxXIndex,
98456
- layout,
98457
- range,
98458
- perSeriesX[si],
98459
- xDomain
98460
- );
98461
- dots.forEach((dot, vi) => {
98462
- const r = computeBubbleRadius(series.bubbleSizes?.[vi], maxBubble, medianRadius);
98463
- primitives.push({
98464
- kind: "circle",
98465
- cx: dot.cx,
98466
- cy: dot.cy,
98467
- r,
98468
- fill: resolveDataPointFill(series, vi, c) ?? c,
98469
- opacity: 0.6,
98470
- part: { role: "dataPoint", seriesIndex: si, pointIndex: vi }
98471
- });
98472
- });
98473
- if (showLabels) {
98474
- series.values.forEach((val2, vi) => {
98475
- const dot = dots[vi];
98476
- const text2 = buildDataLabelText({ chartData, series, pointIndex: vi, value: val2 });
98477
- if (!dot || text2 === void 0) {
98478
- return;
98479
- }
98480
- dataLabels.push({
98481
- kind: "text",
98482
- x: dot.cx,
98483
- y: dot.cy - 10,
98484
- text: text2,
98485
- fontSize: DEFAULT_CHART_DATA_LABEL_PX,
98486
- fill: "#334155",
98487
- textAnchor: "middle"
98488
- });
98489
- });
98490
- }
98491
- }
98492
- return { primitives, dataLabels };
98493
- }
98494
98658
  function categoryX(index, catCount, layout, options) {
98495
98659
  const explicit = options.xPositions?.[index];
98496
98660
  if (explicit !== void 0) {
@@ -98998,10 +99162,7 @@ function valueToX(val2, range, leftX, rightX) {
98998
99162
  const usable = rightX - leftX;
98999
99163
  let ratio;
99000
99164
  if (range.logScale && range.logBase) {
99001
- const base = range.logBase;
99002
- const clampedVal = Math.max(val2, range.min);
99003
- const logVal = Math.log(clampedVal) / Math.log(base);
99004
- const logMin = Math.log(range.min) / Math.log(base);
99165
+ const base = range.logBase, clampedVal = Math.max(val2, range.min), logVal = Math.log(clampedVal) / Math.log(base), logMin = Math.log(range.min) / Math.log(base);
99005
99166
  ratio = (logVal - logMin) / range.span;
99006
99167
  } else {
99007
99168
  ratio = (val2 - range.min) / range.span;
@@ -99009,8 +99170,7 @@ function valueToX(val2, range, leftX, rightX) {
99009
99170
  return range.reverseOrder ? rightX - ratio * usable : leftX + ratio * usable;
99010
99171
  }
99011
99172
  function buildTransposedValueAxis(range, layout) {
99012
- const gridlines = [];
99013
- const axisLabels = [];
99173
+ const gridlines = [], axisLabels = [];
99014
99174
  for (const val2 of axisTickValues(range)) {
99015
99175
  const x = valueToX(val2, range, layout.plotLeft, layout.plotRight);
99016
99176
  gridlines.push({
@@ -99035,8 +99195,7 @@ function buildTransposedValueAxis(range, layout) {
99035
99195
  return { gridlines, axisLabels };
99036
99196
  }
99037
99197
  function buildSideCategoryLabels(categoryLabels, layout) {
99038
- const catCount = Math.max(categoryLabels.length, 1);
99039
- const band = layout.plotHeight / catCount;
99198
+ const catCount = Math.max(categoryLabels.length, 1), band = layout.plotHeight / catCount;
99040
99199
  return categoryLabels.map((label, i) => ({
99041
99200
  kind: "text",
99042
99201
  x: layout.plotLeft - 4,
@@ -99062,16 +99221,7 @@ function barFill(chartData, series, seriesIndex, pointIndex) {
99062
99221
  return resolveDataPointFill(series, pointIndex, paletteColor2(seriesIndex, palette)) ?? seriesColor2(series, seriesIndex, palette);
99063
99222
  }
99064
99223
  function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
99065
- const layout = computePlotLayout(element.width, element.height, chartData, true);
99066
- const catCount = Math.max(categoryLabels.length, 1);
99067
- const series = chartData.series;
99068
- const grouping = chartData.grouping ?? "clustered";
99069
- const isStacked = grouping === "stacked" || grouping === "percentStacked";
99070
- const isPercent = grouping === "percentStacked";
99071
- const range = isPercent ? { min: 0, max: 100, span: 100 } : isStacked ? computeStackedValueRange(series, catCount) : computeValueRangeForChart(series, chartData.axes);
99072
- const { gridlines, axisLabels } = buildTransposedValueAxis(range, layout);
99073
- const zeroX = valueToX(0, range, layout.plotLeft, layout.plotRight);
99074
- const zeroLine = range.min < 0 && range.max > 0 ? {
99224
+ const layout = computePlotLayout(element.width, element.height, chartData, true), catCount = Math.max(categoryLabels.length, 1), series = chartData.series, grouping = chartData.grouping ?? "clustered", isStacked = grouping === "stacked" || grouping === "percentStacked", isPercent = grouping === "percentStacked", range = isPercent ? { min: 0, max: 100, span: 100 } : isStacked ? computeStackedValueRange(series, catCount) : computeValueRangeForChart(series, chartData.axes), { gridlines, axisLabels } = buildTransposedValueAxis(range, layout), zeroX = valueToX(0, range, layout.plotLeft, layout.plotRight), zeroLine = range.min < 0 && range.max > 0 ? {
99075
99225
  kind: "line",
99076
99226
  x1: zeroX,
99077
99227
  y1: layout.plotTop,
@@ -99079,25 +99229,12 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
99079
99229
  y2: layout.plotBottom,
99080
99230
  stroke: ZERO_LINE_COLOR,
99081
99231
  strokeWidth: 1
99082
- } : void 0;
99083
- const primitives = [];
99084
- const dataLabels = [];
99085
- const showLabels = chartData.style?.hasDataLabels;
99086
- const band = layout.plotHeight / catCount;
99232
+ } : void 0, primitives = [], dataLabels = [], showLabels = chartData.style?.hasDataLabels, band = layout.plotHeight / catCount;
99087
99233
  if (!isStacked) {
99088
- const seriesCount = Math.max(series.length, 1);
99089
- const singleBarHeight = chartData.barGapWidth !== void 0 ? band / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100) : band * 0.7 / seriesCount;
99090
- const overlap = chartData.barOverlap ?? 0;
99091
- const step = singleBarHeight * (1 - overlap / 100);
99092
- const clusterHeight = singleBarHeight + step * (seriesCount - 1);
99093
- const groupOffset = (band - clusterHeight) / 2;
99234
+ const seriesCount = Math.max(series.length, 1), singleBarHeight = chartData.barGapWidth !== void 0 ? band / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100) : band * 0.7 / seriesCount, overlap = chartData.barOverlap ?? 0, step = singleBarHeight * (1 - overlap / 100), clusterHeight = singleBarHeight + step * (seriesCount - 1), groupOffset = (band - clusterHeight) / 2;
99094
99235
  for (let ci = 0; ci < catCount; ci++) {
99095
99236
  for (let si = 0; si < series.length; si++) {
99096
- const val2 = series[si].values[ci] ?? 0;
99097
- const y = layout.plotTop + band * ci + groupOffset + step * si;
99098
- const valX = valueToX(val2, range, layout.plotLeft, layout.plotRight);
99099
- const x = Math.min(zeroX, valX);
99100
- const w = Math.max(Math.abs(valX - zeroX), 1);
99237
+ const val2 = series[si].values[ci] ?? 0, y = layout.plotTop + band * ci + groupOffset + step * si, valX = valueToX(val2, range, layout.plotLeft, layout.plotRight), x = Math.min(zeroX, valX), w = Math.max(Math.abs(valX - zeroX), 1);
99101
99238
  primitives.push({
99102
99239
  kind: "rect",
99103
99240
  x,
@@ -99106,7 +99243,13 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
99106
99243
  h: singleBarHeight,
99107
99244
  fill: barFill(chartData, series[si], si, ci),
99108
99245
  rx: 1,
99109
- part: { role: "dataPoint", seriesIndex: si, pointIndex: ci }
99246
+ part: { role: "dataPoint", seriesIndex: si, pointIndex: ci },
99247
+ title: buildMarkTooltip(
99248
+ series[si].name,
99249
+ categoryLabels[ci],
99250
+ val2,
99251
+ series[si].numberFormat
99252
+ )
99110
99253
  });
99111
99254
  if (showLabels) {
99112
99255
  dataLabels.push({
@@ -99123,27 +99266,16 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
99123
99266
  }
99124
99267
  }
99125
99268
  } else {
99126
- const totals = isPercent ? categoryTotals2(series, catCount) : [];
99127
- const barH = band * (isPercent ? 0.6 : 0.7);
99128
- const barOffset = (band - barH) / 2;
99269
+ const totals = isPercent ? categoryTotals2(series, catCount) : [], barH = band * (isPercent ? 0.6 : 0.7), barOffset = (band - barH) / 2;
99129
99270
  for (let ci = 0; ci < catCount; ci++) {
99130
- let posRunning = 0;
99131
- let negRunning = 0;
99271
+ let posRunning = 0, negRunning = 0;
99132
99272
  const catTotal = isPercent ? totals[ci] || 1 : 1;
99133
99273
  for (let si = 0; si < series.length; si++) {
99134
- const rawVal = series[si].values[ci] ?? 0;
99135
- const val2 = isPercent ? rawVal / catTotal * 100 : rawVal;
99274
+ const rawVal = series[si].values[ci] ?? 0, val2 = isPercent ? rawVal / catTotal * 100 : rawVal;
99136
99275
  if (val2 === 0) {
99137
99276
  continue;
99138
99277
  }
99139
- const isNeg = val2 < 0;
99140
- const base = isNeg ? negRunning : posRunning;
99141
- const top = base + val2;
99142
- const y = layout.plotTop + band * ci + barOffset;
99143
- const baseX = valueToX(base, range, layout.plotLeft, layout.plotRight);
99144
- const topX = valueToX(top, range, layout.plotLeft, layout.plotRight);
99145
- const x = Math.min(baseX, topX);
99146
- const w = Math.max(Math.abs(topX - baseX), 0.5);
99278
+ const isNeg = val2 < 0, base = isNeg ? negRunning : posRunning, top = base + val2, y = layout.plotTop + band * ci + barOffset, baseX = valueToX(base, range, layout.plotLeft, layout.plotRight), topX = valueToX(top, range, layout.plotLeft, layout.plotRight), x = Math.min(baseX, topX), w = Math.max(Math.abs(topX - baseX), 0.5);
99147
99279
  primitives.push({
99148
99280
  kind: "rect",
99149
99281
  x,
@@ -99152,7 +99284,13 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
99152
99284
  h: barH,
99153
99285
  fill: barFill(chartData, series[si], si, ci),
99154
99286
  rx: 1,
99155
- part: { role: "dataPoint", seriesIndex: si, pointIndex: ci }
99287
+ part: { role: "dataPoint", seriesIndex: si, pointIndex: ci },
99288
+ title: buildMarkTooltip(
99289
+ series[si].name,
99290
+ categoryLabels[ci],
99291
+ rawVal,
99292
+ series[si].numberFormat
99293
+ )
99156
99294
  });
99157
99295
  if (showLabels && Math.abs(val2) > 0) {
99158
99296
  dataLabels.push({
@@ -99175,8 +99313,7 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
99175
99313
  }
99176
99314
  }
99177
99315
  }
99178
- const legendPos = chartData.style?.legendPosition ?? "b";
99179
- const { legend, legendX, legendY, legendAnchor } = buildLegend(
99316
+ const legendPos = chartData.style?.legendPosition ?? "b", { legend, legendX, legendY, legendAnchor } = buildLegend(
99180
99317
  series,
99181
99318
  chartData.colorPalette,
99182
99319
  layout.svgWidth,
@@ -99811,7 +99948,7 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
99811
99948
  const layoutOpts = computeLayoutOptions(chartData.axes, chartData.dataTable, seriesCount);
99812
99949
  const layout = computePlotLayout(element.width, element.height, chartData, true, layoutOpts);
99813
99950
  const catCount = Math.max(categoryLabels.length, 1);
99814
- const isStacked = kind === "bar" && (chartData.grouping === "stacked" || chartData.grouping === "percentStacked");
99951
+ const isStacked = (kind === "bar" || kind === "line" || kind === "area") && (chartData.grouping === "stacked" || chartData.grouping === "percentStacked");
99815
99952
  const isPercent = isStacked && chartData.grouping === "percentStacked";
99816
99953
  const { secondary } = splitSeriesByAxis(chartData.series, chartData.axes);
99817
99954
  const secondaryIdx = new Set(secondary.map((e) => e.index));
@@ -99873,7 +100010,8 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
99873
100010
  secondaryRange,
99874
100011
  secondaryIdx,
99875
100012
  sourceIndices2,
99876
- horizontalAxis.xPositions
100013
+ horizontalAxis.xPositions,
100014
+ isStacked ? isPercent ? "percentStacked" : "stacked" : "clustered"
99877
100015
  );
99878
100016
  } else if (kind === "area") {
99879
100017
  plot = buildAreas(
@@ -99882,7 +100020,8 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
99882
100020
  layout,
99883
100021
  primaryRange,
99884
100022
  sourceIndices2,
99885
- horizontalAxis.xPositions
100023
+ horizontalAxis.xPositions,
100024
+ isStacked ? isPercent ? "percentStacked" : "stacked" : "clustered"
99886
100025
  );
99887
100026
  } else if (kind === "scatter") {
99888
100027
  plot = buildScatter(chartData, layout, primaryRange);
@@ -102529,8 +102668,7 @@ function seriesColor2(series, index, colorPalette) {
102529
102668
  return series.color ?? series.marker?.spPr?.fillColor ?? paletteColor2(index, colorPalette);
102530
102669
  }
102531
102670
  function computeValueRange2(series) {
102532
- let dataMin = Number.POSITIVE_INFINITY;
102533
- let dataMax = Number.NEGATIVE_INFINITY;
102671
+ let dataMin = Number.POSITIVE_INFINITY, dataMax = Number.NEGATIVE_INFINITY;
102534
102672
  for (const item of series) {
102535
102673
  for (const value of item.values) {
102536
102674
  if (value < dataMin) {
@@ -102548,11 +102686,9 @@ function computeValueRange2(series) {
102548
102686
  return { min, max, span: Math.max(max - min, Number.EPSILON), majorUnit };
102549
102687
  }
102550
102688
  function computeStackedValueRange(series, catCount) {
102551
- let maxSum = 0;
102552
- let minSum = 0;
102689
+ let maxSum = 0, minSum = 0;
102553
102690
  for (let ci = 0; ci < catCount; ci++) {
102554
- let pos2 = 0;
102555
- let neg = 0;
102691
+ let pos2 = 0, neg = 0;
102556
102692
  for (const s of series) {
102557
102693
  const v = s.values[ci] ?? 0;
102558
102694
  if (v >= 0) {
@@ -102571,10 +102707,7 @@ function valueToY2(val2, range, topY, bottomY) {
102571
102707
  const usable = bottomY - topY;
102572
102708
  let ratio;
102573
102709
  if (range.logScale && range.logBase) {
102574
- const base = range.logBase;
102575
- const clampedVal = Math.max(val2, range.min);
102576
- const logVal = Math.log(clampedVal) / Math.log(base);
102577
- const logMin = Math.log(range.min) / Math.log(base);
102710
+ const base = range.logBase, clampedVal = Math.max(val2, range.min), logVal = Math.log(clampedVal) / Math.log(base), logMin = Math.log(range.min) / Math.log(base);
102578
102711
  ratio = (logVal - logMin) / range.span;
102579
102712
  } else {
102580
102713
  ratio = (val2 - range.min) / range.span;
@@ -102597,23 +102730,20 @@ function formatAxisValue2(val2, formatCode) {
102597
102730
  }
102598
102731
  return val2.toFixed(1);
102599
102732
  }
102733
+ function buildMarkTooltip(seriesName, categoryLabel, value, numberFormat) {
102734
+ const label = [seriesName, categoryLabel].filter((part) => Boolean(part && part.length > 0)).join(", "), formatted = formatAxisValue2(value, numberFormat);
102735
+ return label.length > 0 ? `${label}: ${formatted}` : formatted;
102736
+ }
102600
102737
  function categoryAxisBand(chartData) {
102601
102738
  const axis = chartData.axes?.find(
102602
102739
  (candidate) => candidate.axisType === "catAx" || candidate.axisType === "dateAx"
102603
- );
102604
- const fontPx = axis?.fontSize !== void 0 ? chartFontPx(axis.fontSize) : DEFAULT_CHART_TEXT_PX;
102605
- const offset = 4 + 8 * ((axis?.labelOffset ?? 100) / 100);
102740
+ ), fontPx = axis?.fontSize !== void 0 ? chartFontPx(axis.fontSize) : DEFAULT_CHART_TEXT_PX, offset = 4 + 8 * ((axis?.labelOffset ?? 100) / 100);
102606
102741
  return Math.max(24, offset + fontPx * 1.2);
102607
102742
  }
102608
102743
  function computePlotLayout(elementWidth, elementHeight, chartData, hasAxes, options) {
102609
- const svgWidth = Math.max(1, elementWidth);
102610
- const svgHeight = Math.max(1, elementHeight);
102611
- let plotLeft = hasAxes ? 48 : 8;
102612
- let plotTop = 8;
102613
- let plotRight = svgWidth - 8;
102614
- let plotBottom = svgHeight - (hasAxes ? categoryAxisBand(chartData) : 8);
102615
- const style = chartData.style;
102616
- const legendPos = style?.legendPosition ?? "b";
102744
+ const svgWidth = Math.max(1, elementWidth), svgHeight = Math.max(1, elementHeight);
102745
+ let plotLeft = hasAxes ? 48 : 8, plotTop = 8, plotRight = svgWidth - 8, plotBottom = svgHeight - (hasAxes ? categoryAxisBand(chartData) : 8);
102746
+ const style = chartData.style, legendPos = style?.legendPosition ?? "b";
102617
102747
  if (style?.hasTitle) {
102618
102748
  plotTop += 20;
102619
102749
  }
@@ -102638,8 +102768,7 @@ function computePlotLayout(elementWidth, elementHeight, chartData, hasAxes, opti
102638
102768
  const rowCount = options.dataTableRowCount ?? 1;
102639
102769
  plotBottom -= 14 + rowCount * 14;
102640
102770
  }
102641
- const plotWidth = Math.max(plotRight - plotLeft, 1);
102642
- const plotHeight = Math.max(plotBottom - plotTop, 1);
102771
+ const plotWidth = Math.max(plotRight - plotLeft, 1), plotHeight = Math.max(plotBottom - plotTop, 1);
102643
102772
  return {
102644
102773
  svgWidth,
102645
102774
  svgHeight,
@@ -102669,8 +102798,7 @@ function axisTickValues(range) {
102669
102798
  );
102670
102799
  }
102671
102800
  function buildGridlinesAndLabels(range, layout) {
102672
- const gridlines = [];
102673
- const axisLabels = [];
102801
+ const gridlines = [], axisLabels = [];
102674
102802
  for (const val2 of axisTickValues(range)) {
102675
102803
  const y = valueToY2(val2, range, layout.plotTop, layout.plotBottom);
102676
102804
  gridlines.push({
@@ -102730,9 +102858,7 @@ function buildLegend(series, colorPalette, svgWidth, legendPos, svgHeight, plotT
102730
102858
  color: seriesColor2(s, i, colorPalette),
102731
102859
  label: s.name
102732
102860
  }));
102733
- let legendX = svgWidth / 2;
102734
- let legendY = svgHeight - 8;
102735
- let legendAnchor = "middle";
102861
+ let legendX = svgWidth / 2, legendY = svgHeight - 8, legendAnchor = "middle";
102736
102862
  if (legendPos === "r") {
102737
102863
  legendX = svgWidth - 75;
102738
102864
  legendY = plotTop;
@@ -102747,19 +102873,10 @@ function buildLegend(series, colorPalette, svgWidth, legendPos, svgHeight, plotT
102747
102873
  return { legend, legendX, legendY, legendAnchor };
102748
102874
  }
102749
102875
  function computeBarRects(series, catCount, layout, range, colorPalette) {
102750
- const rects = [];
102751
- const seriesCount = Math.max(series.length, 1);
102752
- const barGroupWidth = layout.plotWidth / Math.max(catCount, 1);
102753
- const singleBarWidth = barGroupWidth * 0.7 / seriesCount;
102754
- const groupOffset = (barGroupWidth - singleBarWidth * seriesCount) / 2;
102876
+ const rects = [], seriesCount = Math.max(series.length, 1), barGroupWidth = layout.plotWidth / Math.max(catCount, 1), singleBarWidth = barGroupWidth * 0.7 / seriesCount, groupOffset = (barGroupWidth - singleBarWidth * seriesCount) / 2;
102755
102877
  for (let ci = 0; ci < catCount; ci++) {
102756
102878
  for (let si = 0; si < series.length; si++) {
102757
- const val2 = series[si].values[ci] ?? 0;
102758
- const x = layout.plotLeft + barGroupWidth * ci + groupOffset + singleBarWidth * si;
102759
- const zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom);
102760
- const valY = valueToY2(val2, range, layout.plotTop, layout.plotBottom);
102761
- const y = Math.min(zeroY, valY);
102762
- const h = Math.max(Math.abs(zeroY - valY), 1);
102879
+ const val2 = series[si].values[ci] ?? 0, x = layout.plotLeft + barGroupWidth * ci + groupOffset + singleBarWidth * si, zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom), valY = valueToY2(val2, range, layout.plotTop, layout.plotBottom), y = Math.min(zeroY, valY), h = Math.max(Math.abs(zeroY - valY), 1);
102763
102880
  rects.push({
102764
102881
  x,
102765
102882
  y,
@@ -102772,20 +102889,15 @@ function computeBarRects(series, catCount, layout, range, colorPalette) {
102772
102889
  return rects;
102773
102890
  }
102774
102891
  function computeStackedBarRects(series, catCount, layout, range, colorPalette) {
102775
- const rects = [];
102776
- const barW = layout.plotWidth / Math.max(catCount, 1) * 0.7;
102777
- const barOffset = (layout.plotWidth / Math.max(catCount, 1) - barW) / 2;
102778
- const zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom);
102892
+ const rects = [], barW = layout.plotWidth / Math.max(catCount, 1) * 0.7, barOffset = (layout.plotWidth / Math.max(catCount, 1) - barW) / 2, zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom);
102779
102893
  for (let ci = 0; ci < catCount; ci++) {
102780
- let posTop = zeroY;
102781
- let negBottom = zeroY;
102894
+ let posTop = zeroY, negBottom = zeroY;
102782
102895
  for (let si = 0; si < series.length; si++) {
102783
102896
  const val2 = series[si].values[ci] ?? 0;
102784
102897
  if (val2 === 0) {
102785
102898
  continue;
102786
102899
  }
102787
- const x = layout.plotLeft + layout.plotWidth / Math.max(catCount, 1) * ci + barOffset;
102788
- const h = Math.max(
102900
+ const x = layout.plotLeft + layout.plotWidth / Math.max(catCount, 1) * ci + barOffset, h = Math.max(
102789
102901
  Math.abs(
102790
102902
  valueToY2(val2, range, layout.plotTop, layout.plotBottom) - valueToY2(0, range, layout.plotTop, layout.plotBottom)
102791
102903
  ),
@@ -102823,9 +102935,7 @@ function computeStackedBarRects(series, catCount, layout, range, colorPalette) {
102823
102935
  function computeLinePoints(values, catCount, layout, range) {
102824
102936
  const n = Math.max(catCount, 2);
102825
102937
  return values.map((val2, i) => {
102826
- const nx = n > 1 ? i / (n - 1) : 0;
102827
- const x = layout.plotLeft + layout.plotWidth * nx;
102828
- const y = valueToY2(val2, range, layout.plotTop, layout.plotBottom);
102938
+ const nx = n > 1 ? i / (n - 1) : 0, x = layout.plotLeft + layout.plotWidth * nx, y = valueToY2(val2, range, layout.plotTop, layout.plotBottom);
102829
102939
  return { x, y };
102830
102940
  });
102831
102941
  }
@@ -102833,49 +102943,30 @@ function linePointsToSvgString(points3) {
102833
102943
  return points3.map((p) => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(" ");
102834
102944
  }
102835
102945
  function computePieSlicePath(cx, cy, outerR, innerR, startAngle, endAngle) {
102836
- const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;
102837
- const x1 = cx + outerR * Math.cos(startAngle);
102838
- const y1 = cy + outerR * Math.sin(startAngle);
102839
- const x2 = cx + outerR * Math.cos(endAngle);
102840
- const y2 = cy + outerR * Math.sin(endAngle);
102946
+ const largeArc = endAngle - startAngle > Math.PI ? 1 : 0, x1 = cx + outerR * Math.cos(startAngle), y1 = cy + outerR * Math.sin(startAngle), x2 = cx + outerR * Math.cos(endAngle), y2 = cy + outerR * Math.sin(endAngle);
102841
102947
  let d;
102842
102948
  if (innerR > 0) {
102843
- const ix1 = cx + innerR * Math.cos(startAngle);
102844
- const iy1 = cy + innerR * Math.sin(startAngle);
102845
- const ix2 = cx + innerR * Math.cos(endAngle);
102846
- const iy2 = cy + innerR * Math.sin(endAngle);
102949
+ const ix1 = cx + innerR * Math.cos(startAngle), iy1 = cy + innerR * Math.sin(startAngle), ix2 = cx + innerR * Math.cos(endAngle), iy2 = cy + innerR * Math.sin(endAngle);
102847
102950
  d = `M${x1},${y1} A${outerR},${outerR} 0 ${largeArc} 1 ${x2},${y2} L${ix2},${iy2} A${innerR},${innerR} 0 ${largeArc} 0 ${ix1},${iy1} Z`;
102848
102951
  } else {
102849
102952
  d = `M${cx},${cy} L${x1},${y1} A${outerR},${outerR} 0 ${largeArc} 1 ${x2},${y2} Z`;
102850
102953
  }
102851
- const midAngle = (startAngle + endAngle) / 2;
102852
- const labelR = outerR * 0.7;
102853
- const labelX = cx + labelR * Math.cos(midAngle);
102854
- const labelY = cy + labelR * Math.sin(midAngle);
102954
+ const midAngle = (startAngle + endAngle) / 2, labelR = outerR * 0.7, labelX = cx + labelR * Math.cos(midAngle), labelY = cy + labelR * Math.sin(midAngle);
102855
102955
  return { d, midAngle, labelX, labelY };
102856
102956
  }
102857
102957
  function computePieLayout(elementWidth, elementHeight, chartData, isDoughnut) {
102858
- const size = Math.min(Math.max(elementWidth, 1), Math.max(elementHeight, 1));
102859
- const titleOffset = chartData.style?.hasTitle ? 20 : 0;
102860
- const legendOffset = chartData.style?.hasLegend ? 20 : 0;
102861
- const cx = size / 2;
102862
- const cy = titleOffset + (size - titleOffset - legendOffset) / 2;
102863
- const outerR = Math.max((size - titleOffset - legendOffset) * 0.42, 0);
102864
- const holeRatio = isDoughnut && chartData.doughnutHoleSize !== void 0 ? Math.min(Math.max(chartData.doughnutHoleSize, 10), 90) / 100 : 0.55;
102865
- const innerR = isDoughnut ? outerR * holeRatio : 0;
102958
+ const size = Math.min(Math.max(elementWidth, 1), Math.max(elementHeight, 1)), titleOffset = chartData.style?.hasTitle ? 20 : 0, legendOffset = chartData.style?.hasLegend ? 20 : 0, cx = size / 2, cy = titleOffset + (size - titleOffset - legendOffset) / 2, outerR = Math.max((size - titleOffset - legendOffset) * 0.42, 0), holeRatio = isDoughnut && chartData.doughnutHoleSize !== void 0 ? Math.min(Math.max(chartData.doughnutHoleSize, 10), 90) / 100 : 0.55, innerR = isDoughnut ? outerR * holeRatio : 0;
102866
102959
  return { cx, cy, outerR, innerR, size };
102867
102960
  }
102868
102961
  function computePieSlices(values, cx, cy, outerR, innerR, options) {
102869
102962
  const total = values.reduce((s, v) => s + Math.abs(v), 0) || 1;
102870
102963
  let cumAngle = options?.startAngle ?? -Math.PI / 2;
102871
102964
  return values.map((val2, i) => {
102872
- const sliceAngle = Math.abs(val2) / total * Math.PI * 2;
102873
- const startAngle = cumAngle;
102965
+ const sliceAngle = Math.abs(val2) / total * Math.PI * 2, startAngle = cumAngle;
102874
102966
  cumAngle += sliceAngle;
102875
102967
  const explosion = options?.explosions?.[i] ?? 0;
102876
102968
  if (explosion > 0) {
102877
- const mid = (startAngle + cumAngle) / 2;
102878
- const offset = outerR * (explosion / 100);
102969
+ const mid = (startAngle + cumAngle) / 2, offset = outerR * (explosion / 100);
102879
102970
  return computePieSlicePath(
102880
102971
  cx + Math.cos(mid) * offset,
102881
102972
  cy + Math.sin(mid) * offset,
@@ -102904,9 +102995,7 @@ function computeScatterXDomain(seriesXValues2) {
102904
102995
  return { min, span: Math.max(Math.max(...finite2) - min, 1) };
102905
102996
  }
102906
102997
  function computeScatterDots(values, maxXIndex, layout, range, xValues, xDomain) {
102907
- const finiteX = xValues?.slice(0, values.length).filter(Number.isFinite);
102908
- const minX = xDomain ? xDomain.min : finiteX?.length ? Math.min(...finiteX) : 0;
102909
- const spanX = xDomain ? xDomain.span : finiteX?.length ? Math.max(Math.max(...finiteX) - minX, 1) : maxXIndex;
102998
+ const finiteX = xValues?.slice(0, values.length).filter(Number.isFinite), minX = xDomain ? xDomain.min : finiteX?.length ? Math.min(...finiteX) : 0, spanX = xDomain ? xDomain.span : finiteX?.length ? Math.max(Math.max(...finiteX) - minX, 1) : maxXIndex;
102910
102999
  return values.map((val2, i) => ({
102911
103000
  cx: layout.plotLeft + (spanX > 0 ? (Number.isFinite(xValues?.[i]) ? xValues[i] - minX : i) / spanX : 0) * layout.plotWidth,
102912
103001
  cy: valueToY2(val2, range, layout.plotTop, layout.plotBottom)
@@ -102926,8 +103015,7 @@ function radarAngle(index, catCount) {
102926
103015
  function computeRadarPoints(values, maxVal, radius, cx, cy, catCount) {
102927
103016
  const denom = maxVal > 0 ? maxVal : 1;
102928
103017
  return values.slice(0, Math.max(catCount, 1)).map((val2, i) => {
102929
- const angle = radarAngle(i, catCount);
102930
- const r = Math.abs(val2) / denom * radius;
103018
+ const angle = radarAngle(i, catCount), r = Math.abs(val2) / denom * radius;
102931
103019
  return { x: cx + r * Math.cos(angle), y: cy + r * Math.sin(angle) };
102932
103020
  });
102933
103021
  }
@@ -102994,18 +103082,15 @@ function buildChartViewModel(element) {
102994
103082
  if (element.type !== "chart") {
102995
103083
  return buildFallbackViewModel(element.width, element.height, "Chart");
102996
103084
  }
102997
- const chartEl = element;
102998
- const chartData = chartEl.chartData;
103085
+ const chartEl = element, chartData = chartEl.chartData;
102999
103086
  if (!chartData || chartData.series.length === 0) {
103000
103087
  return buildFallbackViewModel(element.width, element.height, chartData?.title ?? "Chart");
103001
103088
  }
103002
- const chartType = chartData.chartType ?? "bar";
103003
- const kind = resolveChartKind(chartType);
103089
+ const chartType = chartData.chartType ?? "bar", kind = resolveChartKind(chartType);
103004
103090
  if (kind === "unsupported") {
103005
103091
  return buildFallbackViewModel(element.width, element.height, chartData.title ?? chartType);
103006
103092
  }
103007
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
103008
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i) => String(i + 1));
103093
+ const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0), categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i) => String(i + 1));
103009
103094
  if (chartType === "ofPie") {
103010
103095
  return withChartAreaFill(
103011
103096
  withUserShapeOverlay(buildOfPieViewModel(element, chartData, categoryLabels), chartData),
@@ -103082,8 +103167,7 @@ function buildFlatViewModel(element, chartData, categoryLabels, kind) {
103082
103167
  return buildCartesianViewModel(element, chartData, categoryLabels, kind);
103083
103168
  }
103084
103169
  function buildFallbackViewModel(width, height, label) {
103085
- const svgWidth = Math.max(width, 1);
103086
- const svgHeight = Math.max(height, 1);
103170
+ const svgWidth = Math.max(width, 1), svgHeight = Math.max(height, 1);
103087
103171
  return {
103088
103172
  svgWidth,
103089
103173
  svgHeight,
@@ -103131,15 +103215,7 @@ function buildPieViewModel(element, chartData, categoryLabels, isDoughnut) {
103131
103215
  element.height,
103132
103216
  chartData,
103133
103217
  isDoughnut
103134
- );
103135
- const svgWidth = Math.max(size, 100);
103136
- const svgHeight = Math.max(size, 60);
103137
- const pieSeries = chartData.series[0];
103138
- const values = pieSeries?.values ?? [];
103139
- const startAngle = -Math.PI / 2 + (chartData.firstSliceAngle ?? 0) * Math.PI / 180;
103140
- const explosions = pieSeries ? values.map((_v, i) => resolveDataPointExplosion(pieSeries, i)) : void 0;
103141
- const slices = computePieSlices(values, cx, cy, outerR, innerR, { startAngle, explosions });
103142
- const primitives = slices.map(
103218
+ ), svgWidth = Math.max(size, 100), svgHeight = Math.max(size, 60), pieSeries = chartData.series[0], values = pieSeries?.values ?? [], startAngle = -Math.PI / 2 + (chartData.firstSliceAngle ?? 0) * Math.PI / 180, explosions = pieSeries ? values.map((_v, i) => resolveDataPointExplosion(pieSeries, i)) : void 0, slices = computePieSlices(values, cx, cy, outerR, innerR, { startAngle, explosions }), primitives = slices.map(
103143
103219
  ({ d }, i) => ({
103144
103220
  kind: "path",
103145
103221
  d,
@@ -103148,13 +103224,17 @@ function buildPieViewModel(element, chartData, categoryLabels, isDoughnut) {
103148
103224
  fill: pieSeries ? resolveVaryColorFill(pieSeries, i, paletteColor2(i, chartData.colorPalette)) : paletteColor2(i, chartData.colorPalette),
103149
103225
  stroke: "#ffffff",
103150
103226
  strokeWidth: 1.5,
103151
- part: { role: "dataPoint", seriesIndex: 0, pointIndex: i }
103227
+ part: { role: "dataPoint", seriesIndex: 0, pointIndex: i },
103228
+ title: buildMarkTooltip(
103229
+ pieSeries?.name,
103230
+ categoryLabels[i],
103231
+ values[i] ?? 0,
103232
+ pieSeries?.numberFormat
103233
+ )
103152
103234
  })
103153
- );
103154
- const dataLabels = [];
103235
+ ), dataLabels = [];
103155
103236
  if (chartData.style?.hasDataLabels) {
103156
- const percentBase = values.reduce((total, entry2) => total + Math.abs(entry2), 0);
103157
- const labelResult = buildPieDataLabels({
103237
+ const percentBase = values.reduce((total, entry2) => total + Math.abs(entry2), 0), labelResult = buildPieDataLabels({
103158
103238
  slices,
103159
103239
  values,
103160
103240
  cx,
@@ -103174,12 +103254,10 @@ function buildPieViewModel(element, chartData, categoryLabels, isDoughnut) {
103174
103254
  dataLabels.push(...labelResult.labels);
103175
103255
  primitives.push(...labelResult.leaderLines);
103176
103256
  }
103177
- const legendPos = chartData.style?.legendPosition ?? "b";
103178
- const legend = categoryLabels.map((label, i) => ({
103257
+ const legendPos = chartData.style?.legendPosition ?? "b", legend = categoryLabels.map((label, i) => ({
103179
103258
  color: pieSeries ? resolveVaryColorFill(pieSeries, i, paletteColor2(i, chartData.colorPalette)) : paletteColor2(i, chartData.colorPalette),
103180
103259
  label
103181
- }));
103182
- const legendX = svgWidth / 2;
103260
+ })), legendX = svgWidth / 2;
103183
103261
  let legendY = svgHeight - 8;
103184
103262
  const legendAnchor = "middle";
103185
103263
  if (legendPos === "t") {
@@ -103209,14 +103287,7 @@ var RADAR_RING_COLOR = "#cbd5e1";
103209
103287
  var RADAR_SPOKE_COLOR = "#94a3b8";
103210
103288
  var RADAR_LABEL_COLOR = "#64748b";
103211
103289
  function buildRadarViewModel(element, chartData, categoryLabels) {
103212
- const layout = computePlotLayout(element.width, element.height, chartData, false);
103213
- const cx = layout.plotLeft + layout.plotWidth / 2;
103214
- const cy = layout.plotTop + layout.plotHeight / 2;
103215
- const radius = Math.max(Math.min(layout.plotWidth, layout.plotHeight) / 2 - 4, 1);
103216
- const catCount = Math.max(categoryLabels.length, 1);
103217
- const maxVal = Math.max(1, ...chartData.series.flatMap((s) => s.values.map((v) => Math.abs(v))));
103218
- const primitives = [];
103219
- const perimeterLabels = [];
103290
+ const layout = computePlotLayout(element.width, element.height, chartData, false), cx = layout.plotLeft + layout.plotWidth / 2, cy = layout.plotTop + layout.plotHeight / 2, radius = Math.max(Math.min(layout.plotWidth, layout.plotHeight) / 2 - 4, 1), catCount = Math.max(categoryLabels.length, 1), maxVal = Math.max(1, ...chartData.series.flatMap((s) => s.values.map((v) => Math.abs(v)))), primitives = [], perimeterLabels = [];
103220
103291
  for (let r = 1; r <= RADAR_RINGS; r++) {
103221
103292
  const rr = radius * r / RADAR_RINGS;
103222
103293
  primitives.push({
@@ -103253,8 +103324,7 @@ function buildRadarViewModel(element, chartData, categoryLabels) {
103253
103324
  }
103254
103325
  const dataLabels = [];
103255
103326
  chartData.series.forEach((series, si) => {
103256
- const c = seriesColor2(series, si, chartData.colorPalette);
103257
- const pts = computeRadarPoints(series.values, maxVal, radius, cx, cy, catCount);
103327
+ const c = seriesColor2(series, si, chartData.colorPalette), pts = computeRadarPoints(series.values, maxVal, radius, cx, cy, catCount);
103258
103328
  if (pts.length === 0) {
103259
103329
  return;
103260
103330
  }
@@ -103266,7 +103336,8 @@ function buildRadarViewModel(element, chartData, categoryLabels) {
103266
103336
  opacity: 0.2,
103267
103337
  stroke: c,
103268
103338
  strokeWidth: 1.5,
103269
- part: { role: "series", seriesIndex: si }
103339
+ part: { role: "series", seriesIndex: si },
103340
+ title: series.name.length > 0 ? series.name : void 0
103270
103341
  });
103271
103342
  pts.forEach((p, vi) => {
103272
103343
  primitives.push({
@@ -103275,7 +103346,13 @@ function buildRadarViewModel(element, chartData, categoryLabels) {
103275
103346
  cy: p.y,
103276
103347
  r: 3,
103277
103348
  fill: c,
103278
- part: { role: "dataPoint", seriesIndex: si, pointIndex: vi }
103349
+ part: { role: "dataPoint", seriesIndex: si, pointIndex: vi },
103350
+ title: buildMarkTooltip(
103351
+ series.name,
103352
+ categoryLabels[vi],
103353
+ series.values[vi] ?? 0,
103354
+ series.numberFormat
103355
+ )
103279
103356
  });
103280
103357
  });
103281
103358
  if (chartData.style?.hasDataLabels) {
@@ -103296,16 +103373,14 @@ function buildRadarViewModel(element, chartData, categoryLabels) {
103296
103373
  });
103297
103374
  }
103298
103375
  });
103299
- const legendPos = chartData.style?.legendPosition ?? "b";
103300
- const { legend, legendX, legendY, legendAnchor } = buildLegend(
103376
+ const legendPos = chartData.style?.legendPosition ?? "b", { legend, legendX, legendY, legendAnchor } = buildLegend(
103301
103377
  chartData.series,
103302
103378
  chartData.colorPalette,
103303
103379
  layout.svgWidth,
103304
103380
  legendPos,
103305
103381
  layout.svgHeight,
103306
103382
  layout.plotTop
103307
- );
103308
- const title = chartData.style?.hasTitle && chartData.title ? chartData.title : void 0;
103383
+ ), title = chartData.style?.hasTitle && chartData.title ? chartData.title : void 0;
103309
103384
  return {
103310
103385
  svgWidth: layout.svgWidth,
103311
103386
  svgHeight: layout.svgHeight,
@@ -103864,6 +103939,31 @@ var DIRECTIONAL_PRESETS = /* @__PURE__ */ new Set([
103864
103939
  "floatIn",
103865
103940
  "peekIn"
103866
103941
  ]);
103942
+ function reorderAnimationTo(animations, source, targetIndex) {
103943
+ const sorted = [...animations].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
103944
+ const sourceIndex = typeof source === "number" ? source : sorted.findIndex((a) => a.elementId === source.elementId);
103945
+ if (sourceIndex < 0 || sourceIndex >= sorted.length || targetIndex < 0 || targetIndex >= sorted.length || sourceIndex === targetIndex) {
103946
+ return reindexOrder(sorted);
103947
+ }
103948
+ const [moved] = sorted.splice(sourceIndex, 1);
103949
+ sorted.splice(targetIndex, 0, moved);
103950
+ return reindexOrder(sorted);
103951
+ }
103952
+ function buildAnimationTimelineBars(animations) {
103953
+ const sorted = [...animations].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
103954
+ const total = Math.max(
103955
+ 1,
103956
+ ...sorted.map((animation) => (animation.delayMs ?? 0) + (animation.durationMs ?? 500))
103957
+ );
103958
+ return sorted.map((animation) => ({
103959
+ elementId: animation.elementId,
103960
+ leftPercent: (animation.delayMs ?? 0) / total * 100,
103961
+ widthPercent: (animation.durationMs ?? 500) / total * 100
103962
+ }));
103963
+ }
103964
+ function reindexOrder(anims) {
103965
+ return anims.map((a, i) => ({ ...a, order: i }));
103966
+ }
103867
103967
  function animationPresetLabelKey(preset) {
103868
103968
  return `pptx.animation.preset.${preset}`;
103869
103969
  }
@@ -107467,9 +107567,9 @@ function rgbToHex4(r, g, b) {
107467
107567
  function tintColor(hex4, tintFactor) {
107468
107568
  const { r, g, b } = hexToRgb4(hex4);
107469
107569
  return rgbToHex4(
107470
- r + (255 - r) * tintFactor,
107471
- g + (255 - g) * tintFactor,
107472
- b + (255 - b) * tintFactor
107570
+ 255 - (255 - r) * tintFactor,
107571
+ 255 - (255 - g) * tintFactor,
107572
+ 255 - (255 - b) * tintFactor
107473
107573
  );
107474
107574
  }
107475
107575
  function shadeColor(hex4, shadeFactor) {
@@ -107541,12 +107641,10 @@ function applyStyleFill(fill, colorScheme, css, fallback) {
107541
107641
  const fg = normalizeHexColor(
107542
107642
  resolveStyleFillColor(fill.pattern.foreground, colorScheme),
107543
107643
  "#000000"
107544
- );
107545
- const bg = normalizeHexColor(
107644
+ ), bg = normalizeHexColor(
107546
107645
  resolveStyleFillColor(fill.pattern.background, colorScheme),
107547
107646
  "#ffffff"
107548
- );
107549
- const svg = getPatternSvg(fill.pattern.preset, fg, bg);
107647
+ ), svg = getPatternSvg(fill.pattern.preset, fg, bg);
107550
107648
  clearBackground(css);
107551
107649
  if (svg) {
107552
107650
  css.backgroundImage = `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
@@ -107631,11 +107729,7 @@ var BEVEL_LIGHT_OFFSETS = {
107631
107729
  l: { x: 1, y: 0 }
107632
107730
  };
107633
107731
  function cell3DBevelCss(cell3D) {
107634
- const size = Math.max(cell3D.bevelHeight ?? cell3D.bevelWidth ?? 4, 1);
107635
- const dir = cell3D.lightRigDirection ?? "tl";
107636
- const off = BEVEL_LIGHT_OFFSETS[dir] ?? BEVEL_LIGHT_OFFSETS.tl;
107637
- const highlight = `inset ${off.x * size}px ${off.y * size}px ${size}px rgba(255,255,255,0.55)`;
107638
- const shadow = `inset ${-off.x * size}px ${-off.y * size}px ${size}px rgba(0,0,0,0.4)`;
107732
+ const size = Math.max(cell3D.bevelHeight ?? cell3D.bevelWidth ?? 4, 1), dir = cell3D.lightRigDirection ?? "tl", off = BEVEL_LIGHT_OFFSETS[dir] ?? BEVEL_LIGHT_OFFSETS.tl, highlight = `inset ${off.x * size}px ${off.y * size}px ${size}px rgba(255,255,255,0.55)`, shadow = `inset ${-off.x * size}px ${-off.y * size}px ${size}px rgba(0,0,0,0.4)`;
107639
107733
  return { boxShadow: `${highlight}, ${shadow}` };
107640
107734
  }
107641
107735
  function cellRunStyle(run) {
@@ -108740,6 +108834,23 @@ var TABLE_STYLE_PRESETS = [
108740
108834
  borderColor: "#548235"
108741
108835
  }
108742
108836
  ];
108837
+ function applyTableStylePreset(td, preset) {
108838
+ return td.rows.map((row, ri) => ({
108839
+ ...row,
108840
+ cells: row.cells.map((cell) => {
108841
+ const isHeader = ri === 0 && Boolean(td.firstRowHeader);
108842
+ const isBand = Boolean(td.bandedRows) && (ri - (td.firstRowHeader ? 1 : 0)) % 2 === 0;
108843
+ const style = {
108844
+ ...cell.style,
108845
+ backgroundColor: isHeader ? preset.headerBg : isBand ? preset.bandBg : void 0,
108846
+ color: isHeader ? preset.headerFg : cell.style?.color,
108847
+ bold: isHeader ? true : cell.style?.bold,
108848
+ borderColor: preset.borderColor
108849
+ };
108850
+ return { ...cell, style };
108851
+ })
108852
+ }));
108853
+ }
108743
108854
  var SEL = "bg-muted border border-border rounded px-2 py-1 text-[11px] w-full";
108744
108855
  var NUM = "flex-1 bg-muted border border-border rounded px-1.5 py-0.5 w-full text-[11px]";
108745
108856
  var LBL = "text-muted-foreground text-[11px]";
@@ -108758,6 +108869,7 @@ var PATTERN_OPTIONS = OOXML_PATTERN_PRESETS.slice(0, 20);
108758
108869
  var MIN_COLUMN_PROPORTION = 0.03;
108759
108870
  var MIN_ROW_HEIGHT = 16;
108760
108871
  var DEFAULT_ROW_HEIGHT = 32;
108872
+ var MIN_COLUMN_WIDTH_FRACTION = 0.05;
108761
108873
  function computeColumnBoundaries(columnWidths) {
108762
108874
  const result = [];
108763
108875
  let cumulative = 0;
@@ -108786,6 +108898,39 @@ function computeResizedColumnWidths(initialWidths, index, deltaProportion) {
108786
108898
  function computeResizedRowHeight(initialRowHeight, deltaY) {
108787
108899
  return Math.round(Math.max(MIN_ROW_HEIGHT, initialRowHeight + deltaY));
108788
108900
  }
108901
+ function redistributeColumnWidth(widths, index, newFraction) {
108902
+ const oldFraction = widths[index];
108903
+ if (oldFraction === void 0) {
108904
+ return widths;
108905
+ }
108906
+ const diff = newFraction - oldFraction;
108907
+ const next = [...widths];
108908
+ next[index] = newFraction;
108909
+ const othersTotal = 1 - oldFraction;
108910
+ if (othersTotal > 0) {
108911
+ for (let j = 0; j < next.length; j++) {
108912
+ if (j !== index) {
108913
+ next[j] = Math.max(MIN_COLUMN_WIDTH_FRACTION, widths[j] - diff * (widths[j] / othersTotal));
108914
+ }
108915
+ }
108916
+ }
108917
+ const sum = next.reduce((a, b) => a + b, 0);
108918
+ return sum > 0 ? next.map((w) => w / sum) : next;
108919
+ }
108920
+ function evenColumnWidths(count) {
108921
+ if (count <= 0) {
108922
+ return [];
108923
+ }
108924
+ return Array.from({ length: count }, () => 1 / count);
108925
+ }
108926
+ function evenRowHeights(rows) {
108927
+ const count = rows.length;
108928
+ if (count === 0) {
108929
+ return rows;
108930
+ }
108931
+ const avg = Math.round(rows.reduce((s, r) => s + (r.height ?? DEFAULT_ROW_HEIGHT), 0) / count);
108932
+ return rows.map((r) => ({ ...r, height: avg }));
108933
+ }
108789
108934
  function findSmartArtNodeText(data, nodeId) {
108790
108935
  return data.nodes.find((n) => n.id === nodeId)?.text;
108791
108936
  }
@@ -109160,7 +109305,7 @@ function getImageFitStyle(el) {
109160
109305
  const uncropped = {
109161
109306
  width: "100%",
109162
109307
  height: "100%",
109163
- objectFit: "cover"
109308
+ objectFit: "fill"
109164
109309
  };
109165
109310
  if (!isImageLikeElement(el)) {
109166
109311
  return uncropped;
@@ -111710,6 +111855,8 @@ var translationsEn = {
111710
111855
  "pptx.ribbon.customColour": "Custom colour...",
111711
111856
  "pptx.ribbon.textHighlightColour": "Text highlight colour",
111712
111857
  "pptx.ribbon.highlightColourValue": "Highlight colour {{color}}",
111858
+ "pptx.ribbon.fillColourValue": "Fill colour {{color}}",
111859
+ "pptx.ribbon.outlineColourValue": "Outline colour {{color}}",
111713
111860
  "pptx.ribbon.bulletList": "Bullet list",
111714
111861
  "pptx.ribbon.justify": "Justify",
111715
111862
  "pptx.toolbar.findAndReplace": "Find and replace",
@@ -124717,6 +124864,102 @@ function buildSmartArtA11y(data) {
124717
124864
  nodes
124718
124865
  };
124719
124866
  }
124867
+ var LAYOUT_BOUNDS = {
124868
+ // A Venn diagram is typically drawn with 2-3 overlapping sets; beyond a
124869
+ // handful of circles it becomes unreadable.
124870
+ venn: { min: 2, max: 3 },
124871
+ // A 2x2 matrix has exactly four quadrants.
124872
+ matrix: { min: 4, max: 4 },
124873
+ // Pyramids and funnels need at least two tiers to convey a hierarchy.
124874
+ pyramid: { min: 2, max: 5 },
124875
+ funnel: { min: 2, max: 5 },
124876
+ // A target is a small set of concentric rings.
124877
+ target: { min: 2, max: 5 },
124878
+ // Gears mesh in small clusters.
124879
+ gear: { min: 2, max: 3 },
124880
+ // Cycles need at least three steps to read as a loop.
124881
+ cycle: { min: 3 }
124882
+ // Relationship / process / list / hierarchy / timeline are flexible but
124883
+ // still need at least one node to exist.
124884
+ };
124885
+ var DEFAULT_BOUNDS = { min: 1 };
124886
+ function getSmartArtNodeBounds(layout) {
124887
+ if (!layout) {
124888
+ return DEFAULT_BOUNDS;
124889
+ }
124890
+ return LAYOUT_BOUNDS[layout] ?? DEFAULT_BOUNDS;
124891
+ }
124892
+ function canAddTopLevelNode(layout, topLevelCount) {
124893
+ const { max } = getSmartArtNodeBounds(layout);
124894
+ return max === void 0 || topLevelCount < max;
124895
+ }
124896
+ function canRemoveTopLevelNode(layout, topLevelCount) {
124897
+ const { min } = getSmartArtNodeBounds(layout);
124898
+ return topLevelCount > min;
124899
+ }
124900
+ function describeSmartArtBounds(layout) {
124901
+ const { min, max } = getSmartArtNodeBounds(layout);
124902
+ if (min <= 1 && max === void 0) {
124903
+ return void 0;
124904
+ }
124905
+ if (max === void 0) {
124906
+ return `Works best with at least ${min} items.`;
124907
+ }
124908
+ if (min === max) {
124909
+ return `This layout uses exactly ${max} items.`;
124910
+ }
124911
+ return `Works best with ${min} to ${max} items.`;
124912
+ }
124913
+ function addSiblingAfter(data, nodeId) {
124914
+ const next = addSmartArtNode(data, "", nodeId);
124915
+ if (next === data) {
124916
+ return void 0;
124917
+ }
124918
+ const idx = next.nodes.findIndex((n) => n.id === nodeId), inserted = idx >= 0 ? next.nodes[idx + 1] : void 0;
124919
+ return { data: next, focusNodeId: inserted?.id };
124920
+ }
124921
+ function removeEmptyNode(data, nodeId) {
124922
+ if (data.nodes.length <= 1) {
124923
+ return void 0;
124924
+ }
124925
+ const removedIndex = data.nodes.findIndex((n) => n.id === nodeId), next = removeSmartArtNode(data, nodeId);
124926
+ if (next === data) {
124927
+ return void 0;
124928
+ }
124929
+ const focusNode = next.nodes[Math.max(0, removedIndex - 1)];
124930
+ return { data: next, focusNodeId: focusNode?.id };
124931
+ }
124932
+ function demote(data, nodeId) {
124933
+ const next = demoteSmartArtNode(data, nodeId);
124934
+ return next === data ? void 0 : next;
124935
+ }
124936
+ function promote(data, nodeId) {
124937
+ const next = promoteSmartArtNode(data, nodeId);
124938
+ return next === data ? void 0 : next;
124939
+ }
124940
+ function reorder2(data, nodeId, direction) {
124941
+ const next = reorderSmartArtNode(data, nodeId, direction);
124942
+ return next === data ? void 0 : next;
124943
+ }
124944
+ function siblingIndex(data, nodeId) {
124945
+ const node = data.nodes.find((n) => n.id === nodeId);
124946
+ if (!node) {
124947
+ return -1;
124948
+ }
124949
+ const siblings = data.nodes.filter((n) => n.parentId === node.parentId);
124950
+ return siblings.findIndex((n) => n.id === nodeId);
124951
+ }
124952
+ function siblingCount(data, nodeId) {
124953
+ const node = data.nodes.find((n) => n.id === nodeId);
124954
+ if (!node) {
124955
+ return 0;
124956
+ }
124957
+ return data.nodes.filter((n) => n.parentId === node.parentId).length;
124958
+ }
124959
+ var TREE_CONNECTION_TYPES = /* @__PURE__ */ new Set(["parOf", "presParOf", void 0]);
124960
+ function classifyExtraConnections(data) {
124961
+ return (data.connections ?? []).filter((c) => !TREE_CONNECTION_TYPES.has(c.type));
124962
+ }
124720
124963
  var THREE_UNAVAILABLE = {
124721
124964
  ok: false,
124722
124965
  resize: () => {
@@ -129155,6 +129398,17 @@ function resolveInkWidth(widths, index, fallback = 3) {
129155
129398
  }
129156
129399
  return widths[index] > 0 ? widths[index] : fallback;
129157
129400
  }
129401
+ function buildBarActions(opts) {
129402
+ const { slideCount } = opts;
129403
+ const noSlides = slideCount === 0;
129404
+ return [
129405
+ { key: "slides", label: "Slides", disabled: noSlides },
129406
+ { key: "insert", label: "Insert", disabled: noSlides },
129407
+ { key: "inspector", label: "Format", disabled: noSlides },
129408
+ { key: "comments", label: "Comments", disabled: noSlides },
129409
+ { key: "notes", label: "Notes", disabled: noSlides }
129410
+ ];
129411
+ }
129158
129412
  var COMMENT_MENTION_ATTRIBUTE = "data-pptx-comment-mention";
129159
129413
  var COMMENT_MENTION_CLASS = "pptx-comment-mention";
129160
129414
  var usableMentions = (body, mentions) => (mentions ?? []).filter(
@@ -130603,7 +130857,7 @@ var WEIGHT_SUFFIXES = [
130603
130857
  [/black|heavy/iu, "900"],
130604
130858
  [/bold/iu, "700"]
130605
130859
  ];
130606
- var STYLE_TOKEN = /[-_\s]*(?:thin|hairline|extralight|ultralight|light|regular|normal|book|medium|semibold|demibold|extrabold|ultrabold|black|heavy|bold|italic|oblique)+$/giu;
130860
+ var STYLE_TOKEN = /[-_\s]*(?:thin|hairline|extralight|ultralight|light|regular|normal|book|medium|semibold|demibold|extrabold|ultrabold|black|heavy|bold|italic|oblique)$/giu;
130607
130861
  function deriveCustomFontDescriptor(fileName) {
130608
130862
  const stem = fileName.replace(/\.[^.]+$/u, "");
130609
130863
  const italic = /(?:italic|oblique)(?![a-z])/iu.test(stem);
@@ -132631,8 +132885,7 @@ function sanitizeDownloadFilename(input) {
132631
132885
  return cleaned;
132632
132886
  }
132633
132887
  function downloadBlob(blob, filename) {
132634
- const url = URL.createObjectURL(blob);
132635
- const anchor = document.createElement("a");
132888
+ const url = URL.createObjectURL(blob), anchor = document.createElement("a");
132636
132889
  anchor.href = url;
132637
132890
  anchor.download = filename;
132638
132891
  document.body.appendChild(anchor);
@@ -132657,13 +132910,10 @@ function dataUrlToBlob(dataUrl) {
132657
132910
  if (!match?.groups) {
132658
132911
  return void 0;
132659
132912
  }
132660
- const mime = match.groups.mime || "application/octet-stream";
132661
- const isBase64 = Boolean(match.groups.base64);
132662
- const payload = match.groups.payload ?? "";
132913
+ const mime = match.groups.mime || "application/octet-stream", isBase64 = Boolean(match.groups.base64), payload = match.groups.payload ?? "";
132663
132914
  try {
132664
132915
  if (isBase64) {
132665
- const binary = atob(payload);
132666
- const bytes = new Uint8Array(binary.length);
132916
+ const binary = atob(payload), bytes = new Uint8Array(binary.length);
132667
132917
  for (let i = 0; i < binary.length; i++) {
132668
132918
  bytes[i] = binary.charCodeAt(i);
132669
132919
  }
@@ -132675,9 +132925,7 @@ function dataUrlToBlob(dataUrl) {
132675
132925
  }
132676
132926
  }
132677
132927
  function openUrlInNewTab(url) {
132678
- const blob = url.startsWith("data:") ? dataUrlToBlob(url) : void 0;
132679
- const target = blob ? URL.createObjectURL(blob) : url;
132680
- const opened = window.open(target, "_blank");
132928
+ const blob = url.startsWith("data:") ? dataUrlToBlob(url) : void 0, target = blob ? URL.createObjectURL(blob) : url, opened = window.open(target, "_blank");
132681
132929
  if (opened) {
132682
132930
  try {
132683
132931
  opened.opener = null;
@@ -134237,4 +134485,4 @@ function segmentFrameCount(durationMs, fps) {
134237
134485
  * `<p:extLst>` (optional)
134238
134486
  */
134239
134487
 
134240
- export { ACTION_BUTTON_PRESETS, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, ARTISTIC_EFFECTS, AVATAR_COLOR_SWATCHES, BACKSTAGE_NAV, BACKSTAGE_TEMPLATES, BEVEL_PRESETS, BROADCAST_THROTTLE_MS, CATEGORIES, CHARACTER_SPACING_OPTIONS, COLOR_MAP_ALIAS_KEYS, COMMENT_MENTION_ATTRIBUTE, COMMENT_MENTION_CLASS, COMMON_FONTS, CONNECTION_TIMEOUT_MS, CONNECTOR_SITE_SNAP_PX, CUSTOM_FONT_ACCEPT, DEBOUNCE_MS, DEFAULT_BROADCAST_SERVER_URL, DEFAULT_COLOR_CHANGE_TOLERANCE, DEFAULT_COLOR_MAP, DEFAULT_FONT_FAMILY, DEFAULT_INSERT_CHART_KIND, DEFAULT_MOTION_PATH_PRESET_ID, DEFAULT_PALETTE2, DEFAULT_QUICK_ACCESS_COMMAND_IDS, DEFAULT_ROW_HEIGHT, DEFAULT_VIEWER_OPTIONS, DEFAULT_VIEWER_PROFILE, DEFAULT_VIRTUAL_OVERSCAN, DIRECTIONAL_PRESETS, DUOTONE_PRESETS, ELEMENT_ACTION_TYPE_OPTIONS, EMPHASIS_PRESET_VALUES, ENTRANCE_PRESET_VALUES, EQUATION_TEMPLATES, EXIT_PRESET_VALUES, EXPANDED_MAX_HEIGHT, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, EncryptedFileError, FILL_MODE_OPTIONS, FILL_PATTERN_LABEL_KEYS, GRADIENT_TYPE_OPTIONS, HANDOUT_OPTIONS, HIDDEN_SLIDE_LABEL_KEY, HIDDEN_SLIDE_SLASH_GRADIENT, HIGHLIGHTER_COLORS, INDENT_PX, INK_REPLAY_KEYFRAMES, INSERT_CHART_TYPES, LBL, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_HINT_CLASS, LINK_TOOLTIP_HOST_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_PANEL_CLASS, LOCAL_SYNC_ORIGIN, MATERIAL_PRESETS, MAX_INDENT_LEVEL, MAX_ZOOM_SCALE, MEDIA_CHROME_ATTRIBUTE, MIN_ZOOM_SCALE, MOBILE_BREAKPOINT, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, MOTION_PATH_FAMILIES, NOTES_FONT_SIZE_DEFAULT, NOTES_FONT_SIZE_MAX, NOTES_FONT_SIZE_MIN, NOTES_FONT_SIZE_STEP, NUM, OUTLINE_LEVEL_ATTR, OUTLINE_ROW_ATTR, OUTLINE_SLIDE_ATTR, OUTLINE_VIEW_ATTR, PATTERN_OPTIONS, PEN_COLORS, PPTX_OPEN_ACCEPT, PRESENTATION_CHANNEL_NAME, PRESENTATION_HASH, PRESENTATION_HIT_TEST_CSS, PRESENTATION_MESSAGE_ORIGIN, PRESENTATION_NONCE_KEY, PRESENTATION_OPEN_EXTENSIONS, PRESENTATION_STAGE_ATTRIBUTE, PRESENTER_CONSOLE_CLASSES, PRESENTER_CONSOLE_CONTROLS, PRESENTER_NAVIGATOR_LABEL_KEYS, PRESENT_TOOLBAR_CLASSES, PRESETS, PRESET_THEMES, PptxHandler, PptxMarkdownConverter, PresentationAnimationController, QUICK_ACCESS_COMMAND_CATALOG, READING_VIEW_ATTR, READING_VIEW_COUNTER_ATTR, READING_VIEW_STAGE_ATTR, RIBBON_SHAPE_SWATCHES, RIBBON_TRANSITION_PRESETS, RULER_FONT_SIZE, RULER_THICKNESS, SECTION_HEADING, SEL, SHAPE_PRESET_DEFS, SHAPE_QUICK_STYLES, SHORTCUT_REFERENCE_ITEMS, SLIDE_SHOW_OPTIONS, SLIDE_SIZE_PRESETS, SLIDE_TEMPLATES, SLIDE_TRANSITION_KEYFRAMES, SLIDE_TRANSITION_OPTIONS, SLIDE_VIRTUALIZATION_THRESHOLD, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, SORTER_MAX_ZOOM, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, STATUS_BAR_CLASSES, SWITCHABLE_LAYOUT_TYPES, SvgExporter, TABLET_BREAKPOINT, TABLE_STYLE_PRESETS, TAB_ROW_ACTION_CLASSES, TEXT_BUILD_ID_SEP, TEXT_WARP_PRESETS, THEME_CATALOG, THEME_COLOR_SCHEME_KEYS, THEME_COLOR_SLOT_LABEL_KEYS, THEME_PRESETS, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, TOOLBAR_TABS, TRANSITION_DIR_ARROWS, TRANSITION_ORIENTATION_TYPES, TRANSITION_VALID_DIRECTIONS, ThemePresets, VIEWER_OPTIONS_TABS, VIEWER_PREFS_STORAGE_KEY, VIEWER_SHORTCUT_REFERENCE, WEBM_MIME_CANDIDATES, acceptAutosaveRecovery, acceptsPresentationInput, actionAffordanceLabels, activateModalFocus, addChartCategory, addChartSeries, addQuickAccessCommand, addSection, addSmartArtNode, addSmartArtNodeAsChild, addTagToCollections, alignElements, animationEffectLabel, annotationOverlayZIndex, appendPresentationInkPoint, appendTableElementColumn, appendTableElementRow, apply3dEffects, applyAcceptAllSlides, applyAcceptSlide, applyCaseTransformToSegments, applyChartBuildReveal, applyColorChange, applyDuotone, applyFindReplacements, applyFormatToElement, applyMotionPathPreset, applyOutlineEdit, applyPreferenceToOptions, applyReadingViewCommand, applyRehearsalTimings, applyReroutedConnectors, applyResize, applyStyleToSelectedSegments, applyThemeOverrideToSlide, applyThemeToData, attachPresentationVisibilityPause, authorConnectorBetweenSites, autosaveSnapshotMark, availableQuickAccessCommands, backstageCardsFor, beginShapeAdjustment, bringForward, bringToFront, build3DExtrusionData, buildActiveSessionUsers, buildBroadcastViewerUrl, buildCacheKey, buildCalloutLeaderLineSvgPath, buildChartViewModel, buildCollaborationShareUrl, buildContextMenuEntries, buildCreateCollaborationConfig, buildCssGradientFromShapeStyle, buildDirectionGrid, buildDuotoneCacheKey, buildElementClipboardPayload, buildFieldSubstitutionContext, buildFontCatalog, buildHandoutsHtml, buildHollowHitOutline, buildInitialGuides, buildJoinCollaborationConfig, buildLayoutPreviewGeometry, buildMorphAnimationRules, buildMorphTransitionPlan, buildMotionPathPreview, buildNotesHtml, buildNotesPdfBytes, buildOutline, buildOutlineHtml, buildParagraphs, buildPresentationAudienceUrl, buildPreviewAnimation, buildPreviewElements, buildPrintDocument, buildPrintHtmlDocument, buildSaveSlides, buildSlideTemplateContent, buildSlideTemplateSlide, buildSlidesHtml, buildSlidesPdfBytes, buildSmartArt3DModel, buildSmartArtA11y, buildSmartArtPresetData, buildStrokeOutline, buildSummaryZoomView, buildSvgGradientDef, buildTableDataGrid, buildTextBlockStyle, buildTextBody3DSceneStyle, buildTextBodyLayoutStyle, buildTextBuildSpec, buildThemeColorGrid, buildThemeColorMap, buildUserFontFaceStyles, canCommitActionType, canGoNext, canGoPrevious, canInteractWithElement, canvasToJpegData, cellRunStyle, cellStyleToCss, centeredSvgTextLines, chartDataChangeType, chartPartToAttrs, chartPreserveAspectRatio, clampCropValue, clampNotesFontSize, clampPercent, clampSorterZoom, clampTransitionNumber, clampUnitInterval2 as clampUnitInterval, clampZoomScale, clearAllLocalViewerData, clearAudienceContent, clearLocalAwareness, clearMotionPath, clearStoredViewerPrefs, cloneElementForPaste, cloneHistorySnapshot, cloneSlide, cloneTemplateElementsBySlideId, collectConnectorSiteCandidates, collectImagePaths, collectMediaElements, collectUsedFonts, colorWithOpacity, commentTextSegments, comparePresentation, compileEquationTemplateMathMl, compileLatexEquation, computeAllNotesPages, computeColumnBoundaries, computeDrawingViewBox, computeEntranceAnimationDelay, computeHandoutLayout, computeInlineEditorRect, computeKeyboardInset, computeMarqueeHitIds, computeMergeCellDown, computeMergeCellRight, computeResizedColumnWidths, computeResizedRowHeight, computeScrollDelta, computeSelectionRect, computeSmartArtLayout2 as computeSmartArtLayout, computeSnapToShape, computeSplitCell, computeVirtualRange, convertLatexToOmml, convertOmmlToLatex, convertOmmlToMathMl, copyFormatFromElement, createBackstagePresentation, createBlankSlide, createCollaborationLivePatcher, createDefaultChartElement, createDepartureChannel, createInitialPresentationSnapshot, createPlainNotesSegments, createPresenceProjector, createPresentationKeyBuffer, createPresentationSessionId, createPresenterShowGuard, createPresenterTimer, createSyncGate, createTouchGestureRecognizer, createViewerOptionsStore, createViewerZoomStore, createWheelStepBuffer, customGeometryPathsToSvgSubpaths, defaultCssVars, defaultRadius, defaultThemeColors, deleteAutosaveSnapshot, deleteSection, deleteTableColumn, deleteTableRow, deleteTagFromCollections, demoteSmartArtNode, deriveSlideFieldContext, describeFontEmbedding, detectOrientation, detectTouchDevice, discardAutosaveRecovery, distributeElements, downloadBlob, downloadDataUrl, dragAnchorViewY, dragValueForPart, elementActionToPptxAction, elementLockTogglePatch, embeddedFontSaveOptions, encodeGif, endAudienceDisplay, ensureActionAffordanceStyles, ensureChartInteractionStyles, erasePresentationInkAt, escapeHtml22 as escapeHtml2, exportDeckJson, extraQuickAccessCommands, extractPathPoints, filterCommands, filterInteractableIds, filterRenderedElements, findChartPartTarget, findConnectorSiteNear, findInSlides, findMediaElementByElementId, findSmartArtNodeText, firstShowSlideIndex, flattenNodes, flattenTagCollections, forgetSessionDeck, formatAxisValue, formatBackstageDate, formatBackstageSize, formatBytes, formatCommentTimestamp, formatElapsed, formatMobileElapsed, formatRelativeTime, formatSlideCounter, formatTime, formatVersionTimestamp, fpsToFrameIntervalMs, generateBroadcastRoomId, generateElementId, generateNoteLineCount, generatePackageReadme, generatePressureCircles, generateTicks, getAnimationInitialStyle, getAriaLabel, getAriaRole, getAriaRoleDescription, getCachedResult, getCalloutLeaderLineGeometry, getCalloutViewBoxBounds, getCellDiagonalBorders, getChartStylePalette, getCommentMarkerPosition, getCompoundLineOffsets, getCompoundLineWidths, getComputedEffectStyle, getComputedFillStyle, getComputedStrokeStyle, getConnectorEndpointHandles, getContentPartReplayStyles, getCurrentParagraphIndex, getDraggedShapeAdjustments, getDuotoneCachedResult, getElementLabel, getElementTransform, getElementTransformWithoutRotation, getGroupChildParentFill, getImageColorWashStyle, getImageEffectsFilter, getImageEffectsOpacity, getImageFitStyle, getImageSvgFilters, getImageTilingStyle, getInkReplayStyles, getInlineEditorSelection, getLocalStorageUsageSummary, getNotesPrintableArea, getOleBadgeLabel, getOleObjectTypeLabel, getOleTypeColor, getOleTypeLabel, getOverflowSegments, getPatternSvg, getPendingSelectionRestore, getPresetShapeClipPath, getPrintableArea, getResolvedShapeClipPath, getRoundRectRadiusPx2, getSessionTabId, getShapeAdjustmentHandleDescriptors, getShapeConnectionSites, getSlideBackgroundStyle, getSlideTransitionAnimations, getSoftEdgeSvgFilter, getSubstituteFontFamily, getSvgStrokeDasharray, getTableCellBandStyle, getTextBodyRotationTransform, getTextCompensationTransform, getWarpPath, groupElements, groupIntoParagraphs, groupSlidesBySection, guidePxToEmu, handleReadingViewKey, hasCopyableFormat, hasDistinctScriptFonts, hasPressureVariation, hasShapeProperties, hasShowSlideAfter, hasTextProperties, hexToRgbChannels2 as hexToRgbChannels, hiddenSlideCue, hollowTextFillStyle, inlineElementPointerEvents, insertTableColumn, insertTableRow, isActionHidden, isBlackboardActive, isBrowserOpenableMime, isCalloutShape, isCellInRect, isCurrentLayout, isEditableMotionPath, isEditableTextElement, isEditorTextInputTarget, isElementActionable, isElementLocked, isElementRendered, isExportAbortError, isHollowShapeElement, isImageLikeElement, isImageTiled, isInkElement, isKeyboardOpen, isLegacyBinaryPresentation, isLinkedTextBox, isMixedContentBlocked, isMobileViewport, isPpactionUrl, isPresentationAdvanceClick, isPresentationSessionMessage, isStrokeOnlyPresetElement, isSupportedPresentationFile, isTemplateElementId3 as isTemplateElementId, isUrlSafe, lastShowSlideIndex, listAutosaveSnapshots, listBackstageRecentFiles, loadAudienceContent, loadSessionDeck, makeCloneId, makeSlideId, mapEditingWheel, mapEditorKey, mapOutlineKey, mapPresentationKey, mapPresentationWheel, mapSlideSorterKey, masterViewBackgroundColor, masterViewElements, masterViewPseudoSlide, mayLeaveSlideShow, mediaFallbackIcon, mediaFallbackLabelKey, mediaFallbackVisual, mediaPlaybackAttributes, mediaTransportVisible, mergeAdditiveSelection, mergeCells, mergePresentationSnapshot, mergeShapes, mergeSlideTransition, mobileElapsedSince, mobileSlideCounter, morphOptionToMode, motionPathEndPixel, motionPathFamilyLabelKey, motionPathFor, motionPathPresetIdForPath, motionPathPresetLabelKey, motionPathPresetsByFamily, motionPathToSvgD, mountModel3D, movePresenterPointer, moveQuickAccessCommand, moveSectionDown, moveSectionUp, moveSlidesToSection, nestedTextDecorationStyle, newTableElement, nextPresentedSlide, nextShowSlideIndex, normalizeColorsForCapture, normalizeHexColor, normalizeSegments, normalizeStrokeDashType, notesSegmentsToSpans, observeYDocSlides, ooxmlGradientAngleToCssDegrees, openNativeEyeDropper, openPptxFile, openReadingView, openUrlInNewTab, paintedStrokeWidth, paragraphsToSegments, parseDrawingColor, parseDrawingColorOpacity, parsePanoseString, parsePpactionUrl, parseSegmentsFromRichEditor, partitionTemplateElements, pickSupportedMimeType, pieceLetterSpacing, placeAudienceWindow, placeCaretAtEnd, playSlideTransitionPreview, polygonsToSvgPath, pptxActionToElementAction, preprocessCssForCapture, presentationBaseName, presentationInkPath, presenterElapsed, presenterNextDisabled, presenterPaneAdvancesOnClick, presenterPrevDisabled, presenterTimerProgress, pressuresToWidths, previousShowSlideIndex, printPropertiesFrameSlides, printPropertiesSlidesPerPage, probeAutosaveRecovery, projectDrawingShapes, promoteSmartArtNode, publishLiveGeometry, publishLiveInlineText, quickStyleSwatchCss, reResolveSlideColors, readBackstageRecentFile, readRibbonTransitionDraft, readSlideShowOption, readSlidesFromYDoc, readStoredViewerPrefs, readViewportMetrics, readingViewFitScale, rebuildDrawingShapesIfCleared, rebuildTableStructureInRawXml, reconcileSlidesInYDoc, recordProgressPercent, rectToCells, registerCollaborationTeardown, registerCustomFont, registerPersistentAudio, remapTextToSegments, rememberSessionDeck, removeChartCategory, removeChartSeries, removeLastTableElementColumn, removeLastTableElementRow, removeQuickAccessCommand, removeSmartArtNode, removeTableElementColumn, removeTableElementRow, renameSection, reorderSmartArtNode, replaceMasterViewElements, rerouteConnectorsForMovedElements, resetPresenterTimer, resetSlideLayoutPath, resolveActionType, resolveAudienceScreenPlacement, resolveAuthoredCustomShowId, resolveAutoAdvanceDelayMs, resolveAutoFitFontScale, resolveAutosaveActivation, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, resolveChartKind, resolveConnectorEndpointUpdate, resolveDefaultFontFamily, resolveDrawingShapeNodeId, resolveElementActionAffordance, resolveElementInteractivity, resolveFontForScript, resolveGroupChildFill, resolveInkColor, resolveInkOpacity, resolveInkWidth, resolveMetricTrackingPx, resolveOleType, resolvePalette, resolveProfileInitial, resolveSelectionPaneRename, resolveShapeGeometry, resolveShowSlideIndexes, resolveSlideSizeSelection, resolveThemeCatalogEntry, resolveTitleBarStatusKey, resolveTransitionDurationMs, resolveTransportForServerUrl, resolveViewerAddinRows, restoreSegmentSelection, restoreSessionDeck, revealedSmartArtNodeCount, ribbonTransitionUpdates, rulerDragToGuidePosition, runMediaCommand, runPresentationAction, safeOpenUrl, sanitizeColor, sanitizeDownloadFilename, sanitizeGradientStops, sanitizeMathMl, saveAutosaveSnapshot, saveDeckWithPassword, saveViewerProfile, savedPresentationFileName, scanAvailableFontFamilies, schemaLabel, scopeLayoutOptionsToSlide, segmentByScript, segmentFrameCount, segmentsToEditorHtml, segmentsToParagraphs, segmentsToPlainText, sendBackward, sendToBack, setCachedResult, setCellText, setChartAxisGridlineStyle, setChartAxisLogScale, setChartAxisTitleStyle, setChartCategoryLabel, setChartCellValue, setChartDataPointExplosion, setChartDataPointFill, setChartDataPointLabel, setChartDataPointMarker, setChartSeriesChartType, setChartSeriesMarker, setDuotoneCachedResult, setMasterViewBackgroundColor, setMotionPath, setMotionPathEnd, setPendingSelectionRestore, setSmartArtNodeStyle, setTableElementCellText, shapeFillChange, shapeOutlineChange, shouldAutoFollowBroadcaster, shouldCommitSmartArtNodeText, shouldConfirmExternalHyperlink, shouldLoopContinuously, shouldProbeAutosaveRecovery, shouldRoomSlidesReplaceLoad, shouldShowAutosaveRecoveryPrompt, shouldUseSvgWarp, shouldWriteAutosaveSnapshot, slideProgressPercent, slideShowOptionChange, slideSizeFromPreset, slideSizeToCanvasPx, slideStatusLabel, snapBoxToGrid, splitCell, splitRunForMetrics, stepPresenterZoom, stopAllPersistentAudio, storeAudienceContent, strokeOutlineViewBox, styleShadowFilter, substituteFieldText, svgGradientFillRef, svgLineCap, svgPathToPolygons, swapPresentationWindows, switchSmartArtLayout, tableCellCss, tableContainerCss, templateSchemeFromTheme, text3dEmuToPt, text3dPtToEmu, textBuildSpanStyle, themeColorLabel, themeColorSchemesEqual, themeToCssVars, toCssTextOrientation, toCssVerticalDirection, toCssWritingMode, toSlideIndex, toggleBlackboard, togglePresenterTimer, toggleText3dExtrusion, transformTextCase, ungroupElements, updateCellTextInRawXml, updateCellTextStyleInRawXml, updateMasterViewElement, updateMergeAttrsInRawXml, updateSmartArtNodeText, updateTagInCollections, validateRoomId, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius, viewerOptionsToPreferences, warpPreviewPath, withChartPointValue, withChartTitle, withConnectorEndpointUpdate, withFrameSlides, withSlideSizeOrientation, withSlidesPerPage, writeStoredViewerPrefs };
134488
+ export { ACTION_BUTTON_PRESETS, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, ARTISTIC_EFFECTS, AVATAR_COLOR_SWATCHES, BACKSTAGE_NAV, BACKSTAGE_TEMPLATES, BEVEL_PRESETS, BROADCAST_THROTTLE_MS, CATEGORIES, CHARACTER_SPACING_OPTIONS, COLOR_MAP_ALIAS_KEYS, COMMENT_MENTION_ATTRIBUTE, COMMENT_MENTION_CLASS, COMMON_FONTS, CONNECTION_TIMEOUT_MS, CONNECTOR_SITE_SNAP_PX, CUSTOM_FONT_ACCEPT, DEBOUNCE_MS, DEFAULT_BROADCAST_SERVER_URL, DEFAULT_COLOR_CHANGE_TOLERANCE, DEFAULT_COLOR_MAP, DEFAULT_FONT_FAMILY, DEFAULT_INSERT_CHART_KIND, DEFAULT_MOTION_PATH_PRESET_ID, DEFAULT_PALETTE2, DEFAULT_QUICK_ACCESS_COMMAND_IDS, DEFAULT_ROW_HEIGHT, DEFAULT_VIEWER_OPTIONS, DEFAULT_VIEWER_PROFILE, DEFAULT_VIRTUAL_OVERSCAN, DIRECTIONAL_PRESETS, DUOTONE_PRESETS, ELEMENT_ACTION_TYPE_OPTIONS, EMPHASIS_PRESET_VALUES, ENTRANCE_PRESET_VALUES, EQUATION_TEMPLATES, EXIT_PRESET_VALUES, EXPANDED_MAX_HEIGHT, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, EncryptedFileError, FILL_MODE_OPTIONS, FILL_PATTERN_LABEL_KEYS, GRADIENT_TYPE_OPTIONS, HANDOUT_OPTIONS, HIDDEN_SLIDE_LABEL_KEY, HIDDEN_SLIDE_SLASH_GRADIENT, HIGHLIGHTER_COLORS, INDENT_PX, INK_REPLAY_KEYFRAMES, INSERT_CHART_TYPES, LBL, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_HINT_CLASS, LINK_TOOLTIP_HOST_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_PANEL_CLASS, LOCAL_SYNC_ORIGIN, MATERIAL_PRESETS, MAX_INDENT_LEVEL, MAX_ZOOM_SCALE, MEDIA_CHROME_ATTRIBUTE, MIN_ZOOM_SCALE, MOBILE_BREAKPOINT, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, MOTION_PATH_FAMILIES, NOTES_FONT_SIZE_DEFAULT, NOTES_FONT_SIZE_MAX, NOTES_FONT_SIZE_MIN, NOTES_FONT_SIZE_STEP, NUM, OUTLINE_LEVEL_ATTR, OUTLINE_ROW_ATTR, OUTLINE_SLIDE_ATTR, OUTLINE_VIEW_ATTR, PATTERN_OPTIONS, PEN_COLORS, PPTX_OPEN_ACCEPT, PRESENTATION_CHANNEL_NAME, PRESENTATION_HASH, PRESENTATION_HIT_TEST_CSS, PRESENTATION_MESSAGE_ORIGIN, PRESENTATION_NONCE_KEY, PRESENTATION_OPEN_EXTENSIONS, PRESENTATION_STAGE_ATTRIBUTE, PRESENTER_CONSOLE_CLASSES, PRESENTER_CONSOLE_CONTROLS, PRESENTER_NAVIGATOR_LABEL_KEYS, PRESENT_TOOLBAR_CLASSES, PRESETS, PRESET_THEMES, PptxHandler, PptxMarkdownConverter, PresentationAnimationController, QUICK_ACCESS_COMMAND_CATALOG, READING_VIEW_ATTR, READING_VIEW_COUNTER_ATTR, READING_VIEW_STAGE_ATTR, RIBBON_SHAPE_SWATCHES, RIBBON_TRANSITION_PRESETS, RULER_FONT_SIZE, RULER_THICKNESS, SECTION_HEADING, SEL, SHAPE_PRESET_DEFS, SHAPE_QUICK_STYLES, SHORTCUT_REFERENCE_ITEMS, SLIDE_SHOW_OPTIONS, SLIDE_SIZE_PRESETS, SLIDE_TEMPLATES, SLIDE_TRANSITION_KEYFRAMES, SLIDE_TRANSITION_OPTIONS, SLIDE_VIRTUALIZATION_THRESHOLD, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, SORTER_MAX_ZOOM, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, STATUS_BAR_CLASSES, SWITCHABLE_LAYOUT_TYPES, SvgExporter, TABLET_BREAKPOINT, TABLE_STYLE_PRESETS, TAB_ROW_ACTION_CLASSES, TEXT_BUILD_ID_SEP, TEXT_WARP_PRESETS, THEME_CATALOG, THEME_COLOR_SCHEME_KEYS, THEME_COLOR_SLOT_LABEL_KEYS, THEME_PRESETS, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, TOOLBAR_TABS, TRANSITION_DIR_ARROWS, TRANSITION_ORIENTATION_TYPES, TRANSITION_VALID_DIRECTIONS, ThemePresets, VIEWER_OPTIONS_TABS, VIEWER_PREFS_STORAGE_KEY, VIEWER_SHORTCUT_REFERENCE, WEBM_MIME_CANDIDATES, acceptAutosaveRecovery, acceptsPresentationInput, actionAffordanceLabels, activateModalFocus, addChartCategory, addChartSeries, addQuickAccessCommand, addSection, addSiblingAfter, addSmartArtNodeAsChild, addTagToCollections, alignElements, animationEffectLabel, annotationOverlayZIndex, appendPresentationInkPoint, appendTableElementColumn, appendTableElementRow, apply3dEffects, applyAcceptAllSlides, applyAcceptSlide, applyCaseTransformToSegments, applyChartBuildReveal, applyColorChange, applyDuotone, applyFindReplacements, applyFormatToElement, applyMotionPathPreset, applyOutlineEdit, applyPreferenceToOptions, applyReadingViewCommand, applyRehearsalTimings, applyReroutedConnectors, applyResize, applyStyleToSelectedSegments, applyTableStylePreset, applyThemeOverrideToSlide, applyThemeToData, attachPresentationVisibilityPause, authorConnectorBetweenSites, autosaveSnapshotMark, availableQuickAccessCommands, backstageCardsFor, beginShapeAdjustment, bringForward, bringToFront, build3DExtrusionData, buildActiveSessionUsers, buildAnimationTimelineBars, buildBarActions, buildBroadcastViewerUrl, buildCacheKey, buildCalloutLeaderLineSvgPath, buildChartViewModel, buildCollaborationShareUrl, buildContextMenuEntries, buildCreateCollaborationConfig, buildCssGradientFromShapeStyle, buildDirectionGrid, buildDuotoneCacheKey, buildElementClipboardPayload, buildFieldSubstitutionContext, buildFontCatalog, buildHandoutsHtml, buildHollowHitOutline, buildInitialGuides, buildJoinCollaborationConfig, buildLayoutPreviewGeometry, buildMorphAnimationRules, buildMorphTransitionPlan, buildMotionPathPreview, buildNotesHtml, buildNotesPdfBytes, buildOutline, buildOutlineHtml, buildParagraphs, buildPresentationAudienceUrl, buildPreviewAnimation, buildPreviewElements, buildPrintDocument, buildPrintHtmlDocument, buildSaveSlides, buildSlideTemplateContent, buildSlideTemplateSlide, buildSlidesHtml, buildSlidesPdfBytes, buildSmartArt3DModel, buildSmartArtA11y, buildSmartArtPresetData, buildStrokeOutline, buildSummaryZoomView, buildSvgGradientDef, buildTableDataGrid, buildTextBlockStyle, buildTextBody3DSceneStyle, buildTextBodyLayoutStyle, buildTextBuildSpec, buildThemeColorGrid, buildThemeColorMap, buildUserFontFaceStyles, canAddTopLevelNode, canCommitActionType, canGoNext, canGoPrevious, canInteractWithElement, canRemoveTopLevelNode, canvasToJpegData, cellRunStyle, cellStyleToCss, centeredSvgTextLines, chartDataChangeType, chartPartToAttrs, chartPreserveAspectRatio, clampCropValue, clampNotesFontSize, clampPercent, clampSorterZoom, clampTransitionNumber, clampUnitInterval2 as clampUnitInterval, clampZoomScale, classifyExtraConnections, clearAllLocalViewerData, clearAudienceContent, clearLocalAwareness, clearMotionPath, clearStoredViewerPrefs, cloneElementForPaste, cloneHistorySnapshot, cloneSlide, cloneTemplateElementsBySlideId, collectConnectorSiteCandidates, collectImagePaths, collectMediaElements, collectUsedFonts, colorWithOpacity, commentTextSegments, comparePresentation, compileEquationTemplateMathMl, compileLatexEquation, computeAllNotesPages, computeChartLegendLayout, computeColumnBoundaries, computeDrawingViewBox, computeEntranceAnimationDelay, computeHandoutLayout, computeInlineEditorRect, computeKeyboardInset, computeMarqueeHitIds, computeMergeCellDown, computeMergeCellRight, computeResizedColumnWidths, computeResizedRowHeight, computeScrollDelta, computeSelectionRect, computeSmartArtLayout2 as computeSmartArtLayout, computeSnapToShape, computeSplitCell, computeVirtualRange, convertLatexToOmml, convertOmmlToLatex, convertOmmlToMathMl, copyFormatFromElement, createBackstagePresentation, createBlankSlide, createCollaborationLivePatcher, createDefaultChartElement, createDepartureChannel, createInitialPresentationSnapshot, createPlainNotesSegments, createPresenceProjector, createPresentationKeyBuffer, createPresentationSessionId, createPresenterShowGuard, createPresenterTimer, createSyncGate, createTouchGestureRecognizer, createViewerOptionsStore, createViewerZoomStore, createWheelStepBuffer, customGeometryPathsToSvgSubpaths, defaultCssVars, defaultRadius, defaultThemeColors, deleteAutosaveSnapshot, deleteSection, deleteTableColumn, deleteTableRow, deleteTagFromCollections, demote, deriveSlideFieldContext, describeFontEmbedding, describeSmartArtBounds, detectOrientation, detectTouchDevice, discardAutosaveRecovery, distributeElements, downloadBlob, downloadDataUrl, dragAnchorViewY, dragValueForPart, elementActionToPptxAction, elementLockTogglePatch, embeddedFontSaveOptions, encodeGif, endAudienceDisplay, ensureActionAffordanceStyles, ensureChartInteractionStyles, erasePresentationInkAt, escapeHtml22 as escapeHtml2, evenColumnWidths, evenRowHeights, exportDeckJson, extraQuickAccessCommands, extractPathPoints, filterCommands, filterInteractableIds, filterRenderedElements, findChartPartTarget, findConnectorSiteNear, findInSlides, findMediaElementByElementId, findSmartArtNodeText, firstShowSlideIndex, flattenNodes, flattenTagCollections, forgetSessionDeck, formatAxisValue, formatBackstageDate, formatBackstageSize, formatBytes, formatCommentTimestamp, formatElapsed, formatMobileElapsed, formatRelativeTime, formatSlideCounter, formatTime, formatVersionTimestamp, fpsToFrameIntervalMs, generateBroadcastRoomId, generateElementId, generateNoteLineCount, generatePackageReadme, generatePressureCircles, generateTicks, getAnimationInitialStyle, getAriaLabel, getAriaRole, getAriaRoleDescription, getCachedResult, getCalloutLeaderLineGeometry, getCalloutViewBoxBounds, getCellDiagonalBorders, getChartStylePalette, getCommentMarkerPosition, getCompoundLineOffsets, getCompoundLineWidths, getComputedEffectStyle, getComputedFillStyle, getComputedStrokeStyle, getConnectorEndpointHandles, getContentPartReplayStyles, getCurrentParagraphIndex, getDraggedShapeAdjustments, getDuotoneCachedResult, getElementLabel, getElementTransform, getElementTransformWithoutRotation, getGroupChildParentFill, getImageColorWashStyle, getImageEffectsFilter, getImageEffectsOpacity, getImageFitStyle, getImageSvgFilters, getImageTilingStyle, getInkReplayStyles, getInlineEditorSelection, getLocalStorageUsageSummary, getNotesPrintableArea, getOleBadgeLabel, getOleObjectTypeLabel, getOleTypeColor, getOleTypeLabel, getOverflowSegments, getPatternSvg, getPendingSelectionRestore, getPresetShapeClipPath, getPrintableArea, getResolvedShapeClipPath, getRoundRectRadiusPx2, getSessionTabId, getShapeAdjustmentHandleDescriptors, getShapeConnectionSites, getSlideBackgroundStyle, getSlideTransitionAnimations, getSoftEdgeSvgFilter, getSubstituteFontFamily, getSvgStrokeDasharray, getTableCellBandStyle, getTextBodyRotationTransform, getTextCompensationTransform, getWarpPath, groupElements, groupIntoParagraphs, groupSlidesBySection, guidePxToEmu, handleReadingViewKey, hasCopyableFormat, hasDistinctScriptFonts, hasPressureVariation, hasShapeProperties, hasShowSlideAfter, hasTextProperties, hexToRgbChannels2 as hexToRgbChannels, hiddenSlideCue, hollowTextFillStyle, inlineElementPointerEvents, insertTableColumn, insertTableRow, isActionHidden, isBlackboardActive, isBrowserOpenableMime, isCalloutShape, isCellInRect, isCurrentLayout, isEditableMotionPath, isEditableTextElement, isEditorTextInputTarget, isElementActionable, isElementLocked, isElementRendered, isExportAbortError, isHollowShapeElement, isImageLikeElement, isImageTiled, isInkElement, isKeyboardOpen, isLegacyBinaryPresentation, isLinkedTextBox, isMixedContentBlocked, isMobileViewport, isPpactionUrl, isPresentationAdvanceClick, isPresentationSessionMessage, isStrokeOnlyPresetElement, isSupportedPresentationFile, isTemplateElementId3 as isTemplateElementId, isUrlSafe, lastShowSlideIndex, listAutosaveSnapshots, listBackstageRecentFiles, loadAudienceContent, loadSessionDeck, makeCloneId, makeSlideId, mapEditingWheel, mapEditorKey, mapOutlineKey, mapPresentationKey, mapPresentationWheel, mapSlideSorterKey, masterViewBackgroundColor, masterViewElements, masterViewPseudoSlide, mayLeaveSlideShow, mediaFallbackIcon, mediaFallbackLabelKey, mediaFallbackVisual, mediaPlaybackAttributes, mediaTransportVisible, mergeAdditiveSelection, mergeCells, mergePresentationSnapshot, mergeShapes, mergeSlideTransition, mobileElapsedSince, mobileSlideCounter, morphOptionToMode, motionPathEndPixel, motionPathFamilyLabelKey, motionPathFor, motionPathPresetIdForPath, motionPathPresetLabelKey, motionPathPresetsByFamily, motionPathToSvgD, mountModel3D, movePresenterPointer, moveQuickAccessCommand, moveSectionDown, moveSectionUp, moveSlidesToSection, nestedTextDecorationStyle, newTableElement, nextPresentedSlide, nextShowSlideIndex, normalizeColorsForCapture, normalizeHexColor, normalizeSegments, normalizeStrokeDashType, notesSegmentsToSpans, observeYDocSlides, ooxmlGradientAngleToCssDegrees, openNativeEyeDropper, openPptxFile, openReadingView, openUrlInNewTab, paintedStrokeWidth, paragraphsToSegments, parseDrawingColor, parseDrawingColorOpacity, parsePanoseString, parsePpactionUrl, parseSegmentsFromRichEditor, partitionTemplateElements, pickSupportedMimeType, pieceLetterSpacing, placeAudienceWindow, placeCaretAtEnd, playSlideTransitionPreview, polygonsToSvgPath, pptxActionToElementAction, preprocessCssForCapture, presentationBaseName, presentationInkPath, presenterElapsed, presenterNextDisabled, presenterPaneAdvancesOnClick, presenterPrevDisabled, presenterTimerProgress, pressuresToWidths, previousShowSlideIndex, printPropertiesFrameSlides, printPropertiesSlidesPerPage, probeAutosaveRecovery, projectDrawingShapes, promote, publishLiveGeometry, publishLiveInlineText, quickStyleSwatchCss, reResolveSlideColors, readBackstageRecentFile, readRibbonTransitionDraft, readSlideShowOption, readSlidesFromYDoc, readStoredViewerPrefs, readViewportMetrics, readingViewFitScale, rebuildDrawingShapesIfCleared, rebuildTableStructureInRawXml, reconcileSlidesInYDoc, recordProgressPercent, rectToCells, redistributeColumnWidth, registerCollaborationTeardown, registerCustomFont, registerPersistentAudio, remapTextToSegments, rememberSessionDeck, removeChartCategory, removeChartSeries, removeEmptyNode, removeLastTableElementColumn, removeLastTableElementRow, removeQuickAccessCommand, removeSmartArtNode, removeTableElementColumn, removeTableElementRow, renameSection, reorder2 as reorder, reorderAnimationTo, replaceMasterViewElements, rerouteConnectorsForMovedElements, resetPresenterTimer, resetSlideLayoutPath, resolveActionType, resolveAudienceScreenPlacement, resolveAuthoredCustomShowId, resolveAutoAdvanceDelayMs, resolveAutoFitFontScale, resolveAutosaveActivation, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, resolveChartKind, resolveConnectorEndpointUpdate, resolveDefaultFontFamily, resolveDrawingShapeNodeId, resolveElementActionAffordance, resolveElementInteractivity, resolveFontForScript, resolveGroupChildFill, resolveInkColor, resolveInkOpacity, resolveInkWidth, resolveMetricTrackingPx, resolveOleType, resolvePalette, resolveProfileInitial, resolveSelectionPaneRename, resolveShapeGeometry, resolveShowSlideIndexes, resolveSlideSizeSelection, resolveThemeCatalogEntry, resolveTitleBarStatusKey, resolveTransitionDurationMs, resolveTransportForServerUrl, resolveViewerAddinRows, restoreSegmentSelection, restoreSessionDeck, revealedSmartArtNodeCount, ribbonTransitionUpdates, rulerDragToGuidePosition, runMediaCommand, runPresentationAction, safeOpenUrl, sanitizeColor, sanitizeDownloadFilename, sanitizeGradientStops, sanitizeMathMl, saveAutosaveSnapshot, saveDeckWithPassword, saveViewerProfile, savedPresentationFileName, scanAvailableFontFamilies, schemaLabel, scopeLayoutOptionsToSlide, segmentByScript, segmentFrameCount, segmentsToEditorHtml, segmentsToParagraphs, segmentsToPlainText, sendBackward, sendToBack, setCachedResult, setCellText, setChartAxisGridlineStyle, setChartAxisLogScale, setChartAxisTitleStyle, setChartCategoryLabel, setChartCellValue, setChartDataPointExplosion, setChartDataPointFill, setChartDataPointLabel, setChartDataPointMarker, setChartSeriesChartType, setChartSeriesMarker, setDuotoneCachedResult, setMasterViewBackgroundColor, setMotionPath, setMotionPathEnd, setPendingSelectionRestore, setSmartArtNodeStyle, setTableElementCellText, shapeFillChange, shapeOutlineChange, shouldAutoFollowBroadcaster, shouldCommitSmartArtNodeText, shouldConfirmExternalHyperlink, shouldLoopContinuously, shouldProbeAutosaveRecovery, shouldRoomSlidesReplaceLoad, shouldShowAutosaveRecoveryPrompt, shouldUseSvgWarp, shouldWriteAutosaveSnapshot, siblingCount, siblingIndex, slideProgressPercent, slideShowOptionChange, slideSizeFromPreset, slideSizeToCanvasPx, slideStatusLabel, snapBoxToGrid, splitCell, splitRunForMetrics, stepPresenterZoom, stopAllPersistentAudio, storeAudienceContent, strokeOutlineViewBox, styleShadowFilter, substituteFieldText, svgGradientFillRef, svgLineCap, svgPathToPolygons, swapPresentationWindows, switchSmartArtLayout, tableCellCss, tableContainerCss, templateSchemeFromTheme, text3dEmuToPt, text3dPtToEmu, textBuildSpanStyle, themeColorLabel, themeColorSchemesEqual, themeToCssVars, toCssTextOrientation, toCssVerticalDirection, toCssWritingMode, toSlideIndex, toggleBlackboard, togglePresenterTimer, toggleText3dExtrusion, transformTextCase, ungroupElements, updateCellTextInRawXml, updateCellTextStyleInRawXml, updateMasterViewElement, updateMergeAttrsInRawXml, updateSmartArtNodeText, updateTagInCollections, validateRoomId, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius, viewerOptionsToPreferences, warpPreviewPath, withChartPointValue, withChartTitle, withConnectorEndpointUpdate, withFrameSlides, withSlideSizeOrientation, withSlidesPerPage, writeStoredViewerPrefs };