pptx-react-viewer 1.1.1 → 1.1.3

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 (35) hide show
  1. package/dist/{PowerPointViewer-DtLlYf0r.d.mts → PowerPointViewer-CX0a7wz_.d.mts} +2 -0
  2. package/dist/{PowerPointViewer-DtLlYf0r.d.ts → PowerPointViewer-CX0a7wz_.d.ts} +2 -0
  3. package/dist/index.d.mts +2 -2
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +373 -64
  6. package/dist/index.mjs +373 -64
  7. package/dist/pptx-viewer.css +1 -1
  8. package/dist/viewer/index.d.mts +11 -3
  9. package/dist/viewer/index.d.ts +11 -3
  10. package/dist/viewer/index.js +373 -64
  11. package/dist/viewer/index.mjs +373 -64
  12. package/node_modules/emf-converter/package.json +1 -1
  13. package/node_modules/mtx-decompressor/dist/index.d.mts +2 -1
  14. package/node_modules/mtx-decompressor/dist/index.d.ts +2 -1
  15. package/node_modules/mtx-decompressor/dist/index.js +85 -93
  16. package/node_modules/mtx-decompressor/dist/index.mjs +85 -93
  17. package/node_modules/mtx-decompressor/package.json +1 -1
  18. package/node_modules/pptx-viewer-core/dist/{SvgExporter-CPr1npgo.d.ts → SvgExporter-BMjoxMDV.d.ts} +1 -1
  19. package/node_modules/pptx-viewer-core/dist/{SvgExporter-B4-1_Hjp.d.mts → SvgExporter-z6AbXRQg.d.mts} +1 -1
  20. package/node_modules/pptx-viewer-core/dist/cli/index.d.mts +2 -2
  21. package/node_modules/pptx-viewer-core/dist/cli/index.d.ts +2 -2
  22. package/node_modules/pptx-viewer-core/dist/cli/index.js +504 -253
  23. package/node_modules/pptx-viewer-core/dist/cli/index.mjs +504 -253
  24. package/node_modules/pptx-viewer-core/dist/converter/index.d.mts +3 -3
  25. package/node_modules/pptx-viewer-core/dist/converter/index.d.ts +3 -3
  26. package/node_modules/pptx-viewer-core/dist/index.d.mts +318 -6
  27. package/node_modules/pptx-viewer-core/dist/index.d.ts +318 -6
  28. package/node_modules/pptx-viewer-core/dist/index.js +1474 -253
  29. package/node_modules/pptx-viewer-core/dist/index.mjs +1450 -254
  30. package/node_modules/pptx-viewer-core/dist/{presentation-DgkIYhXo.d.mts → presentation-CchuDGfU.d.mts} +17 -1
  31. package/node_modules/pptx-viewer-core/dist/{presentation-DgkIYhXo.d.ts → presentation-CchuDGfU.d.ts} +17 -1
  32. package/node_modules/pptx-viewer-core/dist/{text-operations-dYKZp3zE.d.mts → text-operations-CeukUztU.d.mts} +1 -1
  33. package/node_modules/pptx-viewer-core/dist/{text-operations-B6U6XxWt.d.ts → text-operations-e7JxgI5l.d.ts} +1 -1
  34. package/node_modules/pptx-viewer-core/package.json +1 -1
  35. package/package.json +4 -4
@@ -5188,7 +5188,11 @@ function isoNow() {
5188
5188
  return (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z");
5189
5189
  }
5190
5190
  var STANDARD_LAYOUTS = [
5191
- { name: "Title Slide", type: "ctrTitle" },
5191
+ // `type` is ST_SlideLayoutType per ECMA-376 §19.7.15. The Title Slide
5192
+ // layout uses `title`; `ctrTitle` is a placeholder type (ST_PlaceholderType)
5193
+ // and is not valid here — PowerPoint's OPC loader rejects the package
5194
+ // with ERROR_FILE_CORRUPT (0x80070570) when it sees it.
5195
+ { name: "Title Slide", type: "title" },
5192
5196
  { name: "Title and Content", type: "obj" },
5193
5197
  { name: "Section Header", type: "secHead" },
5194
5198
  { name: "Two Content", type: "twoObj" },
@@ -5222,7 +5226,7 @@ ${slideOverrides}
5222
5226
  <Override PartName="/ppt/viewProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"/>
5223
5227
  <Override PartName="/ppt/tableStyles.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"/>
5224
5228
  <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
5225
- <Override PartName="/docProps/app.xml" ContentType="application/vnd.ms-officedocument.extended-properties+xml"/>
5229
+ <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
5226
5230
  </Types>`;
5227
5231
  }
5228
5232
  function rootRelsXml() {
@@ -6281,33 +6285,10 @@ var PptxPresentationSaveBuilder = class {
6281
6285
  init.presentationData["p:presentation"] = presentation;
6282
6286
  return init.presentationData;
6283
6287
  }
6284
- applyHeaderFooter(presentation, headerFooter) {
6285
- if (!headerFooter) {
6286
- return;
6287
- }
6288
- const hf = presentation["p:hf"] || {};
6289
- if (headerFooter.hasHeader !== void 0) {
6290
- hf["@_hdr"] = headerFooter.hasHeader ? "1" : "0";
6291
- }
6292
- if (headerFooter.hasFooter !== void 0) {
6293
- hf["@_ftr"] = headerFooter.hasFooter ? "1" : "0";
6294
- }
6295
- if (headerFooter.hasDateTime !== void 0) {
6296
- hf["@_dt"] = headerFooter.hasDateTime ? "1" : "0";
6297
- }
6298
- if (headerFooter.hasSlideNumber !== void 0) {
6299
- hf["@_sldNum"] = headerFooter.hasSlideNumber ? "1" : "0";
6300
- }
6301
- if (headerFooter.footerText !== void 0) {
6302
- hf["@_ftrText"] = headerFooter.footerText;
6303
- }
6304
- if (headerFooter.dateTimeText !== void 0) {
6305
- hf["@_dtText"] = headerFooter.dateTimeText;
6306
- }
6307
- if (headerFooter.dateFormat !== void 0) {
6308
- hf["@_dtFmt"] = headerFooter.dateFormat;
6288
+ applyHeaderFooter(presentation, _headerFooter) {
6289
+ if (presentation["p:hf"] !== void 0) {
6290
+ delete presentation["p:hf"];
6309
6291
  }
6310
- presentation["p:hf"] = hf;
6311
6292
  }
6312
6293
  applySlideDimensions(presentation, rawSlideWidthEmu, rawSlideHeightEmu, rawSlideSizeType) {
6313
6294
  const slideSize = presentation["p:sldSz"];
@@ -6571,9 +6552,40 @@ var PptxPresentationSlidesReconciler = class {
6571
6552
  "@_r:id": slide.rId
6572
6553
  };
6573
6554
  });
6574
- presentation["p:sldIdLst"] = slideIdList;
6575
- input.presentationData["p:presentation"] = presentation;
6555
+ input.presentationData["p:presentation"] = this.insertSlideIdListInOrder(
6556
+ presentation,
6557
+ slideIdList
6558
+ );
6559
+ }
6560
+ }
6561
+ /**
6562
+ * Return a new presentation XML object whose `p:sldIdLst` child sits in the
6563
+ * schema-mandated position (after `sldMasterIdLst` / `notesMasterIdLst` /
6564
+ * `handoutMasterIdLst`, before `sldSz`). Non-sldIdLst keys keep their
6565
+ * relative order; attribute keys (`@_...`) stay at the front.
6566
+ */
6567
+ insertSlideIdListInOrder(presentation, slideIdList) {
6568
+ const before = /* @__PURE__ */ new Set([
6569
+ "p:sldMasterIdLst",
6570
+ "p:notesMasterIdLst",
6571
+ "p:handoutMasterIdLst"
6572
+ ]);
6573
+ const rebuilt = {};
6574
+ let inserted = false;
6575
+ for (const key of Object.keys(presentation)) {
6576
+ if (key === "p:sldIdLst") {
6577
+ continue;
6578
+ }
6579
+ if (!inserted && !key.startsWith("@_") && !before.has(key)) {
6580
+ rebuilt["p:sldIdLst"] = slideIdList;
6581
+ inserted = true;
6582
+ }
6583
+ rebuilt[key] = presentation[key];
6576
6584
  }
6585
+ if (!inserted) {
6586
+ rebuilt["p:sldIdLst"] = slideIdList;
6587
+ }
6588
+ return rebuilt;
6577
6589
  }
6578
6590
  async attachNewSlide(init) {
6579
6591
  const sourceSlidePath = init.input.findSourceSlidePath(init.slide.sourceSlideId);
@@ -6983,7 +6995,9 @@ var PptxSlideNotesPartUpdater = class {
6983
6995
  var PptxSlideBackgroundBuilder = class {
6984
6996
  applyBackground(init) {
6985
6997
  const hasBackgroundColor = typeof init.slide.backgroundColor === "string" && init.slide.backgroundColor.length > 0 && init.slide.backgroundColor !== "transparent";
6986
- const hasBackgroundImage = typeof init.slide.backgroundImage === "string" && init.slide.backgroundImage.length > 0;
6998
+ const rawBackgroundImage = typeof init.slide.backgroundImage === "string" ? init.slide.backgroundImage : "";
6999
+ const hasBackgroundImage = rawBackgroundImage.length > 0;
7000
+ const hasDataUrlBackgroundImage = hasBackgroundImage && rawBackgroundImage.startsWith("data:");
6987
7001
  const hasBackgroundGradient = typeof init.slide.backgroundGradient === "string" && init.slide.backgroundGradient.length > 0;
6988
7002
  const cSld = init.slideNode["p:cSld"] || {};
6989
7003
  if (!(hasBackgroundColor || hasBackgroundImage || hasBackgroundGradient)) {
@@ -6991,9 +7005,17 @@ var PptxSlideBackgroundBuilder = class {
6991
7005
  init.slideNode["p:cSld"] = cSld;
6992
7006
  return;
6993
7007
  }
7008
+ const existingBg = cSld["p:bg"];
7009
+ const existingBgPr = existingBg?.["p:bgPr"];
7010
+ const existingHasBlipFill = existingBgPr?.["a:blipFill"] !== void 0;
7011
+ if (!hasDataUrlBackgroundImage && existingHasBlipFill) {
7012
+ this.reorderCSldBgFirst(cSld, existingBg);
7013
+ init.slideNode["p:cSld"] = cSld;
7014
+ return;
7015
+ }
6994
7016
  const backgroundProperties = {};
6995
- if (hasBackgroundImage && init.slide.backgroundImage) {
6996
- const parsedBackgroundImage = init.parseDataUrlToBytes(init.slide.backgroundImage);
7017
+ if (hasDataUrlBackgroundImage) {
7018
+ const parsedBackgroundImage = init.parseDataUrlToBytes(rawBackgroundImage);
6997
7019
  if (parsedBackgroundImage) {
6998
7020
  const backgroundImagePath = init.saveState.nextMediaPath(parsedBackgroundImage.extension);
6999
7021
  init.zip.file(backgroundImagePath, parsedBackgroundImage.bytes);
@@ -7016,9 +7038,42 @@ var PptxSlideBackgroundBuilder = class {
7016
7038
  }
7017
7039
  };
7018
7040
  }
7019
- backgroundProperties["a:effectLst"] = {};
7020
- cSld["p:bg"] = { "p:bgPr": backgroundProperties };
7021
- init.slideNode["p:cSld"] = cSld;
7041
+ const hasFillChild = backgroundProperties["a:blipFill"] !== void 0 || backgroundProperties["a:solidFill"] !== void 0 || backgroundProperties["a:gradFill"] !== void 0 || backgroundProperties["a:pattFill"] !== void 0 || backgroundProperties["a:noFill"] !== void 0 || backgroundProperties["a:grpFill"] !== void 0;
7042
+ if (hasFillChild) {
7043
+ backgroundProperties["a:effectLst"] = {};
7044
+ }
7045
+ if (!hasFillChild) {
7046
+ delete cSld["p:bg"];
7047
+ init.slideNode["p:cSld"] = cSld;
7048
+ return;
7049
+ }
7050
+ const rebuiltCSld = { "p:bg": { "p:bgPr": backgroundProperties } };
7051
+ for (const key of Object.keys(cSld)) {
7052
+ if (key === "p:bg") {
7053
+ continue;
7054
+ }
7055
+ rebuiltCSld[key] = cSld[key];
7056
+ }
7057
+ init.slideNode["p:cSld"] = rebuiltCSld;
7058
+ }
7059
+ reorderCSldBgFirst(cSld, bg) {
7060
+ const keys = Object.keys(cSld);
7061
+ if (keys.length > 0 && keys[0] === "p:bg") {
7062
+ return;
7063
+ }
7064
+ const reordered = { "p:bg": bg };
7065
+ for (const key of keys) {
7066
+ if (key === "p:bg") {
7067
+ continue;
7068
+ }
7069
+ reordered[key] = cSld[key];
7070
+ }
7071
+ for (const key of Object.keys(cSld)) {
7072
+ delete cSld[key];
7073
+ }
7074
+ for (const key of Object.keys(reordered)) {
7075
+ cSld[key] = reordered[key];
7076
+ }
7022
7077
  }
7023
7078
  };
7024
7079
 
@@ -9895,6 +9950,7 @@ var PptxConnectorParser = class {
9895
9950
  slideRelationships,
9896
9951
  this.context.getOrderedSlidePaths()
9897
9952
  );
9953
+ const connElementName = cNvPr?.["@_name"] ? String(cNvPr["@_name"]).trim() : void 0;
9898
9954
  const locks = this.context.parseShapeLocks(
9899
9955
  cNvConnectionShapeProperties?.["a:cxnSpLocks"] ?? cNvConnectionShapeProperties?.["a:spLocks"]
9900
9956
  );
@@ -9902,6 +9958,7 @@ var PptxConnectorParser = class {
9902
9958
  const textResult = this.context.parseConnectorTextBody?.(txBody, slidePath);
9903
9959
  return {
9904
9960
  id,
9961
+ name: connElementName || void 0,
9905
9962
  type: "connector",
9906
9963
  x: Math.round(parseInt(String(offset["@_x"] || "0"), 10) / this.context.emuPerPx),
9907
9964
  y: Math.round(parseInt(String(offset["@_y"] || "0"), 10) / this.context.emuPerPx),
@@ -13431,7 +13488,16 @@ var PptxRuntimeDependencyFactory = class {
13431
13488
  return new fastXmlParser.XMLParser({
13432
13489
  ignoreAttributes: false,
13433
13490
  attributeNamePrefix: "@_",
13434
- parseAttributeValue: false
13491
+ parseAttributeValue: false,
13492
+ // Keep element text as strings. When true (the fast-xml-parser
13493
+ // default), `<AppVersion>16.0000</AppVersion>` is coerced to the
13494
+ // JS number 16, losing the trailing zeros. On save we write back
13495
+ // "16", which fails PowerPoint's strict `[0-9]+\.[0-9]{4}` match
13496
+ // on AppVersion — the loader rejects the package with HRESULT
13497
+ // 0x80070570 (ERROR_FILE_CORRUPT) and shows the repair dialog.
13498
+ // More generally, OOXML element text is always an untyped string;
13499
+ // downstream callers coerce where needed.
13500
+ parseTagValue: false
13435
13501
  });
13436
13502
  }
13437
13503
  createBuilder() {
@@ -14107,7 +14173,7 @@ var TRIPLET_ENCODINGS = [
14107
14173
  { byteCount: 2, xBits: 4, yBits: 4, deltaX: 49, deltaY: 49, xSign: 1, ySign: -1 },
14108
14174
  { byteCount: 2, xBits: 4, yBits: 4, deltaX: 49, deltaY: 49, xSign: -1, ySign: 1 },
14109
14175
  { byteCount: 2, xBits: 4, yBits: 4, deltaX: 49, deltaY: 49, xSign: 1, ySign: 1 },
14110
- // Indices 84-107: 8-bit X + 8-bit Y (3 bytes total)
14176
+ // Indices 84-119: 8-bit X + 8-bit Y (3 bytes total)
14111
14177
  { byteCount: 3, xBits: 8, yBits: 8, deltaX: 1, deltaY: 1, xSign: -1, ySign: -1 },
14112
14178
  { byteCount: 3, xBits: 8, yBits: 8, deltaX: 1, deltaY: 1, xSign: 1, ySign: -1 },
14113
14179
  { byteCount: 3, xBits: 8, yBits: 8, deltaX: 1, deltaY: 1, xSign: -1, ySign: 1 },
@@ -14144,12 +14210,12 @@ var TRIPLET_ENCODINGS = [
14144
14210
  { byteCount: 3, xBits: 8, yBits: 8, deltaX: 513, deltaY: 513, xSign: 1, ySign: -1 },
14145
14211
  { byteCount: 3, xBits: 8, yBits: 8, deltaX: 513, deltaY: 513, xSign: -1, ySign: 1 },
14146
14212
  { byteCount: 3, xBits: 8, yBits: 8, deltaX: 513, deltaY: 513, xSign: 1, ySign: 1 },
14147
- // Indices 108-111: 12-bit X + 12-bit Y (4 bytes total)
14213
+ // Indices 120-123: 12-bit X + 12-bit Y (4 bytes total)
14148
14214
  { byteCount: 4, xBits: 12, yBits: 12, deltaX: 0, deltaY: 0, xSign: -1, ySign: -1 },
14149
14215
  { byteCount: 4, xBits: 12, yBits: 12, deltaX: 0, deltaY: 0, xSign: 1, ySign: -1 },
14150
14216
  { byteCount: 4, xBits: 12, yBits: 12, deltaX: 0, deltaY: 0, xSign: -1, ySign: 1 },
14151
14217
  { byteCount: 4, xBits: 12, yBits: 12, deltaX: 0, deltaY: 0, xSign: 1, ySign: 1 },
14152
- // Indices 112-115: 16-bit X + 16-bit Y (5 bytes total)
14218
+ // Indices 124-127: 16-bit X + 16-bit Y (5 bytes total)
14153
14219
  { byteCount: 5, xBits: 16, yBits: 16, deltaX: 0, deltaY: 0, xSign: -1, ySign: -1 },
14154
14220
  { byteCount: 5, xBits: 16, yBits: 16, deltaX: 0, deltaY: 0, xSign: 1, ySign: -1 },
14155
14221
  { byteCount: 5, xBits: 16, yBits: 16, deltaX: 0, deltaY: 0, xSign: -1, ySign: 1 },
@@ -14238,14 +14304,15 @@ function decodePushInstructions(sIn, sOut, pushCount) {
14238
14304
  if (pushCount === 0) {
14239
14305
  return;
14240
14306
  }
14241
- const values = [];
14242
- let isShort = false;
14307
+ const data = [];
14243
14308
  let remaining = pushCount;
14309
+ let isShort = false;
14310
+ const runValues = [];
14244
14311
  function flush() {
14245
- if (values.length === 0) {
14312
+ if (runValues.length === 0) {
14246
14313
  return;
14247
14314
  }
14248
- const count = values.length;
14315
+ const count = runValues.length;
14249
14316
  if (isShort) {
14250
14317
  if (count < 8) {
14251
14318
  sOut.writeU8(PUSHW + (count - 1));
@@ -14253,7 +14320,7 @@ function decodePushInstructions(sIn, sOut, pushCount) {
14253
14320
  sOut.writeU8(NPUSHW);
14254
14321
  sOut.writeU8(count);
14255
14322
  }
14256
- for (const v of values) {
14323
+ for (const v of runValues) {
14257
14324
  sOut.writeS16(v);
14258
14325
  }
14259
14326
  } else {
@@ -14263,54 +14330,50 @@ function decodePushInstructions(sIn, sOut, pushCount) {
14263
14330
  sOut.writeU8(NPUSHB);
14264
14331
  sOut.writeU8(count);
14265
14332
  }
14266
- for (const v of values) {
14333
+ for (const v of runValues) {
14267
14334
  sOut.writeU8(v & 255);
14268
14335
  }
14269
14336
  }
14270
- values.length = 0;
14337
+ runValues.length = 0;
14271
14338
  }
14272
- function addValue(v) {
14339
+ function put(v) {
14340
+ data.push(v);
14273
14341
  const needsShort = v < 0 || v > 255;
14274
- if (values.length > 0 && needsShort !== isShort) {
14342
+ if (runValues.length > 0 && needsShort !== isShort) {
14275
14343
  flush();
14276
14344
  }
14277
- if (values.length === 0) {
14345
+ if (runValues.length === 0) {
14278
14346
  isShort = needsShort;
14279
14347
  }
14280
- values.push(v);
14281
- if (values.length >= 255) {
14348
+ runValues.push(v);
14349
+ if (runValues.length >= 255) {
14282
14350
  flush();
14283
14351
  }
14284
14352
  }
14285
14353
  while (remaining > 0) {
14286
- const code = sIn.readU8();
14287
- if (code === 251 && remaining >= 4) {
14288
- const a = read255Short(sIn);
14289
- const b = read255Short(sIn);
14290
- const c = read255Short(sIn);
14291
- addValue(a);
14292
- addValue(b);
14293
- addValue(a);
14294
- addValue(c);
14295
- addValue(a);
14296
- remaining -= 5;
14297
- } else if (code === 252 && remaining >= 6) {
14298
- const a = read255Short(sIn);
14299
- const b = read255Short(sIn);
14354
+ const code = sIn.peekU8();
14355
+ if (code === 251 && remaining >= 3 && data.length >= 2) {
14356
+ sIn.readU8();
14357
+ const prev = data[data.length - 2];
14358
+ put(prev);
14359
+ const val = read255Short(sIn);
14360
+ put(val);
14361
+ put(prev);
14362
+ remaining -= 3;
14363
+ } else if (code === 252 && remaining >= 5 && data.length >= 2) {
14364
+ sIn.readU8();
14365
+ const prev = data[data.length - 2];
14366
+ put(prev);
14300
14367
  const c = read255Short(sIn);
14368
+ put(c);
14369
+ put(prev);
14301
14370
  const d = read255Short(sIn);
14302
- addValue(a);
14303
- addValue(b);
14304
- addValue(a);
14305
- addValue(c);
14306
- addValue(a);
14307
- addValue(d);
14308
- addValue(a);
14309
- remaining -= 7;
14371
+ put(d);
14372
+ put(prev);
14373
+ remaining -= 5;
14310
14374
  } else {
14311
- sIn.seekRelative(-1);
14312
14375
  const v = read255Short(sIn);
14313
- addValue(v);
14376
+ put(v);
14314
14377
  remaining -= 1;
14315
14378
  }
14316
14379
  }
@@ -14338,6 +14401,9 @@ function makeGlyphFlags(x, y, onCurve, firstTime) {
14338
14401
  return flags;
14339
14402
  }
14340
14403
  function decodeSimpleGlyph(numContours, streams, out, calcBBox, minX, minY, maxX, maxY) {
14404
+ if (numContours === 0) {
14405
+ return;
14406
+ }
14341
14407
  const sGlyph = streams[0];
14342
14408
  out.writeS16(numContours);
14343
14409
  const bboxPos = out.pos;
@@ -14358,13 +14424,12 @@ function decodeSimpleGlyph(numContours, streams, out, calcBBox, minX, minY, maxX
14358
14424
  }
14359
14425
  let totalPoints = 0;
14360
14426
  for (let c = 0; c < numContours; c++) {
14361
- const pointsInContour = read255UShort(sGlyph);
14362
- totalPoints += pointsInContour;
14363
14427
  if (c === 0) {
14364
- out.writeU16(pointsInContour - 1);
14365
- } else {
14366
- out.writeU16(totalPoints - 1);
14428
+ totalPoints = 1;
14367
14429
  }
14430
+ const pointsInContour = read255UShort(sGlyph);
14431
+ totalPoints += pointsInContour;
14432
+ out.writeU16(totalPoints - 1);
14368
14433
  }
14369
14434
  const flagBytes = new Uint8Array(totalPoints);
14370
14435
  for (let i = 0; i < totalPoints; i++) {
@@ -14377,7 +14442,7 @@ function decodeSimpleGlyph(numContours, streams, out, calcBBox, minX, minY, maxX
14377
14442
  let cumulativeY = 0;
14378
14443
  for (let i = 0; i < totalPoints; i++) {
14379
14444
  const flag = flagBytes[i];
14380
- onCurve[i] = flag >> 7;
14445
+ onCurve[i] = flag & 128 ? 0 : 1;
14381
14446
  const enc = TRIPLET_ENCODINGS[flag & 127];
14382
14447
  const extraBytes = enc.byteCount - 1;
14383
14448
  const subBuf = new Uint8Array(extraBytes);
@@ -14716,7 +14781,10 @@ var AHuff = class _AHuff {
14716
14781
  this.bio = bio;
14717
14782
  this.range = range;
14718
14783
  this.bitCount = bitsUsed(range - 1);
14719
- this.bitCount2 = this.bitCount > 8 ? this.bitCount - 8 : 0;
14784
+ this.bitCount2 = 0;
14785
+ if (range > 256 && range < 512) {
14786
+ this.bitCount2 = bitsUsed(range - 256 - 1) + 1;
14787
+ }
14720
14788
  const treeSize = 2 * range;
14721
14789
  this.tree = Array.from({ length: treeSize });
14722
14790
  for (let i = 0; i < treeSize; i++) {
@@ -14724,6 +14792,7 @@ var AHuff = class _AHuff {
14724
14792
  }
14725
14793
  for (let i = 2; i < treeSize; i++) {
14726
14794
  this.tree[i].up = i >> 1;
14795
+ this.tree[i].weight = 1;
14727
14796
  }
14728
14797
  for (let i = 1; i < range; i++) {
14729
14798
  this.tree[i].left = 2 * i;
@@ -14733,7 +14802,8 @@ var AHuff = class _AHuff {
14733
14802
  for (let i = 0; i < range; i++) {
14734
14803
  const leafIdx = range + i;
14735
14804
  this.tree[leafIdx].code = i;
14736
- this.tree[leafIdx].weight = 1;
14805
+ this.tree[leafIdx].left = -1;
14806
+ this.tree[leafIdx].right = -1;
14737
14807
  }
14738
14808
  this.symbolIndex = Array.from({ length: range });
14739
14809
  for (let i = 0; i < range; i++) {
@@ -14773,15 +14843,13 @@ var AHuff = class _AHuff {
14773
14843
  */
14774
14844
  readSymbol() {
14775
14845
  let a = _AHuff.ROOT;
14776
- while (this.tree[a].code < 0) {
14777
- if (this.bio.inputBit()) {
14778
- a = this.tree[a].right;
14779
- } else {
14780
- a = this.tree[a].left;
14781
- }
14782
- }
14846
+ let symbol;
14847
+ do {
14848
+ a = this.bio.inputBit() ? this.tree[a].right : this.tree[a].left;
14849
+ symbol = this.tree[a].code;
14850
+ } while (symbol < 0);
14783
14851
  this.updateWeight(a);
14784
- return this.tree[a].code;
14852
+ return symbol;
14785
14853
  }
14786
14854
  // --------------------------------------------------------------------
14787
14855
  // Private helpers
@@ -14805,17 +14873,19 @@ var AHuff = class _AHuff {
14805
14873
  updateWeight(a) {
14806
14874
  const tree = this.tree;
14807
14875
  for (; a !== _AHuff.ROOT; a = tree[a].up) {
14876
+ const weightA = tree[a].weight;
14808
14877
  let b = a - 1;
14809
- if (b > 0 && tree[b].weight === tree[a].weight) {
14810
- while (b > _AHuff.ROOT && tree[b - 1].weight === tree[a].weight) {
14878
+ if (tree[b].weight === weightA) {
14879
+ do {
14811
14880
  b--;
14812
- }
14813
- if (b > _AHuff.ROOT && b !== a) {
14881
+ } while (tree[b].weight === weightA);
14882
+ b++;
14883
+ if (b > _AHuff.ROOT) {
14814
14884
  this.swapNodes(a, b);
14815
14885
  a = b;
14816
14886
  }
14817
14887
  }
14818
- tree[a].weight++;
14888
+ tree[a].weight = weightA + 1;
14819
14889
  }
14820
14890
  tree[_AHuff.ROOT].weight++;
14821
14891
  }
@@ -14835,38 +14905,26 @@ var AHuff = class _AHuff {
14835
14905
  */
14836
14906
  swapNodes(a, b) {
14837
14907
  const tree = this.tree;
14838
- const na = tree[a];
14839
- const nb = tree[b];
14840
- let tmp;
14841
- tmp = na.left;
14842
- na.left = nb.left;
14843
- nb.left = tmp;
14844
- tmp = na.right;
14845
- na.right = nb.right;
14846
- nb.right = tmp;
14847
- tmp = na.code;
14848
- na.code = nb.code;
14849
- nb.code = tmp;
14850
- tmp = na.weight;
14851
- na.weight = nb.weight;
14852
- nb.weight = tmp;
14853
- if (na.left) {
14854
- tree[na.left].up = a;
14855
- }
14856
- if (na.right) {
14857
- tree[na.right].up = a;
14858
- }
14859
- if (nb.left) {
14860
- tree[nb.left].up = b;
14861
- }
14862
- if (nb.right) {
14863
- tree[nb.right].up = b;
14864
- }
14865
- if (na.code >= 0) {
14866
- this.symbolIndex[na.code] = a;
14908
+ const upa = tree[a].up;
14909
+ const upb = tree[b].up;
14910
+ const tmp = tree[a];
14911
+ tree[a] = tree[b];
14912
+ tree[b] = tmp;
14913
+ tree[a].up = upa;
14914
+ tree[b].up = upb;
14915
+ let code = tree[a].code;
14916
+ if (code < 0) {
14917
+ tree[tree[a].left].up = a;
14918
+ tree[tree[a].right].up = a;
14919
+ } else {
14920
+ this.symbolIndex[code] = a;
14867
14921
  }
14868
- if (nb.code >= 0) {
14869
- this.symbolIndex[nb.code] = b;
14922
+ code = tree[b].code;
14923
+ if (code < 0) {
14924
+ tree[tree[b].left].up = b;
14925
+ tree[tree[b].right].up = b;
14926
+ } else {
14927
+ this.symbolIndex[code] = b;
14870
14928
  }
14871
14929
  }
14872
14930
  /**
@@ -15245,12 +15303,12 @@ function unpackMtx(data, size) {
15245
15303
  const offset2 = data[4] << 16 | data[5] << 8 | data[6];
15246
15304
  const offset3 = data[7] << 16 | data[8] << 8 | data[9];
15247
15305
  const offsets = [10, offset2, offset3];
15248
- const sizes = [offset2 - 10, offset3 - offset2, size - offset3];
15306
+ const blockSizes = [offset2 - 10, offset3 - offset2, size - offset3];
15249
15307
  const streams = [];
15250
15308
  const decompressedSizes = [];
15251
15309
  for (let i = 0; i < 3; i++) {
15252
15310
  const block = data.subarray(offsets[i]);
15253
- const decompressed = lzcompDecompress(block, sizes[i], versionMagic);
15311
+ const decompressed = lzcompDecompress(block, blockSizes[i], versionMagic);
15254
15312
  streams.push(decompressed);
15255
15313
  decompressedSizes.push(decompressed.length);
15256
15314
  }
@@ -15342,6 +15400,15 @@ function parseEotHeader(data) {
15342
15400
  const fullName = readNameString();
15343
15401
  if (version >= 131074) {
15344
15402
  readNameString();
15403
+ offset += 8;
15404
+ if (offset + 4 <= data.length) {
15405
+ const signatureSize = readUint16LE(data, offset + 2);
15406
+ offset += 4 + signatureSize;
15407
+ }
15408
+ if (offset + 8 <= data.length) {
15409
+ const eudcFontSize = readUint32LE(data, offset + 4);
15410
+ offset += 8 + eudcFontSize;
15411
+ }
15345
15412
  }
15346
15413
  return {
15347
15414
  eotSize,
@@ -23440,12 +23507,6 @@ function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spac
23440
23507
  if (textStyle?.rtl !== void 0) {
23441
23508
  paragraphProps["@_rtl"] = textStyle.rtl ? "1" : "0";
23442
23509
  }
23443
- if (spacing.spacingBefore) {
23444
- paragraphProps["a:spcBef"] = spacing.spacingBefore;
23445
- }
23446
- if (spacing.spacingAfter) {
23447
- paragraphProps["a:spcAft"] = spacing.spacingAfter;
23448
- }
23449
23510
  if (spacing.lineSpacing) {
23450
23511
  paragraphProps["a:lnSpc"] = spacing.lineSpacing;
23451
23512
  } else if (typeof spacing.lineSpacingExactPt === "number" && Number.isFinite(spacing.lineSpacingExactPt)) {
@@ -23455,6 +23516,12 @@ function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spac
23455
23516
  }
23456
23517
  };
23457
23518
  }
23519
+ if (spacing.spacingBefore) {
23520
+ paragraphProps["a:spcBef"] = spacing.spacingBefore;
23521
+ }
23522
+ if (spacing.spacingAfter) {
23523
+ paragraphProps["a:spcAft"] = spacing.spacingAfter;
23524
+ }
23458
23525
  if (typeof textStyle?.paragraphMarginLeft === "number" && Number.isFinite(textStyle.paragraphMarginLeft)) {
23459
23526
  paragraphProps["@_marL"] = String(Math.round(textStyle.paragraphMarginLeft * EMU_PER_PX4));
23460
23527
  }
@@ -23505,9 +23572,10 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
23505
23572
  paragraphProps["a:buNone"] = {};
23506
23573
  return;
23507
23574
  }
23508
- if (bulletInfo.fontFamily) {
23509
- paragraphProps["a:buFont"] = {
23510
- "@_typeface": bulletInfo.fontFamily
23575
+ if (bulletInfo.color) {
23576
+ const colorHex = bulletInfo.color.replace("#", "");
23577
+ paragraphProps["a:buClr"] = {
23578
+ "a:srgbClr": { "@_val": colorHex }
23511
23579
  };
23512
23580
  }
23513
23581
  if (bulletInfo.sizePercent !== void 0) {
@@ -23520,10 +23588,9 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
23520
23588
  "@_val": String(Math.round(bulletInfo.sizePts * 100))
23521
23589
  };
23522
23590
  }
23523
- if (bulletInfo.color) {
23524
- const colorHex = bulletInfo.color.replace("#", "");
23525
- paragraphProps["a:buClr"] = {
23526
- "a:srgbClr": { "@_val": colorHex }
23591
+ if (bulletInfo.fontFamily) {
23592
+ paragraphProps["a:buFont"] = {
23593
+ "@_typeface": bulletInfo.fontFamily
23527
23594
  };
23528
23595
  }
23529
23596
  if (bulletInfo.char) {
@@ -23546,9 +23613,8 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
23546
23613
  }
23547
23614
  function assembleParagraphXml(runs, paragraphProps) {
23548
23615
  const paragraph = {
23549
- "a:endParaRPr": { "@_lang": "en-US" }
23616
+ "a:pPr": paragraphProps
23550
23617
  };
23551
- paragraph["a:pPr"] = paragraphProps;
23552
23618
  const regularRuns = runs.filter((r) => !r.__isField);
23553
23619
  const fieldRuns = runs.filter((r) => r.__isField).map((r) => {
23554
23620
  const { __isField, ...rest } = r;
@@ -23567,6 +23633,7 @@ function assembleParagraphXml(runs, paragraphProps) {
23567
23633
  if (cleanRegularRuns.length === 0 && fieldRuns.length === 0) {
23568
23634
  paragraph["a:r"] = runs.length > 1 ? runs : runs[0];
23569
23635
  }
23636
+ paragraph["a:endParaRPr"] = { "@_lang": "en-US" };
23570
23637
  return paragraph;
23571
23638
  }
23572
23639
  function computeUniformSegmentOverrides(textStyle, textSegments) {
@@ -26405,9 +26472,6 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
26405
26472
  if (style.textCaps && style.textCaps !== "none") {
26406
26473
  runProps["@_cap"] = style.textCaps;
26407
26474
  }
26408
- if (style.rtl !== void 0) {
26409
- runProps["@_rtl"] = style.rtl ? "1" : "0";
26410
- }
26411
26475
  if (style.kumimoji !== void 0) {
26412
26476
  runProps["@_kumimoji"] = style.kumimoji ? "1" : "0";
26413
26477
  }
@@ -26429,17 +26493,19 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
26429
26493
  if (style.bookmark) {
26430
26494
  runProps["@_bmk"] = style.bookmark;
26431
26495
  }
26432
- if (style.fontFamily) {
26433
- runProps["a:latin"] = { "@_typeface": style.fontFamily };
26434
- runProps["a:ea"] = {
26435
- "@_typeface": style.eastAsiaFont || style.fontFamily
26436
- };
26437
- runProps["a:cs"] = {
26438
- "@_typeface": style.complexScriptFont || style.fontFamily
26439
- };
26440
- }
26441
- if (style.symbolFont) {
26442
- runProps["a:sym"] = { "@_typeface": style.symbolFont };
26496
+ if (style.textOutlineWidth || style.textOutlineColor) {
26497
+ const lnObj = {};
26498
+ if (typeof style.textOutlineWidth === "number" && style.textOutlineWidth > 0) {
26499
+ lnObj["@_w"] = String(Math.round(style.textOutlineWidth * _PptxHandlerRuntime.EMU_PER_PX));
26500
+ }
26501
+ if (style.textOutlineColor) {
26502
+ lnObj["a:solidFill"] = {
26503
+ "a:srgbClr": {
26504
+ "@_val": style.textOutlineColor.replace("#", "")
26505
+ }
26506
+ };
26507
+ }
26508
+ runProps["a:ln"] = lnObj;
26443
26509
  }
26444
26510
  if (style.color) {
26445
26511
  runProps["a:solidFill"] = {
@@ -26447,15 +26513,7 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
26447
26513
  "@_val": style.color.replace("#", "")
26448
26514
  }
26449
26515
  };
26450
- }
26451
- if (style.highlightColor) {
26452
- runProps["a:highlight"] = {
26453
- "a:srgbClr": {
26454
- "@_val": style.highlightColor.replace("#", "")
26455
- }
26456
- };
26457
- }
26458
- if (style.textFillGradientStops && style.textFillGradientStops.length > 0) {
26516
+ } else if (style.textFillGradientStops && style.textFillGradientStops.length > 0) {
26459
26517
  const gradStops = style.textFillGradientStops.filter((stop) => Boolean(stop?.color)).map((stop) => {
26460
26518
  const rawPos = (stop.position ?? 0) / 100;
26461
26519
  const posVal = Math.round(Math.max(0, Math.min(1, rawPos)) * 1e5);
@@ -26488,8 +26546,7 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
26488
26546
  }
26489
26547
  runProps["a:gradFill"] = gradFillXml;
26490
26548
  }
26491
- }
26492
- if (style.textFillPattern) {
26549
+ } else if (style.textFillPattern) {
26493
26550
  const pattFill = { "@_prst": style.textFillPattern };
26494
26551
  if (style.textFillPatternForeground) {
26495
26552
  pattFill["a:fgClr"] = {
@@ -26507,6 +26564,17 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
26507
26564
  }
26508
26565
  runProps["a:pattFill"] = pattFill;
26509
26566
  }
26567
+ const textEffectLst = buildTextRunEffectListXml(style);
26568
+ if (textEffectLst) {
26569
+ runProps["a:effectLst"] = textEffectLst;
26570
+ }
26571
+ if (style.highlightColor) {
26572
+ runProps["a:highlight"] = {
26573
+ "a:srgbClr": {
26574
+ "@_val": style.highlightColor.replace("#", "")
26575
+ }
26576
+ };
26577
+ }
26510
26578
  if (style.underline && style.underlineColor) {
26511
26579
  runProps["a:uFill"] = {
26512
26580
  "a:solidFill": {
@@ -26516,23 +26584,17 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
26516
26584
  }
26517
26585
  };
26518
26586
  }
26519
- if (style.textOutlineWidth || style.textOutlineColor) {
26520
- const lnObj = {};
26521
- if (typeof style.textOutlineWidth === "number" && style.textOutlineWidth > 0) {
26522
- lnObj["@_w"] = String(Math.round(style.textOutlineWidth * _PptxHandlerRuntime.EMU_PER_PX));
26523
- }
26524
- if (style.textOutlineColor) {
26525
- lnObj["a:solidFill"] = {
26526
- "a:srgbClr": {
26527
- "@_val": style.textOutlineColor.replace("#", "")
26528
- }
26529
- };
26530
- }
26531
- runProps["a:ln"] = lnObj;
26587
+ if (style.fontFamily) {
26588
+ runProps["a:latin"] = { "@_typeface": style.fontFamily };
26589
+ runProps["a:ea"] = {
26590
+ "@_typeface": style.eastAsiaFont || style.fontFamily
26591
+ };
26592
+ runProps["a:cs"] = {
26593
+ "@_typeface": style.complexScriptFont || style.fontFamily
26594
+ };
26532
26595
  }
26533
- const textEffectLst = buildTextRunEffectListXml(style);
26534
- if (textEffectLst) {
26535
- runProps["a:effectLst"] = textEffectLst;
26596
+ if (style.symbolFont) {
26597
+ runProps["a:sym"] = { "@_typeface": style.symbolFont };
26536
26598
  }
26537
26599
  if (style.hyperlink && resolveHyperlinkRelationshipId) {
26538
26600
  const hyperlinkTarget = String(style.hyperlink).trim();
@@ -26780,6 +26842,55 @@ var PptxHandlerRuntime14 = class extends PptxHandlerRuntime13 {
26780
26842
 
26781
26843
  // src/core/core/runtime/PptxHandlerRuntimeSaveShapeXml.ts
26782
26844
  var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime14 {
26845
+ /**
26846
+ * Build a `p:graphicFrame` XML skeleton for an SDK-created table.
26847
+ *
26848
+ * Tables round-trip as `<p:graphicFrame>/<a:graphic>/<a:graphicData
26849
+ * uri=".../drawingml/2006/table">/<a:tbl>` inside `p:spTree`. When the
26850
+ * element was loaded from an existing file, `el.rawXml` already contains
26851
+ * this envelope and the downstream `serializeTableDataToXml` path
26852
+ * populates cells in place. When the element was created via the SDK
26853
+ * (`SlideBuilder.addTable`), there is no `rawXml`, so this method
26854
+ * fabricates a minimal envelope with an empty `a:tbl`. The element
26855
+ * writer then calls `serializeTableDataToXml`, which triggers
26856
+ * `rebuildTableXmlFromData` and fills in `a:tblGrid` / `a:tr` children.
26857
+ */
26858
+ createTableGraphicFrameXml(el) {
26859
+ const EMU = _PptxHandlerRuntime.EMU_PER_PX;
26860
+ const offX = String(Math.round(el.x * EMU));
26861
+ const offY = String(Math.round(el.y * EMU));
26862
+ const extCx = String(Math.round(Math.max(el.width, 1) * EMU));
26863
+ const extCy = String(Math.round(Math.max(el.height, 1) * EMU));
26864
+ const tblPr = {
26865
+ "@_firstRow": el.tableData?.firstRowHeader ? "1" : "0",
26866
+ "@_bandRow": el.tableData?.bandedRows ? "1" : "0"
26867
+ };
26868
+ if (el.tableData?.tableStyleId) {
26869
+ tblPr["a:tableStyleId"] = el.tableData.tableStyleId;
26870
+ }
26871
+ return {
26872
+ "p:nvGraphicFramePr": {
26873
+ "p:cNvPr": { "@_id": "0", "@_name": el.name || "Table" },
26874
+ "p:cNvGraphicFramePr": {
26875
+ "a:graphicFrameLocks": { "@_noGrp": "1" }
26876
+ },
26877
+ "p:nvPr": {}
26878
+ },
26879
+ "p:xfrm": {
26880
+ "a:off": { "@_x": offX, "@_y": offY },
26881
+ "a:ext": { "@_cx": extCx, "@_cy": extCy }
26882
+ },
26883
+ "a:graphic": {
26884
+ "a:graphicData": {
26885
+ "@_uri": "http://schemas.openxmlformats.org/drawingml/2006/table",
26886
+ "a:tbl": {
26887
+ "a:tblPr": tblPr,
26888
+ "a:tblGrid": {}
26889
+ }
26890
+ }
26891
+ }
26892
+ };
26893
+ }
26783
26894
  /**
26784
26895
  * Build a p:sp XML object for an ink annotation element.
26785
26896
  * Each ink path becomes a separate a:path within a:pathLst,
@@ -28261,14 +28372,15 @@ function writeCellTextFormatting(xmlCell, style, ensureArray6) {
28261
28372
  const paragraphs = ensureArray6(xmlCell["a:txBody"]?.["a:p"]);
28262
28373
  for (const paragraph of paragraphs) {
28263
28374
  const runs = ensureArray6(paragraph?.["a:r"]);
28375
+ const rebuiltRuns = [];
28376
+ let runsChanged = false;
28264
28377
  for (const run of runs) {
28265
28378
  if (!run) {
28379
+ rebuiltRuns.push(run);
28266
28380
  continue;
28267
28381
  }
28268
- if (!run["a:rPr"]) {
28269
- run["a:rPr"] = {};
28270
- }
28271
- const rPr = run["a:rPr"];
28382
+ const existingRPr = run["a:rPr"] ?? {};
28383
+ const rPr = { ...existingRPr };
28272
28384
  if (style.bold !== void 0) {
28273
28385
  rPr["@_b"] = style.bold ? "1" : "0";
28274
28386
  }
@@ -28288,6 +28400,18 @@ function writeCellTextFormatting(xmlCell, style, ensureArray6) {
28288
28400
  }
28289
28401
  };
28290
28402
  }
28403
+ const rebuilt = { "a:rPr": rPr };
28404
+ for (const key of Object.keys(run)) {
28405
+ if (key === "a:rPr") {
28406
+ continue;
28407
+ }
28408
+ rebuilt[key] = run[key];
28409
+ }
28410
+ rebuiltRuns.push(rebuilt);
28411
+ runsChanged = true;
28412
+ }
28413
+ if (runsChanged && rebuiltRuns.length > 0) {
28414
+ paragraph["a:r"] = rebuiltRuns.length === 1 ? rebuiltRuns[0] : rebuiltRuns;
28291
28415
  }
28292
28416
  }
28293
28417
  }
@@ -28309,6 +28433,9 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
28309
28433
  const existingParagraphs = this.ensureArray(txBody["a:p"]);
28310
28434
  const firstRPr = this.ensureArray(existingParagraphs[0]?.["a:r"])[0]?.["a:rPr"];
28311
28435
  const firstPPr = existingParagraphs[0]?.["a:pPr"];
28436
+ const firstEndParaRPr = existingParagraphs[0]?.["a:endParaRPr"];
28437
+ const rPrForRun = firstRPr ? { ...firstRPr } : { "@_lang": "en-US", "@_dirty": "0" };
28438
+ const endParaRPr = firstEndParaRPr ? { ...firstEndParaRPr } : { "@_lang": "en-US", "@_dirty": "0" };
28312
28439
  const lines = text.split("\n");
28313
28440
  const paragraphs = lines.map((line) => {
28314
28441
  const paragraph = {};
@@ -28316,9 +28443,10 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
28316
28443
  paragraph["a:pPr"] = firstPPr;
28317
28444
  }
28318
28445
  paragraph["a:r"] = {
28319
- ...firstRPr ? { "a:rPr": firstRPr } : {},
28446
+ "a:rPr": rPrForRun,
28320
28447
  "a:t": line
28321
28448
  };
28449
+ paragraph["a:endParaRPr"] = endParaRPr;
28322
28450
  return paragraph;
28323
28451
  });
28324
28452
  txBody["a:p"] = paragraphs.length === 1 ? paragraphs[0] : paragraphs;
@@ -28468,14 +28596,27 @@ function serializeCellMergeAttributes(xmlCell, cell) {
28468
28596
  delete xmlCell["@_vMerge"];
28469
28597
  }
28470
28598
  }
28599
+ var DEFAULT_POWERPOINT_TABLE_STYLE_ID = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";
28471
28600
  function serializeTablePropertyFlags(tbl, tableData) {
28472
28601
  const tblPr = tbl["a:tblPr"] ?? {};
28473
- tblPr["@_bandRow"] = tableData.bandedRows ? "1" : "0";
28474
- tblPr["@_bandCol"] = tableData.bandedColumns ? "1" : "0";
28475
- tblPr["@_firstRow"] = tableData.firstRowHeader ? "1" : "0";
28476
- tblPr["@_lastRow"] = tableData.lastRow ? "1" : "0";
28477
- tblPr["@_firstCol"] = tableData.firstCol ? "1" : "0";
28478
- tblPr["@_lastCol"] = tableData.lastCol ? "1" : "0";
28602
+ const setOrDelete = (key, truthy) => {
28603
+ if (truthy) {
28604
+ tblPr[key] = "1";
28605
+ } else {
28606
+ delete tblPr[key];
28607
+ }
28608
+ };
28609
+ setOrDelete("@_bandRow", tableData.bandedRows);
28610
+ setOrDelete("@_bandCol", tableData.bandedColumns);
28611
+ setOrDelete("@_firstRow", tableData.firstRowHeader);
28612
+ setOrDelete("@_lastRow", tableData.lastRow);
28613
+ setOrDelete("@_firstCol", tableData.firstCol);
28614
+ setOrDelete("@_lastCol", tableData.lastCol);
28615
+ if (tableData.tableStyleId) {
28616
+ tblPr["a:tableStyleId"] = tableData.tableStyleId;
28617
+ } else if (!tblPr["a:tableStyleId"]) {
28618
+ tblPr["a:tableStyleId"] = DEFAULT_POWERPOINT_TABLE_STYLE_ID;
28619
+ }
28479
28620
  tbl["a:tblPr"] = tblPr;
28480
28621
  }
28481
28622
  function replaceFirstTextValueInTree(node, localName, newValue, getXmlLocalName) {
@@ -28520,7 +28661,9 @@ function createDefaultXmlCell() {
28520
28661
  "a:bodyPr": {},
28521
28662
  "a:lstStyle": {},
28522
28663
  "a:p": {
28523
- "a:endParaRPr": { "@_lang": "en-US" }
28664
+ // Match PowerPoint's "Insert Table" default: every paragraph-end
28665
+ // run carries `lang="en-US" dirty="0"`.
28666
+ "a:endParaRPr": { "@_lang": "en-US", "@_dirty": "0" }
28524
28667
  }
28525
28668
  },
28526
28669
  "a:tcPr": {}
@@ -28528,6 +28671,11 @@ function createDefaultXmlCell() {
28528
28671
  }
28529
28672
 
28530
28673
  // src/core/core/runtime/table-xml-rebuild.ts
28674
+ var GRID_COL_ID_EXT_URI = "{9D8B030D-6E8A-4147-A177-3AD203B41FA5}";
28675
+ var A16_NAMESPACE = "http://schemas.microsoft.com/office/drawing/2014/main";
28676
+ function randomColumnId() {
28677
+ return String(Math.floor(Math.random() * 4294967295));
28678
+ }
28531
28679
  function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
28532
28680
  const existingXmlRows = ensureArrayFn(tbl["a:tr"]);
28533
28681
  const existingGridCols = ensureArrayFn(
@@ -28536,8 +28684,31 @@ function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
28536
28684
  const totalWidthEmu = existingGridCols.reduce((sum, col) => {
28537
28685
  return sum + (parseInt(String(col?.["@_w"] || "0"), 10) || 0);
28538
28686
  }, 0) || 9144e3;
28539
- const newGridCols = tableData.columnWidths.map((w) => ({
28540
- "@_w": String(Math.round(w * totalWidthEmu))
28687
+ const existingColIds = existingGridCols.map((col) => {
28688
+ const extList = col?.["a:extLst"];
28689
+ const exts = Array.isArray(extList?.["a:ext"]) ? extList["a:ext"] : extList?.["a:ext"] ? [extList["a:ext"]] : [];
28690
+ for (const ext of exts) {
28691
+ if (ext?.["@_uri"] === GRID_COL_ID_EXT_URI) {
28692
+ const colId = ext["a16:colId"];
28693
+ const val = colId?.["@_val"];
28694
+ if (typeof val === "string" && val.length > 0) {
28695
+ return val;
28696
+ }
28697
+ }
28698
+ }
28699
+ return "";
28700
+ });
28701
+ const newGridCols = tableData.columnWidths.map((w, i) => ({
28702
+ "@_w": String(Math.round(w * totalWidthEmu)),
28703
+ "a:extLst": {
28704
+ "a:ext": {
28705
+ "@_uri": GRID_COL_ID_EXT_URI,
28706
+ "a16:colId": {
28707
+ "@_xmlns:a16": A16_NAMESPACE,
28708
+ "@_val": existingColIds[i] || randomColumnId()
28709
+ }
28710
+ }
28711
+ }
28541
28712
  }));
28542
28713
  if (!tbl["a:tblGrid"]) {
28543
28714
  tbl["a:tblGrid"] = {};
@@ -29453,32 +29624,58 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
29453
29624
  };
29454
29625
  for (const variant of variants) {
29455
29626
  const fontData = variant.rawFontData;
29456
- const guid = variant.fontGuid ?? generateFontGuid();
29457
- const fileName = `{${guid}}.fntdata`;
29458
- const fontPartPath = `ppt/fonts/${fileName}`;
29459
- const relativeTarget = `fonts/${fileName}`;
29460
- const obfuscated = obfuscateFont(fontData, guid);
29461
- this.zip.file(fontPartPath, obfuscated);
29627
+ const hasOriginal = Boolean(variant.originalRId && variant.partPath);
29628
+ const reuseObfuscation = hasOriginal && Boolean(variant.fontGuid);
29629
+ const reuseVerbatim = hasOriginal && !variant.fontGuid && Boolean(variant.originalPartBytes);
29630
+ let guid;
29631
+ let fontPartPath;
29632
+ let relativeTarget;
29462
29633
  let rId;
29463
- const existingRel = relationships.find(
29464
- (r) => String(r?.["@_Target"] || "") === relativeTarget
29465
- );
29466
- if (existingRel) {
29467
- rId = String(existingRel["@_Id"]);
29634
+ let bytesToWrite;
29635
+ let fontKeyForXml;
29636
+ if (reuseObfuscation) {
29637
+ guid = variant.fontGuid;
29638
+ fontPartPath = variant.partPath;
29639
+ relativeTarget = fontPartPath.startsWith("ppt/") ? fontPartPath.substring(4) : fontPartPath;
29640
+ rId = variant.originalRId;
29641
+ bytesToWrite = obfuscateFont(fontData, guid);
29642
+ fontKeyForXml = `{${guid}}`;
29643
+ } else if (reuseVerbatim) {
29644
+ guid = "";
29645
+ fontPartPath = variant.partPath;
29646
+ relativeTarget = fontPartPath.startsWith("ppt/") ? fontPartPath.substring(4) : fontPartPath;
29647
+ rId = variant.originalRId;
29648
+ bytesToWrite = variant.originalPartBytes;
29649
+ fontKeyForXml = void 0;
29468
29650
  } else {
29469
- maxId++;
29470
- rId = `rId${maxId}`;
29471
- relationships.push({
29472
- "@_Id": rId,
29473
- "@_Type": _PptxHandlerRuntime.FONT_REL_TYPE,
29474
- "@_Target": relativeTarget
29475
- });
29651
+ guid = variant.fontGuid ?? generateFontGuid();
29652
+ const fileName = `{${guid}}.fntdata`;
29653
+ fontPartPath = `ppt/fonts/${fileName}`;
29654
+ relativeTarget = `fonts/${fileName}`;
29655
+ bytesToWrite = obfuscateFont(fontData, guid);
29656
+ fontKeyForXml = `{${guid}}`;
29657
+ const existingRel = relationships.find(
29658
+ (r) => String(r?.["@_Target"] || "") === relativeTarget
29659
+ );
29660
+ if (existingRel) {
29661
+ rId = String(existingRel["@_Id"]);
29662
+ } else {
29663
+ maxId++;
29664
+ rId = `rId${maxId}`;
29665
+ relationships.push({
29666
+ "@_Id": rId,
29667
+ "@_Type": _PptxHandlerRuntime.FONT_REL_TYPE,
29668
+ "@_Target": relativeTarget
29669
+ });
29670
+ }
29476
29671
  }
29672
+ this.zip.file(fontPartPath, bytesToWrite);
29477
29673
  const variantKey = variant.bold && variant.italic ? "p:boldItalic" : variant.bold ? "p:bold" : variant.italic ? "p:italic" : "p:regular";
29478
- entry[variantKey] = {
29479
- "@_r:id": rId,
29480
- "@_fontKey": `{${guid}}`
29481
- };
29674
+ const variantEntry = { "@_r:id": rId };
29675
+ if (fontKeyForXml) {
29676
+ variantEntry["@_fontKey"] = fontKeyForXml;
29677
+ }
29678
+ entry[variantKey] = variantEntry;
29482
29679
  }
29483
29680
  embeddedFontEntries.push(entry);
29484
29681
  }
@@ -29622,54 +29819,59 @@ var PptxHandlerRuntime25 = class extends PptxHandlerRuntime24 {
29622
29819
  }
29623
29820
  };
29624
29821
  const root = propsData["p:presentationPr"] || {};
29625
- const showPr = root["p:showPr"] || {};
29626
- delete showPr["p:present"];
29627
- delete showPr["p:browse"];
29628
- delete showPr["p:kiosk"];
29629
- if (properties.showType === "browsed") {
29630
- showPr["p:browse"] = {};
29631
- } else if (properties.showType === "kiosk") {
29632
- const kioskNode = {};
29633
- if (properties.kioskRestartTime !== void 0 && properties.kioskRestartTime > 0) {
29634
- kioskNode["@_restart"] = String(properties.kioskRestartTime);
29822
+ const existingShowPr = root["p:showPr"] || {};
29823
+ const rebuiltShowPr = {};
29824
+ for (const key of Object.keys(existingShowPr)) {
29825
+ if (key.startsWith("@_")) {
29826
+ rebuiltShowPr[key] = existingShowPr[key];
29635
29827
  }
29636
- showPr["p:kiosk"] = kioskNode;
29637
- } else {
29638
- showPr["p:present"] = {};
29639
29828
  }
29640
29829
  if (properties.loopContinuously !== void 0) {
29641
- showPr["@_loop"] = properties.loopContinuously ? "1" : "0";
29830
+ rebuiltShowPr["@_loop"] = properties.loopContinuously ? "1" : "0";
29642
29831
  }
29643
29832
  if (properties.showWithNarration !== void 0) {
29644
- showPr["@_showNarration"] = properties.showWithNarration ? "1" : "0";
29833
+ rebuiltShowPr["@_showNarration"] = properties.showWithNarration ? "1" : "0";
29645
29834
  }
29646
29835
  if (properties.showWithAnimation !== void 0) {
29647
- showPr["@_showAnimation"] = properties.showWithAnimation ? "1" : "0";
29836
+ rebuiltShowPr["@_showAnimation"] = properties.showWithAnimation ? "1" : "0";
29648
29837
  }
29649
29838
  if (properties.advanceMode !== void 0) {
29650
- showPr["@_useTimings"] = properties.advanceMode === "useTimings" ? "1" : "0";
29839
+ rebuiltShowPr["@_useTimings"] = properties.advanceMode === "useTimings" ? "1" : "0";
29651
29840
  }
29652
- if (properties.penColor) {
29653
- showPr["p:penClr"] = {
29654
- "a:srgbClr": { "@_val": properties.penColor.replace("#", "") }
29655
- };
29841
+ if (properties.showType === "browsed") {
29842
+ rebuiltShowPr["p:browse"] = {};
29843
+ } else if (properties.showType === "kiosk") {
29844
+ const kioskNode = {};
29845
+ if (properties.kioskRestartTime !== void 0 && properties.kioskRestartTime > 0) {
29846
+ kioskNode["@_restart"] = String(properties.kioskRestartTime);
29847
+ }
29848
+ rebuiltShowPr["p:kiosk"] = kioskNode;
29849
+ } else {
29850
+ rebuiltShowPr["p:present"] = {};
29656
29851
  }
29657
- delete showPr["p:sldAll"];
29658
- delete showPr["p:sldRg"];
29659
- delete showPr["p:custShow"];
29660
29852
  if (properties.showSlidesMode === "range") {
29661
- showPr["p:sldRg"] = {
29853
+ rebuiltShowPr["p:sldRg"] = {
29662
29854
  "@_st": String(properties.showSlidesFrom ?? 1),
29663
29855
  "@_end": String(properties.showSlidesTo ?? 1)
29664
29856
  };
29665
29857
  } else if (properties.showSlidesMode === "customShow" && properties.showSlidesCustomShowId) {
29666
- showPr["p:custShow"] = {
29858
+ rebuiltShowPr["p:custShow"] = {
29667
29859
  "@_id": properties.showSlidesCustomShowId
29668
29860
  };
29669
29861
  } else {
29670
- showPr["p:sldAll"] = {};
29862
+ rebuiltShowPr["p:sldAll"] = {};
29863
+ }
29864
+ if (properties.penColor) {
29865
+ rebuiltShowPr["p:penClr"] = {
29866
+ "a:srgbClr": { "@_val": properties.penColor.replace("#", "") }
29867
+ };
29868
+ } else if (existingShowPr["p:penClr"] !== void 0) {
29869
+ rebuiltShowPr["p:penClr"] = existingShowPr["p:penClr"];
29671
29870
  }
29672
- root["p:showPr"] = showPr;
29871
+ if (existingShowPr["p:extLst"] !== void 0) {
29872
+ rebuiltShowPr["p:extLst"] = existingShowPr["p:extLst"];
29873
+ }
29874
+ root["p:showPr"] = rebuiltShowPr;
29673
29875
  if (properties.printFrameSlides !== void 0 || properties.printSlidesPerPage !== void 0 || properties.printColorMode !== void 0) {
29674
29876
  const prnPr = root["p:prnPr"] || {};
29675
29877
  if (properties.printFrameSlides !== void 0) {
@@ -30800,7 +31002,12 @@ var PptxHandlerRuntime31 = class extends PptxHandlerRuntime30 {
30800
31002
  shape = this.createPictureXml(el, relationshipId);
30801
31003
  }
30802
31004
  if (targetImagePath) {
30803
- this.zip.file(targetImagePath, parsedImage.bytes);
31005
+ const targetExt = targetImagePath.toLowerCase().match(/\.([^./\\]+)$/)?.[1];
31006
+ const parsedExt = parsedImage.extension.toLowerCase();
31007
+ const extensionMismatch = targetExt !== void 0 && targetExt !== parsedExt && !(targetExt === "jpg" && parsedExt === "jpeg") && !(targetExt === "jpeg" && parsedExt === "jpg");
31008
+ if (!extensionMismatch) {
31009
+ this.zip.file(targetImagePath, parsedImage.bytes);
31010
+ }
30804
31011
  }
30805
31012
  } else {
30806
31013
  this.compatibilityService.reportWarning({
@@ -30911,6 +31118,9 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
30911
31118
  if (!shape && el.type === "ink") {
30912
31119
  shape = this.createInkShapeXml(el);
30913
31120
  }
31121
+ if (!shape && el.type === "table") {
31122
+ shape = this.createTableGraphicFrameXml(el);
31123
+ }
30914
31124
  if (!shape) {
30915
31125
  this.compatibilityService.reportWarning({
30916
31126
  code: "SAVE_ELEMENT_SKIPPED",
@@ -31205,6 +31415,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
31205
31415
  );
31206
31416
  } else {
31207
31417
  this.zip.remove("ppt/commentAuthors.xml");
31418
+ await this.stripPresentationCommentAuthorsRelationship();
31208
31419
  }
31209
31420
  const contentTypesXmlAfterComments = await this.zip.file("[Content_Types].xml")?.async("string");
31210
31421
  if (contentTypesXmlAfterComments) {
@@ -31278,8 +31489,39 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
31278
31489
  if (effectiveConformance === "strict") {
31279
31490
  await this.convertZipToStrictConformance();
31280
31491
  }
31492
+ for (const name of Object.keys(this.zip.files)) {
31493
+ if (this.zip.files[name].dir) {
31494
+ delete this.zip.files[name];
31495
+ }
31496
+ }
31281
31497
  return await this.zip.generateAsync({ type: "uint8array" });
31282
31498
  }
31499
+ /**
31500
+ * Remove any Relationship in presentation.xml.rels whose Type matches either
31501
+ * the Transitional or Strict commentAuthors relationship URI.
31502
+ */
31503
+ async stripPresentationCommentAuthorsRelationship() {
31504
+ const relsPath = "ppt/_rels/presentation.xml.rels";
31505
+ const relsXml = await this.zip.file(relsPath)?.async("string");
31506
+ if (!relsXml) {
31507
+ return;
31508
+ }
31509
+ const relsData = this.parser.parse(relsXml);
31510
+ const root = relsData["Relationships"];
31511
+ if (!root) {
31512
+ return;
31513
+ }
31514
+ const relationships = this.ensureArray(root["Relationship"]);
31515
+ const filtered = relationships.filter((relationship) => {
31516
+ const type = String(relationship?.["@_Type"] ?? "");
31517
+ return type !== "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors" && type !== "http://purl.oclc.org/ooxml/officeDocument/relationships/commentAuthors";
31518
+ });
31519
+ if (filtered.length === relationships.length) {
31520
+ return;
31521
+ }
31522
+ root["Relationship"] = filtered;
31523
+ this.zip.file(relsPath, this.builder.build(relsData));
31524
+ }
31283
31525
  };
31284
31526
 
31285
31527
  // src/core/core/runtime/PptxHandlerRuntimeElementParsing.ts
@@ -33264,7 +33506,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
33264
33506
  }
33265
33507
  const shapeStyle = this.extractShapeStyle(effectiveSpPr, styleNode);
33266
33508
  const hasText = text.trim().length > 0;
33267
- const isPlainRect = !prstGeom || prstGeom === "rect";
33509
+ const isPlainRect = (!prstGeom || prstGeom === "rect") && !custGeom;
33268
33510
  const hasVisibleStyle = shapeStyle.fillColor && shapeStyle.fillColor !== "transparent" || (shapeStyle.strokeWidth || 0) > 0;
33269
33511
  let type = "shape";
33270
33512
  if (hasText && isPlainRect && !hasVisibleStyle) {
@@ -33276,6 +33518,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
33276
33518
  slideRelationshipMap,
33277
33519
  this.orderedSlidePaths
33278
33520
  );
33521
+ const elementName = cNvPrForActions?.["@_name"] ? String(cNvPrForActions["@_name"]).trim() : void 0;
33279
33522
  const cNvSpPr = shape?.["p:nvSpPr"]?.["p:cNvSpPr"];
33280
33523
  const spLocksNode = cNvSpPr?.["a:spLocks"];
33281
33524
  const slideLocks = this.parseShapeLocks(spLocksNode);
@@ -33286,6 +33529,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
33286
33529
  const promptText = !hasText && phDefaults?.promptText ? phDefaults.promptText : void 0;
33287
33530
  const commonProps = {
33288
33531
  id,
33532
+ name: elementName || void 0,
33289
33533
  x,
33290
33534
  y,
33291
33535
  width,
@@ -33522,12 +33766,14 @@ var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
33522
33766
  picSlideRels,
33523
33767
  this.orderedSlidePaths
33524
33768
  );
33769
+ const picElementName = picCNvPr?.["@_name"] ? String(picCNvPr["@_name"]).trim() : void 0;
33525
33770
  const picCNvPicPr = pic?.["p:nvPicPr"]?.["p:cNvPicPr"];
33526
33771
  const picLocks = this.parseShapeLocks(
33527
33772
  picCNvPicPr?.["a:picLocks"] ?? picCNvPicPr?.["a:spLocks"]
33528
33773
  );
33529
33774
  return {
33530
33775
  id,
33776
+ name: picElementName || void 0,
33531
33777
  type: "picture",
33532
33778
  x,
33533
33779
  y,
@@ -34074,9 +34320,11 @@ var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
34074
34320
  grpSlideRels,
34075
34321
  this.orderedSlidePaths
34076
34322
  );
34323
+ const grpElementName = grpCNvPr?.["@_name"] ? String(grpCNvPr["@_name"]).trim() : void 0;
34077
34324
  const groupElement = {
34078
34325
  type: "group",
34079
34326
  id: baseId,
34327
+ name: grpElementName || void 0,
34080
34328
  x: parentX,
34081
34329
  y: parentY,
34082
34330
  width: parentW || Math.max(...children.map((c) => c.x + c.width)),
@@ -37956,6 +38204,7 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
37956
38204
  if (!fontBinary || fontBinary.length === 0) {
37957
38205
  return null;
37958
38206
  }
38207
+ const originalPartBytes = new Uint8Array(fontBinary);
37959
38208
  let fontData;
37960
38209
  let resolvedGuid;
37961
38210
  if (isEotFormat(fontBinary)) {
@@ -38009,7 +38258,9 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
38009
38258
  format,
38010
38259
  rawFontData: fontData,
38011
38260
  partPath: fontPath,
38012
- fontGuid: resolvedGuid
38261
+ fontGuid: resolvedGuid,
38262
+ originalRId: rId,
38263
+ originalPartBytes
38013
38264
  };
38014
38265
  } catch {
38015
38266
  return null;