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.
package/dist/index.js CHANGED
@@ -7088,26 +7088,49 @@ function applyScene3dStyle(shapeProps, style) {
7088
7088
  const camera = scene3dNode["a:camera"];
7089
7089
  const lightRig = scene3dNode["a:lightRig"];
7090
7090
  const cameraRot = camera?.["a:rot"];
7091
+ const lightRigRot = lightRig?.["a:rot"];
7091
7092
  style.scene3d = {
7092
7093
  cameraPreset: String(camera?.["@_prst"] || "").trim() || void 0,
7093
- cameraRotX: cameraRot?.["@_lat"] !== void 0 ? parseInt(String(cameraRot["@_lat"]), 10) : void 0,
7094
- cameraRotY: cameraRot?.["@_lon"] !== void 0 ? parseInt(String(cameraRot["@_lon"]), 10) : void 0,
7095
- cameraRotZ: cameraRot?.["@_rev"] !== void 0 ? parseInt(String(cameraRot["@_rev"]), 10) : void 0,
7094
+ cameraFieldOfView: intAttr(camera?.["@_fov"]),
7095
+ cameraZoom: floatAttr(camera?.["@_zoom"]),
7096
+ cameraRotX: intAttr(cameraRot?.["@_lat"]),
7097
+ cameraRotY: intAttr(cameraRot?.["@_lon"]),
7098
+ cameraRotZ: intAttr(cameraRot?.["@_rev"]),
7096
7099
  lightRigType: String(lightRig?.["@_rig"] || "").trim() || void 0,
7097
- lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0
7100
+ lightRigDirection: String(lightRig?.["@_dir"] || "").trim() || void 0,
7101
+ lightRigRotX: intAttr(lightRigRot?.["@_lat"]),
7102
+ lightRigRotY: intAttr(lightRigRot?.["@_lon"]),
7103
+ lightRigRotZ: intAttr(lightRigRot?.["@_rev"])
7098
7104
  };
7099
7105
  const backdrop = scene3dNode["a:backdrop"];
7100
7106
  if (backdrop) {
7101
7107
  style.scene3d.hasBackdrop = true;
7102
7108
  const anchor = backdrop["a:anchor"];
7103
- const anchorAttrs = anchor;
7104
- if (anchorAttrs) {
7105
- style.scene3d.backdropAnchorX = parseInt(String(anchorAttrs["@_x"] || "0"), 10);
7106
- style.scene3d.backdropAnchorY = parseInt(String(anchorAttrs["@_y"] || "0"), 10);
7107
- style.scene3d.backdropAnchorZ = parseInt(String(anchorAttrs["@_z"] || "0"), 10);
7109
+ if (anchor) {
7110
+ style.scene3d.backdropAnchorX = intAttr(anchor["@_x"]) ?? 0;
7111
+ style.scene3d.backdropAnchorY = intAttr(anchor["@_y"]) ?? 0;
7112
+ style.scene3d.backdropAnchorZ = intAttr(anchor["@_z"]) ?? 0;
7113
+ }
7114
+ const norm = backdrop["a:norm"];
7115
+ if (norm) {
7116
+ style.scene3d.backdropNormalX = intAttr(norm["@_dx"]) ?? 0;
7117
+ style.scene3d.backdropNormalY = intAttr(norm["@_dy"]) ?? 0;
7118
+ style.scene3d.backdropNormalZ = intAttr(norm["@_dz"]) ?? 0;
7119
+ }
7120
+ const up = backdrop["a:up"];
7121
+ if (up) {
7122
+ style.scene3d.backdropUpX = intAttr(up["@_dx"]) ?? 0;
7123
+ style.scene3d.backdropUpY = intAttr(up["@_dy"]) ?? 0;
7124
+ style.scene3d.backdropUpZ = intAttr(up["@_dz"]) ?? 0;
7108
7125
  }
7109
7126
  }
7110
7127
  }
7128
+ function intAttr(value) {
7129
+ return value !== void 0 ? parseInt(String(value), 10) : void 0;
7130
+ }
7131
+ function floatAttr(value) {
7132
+ return value !== void 0 ? parseFloat(String(value)) : void 0;
7133
+ }
7111
7134
  function applyShape3dStyle(shapeProps, style, context) {
7112
7135
  const shape3dNode = shapeProps["a:sp3d"];
7113
7136
  if (!shape3dNode) {
@@ -7989,7 +8012,7 @@ var MEDIA_REFERENCE_NAMES = [
7989
8012
  "videoFile",
7990
8013
  "quickTimeFile"
7991
8014
  ];
7992
- function parseDrawingMediaReference(container) {
8015
+ function parseDrawingMediaReference(container, externalRelIds) {
7993
8016
  if (!container) {
7994
8017
  return void 0;
7995
8018
  }
@@ -7998,11 +8021,17 @@ function parseDrawingMediaReference(container) {
7998
8021
  if (!node) {
7999
8022
  continue;
8000
8023
  }
8024
+ const linkId = String(attribute2(node, "link") ?? "").trim() || void 0;
8025
+ const embedId = String(attribute2(node, "embed") ?? "").trim() || void 0;
8001
8026
  return {
8002
8027
  kind,
8003
8028
  mediaType: kind === "videoFile" || kind === "quickTimeFile" ? "video" : "audio",
8004
- relationshipId: String(attribute2(node, "link") ?? attribute2(node, "embed") ?? "").trim() || void 0,
8005
- isLinked: attribute2(node, "link") !== void 0,
8029
+ relationshipId: linkId ?? embedId,
8030
+ // Embedded media legitimately uses r:link pointing at an INTERNAL
8031
+ // media part, so link presence alone does not imply a linked clip.
8032
+ // It is only truly linked when the referenced relationship is
8033
+ // external (TargetMode="External"), mirroring the OLE parser.
8034
+ isLinked: linkId !== void 0 && externalRelIds?.has(linkId) === true,
8006
8035
  name: kind === "wavAudioFile" ? String(attribute2(node, "name") ?? "") || void 0 : void 0,
8007
8036
  contentType: kind === "audioFile" ? String(attribute2(node, "contentType") ?? "") || void 0 : void 0,
8008
8037
  audioCdStart: kind === "audioCd" ? parseAudioCdPosition(child2(node, "st")) : void 0,
@@ -8133,7 +8162,10 @@ var PptxMediaDataParser = class {
8133
8162
  parseMediaData(graphicData, slidePath) {
8134
8163
  const result = {};
8135
8164
  try {
8136
- const reference = parseDrawingMediaReference(graphicData);
8165
+ const reference = parseDrawingMediaReference(
8166
+ graphicData,
8167
+ this.context.externalRelsMap.get(slidePath)
8168
+ );
8137
8169
  if (reference) {
8138
8170
  result.mediaType = reference.mediaType;
8139
8171
  result.mediaReferenceKind = reference.kind;
@@ -13090,6 +13122,7 @@ var PptxNativeAnimationService = class {
13090
13122
  const nodeType = String(cTn["@_nodeType"] || "");
13091
13123
  const presetClass = cTn["@_presetClass"];
13092
13124
  const presetId = cTn["@_presetID"] ? Number.parseInt(String(cTn["@_presetID"]), 10) : void 0;
13125
+ const presetSubtype = cTn["@_presetSubtype"] !== void 0 ? Number.parseInt(String(cTn["@_presetSubtype"]), 10) : void 0;
13093
13126
  const durationMs = cTn["@_dur"] ? Number.parseInt(String(cTn["@_dur"]), 10) : void 0;
13094
13127
  const delayMs = cTn["@_delay"] ? Number.parseInt(String(cTn["@_delay"]), 10) : void 0;
13095
13128
  let trigger = currentTrigger;
@@ -13141,6 +13174,7 @@ var PptxNativeAnimationService = class {
13141
13174
  trigger,
13142
13175
  presetClass: validPresetClass,
13143
13176
  presetId,
13177
+ presetSubtype,
13144
13178
  durationMs,
13145
13179
  delayMs,
13146
13180
  triggerDelayMs: trigger === "afterDelay" ? delayMs : void 0,
@@ -13451,6 +13485,74 @@ function buildP14ExtLst(transitionType, direction, orient, pattern, rawExtLst, x
13451
13485
  return { "p:ext": transitionExt };
13452
13486
  }
13453
13487
 
13488
+ // src/core/services/p15-transition-parser.ts
13489
+ var P15_TRANSITION_PRESETS = /* @__PURE__ */ new Set([
13490
+ "fallOver",
13491
+ "drape",
13492
+ "curtains",
13493
+ "wind",
13494
+ "prestige",
13495
+ "fracture",
13496
+ "crush",
13497
+ "peelOff",
13498
+ "pageCurlDouble",
13499
+ "pageCurlSingle",
13500
+ "airplane",
13501
+ "origami"
13502
+ ]);
13503
+ var PRSTTRANS_EXT_URI = "{D42A27DB-BD31-4B8C-83A1-F6EECF244321}";
13504
+ function optionalBoolean(value) {
13505
+ const valueToken = value === void 0 || value === null ? "" : String(value).trim().toLowerCase();
13506
+ if (valueToken === "1" || valueToken === "true") {
13507
+ return true;
13508
+ }
13509
+ if (valueToken === "0" || valueToken === "false") {
13510
+ return false;
13511
+ }
13512
+ return void 0;
13513
+ }
13514
+ function parseP15FromExtLst(extLstNode, xmlLookupService, getXmlLocalName) {
13515
+ const extEntries = xmlLookupService.getChildrenArrayByLocalName(extLstNode, "ext");
13516
+ for (const ext of extEntries) {
13517
+ if (!ext) {
13518
+ continue;
13519
+ }
13520
+ for (const [key, value] of Object.entries(ext)) {
13521
+ if (key.startsWith("@_")) {
13522
+ continue;
13523
+ }
13524
+ if (getXmlLocalName(key) !== "prstTrans") {
13525
+ continue;
13526
+ }
13527
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
13528
+ continue;
13529
+ }
13530
+ const detail = value;
13531
+ const prst = String(detail["@_prst"] || "").trim();
13532
+ if (!P15_TRANSITION_PRESETS.has(prst)) {
13533
+ continue;
13534
+ }
13535
+ return {
13536
+ type: prst,
13537
+ invX: optionalBoolean(detail["@_invX"]),
13538
+ invY: optionalBoolean(detail["@_invY"])
13539
+ };
13540
+ }
13541
+ }
13542
+ return void 0;
13543
+ }
13544
+ function buildP15ExtLst(transitionType, invX, invY) {
13545
+ const prstTrans = {
13546
+ "@_xmlns:p15": "http://schemas.microsoft.com/office/powerpoint/2012/main",
13547
+ "@_prst": transitionType
13548
+ };
13549
+ const ext = {
13550
+ "@_uri": PRSTTRANS_EXT_URI,
13551
+ "p15:prstTrans": prstTrans
13552
+ };
13553
+ return { "p:ext": ext };
13554
+ }
13555
+
13454
13556
  // src/core/services/slide-transition-xml.ts
13455
13557
  var STANDARD_TRANSITION_TYPES = /* @__PURE__ */ new Set([
13456
13558
  "fade",
@@ -13516,7 +13618,7 @@ function parseTransitionDetails(node, localName22) {
13516
13618
  if (pattern) {
13517
13619
  result.pattern = pattern;
13518
13620
  }
13519
- const thruBlk = optionalBoolean(detail["@_thruBlk"]);
13621
+ const thruBlk = optionalBoolean2(detail["@_thruBlk"]);
13520
13622
  if (thruBlk !== void 0) {
13521
13623
  result.thruBlk = thruBlk;
13522
13624
  }
@@ -13527,7 +13629,7 @@ function parseTransitionAttributes(node) {
13527
13629
  const speedToken = token(node["@_spd"]);
13528
13630
  const speed = SPEEDS.has(speedToken) ? speedToken : void 0;
13529
13631
  const durationMs = unsignedInteger2(node["@_dur"] ?? node["@_p14:dur"], 1);
13530
- const advanceOnClick = optionalBoolean(node["@_advClick"]);
13632
+ const advanceOnClick = optionalBoolean2(node["@_advClick"]);
13531
13633
  const advanceAfterMs = unsignedInteger2(node["@_advTm"]);
13532
13634
  return { speed, durationMs, advanceOnClick, advanceAfterMs };
13533
13635
  }
@@ -13541,7 +13643,7 @@ function parseTransitionSound(raw, lookup, localName22) {
13541
13643
  return {
13542
13644
  soundRId: sound ? attributeByLocalName(sound, "embed", localName22) : void 0,
13543
13645
  soundName: sound ? attributeByLocalName(sound, "name", localName22) : void 0,
13544
- soundLoop: optionalBoolean(start["@_loop"])
13646
+ soundLoop: optionalBoolean2(start["@_loop"])
13545
13647
  };
13546
13648
  }
13547
13649
  const stopSound = Object.keys(raw).some(
@@ -13650,7 +13752,7 @@ function attributeByLocalName(node, name, localName22) {
13650
13752
  function token(value) {
13651
13753
  return value === void 0 || value === null ? "" : String(value).trim();
13652
13754
  }
13653
- function optionalBoolean(value) {
13755
+ function optionalBoolean2(value) {
13654
13756
  const valueToken = token(value).toLowerCase();
13655
13757
  if (!valueToken) {
13656
13758
  return void 0;
@@ -13696,6 +13798,7 @@ var PptxSlideTransitionService = class {
13696
13798
  const { spokes, thruBlk, rawSoundAction, rawExtLst } = details;
13697
13799
  if (rawExtLst && transitionType === "cut") {
13698
13800
  const p14Result = parseP14FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
13801
+ const p15Result = p14Result ? void 0 : parseP15FromExtLst(rawExtLst, this.xmlLookupService, this.getXmlLocalName);
13699
13802
  if (p14Result) {
13700
13803
  transitionType = p14Result.type;
13701
13804
  if (p14Result.direction) {
@@ -13707,6 +13810,8 @@ var PptxSlideTransitionService = class {
13707
13810
  if (p14Result.pattern) {
13708
13811
  pattern = p14Result.pattern;
13709
13812
  }
13813
+ } else if (p15Result) {
13814
+ transitionType = p15Result.type;
13710
13815
  } else if (this.parseMorphFromExtLst(rawExtLst)) {
13711
13816
  transitionType = "morph";
13712
13817
  }
@@ -13788,6 +13893,7 @@ var PptxSlideTransitionService = class {
13788
13893
  }
13789
13894
  const transitionType = transition.type || "cut";
13790
13895
  const isP14Type = P14_TRANSITION_TYPES.has(transitionType);
13896
+ const isP15Type = P15_TRANSITION_PRESETS.has(transitionType);
13791
13897
  const isMorphType = transitionType === "morph";
13792
13898
  const node = createPreservedTransitionNode(transition.rawTransition, this.getXmlLocalName);
13793
13899
  if (isP14Type) {
@@ -13800,6 +13906,8 @@ var PptxSlideTransitionService = class {
13800
13906
  this.xmlLookupService,
13801
13907
  this.getXmlLocalName
13802
13908
  );
13909
+ } else if (isP15Type) {
13910
+ node["p:extLst"] = transition.rawExtLst ?? buildP15ExtLst(transitionType);
13803
13911
  } else if (isMorphType) {
13804
13912
  node["p:extLst"] = this.buildMorphExtLst(transition.rawExtLst);
13805
13913
  } else {
@@ -13810,7 +13918,7 @@ var PptxSlideTransitionService = class {
13810
13918
  if (soundAction) {
13811
13919
  node["p:sndAc"] = soundAction;
13812
13920
  }
13813
- if (transition.rawExtLst && !isP14Type && !isMorphType) {
13921
+ if (transition.rawExtLst && !isP14Type && !isP15Type && !isMorphType) {
13814
13922
  node["p:extLst"] = transition.rawExtLst;
13815
13923
  }
13816
13924
  return node;
@@ -23173,15 +23281,15 @@ function getConnectorPathGeometry(element) {
23173
23281
  // src/core/geometry/transform-utils.ts
23174
23282
  function getElementTransform(element) {
23175
23283
  const transforms = [];
23284
+ if (element.rotation) {
23285
+ transforms.push(`rotate(${element.rotation}deg)`);
23286
+ }
23176
23287
  if (element.flipHorizontal) {
23177
23288
  transforms.push("scaleX(-1)");
23178
23289
  }
23179
23290
  if (element.flipVertical) {
23180
23291
  transforms.push("scaleY(-1)");
23181
23292
  }
23182
- if (element.rotation) {
23183
- transforms.push(`rotate(${element.rotation}deg)`);
23184
- }
23185
23293
  return transforms.length > 0 ? transforms.join(" ") : void 0;
23186
23294
  }
23187
23295
  function getTextCompensationTransform(element) {
@@ -29820,36 +29928,200 @@ async function fetchUrlToBytes(url, options = {}) {
29820
29928
  }
29821
29929
  }
29822
29930
 
29931
+ // src/core/utils/inkml-trace-decode.ts
29932
+ function resolveChannelOrder(root) {
29933
+ const traceFormat = findFirstByLocalName(root, "traceFormat");
29934
+ if (!traceFormat) {
29935
+ return ["X", "Y"];
29936
+ }
29937
+ const channels = ensureArray5(nsGet(traceFormat, "channel"));
29938
+ const names = channels.map(
29939
+ (channel) => String(nsAttr(channel, "name") ?? "").trim().toUpperCase()
29940
+ ).filter((name) => name.length > 0);
29941
+ return names.length > 0 ? names : ["X", "Y"];
29942
+ }
29943
+ function decodeTracePoints(text2, channelOrder) {
29944
+ const points3 = [];
29945
+ const modes = channelOrder.map(() => "explicit");
29946
+ const lastValue = channelOrder.map(() => 0);
29947
+ const lastVelocity = channelOrder.map(() => 0);
29948
+ for (const rawPoint of text2.split(",")) {
29949
+ const tokens = rawPoint.trim().split(/\s+/u).filter((token2) => token2.length > 0);
29950
+ if (tokens.length === 0) {
29951
+ continue;
29952
+ }
29953
+ const decoded = [];
29954
+ for (let i = 0; i < tokens.length && i < channelOrder.length; i++) {
29955
+ const parsed = parseValueToken(tokens[i], modes[i]);
29956
+ if (parsed === void 0) {
29957
+ decoded.push(lastValue[i]);
29958
+ continue;
29959
+ }
29960
+ modes[i] = parsed.mode;
29961
+ const value = applyDiffMode(parsed, i, lastValue, lastVelocity);
29962
+ decoded.push(value);
29963
+ }
29964
+ if (decoded.length >= 2) {
29965
+ points3.push(decoded);
29966
+ }
29967
+ }
29968
+ return points3;
29969
+ }
29970
+ function parseValueToken(token2, currentMode) {
29971
+ let mode = currentMode;
29972
+ let body = token2;
29973
+ const prefix = token2[0];
29974
+ if (prefix === "!") {
29975
+ mode = "explicit";
29976
+ body = token2.slice(1);
29977
+ } else if (prefix === "'") {
29978
+ mode = "single";
29979
+ body = token2.slice(1);
29980
+ } else if (prefix === '"') {
29981
+ mode = "double";
29982
+ body = token2.slice(1);
29983
+ }
29984
+ if (body.length === 0) {
29985
+ return void 0;
29986
+ }
29987
+ const value = Number(body);
29988
+ return Number.isFinite(value) ? { value, mode } : void 0;
29989
+ }
29990
+ function applyDiffMode(parsed, index, lastValue, lastVelocity) {
29991
+ if (parsed.mode === "single") {
29992
+ lastVelocity[index] = parsed.value;
29993
+ lastValue[index] += parsed.value;
29994
+ } else if (parsed.mode === "double") {
29995
+ lastVelocity[index] += parsed.value;
29996
+ lastValue[index] += lastVelocity[index];
29997
+ } else {
29998
+ lastValue[index] = parsed.value;
29999
+ lastVelocity[index] = 0;
30000
+ }
30001
+ return lastValue[index];
30002
+ }
30003
+ function pointsToSvgPath(points3, channelOrder) {
30004
+ const xi = channelOrder.indexOf("X");
30005
+ const yi = channelOrder.indexOf("Y");
30006
+ const xIndex = xi >= 0 ? xi : 0;
30007
+ const yIndex = yi >= 0 ? yi : 1;
30008
+ const segments = [];
30009
+ for (const point of points3) {
30010
+ const x = point[xIndex];
30011
+ const y = point[yIndex];
30012
+ if (!Number.isFinite(x) || !Number.isFinite(y)) {
30013
+ continue;
30014
+ }
30015
+ segments.push(`${segments.length === 0 ? "M" : "L"} ${x} ${y}`);
30016
+ }
30017
+ return segments.join(" ");
30018
+ }
30019
+ function pointsToPressures(points3, channelOrder) {
30020
+ const fIndex = channelOrder.indexOf("F");
30021
+ if (fIndex < 0) {
30022
+ return [];
30023
+ }
30024
+ const pressures = [];
30025
+ for (const point of points3) {
30026
+ const raw = point[fIndex];
30027
+ if (Number.isFinite(raw)) {
30028
+ const normalised = raw > 1 ? raw / 32767 : raw;
30029
+ pressures.push(Math.max(0, Math.min(1, normalised)));
30030
+ }
30031
+ }
30032
+ return pressures;
30033
+ }
30034
+ function nsGet(obj, localName22) {
30035
+ if (localName22 in obj) {
30036
+ return obj[localName22];
30037
+ }
30038
+ for (const key of Object.keys(obj)) {
30039
+ if (localNameOf(key) === localName22 && !key.startsWith("@_")) {
30040
+ return obj[key];
30041
+ }
30042
+ }
30043
+ return void 0;
30044
+ }
30045
+ function nsAttr(obj, localName22) {
30046
+ const direct = obj[`@_${localName22}`];
30047
+ if (direct !== void 0) {
30048
+ return direct;
30049
+ }
30050
+ for (const key of Object.keys(obj)) {
30051
+ if (key.startsWith("@_") && localNameOf(key.slice(2)) === localName22) {
30052
+ return obj[key];
30053
+ }
30054
+ }
30055
+ return void 0;
30056
+ }
30057
+ function localNameOf(key) {
30058
+ const colon = key.indexOf(":");
30059
+ return colon >= 0 ? key.slice(colon + 1) : key;
30060
+ }
30061
+ function findFirstByLocalName(node, localName22) {
30062
+ const direct = nsGet(node, localName22);
30063
+ if (direct && typeof direct === "object") {
30064
+ return Array.isArray(direct) ? direct[0] : direct;
30065
+ }
30066
+ for (const key of Object.keys(node)) {
30067
+ if (key.startsWith("@_") || key === "#text") {
30068
+ continue;
30069
+ }
30070
+ for (const child20 of ensureArray5(node[key])) {
30071
+ if (typeof child20 !== "object") {
30072
+ continue;
30073
+ }
30074
+ const found = findFirstByLocalName(child20, localName22);
30075
+ if (found) {
30076
+ return found;
30077
+ }
30078
+ }
30079
+ }
30080
+ return void 0;
30081
+ }
30082
+ function ensureArray5(value) {
30083
+ if (value === void 0 || value === null) {
30084
+ return [];
30085
+ }
30086
+ return Array.isArray(value) ? value : [value];
30087
+ }
30088
+
29823
30089
  // src/core/utils/inkml-content-part.ts
29824
30090
  var INKML_NAMESPACE = "http://www.w3.org/2003/InkML";
29825
30091
  var METADATA_NAMESPACE = "https://pptx-viewer.dev/inkml/metadata";
29826
30092
  function parseInkMlContent(data) {
29827
- const root = data["ink:ink"] ?? data["ink"];
30093
+ const root = nsGet(data, "ink") ?? data["ink"];
29828
30094
  if (!root) {
29829
30095
  return { strokes: [], rawXml: data };
29830
30096
  }
29831
30097
  const brushes = /* @__PURE__ */ new Map();
29832
- for (const brush of ensureArray5(root["ink:brush"] ?? root["brush"])) {
29833
- const properties = ensureArray5(brush["ink:brushProperty"] ?? brush["brushProperty"]);
30098
+ for (const brush of ensureArray5(nsGet(root, "brush"))) {
30099
+ const properties = ensureArray5(nsGet(brush, "brushProperty"));
29834
30100
  const valueByName = new Map(
29835
- properties.map((property) => [String(property["@_name"] ?? ""), property["@_value"]])
30101
+ properties.map((property) => [
30102
+ String(nsAttr(property, "name") ?? ""),
30103
+ nsAttr(property, "value")
30104
+ ])
29836
30105
  );
29837
- brushes.set(String(brush["@_id"] ?? ""), {
30106
+ brushes.set(String(nsAttr(brush, "id") ?? ""), {
29838
30107
  color: String(valueByName.get("color") ?? "#000000"),
29839
30108
  width: finiteNumber(valueByName.get("width"), 1),
29840
30109
  opacity: finiteNumber(valueByName.get("opacity"), 1)
29841
30110
  });
29842
30111
  }
30112
+ const channelOrder = resolveChannelOrder(root);
29843
30113
  const strokes = [];
29844
- for (const trace of ensureArray5(root["ink:trace"] ?? root["trace"])) {
30114
+ for (const trace of ensureArray5(nsGet(root, "trace"))) {
29845
30115
  const text2 = typeof trace === "string" ? trace : String(trace["#text"] ?? "").trim();
29846
- const path = typeof trace === "string" ? text2 : String(trace["@_pva:path"] ?? "").trim() || text2;
30116
+ const authored = typeof trace === "string" ? "" : String(nsAttr(trace, "path") ?? "").trim();
30117
+ const points3 = authored ? [] : decodeTracePoints(text2, channelOrder);
30118
+ const path = authored || pointsToSvgPath(points3, channelOrder);
29847
30119
  if (!path) {
29848
30120
  continue;
29849
30121
  }
29850
- const brushRef = typeof trace === "string" ? "" : String(trace["@_brushRef"] ?? "").replace("#", "");
30122
+ const brushRef = typeof trace === "string" ? "" : String(nsAttr(trace, "brushRef") ?? "").replace("#", "");
29851
30123
  const brush = brushes.get(brushRef) ?? { color: "#000000", width: 1, opacity: 1 };
29852
- const pressures = tracePressures(text2);
30124
+ const pressures = authored ? tracePressures(text2) : pointsToPressures(points3, channelOrder);
29853
30125
  strokes.push({ ...brush, path, ...pressures.length > 0 ? { pressures } : {} });
29854
30126
  }
29855
30127
  return { strokes, rawXml: data };
@@ -29908,12 +30180,6 @@ function finiteNumber(value, fallback) {
29908
30180
  const parsed = Number(value);
29909
30181
  return Number.isFinite(parsed) ? parsed : fallback;
29910
30182
  }
29911
- function ensureArray5(value) {
29912
- if (value === void 0 || value === null) {
29913
- return [];
29914
- }
29915
- return Array.isArray(value) ? value : [value];
29916
- }
29917
30183
 
29918
30184
  // src/core/utils/smartart-helpers.ts
29919
30185
  var DEFAULT_ACCENT_COLORS = [
@@ -47335,6 +47601,93 @@ var PptxHandlerRuntime = class {
47335
47601
  }
47336
47602
  };
47337
47603
 
47604
+ // src/core/core/runtime/table-style-border-parse.ts
47605
+ var EMU_PER_PIXEL = 9525;
47606
+ var BORDER_SIDES = [
47607
+ "left",
47608
+ "right",
47609
+ "top",
47610
+ "bottom",
47611
+ "insideH",
47612
+ "insideV",
47613
+ "tl2br",
47614
+ "bl2tr"
47615
+ ];
47616
+ function parseSolidFillStyle(solidFill2) {
47617
+ if (!solidFill2) {
47618
+ return void 0;
47619
+ }
47620
+ const schemeClr = solidFill2["a:schemeClr"];
47621
+ if (!schemeClr) {
47622
+ return void 0;
47623
+ }
47624
+ const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
47625
+ if (!schemeColor) {
47626
+ return void 0;
47627
+ }
47628
+ const tintRaw = schemeClr["a:tint"];
47629
+ const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
47630
+ const shadeRaw = schemeClr["a:shade"];
47631
+ const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
47632
+ return { schemeColor, tint, shade };
47633
+ }
47634
+ function parseBorderSide(side) {
47635
+ if (!side) {
47636
+ return void 0;
47637
+ }
47638
+ const ln = side["a:ln"];
47639
+ if (!ln) {
47640
+ return void 0;
47641
+ }
47642
+ const border = {};
47643
+ let has = false;
47644
+ if (ln["a:noFill"] !== void 0) {
47645
+ border.noFill = true;
47646
+ has = true;
47647
+ }
47648
+ const widthEmu = parseInt(String(ln["@_w"] || "0"), 10);
47649
+ if (widthEmu > 0) {
47650
+ border.width = Math.max(1, Math.round(widthEmu / EMU_PER_PIXEL));
47651
+ has = true;
47652
+ }
47653
+ const prstDash = ln["a:prstDash"];
47654
+ const dashVal = prstDash ? String(prstDash["@_val"] || "").trim() : "";
47655
+ if (dashVal) {
47656
+ border.dash = dashVal;
47657
+ has = true;
47658
+ }
47659
+ const solidFill2 = ln["a:solidFill"];
47660
+ const fill = parseSolidFillStyle(solidFill2);
47661
+ if (fill) {
47662
+ border.fill = fill;
47663
+ has = true;
47664
+ } else {
47665
+ const srgb = solidFill2?.["a:srgbClr"];
47666
+ const hex10 = srgb ? String(srgb["@_val"] || "").trim() : "";
47667
+ if (hex10) {
47668
+ border.color = hex10.startsWith("#") ? hex10 : `#${hex10}`;
47669
+ has = true;
47670
+ }
47671
+ }
47672
+ return has ? border : void 0;
47673
+ }
47674
+ function parseTableStyleBorders(tcStyle) {
47675
+ const tcBdr = tcStyle?.["a:tcBdr"];
47676
+ if (!tcBdr) {
47677
+ return void 0;
47678
+ }
47679
+ const result = {};
47680
+ let has = false;
47681
+ for (const name of BORDER_SIDES) {
47682
+ const border = parseBorderSide(tcBdr[`a:${name}`]);
47683
+ if (border) {
47684
+ result[name] = border;
47685
+ has = true;
47686
+ }
47687
+ }
47688
+ return has ? result : void 0;
47689
+ }
47690
+
47338
47691
  // src/core/core/runtime/PptxHandlerRuntimeTableStyles.ts
47339
47692
  var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47340
47693
  /**
@@ -47419,30 +47772,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47419
47772
  return void 0;
47420
47773
  }
47421
47774
  const tcStyle = section["a:tcStyle"];
47422
- if (!tcStyle) {
47423
- return void 0;
47424
- }
47425
- const fill = tcStyle["a:fill"];
47426
- if (!fill) {
47427
- return void 0;
47428
- }
47429
- const solidFill2 = fill["a:solidFill"];
47430
- if (!solidFill2) {
47431
- return void 0;
47432
- }
47433
- const schemeClr = solidFill2["a:schemeClr"];
47434
- if (!schemeClr) {
47435
- return void 0;
47436
- }
47437
- const schemeColor = String(schemeClr["@_val"] || "").trim() || void 0;
47438
- if (!schemeColor) {
47439
- return void 0;
47440
- }
47441
- const tintRaw = schemeClr["a:tint"];
47442
- const tint = tintRaw ? parseInt(String(tintRaw["@_val"] || "0"), 10) || void 0 : void 0;
47443
- const shadeRaw = schemeClr["a:shade"];
47444
- const shade = shadeRaw ? parseInt(String(shadeRaw["@_val"] || "0"), 10) || void 0 : void 0;
47445
- return { schemeColor, tint, shade };
47775
+ const fill = tcStyle?.["a:fill"];
47776
+ return parseSolidFillStyle(fill?.["a:solidFill"]);
47777
+ }
47778
+ /**
47779
+ * Extract border styling from a table style section's
47780
+ * `a:tcStyle/a:tcBdr` (per-side line width, dash, and colour).
47781
+ */
47782
+ extractTableStyleSectionBorders(section) {
47783
+ return parseTableStyleBorders(section?.["a:tcStyle"]);
47446
47784
  }
47447
47785
  /**
47448
47786
  * Extract text properties from a:tcTxStyle in a table style section.
@@ -47589,6 +47927,15 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47589
47927
  textProps[`${name}Text`] = text2;
47590
47928
  }
47591
47929
  }
47930
+ const borderProps = {};
47931
+ for (const name of sectionNames) {
47932
+ const borders = this.extractTableStyleSectionBorders(
47933
+ style[`a:${name}`]
47934
+ );
47935
+ if (borders) {
47936
+ borderProps[`${name}Borders`] = borders;
47937
+ }
47938
+ }
47592
47939
  const entry = {
47593
47940
  styleId,
47594
47941
  styleName,
@@ -47607,7 +47954,8 @@ var PptxHandlerRuntime2 = class extends PptxHandlerRuntime {
47607
47954
  ...swCellFill ? { swCellFill } : {},
47608
47955
  ...neCellFill ? { neCellFill } : {},
47609
47956
  ...nwCellFill ? { nwCellFill } : {},
47610
- ...textProps
47957
+ ...textProps,
47958
+ ...borderProps
47611
47959
  };
47612
47960
  map[styleId] = entry;
47613
47961
  }
@@ -49418,6 +49766,15 @@ var PptxHandlerRuntime11 = class extends PptxHandlerRuntime10 {
49418
49766
  if (align === "justify") {
49419
49767
  return "just";
49420
49768
  }
49769
+ if (align === "justLow") {
49770
+ return "justLow";
49771
+ }
49772
+ if (align === "dist") {
49773
+ return "dist";
49774
+ }
49775
+ if (align === "thaiDist") {
49776
+ return "thaiDist";
49777
+ }
49421
49778
  return void 0;
49422
49779
  }
49423
49780
  pixelsToPoints(px2) {
@@ -50472,6 +50829,16 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
50472
50829
  const chOffY = 0;
50473
50830
  const chExtCx = extCx;
50474
50831
  const chExtCy = extCy;
50832
+ const xfrmAttrs = {};
50833
+ if (typeof group.rotation === "number" && group.rotation !== 0) {
50834
+ xfrmAttrs["@_rot"] = String(Math.round(group.rotation * 6e4));
50835
+ }
50836
+ if (group.flipHorizontal) {
50837
+ xfrmAttrs["@_flipH"] = "1";
50838
+ }
50839
+ if (group.flipVertical) {
50840
+ xfrmAttrs["@_flipV"] = "1";
50841
+ }
50475
50842
  const grpXml = {
50476
50843
  "p:nvGrpSpPr": {
50477
50844
  "p:cNvPr": { "@_id": "0", "@_name": group.id },
@@ -50480,6 +50847,7 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
50480
50847
  },
50481
50848
  "p:grpSpPr": {
50482
50849
  "a:xfrm": {
50850
+ ...xfrmAttrs,
50483
50851
  "a:off": {
50484
50852
  "@_x": String(offX),
50485
50853
  "@_y": String(offY)
@@ -56668,45 +57036,18 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56668
57036
  const s3d = shapeStyle.scene3d;
56669
57037
  const hasData = s3d.cameraPreset || s3d.lightRigType;
56670
57038
  if (hasData) {
56671
- const cameraObj = {};
56672
- if (s3d.cameraPreset) {
56673
- cameraObj["@_prst"] = s3d.cameraPreset;
56674
- }
56675
- if (s3d.cameraRotX !== void 0 || s3d.cameraRotY !== void 0 || s3d.cameraRotZ !== void 0) {
56676
- const rot = {};
56677
- if (s3d.cameraRotX !== void 0) {
56678
- rot["@_lat"] = String(s3d.cameraRotX);
56679
- }
56680
- if (s3d.cameraRotY !== void 0) {
56681
- rot["@_lon"] = String(s3d.cameraRotY);
56682
- }
56683
- if (s3d.cameraRotZ !== void 0) {
56684
- rot["@_rev"] = String(s3d.cameraRotZ);
56685
- }
56686
- cameraObj["a:rot"] = rot;
56687
- }
56688
- const lightRigObj = {};
56689
- if (s3d.lightRigType) {
56690
- lightRigObj["@_rig"] = s3d.lightRigType;
56691
- }
56692
- if (s3d.lightRigDirection) {
56693
- lightRigObj["@_dir"] = s3d.lightRigDirection;
56694
- }
56695
- const scene3dXml = {};
56696
- scene3dXml["a:camera"] = cameraObj;
56697
- if (Object.keys(lightRigObj).length > 0) {
56698
- scene3dXml["a:lightRig"] = lightRigObj;
56699
- }
56700
- if (s3d.hasBackdrop) {
56701
- const backdropObj = {};
56702
- if (s3d.backdropAnchorX !== void 0 || s3d.backdropAnchorY !== void 0 || s3d.backdropAnchorZ !== void 0) {
56703
- backdropObj["a:anchor"] = {
56704
- "@_x": String(s3d.backdropAnchorX ?? 0),
56705
- "@_y": String(s3d.backdropAnchorY ?? 0),
56706
- "@_z": String(s3d.backdropAnchorZ ?? 0)
56707
- };
56708
- }
56709
- scene3dXml["a:backdrop"] = backdropObj;
57039
+ const source = spPr["a:scene3d"] ?? {};
57040
+ const scene3dXml = { ...source };
57041
+ scene3dXml["a:camera"] = buildScene3dCamera(s3d, source);
57042
+ const lightRig = buildScene3dLightRig(s3d, source);
57043
+ if (lightRig) {
57044
+ scene3dXml["a:lightRig"] = lightRig;
57045
+ }
57046
+ const backdrop = buildScene3dBackdrop(s3d);
57047
+ if (backdrop) {
57048
+ scene3dXml["a:backdrop"] = backdrop;
57049
+ } else {
57050
+ delete scene3dXml["a:backdrop"];
56710
57051
  }
56711
57052
  spPr["a:scene3d"] = scene3dXml;
56712
57053
  } else {
@@ -56751,12 +57092,12 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56751
57092
  }
56752
57093
  if (sh3d.extrusionColor) {
56753
57094
  sp3dXml["a:extrusionClr"] = {
56754
- "a:srgbClr": { "@_val": sh3d.extrusionColor }
57095
+ "a:srgbClr": { "@_val": sh3d.extrusionColor.replace("#", "") }
56755
57096
  };
56756
57097
  }
56757
57098
  if (sh3d.contourColor) {
56758
57099
  sp3dXml["a:contourClr"] = {
56759
- "a:srgbClr": { "@_val": sh3d.contourColor }
57100
+ "a:srgbClr": { "@_val": sh3d.contourColor.replace("#", "") }
56760
57101
  };
56761
57102
  }
56762
57103
  spPr["a:sp3d"] = sp3dXml;
@@ -56768,6 +57109,77 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
56768
57109
  }
56769
57110
  }
56770
57111
  };
57112
+ function buildSphereRot(lat, lon, rev) {
57113
+ if (lat === void 0 && lon === void 0 && rev === void 0) {
57114
+ return void 0;
57115
+ }
57116
+ const rot = {};
57117
+ if (lat !== void 0) {
57118
+ rot["@_lat"] = String(lat);
57119
+ }
57120
+ if (lon !== void 0) {
57121
+ rot["@_lon"] = String(lon);
57122
+ }
57123
+ if (rev !== void 0) {
57124
+ rot["@_rev"] = String(rev);
57125
+ }
57126
+ return rot;
57127
+ }
57128
+ function buildScene3dCamera(s3d, source) {
57129
+ const camera = { ...source["a:camera"] ?? {} };
57130
+ if (s3d.cameraPreset) {
57131
+ camera["@_prst"] = s3d.cameraPreset;
57132
+ }
57133
+ if (s3d.cameraFieldOfView !== void 0) {
57134
+ camera["@_fov"] = String(s3d.cameraFieldOfView);
57135
+ }
57136
+ if (s3d.cameraZoom !== void 0) {
57137
+ camera["@_zoom"] = String(s3d.cameraZoom);
57138
+ }
57139
+ const rot = buildSphereRot(s3d.cameraRotX, s3d.cameraRotY, s3d.cameraRotZ);
57140
+ if (rot) {
57141
+ camera["a:rot"] = rot;
57142
+ }
57143
+ return camera;
57144
+ }
57145
+ function buildScene3dLightRig(s3d, source) {
57146
+ const lightRig = { ...source["a:lightRig"] ?? {} };
57147
+ if (s3d.lightRigType) {
57148
+ lightRig["@_rig"] = s3d.lightRigType;
57149
+ }
57150
+ if (s3d.lightRigDirection) {
57151
+ lightRig["@_dir"] = s3d.lightRigDirection;
57152
+ }
57153
+ const rot = buildSphereRot(s3d.lightRigRotX, s3d.lightRigRotY, s3d.lightRigRotZ);
57154
+ if (rot) {
57155
+ lightRig["a:rot"] = rot;
57156
+ }
57157
+ return Object.keys(lightRig).length > 0 ? lightRig : void 0;
57158
+ }
57159
+ function buildScene3dBackdrop(s3d) {
57160
+ const hasNorm = s3d.backdropNormalX !== void 0 || s3d.backdropNormalY !== void 0 || s3d.backdropNormalZ !== void 0;
57161
+ const hasUp = s3d.backdropUpX !== void 0 || s3d.backdropUpY !== void 0 || s3d.backdropUpZ !== void 0;
57162
+ if (!s3d.hasBackdrop || !hasNorm || !hasUp) {
57163
+ return void 0;
57164
+ }
57165
+ return {
57166
+ "a:anchor": {
57167
+ "@_x": String(s3d.backdropAnchorX ?? 0),
57168
+ "@_y": String(s3d.backdropAnchorY ?? 0),
57169
+ "@_z": String(s3d.backdropAnchorZ ?? 0)
57170
+ },
57171
+ "a:norm": {
57172
+ "@_dx": String(s3d.backdropNormalX ?? 0),
57173
+ "@_dy": String(s3d.backdropNormalY ?? 0),
57174
+ "@_dz": String(s3d.backdropNormalZ ?? 0)
57175
+ },
57176
+ "a:up": {
57177
+ "@_dx": String(s3d.backdropUpX ?? 0),
57178
+ "@_dy": String(s3d.backdropUpY ?? 0),
57179
+ "@_dz": String(s3d.backdropUpZ ?? 0)
57180
+ }
57181
+ };
57182
+ }
56771
57183
 
56772
57184
  // src/core/core/runtime/PptxHandlerRuntimeSaveTextWriter.ts
56773
57185
  var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime29 {
@@ -61775,7 +62187,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
61775
62187
  pointsToPixels(points3) {
61776
62188
  return points3 * (96 / 72);
61777
62189
  }
61778
- parseParagraphSpacingPx(spacingNode) {
62190
+ parseParagraphSpacingPx(spacingNode, basisFontSizePx) {
61779
62191
  if (!spacingNode) {
61780
62192
  return void 0;
61781
62193
  }
@@ -61786,6 +62198,13 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
61786
62198
  if (Number.isFinite(spacingPointsRaw)) {
61787
62199
  return this.pointsToPixels(spacingPointsRaw / 100);
61788
62200
  }
62201
+ const spacingPercentRaw = Number.parseInt(
62202
+ String(spacingNode["a:spcPct"]?.["@_val"] || ""),
62203
+ 10
62204
+ );
62205
+ if (Number.isFinite(spacingPercentRaw) && typeof basisFontSizePx === "number" && basisFontSizePx > 0) {
62206
+ return spacingPercentRaw / 1e5 * basisFontSizePx;
62207
+ }
61789
62208
  return void 0;
61790
62209
  }
61791
62210
  parseLineSpacingMultiplier(lineSpacingNode) {
@@ -61865,7 +62284,7 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
61865
62284
 
61866
62285
  // src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
61867
62286
  var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
61868
- resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
62287
+ resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath, effectiveLevelStyles) {
61869
62288
  if (!paragraph) {
61870
62289
  return null;
61871
62290
  }
@@ -61901,11 +62320,8 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
61901
62320
  }
61902
62321
  }
61903
62322
  if (!resolvedBulletProps) {
61904
- if (isBodyPlaceholder) {
61905
- const presentationLevelStyle = this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1];
61906
- return this.createBulletInfoFromLevelStyle(presentationLevelStyle, paragraphIndex);
61907
- }
61908
- return null;
62323
+ const fallbackLevelStyle = effectiveLevelStyles?.[normalizedLevel - 1] ?? effectiveLevelStyles?.[-1] ?? (isBodyPlaceholder ? this.presentationDefaultTextStyle?.levelStyles?.[normalizedLevel - 1] ?? this.presentationDefaultTextStyle?.levelStyles?.[-1] : void 0);
62324
+ return this.createBulletInfoFromLevelStyle(fallbackLevelStyle, paragraphIndex);
61909
62325
  }
61910
62326
  const buFont = resolvedBulletProps["a:buFont"];
61911
62327
  const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
@@ -62395,16 +62811,21 @@ var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
62395
62811
  textStyle.align = paraAlign;
62396
62812
  }
62397
62813
  }
62814
+ const spacingBasisPx = typeof textStyle.fontSize === "number" ? textStyle.fontSize : void 0;
62398
62815
  if (textStyle.paragraphSpacingBefore === void 0) {
62399
62816
  const spacingBefore = this.parseParagraphSpacingPx(
62400
- pPr?.["a:spcBef"]
62817
+ pPr?.["a:spcBef"],
62818
+ spacingBasisPx
62401
62819
  );
62402
62820
  if (spacingBefore !== void 0) {
62403
62821
  textStyle.paragraphSpacingBefore = spacingBefore;
62404
62822
  }
62405
62823
  }
62406
62824
  if (textStyle.paragraphSpacingAfter === void 0) {
62407
- const spacingAfter = this.parseParagraphSpacingPx(pPr?.["a:spcAft"]);
62825
+ const spacingAfter = this.parseParagraphSpacingPx(
62826
+ pPr?.["a:spcAft"],
62827
+ spacingBasisPx
62828
+ );
62408
62829
  if (spacingAfter !== void 0) {
62409
62830
  textStyle.paragraphSpacingAfter = spacingAfter;
62410
62831
  }
@@ -62578,7 +62999,8 @@ var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
62578
62999
  ctx.txBody,
62579
63000
  ctx.inheritedTxBody,
62580
63001
  isBodyPlaceholder,
62581
- ctx.slidePath
63002
+ ctx.slidePath,
63003
+ ctx.effectiveLevelStyles
62582
63004
  );
62583
63005
  if (paragraphBulletInfo && !paragraphBulletInfo.none) {
62584
63006
  let bulletText;
@@ -63187,7 +63609,7 @@ var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63187
63609
  const skewY = xfrm["@_skewY"] ? parseEmuInt(xfrm["@_skewY"]) / 6e4 : void 0;
63188
63610
  const { flipHorizontal, flipVertical } = this.readFlipState(xfrm);
63189
63611
  const nvPr = pic?.["p:nvPicPr"]?.["p:nvPr"];
63190
- const mediaReference = parseDrawingMediaReference(nvPr);
63612
+ const mediaReference = parseDrawingMediaReference(nvPr, this.externalRelsMap.get(slidePath));
63191
63613
  if (mediaReference) {
63192
63614
  this.compatibilityService.inspectMediaReferenceCompatibility(
63193
63615
  mediaReference.kind,
@@ -63955,6 +64377,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63955
64377
  const grpSpPr = group["p:grpSpPr"];
63956
64378
  const xfrm = grpSpPr?.["a:xfrm"];
63957
64379
  let parentX = 0, parentY = 0, parentW = 0, parentH = 0;
64380
+ let groupRotation;
64381
+ let flipHorizontal = false;
64382
+ let flipVertical = false;
63958
64383
  if (xfrm) {
63959
64384
  const off = xfrm["a:off"];
63960
64385
  if (off) {
@@ -63966,6 +64391,12 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
63966
64391
  parentW = Math.round(parseEmuInt2(ext["@_cx"]) / _PptxHandlerRuntime.EMU_PER_PX);
63967
64392
  parentH = Math.round(parseEmuInt2(ext["@_cy"]) / _PptxHandlerRuntime.EMU_PER_PX);
63968
64393
  }
64394
+ if (xfrm["@_rot"] !== void 0 && xfrm["@_rot"] !== null) {
64395
+ const rot = parseInt(String(xfrm["@_rot"]), 10) / 6e4;
64396
+ groupRotation = Number.isFinite(rot) && rot !== 0 ? rot : void 0;
64397
+ }
64398
+ flipHorizontal = this.parseBooleanAttr(xfrm["@_flipH"]);
64399
+ flipVertical = this.parseBooleanAttr(xfrm["@_flipV"]);
63969
64400
  }
63970
64401
  const grpFillStyle = grpSpPr ? this.extractShapeStyle(grpSpPr) : void 0;
63971
64402
  const hasGroupFill = grpFillStyle && grpFillStyle.fillMode && grpFillStyle.fillMode !== "none";
@@ -64011,6 +64442,9 @@ var PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
64011
64442
  y: parentY,
64012
64443
  width: parentW || Math.max(...children10.map((c) => c.x + c.width)),
64013
64444
  height: parentH || Math.max(...children10.map((c) => c.y + c.height)),
64445
+ rotation: groupRotation,
64446
+ flipHorizontal: flipHorizontal || void 0,
64447
+ flipVertical: flipVertical || void 0,
64014
64448
  children: children10,
64015
64449
  rawXml: group,
64016
64450
  actionClick: grpActionClick,
@@ -64181,6 +64615,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
64181
64615
  if (!normalized) {
64182
64616
  return void 0;
64183
64617
  }
64618
+ const canon = (key) => key.toLowerCase() === "folhlink" ? "folHlink" : key;
64184
64619
  if (normalized === "phclr") {
64185
64620
  const injected = this.themeColorMap["phclr"];
64186
64621
  if (injected) {
@@ -64190,17 +64625,18 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
64190
64625
  }
64191
64626
  const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
64192
64627
  if (overrideMap) {
64193
- const remapped = overrideMap[normalized];
64628
+ const remapped = overrideMap[canon(normalized)];
64194
64629
  if (remapped) {
64195
- return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
64630
+ const target = canon(remapped);
64631
+ return this.themeColorMap[target] || this.getDefaultSchemeColorMap()[target];
64196
64632
  }
64197
64633
  } else {
64198
64634
  const defaultAliasTarget = DEFAULT_CLR_MAP_ALIAS[normalized];
64199
64635
  if (defaultAliasTarget) {
64200
- return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
64636
+ return this.themeColorMap[defaultAliasTarget] || this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
64201
64637
  }
64202
64638
  }
64203
- return this.themeColorMap[normalized] || this.getDefaultSchemeColorMap()[normalized];
64639
+ return this.themeColorMap[canon(normalized)] || this.getDefaultSchemeColorMap()[canon(normalized)];
64204
64640
  }
64205
64641
  normalizeStrokeDashType(value) {
64206
64642
  const normalized = String(value ?? "").trim();
@@ -64983,11 +65419,24 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
64983
65419
  }
64984
65420
  }
64985
65421
  }
64986
- const spcBef = this.parseParagraphSpacingPx(levelProps["a:spcBef"]);
65422
+ const defRPrSzRaw = Number.parseInt(
65423
+ String(
65424
+ levelProps["a:defRPr"]?.["@_sz"] || ""
65425
+ ),
65426
+ 10
65427
+ );
65428
+ const basisFontSizePx = Number.isFinite(defRPrSzRaw) ? this.pointsToPixels(defRPrSzRaw / 100) : void 0;
65429
+ const spcBef = this.parseParagraphSpacingPx(
65430
+ levelProps["a:spcBef"],
65431
+ basisFontSizePx
65432
+ );
64987
65433
  if (spcBef !== void 0) {
64988
65434
  style.spaceBefore = spcBef;
64989
65435
  }
64990
- const spcAft = this.parseParagraphSpacingPx(levelProps["a:spcAft"]);
65436
+ const spcAft = this.parseParagraphSpacingPx(
65437
+ levelProps["a:spcAft"],
65438
+ basisFontSizePx
65439
+ );
64991
65440
  if (spcAft !== void 0) {
64992
65441
  style.spaceAfter = spcAft;
64993
65442
  }
@@ -65012,9 +65461,9 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
65012
65461
  }
65013
65462
  const buClr = levelProps["a:buClr"];
65014
65463
  if (buClr) {
65015
- const srgb = buClr["a:srgbClr"];
65016
- if (srgb?.["@_val"]) {
65017
- style.bulletColor = String(srgb["@_val"]);
65464
+ const bulletColor = this.parseColor(buClr);
65465
+ if (bulletColor) {
65466
+ style.bulletColor = bulletColor;
65018
65467
  }
65019
65468
  }
65020
65469
  const buSzPts = levelProps["a:buSzPts"];
@@ -67516,6 +67965,89 @@ var PptxHandlerRuntime83 = class extends PptxHandlerRuntime82 {
67516
67965
  }
67517
67966
  };
67518
67967
 
67968
+ // src/core/core/runtime/smartart-drawing-shape-style.ts
67969
+ function extractDrawingShapeFill(spPr, deps) {
67970
+ const result = {};
67971
+ const solidFill2 = deps.getChild(spPr, "solidFill");
67972
+ if (solidFill2) {
67973
+ result.fillColor = deps.parseColor(solidFill2) ?? void 0;
67974
+ }
67975
+ const gradFill = !solidFill2 ? deps.getChild(spPr, "gradFill") : void 0;
67976
+ if (gradFill) {
67977
+ const stops = deps.extractGradientStops(gradFill).map((stop) => ({
67978
+ color: stop.color,
67979
+ position: stop.position,
67980
+ ...stop.opacity !== void 0 ? { opacity: stop.opacity } : {}
67981
+ }));
67982
+ if (stops.length > 0) {
67983
+ result.fillGradientStops = stops;
67984
+ result.fillGradientType = deps.extractGradientType(gradFill);
67985
+ result.fillGradientAngle = deps.extractGradientAngle(gradFill);
67986
+ result.fillColor ??= stops[Math.floor(stops.length / 2)]?.color;
67987
+ }
67988
+ }
67989
+ const pattFill = !solidFill2 && !gradFill ? deps.getChild(spPr, "pattFill") : void 0;
67990
+ if (pattFill) {
67991
+ const preset = String(pattFill["@_prst"] || "").trim();
67992
+ if (preset) {
67993
+ result.fillPatternPreset = preset;
67994
+ }
67995
+ const fg = deps.parseColor(deps.getChild(pattFill, "fgClr"));
67996
+ const bg = deps.parseColor(deps.getChild(pattFill, "bgClr"));
67997
+ if (fg) {
67998
+ result.fillPatternForegroundColor = fg;
67999
+ }
68000
+ if (bg) {
68001
+ result.fillPatternBackgroundColor = bg;
68002
+ }
68003
+ result.fillColor ??= fg ?? bg;
68004
+ }
68005
+ const blipFill = !solidFill2 && !gradFill && !pattFill ? deps.getChild(spPr, "blipFill") : void 0;
68006
+ if (blipFill) {
68007
+ const blip = deps.getChild(blipFill, "blip");
68008
+ const embed = String(
68009
+ blip?.["@_r:embed"] || blip?.["@_embed"] || blip?.["@_r:link"] || ""
68010
+ ).trim();
68011
+ if (embed) {
68012
+ result.fillBlipEmbedId = embed;
68013
+ }
68014
+ }
68015
+ const shadowColor = deps.extractShadowColor(spPr);
68016
+ if (shadowColor) {
68017
+ result.hasShadow = true;
68018
+ result.shadowColor = shadowColor;
68019
+ }
68020
+ return result;
68021
+ }
68022
+ function extractDrawingShapeTextStyle(txBody, deps) {
68023
+ let fontSize;
68024
+ let fontColor;
68025
+ if (!txBody) {
68026
+ return { fontSize, fontColor };
68027
+ }
68028
+ const paragraphs = deps.getChildren(txBody, "p");
68029
+ for (const p of paragraphs) {
68030
+ const runs = deps.getChildren(p, "r");
68031
+ for (const r of runs) {
68032
+ const rPr = deps.getChild(r, "rPr");
68033
+ if (rPr && !fontSize) {
68034
+ const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
68035
+ if (Number.isFinite(szRaw) && szRaw > 0) {
68036
+ fontSize = szRaw / 100;
68037
+ }
68038
+ fontColor = deps.parseColor(deps.getChild(rPr, "solidFill")) ?? void 0;
68039
+ }
68040
+ if (fontSize) {
68041
+ break;
68042
+ }
68043
+ }
68044
+ if (fontSize) {
68045
+ break;
68046
+ }
68047
+ }
68048
+ return { fontSize, fontColor };
68049
+ }
68050
+
67519
68051
  // src/core/core/runtime/smartart-text-style-resolution.ts
67520
68052
  function resolveSmartArtTextStyles(paragraphs, resolve) {
67521
68053
  for (const paragraph of paragraphs ?? []) {
@@ -67691,8 +68223,7 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67691
68223
  };
67692
68224
  }
67693
68225
  }
67694
- const solidFill2 = this.xmlLookupService.getChildByLocalName(spPr, "solidFill");
67695
- const fillColor = this.parseColor(solidFill2);
68226
+ const fill = extractDrawingShapeFill(spPr, this.drawingShapeStyleDeps());
67696
68227
  const lnNode = this.xmlLookupService.getChildByLocalName(spPr, "ln");
67697
68228
  const lnFill = lnNode ? this.xmlLookupService.getChildByLocalName(lnNode, "solidFill") : void 0;
67698
68229
  const strokeColor = this.parseColor(lnFill);
@@ -67704,7 +68235,10 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67704
68235
  this.collectLocalTextValues(txBody, "t", textValues2);
67705
68236
  }
67706
68237
  const text2 = textValues2.join("").trim() || void 0;
67707
- const { fontSize, fontColor } = this.extractDrawingShapeTextStyle(txBody);
68238
+ const { fontSize, fontColor } = extractDrawingShapeTextStyle(
68239
+ txBody,
68240
+ this.drawingShapeStyleDeps()
68241
+ );
67708
68242
  const paragraphs = txBody ? resolveSmartArtTextStyles(
67709
68243
  parseSmartArtTextParagraphs({ "dgm:t": txBody }),
67710
68244
  (rPr) => this.extractTextRunStyle(rPr, void 0, void 0, false)
@@ -67730,7 +68264,8 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67730
68264
  rotation,
67731
68265
  skewX,
67732
68266
  skewY,
67733
- fillColor: fillColor ?? void 0,
68267
+ ...fill,
68268
+ fillColor: fill.fillColor ?? void 0,
67734
68269
  strokeColor: strokeColor ?? void 0,
67735
68270
  strokeWidth,
67736
68271
  text: structuredText,
@@ -67740,34 +68275,21 @@ var PptxHandlerRuntime84 = class _PptxHandlerRuntime extends PptxHandlerRuntime8
67740
68275
  ...customGeometry
67741
68276
  };
67742
68277
  }
67743
- extractDrawingShapeTextStyle(txBody) {
67744
- let fontSize;
67745
- let fontColor;
67746
- if (!txBody) {
67747
- return { fontSize, fontColor };
67748
- }
67749
- const paragraphs = this.xmlLookupService.getChildrenArrayByLocalName(txBody, "p");
67750
- for (const p of paragraphs) {
67751
- const runs = this.xmlLookupService.getChildrenArrayByLocalName(p, "r");
67752
- for (const r of runs) {
67753
- const rPr = this.xmlLookupService.getChildByLocalName(r, "rPr");
67754
- if (rPr && !fontSize) {
67755
- const szRaw = parseInt(String(rPr["@_sz"] || ""), 10);
67756
- if (Number.isFinite(szRaw) && szRaw > 0) {
67757
- fontSize = szRaw / 100;
67758
- }
67759
- const rprFill = this.xmlLookupService.getChildByLocalName(rPr, "solidFill");
67760
- fontColor = this.parseColor(rprFill) ?? void 0;
67761
- }
67762
- if (fontSize) {
67763
- break;
67764
- }
67765
- }
67766
- if (fontSize) {
67767
- break;
67768
- }
67769
- }
67770
- return { fontSize, fontColor };
68278
+ /**
68279
+ * Build the injected accessor bundle used by the pure drawing-shape style
68280
+ * helpers, binding the shared XML-lookup / colour / gradient / shadow codec
68281
+ * methods so no new colour logic is duplicated here.
68282
+ */
68283
+ drawingShapeStyleDeps() {
68284
+ return {
68285
+ getChild: (node, local) => this.xmlLookupService.getChildByLocalName(node, local),
68286
+ getChildren: (node, local) => this.xmlLookupService.getChildrenArrayByLocalName(node, local),
68287
+ parseColor: (node) => this.parseColor(node),
68288
+ extractGradientStops: (gradFill) => this.extractGradientStops(gradFill),
68289
+ extractGradientType: (gradFill) => this.extractGradientType(gradFill),
68290
+ extractGradientAngle: (gradFill) => this.extractGradientAngle(gradFill),
68291
+ extractShadowColor: (spPr) => this.extractShadowStyle(spPr).shadowColor
68292
+ };
67771
68293
  }
67772
68294
  };
67773
68295
 
@@ -70241,6 +70763,7 @@ var PptxHandlerRuntime95 = class _PptxHandlerRuntime extends PptxHandlerRuntime9
70241
70763
  });
70242
70764
  this.mediaDataParser = new PptxMediaDataParser({
70243
70765
  slideRelsMap: this.slideRelsMap,
70766
+ externalRelsMap: this.externalRelsMap,
70244
70767
  resolvePath: (base, relative) => this.resolvePath(base, relative),
70245
70768
  getPathExtension: (pathValue) => this.getPathExtension(pathValue)
70246
70769
  });
@@ -72931,9 +73454,9 @@ function removeEmptyDataPoint(series, pointIndex) {
72931
73454
  }
72932
73455
  }
72933
73456
  }
72934
- var EMU_PER_PIXEL = 9525;
73457
+ var EMU_PER_PIXEL2 = 9525;
72935
73458
  function pxToEmu(px2) {
72936
- return Math.round(px2 * EMU_PER_PIXEL);
73459
+ return Math.round(px2 * EMU_PER_PIXEL2);
72937
73460
  }
72938
73461
  function placeholderSpXml(ph, shapeId) {
72939
73462
  const name = ph.name ?? `${ph.type.charAt(0).toUpperCase() + ph.type.slice(1)} Placeholder ${shapeId - 1}`;
@@ -74687,7 +75210,7 @@ var GroupBuilder = class _GroupBuilder {
74687
75210
  // src/core/builders/sdk/units.ts
74688
75211
  var PPI = 96;
74689
75212
  var POINTS_PER_INCH = 72;
74690
- var EMU_PER_PIXEL2 = 9525;
75213
+ var EMU_PER_PIXEL3 = 9525;
74691
75214
  var EMU_PER_INCH = 914400;
74692
75215
  var EMU_PER_POINT = 12700;
74693
75216
  function inches(value) {
@@ -74703,10 +75226,10 @@ function pt(value) {
74703
75226
  return Math.round(value / POINTS_PER_INCH * PPI);
74704
75227
  }
74705
75228
  function emuToPixels(emu) {
74706
- return Math.round(emu / EMU_PER_PIXEL2);
75229
+ return Math.round(emu / EMU_PER_PIXEL3);
74707
75230
  }
74708
75231
  function pixelsToEmu(px2) {
74709
- return Math.round(px2 * EMU_PER_PIXEL2);
75232
+ return Math.round(px2 * EMU_PER_PIXEL3);
74710
75233
  }
74711
75234
  function inchesToEmu(value) {
74712
75235
  return Math.round(value * EMU_PER_INCH);
@@ -85052,7 +85575,7 @@ exports.EFFECT_LST_ORDER = EFFECT_LST_ORDER;
85052
85575
  exports.ELEMENT_FIELD_KIND = ELEMENT_FIELD_KIND;
85053
85576
  exports.EMPHASIS_PRESETS = EMPHASIS_PRESETS;
85054
85577
  exports.EMU_PER_INCH = EMU_PER_INCH;
85055
- exports.EMU_PER_PIXEL = EMU_PER_PIXEL2;
85578
+ exports.EMU_PER_PIXEL = EMU_PER_PIXEL3;
85056
85579
  exports.EMU_PER_POINT = EMU_PER_POINT;
85057
85580
  exports.EMU_PER_PX = EMU_PER_PX;
85058
85581
  exports.ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV = ENTERPRISE_FAIL_ON_REVOCATION_UNKNOWN_ENV;