pptx-viewer-core 1.6.6 → 1.6.8

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/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@ All notable changes to this project are documented here.
4
4
  This file is generated from [Conventional Commits](https://www.conventionalcommits.org)
5
5
  by [git-cliff](https://git-cliff.org); do not edit it by hand.
6
6
 
7
+ ## [1.6.7](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.6.7) - 2026-07-19
8
+
9
+ ## [1.6.6](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.6.6) - 2026-07-18
10
+
7
11
  ## [1.6.5](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.6.5) - 2026-07-18
8
12
 
9
13
  ### Documentation
package/dist/cli/index.js CHANGED
@@ -2713,14 +2713,52 @@ function extractSourceOrders(xml) {
2713
2713
  }
2714
2714
  return orders;
2715
2715
  }
2716
+ function ensureArrayLocal(value) {
2717
+ return Array.isArray(value) ? value : value === void 0 ? [] : [value];
2718
+ }
2719
+ function countsSignature(counts) {
2720
+ return [...counts.entries()].sort((a, b) => a[0] < b[0] ? -1 : 1).map(([name, count]) => `${name}:${count}`).join(",");
2721
+ }
2722
+ function pathSignature(path2) {
2723
+ const counts = /* @__PURE__ */ new Map();
2724
+ for (const key of Object.keys(path2)) {
2725
+ const name = localName(key);
2726
+ if (!PATH_COMMANDS.has(name)) {
2727
+ continue;
2728
+ }
2729
+ counts.set(name, (counts.get(name) ?? 0) + ensureArrayLocal(path2[key]).length);
2730
+ }
2731
+ return countsSignature(counts);
2732
+ }
2733
+ function orderSignature(order) {
2734
+ const counts = /* @__PURE__ */ new Map();
2735
+ for (const name of order) {
2736
+ counts.set(name, (counts.get(name) ?? 0) + 1);
2737
+ }
2738
+ return countsSignature(counts);
2739
+ }
2716
2740
  function annotateCustomGeometryCommandOrder(xml, parsed) {
2717
2741
  const orders = extractSourceOrders(xml);
2718
2742
  if (orders.length === 0) {
2719
2743
  return;
2720
2744
  }
2721
2745
  const paths = collectParsedPaths(parsed);
2722
- for (let index = 0; index < Math.min(paths.length, orders.length); index++) {
2723
- commandOrder.set(paths[index], orders[index]);
2746
+ const ordersBySignature = /* @__PURE__ */ new Map();
2747
+ for (const order of orders) {
2748
+ const signature = orderSignature(order);
2749
+ const bucket = ordersBySignature.get(signature);
2750
+ if (bucket) {
2751
+ bucket.push(order);
2752
+ } else {
2753
+ ordersBySignature.set(signature, [order]);
2754
+ }
2755
+ }
2756
+ for (const path2 of paths) {
2757
+ const bucket = ordersBySignature.get(pathSignature(path2));
2758
+ const order = bucket?.shift();
2759
+ if (order) {
2760
+ commandOrder.set(path2, order);
2761
+ }
2724
2762
  }
2725
2763
  }
2726
2764
  function orderedPathCommandEntries(path2, ensureArray16) {
@@ -50730,7 +50768,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50730
50768
  pointsToPixels(points3) {
50731
50769
  return points3 * (96 / 72);
50732
50770
  }
50733
- parseParagraphSpacingPx(spacingNode) {
50771
+ parseParagraphSpacingPx(spacingNode, basisFontSizePx) {
50734
50772
  if (!spacingNode) {
50735
50773
  return void 0;
50736
50774
  }
@@ -50741,6 +50779,13 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50741
50779
  if (Number.isFinite(spacingPointsRaw)) {
50742
50780
  return this.pointsToPixels(spacingPointsRaw / 100);
50743
50781
  }
50782
+ const spacingPercentRaw = Number.parseInt(
50783
+ String(spacingNode["a:spcPct"]?.["@_val"] || ""),
50784
+ 10
50785
+ );
50786
+ if (Number.isFinite(spacingPercentRaw) && typeof basisFontSizePx === "number" && basisFontSizePx > 0) {
50787
+ return spacingPercentRaw / 1e5 * basisFontSizePx;
50788
+ }
50744
50789
  return void 0;
50745
50790
  }
50746
50791
  parseLineSpacingMultiplier(lineSpacingNode) {
@@ -50820,7 +50865,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50820
50865
 
50821
50866
  // src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
50822
50867
  var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50823
- resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
50868
+ resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath, effectiveLevelStyles) {
50824
50869
  if (!paragraph) {
50825
50870
  return null;
50826
50871
  }
@@ -50856,11 +50901,8 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50856
50901
  }
50857
50902
  }
50858
50903
  if (!resolvedBulletProps) {
50859
- if (isBodyPlaceholder) {
50860
- const presentationLevelStyle = this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1];
50861
- return this.createBulletInfoFromLevelStyle(presentationLevelStyle, paragraphIndex);
50862
- }
50863
- return null;
50904
+ const fallbackLevelStyle = effectiveLevelStyles?.[normalizedLevel - 1] ?? effectiveLevelStyles?.[-1] ?? (isBodyPlaceholder ? this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1] : void 0);
50905
+ return this.createBulletInfoFromLevelStyle(fallbackLevelStyle, paragraphIndex);
50864
50906
  }
50865
50907
  const buFont = resolvedBulletProps["a:buFont"];
50866
50908
  const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
@@ -51350,16 +51392,21 @@ var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
51350
51392
  textStyle.align = paraAlign;
51351
51393
  }
51352
51394
  }
51395
+ const spacingBasisPx = typeof textStyle.fontSize === "number" ? textStyle.fontSize : void 0;
51353
51396
  if (textStyle.paragraphSpacingBefore === void 0) {
51354
51397
  const spacingBefore = this.parseParagraphSpacingPx(
51355
- pPr?.["a:spcBef"]
51398
+ pPr?.["a:spcBef"],
51399
+ spacingBasisPx
51356
51400
  );
51357
51401
  if (spacingBefore !== void 0) {
51358
51402
  textStyle.paragraphSpacingBefore = spacingBefore;
51359
51403
  }
51360
51404
  }
51361
51405
  if (textStyle.paragraphSpacingAfter === void 0) {
51362
- const spacingAfter = this.parseParagraphSpacingPx(pPr?.["a:spcAft"]);
51406
+ const spacingAfter = this.parseParagraphSpacingPx(
51407
+ pPr?.["a:spcAft"],
51408
+ spacingBasisPx
51409
+ );
51363
51410
  if (spacingAfter !== void 0) {
51364
51411
  textStyle.paragraphSpacingAfter = spacingAfter;
51365
51412
  }
@@ -51533,7 +51580,8 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
51533
51580
  ctx.txBody,
51534
51581
  ctx.inheritedTxBody,
51535
51582
  isBodyPlaceholder,
51536
- ctx.slidePath
51583
+ ctx.slidePath,
51584
+ ctx.effectiveLevelStyles
51537
51585
  );
51538
51586
  if (paragraphBulletInfo && !paragraphBulletInfo.none) {
51539
51587
  let bulletText;
@@ -53136,6 +53184,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53136
53184
  if (!normalized) {
53137
53185
  return void 0;
53138
53186
  }
53187
+ const canon = (key) => key.toLowerCase() === "folhlink" ? "folHlink" : key;
53139
53188
  if (normalized === "phclr") {
53140
53189
  const injected = this.themeColorMap["phclr"];
53141
53190
  if (injected) {
@@ -53145,17 +53194,18 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53145
53194
  }
53146
53195
  const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
53147
53196
  if (overrideMap) {
53148
- const remapped = overrideMap[normalized];
53197
+ const remapped = overrideMap[canon(normalized)];
53149
53198
  if (remapped) {
53150
- return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
53199
+ const target = canon(remapped);
53200
+ return this.themeColorMap[target] || this.getDefaultSchemeColorMap()[target];
53151
53201
  }
53152
53202
  } else {
53153
53203
  const defaultAliasTarget = DEFAULT_CLR_MAP_ALIAS[normalized];
53154
53204
  if (defaultAliasTarget) {
53155
- return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53205
+ return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53156
53206
  }
53157
53207
  }
53158
- return this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53208
+ return this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53159
53209
  }
53160
53210
  normalizeStrokeDashType(value) {
53161
53211
  const normalized = String(value ?? "").trim();
@@ -53444,6 +53494,40 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53444
53494
  }
53445
53495
  return void 0;
53446
53496
  }
53497
+ /**
53498
+ * Reuse the cached parse of a layout XML part, parsing (and caching) on a
53499
+ * miss. Background resolution runs per slide but the layout/master parts are
53500
+ * large (a themed master can be ~200 KB); re-parsing them for every slide
53501
+ * dominated load time, so share the same parsed object `getLayoutElements`
53502
+ * already populated.
53503
+ */
53504
+ async resolveCachedLayoutXml(layoutPath) {
53505
+ const cached = this.layoutXmlMap.get(layoutPath);
53506
+ if (cached) {
53507
+ return cached;
53508
+ }
53509
+ const xml = await this.zip.file(layoutPath)?.async("string");
53510
+ if (!xml) {
53511
+ return void 0;
53512
+ }
53513
+ const parsed = this.parser.parse(xml);
53514
+ this.layoutXmlMap.set(layoutPath, parsed);
53515
+ return parsed;
53516
+ }
53517
+ /** Reuse the cached parse of a master XML part, parsing (and caching) on a miss. */
53518
+ async resolveCachedMasterXml(masterPath) {
53519
+ const cached = this.masterXmlMap.get(masterPath);
53520
+ if (cached) {
53521
+ return cached;
53522
+ }
53523
+ const xml = await this.zip.file(masterPath)?.async("string");
53524
+ if (!xml) {
53525
+ return void 0;
53526
+ }
53527
+ const parsed = this.parser.parse(xml);
53528
+ this.masterXmlMap.set(masterPath, parsed);
53529
+ return parsed;
53530
+ }
53447
53531
  async getMasterBackgroundImage(layoutPath) {
53448
53532
  const layoutRels = this.slideRelsMap.get(layoutPath);
53449
53533
  if (!layoutRels) {
@@ -53454,9 +53538,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53454
53538
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53455
53539
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53456
53540
  try {
53457
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53458
- if (masterXmlStr) {
53459
- const masterXmlObj = this.parser.parse(masterXmlStr);
53541
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53542
+ if (masterXmlObj) {
53460
53543
  const masterRelsPath = `${masterPath.replace("slideMasters/", "slideMasters/_rels/")}.rels`;
53461
53544
  await this.loadSlideRelationships(masterPath, masterRelsPath);
53462
53545
  return this.extractBackgroundImage(masterXmlObj, masterPath, "p:sldMaster");
@@ -53478,9 +53561,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53478
53561
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53479
53562
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53480
53563
  try {
53481
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53482
- if (layoutXmlStr) {
53483
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53564
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53565
+ if (layoutXmlObj) {
53484
53566
  const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
53485
53567
  await this.loadSlideRelationships(layoutPath, layoutRelsPath);
53486
53568
  const bg = this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
@@ -53506,9 +53588,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53506
53588
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53507
53589
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53508
53590
  try {
53509
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53510
- if (layoutXmlStr) {
53511
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53591
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53592
+ if (layoutXmlObj) {
53512
53593
  const layoutBg = this.extractBackgroundColor(layoutXmlObj, "p:sldLayout");
53513
53594
  if (layoutBg) {
53514
53595
  return layoutBg;
@@ -53535,9 +53616,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53535
53616
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53536
53617
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53537
53618
  try {
53538
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53539
- if (masterXmlStr) {
53540
- const masterXmlObj = this.parser.parse(masterXmlStr);
53619
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53620
+ if (masterXmlObj) {
53541
53621
  return this.extractBackgroundColor(masterXmlObj, "p:sldMaster");
53542
53622
  }
53543
53623
  } catch {
@@ -53564,9 +53644,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53564
53644
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53565
53645
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53566
53646
  try {
53567
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53568
- if (layoutXmlStr) {
53569
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53647
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53648
+ if (layoutXmlObj) {
53570
53649
  const layoutGrad = this.extractBackgroundGradient(layoutXmlObj, "p:sldLayout");
53571
53650
  if (layoutGrad) {
53572
53651
  return layoutGrad;
@@ -53593,9 +53672,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53593
53672
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53594
53673
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53595
53674
  try {
53596
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53597
- if (masterXmlStr) {
53598
- const masterXmlObj = this.parser.parse(masterXmlStr);
53675
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53676
+ if (masterXmlObj) {
53599
53677
  return this.extractBackgroundGradient(masterXmlObj, "p:sldMaster");
53600
53678
  }
53601
53679
  } catch {
@@ -53910,11 +53988,24 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
53910
53988
  }
53911
53989
  }
53912
53990
  }
53913
- const spcBef = this.parseParagraphSpacingPx(levelProps["a:spcBef"]);
53991
+ const defRPrSzRaw = Number.parseInt(
53992
+ String(
53993
+ levelProps["a:defRPr"]?.["@_sz"] || ""
53994
+ ),
53995
+ 10
53996
+ );
53997
+ const basisFontSizePx = Number.isFinite(defRPrSzRaw) ? this.pointsToPixels(defRPrSzRaw / 100) : void 0;
53998
+ const spcBef = this.parseParagraphSpacingPx(
53999
+ levelProps["a:spcBef"],
54000
+ basisFontSizePx
54001
+ );
53914
54002
  if (spcBef !== void 0) {
53915
54003
  style.spaceBefore = spcBef;
53916
54004
  }
53917
- const spcAft = this.parseParagraphSpacingPx(levelProps["a:spcAft"]);
54005
+ const spcAft = this.parseParagraphSpacingPx(
54006
+ levelProps["a:spcAft"],
54007
+ basisFontSizePx
54008
+ );
53918
54009
  if (spcAft !== void 0) {
53919
54010
  style.spaceAfter = spcAft;
53920
54011
  }
@@ -2687,14 +2687,52 @@ function extractSourceOrders(xml) {
2687
2687
  }
2688
2688
  return orders;
2689
2689
  }
2690
+ function ensureArrayLocal(value) {
2691
+ return Array.isArray(value) ? value : value === void 0 ? [] : [value];
2692
+ }
2693
+ function countsSignature(counts) {
2694
+ return [...counts.entries()].sort((a, b) => a[0] < b[0] ? -1 : 1).map(([name, count]) => `${name}:${count}`).join(",");
2695
+ }
2696
+ function pathSignature(path2) {
2697
+ const counts = /* @__PURE__ */ new Map();
2698
+ for (const key of Object.keys(path2)) {
2699
+ const name = localName(key);
2700
+ if (!PATH_COMMANDS.has(name)) {
2701
+ continue;
2702
+ }
2703
+ counts.set(name, (counts.get(name) ?? 0) + ensureArrayLocal(path2[key]).length);
2704
+ }
2705
+ return countsSignature(counts);
2706
+ }
2707
+ function orderSignature(order) {
2708
+ const counts = /* @__PURE__ */ new Map();
2709
+ for (const name of order) {
2710
+ counts.set(name, (counts.get(name) ?? 0) + 1);
2711
+ }
2712
+ return countsSignature(counts);
2713
+ }
2690
2714
  function annotateCustomGeometryCommandOrder(xml, parsed) {
2691
2715
  const orders = extractSourceOrders(xml);
2692
2716
  if (orders.length === 0) {
2693
2717
  return;
2694
2718
  }
2695
2719
  const paths = collectParsedPaths(parsed);
2696
- for (let index = 0; index < Math.min(paths.length, orders.length); index++) {
2697
- commandOrder.set(paths[index], orders[index]);
2720
+ const ordersBySignature = /* @__PURE__ */ new Map();
2721
+ for (const order of orders) {
2722
+ const signature = orderSignature(order);
2723
+ const bucket = ordersBySignature.get(signature);
2724
+ if (bucket) {
2725
+ bucket.push(order);
2726
+ } else {
2727
+ ordersBySignature.set(signature, [order]);
2728
+ }
2729
+ }
2730
+ for (const path2 of paths) {
2731
+ const bucket = ordersBySignature.get(pathSignature(path2));
2732
+ const order = bucket?.shift();
2733
+ if (order) {
2734
+ commandOrder.set(path2, order);
2735
+ }
2698
2736
  }
2699
2737
  }
2700
2738
  function orderedPathCommandEntries(path2, ensureArray16) {
@@ -50704,7 +50742,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50704
50742
  pointsToPixels(points3) {
50705
50743
  return points3 * (96 / 72);
50706
50744
  }
50707
- parseParagraphSpacingPx(spacingNode) {
50745
+ parseParagraphSpacingPx(spacingNode, basisFontSizePx) {
50708
50746
  if (!spacingNode) {
50709
50747
  return void 0;
50710
50748
  }
@@ -50715,6 +50753,13 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50715
50753
  if (Number.isFinite(spacingPointsRaw)) {
50716
50754
  return this.pointsToPixels(spacingPointsRaw / 100);
50717
50755
  }
50756
+ const spacingPercentRaw = Number.parseInt(
50757
+ String(spacingNode["a:spcPct"]?.["@_val"] || ""),
50758
+ 10
50759
+ );
50760
+ if (Number.isFinite(spacingPercentRaw) && typeof basisFontSizePx === "number" && basisFontSizePx > 0) {
50761
+ return spacingPercentRaw / 1e5 * basisFontSizePx;
50762
+ }
50718
50763
  return void 0;
50719
50764
  }
50720
50765
  parseLineSpacingMultiplier(lineSpacingNode) {
@@ -50794,7 +50839,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50794
50839
 
50795
50840
  // src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
50796
50841
  var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50797
- resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
50842
+ resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath, effectiveLevelStyles) {
50798
50843
  if (!paragraph) {
50799
50844
  return null;
50800
50845
  }
@@ -50830,11 +50875,8 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50830
50875
  }
50831
50876
  }
50832
50877
  if (!resolvedBulletProps) {
50833
- if (isBodyPlaceholder) {
50834
- const presentationLevelStyle = this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1];
50835
- return this.createBulletInfoFromLevelStyle(presentationLevelStyle, paragraphIndex);
50836
- }
50837
- return null;
50878
+ const fallbackLevelStyle = effectiveLevelStyles?.[normalizedLevel - 1] ?? effectiveLevelStyles?.[-1] ?? (isBodyPlaceholder ? this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1] : void 0);
50879
+ return this.createBulletInfoFromLevelStyle(fallbackLevelStyle, paragraphIndex);
50838
50880
  }
50839
50881
  const buFont = resolvedBulletProps["a:buFont"];
50840
50882
  const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
@@ -51324,16 +51366,21 @@ var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
51324
51366
  textStyle.align = paraAlign;
51325
51367
  }
51326
51368
  }
51369
+ const spacingBasisPx = typeof textStyle.fontSize === "number" ? textStyle.fontSize : void 0;
51327
51370
  if (textStyle.paragraphSpacingBefore === void 0) {
51328
51371
  const spacingBefore = this.parseParagraphSpacingPx(
51329
- pPr?.["a:spcBef"]
51372
+ pPr?.["a:spcBef"],
51373
+ spacingBasisPx
51330
51374
  );
51331
51375
  if (spacingBefore !== void 0) {
51332
51376
  textStyle.paragraphSpacingBefore = spacingBefore;
51333
51377
  }
51334
51378
  }
51335
51379
  if (textStyle.paragraphSpacingAfter === void 0) {
51336
- const spacingAfter = this.parseParagraphSpacingPx(pPr?.["a:spcAft"]);
51380
+ const spacingAfter = this.parseParagraphSpacingPx(
51381
+ pPr?.["a:spcAft"],
51382
+ spacingBasisPx
51383
+ );
51337
51384
  if (spacingAfter !== void 0) {
51338
51385
  textStyle.paragraphSpacingAfter = spacingAfter;
51339
51386
  }
@@ -51507,7 +51554,8 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
51507
51554
  ctx.txBody,
51508
51555
  ctx.inheritedTxBody,
51509
51556
  isBodyPlaceholder,
51510
- ctx.slidePath
51557
+ ctx.slidePath,
51558
+ ctx.effectiveLevelStyles
51511
51559
  );
51512
51560
  if (paragraphBulletInfo && !paragraphBulletInfo.none) {
51513
51561
  let bulletText;
@@ -53110,6 +53158,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53110
53158
  if (!normalized) {
53111
53159
  return void 0;
53112
53160
  }
53161
+ const canon = (key) => key.toLowerCase() === "folhlink" ? "folHlink" : key;
53113
53162
  if (normalized === "phclr") {
53114
53163
  const injected = this.themeColorMap["phclr"];
53115
53164
  if (injected) {
@@ -53119,17 +53168,18 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53119
53168
  }
53120
53169
  const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
53121
53170
  if (overrideMap) {
53122
- const remapped = overrideMap[normalized];
53171
+ const remapped = overrideMap[canon(normalized)];
53123
53172
  if (remapped) {
53124
- return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
53173
+ const target = canon(remapped);
53174
+ return this.themeColorMap[target] || this.getDefaultSchemeColorMap()[target];
53125
53175
  }
53126
53176
  } else {
53127
53177
  const defaultAliasTarget = DEFAULT_CLR_MAP_ALIAS[normalized];
53128
53178
  if (defaultAliasTarget) {
53129
- return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53179
+ return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53130
53180
  }
53131
53181
  }
53132
- return this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53182
+ return this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53133
53183
  }
53134
53184
  normalizeStrokeDashType(value) {
53135
53185
  const normalized = String(value ?? "").trim();
@@ -53418,6 +53468,40 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53418
53468
  }
53419
53469
  return void 0;
53420
53470
  }
53471
+ /**
53472
+ * Reuse the cached parse of a layout XML part, parsing (and caching) on a
53473
+ * miss. Background resolution runs per slide but the layout/master parts are
53474
+ * large (a themed master can be ~200 KB); re-parsing them for every slide
53475
+ * dominated load time, so share the same parsed object `getLayoutElements`
53476
+ * already populated.
53477
+ */
53478
+ async resolveCachedLayoutXml(layoutPath) {
53479
+ const cached = this.layoutXmlMap.get(layoutPath);
53480
+ if (cached) {
53481
+ return cached;
53482
+ }
53483
+ const xml = await this.zip.file(layoutPath)?.async("string");
53484
+ if (!xml) {
53485
+ return void 0;
53486
+ }
53487
+ const parsed = this.parser.parse(xml);
53488
+ this.layoutXmlMap.set(layoutPath, parsed);
53489
+ return parsed;
53490
+ }
53491
+ /** Reuse the cached parse of a master XML part, parsing (and caching) on a miss. */
53492
+ async resolveCachedMasterXml(masterPath) {
53493
+ const cached = this.masterXmlMap.get(masterPath);
53494
+ if (cached) {
53495
+ return cached;
53496
+ }
53497
+ const xml = await this.zip.file(masterPath)?.async("string");
53498
+ if (!xml) {
53499
+ return void 0;
53500
+ }
53501
+ const parsed = this.parser.parse(xml);
53502
+ this.masterXmlMap.set(masterPath, parsed);
53503
+ return parsed;
53504
+ }
53421
53505
  async getMasterBackgroundImage(layoutPath) {
53422
53506
  const layoutRels = this.slideRelsMap.get(layoutPath);
53423
53507
  if (!layoutRels) {
@@ -53428,9 +53512,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53428
53512
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53429
53513
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53430
53514
  try {
53431
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53432
- if (masterXmlStr) {
53433
- const masterXmlObj = this.parser.parse(masterXmlStr);
53515
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53516
+ if (masterXmlObj) {
53434
53517
  const masterRelsPath = `${masterPath.replace("slideMasters/", "slideMasters/_rels/")}.rels`;
53435
53518
  await this.loadSlideRelationships(masterPath, masterRelsPath);
53436
53519
  return this.extractBackgroundImage(masterXmlObj, masterPath, "p:sldMaster");
@@ -53452,9 +53535,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53452
53535
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53453
53536
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53454
53537
  try {
53455
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53456
- if (layoutXmlStr) {
53457
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53538
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53539
+ if (layoutXmlObj) {
53458
53540
  const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
53459
53541
  await this.loadSlideRelationships(layoutPath, layoutRelsPath);
53460
53542
  const bg = this.extractBackgroundImage(layoutXmlObj, layoutPath, "p:sldLayout");
@@ -53480,9 +53562,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53480
53562
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53481
53563
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53482
53564
  try {
53483
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53484
- if (layoutXmlStr) {
53485
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53565
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53566
+ if (layoutXmlObj) {
53486
53567
  const layoutBg = this.extractBackgroundColor(layoutXmlObj, "p:sldLayout");
53487
53568
  if (layoutBg) {
53488
53569
  return layoutBg;
@@ -53509,9 +53590,8 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
53509
53590
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53510
53591
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53511
53592
  try {
53512
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53513
- if (masterXmlStr) {
53514
- const masterXmlObj = this.parser.parse(masterXmlStr);
53593
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53594
+ if (masterXmlObj) {
53515
53595
  return this.extractBackgroundColor(masterXmlObj, "p:sldMaster");
53516
53596
  }
53517
53597
  } catch {
@@ -53538,9 +53618,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53538
53618
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
53539
53619
  const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${stripParentDirSegments(target)}`;
53540
53620
  try {
53541
- const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
53542
- if (layoutXmlStr) {
53543
- const layoutXmlObj = this.parser.parse(layoutXmlStr);
53621
+ const layoutXmlObj = await this.resolveCachedLayoutXml(layoutPath);
53622
+ if (layoutXmlObj) {
53544
53623
  const layoutGrad = this.extractBackgroundGradient(layoutXmlObj, "p:sldLayout");
53545
53624
  if (layoutGrad) {
53546
53625
  return layoutGrad;
@@ -53567,9 +53646,8 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
53567
53646
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
53568
53647
  const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${stripParentDirSegments(target)}`;
53569
53648
  try {
53570
- const masterXmlStr = await this.zip.file(masterPath)?.async("string");
53571
- if (masterXmlStr) {
53572
- const masterXmlObj = this.parser.parse(masterXmlStr);
53649
+ const masterXmlObj = await this.resolveCachedMasterXml(masterPath);
53650
+ if (masterXmlObj) {
53573
53651
  return this.extractBackgroundGradient(masterXmlObj, "p:sldMaster");
53574
53652
  }
53575
53653
  } catch {
@@ -53884,11 +53962,24 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
53884
53962
  }
53885
53963
  }
53886
53964
  }
53887
- const spcBef = this.parseParagraphSpacingPx(levelProps["a:spcBef"]);
53965
+ const defRPrSzRaw = Number.parseInt(
53966
+ String(
53967
+ levelProps["a:defRPr"]?.["@_sz"] || ""
53968
+ ),
53969
+ 10
53970
+ );
53971
+ const basisFontSizePx = Number.isFinite(defRPrSzRaw) ? this.pointsToPixels(defRPrSzRaw / 100) : void 0;
53972
+ const spcBef = this.parseParagraphSpacingPx(
53973
+ levelProps["a:spcBef"],
53974
+ basisFontSizePx
53975
+ );
53888
53976
  if (spcBef !== void 0) {
53889
53977
  style.spaceBefore = spcBef;
53890
53978
  }
53891
- const spcAft = this.parseParagraphSpacingPx(levelProps["a:spcAft"]);
53979
+ const spcAft = this.parseParagraphSpacingPx(
53980
+ levelProps["a:spcAft"],
53981
+ basisFontSizePx
53982
+ );
53892
53983
  if (spcAft !== void 0) {
53893
53984
  style.spaceAfter = spcAft;
53894
53985
  }
@@ -1,2 +1,2 @@
1
- import { _ as FileSystemAdapter, a as SlideProcessorOptions, c as DocumentConverter, d as normalizePath, f as MediaContext, g as ConversionResult, h as ConversionOptions, i as SlideProcessor, l as deriveOutputPath, m as generateMediaFilename, n as SvgExporter, o as PptxConverterOptions, p as dataUrlToMediaBytes, r as SlideMetadataRenderer, s as PptxMarkdownConverter, t as SvgExportOptions, u as getDirectory } from "../index-BmCX2W7T.js";
1
+ import { _ as FileSystemAdapter, a as SlideProcessorOptions, c as DocumentConverter, d as normalizePath, f as MediaContext, g as ConversionResult, h as ConversionOptions, i as SlideProcessor, l as deriveOutputPath, m as generateMediaFilename, n as SvgExporter, o as PptxConverterOptions, p as dataUrlToMediaBytes, r as SlideMetadataRenderer, s as PptxMarkdownConverter, t as SvgExportOptions, u as getDirectory } from "../index-BZzE92Uh.js";
2
2
  export { type ConversionOptions, type ConversionResult, DocumentConverter, type FileSystemAdapter, MediaContext, type PptxConverterOptions, PptxMarkdownConverter, SlideMetadataRenderer, SlideProcessor, type SlideProcessorOptions, type SvgExportOptions, SvgExporter, dataUrlToMediaBytes, deriveOutputPath, generateMediaFilename, getDirectory, normalizePath };