pptx-viewer-core 1.6.7 → 1.6.9

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.
@@ -7227,36 +7227,200 @@ async function fetchUrlToBytes(url, options = {}) {
7227
7227
  }
7228
7228
  }
7229
7229
 
7230
+ // src/core/utils/inkml-trace-decode.ts
7231
+ function resolveChannelOrder(root) {
7232
+ const traceFormat = findFirstByLocalName(root, "traceFormat");
7233
+ if (!traceFormat) {
7234
+ return ["X", "Y"];
7235
+ }
7236
+ const channels = ensureArray(nsGet(traceFormat, "channel"));
7237
+ const names = channels.map(
7238
+ (channel) => String(nsAttr(channel, "name") ?? "").trim().toUpperCase()
7239
+ ).filter((name) => name.length > 0);
7240
+ return names.length > 0 ? names : ["X", "Y"];
7241
+ }
7242
+ function decodeTracePoints(text2, channelOrder) {
7243
+ const points3 = [];
7244
+ const modes = channelOrder.map(() => "explicit");
7245
+ const lastValue = channelOrder.map(() => 0);
7246
+ const lastVelocity = channelOrder.map(() => 0);
7247
+ for (const rawPoint of text2.split(",")) {
7248
+ const tokens = rawPoint.trim().split(/\s+/u).filter((token2) => token2.length > 0);
7249
+ if (tokens.length === 0) {
7250
+ continue;
7251
+ }
7252
+ const decoded = [];
7253
+ for (let i = 0; i < tokens.length && i < channelOrder.length; i++) {
7254
+ const parsed = parseValueToken(tokens[i], modes[i]);
7255
+ if (parsed === void 0) {
7256
+ decoded.push(lastValue[i]);
7257
+ continue;
7258
+ }
7259
+ modes[i] = parsed.mode;
7260
+ const value = applyDiffMode(parsed, i, lastValue, lastVelocity);
7261
+ decoded.push(value);
7262
+ }
7263
+ if (decoded.length >= 2) {
7264
+ points3.push(decoded);
7265
+ }
7266
+ }
7267
+ return points3;
7268
+ }
7269
+ function parseValueToken(token2, currentMode) {
7270
+ let mode = currentMode;
7271
+ let body = token2;
7272
+ const prefix = token2[0];
7273
+ if (prefix === "!") {
7274
+ mode = "explicit";
7275
+ body = token2.slice(1);
7276
+ } else if (prefix === "'") {
7277
+ mode = "single";
7278
+ body = token2.slice(1);
7279
+ } else if (prefix === '"') {
7280
+ mode = "double";
7281
+ body = token2.slice(1);
7282
+ }
7283
+ if (body.length === 0) {
7284
+ return void 0;
7285
+ }
7286
+ const value = Number(body);
7287
+ return Number.isFinite(value) ? { value, mode } : void 0;
7288
+ }
7289
+ function applyDiffMode(parsed, index, lastValue, lastVelocity) {
7290
+ if (parsed.mode === "single") {
7291
+ lastVelocity[index] = parsed.value;
7292
+ lastValue[index] += parsed.value;
7293
+ } else if (parsed.mode === "double") {
7294
+ lastVelocity[index] += parsed.value;
7295
+ lastValue[index] += lastVelocity[index];
7296
+ } else {
7297
+ lastValue[index] = parsed.value;
7298
+ lastVelocity[index] = 0;
7299
+ }
7300
+ return lastValue[index];
7301
+ }
7302
+ function pointsToSvgPath(points3, channelOrder) {
7303
+ const xi = channelOrder.indexOf("X");
7304
+ const yi = channelOrder.indexOf("Y");
7305
+ const xIndex = xi >= 0 ? xi : 0;
7306
+ const yIndex = yi >= 0 ? yi : 1;
7307
+ const segments = [];
7308
+ for (const point of points3) {
7309
+ const x = point[xIndex];
7310
+ const y = point[yIndex];
7311
+ if (!Number.isFinite(x) || !Number.isFinite(y)) {
7312
+ continue;
7313
+ }
7314
+ segments.push(`${segments.length === 0 ? "M" : "L"} ${x} ${y}`);
7315
+ }
7316
+ return segments.join(" ");
7317
+ }
7318
+ function pointsToPressures(points3, channelOrder) {
7319
+ const fIndex = channelOrder.indexOf("F");
7320
+ if (fIndex < 0) {
7321
+ return [];
7322
+ }
7323
+ const pressures = [];
7324
+ for (const point of points3) {
7325
+ const raw = point[fIndex];
7326
+ if (Number.isFinite(raw)) {
7327
+ const normalised = raw > 1 ? raw / 32767 : raw;
7328
+ pressures.push(Math.max(0, Math.min(1, normalised)));
7329
+ }
7330
+ }
7331
+ return pressures;
7332
+ }
7333
+ function nsGet(obj, localName21) {
7334
+ if (localName21 in obj) {
7335
+ return obj[localName21];
7336
+ }
7337
+ for (const key of Object.keys(obj)) {
7338
+ if (localNameOf(key) === localName21 && !key.startsWith("@_")) {
7339
+ return obj[key];
7340
+ }
7341
+ }
7342
+ return void 0;
7343
+ }
7344
+ function nsAttr(obj, localName21) {
7345
+ const direct = obj[`@_${localName21}`];
7346
+ if (direct !== void 0) {
7347
+ return direct;
7348
+ }
7349
+ for (const key of Object.keys(obj)) {
7350
+ if (key.startsWith("@_") && localNameOf(key.slice(2)) === localName21) {
7351
+ return obj[key];
7352
+ }
7353
+ }
7354
+ return void 0;
7355
+ }
7356
+ function localNameOf(key) {
7357
+ const colon = key.indexOf(":");
7358
+ return colon >= 0 ? key.slice(colon + 1) : key;
7359
+ }
7360
+ function findFirstByLocalName(node, localName21) {
7361
+ const direct = nsGet(node, localName21);
7362
+ if (direct && typeof direct === "object") {
7363
+ return Array.isArray(direct) ? direct[0] : direct;
7364
+ }
7365
+ for (const key of Object.keys(node)) {
7366
+ if (key.startsWith("@_") || key === "#text") {
7367
+ continue;
7368
+ }
7369
+ for (const child20 of ensureArray(node[key])) {
7370
+ if (typeof child20 !== "object") {
7371
+ continue;
7372
+ }
7373
+ const found = findFirstByLocalName(child20, localName21);
7374
+ if (found) {
7375
+ return found;
7376
+ }
7377
+ }
7378
+ }
7379
+ return void 0;
7380
+ }
7381
+ function ensureArray(value) {
7382
+ if (value === void 0 || value === null) {
7383
+ return [];
7384
+ }
7385
+ return Array.isArray(value) ? value : [value];
7386
+ }
7387
+
7230
7388
  // src/core/utils/inkml-content-part.ts
7231
7389
  var INKML_NAMESPACE = "http://www.w3.org/2003/InkML";
7232
7390
  var METADATA_NAMESPACE = "https://pptx-viewer.dev/inkml/metadata";
7233
7391
  function parseInkMlContent(data) {
7234
- const root = data["ink:ink"] ?? data["ink"];
7392
+ const root = nsGet(data, "ink") ?? data["ink"];
7235
7393
  if (!root) {
7236
7394
  return { strokes: [], rawXml: data };
7237
7395
  }
7238
7396
  const brushes = /* @__PURE__ */ new Map();
7239
- for (const brush of ensureArray(root["ink:brush"] ?? root["brush"])) {
7240
- const properties = ensureArray(brush["ink:brushProperty"] ?? brush["brushProperty"]);
7397
+ for (const brush of ensureArray(nsGet(root, "brush"))) {
7398
+ const properties = ensureArray(nsGet(brush, "brushProperty"));
7241
7399
  const valueByName = new Map(
7242
- properties.map((property) => [String(property["@_name"] ?? ""), property["@_value"]])
7400
+ properties.map((property) => [
7401
+ String(nsAttr(property, "name") ?? ""),
7402
+ nsAttr(property, "value")
7403
+ ])
7243
7404
  );
7244
- brushes.set(String(brush["@_id"] ?? ""), {
7405
+ brushes.set(String(nsAttr(brush, "id") ?? ""), {
7245
7406
  color: String(valueByName.get("color") ?? "#000000"),
7246
7407
  width: finiteNumber(valueByName.get("width"), 1),
7247
7408
  opacity: finiteNumber(valueByName.get("opacity"), 1)
7248
7409
  });
7249
7410
  }
7411
+ const channelOrder = resolveChannelOrder(root);
7250
7412
  const strokes = [];
7251
- for (const trace of ensureArray(root["ink:trace"] ?? root["trace"])) {
7413
+ for (const trace of ensureArray(nsGet(root, "trace"))) {
7252
7414
  const text2 = typeof trace === "string" ? trace : String(trace["#text"] ?? "").trim();
7253
- const path2 = typeof trace === "string" ? text2 : String(trace["@_pva:path"] ?? "").trim() || text2;
7415
+ const authored = typeof trace === "string" ? "" : String(nsAttr(trace, "path") ?? "").trim();
7416
+ const points3 = authored ? [] : decodeTracePoints(text2, channelOrder);
7417
+ const path2 = authored || pointsToSvgPath(points3, channelOrder);
7254
7418
  if (!path2) {
7255
7419
  continue;
7256
7420
  }
7257
- const brushRef = typeof trace === "string" ? "" : String(trace["@_brushRef"] ?? "").replace("#", "");
7421
+ const brushRef = typeof trace === "string" ? "" : String(nsAttr(trace, "brushRef") ?? "").replace("#", "");
7258
7422
  const brush = brushes.get(brushRef) ?? { color: "#000000", width: 1, opacity: 1 };
7259
- const pressures = tracePressures(text2);
7423
+ const pressures = authored ? tracePressures(text2) : pointsToPressures(points3, channelOrder);
7260
7424
  strokes.push({ ...brush, path: path2, ...pressures.length > 0 ? { pressures } : {} });
7261
7425
  }
7262
7426
  return { strokes, rawXml: data };
@@ -7315,12 +7479,6 @@ function finiteNumber(value, fallback) {
7315
7479
  const parsed = Number(value);
7316
7480
  return Number.isFinite(parsed) ? parsed : fallback;
7317
7481
  }
7318
- function ensureArray(value) {
7319
- if (value === void 0 || value === null) {
7320
- return [];
7321
- }
7322
- return Array.isArray(value) ? value : [value];
7323
- }
7324
7482
 
7325
7483
  // src/core/utils/strip-parent-dir-segments.ts
7326
7484
  function stripParentDirSegments(path2) {
@@ -17240,7 +17398,7 @@ var MEDIA_REFERENCE_NAMES = [
17240
17398
  "videoFile",
17241
17399
  "quickTimeFile"
17242
17400
  ];
17243
- function parseDrawingMediaReference(container) {
17401
+ function parseDrawingMediaReference(container, externalRelIds) {
17244
17402
  if (!container) {
17245
17403
  return void 0;
17246
17404
  }
@@ -17249,11 +17407,17 @@ function parseDrawingMediaReference(container) {
17249
17407
  if (!node) {
17250
17408
  continue;
17251
17409
  }
17410
+ const linkId = String(attribute2(node, "link") ?? "").trim() || void 0;
17411
+ const embedId = String(attribute2(node, "embed") ?? "").trim() || void 0;
17252
17412
  return {
17253
17413
  kind,
17254
17414
  mediaType: kind === "videoFile" || kind === "quickTimeFile" ? "video" : "audio",
17255
- relationshipId: String(attribute2(node, "link") ?? attribute2(node, "embed") ?? "").trim() || void 0,
17256
- isLinked: attribute2(node, "link") !== void 0,
17415
+ relationshipId: linkId ?? embedId,
17416
+ // Embedded media legitimately uses r:link pointing at an INTERNAL
17417
+ // media part, so link presence alone does not imply a linked clip.
17418
+ // It is only truly linked when the referenced relationship is
17419
+ // external (TargetMode="External"), mirroring the OLE parser.
17420
+ isLinked: linkId !== void 0 && externalRelIds?.has(linkId) === true,
17257
17421
  name: kind === "wavAudioFile" ? String(attribute2(node, "name") ?? "") || void 0 : void 0,
17258
17422
  contentType: kind === "audioFile" ? String(attribute2(node, "contentType") ?? "") || void 0 : void 0,
17259
17423
  audioCdStart: kind === "audioCd" ? parseAudioCdPosition(child11(node, "st")) : void 0,
@@ -23584,26 +23748,49 @@ function applyScene3dStyle(shapeProps, style) {
23584
23748
  const camera = scene3dNode["a:camera"];
23585
23749
  const lightRig = scene3dNode["a:lightRig"];
23586
23750
  const cameraRot = camera?.["a:rot"];
23751
+ const lightRigRot = lightRig?.["a:rot"];
23587
23752
  style.scene3d = {
23588
23753
  cameraPreset: String(camera?.["@_prst"] || "").trim() || void 0,
23589
- cameraRotX: cameraRot?.["@_lat"] !== void 0 ? parseInt(String(cameraRot["@_lat"]), 10) : void 0,
23590
- cameraRotY: cameraRot?.["@_lon"] !== void 0 ? parseInt(String(cameraRot["@_lon"]), 10) : void 0,
23591
- cameraRotZ: cameraRot?.["@_rev"] !== void 0 ? parseInt(String(cameraRot["@_rev"]), 10) : void 0,
23754
+ cameraFieldOfView: intAttr(camera?.["@_fov"]),
23755
+ cameraZoom: floatAttr(camera?.["@_zoom"]),
23756
+ cameraRotX: intAttr(cameraRot?.["@_lat"]),
23757
+ cameraRotY: intAttr(cameraRot?.["@_lon"]),
23758
+ cameraRotZ: intAttr(cameraRot?.["@_rev"]),
23592
23759
  lightRigType: String(lightRig?.["@_rig"] || "").trim() || void 0,
23593
- lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0
23760
+ lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0,
23761
+ lightRigRotX: intAttr(lightRigRot?.["@_lat"]),
23762
+ lightRigRotY: intAttr(lightRigRot?.["@_lon"]),
23763
+ lightRigRotZ: intAttr(lightRigRot?.["@_rev"])
23594
23764
  };
23595
23765
  const backdrop = scene3dNode["a:backdrop"];
23596
23766
  if (backdrop) {
23597
23767
  style.scene3d.hasBackdrop = true;
23598
23768
  const anchor = backdrop["a:anchor"];
23599
- const anchorAttrs = anchor;
23600
- if (anchorAttrs) {
23601
- style.scene3d.backdropAnchorX = parseInt(String(anchorAttrs["@_x"] || "0"), 10);
23602
- style.scene3d.backdropAnchorY = parseInt(String(anchorAttrs["@_y"] || "0"), 10);
23603
- style.scene3d.backdropAnchorZ = parseInt(String(anchorAttrs["@_z"] || "0"), 10);
23769
+ if (anchor) {
23770
+ style.scene3d.backdropAnchorX = intAttr(anchor["@_x"]) ?? 0;
23771
+ style.scene3d.backdropAnchorY = intAttr(anchor["@_y"]) ?? 0;
23772
+ style.scene3d.backdropAnchorZ = intAttr(anchor["@_z"]) ?? 0;
23773
+ }
23774
+ const norm = backdrop["a:norm"];
23775
+ if (norm) {
23776
+ style.scene3d.backdropNormalX = intAttr(norm["@_dx"]) ?? 0;
23777
+ style.scene3d.backdropNormalY = intAttr(norm["@_dy"]) ?? 0;
23778
+ style.scene3d.backdropNormalZ = intAttr(norm["@_dz"]) ?? 0;
23779
+ }
23780
+ const up = backdrop["a:up"];
23781
+ if (up) {
23782
+ style.scene3d.backdropUpX = intAttr(up["@_dx"]) ?? 0;
23783
+ style.scene3d.backdropUpY = intAttr(up["@_dy"]) ?? 0;
23784
+ style.scene3d.backdropUpZ = intAttr(up["@_dz"]) ?? 0;
23604
23785
  }
23605
23786
  }
23606
23787
  }
23788
+ function intAttr(value) {
23789
+ return value !== void 0 ? parseInt(String(value), 10) : void 0;
23790
+ }
23791
+ function floatAttr(value) {
23792
+ return value !== void 0 ? parseFloat(String(value)) : void 0;
23793
+ }
23607
23794
  function applyShape3dStyle(shapeProps, style, context) {
23608
23795
  const shape3dNode = shapeProps["a:sp3d"];
23609
23796
  if (!shape3dNode) {
@@ -24486,7 +24673,10 @@ var PptxMediaDataParser = class {
24486
24673
  parseMediaData(graphicData, slidePath) {
24487
24674
  const result = {};
24488
24675
  try {
24489
- const reference = parseDrawingMediaReference(graphicData);
24676
+ const reference = parseDrawingMediaReference(
24677
+ graphicData,
24678
+ this.context.externalRelsMap.get(slidePath)
24679
+ );
24490
24680
  if (reference) {
24491
24681
  result.mediaType = reference.mediaType;
24492
24682
  result.mediaReferenceKind = reference.kind;
@@ -28139,6 +28329,7 @@ var PptxNativeAnimationService = class {
28139
28329
  const nodeType = String(cTn["@_nodeType"] || "");
28140
28330
  const presetClass = cTn["@_presetClass"];
28141
28331
  const presetId = cTn["@_presetID"] ? Number.parseInt(String(cTn["@_presetID"]), 10) : void 0;
28332
+ const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
28142
28333
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
28143
28334
  const delayMs = cTn["@_delay"] ? Number.parseInt(String(cTn["@_delay"]), 10) : void 0;
28144
28335
  let trigger = currentTrigger;
@@ -28190,6 +28381,7 @@ var PptxNativeAnimationService = class {
28190
28381
  trigger,
28191
28382
  presetClass: validPresetClass,
28192
28383
  presetId,
28384
+ presetSubtype,
28193
28385
  durationMs,
28194
28386
  delayMs,
28195
28387
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
@@ -28500,6 +28692,74 @@ function buildP14ExtLst(transitionType, direction, orient, pattern, rawExtLst, x
28500
28692
  return { "p:ext": transitionExt };
28501
28693
  }
28502
28694
 
28695
+ // src/core/services/p15-transition-parser.ts
28696
+ var P15_TRANSITION_PRESETS = /* @__PURE__ */ new Set([
28697
+ "fallOver",
28698
+ "drape",
28699
+ "curtains",
28700
+ "wind",
28701
+ "prestige",
28702
+ "fracture",
28703
+ "crush",
28704
+ "peelOff",
28705
+ "pageCurlDouble",
28706
+ "pageCurlSingle",
28707
+ "airplane",
28708
+ "origami"
28709
+ ]);
28710
+ var PRSTTRANS_EXT_URI = "{D42A27DB-BD31-4B8C-83A1-F6EECF244321}";
28711
+ function optionalBoolean(value) {
28712
+ const valueToken = value === void 0 || value === null ? "" : String(value).trim().toLowerCase();
28713
+ if (valueToken === "1" || valueToken === "true") {
28714
+ return true;
28715
+ }
28716
+ if (valueToken === "0" || valueToken === "false") {
28717
+ return false;
28718
+ }
28719
+ return void 0;
28720
+ }
28721
+ function parseP15FromExtLst(extLstNode, xmlLookupService, getXmlLocalName) {
28722
+ const extEntries = xmlLookupService.getChildrenArrayByLocalName(extLstNode, "ext");
28723
+ for (const ext of extEntries) {
28724
+ if (!ext) {
28725
+ continue;
28726
+ }
28727
+ for (const [key, value] of Object.entries(ext)) {
28728
+ if (key.startsWith("@_")) {
28729
+ continue;
28730
+ }
28731
+ if (getXmlLocalName(key) !== "prstTrans") {
28732
+ continue;
28733
+ }
28734
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
28735
+ continue;
28736
+ }
28737
+ const detail = value;
28738
+ const prst = String(detail["@_prst"] || "").trim();
28739
+ if (!P15_TRANSITION_PRESETS.has(prst)) {
28740
+ continue;
28741
+ }
28742
+ return {
28743
+ type: prst,
28744
+ invX: optionalBoolean(detail["@_invX"]),
28745
+ invY: optionalBoolean(detail["@_invY"])
28746
+ };
28747
+ }
28748
+ }
28749
+ return void 0;
28750
+ }
28751
+ function buildP15ExtLst(transitionType, invX, invY) {
28752
+ const prstTrans = {
28753
+ "@_xmlns:p15": "http://schemas.microsoft.com/office/powerpoint/2012/main",
28754
+ "@_prst": transitionType
28755
+ };
28756
+ const ext = {
28757
+ "@_uri": PRSTTRANS_EXT_URI,
28758
+ "p15:prstTrans": prstTrans
28759
+ };
28760
+ return { "p:ext": ext };
28761
+ }
28762
+
28503
28763
  // src/core/services/slide-transition-xml.ts
28504
28764
  var STANDARD_TRANSITION_TYPES = /* @__PURE__ */ new Set([
28505
28765
  "fade",
@@ -28565,7 +28825,7 @@ function parseTransitionDetails(node, localName21) {
28565
28825
  if (pattern) {
28566
28826
  result.pattern = pattern;
28567
28827
  }
28568
- const thruBlk = optionalBoolean(detail["@_thruBlk"]);
28828
+ const thruBlk = optionalBoolean2(detail["@_thruBlk"]);
28569
28829
  if (thruBlk !== void 0) {
28570
28830
  result.thruBlk = thruBlk;
28571
28831
  }
@@ -28576,7 +28836,7 @@ function parseTransitionAttributes(node) {
28576
28836
  const speedToken = token(node["@_spd"]);
28577
28837
  const speed = SPEEDS.has(speedToken) ? speedToken : void 0;
28578
28838
  const durationMs = unsignedInteger2(node["@_dur"] ?? node["@_p14:dur"], 1);
28579
- const advanceOnClick = optionalBoolean(node["@_advClick"]);
28839
+ const advanceOnClick = optionalBoolean2(node["@_advClick"]);
28580
28840
  const advanceAfterMs = unsignedInteger2(node["@_advTm"]);
28581
28841
  return { speed, durationMs, advanceOnClick, advanceAfterMs };
28582
28842
  }
@@ -28590,7 +28850,7 @@ function parseTransitionSound(raw, lookup, localName21) {
28590
28850
  return {
28591
28851
  soundRId: sound ? attributeByLocalName(sound, "embed", localName21) : void 0,
28592
28852
  soundName: sound ? attributeByLocalName(sound, "name", localName21) : void 0,
28593
- soundLoop: optionalBoolean(start["@_loop"])
28853
+ soundLoop: optionalBoolean2(start["@_loop"])
28594
28854
  };
28595
28855
  }
28596
28856
  const stopSound = Object.keys(raw).some(
@@ -28699,7 +28959,7 @@ function attributeByLocalName(node, name, localName21) {
28699
28959
  function token(value) {
28700
28960
  return value === void 0 || value === null ? "" : String(value).trim();
28701
28961
  }
28702
- function optionalBoolean(value) {
28962
+ function optionalBoolean2(value) {
28703
28963
  const valueToken = token(value).toLowerCase();
28704
28964
  if (!valueToken) {
28705
28965
  return void 0;
@@ -28745,6 +29005,7 @@ var PptxSlideTransitionService = class {
28745
29005
  const { spokes, thruBlk, rawSoundAction, rawExtLst } = details;
28746
29006
  if (rawExtLst && transitionType === "cut") {
28747
29007
  const p14Result = parseP14FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
29008
+ const p15Result = p14Result ? void 0 : parseP15FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
28748
29009
  if (p14Result) {
28749
29010
  transitionType = p14Result.type;
28750
29011
  if (p14Result.direction) {
@@ -28756,6 +29017,8 @@ var PptxSlideTransitionService = class {
28756
29017
  if (p14Result.pattern) {
28757
29018
  pattern = p14Result.pattern;
28758
29019
  }
29020
+ } else if (p15Result) {
29021
+ transitionType = p15Result.type;
28759
29022
  } else if (this.parseMorphFromExtLst(rawExtLst)) {
28760
29023
  transitionType = "morph";
28761
29024
  }
@@ -28837,6 +29100,7 @@ var PptxSlideTransitionService = class {
28837
29100
  }
28838
29101
  const transitionType = transition.type || "cut";
28839
29102
  const isP14Type = P14_TRANSITION_TYPES.has(transitionType);
29103
+ const isP15Type = P15_TRANSITION_PRESETS.has(transitionType);
28840
29104
  const isMorphType = transitionType === "morph";
28841
29105
  const node = createPreservedTransitionNode(transition.rawTransition, this.getXmlLocalName);
28842
29106
  if (isP14Type) {
@@ -28849,6 +29113,8 @@ var PptxSlideTransitionService = class {
28849
29113
  this.xmlLookupService,
28850
29114
  this.getXmlLocalName
28851
29115
  );
29116
+ } else if (isP15Type) {
29117
+ node["p:extLst"] = transition.rawExtLst ?? buildP15ExtLst(transitionType);
28852
29118
  } else if (isMorphType) {
28853
29119
  node["p:extLst"] = this.buildMorphExtLst(transition.rawExtLst);
28854
29120
  } else {
@@ -28859,7 +29125,7 @@ var PptxSlideTransitionService = class {
28859
29125
  if (soundAction) {
28860
29126
  node["p:sndAc"] = soundAction;
28861
29127
  }
28862
- if (transition.rawExtLst && !isP14Type && !isMorphType) {
29128
+ if (transition.rawExtLst && !isP14Type && !isP15Type && !isMorphType) {
28863
29129
  node["p:extLst"] = transition.rawExtLst;
28864
29130
  }
28865
29131
  return node;
@@ -36743,6 +37009,93 @@ var PptxHandlerRuntime = class {
36743
37009
  }
36744
37010
  };
36745
37011
 
37012
+ // src/core/core/runtime/table-style-border-parse.ts
37013
+ var EMU_PER_PIXEL = 9525;
37014
+ var BORDER_SIDES = [
37015
+ "left",
37016
+ "right",
37017
+ "top",
37018
+ "bottom",
37019
+ "insideH",
37020
+ "insideV",
37021
+ "tl2br",
37022
+ "bl2tr"
37023
+ ];
37024
+ function parseSolidFillStyle(solidFill2) {
37025
+ if (!solidFill2) {
37026
+ return void 0;
37027
+ }
37028
+ const schemeClr = solidFill2["a:schemeClr"];
37029
+ if (!schemeClr) {
37030
+ return void 0;
37031
+ }
37032
+ const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
37033
+ if (!schemeColor) {
37034
+ return void 0;
37035
+ }
37036
+ const tintRaw = schemeClr["a:tint"];
37037
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
37038
+ const shadeRaw = schemeClr["a:shade"];
37039
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
37040
+ return { schemeColor, tint, shade };
37041
+ }
37042
+ function parseBorderSide(side) {
37043
+ if (!side) {
37044
+ return void 0;
37045
+ }
37046
+ const ln = side["a:ln"];
37047
+ if (!ln) {
37048
+ return void 0;
37049
+ }
37050
+ const border = {};
37051
+ let has = false;
37052
+ if (ln["a:noFill"] !== void 0) {
37053
+ border.noFill = true;
37054
+ has = true;
37055
+ }
37056
+ const widthEmu = parseInt(String(ln["@_w"] || "0"), 10);
37057
+ if (widthEmu > 0) {
37058
+ border.width = Math.max(1, Math.round(widthEmu / EMU_PER_PIXEL));
37059
+ has = true;
37060
+ }
37061
+ const prstDash = ln["a:prstDash"];
37062
+ const dashVal = prstDash ? String(prstDash["@_val"] || "").trim() : "";
37063
+ if (dashVal) {
37064
+ border.dash = dashVal;
37065
+ has = true;
37066
+ }
37067
+ const solidFill2 = ln["a:solidFill"];
37068
+ const fill = parseSolidFillStyle(solidFill2);
37069
+ if (fill) {
37070
+ border.fill = fill;
37071
+ has = true;
37072
+ } else {
37073
+ const srgb = solidFill2?.["a:srgbClr"];
37074
+ const hex10 = srgb ? String(srgb["@_val"] || "").trim() : "";
37075
+ if (hex10) {
37076
+ border.color = hex10.startsWith("#") ? hex10 : `#${hex10}`;
37077
+ has = true;
37078
+ }
37079
+ }
37080
+ return has ? border : void 0;
37081
+ }
37082
+ function parseTableStyleBorders(tcStyle) {
37083
+ const tcBdr = tcStyle?.["a:tcBdr"];
37084
+ if (!tcBdr) {
37085
+ return void 0;
37086
+ }
37087
+ const result = {};
37088
+ let has = false;
37089
+ for (const name of BORDER_SIDES) {
37090
+ const border = parseBorderSide(tcBdr[`a:${name}`]);
37091
+ if (border) {
37092
+ result[name] = border;
37093
+ has = true;
37094
+ }
37095
+ }
37096
+ return has ? result : void 0;
37097
+ }
37098
+
36746
37099
  // src/core/core/runtime/PptxHandlerRuntimeTableStyles.ts
36747
37100
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
36748
37101
  /**
@@ -36827,30 +37180,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
36827
37180
  return void 0;
36828
37181
  }
36829
37182
  const tcStyle = section["a:tcStyle"];
36830
- if (!tcStyle) {
36831
- return void 0;
36832
- }
36833
- const fill = tcStyle["a:fill"];
36834
- if (!fill) {
36835
- return void 0;
36836
- }
36837
- const solidFill2 = fill["a:solidFill"];
36838
- if (!solidFill2) {
36839
- return void 0;
36840
- }
36841
- const schemeClr = solidFill2["a:schemeClr"];
36842
- if (!schemeClr) {
36843
- return void 0;
36844
- }
36845
- const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
36846
- if (!schemeColor) {
36847
- return void 0;
36848
- }
36849
- const tintRaw = schemeClr["a:tint"];
36850
- const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
36851
- const shadeRaw = schemeClr["a:shade"];
36852
- const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
36853
- return { schemeColor, tint, shade };
37183
+ const fill = tcStyle?.["a:fill"];
37184
+ return parseSolidFillStyle(fill?.["a:solidFill"]);
37185
+ }
37186
+ /**
37187
+ * Extract border styling from a table style section's
37188
+ * `a:tcStyle/a:tcBdr` (per-side line width, dash, and colour).
37189
+ */
37190
+ extractTableStyleSectionBorders(section) {
37191
+ return parseTableStyleBorders(section?.["a:tcStyle"]);
36854
37192
  }
36855
37193
  /**
36856
37194
  * Extract text properties from a:tcTxStyle in a table style section.
@@ -36997,6 +37335,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
36997
37335
  textProps[`${name}Text`] = text2;
36998
37336
  }
36999
37337
  }
37338
+ const borderProps = {};
37339
+ for (const name of sectionNames) {
37340
+ const borders = this.extractTableStyleSectionBorders(
37341
+ style[`a:${name}`]
37342
+ );
37343
+ if (borders) {
37344
+ borderProps[`${name}Borders`] = borders;
37345
+ }
37346
+ }
37000
37347
  const entry = {
37001
37348
  styleId,
37002
37349
  styleName,
@@ -37015,7 +37362,8 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
37015
37362
  ...swCellFill ? { swCellFill } : {},
37016
37363
  ...neCellFill ? { neCellFill } : {},
37017
37364
  ...nwCellFill ? { nwCellFill } : {},
37018
- ...textProps
37365
+ ...textProps,
37366
+ ...borderProps
37019
37367
  };
37020
37368
  map[styleId] = entry;
37021
37369
  }
@@ -38826,6 +39174,15 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
38826
39174
  if (align === "justify") {
38827
39175
  return "just";
38828
39176
  }
39177
+ if (align === "justLow") {
39178
+ return "justLow";
39179
+ }
39180
+ if (align === "dist") {
39181
+ return "dist";
39182
+ }
39183
+ if (align === "thaiDist") {
39184
+ return "thaiDist";
39185
+ }
38829
39186
  return void 0;
38830
39187
  }
38831
39188
  pixelsToPoints(px) {
@@ -39880,6 +40237,16 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39880
40237
  const chOffY = 0;
39881
40238
  const chExtCx = extCx;
39882
40239
  const chExtCy = extCy;
40240
+ const xfrmAttrs = {};
40241
+ if (typeof group.rotation === "number" && group.rotation !== 0) {
40242
+ xfrmAttrs["@_rot"] = String(Math.round(group.rotation * 6e4));
40243
+ }
40244
+ if (group.flipHorizontal) {
40245
+ xfrmAttrs["@_flipH"] = "1";
40246
+ }
40247
+ if (group.flipVertical) {
40248
+ xfrmAttrs["@_flipV"] = "1";
40249
+ }
39883
40250
  const grpXml = {
39884
40251
  "p:nvGrpSpPr": {
39885
40252
  "p:cNvPr": { "@_id": "0", "@_name": group.id },
@@ -39888,6 +40255,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
39888
40255
  },
39889
40256
  "p:grpSpPr": {
39890
40257
  "a:xfrm": {
40258
+ ...xfrmAttrs,
39891
40259
  "a:off": {
39892
40260
  "@_x": String(offX),
39893
40261
  "@_y": String(offY)
@@ -45635,45 +46003,18 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
45635
46003
  const s3d = shapeStyle.scene3d;
45636
46004
  const hasData = s3d.cameraPreset || s3d.lightRigType;
45637
46005
  if (hasData) {
45638
- const cameraObj = {};
45639
- if (s3d.cameraPreset) {
45640
- cameraObj["@_prst"] = s3d.cameraPreset;
45641
- }
45642
- if (s3d.cameraRotX !== void 0 || s3d.cameraRotY !== void 0 || s3d.cameraRotZ !== void 0) {
45643
- const rot = {};
45644
- if (s3d.cameraRotX !== void 0) {
45645
- rot["@_lat"] = String(s3d.cameraRotX);
45646
- }
45647
- if (s3d.cameraRotY !== void 0) {
45648
- rot["@_lon"] = String(s3d.cameraRotY);
45649
- }
45650
- if (s3d.cameraRotZ !== void 0) {
45651
- rot["@_rev"] = String(s3d.cameraRotZ);
45652
- }
45653
- cameraObj["a:rot"] = rot;
45654
- }
45655
- const lightRigObj = {};
45656
- if (s3d.lightRigType) {
45657
- lightRigObj["@_rig"] = s3d.lightRigType;
45658
- }
45659
- if (s3d.lightRigDirection) {
45660
- lightRigObj["@_dir"] = s3d.lightRigDirection;
45661
- }
45662
- const scene3dXml = {};
45663
- scene3dXml["a:camera"] = cameraObj;
45664
- if (Object.keys(lightRigObj).length > 0) {
45665
- scene3dXml["a:lightRig"] = lightRigObj;
45666
- }
45667
- if (s3d.hasBackdrop) {
45668
- const backdropObj = {};
45669
- if (s3d.backdropAnchorX !== void 0 || s3d.backdropAnchorY !== void 0 || s3d.backdropAnchorZ !== void 0) {
45670
- backdropObj["a:anchor"] = {
45671
- "@_x": String(s3d.backdropAnchorX ?? 0),
45672
- "@_y": String(s3d.backdropAnchorY ?? 0),
45673
- "@_z": String(s3d.backdropAnchorZ ?? 0)
45674
- };
45675
- }
45676
- scene3dXml["a:backdrop"] = backdropObj;
46006
+ const source = spPr["a:scene3d"] ?? {};
46007
+ const scene3dXml = { ...source };
46008
+ scene3dXml["a:camera"] = buildScene3dCamera(s3d, source);
46009
+ const lightRig = buildScene3dLightRig(s3d, source);
46010
+ if (lightRig) {
46011
+ scene3dXml["a:lightRig"] = lightRig;
46012
+ }
46013
+ const backdrop = buildScene3dBackdrop(s3d);
46014
+ if (backdrop) {
46015
+ scene3dXml["a:backdrop"] = backdrop;
46016
+ } else {
46017
+ delete scene3dXml["a:backdrop"];
45677
46018
  }
45678
46019
  spPr["a:scene3d"] = scene3dXml;
45679
46020
  } else {
@@ -45718,12 +46059,12 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
45718
46059
  }
45719
46060
  if (sh3d.extrusionColor) {
45720
46061
  sp3dXml["a:extrusionClr"] = {
45721
- "a:srgbClr": { "@_val": sh3d.extrusionColor }
46062
+ "a:srgbClr": { "@_val": sh3d.extrusionColor.replace("#", "") }
45722
46063
  };
45723
46064
  }
45724
46065
  if (sh3d.contourColor) {
45725
46066
  sp3dXml["a:contourClr"] = {
45726
- "a:srgbClr": { "@_val": sh3d.contourColor }
46067
+ "a:srgbClr": { "@_val": sh3d.contourColor.replace("#", "") }
45727
46068
  };
45728
46069
  }
45729
46070
  spPr["a:sp3d"] = sp3dXml;
@@ -45735,6 +46076,77 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
45735
46076
  }
45736
46077
  }
45737
46078
  };
46079
+ function buildSphereRot(lat, lon, rev) {
46080
+ if (lat === void 0 && lon === void 0 && rev === void 0) {
46081
+ return void 0;
46082
+ }
46083
+ const rot = {};
46084
+ if (lat !== void 0) {
46085
+ rot["@_lat"] = String(lat);
46086
+ }
46087
+ if (lon !== void 0) {
46088
+ rot["@_lon"] = String(lon);
46089
+ }
46090
+ if (rev !== void 0) {
46091
+ rot["@_rev"] = String(rev);
46092
+ }
46093
+ return rot;
46094
+ }
46095
+ function buildScene3dCamera(s3d, source) {
46096
+ const camera = { ...source["a:camera"] ?? {} };
46097
+ if (s3d.cameraPreset) {
46098
+ camera["@_prst"] = s3d.cameraPreset;
46099
+ }
46100
+ if (s3d.cameraFieldOfView !== void 0) {
46101
+ camera["@_fov"] = String(s3d.cameraFieldOfView);
46102
+ }
46103
+ if (s3d.cameraZoom !== void 0) {
46104
+ camera["@_zoom"] = String(s3d.cameraZoom);
46105
+ }
46106
+ const rot = buildSphereRot(s3d.cameraRotX, s3d.cameraRotY, s3d.cameraRotZ);
46107
+ if (rot) {
46108
+ camera["a:rot"] = rot;
46109
+ }
46110
+ return camera;
46111
+ }
46112
+ function buildScene3dLightRig(s3d, source) {
46113
+ const lightRig = { ...source["a:lightRig"] ?? {} };
46114
+ if (s3d.lightRigType) {
46115
+ lightRig["@_rig"] = s3d.lightRigType;
46116
+ }
46117
+ if (s3d.lightRigDirection) {
46118
+ lightRig["@_dir"] = s3d.lightRigDirection;
46119
+ }
46120
+ const rot = buildSphereRot(s3d.lightRigRotX, s3d.lightRigRotY, s3d.lightRigRotZ);
46121
+ if (rot) {
46122
+ lightRig["a:rot"] = rot;
46123
+ }
46124
+ return Object.keys(lightRig).length > 0 ? lightRig : void 0;
46125
+ }
46126
+ function buildScene3dBackdrop(s3d) {
46127
+ const hasNorm = s3d.backdropNormalX !== void 0 || s3d.backdropNormalY !== void 0 || s3d.backdropNormalZ !== void 0;
46128
+ const hasUp = s3d.backdropUpX !== void 0 || s3d.backdropUpY !== void 0 || s3d.backdropUpZ !== void 0;
46129
+ if (!s3d.hasBackdrop || !hasNorm || !hasUp) {
46130
+ return void 0;
46131
+ }
46132
+ return {
46133
+ "a:anchor": {
46134
+ "@_x": String(s3d.backdropAnchorX ?? 0),
46135
+ "@_y": String(s3d.backdropAnchorY ?? 0),
46136
+ "@_z": String(s3d.backdropAnchorZ ?? 0)
46137
+ },
46138
+ "a:norm": {
46139
+ "@_dx": String(s3d.backdropNormalX ?? 0),
46140
+ "@_dy": String(s3d.backdropNormalY ?? 0),
46141
+ "@_dz": String(s3d.backdropNormalZ ?? 0)
46142
+ },
46143
+ "a:up": {
46144
+ "@_dx": String(s3d.backdropUpX ?? 0),
46145
+ "@_dy": String(s3d.backdropUpY ?? 0),
46146
+ "@_dz": String(s3d.backdropUpZ ?? 0)
46147
+ }
46148
+ };
46149
+ }
45738
46150
 
45739
46151
  // src/core/core/runtime/PptxHandlerRuntimeSaveTextWriter.ts
45740
46152
  var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime29 {
@@ -50742,7 +51154,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50742
51154
  pointsToPixels(points3) {
50743
51155
  return points3 * (96 / 72);
50744
51156
  }
50745
- parseParagraphSpacingPx(spacingNode) {
51157
+ parseParagraphSpacingPx(spacingNode, basisFontSizePx) {
50746
51158
  if (!spacingNode) {
50747
51159
  return void 0;
50748
51160
  }
@@ -50753,6 +51165,13 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50753
51165
  if (Number.isFinite(spacingPointsRaw)) {
50754
51166
  return this.pointsToPixels(spacingPointsRaw / 100);
50755
51167
  }
51168
+ const spacingPercentRaw = Number.parseInt(
51169
+ String(spacingNode["a:spcPct"]?.["@_val"] || ""),
51170
+ 10
51171
+ );
51172
+ if (Number.isFinite(spacingPercentRaw) && typeof basisFontSizePx === "number" && basisFontSizePx > 0) {
51173
+ return spacingPercentRaw / 1e5 * basisFontSizePx;
51174
+ }
50756
51175
  return void 0;
50757
51176
  }
50758
51177
  parseLineSpacingMultiplier(lineSpacingNode) {
@@ -50832,7 +51251,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
50832
51251
 
50833
51252
  // src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
50834
51253
  var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50835
- resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
51254
+ resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath, effectiveLevelStyles) {
50836
51255
  if (!paragraph) {
50837
51256
  return null;
50838
51257
  }
@@ -50868,11 +51287,8 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
50868
51287
  }
50869
51288
  }
50870
51289
  if (!resolvedBulletProps) {
50871
- if (isBodyPlaceholder) {
50872
- const presentationLevelStyle = this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1];
50873
- return this.createBulletInfoFromLevelStyle(presentationLevelStyle, paragraphIndex);
50874
- }
50875
- return null;
51290
+ const fallbackLevelStyle = effectiveLevelStyles?.[normalizedLevel - 1] ?? effectiveLevelStyles?.[-1] ?? (isBodyPlaceholder ? this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1] : void 0);
51291
+ return this.createBulletInfoFromLevelStyle(fallbackLevelStyle, paragraphIndex);
50876
51292
  }
50877
51293
  const buFont = resolvedBulletProps["a:buFont"];
50878
51294
  const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
@@ -51362,16 +51778,21 @@ var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
51362
51778
  textStyle.align = paraAlign;
51363
51779
  }
51364
51780
  }
51781
+ const spacingBasisPx = typeof textStyle.fontSize === "number" ? textStyle.fontSize : void 0;
51365
51782
  if (textStyle.paragraphSpacingBefore === void 0) {
51366
51783
  const spacingBefore = this.parseParagraphSpacingPx(
51367
- pPr?.["a:spcBef"]
51784
+ pPr?.["a:spcBef"],
51785
+ spacingBasisPx
51368
51786
  );
51369
51787
  if (spacingBefore !== void 0) {
51370
51788
  textStyle.paragraphSpacingBefore = spacingBefore;
51371
51789
  }
51372
51790
  }
51373
51791
  if (textStyle.paragraphSpacingAfter === void 0) {
51374
- const spacingAfter = this.parseParagraphSpacingPx(pPr?.["a:spcAft"]);
51792
+ const spacingAfter = this.parseParagraphSpacingPx(
51793
+ pPr?.["a:spcAft"],
51794
+ spacingBasisPx
51795
+ );
51375
51796
  if (spacingAfter !== void 0) {
51376
51797
  textStyle.paragraphSpacingAfter = spacingAfter;
51377
51798
  }
@@ -51545,7 +51966,8 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
51545
51966
  ctx.txBody,
51546
51967
  ctx.inheritedTxBody,
51547
51968
  isBodyPlaceholder,
51548
- ctx.slidePath
51969
+ ctx.slidePath,
51970
+ ctx.effectiveLevelStyles
51549
51971
  );
51550
51972
  if (paragraphBulletInfo && !paragraphBulletInfo.none) {
51551
51973
  let bulletText;
@@ -52154,7 +52576,7 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52154
52576
  const skewY = xfrm["@_skewY"] ? parseEmuInt(xfrm["@_skewY"]) / 6e4 : void 0;
52155
52577
  const { flipHorizontal, flipVertical } = this.readFlipState(xfrm);
52156
52578
  const nvPr = pic?.["p:nvPicPr"]?.["p:nvPr"];
52157
- const mediaReference = parseDrawingMediaReference(nvPr);
52579
+ const mediaReference = parseDrawingMediaReference(nvPr, this.externalRelsMap.get(slidePath));
52158
52580
  if (mediaReference) {
52159
52581
  this.compatibilityService.inspectMediaReferenceCompatibility(
52160
52582
  mediaReference.kind,
@@ -52922,6 +53344,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52922
53344
  const grpSpPr = group["p:grpSpPr"];
52923
53345
  const xfrm = grpSpPr?.["a:xfrm"];
52924
53346
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
53347
+ let groupRotation;
53348
+ let flipHorizontal = false;
53349
+ let flipVertical = false;
52925
53350
  if (xfrm) {
52926
53351
  const off = xfrm["a:off"];
52927
53352
  if (off) {
@@ -52933,6 +53358,12 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52933
53358
  parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
52934
53359
  parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
52935
53360
  }
53361
+ if (xfrm["@_rot"] !== void 0 && xfrm["@_rot"] !== null) {
53362
+ const rot = parseInt(String(xfrm["@_rot"]), 10) / 6e4;
53363
+ groupRotation = Number.isFinite(rot) && rot !== 0 ? rot : void 0;
53364
+ }
53365
+ flipHorizontal = this.parseBooleanAttr(xfrm["@_flipH"]);
53366
+ flipVertical = this.parseBooleanAttr(xfrm["@_flipV"]);
52936
53367
  }
52937
53368
  const grpFillStyle = grpSpPr ? this.extractShapeStyle(grpSpPr) : void 0;
52938
53369
  const hasGroupFill = grpFillStyle && grpFillStyle.fillMode && grpFillStyle.fillMode !== "none";
@@ -52978,6 +53409,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
52978
53409
  y: parentY,
52979
53410
  width: parentW || Math.max(...children9.map((c) => c.x + c.width)),
52980
53411
  height: parentH || Math.max(...children9.map((c) => c.y + c.height)),
53412
+ rotation: groupRotation,
53413
+ flipHorizontal: flipHorizontal || void 0,
53414
+ flipVertical: flipVertical || void 0,
52981
53415
  children: children9,
52982
53416
  rawXml: group,
52983
53417
  actionClick: grpActionClick,
@@ -53148,6 +53582,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53148
53582
  if (!normalized) {
53149
53583
  return void 0;
53150
53584
  }
53585
+ const canon = (key) => key.toLowerCase() === "folhlink" ? "folHlink" : key;
53151
53586
  if (normalized === "phclr") {
53152
53587
  const injected = this.themeColorMap["phclr"];
53153
53588
  if (injected) {
@@ -53157,17 +53592,18 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
53157
53592
  }
53158
53593
  const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
53159
53594
  if (overrideMap) {
53160
- const remapped = overrideMap[normalized];
53595
+ const remapped = overrideMap[canon(normalized)];
53161
53596
  if (remapped) {
53162
- return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
53597
+ const target = canon(remapped);
53598
+ return this.themeColorMap[target] || this.getDefaultSchemeColorMap()[target];
53163
53599
  }
53164
53600
  } else {
53165
53601
  const defaultAliasTarget = DEFAULT_CLR_MAP_ALIAS[normalized];
53166
53602
  if (defaultAliasTarget) {
53167
- return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53603
+ return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53168
53604
  }
53169
53605
  }
53170
- return this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
53606
+ return this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
53171
53607
  }
53172
53608
  normalizeStrokeDashType(value) {
53173
53609
  const normalized = String(value ?? "").trim();
@@ -53950,11 +54386,24 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
53950
54386
  }
53951
54387
  }
53952
54388
  }
53953
- const spcBef = this.parseParagraphSpacingPx(levelProps["a:spcBef"]);
54389
+ const defRPrSzRaw = Number.parseInt(
54390
+ String(
54391
+ levelProps["a:defRPr"]?.["@_sz"] || ""
54392
+ ),
54393
+ 10
54394
+ );
54395
+ const basisFontSizePx = Number.isFinite(defRPrSzRaw) ? this.pointsToPixels(defRPrSzRaw / 100) : void 0;
54396
+ const spcBef = this.parseParagraphSpacingPx(
54397
+ levelProps["a:spcBef"],
54398
+ basisFontSizePx
54399
+ );
53954
54400
  if (spcBef !== void 0) {
53955
54401
  style.spaceBefore = spcBef;
53956
54402
  }
53957
- const spcAft = this.parseParagraphSpacingPx(levelProps["a:spcAft"]);
54403
+ const spcAft = this.parseParagraphSpacingPx(
54404
+ levelProps["a:spcAft"],
54405
+ basisFontSizePx
54406
+ );
53958
54407
  if (spcAft !== void 0) {
53959
54408
  style.spaceAfter = spcAft;
53960
54409
  }
@@ -53979,9 +54428,9 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
53979
54428
  }
53980
54429
  const buClr = levelProps["a:buClr"];
53981
54430
  if (buClr) {
53982
- const srgb = buClr["a:srgbClr"];
53983
- if (srgb?.["@_val"]) {
53984
- style.bulletColor = String(srgb["@_val"]);
54431
+ const bulletColor = this.parseColor(buClr);
54432
+ if (bulletColor) {
54433
+ style.bulletColor = bulletColor;
53985
54434
  }
53986
54435
  }
53987
54436
  const buSzPts = levelProps["a:buSzPts"];
@@ -56483,6 +56932,89 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
56483
56932
  }
56484
56933
  };
56485
56934
 
56935
+ // src/core/core/runtime/smartart-drawing-shape-style.ts
56936
+ function extractDrawingShapeFill(spPr, deps) {
56937
+ const result = {};
56938
+ const solidFill2 = deps.getChild(spPr, "solidFill");
56939
+ if (solidFill2) {
56940
+ result.fillColor = deps.parseColor(solidFill2) ?? void 0;
56941
+ }
56942
+ const gradFill = !solidFill2 ? deps.getChild(spPr, "gradFill") : void 0;
56943
+ if (gradFill) {
56944
+ const stops = deps.extractGradientStops(gradFill).map((stop) => ({
56945
+ color: stop.color,
56946
+ position: stop.position,
56947
+ ...stop.opacity !== void 0 ? { opacity: stop.opacity } : {}
56948
+ }));
56949
+ if (stops.length > 0) {
56950
+ result.fillGradientStops = stops;
56951
+ result.fillGradientType = deps.extractGradientType(gradFill);
56952
+ result.fillGradientAngle = deps.extractGradientAngle(gradFill);
56953
+ result.fillColor ??= stops[Math.floor(stops.length / 2)]?.color;
56954
+ }
56955
+ }
56956
+ const pattFill = !solidFill2 && !gradFill ? deps.getChild(spPr, "pattFill") : void 0;
56957
+ if (pattFill) {
56958
+ const preset = String(pattFill["@_prst"] || "").trim();
56959
+ if (preset) {
56960
+ result.fillPatternPreset = preset;
56961
+ }
56962
+ const fg = deps.parseColor(deps.getChild(pattFill, "fgClr"));
56963
+ const bg = deps.parseColor(deps.getChild(pattFill, "bgClr"));
56964
+ if (fg) {
56965
+ result.fillPatternForegroundColor = fg;
56966
+ }
56967
+ if (bg) {
56968
+ result.fillPatternBackgroundColor = bg;
56969
+ }
56970
+ result.fillColor ??= fg ?? bg;
56971
+ }
56972
+ const blipFill = !solidFill2 && !gradFill && !pattFill ? deps.getChild(spPr, "blipFill") : void 0;
56973
+ if (blipFill) {
56974
+ const blip = deps.getChild(blipFill, "blip");
56975
+ const embed = String(
56976
+ blip?.["@_r:embed"] || blip?.["@_embed"] || blip?.["@_r:link"] || ""
56977
+ ).trim();
56978
+ if (embed) {
56979
+ result.fillBlipEmbedId = embed;
56980
+ }
56981
+ }
56982
+ const shadowColor = deps.extractShadowColor(spPr);
56983
+ if (shadowColor) {
56984
+ result.hasShadow = true;
56985
+ result.shadowColor = shadowColor;
56986
+ }
56987
+ return result;
56988
+ }
56989
+ function extractDrawingShapeTextStyle(txBody, deps) {
56990
+ let fontSize;
56991
+ let fontColor;
56992
+ if (!txBody) {
56993
+ return { fontSize, fontColor };
56994
+ }
56995
+ const paragraphs = deps.getChildren(txBody, "p");
56996
+ for (const p of paragraphs) {
56997
+ const runs = deps.getChildren(p, "r");
56998
+ for (const r of runs) {
56999
+ const rPr = deps.getChild(r, "rPr");
57000
+ if (rPr && !fontSize) {
57001
+ const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
57002
+ if (Number.isFinite(szRaw) && szRaw > 0) {
57003
+ fontSize = szRaw / 100;
57004
+ }
57005
+ fontColor = deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
57006
+ }
57007
+ if (fontSize) {
57008
+ break;
57009
+ }
57010
+ }
57011
+ if (fontSize) {
57012
+ break;
57013
+ }
57014
+ }
57015
+ return { fontSize, fontColor };
57016
+ }
57017
+
56486
57018
  // src/core/core/runtime/smartart-text-style-resolution.ts
56487
57019
  function resolveSmartArtTextStyles(paragraphs, resolve2) {
56488
57020
  for (const paragraph of paragraphs ?? []) {
@@ -56658,8 +57190,7 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56658
57190
  };
56659
57191
  }
56660
57192
  }
56661
- const solidFill2 = this.xmlLookupService.getChildByLocalName(spPr, "solidFill");
56662
- const fillColor = this.parseColor(solidFill2);
57193
+ const fill = extractDrawingShapeFill(spPr, this.drawingShapeStyleDeps());
56663
57194
  const lnNode = this.xmlLookupService.getChildByLocalName(spPr, "ln");
56664
57195
  const lnFill = lnNode ? this.xmlLookupService.getChildByLocalName(lnNode, "solidFill") : void 0;
56665
57196
  const strokeColor = this.parseColor(lnFill);
@@ -56671,7 +57202,10 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56671
57202
  this.collectLocalTextValues(txBody, "t", textValues2);
56672
57203
  }
56673
57204
  const text2 = textValues2.join("").trim() || void 0;
56674
- const { fontSize, fontColor } = this.extractDrawingShapeTextStyle(txBody);
57205
+ const { fontSize, fontColor } = extractDrawingShapeTextStyle(
57206
+ txBody,
57207
+ this.drawingShapeStyleDeps()
57208
+ );
56675
57209
  const paragraphs = txBody ? resolveSmartArtTextStyles(
56676
57210
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
56677
57211
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -56697,7 +57231,8 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56697
57231
  rotation,
56698
57232
  skewX,
56699
57233
  skewY,
56700
- fillColor: fillColor ?? void 0,
57234
+ ...fill,
57235
+ fillColor: fill.fillColor ?? void 0,
56701
57236
  strokeColor: strokeColor ?? void 0,
56702
57237
  strokeWidth,
56703
57238
  text: structuredText,
@@ -56707,34 +57242,21 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
56707
57242
  ...customGeometry
56708
57243
  };
56709
57244
  }
56710
- extractDrawingShapeTextStyle(txBody) {
56711
- let fontSize;
56712
- let fontColor;
56713
- if (!txBody) {
56714
- return { fontSize, fontColor };
56715
- }
56716
- const paragraphs = this.xmlLookupService.getChildrenArrayByLocalName(txBody, "p");
56717
- for (const p of paragraphs) {
56718
- const runs = this.xmlLookupService.getChildrenArrayByLocalName(p, "r");
56719
- for (const r of runs) {
56720
- const rPr = this.xmlLookupService.getChildByLocalName(r, "rPr");
56721
- if (rPr && !fontSize) {
56722
- const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
56723
- if (Number.isFinite(szRaw) && szRaw > 0) {
56724
- fontSize = szRaw / 100;
56725
- }
56726
- const rprFill = this.xmlLookupService.getChildByLocalName(rPr, "solidFill");
56727
- fontColor = this.parseColor(rprFill) ?? void 0;
56728
- }
56729
- if (fontSize) {
56730
- break;
56731
- }
56732
- }
56733
- if (fontSize) {
56734
- break;
56735
- }
56736
- }
56737
- return { fontSize, fontColor };
57245
+ /**
57246
+ * Build the injected accessor bundle used by the pure drawing-shape style
57247
+ * helpers, binding the shared XML-lookup / colour / gradient / shadow codec
57248
+ * methods so no new colour logic is duplicated here.
57249
+ */
57250
+ drawingShapeStyleDeps() {
57251
+ return {
57252
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
57253
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
57254
+ parseColor: (node) => this.parseColor(node),
57255
+ extractGradientStops: (gradFill) => this.extractGradientStops(gradFill),
57256
+ extractGradientType: (gradFill) => this.extractGradientType(gradFill),
57257
+ extractGradientAngle: (gradFill) => this.extractGradientAngle(gradFill),
57258
+ extractShadowColor: (spPr) => this.extractShadowStyle(spPr).shadowColor
57259
+ };
56738
57260
  }
56739
57261
  };
56740
57262
 
@@ -59208,6 +59730,7 @@ var PptxHandlerRuntime95 = class _PptxHandlerRuntime extends PptxHandlerRuntime9
59208
59730
  });
59209
59731
  this.mediaDataParser = new PptxMediaDataParser({
59210
59732
  slideRelsMap: this.slideRelsMap,
59733
+ externalRelsMap: this.externalRelsMap,
59211
59734
  resolvePath: (base, relative) => this.resolvePath(base, relative),
59212
59735
  getPathExtension: (pathValue) => this.getPathExtension(pathValue)
59213
59736
  });