pptx-viewer-core 1.1.30 → 1.1.31

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/cli/index.js CHANGED
Binary file
Binary file
package/dist/index.d.mts CHANGED
@@ -3406,9 +3406,14 @@ declare function buildGuideListExtension(guides: PptxDrawingGuide[]): XmlObject;
3406
3406
  /**
3407
3407
  * Supported layout types for the visual layout switcher.
3408
3408
  *
3409
- * These are the layout categories that have dedicated renderers
3410
- * in SmartArtRenderer and can be switched between while preserving
3411
- * node data and connections.
3409
+ * These are the layout categories that have a working reflow implementation in
3410
+ * `reflowSmartArtLayout` (see `smartart-editing-reflow*`), so switching to any
3411
+ * of them re-lays-out the diagram while preserving node data and connections.
3412
+ * Every entry below has a matching `case` in the reflow dispatcher:
3413
+ * list, process, hierarchy, cycle, matrix, pyramid, funnel, target, gear,
3414
+ * venn, timeline, relationship, chevron, bending.
3415
+ *
3416
+ * `unknown` is intentionally excluded (it has no meaningful target layout).
3412
3417
  */
3413
3418
  declare const SWITCHABLE_LAYOUT_TYPES: readonly SmartArtLayoutType[];
3414
3419
  /**
package/dist/index.d.ts CHANGED
@@ -3406,9 +3406,14 @@ declare function buildGuideListExtension(guides: PptxDrawingGuide[]): XmlObject;
3406
3406
  /**
3407
3407
  * Supported layout types for the visual layout switcher.
3408
3408
  *
3409
- * These are the layout categories that have dedicated renderers
3410
- * in SmartArtRenderer and can be switched between while preserving
3411
- * node data and connections.
3409
+ * These are the layout categories that have a working reflow implementation in
3410
+ * `reflowSmartArtLayout` (see `smartart-editing-reflow*`), so switching to any
3411
+ * of them re-lays-out the diagram while preserving node data and connections.
3412
+ * Every entry below has a matching `case` in the reflow dispatcher:
3413
+ * list, process, hierarchy, cycle, matrix, pyramid, funnel, target, gear,
3414
+ * venn, timeline, relationship, chevron, bending.
3415
+ *
3416
+ * `unknown` is intentionally excluded (it has no meaningful target layout).
3412
3417
  */
3413
3418
  declare const SWITCHABLE_LAYOUT_TYPES: readonly SmartArtLayoutType[];
3414
3419
  /**
package/dist/index.js CHANGED
@@ -13772,6 +13772,9 @@ async function parseEmbeddedXlsx(xlsxData) {
13772
13772
  }
13773
13773
  }
13774
13774
 
13775
+ // src/core/core/builders/smart-art-text-helpers.ts
13776
+ var MAX_SMARTART_NODES = 2e3;
13777
+
13775
13778
  // src/core/utils/vml-color-parser.ts
13776
13779
  var NAMED_COLORS = {
13777
13780
  black: "#000000",
@@ -19941,12 +19944,20 @@ function chartDataRemoveCategory(chartData, categoryIndex) {
19941
19944
 
19942
19945
  // src/core/utils/smartart-layout-switch.ts
19943
19946
  var SWITCHABLE_LAYOUT_TYPES = [
19947
+ "list",
19944
19948
  "process",
19945
19949
  "hierarchy",
19946
19950
  "cycle",
19947
19951
  "matrix",
19948
19952
  "pyramid",
19949
- "list"
19953
+ "funnel",
19954
+ "target",
19955
+ "gear",
19956
+ "venn",
19957
+ "timeline",
19958
+ "relationship",
19959
+ "chevron",
19960
+ "bending"
19950
19961
  ];
19951
19962
  function switchSmartArtLayout(currentData, newLayoutType) {
19952
19963
  if (currentData.resolvedLayoutType === newLayoutType) {
@@ -32851,27 +32862,151 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32851
32862
  }
32852
32863
  };
32853
32864
 
32865
+ // src/core/core/runtime/smartart-save-chrome.ts
32866
+ function asObject(value) {
32867
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
32868
+ }
32869
+ function applySmartArtChrome(dataModel, chrome, getLocalName) {
32870
+ if (!chrome || !chrome.backgroundColor && !chrome.outlineColor && (chrome.outlineWidth === null || chrome.outlineWidth === void 0)) {
32871
+ return;
32872
+ }
32873
+ const findKey10 = (obj, name) => Object.keys(obj).find((k) => getLocalName(k) === name);
32874
+ if (chrome.backgroundColor) {
32875
+ const hex7 = chrome.backgroundColor.replace("#", "");
32876
+ const bgKey = findKey10(dataModel, "bg") ?? "dgm:bg";
32877
+ const bg = asObject(dataModel[bgKey]);
32878
+ const fillKey = findKey10(bg, "solidFill") ?? "a:solidFill";
32879
+ bg[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32880
+ dataModel[bgKey] = bg;
32881
+ }
32882
+ const hasOutlineWidth = chrome.outlineWidth !== null && chrome.outlineWidth !== void 0;
32883
+ if (chrome.outlineColor || hasOutlineWidth) {
32884
+ const wholeKey = findKey10(dataModel, "whole") ?? "dgm:whole";
32885
+ const whole = asObject(dataModel[wholeKey]);
32886
+ const lnKey = findKey10(whole, "ln") ?? "a:ln";
32887
+ const ln = asObject(whole[lnKey]);
32888
+ if (hasOutlineWidth) {
32889
+ ln["@_w"] = String(Math.round(chrome.outlineWidth * 12700));
32890
+ }
32891
+ if (chrome.outlineColor) {
32892
+ const hex7 = chrome.outlineColor.replace("#", "");
32893
+ const fillKey = findKey10(ln, "solidFill") ?? "a:solidFill";
32894
+ ln[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32895
+ }
32896
+ whole[lnKey] = ln;
32897
+ dataModel[wholeKey] = whole;
32898
+ }
32899
+ }
32900
+
32854
32901
  // src/core/core/runtime/smartart-xml-builders.ts
32855
- function buildSmartArtPointXml(nodes) {
32856
- return nodes.map((node) => {
32857
- const ptNode = {
32858
- "@_modelId": node.id
32859
- };
32860
- if (node.nodeType) {
32861
- ptNode["@_type"] = node.nodeType;
32902
+ var NON_CONTENT_POINT_TYPES = /* @__PURE__ */ new Set([
32903
+ "doc",
32904
+ "pres",
32905
+ "parTrans",
32906
+ "sibTrans"
32907
+ ]);
32908
+ function pointType(pt2) {
32909
+ return String(pt2["@_type"] || "").trim();
32910
+ }
32911
+ function pointModelId(pt2) {
32912
+ return String(pt2["@_modelId"] || "").trim();
32913
+ }
32914
+ function isContentPoint(pt2) {
32915
+ return !NON_CONTENT_POINT_TYPES.has(pointType(pt2));
32916
+ }
32917
+ function buildPointText(text) {
32918
+ return {
32919
+ "a:bodyPr": {},
32920
+ "a:lstStyle": {},
32921
+ "a:p": {
32922
+ "a:r": {
32923
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32924
+ "a:t": text
32925
+ }
32862
32926
  }
32863
- ptNode["dgm:t"] = {
32864
- "a:bodyPr": {},
32865
- "a:lstStyle": {},
32866
- "a:p": {
32867
- "a:r": {
32868
- "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32869
- "a:t": node.text
32870
- }
32927
+ };
32928
+ }
32929
+ function applyTextToExistingPoint(pt2, text) {
32930
+ const tKey = Object.keys(pt2).find((k) => stripPrefix(k) === "t");
32931
+ if (!tKey) {
32932
+ pt2["dgm:t"] = buildPointText(text);
32933
+ return;
32934
+ }
32935
+ const body = pt2[tKey];
32936
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
32937
+ pt2[tKey] = buildPointText(text);
32938
+ return;
32939
+ }
32940
+ const bodyObj = body;
32941
+ const pKey = Object.keys(bodyObj).find((k) => stripPrefix(k) === "p");
32942
+ const paragraph = pKey ? bodyObj[pKey] : void 0;
32943
+ if (!pKey || Array.isArray(paragraph) || !paragraph || typeof paragraph !== "object") {
32944
+ bodyObj[pKey ?? "a:p"] = {
32945
+ "a:r": {
32946
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32947
+ "a:t": text
32871
32948
  }
32872
32949
  };
32873
- return ptNode;
32874
- });
32950
+ return;
32951
+ }
32952
+ const paragraphObj = paragraph;
32953
+ const rKey = Object.keys(paragraphObj).find((k) => stripPrefix(k) === "r");
32954
+ const run = rKey ? paragraphObj[rKey] : void 0;
32955
+ if (!rKey || Array.isArray(run) || !run || typeof run !== "object") {
32956
+ paragraphObj[rKey ?? "a:r"] = {
32957
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32958
+ "a:t": text
32959
+ };
32960
+ return;
32961
+ }
32962
+ const runObj = run;
32963
+ const textKey = Object.keys(runObj).find((k) => stripPrefix(k) === "t");
32964
+ runObj[textKey ?? "a:t"] = text;
32965
+ }
32966
+ function stripPrefix(key) {
32967
+ const idx = key.indexOf(":");
32968
+ return idx >= 0 ? key.slice(idx + 1) : key;
32969
+ }
32970
+ function mergeSmartArtPointXml(existingPts, nodes) {
32971
+ const desiredById = /* @__PURE__ */ new Map();
32972
+ for (const node of nodes) {
32973
+ const id = String(node.id || "").trim();
32974
+ if (id.length > 0) {
32975
+ desiredById.set(id, node);
32976
+ }
32977
+ }
32978
+ const seenContentIds = /* @__PURE__ */ new Set();
32979
+ const merged = [];
32980
+ for (const pt2 of existingPts) {
32981
+ if (!pt2 || typeof pt2 !== "object") {
32982
+ continue;
32983
+ }
32984
+ if (!isContentPoint(pt2)) {
32985
+ merged.push(pt2);
32986
+ continue;
32987
+ }
32988
+ const modelId = pointModelId(pt2);
32989
+ const desired = modelId.length > 0 ? desiredById.get(modelId) : void 0;
32990
+ if (!desired) {
32991
+ continue;
32992
+ }
32993
+ applyTextToExistingPoint(pt2, desired.text);
32994
+ seenContentIds.add(modelId);
32995
+ merged.push(pt2);
32996
+ }
32997
+ for (const node of nodes) {
32998
+ const id = String(node.id || "").trim();
32999
+ if (id.length === 0 || seenContentIds.has(id)) {
33000
+ continue;
33001
+ }
33002
+ const ptNode = { "@_modelId": id };
33003
+ if (node.nodeType && !NON_CONTENT_POINT_TYPES.has(node.nodeType)) {
33004
+ ptNode["@_type"] = node.nodeType;
33005
+ }
33006
+ ptNode["dgm:t"] = buildPointText(node.text);
33007
+ merged.push(ptNode);
33008
+ }
33009
+ return merged;
32875
33010
  }
32876
33011
  function buildSmartArtConnectionXml(connections) {
32877
33012
  return connections.map((conn) => {
@@ -32916,12 +33051,12 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32916
33051
  if (!this.pendingSmartArtUpdates || this.pendingSmartArtUpdates.length === 0) {
32917
33052
  return;
32918
33053
  }
32919
- for (const { element } of this.pendingSmartArtUpdates) {
33054
+ for (const { element, slidePath: capturedSlidePath } of this.pendingSmartArtUpdates) {
32920
33055
  const smartArtData = element.smartArtData;
32921
33056
  if (!smartArtData?.dataRelId) {
32922
33057
  continue;
32923
33058
  }
32924
- const slidePath = element.rawXml ? this.findSlidePathForElement(element) : void 0;
33059
+ const slidePath = capturedSlidePath && capturedSlidePath.length > 0 ? capturedSlidePath : this.findSlidePathForElement(element);
32925
33060
  if (!slidePath) {
32926
33061
  continue;
32927
33062
  }
@@ -32950,7 +33085,8 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32950
33085
  (k) => this.compatibilityService.getXmlLocalName(k) === "pt"
32951
33086
  );
32952
33087
  if (ptKey) {
32953
- ptList[ptKey] = buildSmartArtPointXml(smartArtData.nodes);
33088
+ const existingPts = this.ensureArray(ptList[ptKey]);
33089
+ ptList[ptKey] = mergeSmartArtPointXml(existingPts, smartArtData.nodes);
32954
33090
  }
32955
33091
  }
32956
33092
  if (smartArtData.connections && smartArtData.connections.length > 0) {
@@ -32967,6 +33103,11 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32967
33103
  }
32968
33104
  }
32969
33105
  }
33106
+ applySmartArtChrome(
33107
+ dataModel,
33108
+ smartArtData.chrome,
33109
+ (k) => this.compatibilityService.getXmlLocalName(k)
33110
+ );
32970
33111
  this.zip.file(dataPartPath, this.builder.build(parsed));
32971
33112
  } catch (e) {
32972
33113
  console.warn(`Failed to save SmartArt data at ${dataPartPath}:`, e);
@@ -33096,7 +33237,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33096
33237
  if (this.customXmlParts.length === 0) {
33097
33238
  return;
33098
33239
  }
33099
- const SAFE_ID = /^[A-Za-z0-9_-]+$/;
33240
+ const SAFE_ID = /^[A-Za-z0-9_-]+$/u;
33100
33241
  let fallbackIndex = 1;
33101
33242
  for (const part of this.customXmlParts) {
33102
33243
  const rawId = String(part.id);
@@ -33207,7 +33348,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33207
33348
  let maxId = 0;
33208
33349
  for (const rel of relationships) {
33209
33350
  const id = String(rel?.["@_Id"] || "");
33210
- const num = parseInt(id.replace(/^rId/, ""), 10);
33351
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33211
33352
  if (Number.isFinite(num) && num > maxId) {
33212
33353
  maxId = num;
33213
33354
  }
@@ -33330,7 +33471,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33330
33471
  let maxId = 0;
33331
33472
  for (const rel of relationships) {
33332
33473
  const id = String(rel?.["@_Id"] || "");
33333
- const num = parseInt(id.replace(/^rId/, ""), 10);
33474
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33334
33475
  if (Number.isFinite(num) && num > maxId) {
33335
33476
  maxId = num;
33336
33477
  }
@@ -43001,13 +43142,13 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
43001
43142
  parentId: parentByNodeId.get(pointId),
43002
43143
  nodeType
43003
43144
  };
43004
- }).filter((entry) => Boolean(entry)).slice(0, 50);
43145
+ }).filter((entry) => Boolean(entry)).slice(0, MAX_SMARTART_NODES);
43005
43146
  if (nodes.length === 0) {
43006
43147
  return void 0;
43007
43148
  }
43008
43149
  const layoutRelationshipId = String(relationshipIds["@_r:lo"] || "").trim();
43009
43150
  const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
43010
- const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
43151
+ const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/u, "") || void 0;
43011
43152
  const chrome = this.parseSmartArtChrome(dataModel);
43012
43153
  const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
43013
43154
  const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
@@ -43055,7 +43196,7 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
43055
43196
  return void 0;
43056
43197
  }
43057
43198
  const dataPath = this.resolveImagePath(slidePath, dataTarget);
43058
- const dataDir = dataPath.replace(/\/[^/]+$/, "");
43199
+ const dataDir = dataPath.replace(/\/[^/]+$/u, "");
43059
43200
  const dataFile = dataPath.split("/").pop() ?? "";
43060
43201
  const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
43061
43202
  const relsXml = await this.zip.file(dataRelsPath)?.async("string");
package/dist/index.mjs CHANGED
@@ -13767,6 +13767,9 @@ async function parseEmbeddedXlsx(xlsxData) {
13767
13767
  }
13768
13768
  }
13769
13769
 
13770
+ // src/core/core/builders/smart-art-text-helpers.ts
13771
+ var MAX_SMARTART_NODES = 2e3;
13772
+
13770
13773
  // src/core/utils/vml-color-parser.ts
13771
13774
  var NAMED_COLORS = {
13772
13775
  black: "#000000",
@@ -19936,12 +19939,20 @@ function chartDataRemoveCategory(chartData, categoryIndex) {
19936
19939
 
19937
19940
  // src/core/utils/smartart-layout-switch.ts
19938
19941
  var SWITCHABLE_LAYOUT_TYPES = [
19942
+ "list",
19939
19943
  "process",
19940
19944
  "hierarchy",
19941
19945
  "cycle",
19942
19946
  "matrix",
19943
19947
  "pyramid",
19944
- "list"
19948
+ "funnel",
19949
+ "target",
19950
+ "gear",
19951
+ "venn",
19952
+ "timeline",
19953
+ "relationship",
19954
+ "chevron",
19955
+ "bending"
19945
19956
  ];
19946
19957
  function switchSmartArtLayout(currentData, newLayoutType) {
19947
19958
  if (currentData.resolvedLayoutType === newLayoutType) {
@@ -32846,27 +32857,151 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32846
32857
  }
32847
32858
  };
32848
32859
 
32860
+ // src/core/core/runtime/smartart-save-chrome.ts
32861
+ function asObject(value) {
32862
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
32863
+ }
32864
+ function applySmartArtChrome(dataModel, chrome, getLocalName) {
32865
+ if (!chrome || !chrome.backgroundColor && !chrome.outlineColor && (chrome.outlineWidth === null || chrome.outlineWidth === void 0)) {
32866
+ return;
32867
+ }
32868
+ const findKey10 = (obj, name) => Object.keys(obj).find((k) => getLocalName(k) === name);
32869
+ if (chrome.backgroundColor) {
32870
+ const hex7 = chrome.backgroundColor.replace("#", "");
32871
+ const bgKey = findKey10(dataModel, "bg") ?? "dgm:bg";
32872
+ const bg = asObject(dataModel[bgKey]);
32873
+ const fillKey = findKey10(bg, "solidFill") ?? "a:solidFill";
32874
+ bg[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32875
+ dataModel[bgKey] = bg;
32876
+ }
32877
+ const hasOutlineWidth = chrome.outlineWidth !== null && chrome.outlineWidth !== void 0;
32878
+ if (chrome.outlineColor || hasOutlineWidth) {
32879
+ const wholeKey = findKey10(dataModel, "whole") ?? "dgm:whole";
32880
+ const whole = asObject(dataModel[wholeKey]);
32881
+ const lnKey = findKey10(whole, "ln") ?? "a:ln";
32882
+ const ln = asObject(whole[lnKey]);
32883
+ if (hasOutlineWidth) {
32884
+ ln["@_w"] = String(Math.round(chrome.outlineWidth * 12700));
32885
+ }
32886
+ if (chrome.outlineColor) {
32887
+ const hex7 = chrome.outlineColor.replace("#", "");
32888
+ const fillKey = findKey10(ln, "solidFill") ?? "a:solidFill";
32889
+ ln[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32890
+ }
32891
+ whole[lnKey] = ln;
32892
+ dataModel[wholeKey] = whole;
32893
+ }
32894
+ }
32895
+
32849
32896
  // src/core/core/runtime/smartart-xml-builders.ts
32850
- function buildSmartArtPointXml(nodes) {
32851
- return nodes.map((node) => {
32852
- const ptNode = {
32853
- "@_modelId": node.id
32854
- };
32855
- if (node.nodeType) {
32856
- ptNode["@_type"] = node.nodeType;
32897
+ var NON_CONTENT_POINT_TYPES = /* @__PURE__ */ new Set([
32898
+ "doc",
32899
+ "pres",
32900
+ "parTrans",
32901
+ "sibTrans"
32902
+ ]);
32903
+ function pointType(pt2) {
32904
+ return String(pt2["@_type"] || "").trim();
32905
+ }
32906
+ function pointModelId(pt2) {
32907
+ return String(pt2["@_modelId"] || "").trim();
32908
+ }
32909
+ function isContentPoint(pt2) {
32910
+ return !NON_CONTENT_POINT_TYPES.has(pointType(pt2));
32911
+ }
32912
+ function buildPointText(text) {
32913
+ return {
32914
+ "a:bodyPr": {},
32915
+ "a:lstStyle": {},
32916
+ "a:p": {
32917
+ "a:r": {
32918
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32919
+ "a:t": text
32920
+ }
32857
32921
  }
32858
- ptNode["dgm:t"] = {
32859
- "a:bodyPr": {},
32860
- "a:lstStyle": {},
32861
- "a:p": {
32862
- "a:r": {
32863
- "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32864
- "a:t": node.text
32865
- }
32922
+ };
32923
+ }
32924
+ function applyTextToExistingPoint(pt2, text) {
32925
+ const tKey = Object.keys(pt2).find((k) => stripPrefix(k) === "t");
32926
+ if (!tKey) {
32927
+ pt2["dgm:t"] = buildPointText(text);
32928
+ return;
32929
+ }
32930
+ const body = pt2[tKey];
32931
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
32932
+ pt2[tKey] = buildPointText(text);
32933
+ return;
32934
+ }
32935
+ const bodyObj = body;
32936
+ const pKey = Object.keys(bodyObj).find((k) => stripPrefix(k) === "p");
32937
+ const paragraph = pKey ? bodyObj[pKey] : void 0;
32938
+ if (!pKey || Array.isArray(paragraph) || !paragraph || typeof paragraph !== "object") {
32939
+ bodyObj[pKey ?? "a:p"] = {
32940
+ "a:r": {
32941
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32942
+ "a:t": text
32866
32943
  }
32867
32944
  };
32868
- return ptNode;
32869
- });
32945
+ return;
32946
+ }
32947
+ const paragraphObj = paragraph;
32948
+ const rKey = Object.keys(paragraphObj).find((k) => stripPrefix(k) === "r");
32949
+ const run = rKey ? paragraphObj[rKey] : void 0;
32950
+ if (!rKey || Array.isArray(run) || !run || typeof run !== "object") {
32951
+ paragraphObj[rKey ?? "a:r"] = {
32952
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32953
+ "a:t": text
32954
+ };
32955
+ return;
32956
+ }
32957
+ const runObj = run;
32958
+ const textKey = Object.keys(runObj).find((k) => stripPrefix(k) === "t");
32959
+ runObj[textKey ?? "a:t"] = text;
32960
+ }
32961
+ function stripPrefix(key) {
32962
+ const idx = key.indexOf(":");
32963
+ return idx >= 0 ? key.slice(idx + 1) : key;
32964
+ }
32965
+ function mergeSmartArtPointXml(existingPts, nodes) {
32966
+ const desiredById = /* @__PURE__ */ new Map();
32967
+ for (const node of nodes) {
32968
+ const id = String(node.id || "").trim();
32969
+ if (id.length > 0) {
32970
+ desiredById.set(id, node);
32971
+ }
32972
+ }
32973
+ const seenContentIds = /* @__PURE__ */ new Set();
32974
+ const merged = [];
32975
+ for (const pt2 of existingPts) {
32976
+ if (!pt2 || typeof pt2 !== "object") {
32977
+ continue;
32978
+ }
32979
+ if (!isContentPoint(pt2)) {
32980
+ merged.push(pt2);
32981
+ continue;
32982
+ }
32983
+ const modelId = pointModelId(pt2);
32984
+ const desired = modelId.length > 0 ? desiredById.get(modelId) : void 0;
32985
+ if (!desired) {
32986
+ continue;
32987
+ }
32988
+ applyTextToExistingPoint(pt2, desired.text);
32989
+ seenContentIds.add(modelId);
32990
+ merged.push(pt2);
32991
+ }
32992
+ for (const node of nodes) {
32993
+ const id = String(node.id || "").trim();
32994
+ if (id.length === 0 || seenContentIds.has(id)) {
32995
+ continue;
32996
+ }
32997
+ const ptNode = { "@_modelId": id };
32998
+ if (node.nodeType && !NON_CONTENT_POINT_TYPES.has(node.nodeType)) {
32999
+ ptNode["@_type"] = node.nodeType;
33000
+ }
33001
+ ptNode["dgm:t"] = buildPointText(node.text);
33002
+ merged.push(ptNode);
33003
+ }
33004
+ return merged;
32870
33005
  }
32871
33006
  function buildSmartArtConnectionXml(connections) {
32872
33007
  return connections.map((conn) => {
@@ -32911,12 +33046,12 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32911
33046
  if (!this.pendingSmartArtUpdates || this.pendingSmartArtUpdates.length === 0) {
32912
33047
  return;
32913
33048
  }
32914
- for (const { element } of this.pendingSmartArtUpdates) {
33049
+ for (const { element, slidePath: capturedSlidePath } of this.pendingSmartArtUpdates) {
32915
33050
  const smartArtData = element.smartArtData;
32916
33051
  if (!smartArtData?.dataRelId) {
32917
33052
  continue;
32918
33053
  }
32919
- const slidePath = element.rawXml ? this.findSlidePathForElement(element) : void 0;
33054
+ const slidePath = capturedSlidePath && capturedSlidePath.length > 0 ? capturedSlidePath : this.findSlidePathForElement(element);
32920
33055
  if (!slidePath) {
32921
33056
  continue;
32922
33057
  }
@@ -32945,7 +33080,8 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32945
33080
  (k) => this.compatibilityService.getXmlLocalName(k) === "pt"
32946
33081
  );
32947
33082
  if (ptKey) {
32948
- ptList[ptKey] = buildSmartArtPointXml(smartArtData.nodes);
33083
+ const existingPts = this.ensureArray(ptList[ptKey]);
33084
+ ptList[ptKey] = mergeSmartArtPointXml(existingPts, smartArtData.nodes);
32949
33085
  }
32950
33086
  }
32951
33087
  if (smartArtData.connections && smartArtData.connections.length > 0) {
@@ -32962,6 +33098,11 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32962
33098
  }
32963
33099
  }
32964
33100
  }
33101
+ applySmartArtChrome(
33102
+ dataModel,
33103
+ smartArtData.chrome,
33104
+ (k) => this.compatibilityService.getXmlLocalName(k)
33105
+ );
32965
33106
  this.zip.file(dataPartPath, this.builder.build(parsed));
32966
33107
  } catch (e) {
32967
33108
  console.warn(`Failed to save SmartArt data at ${dataPartPath}:`, e);
@@ -33091,7 +33232,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33091
33232
  if (this.customXmlParts.length === 0) {
33092
33233
  return;
33093
33234
  }
33094
- const SAFE_ID = /^[A-Za-z0-9_-]+$/;
33235
+ const SAFE_ID = /^[A-Za-z0-9_-]+$/u;
33095
33236
  let fallbackIndex = 1;
33096
33237
  for (const part of this.customXmlParts) {
33097
33238
  const rawId = String(part.id);
@@ -33202,7 +33343,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33202
33343
  let maxId = 0;
33203
33344
  for (const rel of relationships) {
33204
33345
  const id = String(rel?.["@_Id"] || "");
33205
- const num = parseInt(id.replace(/^rId/, ""), 10);
33346
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33206
33347
  if (Number.isFinite(num) && num > maxId) {
33207
33348
  maxId = num;
33208
33349
  }
@@ -33325,7 +33466,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33325
33466
  let maxId = 0;
33326
33467
  for (const rel of relationships) {
33327
33468
  const id = String(rel?.["@_Id"] || "");
33328
- const num = parseInt(id.replace(/^rId/, ""), 10);
33469
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33329
33470
  if (Number.isFinite(num) && num > maxId) {
33330
33471
  maxId = num;
33331
33472
  }
@@ -42996,13 +43137,13 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
42996
43137
  parentId: parentByNodeId.get(pointId),
42997
43138
  nodeType
42998
43139
  };
42999
- }).filter((entry) => Boolean(entry)).slice(0, 50);
43140
+ }).filter((entry) => Boolean(entry)).slice(0, MAX_SMARTART_NODES);
43000
43141
  if (nodes.length === 0) {
43001
43142
  return void 0;
43002
43143
  }
43003
43144
  const layoutRelationshipId = String(relationshipIds["@_r:lo"] || "").trim();
43004
43145
  const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
43005
- const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
43146
+ const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/u, "") || void 0;
43006
43147
  const chrome = this.parseSmartArtChrome(dataModel);
43007
43148
  const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
43008
43149
  const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
@@ -43050,7 +43191,7 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
43050
43191
  return void 0;
43051
43192
  }
43052
43193
  const dataPath = this.resolveImagePath(slidePath, dataTarget);
43053
- const dataDir = dataPath.replace(/\/[^/]+$/, "");
43194
+ const dataDir = dataPath.replace(/\/[^/]+$/u, "");
43054
43195
  const dataFile = dataPath.split("/").pop() ?? "";
43055
43196
  const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
43056
43197
  const relsXml = await this.zip.file(dataRelsPath)?.async("string");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptx-viewer-core",
3
- "version": "1.1.30",
3
+ "version": "1.1.31",
4
4
  "description": "PowerPoint PPTX engine: parse, edit, serialize, and convert .pptx files. Framework-agnostic TypeScript SDK.",
5
5
  "keywords": [
6
6
  "converter",