pptx-viewer-core 1.6.8 → 1.6.10

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.
package/dist/index.mjs CHANGED
@@ -2589,6 +2589,7 @@ var TextShapeXmlFactory = class {
2589
2589
  createXmlElement(init) {
2590
2590
  const { element } = init;
2591
2591
  const isText = element.type === "text";
2592
+ const isTextBox = element.locks?.txBox ?? isText;
2592
2593
  const name = isText ? "TextBox" : "Rectangle";
2593
2594
  const geometry = this.context.normalizePresetGeometry(element.shapeType);
2594
2595
  const adjustmentEntries = Object.entries(element.shapeAdjustments || {}).filter(
@@ -2608,7 +2609,7 @@ var TextShapeXmlFactory = class {
2608
2609
  "@_name": `${name} ${elementId}`
2609
2610
  },
2610
2611
  "p:cNvSpPr": {
2611
- "@_txBox": isText ? "1" : "0"
2612
+ "@_txBox": isTextBox ? "1" : "0"
2612
2613
  },
2613
2614
  "p:nvPr": {}
2614
2615
  },
@@ -3234,6 +3235,21 @@ function cloneXmlObject(value) {
3234
3235
 
3235
3236
  // src/core/utils/presentation-collections.ts
3236
3237
  var SECTION_EXTENSION_URI = "{521415D9-36F7-43E2-AB2F-B90AF26B5E84}";
3238
+ function remapReferenceList(references, mapping, removed) {
3239
+ const result = [];
3240
+ for (const reference of references) {
3241
+ const mapped = mapping.get(reference);
3242
+ if (mapped !== void 0) {
3243
+ result.push(mapped);
3244
+ continue;
3245
+ }
3246
+ if (removed.has(reference)) {
3247
+ continue;
3248
+ }
3249
+ result.push(reference);
3250
+ }
3251
+ return result;
3252
+ }
3237
3253
  function localName4(key) {
3238
3254
  return key.split(":").pop() ?? key;
3239
3255
  }
@@ -3300,7 +3316,7 @@ function updateCustomShow(show, existing) {
3300
3316
  replaceChildren(node, "sldLst", slideList, "p:sldLst");
3301
3317
  return node;
3302
3318
  }
3303
- function applyCustomShows(presentation, shows, lookup) {
3319
+ function applyCustomShows(presentation, shows, lookup, remap) {
3304
3320
  if (shows === void 0) {
3305
3321
  return;
3306
3322
  }
@@ -3314,14 +3330,18 @@ function applyCustomShows(presentation, shows, lookup) {
3314
3330
  const oldList = key ? presentation[key] : void 0;
3315
3331
  const list = cloneXmlObject(oldList) ?? {};
3316
3332
  const oldShows = lookup.getChildrenArrayByLocalName(oldList, "custShow");
3317
- const updated = shows.map(
3318
- (show) => updateCustomShow(
3319
- show,
3333
+ const updated = shows.map((show) => {
3334
+ const effective = remap && remap.changed ? {
3335
+ ...show,
3336
+ slideRIds: remapReferenceList(show.slideRIds, remap.rIdByOldRId, remap.removedRIds)
3337
+ } : show;
3338
+ return updateCustomShow(
3339
+ effective,
3320
3340
  oldShows.find(
3321
3341
  (node) => String(node[attributeKey(node, "id") ?? ""]) === show.id || String(node[attributeKey(node, "name") ?? ""]) === show.name
3322
3342
  )
3323
- )
3324
- );
3343
+ );
3344
+ });
3325
3345
  replaceChildren(list, "custShow", updated, "p:custShow");
3326
3346
  presentation[key ?? "p:custShowLst"] = list;
3327
3347
  }
@@ -3370,7 +3390,7 @@ function updateSection(section) {
3370
3390
  }
3371
3391
  return node;
3372
3392
  }
3373
- function applySections(presentation, sections, lookup) {
3393
+ function applySections(presentation, sections, lookup, remap) {
3374
3394
  if (sections === void 0) {
3375
3395
  return;
3376
3396
  }
@@ -3392,7 +3412,15 @@ function applySections(presentation, sections, lookup) {
3392
3412
  location = { parent: ext, key: "p14:sectionLst", list: ext["p14:sectionLst"] };
3393
3413
  }
3394
3414
  const list = cloneXmlObject(location.list) ?? {};
3395
- replaceChildren(list, "section", sections.map(updateSection), "p14:section");
3415
+ const effectiveSections = remap && remap.changed ? sections.map((section) => ({
3416
+ ...section,
3417
+ slideIds: remapReferenceList(
3418
+ section.slideIds,
3419
+ remap.sldIdByOldSldId,
3420
+ remap.removedSldIds
3421
+ )
3422
+ })) : sections;
3423
+ replaceChildren(list, "section", effectiveSections.map(updateSection), "p14:section");
3396
3424
  location.parent[location.key] = list;
3397
3425
  }
3398
3426
 
@@ -3413,8 +3441,18 @@ var PptxPresentationSaveBuilder = class {
3413
3441
  init.rawSlideHeightEmu,
3414
3442
  init.rawSlideSizeType
3415
3443
  );
3416
- applyCustomShows(presentation, init.options?.customShows, init.xmlLookupService);
3417
- applySections(presentation, init.options?.sections, init.xmlLookupService);
3444
+ applyCustomShows(
3445
+ presentation,
3446
+ init.options?.customShows,
3447
+ init.xmlLookupService,
3448
+ init.slideReferenceRemap
3449
+ );
3450
+ applySections(
3451
+ presentation,
3452
+ init.options?.sections,
3453
+ init.xmlLookupService,
3454
+ init.slideReferenceRemap
3455
+ );
3418
3456
  this.applyPhotoAlbum(presentation, init.options?.photoAlbum);
3419
3457
  presentation = this.applyKinsoku(presentation, init.options?.kinsoku);
3420
3458
  this.applyModifyVerifier(presentation, init.options?.modifyVerifier);
@@ -3509,6 +3547,53 @@ var PptxPresentationSaveBuilder = class {
3509
3547
  }
3510
3548
  };
3511
3549
 
3550
+ // src/core/core/builders/slide-reference-remap.ts
3551
+ function buildSlideReferenceRemap(init) {
3552
+ const pathToNewRId = /* @__PURE__ */ new Map();
3553
+ for (const slide of init.slides) {
3554
+ pathToNewRId.set(slide.id, slide.rId);
3555
+ }
3556
+ const newRIdToNumeric = /* @__PURE__ */ new Map();
3557
+ for (const entry of init.rebuiltSlideIds) {
3558
+ const relationshipId2 = String(entry?.["@_r:id"] ?? "");
3559
+ const numericSlideId = String(entry?.["@_id"] ?? "");
3560
+ if (relationshipId2.length > 0 && numericSlideId.length > 0) {
3561
+ newRIdToNumeric.set(relationshipId2, numericSlideId);
3562
+ }
3563
+ }
3564
+ const rIdByOldRId = /* @__PURE__ */ new Map();
3565
+ const removedRIds = /* @__PURE__ */ new Set();
3566
+ let changed = false;
3567
+ for (const [oldRId, path] of init.originalRIdToPath.entries()) {
3568
+ const newRId = pathToNewRId.get(path);
3569
+ if (newRId === void 0) {
3570
+ removedRIds.add(oldRId);
3571
+ changed = true;
3572
+ continue;
3573
+ }
3574
+ rIdByOldRId.set(oldRId, newRId);
3575
+ if (newRId !== oldRId) {
3576
+ changed = true;
3577
+ }
3578
+ }
3579
+ const sldIdByOldSldId = /* @__PURE__ */ new Map();
3580
+ const removedSldIds = /* @__PURE__ */ new Set();
3581
+ for (const [oldSldId, path] of init.originalSldIdToPath.entries()) {
3582
+ const newRId = pathToNewRId.get(path);
3583
+ const newSldId = newRId === void 0 ? void 0 : newRIdToNumeric.get(newRId);
3584
+ if (newSldId === void 0) {
3585
+ removedSldIds.add(oldSldId);
3586
+ changed = true;
3587
+ continue;
3588
+ }
3589
+ sldIdByOldSldId.set(oldSldId, newSldId);
3590
+ if (newSldId !== oldSldId) {
3591
+ changed = true;
3592
+ }
3593
+ }
3594
+ return { rIdByOldRId, sldIdByOldSldId, removedRIds, removedSldIds, changed };
3595
+ }
3596
+
3512
3597
  // src/core/core/builders/PptxPresentationSlidesReconciler.ts
3513
3598
  var PptxPresentationSlidesReconciler = class {
3514
3599
  async reconcile(input) {
@@ -3554,6 +3639,10 @@ var PptxPresentationSlidesReconciler = class {
3554
3639
  const existingSlideIds = slideIdList ? this.ensureArray(slideIdList["p:sldId"]) : [];
3555
3640
  const slideIdByRid = /* @__PURE__ */ new Map();
3556
3641
  let maxNumericSlideId = 255;
3642
+ const originalRIdToPath = /* @__PURE__ */ new Map();
3643
+ for (const [relationshipId2, target] of slideTargetByRid.entries()) {
3644
+ originalRIdToPath.set(relationshipId2, input.toSlidePathFromTarget(target));
3645
+ }
3557
3646
  for (const slideIdEntry of existingSlideIds) {
3558
3647
  const relationshipId2 = slideIdEntry?.["@_r:id"];
3559
3648
  if (typeof relationshipId2 === "string" && relationshipId2.length > 0) {
@@ -3564,6 +3653,15 @@ var PptxPresentationSlidesReconciler = class {
3564
3653
  maxNumericSlideId = Math.max(maxNumericSlideId, numericSlideId);
3565
3654
  }
3566
3655
  }
3656
+ const originalSldIdToPath = /* @__PURE__ */ new Map();
3657
+ for (const slideIdEntry of existingSlideIds) {
3658
+ const relationshipId2 = String(slideIdEntry?.["@_r:id"] ?? "");
3659
+ const numericSlideId = String(slideIdEntry?.["@_id"] ?? "");
3660
+ const slidePath = originalRIdToPath.get(relationshipId2);
3661
+ if (numericSlideId.length > 0 && slidePath !== void 0) {
3662
+ originalSldIdToPath.set(numericSlideId, slidePath);
3663
+ }
3664
+ }
3567
3665
  for (let index = 0; index < input.slides.length; index++) {
3568
3666
  const slide = input.slides[index];
3569
3667
  slide.slideNumber = index + 1;
@@ -3600,6 +3698,7 @@ var PptxPresentationSlidesReconciler = class {
3600
3698
  ];
3601
3699
  presentationRelsData["Relationships"] = relRoot;
3602
3700
  input.zip.file("ppt/_rels/presentation.xml.rels", input.xmlBuilder.build(presentationRelsData));
3701
+ const rebuiltSlideIds = [];
3603
3702
  if (presentation && slideIdList && input.presentationData) {
3604
3703
  slideIdList["p:sldId"] = input.slides.map((slide) => {
3605
3704
  const existing = slideIdByRid.get(slide.rId);
@@ -3612,11 +3711,18 @@ var PptxPresentationSlidesReconciler = class {
3612
3711
  "@_r:id": slide.rId
3613
3712
  };
3614
3713
  });
3714
+ rebuiltSlideIds.push(...slideIdList["p:sldId"]);
3615
3715
  input.presentationData["p:presentation"] = this.insertSlideIdListInOrder(
3616
3716
  presentation,
3617
3717
  slideIdList
3618
3718
  );
3619
3719
  }
3720
+ return buildSlideReferenceRemap({
3721
+ slides: input.slides,
3722
+ originalRIdToPath,
3723
+ originalSldIdToPath,
3724
+ rebuiltSlideIds
3725
+ });
3620
3726
  }
3621
3727
  /**
3622
3728
  * Return a new presentation XML object whose `p:sldIdLst` child sits in the
@@ -4278,7 +4384,7 @@ var SHAPE_STYLE_ORDER = [
4278
4384
 
4279
4385
  // src/core/core/builders/PptxSlideBackgroundBuilder.ts
4280
4386
  var PptxSlideBackgroundBuilder = class {
4281
- applyBackground(init) {
4387
+ async applyBackground(init) {
4282
4388
  const hasBackgroundColor = typeof init.slide.backgroundColor === "string" && init.slide.backgroundColor.length > 0 && init.slide.backgroundColor !== "transparent";
4283
4389
  const rawBackgroundImage = typeof init.slide.backgroundImage === "string" ? init.slide.backgroundImage : "";
4284
4390
  const hasBackgroundImage = rawBackgroundImage.length > 0;
@@ -4299,8 +4405,8 @@ var PptxSlideBackgroundBuilder = class {
4299
4405
  return;
4300
4406
  }
4301
4407
  const backgroundProperties = {};
4302
- if (hasDataUrlBackgroundImage) {
4303
- const parsedBackgroundImage = init.parseDataUrlToBytes(rawBackgroundImage);
4408
+ if (hasBackgroundImage) {
4409
+ const parsedBackgroundImage = await init.resolveImageToBytes(rawBackgroundImage);
4304
4410
  if (parsedBackgroundImage) {
4305
4411
  const backgroundImagePath = init.saveState.nextMediaPath(parsedBackgroundImage.extension);
4306
4412
  init.zip.file(backgroundImagePath, parsedBackgroundImage.bytes);
@@ -4318,8 +4424,11 @@ var PptxSlideBackgroundBuilder = class {
4318
4424
  },
4319
4425
  BLIP_FILL_ORDER
4320
4426
  );
4427
+ } else {
4428
+ init.reportUnsupportedBackground?.(rawBackgroundImage);
4321
4429
  }
4322
- } else if (hasBackgroundColor && init.slide.backgroundColor) {
4430
+ }
4431
+ if (backgroundProperties["a:blipFill"] === void 0 && hasBackgroundColor && init.slide.backgroundColor) {
4323
4432
  backgroundProperties["a:solidFill"] = {
4324
4433
  "a:srgbClr": {
4325
4434
  "@_val": init.slide.backgroundColor.replace("#", "").toUpperCase()
@@ -4336,6 +4445,11 @@ var PptxSlideBackgroundBuilder = class {
4336
4445
  backgroundProperties["@_shadeToTitle"] = "0";
4337
4446
  }
4338
4447
  if (!hasFillChild) {
4448
+ if (existingBg !== void 0) {
4449
+ this.reorderCSldBgFirst(cSld, existingBg);
4450
+ init.slideNode["p:cSld"] = cSld;
4451
+ return;
4452
+ }
4339
4453
  delete cSld["p:bg"];
4340
4454
  init.slideNode["p:cSld"] = cSld;
4341
4455
  return;
@@ -4409,6 +4523,11 @@ function parseDrawingPercent(value) {
4409
4523
  }
4410
4524
  return clampUnitInterval(parsed / 1e5);
4411
4525
  }
4526
+ function scrgbLinearToSrgb8(linear) {
4527
+ const l = Math.min(1, Math.max(0, linear));
4528
+ const companded = l <= 31308e-7 ? 12.92 * l : 1.055 * l ** (1 / 2.4) - 0.055;
4529
+ return Math.min(255, Math.max(0, Math.round(companded * 255)));
4530
+ }
4412
4531
  function toHex(value) {
4413
4532
  return Math.min(255, Math.max(0, Math.round(value))).toString(16).padStart(2, "0").toUpperCase();
4414
4533
  }
@@ -4962,11 +5081,15 @@ var PptxColorTransformCodec = class {
4962
5081
  }
4963
5082
  if (colorChoice["a:scrgbClr"]) {
4964
5083
  const scrgb = colorChoice["a:scrgbClr"];
4965
- const red = this.percentAttrToUnit(scrgb["@_r"]);
4966
- const green = this.percentAttrToUnit(scrgb["@_g"]);
4967
- const blue = this.percentAttrToUnit(scrgb["@_b"]);
5084
+ const red = parseDrawingFraction(scrgb["@_r"]);
5085
+ const green = parseDrawingFraction(scrgb["@_g"]);
5086
+ const blue = parseDrawingFraction(scrgb["@_b"]);
4968
5087
  if (red !== void 0 && green !== void 0 && blue !== void 0) {
4969
- const base = this.rgbToHex(red * 255, green * 255, blue * 255);
5088
+ const base = this.rgbToHex(
5089
+ scrgbLinearToSrgb8(red),
5090
+ scrgbLinearToSrgb8(green),
5091
+ scrgbLinearToSrgb8(blue)
5092
+ );
4970
5093
  return this.applyColorTransforms(base, scrgb);
4971
5094
  }
4972
5095
  }
@@ -5057,8 +5180,8 @@ var PptxColorTransformCodec = class {
5057
5180
  };
5058
5181
  }
5059
5182
  rgbToHex(r, g, b) {
5060
- const toHex3 = (channelValue) => this.clampColorChannel(channelValue).toString(16).padStart(2, "0").toUpperCase();
5061
- return `#${toHex3(r)}${toHex3(g)}${toHex3(b)}`;
5183
+ const toHex4 = (channelValue) => this.clampColorChannel(channelValue).toString(16).padStart(2, "0").toUpperCase();
5184
+ return `#${toHex4(r)}${toHex4(g)}${toHex4(b)}`;
5062
5185
  }
5063
5186
  applyColorTransforms(baseColor, colorNode) {
5064
5187
  return applyDrawingColorTransforms(baseColor, colorNode);
@@ -5146,6 +5269,22 @@ function mergeDrawingFillXml(original, generated, modeledChildren, childOrder2)
5146
5269
  }
5147
5270
 
5148
5271
  // src/core/core/builders/PptxGradientStyleCodec.ts
5272
+ function extractGradientTileRect(gradFill) {
5273
+ const tileRect = drawingChild(gradFill, "tileRect");
5274
+ if (!tileRect) {
5275
+ return void 0;
5276
+ }
5277
+ const toFraction = (raw) => {
5278
+ const parsed = Number.parseInt(String(raw ?? "0"), 10);
5279
+ return Number.isFinite(parsed) ? parsed / 1e5 : 0;
5280
+ };
5281
+ return {
5282
+ l: toFraction(tileRect["@_l"]),
5283
+ t: toFraction(tileRect["@_t"]),
5284
+ r: toFraction(tileRect["@_r"]),
5285
+ b: toFraction(tileRect["@_b"])
5286
+ };
5287
+ }
5149
5288
  var PptxGradientStyleCodec = class {
5150
5289
  context;
5151
5290
  constructor(context) {
@@ -5256,6 +5395,9 @@ var PptxGradientStyleCodec = class {
5256
5395
  b: Number.isFinite(b) ? this.context.clampUnitInterval(b / 1e5) : 0
5257
5396
  };
5258
5397
  }
5398
+ extractGradientTileRect(gradFill) {
5399
+ return extractGradientTileRect(gradFill);
5400
+ }
5259
5401
  extractGradientFlip(gradFill) {
5260
5402
  const flipRaw = String(gradFill["@_flip"] || "").trim().toLowerCase();
5261
5403
  if (flipRaw === "x" || flipRaw === "y" || flipRaw === "xy" || flipRaw === "none") {
@@ -5427,6 +5569,15 @@ var PptxGradientStyleCodec = class {
5427
5569
  }
5428
5570
  gradientXml["a:lin"] = linNode;
5429
5571
  }
5572
+ if (shapeStyle.fillGradientTileRect) {
5573
+ const tr = shapeStyle.fillGradientTileRect;
5574
+ gradientXml["a:tileRect"] = {
5575
+ "@_l": String(Math.round(tr.l * 1e5)),
5576
+ "@_t": String(Math.round(tr.t * 1e5)),
5577
+ "@_r": String(Math.round(tr.r * 1e5)),
5578
+ "@_b": String(Math.round(tr.b * 1e5))
5579
+ };
5580
+ }
5430
5581
  return mergeDrawingFillXml(
5431
5582
  shapeStyle.fillGradientXml,
5432
5583
  gradientXml,
@@ -6960,7 +7111,7 @@ var PptxColorStyleCodec = class {
6960
7111
  const alphaMod = this.percentAttrToUnit(
6961
7112
  choiceNode["a:alphaMod"]?.["@_val"]
6962
7113
  );
6963
- const alphaOff = this.percentAttrToUnit(
7114
+ const alphaOff = this.signedPercentToUnit(
6964
7115
  choiceNode["a:alphaOff"]?.["@_val"]
6965
7116
  );
6966
7117
  if (alpha === void 0 && alphaMod === void 0 && alphaOff === void 0) {
@@ -6975,6 +7126,18 @@ var PptxColorStyleCodec = class {
6975
7126
  }
6976
7127
  return this.clampUnitInterval(opacity2);
6977
7128
  }
7129
+ /**
7130
+ * Parse an OOXML percentage (thousandths, `100000` = 100%) into a fraction
7131
+ * WITHOUT clamping to [0, 1]. Used for additive offsets like `a:alphaOff`
7132
+ * that legitimately carry negative values.
7133
+ */
7134
+ signedPercentToUnit(value) {
7135
+ const parsed = Number.parseFloat(String(value ?? "").trim());
7136
+ if (!Number.isFinite(parsed)) {
7137
+ return void 0;
7138
+ }
7139
+ return parsed / 1e5;
7140
+ }
6978
7141
  colorWithOpacity(color2, opacity2) {
6979
7142
  if (opacity2 === void 0) {
6980
7143
  return color2;
@@ -7083,26 +7246,49 @@ function applyScene3dStyle(shapeProps, style) {
7083
7246
  const camera = scene3dNode["a:camera"];
7084
7247
  const lightRig = scene3dNode["a:lightRig"];
7085
7248
  const cameraRot = camera?.["a:rot"];
7249
+ const lightRigRot = lightRig?.["a:rot"];
7086
7250
  style.scene3d = {
7087
7251
  cameraPreset: String(camera?.["@_prst"] || "").trim() || void 0,
7088
- cameraRotX: cameraRot?.["@_lat"] !== void 0 ? parseInt(String(cameraRot["@_lat"]), 10) : void 0,
7089
- cameraRotY: cameraRot?.["@_lon"] !== void 0 ? parseInt(String(cameraRot["@_lon"]), 10) : void 0,
7090
- cameraRotZ: cameraRot?.["@_rev"] !== void 0 ? parseInt(String(cameraRot["@_rev"]), 10) : void 0,
7252
+ cameraFieldOfView: intAttr(camera?.["@_fov"]),
7253
+ cameraZoom: floatAttr(camera?.["@_zoom"]),
7254
+ cameraRotX: intAttr(cameraRot?.["@_lat"]),
7255
+ cameraRotY: intAttr(cameraRot?.["@_lon"]),
7256
+ cameraRotZ: intAttr(cameraRot?.["@_rev"]),
7091
7257
  lightRigType: String(lightRig?.["@_rig"] || "").trim() || void 0,
7092
- lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0
7258
+ lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0,
7259
+ lightRigRotX: intAttr(lightRigRot?.["@_lat"]),
7260
+ lightRigRotY: intAttr(lightRigRot?.["@_lon"]),
7261
+ lightRigRotZ: intAttr(lightRigRot?.["@_rev"])
7093
7262
  };
7094
7263
  const backdrop = scene3dNode["a:backdrop"];
7095
7264
  if (backdrop) {
7096
7265
  style.scene3d.hasBackdrop = true;
7097
7266
  const anchor = backdrop["a:anchor"];
7098
- const anchorAttrs = anchor;
7099
- if (anchorAttrs) {
7100
- style.scene3d.backdropAnchorX = parseInt(String(anchorAttrs["@_x"] || "0"), 10);
7101
- style.scene3d.backdropAnchorY = parseInt(String(anchorAttrs["@_y"] || "0"), 10);
7102
- style.scene3d.backdropAnchorZ = parseInt(String(anchorAttrs["@_z"] || "0"), 10);
7267
+ if (anchor) {
7268
+ style.scene3d.backdropAnchorX = intAttr(anchor["@_x"]) ?? 0;
7269
+ style.scene3d.backdropAnchorY = intAttr(anchor["@_y"]) ?? 0;
7270
+ style.scene3d.backdropAnchorZ = intAttr(anchor["@_z"]) ?? 0;
7271
+ }
7272
+ const norm = backdrop["a:norm"];
7273
+ if (norm) {
7274
+ style.scene3d.backdropNormalX = intAttr(norm["@_dx"]) ?? 0;
7275
+ style.scene3d.backdropNormalY = intAttr(norm["@_dy"]) ?? 0;
7276
+ style.scene3d.backdropNormalZ = intAttr(norm["@_dz"]) ?? 0;
7277
+ }
7278
+ const up = backdrop["a:up"];
7279
+ if (up) {
7280
+ style.scene3d.backdropUpX = intAttr(up["@_dx"]) ?? 0;
7281
+ style.scene3d.backdropUpY = intAttr(up["@_dy"]) ?? 0;
7282
+ style.scene3d.backdropUpZ = intAttr(up["@_dz"]) ?? 0;
7103
7283
  }
7104
7284
  }
7105
7285
  }
7286
+ function intAttr(value) {
7287
+ return value !== void 0 ? parseInt(String(value), 10) : void 0;
7288
+ }
7289
+ function floatAttr(value) {
7290
+ return value !== void 0 ? parseFloat(String(value)) : void 0;
7291
+ }
7106
7292
  function applyShape3dStyle(shapeProps, style, context) {
7107
7293
  const shape3dNode = shapeProps["a:sp3d"];
7108
7294
  if (!shape3dNode) {
@@ -7135,10 +7321,12 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
7135
7321
  }
7136
7322
  const hiddenLineFill = hiddenLineProps["a:solidFill"];
7137
7323
  if (hiddenLineFill) {
7324
+ style.strokeFillMode = "solid";
7138
7325
  style.strokeColor = context.parseColor(hiddenLineFill);
7139
7326
  style.strokeOpacity = context.extractColorOpacity(hiddenLineFill);
7140
7327
  }
7141
7328
  } else {
7329
+ style.strokeFillMode = "none";
7142
7330
  style.strokeWidth = 0;
7143
7331
  style.strokeColor = "transparent";
7144
7332
  }
@@ -7156,6 +7344,7 @@ function applyLineProperties(lineNode, shapeProps, style, context, resolveHidden
7156
7344
  }
7157
7345
  function applyStrokeColor(lineNode, style, context) {
7158
7346
  if (lineNode["a:solidFill"]) {
7347
+ style.strokeFillMode = "solid";
7159
7348
  const lineFill = lineNode["a:solidFill"];
7160
7349
  style.strokeColor = context.parseColor(lineFill);
7161
7350
  style.strokeOpacity = context.extractColorOpacity(lineFill);
@@ -7164,10 +7353,15 @@ function applyStrokeColor(lineNode, style, context) {
7164
7353
  style.strokeColorXml = strokeColorXml;
7165
7354
  }
7166
7355
  } else if (lineNode["a:gradFill"]) {
7167
- style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
7168
- style.strokeOpacity = context.extractGradientOpacity(lineNode["a:gradFill"]);
7356
+ style.strokeFillMode = "gradient";
7357
+ const lineGradFill = lineNode["a:gradFill"];
7358
+ style.strokeGradientXml = lineGradFill;
7359
+ style.strokeColor = context.extractGradientFillColor(lineGradFill);
7360
+ style.strokeOpacity = context.extractGradientOpacity(lineGradFill);
7169
7361
  } else if (lineNode["a:pattFill"]) {
7362
+ style.strokeFillMode = "pattern";
7170
7363
  const linePatternFill = lineNode["a:pattFill"];
7364
+ style.strokePatternXml = linePatternFill;
7171
7365
  style.strokeColor = context.parseColor(linePatternFill["a:fgClr"]) || context.parseColor(linePatternFill["a:bgClr"]);
7172
7366
  style.strokeOpacity = context.extractColorOpacity(linePatternFill["a:fgClr"]) || context.extractColorOpacity(linePatternFill["a:bgClr"]);
7173
7367
  }
@@ -7296,6 +7490,10 @@ var PptxShapeStyleExtractor = class {
7296
7490
  style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
7297
7491
  style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
7298
7492
  style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
7493
+ const gradTileRect = extractGradientTileRect(gradFill);
7494
+ if (gradTileRect) {
7495
+ style.fillGradientTileRect = gradTileRect;
7496
+ }
7299
7497
  const gradFlip = this.context.extractGradientFlip(gradFill);
7300
7498
  if (gradFlip) {
7301
7499
  style.fillGradientFlip = gradFlip;
@@ -7984,7 +8182,7 @@ var MEDIA_REFERENCE_NAMES = [
7984
8182
  "videoFile",
7985
8183
  "quickTimeFile"
7986
8184
  ];
7987
- function parseDrawingMediaReference(container) {
8185
+ function parseDrawingMediaReference(container, externalRelIds) {
7988
8186
  if (!container) {
7989
8187
  return void 0;
7990
8188
  }
@@ -7993,11 +8191,17 @@ function parseDrawingMediaReference(container) {
7993
8191
  if (!node) {
7994
8192
  continue;
7995
8193
  }
8194
+ const linkId = String(attribute2(node, "link") ?? "").trim() || void 0;
8195
+ const embedId = String(attribute2(node, "embed") ?? "").trim() || void 0;
7996
8196
  return {
7997
8197
  kind,
7998
8198
  mediaType: kind === "videoFile" || kind === "quickTimeFile" ? "video" : "audio",
7999
- relationshipId: String(attribute2(node, "link") ?? attribute2(node, "embed") ?? "").trim() || void 0,
8000
- isLinked: attribute2(node, "link") !== void 0,
8199
+ relationshipId: linkId ?? embedId,
8200
+ // Embedded media legitimately uses r:link pointing at an INTERNAL
8201
+ // media part, so link presence alone does not imply a linked clip.
8202
+ // It is only truly linked when the referenced relationship is
8203
+ // external (TargetMode="External"), mirroring the OLE parser.
8204
+ isLinked: linkId !== void 0 && externalRelIds?.has(linkId) === true,
8001
8205
  name: kind === "wavAudioFile" ? String(attribute2(node, "name") ?? "") || void 0 : void 0,
8002
8206
  contentType: kind === "audioFile" ? String(attribute2(node, "contentType") ?? "") || void 0 : void 0,
8003
8207
  audioCdStart: kind === "audioCd" ? parseAudioCdPosition(child2(node, "st")) : void 0,
@@ -8128,7 +8332,10 @@ var PptxMediaDataParser = class {
8128
8332
  parseMediaData(graphicData, slidePath) {
8129
8333
  const result = {};
8130
8334
  try {
8131
- const reference = parseDrawingMediaReference(graphicData);
8335
+ const reference = parseDrawingMediaReference(
8336
+ graphicData,
8337
+ this.context.externalRelsMap.get(slidePath)
8338
+ );
8132
8339
  if (reference) {
8133
8340
  result.mediaType = reference.mediaType;
8134
8341
  result.mediaReferenceKind = reference.kind;
@@ -8739,6 +8946,7 @@ var PptxLoadDataBuilder = class {
8739
8946
  layoutOptions = [];
8740
8947
  headerFooter;
8741
8948
  presentationProperties;
8949
+ viewProperties;
8742
8950
  customShows;
8743
8951
  sections;
8744
8952
  warnings = [];
@@ -8798,6 +9006,10 @@ var PptxLoadDataBuilder = class {
8798
9006
  this.presentationProperties = presentationProperties;
8799
9007
  return this;
8800
9008
  }
9009
+ withViewProperties(viewProperties) {
9010
+ this.viewProperties = viewProperties;
9011
+ return this;
9012
+ }
8801
9013
  withCustomShows(customShows) {
8802
9014
  this.customShows = customShows;
8803
9015
  return this;
@@ -8935,6 +9147,7 @@ var PptxLoadDataBuilder = class {
8935
9147
  layoutOptions: this.layoutOptions,
8936
9148
  headerFooter: this.headerFooter,
8937
9149
  presentationProperties: this.presentationProperties,
9150
+ viewProperties: this.viewProperties,
8938
9151
  customShows: this.customShows,
8939
9152
  sections: this.sections,
8940
9153
  warnings: this.warnings,
@@ -9317,7 +9530,7 @@ var PptxSlideCommentsXmlFactory = class {
9317
9530
  const createdAtIso = this.resolveCreatedAt(comment.createdAt);
9318
9531
  const x = init.saveState.toEmu(comment.x, 0);
9319
9532
  const y = init.saveState.toEmu(comment.y, 0);
9320
- return {
9533
+ const node = {
9321
9534
  ...withoutChildrenByLocalName(comment.rawXml ?? {}, /* @__PURE__ */ new Set(["pos", "text"])),
9322
9535
  "@_authorId": authorId,
9323
9536
  "@_dt": createdAtIso,
@@ -9328,6 +9541,28 @@ var PptxSlideCommentsXmlFactory = class {
9328
9541
  },
9329
9542
  "p:text": String(comment.text || "")
9330
9543
  };
9544
+ this.applyResolvedState(node, comment);
9545
+ return node;
9546
+ }
9547
+ /**
9548
+ * Reflect the (possibly edited) `resolved` flag onto the legacy comment
9549
+ * node. PowerPoint's legacy comment schema has no standard resolved marker,
9550
+ * but the parser reads a non-standard `@_done` / `@_resolved` attribute, so
9551
+ * we re-emit the current state rather than leaving the stale value carried
9552
+ * over from `rawXml`. The original attribute name is preserved when present.
9553
+ */
9554
+ applyResolvedState(node, comment) {
9555
+ const raw = comment.rawXml;
9556
+ const hadResolvedAttr = raw?.["@_resolved"] !== void 0;
9557
+ const hadDoneAttr = raw?.["@_done"] !== void 0;
9558
+ const key = hadResolvedAttr && !hadDoneAttr ? "@_resolved" : "@_done";
9559
+ delete node["@_done"];
9560
+ delete node["@_resolved"];
9561
+ if (comment.resolved === true) {
9562
+ node[key] = "1";
9563
+ } else if (hadResolvedAttr || hadDoneAttr) {
9564
+ node[key] = "0";
9565
+ }
9331
9566
  }
9332
9567
  resolveCreatedAt(createdAt) {
9333
9568
  const candidate = String(createdAt || "").trim();
@@ -10640,6 +10875,226 @@ var PptxCompatibilityService = class {
10640
10875
  }
10641
10876
  };
10642
10877
 
10878
+ // src/core/utils/xml-access.ts
10879
+ var ATTR_PREFIX = "@_";
10880
+ var TEXT_KEY = "#text";
10881
+ function isXmlObject(value) {
10882
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10883
+ }
10884
+ function coerceString(value) {
10885
+ if (typeof value === "string") {
10886
+ return value;
10887
+ }
10888
+ if (typeof value === "number" || typeof value === "boolean") {
10889
+ return String(value);
10890
+ }
10891
+ return void 0;
10892
+ }
10893
+ function xmlChild(node, key) {
10894
+ if (!isXmlObject(node)) {
10895
+ return void 0;
10896
+ }
10897
+ const value = node[key];
10898
+ if (Array.isArray(value)) {
10899
+ const first = value[0];
10900
+ return isXmlObject(first) ? first : void 0;
10901
+ }
10902
+ return isXmlObject(value) ? value : void 0;
10903
+ }
10904
+ function xmlChildren(node, key) {
10905
+ if (!isXmlObject(node)) {
10906
+ return [];
10907
+ }
10908
+ const value = node[key];
10909
+ if (value === void 0 || value === null) {
10910
+ return [];
10911
+ }
10912
+ if (Array.isArray(value)) {
10913
+ return value.filter(isXmlObject);
10914
+ }
10915
+ return isXmlObject(value) ? [value] : [];
10916
+ }
10917
+ function xmlHasChild(node, key) {
10918
+ return isXmlObject(node) && Object.hasOwn(node, key);
10919
+ }
10920
+ function xmlAttr(node, name) {
10921
+ if (!isXmlObject(node)) {
10922
+ return void 0;
10923
+ }
10924
+ return coerceString(node[ATTR_PREFIX + name]);
10925
+ }
10926
+ function xmlAttrNumber(node, name) {
10927
+ const raw = xmlAttr(node, name);
10928
+ if (raw === void 0) {
10929
+ return void 0;
10930
+ }
10931
+ const parsed = Number(raw);
10932
+ return Number.isFinite(parsed) ? parsed : void 0;
10933
+ }
10934
+ function xmlAttrBool(node, name) {
10935
+ const raw = xmlAttr(node, name);
10936
+ if (raw === void 0) {
10937
+ return void 0;
10938
+ }
10939
+ const normalized = raw.trim().toLowerCase();
10940
+ if (normalized === "1" || normalized === "true") {
10941
+ return true;
10942
+ }
10943
+ if (normalized === "0" || normalized === "false") {
10944
+ return false;
10945
+ }
10946
+ return void 0;
10947
+ }
10948
+ function xmlText(node) {
10949
+ if (typeof node === "string") {
10950
+ return node;
10951
+ }
10952
+ if (!isXmlObject(node)) {
10953
+ return void 0;
10954
+ }
10955
+ return coerceString(node[TEXT_KEY]);
10956
+ }
10957
+ function xmlPath(node, ...keys) {
10958
+ let current = isXmlObject(node) ? node : void 0;
10959
+ for (const key of keys) {
10960
+ if (!current) {
10961
+ return void 0;
10962
+ }
10963
+ current = xmlChild(current, key);
10964
+ }
10965
+ return current;
10966
+ }
10967
+ function isXmlNode(value) {
10968
+ return isXmlObject(value);
10969
+ }
10970
+
10971
+ // src/core/utils/app-properties-titles.ts
10972
+ var SLIDE_TITLES_NAME = "Slide Titles";
10973
+ function coerceText(value) {
10974
+ if (typeof value === "string") {
10975
+ return value;
10976
+ }
10977
+ if (typeof value === "number" || typeof value === "boolean") {
10978
+ return String(value);
10979
+ }
10980
+ if (isXmlNode(value)) {
10981
+ const text2 = value["#text"];
10982
+ return text2 === void 0 || text2 === null ? "" : String(text2);
10983
+ }
10984
+ return "";
10985
+ }
10986
+ function coerceCount(value) {
10987
+ const parsed = Number.parseInt(coerceText(value), 10);
10988
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
10989
+ }
10990
+ function readLpstrList(vector) {
10991
+ if (!vector) {
10992
+ return [];
10993
+ }
10994
+ const raw = vector["vt:lpstr"];
10995
+ if (raw === void 0 || raw === null) {
10996
+ return [];
10997
+ }
10998
+ return (Array.isArray(raw) ? raw : [raw]).map(coerceText);
10999
+ }
11000
+ function isSlideTitlesCategory(name) {
11001
+ const normalized = name.trim().toLowerCase();
11002
+ return normalized === "slide titles" || normalized.includes("slide") && normalized.includes("title");
11003
+ }
11004
+ function readCategories(headingPairs, titlesOfParts) {
11005
+ const variants = xmlChildren(xmlChild(headingPairs, "vt:vector"), "vt:variant");
11006
+ const entries = readLpstrList(xmlChild(titlesOfParts, "vt:vector"));
11007
+ const categories = [];
11008
+ let offset = 0;
11009
+ for (let i = 0; i + 1 < variants.length; i += 2) {
11010
+ const name = coerceText(variants[i]["vt:lpstr"]);
11011
+ const count = coerceCount(variants[i + 1]["vt:i4"]);
11012
+ categories.push({ name, entries: entries.slice(offset, offset + count) });
11013
+ offset += count;
11014
+ }
11015
+ return categories;
11016
+ }
11017
+ function writeHeadingPairs(appProps, categories) {
11018
+ const variants = [];
11019
+ for (const category of categories) {
11020
+ variants.push({ "vt:lpstr": category.name });
11021
+ variants.push({ "vt:i4": String(category.entries.length) });
11022
+ }
11023
+ appProps["HeadingPairs"] = {
11024
+ "vt:vector": {
11025
+ "@_size": String(variants.length),
11026
+ "@_baseType": "variant",
11027
+ "vt:variant": variants
11028
+ }
11029
+ };
11030
+ }
11031
+ function writeTitlesOfParts(appProps, categories) {
11032
+ const allEntries = categories.flatMap((category) => category.entries);
11033
+ const lpstr = allEntries.map((entry) => ({ "#text": entry }));
11034
+ appProps["TitlesOfParts"] = {
11035
+ "vt:vector": {
11036
+ "@_size": String(allEntries.length),
11037
+ "@_baseType": "lpstr",
11038
+ "vt:lpstr": lpstr
11039
+ }
11040
+ };
11041
+ }
11042
+ function applySlideTitlesToAppProps(appProps, titles) {
11043
+ const headingPairs = xmlChild(appProps, "HeadingPairs");
11044
+ if (!headingPairs) {
11045
+ return;
11046
+ }
11047
+ const titlesOfParts = xmlChild(appProps, "TitlesOfParts");
11048
+ const categories = readCategories(headingPairs, titlesOfParts);
11049
+ const slideCategory = categories.find((category) => isSlideTitlesCategory(category.name));
11050
+ if (slideCategory) {
11051
+ slideCategory.entries = titles;
11052
+ } else {
11053
+ categories.push({ name: SLIDE_TITLES_NAME, entries: titles });
11054
+ }
11055
+ writeHeadingPairs(appProps, categories);
11056
+ writeTitlesOfParts(appProps, categories);
11057
+ }
11058
+
11059
+ // src/core/utils/slide-title.ts
11060
+ var TITLE_PLACEHOLDER_TYPES = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
11061
+ function getElementPlaceholderType(element) {
11062
+ const explicit = element.placeholderType;
11063
+ if (typeof explicit === "string" && explicit.trim().length > 0) {
11064
+ return explicit.trim().toLowerCase();
11065
+ }
11066
+ const ph = xmlPath(element.rawXml, "p:nvSpPr", "p:nvPr", "p:ph");
11067
+ const type = xmlAttr(ph, "type");
11068
+ return type ? type.trim().toLowerCase() : void 0;
11069
+ }
11070
+ function getElementPlainText(element) {
11071
+ const maybe = element;
11072
+ if (typeof maybe.text === "string" && maybe.text.trim().length > 0) {
11073
+ return maybe.text.trim();
11074
+ }
11075
+ if (Array.isArray(maybe.textSegments)) {
11076
+ const joined = maybe.textSegments.map((segment) => typeof segment?.text === "string" ? segment.text : "").join("");
11077
+ return joined.trim();
11078
+ }
11079
+ return "";
11080
+ }
11081
+ function deriveSlideTitle(slide) {
11082
+ const elements2 = slide.elements ?? [];
11083
+ for (const element of elements2) {
11084
+ const phType = getElementPlaceholderType(element);
11085
+ if (phType && TITLE_PLACEHOLDER_TYPES.has(phType)) {
11086
+ const text2 = getElementPlainText(element);
11087
+ if (text2) {
11088
+ return text2;
11089
+ }
11090
+ }
11091
+ }
11092
+ return "";
11093
+ }
11094
+ function deriveSlideTitles(slides) {
11095
+ return slides.map((slide) => deriveSlideTitle(slide));
11096
+ }
11097
+
10643
11098
  // src/core/services/PptxDocumentPropertiesUpdater.ts
10644
11099
  var PptxDocumentPropertiesUpdater = class {
10645
11100
  context;
@@ -10703,6 +11158,7 @@ var PptxDocumentPropertiesUpdater = class {
10703
11158
  appProps["Slides"] = String(slides.length);
10704
11159
  appProps["HiddenSlides"] = String(hiddenSlidesCount);
10705
11160
  appProps["Notes"] = String(notesCount);
11161
+ this.updateSlideTitleProperties(appProps, slides);
10706
11162
  appData["Properties"] = appProps;
10707
11163
  this.context.zip.file("docProps/app.xml", this.context.builder.build(appData));
10708
11164
  } catch (error) {
@@ -10745,6 +11201,15 @@ var PptxDocumentPropertiesUpdater = class {
10745
11201
  }
10746
11202
  }
10747
11203
  }
11204
+ /**
11205
+ * Recompute `TitlesOfParts` / `HeadingPairs` from the current slide set so
11206
+ * the per-slide title list in `app.xml` stays consistent after slides are
11207
+ * added, removed, or retitled. Delegates the vector rebuild to a pure
11208
+ * helper; here we only derive the ordered titles.
11209
+ */
11210
+ updateSlideTitleProperties(appProps, slides) {
11211
+ applySlideTitlesToAppProps(appProps, deriveSlideTitles(slides));
11212
+ }
10748
11213
  applyAppPropertiesOverrides(appProps, overrides10) {
10749
11214
  if (!overrides10) {
10750
11215
  return;
@@ -12573,6 +13038,16 @@ function extractChildKeyframes(childTnList) {
12573
13038
  }
12574
13039
  return void 0;
12575
13040
  }
13041
+ function parseTimingPercentFraction(raw) {
13042
+ if (raw === void 0 || raw === null) {
13043
+ return void 0;
13044
+ }
13045
+ const parsed = Number.parseInt(String(raw), 10);
13046
+ if (!Number.isFinite(parsed) || parsed <= 0) {
13047
+ return void 0;
13048
+ }
13049
+ return Math.min(1, parsed / 1e5);
13050
+ }
12576
13051
  function extractRepeatInfo(cTn) {
12577
13052
  let repeatCount;
12578
13053
  let autoReverse;
@@ -12716,11 +13191,11 @@ function ensureArray4(value) {
12716
13191
  return [];
12717
13192
  }
12718
13193
  if (!Array.isArray(value)) {
12719
- return isXmlObject(value) ? [value] : [];
13194
+ return isXmlObject2(value) ? [value] : [];
12720
13195
  }
12721
- return value.filter((entry) => isXmlObject(entry));
13196
+ return value.filter((entry) => isXmlObject2(entry));
12722
13197
  }
12723
- function isXmlObject(value) {
13198
+ function isXmlObject2(value) {
12724
13199
  return typeof value === "object" && value !== null && !Array.isArray(value);
12725
13200
  }
12726
13201
  var VALID_CONDITION_EVENTS = /* @__PURE__ */ new Set([
@@ -13085,8 +13560,11 @@ var PptxNativeAnimationService = class {
13085
13560
  const nodeType = String(cTn["@_nodeType"] || "");
13086
13561
  const presetClass = cTn["@_presetClass"];
13087
13562
  const presetId = cTn["@_presetID"] ? Number.parseInt(String(cTn["@_presetID"]), 10) : void 0;
13563
+ const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
13088
13564
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
13089
13565
  const delayMs = cTn["@_delay"] ? Number.parseInt(String(cTn["@_delay"]), 10) : void 0;
13566
+ const accel = parseTimingPercentFraction(cTn["@_accel"]);
13567
+ const decel = parseTimingPercentFraction(cTn["@_decel"]);
13090
13568
  let trigger = currentTrigger;
13091
13569
  if (nodeType === "afterPrevious" || nodeType === "afterPrev") {
13092
13570
  trigger = "afterPrevious";
@@ -13136,8 +13614,11 @@ var PptxNativeAnimationService = class {
13136
13614
  trigger,
13137
13615
  presetClass: validPresetClass,
13138
13616
  presetId,
13617
+ presetSubtype,
13139
13618
  durationMs,
13140
13619
  delayMs,
13620
+ accel,
13621
+ decel,
13141
13622
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
13142
13623
  motionPath: childMotion.motionPath,
13143
13624
  motionOrigin: childMotion.motionOrigin,
@@ -13446,6 +13927,74 @@ function buildP14ExtLst(transitionType, direction, orient, pattern, rawExtLst, x
13446
13927
  return { "p:ext": transitionExt };
13447
13928
  }
13448
13929
 
13930
+ // src/core/services/p15-transition-parser.ts
13931
+ var P15_TRANSITION_PRESETS = /* @__PURE__ */ new Set([
13932
+ "fallOver",
13933
+ "drape",
13934
+ "curtains",
13935
+ "wind",
13936
+ "prestige",
13937
+ "fracture",
13938
+ "crush",
13939
+ "peelOff",
13940
+ "pageCurlDouble",
13941
+ "pageCurlSingle",
13942
+ "airplane",
13943
+ "origami"
13944
+ ]);
13945
+ var PRSTTRANS_EXT_URI = "{D42A27DB-BD31-4B8C-83A1-F6EECF244321}";
13946
+ function optionalBoolean(value) {
13947
+ const valueToken = value === void 0 || value === null ? "" : String(value).trim().toLowerCase();
13948
+ if (valueToken === "1" || valueToken === "true") {
13949
+ return true;
13950
+ }
13951
+ if (valueToken === "0" || valueToken === "false") {
13952
+ return false;
13953
+ }
13954
+ return void 0;
13955
+ }
13956
+ function parseP15FromExtLst(extLstNode, xmlLookupService, getXmlLocalName) {
13957
+ const extEntries = xmlLookupService.getChildrenArrayByLocalName(extLstNode, "ext");
13958
+ for (const ext of extEntries) {
13959
+ if (!ext) {
13960
+ continue;
13961
+ }
13962
+ for (const [key, value] of Object.entries(ext)) {
13963
+ if (key.startsWith("@_")) {
13964
+ continue;
13965
+ }
13966
+ if (getXmlLocalName(key) !== "prstTrans") {
13967
+ continue;
13968
+ }
13969
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
13970
+ continue;
13971
+ }
13972
+ const detail = value;
13973
+ const prst = String(detail["@_prst"] || "").trim();
13974
+ if (!P15_TRANSITION_PRESETS.has(prst)) {
13975
+ continue;
13976
+ }
13977
+ return {
13978
+ type: prst,
13979
+ invX: optionalBoolean(detail["@_invX"]),
13980
+ invY: optionalBoolean(detail["@_invY"])
13981
+ };
13982
+ }
13983
+ }
13984
+ return void 0;
13985
+ }
13986
+ function buildP15ExtLst(transitionType, invX, invY) {
13987
+ const prstTrans = {
13988
+ "@_xmlns:p15": "http://schemas.microsoft.com/office/powerpoint/2012/main",
13989
+ "@_prst": transitionType
13990
+ };
13991
+ const ext = {
13992
+ "@_uri": PRSTTRANS_EXT_URI,
13993
+ "p15:prstTrans": prstTrans
13994
+ };
13995
+ return { "p:ext": ext };
13996
+ }
13997
+
13449
13998
  // src/core/services/slide-transition-xml.ts
13450
13999
  var STANDARD_TRANSITION_TYPES = /* @__PURE__ */ new Set([
13451
14000
  "fade",
@@ -13511,7 +14060,7 @@ function parseTransitionDetails(node, localName22) {
13511
14060
  if (pattern) {
13512
14061
  result.pattern = pattern;
13513
14062
  }
13514
- const thruBlk = optionalBoolean(detail["@_thruBlk"]);
14063
+ const thruBlk = optionalBoolean2(detail["@_thruBlk"]);
13515
14064
  if (thruBlk !== void 0) {
13516
14065
  result.thruBlk = thruBlk;
13517
14066
  }
@@ -13522,7 +14071,7 @@ function parseTransitionAttributes(node) {
13522
14071
  const speedToken = token(node["@_spd"]);
13523
14072
  const speed = SPEEDS.has(speedToken) ? speedToken : void 0;
13524
14073
  const durationMs = unsignedInteger2(node["@_dur"] ?? node["@_p14:dur"], 1);
13525
- const advanceOnClick = optionalBoolean(node["@_advClick"]);
14074
+ const advanceOnClick = optionalBoolean2(node["@_advClick"]);
13526
14075
  const advanceAfterMs = unsignedInteger2(node["@_advTm"]);
13527
14076
  return { speed, durationMs, advanceOnClick, advanceAfterMs };
13528
14077
  }
@@ -13536,7 +14085,7 @@ function parseTransitionSound(raw, lookup, localName22) {
13536
14085
  return {
13537
14086
  soundRId: sound ? attributeByLocalName(sound, "embed", localName22) : void 0,
13538
14087
  soundName: sound ? attributeByLocalName(sound, "name", localName22) : void 0,
13539
- soundLoop: optionalBoolean(start["@_loop"])
14088
+ soundLoop: optionalBoolean2(start["@_loop"])
13540
14089
  };
13541
14090
  }
13542
14091
  const stopSound = Object.keys(raw).some(
@@ -13645,7 +14194,7 @@ function attributeByLocalName(node, name, localName22) {
13645
14194
  function token(value) {
13646
14195
  return value === void 0 || value === null ? "" : String(value).trim();
13647
14196
  }
13648
- function optionalBoolean(value) {
14197
+ function optionalBoolean2(value) {
13649
14198
  const valueToken = token(value).toLowerCase();
13650
14199
  if (!valueToken) {
13651
14200
  return void 0;
@@ -13691,6 +14240,7 @@ var PptxSlideTransitionService = class {
13691
14240
  const { spokes, thruBlk, rawSoundAction, rawExtLst } = details;
13692
14241
  if (rawExtLst && transitionType === "cut") {
13693
14242
  const p14Result = parseP14FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
14243
+ const p15Result = p14Result ? void 0 : parseP15FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
13694
14244
  if (p14Result) {
13695
14245
  transitionType = p14Result.type;
13696
14246
  if (p14Result.direction) {
@@ -13702,6 +14252,8 @@ var PptxSlideTransitionService = class {
13702
14252
  if (p14Result.pattern) {
13703
14253
  pattern = p14Result.pattern;
13704
14254
  }
14255
+ } else if (p15Result) {
14256
+ transitionType = p15Result.type;
13705
14257
  } else if (this.parseMorphFromExtLst(rawExtLst)) {
13706
14258
  transitionType = "morph";
13707
14259
  }
@@ -13783,6 +14335,7 @@ var PptxSlideTransitionService = class {
13783
14335
  }
13784
14336
  const transitionType = transition.type || "cut";
13785
14337
  const isP14Type = P14_TRANSITION_TYPES.has(transitionType);
14338
+ const isP15Type = P15_TRANSITION_PRESETS.has(transitionType);
13786
14339
  const isMorphType = transitionType === "morph";
13787
14340
  const node = createPreservedTransitionNode(transition.rawTransition, this.getXmlLocalName);
13788
14341
  if (isP14Type) {
@@ -13795,6 +14348,8 @@ var PptxSlideTransitionService = class {
13795
14348
  this.xmlLookupService,
13796
14349
  this.getXmlLocalName
13797
14350
  );
14351
+ } else if (isP15Type) {
14352
+ node["p:extLst"] = transition.rawExtLst ?? buildP15ExtLst(transitionType);
13798
14353
  } else if (isMorphType) {
13799
14354
  node["p:extLst"] = this.buildMorphExtLst(transition.rawExtLst);
13800
14355
  } else {
@@ -13805,7 +14360,7 @@ var PptxSlideTransitionService = class {
13805
14360
  if (soundAction) {
13806
14361
  node["p:sndAc"] = soundAction;
13807
14362
  }
13808
- if (transition.rawExtLst && !isP14Type && !isMorphType) {
14363
+ if (transition.rawExtLst && !isP14Type && !isP15Type && !isMorphType) {
13809
14364
  node["p:extLst"] = transition.rawExtLst;
13810
14365
  }
13811
14366
  return node;
@@ -14304,7 +14859,7 @@ function updateEffectNodeAttributes(cTn, anim, currentPresetClass) {
14304
14859
  if (stCondList && anim.delayMs !== void 0) {
14305
14860
  const conditions = ensureArray4(stCondList["p:cond"]);
14306
14861
  for (const cond of conditions) {
14307
- if (isXmlObject(cond)) {
14862
+ if (isXmlObject2(cond)) {
14308
14863
  cond["@_delay"] = String(anim.delayMs);
14309
14864
  }
14310
14865
  }
@@ -24395,7 +24950,7 @@ function getCalloutViewBoxBounds(width, height, geometry, padding = 2) {
24395
24950
  }
24396
24951
 
24397
24952
  // src/core/core/runtime/omml-sibling-order.ts
24398
- function isXmlObject2(value) {
24953
+ function isXmlObject3(value) {
24399
24954
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
24400
24955
  }
24401
24956
  function ensureItems(value) {
@@ -24498,7 +25053,7 @@ function collectParsedOmathNodes(root) {
24498
25053
  }
24499
25054
  if (localName9(key) === "oMath") {
24500
25055
  for (const item of ensureItems(value)) {
24501
- if (isXmlObject2(item)) {
25056
+ if (isXmlObject3(item)) {
24502
25057
  result.push(item);
24503
25058
  }
24504
25059
  }
@@ -24561,7 +25116,7 @@ function reorderContainer(node, rawInner) {
24561
25116
  occurrence.set(child20.tag, index + 1);
24562
25117
  const value = ensureItems(node[child20.tag])[index];
24563
25118
  resolved.push({ tag: child20.tag, value });
24564
- if (isXmlObject2(value) && child20.inner) {
25119
+ if (isXmlObject3(value) && child20.inner) {
24565
25120
  reorderContainer(value, child20.inner);
24566
25121
  }
24567
25122
  }
@@ -24605,7 +25160,7 @@ function localName10(name) {
24605
25160
  const colon = name.indexOf(":");
24606
25161
  return colon >= 0 ? name.slice(colon + 1) : name;
24607
25162
  }
24608
- function isXmlObject3(value) {
25163
+ function isXmlObject4(value) {
24609
25164
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
24610
25165
  }
24611
25166
  function collectParsedParagraphs(root) {
@@ -24630,7 +25185,7 @@ function collectParsedParagraphs(root) {
24630
25185
  continue;
24631
25186
  }
24632
25187
  paragraphs.push(
24633
- ...(Array.isArray(childValue) ? childValue : [childValue]).filter(isXmlObject3)
25188
+ ...(Array.isArray(childValue) ? childValue : [childValue]).filter(isXmlObject4)
24634
25189
  );
24635
25190
  }
24636
25191
  } else {
@@ -24677,7 +25232,7 @@ function directChildrenByLocalName(paragraphs, name) {
24677
25232
  return [];
24678
25233
  }
24679
25234
  const values = Array.isArray(value) ? value : [value];
24680
- return values.filter(isXmlObject3);
25235
+ return values.filter(isXmlObject4);
24681
25236
  })
24682
25237
  );
24683
25238
  }
@@ -26092,99 +26647,6 @@ function detectFontFormat(data) {
26092
26647
  return "truetype";
26093
26648
  }
26094
26649
 
26095
- // src/core/utils/xml-access.ts
26096
- var ATTR_PREFIX = "@_";
26097
- var TEXT_KEY = "#text";
26098
- function isXmlObject4(value) {
26099
- return typeof value === "object" && value !== null && !Array.isArray(value);
26100
- }
26101
- function coerceString(value) {
26102
- if (typeof value === "string") {
26103
- return value;
26104
- }
26105
- if (typeof value === "number" || typeof value === "boolean") {
26106
- return String(value);
26107
- }
26108
- return void 0;
26109
- }
26110
- function xmlChild(node, key) {
26111
- if (!isXmlObject4(node)) {
26112
- return void 0;
26113
- }
26114
- const value = node[key];
26115
- if (Array.isArray(value)) {
26116
- const first = value[0];
26117
- return isXmlObject4(first) ? first : void 0;
26118
- }
26119
- return isXmlObject4(value) ? value : void 0;
26120
- }
26121
- function xmlChildren(node, key) {
26122
- if (!isXmlObject4(node)) {
26123
- return [];
26124
- }
26125
- const value = node[key];
26126
- if (value === void 0 || value === null) {
26127
- return [];
26128
- }
26129
- if (Array.isArray(value)) {
26130
- return value.filter(isXmlObject4);
26131
- }
26132
- return isXmlObject4(value) ? [value] : [];
26133
- }
26134
- function xmlHasChild(node, key) {
26135
- return isXmlObject4(node) && Object.hasOwn(node, key);
26136
- }
26137
- function xmlAttr(node, name) {
26138
- if (!isXmlObject4(node)) {
26139
- return void 0;
26140
- }
26141
- return coerceString(node[ATTR_PREFIX + name]);
26142
- }
26143
- function xmlAttrNumber(node, name) {
26144
- const raw = xmlAttr(node, name);
26145
- if (raw === void 0) {
26146
- return void 0;
26147
- }
26148
- const parsed = Number(raw);
26149
- return Number.isFinite(parsed) ? parsed : void 0;
26150
- }
26151
- function xmlAttrBool(node, name) {
26152
- const raw = xmlAttr(node, name);
26153
- if (raw === void 0) {
26154
- return void 0;
26155
- }
26156
- const normalized = raw.trim().toLowerCase();
26157
- if (normalized === "1" || normalized === "true") {
26158
- return true;
26159
- }
26160
- if (normalized === "0" || normalized === "false") {
26161
- return false;
26162
- }
26163
- return void 0;
26164
- }
26165
- function xmlText(node) {
26166
- if (typeof node === "string") {
26167
- return node;
26168
- }
26169
- if (!isXmlObject4(node)) {
26170
- return void 0;
26171
- }
26172
- return coerceString(node[TEXT_KEY]);
26173
- }
26174
- function xmlPath(node, ...keys) {
26175
- let current = isXmlObject4(node) ? node : void 0;
26176
- for (const key of keys) {
26177
- if (!current) {
26178
- return void 0;
26179
- }
26180
- current = xmlChild(current, key);
26181
- }
26182
- return current;
26183
- }
26184
- function isXmlNode(value) {
26185
- return isXmlObject4(value);
26186
- }
26187
-
26188
26650
  // src/core/utils/presentation-section-parser.ts
26189
26651
  function findSectionList2(presentation, lookup) {
26190
26652
  const direct = lookup.getChildByLocalName(presentation, "sectionLst");
@@ -29520,6 +29982,7 @@ function getSvgStrokeDasharray(dashType, strokeWidth, customDashSegments) {
29520
29982
  // src/core/utils/element-xml-builders.ts
29521
29983
  function createTemplateShapeRawXml(element) {
29522
29984
  const isText = element.type === "text";
29985
+ const isTextBox = element.locks?.txBox ?? isText;
29523
29986
  const name = isText ? "TextBox" : "Rectangle";
29524
29987
  const geometry = element.shapeType === "cylinder" ? "can" : element.shapeType || "rect";
29525
29988
  const adjustmentEntries = Object.entries(element.shapeAdjustments || {}).filter(
@@ -29538,7 +30001,7 @@ function createTemplateShapeRawXml(element) {
29538
30001
  "@_name": `${name} ${Math.floor(Math.random() * 100)}`
29539
30002
  },
29540
30003
  "p:cNvSpPr": {
29541
- "@_txBox": isText ? "1" : "0"
30004
+ "@_txBox": isTextBox ? "1" : "0"
29542
30005
  },
29543
30006
  "p:nvPr": {}
29544
30007
  },
@@ -29815,36 +30278,200 @@ async function fetchUrlToBytes(url, options = {}) {
29815
30278
  }
29816
30279
  }
29817
30280
 
30281
+ // src/core/utils/inkml-trace-decode.ts
30282
+ function resolveChannelOrder(root) {
30283
+ const traceFormat = findFirstByLocalName(root, "traceFormat");
30284
+ if (!traceFormat) {
30285
+ return ["X", "Y"];
30286
+ }
30287
+ const channels = ensureArray5(nsGet(traceFormat, "channel"));
30288
+ const names = channels.map(
30289
+ (channel) => String(nsAttr(channel, "name") ?? "").trim().toUpperCase()
30290
+ ).filter((name) => name.length > 0);
30291
+ return names.length > 0 ? names : ["X", "Y"];
30292
+ }
30293
+ function decodeTracePoints(text2, channelOrder) {
30294
+ const points3 = [];
30295
+ const modes = channelOrder.map(() => "explicit");
30296
+ const lastValue = channelOrder.map(() => 0);
30297
+ const lastVelocity = channelOrder.map(() => 0);
30298
+ for (const rawPoint of text2.split(",")) {
30299
+ const tokens = rawPoint.trim().split(/\s+/u).filter((token2) => token2.length > 0);
30300
+ if (tokens.length === 0) {
30301
+ continue;
30302
+ }
30303
+ const decoded = [];
30304
+ for (let i = 0; i < tokens.length && i < channelOrder.length; i++) {
30305
+ const parsed = parseValueToken(tokens[i], modes[i]);
30306
+ if (parsed === void 0) {
30307
+ decoded.push(lastValue[i]);
30308
+ continue;
30309
+ }
30310
+ modes[i] = parsed.mode;
30311
+ const value = applyDiffMode(parsed, i, lastValue, lastVelocity);
30312
+ decoded.push(value);
30313
+ }
30314
+ if (decoded.length >= 2) {
30315
+ points3.push(decoded);
30316
+ }
30317
+ }
30318
+ return points3;
30319
+ }
30320
+ function parseValueToken(token2, currentMode) {
30321
+ let mode = currentMode;
30322
+ let body = token2;
30323
+ const prefix = token2[0];
30324
+ if (prefix === "!") {
30325
+ mode = "explicit";
30326
+ body = token2.slice(1);
30327
+ } else if (prefix === "'") {
30328
+ mode = "single";
30329
+ body = token2.slice(1);
30330
+ } else if (prefix === '"') {
30331
+ mode = "double";
30332
+ body = token2.slice(1);
30333
+ }
30334
+ if (body.length === 0) {
30335
+ return void 0;
30336
+ }
30337
+ const value = Number(body);
30338
+ return Number.isFinite(value) ? { value, mode } : void 0;
30339
+ }
30340
+ function applyDiffMode(parsed, index, lastValue, lastVelocity) {
30341
+ if (parsed.mode === "single") {
30342
+ lastVelocity[index] = parsed.value;
30343
+ lastValue[index] += parsed.value;
30344
+ } else if (parsed.mode === "double") {
30345
+ lastVelocity[index] += parsed.value;
30346
+ lastValue[index] += lastVelocity[index];
30347
+ } else {
30348
+ lastValue[index] = parsed.value;
30349
+ lastVelocity[index] = 0;
30350
+ }
30351
+ return lastValue[index];
30352
+ }
30353
+ function pointsToSvgPath(points3, channelOrder) {
30354
+ const xi = channelOrder.indexOf("X");
30355
+ const yi = channelOrder.indexOf("Y");
30356
+ const xIndex = xi >= 0 ? xi : 0;
30357
+ const yIndex = yi >= 0 ? yi : 1;
30358
+ const segments = [];
30359
+ for (const point of points3) {
30360
+ const x = point[xIndex];
30361
+ const y = point[yIndex];
30362
+ if (!Number.isFinite(x) || !Number.isFinite(y)) {
30363
+ continue;
30364
+ }
30365
+ segments.push(`${segments.length === 0 ? "M" : "L"} ${x} ${y}`);
30366
+ }
30367
+ return segments.join(" ");
30368
+ }
30369
+ function pointsToPressures(points3, channelOrder) {
30370
+ const fIndex = channelOrder.indexOf("F");
30371
+ if (fIndex < 0) {
30372
+ return [];
30373
+ }
30374
+ const pressures = [];
30375
+ for (const point of points3) {
30376
+ const raw = point[fIndex];
30377
+ if (Number.isFinite(raw)) {
30378
+ const normalised = raw > 1 ? raw / 32767 : raw;
30379
+ pressures.push(Math.max(0, Math.min(1, normalised)));
30380
+ }
30381
+ }
30382
+ return pressures;
30383
+ }
30384
+ function nsGet(obj, localName22) {
30385
+ if (localName22 in obj) {
30386
+ return obj[localName22];
30387
+ }
30388
+ for (const key of Object.keys(obj)) {
30389
+ if (localNameOf(key) === localName22 && !key.startsWith("@_")) {
30390
+ return obj[key];
30391
+ }
30392
+ }
30393
+ return void 0;
30394
+ }
30395
+ function nsAttr(obj, localName22) {
30396
+ const direct = obj[`@_${localName22}`];
30397
+ if (direct !== void 0) {
30398
+ return direct;
30399
+ }
30400
+ for (const key of Object.keys(obj)) {
30401
+ if (key.startsWith("@_") && localNameOf(key.slice(2)) === localName22) {
30402
+ return obj[key];
30403
+ }
30404
+ }
30405
+ return void 0;
30406
+ }
30407
+ function localNameOf(key) {
30408
+ const colon = key.indexOf(":");
30409
+ return colon >= 0 ? key.slice(colon + 1) : key;
30410
+ }
30411
+ function findFirstByLocalName(node, localName22) {
30412
+ const direct = nsGet(node, localName22);
30413
+ if (direct && typeof direct === "object") {
30414
+ return Array.isArray(direct) ? direct[0] : direct;
30415
+ }
30416
+ for (const key of Object.keys(node)) {
30417
+ if (key.startsWith("@_") || key === "#text") {
30418
+ continue;
30419
+ }
30420
+ for (const child20 of ensureArray5(node[key])) {
30421
+ if (typeof child20 !== "object") {
30422
+ continue;
30423
+ }
30424
+ const found = findFirstByLocalName(child20, localName22);
30425
+ if (found) {
30426
+ return found;
30427
+ }
30428
+ }
30429
+ }
30430
+ return void 0;
30431
+ }
30432
+ function ensureArray5(value) {
30433
+ if (value === void 0 || value === null) {
30434
+ return [];
30435
+ }
30436
+ return Array.isArray(value) ? value : [value];
30437
+ }
30438
+
29818
30439
  // src/core/utils/inkml-content-part.ts
29819
30440
  var INKML_NAMESPACE = "http://www.w3.org/2003/InkML";
29820
30441
  var METADATA_NAMESPACE = "https://pptx-viewer.dev/inkml/metadata";
29821
30442
  function parseInkMlContent(data) {
29822
- const root = data["ink:ink"] ?? data["ink"];
30443
+ const root = nsGet(data, "ink") ?? data["ink"];
29823
30444
  if (!root) {
29824
30445
  return { strokes: [], rawXml: data };
29825
30446
  }
29826
30447
  const brushes = /* @__PURE__ */ new Map();
29827
- for (const brush of ensureArray5(root["ink:brush"] ?? root["brush"])) {
29828
- const properties = ensureArray5(brush["ink:brushProperty"] ?? brush["brushProperty"]);
30448
+ for (const brush of ensureArray5(nsGet(root, "brush"))) {
30449
+ const properties = ensureArray5(nsGet(brush, "brushProperty"));
29829
30450
  const valueByName = new Map(
29830
- properties.map((property) => [String(property["@_name"] ?? ""), property["@_value"]])
30451
+ properties.map((property) => [
30452
+ String(nsAttr(property, "name") ?? ""),
30453
+ nsAttr(property, "value")
30454
+ ])
29831
30455
  );
29832
- brushes.set(String(brush["@_id"] ?? ""), {
30456
+ brushes.set(String(nsAttr(brush, "id") ?? ""), {
29833
30457
  color: String(valueByName.get("color") ?? "#000000"),
29834
30458
  width: finiteNumber(valueByName.get("width"), 1),
29835
30459
  opacity: finiteNumber(valueByName.get("opacity"), 1)
29836
30460
  });
29837
30461
  }
30462
+ const channelOrder = resolveChannelOrder(root);
29838
30463
  const strokes = [];
29839
- for (const trace of ensureArray5(root["ink:trace"] ?? root["trace"])) {
30464
+ for (const trace of ensureArray5(nsGet(root, "trace"))) {
29840
30465
  const text2 = typeof trace === "string" ? trace : String(trace["#text"] ?? "").trim();
29841
- const path = typeof trace === "string" ? text2 : String(trace["@_pva:path"] ?? "").trim() || text2;
30466
+ const authored = typeof trace === "string" ? "" : String(nsAttr(trace, "path") ?? "").trim();
30467
+ const points3 = authored ? [] : decodeTracePoints(text2, channelOrder);
30468
+ const path = authored || pointsToSvgPath(points3, channelOrder);
29842
30469
  if (!path) {
29843
30470
  continue;
29844
30471
  }
29845
- const brushRef = typeof trace === "string" ? "" : String(trace["@_brushRef"] ?? "").replace("#", "");
30472
+ const brushRef = typeof trace === "string" ? "" : String(nsAttr(trace, "brushRef") ?? "").replace("#", "");
29846
30473
  const brush = brushes.get(brushRef) ?? { color: "#000000", width: 1, opacity: 1 };
29847
- const pressures = tracePressures(text2);
30474
+ const pressures = authored ? tracePressures(text2) : pointsToPressures(points3, channelOrder);
29848
30475
  strokes.push({ ...brush, path, ...pressures.length > 0 ? { pressures } : {} });
29849
30476
  }
29850
30477
  return { strokes, rawXml: data };
@@ -29903,12 +30530,6 @@ function finiteNumber(value, fallback) {
29903
30530
  const parsed = Number(value);
29904
30531
  return Number.isFinite(parsed) ? parsed : fallback;
29905
30532
  }
29906
- function ensureArray5(value) {
29907
- if (value === void 0 || value === null) {
29908
- return [];
29909
- }
29910
- return Array.isArray(value) ? value : [value];
29911
- }
29912
30533
 
29913
30534
  // src/core/utils/smartart-helpers.ts
29914
30535
  var DEFAULT_ACCENT_COLORS = [
@@ -32571,6 +33192,122 @@ function applyNodeStylesToElements(elements2, nodes) {
32571
33192
  });
32572
33193
  }
32573
33194
 
33195
+ // src/core/utils/smartart-pres-layout-vars.ts
33196
+ var CONTAINER_LOCAL_NAMES = /* @__PURE__ */ new Set(["presLayoutVars", "varLst"]);
33197
+ function localNameOf2(key) {
33198
+ const idx = key.indexOf(":");
33199
+ return idx >= 0 ? key.slice(idx + 1) : key;
33200
+ }
33201
+ function findVarsContainer(node) {
33202
+ if (!node || typeof node !== "object") {
33203
+ return void 0;
33204
+ }
33205
+ if (Array.isArray(node)) {
33206
+ for (const entry of node) {
33207
+ const found = findVarsContainer(entry);
33208
+ if (found) {
33209
+ return found;
33210
+ }
33211
+ }
33212
+ return void 0;
33213
+ }
33214
+ for (const [key, value] of Object.entries(node)) {
33215
+ if (key.startsWith("@_")) {
33216
+ continue;
33217
+ }
33218
+ if (CONTAINER_LOCAL_NAMES.has(localNameOf2(key))) {
33219
+ const container = Array.isArray(value) ? value[0] : value;
33220
+ if (container && typeof container === "object") {
33221
+ return container;
33222
+ }
33223
+ }
33224
+ const nested = findVarsContainer(value);
33225
+ if (nested) {
33226
+ return nested;
33227
+ }
33228
+ }
33229
+ return void 0;
33230
+ }
33231
+ function varValue(container, name) {
33232
+ for (const [key, value] of Object.entries(container)) {
33233
+ if (key.startsWith("@_") || localNameOf2(key) !== name) {
33234
+ continue;
33235
+ }
33236
+ const node = Array.isArray(value) ? value[0] : value;
33237
+ if (node && typeof node === "object") {
33238
+ const raw = node["@_val"];
33239
+ const str = String(raw ?? "").trim();
33240
+ return str.length > 0 ? str : void 0;
33241
+ }
33242
+ }
33243
+ return void 0;
33244
+ }
33245
+ function boolValue2(container, name) {
33246
+ const raw = varValue(container, name);
33247
+ if (raw === void 0) {
33248
+ return void 0;
33249
+ }
33250
+ const lower = raw.toLowerCase();
33251
+ return lower === "1" || lower === "true" || lower === "on";
33252
+ }
33253
+ function intValue(container, name) {
33254
+ const raw = varValue(container, name);
33255
+ if (raw === void 0) {
33256
+ return void 0;
33257
+ }
33258
+ const parsed = Number.parseInt(raw, 10);
33259
+ return Number.isFinite(parsed) ? parsed : void 0;
33260
+ }
33261
+ var DIRECTIONS = /* @__PURE__ */ new Set(["norm", "rev"]);
33262
+ var HIER_BRANCHES = /* @__PURE__ */ new Set(["std", "init", "l", "r", "hang"]);
33263
+ function parseSmartArtPresLayoutVars(container) {
33264
+ if (!container) {
33265
+ return void 0;
33266
+ }
33267
+ const vars = findVarsContainer(container);
33268
+ if (!vars) {
33269
+ return void 0;
33270
+ }
33271
+ const result = {};
33272
+ const direction = varValue(vars, "dir");
33273
+ if (direction && DIRECTIONS.has(direction)) {
33274
+ result.direction = direction;
33275
+ }
33276
+ const hierBranch = varValue(vars, "hierBranch");
33277
+ if (hierBranch && HIER_BRANCHES.has(hierBranch)) {
33278
+ result.hierarchyBranch = hierBranch;
33279
+ }
33280
+ const orgChart = boolValue2(vars, "orgChart");
33281
+ if (orgChart !== void 0) {
33282
+ result.orgChart = orgChart;
33283
+ }
33284
+ const chMax = intValue(vars, "chMax");
33285
+ if (chMax !== void 0) {
33286
+ result.childMax = chMax;
33287
+ }
33288
+ const chPref = intValue(vars, "chPref");
33289
+ if (chPref !== void 0) {
33290
+ result.childPreferred = chPref;
33291
+ }
33292
+ const bulletEnabled = boolValue2(vars, "bulletEnabled");
33293
+ if (bulletEnabled !== void 0) {
33294
+ result.bulletEnabled = bulletEnabled;
33295
+ }
33296
+ const animLvl = varValue(vars, "animLvl");
33297
+ if (animLvl !== void 0) {
33298
+ result.animationLevel = animLvl;
33299
+ }
33300
+ const animOne = varValue(vars, "animOne");
33301
+ if (animOne !== void 0) {
33302
+ result.animateOne = animOne;
33303
+ }
33304
+ const resizeHandles = varValue(vars, "resizeHandles");
33305
+ if (resizeHandles !== void 0) {
33306
+ result.resizeHandles = resizeHandles;
33307
+ }
33308
+ return Object.keys(result).length > 0 ? result : void 0;
33309
+ }
33310
+
32574
33311
  // src/core/utils/smartart-decompose.ts
32575
33312
  function quickStyleStrokeScale(quickStyle) {
32576
33313
  if (!quickStyle?.effectIntensity) {
@@ -32676,15 +33413,27 @@ function decomposeSmartArt(smartArtData, containerBounds, themeColorMap, layoutD
32676
33413
  smartArtData.colorTransform?.fillColors
32677
33414
  );
32678
33415
  const layoutType = resolveEffectiveLayoutType(smartArtData);
33416
+ const layoutVars = smartArtData.presLayoutVars ?? parseSmartArtPresLayoutVars(smartArtData.layoutDefinition?.rawXml);
33417
+ const orderedNodes = layoutVars?.direction === "rev" ? [...nodes].reverse() : nodes;
32679
33418
  const namedLayout = smartArtData.layout;
32680
33419
  if (namedLayout) {
32681
- const namedResult = dispatchNamedLayout(namedLayout, nodes, containerBounds, effectiveThemeMap);
33420
+ const namedResult = dispatchNamedLayout(
33421
+ namedLayout,
33422
+ orderedNodes,
33423
+ containerBounds,
33424
+ effectiveThemeMap
33425
+ );
32682
33426
  if (namedResult) {
32683
- return applyNodeStylesToElements(namedResult, nodes);
33427
+ return applyNodeStylesToElements(namedResult, orderedNodes);
32684
33428
  }
32685
33429
  }
32686
- const algorithmic = dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap);
32687
- return algorithmic ? applyNodeStylesToElements(algorithmic, nodes) : algorithmic;
33430
+ const algorithmic = dispatchLayoutByType(
33431
+ layoutType,
33432
+ orderedNodes,
33433
+ containerBounds,
33434
+ effectiveThemeMap
33435
+ );
33436
+ return algorithmic ? applyNodeStylesToElements(algorithmic, orderedNodes) : algorithmic;
32688
33437
  }
32689
33438
  function dispatchLayoutByType(layoutType, nodes, containerBounds, effectiveThemeMap) {
32690
33439
  switch (layoutType) {
@@ -42463,6 +43212,128 @@ function applySmartArtConnectionAttributes(xml, connection, fallbackModelId) {
42463
43212
  applyNullableAttribute(xml, "@_presId", connection.presentationId);
42464
43213
  }
42465
43214
 
43215
+ // src/core/utils/smartart-color-lists.ts
43216
+ var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
43217
+ "srgbClr",
43218
+ "schemeClr",
43219
+ "scrgbClr",
43220
+ "sysClr",
43221
+ "prstClr",
43222
+ "hslClr"
43223
+ ]);
43224
+ var COLOR_METHODS2 = /* @__PURE__ */ new Set(["span", "cycle", "repeat"]);
43225
+ var HUE_DIRECTIONS2 = /* @__PURE__ */ new Set(["cw", "ccw"]);
43226
+ var PRIMARY_LABEL_PRIORITY = ["node0", "node1", "node2", "node3", "node4", "node"];
43227
+ function localNameOf3(key) {
43228
+ const idx = key.indexOf(":");
43229
+ return idx >= 0 ? key.slice(idx + 1) : key;
43230
+ }
43231
+ function parseSmartArtColorListHexes(list, deps) {
43232
+ if (!list) {
43233
+ return [];
43234
+ }
43235
+ const out = [];
43236
+ for (const [key, value] of Object.entries(list)) {
43237
+ if (key.startsWith("@_")) {
43238
+ continue;
43239
+ }
43240
+ const local = localNameOf3(key);
43241
+ if (!COLOR_LOCAL_NAMES.has(local)) {
43242
+ continue;
43243
+ }
43244
+ const nodes = Array.isArray(value) ? value : [value];
43245
+ for (const node of nodes) {
43246
+ if (!node || typeof node !== "object") {
43247
+ continue;
43248
+ }
43249
+ const wrapper = { [`a:${local}`]: node };
43250
+ const hex10 = deps.parseColorChoice(wrapper) ?? deps.resolveScheme(node);
43251
+ if (hex10) {
43252
+ out.push(hex10);
43253
+ }
43254
+ }
43255
+ }
43256
+ return out;
43257
+ }
43258
+ function listInterpolation(list) {
43259
+ if (!list) {
43260
+ return void 0;
43261
+ }
43262
+ const method = String(list["@_meth"] ?? "").trim();
43263
+ const hueDir = String(list["@_hueDir"] ?? "").trim();
43264
+ const meta = {};
43265
+ if (COLOR_METHODS2.has(method)) {
43266
+ meta.method = method;
43267
+ }
43268
+ if (HUE_DIRECTIONS2.has(hueDir)) {
43269
+ meta.hueDirection = hueDir;
43270
+ }
43271
+ return meta.method || meta.hueDirection ? meta : void 0;
43272
+ }
43273
+ function parseLabel(lbl, deps) {
43274
+ const fillList = deps.getChild(lbl, "fillClrLst");
43275
+ const lineList = deps.getChild(lbl, "linClrLst");
43276
+ return {
43277
+ name: String(lbl["@_name"] ?? "").trim(),
43278
+ fill: parseSmartArtColorListHexes(fillList, deps),
43279
+ line: parseSmartArtColorListHexes(lineList, deps),
43280
+ textFill: parseSmartArtColorListHexes(deps.getChild(lbl, "txFillClrLst"), deps),
43281
+ textLine: parseSmartArtColorListHexes(deps.getChild(lbl, "txLinClrLst"), deps),
43282
+ effect: parseSmartArtColorListHexes(deps.getChild(lbl, "effectClrLst"), deps),
43283
+ textEffect: parseSmartArtColorListHexes(deps.getChild(lbl, "txEffectClrLst"), deps),
43284
+ fillInterpolation: listInterpolation(fillList),
43285
+ lineInterpolation: listInterpolation(lineList)
43286
+ };
43287
+ }
43288
+ function selectPrimary(parsed) {
43289
+ const byName = new Map(parsed.map((p) => [p.name, p]));
43290
+ for (const name of PRIMARY_LABEL_PRIORITY) {
43291
+ const candidate = byName.get(name);
43292
+ if (candidate && candidate.fill.length > 0) {
43293
+ return candidate;
43294
+ }
43295
+ }
43296
+ for (const name of PRIMARY_LABEL_PRIORITY) {
43297
+ const candidate = byName.get(name);
43298
+ if (candidate && (candidate.line.length > 0 || candidate.fill.length > 0)) {
43299
+ return candidate;
43300
+ }
43301
+ }
43302
+ return parsed.find((p) => p.fill.length > 0) ?? parsed.find((p) => p.line.length > 0);
43303
+ }
43304
+ function buildSmartArtColorLists(styleLbls, deps) {
43305
+ const parsed = styleLbls.map((lbl) => parseLabel(lbl, deps));
43306
+ const primary = selectPrimary(parsed);
43307
+ let fillColors = primary?.fill ?? [];
43308
+ let lineColors = primary?.line ?? [];
43309
+ if (fillColors.length === 0) {
43310
+ fillColors = parsed.map((p) => p.fill[0]).filter((c) => Boolean(c));
43311
+ }
43312
+ if (lineColors.length === 0) {
43313
+ lineColors = parsed.map((p) => p.line[0]).filter((c) => Boolean(c));
43314
+ }
43315
+ const result = { fillColors, lineColors };
43316
+ if (primary?.textFill.length) {
43317
+ result.textFillColors = primary.textFill;
43318
+ }
43319
+ if (primary?.textLine.length) {
43320
+ result.textLineColors = primary.textLine;
43321
+ }
43322
+ if (primary?.effect.length) {
43323
+ result.effectColors = primary.effect;
43324
+ }
43325
+ if (primary?.textEffect.length) {
43326
+ result.textEffectColors = primary.textEffect;
43327
+ }
43328
+ if (primary?.fillInterpolation) {
43329
+ result.fillInterpolation = primary.fillInterpolation;
43330
+ }
43331
+ if (primary?.lineInterpolation) {
43332
+ result.lineInterpolation = primary.lineInterpolation;
43333
+ }
43334
+ return result;
43335
+ }
43336
+
42466
43337
  // src/core/utils/modern-comment-constants.ts
42467
43338
  var MODERN_COMMENT_NAMESPACE = "http://schemas.microsoft.com/office/powerpoint/2018/8/main";
42468
43339
  var MODERN_COMMENT_RELATIONSHIP = "http://schemas.microsoft.com/office/2018/10/relationships/comments";
@@ -44769,6 +45640,28 @@ function buildGeneratedChartAxis(axId, crossId, pos2, formatting) {
44769
45640
  return axis;
44770
45641
  }
44771
45642
 
45643
+ // src/core/utils/chart-xml-container-map.ts
45644
+ var CONTAINER_MAP = {
45645
+ pie: { tag: "c:pieChart", family: "pie" },
45646
+ pie3D: { tag: "c:pie3DChart", family: "pie" },
45647
+ ofPie: { tag: "c:ofPieChart", family: "ofPie" },
45648
+ doughnut: { tag: "c:doughnutChart", family: "doughnut" },
45649
+ scatter: { tag: "c:scatterChart", family: "scatter" },
45650
+ bubble: { tag: "c:bubbleChart", family: "bubble" },
45651
+ line: { tag: "c:lineChart", family: "line" },
45652
+ line3D: { tag: "c:line3DChart", family: "line" },
45653
+ area: { tag: "c:areaChart", family: "area" },
45654
+ area3D: { tag: "c:area3DChart", family: "area" },
45655
+ radar: { tag: "c:radarChart", family: "radar" },
45656
+ stock: { tag: "c:stockChart", family: "stock" },
45657
+ surface: { tag: "c:surfaceChart", family: "surface" },
45658
+ bar: { tag: "c:barChart", family: "bar" },
45659
+ bar3D: { tag: "c:bar3DChart", family: "bar" }
45660
+ };
45661
+ function resolveChartContainerType(type) {
45662
+ return CONTAINER_MAP[type] ?? { tag: "c:barChart", family: "bar" };
45663
+ }
45664
+
44772
45665
  // src/core/utils/chart-xml-generator.ts
44773
45666
  var NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
44774
45667
  var NS_A2 = "http://schemas.openxmlformats.org/drawingml/2006/main";
@@ -44799,29 +45692,6 @@ function strLit(values) {
44799
45692
  }
44800
45693
  };
44801
45694
  }
44802
- function resolveType(type) {
44803
- switch (type) {
44804
- case "pie":
44805
- case "pie3D":
44806
- return { tag: "c:pieChart", family: "pie" };
44807
- case "doughnut":
44808
- return { tag: "c:doughnutChart", family: "doughnut" };
44809
- case "scatter":
44810
- return { tag: "c:scatterChart", family: "scatter" };
44811
- case "bubble":
44812
- return { tag: "c:bubbleChart", family: "bubble" };
44813
- case "line":
44814
- case "line3D":
44815
- return { tag: "c:lineChart", family: "line" };
44816
- case "area":
44817
- case "area3D":
44818
- return { tag: "c:areaChart", family: "area" };
44819
- case "radar":
44820
- return { tag: "c:radarChart", family: "radar" };
44821
- default:
44822
- return { tag: "c:barChart", family: "bar" };
44823
- }
44824
- }
44825
45695
  function fillSpPr(color2, asLine) {
44826
45696
  const h = hex6(color2);
44827
45697
  if (!h) {
@@ -44889,7 +45759,10 @@ function buildChartTypeContainer(chartData, family) {
44889
45759
  } else if (family === "scatter") {
44890
45760
  container["c:scatterStyle"] = { "@_val": "lineMarker" };
44891
45761
  container["c:varyColors"] = { "@_val": "0" };
44892
- } else {
45762
+ } else if (family === "ofPie") {
45763
+ container["c:ofPieType"] = { "@_val": "pie" };
45764
+ container["c:varyColors"] = { "@_val": "1" };
45765
+ } else if (family === "stock" || family === "surface") ; else {
44893
45766
  container["c:varyColors"] = { "@_val": family === "bubble" ? "0" : "1" };
44894
45767
  }
44895
45768
  container["c:ser"] = chartData.series.map(
@@ -44901,12 +45774,13 @@ function buildChartTypeContainer(chartData, family) {
44901
45774
  if (family === "line" && chartData.upDownBars !== void 0) {
44902
45775
  applyChartUpDownBars(container, chartData.upDownBars, (key) => key.replace(/^.*:/u, ""));
44903
45776
  }
44904
- if (family === "bar") {
45777
+ if (family === "bar" || family === "ofPie") {
44905
45778
  container["c:gapWidth"] = { "@_val": "150" };
44906
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
44907
- } else if (family === "line" || family === "area" || family === "radar") {
44908
- container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
44909
- } else if (family === "scatter" || family === "bubble") {
45779
+ }
45780
+ if (family === "stock") {
45781
+ container["c:hiLowLines"] = {};
45782
+ }
45783
+ if (family === "bar" || family === "line" || family === "area" || family === "radar" || family === "scatter" || family === "bubble" || family === "stock" || family === "surface") {
44910
45784
  container["c:axId"] = [{ "@_val": String(CAT_AX_ID) }, { "@_val": String(VAL_AX_ID) }];
44911
45785
  } else if (family === "doughnut") {
44912
45786
  container["c:holeSize"] = { "@_val": "50" };
@@ -44919,7 +45793,8 @@ function buildPlotArea(chartData, tag, family) {
44919
45793
  if (chartData.style) {
44920
45794
  applyChartDataLabelsToXml(plotArea, chartData.style, (key) => key.replace(/^.*:/u, ""));
44921
45795
  }
44922
- if (family !== "pie" && family !== "doughnut" && SCATTER_LIKE.has(chartData.chartType)) {
45796
+ const hasAxes = family !== "pie" && family !== "doughnut" && family !== "ofPie";
45797
+ if (hasAxes && SCATTER_LIKE.has(chartData.chartType)) {
44923
45798
  plotArea["c:valAx"] = [
44924
45799
  buildGeneratedChartAxis(
44925
45800
  CAT_AX_ID,
@@ -44934,7 +45809,7 @@ function buildPlotArea(chartData, tag, family) {
44934
45809
  axisFormatting(chartData, "valAx", VAL_AX_ID, 1)
44935
45810
  )
44936
45811
  ];
44937
- } else if (family !== "pie" && family !== "doughnut") {
45812
+ } else if (hasAxes) {
44938
45813
  const dateAxis = chartData.dateCategories ? axisFormatting(chartData, "dateAx", CAT_AX_ID) : void 0;
44939
45814
  plotArea[dateAxis ? "c:dateAx" : "c:catAx"] = buildGeneratedChartAxis(
44940
45815
  CAT_AX_ID,
@@ -44953,7 +45828,7 @@ function buildPlotArea(chartData, tag, family) {
44953
45828
  return plotArea;
44954
45829
  }
44955
45830
  function buildChartSpaceXml(chartData) {
44956
- const { tag, family } = resolveType(chartData.chartType);
45831
+ const { tag, family } = resolveChartContainerType(chartData.chartType);
44957
45832
  const chart = {};
44958
45833
  if (chartData.title) {
44959
45834
  chart["c:title"] = {
@@ -46885,6 +47760,7 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
46885
47760
  let playbackSpeed;
46886
47761
  let trimStartMs;
46887
47762
  let trimEndMs;
47763
+ let embedRId;
46888
47764
  const bookmarks = [];
46889
47765
  const extLst = mediaNode["p:extLst"] ?? cMediaNode["p:extLst"];
46890
47766
  if (extLst) {
@@ -46892,6 +47768,13 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
46892
47768
  for (const ext of exts) {
46893
47769
  const p14Media = ext["p14:media"];
46894
47770
  if (p14Media) {
47771
+ if (embedRId === void 0) {
47772
+ const embedRaw = p14Media["@_r:embed"] ?? p14Media["@_embed"];
47773
+ const embedStr = embedRaw === void 0 ? "" : String(embedRaw).trim();
47774
+ if (embedStr.length > 0) {
47775
+ embedRId = embedStr;
47776
+ }
47777
+ }
46895
47778
  const p14Trim = p14Media["p14:trim"];
46896
47779
  if (p14Trim) {
46897
47780
  const st = p14Trim["@_st"];
@@ -46961,7 +47844,8 @@ function parseMediaExtensionData(mediaNode, cMediaNode, shapeId, ensureArray16)
46961
47844
  fadeInDuration,
46962
47845
  fadeOutDuration,
46963
47846
  playbackSpeed,
46964
- bookmarks
47847
+ bookmarks,
47848
+ embedRId
46965
47849
  };
46966
47850
  }
46967
47851
 
@@ -47191,6 +48075,12 @@ var PptxHandlerRuntime = class {
47191
48075
  loadedEmbeddedFonts = [];
47192
48076
  /** Typed source metadata for lossless embedded-font list round trips. */
47193
48077
  loadedEmbeddedFontList;
48078
+ /**
48079
+ * View properties parsed from `ppt/viewProps.xml` during load, preserved so
48080
+ * an unmodified load -> save round-trips the typed model and callers that do
48081
+ * not override `saveOptions.viewProperties` still persist the loaded state.
48082
+ */
48083
+ loadedViewProperties;
47194
48084
  /** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
47195
48085
  commentAuthorMap = /* @__PURE__ */ new Map();
47196
48086
  /** Full comment author details keyed by author ID, preserving initials/lastIdx/clrIdx for round-trip. */
@@ -47330,19 +48220,266 @@ var PptxHandlerRuntime = class {
47330
48220
  }
47331
48221
  };
47332
48222
 
48223
+ // src/core/core/runtime/table-style-border-parse.ts
48224
+ var EMU_PER_PIXEL = 9525;
48225
+ var BORDER_SIDES = [
48226
+ "left",
48227
+ "right",
48228
+ "top",
48229
+ "bottom",
48230
+ "insideH",
48231
+ "insideV",
48232
+ "tl2br",
48233
+ "bl2tr"
48234
+ ];
48235
+ function parseSolidFillStyle(solidFill2) {
48236
+ if (!solidFill2) {
48237
+ return void 0;
48238
+ }
48239
+ const schemeClr = solidFill2["a:schemeClr"];
48240
+ if (!schemeClr) {
48241
+ return void 0;
48242
+ }
48243
+ const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
48244
+ if (!schemeColor) {
48245
+ return void 0;
48246
+ }
48247
+ const tintRaw = schemeClr["a:tint"];
48248
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
48249
+ const shadeRaw = schemeClr["a:shade"];
48250
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
48251
+ return { schemeColor, tint, shade };
48252
+ }
48253
+ function parseBorderSide(side) {
48254
+ if (!side) {
48255
+ return void 0;
48256
+ }
48257
+ const ln = side["a:ln"];
48258
+ if (!ln) {
48259
+ return void 0;
48260
+ }
48261
+ const border = {};
48262
+ let has = false;
48263
+ if (ln["a:noFill"] !== void 0) {
48264
+ border.noFill = true;
48265
+ has = true;
48266
+ }
48267
+ const widthEmu = parseInt(String(ln["@_w"] || "0"), 10);
48268
+ if (widthEmu > 0) {
48269
+ border.width = Math.max(1, Math.round(widthEmu / EMU_PER_PIXEL));
48270
+ has = true;
48271
+ }
48272
+ const prstDash = ln["a:prstDash"];
48273
+ const dashVal = prstDash ? String(prstDash["@_val"] || "").trim() : "";
48274
+ if (dashVal) {
48275
+ border.dash = dashVal;
48276
+ has = true;
48277
+ }
48278
+ const solidFill2 = ln["a:solidFill"];
48279
+ const fill = parseSolidFillStyle(solidFill2);
48280
+ if (fill) {
48281
+ border.fill = fill;
48282
+ has = true;
48283
+ } else {
48284
+ const srgb = solidFill2?.["a:srgbClr"];
48285
+ const hex10 = srgb ? String(srgb["@_val"] || "").trim() : "";
48286
+ if (hex10) {
48287
+ border.color = hex10.startsWith("#") ? hex10 : `#${hex10}`;
48288
+ has = true;
48289
+ }
48290
+ }
48291
+ return has ? border : void 0;
48292
+ }
48293
+ function parseTableStyleBorders(tcStyle) {
48294
+ const tcBdr = tcStyle?.["a:tcBdr"];
48295
+ if (!tcBdr) {
48296
+ return void 0;
48297
+ }
48298
+ const result = {};
48299
+ let has = false;
48300
+ for (const name of BORDER_SIDES) {
48301
+ const border = parseBorderSide(tcBdr[`a:${name}`]);
48302
+ if (border) {
48303
+ result[name] = border;
48304
+ has = true;
48305
+ }
48306
+ }
48307
+ return has ? result : void 0;
48308
+ }
48309
+
48310
+ // src/core/core/runtime/table-style-fill-parse.ts
48311
+ function toHex3(raw) {
48312
+ const hex10 = String(raw ?? "").trim();
48313
+ if (!hex10) {
48314
+ return void 0;
48315
+ }
48316
+ return hex10.startsWith("#") ? hex10 : `#${hex10}`;
48317
+ }
48318
+ function parseColorChoiceFill(node) {
48319
+ if (!node) {
48320
+ return void 0;
48321
+ }
48322
+ const scheme = parseSolidFillStyle(node);
48323
+ if (scheme) {
48324
+ return scheme;
48325
+ }
48326
+ const srgb = node["a:srgbClr"];
48327
+ const color2 = toHex3(srgb?.["@_val"]);
48328
+ if (!color2) {
48329
+ return void 0;
48330
+ }
48331
+ const fill = { schemeColor: "", color: color2 };
48332
+ const tintRaw = srgb?.["a:tint"];
48333
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
48334
+ if (tint !== void 0) {
48335
+ fill.tint = tint;
48336
+ }
48337
+ const shadeRaw = srgb?.["a:shade"];
48338
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
48339
+ if (shade !== void 0) {
48340
+ fill.shade = shade;
48341
+ }
48342
+ return fill;
48343
+ }
48344
+ function parseGradientFill(gradFill) {
48345
+ const gsLst = gradFill["a:gsLst"];
48346
+ const rawStops = gsLst?.["a:gs"];
48347
+ const gsNodes = Array.isArray(rawStops) ? rawStops : rawStops ? [rawStops] : [];
48348
+ const stops = [];
48349
+ for (const gs of gsNodes) {
48350
+ const fill = parseColorChoiceFill(gs);
48351
+ if (!fill) {
48352
+ continue;
48353
+ }
48354
+ const position2 = (parseInt(String(gs["@_pos"] || "0"), 10) || 0) / 1e3;
48355
+ stops.push({ position: position2, fill });
48356
+ }
48357
+ if (stops.length === 0) {
48358
+ return void 0;
48359
+ }
48360
+ const lin = gradFill["a:lin"];
48361
+ if (lin) {
48362
+ const angRaw = parseInt(String(lin["@_ang"] || "0"), 10) || 0;
48363
+ const angle = (angRaw / 6e4 % 360 + 360) % 360;
48364
+ return { stops, angle, type: "linear" };
48365
+ }
48366
+ if (gradFill["a:path"] !== void 0) {
48367
+ return { stops, type: "radial" };
48368
+ }
48369
+ return { stops, type: "linear" };
48370
+ }
48371
+ function parsePatternFill(pattFill) {
48372
+ const preset = String(pattFill["@_prst"] || "").trim();
48373
+ if (!preset) {
48374
+ return void 0;
48375
+ }
48376
+ const pattern = { preset };
48377
+ const foreground = parseColorChoiceFill(pattFill["a:fgClr"]);
48378
+ if (foreground) {
48379
+ pattern.foreground = foreground;
48380
+ }
48381
+ const background = parseColorChoiceFill(pattFill["a:bgClr"]);
48382
+ if (background) {
48383
+ pattern.background = background;
48384
+ }
48385
+ return pattern;
48386
+ }
48387
+ function parseTableStyleSectionFill(section) {
48388
+ if (!section) {
48389
+ return void 0;
48390
+ }
48391
+ const tcStyle = section["a:tcStyle"];
48392
+ const fillWrap = tcStyle?.["a:fill"];
48393
+ if (!fillWrap) {
48394
+ return void 0;
48395
+ }
48396
+ if (fillWrap["a:noFill"] !== void 0) {
48397
+ return { schemeColor: "", noFill: true };
48398
+ }
48399
+ const solid = fillWrap["a:solidFill"];
48400
+ if (solid) {
48401
+ return parseColorChoiceFill(solid);
48402
+ }
48403
+ const grad = fillWrap["a:gradFill"];
48404
+ if (grad) {
48405
+ const gradient = parseGradientFill(grad);
48406
+ if (gradient) {
48407
+ return { schemeColor: "", gradient };
48408
+ }
48409
+ }
48410
+ const patt = fillWrap["a:pattFill"];
48411
+ if (patt) {
48412
+ const pattern = parsePatternFill(patt);
48413
+ if (pattern) {
48414
+ return { schemeColor: "", pattern };
48415
+ }
48416
+ }
48417
+ return void 0;
48418
+ }
48419
+ function parseTableStyleSectionText(section) {
48420
+ const tcTxStyle = section?.["a:tcTxStyle"];
48421
+ if (!tcTxStyle) {
48422
+ return void 0;
48423
+ }
48424
+ const result = {};
48425
+ let hasProps = false;
48426
+ if (tcTxStyle["@_b"] === "on") {
48427
+ result.bold = true;
48428
+ hasProps = true;
48429
+ }
48430
+ if (tcTxStyle["@_i"] === "on") {
48431
+ result.italic = true;
48432
+ hasProps = true;
48433
+ }
48434
+ const underline = String(tcTxStyle["@_u"] || "").trim();
48435
+ if (underline && underline !== "none") {
48436
+ result.underline = true;
48437
+ hasProps = true;
48438
+ }
48439
+ const font = tcTxStyle["a:font"];
48440
+ const face = font ? String(font["@_typeface"] || "").trim() : "";
48441
+ if (face) {
48442
+ result.fontFace = face;
48443
+ hasProps = true;
48444
+ }
48445
+ const fontRef = tcTxStyle["a:fontRef"];
48446
+ const idx = fontRef ? String(fontRef["@_idx"] || "").trim() : "";
48447
+ if (idx) {
48448
+ result.fontRefIdx = idx;
48449
+ hasProps = true;
48450
+ }
48451
+ const schemeClr = fontRef?.["a:schemeClr"] ?? tcTxStyle["a:schemeClr"];
48452
+ if (schemeClr) {
48453
+ const val = String(schemeClr["@_val"] || "").trim();
48454
+ if (val) {
48455
+ result.fontSchemeColor = val;
48456
+ hasProps = true;
48457
+ const tintNode = schemeClr["a:tint"];
48458
+ if (tintNode) {
48459
+ result.fontTint = parseInt(String(tintNode["@_val"] || "0"), 10) || void 0;
48460
+ }
48461
+ const shadeNode = schemeClr["a:shade"];
48462
+ if (shadeNode) {
48463
+ result.fontShade = parseInt(String(shadeNode["@_val"] || "0"), 10) || void 0;
48464
+ }
48465
+ }
48466
+ } else {
48467
+ const srgb = fontRef?.["a:srgbClr"] ?? tcTxStyle["a:srgbClr"];
48468
+ const hex10 = toHex3(srgb?.["@_val"]);
48469
+ if (hex10) {
48470
+ result.fontColor = hex10;
48471
+ hasProps = true;
48472
+ }
48473
+ }
48474
+ return hasProps ? result : void 0;
48475
+ }
48476
+
47333
48477
  // src/core/core/runtime/PptxHandlerRuntimeTableStyles.ts
47334
48478
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47335
48479
  /**
47336
- * Export slides to a raster/vector format.
47337
- *
47338
- * This is a stub that signals export intent. Actual rendering requires a
47339
- * platform-specific canvas or PDF library (e.g. Puppeteer, node-canvas,
47340
- * pdfkit). Host applications should override or extend this method with
47341
- * their own rendering pipeline.
47342
- *
47343
- * @param _slides The slides to export.
47344
- * @param _options Export options (format, DPI, slide indices, etc.).
47345
- * @returns A map of slide index → exported binary data.
48480
+ * Export slides to a raster/vector format. This is a stub that signals
48481
+ * export intent; actual rendering requires a platform-specific canvas or
48482
+ * PDF backend that host applications wire in by overriding this method.
47346
48483
  */
47347
48484
  async exportSlides(slides, options) {
47348
48485
  this.compatibilityService.reportWarning({
@@ -47407,77 +48544,26 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47407
48544
  }
47408
48545
  /**
47409
48546
  * Extract fill information from a table style section element
47410
- * (e.g. `a:wholeTbl`, `a:band1H`, `a:firstRow`).
48547
+ * (e.g. `a:wholeTbl`, `a:band1H`, `a:firstRow`). Handles scheme + sRGB
48548
+ * solids, gradients, preset patterns, and `a:noFill` (issue #95).
47411
48549
  */
47412
48550
  extractTableStyleSectionFill(section) {
47413
- if (!section) {
47414
- return void 0;
47415
- }
47416
- const tcStyle = section["a:tcStyle"];
47417
- if (!tcStyle) {
47418
- return void 0;
47419
- }
47420
- const fill = tcStyle["a:fill"];
47421
- if (!fill) {
47422
- return void 0;
47423
- }
47424
- const solidFill2 = fill["a:solidFill"];
47425
- if (!solidFill2) {
47426
- return void 0;
47427
- }
47428
- const schemeClr = solidFill2["a:schemeClr"];
47429
- if (!schemeClr) {
47430
- return void 0;
47431
- }
47432
- const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
47433
- if (!schemeColor) {
47434
- return void 0;
47435
- }
47436
- const tintRaw = schemeClr["a:tint"];
47437
- const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
47438
- const shadeRaw = schemeClr["a:shade"];
47439
- const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
47440
- return { schemeColor, tint, shade };
48551
+ return parseTableStyleSectionFill(section);
48552
+ }
48553
+ /**
48554
+ * Extract border styling from a table style section's
48555
+ * `a:tcStyle/a:tcBdr` (per-side line width, dash, and colour).
48556
+ */
48557
+ extractTableStyleSectionBorders(section) {
48558
+ return parseTableStyleBorders(section?.["a:tcStyle"]);
47441
48559
  }
47442
48560
  /**
47443
- * Extract text properties from a:tcTxStyle in a table style section.
48561
+ * Extract text properties from `a:tcTxStyle` in a table style section.
48562
+ * Captures bold/italic/underline, typeface, font-collection index, and the
48563
+ * font colour (scheme or sRGB) (issue #95).
47444
48564
  */
47445
48565
  extractTableStyleSectionText(section) {
47446
- if (!section) {
47447
- return void 0;
47448
- }
47449
- const tcTxStyle = section["a:tcTxStyle"];
47450
- if (!tcTxStyle) {
47451
- return void 0;
47452
- }
47453
- const result = {};
47454
- let hasProps = false;
47455
- if (tcTxStyle["@_b"] === "on") {
47456
- result.bold = true;
47457
- hasProps = true;
47458
- }
47459
- if (tcTxStyle["@_i"] === "on") {
47460
- result.italic = true;
47461
- hasProps = true;
47462
- }
47463
- const fontClr = tcTxStyle["a:fontRef"];
47464
- const schemeClr = fontClr?.["a:schemeClr"] ?? tcTxStyle["a:schemeClr"];
47465
- if (schemeClr) {
47466
- const val = String(schemeClr["@_val"] || "").trim();
47467
- if (val) {
47468
- result.fontSchemeColor = val;
47469
- hasProps = true;
47470
- const tintNode = schemeClr["a:tint"];
47471
- if (tintNode) {
47472
- result.fontTint = parseInt(String(tintNode["@_val"] || "0"), 10) || void 0;
47473
- }
47474
- const shadeNode = schemeClr["a:shade"];
47475
- if (shadeNode) {
47476
- result.fontShade = parseInt(String(shadeNode["@_val"] || "0"), 10) || void 0;
47477
- }
47478
- }
47479
- }
47480
- return hasProps ? result : void 0;
48566
+ return parseTableStyleSectionText(section);
47481
48567
  }
47482
48568
  ensureArray(val) {
47483
48569
  if (!val) {
@@ -47584,6 +48670,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47584
48670
  textProps[`${name}Text`] = text2;
47585
48671
  }
47586
48672
  }
48673
+ const borderProps = {};
48674
+ for (const name of sectionNames) {
48675
+ const borders = this.extractTableStyleSectionBorders(
48676
+ style[`a:${name}`]
48677
+ );
48678
+ if (borders) {
48679
+ borderProps[`${name}Borders`] = borders;
48680
+ }
48681
+ }
47587
48682
  const entry = {
47588
48683
  styleId,
47589
48684
  styleName,
@@ -47602,7 +48697,8 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47602
48697
  ...swCellFill ? { swCellFill } : {},
47603
48698
  ...neCellFill ? { neCellFill } : {},
47604
48699
  ...nwCellFill ? { nwCellFill } : {},
47605
- ...textProps
48700
+ ...textProps,
48701
+ ...borderProps
47606
48702
  };
47607
48703
  map[styleId] = entry;
47608
48704
  }
@@ -48147,6 +49243,7 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
48147
49243
  );
48148
49244
  const trimStartMs = timing.trimStartMs ?? extData.trimStartMs;
48149
49245
  const trimEndMs = timing.trimEndMs ?? extData.trimEndMs;
49246
+ const mediaEmbedPath = extData.embedRId ? this.resolveRelationshipTarget(slidePath, extData.embedRId) : void 0;
48150
49247
  result.set(shapeId, {
48151
49248
  trimStartMs: trimStartMs !== void 0 && !isNaN(trimStartMs) ? trimStartMs : void 0,
48152
49249
  trimEndMs: trimEndMs !== void 0 && !isNaN(trimEndMs) ? trimEndMs : void 0,
@@ -48160,7 +49257,8 @@ var PptxHandlerRuntime6 = class extends PptxHandlerRuntime5 {
48160
49257
  playAcrossSlides: timing.playAcrossSlides || void 0,
48161
49258
  hideWhenNotPlaying: hideWhenNotPlaying || void 0,
48162
49259
  bookmarks: extData.bookmarks.length > 0 ? extData.bookmarks : void 0,
48163
- playbackSpeed: extData.playbackSpeed
49260
+ playbackSpeed: extData.playbackSpeed,
49261
+ mediaEmbedPath
48164
49262
  });
48165
49263
  }
48166
49264
  }
@@ -48336,6 +49434,10 @@ var PptxHandlerRuntime7 = class extends PptxHandlerRuntime6 {
48336
49434
  if (!timing) {
48337
49435
  continue;
48338
49436
  }
49437
+ if (timing.mediaEmbedPath && (typeof el.mediaPath !== "string" || el.mediaPath.length === 0)) {
49438
+ el.mediaPath = timing.mediaEmbedPath;
49439
+ el.mediaMimeType = this.getImageMimeType(timing.mediaEmbedPath);
49440
+ }
48339
49441
  if (timing.trimStartMs !== void 0) {
48340
49442
  el.trimStartMs = timing.trimStartMs;
48341
49443
  }
@@ -49342,7 +50444,7 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
49342
50444
  }
49343
50445
  }
49344
50446
  async reconcilePresentationSlidesForSave(params) {
49345
- await this.presentationSlidesReconciler.reconcile({
50447
+ return await this.presentationSlidesReconciler.reconcile({
49346
50448
  ...params,
49347
50449
  zip: this.zip,
49348
50450
  parser: this.parser,
@@ -49413,6 +50515,15 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
49413
50515
  if (align === "justify") {
49414
50516
  return "just";
49415
50517
  }
50518
+ if (align === "justLow") {
50519
+ return "justLow";
50520
+ }
50521
+ if (align === "dist") {
50522
+ return "dist";
50523
+ }
50524
+ if (align === "thaiDist") {
50525
+ return "thaiDist";
50526
+ }
49416
50527
  return void 0;
49417
50528
  }
49418
50529
  pixelsToPoints(px2) {
@@ -49626,6 +50737,31 @@ function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
49626
50737
  }
49627
50738
  return fontNode;
49628
50739
  }
50740
+ function buildUnderlineLineXml(line2) {
50741
+ const uln = {};
50742
+ if (typeof line2.widthEmu === "number" && Number.isFinite(line2.widthEmu)) {
50743
+ uln["@_w"] = String(Math.round(line2.widthEmu));
50744
+ }
50745
+ if (line2.compound) {
50746
+ uln["@_cmpd"] = line2.compound;
50747
+ }
50748
+ if (line2.cap) {
50749
+ uln["@_cap"] = line2.cap;
50750
+ }
50751
+ if (line2.algn) {
50752
+ uln["@_algn"] = line2.algn;
50753
+ }
50754
+ if (line2.prstDash) {
50755
+ uln["a:prstDash"] = { "@_val": line2.prstDash };
50756
+ }
50757
+ if (line2.headEndXml) {
50758
+ uln["a:headEnd"] = line2.headEndXml;
50759
+ }
50760
+ if (line2.tailEndXml) {
50761
+ uln["a:tailEnd"] = line2.tailEndXml;
50762
+ }
50763
+ return uln;
50764
+ }
49629
50765
  var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime11 {
49630
50766
  createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
49631
50767
  const runProps = {
@@ -49646,6 +50782,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
49646
50782
  }
49647
50783
  if (style.underline) {
49648
50784
  runProps["@_u"] = style.underlineStyle || "sng";
50785
+ } else if (style.underlineExplicitNone) {
50786
+ runProps["@_u"] = "none";
49649
50787
  }
49650
50788
  if (style.strikethrough !== void 0) {
49651
50789
  runProps["@_strike"] = style.strikethrough ? style.strikeType || "sngStrike" : "noStrike";
@@ -49661,6 +50799,8 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
49661
50799
  }
49662
50800
  if (style.textCaps && style.textCaps !== "none") {
49663
50801
  runProps["@_cap"] = style.textCaps;
50802
+ } else if (style.textCapsExplicitNone) {
50803
+ runProps["@_cap"] = "none";
49664
50804
  }
49665
50805
  if (style.kumimoji !== void 0) {
49666
50806
  runProps["@_kumimoji"] = style.kumimoji ? "1" : "0";
@@ -49769,13 +50909,21 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
49769
50909
  runProps["a:effectDag"] = style.textEffectDagXml;
49770
50910
  }
49771
50911
  if (style.highlightColor) {
49772
- runProps["a:highlight"] = {
49773
- "a:srgbClr": {
49774
- "@_val": style.highlightColor.replace("#", "")
49775
- }
49776
- };
50912
+ const resolvedHighlight = style.highlightColorXml ? this.parseColor(style.highlightColorXml) : void 0;
50913
+ runProps["a:highlight"] = serializeColorChoice(
50914
+ style.highlightColorXml,
50915
+ resolvedHighlight,
50916
+ style.highlightColor
50917
+ );
49777
50918
  }
49778
- if (style.underline && style.underlineColor) {
50919
+ if (style.underlineLineFollowsText) {
50920
+ runProps["a:uLnTx"] = {};
50921
+ } else if (style.underlineLine) {
50922
+ runProps["a:uLn"] = buildUnderlineLineXml(style.underlineLine);
50923
+ }
50924
+ if (style.underlineFillFollowsText) {
50925
+ runProps["a:uFillTx"] = {};
50926
+ } else if (style.underline && style.underlineColor) {
49779
50927
  runProps["a:uFill"] = {
49780
50928
  "a:solidFill": {
49781
50929
  "a:srgbClr": {
@@ -49784,21 +50932,28 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
49784
50932
  }
49785
50933
  };
49786
50934
  }
49787
- if (style.fontFamily) {
50935
+ const latinFace = style.latinFontThemeToken ?? style.fontFamily;
50936
+ if (latinFace) {
49788
50937
  runProps["a:latin"] = applyFontMetadata(
49789
- { "@_typeface": style.fontFamily },
50938
+ { "@_typeface": latinFace },
49790
50939
  style.latinFontPanose,
49791
50940
  style.latinFontPitchFamily,
49792
50941
  style.latinFontCharset
49793
50942
  );
50943
+ }
50944
+ const eastAsiaFace = style.eastAsiaFontThemeToken ?? style.eastAsiaFont;
50945
+ if (eastAsiaFace) {
49794
50946
  runProps["a:ea"] = applyFontMetadata(
49795
- { "@_typeface": style.eastAsiaFont || style.fontFamily },
50947
+ { "@_typeface": eastAsiaFace },
49796
50948
  style.eastAsiaFontPanose,
49797
50949
  style.eastAsiaFontPitchFamily,
49798
50950
  style.eastAsiaFontCharset
49799
50951
  );
50952
+ }
50953
+ const complexScriptFace = style.complexScriptFontThemeToken ?? style.complexScriptFont;
50954
+ if (complexScriptFace) {
49800
50955
  runProps["a:cs"] = applyFontMetadata(
49801
- { "@_typeface": style.complexScriptFont || style.fontFamily },
50956
+ { "@_typeface": complexScriptFace },
49802
50957
  style.complexScriptFontPanose,
49803
50958
  style.complexScriptFontPitchFamily,
49804
50959
  style.complexScriptFontCharset
@@ -49848,12 +51003,17 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
49848
51003
  if (mouseOverTarget.length > 0) {
49849
51004
  const mouseOverRelId = resolveHyperlinkRelationshipId(mouseOverTarget);
49850
51005
  if (mouseOverRelId) {
49851
- runProps["a:hlinkMouseOver"] = {
49852
- "@_r:id": mouseOverRelId
49853
- };
51006
+ const mouseOverNode = { "@_r:id": mouseOverRelId };
51007
+ if (style.hyperlinkMouseOverSoundXml && typeof style.hyperlinkMouseOverSoundXml === "object") {
51008
+ mouseOverNode["a:snd"] = style.hyperlinkMouseOverSoundXml;
51009
+ }
51010
+ runProps["a:hlinkMouseOver"] = mouseOverNode;
49854
51011
  }
49855
51012
  }
49856
51013
  }
51014
+ if (style.runPropertiesExtLstXml && typeof style.runPropertiesExtLstXml === "object") {
51015
+ runProps["a:extLst"] = style.runPropertiesExtLstXml;
51016
+ }
49857
51017
  return runProps;
49858
51018
  }
49859
51019
  applyHyperlinkExtraAttrs(hlinkNode, style) {
@@ -49872,22 +51032,26 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
49872
51032
  if (style.hyperlinkEndSound !== void 0) {
49873
51033
  hlinkNode["@_endSnd"] = style.hyperlinkEndSound ? "1" : "0";
49874
51034
  }
51035
+ if (style.hyperlinkSoundXml && typeof style.hyperlinkSoundXml === "object") {
51036
+ hlinkNode["a:snd"] = style.hyperlinkSoundXml;
51037
+ }
49875
51038
  }
49876
51039
  };
49877
51040
 
49878
51041
  // src/core/core/runtime/PptxHandlerRuntimeSaveParagraphs.ts
49879
51042
  var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
49880
51043
  createParagraphsFromTextContent(text2, textStyle, textSegments, resolveHyperlinkRelationshipId) {
49881
- const paragraphAlign = this.textAlignToDrawingValue(textStyle?.align);
49882
- const spacing = {
49883
- spacingBefore: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingBefore),
49884
- spacingAfter: this.createParagraphSpacingXmlFromPx(textStyle?.paragraphSpacingAfter),
49885
- lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
49886
- lineSpacingExactPt: textStyle?.lineSpacingExactPt
49887
- };
49888
- const createParagraph = (runs, bulletInfo, level, endParaRunProperties) => {
51044
+ const createParagraph = (runs, bulletInfo, level, endParaRunProperties, paragraphProperties2) => {
51045
+ const effectiveStyle = paragraphProperties2 ? { ...textStyle, ...paragraphProperties2 } : textStyle;
51046
+ const paragraphAlign = this.textAlignToDrawingValue(effectiveStyle?.align);
51047
+ const spacing = {
51048
+ spacingBefore: this.createParagraphSpacingXmlFromPx(effectiveStyle?.paragraphSpacingBefore),
51049
+ spacingAfter: this.createParagraphSpacingXmlFromPx(effectiveStyle?.paragraphSpacingAfter),
51050
+ lineSpacing: this.createLineSpacingXmlFromMultiplier(effectiveStyle?.lineSpacing),
51051
+ lineSpacingExactPt: effectiveStyle?.lineSpacingExactPt
51052
+ };
49889
51053
  const paragraphProps = buildParagraphPropertiesXml(
49890
- textStyle,
51054
+ effectiveStyle,
49891
51055
  paragraphAlign,
49892
51056
  bulletInfo,
49893
51057
  spacing,
@@ -49899,12 +51063,22 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
49899
51063
  "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
49900
51064
  "a:t": runText
49901
51065
  });
49902
- const createFieldRun = (runText, style, fieldType, fieldGuid) => ({
49903
- "@_type": fieldType,
49904
- ...fieldGuid ? { "@_id": fieldGuid } : {},
49905
- "a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
49906
- "a:t": runText
49907
- });
51066
+ const createFieldRun = (runText, style, fieldType, fieldGuid, fieldGuidAttr, fieldParagraphPropertiesXml) => {
51067
+ const fld = { "@_type": fieldType };
51068
+ if (fieldGuid) {
51069
+ if (fieldGuidAttr === "uuid") {
51070
+ fld["@_uuid"] = fieldGuid;
51071
+ } else {
51072
+ fld["@_id"] = fieldGuid;
51073
+ }
51074
+ }
51075
+ fld["a:rPr"] = this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId);
51076
+ if (fieldParagraphPropertiesXml && typeof fieldParagraphPropertiesXml === "object") {
51077
+ fld["a:pPr"] = fieldParagraphPropertiesXml;
51078
+ }
51079
+ fld["a:t"] = runText;
51080
+ return fld;
51081
+ };
49908
51082
  const createRubyRun = (segment, style) => {
49909
51083
  const rubyPr = {};
49910
51084
  if (segment.rubyAlignment) {
@@ -49943,17 +51117,27 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
49943
51117
  let currentBulletInfo;
49944
51118
  let currentLevel;
49945
51119
  let currentEndParaRunProperties;
51120
+ let currentParagraphProperties;
51121
+ let capturedParagraphMeta = false;
49946
51122
  const pushParagraph = () => {
49947
51123
  if (currentRuns.length === 0) {
49948
51124
  currentRuns.push(createRun("", textStyle));
49949
51125
  }
49950
51126
  paragraphs.push(
49951
- createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
51127
+ createParagraph(
51128
+ currentRuns,
51129
+ currentBulletInfo,
51130
+ currentLevel,
51131
+ currentEndParaRunProperties,
51132
+ currentParagraphProperties
51133
+ )
49952
51134
  );
49953
51135
  currentRuns = [];
49954
51136
  currentBulletInfo = void 0;
49955
51137
  currentLevel = void 0;
49956
51138
  currentEndParaRunProperties = void 0;
51139
+ currentParagraphProperties = void 0;
51140
+ capturedParagraphMeta = false;
49957
51141
  };
49958
51142
  if (textSegments && textSegments.length > 0) {
49959
51143
  const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
@@ -49963,7 +51147,7 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
49963
51147
  ...segment.style,
49964
51148
  ...uniformSegmentOverrides
49965
51149
  };
49966
- if (currentRuns.length === 0) {
51150
+ if (!capturedParagraphMeta) {
49967
51151
  if (segment.bulletInfo) {
49968
51152
  currentBulletInfo = segment.bulletInfo;
49969
51153
  }
@@ -49973,6 +51157,10 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
49973
51157
  if (segment.endParaRunProperties) {
49974
51158
  currentEndParaRunProperties = segment.endParaRunProperties;
49975
51159
  }
51160
+ if (segment.paragraphProperties) {
51161
+ currentParagraphProperties = segment.paragraphProperties;
51162
+ }
51163
+ capturedParagraphMeta = true;
49976
51164
  }
49977
51165
  if (segment.isLineBreak) {
49978
51166
  const brNode = {};
@@ -50007,7 +51195,9 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
50007
51195
  linePart,
50008
51196
  segmentStyle,
50009
51197
  segment.fieldType,
50010
- segment.fieldGuid
51198
+ segment.fieldGuid,
51199
+ segment.fieldGuidAttr,
51200
+ segment.fieldParagraphPropertiesXml
50011
51201
  );
50012
51202
  fieldRun.__isField = true;
50013
51203
  currentRuns.push(fieldRun);
@@ -50467,6 +51657,16 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
50467
51657
  const chOffY = 0;
50468
51658
  const chExtCx = extCx;
50469
51659
  const chExtCy = extCy;
51660
+ const xfrmAttrs = {};
51661
+ if (typeof group.rotation === "number" && group.rotation !== 0) {
51662
+ xfrmAttrs["@_rot"] = String(Math.round(group.rotation * 6e4));
51663
+ }
51664
+ if (group.flipHorizontal) {
51665
+ xfrmAttrs["@_flipH"] = "1";
51666
+ }
51667
+ if (group.flipVertical) {
51668
+ xfrmAttrs["@_flipV"] = "1";
51669
+ }
50470
51670
  const grpXml = {
50471
51671
  "p:nvGrpSpPr": {
50472
51672
  "p:cNvPr": { "@_id": "0", "@_name": group.id },
@@ -50475,6 +51675,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
50475
51675
  },
50476
51676
  "p:grpSpPr": {
50477
51677
  "a:xfrm": {
51678
+ ...xfrmAttrs,
50478
51679
  "a:off": {
50479
51680
  "@_x": String(offX),
50480
51681
  "@_y": String(offY)
@@ -50761,7 +51962,95 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
50761
51962
  };
50762
51963
 
50763
51964
  // src/core/core/runtime/PptxHandlerRuntimeTextStyleUtils.ts
51965
+ var SCRIPT_CANDIDATES = {
51966
+ cjk: ["Hans", "Hant", "Jpan", "Hang"],
51967
+ kana: ["Jpan", "Hans", "Hant"],
51968
+ hangul: ["Hang"],
51969
+ arabic: ["Arab"],
51970
+ hebrew: ["Hebr"],
51971
+ thai: ["Thai"]
51972
+ };
51973
+ function aggregateFontScriptOverrides(perPathMap) {
51974
+ const aggregate = {};
51975
+ for (const overrides10 of perPathMap.values()) {
51976
+ for (const [script, typeface] of Object.entries(overrides10)) {
51977
+ if (!(script in aggregate)) {
51978
+ aggregate[script] = typeface;
51979
+ }
51980
+ }
51981
+ }
51982
+ return aggregate;
51983
+ }
51984
+ function detectDominantScript(text2) {
51985
+ const counts = {};
51986
+ for (const ch of text2) {
51987
+ const code = ch.codePointAt(0) ?? 0;
51988
+ let cat;
51989
+ if (code >= 4352 && code <= 4607) {
51990
+ cat = "hangul";
51991
+ } else if (code >= 44032 && code <= 55215) {
51992
+ cat = "hangul";
51993
+ } else if (code >= 12352 && code <= 12543) {
51994
+ cat = "kana";
51995
+ } else if (code >= 19968 && code <= 40959 || code >= 13312 && code <= 19903 || code >= 63744 && code <= 64255) {
51996
+ cat = "cjk";
51997
+ } else if (code >= 1536 && code <= 1791) {
51998
+ cat = "arabic";
51999
+ } else if (code >= 1424 && code <= 1535) {
52000
+ cat = "hebrew";
52001
+ } else if (code >= 3584 && code <= 3711) {
52002
+ cat = "thai";
52003
+ }
52004
+ if (cat) {
52005
+ counts[cat] = (counts[cat] ?? 0) + 1;
52006
+ }
52007
+ }
52008
+ let best;
52009
+ let bestCount = 0;
52010
+ for (const [cat, count] of Object.entries(counts)) {
52011
+ if (count > bestCount) {
52012
+ best = cat;
52013
+ bestCount = count;
52014
+ }
52015
+ }
52016
+ return best;
52017
+ }
50764
52018
  var PptxHandlerRuntime17 = class extends PptxHandlerRuntime16 {
52019
+ /**
52020
+ * Resolve the automatic per-script fallback face for a run's text from the
52021
+ * theme's `<a:font script="...">` overrides (#83). Body (minor) fonts win
52022
+ * over heading (major) fonts. Returns `undefined` when the deck declares no
52023
+ * script overrides or the text needs no fallback.
52024
+ */
52025
+ resolveScriptFallbackFont(text2) {
52026
+ if (!text2) {
52027
+ return void 0;
52028
+ }
52029
+ if (this.masterThemeMinorFontScripts.size === 0 && this.masterThemeMajorFontScripts.size === 0) {
52030
+ return void 0;
52031
+ }
52032
+ const category = detectDominantScript(text2);
52033
+ if (!category) {
52034
+ return void 0;
52035
+ }
52036
+ const candidates = SCRIPT_CANDIDATES[category];
52037
+ if (!candidates) {
52038
+ return void 0;
52039
+ }
52040
+ const minor = aggregateFontScriptOverrides(this.masterThemeMinorFontScripts);
52041
+ for (const key of candidates) {
52042
+ if (minor[key]) {
52043
+ return minor[key];
52044
+ }
52045
+ }
52046
+ const major = aggregateFontScriptOverrides(this.masterThemeMajorFontScripts);
52047
+ for (const key of candidates) {
52048
+ if (major[key]) {
52049
+ return major[key];
52050
+ }
52051
+ }
52052
+ return void 0;
52053
+ }
50765
52054
  textStylesEqual(left, right) {
50766
52055
  const keys = [
50767
52056
  "fontFamily",
@@ -50922,6 +52211,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
50922
52211
  const esVal = String(endSnd).trim().toLowerCase();
50923
52212
  style.hyperlinkEndSound = esVal === "1" || esVal === "true";
50924
52213
  }
52214
+ const clickSnd = hyperlinkNode["a:snd"];
52215
+ if (clickSnd && typeof clickSnd === "object") {
52216
+ style.hyperlinkSoundXml = clickSnd;
52217
+ }
50925
52218
  }
50926
52219
  const actionStr = String(hyperlinkNode?.["@_action"] || "").trim();
50927
52220
  if (actionStr) {
@@ -50951,6 +52244,10 @@ var PptxHandlerRuntime18 = class extends PptxHandlerRuntime17 {
50951
52244
  } else {
50952
52245
  style.hyperlinkMouseOver = mouseOverRelId;
50953
52246
  }
52247
+ const mouseOverSnd = hlinkMouseOver["a:snd"];
52248
+ if (mouseOverSnd && typeof mouseOverSnd === "object") {
52249
+ style.hyperlinkMouseOverSoundXml = mouseOverSnd;
52250
+ }
50954
52251
  }
50955
52252
  }
50956
52253
  }
@@ -51177,6 +52474,8 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
51177
52474
  if (rawU.length > 0 && rawU !== "none") {
51178
52475
  style.underlineStyle = rawU;
51179
52476
  }
52477
+ } else if (underlineToken === "none") {
52478
+ style.underlineExplicitNone = true;
51180
52479
  }
51181
52480
  }
51182
52481
  const uFill = runProperties2["a:uFill"];
@@ -51188,6 +52487,46 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
51188
52487
  style.underlineColor = underlineColor;
51189
52488
  }
51190
52489
  }
52490
+ if (uLn) {
52491
+ const line2 = {};
52492
+ const widthEmu = Number.parseInt(String(uLn["@_w"] ?? ""), 10);
52493
+ if (Number.isFinite(widthEmu)) {
52494
+ line2.widthEmu = widthEmu;
52495
+ }
52496
+ const compound = String(uLn["@_cmpd"] ?? "").trim();
52497
+ if (compound) {
52498
+ line2.compound = compound;
52499
+ }
52500
+ const cap = String(uLn["@_cap"] ?? "").trim();
52501
+ if (cap) {
52502
+ line2.cap = cap;
52503
+ }
52504
+ const algn = String(uLn["@_algn"] ?? "").trim();
52505
+ if (algn) {
52506
+ line2.algn = algn;
52507
+ }
52508
+ const prstDash = String(uLn["a:prstDash"]?.["@_val"] ?? "").trim();
52509
+ if (prstDash) {
52510
+ line2.prstDash = prstDash;
52511
+ }
52512
+ const headEnd = uLn["a:headEnd"];
52513
+ if (headEnd && typeof headEnd === "object") {
52514
+ line2.headEndXml = headEnd;
52515
+ }
52516
+ const tailEnd = uLn["a:tailEnd"];
52517
+ if (tailEnd && typeof tailEnd === "object") {
52518
+ line2.tailEndXml = tailEnd;
52519
+ }
52520
+ if (Object.keys(line2).length > 0) {
52521
+ style.underlineLine = line2;
52522
+ }
52523
+ }
52524
+ if (runProperties2["a:uLnTx"] !== void 0) {
52525
+ style.underlineLineFollowsText = true;
52526
+ }
52527
+ if (runProperties2["a:uFillTx"] !== void 0) {
52528
+ style.underlineFillFollowsText = true;
52529
+ }
51191
52530
  if (runProperties2["@_strike"] !== void 0) {
51192
52531
  const strikeToken = String(runProperties2["@_strike"] || "").trim().toLowerCase();
51193
52532
  style.strikethrough = strikeToken.length > 0 && strikeToken !== "nostrike" && strikeToken !== "none" && strikeToken !== "0" && strikeToken !== "false";
@@ -51231,10 +52570,15 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
51231
52570
  }
51232
52571
  }
51233
52572
  if (runProperties2["a:highlight"]) {
51234
- const highlightHex = this.parseColor(xmlChild(runProperties2, "a:highlight"));
52573
+ const highlightNode = xmlChild(runProperties2, "a:highlight");
52574
+ const highlightHex = this.parseColor(highlightNode);
51235
52575
  if (highlightHex) {
51236
52576
  style.highlightColor = highlightHex;
51237
52577
  }
52578
+ const highlightXml = extractColorChoiceXml(highlightNode);
52579
+ if (highlightXml) {
52580
+ style.highlightColorXml = highlightXml;
52581
+ }
51238
52582
  }
51239
52583
  const textFillVariants = this.extractTextFillVariants(runProperties2);
51240
52584
  if (textFillVariants.textFillGradient) {
@@ -51255,16 +52599,28 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
51255
52599
  const latin = xmlChild(runProperties2, "a:latin");
51256
52600
  const eastAsian = xmlChild(runProperties2, "a:ea");
51257
52601
  const complexScript = xmlChild(runProperties2, "a:cs");
51258
- const chosenTypeface = xmlAttr(latin, "typeface") || xmlAttr(eastAsian, "typeface") || xmlAttr(complexScript, "typeface");
52602
+ const latinTypefaceToken = xmlAttr(latin, "typeface");
52603
+ const eaTypefaceToken = xmlAttr(eastAsian, "typeface");
52604
+ const csTypefaceToken = xmlAttr(complexScript, "typeface");
52605
+ const chosenTypeface = latinTypefaceToken || eaTypefaceToken || csTypefaceToken;
51259
52606
  const resolvedTypeface = this.resolveThemeTypeface(chosenTypeface);
51260
52607
  if (resolvedTypeface) {
51261
52608
  style.fontFamily = resolvedTypeface;
51262
52609
  }
51263
- const eaTypeface = this.resolveThemeTypeface(xmlAttr(eastAsian, "typeface"));
52610
+ if (latinTypefaceToken && latinTypefaceToken.startsWith("+")) {
52611
+ style.latinFontThemeToken = latinTypefaceToken;
52612
+ }
52613
+ if (eaTypefaceToken && eaTypefaceToken.startsWith("+")) {
52614
+ style.eastAsiaFontThemeToken = eaTypefaceToken;
52615
+ }
52616
+ if (csTypefaceToken && csTypefaceToken.startsWith("+")) {
52617
+ style.complexScriptFontThemeToken = csTypefaceToken;
52618
+ }
52619
+ const eaTypeface = this.resolveThemeTypeface(eaTypefaceToken);
51264
52620
  if (eaTypeface) {
51265
52621
  style.eastAsiaFont = eaTypeface;
51266
52622
  }
51267
- const csTypeface = this.resolveThemeTypeface(xmlAttr(complexScript, "typeface"));
52623
+ const csTypeface = this.resolveThemeTypeface(csTypefaceToken);
51268
52624
  if (csTypeface) {
51269
52625
  style.complexScriptFont = csTypeface;
51270
52626
  }
@@ -51280,6 +52636,9 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
51280
52636
  const capAttr = String(runProperties2["@_cap"] || "").trim().toLowerCase();
51281
52637
  if (capAttr === "all" || capAttr === "small") {
51282
52638
  style.textCaps = capAttr;
52639
+ } else if (capAttr === "none") {
52640
+ style.textCaps = "none";
52641
+ style.textCapsExplicitNone = true;
51283
52642
  }
51284
52643
  const symNode = xmlChild(runProperties2, "a:sym");
51285
52644
  if (symNode) {
@@ -51339,6 +52698,12 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
51339
52698
  this.applyTextRunEffects(style, runEffectList);
51340
52699
  }
51341
52700
  this.applyTextRunEffectDag(style, runProperties2);
52701
+ if (includeDefaultAlignment) {
52702
+ const runExtLst = runProperties2["a:extLst"];
52703
+ if (runExtLst && typeof runExtLst === "object") {
52704
+ style.runPropertiesExtLstXml = runExtLst;
52705
+ }
52706
+ }
51342
52707
  return style;
51343
52708
  }
51344
52709
  /**
@@ -52010,12 +53375,63 @@ function writeCellTextFormatting(xmlCell, style, ensureArray16) {
52010
53375
  }
52011
53376
 
52012
53377
  // src/core/core/runtime/PptxHandlerRuntimeSaveTableStyles.ts
53378
+ function flattenCellTxBodyText(txBody, ensureArray16) {
53379
+ if (!txBody) {
53380
+ return "";
53381
+ }
53382
+ const paragraphs = ensureArray16(txBody["a:p"]);
53383
+ const lines = [];
53384
+ for (const paragraph of paragraphs) {
53385
+ const runs = ensureArray16(paragraph?.["a:r"]);
53386
+ const fields = ensureArray16(paragraph?.["a:fld"]);
53387
+ let lineText = "";
53388
+ for (const run of runs) {
53389
+ lineText += String(run?.["a:t"] ?? "");
53390
+ }
53391
+ for (const field of fields) {
53392
+ lineText += String(field?.["a:t"] ?? "");
53393
+ }
53394
+ lines.push(lineText);
53395
+ }
53396
+ return lines.join("\n");
53397
+ }
53398
+ function isRichCellTxBody(txBody, ensureArray16) {
53399
+ if (!txBody) {
53400
+ return false;
53401
+ }
53402
+ const paragraphs = ensureArray16(txBody["a:p"]);
53403
+ let totalRuns = 0;
53404
+ for (const paragraph of paragraphs) {
53405
+ const runs = ensureArray16(paragraph?.["a:r"]);
53406
+ totalRuns += runs.length;
53407
+ if (totalRuns > 1) {
53408
+ return true;
53409
+ }
53410
+ if (ensureArray16(paragraph?.["a:fld"]).length > 0) {
53411
+ return true;
53412
+ }
53413
+ for (const run of runs) {
53414
+ const rPr = run?.["a:rPr"];
53415
+ if (rPr?.["a:hlinkClick"] !== void 0) {
53416
+ return true;
53417
+ }
53418
+ }
53419
+ }
53420
+ return false;
53421
+ }
52013
53422
  var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime21 {
52014
53423
  /**
52015
53424
  * Write plain text into a table cell's txBody, preserving
52016
53425
  * existing run properties where possible.
52017
53426
  */
52018
53427
  writeTableCellText(xmlCell, text2) {
53428
+ const ensureArray16 = this.ensureArray.bind(this);
53429
+ const existingTxBody = xmlCell["a:txBody"];
53430
+ if (existingTxBody && ensureArray16(existingTxBody["a:p"]).length > 0) {
53431
+ if (flattenCellTxBodyText(existingTxBody, ensureArray16) === text2) {
53432
+ return;
53433
+ }
53434
+ }
52019
53435
  if (!xmlCell["a:txBody"]) {
52020
53436
  xmlCell["a:txBody"] = { "a:bodyPr": {}, "a:p": {} };
52021
53437
  }
@@ -52143,7 +53559,9 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
52143
53559
  }
52144
53560
  delete tcPr["a:tcMar"];
52145
53561
  writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime.EMU_PER_PX);
52146
- writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
53562
+ if (!isRichCellTxBody(xmlCell["a:txBody"], this.ensureArray.bind(this))) {
53563
+ writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
53564
+ }
52147
53565
  const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
52148
53566
  for (const key of Object.keys(tcPr)) {
52149
53567
  delete tcPr[key];
@@ -53828,7 +55246,7 @@ function findKey19(obj, name, getLocalName2) {
53828
55246
  function hex9(value) {
53829
55247
  return value.replace("#", "");
53830
55248
  }
53831
- var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
55249
+ var COLOR_LOCAL_NAMES2 = /* @__PURE__ */ new Set([
53832
55250
  "srgbClr",
53833
55251
  "schemeClr",
53834
55252
  "sysClr",
@@ -53837,7 +55255,7 @@ var COLOR_LOCAL_NAMES = /* @__PURE__ */ new Set([
53837
55255
  "hslClr"
53838
55256
  ]);
53839
55257
  function applyColorToList(list, value, getLocalName2) {
53840
- const colorKey = Object.keys(list).find((k) => COLOR_LOCAL_NAMES.has(getLocalName2(k)));
55258
+ const colorKey = Object.keys(list).find((k) => COLOR_LOCAL_NAMES2.has(getLocalName2(k)));
53841
55259
  const srgb = { "@_val": hex9(value) };
53842
55260
  if (!colorKey) {
53843
55261
  list["a:srgbClr"] = srgb;
@@ -56329,6 +57747,33 @@ var PptxHandlerRuntime27 = class extends PptxHandlerRuntime26 {
56329
57747
  }
56330
57748
  };
56331
57749
 
57750
+ // src/core/core/runtime/save-line-fill.ts
57751
+ function writeLineFill(lineNode, shapeStyle, parseColor) {
57752
+ delete lineNode["a:noFill"];
57753
+ delete lineNode["a:solidFill"];
57754
+ delete lineNode["a:gradFill"];
57755
+ delete lineNode["a:pattFill"];
57756
+ if (shapeStyle.strokeColor === "transparent" || shapeStyle.strokeWidth === 0) {
57757
+ lineNode["a:noFill"] = {};
57758
+ return;
57759
+ }
57760
+ if (shapeStyle.strokeFillMode === "gradient" && shapeStyle.strokeGradientXml) {
57761
+ lineNode["a:gradFill"] = shapeStyle.strokeGradientXml;
57762
+ return;
57763
+ }
57764
+ if (shapeStyle.strokeFillMode === "pattern" && shapeStyle.strokePatternXml) {
57765
+ lineNode["a:pattFill"] = shapeStyle.strokePatternXml;
57766
+ return;
57767
+ }
57768
+ const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? parseColor(shapeStyle.strokeColorXml) : void 0;
57769
+ lineNode["a:solidFill"] = serializeColorChoice(
57770
+ shapeStyle.strokeColorXml,
57771
+ resolvedStrokeOriginal,
57772
+ shapeStyle.strokeColor ?? "#000000",
57773
+ shapeStyle.strokeOpacity
57774
+ );
57775
+ }
57776
+
56332
57777
  // src/core/core/runtime/PptxHandlerRuntimeSaveShapeStyleWriter.ts
56333
57778
  var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime27 {
56334
57779
  /**
@@ -56399,26 +57844,14 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
56399
57844
  );
56400
57845
  }
56401
57846
  }
56402
- if (shapeStyle.strokeColor !== void 0) {
57847
+ if (shapeStyle.strokeColor !== void 0 || shapeStyle.strokeFillMode === "gradient" || shapeStyle.strokeFillMode === "pattern") {
56403
57848
  if (!spPr["a:ln"]) {
56404
57849
  spPr["a:ln"] = {};
56405
57850
  }
56406
57851
  const lineNode = spPr["a:ln"];
56407
57852
  const w = Math.round((shapeStyle.strokeWidth || 1) * _PptxHandlerRuntime.EMU_PER_PX);
56408
57853
  lineNode["@_w"] = String(w);
56409
- if (shapeStyle.strokeColor === "transparent" || shapeStyle.strokeWidth === 0) {
56410
- lineNode["a:noFill"] = {};
56411
- delete lineNode["a:solidFill"];
56412
- } else {
56413
- delete lineNode["a:noFill"];
56414
- const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
56415
- lineNode["a:solidFill"] = serializeColorChoice(
56416
- shapeStyle.strokeColorXml,
56417
- resolvedStrokeOriginal,
56418
- shapeStyle.strokeColor,
56419
- shapeStyle.strokeOpacity
56420
- );
56421
- }
57854
+ this.applyLineFill(lineNode, shapeStyle);
56422
57855
  }
56423
57856
  if (shapeStyle.strokeDash !== void 0) {
56424
57857
  if (!spPr["a:ln"]) {
@@ -56508,6 +57941,15 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
56508
57941
  spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
56509
57942
  }
56510
57943
  }
57944
+ /**
57945
+ * Emit the single fill child of an `<a:ln>` (CT_LineProperties allows at
57946
+ * most one of noFill/solidFill/gradFill/pattFill). Delegates to
57947
+ * {@link writeLineFill} so the logic stays unit-testable without the full
57948
+ * save runtime (issue #87).
57949
+ */
57950
+ applyLineFill(lineNode, shapeStyle) {
57951
+ writeLineFill(lineNode, shapeStyle, (colorNode) => this.parseColor(colorNode));
57952
+ }
56511
57953
  /**
56512
57954
  * Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
56513
57955
  * from the persisted ref indices/colour XML. Emits children in spec
@@ -56663,45 +58105,18 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56663
58105
  const s3d = shapeStyle.scene3d;
56664
58106
  const hasData = s3d.cameraPreset || s3d.lightRigType;
56665
58107
  if (hasData) {
56666
- const cameraObj = {};
56667
- if (s3d.cameraPreset) {
56668
- cameraObj["@_prst"] = s3d.cameraPreset;
56669
- }
56670
- if (s3d.cameraRotX !== void 0 || s3d.cameraRotY !== void 0 || s3d.cameraRotZ !== void 0) {
56671
- const rot = {};
56672
- if (s3d.cameraRotX !== void 0) {
56673
- rot["@_lat"] = String(s3d.cameraRotX);
56674
- }
56675
- if (s3d.cameraRotY !== void 0) {
56676
- rot["@_lon"] = String(s3d.cameraRotY);
56677
- }
56678
- if (s3d.cameraRotZ !== void 0) {
56679
- rot["@_rev"] = String(s3d.cameraRotZ);
56680
- }
56681
- cameraObj["a:rot"] = rot;
56682
- }
56683
- const lightRigObj = {};
56684
- if (s3d.lightRigType) {
56685
- lightRigObj["@_rig"] = s3d.lightRigType;
56686
- }
56687
- if (s3d.lightRigDirection) {
56688
- lightRigObj["@_dir"] = s3d.lightRigDirection;
56689
- }
56690
- const scene3dXml = {};
56691
- scene3dXml["a:camera"] = cameraObj;
56692
- if (Object.keys(lightRigObj).length > 0) {
56693
- scene3dXml["a:lightRig"] = lightRigObj;
56694
- }
56695
- if (s3d.hasBackdrop) {
56696
- const backdropObj = {};
56697
- if (s3d.backdropAnchorX !== void 0 || s3d.backdropAnchorY !== void 0 || s3d.backdropAnchorZ !== void 0) {
56698
- backdropObj["a:anchor"] = {
56699
- "@_x": String(s3d.backdropAnchorX ?? 0),
56700
- "@_y": String(s3d.backdropAnchorY ?? 0),
56701
- "@_z": String(s3d.backdropAnchorZ ?? 0)
56702
- };
56703
- }
56704
- scene3dXml["a:backdrop"] = backdropObj;
58108
+ const source = spPr["a:scene3d"] ?? {};
58109
+ const scene3dXml = { ...source };
58110
+ scene3dXml["a:camera"] = buildScene3dCamera(s3d, source);
58111
+ const lightRig = buildScene3dLightRig(s3d, source);
58112
+ if (lightRig) {
58113
+ scene3dXml["a:lightRig"] = lightRig;
58114
+ }
58115
+ const backdrop = buildScene3dBackdrop(s3d);
58116
+ if (backdrop) {
58117
+ scene3dXml["a:backdrop"] = backdrop;
58118
+ } else {
58119
+ delete scene3dXml["a:backdrop"];
56705
58120
  }
56706
58121
  spPr["a:scene3d"] = scene3dXml;
56707
58122
  } else {
@@ -56746,12 +58161,12 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56746
58161
  }
56747
58162
  if (sh3d.extrusionColor) {
56748
58163
  sp3dXml["a:extrusionClr"] = {
56749
- "a:srgbClr": { "@_val": sh3d.extrusionColor }
58164
+ "a:srgbClr": { "@_val": sh3d.extrusionColor.replace("#", "") }
56750
58165
  };
56751
58166
  }
56752
58167
  if (sh3d.contourColor) {
56753
58168
  sp3dXml["a:contourClr"] = {
56754
- "a:srgbClr": { "@_val": sh3d.contourColor }
58169
+ "a:srgbClr": { "@_val": sh3d.contourColor.replace("#", "") }
56755
58170
  };
56756
58171
  }
56757
58172
  spPr["a:sp3d"] = sp3dXml;
@@ -56763,6 +58178,77 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56763
58178
  }
56764
58179
  }
56765
58180
  };
58181
+ function buildSphereRot(lat, lon, rev) {
58182
+ if (lat === void 0 && lon === void 0 && rev === void 0) {
58183
+ return void 0;
58184
+ }
58185
+ const rot = {};
58186
+ if (lat !== void 0) {
58187
+ rot["@_lat"] = String(lat);
58188
+ }
58189
+ if (lon !== void 0) {
58190
+ rot["@_lon"] = String(lon);
58191
+ }
58192
+ if (rev !== void 0) {
58193
+ rot["@_rev"] = String(rev);
58194
+ }
58195
+ return rot;
58196
+ }
58197
+ function buildScene3dCamera(s3d, source) {
58198
+ const camera = { ...source["a:camera"] ?? {} };
58199
+ if (s3d.cameraPreset) {
58200
+ camera["@_prst"] = s3d.cameraPreset;
58201
+ }
58202
+ if (s3d.cameraFieldOfView !== void 0) {
58203
+ camera["@_fov"] = String(s3d.cameraFieldOfView);
58204
+ }
58205
+ if (s3d.cameraZoom !== void 0) {
58206
+ camera["@_zoom"] = String(s3d.cameraZoom);
58207
+ }
58208
+ const rot = buildSphereRot(s3d.cameraRotX, s3d.cameraRotY, s3d.cameraRotZ);
58209
+ if (rot) {
58210
+ camera["a:rot"] = rot;
58211
+ }
58212
+ return camera;
58213
+ }
58214
+ function buildScene3dLightRig(s3d, source) {
58215
+ const lightRig = { ...source["a:lightRig"] ?? {} };
58216
+ if (s3d.lightRigType) {
58217
+ lightRig["@_rig"] = s3d.lightRigType;
58218
+ }
58219
+ if (s3d.lightRigDirection) {
58220
+ lightRig["@_dir"] = s3d.lightRigDirection;
58221
+ }
58222
+ const rot = buildSphereRot(s3d.lightRigRotX, s3d.lightRigRotY, s3d.lightRigRotZ);
58223
+ if (rot) {
58224
+ lightRig["a:rot"] = rot;
58225
+ }
58226
+ return Object.keys(lightRig).length > 0 ? lightRig : void 0;
58227
+ }
58228
+ function buildScene3dBackdrop(s3d) {
58229
+ const hasNorm = s3d.backdropNormalX !== void 0 || s3d.backdropNormalY !== void 0 || s3d.backdropNormalZ !== void 0;
58230
+ const hasUp = s3d.backdropUpX !== void 0 || s3d.backdropUpY !== void 0 || s3d.backdropUpZ !== void 0;
58231
+ if (!s3d.hasBackdrop || !hasNorm || !hasUp) {
58232
+ return void 0;
58233
+ }
58234
+ return {
58235
+ "a:anchor": {
58236
+ "@_x": String(s3d.backdropAnchorX ?? 0),
58237
+ "@_y": String(s3d.backdropAnchorY ?? 0),
58238
+ "@_z": String(s3d.backdropAnchorZ ?? 0)
58239
+ },
58240
+ "a:norm": {
58241
+ "@_dx": String(s3d.backdropNormalX ?? 0),
58242
+ "@_dy": String(s3d.backdropNormalY ?? 0),
58243
+ "@_dz": String(s3d.backdropNormalZ ?? 0)
58244
+ },
58245
+ "a:up": {
58246
+ "@_dx": String(s3d.backdropUpX ?? 0),
58247
+ "@_dy": String(s3d.backdropUpY ?? 0),
58248
+ "@_dz": String(s3d.backdropUpZ ?? 0)
58249
+ }
58250
+ };
58251
+ }
56766
58252
 
56767
58253
  // src/core/core/runtime/PptxHandlerRuntimeSaveTextWriter.ts
56768
58254
  var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime29 {
@@ -58803,14 +60289,20 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
58803
60289
  relationshipType: constants.slideSyncRelationshipType,
58804
60290
  contentType: constants.slideSyncContentType
58805
60291
  });
58806
- this.slideBackgroundBuilder.applyBackground({
60292
+ await this.slideBackgroundBuilder.applyBackground({
58807
60293
  slideNode,
58808
60294
  slide,
58809
60295
  zip: this.zip,
58810
60296
  saveState: saveSession,
58811
60297
  relationshipRegistry: slideRelationshipRegistry,
58812
60298
  slideImageRelationshipType: constants.slideImageRelationshipType,
58813
- parseDataUrlToBytes: (dataUrl) => this.parseDataUrlToBytes(dataUrl)
60299
+ resolveImageToBytes: (url) => this.resolveMediaToBytes(url),
60300
+ reportUnsupportedBackground: (imageUrl) => this.compatibilityService.reportWarning({
60301
+ code: "SAVE_BACKGROUND_IMAGE_UNSUPPORTED",
60302
+ message: `Slide background image could not be embedded and was preserved as-is or omitted: ${imageUrl.slice(0, 120)}`,
60303
+ scope: "save",
60304
+ slideId: slide.id
60305
+ })
58814
60306
  });
58815
60307
  this.slideCommentPartWriter.writeComments({
58816
60308
  slide,
@@ -60315,7 +61807,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
60315
61807
  } = saveConstants;
60316
61808
  this.compatibilityService.resetWarnings();
60317
61809
  const saveSession = new PptxSaveStateBuilder().withZip(this.zip).withCommentAuthorMap(this.commentAuthorMap).withCommentAuthorDetails(this.commentAuthorDetails).withCommentAuthorsRootXml(this.commentAuthorsRootXml).withEmuPerPx(_PptxHandlerRuntime.EMU_PER_PX).build();
60318
- await this.reconcilePresentationSlidesForSave({
61810
+ const slideReferenceRemap = await this.reconcilePresentationSlidesForSave({
60319
61811
  slides,
60320
61812
  saveSession,
60321
61813
  slideRelationshipType,
@@ -60410,7 +61902,8 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
60410
61902
  rawSlideWidthEmu: this.rawSlideWidthEmu,
60411
61903
  rawSlideHeightEmu: this.rawSlideHeightEmu,
60412
61904
  rawSlideSizeType: this.rawSlideSizeType,
60413
- xmlLookupService: this.xmlLookupService
61905
+ xmlLookupService: this.xmlLookupService,
61906
+ slideReferenceRemap
60414
61907
  });
60415
61908
  this.deduplicateExtensionLists(this.presentationData);
60416
61909
  if (effectiveConformance === "transitional") {
@@ -60427,7 +61920,7 @@ var PptxHandlerRuntime51 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
60427
61920
  printSlidesPerPage: options.handoutMaster.slidesPerPage
60428
61921
  } : options?.presentationProperties;
60429
61922
  await this.applyPresentationPropertiesPart(presentationProperties);
60430
- await this.applyViewPropertiesPart(options?.viewProperties);
61923
+ await this.applyViewPropertiesPart(options?.viewProperties ?? this.loadedViewProperties);
60431
61924
  await this.applyTableStylesPart(options?.tableStyles);
60432
61925
  await this.documentPropertiesUpdater.updateOnSave(slides, {
60433
61926
  coreProperties: options?.coreProperties,
@@ -60715,26 +62208,16 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
60715
62208
  return true;
60716
62209
  }
60717
62210
  const typesMatch = source.type === target.type || source.type === "ctrtitle" && target.type === "title" || source.type === "subtitle" && target.type === "body";
60718
- if (source.idx !== void 0 && target.idx !== void 0) {
60719
- if (source.idx !== target.idx) {
60720
- return false;
60721
- }
60722
- if (source.type && target.type && !typesMatch) {
60723
- return false;
60724
- }
60725
- return true;
60726
- }
60727
- if (source.idx !== void 0 && target.idx === void 0) {
60728
- const singletonTypes = /* @__PURE__ */ new Set(["title", "ctrtitle", "subtitle", "dt", "ftr", "sldnum"]);
60729
- if (source.type && singletonTypes.has(source.type)) {
60730
- return typesMatch;
60731
- }
62211
+ const sourceIdx = source.idx ?? "0";
62212
+ const targetIdx = target.idx ?? "0";
62213
+ if (sourceIdx !== targetIdx) {
60732
62214
  return false;
60733
62215
  }
60734
62216
  if (source.type && target.type && !typesMatch) {
60735
62217
  return false;
60736
62218
  }
60737
- if (source.type && !target.type) {
62219
+ const bothHaveExplicitIdx = source.idx !== void 0 && target.idx !== void 0;
62220
+ if (!bothHaveExplicitIdx && source.type && !target.type) {
60738
62221
  return false;
60739
62222
  }
60740
62223
  return true;
@@ -62180,6 +63663,19 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
62180
63663
  });
62181
63664
  return hasAny ? locks : void 0;
62182
63665
  }
63666
+ /**
63667
+ * Parse the `@txBox` attribute from a `p:cNvSpPr` node. Returns `true` /
63668
+ * `false` when the attribute is present, or `undefined` when absent so
63669
+ * callers can distinguish "not a text box" from "unspecified".
63670
+ */
63671
+ parseTxBoxFlag(cNvSpPr) {
63672
+ const raw = cNvSpPr?.["@_txBox"];
63673
+ if (raw === void 0) {
63674
+ return void 0;
63675
+ }
63676
+ const val = String(raw).trim().toLowerCase();
63677
+ return val === "1" || val === "true";
63678
+ }
62183
63679
  /**
62184
63680
  * Extract body-level text properties from `a:bodyPr` and apply them to the
62185
63681
  * provided {@link TextStyle}. Returns linked-textbox info when present.
@@ -62362,6 +63858,62 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
62362
63858
 
62363
63859
  // src/core/core/runtime/PptxHandlerRuntimeShapeTextParsing.ts
62364
63860
  var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime61 {
63861
+ /**
63862
+ * Extract a paragraph's OWN `a:pPr` geometry (align, spacing, margins,
63863
+ * indent, tabs, rtl) as a partial {@link TextStyle} so per-paragraph
63864
+ * formatting round-trips rather than collapsing to one shape-level pPr
63865
+ * (#69). Inherited layout/master values are not re-stamped.
63866
+ */
63867
+ extractParagraphOwnProperties(p, basisFontSize) {
63868
+ const pPr = p["a:pPr"];
63869
+ if (!pPr) {
63870
+ return void 0;
63871
+ }
63872
+ const pp = { ...parseParagraphMargins(pPr) };
63873
+ const align = pPr["@_algn"] !== void 0 ? parseAlignmentAttr2(String(pPr["@_algn"])) : void 0;
63874
+ if (align) {
63875
+ pp.align = align;
63876
+ }
63877
+ const rtl = parseParagraphRtl(pPr);
63878
+ if (rtl !== void 0) {
63879
+ pp.rtl = rtl;
63880
+ }
63881
+ const spcBef = this.parseParagraphSpacingPx(
63882
+ pPr["a:spcBef"],
63883
+ basisFontSize
63884
+ );
63885
+ if (spcBef !== void 0) {
63886
+ pp.paragraphSpacingBefore = spcBef;
63887
+ }
63888
+ const spcAft = this.parseParagraphSpacingPx(
63889
+ pPr["a:spcAft"],
63890
+ basisFontSize
63891
+ );
63892
+ if (spcAft !== void 0) {
63893
+ pp.paragraphSpacingAfter = spcAft;
63894
+ }
63895
+ const lnSpcNode = pPr["a:lnSpc"];
63896
+ const lineSpacing = this.parseLineSpacingMultiplier(lnSpcNode);
63897
+ const exactPt = lineSpacing === void 0 ? this.parseLineSpacingExactPt(lnSpcNode) : void 0;
63898
+ if (lineSpacing !== void 0) {
63899
+ pp.lineSpacing = lineSpacing;
63900
+ } else if (exactPt !== void 0) {
63901
+ pp.lineSpacingExactPt = exactPt;
63902
+ }
63903
+ const tabStops = parseTabStops(pPr);
63904
+ if (tabStops && tabStops.length > 0) {
63905
+ pp.tabStops = tabStops;
63906
+ }
63907
+ const defRPr = pPr["a:defRPr"];
63908
+ if (defRPr && typeof defRPr === "object") {
63909
+ pp.paragraphDefaultRunPropertiesXml = defRPr;
63910
+ }
63911
+ const pPrExtLst = pPr["a:extLst"];
63912
+ if (pPrExtLst && typeof pPrExtLst === "object") {
63913
+ pp.paragraphPropertiesExtLstXml = pPrExtLst;
63914
+ }
63915
+ return Object.keys(pp).length > 0 ? pp : void 0;
63916
+ }
62365
63917
  /**
62366
63918
  * Resolve paragraph-level styles (alignment, spacing, margins, tabs,
62367
63919
  * level styles) for a single paragraph. Modifies `textStyle` in place
@@ -62610,6 +64162,12 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
62610
64162
  ...mergedDefaultRunStyle,
62611
64163
  ...this.extractTextRunStyle(runProps, paraAlign, ctx.slideRelationshipMap)
62612
64164
  };
64165
+ if (!runStyle2.scriptFallbackFont) {
64166
+ const fallback = this.resolveScriptFallbackFont(runText);
64167
+ if (fallback) {
64168
+ runStyle2.scriptFallbackFont = fallback;
64169
+ }
64170
+ }
62613
64171
  parts.push(runText);
62614
64172
  segments.push({ text: runText, style: runStyle2 });
62615
64173
  maybeSeed(runStyle2);
@@ -62651,14 +64209,25 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
62651
64209
  )
62652
64210
  };
62653
64211
  const fldType = String(field["@_type"] || "").trim() || void 0;
62654
- const fldGuid = String(field["@_uuid"] || field["@_id"] || "").trim() || void 0;
64212
+ const uuidAttr = String(field["@_uuid"] || "").trim();
64213
+ const idAttr = String(field["@_id"] || "").trim();
64214
+ const fldGuid = uuidAttr || idAttr || void 0;
64215
+ const fldGuidAttr = uuidAttr ? "uuid" : idAttr ? "id" : void 0;
62655
64216
  parts.push(fieldText);
62656
- segments.push({
64217
+ const fieldSegment = {
62657
64218
  text: fieldText,
62658
64219
  style: fieldRunStyle,
62659
64220
  fieldType: fldType,
62660
64221
  fieldGuid: fldGuid
62661
- });
64222
+ };
64223
+ if (fldGuidAttr) {
64224
+ fieldSegment.fieldGuidAttr = fldGuidAttr;
64225
+ }
64226
+ const fieldPPr = field["a:pPr"];
64227
+ if (fieldPPr && typeof fieldPPr === "object") {
64228
+ fieldSegment.fieldParagraphPropertiesXml = fieldPPr;
64229
+ }
64230
+ segments.push(fieldSegment);
62662
64231
  maybeSeed(fieldRunStyle);
62663
64232
  };
62664
64233
  const processMathElement = (mathEl) => {
@@ -62785,6 +64354,11 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
62785
64354
  ...endParaRPrRaw
62786
64355
  };
62787
64356
  }
64357
+ const basisFontSize = typeof mergedDefaultRunStyle.fontSize === "number" ? mergedDefaultRunStyle.fontSize : void 0;
64358
+ const paragraphOwnProps = this.extractParagraphOwnProperties(p, basisFontSize);
64359
+ if (paragraphOwnProps) {
64360
+ segments[firstSegmentIndex].paragraphProperties = paragraphOwnProps;
64361
+ }
62788
64362
  }
62789
64363
  return { parts, segments, seedStyle };
62790
64364
  }
@@ -63093,7 +64667,11 @@ var PptxHandlerRuntime64 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63093
64667
  const inheritedCNvSpPr = xmlPath(inheritedPlaceholder?.shape, "p:nvSpPr", "p:cNvSpPr") ?? xmlPath(inheritedPlaceholder?.picture, "p:nvPicPr", "p:cNvPicPr");
63094
64668
  const inheritedLockNode = inheritedCNvSpPr?.["a:spLocks"] ?? inheritedCNvSpPr?.["a:picLocks"];
63095
64669
  const inheritedLocks = this.parseShapeLocks(inheritedLockNode);
63096
- const locks = inheritedLocks ? { ...inheritedLocks, ...slideLocks } : slideLocks;
64670
+ let locks = inheritedLocks ? { ...inheritedLocks, ...slideLocks } : slideLocks;
64671
+ const txBox = this.parseTxBoxFlag(cNvSpPr);
64672
+ if (txBox !== void 0) {
64673
+ locks = { ...locks ?? {}, txBox };
64674
+ }
63097
64675
  const promptText = !hasText && phDefaults?.promptText ? phDefaults.promptText : void 0;
63098
64676
  const opaqueExtLstXml = this.extractOpaqueSpPrExtLst(effectiveSpPr);
63099
64677
  const commonProps = {
@@ -63192,7 +64770,7 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63192
64770
  const skewY = xfrm["@_skewY"] ? parseEmuInt(xfrm["@_skewY"]) / 6e4 : void 0;
63193
64771
  const { flipHorizontal, flipVertical } = this.readFlipState(xfrm);
63194
64772
  const nvPr = pic?.["p:nvPicPr"]?.["p:nvPr"];
63195
- const mediaReference = parseDrawingMediaReference(nvPr);
64773
+ const mediaReference = parseDrawingMediaReference(nvPr, this.externalRelsMap.get(slidePath));
63196
64774
  if (mediaReference) {
63197
64775
  this.compatibilityService.inspectMediaReferenceCompatibility(
63198
64776
  mediaReference.kind,
@@ -63960,6 +65538,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63960
65538
  const grpSpPr = group["p:grpSpPr"];
63961
65539
  const xfrm = grpSpPr?.["a:xfrm"];
63962
65540
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
65541
+ let groupRotation;
65542
+ let flipHorizontal = false;
65543
+ let flipVertical = false;
63963
65544
  if (xfrm) {
63964
65545
  const off = xfrm["a:off"];
63965
65546
  if (off) {
@@ -63971,6 +65552,12 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63971
65552
  parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
63972
65553
  parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
63973
65554
  }
65555
+ if (xfrm["@_rot"] !== void 0 && xfrm["@_rot"] !== null) {
65556
+ const rot = parseInt(String(xfrm["@_rot"]), 10) / 6e4;
65557
+ groupRotation = Number.isFinite(rot) && rot !== 0 ? rot : void 0;
65558
+ }
65559
+ flipHorizontal = this.parseBooleanAttr(xfrm["@_flipH"]);
65560
+ flipVertical = this.parseBooleanAttr(xfrm["@_flipV"]);
63974
65561
  }
63975
65562
  const grpFillStyle = grpSpPr ? this.extractShapeStyle(grpSpPr) : void 0;
63976
65563
  const hasGroupFill = grpFillStyle && grpFillStyle.fillMode && grpFillStyle.fillMode !== "none";
@@ -64016,6 +65603,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
64016
65603
  y: parentY,
64017
65604
  width: parentW || Math.max(...children10.map((c) => c.x + c.width)),
64018
65605
  height: parentH || Math.max(...children10.map((c) => c.y + c.height)),
65606
+ rotation: groupRotation,
65607
+ flipHorizontal: flipHorizontal || void 0,
65608
+ flipVertical: flipVertical || void 0,
64019
65609
  children: children10,
64020
65610
  rawXml: group,
64021
65611
  actionClick: grpActionClick,
@@ -65032,9 +66622,9 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
65032
66622
  }
65033
66623
  const buClr = levelProps["a:buClr"];
65034
66624
  if (buClr) {
65035
- const srgb = buClr["a:srgbClr"];
65036
- if (srgb?.["@_val"]) {
65037
- style.bulletColor = String(srgb["@_val"]);
66625
+ const bulletColor = this.parseColor(buClr);
66626
+ if (bulletColor) {
66627
+ style.bulletColor = bulletColor;
65038
66628
  }
65039
66629
  }
65040
66630
  const buSzPts = levelProps["a:buSzPts"];
@@ -66634,16 +68224,20 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
66634
68224
  }
66635
68225
  let fontScheme;
66636
68226
  if (hasFonts) {
68227
+ const majorByScript = this.aggregateFontScriptOverrides(this.masterThemeMajorFontScripts);
68228
+ const minorByScript = this.aggregateFontScriptOverrides(this.masterThemeMinorFontScripts);
66637
68229
  fontScheme = {
66638
68230
  majorFont: {
66639
68231
  latin: this.themeFontMap["mj-lt"],
66640
68232
  eastAsia: this.themeFontMap["mj-ea"],
66641
- complexScript: this.themeFontMap["mj-cs"]
68233
+ complexScript: this.themeFontMap["mj-cs"],
68234
+ ...Object.keys(majorByScript).length > 0 ? { byScript: majorByScript } : {}
66642
68235
  },
66643
68236
  minorFont: {
66644
68237
  latin: this.themeFontMap["mn-lt"],
66645
68238
  eastAsia: this.themeFontMap["mn-ea"],
66646
- complexScript: this.themeFontMap["mn-cs"]
68239
+ complexScript: this.themeFontMap["mn-cs"],
68240
+ ...Object.keys(minorByScript).length > 0 ? { byScript: minorByScript } : {}
66647
68241
  }
66648
68242
  };
66649
68243
  }
@@ -66851,6 +68445,23 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
66851
68445
  *
66852
68446
  * Phase 4 Stream A / M4.
66853
68447
  */
68448
+ /**
68449
+ * Flatten a per-theme-path script-override map (`themePath -> {script ->
68450
+ * typeface}`) into a single `{script -> typeface}` lookup for
68451
+ * {@link buildThemeObject}. Earlier entries win on collision, which matches
68452
+ * the primary-theme-first parse order. Phase 4 Stream A / M4 (#83).
68453
+ */
68454
+ aggregateFontScriptOverrides(perPathMap) {
68455
+ const aggregate = {};
68456
+ for (const overrides10 of perPathMap.values()) {
68457
+ for (const [script, typeface] of Object.entries(overrides10)) {
68458
+ if (!(script in aggregate)) {
68459
+ aggregate[script] = typeface;
68460
+ }
68461
+ }
68462
+ }
68463
+ return aggregate;
68464
+ }
66854
68465
  collectFontScriptOverrides(fontNode) {
66855
68466
  const overrides10 = {};
66856
68467
  if (!fontNode) {
@@ -67486,33 +69097,16 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
67486
69097
  const metadata = parseSmartArtDefinitionMetadata(colorsDef, localName22);
67487
69098
  const labels = parseSmartArtColorStyleLabels(colorsDef, localName22);
67488
69099
  const name = metadata.titles?.[0]?.value || String(colorsDef["@_title"] || colorsDef["@_uniqueId"] || "").trim() || void 0;
67489
- const fillColors = [];
67490
- const lineColors = [];
67491
69100
  const styleLbls = this.xmlLookupService.getChildrenArrayByLocalName(colorsDef, "styleLbl");
67492
- for (const lbl of styleLbls) {
67493
- const fillClrLst = this.xmlLookupService.getChildByLocalName(lbl, "fillClrLst");
67494
- const linClrLst = this.xmlLookupService.getChildByLocalName(lbl, "linClrLst");
67495
- if (fillClrLst) {
67496
- const color2 = this.parseColor(fillClrLst) ?? this.resolveSmartArtSchemeColor(
67497
- this.xmlLookupService.getChildByLocalName(fillClrLst, "schemeClr")
67498
- );
67499
- if (color2) {
67500
- fillColors.push(color2);
67501
- }
67502
- }
67503
- if (linClrLst) {
67504
- const color2 = this.parseColor(linClrLst) ?? this.resolveSmartArtSchemeColor(
67505
- this.xmlLookupService.getChildByLocalName(linClrLst, "schemeClr")
67506
- );
67507
- if (color2) {
67508
- lineColors.push(color2);
67509
- }
67510
- }
67511
- }
67512
- if (fillColors.length === 0 && lineColors.length === 0) {
69101
+ const colorLists = buildSmartArtColorLists(styleLbls, {
69102
+ getChild: (node, childName) => this.xmlLookupService.getChildByLocalName(node, childName),
69103
+ parseColorChoice: (colorChoice) => this.parseColor(colorChoice),
69104
+ resolveScheme: (colorNode) => this.resolveSmartArtSchemeColor(colorNode)
69105
+ });
69106
+ if (colorLists.fillColors.length === 0 && colorLists.lineColors.length === 0) {
67513
69107
  return void 0;
67514
69108
  }
67515
- return { ...metadata, name, fillColors, lineColors, labels };
69109
+ return { ...metadata, name, ...colorLists, labels };
67516
69110
  } catch {
67517
69111
  return void 0;
67518
69112
  }
@@ -67536,6 +69130,89 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
67536
69130
  }
67537
69131
  };
67538
69132
 
69133
+ // src/core/core/runtime/smartart-drawing-shape-style.ts
69134
+ function extractDrawingShapeFill(spPr, deps) {
69135
+ const result = {};
69136
+ const solidFill2 = deps.getChild(spPr, "solidFill");
69137
+ if (solidFill2) {
69138
+ result.fillColor = deps.parseColor(solidFill2) ?? void 0;
69139
+ }
69140
+ const gradFill = !solidFill2 ? deps.getChild(spPr, "gradFill") : void 0;
69141
+ if (gradFill) {
69142
+ const stops = deps.extractGradientStops(gradFill).map((stop) => ({
69143
+ color: stop.color,
69144
+ position: stop.position,
69145
+ ...stop.opacity !== void 0 ? { opacity: stop.opacity } : {}
69146
+ }));
69147
+ if (stops.length > 0) {
69148
+ result.fillGradientStops = stops;
69149
+ result.fillGradientType = deps.extractGradientType(gradFill);
69150
+ result.fillGradientAngle = deps.extractGradientAngle(gradFill);
69151
+ result.fillColor ??= stops[Math.floor(stops.length / 2)]?.color;
69152
+ }
69153
+ }
69154
+ const pattFill = !solidFill2 && !gradFill ? deps.getChild(spPr, "pattFill") : void 0;
69155
+ if (pattFill) {
69156
+ const preset = String(pattFill["@_prst"] || "").trim();
69157
+ if (preset) {
69158
+ result.fillPatternPreset = preset;
69159
+ }
69160
+ const fg = deps.parseColor(deps.getChild(pattFill, "fgClr"));
69161
+ const bg = deps.parseColor(deps.getChild(pattFill, "bgClr"));
69162
+ if (fg) {
69163
+ result.fillPatternForegroundColor = fg;
69164
+ }
69165
+ if (bg) {
69166
+ result.fillPatternBackgroundColor = bg;
69167
+ }
69168
+ result.fillColor ??= fg ?? bg;
69169
+ }
69170
+ const blipFill = !solidFill2 && !gradFill && !pattFill ? deps.getChild(spPr, "blipFill") : void 0;
69171
+ if (blipFill) {
69172
+ const blip = deps.getChild(blipFill, "blip");
69173
+ const embed = String(
69174
+ blip?.["@_r:embed"] || blip?.["@_embed"] || blip?.["@_r:link"] || ""
69175
+ ).trim();
69176
+ if (embed) {
69177
+ result.fillBlipEmbedId = embed;
69178
+ }
69179
+ }
69180
+ const shadowColor = deps.extractShadowColor(spPr);
69181
+ if (shadowColor) {
69182
+ result.hasShadow = true;
69183
+ result.shadowColor = shadowColor;
69184
+ }
69185
+ return result;
69186
+ }
69187
+ function extractDrawingShapeTextStyle(txBody, deps) {
69188
+ let fontSize;
69189
+ let fontColor;
69190
+ if (!txBody) {
69191
+ return { fontSize, fontColor };
69192
+ }
69193
+ const paragraphs = deps.getChildren(txBody, "p");
69194
+ for (const p of paragraphs) {
69195
+ const runs = deps.getChildren(p, "r");
69196
+ for (const r of runs) {
69197
+ const rPr = deps.getChild(r, "rPr");
69198
+ if (rPr && !fontSize) {
69199
+ const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
69200
+ if (Number.isFinite(szRaw) && szRaw > 0) {
69201
+ fontSize = szRaw / 100;
69202
+ }
69203
+ fontColor = deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
69204
+ }
69205
+ if (fontSize) {
69206
+ break;
69207
+ }
69208
+ }
69209
+ if (fontSize) {
69210
+ break;
69211
+ }
69212
+ }
69213
+ return { fontSize, fontColor };
69214
+ }
69215
+
67539
69216
  // src/core/core/runtime/smartart-text-style-resolution.ts
67540
69217
  function resolveSmartArtTextStyles(paragraphs, resolve) {
67541
69218
  for (const paragraph of paragraphs ?? []) {
@@ -67711,8 +69388,7 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67711
69388
  };
67712
69389
  }
67713
69390
  }
67714
- const solidFill2 = this.xmlLookupService.getChildByLocalName(spPr, "solidFill");
67715
- const fillColor = this.parseColor(solidFill2);
69391
+ const fill = extractDrawingShapeFill(spPr, this.drawingShapeStyleDeps());
67716
69392
  const lnNode = this.xmlLookupService.getChildByLocalName(spPr, "ln");
67717
69393
  const lnFill = lnNode ? this.xmlLookupService.getChildByLocalName(lnNode, "solidFill") : void 0;
67718
69394
  const strokeColor = this.parseColor(lnFill);
@@ -67724,7 +69400,10 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67724
69400
  this.collectLocalTextValues(txBody, "t", textValues2);
67725
69401
  }
67726
69402
  const text2 = textValues2.join("").trim() || void 0;
67727
- const { fontSize, fontColor } = this.extractDrawingShapeTextStyle(txBody);
69403
+ const { fontSize, fontColor } = extractDrawingShapeTextStyle(
69404
+ txBody,
69405
+ this.drawingShapeStyleDeps()
69406
+ );
67728
69407
  const paragraphs = txBody ? resolveSmartArtTextStyles(
67729
69408
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
67730
69409
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -67750,7 +69429,8 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67750
69429
  rotation,
67751
69430
  skewX,
67752
69431
  skewY,
67753
- fillColor: fillColor ?? void 0,
69432
+ ...fill,
69433
+ fillColor: fill.fillColor ?? void 0,
67754
69434
  strokeColor: strokeColor ?? void 0,
67755
69435
  strokeWidth,
67756
69436
  text: structuredText,
@@ -67760,36 +69440,126 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67760
69440
  ...customGeometry
67761
69441
  };
67762
69442
  }
67763
- extractDrawingShapeTextStyle(txBody) {
67764
- let fontSize;
67765
- let fontColor;
67766
- if (!txBody) {
67767
- return { fontSize, fontColor };
67768
- }
67769
- const paragraphs = this.xmlLookupService.getChildrenArrayByLocalName(txBody, "p");
67770
- for (const p of paragraphs) {
67771
- const runs = this.xmlLookupService.getChildrenArrayByLocalName(p, "r");
67772
- for (const r of runs) {
67773
- const rPr = this.xmlLookupService.getChildByLocalName(r, "rPr");
67774
- if (rPr && !fontSize) {
67775
- const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
67776
- if (Number.isFinite(szRaw) && szRaw > 0) {
67777
- fontSize = szRaw / 100;
67778
- }
67779
- const rprFill = this.xmlLookupService.getChildByLocalName(rPr, "solidFill");
67780
- fontColor = this.parseColor(rprFill) ?? void 0;
67781
- }
67782
- if (fontSize) {
67783
- break;
67784
- }
67785
- }
67786
- if (fontSize) {
67787
- break;
69443
+ /**
69444
+ * Build the injected accessor bundle used by the pure drawing-shape style
69445
+ * helpers, binding the shared XML-lookup / colour / gradient / shadow codec
69446
+ * methods so no new colour logic is duplicated here.
69447
+ */
69448
+ drawingShapeStyleDeps() {
69449
+ return {
69450
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
69451
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
69452
+ parseColor: (node) => this.parseColor(node),
69453
+ extractGradientStops: (gradFill) => this.extractGradientStops(gradFill),
69454
+ extractGradientType: (gradFill) => this.extractGradientType(gradFill),
69455
+ extractGradientAngle: (gradFill) => this.extractGradientAngle(gradFill),
69456
+ extractShadowColor: (spPr) => this.extractShadowStyle(spPr).shadowColor
69457
+ };
69458
+ }
69459
+ };
69460
+
69461
+ // src/core/core/runtime/smartart-drawing-blip.ts
69462
+ function collectDrawingShapeNodes(root, getChildren) {
69463
+ const out = [];
69464
+ const walk = (container) => {
69465
+ if (!container) {
69466
+ return;
69467
+ }
69468
+ for (const sp of getChildren(container, "sp")) {
69469
+ out.push({ node: sp, isPic: false });
69470
+ }
69471
+ for (const pic of getChildren(container, "pic")) {
69472
+ out.push({ node: pic, isPic: true });
69473
+ }
69474
+ for (const grp of getChildren(container, "grpSp")) {
69475
+ walk(grp);
69476
+ }
69477
+ };
69478
+ walk(root);
69479
+ return out;
69480
+ }
69481
+ function picBlipEmbedId(pic, getChild) {
69482
+ const blip = getChild(getChild(pic, "blipFill"), "blip");
69483
+ if (!blip) {
69484
+ return void 0;
69485
+ }
69486
+ const embed = String(blip["@_r:embed"] || blip["@_embed"] || blip["@_r:link"] || "").trim();
69487
+ return embed.length > 0 ? embed : void 0;
69488
+ }
69489
+ function parseDrawingRelTargets(relsXml, parse, ensureArray16) {
69490
+ const map = /* @__PURE__ */ new Map();
69491
+ try {
69492
+ const relsRoot = parse(relsXml)["Relationships"];
69493
+ if (!relsRoot) {
69494
+ return map;
69495
+ }
69496
+ for (const rel of ensureArray16(relsRoot["Relationship"])) {
69497
+ const id = String(rel?.["@_Id"] || "").trim();
69498
+ const target = String(rel?.["@_Target"] || "").trim();
69499
+ if (id.length > 0 && target.length > 0) {
69500
+ map.set(id, target);
67788
69501
  }
67789
69502
  }
67790
- return { fontSize, fontColor };
69503
+ } catch {
67791
69504
  }
67792
- };
69505
+ return map;
69506
+ }
69507
+ async function resolveDrawingBlipFills(shapes, drawingPath, deps) {
69508
+ const pending = shapes.filter((shape) => shape.fillBlipEmbedId && !shape.fillImageUrl);
69509
+ if (pending.length === 0) {
69510
+ return;
69511
+ }
69512
+ const dir = drawingPath.replace(/\/[^/]+$/u, "");
69513
+ const file = drawingPath.split("/").pop() ?? "";
69514
+ const relsXml = await deps.readText(`${dir}/_rels/${file}.rels`);
69515
+ if (!relsXml) {
69516
+ return;
69517
+ }
69518
+ const targets = parseDrawingRelTargets(relsXml, deps.parse, deps.ensureArray);
69519
+ for (const shape of pending) {
69520
+ const target = targets.get(shape.fillBlipEmbedId ?? "");
69521
+ if (!target) {
69522
+ continue;
69523
+ }
69524
+ const source = /^(?:https?:|data:)/u.test(target) ? target : deps.resolveImagePath(drawingPath, target);
69525
+ const resolved = await deps.getImageData(source);
69526
+ if (resolved) {
69527
+ shape.fillImageUrl = resolved;
69528
+ }
69529
+ }
69530
+ }
69531
+ async function parseDrawingShapesFromPart(drawingPath, deps) {
69532
+ const xmlString = await deps.readText(drawingPath);
69533
+ if (!xmlString) {
69534
+ return [];
69535
+ }
69536
+ try {
69537
+ const xml = deps.parse(xmlString);
69538
+ const drawing = deps.getChild(xml, "drawing");
69539
+ const spTree = deps.getChild(drawing || xml, "spTree");
69540
+ if (!spTree) {
69541
+ return [];
69542
+ }
69543
+ const shapes = [];
69544
+ collectDrawingShapeNodes(spTree, deps.getChildren).forEach(({ node, isPic }, index) => {
69545
+ const shape = deps.parseDrawingShape(node, index, deps.emuPerPx);
69546
+ if (!shape) {
69547
+ return;
69548
+ }
69549
+ if (isPic && !shape.fillBlipEmbedId) {
69550
+ const embed = picBlipEmbedId(node, deps.getChild);
69551
+ if (embed) {
69552
+ shape.fillBlipEmbedId = embed;
69553
+ }
69554
+ }
69555
+ shapes.push(shape);
69556
+ });
69557
+ await resolveDrawingBlipFills(shapes, drawingPath, deps);
69558
+ return shapes;
69559
+ } catch {
69560
+ return [];
69561
+ }
69562
+ }
67793
69563
 
67794
69564
  // src/core/core/runtime/smartart-layout-category.ts
67795
69565
  var CATEGORY_FAMILY = {
@@ -67926,6 +69696,7 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67926
69696
  layoutDefinition,
67927
69697
  nodes,
67928
69698
  connections: parsedConnections.length > 0 ? parsedConnections : void 0,
69699
+ presLayoutVars: parseSmartArtPresLayoutVars(dataModel),
67929
69700
  drawingShapes: drawingShapes.length > 0 ? drawingShapes : void 0,
67930
69701
  chrome,
67931
69702
  colorTransform,
@@ -68004,30 +69775,28 @@ var PptxHandlerRuntime85 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
68004
69775
  }
68005
69776
  }
68006
69777
  /**
68007
- * Parse SmartArt drawing shapes given an absolute part path.
69778
+ * Parse cached SmartArt drawing shapes from an absolute part path.
68008
69779
  *
68009
- * Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
68010
- * relationship id) with a path-based lookup so the resolution layer
68011
- * can pull the part from anywhere in the package.
69780
+ * Enumerates `dsp:sp` / bare `dsp:pic` (incl. nested `dsp:grpSp`) and
69781
+ * resolves picture (blip) fills to data URLs via the drawing part's own
69782
+ * relationships. Delegates to a pure helper with an injected dep bundle.
68012
69783
  */
68013
69784
  async parseSmartArtDrawingShapesFromPath(drawingPath) {
68014
- const xmlString = await this.zip.file(drawingPath)?.async("string");
68015
- if (!xmlString) {
68016
- return [];
68017
- }
68018
- try {
68019
- const xml = this.parser.parse(xmlString);
68020
- const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
68021
- const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
68022
- if (!spTree) {
68023
- return [];
68024
- }
68025
- const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
68026
- const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
68027
- return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
68028
- } catch {
68029
- return [];
68030
- }
69785
+ return parseDrawingShapesFromPart(drawingPath, this.drawingBlipDeps());
69786
+ }
69787
+ /** Bind runtime zip / parser / lookup / image helpers for the drawing parser. */
69788
+ drawingBlipDeps() {
69789
+ return {
69790
+ readText: (path) => this.zip.file(path)?.async("string") ?? Promise.resolve(void 0),
69791
+ parse: (xml) => this.parser.parse(xml),
69792
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
69793
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
69794
+ parseDrawingShape: (sp, index, emuPerPx) => this.parseDrawingShape(sp, index, emuPerPx),
69795
+ emuPerPx: _PptxHandlerRuntime.EMU_PER_PX,
69796
+ ensureArray: (value) => this.ensureArray(value),
69797
+ resolveImagePath: (base, target) => this.resolveImagePath(base, target),
69798
+ getImageData: (path) => this.getImageData(path)
69799
+ };
68031
69800
  }
68032
69801
  };
68033
69802
 
@@ -68725,6 +70494,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
68725
70494
  grouping = "clustered";
68726
70495
  }
68727
70496
  }
70497
+ const varyColors = this.parseChartBoolVal(seriesContainer, "varyColors");
70498
+ const firstSliceAngle = this.parseChartNumberVal(seriesContainer, "firstSliceAng");
70499
+ const doughnutHoleSize = this.parseChartNumberVal(seriesContainer, "holeSize");
70500
+ const barGapWidth = this.parseChartNumberVal(seriesContainer, "gapWidth");
70501
+ const barOverlap = this.parseChartNumberVal(seriesContainer, "overlap");
68728
70502
  const chartPartPath = chartPart.partPath;
68729
70503
  const dataTable = parseDataTable(plotArea, this.xmlLookupService);
68730
70504
  const dropLines = parseLineStyle(
@@ -68801,6 +70575,11 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
68801
70575
  title: titleTextValues[0],
68802
70576
  style: chartStyle,
68803
70577
  grouping,
70578
+ ...varyColors !== void 0 ? { varyColors } : {},
70579
+ ...firstSliceAngle !== void 0 ? { firstSliceAngle } : {},
70580
+ ...doughnutHoleSize !== void 0 ? { doughnutHoleSize } : {},
70581
+ ...barGapWidth !== void 0 ? { barGapWidth } : {},
70582
+ ...barOverlap !== void 0 ? { barOverlap } : {},
68804
70583
  chartPartPath,
68805
70584
  chartRelationshipId,
68806
70585
  ...dataTable ? { dataTable } : {},
@@ -68877,6 +70656,35 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
68877
70656
  }
68878
70657
  return { categories, series };
68879
70658
  }
70659
+ /**
70660
+ * Read a numeric `@val` from a named child of a chart-type container.
70661
+ * Returns `undefined` when the child or its `@val` is absent/non-finite.
70662
+ */
70663
+ parseChartNumberVal(container, localName22) {
70664
+ const node = this.xmlLookupService.getChildByLocalName(container, localName22);
70665
+ const raw = node?.["@_val"];
70666
+ if (raw === void 0 || raw === null || raw === "") {
70667
+ return void 0;
70668
+ }
70669
+ const num = Number.parseFloat(String(raw));
70670
+ return Number.isFinite(num) ? num : void 0;
70671
+ }
70672
+ /**
70673
+ * Read a boolean `@val` from a named child of a chart-type container.
70674
+ * A present element with no `@val` follows the OOXML `CT_Boolean` default
70675
+ * of `true`; `undefined` when the child is absent.
70676
+ */
70677
+ parseChartBoolVal(container, localName22) {
70678
+ const node = this.xmlLookupService.getChildByLocalName(container, localName22);
70679
+ if (!node) {
70680
+ return void 0;
70681
+ }
70682
+ const raw = node["@_val"];
70683
+ if (raw === void 0 || raw === null || raw === "") {
70684
+ return true;
70685
+ }
70686
+ return !(raw === "0" || raw === "false");
70687
+ }
68880
70688
  /**
68881
70689
  * Build the series array from raw OOXML `c:ser` nodes.
68882
70690
  *
@@ -68920,6 +70728,10 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
68920
70728
  );
68921
70729
  const dataLabels = parseSeriesDataLabels(seriesNode, this.xmlLookupService);
68922
70730
  const explosion = parseSeriesExplosion(seriesNode, this.xmlLookupService);
70731
+ const smoothNode = this.xmlLookupService.getChildByLocalName(seriesNode, "smooth");
70732
+ const smooth = smoothNode ? !(smoothNode["@_val"] === "0" || smoothNode["@_val"] === "false") : void 0;
70733
+ const invertNode = this.xmlLookupService.getChildByLocalName(seriesNode, "invertIfNegative");
70734
+ const invertIfNegative = invertNode ? !(invertNode["@_val"] === "0" || invertNode["@_val"] === "false") : void 0;
68923
70735
  return {
68924
70736
  name: seriesName.trim().length > 0 ? seriesName : `Series ${seriesIndex + 1}`,
68925
70737
  values: fallbackValues,
@@ -68930,6 +70742,8 @@ var PptxHandlerRuntime90 = class extends PptxHandlerRuntime89 {
68930
70742
  ...seriesMarker ? { marker: seriesMarker } : {},
68931
70743
  ...dataLabels.length > 0 ? { dataLabels } : {},
68932
70744
  ...explosion !== void 0 ? { explosion } : {},
70745
+ ...invertIfNegative !== void 0 ? { invertIfNegative } : {},
70746
+ ...smooth !== void 0 ? { smooth } : {},
68933
70747
  ...axisId !== void 0 ? { axisId } : {},
68934
70748
  ...seriesChartType ? { seriesChartType } : {}
68935
70749
  };
@@ -69756,6 +71570,8 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
69756
71570
  async buildLoadData(presentationState, slidesWithWarnings, slideMasters) {
69757
71571
  const headerFooter = this.extractHeaderFooter();
69758
71572
  const presentationProperties = await this.parsePresentationProperties();
71573
+ const viewProperties = await this.parseViewProperties();
71574
+ this.loadedViewProperties = viewProperties;
69759
71575
  const customShows = this.parseCustomShows();
69760
71576
  const tableStyleMap = await this.parseTableStyles();
69761
71577
  const embeddedFontList = parseEmbeddedFontList(this.presentationData);
@@ -69785,7 +71601,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
69785
71601
  presentationState.height,
69786
71602
  this.rawSlideWidthEmu,
69787
71603
  this.rawSlideHeightEmu
69788
- ).withNotesDimensions(presentationState.notesWidthEmu, presentationState.notesHeightEmu).withSlides(slidesWithWarnings).withLayoutOptions(this.getLayoutOptions()).withHeaderFooter(headerFooter).withPresentationProperties(presentationProperties).withCustomShows(customShows).withSections(
71604
+ ).withNotesDimensions(presentationState.notesWidthEmu, presentationState.notesHeightEmu).withSlides(slidesWithWarnings).withLayoutOptions(this.getLayoutOptions()).withHeaderFooter(headerFooter).withPresentationProperties(presentationProperties).withViewProperties(viewProperties).withCustomShows(customShows).withSections(
69789
71605
  presentationState.orderedSections.length > 0 ? presentationState.orderedSections : void 0
69790
71606
  ).withWarnings(this.compatibilityService.getWarnings()).withThemeColorMap({ ...this.themeColorMap }).withTheme(this.buildThemeObject()).withThemeOptions(themeOptions.length > 0 ? themeOptions : void 0).withTableStyleMap(tableStyleMap).withEmbeddedFonts(embeddedFonts.length > 0 ? embeddedFonts : void 0).withEmbeddedFontList(embeddedFontList).withMruColors(presentationProperties?.mruColors).withNotesMaster(notesMaster).withHandoutMaster(handoutMaster).withSlideMasters(slideMasters.length > 0 ? slideMasters : void 0).withTags(tags.length > 0 ? tags : void 0).withCustomProperties(customProperties.length > 0 ? customProperties : void 0).withCoreProperties(coreProperties).withAppProperties(appProperties).withHasMacros(this.vbaProjectBin !== null ? true : void 0).withHasDigitalSignatures(this.signatureDetection?.hasSignatures || void 0).withDigitalSignatureCount(
69791
71607
  this.signatureDetection?.signatureCount && this.signatureDetection.signatureCount > 0 ? this.signatureDetection.signatureCount : void 0
@@ -69916,6 +71732,7 @@ var PptxHandlerRuntime94 = class extends PptxHandlerRuntime93 {
69916
71732
  this.customXmlParts = [];
69917
71733
  this.loadedEmbeddedFonts = [];
69918
71734
  this.loadedEmbeddedFontList = void 0;
71735
+ this.loadedViewProperties = void 0;
69919
71736
  this.orderedSlidePaths = [];
69920
71737
  this.zip = null;
69921
71738
  }
@@ -70261,6 +72078,7 @@ var PptxHandlerRuntime95 = class _PptxHandlerRuntime extends PptxHandlerRuntime9
70261
72078
  });
70262
72079
  this.mediaDataParser = new PptxMediaDataParser({
70263
72080
  slideRelsMap: this.slideRelsMap,
72081
+ externalRelsMap: this.externalRelsMap,
70264
72082
  resolvePath: (base, relative) => this.resolvePath(base, relative),
70265
72083
  getPathExtension: (pathValue) => this.getPathExtension(pathValue)
70266
72084
  });
@@ -70872,11 +72690,13 @@ function parseDrawingColorChoice(colorNode) {
70872
72690
  }
70873
72691
  if (colorNode["a:scrgbClr"]) {
70874
72692
  const scrgb = colorNode["a:scrgbClr"];
70875
- const red = parseDrawingPercent(scrgb["@_r"]);
70876
- const green = parseDrawingPercent(scrgb["@_g"]);
70877
- const blue = parseDrawingPercent(scrgb["@_b"]);
72693
+ const red = parseDrawingFraction(scrgb["@_r"]);
72694
+ const green = parseDrawingFraction(scrgb["@_g"]);
72695
+ const blue = parseDrawingFraction(scrgb["@_b"]);
70878
72696
  if (red !== void 0 && green !== void 0 && blue !== void 0) {
70879
- const base = `#${toHex(red * 255)}${toHex(green * 255)}${toHex(blue * 255)}`;
72697
+ const base = `#${toHex(scrgbLinearToSrgb8(red))}${toHex(scrgbLinearToSrgb8(green))}${toHex(
72698
+ scrgbLinearToSrgb8(blue)
72699
+ )}`;
70880
72700
  return applyDrawingColorTransforms(base, scrgb);
70881
72701
  }
70882
72702
  }
@@ -70961,7 +72781,7 @@ function parseDrawingColorOpacity(colorNode) {
70961
72781
  const alphaMod = parseDrawingPercent(
70962
72782
  colorChoice["a:alphaMod"]?.["@_val"]
70963
72783
  );
70964
- const alphaOff = parseDrawingPercent(
72784
+ const alphaOff = parseDrawingFraction(
70965
72785
  colorChoice["a:alphaOff"]?.["@_val"]
70966
72786
  );
70967
72787
  if (alpha === void 0 && alphaMod === void 0 && alphaOff === void 0) {
@@ -72951,9 +74771,9 @@ function removeEmptyDataPoint(series, pointIndex) {
72951
74771
  }
72952
74772
  }
72953
74773
  }
72954
- var EMU_PER_PIXEL = 9525;
74774
+ var EMU_PER_PIXEL2 = 9525;
72955
74775
  function pxToEmu(px2) {
72956
- return Math.round(px2 * EMU_PER_PIXEL);
74776
+ return Math.round(px2 * EMU_PER_PIXEL2);
72957
74777
  }
72958
74778
  function placeholderSpXml(ph, shapeId) {
72959
74779
  const name = ph.name ?? `${ph.type.charAt(0).toUpperCase() + ph.type.slice(1)} Placeholder ${shapeId - 1}`;
@@ -74707,7 +76527,7 @@ var GroupBuilder = class _GroupBuilder {
74707
76527
  // src/core/builders/sdk/units.ts
74708
76528
  var PPI = 96;
74709
76529
  var POINTS_PER_INCH = 72;
74710
- var EMU_PER_PIXEL2 = 9525;
76530
+ var EMU_PER_PIXEL3 = 9525;
74711
76531
  var EMU_PER_INCH = 914400;
74712
76532
  var EMU_PER_POINT = 12700;
74713
76533
  function inches(value) {
@@ -74723,10 +76543,10 @@ function pt(value) {
74723
76543
  return Math.round(value / POINTS_PER_INCH * PPI);
74724
76544
  }
74725
76545
  function emuToPixels(emu) {
74726
- return Math.round(emu / EMU_PER_PIXEL2);
76546
+ return Math.round(emu / EMU_PER_PIXEL3);
74727
76547
  }
74728
76548
  function pixelsToEmu(px2) {
74729
- return Math.round(px2 * EMU_PER_PIXEL2);
76549
+ return Math.round(px2 * EMU_PER_PIXEL3);
74730
76550
  }
74731
76551
  function inchesToEmu(value) {
74732
76552
  return Math.round(value * EMU_PER_INCH);
@@ -85034,4 +86854,4 @@ var SvgExporter = class _SvgExporter {
85034
86854
  * `<p:extLst>` (optional)
85035
86855
  */
85036
86856
 
85037
- export { ALL_ANIMATION_PRESETS, BLIP_FILL_ORDER, CLOUD_CALLOUT_TAIL_COUNT, CLOUD_LOBE_COUNT, COLOR_MAP_ALIAS_KEYS, CONNECTOR_ARROW_OPTIONS, CONNECTOR_GEOMETRY_OPTIONS, ChartBuilder, ConnectorBuilder, ConnectorXmlFactory, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_COLOR_MAP, DEFAULT_FILL_COLOR, DEFAULT_FONT_FAMILY, DEFAULT_MAX_UNCOMPRESSED_BYTES, DEFAULT_SCHEME_COLOR_MAP, DEFAULT_STROKE_COLOR, DEFAULT_TEXT_COLOR, DEFAULT_TEXT_FONT_SIZE, DIGEST_ALGORITHM_TO_HASH, DIGEST_ALGORITHM_TO_WEB_CRYPTO, DIGITAL_SIGNATURE_ORIGIN_REL_TYPE, DIGITAL_SIGNATURE_REL_TYPE, DataIntegrityError, DocumentConverter, EFFECT_LST_ORDER, ELEMENT_FIELD_KIND, EMPHASIS_PRESETS, EMU_PER_INCH, EMU_PER_PIXEL2 as EMU_PER_PIXEL, EMU_PER_POINT, EMU_PER_PX, ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV, ENTERPRISE_REQUIRE_REVOCATION_ENV, ENTERPRISE_REQUIRE_TIMESTAMP_ENV, ENTERPRISE_TRUST_ROOTS_FILE_ENV, ENTERPRISE_TRUST_ROOTS_PEM_ENV, ENTRANCE_PRESETS, EXIT_PRESETS, EncryptedFileError, FONT_SUBSTITUTION_MAP, FreeformPathBuilder, GroupBuilder, ImageBuilder, IncorrectPasswordError, MAX_TABLE_DIMENSION, MAX_ZIP_ENTRY_COUNT, MIN_ELEMENT_SIZE, MIN_TABLE_DIMENSION, MOTION_PATH_PRESETS, MediaBuilder, MediaContext, MediaGraphicFrameXmlFactory, OOXML_TO_PRESET_EMPH, OOXML_TO_PRESET_ENTR, OOXML_TO_PRESET_EXIT, OPC_RELATIONSHIP_TRANSFORM, OPENXML_COVERAGE, OPENXML_SCHEMA_CONSTRUCT_IDS, OPENXML_STRICT_SCHEMA_CONSTRUCT_IDS, OPENXML_TRANSITIONAL_SCHEMA_CONSTRUCT_IDS, Ole2ParseError, P14_GUIDE_URI, P15_GUIDE_URI, PANOSE_FAMILY_MAP, PANOSE_MONOSPACE_PROPORTION, PANOSE_SANS_SERIF_STYLES, PANOSE_WEIGHT_MAP, POWERPOINT_PRESENCE_KEY, PPTX_VIEWER_MANIFEST_NS, PRESET_COLOR_MAP, PRESET_SHAPE_CATEGORY_LABELS, PRESET_SHAPE_CLIP_PATHS, PRESET_SHAPE_DEFINITIONS, PRESET_SHAPE_GEOMETRY_TABLE, PRESET_TO_OOXML, PictureXmlFactory, PptxAnimationWriteService, PptxColorStyleCodec, PptxCommentAuthorsXmlFactory, PptxCommentXmlFactoryProvider, PptxCompatibilityService, PptxConnectorParser, PptxContentTypesBuilder, PptxDocumentPropertiesUpdater, PptxEditorAnimationService, PptxElementTransformUpdater, PptxElementXmlBuilder, PptxGraphicFrameParser, PptxHandler, PptxHandlerRuntime96 as PptxHandlerRuntime, PptxHandlerRuntimeFactory, PptxLoadDataBuilder, PptxMarkdownConverter, PptxMediaDataParser, PptxNativeAnimationService, PptxPresentationSaveBuilder, PptxPresentationSlidesReconciler, PptxRuntimeDependencyFactory, PptxSaveConstantsFactory, PptxSaveState as PptxSaveSession, PptxSaveStateBuilder as PptxSaveSessionBuilder, PptxSaveState, PptxSaveStateBuilder, PptxShapeIdValidator, PptxShapeStyleExtractor, PptxSlideBackgroundBuilder, PptxSlideBuilder, PptxSlideCommentPartWriter, PptxSlideCommentsXmlFactory, PptxSlideElementsBuilder, PptxSlideLoaderService, PptxSlideMediaRelationshipBuilder, PptxSlideNotesBuilder, PptxSlideNotesPartUpdater, PptxSlideRelationshipRegistry, PptxSlideTransitionService, PptxTableDataParser, PptxTemplateBackgroundService, PptxXmlBuilder, PptxXmlFactoryProvider, PptxXmlLookupService, Presentation, PresentationBuilder, SHAPE_TREE_ELEMENT_TAGS, SLIDE_FIELD_KIND, SMART_ART_DEFINITION_PARTS, SP_PR_ORDER, STROKE_DASH_OPTIONS, SUPPORTED_XML_CANON_TRANSFORMS, SWITCHABLE_LAYOUT_TYPES, SYSTEM_COLOR_MAP, ShapeBuilder, SlideBuilder, SlideProcessor, SlideSizes, SvgExporter, TC_PR_BORDERS_ORDER, THEME_COLOR_SCHEME_KEYS, THEME_PRESETS, TRANSITION_VALID_DIRECTIONS, TableBuilder, TextBuilder, TextShapeXmlFactory, ThemePresets, VML_SHAPE_TAGS, XMLDSIG_NS, XML_TRANSFORM_ENVELOPED_SIGNATURE, ZipBombError, addChartCategory, addChartSeries, addSection, addSmartArtNode, addSmartArtNodeAsChild, applyBubbleChartOptions, applyChartLayouts, applyChartManualLayout, applyChartUpDownBars, applyCustomShows, applyDiagramRelationshipIds, applyDrawingColorTransforms, applyDrawingLineDash, applyDrawingMediaReference, applyKinsokuToXml, applySections, applySmartArtConstraintRules, applySmartArtLayoutDefinition, applyTableCellTextAndStyle, applyTemplate, applyThemeOverrideToSlide, applyThemeToData, areNamespacesSupported, buildCalloutLeaderLineSvgPath, buildClrMapOverrideXml, buildFontFamilyString, buildGuideListExtension, buildInkMlContent, buildLinkedTextBoxChains, buildOle2, buildSingleEffectNode, buildSrgbColorChoice, buildThemeColorMap, catmullRomToBezier, chartDataAddCategory, chartDataAddSeries, chartDataChangeType, chartDataRemoveCategory, chartDataRemoveSeries, chartDataUpdatePoint, checkBlankSlide, checkComplexTables, checkDuplicateTitles, checkLowContrast, checkMissingAltText, checkMissingSlideTitle, checkPresentation, clampUnitInterval, classifyPanose, cloneElement, cloneShapeStyle, cloneSlide, cloneTemplateElementsBySlideId, cloneTextStyle, cloneXmlObject, cm, cmToEmu, colorWithOpacity, colorsEqual, combineShapes, computeContrastRatio, computeCycleLayout, computeDetailStatus, computeDigestBase64 as computeDigestBase64WebCrypto, computeHierarchyLayout, computeLinearLayout, computeMatrixLayout, computePyramidLayout, computeSmartArtLayout, computeSnakeLayout, computeVerificationStatus, convertXmlToStrict, createArrayBufferCopy, createBuiltinVariables, createChartElement, createConnectorElement, createDefaultPptxHandlerRuntime, createEditorId, createFreeformElement, createGroupElement, createImageElement, createLayout, createLayouts, createMediaElement, createModifyVerifier, createPptxSaveConstants, createShapeElement, createTableCellXml, createTableElement, createTableGraphicFrameRawXml, createTemplateConnectorRawXml, createTemplateShapeRawXml, createTextElement, createUniformTextSegments, dataUrlToMediaBytes, decodeOle10Native, decodeXmlEntities, decomposeSmartArt, decryptPptx, demoteSmartArtNode, deobfuscateFont, deriveOutputPath, detectDigitalSignatures, detectFileFormat, detectFontFormat, detectOleObjectType, detectStrictConformance, diffPresentations, diffSlides, distributeSegmentsAcrossChain, douglasPeucker, duplicateElement, duplicateSlide, elementActionToPptxAction, elementHasAction, emuToPixels, encryptPptx, ensureArrayValue, escapeXmlAttr, escapeXmlText, estimateTextBoxCapacity, evaluateGeometryPaths, evaluateGuides, evaluatePresetShape, extractAllTagText, extractColorChoiceXml, extractFirstTagText, extractGraphicBuilds, extractGuidFromPartName, extractModel3DTransform, extractStyleReferenceColorXml, extractTagAttribute, fetchUrlToBytes, findCustomShow, findLayoutByName, findLayoutByType, findOpenXmlCoverage, findPlaceholders, findText, formatCommentTimestamp, fragmentShapes, generateFontGuid, generateLayoutXml, generateMediaFilename, getAdjustmentAwareClipPath, getAdjustmentAwareShapeClipPath, getAnimationPresetInfo, getCalloutLeaderLineGeometry, getCalloutTier, getCalloutViewBoxBounds, getCloudCalloutClipPath, getCloudClipPath, getCloudPathForRendering, getCommentMarkerPosition, getConnectorAdjustment, getConnectorPathGeometry, getCssBorderDashStyle, getCustomShowNames, getCustomShowPositionLabel, getDirectory, getElementLabel, getElementTextContent, getElementTransform, getImageMaskStyle, getLinkedTextBoxSegments, getNativeAnimationPresetMetadata, getOleObjectTypeLabel, getPanoseWeight, getPresetShapeClipPath, getPresetsByCategory, getRoundRectRadiusPx, getSectionForSlide, getSectionSlideRange, getShapeClipPath, getShapeClipPathFromPreset, getShapeType, getSignaturePathsToStrip, getSubstituteFontFamily, getSubstituteFonts, getSupportedNamespaces, getSvgStrokeDasharray, getTextCompensationTransform, getThemePreset, getZoomElements, getZoomTargetSlideIndexes, guidToKey, guideEmuToPx, guidePxToEmu, hasDirectSubstitution, hasNonTrivialOverride, hasShapeProperties, hasTextProperties, hexToRgbChannels, hslToRgb, inches, inchesToEmu, inferOleExtensionFromTarget, interpolateShapeGeometry, intersectPolygons, intersectShapes, intersectSvgPaths, isAlternateContentChoiceSupported, isAlternateContentChoiceXmlSupported, isCalloutShape, isConnectorElement, isEditableTextElement, isImageLikeElement, isInkElement, isNamespaceSupported, isOle2CompoundFile, isShapeElement, isStrictNamespaceUri, isSummaryZoomSlide, isSwitchableLayoutType, isTemplateElement, isTextElement, isTransitionalNamespaceUri, isValidBase64, isXmlNode, isZoomElement, isZoomElement2 as isZoomElementUtil, layoutEngineShapesToDrawingShapes, listUnassessedOpenXmlCoverage, lookupPresetShape, mailMerge, mergePresentation, mergeShapes, mergeStyleParts, mergeThemeColorOverride, mimeTypeForOleFile, mm, moveSlidesToSection, navigateCustomShow, normalizeHexColor, normalizeNamespaceUri, normalizePartPath, normalizePath, normalizeStrictXml, normalizeStrokeDashType, obfuscateFont, oleBytesToDataUrl, ooxmlArcToSvg, ooxmlToPresetName, orderedXmlKey, parseActiveXControlsFromSlide, parseAdjustmentValues, parseBodyPrBooleanAttrs, parseBubbleChartOptions, parseChart3DSurfaces, parseChartAxes, parseChartLayouts, parseChartManualLayout, parseChartUpDownBars, parseCondition, parseConditionList, parseCustomShows, parseCxChartSeries, parseDataTable, parseDataUrlToBytes, parseDiagramRelationshipIds, parseDrawingColor, parseDrawingColorChoice, parseDrawingColorOpacity, parseDrawingFraction, parseDrawingHueDegrees, parseDrawingLineDash, parseDrawingMediaReference, parseDrawingPercent, parseEmbeddedXlsx, parseGuideDefinitions, parseHexColor, parseInkMlContent, parseKinsoku, parseLayoutDefinition, parseLineStyle, parseMarker, parseOle2, parsePanoseBytes, parsePanoseString, parsePresentationDrawingGuides, parseSeriesDataLabels, parseSeriesDataPoints, parseSeriesErrBars, parseSeriesExplosion, parseSeriesTrendlines, parseShapeProps, parseSignatureXml, parseSlideDrawingGuides, parseSmartArtColorStyleLabels, parseSmartArtConstraintRules, parseSmartArtDefinitionHeaderList, parseSmartArtDefinitionMetadata, parseSmartArtLayoutDefinition, parseSmartArtQuickStyleLabels, parseStructuredCustomGeometry, parseSvgPath, parseTimeTargetElement, parseVmlElement, parseVmlElements, pixelsToEmu, polygonsToSvgPath, pptxActionToElementAction, promoteSmartArtNode, pt, reResolveSlideColors, readFileAsDataUrl, rebuildTableStructureInRawXml, reconcileAnimationTargets, reflowSmartArtLayout, relativeLuminance, relayoutSmartArt, remapEditorAnimationsToShapeIds, removeChartCategory, removeChartSeries, removeSection, removeSmartArtNode, reorderObjectKeys, reorderSections, reorderSmartArtNode, reorderSmartArtNodeToIndex, repairPptx, replaceShapeGeometry, replaceText, replaceTextInSlide, replaceWithCustomGeometry, resetCloneIdCounter, resetDecomposeCounter, resetIdCounter, resetSectionIdCounter, resetSmartArtEditCounter, resolveCoordinate, resolveCustomShowSlideIndices, resolveLayoutDisplayName, resolveModel3DMimeType, resolveReferenceUriToPart, resolveTableCellStyle, rgbToHsl, selectAlternateContentBranch, serializeColorChoice, serializeCondition, serializeConditionList, serializeGraphicBuild, serializeSmartArtDefinitionHeaderList, serializeSvgPath, serializeTimeTargetElement, setChartAxis, setChartAxisGridlineStyle, setChartAxisLogScale, setChartAxisTitleStyle, setChartCategories, setChartDataLabels, setChartDataPointExplosion, setChartDataPointFill, setChartDataPointLabel, setChartDataPointMarker, setChartGrouping, setChartLegend, setChartSeriesChartType, setChartSeriesColor, setChartSeriesErrorBars, setChartSeriesMarker, setChartSeriesTrendline, setChartTitle, setChartType, setElementLocked, setSmartArtNodeStyle, shouldRenderFallbackLabel, shouldReturnToZoomSlide, stripParentDirSegments, stripXmlOrderSuffix, subtractPolygons, subtractShapes, subtractSvgPaths, summarizeOpenXmlCoverage, summarizeOpenXmlCoverageByVocabulary, svgPathToPolygons, switchSmartArtLayout, themeColorSchemesEqual, toHex, toStrictNamespaceUri, unionPolygons, unionShapes, unionSvgPaths, unwrapAlternateContent, unwrapOleEmbedding, updateCellTextInRawXml, updateCellTextStyleInRawXml, updateChartDataPoint, updateChartSeriesValues, updateMergeAttrsInRawXml, updateSmartArtNodeText, validatePptx, validateSmartArtColorStyleLabels, validateSmartArtConstraintRules, validateSmartArtDefinitionHeaderList, validateSmartArtDefinitionMetadata, validateSmartArtLayoutDefinition, verifyModifyPassword, verifyPassword, verifySignatureDigests, withThemePlaceholderColor, writeBodyPrBooleanAttrs, xmlAttr, xmlAttrBool, xmlAttrNumber, xmlChild, xmlChildren, xmlPath, xmlText };
86857
+ export { ALL_ANIMATION_PRESETS, BLIP_FILL_ORDER, CLOUD_CALLOUT_TAIL_COUNT, CLOUD_LOBE_COUNT, COLOR_MAP_ALIAS_KEYS, CONNECTOR_ARROW_OPTIONS, CONNECTOR_GEOMETRY_OPTIONS, ChartBuilder, ConnectorBuilder, ConnectorXmlFactory, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_COLOR_MAP, DEFAULT_FILL_COLOR, DEFAULT_FONT_FAMILY, DEFAULT_MAX_UNCOMPRESSED_BYTES, DEFAULT_SCHEME_COLOR_MAP, DEFAULT_STROKE_COLOR, DEFAULT_TEXT_COLOR, DEFAULT_TEXT_FONT_SIZE, DIGEST_ALGORITHM_TO_HASH, DIGEST_ALGORITHM_TO_WEB_CRYPTO, DIGITAL_SIGNATURE_ORIGIN_REL_TYPE, DIGITAL_SIGNATURE_REL_TYPE, DataIntegrityError, DocumentConverter, EFFECT_LST_ORDER, ELEMENT_FIELD_KIND, EMPHASIS_PRESETS, EMU_PER_INCH, EMU_PER_PIXEL3 as EMU_PER_PIXEL, EMU_PER_POINT, EMU_PER_PX, ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV, ENTERPRISE_REQUIRE_REVOCATION_ENV, ENTERPRISE_REQUIRE_TIMESTAMP_ENV, ENTERPRISE_TRUST_ROOTS_FILE_ENV, ENTERPRISE_TRUST_ROOTS_PEM_ENV, ENTRANCE_PRESETS, EXIT_PRESETS, EncryptedFileError, FONT_SUBSTITUTION_MAP, FreeformPathBuilder, GroupBuilder, ImageBuilder, IncorrectPasswordError, MAX_TABLE_DIMENSION, MAX_ZIP_ENTRY_COUNT, MIN_ELEMENT_SIZE, MIN_TABLE_DIMENSION, MOTION_PATH_PRESETS, MediaBuilder, MediaContext, MediaGraphicFrameXmlFactory, OOXML_TO_PRESET_EMPH, OOXML_TO_PRESET_ENTR, OOXML_TO_PRESET_EXIT, OPC_RELATIONSHIP_TRANSFORM, OPENXML_COVERAGE, OPENXML_SCHEMA_CONSTRUCT_IDS, OPENXML_STRICT_SCHEMA_CONSTRUCT_IDS, OPENXML_TRANSITIONAL_SCHEMA_CONSTRUCT_IDS, Ole2ParseError, P14_GUIDE_URI, P15_GUIDE_URI, PANOSE_FAMILY_MAP, PANOSE_MONOSPACE_PROPORTION, PANOSE_SANS_SERIF_STYLES, PANOSE_WEIGHT_MAP, POWERPOINT_PRESENCE_KEY, PPTX_VIEWER_MANIFEST_NS, PRESET_COLOR_MAP, PRESET_SHAPE_CATEGORY_LABELS, PRESET_SHAPE_CLIP_PATHS, PRESET_SHAPE_DEFINITIONS, PRESET_SHAPE_GEOMETRY_TABLE, PRESET_TO_OOXML, PictureXmlFactory, PptxAnimationWriteService, PptxColorStyleCodec, PptxCommentAuthorsXmlFactory, PptxCommentXmlFactoryProvider, PptxCompatibilityService, PptxConnectorParser, PptxContentTypesBuilder, PptxDocumentPropertiesUpdater, PptxEditorAnimationService, PptxElementTransformUpdater, PptxElementXmlBuilder, PptxGraphicFrameParser, PptxHandler, PptxHandlerRuntime96 as PptxHandlerRuntime, PptxHandlerRuntimeFactory, PptxLoadDataBuilder, PptxMarkdownConverter, PptxMediaDataParser, PptxNativeAnimationService, PptxPresentationSaveBuilder, PptxPresentationSlidesReconciler, PptxRuntimeDependencyFactory, PptxSaveConstantsFactory, PptxSaveState as PptxSaveSession, PptxSaveStateBuilder as PptxSaveSessionBuilder, PptxSaveState, PptxSaveStateBuilder, PptxShapeIdValidator, PptxShapeStyleExtractor, PptxSlideBackgroundBuilder, PptxSlideBuilder, PptxSlideCommentPartWriter, PptxSlideCommentsXmlFactory, PptxSlideElementsBuilder, PptxSlideLoaderService, PptxSlideMediaRelationshipBuilder, PptxSlideNotesBuilder, PptxSlideNotesPartUpdater, PptxSlideRelationshipRegistry, PptxSlideTransitionService, PptxTableDataParser, PptxTemplateBackgroundService, PptxXmlBuilder, PptxXmlFactoryProvider, PptxXmlLookupService, Presentation, PresentationBuilder, SHAPE_TREE_ELEMENT_TAGS, SLIDE_FIELD_KIND, SMART_ART_DEFINITION_PARTS, SP_PR_ORDER, STROKE_DASH_OPTIONS, SUPPORTED_XML_CANON_TRANSFORMS, SWITCHABLE_LAYOUT_TYPES, SYSTEM_COLOR_MAP, ShapeBuilder, SlideBuilder, SlideProcessor, SlideSizes, SvgExporter, TC_PR_BORDERS_ORDER, THEME_COLOR_SCHEME_KEYS, THEME_PRESETS, TRANSITION_VALID_DIRECTIONS, TableBuilder, TextBuilder, TextShapeXmlFactory, ThemePresets, VML_SHAPE_TAGS, XMLDSIG_NS, XML_TRANSFORM_ENVELOPED_SIGNATURE, ZipBombError, addChartCategory, addChartSeries, addSection, addSmartArtNode, addSmartArtNodeAsChild, applyBubbleChartOptions, applyChartLayouts, applyChartManualLayout, applyChartUpDownBars, applyCustomShows, applyDiagramRelationshipIds, applyDrawingColorTransforms, applyDrawingLineDash, applyDrawingMediaReference, applyKinsokuToXml, applySections, applySmartArtConstraintRules, applySmartArtLayoutDefinition, applyTableCellTextAndStyle, applyTemplate, applyThemeOverrideToSlide, applyThemeToData, areNamespacesSupported, buildCalloutLeaderLineSvgPath, buildClrMapOverrideXml, buildFontFamilyString, buildGuideListExtension, buildInkMlContent, buildLinkedTextBoxChains, buildOle2, buildSingleEffectNode, buildSlideReferenceRemap, buildSrgbColorChoice, buildThemeColorMap, catmullRomToBezier, chartDataAddCategory, chartDataAddSeries, chartDataChangeType, chartDataRemoveCategory, chartDataRemoveSeries, chartDataUpdatePoint, checkBlankSlide, checkComplexTables, checkDuplicateTitles, checkLowContrast, checkMissingAltText, checkMissingSlideTitle, checkPresentation, clampUnitInterval, classifyPanose, cloneElement, cloneShapeStyle, cloneSlide, cloneTemplateElementsBySlideId, cloneTextStyle, cloneXmlObject, cm, cmToEmu, colorWithOpacity, colorsEqual, combineShapes, computeContrastRatio, computeCycleLayout, computeDetailStatus, computeDigestBase64 as computeDigestBase64WebCrypto, computeHierarchyLayout, computeLinearLayout, computeMatrixLayout, computePyramidLayout, computeSmartArtLayout, computeSnakeLayout, computeVerificationStatus, convertXmlToStrict, createArrayBufferCopy, createBuiltinVariables, createChartElement, createConnectorElement, createDefaultPptxHandlerRuntime, createEditorId, createFreeformElement, createGroupElement, createImageElement, createLayout, createLayouts, createMediaElement, createModifyVerifier, createPptxSaveConstants, createShapeElement, createTableCellXml, createTableElement, createTableGraphicFrameRawXml, createTemplateConnectorRawXml, createTemplateShapeRawXml, createTextElement, createUniformTextSegments, dataUrlToMediaBytes, decodeOle10Native, decodeXmlEntities, decomposeSmartArt, decryptPptx, demoteSmartArtNode, deobfuscateFont, deriveOutputPath, deriveSlideTitle, deriveSlideTitles, detectDigitalSignatures, detectFileFormat, detectFontFormat, detectOleObjectType, detectStrictConformance, diffPresentations, diffSlides, distributeSegmentsAcrossChain, douglasPeucker, duplicateElement, duplicateSlide, elementActionToPptxAction, elementHasAction, emuToPixels, encryptPptx, ensureArrayValue, escapeXmlAttr, escapeXmlText, estimateTextBoxCapacity, evaluateGeometryPaths, evaluateGuides, evaluatePresetShape, extractAllTagText, extractColorChoiceXml, extractFirstTagText, extractGraphicBuilds, extractGuidFromPartName, extractModel3DTransform, extractStyleReferenceColorXml, extractTagAttribute, fetchUrlToBytes, findCustomShow, findLayoutByName, findLayoutByType, findOpenXmlCoverage, findPlaceholders, findText, formatCommentTimestamp, fragmentShapes, generateFontGuid, generateLayoutXml, generateMediaFilename, getAdjustmentAwareClipPath, getAdjustmentAwareShapeClipPath, getAnimationPresetInfo, getCalloutLeaderLineGeometry, getCalloutTier, getCalloutViewBoxBounds, getCloudCalloutClipPath, getCloudClipPath, getCloudPathForRendering, getCommentMarkerPosition, getConnectorAdjustment, getConnectorPathGeometry, getCssBorderDashStyle, getCustomShowNames, getCustomShowPositionLabel, getDirectory, getElementLabel, getElementTextContent, getElementTransform, getImageMaskStyle, getLinkedTextBoxSegments, getNativeAnimationPresetMetadata, getOleObjectTypeLabel, getPanoseWeight, getPresetShapeClipPath, getPresetsByCategory, getRoundRectRadiusPx, getSectionForSlide, getSectionSlideRange, getShapeClipPath, getShapeClipPathFromPreset, getShapeType, getSignaturePathsToStrip, getSubstituteFontFamily, getSubstituteFonts, getSupportedNamespaces, getSvgStrokeDasharray, getTextCompensationTransform, getThemePreset, getZoomElements, getZoomTargetSlideIndexes, guidToKey, guideEmuToPx, guidePxToEmu, hasDirectSubstitution, hasNonTrivialOverride, hasShapeProperties, hasTextProperties, hexToRgbChannels, hslToRgb, inches, inchesToEmu, inferOleExtensionFromTarget, interpolateShapeGeometry, intersectPolygons, intersectShapes, intersectSvgPaths, isAlternateContentChoiceSupported, isAlternateContentChoiceXmlSupported, isCalloutShape, isConnectorElement, isEditableTextElement, isImageLikeElement, isInkElement, isNamespaceSupported, isOle2CompoundFile, isShapeElement, isStrictNamespaceUri, isSummaryZoomSlide, isSwitchableLayoutType, isTemplateElement, isTextElement, isTransitionalNamespaceUri, isValidBase64, isXmlNode, isZoomElement, isZoomElement2 as isZoomElementUtil, layoutEngineShapesToDrawingShapes, listUnassessedOpenXmlCoverage, lookupPresetShape, mailMerge, mergePresentation, mergeShapes, mergeStyleParts, mergeThemeColorOverride, mimeTypeForOleFile, mm, moveSlidesToSection, navigateCustomShow, normalizeHexColor, normalizeNamespaceUri, normalizePartPath, normalizePath, normalizeStrictXml, normalizeStrokeDashType, obfuscateFont, oleBytesToDataUrl, ooxmlArcToSvg, ooxmlToPresetName, orderedXmlKey, parseActiveXControlsFromSlide, parseAdjustmentValues, parseBodyPrBooleanAttrs, parseBubbleChartOptions, parseChart3DSurfaces, parseChartAxes, parseChartLayouts, parseChartManualLayout, parseChartUpDownBars, parseCondition, parseConditionList, parseCustomShows, parseCxChartSeries, parseDataTable, parseDataUrlToBytes, parseDiagramRelationshipIds, parseDrawingColor, parseDrawingColorChoice, parseDrawingColorOpacity, parseDrawingFraction, parseDrawingHueDegrees, parseDrawingLineDash, parseDrawingMediaReference, parseDrawingPercent, parseEmbeddedXlsx, parseGuideDefinitions, parseHexColor, parseInkMlContent, parseKinsoku, parseLayoutDefinition, parseLineStyle, parseMarker, parseOle2, parsePanoseBytes, parsePanoseString, parsePresentationDrawingGuides, parseSeriesDataLabels, parseSeriesDataPoints, parseSeriesErrBars, parseSeriesExplosion, parseSeriesTrendlines, parseShapeProps, parseSignatureXml, parseSlideDrawingGuides, parseSmartArtColorStyleLabels, parseSmartArtConstraintRules, parseSmartArtDefinitionHeaderList, parseSmartArtDefinitionMetadata, parseSmartArtLayoutDefinition, parseSmartArtQuickStyleLabels, parseStructuredCustomGeometry, parseSvgPath, parseTimeTargetElement, parseVmlElement, parseVmlElements, pixelsToEmu, polygonsToSvgPath, pptxActionToElementAction, promoteSmartArtNode, pt, reResolveSlideColors, readFileAsDataUrl, rebuildTableStructureInRawXml, reconcileAnimationTargets, reflowSmartArtLayout, relativeLuminance, relayoutSmartArt, remapEditorAnimationsToShapeIds, removeChartCategory, removeChartSeries, removeSection, removeSmartArtNode, reorderObjectKeys, reorderSections, reorderSmartArtNode, reorderSmartArtNodeToIndex, repairPptx, replaceShapeGeometry, replaceText, replaceTextInSlide, replaceWithCustomGeometry, resetCloneIdCounter, resetDecomposeCounter, resetIdCounter, resetSectionIdCounter, resetSmartArtEditCounter, resolveCoordinate, resolveCustomShowSlideIndices, resolveLayoutDisplayName, resolveModel3DMimeType, resolveReferenceUriToPart, resolveTableCellStyle, rgbToHsl, selectAlternateContentBranch, serializeColorChoice, serializeCondition, serializeConditionList, serializeGraphicBuild, serializeSmartArtDefinitionHeaderList, serializeSvgPath, serializeTimeTargetElement, setChartAxis, setChartAxisGridlineStyle, setChartAxisLogScale, setChartAxisTitleStyle, setChartCategories, setChartDataLabels, setChartDataPointExplosion, setChartDataPointFill, setChartDataPointLabel, setChartDataPointMarker, setChartGrouping, setChartLegend, setChartSeriesChartType, setChartSeriesColor, setChartSeriesErrorBars, setChartSeriesMarker, setChartSeriesTrendline, setChartTitle, setChartType, setElementLocked, setSmartArtNodeStyle, shouldRenderFallbackLabel, shouldReturnToZoomSlide, stripParentDirSegments, stripXmlOrderSuffix, subtractPolygons, subtractShapes, subtractSvgPaths, summarizeOpenXmlCoverage, summarizeOpenXmlCoverageByVocabulary, svgPathToPolygons, switchSmartArtLayout, themeColorSchemesEqual, toHex, toStrictNamespaceUri, unionPolygons, unionShapes, unionSvgPaths, unwrapAlternateContent, unwrapOleEmbedding, updateCellTextInRawXml, updateCellTextStyleInRawXml, updateChartDataPoint, updateChartSeriesValues, updateMergeAttrsInRawXml, updateSmartArtNodeText, validatePptx, validateSmartArtColorStyleLabels, validateSmartArtConstraintRules, validateSmartArtDefinitionHeaderList, validateSmartArtDefinitionMetadata, validateSmartArtLayoutDefinition, verifyModifyPassword, verifyPassword, verifySignatureDigests, withThemePlaceholderColor, writeBodyPrBooleanAttrs, xmlAttr, xmlAttrBool, xmlAttrNumber, xmlChild, xmlChildren, xmlPath, xmlText };