pptx-react-viewer 2.18.0 → 2.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +712 -0
  2. package/dist/{AiChatPanel-SSSBERWJ.mjs → AiChatPanel-GRAIPSG3.mjs} +4 -4
  3. package/dist/AiChatPanel-GRAIPSG3.mjs.br +0 -0
  4. package/dist/AiChatPanel-GRAIPSG3.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-UN5DHPZY.js → AiChatPanel-JSTZ6W7R.js} +24 -24
  6. package/dist/AiChatPanel-JSTZ6W7R.js.br +0 -0
  7. package/dist/AiChatPanel-JSTZ6W7R.js.gz +0 -0
  8. package/dist/{Model3DScene-LYEESYAI.mjs → Model3DScene-FXDA7OII.mjs} +1 -1
  9. package/dist/Model3DScene-FXDA7OII.mjs.br +0 -0
  10. package/dist/Model3DScene-FXDA7OII.mjs.gz +0 -0
  11. package/dist/{Model3DScene-4RPYKC2I.js → Model3DScene-WLRZXJHN.js} +2 -2
  12. package/dist/Model3DScene-WLRZXJHN.js.br +0 -0
  13. package/dist/Model3DScene-WLRZXJHN.js.gz +0 -0
  14. package/dist/{PowerPointViewer-Cf4YHjdF.d.ts → PowerPointViewer-DVFkeluD.d.ts} +2 -2
  15. package/dist/PowerPointViewer-DVFkeluD.d.ts.map +1 -0
  16. package/dist/{audience-content-store-CyS0oP6t.d.ts → audience-content-store-ChVOSdBh.d.ts} +2 -2
  17. package/dist/{audience-content-store-CyS0oP6t.d.ts.map → audience-content-store-ChVOSdBh.d.ts.map} +1 -1
  18. package/dist/{chunk-QUB5OSKY.mjs → chunk-5ZQ3ZQ3M.mjs} +71 -125
  19. package/dist/chunk-5ZQ3ZQ3M.mjs.br +0 -0
  20. package/dist/chunk-5ZQ3ZQ3M.mjs.gz +0 -0
  21. package/dist/{chunk-O7FTUUXP.mjs → chunk-B55E3KXL.mjs} +210 -92
  22. package/dist/chunk-B55E3KXL.mjs.br +0 -0
  23. package/dist/chunk-B55E3KXL.mjs.gz +0 -0
  24. package/dist/{chunk-7XF6S4AM.mjs → chunk-KQGS6A5J.mjs} +1 -1
  25. package/dist/chunk-KQGS6A5J.mjs.br +0 -0
  26. package/dist/chunk-KQGS6A5J.mjs.gz +0 -0
  27. package/dist/{chunk-ASKYZ5ZY.js → chunk-LMTUC7U7.js} +440 -494
  28. package/dist/chunk-LMTUC7U7.js.br +0 -0
  29. package/dist/chunk-LMTUC7U7.js.gz +0 -0
  30. package/dist/{chunk-RTUGI4HQ.js → chunk-MVKRI3CZ.js} +9 -0
  31. package/dist/chunk-MVKRI3CZ.js.br +0 -0
  32. package/dist/chunk-MVKRI3CZ.js.gz +0 -0
  33. package/dist/{chunk-4LWGAVAP.js → chunk-PIJAFM4B.js} +197 -2425
  34. package/dist/chunk-PIJAFM4B.js.br +0 -0
  35. package/dist/chunk-PIJAFM4B.js.gz +0 -0
  36. package/dist/{chunk-GODW6RNR.mjs → chunk-PNR3J26S.mjs} +1173 -1051
  37. package/dist/chunk-PNR3J26S.mjs.br +0 -0
  38. package/dist/chunk-PNR3J26S.mjs.gz +0 -0
  39. package/dist/{chunk-MAVLV56S.js → chunk-SCGIXXN5.js} +3 -3
  40. package/dist/chunk-SCGIXXN5.js.br +0 -0
  41. package/dist/chunk-SCGIXXN5.js.gz +0 -0
  42. package/dist/{chunk-SNL6LBRX.mjs → chunk-SQJBFMEX.mjs} +9 -0
  43. package/dist/chunk-SQJBFMEX.mjs.br +0 -0
  44. package/dist/chunk-SQJBFMEX.mjs.gz +0 -0
  45. package/dist/{chunk-WVDM36ZM.js → chunk-T7BIRNE4.js} +1185 -1067
  46. package/dist/chunk-T7BIRNE4.js.br +0 -0
  47. package/dist/chunk-T7BIRNE4.js.gz +0 -0
  48. package/dist/{chunk-ICZDMFF2.js → chunk-TPC65IB2.js} +1219 -1101
  49. package/dist/chunk-TPC65IB2.js.br +0 -0
  50. package/dist/chunk-TPC65IB2.js.gz +0 -0
  51. package/dist/{chunk-BZOL6FXF.mjs → chunk-WGXQXHCS.mjs} +52 -2280
  52. package/dist/chunk-WGXQXHCS.mjs.br +0 -0
  53. package/dist/chunk-WGXQXHCS.mjs.gz +0 -0
  54. package/dist/i18n.js +4 -4
  55. package/dist/i18n.js.br +0 -0
  56. package/dist/i18n.js.gz +0 -0
  57. package/dist/i18n.mjs +1 -1
  58. package/dist/i18n.mjs.br +0 -0
  59. package/dist/i18n.mjs.gz +0 -0
  60. package/dist/index.d.ts +38 -1
  61. package/dist/index.js +47 -47
  62. package/dist/index.js.br +0 -0
  63. package/dist/index.js.gz +0 -0
  64. package/dist/index.mjs +6 -6
  65. package/dist/index.mjs.br +0 -0
  66. package/dist/index.mjs.gz +0 -0
  67. package/dist/internals.d.ts +102 -15
  68. package/dist/internals.d.ts.map +1 -1
  69. package/dist/internals.js +79 -79
  70. package/dist/internals.js.br +0 -0
  71. package/dist/internals.js.gz +0 -0
  72. package/dist/internals.mjs +4 -4
  73. package/dist/internals.mjs.br +0 -0
  74. package/dist/internals.mjs.gz +0 -0
  75. package/dist/{types-C_CTI-QE.d.ts → types-TCH6icpi.d.ts} +23 -1
  76. package/dist/{types-C_CTI-QE.d.ts.map → types-TCH6icpi.d.ts.map} +1 -1
  77. package/dist/{useViewerBuildingBlocks-DItilDbP.d.ts → useViewerBuildingBlocks-BKb0qs1j.d.ts} +20 -4
  78. package/dist/{useViewerBuildingBlocks-DItilDbP.d.ts.map → useViewerBuildingBlocks-BKb0qs1j.d.ts.map} +1 -1
  79. package/dist/viewer/index.d.ts +38 -1
  80. package/dist/viewer/index.js +27 -27
  81. package/dist/viewer/index.js.br +0 -0
  82. package/dist/viewer/index.js.gz +0 -0
  83. package/dist/viewer/index.mjs +6 -6
  84. package/dist/viewer/index.mjs.br +0 -0
  85. package/dist/viewer/index.mjs.gz +0 -0
  86. package/package.json +1 -1
  87. package/dist/AiChatPanel-SSSBERWJ.mjs.br +0 -0
  88. package/dist/AiChatPanel-SSSBERWJ.mjs.gz +0 -0
  89. package/dist/AiChatPanel-UN5DHPZY.js.br +0 -0
  90. package/dist/AiChatPanel-UN5DHPZY.js.gz +0 -0
  91. package/dist/Model3DScene-4RPYKC2I.js.br +0 -0
  92. package/dist/Model3DScene-4RPYKC2I.js.gz +0 -0
  93. package/dist/Model3DScene-LYEESYAI.mjs.br +0 -0
  94. package/dist/Model3DScene-LYEESYAI.mjs.gz +0 -0
  95. package/dist/PowerPointViewer-Cf4YHjdF.d.ts.map +0 -1
  96. package/dist/SurfaceChart3DScene-ACPKCWLJ.js +0 -78
  97. package/dist/SurfaceChart3DScene-ACPKCWLJ.js.br +0 -0
  98. package/dist/SurfaceChart3DScene-ACPKCWLJ.js.gz +0 -0
  99. package/dist/SurfaceChart3DScene-JR62SOYO.mjs +0 -76
  100. package/dist/SurfaceChart3DScene-JR62SOYO.mjs.br +0 -0
  101. package/dist/SurfaceChart3DScene-JR62SOYO.mjs.gz +0 -0
  102. package/dist/chunk-4LWGAVAP.js.br +0 -0
  103. package/dist/chunk-4LWGAVAP.js.gz +0 -0
  104. package/dist/chunk-7XF6S4AM.mjs.br +0 -0
  105. package/dist/chunk-7XF6S4AM.mjs.gz +0 -0
  106. package/dist/chunk-ASKYZ5ZY.js.br +0 -0
  107. package/dist/chunk-ASKYZ5ZY.js.gz +0 -0
  108. package/dist/chunk-BZOL6FXF.mjs.br +0 -0
  109. package/dist/chunk-BZOL6FXF.mjs.gz +0 -0
  110. package/dist/chunk-GODW6RNR.mjs.br +0 -0
  111. package/dist/chunk-GODW6RNR.mjs.gz +0 -0
  112. package/dist/chunk-ICZDMFF2.js.br +0 -0
  113. package/dist/chunk-ICZDMFF2.js.gz +0 -0
  114. package/dist/chunk-MAVLV56S.js.br +0 -0
  115. package/dist/chunk-MAVLV56S.js.gz +0 -0
  116. package/dist/chunk-O7FTUUXP.mjs.br +0 -0
  117. package/dist/chunk-O7FTUUXP.mjs.gz +0 -0
  118. package/dist/chunk-QUB5OSKY.mjs.br +0 -0
  119. package/dist/chunk-QUB5OSKY.mjs.gz +0 -0
  120. package/dist/chunk-RTUGI4HQ.js.br +0 -0
  121. package/dist/chunk-RTUGI4HQ.js.gz +0 -0
  122. package/dist/chunk-SNL6LBRX.mjs.br +0 -0
  123. package/dist/chunk-SNL6LBRX.mjs.gz +0 -0
  124. package/dist/chunk-WVDM36ZM.js.br +0 -0
  125. package/dist/chunk-WVDM36ZM.js.gz +0 -0
@@ -21501,6 +21501,25 @@ function hasDrawingChild(node, requestedName) {
21501
21501
  }
21502
21502
  return false;
21503
21503
  }
21504
+ function hasEmptyDrawingChild(node, requestedName) {
21505
+ if (!node) {
21506
+ return false;
21507
+ }
21508
+ for (const [key2, value] of Object.entries(node)) {
21509
+ if (key2.startsWith(ATTRIBUTE_PREFIX) || key2 === "#text") {
21510
+ continue;
21511
+ }
21512
+ if (key2.split(":").at(-1) !== requestedName) {
21513
+ continue;
21514
+ }
21515
+ const child222 = Array.isArray(value) ? value[0] : value;
21516
+ if (child222 === "" || child222 === void 0) {
21517
+ return true;
21518
+ }
21519
+ return typeof child222 === "object" && !Array.isArray(child222) && Object.keys(child222).every((childKey3) => childKey3.startsWith(ATTRIBUTE_PREFIX));
21520
+ }
21521
+ return false;
21522
+ }
21504
21523
  function drawingChildren(node, requestedName) {
21505
21524
  if (!node) {
21506
21525
  return [];
@@ -25255,6 +25274,141 @@ function reconcileSmartArtTextParagraphs(paragraphs, desired) {
25255
25274
  insertAt(result, prefix, desired.slice(prefix, desired.length - suffix));
25256
25275
  return result.length > 0 ? result : [{ items: [] }];
25257
25276
  }
25277
+ var ATTR_PREFIX = "@_";
25278
+ var TEXT_KEY = "#text";
25279
+ function isXmlObject2(value) {
25280
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25281
+ }
25282
+ function coerceString(value) {
25283
+ if (typeof value === "string") {
25284
+ return value;
25285
+ }
25286
+ if (typeof value === "number" || typeof value === "boolean") {
25287
+ return String(value);
25288
+ }
25289
+ return void 0;
25290
+ }
25291
+ function xmlChild(node, key2) {
25292
+ if (!isXmlObject2(node)) {
25293
+ return void 0;
25294
+ }
25295
+ const value = node[key2];
25296
+ if (Array.isArray(value)) {
25297
+ const first = value[0];
25298
+ return isXmlObject2(first) ? first : void 0;
25299
+ }
25300
+ return isXmlObject2(value) ? value : void 0;
25301
+ }
25302
+ function xmlChildren(node, key2) {
25303
+ if (!isXmlObject2(node)) {
25304
+ return [];
25305
+ }
25306
+ const value = node[key2];
25307
+ if (value === void 0 || value === null) {
25308
+ return [];
25309
+ }
25310
+ if (Array.isArray(value)) {
25311
+ return value.filter(isXmlObject2);
25312
+ }
25313
+ return isXmlObject2(value) ? [value] : [];
25314
+ }
25315
+ function xmlHasChild(node, key2) {
25316
+ return isXmlObject2(node) && Object.hasOwn(node, key2);
25317
+ }
25318
+ function ensureXmlChild(parent, key2) {
25319
+ if (!isXmlObject2(parent) || !Object.hasOwn(parent, key2)) {
25320
+ return void 0;
25321
+ }
25322
+ const existing = parent[key2];
25323
+ if (isXmlObject2(existing)) {
25324
+ return existing;
25325
+ }
25326
+ if (Array.isArray(existing)) {
25327
+ const first = existing[0];
25328
+ return isXmlObject2(first) ? first : void 0;
25329
+ }
25330
+ if (existing === "" || existing === void 0 || existing === null) {
25331
+ const created = {};
25332
+ parent[key2] = created;
25333
+ return created;
25334
+ }
25335
+ return void 0;
25336
+ }
25337
+ function ensureXmlChildren(parent, key2) {
25338
+ if (!Object.hasOwn(parent, key2)) {
25339
+ return [];
25340
+ }
25341
+ const value = parent[key2];
25342
+ if (!Array.isArray(value)) {
25343
+ const single = ensureXmlChild(parent, key2);
25344
+ return single ? [single] : [];
25345
+ }
25346
+ const healed = [];
25347
+ for (const [index, entry2] of value.entries()) {
25348
+ if (isXmlObject2(entry2)) {
25349
+ healed.push(entry2);
25350
+ continue;
25351
+ }
25352
+ const created = {};
25353
+ value[index] = created;
25354
+ healed.push(created);
25355
+ }
25356
+ return healed;
25357
+ }
25358
+ function ensureXmlChildOrCreate(parent, key2, position2 = "last") {
25359
+ const existing = ensureXmlChild(parent, key2);
25360
+ if (existing) {
25361
+ return existing;
25362
+ }
25363
+ const created = {};
25364
+ if (position2 === "last") {
25365
+ parent[key2] = created;
25366
+ return created;
25367
+ }
25368
+ const carried = { ...parent };
25369
+ for (const existingKey of Object.keys(parent)) {
25370
+ delete parent[existingKey];
25371
+ }
25372
+ parent[key2] = created;
25373
+ Object.assign(parent, carried);
25374
+ return created;
25375
+ }
25376
+ function xmlAttr(node, name) {
25377
+ if (!isXmlObject2(node)) {
25378
+ return void 0;
25379
+ }
25380
+ return coerceString(node[ATTR_PREFIX + name]);
25381
+ }
25382
+ function xmlAttrNumber(node, name) {
25383
+ const raw = xmlAttr(node, name);
25384
+ if (raw === void 0) {
25385
+ return void 0;
25386
+ }
25387
+ const parsed = Number(raw);
25388
+ return Number.isFinite(parsed) ? parsed : void 0;
25389
+ }
25390
+ function xmlText(node) {
25391
+ if (typeof node === "string") {
25392
+ return node;
25393
+ }
25394
+ if (!isXmlObject2(node)) {
25395
+ return void 0;
25396
+ }
25397
+ return coerceString(node[TEXT_KEY]);
25398
+ }
25399
+ function xmlPath(node, ...keys) {
25400
+ let current = isXmlObject2(node) ? node : void 0;
25401
+ for (const key2 of keys) {
25402
+ if (!current) {
25403
+ return void 0;
25404
+ }
25405
+ current = xmlChild(current, key2);
25406
+ }
25407
+ return current;
25408
+ }
25409
+ function isXmlNode(value) {
25410
+ return isXmlObject2(value);
25411
+ }
25258
25412
  var EMU_PER_PX2 = 9525;
25259
25413
  function parseBoolAttr2(value) {
25260
25414
  if (value === void 0 || value === null) {
@@ -25417,7 +25571,7 @@ function parseBulletInfo(pPr, paragraphIndex = 0) {
25417
25571
  if (!pPr) {
25418
25572
  return null;
25419
25573
  }
25420
- if (pPr["a:buNone"]) {
25574
+ if (xmlHasChild(pPr, "a:buNone")) {
25421
25575
  return { none: true };
25422
25576
  }
25423
25577
  const buFont = pPr["a:buFont"];
@@ -34415,83 +34569,6 @@ function resolveLayoutDisplayName(input) {
34415
34569
  }
34416
34570
  return fallbackFromPath(input.path);
34417
34571
  }
34418
- var ATTR_PREFIX = "@_";
34419
- var TEXT_KEY = "#text";
34420
- function isXmlObject2(value) {
34421
- return typeof value === "object" && value !== null && !Array.isArray(value);
34422
- }
34423
- function coerceString(value) {
34424
- if (typeof value === "string") {
34425
- return value;
34426
- }
34427
- if (typeof value === "number" || typeof value === "boolean") {
34428
- return String(value);
34429
- }
34430
- return void 0;
34431
- }
34432
- function xmlChild(node, key2) {
34433
- if (!isXmlObject2(node)) {
34434
- return void 0;
34435
- }
34436
- const value = node[key2];
34437
- if (Array.isArray(value)) {
34438
- const first = value[0];
34439
- return isXmlObject2(first) ? first : void 0;
34440
- }
34441
- return isXmlObject2(value) ? value : void 0;
34442
- }
34443
- function xmlChildren(node, key2) {
34444
- if (!isXmlObject2(node)) {
34445
- return [];
34446
- }
34447
- const value = node[key2];
34448
- if (value === void 0 || value === null) {
34449
- return [];
34450
- }
34451
- if (Array.isArray(value)) {
34452
- return value.filter(isXmlObject2);
34453
- }
34454
- return isXmlObject2(value) ? [value] : [];
34455
- }
34456
- function xmlHasChild(node, key2) {
34457
- return isXmlObject2(node) && Object.hasOwn(node, key2);
34458
- }
34459
- function xmlAttr(node, name) {
34460
- if (!isXmlObject2(node)) {
34461
- return void 0;
34462
- }
34463
- return coerceString(node[ATTR_PREFIX + name]);
34464
- }
34465
- function xmlAttrNumber(node, name) {
34466
- const raw = xmlAttr(node, name);
34467
- if (raw === void 0) {
34468
- return void 0;
34469
- }
34470
- const parsed = Number(raw);
34471
- return Number.isFinite(parsed) ? parsed : void 0;
34472
- }
34473
- function xmlText(node) {
34474
- if (typeof node === "string") {
34475
- return node;
34476
- }
34477
- if (!isXmlObject2(node)) {
34478
- return void 0;
34479
- }
34480
- return coerceString(node[TEXT_KEY]);
34481
- }
34482
- function xmlPath(node, ...keys) {
34483
- let current = isXmlObject2(node) ? node : void 0;
34484
- for (const key2 of keys) {
34485
- if (!current) {
34486
- return void 0;
34487
- }
34488
- current = xmlChild(current, key2);
34489
- }
34490
- return current;
34491
- }
34492
- function isXmlNode(value) {
34493
- return isXmlObject2(value);
34494
- }
34495
34572
  var ORDER2 = [
34496
34573
  "varyColors",
34497
34574
  "ser",
@@ -36325,7 +36402,16 @@ var PptxShapeStyleExtractor = class {
36325
36402
  Object.assign(style, this.context.extractBlurStyle(shapeProps));
36326
36403
  Object.assign(style, this.context.extractEffectDagStyle(shapeProps));
36327
36404
  if (styleNode?.["a:effectRef"]) {
36405
+ const suppressInherited = hasEmptyDrawingChild(shapeProps, "effectLst");
36406
+ const authored = suppressInherited ? new Set(Object.keys(style)) : void 0;
36328
36407
  this.context.resolveThemeEffectRef(styleNode["a:effectRef"], style);
36408
+ if (authored) {
36409
+ for (const key2 of Object.keys(style)) {
36410
+ if (!authored.has(key2) && key2 !== "effectRefIdx" && key2 !== "effectRefColorXml") {
36411
+ delete style[key2];
36412
+ }
36413
+ }
36414
+ }
36329
36415
  }
36330
36416
  const fontRef = styleNode?.["a:fontRef"];
36331
36417
  if (fontRef) {
@@ -37295,6 +37381,150 @@ var PptxMediaDataParser = class {
37295
37381
  return mimeMap[extension];
37296
37382
  }
37297
37383
  };
37384
+ var LOCK_ATTRIBUTE = {
37385
+ noGrouping: "@_noGrp",
37386
+ noRotation: "@_noRot",
37387
+ noMove: "@_noMove",
37388
+ noResize: "@_noResize",
37389
+ noTextEdit: "@_noTextEdit",
37390
+ noSelect: "@_noSelect",
37391
+ noChangeAspect: "@_noChangeAspect",
37392
+ noEditPoints: "@_noEditPoints",
37393
+ noAdjustHandles: "@_noAdjustHandles",
37394
+ noChangeArrowheads: "@_noChangeArrowheads",
37395
+ noChangeShapeType: "@_noChangeShapeType",
37396
+ noDrilldown: "@_noDrilldown"
37397
+ };
37398
+ var AG_LOCKING = [
37399
+ "noGrouping",
37400
+ "noSelect",
37401
+ "noRotation",
37402
+ "noChangeAspect",
37403
+ "noMove",
37404
+ "noResize",
37405
+ "noEditPoints",
37406
+ "noAdjustHandles",
37407
+ "noChangeArrowheads",
37408
+ "noChangeShapeType"
37409
+ ];
37410
+ var SHAPE_LOCK_CONTAINERS = {
37411
+ "p:sp": {
37412
+ nvKey: "p:nvSpPr",
37413
+ cNvKey: "p:cNvSpPr",
37414
+ lockTag: "a:spLocks",
37415
+ permitted: [...AG_LOCKING, "noTextEdit"]
37416
+ },
37417
+ "p:pic": {
37418
+ nvKey: "p:nvPicPr",
37419
+ cNvKey: "p:cNvPicPr",
37420
+ lockTag: "a:picLocks",
37421
+ permitted: AG_LOCKING
37422
+ },
37423
+ "p:cxnSp": {
37424
+ nvKey: "p:nvCxnSpPr",
37425
+ cNvKey: "p:cNvCxnSpPr",
37426
+ lockTag: "a:cxnSpLocks",
37427
+ permitted: AG_LOCKING
37428
+ },
37429
+ "p:grpSp": {
37430
+ nvKey: "p:nvGrpSpPr",
37431
+ cNvKey: "p:cNvGrpSpPr",
37432
+ lockTag: "a:grpSpLocks",
37433
+ // CT_GroupLocking omits the shape-editing half of AG_Locking; `@noUngrp`
37434
+ // is its own addition and has no model property, so it survives as a
37435
+ // carried-over attribute rather than being written from the model.
37436
+ permitted: ["noGrouping", "noSelect", "noRotation", "noChangeAspect", "noMove", "noResize"]
37437
+ },
37438
+ "p:graphicFrame": {
37439
+ nvKey: "p:nvGraphicFramePr",
37440
+ cNvKey: "p:cNvGraphicFramePr",
37441
+ lockTag: "a:graphicFrameLocks",
37442
+ // `CT_GraphicalObjectFrameLocking` is NOT `AG_Locking`: it has no
37443
+ // `@noRot`, no `@noTextEdit` and none of the geometry-editing flags, and
37444
+ // it is the only type that declares `@noDrilldown`. Aliasing it onto the
37445
+ // shape list would emit five attributes the schema rejects.
37446
+ permitted: ["noGrouping", "noDrilldown", "noSelect", "noChangeAspect", "noMove", "noResize"]
37447
+ }
37448
+ };
37449
+ function resolveShapeLockContainer(shape, bucketKey) {
37450
+ if (shape) {
37451
+ for (const spec2 of Object.values(SHAPE_LOCK_CONTAINERS)) {
37452
+ if (asNode(shape[spec2.nvKey])) {
37453
+ return spec2;
37454
+ }
37455
+ }
37456
+ }
37457
+ return SHAPE_LOCK_CONTAINERS[bucketKey];
37458
+ }
37459
+ function asNode(value) {
37460
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
37461
+ }
37462
+ function parseShapeLocksFromNode(shape, spec2) {
37463
+ const nv = asNode(shape?.[spec2.nvKey]);
37464
+ const container = asNode(nv?.[spec2.cNvKey]);
37465
+ return parseShapeLockNode(asNode(container?.[spec2.lockTag]), spec2);
37466
+ }
37467
+ function resolveLockContainerNode(shape, spec2, create) {
37468
+ const nv = asNode(shape[spec2.nvKey]);
37469
+ if (!nv) {
37470
+ return void 0;
37471
+ }
37472
+ const existing = asNode(nv[spec2.cNvKey]);
37473
+ if (existing || !create) {
37474
+ return existing;
37475
+ }
37476
+ const created = {};
37477
+ const rebuilt = {};
37478
+ if ("p:cNvPr" in nv) {
37479
+ rebuilt["p:cNvPr"] = nv["p:cNvPr"];
37480
+ }
37481
+ rebuilt[spec2.cNvKey] = created;
37482
+ for (const [key2, value] of Object.entries(nv)) {
37483
+ if (key2 !== "p:cNvPr" && key2 !== spec2.cNvKey) {
37484
+ rebuilt[key2] = value;
37485
+ }
37486
+ }
37487
+ for (const key2 of Object.keys(nv)) {
37488
+ delete nv[key2];
37489
+ }
37490
+ Object.assign(nv, rebuilt);
37491
+ return created;
37492
+ }
37493
+ var MODELLED_ATTRIBUTES = new Set(Object.values(LOCK_ATTRIBUTE));
37494
+ function buildShapeLockNode(locks, spec2, existing) {
37495
+ const node = {};
37496
+ for (const [key2, value] of Object.entries(existing ?? {})) {
37497
+ if (!MODELLED_ATTRIBUTES.has(key2)) {
37498
+ node[key2] = value;
37499
+ }
37500
+ }
37501
+ if (locks) {
37502
+ for (const prop of spec2.permitted) {
37503
+ const value = locks[prop];
37504
+ if (value !== void 0) {
37505
+ node[LOCK_ATTRIBUTE[prop]] = value ? "1" : "0";
37506
+ }
37507
+ }
37508
+ }
37509
+ return Object.keys(node).length > 0 ? node : void 0;
37510
+ }
37511
+ function parseShapeLockNode(node, spec2) {
37512
+ if (!node) {
37513
+ return void 0;
37514
+ }
37515
+ const locks = {};
37516
+ let hasAny = false;
37517
+ for (const prop of spec2.permitted) {
37518
+ const raw = node[LOCK_ATTRIBUTE[prop]];
37519
+ if (raw === void 0) {
37520
+ continue;
37521
+ }
37522
+ const value = String(raw).trim().toLowerCase();
37523
+ locks[prop] = value === "1" || value === "true";
37524
+ hasAny = true;
37525
+ }
37526
+ return hasAny ? locks : void 0;
37527
+ }
37298
37528
  var KNOWN_GRAPHIC_FRAME_EXT_URIS = /* @__PURE__ */ new Set([
37299
37529
  // Office 365+ 3D model envelope; handled by parseModel3DElement.
37300
37530
  "{D42C27E5-1956-4C4D-AC15-FE9D03D7D63E}"
@@ -37540,7 +37770,15 @@ var PptxGraphicFrameParser = class {
37540
37770
  skewY: transform?.["@_skewY"] ? parseInt(String(transform["@_skewY"]), 10) / 6e4 : void 0,
37541
37771
  flipHorizontal,
37542
37772
  flipVertical,
37543
- rawXml: frame2
37773
+ rawXml: frame2,
37774
+ // `a:graphicFrameLocks` is the lock element for every family that
37775
+ // round-trips as a graphic frame (table, chart, SmartArt, OLE
37776
+ // object, graphic-frame media, loaded ink). Reading it is what
37777
+ // makes the writer safe: `serializeShapeLocks` rebuilds the node
37778
+ // from `element.locks` and treats an absent bag as "the user
37779
+ // cleared the locks", so a lock that is never parsed would be
37780
+ // erased on the first save.
37781
+ locks: parseShapeLocksFromNode(frame2, SHAPE_LOCK_CONTAINERS["p:graphicFrame"])
37544
37782
  };
37545
37783
  const extensionXml = collectGraphicFrameExtensions(graphicData);
37546
37784
  if (type === "table" && graphicData) {
@@ -44000,6 +44238,7 @@ function annotateOmmlSiblingOrder(xml, parsed) {
44000
44238
  }
44001
44239
  }
44002
44240
  }
44241
+ var MAX_XML_NESTING_DEPTH = 256;
44003
44242
  var PptxRuntimeDependencyFactory = class {
44004
44243
  createParser() {
44005
44244
  const parser = new fastXmlParser.XMLParser({
@@ -44065,7 +44304,26 @@ var PptxRuntimeDependencyFactory = class {
44065
44304
  // (`p:cNvPr/@name`), alt text (`@descr`) and layout names
44066
44305
  // (`p:cSld/@name`), which are read from the MODEL, so under-decoding is
44067
44306
  // user-visible even without a save.
44068
- attributeValueProcessor: (_attrName, attrValue) => decodeXmlEntities(attrValue)
44307
+ attributeValueProcessor: (_attrName, attrValue) => decodeXmlEntities(attrValue),
44308
+ // See MAX_XML_NESTING_DEPTH. The parser rejects when the open-tag stack
44309
+ // is STRICTLY greater than this, so it tolerates a part one element
44310
+ // deeper than the number given; the builder is compensated below so the
44311
+ // two ceilings land on the same part.
44312
+ maxNestedTags: MAX_XML_NESTING_DEPTH
44313
+ // XML comments stay DROPPED (`commentPropName` left at its `false`
44314
+ // default), deliberately. Scanning every part of all 45 committed decks
44315
+ // found ZERO comments, in slides, rels and `[Content_Types].xml` alike,
44316
+ // so nothing we have is losing anything. Turning it on would not be
44317
+ // free or even faithful: fast-xml-parser stores a comment as a
44318
+ // `#comment` KEY on its parent, which (a) injects a key the ~50 runtime
44319
+ // mixins that enumerate `Object.keys(spTree)` have never seen, and (b)
44320
+ // groups by tag like every other key, so `<!--A--><p:sp/><!--B--><p:sp/>`
44321
+ // rebuilds as `<!--A--><!--B--><p:sp/><p:sp/>` - the same interleaved-
44322
+ // sibling collapse that has already cost this repo four separate order
44323
+ // annotators (custGeom, OMML, SmartArt text, a:fld/a:br). An XML comment
44324
+ // carries no schema meaning, so the choice is between dropping one and
44325
+ // relocating it, and dropping is the honest half. Parts we do not parse
44326
+ // keep their comments regardless: they are copied through byte for byte.
44069
44327
  });
44070
44328
  const parse = parser.parse.bind(parser);
44071
44329
  parser.parse = ((xml, validationOption) => {
@@ -44130,7 +44388,21 @@ var PptxRuntimeDependencyFactory = class {
44130
44388
  // `\r`, and `encodeXmlAttributeValue` applies the attribute rules.
44131
44389
  processEntities: false,
44132
44390
  tagValueProcessor: (_tagName, tagValue) => encodeXmlTextValue(String(tagValue)),
44133
- attributeValueProcessor: (_attrName, attrValue) => encodeXmlAttributeValue(String(attrValue))
44391
+ attributeValueProcessor: (_attrName, attrValue) => encodeXmlAttributeValue(String(attrValue)),
44392
+ // See MAX_XML_NESTING_DEPTH. The doubling makes the PARSER the single
44393
+ // gatekeeper: whatever it let into the model, the builder can write back.
44394
+ // Matching the two numbers exactly does not achieve that, because the
44395
+ // builder measures a different thing. It walks the parsed OBJECT, where
44396
+ // repeated siblings sit under an extra array level and our own
44397
+ // order-annotation keys (`#pptx-order-N`, custGeom / OMML / SmartArt /
44398
+ // paragraph) add levels the source XML never had, so its depth runs 1-2
44399
+ // above the parser's for the same part and drifts with what the
44400
+ // annotators do. Deriving that offset would mean pinning two libraries'
44401
+ // internals plus our annotators; a margin no realistic accounting
44402
+ // difference can cross is both simpler and stabler, and the builder
44403
+ // still keeps a bound of its own for models built programmatically
44404
+ // rather than parsed. The round-trip test asserts the property directly.
44405
+ maxNestedTags: MAX_XML_NESTING_DEPTH * 2
44134
44406
  });
44135
44407
  const build = builder2.build.bind(builder2);
44136
44408
  builder2.build = ((value) => stripXmlOrderMarkers(build(value)));
@@ -54158,95 +54430,6 @@ var PptxHandlerRuntime2 = class _PptxHandlerRuntime extends PptxHandlerRuntime {
54158
54430
  }
54159
54431
  }
54160
54432
  };
54161
- var LOCK_ATTRIBUTE = {
54162
- noGrouping: "@_noGrp",
54163
- noRotation: "@_noRot",
54164
- noMove: "@_noMove",
54165
- noResize: "@_noResize",
54166
- noTextEdit: "@_noTextEdit",
54167
- noSelect: "@_noSelect",
54168
- noChangeAspect: "@_noChangeAspect",
54169
- noEditPoints: "@_noEditPoints",
54170
- noAdjustHandles: "@_noAdjustHandles",
54171
- noChangeArrowheads: "@_noChangeArrowheads",
54172
- noChangeShapeType: "@_noChangeShapeType"
54173
- };
54174
- var AG_LOCKING = [
54175
- "noGrouping",
54176
- "noSelect",
54177
- "noRotation",
54178
- "noChangeAspect",
54179
- "noMove",
54180
- "noResize",
54181
- "noEditPoints",
54182
- "noAdjustHandles",
54183
- "noChangeArrowheads",
54184
- "noChangeShapeType"
54185
- ];
54186
- var SHAPE_LOCK_CONTAINERS = {
54187
- "p:sp": {
54188
- nvKey: "p:nvSpPr",
54189
- cNvKey: "p:cNvSpPr",
54190
- lockTag: "a:spLocks",
54191
- permitted: [...AG_LOCKING, "noTextEdit"]
54192
- },
54193
- "p:pic": {
54194
- nvKey: "p:nvPicPr",
54195
- cNvKey: "p:cNvPicPr",
54196
- lockTag: "a:picLocks",
54197
- permitted: AG_LOCKING
54198
- },
54199
- "p:cxnSp": {
54200
- nvKey: "p:nvCxnSpPr",
54201
- cNvKey: "p:cNvCxnSpPr",
54202
- lockTag: "a:cxnSpLocks",
54203
- permitted: AG_LOCKING
54204
- },
54205
- "p:grpSp": {
54206
- nvKey: "p:nvGrpSpPr",
54207
- cNvKey: "p:cNvGrpSpPr",
54208
- lockTag: "a:grpSpLocks",
54209
- // CT_GroupLocking omits the shape-editing half of AG_Locking; `@noUngrp`
54210
- // is its own addition and has no model property, so it survives as a
54211
- // carried-over attribute rather than being written from the model.
54212
- permitted: ["noGrouping", "noSelect", "noRotation", "noChangeAspect", "noMove", "noResize"]
54213
- }
54214
- };
54215
- var MODELLED_ATTRIBUTES = new Set(Object.values(LOCK_ATTRIBUTE));
54216
- function buildShapeLockNode(locks, spec2, existing) {
54217
- const node = {};
54218
- for (const [key2, value] of Object.entries(existing ?? {})) {
54219
- if (!MODELLED_ATTRIBUTES.has(key2)) {
54220
- node[key2] = value;
54221
- }
54222
- }
54223
- if (locks) {
54224
- for (const prop of spec2.permitted) {
54225
- const value = locks[prop];
54226
- if (value !== void 0) {
54227
- node[LOCK_ATTRIBUTE[prop]] = value ? "1" : "0";
54228
- }
54229
- }
54230
- }
54231
- return Object.keys(node).length > 0 ? node : void 0;
54232
- }
54233
- function parseShapeLockNode(node, spec2) {
54234
- if (!node) {
54235
- return void 0;
54236
- }
54237
- const locks = {};
54238
- let hasAny = false;
54239
- for (const prop of spec2.permitted) {
54240
- const raw = node[LOCK_ATTRIBUTE[prop]];
54241
- if (raw === void 0) {
54242
- continue;
54243
- }
54244
- const value = String(raw).trim().toLowerCase();
54245
- locks[prop] = value === "1" || value === "true";
54246
- hasAny = true;
54247
- }
54248
- return hasAny ? locks : void 0;
54249
- }
54250
54433
  var PptxHandlerRuntime3 = class extends PptxHandlerRuntime2 {
54251
54434
  /**
54252
54435
  * Write or remove a single `a:hlinkClick` / `a:hlinkHover` node on
@@ -54307,20 +54490,26 @@ var PptxHandlerRuntime3 = class extends PptxHandlerRuntime2 {
54307
54490
  }
54308
54491
  return "p:sp";
54309
54492
  }
54493
+ /**
54494
+ * The `p:cNvPr` an element's hyperlinks hang on.
54495
+ *
54496
+ * Resolved from the MARKUP, not from `el.type`, for exactly the reason
54497
+ * {@link resolveShapeLockContainer} documents: the two disagree in real
54498
+ * files. `media` buckets as `p:graphicFrame`, but PowerPoint writes a video
54499
+ * as a `p:pic`, so looking for `p:nvGraphicFramePr` found nothing and the
54500
+ * writer returned early - a hyperlink or an action on a video or an audio
54501
+ * clip was accepted by the editor and then never reached the saved file.
54502
+ * Loaded ink is the mirror image: it buckets as `p:sp` and arrives as a
54503
+ * graphic frame or a `p:contentPart`. This is the unfixed sibling of the
54504
+ * lock-container bug, and it shares the fix rather than restating it.
54505
+ */
54310
54506
  getCnvPrNode(shape, key2) {
54311
- if (key2 === "p:pic") {
54312
- return xmlPath(shape, "p:nvPicPr", "p:cNvPr");
54507
+ const contentPart = xmlPath(shape, "p:nvContentPartPr", "p:cNvPr");
54508
+ if (contentPart) {
54509
+ return contentPart;
54313
54510
  }
54314
- if (key2 === "p:cxnSp") {
54315
- return xmlPath(shape, "p:nvCxnSpPr", "p:cNvPr");
54316
- }
54317
- if (key2 === "p:graphicFrame") {
54318
- return xmlPath(shape, "p:nvGraphicFramePr", "p:cNvPr");
54319
- }
54320
- if (key2 === "p:grpSp") {
54321
- return xmlPath(shape, "p:nvGrpSpPr", "p:cNvPr");
54322
- }
54323
- return xmlPath(shape, "p:nvSpPr", "p:cNvPr");
54511
+ const spec2 = resolveShapeLockContainer(shape, key2);
54512
+ return xmlPath(shape, spec2?.nvKey ?? "p:nvSpPr", "p:cNvPr");
54324
54513
  }
54325
54514
  /**
54326
54515
  * Serialize shape-level actions back onto the `p:cNvPr` node, updating
@@ -54342,27 +54531,35 @@ var PptxHandlerRuntime3 = class extends PptxHandlerRuntime2 {
54342
54531
  * Serialize shape lock attributes from an element back into the XML.
54343
54532
  *
54344
54533
  * Writes `a:spLocks` (shapes), `a:picLocks` (pictures), `a:cxnSpLocks`
54345
- * (connectors) or `a:grpSpLocks` (groups) onto that family's own
54346
- * `p:cNvXxxPr` container, restricted to the attributes that container's
54347
- * type declares. See {@link module:shape-lock-containers} for why the four
54348
- * are not interchangeable, and for the one family
54349
- * (`a:graphicFrameLocks`) deliberately left out.
54534
+ * (connectors), `a:grpSpLocks` (groups) or `a:graphicFrameLocks` (tables,
54535
+ * charts, SmartArt, OLE objects, media) onto that family's own `p:cNvXxxPr`
54536
+ * container, restricted to the attributes that container's type declares.
54537
+ * See {@link module:shape-lock-containers} for why the five are not
54538
+ * interchangeable.
54539
+ *
54540
+ * The container is resolved from the MARKUP, not from `el.type`: PowerPoint
54541
+ * writes media as a `p:pic` even though the type buckets as
54542
+ * `p:graphicFrame`, and loaded ink as a graphic frame even though it buckets
54543
+ * as `p:sp`. Trusting the type there would rebuild the wrong lock element
54544
+ * and delete the authored one.
54350
54545
  */
54351
54546
  serializeShapeLocks(shape, el) {
54352
- const spec2 = SHAPE_LOCK_CONTAINERS[this.getTreeBucketKeyForElementType(el.type)];
54547
+ const spec2 = resolveShapeLockContainer(shape, this.getTreeBucketKeyForElementType(el.type));
54353
54548
  if (!spec2) {
54354
54549
  return;
54355
54550
  }
54356
- const container = xmlPath(shape, spec2.nvKey, spec2.cNvKey);
54357
- if (!container) {
54551
+ const locks = "locks" in el ? el.locks : void 0;
54552
+ const existing = resolveLockContainerNode(shape, spec2, false);
54553
+ const next = buildShapeLockNode(locks, spec2, existing?.[spec2.lockTag]);
54554
+ if (!next) {
54555
+ if (existing) {
54556
+ delete existing[spec2.lockTag];
54557
+ }
54358
54558
  return;
54359
54559
  }
54360
- const locks = "locks" in el ? el.locks : void 0;
54361
- const next = buildShapeLockNode(locks, spec2, container[spec2.lockTag]);
54362
- if (next) {
54560
+ const container = existing ?? resolveLockContainerNode(shape, spec2, true);
54561
+ if (container) {
54363
54562
  container[spec2.lockTag] = next;
54364
- } else {
54365
- delete container[spec2.lockTag];
54366
54563
  }
54367
54564
  }
54368
54565
  };
@@ -57096,6 +57293,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57096
57293
  * `rebuildTableXmlFromData` and fills in `a:tblGrid` / `a:tr` children.
57097
57294
  */
57098
57295
  createTableGraphicFrameXml(el) {
57296
+ el.locks = { noGrouping: true, ...el.locks };
57099
57297
  const EMU = _PptxHandlerRuntime4.EMU_PER_PX;
57100
57298
  const offX = String(Math.round(el.x * EMU));
57101
57299
  const offY = String(Math.round(el.y * EMU));
@@ -57197,6 +57395,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57197
57395
  * specified relationship ID.
57198
57396
  */
57199
57397
  createOleGraphicFrameXml(el, embedRelationshipId) {
57398
+ el.locks = { noChangeAspect: true, ...el.locks };
57200
57399
  const EMU = _PptxHandlerRuntime4.EMU_PER_PX;
57201
57400
  const offX = String(Math.round(el.x * EMU));
57202
57401
  const offY = String(Math.round(el.y * EMU));
@@ -57490,6 +57689,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime4 extends PptxHandlerRuntime
57490
57689
  if (!xml) {
57491
57690
  return null;
57492
57691
  }
57692
+ this.serializeShapeLocks(xml, child222);
57493
57693
  applyGroupChildTransform(xml, child222, _PptxHandlerRuntime4.EMU_PER_PX);
57494
57694
  return { tag: "p:grpSp", xml };
57495
57695
  }
@@ -59421,7 +59621,7 @@ function buildChartPoints(values) {
59421
59621
  var DEFAULT_ROW_HEIGHT_PX = 40;
59422
59622
  var DEFAULT_ROW_HEIGHT_EMU = DEFAULT_ROW_HEIGHT_PX * EMU_PER_PX;
59423
59623
  function ensureArray16(value) {
59424
- if (!value) {
59624
+ if (value === void 0 || value === null) {
59425
59625
  return [];
59426
59626
  }
59427
59627
  return Array.isArray(value) ? value : [value];
@@ -59621,37 +59821,38 @@ function updateCellTextInRawXml(element, rowIndex, colIndex, text2) {
59621
59821
  if (colIndex < 0 || colIndex >= cells.length) {
59622
59822
  return void 0;
59623
59823
  }
59624
- const cell = cells[colIndex];
59625
- const existingTxBody = cell["a:txBody"];
59824
+ cells[colIndex]["a:txBody"] = rebuildCellTextBody(
59825
+ cells[colIndex]["a:txBody"],
59826
+ text2
59827
+ );
59828
+ return newRawXml;
59829
+ }
59830
+ function rebuildCellTextBody(existingTxBody, text2) {
59626
59831
  const existingParagraphs = ensureArray16(
59627
59832
  existingTxBody?.["a:p"]
59628
59833
  );
59629
59834
  const firstParagraph = existingParagraphs.length > 0 ? existingParagraphs[0] : void 0;
59630
59835
  const existingRuns = firstParagraph ? ensureArray16(firstParagraph["a:r"]) : [];
59631
59836
  const firstRunProps = existingRuns.length > 0 ? existingRuns[0]["a:rPr"] : void 0;
59632
- const newRun = { "a:t": text2 };
59633
- if (firstRunProps) {
59837
+ const newRun = {};
59838
+ if (firstRunProps !== void 0) {
59634
59839
  newRun["a:rPr"] = firstRunProps;
59635
59840
  }
59636
- const newParagraph = {
59637
- "a:r": newRun
59638
- };
59639
- if (firstParagraph?.["a:pPr"]) {
59841
+ newRun["a:t"] = text2;
59842
+ const newParagraph = {};
59843
+ if (firstParagraph?.["a:pPr"] !== void 0) {
59640
59844
  newParagraph["a:pPr"] = firstParagraph["a:pPr"];
59641
59845
  }
59642
- const bodyPr = existingTxBody?.["a:bodyPr"];
59643
- const lstStyle = existingTxBody?.["a:lstStyle"];
59644
- const newTxBody = {
59645
- "a:p": newParagraph
59646
- };
59647
- if (bodyPr !== void 0) {
59648
- newTxBody["a:bodyPr"] = bodyPr;
59846
+ newParagraph["a:r"] = newRun;
59847
+ const newTxBody = {};
59848
+ if (existingTxBody?.["a:bodyPr"] !== void 0) {
59849
+ newTxBody["a:bodyPr"] = existingTxBody["a:bodyPr"];
59649
59850
  }
59650
- if (lstStyle !== void 0) {
59651
- newTxBody["a:lstStyle"] = lstStyle;
59851
+ if (existingTxBody?.["a:lstStyle"] !== void 0) {
59852
+ newTxBody["a:lstStyle"] = existingTxBody["a:lstStyle"];
59652
59853
  }
59653
- cell["a:txBody"] = newTxBody;
59654
- return newRawXml;
59854
+ newTxBody["a:p"] = newParagraph;
59855
+ return newTxBody;
59655
59856
  }
59656
59857
  function updateCellTextStyleInRawXml(element, rowIndex, colIndex, styleUpdates) {
59657
59858
  if (!element.rawXml) {
@@ -59675,11 +59876,15 @@ function updateCellTextStyleInRawXml(element, rowIndex, colIndex, styleUpdates)
59675
59876
  if (!txBody) {
59676
59877
  return void 0;
59677
59878
  }
59678
- const paragraphs = ensureArray16(txBody["a:p"]);
59879
+ const paragraphs = ensureXmlChildren(txBody, "a:p");
59679
59880
  for (const paragraph of paragraphs) {
59881
+ if ("align" in styleUpdates) {
59882
+ const pPr = ensureXmlChildOrCreate(paragraph, "a:pPr", "first");
59883
+ pPr["@_algn"] = styleUpdates.align === "left" ? "l" : styleUpdates.align === "center" ? "ctr" : styleUpdates.align === "right" ? "r" : styleUpdates.align === "justify" ? "just" : String(styleUpdates.align);
59884
+ }
59680
59885
  const runs = ensureArray16(paragraph["a:r"]);
59681
59886
  for (const run of runs) {
59682
- const rPr = run["a:rPr"] ?? {};
59887
+ const rPr = ensureXmlChildOrCreate(run, "a:rPr", "first");
59683
59888
  if ("bold" in styleUpdates) {
59684
59889
  if (styleUpdates.bold) {
59685
59890
  rPr["@_b"] = "1";
@@ -59712,15 +59917,9 @@ function updateCellTextStyleInRawXml(element, rowIndex, colIndex, styleUpdates)
59712
59917
  const hex4 = styleUpdates.color.replace("#", "");
59713
59918
  rPr["a:solidFill"] = { "a:srgbClr": { "@_val": hex4 } };
59714
59919
  }
59715
- if ("align" in styleUpdates) {
59716
- const pPr = paragraph["a:pPr"] ?? {};
59717
- pPr["@_algn"] = styleUpdates.align === "left" ? "l" : styleUpdates.align === "center" ? "ctr" : styleUpdates.align === "right" ? "r" : styleUpdates.align === "justify" ? "just" : String(styleUpdates.align);
59718
- paragraph["a:pPr"] = pPr;
59719
- }
59720
- run["a:rPr"] = rPr;
59721
59920
  }
59722
- if (runs.length === 0 && paragraph["a:endParaRPr"]) {
59723
- const endRPr = paragraph["a:endParaRPr"];
59921
+ const endRPr = runs.length === 0 ? ensureXmlChild(paragraph, "a:endParaRPr") : void 0;
59922
+ if (endRPr) {
59724
59923
  if ("bold" in styleUpdates) {
59725
59924
  if (styleUpdates.bold) {
59726
59925
  endRPr["@_b"] = "1";
@@ -59794,35 +59993,10 @@ function updateMergeAttrsInRawXml(element, tableData) {
59794
59993
  delete xmlCell["@_vMerge"];
59795
59994
  }
59796
59995
  if (cell.text !== void 0) {
59797
- const existingTxBody = xmlCell["a:txBody"];
59798
- const existingParagraphs = existingTxBody ? ensureArray16(existingTxBody["a:p"]) : [];
59799
- const firstParagraph = existingParagraphs.length > 0 ? existingParagraphs[0] : void 0;
59800
- const existingRuns = firstParagraph ? ensureArray16(firstParagraph["a:r"]) : [];
59801
- const firstRunProps = existingRuns.length > 0 ? existingRuns[0]["a:rPr"] : void 0;
59802
- const newRun = {
59803
- "a:t": cell.text
59804
- };
59805
- if (firstRunProps) {
59806
- newRun["a:rPr"] = firstRunProps;
59807
- }
59808
- const newParagraph = {
59809
- "a:r": newRun
59810
- };
59811
- if (firstParagraph?.["a:pPr"]) {
59812
- newParagraph["a:pPr"] = firstParagraph["a:pPr"];
59813
- }
59814
- const bodyPr = existingTxBody?.["a:bodyPr"];
59815
- const lstStyle = existingTxBody?.["a:lstStyle"];
59816
- const newTxBody = {
59817
- "a:p": newParagraph
59818
- };
59819
- if (bodyPr !== void 0) {
59820
- newTxBody["a:bodyPr"] = bodyPr;
59821
- }
59822
- if (lstStyle !== void 0) {
59823
- newTxBody["a:lstStyle"] = lstStyle;
59824
- }
59825
- xmlCell["a:txBody"] = newTxBody;
59996
+ xmlCell["a:txBody"] = rebuildCellTextBody(
59997
+ xmlCell["a:txBody"],
59998
+ cell.text
59999
+ );
59826
60000
  }
59827
60001
  }
59828
60002
  }
@@ -64168,10 +64342,13 @@ var PptxHandlerRuntime31 = class extends PptxHandlerRuntime30 {
64168
64342
  }
64169
64343
  /** Apply geometry preset or custom paths to spPr. */
64170
64344
  applyGeometryUpdate(shape, el) {
64171
- if (!hasShapeProperties(el) || !shape["p:spPr"]) {
64345
+ if (!hasShapeProperties(el)) {
64346
+ return;
64347
+ }
64348
+ const spPr = ensureXmlChild(shape, "p:spPr");
64349
+ if (!spPr) {
64172
64350
  return;
64173
64351
  }
64174
- const spPr = shape["p:spPr"];
64175
64352
  const elWithPaths = el;
64176
64353
  if (elWithPaths.customGeometryPaths && elWithPaths.customGeometryPaths.length > 0) {
64177
64354
  delete spPr["a:prstGeom"];
@@ -64804,7 +64981,7 @@ var PptxHandlerRuntime35 = class _PptxHandlerRuntime12 extends PptxHandlerRuntim
64804
64981
  }
64805
64982
  applyZoomTransform(shapeProperties, el) {
64806
64983
  const emu2 = _PptxHandlerRuntime12.EMU_PER_PX;
64807
- const transform = shapeProperties["a:xfrm"] ??= {};
64984
+ const transform = ensureXmlChildOrCreate(shapeProperties, "a:xfrm");
64808
64985
  transform["a:off"] = {
64809
64986
  "@_x": String(Math.round(el.x * emu2)),
64810
64987
  "@_y": String(Math.round(el.y * emu2))
@@ -64831,8 +65008,8 @@ var PptxHandlerRuntime35 = class _PptxHandlerRuntime12 extends PptxHandlerRuntim
64831
65008
  if (!relationshipId2) {
64832
65009
  return;
64833
65010
  }
64834
- const blipFill = zoomProperties["p166:blipFill"] ??= {};
64835
- const blip = blipFill["a:blip"] ??= {};
65011
+ const blipFill = ensureXmlChildOrCreate(zoomProperties, "p166:blipFill");
65012
+ const blip = ensureXmlChildOrCreate(blipFill, "a:blip");
64836
65013
  blip["@_r:embed"] = relationshipId2;
64837
65014
  }
64838
65015
  updateZoomFallback(shape, el, relationshipId2) {
@@ -64842,11 +65019,11 @@ var PptxHandlerRuntime35 = class _PptxHandlerRuntime12 extends PptxHandlerRuntim
64842
65019
  if (!picture) {
64843
65020
  return;
64844
65021
  }
64845
- const shapeProperties = picture["p:spPr"] ??= {};
65022
+ const shapeProperties = ensureXmlChildOrCreate(picture, "p:spPr");
64846
65023
  this.applyZoomTransform(shapeProperties, el);
64847
65024
  if (relationshipId2) {
64848
- const blipFill = picture["p:blipFill"] ??= {};
64849
- const blip = blipFill["a:blip"] ??= {};
65025
+ const blipFill = ensureXmlChildOrCreate(picture, "p:blipFill");
65026
+ const blip = ensureXmlChildOrCreate(blipFill, "a:blip");
64850
65027
  blip["@_r:embed"] = relationshipId2;
64851
65028
  }
64852
65029
  }
@@ -64941,7 +65118,7 @@ var PptxHandlerRuntime37 = class _PptxHandlerRuntime13 extends PptxHandlerRuntim
64941
65118
  continue;
64942
65119
  }
64943
65120
  const object = target.rawXml ?? existing[index] ?? {};
64944
- const properties = object["psuz:zmPr"] ??= {};
65121
+ const properties = ensureXmlChildOrCreate(object, "psuz:zmPr");
64945
65122
  const tile = this.summaryTileElement(el, target, index);
64946
65123
  const relationshipShape = {
64947
65124
  "psezm:sectionZmObj": { "psezm:zmPr": properties }
@@ -64956,8 +65133,10 @@ var PptxHandlerRuntime37 = class _PptxHandlerRuntime13 extends PptxHandlerRuntim
64956
65133
  this.applyOptionalAttribute(object, "@_scaleFactorY", target.scaleFactorY);
64957
65134
  properties["@_id"] ??= `{${generateFontGuid()}}`;
64958
65135
  properties["@_imageType"] ??= "preview";
64959
- properties["p166:blipFill"] ??= this.buildZoomBlipFill(relationshipId2);
64960
- const shapeProperties = properties["p166:spPr"] ??= this.buildZoomShapeProperties(tile);
65136
+ if (!xmlHasChild(properties, "p166:blipFill")) {
65137
+ properties["p166:blipFill"] = this.buildZoomBlipFill(relationshipId2);
65138
+ }
65139
+ const shapeProperties = xmlHasChild(properties, "p166:spPr") ? ensureXmlChildOrCreate(properties, "p166:spPr") : properties["p166:spPr"] = this.buildZoomShapeProperties(tile);
64961
65140
  this.applyZoomTransform(shapeProperties, tile);
64962
65141
  this.applyZoomBlipRelationship(properties, relationshipId2);
64963
65142
  target.sectionId = sectionId;
@@ -65023,10 +65202,10 @@ var PptxHandlerRuntime37 = class _PptxHandlerRuntime13 extends PptxHandlerRuntim
65023
65202
  group2["p:pic"] = targets.map((target, index) => {
65024
65203
  const tile = this.summaryTileElement(el, target, index);
65025
65204
  const picture = existing[index] ?? this.buildZoomFallbackPicture(tile, relationships[index]);
65026
- this.applyZoomTransform(picture["p:spPr"] ??= {}, tile);
65205
+ this.applyZoomTransform(ensureXmlChildOrCreate(picture, "p:spPr"), tile);
65027
65206
  if (relationships[index]) {
65028
- const fill = picture["p:blipFill"] ??= {};
65029
- const blip = fill["a:blip"] ??= {};
65207
+ const fill = ensureXmlChildOrCreate(picture, "p:blipFill");
65208
+ const blip = ensureXmlChildOrCreate(fill, "a:blip");
65030
65209
  blip["@_r:embed"] = relationships[index];
65031
65210
  }
65032
65211
  return picture;
@@ -65121,12 +65300,11 @@ var PptxHandlerRuntime38 = class _PptxHandlerRuntime14 extends PptxHandlerRuntim
65121
65300
  el.rawXml = shape;
65122
65301
  return shape;
65123
65302
  }
65124
- shape["p16:model3Drel"] ??= {};
65125
- shape["p16:model3Drel"]["@_r:id"] = modelRelationshipId;
65126
- const spPr = shape["p16:spPr"] ??= {};
65303
+ ensureXmlChildOrCreate(shape, "p16:model3Drel")["@_r:id"] = modelRelationshipId;
65304
+ const spPr = ensureXmlChildOrCreate(shape, "p16:spPr");
65127
65305
  this.applyModel3DTransform(spPr, el);
65128
65306
  if (poster.relationshipId) {
65129
- const posterNode = shape["p16:posterImage"] ??= {};
65307
+ const posterNode = ensureXmlChildOrCreate(shape, "p16:posterImage");
65130
65308
  posterNode["@_r:embed"] = poster.relationshipId;
65131
65309
  this.updateModel3DFallback(shape, el, poster.relationshipId);
65132
65310
  }
@@ -65191,7 +65369,7 @@ var PptxHandlerRuntime38 = class _PptxHandlerRuntime14 extends PptxHandlerRuntim
65191
65369
  return result;
65192
65370
  }
65193
65371
  applyModel3DTransform(spPr, el) {
65194
- const transform = spPr["a:xfrm"] ??= {};
65372
+ const transform = ensureXmlChildOrCreate(spPr, "a:xfrm");
65195
65373
  const emu2 = _PptxHandlerRuntime14.EMU_PER_PX;
65196
65374
  transform["a:off"] = {
65197
65375
  "@_x": String(Math.round(el.x * emu2)),
@@ -65247,9 +65425,9 @@ var PptxHandlerRuntime38 = class _PptxHandlerRuntime14 extends PptxHandlerRuntim
65247
65425
  if (!picture) {
65248
65426
  return;
65249
65427
  }
65250
- this.applyModel3DTransform(picture["p:spPr"] ??= {}, el);
65251
- const fill = picture["p:blipFill"] ??= {};
65252
- const blip = fill["a:blip"] ??= {};
65428
+ this.applyModel3DTransform(ensureXmlChildOrCreate(picture, "p:spPr"), el);
65429
+ const fill = ensureXmlChildOrCreate(picture, "p:blipFill");
65430
+ const blip = ensureXmlChildOrCreate(fill, "a:blip");
65253
65431
  blip["@_r:embed"] = posterRelationshipId;
65254
65432
  }
65255
65433
  };
@@ -65369,7 +65547,7 @@ var PptxHandlerRuntime39 = class _PptxHandlerRuntime15 extends PptxHandlerRuntim
65369
65547
  }
65370
65548
  applyContentPartTransform(shape, el) {
65371
65549
  const emu2 = _PptxHandlerRuntime15.EMU_PER_PX;
65372
- const transform = shape["p:xfrm"] ??= {};
65550
+ const transform = ensureXmlChildOrCreate(shape, "p:xfrm");
65373
65551
  transform["a:off"] = {
65374
65552
  "@_x": String(Math.round(el.x * emu2)),
65375
65553
  "@_y": String(Math.round(el.y * emu2))
@@ -65870,12 +66048,14 @@ var PptxHandlerRuntime40 = class _PptxHandlerRuntime16 extends PptxHandlerRuntim
65870
66048
  this.applyImageProperties(shape, el);
65871
66049
  this.finalizePictureBlipFillOrder(shape);
65872
66050
  this.applyGeometryUpdate(shape, el);
65873
- if (hasShapeProperties(el) && el.shapeStyle && shape["p:spPr"]) {
65874
- const spPr = shape["p:spPr"];
65875
- this.applyFillAndStroke(spPr, el.shapeStyle, ctx.inheritedGroupFill);
65876
- this.applyEffectsAndThreeD(spPr, el.shapeStyle);
65877
- this.finalizeSpPrSchemaOrder(shape);
65878
- this.applyShapeStyleRefs(shape, el.shapeStyle);
66051
+ if (hasShapeProperties(el) && el.shapeStyle) {
66052
+ const spPr = ensureXmlChild(shape, "p:spPr");
66053
+ if (spPr) {
66054
+ this.applyFillAndStroke(spPr, el.shapeStyle, ctx.inheritedGroupFill);
66055
+ this.applyEffectsAndThreeD(spPr, el.shapeStyle);
66056
+ this.finalizeSpPrSchemaOrder(shape);
66057
+ this.applyShapeStyleRefs(shape, el.shapeStyle);
66058
+ }
65879
66059
  }
65880
66060
  if (hasTextProperties(el)) {
65881
66061
  this.applyTextBodyContent(
@@ -71631,6 +71811,12 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime28 extends PptxHandlerRuntim
71631
71811
  isLinked: mediaReference.isLinked,
71632
71812
  posterFramePath,
71633
71813
  posterFrameData,
71814
+ // Real PowerPoint media is `p:pic`-shaped even though the
71815
+ // `media` type buckets as `p:graphicFrame`, so its locks live
71816
+ // in `a:picLocks`. The writer resolves the same container from
71817
+ // the markup; leaving this unparsed would hand it an empty bag
71818
+ // and delete the authored lock on the first save.
71819
+ locks: parseShapeLocksFromNode(pic, SHAPE_LOCK_CONTAINERS["p:pic"]),
71634
71820
  rawXml: pic
71635
71821
  };
71636
71822
  }
@@ -73768,11 +73954,11 @@ var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
73768
73954
  if (!masterXmlStr) {
73769
73955
  return [];
73770
73956
  }
73771
- const masterXmlObj = this.parser.parse(masterXmlStr);
73957
+ const masterXmlObj = this.masterXmlMap.get(masterPath) ?? this.parser.parse(masterXmlStr);
73772
73958
  this.masterXmlMap.set(masterPath, masterXmlObj);
73773
73959
  const masterRelsPath = partRelsPath(masterPath);
73774
73960
  await this.loadSlideRelationships(masterPath, masterRelsPath);
73775
- const spTree = masterXmlObj["p:sldMaster"]?.["p:cSld"]?.["p:spTree"];
73961
+ const spTree = xmlPath(masterXmlObj, "p:sldMaster", "p:cSld", "p:spTree");
73776
73962
  if (!spTree) {
73777
73963
  this.masterCache.set(masterPath, []);
73778
73964
  return [];
@@ -77750,7 +77936,7 @@ var PptxHandlerRuntime91 = class extends PptxHandlerRuntime90 {
77750
77936
  ).trim();
77751
77937
  const seriesShapeProperties = this.xmlLookupService.getChildByLocalName(seriesNode, "spPr");
77752
77938
  const readsLineColor = seriesChartType === "line" || seriesChartType === "line3D" || seriesChartType === "scatter" || seriesChartType === "radar" || seriesChartType === "stock";
77753
- const seriesColor23 = this.parseColor(
77939
+ const seriesColor22 = this.parseColor(
77754
77940
  this.xmlLookupService.getChildByLocalName(seriesShapeProperties, "solidFill")
77755
77941
  ) ?? (readsLineColor ? this.parseColor(
77756
77942
  this.xmlLookupService.getChildByLocalName(
@@ -77804,7 +77990,7 @@ var PptxHandlerRuntime91 = class extends PptxHandlerRuntime90 {
77804
77990
  ...dataLabelOptions && Object.keys(dataLabelOptions).length > 0 ? { dataLabelOptions } : {},
77805
77991
  ...lineNoFill ? { lineNoFill } : {},
77806
77992
  ...seriesNumberFormat ? { numberFormat: seriesNumberFormat } : {},
77807
- color: seriesColor23,
77993
+ color: seriesColor22,
77808
77994
  ...trendlines.length > 0 ? { trendlines } : {},
77809
77995
  ...errBars.length > 0 ? { errBars } : {},
77810
77996
  ...dataPoints.length > 0 ? { dataPoints } : {},
@@ -92890,357 +93076,10 @@ function strokeOnlyPresetPathData(element) {
92890
93076
  const stroked = paths.filter((path) => path.stroke !== false).map((path) => path.d);
92891
93077
  return stroked.length > 0 ? stroked.join(" ") : void 0;
92892
93078
  }
92893
- function round4(value) {
92894
- return Math.round(value * 1e4) / 1e4;
92895
- }
92896
- function svgGradientId(elementId, suffix = "grad") {
92897
- const seed = String(elementId).replace(/[^a-zA-Z0-9_-]/gu, "_");
92898
- return `pptx-${suffix}-${seed}`;
92899
- }
92900
- function toSvgStops(stops) {
92901
- return sanitizeGradientStops(stops).map((stop) => ({
92902
- offset: round4(stop.position / 100),
92903
- color: stop.color,
92904
- ...typeof stop.opacity === "number" ? { opacity: round4(stop.opacity) } : {}
92905
- }));
92906
- }
92907
- function linearEndpoints(angleDegrees) {
92908
- const radians = angleDegrees * Math.PI / 180;
92909
- const dx = Math.cos(radians);
92910
- const dy = Math.sin(radians);
92911
- const span = (Math.abs(dx) + Math.abs(dy)) / 2;
92912
- return {
92913
- x1: round4(0.5 - dx * span),
92914
- y1: round4(0.5 - dy * span),
92915
- x2: round4(0.5 + dx * span),
92916
- y2: round4(0.5 + dy * span)
92917
- };
92918
- }
92919
- function buildFromSource(source, id) {
92920
- const { stops } = source;
92921
- if (stops.length === 0) {
92922
- return void 0;
92923
- }
92924
- if ((source.type || "linear") === "radial") {
92925
- const { cx, cy } = computeGradientCenter(source.fillToRect, source.focalPoint);
92926
- const fx = cx / 100;
92927
- const fy = cy / 100;
92928
- const r = Math.hypot(Math.max(fx, 1 - fx), Math.max(fy, 1 - fy));
92929
- return { kind: "radial", id, cx: round4(fx), cy: round4(fy), r: round4(r), stops };
92930
- }
92931
- const angle = typeof source.angle === "number" && Number.isFinite(source.angle) ? source.angle : 90;
92932
- return { kind: "linear", id, ...linearEndpoints(angle), stops };
92933
- }
92934
- function buildSvgGradientDef(style, elementId) {
92935
- if (!style || style.fillMode !== "gradient") {
92936
- return void 0;
92937
- }
92938
- return buildFromSource(
92939
- {
92940
- stops: toSvgStops(style.fillGradientStops),
92941
- type: style.fillGradientType,
92942
- angle: style.fillGradientAngle,
92943
- fillToRect: style.fillGradientFillToRect,
92944
- focalPoint: style.fillGradientFocalPoint
92945
- },
92946
- svgGradientId(elementId)
92947
- );
92948
- }
92949
- function buildSvgStrokeGradientDef(style, elementId) {
92950
- if (!style || style.strokeFillMode !== "gradient") {
92951
- return void 0;
92952
- }
92953
- return buildFromSource(
92954
- {
92955
- stops: toSvgStops(style.strokeGradientStops),
92956
- type: style.strokeGradientType,
92957
- angle: style.strokeGradientAngle
92958
- },
92959
- svgGradientId(elementId, "stroke")
92960
- );
92961
- }
92962
- function buildSvgStrokePatternDef(style, elementId) {
92963
- if (!style || style.strokeFillMode !== "pattern" || !style.strokePatternPreset) {
92964
- return void 0;
92965
- }
92966
- const fg = normalizeHexColor(style.strokeColor, "#000000");
92967
- const bg = normalizeHexColor(style.strokePatternBackgroundColor, "#ffffff");
92968
- const tile = getPatternTile(style.strokePatternPreset, fg, bg);
92969
- if (!tile) {
92970
- return void 0;
92971
- }
92972
- const markup = `<svg xmlns="http://www.w3.org/2000/svg" width="${tile.w}" height="${tile.h}">${tile.inner}</svg>`;
92973
- return {
92974
- kind: "pattern",
92975
- id: svgGradientId(elementId, "strokepat"),
92976
- width: tile.w,
92977
- height: tile.h,
92978
- href: `data:image/svg+xml,${encodeURIComponent(markup)}`
92979
- };
92980
- }
92981
- function svgGradientFillRef(def) {
92982
- return `url(#${def.id})`;
92983
- }
92984
- var DEFAULT_OPEN_PRESET_STROKE_WIDTH = 2;
92985
- function outlinePathData(clipPath, width, height) {
92986
- if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
92987
- return void 0;
92988
- }
92989
- const rect2 = `M 0 0 L ${width} 0 L ${width} ${height} L 0 ${height} Z`;
92990
- if (!clipPath) {
92991
- return rect2;
92992
- }
92993
- const asPath = /^path\('(.*)'\)$/su.exec(clipPath.trim());
92994
- if (asPath) {
92995
- return asPath[1];
92996
- }
92997
- const asPolygon = /^polygon\((.*)\)$/su.exec(clipPath.trim());
92998
- if (asPolygon) {
92999
- const points3 = asPolygon[1].split(",").map((pair) => pair.trim().split(/\s+/u)).filter((parts) => parts.length === 2).map(([rawX, rawY]) => {
93000
- const toPx2 = (token2, extent) => token2.endsWith("%") ? Number.parseFloat(token2) / 100 * extent : Number.parseFloat(token2);
93001
- return [toPx2(rawX, width), toPx2(rawY, height)];
93002
- }).filter(([x, y]) => Number.isFinite(x) && Number.isFinite(y));
93003
- if (points3.length < 3) {
93004
- return rect2;
93005
- }
93006
- const [first, ...rest] = points3;
93007
- return `M ${first[0]} ${first[1]} ${rest.map(([x, y]) => `L ${x} ${y}`).join(" ")} Z`;
93008
- }
93009
- return rect2;
93010
- }
93011
- function outlineStrands(compoundLine, strokeWidth) {
93012
- const offsets = getCompoundLineOffsets(compoundLine, strokeWidth);
93013
- if (offsets.length <= 1) {
93014
- return [{ strokeWidth, offset: 0 }];
93015
- }
93016
- const widths = getCompoundLineWidths(compoundLine, strokeWidth);
93017
- return offsets.map((offset, idx) => ({ strokeWidth: widths[idx] ?? strokeWidth, offset }));
93018
- }
93019
- function buildStrokeOutline(element) {
93020
- if (!hasShapeProperties(element)) {
93021
- return void 0;
93022
- }
93023
- const style = element.shapeStyle;
93024
- const declaredWidth = Math.max(0, style?.strokeWidth ?? 0);
93025
- const openPresetD = strokeOnlyPresetPathData(element);
93026
- if (!openPresetD && (!style || declaredWidth <= 0)) {
93027
- return void 0;
93028
- }
93029
- const paint = style && declaredWidth > 0 ? buildSvgStrokeGradientDef(style, element.id) ?? buildSvgStrokePatternDef(style, element.id) : void 0;
93030
- if (!paint && !openPresetD) {
93031
- return void 0;
93032
- }
93033
- const d = openPresetD ?? outlinePathData(getResolvedShapeClipPath(element), element.width, element.height);
93034
- if (!d) {
93035
- return void 0;
93036
- }
93037
- const strokeWidth = declaredWidth > 0 ? declaredWidth : DEFAULT_OPEN_PRESET_STROKE_WIDTH;
93038
- return {
93039
- d,
93040
- paint,
93041
- stroke: paint ? svgGradientFillRef(paint) : colorWithOpacity(style?.strokeColor ?? DEFAULT_STROKE_COLOR, style?.strokeOpacity),
93042
- strokeWidth,
93043
- strands: outlineStrands(style?.compoundLine, strokeWidth),
93044
- dashArray: getSvgStrokeDasharray(
93045
- normalizeStrokeDashType(style?.strokeDash),
93046
- Math.max(strokeWidth, 1),
93047
- style?.customDashSegments
93048
- ),
93049
- lineCap: svgLineCap(style?.lineCap),
93050
- lineJoin: style?.lineJoin === "bevel" ? "bevel" : style?.lineJoin === "miter" ? "miter" : "round"
93051
- };
93052
- }
93053
- function strokeOutlineViewBox(element) {
93054
- const width = Math.max(element.width, MIN_ELEMENT_SIZE);
93055
- const height = Math.max(element.height, MIN_ELEMENT_SIZE);
93056
- return `0 0 ${width} ${height}`;
93057
- }
93058
- function suppressesCssBorder(element) {
93059
- return buildStrokeOutline(element) !== void 0;
93060
- }
93061
- var HOLLOW_HIT_MIN_WIDTH = 10;
93062
- function isHollowShapeElement(element) {
93063
- if (element.type !== "shape" || !hasShapeProperties(element)) {
93064
- return false;
93065
- }
93066
- const style = element.shapeStyle;
93067
- const filled = style?.fillColor !== void 0 && style.fillColor !== "transparent" || style?.fillMode === "gradient" || style?.fillMode === "pattern" || style?.fillMode === "image" || style?.fillMode === "group" || Boolean(style?.fillGradient);
93068
- if (filled) {
93069
- return false;
93070
- }
93071
- return getElementTextContent(element).trim() === "";
93072
- }
93073
- function buildHollowHitOutline(element) {
93074
- if (!isHollowShapeElement(element)) {
93075
- return void 0;
93076
- }
93077
- const d = outlinePathData(getResolvedShapeClipPath(element), element.width, element.height);
93078
- if (!d) {
93079
- return void 0;
93080
- }
93081
- const strokeWidth = hasShapeProperties(element) ? element.shapeStyle?.strokeWidth ?? 0 : 0;
93082
- return { d, strokeWidth: Math.max(strokeWidth * 3, HOLLOW_HIT_MIN_WIDTH) };
93083
- }
93084
- function createWheelStepBuffer() {
93085
- return { accumulated: 0 };
93086
- }
93087
- var LINE_PX = 16;
93088
- var PAGE_PX = 400;
93089
- var STEP_THRESHOLD_PX = 120;
93090
- var ZOOM_PER_PX = 15e-4;
93091
- function normalizeWheelDelta({ deltaY, deltaMode = 0 }) {
93092
- if (deltaMode === 1) {
93093
- return deltaY * LINE_PX;
93094
- }
93095
- if (deltaMode === 2) {
93096
- return deltaY * PAGE_PX;
93097
- }
93098
- return deltaY;
93099
- }
93100
- function accumulate(buffer, px3) {
93101
- if (px3 !== 0 && Math.sign(px3) !== Math.sign(buffer.accumulated)) {
93102
- buffer.accumulated = 0;
93103
- }
93104
- buffer.accumulated += px3;
93105
- if (buffer.accumulated >= STEP_THRESHOLD_PX) {
93106
- buffer.accumulated = 0;
93107
- return { intent: "next-slide" };
93108
- }
93109
- if (buffer.accumulated <= -STEP_THRESHOLD_PX) {
93110
- buffer.accumulated = 0;
93111
- return { intent: "previous-slide" };
93112
- }
93113
- return { intent: "none" };
93114
- }
93115
- function mapEditingWheel(input, buffer, canScrollFurther) {
93116
- const px3 = normalizeWheelDelta(input);
93117
- if (input.ctrlKey === true || input.metaKey === true) {
93118
- buffer.accumulated = 0;
93119
- return { intent: "zoom", deltaScale: -px3 * ZOOM_PER_PX };
93120
- }
93121
- if (canScrollFurther) {
93122
- buffer.accumulated = 0;
93123
- return { intent: "scroll" };
93124
- }
93125
- return accumulate(buffer, px3);
93126
- }
93127
- function mapPresentationWheel(input, buffer) {
93128
- return accumulate(buffer, normalizeWheelDelta(input));
93129
- }
93130
- var CYLINDER_RADIUS = "48% / 12%";
93131
- var MIN_ROUND_RECT_RADIUS_PX = 0.01;
93132
- function resolveShapeGeometry(element) {
93133
- const shapeType = getShapeType(element.shapeType);
93134
- if (element.type === "connector" || shapeType === "connector") {
93135
- return { kind: "bare" };
93136
- }
93137
- if (isStrokeOnlyPresetElement(element)) {
93138
- return { kind: "strokeOnly" };
93139
- }
93140
- if (shapeType === "roundRect" && hasShapeProperties(element)) {
93141
- const radiusPx = getRoundRectRadiusPx(element);
93142
- return radiusPx > MIN_ROUND_RECT_RADIUS_PX ? { kind: "borderRadius", radius: `${radiusPx}px` } : { kind: "none" };
93143
- }
93144
- if (shapeType === "ellipse") {
93145
- return { kind: "borderRadius", radius: "50%" };
93146
- }
93147
- const clipPath = isIdentityRectClip(element) ? void 0 : getResolvedShapeClipPath(element);
93148
- if (clipPath) {
93149
- return { kind: "clipPath", clipPath };
93150
- }
93151
- if (shapeType === "line") {
93152
- const authored = element.shapeStyle?.strokeWidth;
93153
- return { kind: "lineEdge", strokeWidth: Math.max(Math.max(0, authored ?? 0), 2) };
93154
- }
93155
- if (shapeType === "cylinder") {
93156
- return { kind: "borderRadius", radius: CYLINDER_RADIUS };
93157
- }
93158
- return { kind: "none" };
93159
- }
93160
- function hasStrokePaint(style) {
93161
- if (!style || Math.max(0, style.strokeWidth ?? 0) <= 0) {
93162
- return false;
93163
- }
93164
- return style.strokeColor !== void 0 || style.strokeFillMode !== void 0;
93165
- }
93166
- function paintedStrokeWidth(style) {
93167
- return hasStrokePaint(style) ? Math.max(0, style?.strokeWidth ?? 0) : 0;
93168
- }
93169
- var NO_STROKE = {
93170
- borderWidth: 0,
93171
- borderStyle: void 0,
93172
- borderColor: void 0,
93173
- border: void 0,
93174
- strokeLinejoin: void 0,
93175
- strokeLinecap: void 0,
93176
- strokeMiterlimit: void 0
93177
- };
93178
- function svgLineJoin(join) {
93179
- switch (join) {
93180
- case "round":
93181
- return "round";
93182
- case "bevel":
93183
- return "bevel";
93184
- case "miter":
93185
- return "miter";
93186
- default:
93187
- return void 0;
93188
- }
93189
- }
93190
- function svgStrokeLineCap(cap) {
93191
- switch (cap) {
93192
- case "rnd":
93193
- return "round";
93194
- case "sq":
93195
- return "square";
93196
- case "flat":
93197
- return "butt";
93198
- default:
93199
- return void 0;
93200
- }
93201
- }
93202
- function strokeMiterLimit(style) {
93203
- if (style?.lineJoin !== "miter" || typeof style.miterLimit !== "number") {
93204
- return void 0;
93205
- }
93206
- if (!Number.isFinite(style.miterLimit)) {
93207
- return void 0;
93208
- }
93209
- return Math.max(style.miterLimit / 1e5, 1);
93210
- }
93211
- function getComputedStrokeStyle(element) {
93212
- if (!hasShapeProperties(element)) {
93213
- return NO_STROKE;
93214
- }
93215
- const style = element.shapeStyle;
93216
- const width = suppressesCssBorder(element) ? 0 : paintedStrokeWidth(style);
93217
- const joins = {
93218
- strokeLinejoin: svgLineJoin(style?.lineJoin),
93219
- strokeLinecap: svgStrokeLineCap(style?.lineCap),
93220
- strokeMiterlimit: strokeMiterLimit(style)
93221
- };
93222
- if (width <= 0 || !style) {
93223
- return { ...NO_STROKE, ...joins };
93224
- }
93225
- const borderWidth = width;
93226
- const borderStyle = getCssBorderDashStyle(
93227
- normalizeStrokeDashType(style.strokeDash),
93228
- style.compoundLine
93229
- );
93230
- const rawColor = style.strokeColor ?? DEFAULT_STROKE_COLOR;
93231
- const borderColor = style.strokeOpacity === void 0 ? rawColor : colorWithOpacity(normalizeHexColor(rawColor, DEFAULT_STROKE_COLOR), style.strokeOpacity);
93232
- return {
93233
- borderWidth,
93234
- borderStyle,
93235
- borderColor,
93236
- border: `${borderWidth}px ${borderStyle ?? "solid"} ${borderColor}`,
93237
- ...joins
93238
- };
93239
- }
93240
93079
  var DEFAULT_SHADOW_COLOR = "#000000";
93241
93080
  var DEFAULT_GLOW_COLOR = "#ffff00";
93242
93081
  function escapeSvgAttr(value) {
93243
- return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
93082
+ return String(value).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
93244
93083
  }
93245
93084
  function clampUnitInterval22(value) {
93246
93085
  return Math.min(1, Math.max(0, value));
@@ -93625,6 +93464,353 @@ function getComputedEffectStyle(element, options = {}) {
93625
93464
  }
93626
93465
  return result;
93627
93466
  }
93467
+ function round4(value) {
93468
+ return Math.round(value * 1e4) / 1e4;
93469
+ }
93470
+ function svgGradientId(elementId, suffix = "grad") {
93471
+ const seed = String(elementId).replace(/[^a-zA-Z0-9_-]/gu, "_");
93472
+ return `pptx-${suffix}-${seed}`;
93473
+ }
93474
+ function toSvgStops(stops) {
93475
+ return sanitizeGradientStops(stops).map((stop) => ({
93476
+ offset: round4(stop.position / 100),
93477
+ color: stop.color,
93478
+ ...typeof stop.opacity === "number" ? { opacity: round4(stop.opacity) } : {}
93479
+ }));
93480
+ }
93481
+ function linearEndpoints(angleDegrees) {
93482
+ const radians = angleDegrees * Math.PI / 180;
93483
+ const dx = Math.cos(radians);
93484
+ const dy = Math.sin(radians);
93485
+ const span = (Math.abs(dx) + Math.abs(dy)) / 2;
93486
+ return {
93487
+ x1: round4(0.5 - dx * span),
93488
+ y1: round4(0.5 - dy * span),
93489
+ x2: round4(0.5 + dx * span),
93490
+ y2: round4(0.5 + dy * span)
93491
+ };
93492
+ }
93493
+ function buildFromSource(source, id) {
93494
+ const { stops } = source;
93495
+ if (stops.length === 0) {
93496
+ return void 0;
93497
+ }
93498
+ if ((source.type || "linear") === "radial") {
93499
+ const { cx, cy } = computeGradientCenter(source.fillToRect, source.focalPoint);
93500
+ const fx = cx / 100;
93501
+ const fy = cy / 100;
93502
+ const r = Math.hypot(Math.max(fx, 1 - fx), Math.max(fy, 1 - fy));
93503
+ return { kind: "radial", id, cx: round4(fx), cy: round4(fy), r: round4(r), stops };
93504
+ }
93505
+ const angle = typeof source.angle === "number" && Number.isFinite(source.angle) ? source.angle : 90;
93506
+ return { kind: "linear", id, ...linearEndpoints(angle), stops };
93507
+ }
93508
+ function buildSvgGradientDef(style, elementId) {
93509
+ if (!style || style.fillMode !== "gradient") {
93510
+ return void 0;
93511
+ }
93512
+ return buildFromSource(
93513
+ {
93514
+ stops: toSvgStops(style.fillGradientStops),
93515
+ type: style.fillGradientType,
93516
+ angle: style.fillGradientAngle,
93517
+ fillToRect: style.fillGradientFillToRect,
93518
+ focalPoint: style.fillGradientFocalPoint
93519
+ },
93520
+ svgGradientId(elementId)
93521
+ );
93522
+ }
93523
+ function buildSvgStrokeGradientDef(style, elementId) {
93524
+ if (!style || style.strokeFillMode !== "gradient") {
93525
+ return void 0;
93526
+ }
93527
+ return buildFromSource(
93528
+ {
93529
+ stops: toSvgStops(style.strokeGradientStops),
93530
+ type: style.strokeGradientType,
93531
+ angle: style.strokeGradientAngle
93532
+ },
93533
+ svgGradientId(elementId, "stroke")
93534
+ );
93535
+ }
93536
+ function buildSvgStrokePatternDef(style, elementId) {
93537
+ if (!style || style.strokeFillMode !== "pattern" || !style.strokePatternPreset) {
93538
+ return void 0;
93539
+ }
93540
+ const fg = normalizeHexColor(style.strokeColor, "#000000");
93541
+ const bg = normalizeHexColor(style.strokePatternBackgroundColor, "#ffffff");
93542
+ const tile = getPatternTile(style.strokePatternPreset, fg, bg);
93543
+ if (!tile) {
93544
+ return void 0;
93545
+ }
93546
+ const markup = `<svg xmlns="http://www.w3.org/2000/svg" width="${tile.w}" height="${tile.h}">${tile.inner}</svg>`;
93547
+ return {
93548
+ kind: "pattern",
93549
+ id: svgGradientId(elementId, "strokepat"),
93550
+ width: tile.w,
93551
+ height: tile.h,
93552
+ href: `data:image/svg+xml,${encodeURIComponent(markup)}`
93553
+ };
93554
+ }
93555
+ function svgGradientFillRef(def) {
93556
+ return `url(#${def.id})`;
93557
+ }
93558
+ var DEFAULT_OPEN_PRESET_STROKE_WIDTH = 2;
93559
+ function outlinePathData(clipPath, width, height) {
93560
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
93561
+ return void 0;
93562
+ }
93563
+ const rect2 = `M 0 0 L ${width} 0 L ${width} ${height} L 0 ${height} Z`;
93564
+ if (!clipPath) {
93565
+ return rect2;
93566
+ }
93567
+ const asPath = /^path\('(.*)'\)$/su.exec(clipPath.trim());
93568
+ if (asPath) {
93569
+ return asPath[1];
93570
+ }
93571
+ const asPolygon = /^polygon\((.*)\)$/su.exec(clipPath.trim());
93572
+ if (asPolygon) {
93573
+ const points3 = asPolygon[1].split(",").map((pair) => pair.trim().split(/\s+/u)).filter((parts) => parts.length === 2).map(([rawX, rawY]) => {
93574
+ const toPx2 = (token2, extent) => token2.endsWith("%") ? Number.parseFloat(token2) / 100 * extent : Number.parseFloat(token2);
93575
+ return [toPx2(rawX, width), toPx2(rawY, height)];
93576
+ }).filter(([x, y]) => Number.isFinite(x) && Number.isFinite(y));
93577
+ if (points3.length < 3) {
93578
+ return rect2;
93579
+ }
93580
+ const [first, ...rest] = points3;
93581
+ return `M ${first[0]} ${first[1]} ${rest.map(([x, y]) => `L ${x} ${y}`).join(" ")} Z`;
93582
+ }
93583
+ return rect2;
93584
+ }
93585
+ function outlineStrands(compoundLine, strokeWidth) {
93586
+ const offsets = getCompoundLineOffsets(compoundLine, strokeWidth);
93587
+ if (offsets.length <= 1) {
93588
+ return [{ strokeWidth, offset: 0 }];
93589
+ }
93590
+ const widths = getCompoundLineWidths(compoundLine, strokeWidth);
93591
+ return offsets.map((offset, idx) => ({ strokeWidth: widths[idx] ?? strokeWidth, offset }));
93592
+ }
93593
+ function buildStrokeOutline(element) {
93594
+ if (!hasShapeProperties(element)) {
93595
+ return void 0;
93596
+ }
93597
+ const style = element.shapeStyle;
93598
+ const declaredWidth = Math.max(0, style?.strokeWidth ?? 0);
93599
+ const openPresetD = strokeOnlyPresetPathData(element);
93600
+ if (!openPresetD && (!style || declaredWidth <= 0)) {
93601
+ return void 0;
93602
+ }
93603
+ const paint = style && declaredWidth > 0 ? buildSvgStrokeGradientDef(style, element.id) ?? buildSvgStrokePatternDef(style, element.id) : void 0;
93604
+ if (!paint && !openPresetD) {
93605
+ return void 0;
93606
+ }
93607
+ const d = openPresetD ?? outlinePathData(getResolvedShapeClipPath(element), element.width, element.height);
93608
+ if (!d) {
93609
+ return void 0;
93610
+ }
93611
+ const strokeWidth = declaredWidth > 0 ? declaredWidth : DEFAULT_OPEN_PRESET_STROKE_WIDTH;
93612
+ return {
93613
+ d,
93614
+ paint,
93615
+ stroke: paint ? svgGradientFillRef(paint) : colorWithOpacity(style?.strokeColor ?? DEFAULT_STROKE_COLOR, style?.strokeOpacity),
93616
+ strokeWidth,
93617
+ strands: outlineStrands(style?.compoundLine, strokeWidth),
93618
+ dashArray: getSvgStrokeDasharray(
93619
+ normalizeStrokeDashType(style?.strokeDash),
93620
+ Math.max(strokeWidth, 1),
93621
+ style?.customDashSegments
93622
+ ),
93623
+ lineCap: svgLineCap(style?.lineCap),
93624
+ lineJoin: style?.lineJoin === "bevel" ? "bevel" : style?.lineJoin === "miter" ? "miter" : "round"
93625
+ };
93626
+ }
93627
+ function strokeOutlineViewBox(element) {
93628
+ const width = Math.max(element.width, MIN_ELEMENT_SIZE);
93629
+ const height = Math.max(element.height, MIN_ELEMENT_SIZE);
93630
+ return `0 0 ${width} ${height}`;
93631
+ }
93632
+ function suppressesCssBorder(element) {
93633
+ return buildStrokeOutline(element) !== void 0;
93634
+ }
93635
+ var HOLLOW_HIT_MIN_WIDTH = 10;
93636
+ function isHollowShapeElement(element) {
93637
+ if (element.type !== "shape" || !hasShapeProperties(element)) {
93638
+ return false;
93639
+ }
93640
+ const style = element.shapeStyle;
93641
+ const filled = style?.fillColor !== void 0 && style.fillColor !== "transparent" || style?.fillMode === "gradient" || style?.fillMode === "pattern" || style?.fillMode === "image" || style?.fillMode === "group" || Boolean(style?.fillGradient);
93642
+ if (filled) {
93643
+ return false;
93644
+ }
93645
+ return getElementTextContent(element).trim() === "";
93646
+ }
93647
+ function buildHollowHitOutline(element) {
93648
+ if (!isHollowShapeElement(element)) {
93649
+ return void 0;
93650
+ }
93651
+ const d = outlinePathData(getResolvedShapeClipPath(element), element.width, element.height);
93652
+ if (!d) {
93653
+ return void 0;
93654
+ }
93655
+ const strokeWidth = hasShapeProperties(element) ? element.shapeStyle?.strokeWidth ?? 0 : 0;
93656
+ return { d, strokeWidth: Math.max(strokeWidth * 3, HOLLOW_HIT_MIN_WIDTH) };
93657
+ }
93658
+ function createWheelStepBuffer() {
93659
+ return { accumulated: 0 };
93660
+ }
93661
+ var LINE_PX = 16;
93662
+ var PAGE_PX = 400;
93663
+ var STEP_THRESHOLD_PX = 120;
93664
+ var ZOOM_PER_PX = 15e-4;
93665
+ function normalizeWheelDelta({ deltaY, deltaMode = 0 }) {
93666
+ if (deltaMode === 1) {
93667
+ return deltaY * LINE_PX;
93668
+ }
93669
+ if (deltaMode === 2) {
93670
+ return deltaY * PAGE_PX;
93671
+ }
93672
+ return deltaY;
93673
+ }
93674
+ function accumulate(buffer, px3) {
93675
+ if (px3 !== 0 && Math.sign(px3) !== Math.sign(buffer.accumulated)) {
93676
+ buffer.accumulated = 0;
93677
+ }
93678
+ buffer.accumulated += px3;
93679
+ if (buffer.accumulated >= STEP_THRESHOLD_PX) {
93680
+ buffer.accumulated = 0;
93681
+ return { intent: "next-slide" };
93682
+ }
93683
+ if (buffer.accumulated <= -STEP_THRESHOLD_PX) {
93684
+ buffer.accumulated = 0;
93685
+ return { intent: "previous-slide" };
93686
+ }
93687
+ return { intent: "none" };
93688
+ }
93689
+ function mapEditingWheel(input, buffer, canScrollFurther) {
93690
+ const px3 = normalizeWheelDelta(input);
93691
+ if (input.ctrlKey === true || input.metaKey === true) {
93692
+ buffer.accumulated = 0;
93693
+ return { intent: "zoom", deltaScale: -px3 * ZOOM_PER_PX };
93694
+ }
93695
+ if (canScrollFurther) {
93696
+ buffer.accumulated = 0;
93697
+ return { intent: "scroll" };
93698
+ }
93699
+ return accumulate(buffer, px3);
93700
+ }
93701
+ function mapPresentationWheel(input, buffer) {
93702
+ return accumulate(buffer, normalizeWheelDelta(input));
93703
+ }
93704
+ var CYLINDER_RADIUS = "48% / 12%";
93705
+ var MIN_ROUND_RECT_RADIUS_PX = 0.01;
93706
+ function resolveShapeGeometry(element) {
93707
+ const shapeType = getShapeType(element.shapeType);
93708
+ if (element.type === "connector" || shapeType === "connector") {
93709
+ return { kind: "bare" };
93710
+ }
93711
+ if (isStrokeOnlyPresetElement(element)) {
93712
+ return { kind: "strokeOnly" };
93713
+ }
93714
+ if (shapeType === "roundRect" && hasShapeProperties(element)) {
93715
+ const radiusPx = getRoundRectRadiusPx(element);
93716
+ return radiusPx > MIN_ROUND_RECT_RADIUS_PX ? { kind: "borderRadius", radius: `${radiusPx}px` } : { kind: "none" };
93717
+ }
93718
+ if (shapeType === "ellipse") {
93719
+ return { kind: "borderRadius", radius: "50%" };
93720
+ }
93721
+ const clipPath = isIdentityRectClip(element) ? void 0 : getResolvedShapeClipPath(element);
93722
+ if (clipPath) {
93723
+ return { kind: "clipPath", clipPath };
93724
+ }
93725
+ if (shapeType === "line") {
93726
+ const authored = element.shapeStyle?.strokeWidth;
93727
+ return { kind: "lineEdge", strokeWidth: Math.max(Math.max(0, authored ?? 0), 2) };
93728
+ }
93729
+ if (shapeType === "cylinder") {
93730
+ return { kind: "borderRadius", radius: CYLINDER_RADIUS };
93731
+ }
93732
+ return { kind: "none" };
93733
+ }
93734
+ function hasStrokePaint(style) {
93735
+ if (!style || Math.max(0, style.strokeWidth ?? 0) <= 0) {
93736
+ return false;
93737
+ }
93738
+ return style.strokeColor !== void 0 || style.strokeFillMode !== void 0;
93739
+ }
93740
+ function paintedStrokeWidth(style) {
93741
+ return hasStrokePaint(style) ? Math.max(0, style?.strokeWidth ?? 0) : 0;
93742
+ }
93743
+ var NO_STROKE = {
93744
+ borderWidth: 0,
93745
+ borderStyle: void 0,
93746
+ borderColor: void 0,
93747
+ border: void 0,
93748
+ strokeLinejoin: void 0,
93749
+ strokeLinecap: void 0,
93750
+ strokeMiterlimit: void 0
93751
+ };
93752
+ function svgLineJoin(join) {
93753
+ switch (join) {
93754
+ case "round":
93755
+ return "round";
93756
+ case "bevel":
93757
+ return "bevel";
93758
+ case "miter":
93759
+ return "miter";
93760
+ default:
93761
+ return void 0;
93762
+ }
93763
+ }
93764
+ function svgStrokeLineCap(cap) {
93765
+ switch (cap) {
93766
+ case "rnd":
93767
+ return "round";
93768
+ case "sq":
93769
+ return "square";
93770
+ case "flat":
93771
+ return "butt";
93772
+ default:
93773
+ return void 0;
93774
+ }
93775
+ }
93776
+ function strokeMiterLimit(style) {
93777
+ if (style?.lineJoin !== "miter" || typeof style.miterLimit !== "number") {
93778
+ return void 0;
93779
+ }
93780
+ if (!Number.isFinite(style.miterLimit)) {
93781
+ return void 0;
93782
+ }
93783
+ return Math.max(style.miterLimit / 1e5, 1);
93784
+ }
93785
+ function getComputedStrokeStyle(element) {
93786
+ if (!hasShapeProperties(element)) {
93787
+ return NO_STROKE;
93788
+ }
93789
+ const style = element.shapeStyle;
93790
+ const width = suppressesCssBorder(element) ? 0 : paintedStrokeWidth(style);
93791
+ const joins = {
93792
+ strokeLinejoin: svgLineJoin(style?.lineJoin),
93793
+ strokeLinecap: svgStrokeLineCap(style?.lineCap),
93794
+ strokeMiterlimit: strokeMiterLimit(style)
93795
+ };
93796
+ if (width <= 0 || !style) {
93797
+ return { ...NO_STROKE, ...joins };
93798
+ }
93799
+ const borderWidth = width;
93800
+ const borderStyle = getCssBorderDashStyle(
93801
+ normalizeStrokeDashType(style.strokeDash),
93802
+ style.compoundLine
93803
+ );
93804
+ const rawColor = style.strokeColor ?? DEFAULT_STROKE_COLOR;
93805
+ const borderColor = style.strokeOpacity === void 0 ? rawColor : colorWithOpacity(normalizeHexColor(rawColor, DEFAULT_STROKE_COLOR), style.strokeOpacity);
93806
+ return {
93807
+ borderWidth,
93808
+ borderStyle,
93809
+ borderColor,
93810
+ border: `${borderWidth}px ${borderStyle ?? "solid"} ${borderColor}`,
93811
+ ...joins
93812
+ };
93813
+ }
93628
93814
  function isImageTiled(element) {
93629
93815
  if (!isImageLikeElement(element)) {
93630
93816
  return false;
@@ -96648,24 +96834,6 @@ function getChartStylePalette(styleId) {
96648
96834
  }
96649
96835
  return palette;
96650
96836
  }
96651
- function seriesColor2(series, index, styleId, colorPalette) {
96652
- const explicit = series.color ?? series.marker?.spPr?.fillColor;
96653
- if (explicit) {
96654
- return explicit;
96655
- }
96656
- if (colorPalette && colorPalette.length > 0) {
96657
- return colorPalette[index % colorPalette.length];
96658
- }
96659
- const palette = getChartStylePalette(styleId);
96660
- return palette[index % palette.length];
96661
- }
96662
- function paletteColor(index, styleId, colorPalette) {
96663
- if (colorPalette && colorPalette.length > 0) {
96664
- return colorPalette[index % colorPalette.length];
96665
- }
96666
- const palette = getChartStylePalette(styleId);
96667
- return palette[index % palette.length];
96668
- }
96669
96837
  function computeValueRange(series) {
96670
96838
  const allValues = series.flatMap((s) => s.values);
96671
96839
  if (allValues.length === 0) {
@@ -96677,20 +96845,6 @@ function computeValueRange(series) {
96677
96845
  );
96678
96846
  return { min, max, span: Math.max(max - min, Number.EPSILON), majorUnit };
96679
96847
  }
96680
- function valueToY(val2, range, topY, bottomY) {
96681
- const usable = bottomY - topY;
96682
- let ratio;
96683
- if (range.logScale && range.logBase) {
96684
- const base = range.logBase;
96685
- const clampedVal = Math.max(val2, range.min);
96686
- const logVal = Math.log(clampedVal) / Math.log(base);
96687
- const logMin = Math.log(range.min) / Math.log(base);
96688
- ratio = (logVal - logMin) / range.span;
96689
- } else {
96690
- ratio = (val2 - range.min) / range.span;
96691
- }
96692
- return range.reverseOrder ? topY + ratio * usable : bottomY - ratio * usable;
96693
- }
96694
96848
  function formatAxisValue(val2, formatCode) {
96695
96849
  const formatted = formatChartNumber(val2, formatCode);
96696
96850
  if (formatted !== void 0) {
@@ -96707,50 +96861,6 @@ function formatAxisValue(val2, formatCode) {
96707
96861
  }
96708
96862
  return val2.toFixed(1);
96709
96863
  }
96710
- function computeLayout(elementWidth, elementHeight, style, hasAxes, legendPos, options) {
96711
- const svgWidth = Math.max(1, elementWidth);
96712
- const svgHeight = Math.max(1, elementHeight);
96713
- let plotLeft = hasAxes ? 48 : 8;
96714
- let plotTop = 8;
96715
- let plotRight = svgWidth - 8;
96716
- let plotBottom = svgHeight - (hasAxes ? 24 : 8);
96717
- if (style?.hasTitle) {
96718
- plotTop += 20;
96719
- }
96720
- if (style?.hasLegend) {
96721
- if (legendPos === "b") {
96722
- plotBottom -= 20;
96723
- } else if (legendPos === "t") {
96724
- plotTop += 20;
96725
- } else if (legendPos === "r") {
96726
- plotRight -= 80;
96727
- } else if (legendPos === "l") {
96728
- plotLeft += 80;
96729
- }
96730
- }
96731
- if (options?.hasSecondaryValueAxis) {
96732
- plotRight -= 40;
96733
- }
96734
- if (options?.hasSecondaryCategoryAxis) {
96735
- plotTop += 16;
96736
- }
96737
- if (options?.hasDataTable) {
96738
- const rowCount = options.dataTableRowCount ?? 1;
96739
- plotBottom -= 14 + rowCount * 14;
96740
- }
96741
- const pw = Math.max(plotRight - plotLeft, 1);
96742
- const ph = Math.max(plotBottom - plotTop, 1);
96743
- return {
96744
- plotLeft,
96745
- plotTop,
96746
- plotRight: plotLeft + pw,
96747
- plotBottom: plotTop + ph,
96748
- plotWidth: pw,
96749
- plotHeight: ph,
96750
- svgWidth,
96751
- svgHeight
96752
- };
96753
- }
96754
96864
  var DEFAULT_CHART_AREA_FILL = "#0f172a11";
96755
96865
  function resolve(fill, fallback) {
96756
96866
  if (fill === "none") {
@@ -97714,7 +97824,7 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
97714
97824
  const valY = valueToY2(val2, activeRange, layout.plotTop, layout.plotBottom);
97715
97825
  const y = Math.min(zeroY, valY);
97716
97826
  const h = Math.max(Math.abs(zeroY - valY), 1);
97717
- const baseFill = varyColorsSingle ? resolveVaryColorFill(series[si], sourceIndex, paletteColor2(sourceIndex, palette)) : resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor22(series[si], si, palette);
97827
+ const baseFill = varyColorsSingle ? resolveVaryColorFill(series[si], sourceIndex, paletteColor2(sourceIndex, palette)) : resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
97718
97828
  primitives.push({
97719
97829
  kind: "rect",
97720
97830
  x,
@@ -97803,7 +97913,7 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
97803
97913
  const topY = valueToY2(top, primaryRange, layout.plotTop, layout.plotBottom);
97804
97914
  const y = Math.min(baseY, topY);
97805
97915
  const h = Math.max(Math.abs(baseY - topY), 0.5);
97806
- const pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor22(series[si], si, palette);
97916
+ const pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
97807
97917
  primitives.push({
97808
97918
  kind: "rect",
97809
97919
  x,
@@ -98083,7 +98193,7 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
98083
98193
  x: xPositions?.[index] ?? point.x
98084
98194
  })
98085
98195
  );
98086
- const c = seriesColor22(series, si, chartData.colorPalette);
98196
+ const c = seriesColor2(series, si, chartData.colorPalette);
98087
98197
  const seriesPart = { role: "series", seriesIndex: si };
98088
98198
  const allVisible = visible.every(Boolean);
98089
98199
  if (allVisible) {
@@ -98177,7 +98287,7 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
98177
98287
  ...point,
98178
98288
  x: xPositions?.[index] ?? point.x
98179
98289
  }));
98180
- const c = seriesColor22(series, si, chartData.colorPalette);
98290
+ const c = seriesColor2(series, si, chartData.colorPalette);
98181
98291
  const lineStr = linePointsToSvgString(pts);
98182
98292
  const firstPt = pts[0];
98183
98293
  const lastPt = pts[pts.length - 1];
@@ -98265,7 +98375,7 @@ function buildScatter(chartData, layout, range) {
98265
98375
  const smoothStyle = chartData.scatterStyle === "smooth" || chartData.scatterStyle === "smoothMarker";
98266
98376
  for (let si = 0; si < chartData.series.length; si++) {
98267
98377
  const series = chartData.series[si];
98268
- const c = seriesColor22(series, si, chartData.colorPalette);
98378
+ const c = seriesColor2(series, si, chartData.colorPalette);
98269
98379
  const dots = computeScatterDots(
98270
98380
  series.values,
98271
98381
  maxXIndex,
@@ -98343,7 +98453,7 @@ function buildBubbles(chartData, layout, range) {
98343
98453
  const medianRadius = Math.min(layout.plotWidth, layout.plotHeight) * 0.04;
98344
98454
  for (let si = 0; si < chartData.series.length; si++) {
98345
98455
  const series = chartData.series[si];
98346
- const c = seriesColor22(series, si, chartData.colorPalette);
98456
+ const c = seriesColor2(series, si, chartData.colorPalette);
98347
98457
  const dots = computeScatterDots(
98348
98458
  series.values,
98349
98459
  maxXIndex,
@@ -98953,7 +99063,7 @@ function barFill(chartData, series, seriesIndex, pointIndex) {
98953
99063
  if (chartData.varyColors === true && chartData.series.length === 1) {
98954
99064
  return resolveVaryColorFill(series, pointIndex, paletteColor2(pointIndex, palette));
98955
99065
  }
98956
- return resolveDataPointFill(series, pointIndex, paletteColor2(seriesIndex, palette)) ?? seriesColor22(series, seriesIndex, palette);
99066
+ return resolveDataPointFill(series, pointIndex, paletteColor2(seriesIndex, palette)) ?? seriesColor2(series, seriesIndex, palette);
98957
99067
  }
98958
99068
  function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
98959
99069
  const layout = computePlotLayout(element.width, element.height, chartData, true);
@@ -99448,7 +99558,7 @@ function computeTrendlinePrimitives(chartData, catCount, layout, range, mode = "
99448
99558
  return;
99449
99559
  }
99450
99560
  const pathD = points3.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`).join(" ");
99451
- const strokeColor = tl.color ?? seriesColor22(series, si, colorPalette);
99561
+ const strokeColor = tl.color ?? seriesColor2(series, si, colorPalette);
99452
99562
  const pathPrimitive = {
99453
99563
  kind: "path",
99454
99564
  d: pathD,
@@ -99640,7 +99750,7 @@ function computeDataTablePrimitives(chartData, layout, colorPalette) {
99640
99750
  if (showK) {
99641
99751
  const swatchX = layout.plotLeft + DATA_TABLE_PADDING;
99642
99752
  const swatchY = ry + DATA_TABLE_ROW_H / 2 - 3;
99643
- const swatchColor = seriesColor22(s, si, colorPalette);
99753
+ const swatchColor = seriesColor2(s, si, colorPalette);
99644
99754
  out.push({
99645
99755
  kind: "rect",
99646
99756
  x: swatchX,
@@ -99963,7 +100073,7 @@ function buildComboViewModel(element, chartData, categoryLabels) {
99963
100073
  return;
99964
100074
  }
99965
100075
  const range = rangeForSeries(seriesIndex, primaryRange, secondaryRange, secondaryIndexes);
99966
- const fill = seriesColor22(series, seriesIndex, chartData.colorPalette);
100076
+ const fill = seriesColor2(series, seriesIndex, chartData.colorPalette);
99967
100077
  const points3 = sourceIndices2.map((sourceIndex, displayIndex) => {
99968
100078
  const value = series.values[sourceIndex] ?? 0;
99969
100079
  return {
@@ -100010,15 +100120,30 @@ function buildComboViewModel(element, chartData, categoryLabels) {
100010
100120
  });
100011
100121
  primitives.push(...horizontalAxis.tickMarks);
100012
100122
  const displayChartData = horizontalAxis.displayChartData;
100013
- primitives.push(
100123
+ const overlays = [
100014
100124
  ...computeErrorBarPrimitives(displayChartData, catCount, layout, primaryRange, "line", {
100015
100125
  xPositions: horizontalAxis.xPositions,
100016
100126
  seriesRanges: chartData.series.map(
100017
100127
  (_series, index) => rangeForSeries(index, primaryRange, secondaryRange, secondaryIndexes)
100018
100128
  ),
100019
100129
  seriesModes: chartData.series.map((_series, index) => index === 0 ? "bar" : "line")
100020
- })
100130
+ }),
100131
+ ...computeTrendlinePrimitives(
100132
+ displayChartData,
100133
+ catCount,
100134
+ layout,
100135
+ primaryRange,
100136
+ "bar",
100137
+ chartData.colorPalette
100138
+ ),
100139
+ ...computeAxisTitlePrimitives(chartData, layout)
100140
+ ];
100141
+ const dataTablePrimitives = computeDataTablePrimitives(
100142
+ displayChartData,
100143
+ layout,
100144
+ chartData.colorPalette
100021
100145
  );
100146
+ primitives.push(...overlays, ...dataTablePrimitives);
100022
100147
  return {
100023
100148
  svgWidth: layout.svgWidth,
100024
100149
  svgHeight: layout.svgHeight,
@@ -100036,7 +100161,9 @@ function buildComboViewModel(element, chartData, categoryLabels) {
100036
100161
  legendY,
100037
100162
  legendAnchor,
100038
100163
  secondaryGridlines: secondaryAxis?.gridlines,
100039
- secondaryAxisLabels: secondaryAxis?.axisLabels
100164
+ secondaryAxisLabels: secondaryAxis?.axisLabels,
100165
+ overlays: overlays.length > 0 ? overlays : void 0,
100166
+ dataTable: dataTablePrimitives.length > 0 ? dataTablePrimitives : void 0
100040
100167
  };
100041
100168
  }
100042
100169
  function appendBarLabels(series, chartData, layout, catCount, range, sourceIndices2, labels, xPositions) {
@@ -100073,7 +100200,7 @@ function buildStockViewModel(element, chartData, categoryLabels) {
100073
100200
  computeLayoutOptions(chartData.axes, chartData.dataTable, chartData.series.length)
100074
100201
  );
100075
100202
  const catCount = Math.max(categoryLabels.length, 1);
100076
- const range = computeValueRange2(chartData.series);
100203
+ const range = computeValueRangeForChart(chartData.series, chartData.axes);
100077
100204
  const valueAxis = chartData.axes?.find((axis) => axis.axisType === "valAx" && axis.axPos !== "r");
100078
100205
  const categoryAxis = chartData.axes?.find(
100079
100206
  (axis) => (axis.axisType === "catAx" || axis.axisType === "dateAx") && axis.axisId === valueAxis?.crossAxisId
@@ -100110,6 +100237,12 @@ function buildStockViewModel(element, chartData, categoryLabels) {
100110
100237
  const closeSeries = chartData.series[hasFour ? 3 : 2];
100111
100238
  const primitives = [];
100112
100239
  const dataLabels = [];
100240
+ primitives.push(
100241
+ ...computeHelperLinePrimitives(chartData, layout, range, catCount, {
100242
+ mode: "bar",
100243
+ xPositions: horizontalAxis.xPositions
100244
+ })
100245
+ );
100113
100246
  if (highSeries && lowSeries && closeSeries) {
100114
100247
  const barGroupWidth = layout.plotWidth / catCount;
100115
100248
  const candleWidth = barGroupWidth * 0.5;
@@ -100164,6 +100297,27 @@ function buildStockViewModel(element, chartData, categoryLabels) {
100164
100297
  }
100165
100298
  }
100166
100299
  primitives.push(...horizontalAxis.tickMarks);
100300
+ const displayChartData = horizontalAxis.displayChartData;
100301
+ const overlays = [
100302
+ ...computeTrendlinePrimitives(
100303
+ displayChartData,
100304
+ catCount,
100305
+ layout,
100306
+ range,
100307
+ "bar",
100308
+ chartData.colorPalette
100309
+ ),
100310
+ ...computeErrorBarPrimitives(displayChartData, catCount, layout, range, "bar", {
100311
+ xPositions: horizontalAxis.xPositions
100312
+ }),
100313
+ ...computeAxisTitlePrimitives(chartData, layout)
100314
+ ];
100315
+ const dataTablePrimitives = computeDataTablePrimitives(
100316
+ displayChartData,
100317
+ layout,
100318
+ chartData.colorPalette
100319
+ );
100320
+ primitives.push(...overlays, ...dataTablePrimitives);
100167
100321
  const title = chartData.style?.hasTitle && chartData.title ? chartData.title : void 0;
100168
100322
  return {
100169
100323
  svgWidth: layout.svgWidth,
@@ -100180,7 +100334,9 @@ function buildStockViewModel(element, chartData, categoryLabels) {
100180
100334
  legend: chartData.style?.hasLegend ? legend : [],
100181
100335
  legendX,
100182
100336
  legendY,
100183
- legendAnchor
100337
+ legendAnchor,
100338
+ overlays: overlays.length > 0 ? overlays : void 0,
100339
+ dataTable: dataTablePrimitives.length > 0 ? dataTablePrimitives : void 0
100184
100340
  };
100185
100341
  }
100186
100342
  function percentile(sorted, p, method) {
@@ -101413,7 +101569,8 @@ function buildIsometricSurfaceViewModel(element, chartData, categoryLabels) {
101413
101569
  fill: `rgb(${r},${g},${b})`,
101414
101570
  stroke: "none",
101415
101571
  strokeWidth: 0,
101416
- opacity: 0.9
101572
+ opacity: 0.9,
101573
+ part: { role: "dataPoint", seriesIndex: row, pointIndex: col }
101417
101574
  });
101418
101575
  primitives.push({
101419
101576
  kind: "polygon",
@@ -101468,7 +101625,8 @@ function buildFlatSurfaceViewModel(element, chartData, categoryLabels) {
101468
101625
  w: cellW + 0.5,
101469
101626
  h: cellH + 0.5,
101470
101627
  fill: `rgb(${r},${g},${b})`,
101471
- opacity: 0.85
101628
+ opacity: 0.85,
101629
+ part: { role: "dataPoint", seriesIndex: si, pointIndex: ci }
101472
101630
  });
101473
101631
  }
101474
101632
  }
@@ -101738,6 +101896,7 @@ var WF_COLOR_POSITIVE = "#22c55e";
101738
101896
  var WF_COLOR_NEGATIVE = "#ef4444";
101739
101897
  var WF_COLOR_TOTAL = "#6366f1";
101740
101898
  var WF_CONNECTOR_COLOR = "#94a3b8";
101899
+ var REGION_LEGEND_BANDS = 32;
101741
101900
  function buildWaterfallViewModel(element, chartData, categoryLabels) {
101742
101901
  const layout = computePlotLayout(element.width, element.height, chartData, true);
101743
101902
  const series = chartData.series[0];
@@ -102171,6 +102330,10 @@ function buildRegionMapViewModel(element, chartData, categoryLabels) {
102171
102330
  fill,
102172
102331
  stroke: "#94a3b8",
102173
102332
  strokeWidth: Math.max(0.5 / mapScale, 0.3),
102333
+ // Hover tooltip. A choropleth prints only the value inside the shape
102334
+ // (and only where the shape is big enough), so without this the reader
102335
+ // has no way to find out WHICH country a patch of colour is.
102336
+ title: entry2 ? `${region.name}: ${formatAxisValue2(entry2.value)}` : region.name,
102174
102337
  ...entry2 ? {
102175
102338
  part: {
102176
102339
  role: "dataPoint",
@@ -102203,27 +102366,16 @@ function buildRegionMapViewModel(element, chartData, categoryLabels) {
102203
102366
  const legendY = mapOffsetY + mapAreaH + 4;
102204
102367
  const barW = Math.min(svgWidth * 0.4, 160);
102205
102368
  const barX = (svgWidth - barW) / 2;
102206
- const gradStops = [
102207
- { offset: 0, color: "#dbeafe" },
102208
- { offset: 0.5, color: "#3b82f6" },
102209
- { offset: 1, color: "#1e3a5f" }
102210
- ];
102211
- const stopCount = gradStops.length - 1;
102212
- for (let si = 0; si < stopCount; si++) {
102213
- const stopA = gradStops[si];
102214
- const stopB = gradStops[si + 1];
102215
- if (stopA === void 0 || stopB === void 0) {
102216
- continue;
102217
- }
102218
- const midColor = lerpColor(stopA.color, stopB.color, 0.5);
102369
+ for (let band = 0; band < REGION_LEGEND_BANDS; band++) {
102219
102370
  primitives.push({
102220
102371
  kind: "rect",
102221
- x: barX + stopA.offset * barW,
102372
+ x: barX + band / REGION_LEGEND_BANDS * barW,
102222
102373
  y: legendY,
102223
- w: (stopB.offset - stopA.offset) * barW,
102374
+ // A hair of overlap: adjacent rects on fractional pixel boundaries
102375
+ // otherwise leave hairline gaps once the slide's zoom transform lands.
102376
+ w: barW / REGION_LEGEND_BANDS + 0.5,
102224
102377
  h: 8,
102225
- fill: midColor,
102226
- rx: si === 0 ? 4 : 0
102378
+ fill: sequentialColorScale((band + 0.5) / REGION_LEGEND_BANDS)
102227
102379
  });
102228
102380
  }
102229
102381
  primitives.push(
@@ -102377,7 +102529,7 @@ function paletteColor2(index, colorPalette) {
102377
102529
  const pal = colorPalette && colorPalette.length > 0 ? colorPalette : DEFAULT_PALETTE;
102378
102530
  return pal[index % pal.length];
102379
102531
  }
102380
- function seriesColor22(series, index, colorPalette) {
102532
+ function seriesColor2(series, index, colorPalette) {
102381
102533
  return series.color ?? series.marker?.spPr?.fillColor ?? paletteColor2(index, colorPalette);
102382
102534
  }
102383
102535
  function computeValueRange2(series) {
@@ -102579,7 +102731,7 @@ function buildCategoryLabels(categoryLabels, layout, catSpacing) {
102579
102731
  }
102580
102732
  function buildLegend(series, colorPalette, svgWidth, legendPos, svgHeight, plotTop) {
102581
102733
  const legend = series.map((s, i) => ({
102582
- color: seriesColor22(s, i, colorPalette),
102734
+ color: seriesColor2(s, i, colorPalette),
102583
102735
  label: s.name
102584
102736
  }));
102585
102737
  let legendX = svgWidth / 2;
@@ -102617,7 +102769,7 @@ function computeBarRects(series, catCount, layout, range, colorPalette) {
102617
102769
  y,
102618
102770
  w: singleBarWidth,
102619
102771
  h,
102620
- fill: seriesColor22(series[si], si, colorPalette)
102772
+ fill: seriesColor2(series[si], si, colorPalette)
102621
102773
  });
102622
102774
  }
102623
102775
  }
@@ -102650,7 +102802,7 @@ function computeStackedBarRects(series, catCount, layout, range, colorPalette) {
102650
102802
  y,
102651
102803
  w: barW,
102652
102804
  h,
102653
- fill: seriesColor22(series[si], si, colorPalette),
102805
+ fill: seriesColor2(series[si], si, colorPalette),
102654
102806
  seriesIndex: si,
102655
102807
  pointIndex: ci
102656
102808
  });
@@ -102662,7 +102814,7 @@ function computeStackedBarRects(series, catCount, layout, range, colorPalette) {
102662
102814
  y,
102663
102815
  w: barW,
102664
102816
  h,
102665
- fill: seriesColor22(series[si], si, colorPalette),
102817
+ fill: seriesColor2(series[si], si, colorPalette),
102666
102818
  seriesIndex: si,
102667
102819
  pointIndex: ci
102668
102820
  });
@@ -102790,6 +102942,9 @@ function radarRingPoints(cx, cy, rr, catCount) {
102790
102942
  return `${(cx + rr * Math.cos(angle)).toFixed(2)},${(cy + rr * Math.sin(angle)).toFixed(2)}`;
102791
102943
  }).join(" ");
102792
102944
  }
102945
+ function chartPreserveAspectRatio(kind) {
102946
+ return kind === "pie" || kind === "doughnut" || kind === "radar" || kind === "regionMap" ? "xMidYMid meet" : "none";
102947
+ }
102793
102948
  function resolveChartKind(chartType) {
102794
102949
  switch (chartType) {
102795
102950
  case "bar":
@@ -103102,7 +103257,7 @@ function buildRadarViewModel(element, chartData, categoryLabels) {
103102
103257
  }
103103
103258
  const dataLabels = [];
103104
103259
  chartData.series.forEach((series, si) => {
103105
- const c = seriesColor22(series, si, chartData.colorPalette);
103260
+ const c = seriesColor2(series, si, chartData.colorPalette);
103106
103261
  const pts = computeRadarPoints(series.values, maxVal, radius, cx, cy, catCount);
103107
103262
  if (pts.length === 0) {
103108
103263
  return;
@@ -103342,6 +103497,31 @@ function withChartTitle(chartData, title) {
103342
103497
  style: { ...chartData.style, hasTitle: trimmed.length > 0 }
103343
103498
  };
103344
103499
  }
103500
+ var STYLE_ELEMENT_ID = "pptx-chart-interaction-styles";
103501
+ var INTERACTION_CSS = `
103502
+ .pptx-chart-interactive svg [data-chart-part] { pointer-events: auto; cursor: pointer; }
103503
+ .pptx-chart-interactive svg [data-chart-part]:hover { filter: brightness(1.12); }
103504
+ .pptx-chart-interactive svg [data-chart-part='title'] { cursor: text; }
103505
+ /* A data label is decoration painted ON TOP of the mark it describes, so it
103506
+ must never intercept that mark's click. The treemap made this unmissable -
103507
+ its label sits dead-centre on the cell, so clicking a cell hit the <text> and
103508
+ selected nothing - but every kind's data labels overlap their marks. Only
103509
+ labels are excluded: the chart title is itself a part and stays clickable.
103510
+ Bindings whose chart <svg> is blanket pointer-events:none (React) never saw
103511
+ this; the other three did, which is exactly why the rule belongs here. */
103512
+ .pptx-chart-interactive svg text:not([data-chart-part]) { pointer-events: none; }
103513
+ .pptx-chart-interactive svg .pptx-chart-part-selected { filter: drop-shadow(0 0 2.5px #3b82f6); }
103514
+ .pptx-chart-interactive svg .pptx-chart-part-selected:hover { filter: drop-shadow(0 0 2.5px #3b82f6) brightness(1.12); }
103515
+ `;
103516
+ function ensureChartInteractionStyles() {
103517
+ if (typeof document === "undefined" || document.getElementById(STYLE_ELEMENT_ID)) {
103518
+ return;
103519
+ }
103520
+ const style = document.createElement("style");
103521
+ style.id = STYLE_ELEMENT_ID;
103522
+ style.textContent = INTERACTION_CSS;
103523
+ document.head.appendChild(style);
103524
+ }
103345
103525
  var HARD_STOP = "#000 50%, transparent 50%";
103346
103526
  var EDGE_CONFIG = {
103347
103527
  left: {
@@ -107848,6 +108028,27 @@ function tableCellCss(tableData, cell, position2, context, base) {
107848
108028
  }
107849
108029
  return css;
107850
108030
  }
108031
+ function withCellText(cell, text2) {
108032
+ const next = { ...cell, text: text2 };
108033
+ delete next.textRuns;
108034
+ return next;
108035
+ }
108036
+ function setCellText(element, rowIndex, colIndex, text2) {
108037
+ const tableData = element.tableData;
108038
+ if (!tableData) {
108039
+ return element;
108040
+ }
108041
+ const rows = tableData.rows.map((row, ri) => {
108042
+ if (ri !== rowIndex) {
108043
+ return row;
108044
+ }
108045
+ return {
108046
+ ...row,
108047
+ cells: row.cells.map((cell, ci) => ci === colIndex ? withCellText(cell, text2) : cell)
108048
+ };
108049
+ });
108050
+ return { ...element, tableData: { ...tableData, rows } };
108051
+ }
107851
108052
  function computeBoundingRect(cells) {
107852
108053
  if (cells.length === 0) {
107853
108054
  return void 0;
@@ -107980,8 +108181,7 @@ function mergeCells(cells, tableData) {
107980
108181
  }
107981
108182
  if (ri === rect2.startRow && ci === rect2.startCol) {
107982
108183
  return {
107983
- ...cell,
107984
- text: combinedText,
108184
+ ...withCellText(cell, combinedText),
107985
108185
  gridSpan: colCount > 1 ? colCount : void 0,
107986
108186
  rowSpan: rowCount > 1 ? rowCount : void 0,
107987
108187
  hMerge: void 0,
@@ -107990,8 +108190,7 @@ function mergeCells(cells, tableData) {
107990
108190
  }
107991
108191
  if (ri === rect2.startRow) {
107992
108192
  return {
107993
- ...cell,
107994
- text: "",
108193
+ ...withCellText(cell, ""),
107995
108194
  hMerge: true,
107996
108195
  vMerge: void 0,
107997
108196
  gridSpan: void 0,
@@ -108000,8 +108199,7 @@ function mergeCells(cells, tableData) {
108000
108199
  }
108001
108200
  if (ci === rect2.startCol) {
108002
108201
  return {
108003
- ...cell,
108004
- text: "",
108202
+ ...withCellText(cell, ""),
108005
108203
  vMerge: true,
108006
108204
  hMerge: void 0,
108007
108205
  gridSpan: void 0,
@@ -108009,8 +108207,7 @@ function mergeCells(cells, tableData) {
108009
108207
  };
108010
108208
  }
108011
108209
  return {
108012
- ...cell,
108013
- text: "",
108210
+ ...withCellText(cell, ""),
108014
108211
  hMerge: true,
108015
108212
  vMerge: true,
108016
108213
  gridSpan: void 0,
@@ -108288,22 +108485,6 @@ function deleteTableColumn(tableData, colIdx) {
108288
108485
  const newWidths = normalizeWidths(tableData.columnWidths.filter((_, i) => i !== colIdx));
108289
108486
  return { ...tableData, rows: newRows, columnWidths: newWidths };
108290
108487
  }
108291
- function setCellText(element, rowIndex, colIndex, text2) {
108292
- const tableData = element.tableData;
108293
- if (!tableData) {
108294
- return element;
108295
- }
108296
- const rows = tableData.rows.map((row, ri) => {
108297
- if (ri !== rowIndex) {
108298
- return row;
108299
- }
108300
- return {
108301
- ...row,
108302
- cells: row.cells.map((cell, ci) => ci === colIndex ? { ...cell, text: text2 } : cell)
108303
- };
108304
- });
108305
- return { ...element, tableData: { ...tableData, rows } };
108306
- }
108307
108488
  function buildTableDataGrid(element) {
108308
108489
  const tableData = element.tableData;
108309
108490
  const sourceRows = tableData?.rows ?? [];
@@ -109722,12 +109903,21 @@ var translationsEn = {
109722
109903
  "pptx.autosave.disabled": "AutoSave unavailable",
109723
109904
  "pptx.autosave.disabledNoFilePath": "AutoSave disabled: no file path provided",
109724
109905
  "pptx.autosave.disabledToggleOff": "AutoSave off",
109906
+ "pptx.autosave.disabledByHost": "AutoSave turned off by this application",
109907
+ "pptx.autosave.disabledReadOnly": "AutoSave disabled: this presentation is read-only",
109725
109908
  "pptx.autosave.justNow": "just now",
109726
109909
  "pptx.autosave.oneMinAgo": "1 min ago",
109727
109910
  "pptx.autosave.minutesAgo": "{{count}} min ago",
109728
109911
  "pptx.autosave.saveFailed": "Save failed",
109729
109912
  "pptx.autosave.savedShort": "Saved",
109730
109913
  "pptx.autosave.allChangesSaved": "All changes saved",
109914
+ // Crash-recovery prompt (offered on load when a newer snapshot exists)
109915
+ "pptx.autosave.recovery.title": "Recover unsaved changes?",
109916
+ "pptx.autosave.recovery.message": 'An autosaved copy of "{{file}}" ({{size}}) has changes that are not in the version you just opened.',
109917
+ "pptx.autosave.recovery.savedLabel": "Autosaved {{when}}",
109918
+ "pptx.autosave.recovery.hoursAgo": "{{count}} h ago",
109919
+ "pptx.autosave.recovery.restore": "Restore",
109920
+ "pptx.autosave.recovery.discard": "Discard",
109731
109921
  // Title bar (PowerPoint-style top chrome row)
109732
109922
  "pptx.titleBar.autoSave": "AutoSave",
109733
109923
  "pptx.titleBar.autoSaveOn": "On",
@@ -115636,6 +115826,22 @@ function hollowTextFillStyle(s, painted = {}) {
115636
115826
  }
115637
115827
  return hollow;
115638
115828
  }
115829
+ function nestedTextDecorationStyle(style) {
115830
+ const nested = {};
115831
+ for (const key2 of [
115832
+ "textDecoration",
115833
+ "textDecorationLine",
115834
+ "textDecorationColor",
115835
+ "textDecorationStyle",
115836
+ "textDecorationThickness"
115837
+ ]) {
115838
+ const value = style[key2];
115839
+ if (value !== void 0) {
115840
+ nested[key2] = value;
115841
+ }
115842
+ }
115843
+ return Object.keys(nested).length > 0 ? nested : void 0;
115844
+ }
115639
115845
  function segmentStyleToCss(seg, fontScale = 1, context = {}) {
115640
115846
  const s = seg.style ?? {};
115641
115847
  const style = {};
@@ -116148,16 +116354,51 @@ function correspondingChildren(a, b) {
116148
116354
  }
116149
116355
  return paired;
116150
116356
  }
116357
+ function expandUnpairedWrappers(children7, counterpart) {
116358
+ let expanded = false;
116359
+ const out = [];
116360
+ for (const child23 of children7) {
116361
+ const nested = groupChildren(child23);
116362
+ if (nested && !correspondingGroup(child23, counterpart)) {
116363
+ expanded = true;
116364
+ for (const leaf of expandUnpairedWrappers(nested, counterpart) ?? nested) {
116365
+ out.push(toAbsolute(leaf, child23.x, child23.y));
116366
+ }
116367
+ continue;
116368
+ }
116369
+ out.push(child23);
116370
+ }
116371
+ return expanded ? out : void 0;
116372
+ }
116373
+ function correspondingCast(children7, twinChildren) {
116374
+ const direct = correspondingChildren(children7, twinChildren);
116375
+ if (direct) {
116376
+ return { from: [...children7], to: [...twinChildren], paired: direct };
116377
+ }
116378
+ const expandedFrom = expandUnpairedWrappers(children7, twinChildren);
116379
+ const expandedTo = expandUnpairedWrappers(twinChildren, children7);
116380
+ if (!expandedFrom && !expandedTo) {
116381
+ return void 0;
116382
+ }
116383
+ const from = expandedFrom ?? [...children7];
116384
+ const to = expandedTo ?? [...twinChildren];
116385
+ const paired = correspondingChildren(from, to);
116386
+ return paired ? { from, to, paired } : void 0;
116387
+ }
116151
116388
  function flattenMorphElements(elements, counterpart, offsetX = 0, offsetY = 0) {
116389
+ return flattenMorphLevel(elements, counterpart, offsetX, offsetY, true);
116390
+ }
116391
+ function flattenMorphLevel(elements, counterpart, offsetX, offsetY, topLevel) {
116152
116392
  const out = [];
116153
116393
  for (const element of elements) {
116154
116394
  const children7 = groupChildren(element);
116155
- if (children7 && containsMorphNamedDescendant(element)) {
116395
+ if (children7 && (!topLevel || containsMorphNamedDescendant(element))) {
116156
116396
  const twin = correspondingGroup(element, counterpart);
116157
116397
  const twinChildren = twin ? groupChildren(twin) ?? [] : void 0;
116158
- if (twinChildren && correspondingChildren(children7, twinChildren)) {
116398
+ const cast = twinChildren ? correspondingCast(children7, twinChildren) : void 0;
116399
+ if (cast) {
116159
116400
  out.push(
116160
- ...flattenMorphElements(children7, twinChildren, offsetX + element.x, offsetY + element.y)
116401
+ ...flattenMorphLevel(cast.from, cast.to, offsetX + element.x, offsetY + element.y, false)
116161
116402
  );
116162
116403
  continue;
116163
116404
  }
@@ -116168,25 +116409,25 @@ function flattenMorphElements(elements, counterpart, offsetX = 0, offsetY = 0) {
116168
116409
  }
116169
116410
  function morphGroupChildPairs(elements, counterpart) {
116170
116411
  const pairs2 = /* @__PURE__ */ new Map();
116171
- collectGroupChildPairs(elements, counterpart, pairs2);
116412
+ collectGroupChildPairs(elements, counterpart, pairs2, true);
116172
116413
  return pairs2;
116173
116414
  }
116174
- function collectGroupChildPairs(elements, counterpart, into) {
116415
+ function collectGroupChildPairs(elements, counterpart, into, topLevel) {
116175
116416
  for (const element of elements) {
116176
116417
  const children7 = groupChildren(element);
116177
- if (!children7 || !containsMorphNamedDescendant(element)) {
116418
+ if (!children7 || topLevel && !containsMorphNamedDescendant(element)) {
116178
116419
  continue;
116179
116420
  }
116180
116421
  const twin = correspondingGroup(element, counterpart);
116181
116422
  const twinChildren = twin ? groupChildren(twin) ?? [] : void 0;
116182
- const corresponded = twinChildren ? correspondingChildren(children7, twinChildren) : void 0;
116183
- if (!corresponded) {
116423
+ const cast = twinChildren ? correspondingCast(children7, twinChildren) : void 0;
116424
+ if (!cast) {
116184
116425
  continue;
116185
116426
  }
116186
- for (const [child23, twinChild] of corresponded) {
116427
+ for (const [child23, twinChild] of cast.paired) {
116187
116428
  into.set(child23.id, twinChild.id);
116188
116429
  }
116189
- collectGroupChildPairs(children7, twinChildren ?? [], into);
116430
+ collectGroupChildPairs(cast.from, cast.to, into, false);
116190
116431
  }
116191
116432
  }
116192
116433
  var OUTLINE_SAMPLE_COUNT = 64;
@@ -124492,268 +124733,6 @@ async function mountModel3D(container, modelUrl, options) {
124492
124733
  }
124493
124734
  };
124494
124735
  }
124495
- var GRID_SPACING = 0.5;
124496
- var MAX_HEIGHT = 1.5;
124497
- function computeGridExtent(cols, rows) {
124498
- return {
124499
- gridWidth: Math.max(cols - 1, 1) * GRID_SPACING,
124500
- gridDepth: Math.max(rows - 1, 1) * GRID_SPACING
124501
- };
124502
- }
124503
- function buildSurfaceGeometry(three, cols, rows, heightMap, colorMap) {
124504
- const widthSegs = Math.max(cols - 1, 0);
124505
- const depthSegs = Math.max(rows - 1, 0);
124506
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
124507
- const geo = new three.PlaneGeometry(gridWidth, gridDepth, widthSegs, depthSegs);
124508
- geo.rotateX(-Math.PI / 2);
124509
- const pos2 = geo.attributes.position;
124510
- const vertexCount = pos2.count;
124511
- const colors = new Float32Array(vertexCount * 3);
124512
- for (let i = 0; i < vertexCount; i++) {
124513
- const row = Math.floor(i / cols);
124514
- const col = i % cols;
124515
- const idx = row * cols + col;
124516
- const h = idx < heightMap.length ? heightMap[idx] : 0;
124517
- pos2.setY(i, h * MAX_HEIGHT);
124518
- const ci = idx * 3;
124519
- colors[i * 3] = ci < colorMap.length ? colorMap[ci] : 0.5;
124520
- colors[i * 3 + 1] = ci + 1 < colorMap.length ? colorMap[ci + 1] : 0.5;
124521
- colors[i * 3 + 2] = ci + 2 < colorMap.length ? colorMap[ci + 2] : 0.5;
124522
- }
124523
- geo.setAttribute("color", new three.BufferAttribute(colors, 3));
124524
- geo.computeVertexNormals();
124525
- pos2.needsUpdate = true;
124526
- const wireGeometry = new three.WireframeGeometry(geo);
124527
- return { geometry: geo, wireGeometry };
124528
- }
124529
- function buildSurfaceLabels(cols, rows, categoryLabels, seriesNames, maxCat = 8, maxSer = 6) {
124530
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
124531
- const labels = [];
124532
- const catStep = Math.max(1, Math.ceil(categoryLabels.length / maxCat));
124533
- for (let i = 0; i < categoryLabels.length; i += catStep) {
124534
- const x = -gridWidth / 2 + i / Math.max(cols - 1, 1) * gridWidth;
124535
- labels.push({
124536
- key: `cat-${i}`,
124537
- text: categoryLabels[i],
124538
- anchor: [x, -0.15, gridDepth / 2 + 0.25],
124539
- axis: "category"
124540
- });
124541
- }
124542
- const serStep = Math.max(1, Math.ceil(seriesNames.length / maxSer));
124543
- for (let i = 0; i < seriesNames.length; i += serStep) {
124544
- const z = -gridDepth / 2 + i / Math.max(rows - 1, 1) * gridDepth;
124545
- labels.push({
124546
- key: `ser-${i}`,
124547
- text: seriesNames[i],
124548
- anchor: [gridWidth / 2 + 0.3, -0.15, z],
124549
- axis: "series"
124550
- });
124551
- }
124552
- labels.push({
124553
- key: "value-axis",
124554
- text: "Value",
124555
- anchor: [-gridWidth / 2 - 0.35, 0.75, -gridDepth / 2],
124556
- axis: "value"
124557
- });
124558
- return labels;
124559
- }
124560
- function computeCameraPlacement(cols, rows) {
124561
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
124562
- const maxExtent = Math.max(gridWidth, gridDepth, MAX_HEIGHT);
124563
- const dist2 = maxExtent * 1.8;
124564
- return {
124565
- position: [dist2 * 0.8, dist2 * 0.7, dist2 * 0.8],
124566
- target: [0, 0.3, 0]
124567
- };
124568
- }
124569
- var SURFACE_THREE_UNAVAILABLE = {
124570
- ok: false,
124571
- resize: () => {
124572
- },
124573
- dispose: () => {
124574
- }
124575
- };
124576
- var FOV2 = 45;
124577
- async function loadThree2() {
124578
- try {
124579
- return await import('./three.module-GNNNRIMK.js');
124580
- } catch {
124581
- return null;
124582
- }
124583
- }
124584
- async function loadOrbitControlsCtor2() {
124585
- try {
124586
- const mod = await import('./OrbitControls-SMYCPLXO.js');
124587
- return mod.OrbitControls;
124588
- } catch {
124589
- return null;
124590
- }
124591
- }
124592
- function createLabelOverlay(doc, labels) {
124593
- const layer = doc.createElement("div");
124594
- Object.assign(layer.style, {
124595
- position: "absolute",
124596
- inset: "0",
124597
- pointerEvents: "none",
124598
- overflow: "hidden"
124599
- });
124600
- const nodes = labels.map((label) => {
124601
- const node = doc.createElement("div");
124602
- node.textContent = label.text;
124603
- const color2 = label.axis === "value" ? "#999" : "#666";
124604
- Object.assign(node.style, {
124605
- position: "absolute",
124606
- fontSize: "9px",
124607
- color: color2,
124608
- whiteSpace: "nowrap",
124609
- userSelect: "none",
124610
- transform: "translate(-50%, -50%)",
124611
- willChange: "left, top"
124612
- });
124613
- if (label.axis === "value") {
124614
- node.style.writingMode = "vertical-rl";
124615
- }
124616
- layer.appendChild(node);
124617
- return node;
124618
- });
124619
- return { layer, nodes };
124620
- }
124621
- async function mountSurfaceChart3D(container, options) {
124622
- const three = await loadThree2();
124623
- const OrbitCtrlCtor = three ? await loadOrbitControlsCtor2() : null;
124624
- if (!three || !OrbitCtrlCtor) {
124625
- return SURFACE_THREE_UNAVAILABLE;
124626
- }
124627
- const { cols, rows } = options;
124628
- let width = Math.max(1, options.width);
124629
- let height = Math.max(1, options.height);
124630
- const renderer = new three.WebGLRenderer({ antialias: true, alpha: true });
124631
- renderer.setPixelRatio(
124632
- Math.min(
124633
- typeof window === "undefined" ? 1 : window.devicePixelRatio || 1,
124634
- options.maxPixelRatio ?? 2
124635
- )
124636
- );
124637
- renderer.setSize(width, height, false);
124638
- const canvas = renderer.domElement;
124639
- canvas.style.width = `${width}px`;
124640
- canvas.style.height = `${height}px`;
124641
- canvas.style.display = "block";
124642
- canvas.style.willChange = "transform";
124643
- container.appendChild(canvas);
124644
- const scene = new three.Scene();
124645
- scene.add(new three.AmbientLight(16777215, 0.6));
124646
- const key2 = new three.DirectionalLight(16777215, 0.8);
124647
- key2.position.set(5, 8, 5);
124648
- scene.add(key2);
124649
- const fill = new three.DirectionalLight(16777215, 0.3);
124650
- fill.position.set(-3, 4, -2);
124651
- scene.add(fill);
124652
- const camera = new three.PerspectiveCamera(FOV2, width / height, 0.1, 1e3);
124653
- const placement = computeCameraPlacement(cols, rows);
124654
- camera.position.set(...placement.position);
124655
- const target = new three.Vector3(...placement.target);
124656
- camera.lookAt(target);
124657
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
124658
- const floorSize = Math.max(gridWidth, gridDepth) * 1.2;
124659
- const gridFloor = new three.GridHelper(floorSize, Math.max(cols, rows), 13421772, 15263976);
124660
- gridFloor.position.y = -0.02;
124661
- scene.add(gridFloor);
124662
- const { geometry, wireGeometry } = buildSurfaceGeometry(
124663
- three,
124664
- cols,
124665
- rows,
124666
- options.heightMap,
124667
- options.colorMap
124668
- );
124669
- const surfaceMaterial = new three.MeshPhongMaterial({
124670
- vertexColors: true,
124671
- side: three.DoubleSide,
124672
- shininess: 30,
124673
- transparent: true,
124674
- opacity: 0.92
124675
- });
124676
- const surfaceMesh = new three.Mesh(geometry, surfaceMaterial);
124677
- scene.add(surfaceMesh);
124678
- let wireMaterial = null;
124679
- if (options.wireframe) {
124680
- wireMaterial = new three.LineBasicMaterial({
124681
- color: 3355443,
124682
- transparent: true,
124683
- opacity: 0.25
124684
- });
124685
- scene.add(new three.LineSegments(wireGeometry, wireMaterial));
124686
- }
124687
- const controls = new OrbitCtrlCtor(camera, canvas);
124688
- controls.enablePan = true;
124689
- controls.enableZoom = true;
124690
- controls.enableRotate = true;
124691
- controls.minDistance = 1;
124692
- controls.maxDistance = 20;
124693
- controls.maxPolarAngle = Math.PI / 2 + 0.3;
124694
- controls.target.copy(target);
124695
- controls.update();
124696
- const doc = container.ownerDocument ?? document;
124697
- const labels = buildSurfaceLabels(cols, rows, options.categoryLabels, options.seriesNames);
124698
- const { layer, nodes } = createLabelOverlay(doc, labels);
124699
- container.appendChild(layer);
124700
- const anchors = labels.map((l) => new three.Vector3(...l.anchor));
124701
- const projected = new three.Vector3();
124702
- const updateLabels = () => {
124703
- for (let i = 0; i < nodes.length; i++) {
124704
- projected.copy(anchors[i]).project(camera);
124705
- const node = nodes[i];
124706
- if (projected.z > 1) {
124707
- node.style.display = "none";
124708
- continue;
124709
- }
124710
- node.style.display = "";
124711
- node.style.left = `${(projected.x + 1) / 2 * width}px`;
124712
- node.style.top = `${(-projected.y + 1) / 2 * height}px`;
124713
- }
124714
- };
124715
- let frame2 = 0;
124716
- let disposed = false;
124717
- const renderLoop = () => {
124718
- if (disposed) {
124719
- return;
124720
- }
124721
- frame2 = requestAnimationFrame(renderLoop);
124722
- controls.update();
124723
- renderer.render(scene, camera);
124724
- updateLabels();
124725
- };
124726
- frame2 = requestAnimationFrame(renderLoop);
124727
- return {
124728
- ok: true,
124729
- resize(w, h) {
124730
- width = Math.max(1, w);
124731
- height = Math.max(1, h);
124732
- camera.aspect = width / height;
124733
- camera.updateProjectionMatrix();
124734
- renderer.setSize(width, height, false);
124735
- canvas.style.width = `${width}px`;
124736
- canvas.style.height = `${height}px`;
124737
- },
124738
- dispose() {
124739
- if (disposed) {
124740
- return;
124741
- }
124742
- disposed = true;
124743
- cancelAnimationFrame(frame2);
124744
- controls.dispose();
124745
- geometry.dispose();
124746
- wireGeometry.dispose();
124747
- surfaceMaterial.dispose();
124748
- wireMaterial?.dispose();
124749
- gridFloor.dispose();
124750
- scene.clear();
124751
- renderer.dispose();
124752
- canvas.remove();
124753
- layer.remove();
124754
- }
124755
- };
124756
- }
124757
124736
  var AVERAGE_ADVANCE_RATIO = 0.5;
124758
124737
  function wrapTextByEstimatedWidth(text2, maxWidth, fontSize, options = {}) {
124759
124738
  if (!text2 || text2.trim().length === 0) {
@@ -125156,6 +125135,7 @@ function savedPresentationFileName(sourceName, format = "pptx") {
125156
125135
  var AUTOSAVE_DB_NAME = "pptx-viewer-autosave";
125157
125136
  var AUTOSAVE_DB_VERSION = 1;
125158
125137
  var AUTOSAVE_STORE_NAME = "recoveryVersions";
125138
+ var AUTOSAVE_DEFAULT_INTERVAL_SECONDS = 120;
125159
125139
  var AUTOSAVE_MIN_INTERVAL_SECONDS = 10;
125160
125140
  function openAutosaveDb() {
125161
125141
  return new Promise((resolve2, reject) => {
@@ -125319,6 +125299,117 @@ async function saveAutosaveSnapshot(filePath, data) {
125319
125299
  return putAutosaveRecord(filePath, data);
125320
125300
  }
125321
125301
  }
125302
+ var AUTOSAVE_RECOVERY_WINDOW_MS = 24 * 60 * 60 * 1e3;
125303
+ var CONSUMED_KEY = "pptx-viewer-recovery-consumed";
125304
+ function markAutosaveSnapshotConsumed(timestamp) {
125305
+ try {
125306
+ if (typeof sessionStorage === "undefined" || !Number.isFinite(timestamp)) {
125307
+ return;
125308
+ }
125309
+ const previous = consumedAutosaveSnapshotTimestamp();
125310
+ if (timestamp > previous) {
125311
+ sessionStorage.setItem(CONSUMED_KEY, String(timestamp));
125312
+ }
125313
+ } catch {
125314
+ }
125315
+ }
125316
+ function consumedAutosaveSnapshotTimestamp() {
125317
+ try {
125318
+ if (typeof sessionStorage === "undefined") {
125319
+ return 0;
125320
+ }
125321
+ const raw = sessionStorage.getItem(CONSUMED_KEY);
125322
+ const value = raw === null ? Number.NaN : Number(raw);
125323
+ return Number.isFinite(value) ? value : 0;
125324
+ } catch {
125325
+ return 0;
125326
+ }
125327
+ }
125328
+ function shouldProbeAutosaveRecovery(input) {
125329
+ return !input.alreadyChecked && input.autosaveAllowed && Boolean(input.filePath) && !input.loading && !input.error && input.slideCount > 0;
125330
+ }
125331
+ function formatSnapshotSize(bytes) {
125332
+ if (!Number.isFinite(bytes) || bytes <= 0) {
125333
+ return "0 KB";
125334
+ }
125335
+ if (bytes < 1024 * 1024) {
125336
+ return `${Math.max(1, Math.round(bytes / 1024))} KB`;
125337
+ }
125338
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
125339
+ }
125340
+ function ageKeyFor(ageMinutes) {
125341
+ if (ageMinutes < 1) {
125342
+ return { key: "pptx.autosave.justNow", count: 0 };
125343
+ }
125344
+ if (ageMinutes === 1) {
125345
+ return { key: "pptx.autosave.oneMinAgo", count: 1 };
125346
+ }
125347
+ if (ageMinutes < 60) {
125348
+ return { key: "pptx.autosave.minutesAgo", count: ageMinutes };
125349
+ }
125350
+ return { key: "pptx.autosave.recovery.hoursAgo", count: Math.floor(ageMinutes / 60) };
125351
+ }
125352
+ function autosaveRecoveryPrompt(input) {
125353
+ const record = input.record;
125354
+ if (!record || record.size <= 0 || !record.key) {
125355
+ return null;
125356
+ }
125357
+ const age = input.now - record.timestamp;
125358
+ if (!Number.isFinite(age) || age < 0 || age >= AUTOSAVE_RECOVERY_WINDOW_MS) {
125359
+ return null;
125360
+ }
125361
+ if (record.timestamp <= (input.consumedTimestamp ?? 0)) {
125362
+ return null;
125363
+ }
125364
+ const ageMinutes = Math.floor(age / 6e4);
125365
+ const relative = ageKeyFor(ageMinutes);
125366
+ return {
125367
+ filePath: record.key,
125368
+ timestamp: record.timestamp,
125369
+ size: record.size,
125370
+ ageMinutes,
125371
+ titleKey: "pptx.autosave.recovery.title",
125372
+ messageKey: "pptx.autosave.recovery.message",
125373
+ messageParams: { file: record.key, size: formatSnapshotSize(record.size) },
125374
+ ageKey: relative.key,
125375
+ ageParams: { count: relative.count },
125376
+ restoreKey: "pptx.autosave.recovery.restore",
125377
+ discardKey: "pptx.autosave.recovery.discard"
125378
+ };
125379
+ }
125380
+ function shouldShowAutosaveRecoveryPrompt(input) {
125381
+ return Boolean(input.prompt) && !input.presenting;
125382
+ }
125383
+ async function probeAutosaveRecovery(filePath, now = Date.now()) {
125384
+ if (typeof indexedDB === "undefined") {
125385
+ return null;
125386
+ }
125387
+ try {
125388
+ const record = await getAutosaveSnapshot(filePath);
125389
+ const prompt = autosaveRecoveryPrompt({
125390
+ record: record ? { key: record.key, timestamp: record.timestamp, size: record.size } : void 0,
125391
+ now,
125392
+ consumedTimestamp: consumedAutosaveSnapshotTimestamp()
125393
+ });
125394
+ if (!prompt || !record) {
125395
+ return null;
125396
+ }
125397
+ return { prompt, record };
125398
+ } catch {
125399
+ return null;
125400
+ }
125401
+ }
125402
+ function acceptAutosaveRecovery(record) {
125403
+ markAutosaveSnapshotConsumed(record.timestamp);
125404
+ return record.data instanceof Uint8Array ? record.data : new Uint8Array(record.data);
125405
+ }
125406
+ async function discardAutosaveRecovery(record) {
125407
+ markAutosaveSnapshotConsumed(record.timestamp);
125408
+ try {
125409
+ await deleteAutosaveSnapshot(record.key);
125410
+ } catch {
125411
+ }
125412
+ }
125322
125413
  function secureRandomBytes(length) {
125323
125414
  const bytes = new Uint8Array(length);
125324
125415
  if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
@@ -125517,6 +125608,7 @@ async function restoreSessionDeck() {
125517
125608
  const snapshot = await getAutosaveSnapshot(deck.fileName);
125518
125609
  const bytes = snapshot ? toBytes(snapshot.data) : null;
125519
125610
  if (snapshot && bytes && bytes.byteLength > 0 && snapshot.timestamp > deck.timestamp) {
125611
+ markAutosaveSnapshotConsumed(snapshot.timestamp);
125520
125612
  return { fileName: deck.fileName, data: bytes, timestamp: snapshot.timestamp };
125521
125613
  }
125522
125614
  } catch {
@@ -126907,11 +126999,13 @@ var TITLE_PH_TYPES = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
126907
126999
  var CHROME_PH_TYPES = /* @__PURE__ */ new Set(["ftr", "hdr", "dt", "sldnum"]);
126908
127000
  var OUTLINE_TITLE_ELEMENT_NAME = "Title";
126909
127001
  function placeholderType(element) {
126910
- const ph = element.rawXml?.["p:nvSpPr"]?.["p:nvPr"]?.["p:ph"];
126911
- if (!ph) {
127002
+ const nvPr = element.rawXml?.["p:nvSpPr"]?.["p:nvPr"];
127003
+ const ph = nvPr === void 0 || typeof nvPr === "string" ? void 0 : nvPr["p:ph"];
127004
+ if (ph === void 0) {
126912
127005
  return void 0;
126913
127006
  }
126914
- const type = typeof ph["@_type"] === "string" ? ph["@_type"].trim().toLowerCase() : "";
127007
+ const rawType = typeof ph === "object" && ph !== null ? ph["@_type"] : void 0;
127008
+ const type = typeof rawType === "string" ? rawType.trim().toLowerCase() : "";
126915
127009
  return type.length > 0 ? type : "body";
126916
127010
  }
126917
127011
  function isTextBearing(element) {
@@ -130742,6 +130836,34 @@ function shouldWriteAutosaveSnapshot(input) {
130742
130836
  }
130743
130837
  return input.sources.some((source, index) => !Object.is(source, previous.sources[index]));
130744
130838
  }
130839
+ function resolveAutosaveActivation(input) {
130840
+ if (input.hostAutosave === false) {
130841
+ return { active: false, toggleAvailable: false, reason: "autosave_host_off" };
130842
+ }
130843
+ if (!input.userEnabled) {
130844
+ return { active: false, toggleAvailable: true, reason: "autosave_toggle_off" };
130845
+ }
130846
+ if (!input.filePath) {
130847
+ return { active: false, toggleAvailable: true, reason: "no_file_path" };
130848
+ }
130849
+ if (!input.canEdit) {
130850
+ return { active: false, toggleAvailable: true, reason: "read_only" };
130851
+ }
130852
+ return { active: true, toggleAvailable: true };
130853
+ }
130854
+ var AUTOSAVE_DEFAULT_INTERVAL_MS = AUTOSAVE_DEFAULT_INTERVAL_SECONDS * 1e3;
130855
+ var HOST_INTERVAL_FLOOR_MS = 50;
130856
+ function resolveAutosaveIntervalMs(input) {
130857
+ const host = input.hostIntervalMs;
130858
+ if (typeof host === "number" && Number.isFinite(host)) {
130859
+ return Math.max(HOST_INTERVAL_FLOOR_MS, host);
130860
+ }
130861
+ const seconds = input.optionsIntervalSeconds;
130862
+ if (typeof seconds === "number" && Number.isFinite(seconds)) {
130863
+ return Math.max(AUTOSAVE_MIN_INTERVAL_SECONDS, seconds) * 1e3;
130864
+ }
130865
+ return AUTOSAVE_DEFAULT_INTERVAL_MS;
130866
+ }
130745
130867
  var BACKSTAGE_NAV = [
130746
130868
  { id: "home", label: "Home", labelKey: "pptx.backstage.nav.home" },
130747
130869
  { id: "new", label: "New", labelKey: "pptx.backstage.nav.new" },
@@ -134105,6 +134227,7 @@ exports.VIEWER_OPTIONS_TABS = VIEWER_OPTIONS_TABS;
134105
134227
  exports.VIEWER_PREFS_STORAGE_KEY = VIEWER_PREFS_STORAGE_KEY;
134106
134228
  exports.VIEWER_SHORTCUT_REFERENCE = VIEWER_SHORTCUT_REFERENCE;
134107
134229
  exports.WEBM_MIME_CANDIDATES = WEBM_MIME_CANDIDATES;
134230
+ exports.acceptAutosaveRecovery = acceptAutosaveRecovery;
134108
134231
  exports.acceptsPresentationInput = acceptsPresentationInput;
134109
134232
  exports.actionAffordanceLabels = actionAffordanceLabels;
134110
134233
  exports.activateModalFocus = activateModalFocus;
@@ -134207,9 +134330,9 @@ exports.canvasToJpegData = canvasToJpegData;
134207
134330
  exports.cellRunStyle = cellRunStyle;
134208
134331
  exports.cellStyleToCss = cellStyleToCss;
134209
134332
  exports.centeredSvgTextLines = centeredSvgTextLines;
134210
- exports.chartAreaFill = chartAreaFill;
134211
134333
  exports.chartDataChangeType = chartDataChangeType;
134212
134334
  exports.chartPartToAttrs = chartPartToAttrs;
134335
+ exports.chartPreserveAspectRatio = chartPreserveAspectRatio;
134213
134336
  exports.clampCropValue = clampCropValue;
134214
134337
  exports.clampNotesFontSize = clampNotesFontSize;
134215
134338
  exports.clampPercent = clampPercent;
@@ -134242,8 +134365,6 @@ exports.computeEntranceAnimationDelay = computeEntranceAnimationDelay;
134242
134365
  exports.computeHandoutLayout = computeHandoutLayout;
134243
134366
  exports.computeInlineEditorRect = computeInlineEditorRect;
134244
134367
  exports.computeKeyboardInset = computeKeyboardInset;
134245
- exports.computeLayout = computeLayout;
134246
- exports.computeLayoutOptions = computeLayoutOptions;
134247
134368
  exports.computeMarqueeHitIds = computeMarqueeHitIds;
134248
134369
  exports.computeMergeCellDown = computeMergeCellDown;
134249
134370
  exports.computeMergeCellRight = computeMergeCellRight;
@@ -134254,8 +134375,6 @@ exports.computeSelectionRect = computeSelectionRect;
134254
134375
  exports.computeSmartArtLayout = computeSmartArtLayout2;
134255
134376
  exports.computeSnapToShape = computeSnapToShape;
134256
134377
  exports.computeSplitCell = computeSplitCell;
134257
- exports.computeValueRange = computeValueRange;
134258
- exports.computeValueRangeForChart = computeValueRangeForChart;
134259
134378
  exports.computeVirtualRange = computeVirtualRange;
134260
134379
  exports.convertLatexToOmml = convertLatexToOmml;
134261
134380
  exports.convertOmmlToLatex = convertOmmlToLatex;
@@ -134292,6 +134411,7 @@ exports.deriveSlideFieldContext = deriveSlideFieldContext;
134292
134411
  exports.describeFontEmbedding = describeFontEmbedding;
134293
134412
  exports.detectOrientation = detectOrientation;
134294
134413
  exports.detectTouchDevice = detectTouchDevice;
134414
+ exports.discardAutosaveRecovery = discardAutosaveRecovery;
134295
134415
  exports.distributeElements = distributeElements;
134296
134416
  exports.downloadBlob = downloadBlob;
134297
134417
  exports.downloadDataUrl = downloadDataUrl;
@@ -134303,6 +134423,7 @@ exports.embeddedFontSaveOptions = embeddedFontSaveOptions;
134303
134423
  exports.encodeGif = encodeGif;
134304
134424
  exports.endAudienceDisplay = endAudienceDisplay;
134305
134425
  exports.ensureActionAffordanceStyles = ensureActionAffordanceStyles;
134426
+ exports.ensureChartInteractionStyles = ensureChartInteractionStyles;
134306
134427
  exports.erasePresentationInkAt = erasePresentationInkAt;
134307
134428
  exports.escapeHtml2 = escapeHtml22;
134308
134429
  exports.exportDeckJson = exportDeckJson;
@@ -134321,7 +134442,6 @@ exports.flattenNodes = flattenNodes;
134321
134442
  exports.flattenTagCollections = flattenTagCollections;
134322
134443
  exports.forgetSessionDeck = forgetSessionDeck;
134323
134444
  exports.formatAxisValue = formatAxisValue;
134324
- exports.formatAxisValueWithUnits = formatAxisValueWithUnits;
134325
134445
  exports.formatBackstageDate = formatBackstageDate;
134326
134446
  exports.formatBackstageSize = formatBackstageSize;
134327
134447
  exports.formatBytes = formatBytes;
@@ -134335,7 +134455,6 @@ exports.formatVersionTimestamp = formatVersionTimestamp;
134335
134455
  exports.fpsToFrameIntervalMs = fpsToFrameIntervalMs;
134336
134456
  exports.generateBroadcastRoomId = generateBroadcastRoomId;
134337
134457
  exports.generateElementId = generateElementId;
134338
- exports.generateLogTicks = generateLogTicks;
134339
134458
  exports.generateNoteLineCount = generateNoteLineCount;
134340
134459
  exports.generatePackageReadme = generatePackageReadme;
134341
134460
  exports.generatePressureCircles = generatePressureCircles;
@@ -134358,7 +134477,6 @@ exports.getComputedStrokeStyle = getComputedStrokeStyle;
134358
134477
  exports.getConnectorEndpointHandles = getConnectorEndpointHandles;
134359
134478
  exports.getContentPartReplayStyles = getContentPartReplayStyles;
134360
134479
  exports.getCurrentParagraphIndex = getCurrentParagraphIndex;
134361
- exports.getDisplayUnitLabel = getDisplayUnitLabel;
134362
134480
  exports.getDraggedShapeAdjustments = getDraggedShapeAdjustments;
134363
134481
  exports.getDuotoneCachedResult = getDuotoneCachedResult;
134364
134482
  exports.getElementLabel = getElementLabel;
@@ -134386,7 +134504,6 @@ exports.getPresetShapeClipPath = getPresetShapeClipPath;
134386
134504
  exports.getPrintableArea = getPrintableArea;
134387
134505
  exports.getResolvedShapeClipPath = getResolvedShapeClipPath;
134388
134506
  exports.getRoundRectRadiusPx2 = getRoundRectRadiusPx2;
134389
- exports.getSecondaryValueAxis = getSecondaryValueAxis;
134390
134507
  exports.getSessionTabId = getSessionTabId;
134391
134508
  exports.getShapeAdjustmentHandleDescriptors = getShapeAdjustmentHandleDescriptors;
134392
134509
  exports.getShapeConnectionSites = getShapeConnectionSites;
@@ -134412,6 +134529,7 @@ exports.hasShowSlideAfter = hasShowSlideAfter;
134412
134529
  exports.hasTextProperties = hasTextProperties;
134413
134530
  exports.hexToRgbChannels = hexToRgbChannels2;
134414
134531
  exports.hiddenSlideCue = hiddenSlideCue;
134532
+ exports.hollowTextFillStyle = hollowTextFillStyle;
134415
134533
  exports.inlineElementPointerEvents = inlineElementPointerEvents;
134416
134534
  exports.insertTableColumn = insertTableColumn;
134417
134535
  exports.insertTableRow = insertTableRow;
@@ -134482,12 +134600,12 @@ exports.motionPathPresetLabelKey = motionPathPresetLabelKey;
134482
134600
  exports.motionPathPresetsByFamily = motionPathPresetsByFamily;
134483
134601
  exports.motionPathToSvgD = motionPathToSvgD;
134484
134602
  exports.mountModel3D = mountModel3D;
134485
- exports.mountSurfaceChart3D = mountSurfaceChart3D;
134486
134603
  exports.movePresenterPointer = movePresenterPointer;
134487
134604
  exports.moveQuickAccessCommand = moveQuickAccessCommand;
134488
134605
  exports.moveSectionDown = moveSectionDown;
134489
134606
  exports.moveSectionUp = moveSectionUp;
134490
134607
  exports.moveSlidesToSection = moveSlidesToSection;
134608
+ exports.nestedTextDecorationStyle = nestedTextDecorationStyle;
134491
134609
  exports.newTableElement = newTableElement;
134492
134610
  exports.nextPresentedSlide = nextPresentedSlide;
134493
134611
  exports.nextShowSlideIndex = nextShowSlideIndex;
@@ -134495,7 +134613,6 @@ exports.normalizeColorsForCapture = normalizeColorsForCapture;
134495
134613
  exports.normalizeHexColor = normalizeHexColor;
134496
134614
  exports.normalizeSegments = normalizeSegments;
134497
134615
  exports.normalizeStrokeDashType = normalizeStrokeDashType;
134498
- exports.normalizeValue = normalizeValue;
134499
134616
  exports.notesSegmentsToSpans = notesSegmentsToSpans;
134500
134617
  exports.observeYDocSlides = observeYDocSlides;
134501
134618
  exports.ooxmlGradientAngleToCssDegrees = ooxmlGradientAngleToCssDegrees;
@@ -134504,7 +134621,6 @@ exports.openPptxFile = openPptxFile;
134504
134621
  exports.openReadingView = openReadingView;
134505
134622
  exports.openUrlInNewTab = openUrlInNewTab;
134506
134623
  exports.paintedStrokeWidth = paintedStrokeWidth;
134507
- exports.paletteColor = paletteColor;
134508
134624
  exports.paragraphsToSegments = paragraphsToSegments;
134509
134625
  exports.parseDrawingColor = parseDrawingColor;
134510
134626
  exports.parseDrawingColorOpacity = parseDrawingColorOpacity;
@@ -134531,6 +134647,7 @@ exports.pressuresToWidths = pressuresToWidths;
134531
134647
  exports.previousShowSlideIndex = previousShowSlideIndex;
134532
134648
  exports.printPropertiesFrameSlides = printPropertiesFrameSlides;
134533
134649
  exports.printPropertiesSlidesPerPage = printPropertiesSlidesPerPage;
134650
+ exports.probeAutosaveRecovery = probeAutosaveRecovery;
134534
134651
  exports.projectDrawingShapes = projectDrawingShapes;
134535
134652
  exports.promoteSmartArtNode = promoteSmartArtNode;
134536
134653
  exports.publishLiveGeometry = publishLiveGeometry;
@@ -134573,7 +134690,10 @@ exports.resolveAudienceScreenPlacement = resolveAudienceScreenPlacement;
134573
134690
  exports.resolveAuthoredCustomShowId = resolveAuthoredCustomShowId;
134574
134691
  exports.resolveAutoAdvanceDelayMs = resolveAutoAdvanceDelayMs;
134575
134692
  exports.resolveAutoFitFontScale = resolveAutoFitFontScale;
134693
+ exports.resolveAutosaveActivation = resolveAutosaveActivation;
134694
+ exports.resolveAutosaveIntervalMs = resolveAutosaveIntervalMs;
134576
134695
  exports.resolveAutosaveIntervalSeconds = resolveAutosaveIntervalSeconds;
134696
+ exports.resolveChartKind = resolveChartKind;
134577
134697
  exports.resolveConnectorEndpointUpdate = resolveConnectorEndpointUpdate;
134578
134698
  exports.resolveDefaultFontFamily = resolveDefaultFontFamily;
134579
134699
  exports.resolveDrawingShapeNodeId = resolveDrawingShapeNodeId;
@@ -134588,7 +134708,6 @@ exports.resolveMetricTrackingPx = resolveMetricTrackingPx;
134588
134708
  exports.resolveOleType = resolveOleType;
134589
134709
  exports.resolvePalette = resolvePalette;
134590
134710
  exports.resolveProfileInitial = resolveProfileInitial;
134591
- exports.resolveRegionCode = resolveRegionCode;
134592
134711
  exports.resolveSelectionPaneRename = resolveSelectionPaneRename;
134593
134712
  exports.resolveShapeGeometry = resolveShapeGeometry;
134594
134713
  exports.resolveShowSlideIndexes = resolveShowSlideIndexes;
@@ -134624,9 +134743,8 @@ exports.segmentsToParagraphs = segmentsToParagraphs;
134624
134743
  exports.segmentsToPlainText = segmentsToPlainText;
134625
134744
  exports.sendBackward = sendBackward;
134626
134745
  exports.sendToBack = sendToBack;
134627
- exports.sequentialColorScale = sequentialColorScale;
134628
- exports.seriesColor = seriesColor2;
134629
134746
  exports.setCachedResult = setCachedResult;
134747
+ exports.setCellText = setCellText;
134630
134748
  exports.setChartAxisGridlineStyle = setChartAxisGridlineStyle;
134631
134749
  exports.setChartAxisLogScale = setChartAxisLogScale;
134632
134750
  exports.setChartAxisTitleStyle = setChartAxisTitleStyle;
@@ -134651,6 +134769,8 @@ exports.shouldAutoFollowBroadcaster = shouldAutoFollowBroadcaster;
134651
134769
  exports.shouldCommitSmartArtNodeText = shouldCommitSmartArtNodeText;
134652
134770
  exports.shouldConfirmExternalHyperlink = shouldConfirmExternalHyperlink;
134653
134771
  exports.shouldLoopContinuously = shouldLoopContinuously;
134772
+ exports.shouldProbeAutosaveRecovery = shouldProbeAutosaveRecovery;
134773
+ exports.shouldShowAutosaveRecoveryPrompt = shouldShowAutosaveRecoveryPrompt;
134654
134774
  exports.shouldUseSvgWarp = shouldUseSvgWarp;
134655
134775
  exports.shouldWriteAutosaveSnapshot = shouldWriteAutosaveSnapshot;
134656
134776
  exports.slideProgressPercent = slideProgressPercent;
@@ -134661,7 +134781,6 @@ exports.slideStatusLabel = slideStatusLabel;
134661
134781
  exports.snapBoxToGrid = snapBoxToGrid;
134662
134782
  exports.splitCell = splitCell;
134663
134783
  exports.splitRunForMetrics = splitRunForMetrics;
134664
- exports.splitSeriesByAxis = splitSeriesByAxis;
134665
134784
  exports.stepPresenterZoom = stepPresenterZoom;
134666
134785
  exports.stopAllPersistentAudio = stopAllPersistentAudio;
134667
134786
  exports.storeAudienceContent = storeAudienceContent;
@@ -134698,7 +134817,6 @@ exports.updateMergeAttrsInRawXml = updateMergeAttrsInRawXml;
134698
134817
  exports.updateSmartArtNodeText = updateSmartArtNodeText;
134699
134818
  exports.updateTagInCollections = updateTagInCollections;
134700
134819
  exports.validateRoomId = validateRoomId;
134701
- exports.valueToY = valueToY;
134702
134820
  exports.vermilionDarkColors = vermilionDarkColors;
134703
134821
  exports.vermilionDarkTheme = vermilionDarkTheme;
134704
134822
  exports.vermilionLightColors = vermilionLightColors;