ooxml-core 1.6.2 → 1.7.0

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.
Files changed (52) hide show
  1. package/dist/automation/index.cjs +481 -231
  2. package/dist/automation/index.mjs +481 -231
  3. package/dist/geometry/index.cjs +25 -0
  4. package/dist/geometry/index.d.ts +1 -0
  5. package/dist/geometry/index.d.ts.map +1 -1
  6. package/dist/geometry/index.mjs +24 -1
  7. package/dist/geometry/nudge.d.ts +12 -0
  8. package/dist/geometry/nudge.d.ts.map +1 -0
  9. package/dist/geometry/rotation-drag.d.ts +6 -0
  10. package/dist/geometry/rotation-drag.d.ts.map +1 -1
  11. package/dist/index.cjs +25 -0
  12. package/dist/index.mjs +25 -0
  13. package/dist/pptx/automation/index.cjs +7 -2
  14. package/dist/pptx/cli/index.cjs +7 -2
  15. package/dist/pptx/converter/index.cjs +7 -2
  16. package/dist/pptx/index.cjs +7 -2
  17. package/dist/teams/index.cjs +7 -2
  18. package/dist/teams/index.mjs +7 -2
  19. package/dist/visio/edit-commands.d.ts +3 -1
  20. package/dist/visio/edit-commands.d.ts.map +1 -1
  21. package/dist/visio/edit-layer-properties.d.ts +22 -0
  22. package/dist/visio/edit-layer-properties.d.ts.map +1 -0
  23. package/dist/visio/edit-text-instance.d.ts +21 -0
  24. package/dist/visio/edit-text-instance.d.ts.map +1 -0
  25. package/dist/visio/edit-text-ranges.d.ts.map +1 -1
  26. package/dist/visio/edit-text-scope.d.ts +6 -1
  27. package/dist/visio/edit-text-scope.d.ts.map +1 -1
  28. package/dist/visio/edit-text-target.d.ts +11 -1
  29. package/dist/visio/edit-text-target.d.ts.map +1 -1
  30. package/dist/visio/edit-text.d.ts +2 -1
  31. package/dist/visio/edit-text.d.ts.map +1 -1
  32. package/dist/visio/edit.d.ts +1 -1
  33. package/dist/visio/edit.d.ts.map +1 -1
  34. package/dist/visio/index.cjs +470 -220
  35. package/dist/visio/index.d.ts +1 -1
  36. package/dist/visio/index.d.ts.map +1 -1
  37. package/dist/visio/index.mjs +470 -220
  38. package/dist/visio/text-fields.d.ts.map +1 -1
  39. package/dist/visio/ui/edit-commands.d.ts.map +1 -1
  40. package/dist/visio/ui/edit-error.d.ts +4 -1
  41. package/dist/visio/ui/edit-error.d.ts.map +1 -1
  42. package/dist/visio/ui/guides.d.ts +5 -0
  43. package/dist/visio/ui/guides.d.ts.map +1 -1
  44. package/dist/visio/ui/index.cjs +19768 -1874
  45. package/dist/visio/ui/index.d.ts +1 -0
  46. package/dist/visio/ui/index.d.ts.map +1 -1
  47. package/dist/visio/ui/index.mjs +19765 -1877
  48. package/dist/visio/ui/sample-drawing.d.ts +8 -0
  49. package/dist/visio/ui/sample-drawing.d.ts.map +1 -0
  50. package/dist/visio/ui/shape-move.d.ts +6 -0
  51. package/dist/visio/ui/shape-move.d.ts.map +1 -1
  52. package/package.json +2 -1
@@ -4101,7 +4101,7 @@ function assertUnlayeredShape(shape, document) {
4101
4101
  }
4102
4102
 
4103
4103
  // visio/edit-text-target.ts
4104
- function localTextTarget(root2, document, shapeId2, check) {
4104
+ function textTarget(root2, shapeId2, check) {
4105
4105
  const shapeChildren = (parent) => {
4106
4106
  const containers = children2(parent, "Shapes");
4107
4107
  if (containers.length > 1)
@@ -4109,35 +4109,145 @@ function localTextTarget(root2, document, shapeId2, check) {
4109
4109
  return children2(containers[0], "Shape");
4110
4110
  };
4111
4111
  const shapes = /* @__PURE__ */ new Map();
4112
- const pending = shapeChildren(root2).map((node2) => ({ node: node2, inherited: false, deleted: false }));
4112
+ const pending = shapeChildren(root2).map((node2) => ({
4113
+ node: node2,
4114
+ masterId: void 0,
4115
+ deleted: false
4116
+ }));
4113
4117
  while (pending.length) {
4114
4118
  check();
4115
4119
  const item = pending.pop(), id3 = attribute2(item.node, "ID");
4116
4120
  if (!id3 || shapes.has(id3))
4117
4121
  fail("INVALID_SHAPE_ID", "Local shape IDs must be present and unique.");
4118
- const inherited = item.inherited || item.node.hasAttribute("Master") || item.node.hasAttribute("MasterShape");
4122
+ const masterId = attribute2(item.node, "Master") ?? item.masterId;
4119
4123
  const deleted = item.deleted || ["1", "true"].includes(attribute2(item.node, "Del") ?? "");
4120
- shapes.set(id3, { node: item.node, inherited, deleted });
4121
- for (const node2 of shapeChildren(item.node)) pending.push({ node: node2, inherited, deleted });
4124
+ shapes.set(id3, { node: item.node, masterId, deleted });
4125
+ for (const node2 of shapeChildren(item.node)) pending.push({ node: node2, masterId, deleted });
4122
4126
  }
4123
4127
  const target2 = shapes.get(shapeId2);
4124
4128
  if (!target2) fail("EDIT_TARGET_NOT_FOUND", "Local shape does not exist.");
4125
- if (target2.inherited || target2.deleted)
4126
- fail("UNSUPPORTED_TEXT_EDIT", "Master-linked or deleted shapes cannot be edited.");
4129
+ if (target2.deleted) fail("UNSUPPORTED_TEXT_EDIT", "Deleted shapes cannot be edited.");
4130
+ const masterShapeId = attribute2(target2.node, "MasterShape");
4131
+ if (masterShapeId !== void 0 && target2.masterId === void 0)
4132
+ fail("UNSUPPORTED_TEXT_EDIT", "The shape refers to a master that is not on this page.");
4133
+ return {
4134
+ node: target2.node,
4135
+ ...target2.masterId !== void 0 ? { masterId: target2.masterId } : {},
4136
+ ...masterShapeId !== void 0 ? { masterShapeId } : {}
4137
+ };
4138
+ }
4139
+ function localTextTarget(root2, document, shapeId2, check) {
4140
+ const target2 = textTarget(root2, shapeId2, check);
4141
+ if (target2.masterId !== void 0)
4142
+ fail("UNSUPPORTED_TEXT_EDIT", "Text ranges and fields of stencil shapes cannot be edited.");
4127
4143
  assertShapeLocks(target2.node, document, ["LockTextEdit"]);
4128
4144
  return target2.node;
4129
4145
  }
4130
4146
 
4147
+ // visio/edit-text-instance.ts
4148
+ var fieldSections = (shape) => children2(shape, "Section").filter((section2) => attribute2(section2, "N") === "Field");
4149
+ var isMarkup = (node2) => node2.nodeType !== 3 && node2.nodeType !== 4;
4150
+ var knownMarkup = (text3) => Array.from(text3.childNodes).every(
4151
+ (node2) => !isMarkup(node2) || ["cp", "pp", "tp", "fld"].includes(node2.localName)
4152
+ );
4153
+ function assertUnlocked(shape, template) {
4154
+ const local = children2(shape, "Cell").some((cell) => attribute2(cell, "N") === "LockTextEdit");
4155
+ for (const cell of children2(local ? shape : template, "Cell")) {
4156
+ if (attribute2(cell, "N") !== "LockTextEdit") continue;
4157
+ if (cell.hasAttribute("E") || cell.hasAttribute("F") || Number(attribute2(cell, "V")) !== 0)
4158
+ fail("EDIT_PROTECTED_CELL", "The shape is protected against text editing.");
4159
+ }
4160
+ }
4161
+ function single(shape, what) {
4162
+ const texts = children2(shape, "Text");
4163
+ if (texts.length > 1) fail("UNSUPPORTED_TEXT_EDIT", `${what} has more than one Text element.`);
4164
+ return texts[0];
4165
+ }
4166
+ function insertBeforeTail(shape, node2, tail) {
4167
+ const after = Array.from(shape.childNodes).find(
4168
+ (child3) => child3.nodeType === 1 && tail.includes(child3.localName)
4169
+ );
4170
+ shape.insertBefore(node2, after ?? null);
4171
+ }
4172
+ var AFTER_TEXT = ["Data1", "Data2", "Data3", "ForeignData", "Shapes"];
4173
+ function replaceInstanceText(shape, template, text3) {
4174
+ const local = single(shape, "The shape");
4175
+ const inherited = single(template, "The master shape");
4176
+ if (local && Array.from(local.childNodes).some(isMarkup))
4177
+ fail(
4178
+ "UNSUPPORTED_TEXT_EDIT",
4179
+ "This stencil shape has its own formatted text; edit part of the text instead."
4180
+ );
4181
+ if (!local && inherited && !knownMarkup(inherited))
4182
+ fail("UNSUPPORTED_TEXT_EDIT", "The master text has markup this editor does not know.");
4183
+ if (fieldSections(shape).length)
4184
+ fail("UNSUPPORTED_TEXT_EDIT", "This stencil shape has its own text fields; edit around them.");
4185
+ assertUnlocked(shape, template);
4186
+ const fields = local ? [] : fieldSections(template).flatMap((section2) => children2(section2, "Row"));
4187
+ const current = local ?? inherited;
4188
+ if (!fields.length && current && !Array.from(current.childNodes).some(isMarkup)) {
4189
+ if (decodeVisioPlainText(current.textContent ?? "") === text3) return false;
4190
+ }
4191
+ const document = shape.ownerDocument;
4192
+ if (fields.length) {
4193
+ const section2 = document.createElementNS(shape.namespaceURI, "Section");
4194
+ section2.setAttribute("N", "Field");
4195
+ for (const row2 of fields) {
4196
+ const index = attribute2(row2, "IX");
4197
+ if (index === void 0)
4198
+ fail("UNSUPPORTED_TEXT_EDIT", "The master text fields cannot be identified.");
4199
+ const removed = document.createElementNS(shape.namespaceURI, "Row");
4200
+ removed.setAttribute("IX", index);
4201
+ removed.setAttribute("Del", "1");
4202
+ section2.appendChild(removed);
4203
+ }
4204
+ insertBeforeTail(shape, section2, ["Text", ...AFTER_TEXT]);
4205
+ }
4206
+ let node2 = local;
4207
+ if (!node2) {
4208
+ node2 = document.createElementNS(shape.namespaceURI, "Text");
4209
+ insertBeforeTail(shape, node2, AFTER_TEXT);
4210
+ }
4211
+ while (node2.firstChild) node2.removeChild(node2.firstChild);
4212
+ node2.appendChild(document.createTextNode(encodeVisioPlainText(text3)));
4213
+ return true;
4214
+ }
4215
+ function instanceTextNode(shape, template) {
4216
+ const local = single(shape, "The shape");
4217
+ assertUnlocked(shape, template);
4218
+ if (local) return { text: local, discard: () => {
4219
+ } };
4220
+ const inherited = single(template, "The master shape");
4221
+ if (!inherited) fail("UNSUPPORTED_TEXT_RANGE", "The stencil shape has no text to edit.");
4222
+ if (!knownMarkup(inherited))
4223
+ fail("UNSUPPORTED_TEXT_RANGE", "The master text has markup this editor does not know.");
4224
+ if (fieldSections(shape).length)
4225
+ fail("UNSUPPORTED_TEXT_RANGE", "This stencil shape overrides its master text fields.");
4226
+ const text3 = shape.ownerDocument.importNode(inherited, true);
4227
+ insertBeforeTail(shape, text3, AFTER_TEXT);
4228
+ return { text: text3, discard: () => void shape.removeChild(text3) };
4229
+ }
4230
+
4131
4231
  // visio/edit-text.ts
4132
- async function replacePlainText(root2, document, shapeId2, text3, check, assertDependencies2) {
4232
+ var plain = (node2) => Array.from(node2.childNodes).every((item) => item.nodeType === 3 || item.nodeType === 4);
4233
+ var hasFields = (shape) => children2(shape, "Section").some((section2) => attribute2(section2, "N") === "Field");
4234
+ async function replacePlainText(root2, document, shapeId2, text3, check, assertDependencies2, masterTemplate2) {
4235
+ const found = textTarget(root2, shapeId2, check);
4236
+ if (found.masterId !== void 0) {
4237
+ if (!masterTemplate2)
4238
+ fail("UNSUPPORTED_TEXT_EDIT", "Stencil shapes cannot be edited without their masters.");
4239
+ const template = await masterTemplate2(found.masterId, found.masterShapeId);
4240
+ check();
4241
+ return replaceInstanceText(found.node, template, text3);
4242
+ }
4133
4243
  const target2 = localTextTarget(root2, document, shapeId2, check);
4134
4244
  const texts = children2(target2, "Text");
4135
4245
  if (texts.length !== 1)
4136
4246
  fail("UNSUPPORTED_TEXT_EDIT", "Editing requires one existing local Text element.");
4137
4247
  const node2 = texts[0];
4138
- if (Array.from(node2.childNodes).some((item) => item.nodeType !== 3 && item.nodeType !== 4))
4248
+ if (!plain(node2))
4139
4249
  fail("UNSUPPORTED_TEXT_EDIT", "Rich text, fields and unknown text markup cannot be edited.");
4140
- if (children2(target2, "Section").some((section2) => attribute2(section2, "N") === "Field"))
4250
+ if (hasFields(target2))
4141
4251
  fail(
4142
4252
  "UNSUPPORTED_TEXT_EDIT",
4143
4253
  "Replacing all text would remove its text fields; edit the text around the fields instead."
@@ -8467,31 +8577,32 @@ var DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "S
8467
8577
  var pad = (value, length = 2) => String(value).padStart(length, "0");
8468
8578
  function formatDate(date2, picture) {
8469
8579
  const hours = date2.getUTCHours();
8470
- const tokens2 = {
8471
- yyyy: () => pad(date2.getUTCFullYear(), 4),
8472
- yy: () => pad(date2.getUTCFullYear() % 100),
8473
- MMMM: () => MONTHS[date2.getUTCMonth()],
8474
- MMM: () => MONTHS[date2.getUTCMonth()].slice(0, 3),
8475
- MM: () => pad(date2.getUTCMonth() + 1),
8476
- M: () => String(date2.getUTCMonth() + 1),
8477
- dddd: () => DAYS[date2.getUTCDay()],
8478
- ddd: () => DAYS[date2.getUTCDay()].slice(0, 3),
8479
- dd: () => pad(date2.getUTCDate()),
8480
- d: () => String(date2.getUTCDate()),
8481
- HH: () => pad(hours),
8482
- H: () => String(hours),
8483
- hh: () => pad(hours % 12 || 12),
8484
- h: () => String(hours % 12 || 12),
8485
- mm: () => pad(date2.getUTCMinutes()),
8486
- ss: () => pad(date2.getUTCSeconds()),
8487
- tt: () => hours < 12 ? "AM" : "PM"
8488
- };
8580
+ const tokens2 = new Map(
8581
+ Object.entries({
8582
+ yyyy: () => pad(date2.getUTCFullYear(), 4),
8583
+ yy: () => pad(date2.getUTCFullYear() % 100),
8584
+ MMMM: () => MONTHS[date2.getUTCMonth()],
8585
+ MMM: () => MONTHS[date2.getUTCMonth()].slice(0, 3),
8586
+ MM: () => pad(date2.getUTCMonth() + 1),
8587
+ M: () => String(date2.getUTCMonth() + 1),
8588
+ dddd: () => DAYS[date2.getUTCDay()],
8589
+ ddd: () => DAYS[date2.getUTCDay()].slice(0, 3),
8590
+ dd: () => pad(date2.getUTCDate()),
8591
+ d: () => String(date2.getUTCDate()),
8592
+ HH: () => pad(hours),
8593
+ H: () => String(hours),
8594
+ hh: () => pad(hours % 12 || 12),
8595
+ h: () => String(hours % 12 || 12),
8596
+ mm: () => pad(date2.getUTCMinutes()),
8597
+ ss: () => pad(date2.getUTCSeconds()),
8598
+ tt: () => hours < 12 ? "AM" : "PM"
8599
+ })
8600
+ );
8489
8601
  return picture.replace(
8490
8602
  /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|tt|"[^"]*"/g,
8491
8603
  (token) => {
8492
8604
  if (token.startsWith('"')) return token.slice(1, -1);
8493
- const format = tokens2[token];
8494
- return typeof format === "function" ? format() : token;
8605
+ return tokens2.get(token)?.() ?? token;
8495
8606
  }
8496
8607
  );
8497
8608
  }
@@ -14895,8 +15006,8 @@ function columnName(col) {
14895
15006
  return name3;
14896
15007
  }
14897
15008
  function quoteSheetName(name3) {
14898
- const plain = /^[A-Za-z_][A-Za-z0-9_.]*$/.test(name3) && !/^[A-Za-z]{1,3}[0-9]+$/.test(name3) && !/^[Rr][0-9]*([Cc][0-9]*)?$/.test(name3) && !/^(TRUE|FALSE)$/i.test(name3);
14899
- return plain ? name3 : `'${name3.replace(/'/g, "''")}'`;
15009
+ const plain2 = /^[A-Za-z_][A-Za-z0-9_.]*$/.test(name3) && !/^[A-Za-z]{1,3}[0-9]+$/.test(name3) && !/^[Rr][0-9]*([Cc][0-9]*)?$/.test(name3) && !/^(TRUE|FALSE)$/i.test(name3);
15010
+ return plain2 ? name3 : `'${name3.replace(/'/g, "''")}'`;
14900
15011
  }
14901
15012
  function formatNumber2(value) {
14902
15013
  return String(value).replace("e", "E");
@@ -15725,8 +15836,8 @@ function parseSupBook(data) {
15725
15836
  function sheetRange(first2, last) {
15726
15837
  if (first2 === last)
15727
15838
  return quoteSheetName(first2);
15728
- const plain = quoteSheetName(first2) === first2 && quoteSheetName(last) === last;
15729
- return plain ? `${first2}:${last}` : `'${`${first2}:${last}`.replace(/'/g, "''")}'`;
15839
+ const plain2 = quoteSheetName(first2) === first2 && quoteSheetName(last) === last;
15840
+ return plain2 ? `${first2}:${last}` : `'${`${first2}:${last}`.replace(/'/g, "''")}'`;
15730
15841
  }
15731
15842
  function parseGlobals(records) {
15732
15843
  const first2 = records[0];
@@ -21095,7 +21206,201 @@ async function assertFormattingDependencies(pkg, pagePaths, roots, pageId2, shap
21095
21206
  }
21096
21207
  }
21097
21208
 
21209
+ // visio/edit-master-index.ts
21210
+ function inheritedProtection(node2, ancestor) {
21211
+ try {
21212
+ const boolean2 = (cell) => {
21213
+ if (!cell || cell.hasAttribute("E"))
21214
+ fail("EDIT_PROTECTED_CELL", "Inherited protection has an unresolved or error cache.");
21215
+ const value = visioFormulaCachedValue(attribute2(cell, "V") ?? "", attribute2(cell, "U"));
21216
+ if (value.unit !== "scalar" || ![0, 1].includes(value.value))
21217
+ fail("EDIT_PROTECTED_CELL", "Inherited protection requires scalar boolean caches.");
21218
+ return value.value;
21219
+ };
21220
+ if (boolean2(node2) !== boolean2(ancestor))
21221
+ fail(
21222
+ "EDIT_PROTECTED_CELL",
21223
+ "Delegated master style protection cache disagrees with its ancestor."
21224
+ );
21225
+ } catch (error) {
21226
+ fail(
21227
+ "EDIT_PROTECTED_CELL",
21228
+ `Inherited master style protection cannot be proven: ${error instanceof Error ? error.message : "invalid cache"}`
21229
+ );
21230
+ }
21231
+ }
21232
+ function masterCells(sheet, charge = () => {
21233
+ }) {
21234
+ const result = /* @__PURE__ */ new Map();
21235
+ if (!sheet) return result;
21236
+ const add = (name3, node2) => {
21237
+ charge();
21238
+ const id3 = name3.toLowerCase();
21239
+ if (result.has(id3) && result.get(id3) !== node2)
21240
+ fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Ambiguous effective master cells.");
21241
+ result.set(id3, node2);
21242
+ };
21243
+ for (const node2 of children2(sheet, "Cell")) add(attribute2(node2, "N") ?? "", node2);
21244
+ for (const section2 of children2(sheet, "Section")) {
21245
+ const name3 = attribute2(section2, "N") ?? "";
21246
+ const prefix2 = name3 === "Geometry" ? `Geometry${Number(attribute2(section2, "IX") ?? "0") + 1}` : name3 === "Control" ? "Controls" : name3;
21247
+ for (const node2 of children2(section2, "Cell"))
21248
+ add(`${prefix2}.${attribute2(node2, "N") ?? ""}`, node2);
21249
+ for (const row2 of children2(section2, "Row"))
21250
+ for (const node2 of children2(row2, "Cell")) {
21251
+ const n = attribute2(node2, "N") ?? "";
21252
+ const rowName = attribute2(row2, "N");
21253
+ const index = attribute2(row2, "IX") ?? (prefix2 === "Controls" && /^Row_\d+$/.test(rowName ?? "") ? String(Number(rowName.slice(4)) - 1) : void 0);
21254
+ const ix = index ?? "0", r = rowName ?? (prefix2 === "Controls" ? `Row_${Number(ix) + 1}` : ix);
21255
+ add(
21256
+ name3 === "Geometry" || ["Controls", "Scratch", "Connection"].includes(prefix2) ? `${prefix2}.${n}${ix}` : n === "Value" && ["User", "Prop"].includes(name3) ? `${prefix2}.${r}` : `${prefix2}.${r}.${n}`,
21257
+ node2
21258
+ );
21259
+ if (name3 !== "Geometry") add(`${prefix2}.${r}.${n}`, node2);
21260
+ if (prefix2 === "Controls" && n === "X") add(`${prefix2}.${r}`, node2);
21261
+ if (name3 !== "Geometry" && index !== void 0) add(`${prefix2}.$row${ix}.${n}`, node2);
21262
+ }
21263
+ }
21264
+ return result;
21265
+ }
21266
+ function masterShapes(root2) {
21267
+ const result = [], pending = [root2];
21268
+ while (pending.length) {
21269
+ const parent = pending.pop();
21270
+ for (const container of children2(parent, "Shapes"))
21271
+ for (const shape of children2(container, "Shape")) {
21272
+ result.push(shape);
21273
+ pending.push(shape);
21274
+ }
21275
+ }
21276
+ return result;
21277
+ }
21278
+ function assertMasterMarkup(root2, known, check) {
21279
+ for (const node2 of [root2, ...Array.from(root2.getElementsByTagName("*"))]) {
21280
+ check();
21281
+ if (node2.namespaceURI === root2.namespaceURI && node2.hasAttribute("F") && !known.has(node2))
21282
+ fail(
21283
+ "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
21284
+ "Master formula outside admitted sheet cells has unknown scope."
21285
+ );
21286
+ }
21287
+ }
21288
+ function masterStyleCells(document, template, instance, check, charge = () => {
21289
+ }, verifyMovementProtection = false) {
21290
+ const styles = /* @__PURE__ */ new Map();
21291
+ for (const container of children2(document, "StyleSheets"))
21292
+ for (const style2 of children2(container, "StyleSheet")) {
21293
+ charge();
21294
+ const id3 = attribute2(style2, "ID");
21295
+ if (!id3 || styles.has(id3))
21296
+ fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Ambiguous master style IDs.");
21297
+ styles.set(id3, style2);
21298
+ }
21299
+ const defaults = children2(document, "DocumentSheet")[0];
21300
+ const collect = (id3, category, seen = /* @__PURE__ */ new Set()) => {
21301
+ check();
21302
+ if (seen.has(id3) || seen.size >= 64)
21303
+ fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Invalid inherited master style ancestry.");
21304
+ seen.add(id3);
21305
+ const style2 = styles.get(id3);
21306
+ if (!style2) fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Missing inherited master style.");
21307
+ const own = masterCells(style2, charge);
21308
+ assertMasterMarkup(style2, new Set(own.values()), check);
21309
+ const parent = attribute2(style2, category);
21310
+ const result2 = parent !== void 0 && parent !== id3 ? collect(parent, category, seen) : /* @__PURE__ */ new Map();
21311
+ for (const [name3, node2] of own) {
21312
+ charge();
21313
+ if (attribute2(node2, "F") !== "Inh") result2.set(name3, node2);
21314
+ else if (verifyMovementProtection && /^lock(move[xy]|width|height|aspect|delete)$/.test(name3)) {
21315
+ charge();
21316
+ inheritedProtection(node2, result2.get(name3));
21317
+ }
21318
+ }
21319
+ return result2;
21320
+ };
21321
+ const result = /* @__PURE__ */ new Map();
21322
+ for (const category of ["LineStyle", "FillStyle", "TextStyle"]) {
21323
+ const id3 = attribute2(instance, category) ?? attribute2(template, category) ?? attribute2(defaults, category) ?? (styles.has("0") ? "0" : void 0);
21324
+ if (id3 !== void 0)
21325
+ for (const [name3, node2] of collect(id3, category)) {
21326
+ charge();
21327
+ if (result.has(name3) && result.get(name3) !== node2)
21328
+ fail(
21329
+ "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
21330
+ "Master style categories have ambiguous overlapping inputs."
21331
+ );
21332
+ result.set(name3, node2);
21333
+ }
21334
+ }
21335
+ return result;
21336
+ }
21337
+ function overlay(cells4, additions, kind, charge) {
21338
+ const aliases = /* @__PURE__ */ new Map(), inherited = /* @__PURE__ */ new Map();
21339
+ for (const [name3, source] of cells4) {
21340
+ charge();
21341
+ const names = aliases.get(source.node) ?? /* @__PURE__ */ new Set();
21342
+ names.add(name3);
21343
+ aliases.set(source.node, names);
21344
+ }
21345
+ for (const [name3, node2] of additions) {
21346
+ charge();
21347
+ const source = cells4.get(name3);
21348
+ if (source) inherited.set(node2, source);
21349
+ }
21350
+ for (const [name3, node2] of additions) {
21351
+ charge();
21352
+ if (attribute2(node2, "F") === "Inh") {
21353
+ const source = cells4.get(name3) ?? inherited.get(node2);
21354
+ if (!source)
21355
+ fail(
21356
+ "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
21357
+ "Inherited master cell has no effective source."
21358
+ );
21359
+ cells4.set(name3, source);
21360
+ const names2 = aliases.get(source.node) ?? /* @__PURE__ */ new Set();
21361
+ names2.add(name3);
21362
+ aliases.set(source.node, names2);
21363
+ continue;
21364
+ }
21365
+ const previous = cells4.get(name3), names = aliases.get(node2) ?? /* @__PURE__ */ new Set();
21366
+ if (previous && previous.node !== node2) {
21367
+ for (const alias of aliases.get(previous.node) ?? []) {
21368
+ charge();
21369
+ cells4.set(alias, { node: node2, kind });
21370
+ names.add(alias);
21371
+ }
21372
+ aliases.delete(previous.node);
21373
+ }
21374
+ cells4.set(name3, { node: node2, kind });
21375
+ names.add(name3);
21376
+ aliases.set(node2, names);
21377
+ }
21378
+ }
21379
+
21098
21380
  // visio/edit-text-scope.ts
21381
+ function masterTemplate(pkg) {
21382
+ const missing = () => fail("UNSUPPORTED_TEXT_EDIT", "The master of this stencil shape cannot be resolved.");
21383
+ return async (masterId, masterShapeId) => {
21384
+ const documentPart2 = await related(pkg, "", "document");
21385
+ const mastersPart = documentPart2 && await related(pkg, documentPart2, "masters", false);
21386
+ if (!mastersPart) return missing();
21387
+ const definitions = children2(await visioXml(pkg, mastersPart, "Masters"), "Master").filter(
21388
+ (node2) => attribute2(node2, "ID") === masterId
21389
+ );
21390
+ if (definitions.length !== 1) return missing();
21391
+ const root2 = await visioXml(
21392
+ pkg,
21393
+ await indexedPart(pkg, mastersPart, definitions[0], "master"),
21394
+ "MasterContents"
21395
+ );
21396
+ if (masterShapeId === void 0) {
21397
+ const tops = children2(children2(root2, "Shapes")[0], "Shape");
21398
+ return tops.length === 1 ? tops[0] : missing();
21399
+ }
21400
+ const matches = masterShapes(root2).filter((shape) => attribute2(shape, "ID") === masterShapeId);
21401
+ return matches.length === 1 ? matches[0] : missing();
21402
+ };
21403
+ }
21099
21404
  function replaceScopedPlainText(pkg, pagePaths, roots, document, edit, check) {
21100
21405
  return replacePlainText(
21101
21406
  roots.get(edit.pageId),
@@ -21111,7 +21416,8 @@ function replaceScopedPlainText(pkg, pagePaths, roots, document, edit, check) {
21111
21416
  shape,
21112
21417
  /* @__PURE__ */ new Map([["TheText", text3]]),
21113
21418
  check
21114
- )
21419
+ ),
21420
+ masterTemplate(pkg)
21115
21421
  );
21116
21422
  }
21117
21423
 
@@ -21235,12 +21541,17 @@ function textRangeNodes(node2, edit) {
21235
21541
 
21236
21542
  // visio/edit-text-ranges.ts
21237
21543
  async function replaceScopedTextRanges(pkg, pagePaths, roots, document, edit, check) {
21238
- const shape = localTextTarget(roots.get(edit.pageId), document, edit.shapeId, check);
21544
+ const found = textTarget(roots.get(edit.pageId), edit.shapeId, check);
21545
+ const instance = found.masterId === void 0 ? void 0 : instanceTextNode(
21546
+ found.node,
21547
+ await masterTemplate(pkg)(found.masterId, found.masterShapeId)
21548
+ );
21549
+ const shape = instance ? found.node : localTextTarget(roots.get(edit.pageId), document, edit.shapeId, check);
21239
21550
  const texts = children2(shape, "Text");
21240
21551
  if (texts.length !== 1)
21241
21552
  fail("UNSUPPORTED_TEXT_RANGE", "Range editing requires one existing local Text element.");
21242
21553
  const text3 = texts[0];
21243
- if (Array.from(text3.childNodes).some((node2) => ![3, 4].includes(node2.nodeType))) {
21554
+ if (!instance && Array.from(text3.childNodes).some((node2) => ![3, 4].includes(node2.nodeType))) {
21244
21555
  const characters = effectiveFormattingRows(shape, document, "Character"), paragraphs = effectiveFormattingRows(shape, document, "Paragraph");
21245
21556
  assertFormattingText(shape, characters, paragraphs);
21246
21557
  }
@@ -21257,16 +21568,20 @@ async function replaceScopedTextRanges(pkg, pagePaths, roots, document, edit, ch
21257
21568
  }
21258
21569
  }
21259
21570
  const plan = textRangeNodes(text3, edit);
21260
- if (!plan.changed) return false;
21261
- await assertFormattingDependencies(
21262
- pkg,
21263
- pagePaths,
21264
- roots,
21265
- edit.pageId,
21266
- shape,
21267
- /* @__PURE__ */ new Map([["TheText", text3]]),
21268
- check
21269
- );
21571
+ if (!plan.changed) {
21572
+ instance?.discard();
21573
+ return false;
21574
+ }
21575
+ if (!instance)
21576
+ await assertFormattingDependencies(
21577
+ pkg,
21578
+ pagePaths,
21579
+ roots,
21580
+ edit.pageId,
21581
+ shape,
21582
+ /* @__PURE__ */ new Map([["TheText", text3]]),
21583
+ check
21584
+ );
21270
21585
  check();
21271
21586
  while (text3.firstChild) text3.removeChild(text3.firstChild);
21272
21587
  for (const node2 of plan.nodes) text3.appendChild(node2);
@@ -22278,6 +22593,96 @@ function snapshotAssignLayers(edit) {
22278
22593
  };
22279
22594
  }
22280
22595
 
22596
+ // visio/edit-layer-properties.ts
22597
+ var FLAGS = [
22598
+ ["visible", "Visible"],
22599
+ ["print", "Print"],
22600
+ ["lock", "Lock"]
22601
+ ];
22602
+ function snapshotLayerProperties(edit) {
22603
+ if (typeof edit.pageId !== "string" || !edit.pageId || edit.pageId.length > 256)
22604
+ fail("INVALID_EDIT", "Invalid edit target.");
22605
+ if (typeof edit.layerId !== "string" || !/^(0|[1-9]\d{0,9})$/.test(edit.layerId))
22606
+ fail("INVALID_EDIT", "Layer IDs must be canonical unsigned integers.");
22607
+ const result = {
22608
+ type: "set-layer-properties",
22609
+ pageId: edit.pageId,
22610
+ layerId: edit.layerId
22611
+ };
22612
+ for (const [key2] of FLAGS) {
22613
+ const value = edit[key2];
22614
+ if (value === void 0) continue;
22615
+ if (typeof value !== "boolean") fail("INVALID_EDIT", "Layer flags are true or false.");
22616
+ result[key2] = value;
22617
+ }
22618
+ if (!FLAGS.some(([key2]) => result[key2] !== void 0))
22619
+ fail("INVALID_EDIT", "A layer edit needs at least one flag.");
22620
+ return result;
22621
+ }
22622
+ async function editVsdxLayerProperties(pkg, parts, pages, edits, limits, maxOutput, deadline, check) {
22623
+ const documentPart2 = await related(pkg, "", "document");
22624
+ const pagesPart = await related(pkg, documentPart2, "pages");
22625
+ const source = await visioXml(pkg, pagesPart, "Pages");
22626
+ const pageList = source.ownerDocument.cloneNode(true).documentElement;
22627
+ let changed = false;
22628
+ for (const edit of edits) {
22629
+ check();
22630
+ if (!pages.has(edit.pageId)) fail("EDIT_TARGET_NOT_FOUND", "Page does not exist.");
22631
+ const page = children2(pageList, "Page").find((node2) => attribute2(node2, "ID") === edit.pageId);
22632
+ const sheets = page ? children2(page, "PageSheet") : [];
22633
+ if (sheets.length !== 1) fail("UNSUPPORTED_LAYER_EDIT", "One explicit PageSheet is required.");
22634
+ const sections = children2(sheets[0], "Section").filter(
22635
+ (node2) => attribute2(node2, "N") === "Layer"
22636
+ );
22637
+ if (sections.length !== 1)
22638
+ fail("EDIT_TARGET_NOT_FOUND", "The layer does not belong to this page.");
22639
+ const rows = children2(sections[0], "Row").filter(
22640
+ (row3) => attribute2(row3, "IX") === edit.layerId
22641
+ );
22642
+ if (rows.length !== 1 || rows[0].hasAttribute("Del"))
22643
+ fail("EDIT_TARGET_NOT_FOUND", "The layer does not belong to this page.");
22644
+ const row2 = rows[0];
22645
+ for (const [key2, name3] of FLAGS) {
22646
+ const value = edit[key2];
22647
+ if (value === void 0) continue;
22648
+ const cells4 = children2(row2, "Cell").filter((cell2) => attribute2(cell2, "N") === name3);
22649
+ if (cells4.length > 1) fail("UNSUPPORTED_LAYER_EDIT", `Duplicate layer ${name3} cells.`);
22650
+ let cell = cells4[0];
22651
+ if (cell && (cell.hasAttribute("E") || executableCellFormula(attribute2(cell, "F"))))
22652
+ fail("UNSUPPORTED_LAYER_EDIT", `The layer's ${name3} flag is set by a formula.`);
22653
+ const next = value ? "1" : "0";
22654
+ if (cell && attribute2(cell, "V") === next) continue;
22655
+ if (!cell) {
22656
+ cell = row2.ownerDocument.createElementNS(row2.namespaceURI, "Cell");
22657
+ cell.setAttribute("N", name3);
22658
+ row2.appendChild(cell);
22659
+ }
22660
+ cell.setAttribute("V", next);
22661
+ changed = true;
22662
+ }
22663
+ }
22664
+ const original = parts.get(pagesPart);
22665
+ if (!changed)
22666
+ return {
22667
+ bytes: await writeEditedPackage(parts, maxOutput, deadline, check),
22668
+ changedParts: [],
22669
+ diagnostics: []
22670
+ };
22671
+ const serialized = serializeEditedXml(pageList, limits, check);
22672
+ const total = [...parts.values()].reduce((sum, bytes2) => sum + bytes2.length, 0) + serialized.bytes.length - (original?.length ?? 0);
22673
+ if (total > limits.maxTotalBytes) fail("LIMIT_TOTAL", "Edited package total exceeds limit.");
22674
+ parts.set(pagesPart, serialized.bytes);
22675
+ const bytes = await writeEditedPackage(parts, maxOutput, deadline, check);
22676
+ const verified = await openEditablePackage(
22677
+ bytes,
22678
+ { ...limits, maxInputBytes: maxOutput, maxRuntimeMs: Math.max(1, deadline - Date.now()) },
22679
+ check
22680
+ );
22681
+ await visioXml(verified.pkg, pagesPart, "Pages");
22682
+ check();
22683
+ return { bytes, changedParts: [pagesPart], diagnostics: [] };
22684
+ }
22685
+
22281
22686
  // visio/edit-guide-commands.ts
22282
22687
  var isVisioGuideEdit = (edit) => edit.type === "create-guide" || edit.type === "move-guide" || edit.type === "delete-guide";
22283
22688
  function snapshotGuideEdit(edit) {
@@ -22860,6 +23265,7 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
22860
23265
  if (edit.type === "insert-picture") return snapshotPictureInsert(edit);
22861
23266
  if (edit.type === "set-page-theme") return snapshotPageTheme(edit);
22862
23267
  if (edit.type === "assign-layers") return snapshotAssignLayers(edit);
23268
+ if (edit.type === "set-layer-properties") return snapshotLayerProperties(edit);
22863
23269
  if (isVisioGuideEdit(edit)) return snapshotGuideEdit(edit);
22864
23270
  if (isVisioMetadataEdit(edit)) return snapshotMetadataEdit(edit);
22865
23271
  if (isVisioGroupEdit(edit)) return snapshotGroupEdit(edit);
@@ -24770,177 +25176,6 @@ function analyzeVisioMasterFormula(source, options) {
24770
25176
  return { ...analysis, references: [...references.values()], dynamic: dynamic2, readsText, readsTheme };
24771
25177
  }
24772
25178
 
24773
- // visio/edit-master-index.ts
24774
- function inheritedProtection(node2, ancestor) {
24775
- try {
24776
- const boolean2 = (cell) => {
24777
- if (!cell || cell.hasAttribute("E"))
24778
- fail("EDIT_PROTECTED_CELL", "Inherited protection has an unresolved or error cache.");
24779
- const value = visioFormulaCachedValue(attribute2(cell, "V") ?? "", attribute2(cell, "U"));
24780
- if (value.unit !== "scalar" || ![0, 1].includes(value.value))
24781
- fail("EDIT_PROTECTED_CELL", "Inherited protection requires scalar boolean caches.");
24782
- return value.value;
24783
- };
24784
- if (boolean2(node2) !== boolean2(ancestor))
24785
- fail(
24786
- "EDIT_PROTECTED_CELL",
24787
- "Delegated master style protection cache disagrees with its ancestor."
24788
- );
24789
- } catch (error) {
24790
- fail(
24791
- "EDIT_PROTECTED_CELL",
24792
- `Inherited master style protection cannot be proven: ${error instanceof Error ? error.message : "invalid cache"}`
24793
- );
24794
- }
24795
- }
24796
- function masterCells(sheet, charge = () => {
24797
- }) {
24798
- const result = /* @__PURE__ */ new Map();
24799
- if (!sheet) return result;
24800
- const add = (name3, node2) => {
24801
- charge();
24802
- const id3 = name3.toLowerCase();
24803
- if (result.has(id3) && result.get(id3) !== node2)
24804
- fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Ambiguous effective master cells.");
24805
- result.set(id3, node2);
24806
- };
24807
- for (const node2 of children2(sheet, "Cell")) add(attribute2(node2, "N") ?? "", node2);
24808
- for (const section2 of children2(sheet, "Section")) {
24809
- const name3 = attribute2(section2, "N") ?? "";
24810
- const prefix2 = name3 === "Geometry" ? `Geometry${Number(attribute2(section2, "IX") ?? "0") + 1}` : name3 === "Control" ? "Controls" : name3;
24811
- for (const node2 of children2(section2, "Cell"))
24812
- add(`${prefix2}.${attribute2(node2, "N") ?? ""}`, node2);
24813
- for (const row2 of children2(section2, "Row"))
24814
- for (const node2 of children2(row2, "Cell")) {
24815
- const n = attribute2(node2, "N") ?? "";
24816
- const rowName = attribute2(row2, "N");
24817
- const index = attribute2(row2, "IX") ?? (prefix2 === "Controls" && /^Row_\d+$/.test(rowName ?? "") ? String(Number(rowName.slice(4)) - 1) : void 0);
24818
- const ix = index ?? "0", r = rowName ?? (prefix2 === "Controls" ? `Row_${Number(ix) + 1}` : ix);
24819
- add(
24820
- name3 === "Geometry" || ["Controls", "Scratch", "Connection"].includes(prefix2) ? `${prefix2}.${n}${ix}` : n === "Value" && ["User", "Prop"].includes(name3) ? `${prefix2}.${r}` : `${prefix2}.${r}.${n}`,
24821
- node2
24822
- );
24823
- if (name3 !== "Geometry") add(`${prefix2}.${r}.${n}`, node2);
24824
- if (prefix2 === "Controls" && n === "X") add(`${prefix2}.${r}`, node2);
24825
- if (name3 !== "Geometry" && index !== void 0) add(`${prefix2}.$row${ix}.${n}`, node2);
24826
- }
24827
- }
24828
- return result;
24829
- }
24830
- function masterShapes(root2) {
24831
- const result = [], pending = [root2];
24832
- while (pending.length) {
24833
- const parent = pending.pop();
24834
- for (const container of children2(parent, "Shapes"))
24835
- for (const shape of children2(container, "Shape")) {
24836
- result.push(shape);
24837
- pending.push(shape);
24838
- }
24839
- }
24840
- return result;
24841
- }
24842
- function assertMasterMarkup(root2, known, check) {
24843
- for (const node2 of [root2, ...Array.from(root2.getElementsByTagName("*"))]) {
24844
- check();
24845
- if (node2.namespaceURI === root2.namespaceURI && node2.hasAttribute("F") && !known.has(node2))
24846
- fail(
24847
- "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
24848
- "Master formula outside admitted sheet cells has unknown scope."
24849
- );
24850
- }
24851
- }
24852
- function masterStyleCells(document, template, instance, check, charge = () => {
24853
- }, verifyMovementProtection = false) {
24854
- const styles = /* @__PURE__ */ new Map();
24855
- for (const container of children2(document, "StyleSheets"))
24856
- for (const style2 of children2(container, "StyleSheet")) {
24857
- charge();
24858
- const id3 = attribute2(style2, "ID");
24859
- if (!id3 || styles.has(id3))
24860
- fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Ambiguous master style IDs.");
24861
- styles.set(id3, style2);
24862
- }
24863
- const defaults = children2(document, "DocumentSheet")[0];
24864
- const collect = (id3, category, seen = /* @__PURE__ */ new Set()) => {
24865
- check();
24866
- if (seen.has(id3) || seen.size >= 64)
24867
- fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Invalid inherited master style ancestry.");
24868
- seen.add(id3);
24869
- const style2 = styles.get(id3);
24870
- if (!style2) fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Missing inherited master style.");
24871
- const own = masterCells(style2, charge);
24872
- assertMasterMarkup(style2, new Set(own.values()), check);
24873
- const parent = attribute2(style2, category);
24874
- const result2 = parent !== void 0 && parent !== id3 ? collect(parent, category, seen) : /* @__PURE__ */ new Map();
24875
- for (const [name3, node2] of own) {
24876
- charge();
24877
- if (attribute2(node2, "F") !== "Inh") result2.set(name3, node2);
24878
- else if (verifyMovementProtection && /^lock(move[xy]|width|height|aspect|delete)$/.test(name3)) {
24879
- charge();
24880
- inheritedProtection(node2, result2.get(name3));
24881
- }
24882
- }
24883
- return result2;
24884
- };
24885
- const result = /* @__PURE__ */ new Map();
24886
- for (const category of ["LineStyle", "FillStyle", "TextStyle"]) {
24887
- const id3 = attribute2(instance, category) ?? attribute2(template, category) ?? attribute2(defaults, category) ?? (styles.has("0") ? "0" : void 0);
24888
- if (id3 !== void 0)
24889
- for (const [name3, node2] of collect(id3, category)) {
24890
- charge();
24891
- if (result.has(name3) && result.get(name3) !== node2)
24892
- fail(
24893
- "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
24894
- "Master style categories have ambiguous overlapping inputs."
24895
- );
24896
- result.set(name3, node2);
24897
- }
24898
- }
24899
- return result;
24900
- }
24901
- function overlay(cells4, additions, kind, charge) {
24902
- const aliases = /* @__PURE__ */ new Map(), inherited = /* @__PURE__ */ new Map();
24903
- for (const [name3, source] of cells4) {
24904
- charge();
24905
- const names = aliases.get(source.node) ?? /* @__PURE__ */ new Set();
24906
- names.add(name3);
24907
- aliases.set(source.node, names);
24908
- }
24909
- for (const [name3, node2] of additions) {
24910
- charge();
24911
- const source = cells4.get(name3);
24912
- if (source) inherited.set(node2, source);
24913
- }
24914
- for (const [name3, node2] of additions) {
24915
- charge();
24916
- if (attribute2(node2, "F") === "Inh") {
24917
- const source = cells4.get(name3) ?? inherited.get(node2);
24918
- if (!source)
24919
- fail(
24920
- "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
24921
- "Inherited master cell has no effective source."
24922
- );
24923
- cells4.set(name3, source);
24924
- const names2 = aliases.get(source.node) ?? /* @__PURE__ */ new Set();
24925
- names2.add(name3);
24926
- aliases.set(source.node, names2);
24927
- continue;
24928
- }
24929
- const previous = cells4.get(name3), names = aliases.get(node2) ?? /* @__PURE__ */ new Set();
24930
- if (previous && previous.node !== node2) {
24931
- for (const alias of aliases.get(previous.node) ?? []) {
24932
- charge();
24933
- cells4.set(alias, { node: node2, kind });
24934
- names.add(alias);
24935
- }
24936
- aliases.delete(previous.node);
24937
- }
24938
- cells4.set(name3, { node: node2, kind });
24939
- names.add(name3);
24940
- aliases.set(node2, names);
24941
- }
24942
- }
24943
-
24944
25179
  // visio/edit-master-scope.ts
24945
25180
  function problem(message) {
24946
25181
  return fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", message);
@@ -29328,6 +29563,21 @@ async function editVsdxTransaction(input, edits, options, clock = { deadline: 0,
29328
29563
  check
29329
29564
  );
29330
29565
  }
29566
+ const layerFlags = allCommands.filter((command2) => command2.type === "set-layer-properties");
29567
+ if (layerFlags.length) {
29568
+ if (layerFlags.length !== allCommands.length)
29569
+ fail("EDIT_MIXED_LAYER_TRANSACTION", "Layer properties require their own transaction.");
29570
+ return editVsdxLayerProperties(
29571
+ pkg,
29572
+ parts,
29573
+ pages,
29574
+ layerFlags,
29575
+ limits,
29576
+ maxOutput,
29577
+ deadline,
29578
+ check
29579
+ );
29580
+ }
29331
29581
  const layers = allCommands.filter((command2) => command2.type === "assign-layers");
29332
29582
  if (layers.length) {
29333
29583
  if (layers.length !== allCommands.length)
@@ -29509,7 +29759,7 @@ async function editVsdxTransaction(input, edits, options, clock = { deadline: 0,
29509
29759
  ))
29510
29760
  dirty.set(pages.get(pageId2), roots.get(pageId2));
29511
29761
  duplicateChanged = true;
29512
- } else if (command2.type !== "insert-picture" && command2.type !== "set-page-theme" && command2.type !== "create-subprocess" && !isVisioCommentEdit(command2) && !isVisioDataEdit(command2) && command2.type !== "assign-layers") {
29762
+ } else if (command2.type !== "insert-picture" && command2.type !== "set-page-theme" && command2.type !== "create-subprocess" && !isVisioCommentEdit(command2) && !isVisioDataEdit(command2) && command2.type !== "assign-layers" && command2.type !== "set-layer-properties") {
29513
29763
  for (const pageId2 of applyGeometryEdit(roots, document, command2, check, masterMovePins))
29514
29764
  dirty.set(pages.get(pageId2), roots.get(pageId2));
29515
29765
  }