pptx-viewer-core 1.1.30 → 1.1.32

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
  /**
@@ -3532,7 +3537,23 @@ declare function resolveModel3DMimeType(modelPath: string): string | undefined;
3532
3537
  * - Load: normalize Strict URIs to Transitional for internal processing
3533
3538
  * - Save: convert Transitional URIs back to Strict for round-trip fidelity
3534
3539
  *
3535
- * Reference: ECMA-376 5th Edition, Part 1, Annex A & B.
3540
+ * Only the markup-language families defined by ISO/IEC 29500-1 (Fundamentals
3541
+ * and Markup Language Reference) are remapped between conformance classes:
3542
+ * `presentationml`, `drawingml`, `spreadsheetml`, `wordprocessingml`,
3543
+ * `officeDocument` (including its relationship-type URIs), `schemaLibrary`, and
3544
+ * `descriptions`. This matches the authoritative translation table the Open XML
3545
+ * SDK applies when opening a Strict package.
3546
+ *
3547
+ * The Open Packaging Conventions (ISO/IEC 29500-2: `package/*` content-types and
3548
+ * relationships, and the OPC-defined relationship types such as
3549
+ * core-properties and digital-signature) and Markup Compatibility & Extensibility
3550
+ * (ISO/IEC 29500-3: `markup-compatibility/2006`) are SHARED, conformance-INDEPENDENT
3551
+ * specifications. Real Office "Strict Open XML" files keep those namespaces and
3552
+ * relationship types in their canonical `schemas.openxmlformats.org` form even
3553
+ * though the markup inside the parts uses Strict (`purl.oclc.org`) namespaces.
3554
+ * They are therefore intentionally NOT remapped here, in either direction.
3555
+ *
3556
+ * Reference: ECMA-376 5th Edition, Part 1, Annex A & B; ISO/IEC 29500 Parts 2-4.
3536
3557
  */
3537
3558
  /** OOXML conformance class. */
3538
3559
  type OoxmlConformanceClass = 'strict' | 'transitional';
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
  /**
@@ -3532,7 +3537,23 @@ declare function resolveModel3DMimeType(modelPath: string): string | undefined;
3532
3537
  * - Load: normalize Strict URIs to Transitional for internal processing
3533
3538
  * - Save: convert Transitional URIs back to Strict for round-trip fidelity
3534
3539
  *
3535
- * Reference: ECMA-376 5th Edition, Part 1, Annex A & B.
3540
+ * Only the markup-language families defined by ISO/IEC 29500-1 (Fundamentals
3541
+ * and Markup Language Reference) are remapped between conformance classes:
3542
+ * `presentationml`, `drawingml`, `spreadsheetml`, `wordprocessingml`,
3543
+ * `officeDocument` (including its relationship-type URIs), `schemaLibrary`, and
3544
+ * `descriptions`. This matches the authoritative translation table the Open XML
3545
+ * SDK applies when opening a Strict package.
3546
+ *
3547
+ * The Open Packaging Conventions (ISO/IEC 29500-2: `package/*` content-types and
3548
+ * relationships, and the OPC-defined relationship types such as
3549
+ * core-properties and digital-signature) and Markup Compatibility & Extensibility
3550
+ * (ISO/IEC 29500-3: `markup-compatibility/2006`) are SHARED, conformance-INDEPENDENT
3551
+ * specifications. Real Office "Strict Open XML" files keep those namespaces and
3552
+ * relationship types in their canonical `schemas.openxmlformats.org` form even
3553
+ * though the markup inside the parts uses Strict (`purl.oclc.org`) namespaces.
3554
+ * They are therefore intentionally NOT remapped here, in either direction.
3555
+ *
3556
+ * Reference: ECMA-376 5th Edition, Part 1, Annex A & B; ISO/IEC 29500 Parts 2-4.
3536
3557
  */
3537
3558
  /** OOXML conformance class. */
3538
3559
  type OoxmlConformanceClass = 'strict' | 'transitional';
package/dist/index.js CHANGED
@@ -12010,7 +12010,11 @@ var PptxSaveConstantsFactory = class {
12010
12010
  slideAudioRelationshipType: "http://purl.oclc.org/ooxml/officeDocument/relationships/audio",
12011
12011
  slideCommentRelationshipType: "http://purl.oclc.org/ooxml/officeDocument/relationships/comments",
12012
12012
  slideNotesRelationshipType: "http://purl.oclc.org/ooxml/officeDocument/relationships/notesSlide",
12013
- relationshipsNamespace: "http://purl.oclc.org/ooxml/package/relationships",
12013
+ // The OPC relationships namespace (the xmlns of .rels parts) is
12014
+ // conformance-independent: real Strict packages keep the canonical
12015
+ // schemas.openxmlformats.org form. Only the relationship *type*
12016
+ // URIs above switch to Strict. See strict-namespace-map.ts.
12017
+ relationshipsNamespace: "http://schemas.openxmlformats.org/package/2006/relationships",
12014
12018
  // Content types are NOT namespace-dependent; they stay the same
12015
12019
  // in both Strict and Transitional conformance.
12016
12020
  slideContentType: "application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
@@ -13772,6 +13776,9 @@ async function parseEmbeddedXlsx(xlsxData) {
13772
13776
  }
13773
13777
  }
13774
13778
 
13779
+ // src/core/core/builders/smart-art-text-helpers.ts
13780
+ var MAX_SMARTART_NODES = 2e3;
13781
+
13775
13782
  // src/core/utils/vml-color-parser.ts
13776
13783
  var NAMED_COLORS = {
13777
13784
  black: "#000000",
@@ -19941,12 +19948,20 @@ function chartDataRemoveCategory(chartData, categoryIndex) {
19941
19948
 
19942
19949
  // src/core/utils/smartart-layout-switch.ts
19943
19950
  var SWITCHABLE_LAYOUT_TYPES = [
19951
+ "list",
19944
19952
  "process",
19945
19953
  "hierarchy",
19946
19954
  "cycle",
19947
19955
  "matrix",
19948
19956
  "pyramid",
19949
- "list"
19957
+ "funnel",
19958
+ "target",
19959
+ "gear",
19960
+ "venn",
19961
+ "timeline",
19962
+ "relationship",
19963
+ "chevron",
19964
+ "bending"
19950
19965
  ];
19951
19966
  function switchSmartArtLayout(currentData, newLayoutType) {
19952
19967
  if (currentData.resolvedLayoutType === newLayoutType) {
@@ -20171,26 +20186,27 @@ var NAMESPACE_PAIRS = [
20171
20186
  "http://purl.oclc.org/ooxml/officeDocument/docPropsVTypes",
20172
20187
  "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
20173
20188
  ],
20174
- // -- Package-level relationships --
20189
+ // -- OfficeDocument document relationship --
20190
+ // (Other OPC-defined relationship types - package/relationships,
20191
+ // core-properties, digital-signature - are conformance-independent and
20192
+ // intentionally omitted; see the module header.)
20175
20193
  [
20176
20194
  "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument",
20177
20195
  "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
20178
20196
  ],
20197
+ // -- Schema Library --
20179
20198
  [
20180
- "http://purl.oclc.org/ooxml/package/relationships",
20181
- "http://schemas.openxmlformats.org/package/2006/relationships"
20182
- ],
20183
- [
20184
- "http://purl.oclc.org/ooxml/package/relationships/metadata/core-properties",
20185
- "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"
20199
+ "http://purl.oclc.org/ooxml/schemaLibrary/main",
20200
+ "http://schemas.openxmlformats.org/schemaLibrary/2006/main"
20186
20201
  ],
20202
+ // -- Content-type descriptions (note the distinct transitional host) --
20187
20203
  [
20188
- "http://purl.oclc.org/ooxml/package/relationships/digital-signature/origin",
20189
- "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
20204
+ "http://purl.oclc.org/ooxml/descriptions/base",
20205
+ "http://descriptions.openxmlformats.org/description/base"
20190
20206
  ],
20191
20207
  [
20192
- "http://purl.oclc.org/ooxml/package/relationships/digital-signature/signature",
20193
- "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature"
20208
+ "http://purl.oclc.org/ooxml/descriptions/full",
20209
+ "http://descriptions.openxmlformats.org/description/full"
20194
20210
  ],
20195
20211
  // -- SpreadsheetML (for embedded charts / workbooks) --
20196
20212
  [
@@ -20201,11 +20217,6 @@ var NAMESPACE_PAIRS = [
20201
20217
  [
20202
20218
  "http://purl.oclc.org/ooxml/wordprocessingml/main",
20203
20219
  "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
20204
- ],
20205
- // -- Markup Compatibility --
20206
- [
20207
- "http://purl.oclc.org/ooxml/markup-compatibility/2006",
20208
- "http://schemas.openxmlformats.org/markup-compatibility/2006"
20209
20220
  ]
20210
20221
  ];
20211
20222
  var STRICT_TO_TRANSITIONAL_NS = new Map(NAMESPACE_PAIRS);
@@ -20219,7 +20230,8 @@ var ALGORITHMIC_FAMILIES = /* @__PURE__ */ new Set([
20219
20230
  "drawingml",
20220
20231
  "spreadsheetml",
20221
20232
  "wordprocessingml",
20222
- "officeDocument"
20233
+ "officeDocument",
20234
+ "schemaLibrary"
20223
20235
  ]);
20224
20236
  function deriveTransitionalUri(uri) {
20225
20237
  if (!uri.startsWith(STRICT_BASE)) {
@@ -32851,27 +32863,151 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32851
32863
  }
32852
32864
  };
32853
32865
 
32866
+ // src/core/core/runtime/smartart-save-chrome.ts
32867
+ function asObject(value) {
32868
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
32869
+ }
32870
+ function applySmartArtChrome(dataModel, chrome, getLocalName) {
32871
+ if (!chrome || !chrome.backgroundColor && !chrome.outlineColor && (chrome.outlineWidth === null || chrome.outlineWidth === void 0)) {
32872
+ return;
32873
+ }
32874
+ const findKey10 = (obj, name) => Object.keys(obj).find((k) => getLocalName(k) === name);
32875
+ if (chrome.backgroundColor) {
32876
+ const hex7 = chrome.backgroundColor.replace("#", "");
32877
+ const bgKey = findKey10(dataModel, "bg") ?? "dgm:bg";
32878
+ const bg = asObject(dataModel[bgKey]);
32879
+ const fillKey = findKey10(bg, "solidFill") ?? "a:solidFill";
32880
+ bg[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32881
+ dataModel[bgKey] = bg;
32882
+ }
32883
+ const hasOutlineWidth = chrome.outlineWidth !== null && chrome.outlineWidth !== void 0;
32884
+ if (chrome.outlineColor || hasOutlineWidth) {
32885
+ const wholeKey = findKey10(dataModel, "whole") ?? "dgm:whole";
32886
+ const whole = asObject(dataModel[wholeKey]);
32887
+ const lnKey = findKey10(whole, "ln") ?? "a:ln";
32888
+ const ln = asObject(whole[lnKey]);
32889
+ if (hasOutlineWidth) {
32890
+ ln["@_w"] = String(Math.round(chrome.outlineWidth * 12700));
32891
+ }
32892
+ if (chrome.outlineColor) {
32893
+ const hex7 = chrome.outlineColor.replace("#", "");
32894
+ const fillKey = findKey10(ln, "solidFill") ?? "a:solidFill";
32895
+ ln[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32896
+ }
32897
+ whole[lnKey] = ln;
32898
+ dataModel[wholeKey] = whole;
32899
+ }
32900
+ }
32901
+
32854
32902
  // 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;
32903
+ var NON_CONTENT_POINT_TYPES = /* @__PURE__ */ new Set([
32904
+ "doc",
32905
+ "pres",
32906
+ "parTrans",
32907
+ "sibTrans"
32908
+ ]);
32909
+ function pointType(pt2) {
32910
+ return String(pt2["@_type"] || "").trim();
32911
+ }
32912
+ function pointModelId(pt2) {
32913
+ return String(pt2["@_modelId"] || "").trim();
32914
+ }
32915
+ function isContentPoint(pt2) {
32916
+ return !NON_CONTENT_POINT_TYPES.has(pointType(pt2));
32917
+ }
32918
+ function buildPointText(text) {
32919
+ return {
32920
+ "a:bodyPr": {},
32921
+ "a:lstStyle": {},
32922
+ "a:p": {
32923
+ "a:r": {
32924
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32925
+ "a:t": text
32926
+ }
32862
32927
  }
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
- }
32928
+ };
32929
+ }
32930
+ function applyTextToExistingPoint(pt2, text) {
32931
+ const tKey = Object.keys(pt2).find((k) => stripPrefix(k) === "t");
32932
+ if (!tKey) {
32933
+ pt2["dgm:t"] = buildPointText(text);
32934
+ return;
32935
+ }
32936
+ const body = pt2[tKey];
32937
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
32938
+ pt2[tKey] = buildPointText(text);
32939
+ return;
32940
+ }
32941
+ const bodyObj = body;
32942
+ const pKey = Object.keys(bodyObj).find((k) => stripPrefix(k) === "p");
32943
+ const paragraph = pKey ? bodyObj[pKey] : void 0;
32944
+ if (!pKey || Array.isArray(paragraph) || !paragraph || typeof paragraph !== "object") {
32945
+ bodyObj[pKey ?? "a:p"] = {
32946
+ "a:r": {
32947
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32948
+ "a:t": text
32871
32949
  }
32872
32950
  };
32873
- return ptNode;
32874
- });
32951
+ return;
32952
+ }
32953
+ const paragraphObj = paragraph;
32954
+ const rKey = Object.keys(paragraphObj).find((k) => stripPrefix(k) === "r");
32955
+ const run = rKey ? paragraphObj[rKey] : void 0;
32956
+ if (!rKey || Array.isArray(run) || !run || typeof run !== "object") {
32957
+ paragraphObj[rKey ?? "a:r"] = {
32958
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32959
+ "a:t": text
32960
+ };
32961
+ return;
32962
+ }
32963
+ const runObj = run;
32964
+ const textKey = Object.keys(runObj).find((k) => stripPrefix(k) === "t");
32965
+ runObj[textKey ?? "a:t"] = text;
32966
+ }
32967
+ function stripPrefix(key) {
32968
+ const idx = key.indexOf(":");
32969
+ return idx >= 0 ? key.slice(idx + 1) : key;
32970
+ }
32971
+ function mergeSmartArtPointXml(existingPts, nodes) {
32972
+ const desiredById = /* @__PURE__ */ new Map();
32973
+ for (const node of nodes) {
32974
+ const id = String(node.id || "").trim();
32975
+ if (id.length > 0) {
32976
+ desiredById.set(id, node);
32977
+ }
32978
+ }
32979
+ const seenContentIds = /* @__PURE__ */ new Set();
32980
+ const merged = [];
32981
+ for (const pt2 of existingPts) {
32982
+ if (!pt2 || typeof pt2 !== "object") {
32983
+ continue;
32984
+ }
32985
+ if (!isContentPoint(pt2)) {
32986
+ merged.push(pt2);
32987
+ continue;
32988
+ }
32989
+ const modelId = pointModelId(pt2);
32990
+ const desired = modelId.length > 0 ? desiredById.get(modelId) : void 0;
32991
+ if (!desired) {
32992
+ continue;
32993
+ }
32994
+ applyTextToExistingPoint(pt2, desired.text);
32995
+ seenContentIds.add(modelId);
32996
+ merged.push(pt2);
32997
+ }
32998
+ for (const node of nodes) {
32999
+ const id = String(node.id || "").trim();
33000
+ if (id.length === 0 || seenContentIds.has(id)) {
33001
+ continue;
33002
+ }
33003
+ const ptNode = { "@_modelId": id };
33004
+ if (node.nodeType && !NON_CONTENT_POINT_TYPES.has(node.nodeType)) {
33005
+ ptNode["@_type"] = node.nodeType;
33006
+ }
33007
+ ptNode["dgm:t"] = buildPointText(node.text);
33008
+ merged.push(ptNode);
33009
+ }
33010
+ return merged;
32875
33011
  }
32876
33012
  function buildSmartArtConnectionXml(connections) {
32877
33013
  return connections.map((conn) => {
@@ -32916,12 +33052,12 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32916
33052
  if (!this.pendingSmartArtUpdates || this.pendingSmartArtUpdates.length === 0) {
32917
33053
  return;
32918
33054
  }
32919
- for (const { element } of this.pendingSmartArtUpdates) {
33055
+ for (const { element, slidePath: capturedSlidePath } of this.pendingSmartArtUpdates) {
32920
33056
  const smartArtData = element.smartArtData;
32921
33057
  if (!smartArtData?.dataRelId) {
32922
33058
  continue;
32923
33059
  }
32924
- const slidePath = element.rawXml ? this.findSlidePathForElement(element) : void 0;
33060
+ const slidePath = capturedSlidePath && capturedSlidePath.length > 0 ? capturedSlidePath : this.findSlidePathForElement(element);
32925
33061
  if (!slidePath) {
32926
33062
  continue;
32927
33063
  }
@@ -32950,7 +33086,8 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32950
33086
  (k) => this.compatibilityService.getXmlLocalName(k) === "pt"
32951
33087
  );
32952
33088
  if (ptKey) {
32953
- ptList[ptKey] = buildSmartArtPointXml(smartArtData.nodes);
33089
+ const existingPts = this.ensureArray(ptList[ptKey]);
33090
+ ptList[ptKey] = mergeSmartArtPointXml(existingPts, smartArtData.nodes);
32954
33091
  }
32955
33092
  }
32956
33093
  if (smartArtData.connections && smartArtData.connections.length > 0) {
@@ -32967,6 +33104,11 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32967
33104
  }
32968
33105
  }
32969
33106
  }
33107
+ applySmartArtChrome(
33108
+ dataModel,
33109
+ smartArtData.chrome,
33110
+ (k) => this.compatibilityService.getXmlLocalName(k)
33111
+ );
32970
33112
  this.zip.file(dataPartPath, this.builder.build(parsed));
32971
33113
  } catch (e) {
32972
33114
  console.warn(`Failed to save SmartArt data at ${dataPartPath}:`, e);
@@ -33096,7 +33238,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33096
33238
  if (this.customXmlParts.length === 0) {
33097
33239
  return;
33098
33240
  }
33099
- const SAFE_ID = /^[A-Za-z0-9_-]+$/;
33241
+ const SAFE_ID = /^[A-Za-z0-9_-]+$/u;
33100
33242
  let fallbackIndex = 1;
33101
33243
  for (const part of this.customXmlParts) {
33102
33244
  const rawId = String(part.id);
@@ -33207,7 +33349,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33207
33349
  let maxId = 0;
33208
33350
  for (const rel of relationships) {
33209
33351
  const id = String(rel?.["@_Id"] || "");
33210
- const num = parseInt(id.replace(/^rId/, ""), 10);
33352
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33211
33353
  if (Number.isFinite(num) && num > maxId) {
33212
33354
  maxId = num;
33213
33355
  }
@@ -33330,7 +33472,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33330
33472
  let maxId = 0;
33331
33473
  for (const rel of relationships) {
33332
33474
  const id = String(rel?.["@_Id"] || "");
33333
- const num = parseInt(id.replace(/^rId/, ""), 10);
33475
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33334
33476
  if (Number.isFinite(num) && num > maxId) {
33335
33477
  maxId = num;
33336
33478
  }
@@ -36159,6 +36301,12 @@ var PptxHandlerRuntime40 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
36159
36301
  xmlLookupService: this.xmlLookupService
36160
36302
  });
36161
36303
  this.deduplicateExtensionLists(this.presentationData);
36304
+ if (effectiveConformance === "transitional") {
36305
+ const presentationNode = this.presentationData["p:presentation"];
36306
+ if (presentationNode && "@_conformance" in presentationNode) {
36307
+ delete presentationNode["@_conformance"];
36308
+ }
36309
+ }
36162
36310
  const presentationXml2 = this.builder.build(this.presentationData);
36163
36311
  this.zip.file("ppt/presentation.xml", presentationXml2);
36164
36312
  }
@@ -43001,13 +43149,13 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
43001
43149
  parentId: parentByNodeId.get(pointId),
43002
43150
  nodeType
43003
43151
  };
43004
- }).filter((entry) => Boolean(entry)).slice(0, 50);
43152
+ }).filter((entry) => Boolean(entry)).slice(0, MAX_SMARTART_NODES);
43005
43153
  if (nodes.length === 0) {
43006
43154
  return void 0;
43007
43155
  }
43008
43156
  const layoutRelationshipId = String(relationshipIds["@_r:lo"] || "").trim();
43009
43157
  const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
43010
- const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
43158
+ const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/u, "") || void 0;
43011
43159
  const chrome = this.parseSmartArtChrome(dataModel);
43012
43160
  const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
43013
43161
  const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
@@ -43055,7 +43203,7 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
43055
43203
  return void 0;
43056
43204
  }
43057
43205
  const dataPath = this.resolveImagePath(slidePath, dataTarget);
43058
- const dataDir = dataPath.replace(/\/[^/]+$/, "");
43206
+ const dataDir = dataPath.replace(/\/[^/]+$/u, "");
43059
43207
  const dataFile = dataPath.split("/").pop() ?? "";
43060
43208
  const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
43061
43209
  const relsXml = await this.zip.file(dataRelsPath)?.async("string");
package/dist/index.mjs CHANGED
@@ -12005,7 +12005,11 @@ var PptxSaveConstantsFactory = class {
12005
12005
  slideAudioRelationshipType: "http://purl.oclc.org/ooxml/officeDocument/relationships/audio",
12006
12006
  slideCommentRelationshipType: "http://purl.oclc.org/ooxml/officeDocument/relationships/comments",
12007
12007
  slideNotesRelationshipType: "http://purl.oclc.org/ooxml/officeDocument/relationships/notesSlide",
12008
- relationshipsNamespace: "http://purl.oclc.org/ooxml/package/relationships",
12008
+ // The OPC relationships namespace (the xmlns of .rels parts) is
12009
+ // conformance-independent: real Strict packages keep the canonical
12010
+ // schemas.openxmlformats.org form. Only the relationship *type*
12011
+ // URIs above switch to Strict. See strict-namespace-map.ts.
12012
+ relationshipsNamespace: "http://schemas.openxmlformats.org/package/2006/relationships",
12009
12013
  // Content types are NOT namespace-dependent; they stay the same
12010
12014
  // in both Strict and Transitional conformance.
12011
12015
  slideContentType: "application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
@@ -13767,6 +13771,9 @@ async function parseEmbeddedXlsx(xlsxData) {
13767
13771
  }
13768
13772
  }
13769
13773
 
13774
+ // src/core/core/builders/smart-art-text-helpers.ts
13775
+ var MAX_SMARTART_NODES = 2e3;
13776
+
13770
13777
  // src/core/utils/vml-color-parser.ts
13771
13778
  var NAMED_COLORS = {
13772
13779
  black: "#000000",
@@ -19936,12 +19943,20 @@ function chartDataRemoveCategory(chartData, categoryIndex) {
19936
19943
 
19937
19944
  // src/core/utils/smartart-layout-switch.ts
19938
19945
  var SWITCHABLE_LAYOUT_TYPES = [
19946
+ "list",
19939
19947
  "process",
19940
19948
  "hierarchy",
19941
19949
  "cycle",
19942
19950
  "matrix",
19943
19951
  "pyramid",
19944
- "list"
19952
+ "funnel",
19953
+ "target",
19954
+ "gear",
19955
+ "venn",
19956
+ "timeline",
19957
+ "relationship",
19958
+ "chevron",
19959
+ "bending"
19945
19960
  ];
19946
19961
  function switchSmartArtLayout(currentData, newLayoutType) {
19947
19962
  if (currentData.resolvedLayoutType === newLayoutType) {
@@ -20166,26 +20181,27 @@ var NAMESPACE_PAIRS = [
20166
20181
  "http://purl.oclc.org/ooxml/officeDocument/docPropsVTypes",
20167
20182
  "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
20168
20183
  ],
20169
- // -- Package-level relationships --
20184
+ // -- OfficeDocument document relationship --
20185
+ // (Other OPC-defined relationship types - package/relationships,
20186
+ // core-properties, digital-signature - are conformance-independent and
20187
+ // intentionally omitted; see the module header.)
20170
20188
  [
20171
20189
  "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument",
20172
20190
  "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
20173
20191
  ],
20192
+ // -- Schema Library --
20174
20193
  [
20175
- "http://purl.oclc.org/ooxml/package/relationships",
20176
- "http://schemas.openxmlformats.org/package/2006/relationships"
20177
- ],
20178
- [
20179
- "http://purl.oclc.org/ooxml/package/relationships/metadata/core-properties",
20180
- "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"
20194
+ "http://purl.oclc.org/ooxml/schemaLibrary/main",
20195
+ "http://schemas.openxmlformats.org/schemaLibrary/2006/main"
20181
20196
  ],
20197
+ // -- Content-type descriptions (note the distinct transitional host) --
20182
20198
  [
20183
- "http://purl.oclc.org/ooxml/package/relationships/digital-signature/origin",
20184
- "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
20199
+ "http://purl.oclc.org/ooxml/descriptions/base",
20200
+ "http://descriptions.openxmlformats.org/description/base"
20185
20201
  ],
20186
20202
  [
20187
- "http://purl.oclc.org/ooxml/package/relationships/digital-signature/signature",
20188
- "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature"
20203
+ "http://purl.oclc.org/ooxml/descriptions/full",
20204
+ "http://descriptions.openxmlformats.org/description/full"
20189
20205
  ],
20190
20206
  // -- SpreadsheetML (for embedded charts / workbooks) --
20191
20207
  [
@@ -20196,11 +20212,6 @@ var NAMESPACE_PAIRS = [
20196
20212
  [
20197
20213
  "http://purl.oclc.org/ooxml/wordprocessingml/main",
20198
20214
  "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
20199
- ],
20200
- // -- Markup Compatibility --
20201
- [
20202
- "http://purl.oclc.org/ooxml/markup-compatibility/2006",
20203
- "http://schemas.openxmlformats.org/markup-compatibility/2006"
20204
20215
  ]
20205
20216
  ];
20206
20217
  var STRICT_TO_TRANSITIONAL_NS = new Map(NAMESPACE_PAIRS);
@@ -20214,7 +20225,8 @@ var ALGORITHMIC_FAMILIES = /* @__PURE__ */ new Set([
20214
20225
  "drawingml",
20215
20226
  "spreadsheetml",
20216
20227
  "wordprocessingml",
20217
- "officeDocument"
20228
+ "officeDocument",
20229
+ "schemaLibrary"
20218
20230
  ]);
20219
20231
  function deriveTransitionalUri(uri) {
20220
20232
  if (!uri.startsWith(STRICT_BASE)) {
@@ -32846,27 +32858,151 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32846
32858
  }
32847
32859
  };
32848
32860
 
32861
+ // src/core/core/runtime/smartart-save-chrome.ts
32862
+ function asObject(value) {
32863
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
32864
+ }
32865
+ function applySmartArtChrome(dataModel, chrome, getLocalName) {
32866
+ if (!chrome || !chrome.backgroundColor && !chrome.outlineColor && (chrome.outlineWidth === null || chrome.outlineWidth === void 0)) {
32867
+ return;
32868
+ }
32869
+ const findKey10 = (obj, name) => Object.keys(obj).find((k) => getLocalName(k) === name);
32870
+ if (chrome.backgroundColor) {
32871
+ const hex7 = chrome.backgroundColor.replace("#", "");
32872
+ const bgKey = findKey10(dataModel, "bg") ?? "dgm:bg";
32873
+ const bg = asObject(dataModel[bgKey]);
32874
+ const fillKey = findKey10(bg, "solidFill") ?? "a:solidFill";
32875
+ bg[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32876
+ dataModel[bgKey] = bg;
32877
+ }
32878
+ const hasOutlineWidth = chrome.outlineWidth !== null && chrome.outlineWidth !== void 0;
32879
+ if (chrome.outlineColor || hasOutlineWidth) {
32880
+ const wholeKey = findKey10(dataModel, "whole") ?? "dgm:whole";
32881
+ const whole = asObject(dataModel[wholeKey]);
32882
+ const lnKey = findKey10(whole, "ln") ?? "a:ln";
32883
+ const ln = asObject(whole[lnKey]);
32884
+ if (hasOutlineWidth) {
32885
+ ln["@_w"] = String(Math.round(chrome.outlineWidth * 12700));
32886
+ }
32887
+ if (chrome.outlineColor) {
32888
+ const hex7 = chrome.outlineColor.replace("#", "");
32889
+ const fillKey = findKey10(ln, "solidFill") ?? "a:solidFill";
32890
+ ln[fillKey] = { "a:srgbClr": { "@_val": hex7 } };
32891
+ }
32892
+ whole[lnKey] = ln;
32893
+ dataModel[wholeKey] = whole;
32894
+ }
32895
+ }
32896
+
32849
32897
  // 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;
32898
+ var NON_CONTENT_POINT_TYPES = /* @__PURE__ */ new Set([
32899
+ "doc",
32900
+ "pres",
32901
+ "parTrans",
32902
+ "sibTrans"
32903
+ ]);
32904
+ function pointType(pt2) {
32905
+ return String(pt2["@_type"] || "").trim();
32906
+ }
32907
+ function pointModelId(pt2) {
32908
+ return String(pt2["@_modelId"] || "").trim();
32909
+ }
32910
+ function isContentPoint(pt2) {
32911
+ return !NON_CONTENT_POINT_TYPES.has(pointType(pt2));
32912
+ }
32913
+ function buildPointText(text) {
32914
+ return {
32915
+ "a:bodyPr": {},
32916
+ "a:lstStyle": {},
32917
+ "a:p": {
32918
+ "a:r": {
32919
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32920
+ "a:t": text
32921
+ }
32857
32922
  }
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
- }
32923
+ };
32924
+ }
32925
+ function applyTextToExistingPoint(pt2, text) {
32926
+ const tKey = Object.keys(pt2).find((k) => stripPrefix(k) === "t");
32927
+ if (!tKey) {
32928
+ pt2["dgm:t"] = buildPointText(text);
32929
+ return;
32930
+ }
32931
+ const body = pt2[tKey];
32932
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
32933
+ pt2[tKey] = buildPointText(text);
32934
+ return;
32935
+ }
32936
+ const bodyObj = body;
32937
+ const pKey = Object.keys(bodyObj).find((k) => stripPrefix(k) === "p");
32938
+ const paragraph = pKey ? bodyObj[pKey] : void 0;
32939
+ if (!pKey || Array.isArray(paragraph) || !paragraph || typeof paragraph !== "object") {
32940
+ bodyObj[pKey ?? "a:p"] = {
32941
+ "a:r": {
32942
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32943
+ "a:t": text
32866
32944
  }
32867
32945
  };
32868
- return ptNode;
32869
- });
32946
+ return;
32947
+ }
32948
+ const paragraphObj = paragraph;
32949
+ const rKey = Object.keys(paragraphObj).find((k) => stripPrefix(k) === "r");
32950
+ const run = rKey ? paragraphObj[rKey] : void 0;
32951
+ if (!rKey || Array.isArray(run) || !run || typeof run !== "object") {
32952
+ paragraphObj[rKey ?? "a:r"] = {
32953
+ "a:rPr": { "@_lang": "en-US", "@_dirty": "0" },
32954
+ "a:t": text
32955
+ };
32956
+ return;
32957
+ }
32958
+ const runObj = run;
32959
+ const textKey = Object.keys(runObj).find((k) => stripPrefix(k) === "t");
32960
+ runObj[textKey ?? "a:t"] = text;
32961
+ }
32962
+ function stripPrefix(key) {
32963
+ const idx = key.indexOf(":");
32964
+ return idx >= 0 ? key.slice(idx + 1) : key;
32965
+ }
32966
+ function mergeSmartArtPointXml(existingPts, nodes) {
32967
+ const desiredById = /* @__PURE__ */ new Map();
32968
+ for (const node of nodes) {
32969
+ const id = String(node.id || "").trim();
32970
+ if (id.length > 0) {
32971
+ desiredById.set(id, node);
32972
+ }
32973
+ }
32974
+ const seenContentIds = /* @__PURE__ */ new Set();
32975
+ const merged = [];
32976
+ for (const pt2 of existingPts) {
32977
+ if (!pt2 || typeof pt2 !== "object") {
32978
+ continue;
32979
+ }
32980
+ if (!isContentPoint(pt2)) {
32981
+ merged.push(pt2);
32982
+ continue;
32983
+ }
32984
+ const modelId = pointModelId(pt2);
32985
+ const desired = modelId.length > 0 ? desiredById.get(modelId) : void 0;
32986
+ if (!desired) {
32987
+ continue;
32988
+ }
32989
+ applyTextToExistingPoint(pt2, desired.text);
32990
+ seenContentIds.add(modelId);
32991
+ merged.push(pt2);
32992
+ }
32993
+ for (const node of nodes) {
32994
+ const id = String(node.id || "").trim();
32995
+ if (id.length === 0 || seenContentIds.has(id)) {
32996
+ continue;
32997
+ }
32998
+ const ptNode = { "@_modelId": id };
32999
+ if (node.nodeType && !NON_CONTENT_POINT_TYPES.has(node.nodeType)) {
33000
+ ptNode["@_type"] = node.nodeType;
33001
+ }
33002
+ ptNode["dgm:t"] = buildPointText(node.text);
33003
+ merged.push(ptNode);
33004
+ }
33005
+ return merged;
32870
33006
  }
32871
33007
  function buildSmartArtConnectionXml(connections) {
32872
33008
  return connections.map((conn) => {
@@ -32911,12 +33047,12 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32911
33047
  if (!this.pendingSmartArtUpdates || this.pendingSmartArtUpdates.length === 0) {
32912
33048
  return;
32913
33049
  }
32914
- for (const { element } of this.pendingSmartArtUpdates) {
33050
+ for (const { element, slidePath: capturedSlidePath } of this.pendingSmartArtUpdates) {
32915
33051
  const smartArtData = element.smartArtData;
32916
33052
  if (!smartArtData?.dataRelId) {
32917
33053
  continue;
32918
33054
  }
32919
- const slidePath = element.rawXml ? this.findSlidePathForElement(element) : void 0;
33055
+ const slidePath = capturedSlidePath && capturedSlidePath.length > 0 ? capturedSlidePath : this.findSlidePathForElement(element);
32920
33056
  if (!slidePath) {
32921
33057
  continue;
32922
33058
  }
@@ -32945,7 +33081,8 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32945
33081
  (k) => this.compatibilityService.getXmlLocalName(k) === "pt"
32946
33082
  );
32947
33083
  if (ptKey) {
32948
- ptList[ptKey] = buildSmartArtPointXml(smartArtData.nodes);
33084
+ const existingPts = this.ensureArray(ptList[ptKey]);
33085
+ ptList[ptKey] = mergeSmartArtPointXml(existingPts, smartArtData.nodes);
32949
33086
  }
32950
33087
  }
32951
33088
  if (smartArtData.connections && smartArtData.connections.length > 0) {
@@ -32962,6 +33099,11 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
32962
33099
  }
32963
33100
  }
32964
33101
  }
33102
+ applySmartArtChrome(
33103
+ dataModel,
33104
+ smartArtData.chrome,
33105
+ (k) => this.compatibilityService.getXmlLocalName(k)
33106
+ );
32965
33107
  this.zip.file(dataPartPath, this.builder.build(parsed));
32966
33108
  } catch (e) {
32967
33109
  console.warn(`Failed to save SmartArt data at ${dataPartPath}:`, e);
@@ -33091,7 +33233,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33091
33233
  if (this.customXmlParts.length === 0) {
33092
33234
  return;
33093
33235
  }
33094
- const SAFE_ID = /^[A-Za-z0-9_-]+$/;
33236
+ const SAFE_ID = /^[A-Za-z0-9_-]+$/u;
33095
33237
  let fallbackIndex = 1;
33096
33238
  for (const part of this.customXmlParts) {
33097
33239
  const rawId = String(part.id);
@@ -33202,7 +33344,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33202
33344
  let maxId = 0;
33203
33345
  for (const rel of relationships) {
33204
33346
  const id = String(rel?.["@_Id"] || "");
33205
- const num = parseInt(id.replace(/^rId/, ""), 10);
33347
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33206
33348
  if (Number.isFinite(num) && num > maxId) {
33207
33349
  maxId = num;
33208
33350
  }
@@ -33325,7 +33467,7 @@ var PptxHandlerRuntime24 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
33325
33467
  let maxId = 0;
33326
33468
  for (const rel of relationships) {
33327
33469
  const id = String(rel?.["@_Id"] || "");
33328
- const num = parseInt(id.replace(/^rId/, ""), 10);
33470
+ const num = parseInt(id.replace(/^rId/u, ""), 10);
33329
33471
  if (Number.isFinite(num) && num > maxId) {
33330
33472
  maxId = num;
33331
33473
  }
@@ -36154,6 +36296,12 @@ var PptxHandlerRuntime40 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
36154
36296
  xmlLookupService: this.xmlLookupService
36155
36297
  });
36156
36298
  this.deduplicateExtensionLists(this.presentationData);
36299
+ if (effectiveConformance === "transitional") {
36300
+ const presentationNode = this.presentationData["p:presentation"];
36301
+ if (presentationNode && "@_conformance" in presentationNode) {
36302
+ delete presentationNode["@_conformance"];
36303
+ }
36304
+ }
36157
36305
  const presentationXml2 = this.builder.build(this.presentationData);
36158
36306
  this.zip.file("ppt/presentation.xml", presentationXml2);
36159
36307
  }
@@ -42996,13 +43144,13 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
42996
43144
  parentId: parentByNodeId.get(pointId),
42997
43145
  nodeType
42998
43146
  };
42999
- }).filter((entry) => Boolean(entry)).slice(0, 50);
43147
+ }).filter((entry) => Boolean(entry)).slice(0, MAX_SMARTART_NODES);
43000
43148
  if (nodes.length === 0) {
43001
43149
  return void 0;
43002
43150
  }
43003
43151
  const layoutRelationshipId = String(relationshipIds["@_r:lo"] || "").trim();
43004
43152
  const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
43005
- const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
43153
+ const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/u, "") || void 0;
43006
43154
  const chrome = this.parseSmartArtChrome(dataModel);
43007
43155
  const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
43008
43156
  const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
@@ -43050,7 +43198,7 @@ var PptxHandlerRuntime70 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
43050
43198
  return void 0;
43051
43199
  }
43052
43200
  const dataPath = this.resolveImagePath(slidePath, dataTarget);
43053
- const dataDir = dataPath.replace(/\/[^/]+$/, "");
43201
+ const dataDir = dataPath.replace(/\/[^/]+$/u, "");
43054
43202
  const dataFile = dataPath.split("/").pop() ?? "";
43055
43203
  const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
43056
43204
  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.32",
4
4
  "description": "PowerPoint PPTX engine: parse, edit, serialize, and convert .pptx files. Framework-agnostic TypeScript SDK.",
5
5
  "keywords": [
6
6
  "converter",