ooxml-core 0.9.0 → 0.11.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 (320) hide show
  1. package/README.md +14 -13
  2. package/dist/automation/docx.d.ts +13 -0
  3. package/dist/automation/docx.d.ts.map +1 -0
  4. package/dist/automation/index.cjs +36838 -0
  5. package/dist/automation/index.d.ts +6 -0
  6. package/dist/automation/index.d.ts.map +1 -0
  7. package/dist/automation/index.mjs +36824 -0
  8. package/dist/automation/node.cjs +103 -0
  9. package/dist/automation/node.d.ts +16 -0
  10. package/dist/automation/node.d.ts.map +1 -0
  11. package/dist/automation/node.mjs +101 -0
  12. package/dist/automation/visio.d.ts +30 -0
  13. package/dist/automation/visio.d.ts.map +1 -0
  14. package/dist/automation/xlsx.d.ts +25 -0
  15. package/dist/automation/xlsx.d.ts.map +1 -0
  16. package/dist/crypto/aes-ecb.d.ts +13 -0
  17. package/dist/crypto/aes-ecb.d.ts.map +1 -0
  18. package/dist/crypto/decrypt.d.ts +63 -0
  19. package/dist/crypto/decrypt.d.ts.map +1 -0
  20. package/dist/crypto/detect.d.ts +56 -0
  21. package/dist/crypto/detect.d.ts.map +1 -0
  22. package/dist/crypto/encrypt.d.ts +27 -0
  23. package/dist/crypto/encrypt.d.ts.map +1 -0
  24. package/dist/crypto/encryption-info-write.d.ts +46 -0
  25. package/dist/crypto/encryption-info-write.d.ts.map +1 -0
  26. package/dist/crypto/encryption-info.d.ts +22 -0
  27. package/dist/crypto/encryption-info.d.ts.map +1 -0
  28. package/dist/crypto/errors.d.ts +39 -0
  29. package/dist/crypto/errors.d.ts.map +1 -0
  30. package/dist/crypto/index.cjs +1805 -0
  31. package/dist/crypto/index.d.ts +26 -0
  32. package/dist/crypto/index.d.ts.map +1 -0
  33. package/dist/crypto/index.mjs +1774 -0
  34. package/dist/crypto/key-derivation.d.ts +73 -0
  35. package/dist/crypto/key-derivation.d.ts.map +1 -0
  36. package/dist/crypto/types.d.ts +104 -0
  37. package/dist/crypto/types.d.ts.map +1 -0
  38. package/dist/docx/embedded.cjs +2 -0
  39. package/dist/docx/embedded.mjs +2 -0
  40. package/dist/docx/index.cjs +2 -0
  41. package/dist/docx/index.mjs +2 -0
  42. package/dist/docx/load/detect.d.ts +14 -2
  43. package/dist/docx/load/detect.d.ts.map +1 -1
  44. package/dist/docx/load/index.cjs +8995 -7728
  45. package/dist/docx/load/index.d.ts +3 -1
  46. package/dist/docx/load/index.d.ts.map +1 -1
  47. package/dist/docx/load/index.mjs +8990 -7729
  48. package/dist/docx/load/legacy-doc.d.ts.map +1 -1
  49. package/dist/index.cjs +749 -19
  50. package/dist/index.mjs +749 -19
  51. package/dist/opc/index.cjs +797 -1
  52. package/dist/opc/index.d.ts +2 -0
  53. package/dist/opc/index.d.ts.map +1 -1
  54. package/dist/opc/index.mjs +784 -3
  55. package/dist/opc/properties/app.d.ts +10 -0
  56. package/dist/opc/properties/app.d.ts.map +1 -0
  57. package/dist/opc/properties/core.d.ts +13 -0
  58. package/dist/opc/properties/core.d.ts.map +1 -0
  59. package/dist/opc/properties/custom.d.ts +15 -0
  60. package/dist/opc/properties/custom.d.ts.map +1 -0
  61. package/dist/opc/properties/index.d.ts +5 -0
  62. package/dist/opc/properties/index.d.ts.map +1 -0
  63. package/dist/opc/properties/types.d.ts +114 -0
  64. package/dist/opc/properties/types.d.ts.map +1 -0
  65. package/dist/opc/relationship-types.d.ts +1 -0
  66. package/dist/opc/relationship-types.d.ts.map +1 -1
  67. package/dist/opc/safe-href.d.ts +34 -0
  68. package/dist/opc/safe-href.d.ts.map +1 -1
  69. package/dist/opc/signature/constants.d.ts +42 -0
  70. package/dist/opc/signature/constants.d.ts.map +1 -0
  71. package/dist/opc/signature/detection.d.ts +97 -0
  72. package/dist/opc/signature/detection.d.ts.map +1 -0
  73. package/dist/opc/signature/digest.d.ts +16 -0
  74. package/dist/opc/signature/digest.d.ts.map +1 -0
  75. package/dist/opc/signature/index.d.ts +8 -0
  76. package/dist/opc/signature/index.d.ts.map +1 -0
  77. package/dist/opc/signature/inspection-status.d.ts +24 -0
  78. package/dist/opc/signature/inspection-status.d.ts.map +1 -0
  79. package/dist/opc/signature/reference-utils.d.ts +12 -0
  80. package/dist/opc/signature/reference-utils.d.ts.map +1 -0
  81. package/dist/opc/signature/types.d.ts +90 -0
  82. package/dist/opc/signature/types.d.ts.map +1 -0
  83. package/dist/opc/signature/xml-utils.d.ts +35 -0
  84. package/dist/opc/signature/xml-utils.d.ts.map +1 -0
  85. package/dist/pptx/automation/index.cjs +149047 -0
  86. package/dist/pptx/automation/index.d.ts +1474 -0
  87. package/dist/pptx/automation/index.d.ts.map +1 -0
  88. package/dist/pptx/automation/index.mjs +148926 -0
  89. package/dist/pptx/chunks/{index-CojJtI77.d.ts → index-BWRd8p4y.d.ts} +10 -12
  90. package/dist/pptx/chunks/index-BWRd8p4y.d.ts.map +1 -0
  91. package/dist/pptx/chunks/index-LoCVDu8Z.d.ts +9644 -0
  92. package/dist/pptx/chunks/index-LoCVDu8Z.d.ts.map +1 -0
  93. package/dist/pptx/chunks/{signature-inspection-status-Bh2oap7B.d.ts → inspection-status-B2E-jSpG.d.ts} +8 -8
  94. package/dist/pptx/chunks/inspection-status-B2E-jSpG.d.ts.map +1 -0
  95. package/dist/pptx/chunks/{text-operations-IlJiffp7.d.ts → text-operations-2tKzrY5o.d.ts} +7381 -7381
  96. package/dist/pptx/chunks/text-operations-2tKzrY5o.d.ts.map +1 -0
  97. package/dist/pptx/cli/index.cjs +1409 -895
  98. package/dist/pptx/cli/index.d.ts +1 -1
  99. package/dist/pptx/cli/index.mjs +1409 -895
  100. package/dist/pptx/converter/index.d.ts +1 -1
  101. package/dist/pptx/index.cjs +1933 -1391
  102. package/dist/pptx/index.d.ts +5 -9692
  103. package/dist/pptx/index.mjs +1933 -1391
  104. package/dist/pptx/signature-node/index.cjs +5 -5
  105. package/dist/pptx/signature-node/index.d.ts +1 -1
  106. package/dist/pptx/signature-node/index.mjs +5 -5
  107. package/dist/visio/edit-geometry-admission.d.ts +1 -1
  108. package/dist/visio/edit-geometry-admission.d.ts.map +1 -1
  109. package/dist/visio/edit-geometry.d.ts +1 -1
  110. package/dist/visio/edit-geometry.d.ts.map +1 -1
  111. package/dist/visio/edit-master-index.d.ts +10 -0
  112. package/dist/visio/edit-master-index.d.ts.map +1 -0
  113. package/dist/visio/edit-master-move.d.ts +12 -0
  114. package/dist/visio/edit-master-move.d.ts.map +1 -0
  115. package/dist/visio/edit-master-scope.d.ts +7 -0
  116. package/dist/visio/edit-master-scope.d.ts.map +1 -0
  117. package/dist/visio/edit-recalculate-index.d.ts +2 -0
  118. package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
  119. package/dist/visio/edit-scope.d.ts +1 -1
  120. package/dist/visio/edit-scope.d.ts.map +1 -1
  121. package/dist/visio/edit.d.ts.map +1 -1
  122. package/dist/visio/formula-arithmetic.d.ts +8 -0
  123. package/dist/visio/formula-arithmetic.d.ts.map +1 -0
  124. package/dist/visio/formula-evaluate.d.ts.map +1 -1
  125. package/dist/visio/formula-master.d.ts +13 -0
  126. package/dist/visio/formula-master.d.ts.map +1 -0
  127. package/dist/visio/formula-numeric-functions.d.ts +8 -0
  128. package/dist/visio/formula-numeric-functions.d.ts.map +1 -0
  129. package/dist/visio/formula.d.ts +1 -1
  130. package/dist/visio/formula.d.ts.map +1 -1
  131. package/dist/visio/index.cjs +687 -71
  132. package/dist/visio/index.mjs +687 -71
  133. package/dist/xlsx/edit/annotations.d.ts +5 -1
  134. package/dist/xlsx/edit/annotations.d.ts.map +1 -1
  135. package/dist/xlsx/edit/cell-values.d.ts +7 -2
  136. package/dist/xlsx/edit/cell-values.d.ts.map +1 -1
  137. package/dist/xlsx/edit/clipboard.d.ts.map +1 -1
  138. package/dist/xlsx/edit/doc-properties.d.ts +14 -0
  139. package/dist/xlsx/edit/doc-properties.d.ts.map +1 -0
  140. package/dist/xlsx/edit/fill-series.d.ts.map +1 -1
  141. package/dist/xlsx/edit/find.d.ts +2 -1
  142. package/dist/xlsx/edit/find.d.ts.map +1 -1
  143. package/dist/xlsx/edit/format-lines.d.ts +22 -0
  144. package/dist/xlsx/edit/format-lines.d.ts.map +1 -0
  145. package/dist/xlsx/edit/format.d.ts +2 -1
  146. package/dist/xlsx/edit/format.d.ts.map +1 -1
  147. package/dist/xlsx/edit/history-refs.d.ts +51 -0
  148. package/dist/xlsx/edit/history-refs.d.ts.map +1 -0
  149. package/dist/xlsx/edit/history.d.ts +40 -5
  150. package/dist/xlsx/edit/history.d.ts.map +1 -1
  151. package/dist/xlsx/edit/index.d.ts +3 -0
  152. package/dist/xlsx/edit/index.d.ts.map +1 -1
  153. package/dist/xlsx/edit/input-text.d.ts +13 -0
  154. package/dist/xlsx/edit/input-text.d.ts.map +1 -0
  155. package/dist/xlsx/edit/merge.d.ts +10 -2
  156. package/dist/xlsx/edit/merge.d.ts.map +1 -1
  157. package/dist/xlsx/edit/session.d.ts.map +1 -1
  158. package/dist/xlsx/edit/sheets.d.ts.map +1 -1
  159. package/dist/xlsx/edit/shift-formulas.d.ts +2 -1
  160. package/dist/xlsx/edit/shift-formulas.d.ts.map +1 -1
  161. package/dist/xlsx/edit/shift-preserved.d.ts +17 -0
  162. package/dist/xlsx/edit/shift-preserved.d.ts.map +1 -0
  163. package/dist/xlsx/edit/shift-sheet.d.ts +2 -2
  164. package/dist/xlsx/edit/shift-sheet.d.ts.map +1 -1
  165. package/dist/xlsx/edit/structure.d.ts.map +1 -1
  166. package/dist/xlsx/edit/types.d.ts +7 -0
  167. package/dist/xlsx/edit/types.d.ts.map +1 -1
  168. package/dist/xlsx/edit/validation-list.d.ts +24 -0
  169. package/dist/xlsx/edit/validation-list.d.ts.map +1 -0
  170. package/dist/xlsx/edit/validation.d.ts +2 -1
  171. package/dist/xlsx/edit/validation.d.ts.map +1 -1
  172. package/dist/xlsx/formula/area-index.d.ts +18 -0
  173. package/dist/xlsx/formula/area-index.d.ts.map +1 -0
  174. package/dist/xlsx/formula/array-context.d.ts.map +1 -1
  175. package/dist/xlsx/formula/ast.d.ts +5 -1
  176. package/dist/xlsx/formula/ast.d.ts.map +1 -1
  177. package/dist/xlsx/formula/call.d.ts.map +1 -1
  178. package/dist/xlsx/formula/coerce.d.ts.map +1 -1
  179. package/dist/xlsx/formula/context.d.ts +5 -0
  180. package/dist/xlsx/formula/context.d.ts.map +1 -1
  181. package/dist/xlsx/formula/date-serial.d.ts +11 -4
  182. package/dist/xlsx/formula/date-serial.d.ts.map +1 -1
  183. package/dist/xlsx/formula/engine-core.d.ts +6 -0
  184. package/dist/xlsx/formula/engine-core.d.ts.map +1 -1
  185. package/dist/xlsx/formula/engine-host.d.ts +35 -3
  186. package/dist/xlsx/formula/engine-host.d.ts.map +1 -1
  187. package/dist/xlsx/formula/engine-util.d.ts.map +1 -1
  188. package/dist/xlsx/formula/engine.d.ts.map +1 -1
  189. package/dist/xlsx/formula/evaluator.d.ts.map +1 -1
  190. package/dist/xlsx/formula/functions/array-shape.d.ts.map +1 -1
  191. package/dist/xlsx/formula/functions/array.d.ts.map +1 -1
  192. package/dist/xlsx/formula/functions/criteria-index.d.ts +12 -0
  193. package/dist/xlsx/formula/functions/criteria-index.d.ts.map +1 -0
  194. package/dist/xlsx/formula/functions/criteria.d.ts +24 -16
  195. package/dist/xlsx/formula/functions/criteria.d.ts.map +1 -1
  196. package/dist/xlsx/formula/functions/date-calc.d.ts +4 -0
  197. package/dist/xlsx/formula/functions/date-calc.d.ts.map +1 -1
  198. package/dist/xlsx/formula/functions/depreciation.d.ts.map +1 -1
  199. package/dist/xlsx/formula/functions/financial.d.ts.map +1 -1
  200. package/dist/xlsx/formula/functions/helpers.d.ts.map +1 -1
  201. package/dist/xlsx/formula/functions/logical.d.ts.map +1 -1
  202. package/dist/xlsx/formula/functions/lookup-core.d.ts +14 -2
  203. package/dist/xlsx/formula/functions/lookup-core.d.ts.map +1 -1
  204. package/dist/xlsx/formula/functions/lookup.d.ts.map +1 -1
  205. package/dist/xlsx/formula/functions/math-mod.d.ts +8 -0
  206. package/dist/xlsx/formula/functions/math-mod.d.ts.map +1 -0
  207. package/dist/xlsx/formula/functions/math-sum.d.ts.map +1 -1
  208. package/dist/xlsx/formula/functions/math.d.ts.map +1 -1
  209. package/dist/xlsx/formula/functions/statistical-count.d.ts.map +1 -1
  210. package/dist/xlsx/formula/functions/statistical.d.ts.map +1 -1
  211. package/dist/xlsx/formula/functions/stats-core.d.ts +6 -0
  212. package/dist/xlsx/formula/functions/stats-core.d.ts.map +1 -1
  213. package/dist/xlsx/formula/functions/text-case.d.ts +14 -0
  214. package/dist/xlsx/formula/functions/text-case.d.ts.map +1 -0
  215. package/dist/xlsx/formula/functions/text.d.ts.map +1 -1
  216. package/dist/xlsx/formula/functions/workdays.d.ts.map +1 -1
  217. package/dist/xlsx/formula/graph-index.d.ts +15 -0
  218. package/dist/xlsx/formula/graph-index.d.ts.map +1 -0
  219. package/dist/xlsx/formula/graph.d.ts +13 -18
  220. package/dist/xlsx/formula/graph.d.ts.map +1 -1
  221. package/dist/xlsx/formula/operators.d.ts +9 -0
  222. package/dist/xlsx/formula/operators.d.ts.map +1 -1
  223. package/dist/xlsx/formula/parser.d.ts +2 -0
  224. package/dist/xlsx/formula/parser.d.ts.map +1 -1
  225. package/dist/xlsx/formula/references.d.ts +4 -1
  226. package/dist/xlsx/formula/references.d.ts.map +1 -1
  227. package/dist/xlsx/formula/text-number.d.ts.map +1 -1
  228. package/dist/xlsx/formula/transform.d.ts.map +1 -1
  229. package/dist/xlsx/formula/values.d.ts +44 -3
  230. package/dist/xlsx/formula/values.d.ts.map +1 -1
  231. package/dist/xlsx/index.cjs +4698 -1322
  232. package/dist/xlsx/index.mjs +4688 -1323
  233. package/dist/xlsx/layout/anchors.d.ts +47 -0
  234. package/dist/xlsx/layout/anchors.d.ts.map +1 -0
  235. package/dist/xlsx/layout/cf-evaluator.d.ts +1 -2
  236. package/dist/xlsx/layout/cf-evaluator.d.ts.map +1 -1
  237. package/dist/xlsx/layout/cf-helpers.d.ts +8 -1
  238. package/dist/xlsx/layout/cf-helpers.d.ts.map +1 -1
  239. package/dist/xlsx/layout/index.d.ts +1 -0
  240. package/dist/xlsx/layout/index.d.ts.map +1 -1
  241. package/dist/xlsx/load/csv.d.ts +24 -3
  242. package/dist/xlsx/load/csv.d.ts.map +1 -1
  243. package/dist/xlsx/load/detect.d.ts +39 -7
  244. package/dist/xlsx/load/detect.d.ts.map +1 -1
  245. package/dist/xlsx/load/errors.d.ts +10 -0
  246. package/dist/xlsx/load/errors.d.ts.map +1 -0
  247. package/dist/xlsx/load/index.cjs +16220 -12163
  248. package/dist/xlsx/load/index.d.ts +5 -2
  249. package/dist/xlsx/load/index.d.ts.map +1 -1
  250. package/dist/xlsx/load/index.mjs +16213 -12164
  251. package/dist/xlsx/load/text-decode.d.ts +7 -0
  252. package/dist/xlsx/load/text-decode.d.ts.map +1 -0
  253. package/dist/xlsx/model.d.ts +121 -17
  254. package/dist/xlsx/model.d.ts.map +1 -1
  255. package/dist/xlsx/numfmt/date.d.ts +7 -0
  256. package/dist/xlsx/numfmt/date.d.ts.map +1 -1
  257. package/dist/xlsx/numfmt/format.d.ts.map +1 -1
  258. package/dist/xlsx/numfmt/fraction.d.ts +5 -1
  259. package/dist/xlsx/numfmt/fraction.d.ts.map +1 -1
  260. package/dist/xlsx/numfmt/input-date.d.ts.map +1 -1
  261. package/dist/xlsx/numfmt/input.d.ts.map +1 -1
  262. package/dist/xlsx/numfmt/number.d.ts.map +1 -1
  263. package/dist/xlsx/read/conditional.d.ts.map +1 -1
  264. package/dist/xlsx/read/drawing.d.ts +2 -2
  265. package/dist/xlsx/read/drawing.d.ts.map +1 -1
  266. package/dist/xlsx/read/load.d.ts.map +1 -1
  267. package/dist/xlsx/read/package.d.ts +18 -2
  268. package/dist/xlsx/read/package.d.ts.map +1 -1
  269. package/dist/xlsx/read/sheet-data.d.ts.map +1 -1
  270. package/dist/xlsx/read/sheet-props.d.ts +15 -1
  271. package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
  272. package/dist/xlsx/read/smart-art.d.ts +12 -0
  273. package/dist/xlsx/read/smart-art.d.ts.map +1 -0
  274. package/dist/xlsx/read/styles.d.ts.map +1 -1
  275. package/dist/xlsx/read/workbook-part.d.ts +5 -2
  276. package/dist/xlsx/read/workbook-part.d.ts.map +1 -1
  277. package/dist/xlsx/read/worksheet.d.ts.map +1 -1
  278. package/dist/xlsx/write/attr-merge.d.ts +10 -0
  279. package/dist/xlsx/write/attr-merge.d.ts.map +1 -0
  280. package/dist/xlsx/write/carried-refs.d.ts +61 -0
  281. package/dist/xlsx/write/carried-refs.d.ts.map +1 -0
  282. package/dist/xlsx/write/comments.d.ts +12 -2
  283. package/dist/xlsx/write/comments.d.ts.map +1 -1
  284. package/dist/xlsx/write/conditional.d.ts.map +1 -1
  285. package/dist/xlsx/write/doc-props.d.ts +30 -0
  286. package/dist/xlsx/write/doc-props.d.ts.map +1 -0
  287. package/dist/xlsx/write/drawing.d.ts +5 -0
  288. package/dist/xlsx/write/drawing.d.ts.map +1 -1
  289. package/dist/xlsx/write/metadata.d.ts +23 -0
  290. package/dist/xlsx/write/metadata.d.ts.map +1 -0
  291. package/dist/xlsx/write/package-writer.d.ts +6 -0
  292. package/dist/xlsx/write/package-writer.d.ts.map +1 -1
  293. package/dist/xlsx/write/page-setup.d.ts +8 -0
  294. package/dist/xlsx/write/page-setup.d.ts.map +1 -0
  295. package/dist/xlsx/write/save.d.ts.map +1 -1
  296. package/dist/xlsx/write/sheet-data.d.ts +8 -0
  297. package/dist/xlsx/write/sheet-data.d.ts.map +1 -1
  298. package/dist/xlsx/write/sheet-parts.d.ts +6 -0
  299. package/dist/xlsx/write/sheet-parts.d.ts.map +1 -1
  300. package/dist/xlsx/write/sheet-props.d.ts +0 -6
  301. package/dist/xlsx/write/sheet-props.d.ts.map +1 -1
  302. package/dist/xlsx/write/styles.d.ts.map +1 -1
  303. package/dist/xlsx/write/table-patch.d.ts +12 -0
  304. package/dist/xlsx/write/table-patch.d.ts.map +1 -0
  305. package/dist/xlsx/write/tables.d.ts +9 -0
  306. package/dist/xlsx/write/tables.d.ts.map +1 -1
  307. package/dist/xlsx/write/vml-ids.d.ts +29 -0
  308. package/dist/xlsx/write/vml-ids.d.ts.map +1 -0
  309. package/dist/xlsx/write/workbook-part.d.ts +1 -4
  310. package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
  311. package/dist/xlsx/write/worksheet.d.ts.map +1 -1
  312. package/dist/xml/index.cjs +4 -0
  313. package/dist/xml/index.mjs +4 -0
  314. package/dist/xml/namespaces.d.ts +4 -0
  315. package/dist/xml/namespaces.d.ts.map +1 -1
  316. package/package.json +26 -3
  317. package/dist/pptx/chunks/index-CojJtI77.d.ts.map +0 -1
  318. package/dist/pptx/chunks/signature-inspection-status-Bh2oap7B.d.ts.map +0 -1
  319. package/dist/pptx/chunks/text-operations-IlJiffp7.d.ts.map +0 -1
  320. package/dist/pptx/index.d.ts.map +0 -1
@@ -4350,6 +4350,8 @@ function isSafeHyperlinkHref(href) {
4350
4350
  const scheme = /^([a-z][a-z0-9+.-]*:)/i.exec(href.trim())?.[1];
4351
4351
  return scheme !== void 0 && SAFE_SCHEMES.has(scheme.toLowerCase());
4352
4352
  }
4353
+ var OPEN_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "mailto"]);
4354
+ /* @__PURE__ */ new Set([...OPEN_SCHEMES, "ftp", "file"]);
4353
4355
 
4354
4356
  // src/visio/shape-metadata.ts
4355
4357
  function createMetadataBudget(options = {}) {
@@ -4965,16 +4967,16 @@ async function parseVsdx(input, options = {}) {
4965
4967
  const id = metadata(attribute2(master, "ID") ?? "", 256, "Master ID");
4966
4968
  if (!id || masters.has(id))
4967
4969
  throw new VisioPackageError("INVALID_MASTER_ID", "Master IDs must be present and unique.");
4968
- const masterShapes = readShapes(await visioXml(pkg, part, "MasterContents"));
4970
+ const masterShapes2 = readShapes(await visioXml(pkg, part, "MasterContents"));
4969
4971
  await prepareImages(
4970
- masterShapes,
4972
+ masterShapes2,
4971
4973
  pkg,
4972
4974
  part,
4973
4975
  report,
4974
4976
  options.images,
4975
4977
  options.metafileConverter
4976
4978
  );
4977
- masters.set(id, masterShapes);
4979
+ masters.set(id, masterShapes2);
4978
4980
  }
4979
4981
  }
4980
4982
  let geometryCount = 0, textCount = 0, expansionCount = 0, textRuns = 0, paragraphCount = 0;
@@ -5490,6 +5492,105 @@ var themeInputs = [
5490
5492
  "QuickStyleVariation"
5491
5493
  ];
5492
5494
 
5495
+ // src/visio/formula-arithmetic.ts
5496
+ function finiteFormulaValue(value) {
5497
+ if (!Number.isFinite(value.value)) return formulaFailure("value", "Formula result is not finite");
5498
+ if (!["scalar", "length", "area", "angle", "time"].includes(value.unit))
5499
+ return formulaFailure("unit", "Unknown resolved unit");
5500
+ return value;
5501
+ }
5502
+ function compatibleFormulaUnits(a, b) {
5503
+ if (a.unit === b.unit) return a.unit;
5504
+ if (a.unit === "scalar" && a.value === 0) return b.unit;
5505
+ if (b.unit === "scalar" && b.value === 0) return a.unit;
5506
+ return formulaFailure("unit", `Incompatible units ${a.unit} and ${b.unit}`);
5507
+ }
5508
+ var lengthPower = (unit) => unit === "scalar" ? 0 : unit === "length" ? 1 : unit === "area" ? 2 : void 0;
5509
+ function fromPower(power) {
5510
+ if (power === 0) return "scalar";
5511
+ if (power === 1) return "length";
5512
+ if (power === 2) return "area";
5513
+ return formulaFailure("unit", "Unsupported dimensional power");
5514
+ }
5515
+ function formulaProductUnit(a, b) {
5516
+ if (a === "scalar") return b;
5517
+ if (b === "scalar") return a;
5518
+ const left = lengthPower(a), right = lengthPower(b);
5519
+ if (left === void 0 || right === void 0)
5520
+ return formulaFailure("unit", "Mixed dimensions are unsupported");
5521
+ return fromPower(left + right);
5522
+ }
5523
+ function formulaQuotientUnit(a, b) {
5524
+ if (b === "scalar") return a;
5525
+ if (a === b) return "scalar";
5526
+ const left = lengthPower(a), right = lengthPower(b);
5527
+ if (left === void 0 || right === void 0)
5528
+ return formulaFailure("unit", "Mixed dimensions are unsupported");
5529
+ return fromPower(left - right);
5530
+ }
5531
+ function formulaExponentUnit(a, exponent) {
5532
+ if (exponent.unit !== "scalar") return formulaFailure("unit", "Exponents must be scalar");
5533
+ if (a === "scalar") return "scalar";
5534
+ if (exponent.value === 0) return "scalar";
5535
+ if (exponent.value === 1) return a;
5536
+ const power = lengthPower(a);
5537
+ if (power === void 0) return formulaFailure("unit", "Unsupported dimensional power");
5538
+ return fromPower(power * exponent.value);
5539
+ }
5540
+ function formulaSquareRootUnit(unit) {
5541
+ if (unit === "scalar") return "scalar";
5542
+ if (unit === "area") return "length";
5543
+ return formulaFailure("unit", "Square root requires scalar or square inches");
5544
+ }
5545
+
5546
+ // src/visio/formula-numeric-functions.ts
5547
+ var numericFormulaFunctions = /* @__PURE__ */ new Set([
5548
+ "AND",
5549
+ "OR",
5550
+ "NOT",
5551
+ "BITAND",
5552
+ "BITOR",
5553
+ "BITXOR",
5554
+ "MODULUS"
5555
+ ]);
5556
+ function evaluateNumericFormulaFunction(name, args) {
5557
+ const arity = (min, max = min) => {
5558
+ if (args.length < min || args.length > max)
5559
+ return formulaFailure("arity", `Invalid ${name} argument count`);
5560
+ };
5561
+ const scalar2 = (value) => ({ value, unit: "scalar" });
5562
+ if (name === "AND" || name === "OR" || name === "NOT") {
5563
+ arity(1, name === "NOT" ? 1 : 1024);
5564
+ const values = args.map((arg) => finiteFormulaValue(arg).value !== 0);
5565
+ return scalar2(
5566
+ Number(
5567
+ name === "AND" ? values.every(Boolean) : name === "OR" ? values.some(Boolean) : !values[0]
5568
+ )
5569
+ );
5570
+ }
5571
+ if (["BITAND", "BITOR", "BITXOR"].includes(name)) {
5572
+ arity(2);
5573
+ const values = args.map((arg) => {
5574
+ if (arg.unit !== "scalar") return formulaFailure("unit", `${name} requires scalar bitmasks`);
5575
+ if (!Number.isInteger(arg.value) || arg.value < 0 || arg.value > 65535)
5576
+ return formulaFailure("value", `${name} requires an integer from 0 to 65535`);
5577
+ return arg.value;
5578
+ });
5579
+ return scalar2(
5580
+ name === "BITAND" ? values[0] & values[1] : name === "BITOR" ? values[0] | values[1] : values[0] ^ values[1]
5581
+ );
5582
+ }
5583
+ if (name === "MODULUS") {
5584
+ arity(2);
5585
+ const dividend = finiteFormulaValue(args[0]), divisor = finiteFormulaValue(args[1]);
5586
+ const unit = compatibleFormulaUnits(dividend, divisor);
5587
+ if (divisor.value === 0) return formulaFailure("value", "MODULUS division by zero");
5588
+ const remainder = dividend.value - Math.floor(dividend.value / divisor.value) * divisor.value;
5589
+ return finiteFormulaValue({ value: remainder === 0 ? 0 : remainder, unit });
5590
+ }
5591
+ return formulaFailure("unsupported", `Unsupported numeric function ${name}`);
5592
+ }
5593
+
5493
5594
  // src/visio/formula-evaluate.ts
5494
5595
  var supported = /* @__PURE__ */ new Set([
5495
5596
  "GUARD",
@@ -5503,7 +5604,8 @@ var supported = /* @__PURE__ */ new Set([
5503
5604
  "TAN",
5504
5605
  "ATAN2",
5505
5606
  "SIGN",
5506
- "PI"
5607
+ "PI",
5608
+ ...numericFormulaFunctions
5507
5609
  ]);
5508
5610
  var staticUnsupported = /* @__PURE__ */ new Set([
5509
5611
  "ROUND",
@@ -5535,7 +5637,9 @@ var staticUnsupported = /* @__PURE__ */ new Set([
5535
5637
  "BITXOR",
5536
5638
  "TINT",
5537
5639
  "MSOTINT",
5538
- "SHADE"
5640
+ "SHADE",
5641
+ "LUMDIFF",
5642
+ "MODULUS"
5539
5643
  ]);
5540
5644
  var dynamic = /* @__PURE__ */ new Set([
5541
5645
  "INDIRECT",
@@ -5594,41 +5698,23 @@ function analyzeVisioFormula(source, limits = {}) {
5594
5698
  guarded
5595
5699
  };
5596
5700
  }
5597
- function finite2(value) {
5598
- if (!Number.isFinite(value.value)) return formulaFailure("value", "Formula result is not finite");
5599
- if (!["scalar", "length", "angle", "time"].includes(value.unit))
5600
- return formulaFailure("unit", "Unknown resolved unit");
5601
- return value;
5602
- }
5603
- function compatible(a, b) {
5604
- if (a.unit === b.unit) return a.unit;
5605
- if (a.unit === "scalar" && a.value === 0) return b.unit;
5606
- if (b.unit === "scalar" && b.value === 0) return a.unit;
5607
- return formulaFailure("unit", `Incompatible units ${a.unit} and ${b.unit}`);
5608
- }
5609
5701
  function binary(operator, a, b) {
5610
5702
  let unit;
5611
5703
  if (operator === "+" || operator === "-") {
5612
- unit = compatible(a, b);
5613
- return finite2({ value: operator === "+" ? a.value + b.value : a.value - b.value, unit });
5704
+ unit = compatibleFormulaUnits(a, b);
5705
+ return finiteFormulaValue({ value: operator === "+" ? a.value + b.value : a.value - b.value, unit });
5614
5706
  }
5615
5707
  if (operator === "*") {
5616
- if (a.unit !== "scalar" && b.unit !== "scalar")
5617
- return formulaFailure("unit", "Compound dimensions are unsupported");
5618
- return finite2({ value: a.value * b.value, unit: a.unit === "scalar" ? b.unit : a.unit });
5708
+ return finiteFormulaValue({ value: a.value * b.value, unit: formulaProductUnit(a.unit, b.unit) });
5619
5709
  }
5620
5710
  if (operator === "/") {
5621
5711
  if (b.value === 0) return formulaFailure("value", "Division by zero");
5622
- if (b.unit !== "scalar" && a.unit !== b.unit)
5623
- return formulaFailure("unit", "Inverse dimensions are unsupported");
5624
- return finite2({ value: a.value / b.value, unit: a.unit === b.unit ? "scalar" : a.unit });
5712
+ return finiteFormulaValue({ value: a.value / b.value, unit: formulaQuotientUnit(a.unit, b.unit) });
5625
5713
  }
5626
5714
  if (operator === "^") {
5627
- if (b.unit !== "scalar" || a.unit !== "scalar" && b.value !== 1 && b.value !== 0)
5628
- return formulaFailure("unit", "Dimensional powers are unsupported");
5629
- return finite2({ value: a.value ** b.value, unit: b.value === 0 ? "scalar" : a.unit });
5715
+ return finiteFormulaValue({ value: a.value ** b.value, unit: formulaExponentUnit(a.unit, b) });
5630
5716
  }
5631
- compatible(a, b);
5717
+ compatibleFormulaUnits(a, b);
5632
5718
  const comparisons = {
5633
5719
  "=": a.value === b.value,
5634
5720
  "<>": a.value !== b.value,
@@ -5652,13 +5738,13 @@ function evaluateVisioFormula(source, resolve, limits = {}) {
5652
5738
  if (++steps > maxSteps || depth > maxDepth)
5653
5739
  return formulaFailure("limit", "Formula evaluation limit");
5654
5740
  limits.onStep?.();
5655
- if (node.kind === "number") return finite2({ value: node.value, unit: node.unit });
5741
+ if (node.kind === "number") return finiteFormulaValue({ value: node.value, unit: node.unit });
5656
5742
  if (node.kind === "string")
5657
5743
  return formulaFailure("value", "String results are outside the numeric formula subset");
5658
- if (node.kind === "reference") return finite2(resolve(node.reference));
5744
+ if (node.kind === "reference") return finiteFormulaValue(resolve(node.reference));
5659
5745
  if (node.kind === "unary") {
5660
5746
  const result = evaluate(node.operand, depth + 1);
5661
- return finite2({
5747
+ return finiteFormulaValue({
5662
5748
  value: node.operator === "-" ? -result.value : result.value,
5663
5749
  unit: result.unit
5664
5750
  });
@@ -5672,6 +5758,11 @@ function evaluateVisioFormula(source, resolve, limits = {}) {
5672
5758
  return formulaFailure("arity", `Invalid ${name} argument count`);
5673
5759
  };
5674
5760
  const arg = (index) => evaluate(node.args[index], depth + 1);
5761
+ if (numericFormulaFunctions.has(name))
5762
+ return evaluateNumericFormulaFunction(
5763
+ name,
5764
+ node.args.map((_, index) => arg(index))
5765
+ );
5675
5766
  if (name === "PI") {
5676
5767
  arity(0);
5677
5768
  return { value: Math.PI, unit: "scalar" };
@@ -5691,18 +5782,18 @@ function evaluateVisioFormula(source, resolve, limits = {}) {
5691
5782
  const args = node.args.map((_, i) => arg(i));
5692
5783
  let result = args[0];
5693
5784
  for (const item of args.slice(1)) {
5694
- const unit = compatible(result, item);
5785
+ const unit = compatibleFormulaUnits(result, item);
5695
5786
  result = {
5696
5787
  value: name === "MIN" ? Math.min(result.value, item.value) : Math.max(result.value, item.value),
5697
5788
  unit
5698
5789
  };
5699
5790
  }
5700
- return finite2(result);
5791
+ return finiteFormulaValue(result);
5701
5792
  }
5702
5793
  if (name === "ATAN2") {
5703
5794
  arity(2);
5704
5795
  const y = arg(0), x = arg(1);
5705
- compatible(y, x);
5796
+ compatibleFormulaUnits(y, x);
5706
5797
  return { value: Math.atan2(y.value, x.value), unit: "angle" };
5707
5798
  }
5708
5799
  if (name === "SIGN") {
@@ -5720,12 +5811,11 @@ function evaluateVisioFormula(source, resolve, limits = {}) {
5720
5811
  const value = arg(0);
5721
5812
  if (name === "ABS") return { value: Math.abs(value.value), unit: value.unit };
5722
5813
  if (name === "SQRT") {
5723
- if (value.unit !== "scalar") return formulaFailure("unit", "Dimensional SQRT unsupported");
5724
- return finite2({ value: Math.sqrt(value.value), unit: "scalar" });
5814
+ return finiteFormulaValue({ value: Math.sqrt(value.value), unit: formulaSquareRootUnit(value.unit) });
5725
5815
  }
5726
5816
  if (value.unit !== "angle" && value.unit !== "scalar")
5727
5817
  return formulaFailure("unit", `${name} requires radians`);
5728
- return finite2({
5818
+ return finiteFormulaValue({
5729
5819
  value: name === "SIN" ? Math.sin(value.value) : name === "COS" ? Math.cos(value.value) : Math.tan(value.value),
5730
5820
  unit: "scalar"
5731
5821
  });
@@ -6087,7 +6177,7 @@ function recalculateVisioCells(roots, changed, options = {}) {
6087
6177
  if (active.size >= maxDepth)
6088
6178
  fail("LIMIT_FORMULA_DEPTH", "ShapeSheet dependency depth limit exceeded.");
6089
6179
  const item = cells3.get(id);
6090
- if (!item || item.unsafe)
6180
+ if (!item || item.unsafe && (!item.node || !options.masterMovePins?.has(item.node)))
6091
6181
  fail(
6092
6182
  "EDIT_UNSUPPORTED_DEPENDENCY",
6093
6183
  "Affected formula references missing, inherited or grouped cells."
@@ -6240,7 +6330,7 @@ function setCell(shape, name, value, formula) {
6240
6330
  if (formula) node.setAttribute("F", formula);
6241
6331
  else if (attribute2(node, "F") !== "No Formula") node.removeAttribute("F");
6242
6332
  }
6243
- function admitted(root, shapeId) {
6333
+ function admitted(root, shapeId, masterMovePins = /* @__PURE__ */ new Set()) {
6244
6334
  const containers = children(root, "Shapes");
6245
6335
  if (containers.length !== 1)
6246
6336
  fail("UNSUPPORTED_GEOMETRY_EDIT", "One local Shapes container is required.");
@@ -6250,7 +6340,10 @@ function admitted(root, shapeId) {
6250
6340
  if (candidates.length !== 1)
6251
6341
  fail("EDIT_TARGET_NOT_FOUND", "A unique top-level local shape is required.");
6252
6342
  const shape = candidates[0];
6253
- if (shape.hasAttribute("Master") || shape.hasAttribute("MasterShape") || ["1", "true"].includes(attribute2(shape, "Del") ?? "") || children(shape, "Shapes").length || children(shape, "ForeignData").length || children(shape, "Rel").length || attribute2(shape, "Type") && attribute2(shape, "Type") !== "Shape")
6343
+ if ((shape.hasAttribute("Master") || shape.hasAttribute("MasterShape")) && !["PinX", "PinY"].every((name) => {
6344
+ const cell = cells(shape).get(name);
6345
+ return cell && masterMovePins.has(cell);
6346
+ }) || ["1", "true"].includes(attribute2(shape, "Del") ?? "") || children(shape, "Shapes").length || children(shape, "ForeignData").length || children(shape, "Rel").length || attribute2(shape, "Type") && attribute2(shape, "Type") !== "Shape")
6254
6347
  fail(
6255
6348
  "UNSUPPORTED_GEOMETRY_EDIT",
6256
6349
  "Master, group, foreign, deleted and non-shape operations are unsupported."
@@ -6457,7 +6550,7 @@ function createRectangle(root, edit) {
6457
6550
  container.appendChild(shape);
6458
6551
  return shape;
6459
6552
  }
6460
- function applyGeometryEdit(roots, document, edit, check) {
6553
+ function applyGeometryEdit(roots, document, edit, check, masterMovePins = /* @__PURE__ */ new Set()) {
6461
6554
  check();
6462
6555
  const root = roots.get(edit.pageId);
6463
6556
  if (!root) fail("EDIT_TARGET_NOT_FOUND", "Page does not exist.");
@@ -6469,7 +6562,11 @@ function applyGeometryEdit(roots, document, edit, check) {
6469
6562
  expected = { width: edit.width, height: edit.height, x: edit.x, y: edit.y };
6470
6563
  for (const name of ["Width", "Height", "PinX", "PinY"]) add(name);
6471
6564
  } else {
6472
- const shape = admitted(root, edit.shapeId);
6565
+ const shape = admitted(
6566
+ root,
6567
+ edit.shapeId,
6568
+ edit.type === "move-shape" ? masterMovePins : /* @__PURE__ */ new Set()
6569
+ );
6473
6570
  protectedShape(shape, document);
6474
6571
  if (edit.type !== "delete-shape") {
6475
6572
  for (const connections2 of children(root, "Connects"))
@@ -6547,8 +6644,10 @@ function applyGeometryEdit(roots, document, edit, check) {
6547
6644
  }
6548
6645
  }
6549
6646
  if (!changed.length) return [];
6550
- const affectedPages = recalculateVisioCells(roots, changed, { check });
6551
- const result = cells(admitted(root, edit.shapeId));
6647
+ const affectedPages = recalculateVisioCells(roots, changed, { check, masterMovePins });
6648
+ const result = cells(
6649
+ admitted(root, edit.shapeId, edit.type === "move-shape" ? masterMovePins : /* @__PURE__ */ new Set())
6650
+ );
6552
6651
  if (expected && (numeric3(result.get("Width")) !== expected.width || numeric3(result.get("Height")) !== expected.height || numeric3(result.get("PinX"), expected.width / 2) !== expected.x || numeric3(result.get("PinY"), expected.height / 2) !== expected.y))
6553
6652
  fail(
6554
6653
  "EDIT_UNSUPPORTED_DEPENDENCY",
@@ -6557,6 +6656,525 @@ function applyGeometryEdit(roots, document, edit, check) {
6557
6656
  return [.../* @__PURE__ */ new Set([edit.pageId, ...affectedPages])];
6558
6657
  }
6559
6658
 
6659
+ // src/visio/formula-master.ts
6660
+ function analyzeVisioMasterFormula(source, options) {
6661
+ const ast = parseVisioFormula(source);
6662
+ const analysis = analyzeVisioFormula(ast);
6663
+ const references = /* @__PURE__ */ new Map();
6664
+ for (const ref of analysis.references)
6665
+ references.set(`${ref.shapeId ?? ""}!${ref.cell.toLowerCase()}`, ref);
6666
+ let dynamic2 = false, readsText = false, readsTheme = false;
6667
+ const queue = [ast];
6668
+ while (queue.length) {
6669
+ const node = queue.pop();
6670
+ if (node.kind === "unary") queue.push(node.operand);
6671
+ if (node.kind === "binary") queue.push(node.left, node.right);
6672
+ if (node.kind !== "call") continue;
6673
+ queue.push(...node.args);
6674
+ if (["THEME", "THEMEVAL", "ISTHEMED"].includes(node.name)) readsTheme = true;
6675
+ let local = !analyzeVisioFormula({ kind: "call", name: node.name, args: [] }).dynamic;
6676
+ if (node.name === "SETATREF")
6677
+ local = node.args.length === 1 && node.args[0].kind === "reference";
6678
+ if (["TEXTWIDTH", "TEXTHEIGHT", "SHAPETEXT"].includes(node.name)) {
6679
+ const text = node.args[0];
6680
+ const count = node.name === "TEXTHEIGHT" ? node.args.length === 2 : node.args.length === 1;
6681
+ local = options.textFieldFree && count && text?.kind === "reference" && text.reference.shapeId === void 0 && text.reference.cell.toLowerCase() === "thetext";
6682
+ readsText = true;
6683
+ }
6684
+ if (["LUM", "HUE", "SAT"].includes(node.name)) {
6685
+ local = node.args.length === 1;
6686
+ const arg = node.args[0];
6687
+ if (arg?.kind === "string") {
6688
+ local = /^[A-Za-z_][A-Za-z0-9_.]*$/.test(arg.value);
6689
+ if (local) references.set(`!${arg.value.toLowerCase()}`, { cell: arg.value });
6690
+ }
6691
+ }
6692
+ if (node.name === "STRSAME") local = node.args.length === 2;
6693
+ if (!local) dynamic2 = true;
6694
+ }
6695
+ return { ...analysis, references: [...references.values()], dynamic: dynamic2, readsText, readsTheme };
6696
+ }
6697
+
6698
+ // src/visio/edit-master-move.ts
6699
+ var protection = [
6700
+ "LockMoveX",
6701
+ "LockMoveY",
6702
+ "LockWidth",
6703
+ "LockHeight",
6704
+ "LockAspect",
6705
+ "LockDelete"
6706
+ ];
6707
+ var dimensions2 = ["PinX", "PinY", "Width", "Height", "LocPinX", "LocPinY"];
6708
+ function prepareMasterMovePins(roots, commands, bindings, check) {
6709
+ const result = /* @__PURE__ */ new Set();
6710
+ let work = 1e5;
6711
+ const charge = (amount = 1) => {
6712
+ check();
6713
+ work -= amount;
6714
+ if (work < 0)
6715
+ fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Master move preparation budget exceeded.");
6716
+ };
6717
+ const analyze = (formula) => {
6718
+ charge(formula.length);
6719
+ return analyzeVisioFormula(formula);
6720
+ };
6721
+ for (const command2 of commands) {
6722
+ charge();
6723
+ const root = roots.get(command2.pageId);
6724
+ const instance = children(children(root, "Shapes")[0], "Shape").find(
6725
+ (shape) => attribute2(shape, "ID") === command2.shapeId
6726
+ );
6727
+ if (!instance?.hasAttribute("Master")) continue;
6728
+ if (command2.type !== "move-shape")
6729
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "Master-linked resizing and deletion remain unsupported.");
6730
+ const binding = bindings.find((candidate) => candidate.instance === instance);
6731
+ if (!binding) fail("UNSUPPORTED_GEOMETRY_EDIT", "A unique effective master root is required.");
6732
+ for (const node of [instance, binding.template]) {
6733
+ charge();
6734
+ if (attribute2(node, "Type") !== "Shape" || children(node, "Shapes").length || children(node, "ForeignData").length || children(node, "Rel").length || ["1", "true"].includes(attribute2(node, "Del") ?? ""))
6735
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "Master moves require top-level local 2D shape roots.");
6736
+ }
6737
+ for (const name of ["BeginX", "BeginY", "EndX", "EndY"])
6738
+ if (binding.cells.has(name.toLowerCase()))
6739
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "Master lines and endpoint routing remain unsupported.");
6740
+ const oneD = binding.cells.get("oned")?.node;
6741
+ charge();
6742
+ if (oneD && (numeric3(oneD) !== 0 || visioFormulaCachedValue(attribute2(oneD, "V") ?? "", attribute2(oneD, "U")).unit !== "scalar" || executableCellFormula(attribute2(oneD, "F"))))
6743
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "A static effective 2D master is required.");
6744
+ const local = cells(instance);
6745
+ for (const name of dimensions2) {
6746
+ charge();
6747
+ const node = local.get(name);
6748
+ numeric3(node);
6749
+ if (visioFormulaCachedValue("0", attribute2(node, "U") ?? "DL").unit !== "length")
6750
+ fail("EDIT_FORMULA_UNIT", "Master transform caches require length units.");
6751
+ }
6752
+ if (numeric3(local.get("Width")) <= 0 || numeric3(local.get("Height")) <= 0)
6753
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "Positive explicit local dimensions are required.");
6754
+ for (const name of protection) {
6755
+ charge();
6756
+ const node = binding.cells.get(name.toLowerCase())?.node;
6757
+ if (!node || visioFormulaCachedValue(attribute2(node, "V") ?? "", attribute2(node, "U")).unit !== "scalar" || numeric3(node) !== 0)
6758
+ fail(
6759
+ "EDIT_PROTECTED_CELL",
6760
+ "Effective master protection must be explicitly proven inactive."
6761
+ );
6762
+ const formula = executableCellFormula(attribute2(node, "F"));
6763
+ if (formula) {
6764
+ const analysis = analyze(formula);
6765
+ if (analysis.dynamic || analysis.references.length || analysis.unsupportedFunctions.length)
6766
+ fail("EDIT_PROTECTED_CELL", "Effective master protection dependencies are unsupported.");
6767
+ const value = evaluateVisioFormula(
6768
+ formula,
6769
+ () => fail("EDIT_PROTECTED_CELL", "Unexpected protection dependency."),
6770
+ { onStep: () => charge() }
6771
+ );
6772
+ if (value.unit !== "scalar" || value.value !== 0)
6773
+ fail("EDIT_PROTECTED_CELL", "Effective master protection is active or stale.");
6774
+ }
6775
+ }
6776
+ for (const name of ["PinX", "PinY"]) {
6777
+ charge();
6778
+ const node = local.get(name);
6779
+ if (binding.cells.get(name.toLowerCase())?.node !== node)
6780
+ fail("EDIT_PROTECTED_CELL", "The rotation pin must be an explicit local override.");
6781
+ charge(executableCellFormula(attribute2(node, "F"))?.length ?? 0);
6782
+ editableCell(node);
6783
+ const inherited = binding.inheritedCells.get(name.toLowerCase())?.node;
6784
+ numeric3(inherited);
6785
+ if (visioFormulaCachedValue("0", attribute2(inherited, "U") ?? "DL").unit !== "length")
6786
+ fail("EDIT_FORMULA_UNIT", "Inherited rotation pins require length units.");
6787
+ const formula = executableCellFormula(attribute2(inherited, "F"));
6788
+ if (formula) {
6789
+ const analysis = analyze(formula);
6790
+ if (analysis.guarded || analysis.dynamic || analysis.unsupportedFunctions.length)
6791
+ fail("EDIT_PROTECTED_CELL", "Protected or redirected master pins cannot be overridden.");
6792
+ }
6793
+ result.add(node);
6794
+ }
6795
+ }
6796
+ if (result.size) {
6797
+ const indexed = indexCells(roots, { check });
6798
+ const pins = new Set(
6799
+ [...indexed.values()].filter((cell) => cell.node && result.has(cell.node)).map(key)
6800
+ );
6801
+ for (const cell of indexed.values())
6802
+ if (charge(), cell.dependencies.some((dependency) => pins.has(dependency)))
6803
+ fail("EDIT_UNSUPPORTED_DEPENDENCY", "A page cache depends on a master rotation pin.");
6804
+ }
6805
+ return result;
6806
+ }
6807
+
6808
+ // src/visio/edit-master-index.ts
6809
+ function masterCells(sheet, charge = () => {
6810
+ }) {
6811
+ const result = /* @__PURE__ */ new Map();
6812
+ if (!sheet) return result;
6813
+ const add = (name, node) => {
6814
+ charge();
6815
+ const id = name.toLowerCase();
6816
+ if (result.has(id) && result.get(id) !== node)
6817
+ fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Ambiguous effective master cells.");
6818
+ result.set(id, node);
6819
+ };
6820
+ for (const node of children(sheet, "Cell")) add(attribute2(node, "N") ?? "", node);
6821
+ for (const section of children(sheet, "Section")) {
6822
+ const name = attribute2(section, "N") ?? "";
6823
+ const prefix = name === "Geometry" ? `Geometry${Number(attribute2(section, "IX") ?? "0") + 1}` : name === "Control" ? "Controls" : name;
6824
+ for (const node of children(section, "Cell"))
6825
+ add(`${prefix}.${attribute2(node, "N") ?? ""}`, node);
6826
+ for (const row of children(section, "Row"))
6827
+ for (const node of children(row, "Cell")) {
6828
+ const n = attribute2(node, "N") ?? "";
6829
+ const rowName = attribute2(row, "N");
6830
+ const index = attribute2(row, "IX") ?? (prefix === "Controls" && /^Row_\d+$/.test(rowName ?? "") ? String(Number(rowName.slice(4)) - 1) : void 0);
6831
+ const ix = index ?? "0", r = rowName ?? (prefix === "Controls" ? `Row_${Number(ix) + 1}` : ix);
6832
+ add(
6833
+ name === "Geometry" || ["Controls", "Scratch", "Connection"].includes(prefix) ? `${prefix}.${n}${ix}` : n === "Value" && ["User", "Prop"].includes(name) ? `${prefix}.${r}` : `${prefix}.${r}.${n}`,
6834
+ node
6835
+ );
6836
+ if (name !== "Geometry") add(`${prefix}.${r}.${n}`, node);
6837
+ if (prefix === "Controls" && n === "X") add(`${prefix}.${r}`, node);
6838
+ if (name !== "Geometry" && index !== void 0) add(`${prefix}.$row${ix}.${n}`, node);
6839
+ }
6840
+ }
6841
+ return result;
6842
+ }
6843
+ function masterShapes(root) {
6844
+ const result = [], pending = [root];
6845
+ while (pending.length) {
6846
+ const parent = pending.pop();
6847
+ for (const container of children(parent, "Shapes"))
6848
+ for (const shape of children(container, "Shape")) {
6849
+ result.push(shape);
6850
+ pending.push(shape);
6851
+ }
6852
+ }
6853
+ return result;
6854
+ }
6855
+ function assertMasterMarkup(root, known, check) {
6856
+ for (const node of [root, ...Array.from(root.getElementsByTagName("*"))]) {
6857
+ check();
6858
+ if (node.namespaceURI === root.namespaceURI && node.hasAttribute("F") && !known.has(node))
6859
+ fail(
6860
+ "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
6861
+ "Master formula outside admitted sheet cells has unknown scope."
6862
+ );
6863
+ }
6864
+ }
6865
+ function masterStyleCells(document, template, instance, check, charge = () => {
6866
+ }) {
6867
+ const styles = /* @__PURE__ */ new Map();
6868
+ for (const container of children(document, "StyleSheets"))
6869
+ for (const style of children(container, "StyleSheet")) {
6870
+ charge();
6871
+ const id = attribute2(style, "ID");
6872
+ if (!id || styles.has(id))
6873
+ fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Ambiguous master style IDs.");
6874
+ styles.set(id, style);
6875
+ }
6876
+ const defaults = children(document, "DocumentSheet")[0];
6877
+ const collect = (id, category, seen = /* @__PURE__ */ new Set()) => {
6878
+ check();
6879
+ if (seen.has(id) || seen.size >= 64)
6880
+ fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Invalid inherited master style ancestry.");
6881
+ seen.add(id);
6882
+ const style = styles.get(id);
6883
+ if (!style) fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Missing inherited master style.");
6884
+ const own = masterCells(style, charge);
6885
+ assertMasterMarkup(style, new Set(own.values()), check);
6886
+ const parent = attribute2(style, category);
6887
+ const result2 = parent !== void 0 && parent !== id ? collect(parent, category, seen) : /* @__PURE__ */ new Map();
6888
+ for (const [name, node] of own) {
6889
+ charge();
6890
+ if (attribute2(node, "F") !== "Inh") result2.set(name, node);
6891
+ }
6892
+ return result2;
6893
+ };
6894
+ const result = /* @__PURE__ */ new Map();
6895
+ for (const category of ["LineStyle", "FillStyle", "TextStyle"]) {
6896
+ const id = attribute2(instance, category) ?? attribute2(template, category) ?? attribute2(defaults, category) ?? (styles.has("0") ? "0" : void 0);
6897
+ if (id !== void 0)
6898
+ for (const [name, node] of collect(id, category)) {
6899
+ charge();
6900
+ if (result.has(name) && result.get(name) !== node)
6901
+ fail(
6902
+ "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
6903
+ "Master style categories have ambiguous overlapping inputs."
6904
+ );
6905
+ result.set(name, node);
6906
+ }
6907
+ }
6908
+ return result;
6909
+ }
6910
+ function overlay(cells3, additions, kind, charge) {
6911
+ const aliases = /* @__PURE__ */ new Map(), inherited = /* @__PURE__ */ new Map();
6912
+ for (const [name, source] of cells3) {
6913
+ charge();
6914
+ const names = aliases.get(source.node) ?? /* @__PURE__ */ new Set();
6915
+ names.add(name);
6916
+ aliases.set(source.node, names);
6917
+ }
6918
+ for (const [name, node] of additions) {
6919
+ charge();
6920
+ const source = cells3.get(name);
6921
+ if (source) inherited.set(node, source);
6922
+ }
6923
+ for (const [name, node] of additions) {
6924
+ charge();
6925
+ if (attribute2(node, "F") === "Inh") {
6926
+ const source = cells3.get(name) ?? inherited.get(node);
6927
+ if (!source)
6928
+ fail(
6929
+ "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
6930
+ "Inherited master cell has no effective source."
6931
+ );
6932
+ cells3.set(name, source);
6933
+ const names2 = aliases.get(source.node) ?? /* @__PURE__ */ new Set();
6934
+ names2.add(name);
6935
+ aliases.set(source.node, names2);
6936
+ continue;
6937
+ }
6938
+ const previous = cells3.get(name), names = aliases.get(node) ?? /* @__PURE__ */ new Set();
6939
+ if (previous && previous.node !== node) {
6940
+ for (const alias of aliases.get(previous.node) ?? []) {
6941
+ charge();
6942
+ cells3.set(alias, { node, kind });
6943
+ names.add(alias);
6944
+ }
6945
+ aliases.delete(previous.node);
6946
+ }
6947
+ cells3.set(name, { node, kind });
6948
+ names.add(name);
6949
+ aliases.set(node, names);
6950
+ }
6951
+ }
6952
+
6953
+ // src/visio/edit-master-scope.ts
6954
+ function problem(message) {
6955
+ return fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", message);
6956
+ }
6957
+ var themeCell = /^(ColorSchemeIndex|EffectSchemeIndex|FontSchemeIndex|ThemeIndex|QuickStyle.*)$/i;
6958
+ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
6959
+ const instances = [...roots].flatMap(
6960
+ ([pageId, root]) => masterShapes(root).filter((shape) => shape.hasAttribute("Master")).map((instance) => ({ pageId, instance }))
6961
+ );
6962
+ if (!instances.length) return /* @__PURE__ */ new Set();
6963
+ const documentPart = await related(pkg, "", "document");
6964
+ if (!documentPart) problem("Missing master document relationship.");
6965
+ const document = await visioXml(pkg, documentPart, "VisioDocument");
6966
+ const mastersPart = await related(pkg, documentPart, "masters", false);
6967
+ if (!mastersPart) problem("Active master definitions are missing.");
6968
+ const definitions = /* @__PURE__ */ new Map();
6969
+ for (const node of children(await visioXml(pkg, mastersPart, "Masters"), "Master")) {
6970
+ const id = attribute2(node, "ID");
6971
+ if (!id || definitions.has(id)) problem("Master IDs are ambiguous.");
6972
+ definitions.set(id, node);
6973
+ }
6974
+ const loaded = /* @__PURE__ */ new Map();
6975
+ const bindings = [];
6976
+ let buildWork = 1e5;
6977
+ const charge = () => {
6978
+ check();
6979
+ if (--buildWork < 0) problem("Master effective-cell construction budget exceeded.");
6980
+ };
6981
+ const pageBindings = /* @__PURE__ */ new Map();
6982
+ const pageShapes = /* @__PURE__ */ new Map();
6983
+ for (const [pageId, root] of roots)
6984
+ for (const shape of masterShapes(root)) {
6985
+ const id = attribute2(shape, "ID");
6986
+ if (!id) problem("Page shape ID is missing.");
6987
+ const key2 = JSON.stringify([pageId, id]);
6988
+ if (pageShapes.has(key2)) problem("Page sheet IDs have ambiguous group scopes.");
6989
+ pageShapes.set(key2, shape);
6990
+ }
6991
+ for (const { pageId, instance } of instances) {
6992
+ check();
6993
+ const masterId = attribute2(instance, "Master"), definition = definitions.get(masterId);
6994
+ if (!definition) problem("Active master ID cannot be resolved.");
6995
+ let root = loaded.get(masterId);
6996
+ if (!root) {
6997
+ root = await visioXml(
6998
+ pkg,
6999
+ await indexedPart(pkg, mastersPart, definition, "master"),
7000
+ "MasterContents"
7001
+ );
7002
+ loaded.set(masterId, root);
7003
+ }
7004
+ const tops = children(children(root, "Shapes")[0], "Shape");
7005
+ if (tops.length !== 1) problem("Only a uniquely rooted master can prove independence.");
7006
+ const templates = masterShapes(root), context = /* @__PURE__ */ new Map();
7007
+ assertMasterMarkup(
7008
+ root,
7009
+ new Set(
7010
+ templates.flatMap((shape) => {
7011
+ charge();
7012
+ return [...masterCells(shape, charge).values()];
7013
+ })
7014
+ ),
7015
+ check
7016
+ );
7017
+ const locals = [instance, ...masterShapes(instance)];
7018
+ const byTemplate = /* @__PURE__ */ new Map();
7019
+ const rootId = attribute2(tops[0], "ID");
7020
+ if (!rootId) problem("Master root shape ID is missing.");
7021
+ const explicitRoot = attribute2(instance, "MasterShape");
7022
+ if (explicitRoot !== void 0 && explicitRoot !== rootId)
7023
+ problem("Master root mapping is ambiguous.");
7024
+ byTemplate.set(rootId, instance);
7025
+ for (const local of locals.slice(1)) {
7026
+ if (local.hasAttribute("Master")) problem("Nested master inheritance is unsupported.");
7027
+ const id = attribute2(local, "MasterShape");
7028
+ if (id === void 0) continue;
7029
+ if (byTemplate.has(id)) problem("MasterShape mappings are ambiguous.");
7030
+ byTemplate.set(id, local);
7031
+ }
7032
+ for (const template of templates) {
7033
+ charge();
7034
+ if (bindings.length >= 1e4) problem("Master effective binding limit exceeded.");
7035
+ check();
7036
+ if (template.hasAttribute("Master") || template.hasAttribute("MasterShape"))
7037
+ problem("Chained master definitions are unsupported.");
7038
+ const templateId = attribute2(template, "ID");
7039
+ if (!templateId || context.has(templateId)) problem("Master-local sheet IDs are ambiguous.");
7040
+ const local = byTemplate.get(templateId), cells3 = /* @__PURE__ */ new Map();
7041
+ for (const [name, node] of masterStyleCells(document, template, local, check, charge))
7042
+ cells3.set(name, { node, kind: "style" });
7043
+ overlay(cells3, masterCells(template, charge), "template", charge);
7044
+ const inheritedCells = new Map(cells3);
7045
+ overlay(cells3, masterCells(local, charge), "instance", charge);
7046
+ const binding = {
7047
+ id: `${pageId}:${attribute2(instance, "ID")}:${templateId}`,
7048
+ pageId,
7049
+ template,
7050
+ cells: cells3,
7051
+ inheritedCells,
7052
+ context,
7053
+ ...local ? { instance: local } : {}
7054
+ };
7055
+ context.set(templateId, binding);
7056
+ bindings.push(binding);
7057
+ if (local) pageBindings.set(JSON.stringify([pageId, attribute2(local, "ID")]), binding);
7058
+ }
7059
+ for (const id of byTemplate.keys())
7060
+ if (!context.has(id)) problem("MasterShape refers to a missing template.");
7061
+ }
7062
+ const movePins = prepareMasterMovePins(roots, commands, bindings, check);
7063
+ const changed = commands.flatMap(
7064
+ (command2) => command2.type === "delete-shape" ? [] : (command2.type === "move-shape" ? ["PinX", "PinY"] : command2.type === "resize-shape" ? ["Width", "Height"] : ["Width", "Height", "PinX", "PinY"]).map((cell) => ({ pageId: command2.pageId, shapeId: command2.shapeId, cell }))
7065
+ );
7066
+ const query = createVisioDependencyQuery(roots, { check });
7067
+ const directAffected = (pageId, shapeId, cell) => commands.some(
7068
+ (command2) => command2.pageId === pageId && command2.shapeId === shapeId && (command2.type === "delete-shape" || changed.some(
7069
+ (target) => target.pageId === pageId && target.shapeId === shapeId && target.cell.toLowerCase() === cell.toLowerCase()
7070
+ ))
7071
+ );
7072
+ const active = /* @__PURE__ */ new Set(), done = /* @__PURE__ */ new Set();
7073
+ const pageInputs = /* @__PURE__ */ new Map();
7074
+ const pageInput = (pageId, shapeId) => {
7075
+ const id = JSON.stringify([pageId, shapeId]);
7076
+ const bound2 = pageBindings.get(id) ?? pageInputs.get(id);
7077
+ if (bound2) return bound2;
7078
+ const shape = pageShapes.get(id);
7079
+ if (!shape) problem("Local master override has a missing page reference.");
7080
+ const cells3 = /* @__PURE__ */ new Map();
7081
+ for (const [name, node] of masterStyleCells(document, shape, shape, check, charge))
7082
+ cells3.set(name, { node, kind: "style" });
7083
+ overlay(cells3, masterCells(shape, charge), "instance", charge);
7084
+ const result = {
7085
+ id: `page:${id}`,
7086
+ pageId,
7087
+ template: shape,
7088
+ instance: shape,
7089
+ cells: cells3,
7090
+ inheritedCells: /* @__PURE__ */ new Map(),
7091
+ context: /* @__PURE__ */ new Map()
7092
+ };
7093
+ pageInputs.set(id, result);
7094
+ return result;
7095
+ };
7096
+ let steps = 1e5;
7097
+ const inspect2 = (binding, name) => {
7098
+ check();
7099
+ if (--steps < 0) problem("Master dependency proof exceeded its cell budget.");
7100
+ name = name.toLowerCase();
7101
+ const pageShapeId = attribute2(binding.instance, "ID");
7102
+ if (pageShapeId !== void 0 && directAffected(binding.pageId, pageShapeId, name))
7103
+ problem("Effective master cache depends on an edited page cell.");
7104
+ const id = JSON.stringify([binding.id, name]);
7105
+ if (done.has(id)) return;
7106
+ if (active.has(id) || active.size >= 64)
7107
+ problem("Master dependency proof is cyclic or too deep.");
7108
+ active.add(id);
7109
+ const source = binding.cells.get(name);
7110
+ if (!source) {
7111
+ const defaults = {
7112
+ locpinx: "width",
7113
+ locpiny: "height",
7114
+ txtwidth: "width",
7115
+ txtheight: "height",
7116
+ txtpinx: "width",
7117
+ txtpiny: "height",
7118
+ txtlocpinx: "txtwidth",
7119
+ txtlocpiny: "txtheight"
7120
+ };
7121
+ const dimension = defaults[name];
7122
+ if (dimension) inspect2(binding, dimension);
7123
+ else if (!themeCell.test(name)) problem(`Missing effective master reference ${name}.`);
7124
+ } else {
7125
+ const formula = executableCellFormula(attribute2(source.node, "F"));
7126
+ if (formula && !inertDoubleClickFormula(attribute2(source.node, "N") ?? "", formula)) {
7127
+ const text = children(binding.instance, "Text")[0] ?? children(binding.template, "Text")[0];
7128
+ const textFieldFree = ![...binding.cells.keys()].some((key2) => /^fields?\./i.test(key2)) && (!text || !Array.from(text.getElementsByTagName("*")).some(
7129
+ (node) => node.localName.toLowerCase() === "fld"
7130
+ ));
7131
+ let analysis;
7132
+ try {
7133
+ analysis = analyzeVisioMasterFormula(formula, { textFieldFree });
7134
+ } catch (error) {
7135
+ problem(
7136
+ `Cannot analyze effective master formula: ${error instanceof Error ? error.message : "invalid formula"}`
7137
+ );
7138
+ }
7139
+ if (analysis.dynamic) problem("Effective master formula has unknown dynamic dependencies.");
7140
+ for (const ref of analysis.references) {
7141
+ if (analysis.readsText && ref.shapeId === void 0 && ref.cell.toLowerCase() === "thetext")
7142
+ continue;
7143
+ if (ref.shapeId === void 0) inspect2(binding, ref.cell);
7144
+ else if (source.kind === "template") {
7145
+ const target = binding.context.get(ref.shapeId);
7146
+ if (!target) problem("Missing master-local Sheet reference.");
7147
+ inspect2(target, ref.cell);
7148
+ } else {
7149
+ if (source.kind === "style")
7150
+ problem("Explicit sheet references in inherited master styles are ambiguous.");
7151
+ if (directAffected(binding.pageId, ref.shapeId, ref.cell) || query({ pageId: binding.pageId, shapeId: ref.shapeId, cell: ref.cell }, changed))
7152
+ problem("Effective master cache depends on an edited page shape.");
7153
+ inspect2(pageInput(binding.pageId, ref.shapeId), ref.cell);
7154
+ }
7155
+ }
7156
+ if (analysis.readsText) {
7157
+ for (const cell of binding.cells.keys())
7158
+ if (/^(character\.|paragraph\.|tabs\.|leftmargin$|rightmargin$|topmargin$|bottommargin$)/i.test(
7159
+ cell
7160
+ ))
7161
+ inspect2(binding, cell);
7162
+ }
7163
+ }
7164
+ }
7165
+ active.delete(id);
7166
+ done.add(id);
7167
+ };
7168
+ for (const binding of bindings)
7169
+ for (const name of binding.cells.keys()) {
7170
+ const source = binding.cells.get(name);
7171
+ if (["pinx", "piny"].includes(name) && source?.kind === "instance" && movePins.has(source.node))
7172
+ continue;
7173
+ inspect2(binding, name);
7174
+ }
7175
+ return movePins;
7176
+ }
7177
+
6560
7178
  // src/visio/edit-scope.ts
6561
7179
  var admitted2 = (node) => node.namespaceURI === VISIO_NS || node.namespaceURI === VISIO_LEGACY_NS;
6562
7180
  function cells2(sheet) {
@@ -6639,31 +7257,10 @@ async function assertGeometryPackageScope(pkg, pagePaths, commands, check, roots
6639
7257
  let documentRoot;
6640
7258
  for (const path of pkg.paths()) {
6641
7259
  if (!/^visio\/.*\.xml$/i.test(path) || pagePaths.has(path)) continue;
6642
- if (/^visio\/masters\//i.test(path) && !hasMasterInstances) continue;
7260
+ if (/^visio\/masters\//i.test(path)) continue;
6643
7261
  const root = await pkg.readXml(path);
6644
7262
  const masterScope = /^visio\/masters\//i.test(path) || admitted2(root) && ["MasterContents", "Masters"].includes(root.localName);
6645
- if (masterScope) {
6646
- if (hasMasterInstances)
6647
- for (const node of [root, ...Array.from(root.getElementsByTagName("*"))]) {
6648
- check();
6649
- if (!admitted2(node)) continue;
6650
- const source = executableCellFormula(attribute2(node, "F"));
6651
- if (!source || inertDoubleClickFormula(attribute2(node, "N") ?? "", source)) continue;
6652
- try {
6653
- if (analyzeVisioFormula(source).dynamic)
6654
- fail(
6655
- "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
6656
- "Used master formulas have unknown dynamic dependencies."
6657
- );
6658
- } catch (error) {
6659
- fail(
6660
- "EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY",
6661
- `Cannot prove used master formula independence: ${error instanceof Error ? error.message : "invalid formula"}`
6662
- );
6663
- }
6664
- }
6665
- continue;
6666
- }
7263
+ if (masterScope) continue;
6667
7264
  if (admitted2(root) && root.localName === "VisioDocument") {
6668
7265
  if (documentRoot)
6669
7266
  fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Multiple document scopes are ambiguous.");
@@ -6695,7 +7292,24 @@ async function assertGeometryPackageScope(pkg, pagePaths, commands, check, roots
6695
7292
  });
6696
7293
  }
6697
7294
  }
6698
- if (!documentRoot) return;
7295
+ let movePins = /* @__PURE__ */ new Set();
7296
+ if (hasMasterInstances) {
7297
+ for (const command2 of commands) {
7298
+ const root = roots.get(command2.pageId);
7299
+ if (!root) continue;
7300
+ const target = Array.from(root.getElementsByTagNameNS(root.namespaceURI, "Shape")).find(
7301
+ (shape) => attribute2(shape, "ID") === command2.shapeId
7302
+ );
7303
+ if (target?.hasAttribute("MasterShape") && !target.hasAttribute("Master"))
7304
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "Editing master-linked shapes is unsupported.");
7305
+ if (target?.hasAttribute("Master") && (command2.type !== "move-shape" || !["PinX", "PinY", "Width", "Height", "LocPinX", "LocPinY"].every(
7306
+ (name) => children(target, "Cell").some((node) => attribute2(node, "N") === name)
7307
+ )))
7308
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "Master moves require complete local transform caches.");
7309
+ }
7310
+ movePins = await assertVisioMasterIndependence(pkg, roots, commands, check);
7311
+ }
7312
+ if (!documentRoot) return movePins;
6699
7313
  const styles = /* @__PURE__ */ new Map();
6700
7314
  for (const container of children(documentRoot, "StyleSheets"))
6701
7315
  for (const style of children(container, "StyleSheet")) {
@@ -6760,6 +7374,7 @@ async function assertGeometryPackageScope(pkg, pagePaths, commands, check, roots
6760
7374
  }
6761
7375
  }
6762
7376
  }
7377
+ return movePins;
6763
7378
  }
6764
7379
 
6765
7380
  // src/visio/edit.ts
@@ -6787,12 +7402,13 @@ async function editVsdx(input, edits, options = {}) {
6787
7402
  const roots = /* @__PURE__ */ new Map();
6788
7403
  const geometry = commands.some((command2) => command2.type !== "replace-plain-text");
6789
7404
  let document;
7405
+ let masterMovePins = /* @__PURE__ */ new Set();
6790
7406
  if (geometry) {
6791
7407
  for (const [pageId, path2] of pages) {
6792
7408
  const sourceRoot = await visioXml(pkg, path2, "PageContents");
6793
7409
  roots.set(pageId, sourceRoot.ownerDocument.cloneNode(true).documentElement);
6794
7410
  }
6795
- await assertGeometryPackageScope(
7411
+ masterMovePins = await assertGeometryPackageScope(
6796
7412
  pkg,
6797
7413
  new Set(pages.values()),
6798
7414
  commands.filter((command2) => command2.type !== "replace-plain-text"),
@@ -6819,7 +7435,7 @@ async function editVsdx(input, edits, options = {}) {
6819
7435
  textChanged = true;
6820
7436
  }
6821
7437
  } else {
6822
- for (const pageId of applyGeometryEdit(roots, document, command2, check))
7438
+ for (const pageId of applyGeometryEdit(roots, document, command2, check, masterMovePins))
6823
7439
  dirty.set(pages.get(pageId), roots.get(pageId));
6824
7440
  }
6825
7441
  }