ooxml-core 1.8.4 → 1.10.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 (347) hide show
  1. package/dist/PptxHandler-5UURGJEV.mjs +2 -0
  2. package/dist/{PptxHandler-BL4B7CZO.mjs → PptxHandler-ADEFY476.mjs} +2 -2
  3. package/dist/PptxHandler-U5XB2HUE.cjs +11 -0
  4. package/dist/automation/index.cjs +7239 -4037
  5. package/dist/automation/index.mjs +7239 -4037
  6. package/dist/chunk-3N6XMMTT.cjs +87913 -0
  7. package/dist/{chunk-TTPZITQN.mjs → chunk-5NVJN4E6.mjs} +30 -2
  8. package/dist/{chunk-ZAP5WLEN.mjs → chunk-A6P7G3UK.mjs} +1 -1
  9. package/dist/{chunk-CPKNMQLX.cjs → chunk-AWIDASUW.cjs} +25 -2
  10. package/dist/{chunk-SVQZXP3F.mjs → chunk-CBNKBVX5.mjs} +25 -2
  11. package/dist/{chunk-GAGSCAR3.mjs → chunk-CCHYFCPD.mjs} +1199 -348
  12. package/dist/chunk-R6KSBNKX.mjs +44133 -0
  13. package/dist/chunk-S6DOCMQC.cjs +44451 -0
  14. package/dist/{chunk-Z7IQR4S4.mjs → chunk-WUE5ZHU3.mjs} +269 -21
  15. package/dist/chunk-ZE53K7DH.mjs +87907 -0
  16. package/dist/{chunk-NIHPA63A.mjs → chunk-ZOUGMAZG.mjs} +54 -37
  17. package/dist/docx/block-parser.d.ts.map +1 -1
  18. package/dist/docx/cell-blocks.d.ts +4 -0
  19. package/dist/docx/cell-blocks.d.ts.map +1 -0
  20. package/dist/docx/document-paragraphs.d.ts.map +1 -1
  21. package/dist/docx/document-parts.d.ts +2 -0
  22. package/dist/docx/document-parts.d.ts.map +1 -1
  23. package/dist/docx/embedded.cjs +189 -20
  24. package/dist/docx/embedded.mjs +189 -20
  25. package/dist/docx/index.cjs +219 -24
  26. package/dist/docx/index.mjs +219 -24
  27. package/dist/docx/layout/adapt-table.d.ts +2 -2
  28. package/dist/docx/layout/adapt-table.d.ts.map +1 -1
  29. package/dist/docx/layout/adapter.d.ts.map +1 -1
  30. package/dist/docx/layout/flow-paragraph.d.ts +5 -0
  31. package/dist/docx/layout/flow-paragraph.d.ts.map +1 -1
  32. package/dist/docx/layout/flow-table.d.ts +2 -1
  33. package/dist/docx/layout/flow-table.d.ts.map +1 -1
  34. package/dist/docx/layout/footnote-columns.d.ts +22 -0
  35. package/dist/docx/layout/footnote-columns.d.ts.map +1 -0
  36. package/dist/docx/layout/footnote-flow.d.ts +27 -0
  37. package/dist/docx/layout/footnote-flow.d.ts.map +1 -0
  38. package/dist/docx/layout/footnote-split.d.ts +7 -0
  39. package/dist/docx/layout/footnote-split.d.ts.map +1 -0
  40. package/dist/docx/layout/index.cjs +1528 -119
  41. package/dist/docx/layout/index.mjs +1528 -120
  42. package/dist/docx/layout/input.d.ts +17 -1
  43. package/dist/docx/layout/input.d.ts.map +1 -1
  44. package/dist/docx/layout/legacy-footnote-flow.d.ts +18 -0
  45. package/dist/docx/layout/legacy-footnote-flow.d.ts.map +1 -0
  46. package/dist/docx/layout/line-metrics.d.ts.map +1 -1
  47. package/dist/docx/layout/nested-frame-profile.d.ts +9 -0
  48. package/dist/docx/layout/nested-frame-profile.d.ts.map +1 -0
  49. package/dist/docx/layout/page-cursor.d.ts +15 -8
  50. package/dist/docx/layout/page-cursor.d.ts.map +1 -1
  51. package/dist/docx/layout/page-flow.d.ts.map +1 -1
  52. package/dist/docx/layout/paragraph-layout.d.ts.map +1 -1
  53. package/dist/docx/layout/paragraph-tokens.d.ts +2 -0
  54. package/dist/docx/layout/paragraph-tokens.d.ts.map +1 -1
  55. package/dist/docx/layout/reference-footnotes.d.ts +7 -0
  56. package/dist/docx/layout/reference-footnotes.d.ts.map +1 -0
  57. package/dist/docx/layout/result.d.ts +44 -0
  58. package/dist/docx/layout/result.d.ts.map +1 -1
  59. package/dist/docx/layout/section-flow.d.ts +2 -0
  60. package/dist/docx/layout/section-flow.d.ts.map +1 -1
  61. package/dist/docx/layout/table-border-layout.d.ts +16 -0
  62. package/dist/docx/layout/table-border-layout.d.ts.map +1 -0
  63. package/dist/docx/layout/table-cell-layout.d.ts +12 -0
  64. package/dist/docx/layout/table-cell-layout.d.ts.map +1 -0
  65. package/dist/docx/layout/table-content.d.ts +4 -0
  66. package/dist/docx/layout/table-content.d.ts.map +1 -0
  67. package/dist/docx/layout/table-footnotes.d.ts +32 -0
  68. package/dist/docx/layout/table-footnotes.d.ts.map +1 -0
  69. package/dist/docx/layout/table-frames.d.ts +4 -0
  70. package/dist/docx/layout/table-frames.d.ts.map +1 -0
  71. package/dist/docx/layout/table-layout.d.ts +16 -5
  72. package/dist/docx/layout/table-layout.d.ts.map +1 -1
  73. package/dist/docx/layout/table-note-completion.d.ts +5 -0
  74. package/dist/docx/layout/table-note-completion.d.ts.map +1 -0
  75. package/dist/docx/layout/table-note-stories.d.ts +6 -0
  76. package/dist/docx/layout/table-note-stories.d.ts.map +1 -0
  77. package/dist/docx/load/index.cjs +194 -25
  78. package/dist/docx/load/index.mjs +194 -25
  79. package/dist/docx/model-run.d.ts +2 -0
  80. package/dist/docx/model-run.d.ts.map +1 -1
  81. package/dist/docx/model.d.ts +7 -0
  82. package/dist/docx/model.d.ts.map +1 -1
  83. package/dist/docx/notes.d.ts +5 -0
  84. package/dist/docx/notes.d.ts.map +1 -1
  85. package/dist/docx/parse-table.d.ts.map +1 -1
  86. package/dist/docx/parse.d.ts.map +1 -1
  87. package/dist/docx/save.d.ts.map +1 -1
  88. package/dist/docx/section-model.d.ts +2 -0
  89. package/dist/docx/section-model.d.ts.map +1 -1
  90. package/dist/docx/sections.d.ts.map +1 -1
  91. package/dist/docx/settings.d.ts +2 -0
  92. package/dist/docx/settings.d.ts.map +1 -1
  93. package/dist/docx/table-model.d.ts +3 -1
  94. package/dist/docx/table-model.d.ts.map +1 -1
  95. package/dist/docx/ui/index.cjs +55 -0
  96. package/dist/docx/ui/index.d.ts +1 -0
  97. package/dist/docx/ui/index.d.ts.map +1 -1
  98. package/dist/docx/ui/index.mjs +55 -1
  99. package/dist/docx/ui/table-structure-guard.d.ts +4 -0
  100. package/dist/docx/ui/table-structure-guard.d.ts.map +1 -0
  101. package/dist/docx/write-footnote-columns.d.ts +3 -0
  102. package/dist/docx/write-footnote-columns.d.ts.map +1 -0
  103. package/dist/docx/write-notes.d.ts.map +1 -1
  104. package/dist/docx/write-run.d.ts.map +1 -1
  105. package/dist/docx/write-sections.d.ts.map +1 -1
  106. package/dist/index.cjs +8 -5
  107. package/dist/index.mjs +8 -5
  108. package/dist/opc/clone-part-graph.d.ts +4 -0
  109. package/dist/opc/clone-part-graph.d.ts.map +1 -1
  110. package/dist/opc/index.cjs +8 -5
  111. package/dist/opc/index.mjs +8 -5
  112. package/dist/pptx/automation/index.cjs +1156 -389
  113. package/dist/pptx/automation/index.d.ts +4 -4
  114. package/dist/pptx/automation/index.mjs +5 -5
  115. package/dist/pptx/chunks/{index-CKIUurnd.d.ts → index-Cuxtr76Y.d.ts} +29 -10
  116. package/dist/pptx/chunks/index-Cuxtr76Y.d.ts.map +1 -0
  117. package/dist/pptx/chunks/{index-Cn-GzYGp.d.ts → index-DUCGeZh7.d.ts} +94 -5
  118. package/dist/pptx/chunks/index-DUCGeZh7.d.ts.map +1 -0
  119. package/dist/pptx/chunks/{smart-art-Q2kZQtHh.d.ts → smart-art-D-sXa_Nb.d.ts} +11 -1
  120. package/dist/pptx/chunks/smart-art-D-sXa_Nb.d.ts.map +1 -0
  121. package/dist/pptx/chunks/{text-operations-BHfAm5K9.d.ts → text-operations-BqHmLaLA.d.ts} +54 -13
  122. package/dist/pptx/chunks/text-operations-BqHmLaLA.d.ts.map +1 -0
  123. package/dist/pptx/cli/index.cjs +1157 -395
  124. package/dist/pptx/cli/index.d.ts +1 -1
  125. package/dist/pptx/cli/index.mjs +4 -4
  126. package/dist/pptx/converter/index.cjs +54 -36
  127. package/dist/pptx/converter/index.d.ts +1 -1
  128. package/dist/pptx/converter/index.mjs +2 -2
  129. package/dist/pptx/editor/render/collaboration-live-patch-target.cjs +2 -2
  130. package/dist/pptx/editor/render/collaboration-live-patch-target.mjs +1 -1
  131. package/dist/pptx/editor/render/find-replace.cjs +416 -45
  132. package/dist/pptx/editor/render/find-replace.d.ts +35 -4
  133. package/dist/pptx/editor/render/find-replace.d.ts.map +1 -1
  134. package/dist/pptx/editor/render/find-replace.mjs +416 -46
  135. package/dist/pptx/editor/render/remap-text.cjs +2 -2
  136. package/dist/pptx/editor/render/remap-text.d.ts.map +1 -1
  137. package/dist/pptx/editor/render/remap-text.mjs +1 -1
  138. package/dist/pptx/editor/render/slide-operations.cjs +87 -0
  139. package/dist/pptx/editor/render/slide-operations.d.ts +17 -1
  140. package/dist/pptx/editor/render/slide-operations.d.ts.map +1 -1
  141. package/dist/pptx/editor/render/slide-operations.mjs +83 -1
  142. package/dist/pptx/editor/render/slide-search.cjs +6 -10
  143. package/dist/pptx/editor/render/slide-search.d.ts +1 -1
  144. package/dist/pptx/editor/render/slide-search.mjs +6 -10
  145. package/dist/pptx/editor/render/template-editing.d.ts +1 -1
  146. package/dist/pptx/editor/render/template-editing.d.ts.map +1 -1
  147. package/dist/pptx/index.cjs +1651 -419
  148. package/dist/pptx/index.d.ts +5 -5
  149. package/dist/pptx/index.mjs +5 -5
  150. package/dist/pptx/smartart-layouts/index.d.ts +1 -1
  151. package/dist/teams/index.cjs +965 -34
  152. package/dist/teams/index.mjs +965 -34
  153. package/dist/visio/accessibility.d.ts +10 -0
  154. package/dist/visio/accessibility.d.ts.map +1 -0
  155. package/dist/visio/cell-formula.d.ts +2 -0
  156. package/dist/visio/cell-formula.d.ts.map +1 -1
  157. package/dist/visio/connector-curve-aligned.d.ts +5 -0
  158. package/dist/visio/connector-curve-aligned.d.ts.map +1 -0
  159. package/dist/visio/connector-curve-spans.d.ts +14 -0
  160. package/dist/visio/connector-curve-spans.d.ts.map +1 -0
  161. package/dist/visio/connector-jumps.d.ts +5 -0
  162. package/dist/visio/connector-jumps.d.ts.map +1 -0
  163. package/dist/visio/connector-route-walk.d.ts +2 -1
  164. package/dist/visio/connector-route-walk.d.ts.map +1 -1
  165. package/dist/visio/date-cache.d.ts +3 -0
  166. package/dist/visio/date-cache.d.ts.map +1 -0
  167. package/dist/visio/edit-alt-text-scope.d.ts +5 -0
  168. package/dist/visio/edit-alt-text-scope.d.ts.map +1 -0
  169. package/dist/visio/edit-alt-text.d.ts +3 -0
  170. package/dist/visio/edit-alt-text.d.ts.map +1 -0
  171. package/dist/visio/edit-commands.d.ts +7 -2
  172. package/dist/visio/edit-commands.d.ts.map +1 -1
  173. package/dist/visio/edit-formatting-commands.d.ts +5 -0
  174. package/dist/visio/edit-formatting-commands.d.ts.map +1 -1
  175. package/dist/visio/edit-formatting-paint.d.ts.map +1 -1
  176. package/dist/visio/edit-formatting-scope.d.ts.map +1 -1
  177. package/dist/visio/edit-line-jump-cache.d.ts +4 -0
  178. package/dist/visio/edit-line-jump-cache.d.ts.map +1 -0
  179. package/dist/visio/edit-master-index.d.ts.map +1 -1
  180. package/dist/visio/edit-metadata-commands.d.ts +10 -2
  181. package/dist/visio/edit-metadata-commands.d.ts.map +1 -1
  182. package/dist/visio/edit-metadata.d.ts +3 -1
  183. package/dist/visio/edit-metadata.d.ts.map +1 -1
  184. package/dist/visio/edit-page-alt-text.d.ts +4 -0
  185. package/dist/visio/edit-page-alt-text.d.ts.map +1 -0
  186. package/dist/visio/edit-page-layout.d.ts.map +1 -1
  187. package/dist/visio/edit-page-rename.d.ts.map +1 -1
  188. package/dist/visio/edit-page-setup-commands.d.ts +7 -1
  189. package/dist/visio/edit-page-setup-commands.d.ts.map +1 -1
  190. package/dist/visio/edit-page-size.d.ts.map +1 -1
  191. package/dist/visio/edit-pages.d.ts.map +1 -1
  192. package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
  193. package/dist/visio/edit-scope.d.ts.map +1 -1
  194. package/dist/visio/edit-shape-create.d.ts.map +1 -1
  195. package/dist/visio/edit-stencil-connector-write.d.ts.map +1 -1
  196. package/dist/visio/edit-style-admission.d.ts.map +1 -1
  197. package/dist/visio/edit-text-field.d.ts.map +1 -1
  198. package/dist/visio/edit-text.d.ts.map +1 -1
  199. package/dist/visio/edit.d.ts +1 -1
  200. package/dist/visio/edit.d.ts.map +1 -1
  201. package/dist/visio/index.cjs +1215 -248
  202. package/dist/visio/index.d.ts +2 -1
  203. package/dist/visio/index.d.ts.map +1 -1
  204. package/dist/visio/index.mjs +1215 -249
  205. package/dist/visio/line-jumps.d.ts +1 -5
  206. package/dist/visio/line-jumps.d.ts.map +1 -1
  207. package/dist/visio/model.d.ts +13 -0
  208. package/dist/visio/model.d.ts.map +1 -1
  209. package/dist/visio/page-layout.d.ts +11 -2
  210. package/dist/visio/page-layout.d.ts.map +1 -1
  211. package/dist/visio/parser.d.ts.map +1 -1
  212. package/dist/visio/shape-metadata.d.ts +6 -0
  213. package/dist/visio/shape-metadata.d.ts.map +1 -1
  214. package/dist/visio/shapes.d.ts.map +1 -1
  215. package/dist/visio/text-field-case.d.ts +2 -0
  216. package/dist/visio/text-field-case.d.ts.map +1 -0
  217. package/dist/visio/text-field-display.d.ts.map +1 -1
  218. package/dist/visio/text-field-fraction.d.ts +3 -0
  219. package/dist/visio/text-field-fraction.d.ts.map +1 -0
  220. package/dist/visio/text-field-numeric.d.ts +4 -0
  221. package/dist/visio/text-field-numeric.d.ts.map +1 -0
  222. package/dist/visio/text-field-system-date.d.ts +4 -0
  223. package/dist/visio/text-field-system-date.d.ts.map +1 -0
  224. package/dist/visio/text-fields.d.ts +1 -0
  225. package/dist/visio/text-fields.d.ts.map +1 -1
  226. package/dist/visio/ui/connector-preview.d.ts +1 -1
  227. package/dist/visio/ui/connector-preview.d.ts.map +1 -1
  228. package/dist/visio/ui/data-graphic-rules.d.ts +2 -0
  229. package/dist/visio/ui/data-graphic-rules.d.ts.map +1 -1
  230. package/dist/visio/ui/data-graphics.d.ts +3 -2
  231. package/dist/visio/ui/data-graphics.d.ts.map +1 -1
  232. package/dist/visio/ui/edit-commands.d.ts.map +1 -1
  233. package/dist/visio/ui/index.cjs +19310 -18157
  234. package/dist/visio/ui/index.mjs +19310 -18158
  235. package/dist/visio/ui/scene-details.d.ts.map +1 -1
  236. package/dist/visio/ui/scene-validation.d.ts.map +1 -1
  237. package/dist/visio/ui/snapshot-scene.d.ts +2 -1
  238. package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
  239. package/dist/visio/ui/text-field-catalog.d.ts.map +1 -1
  240. package/dist/visio/xml-attribute-whitespace.d.ts +5 -0
  241. package/dist/visio/xml-attribute-whitespace.d.ts.map +1 -0
  242. package/dist/xlsx/edit/index.d.ts +1 -0
  243. package/dist/xlsx/edit/index.d.ts.map +1 -1
  244. package/dist/xlsx/edit/insert-guard.d.ts.map +1 -1
  245. package/dist/xlsx/edit/merge.d.ts.map +1 -1
  246. package/dist/xlsx/edit/page-breaks.d.ts +5 -0
  247. package/dist/xlsx/edit/page-breaks.d.ts.map +1 -0
  248. package/dist/xlsx/edit/pivots.d.ts +8 -0
  249. package/dist/xlsx/edit/pivots.d.ts.map +1 -0
  250. package/dist/xlsx/edit/print-titles.d.ts +7 -0
  251. package/dist/xlsx/edit/print-titles.d.ts.map +1 -0
  252. package/dist/xlsx/edit/session.d.ts.map +1 -1
  253. package/dist/xlsx/edit/sheets.d.ts.map +1 -1
  254. package/dist/xlsx/edit/shift-formulas.d.ts.map +1 -1
  255. package/dist/xlsx/edit/shift-sheet.d.ts.map +1 -1
  256. package/dist/xlsx/edit/sparkline-ranges.d.ts +11 -0
  257. package/dist/xlsx/edit/sparkline-ranges.d.ts.map +1 -0
  258. package/dist/xlsx/edit/sparkline-xml.d.ts +13 -0
  259. package/dist/xlsx/edit/sparkline-xml.d.ts.map +1 -0
  260. package/dist/xlsx/edit/sparklines.d.ts +16 -0
  261. package/dist/xlsx/edit/sparklines.d.ts.map +1 -0
  262. package/dist/xlsx/edit/table-edits.d.ts.map +1 -1
  263. package/dist/xlsx/edit/tables.d.ts.map +1 -1
  264. package/dist/xlsx/edit/types.d.ts +22 -1
  265. package/dist/xlsx/edit/types.d.ts.map +1 -1
  266. package/dist/xlsx/formula/functions/text-regex.d.ts.map +1 -1
  267. package/dist/xlsx/index.cjs +3638 -1199
  268. package/dist/xlsx/index.d.ts +1 -0
  269. package/dist/xlsx/index.d.ts.map +1 -1
  270. package/dist/xlsx/index.mjs +3619 -1200
  271. package/dist/xlsx/layout/cell-view.d.ts +2 -0
  272. package/dist/xlsx/layout/cell-view.d.ts.map +1 -1
  273. package/dist/xlsx/layout/header-footer.d.ts +58 -0
  274. package/dist/xlsx/layout/header-footer.d.ts.map +1 -0
  275. package/dist/xlsx/layout/index.d.ts +5 -0
  276. package/dist/xlsx/layout/index.d.ts.map +1 -1
  277. package/dist/xlsx/layout/print-breaks.d.ts +11 -0
  278. package/dist/xlsx/layout/print-breaks.d.ts.map +1 -0
  279. package/dist/xlsx/layout/print-layout.d.ts +34 -0
  280. package/dist/xlsx/layout/print-layout.d.ts.map +1 -0
  281. package/dist/xlsx/layout/print-merges.d.ts +18 -0
  282. package/dist/xlsx/layout/print-merges.d.ts.map +1 -0
  283. package/dist/xlsx/layout/print-repeat.d.ts +12 -0
  284. package/dist/xlsx/layout/print-repeat.d.ts.map +1 -0
  285. package/dist/xlsx/layout/print-titles.d.ts +20 -0
  286. package/dist/xlsx/layout/print-titles.d.ts.map +1 -0
  287. package/dist/xlsx/layout/sparkline-data.d.ts.map +1 -1
  288. package/dist/xlsx/layout/sparkline-view.d.ts.map +1 -1
  289. package/dist/xlsx/load/index.cjs +8165 -6945
  290. package/dist/xlsx/load/index.mjs +8165 -6945
  291. package/dist/xlsx/model-pivots.d.ts +67 -0
  292. package/dist/xlsx/model-pivots.d.ts.map +1 -0
  293. package/dist/xlsx/model.d.ts +5 -0
  294. package/dist/xlsx/model.d.ts.map +1 -1
  295. package/dist/xlsx/pivot/admission.d.ts +5 -0
  296. package/dist/xlsx/pivot/admission.d.ts.map +1 -0
  297. package/dist/xlsx/pivot/aggregate.d.ts +21 -0
  298. package/dist/xlsx/pivot/aggregate.d.ts.map +1 -0
  299. package/dist/xlsx/pivot/cache-xml.d.ts +9 -0
  300. package/dist/xlsx/pivot/cache-xml.d.ts.map +1 -0
  301. package/dist/xlsx/pivot/data.d.ts +12 -0
  302. package/dist/xlsx/pivot/data.d.ts.map +1 -0
  303. package/dist/xlsx/pivot/hierarchy-first.d.ts +21 -0
  304. package/dist/xlsx/pivot/hierarchy-first.d.ts.map +1 -0
  305. package/dist/xlsx/pivot/hierarchy.d.ts +5 -0
  306. package/dist/xlsx/pivot/hierarchy.d.ts.map +1 -0
  307. package/dist/xlsx/pivot/index.d.ts +3 -0
  308. package/dist/xlsx/pivot/index.d.ts.map +1 -0
  309. package/dist/xlsx/pivot/measures.d.ts +13 -0
  310. package/dist/xlsx/pivot/measures.d.ts.map +1 -0
  311. package/dist/xlsx/pivot/read.d.ts +5 -0
  312. package/dist/xlsx/pivot/read.d.ts.map +1 -0
  313. package/dist/xlsx/pivot/table-xml.d.ts +5 -0
  314. package/dist/xlsx/pivot/table-xml.d.ts.map +1 -0
  315. package/dist/xlsx/pivot/values-axis.d.ts +9 -0
  316. package/dist/xlsx/pivot/values-axis.d.ts.map +1 -0
  317. package/dist/xlsx/pivot/write.d.ts +11 -0
  318. package/dist/xlsx/pivot/write.d.ts.map +1 -0
  319. package/dist/xlsx/read/load.d.ts.map +1 -1
  320. package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
  321. package/dist/xlsx/ui/commands/i18n/index.d.ts.map +1 -1
  322. package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -1
  323. package/dist/xlsx/ui/commands/i18n/pivots.d.ts +3 -0
  324. package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -0
  325. package/dist/xlsx/ui/commands/i18n/print-layout.d.ts +3 -0
  326. package/dist/xlsx/ui/commands/i18n/print-layout.d.ts.map +1 -0
  327. package/dist/xlsx/ui/commands/i18n/sparklines.d.ts +3 -0
  328. package/dist/xlsx/ui/commands/i18n/sparklines.d.ts.map +1 -0
  329. package/dist/xlsx/ui/commands/i18n/tools.d.ts.map +1 -1
  330. package/dist/xlsx/ui/commands/page-breaks.d.ts +3 -0
  331. package/dist/xlsx/ui/commands/page-breaks.d.ts.map +1 -0
  332. package/dist/xlsx/ui/index.cjs +2421 -288
  333. package/dist/xlsx/ui/index.d.ts +1 -0
  334. package/dist/xlsx/ui/index.d.ts.map +1 -1
  335. package/dist/xlsx/ui/index.mjs +2421 -289
  336. package/dist/xlsx/write/page-setup.d.ts.map +1 -1
  337. package/dist/xlsx/write/save.d.ts.map +1 -1
  338. package/dist/xlsx/write/sheet-parts.d.ts +1 -0
  339. package/dist/xlsx/write/sheet-parts.d.ts.map +1 -1
  340. package/dist/xlsx/write/workbook-part.d.ts +1 -1
  341. package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
  342. package/dist/xlsx/write/worksheet.d.ts.map +1 -1
  343. package/package.json +1 -1
  344. package/dist/pptx/chunks/index-CKIUurnd.d.ts.map +0 -1
  345. package/dist/pptx/chunks/index-Cn-GzYGp.d.ts.map +0 -1
  346. package/dist/pptx/chunks/smart-art-Q2kZQtHh.d.ts.map +0 -1
  347. package/dist/pptx/chunks/text-operations-BHfAm5K9.d.ts.map +0 -1
@@ -1314,15 +1314,16 @@ function inspect(bytes, limits) {
1314
1314
  // visio/edit-metadata-commands.ts
1315
1315
  var VISIO_METADATA_TEXT_LIMIT = 4096;
1316
1316
  var VISIO_PICTURE_MAX_BYTES = VISIO_RASTER_IMAGE_LIMITS.maxImageBytes;
1317
- var isVisioMetadataEdit = (edit) => edit.type === "set-shape-hyperlink" || edit.type === "set-shape-screentip";
1317
+ var isVisioMetadataEdit = (edit) => edit.type === "set-shape-hyperlink" || edit.type === "set-shape-screentip" || edit.type === "set-shape-alt-text";
1318
1318
  var invalidText = /[\u0000-\u0008\u000b\u000c\u000e-\u001f￾￿]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/u;
1319
- function field(value, singleLine2) {
1319
+ function metadataText(value, singleLine2) {
1320
1320
  if (typeof value !== "string" || value.length > VISIO_METADATA_TEXT_LIMIT)
1321
- fail("INVALID_EDIT", "Link and ScreenTip text must be strings within the length limit.");
1322
- if (invalidText.test(value) || /[\r\n\t]/.test(value))
1323
- fail("INVALID_EDIT_TEXT", "Link or ScreenTip text contains invalid characters.");
1321
+ fail("INVALID_EDIT", "Shape metadata text must be strings within the length limit.");
1322
+ if (invalidText.test(value) || singleLine2 && /[\r\n\t]/.test(value))
1323
+ fail("INVALID_EDIT_TEXT", "Shape metadata text contains invalid characters.");
1324
1324
  return value;
1325
1325
  }
1326
+ var field = metadataText;
1326
1327
  function target(edit) {
1327
1328
  if (typeof edit.pageId !== "string" || !edit.pageId || edit.pageId.length > 256 || typeof edit.shapeId !== "string" || !/^[1-9]\d{0,9}$/.test(edit.shapeId) || Number(edit.shapeId) > 4294967295)
1328
1329
  fail("INVALID_EDIT", "Invalid edit shape target.");
@@ -1330,8 +1331,15 @@ function target(edit) {
1330
1331
  }
1331
1332
  function snapshotMetadataEdit(edit) {
1332
1333
  const base2 = target(edit);
1334
+ if (edit.type === "set-shape-alt-text")
1335
+ return {
1336
+ ...base2,
1337
+ type: edit.type,
1338
+ title: field(edit.title, true),
1339
+ description: field(edit.description, false)
1340
+ };
1333
1341
  if (edit.type === "set-shape-screentip")
1334
- return { ...base2, type: edit.type, text: field(edit.text) };
1342
+ return { ...base2, type: edit.type, text: field(edit.text, true) };
1335
1343
  if (edit.row !== void 0 && (typeof edit.row !== "string" || !/^[A-Za-z_]\w{0,63}$/.test(edit.row)))
1336
1344
  fail("INVALID_EDIT", "Hyperlink row names must be ShapeSheet row names.");
1337
1345
  const link = edit.hyperlink;
@@ -1341,9 +1349,9 @@ function snapshotMetadataEdit(edit) {
1341
1349
  }
1342
1350
  if (!link || typeof link !== "object") fail("INVALID_EDIT", "Invalid hyperlink fields.");
1343
1351
  const hyperlink2 = {
1344
- address: field(link.address).trim(),
1345
- subAddress: field(link.subAddress).trim(),
1346
- description: field(link.description)
1352
+ address: field(link.address, true).trim(),
1353
+ subAddress: field(link.subAddress, true).trim(),
1354
+ description: field(link.description, true)
1347
1355
  };
1348
1356
  if (!hyperlink2.address && !hyperlink2.subAddress)
1349
1357
  fail("INVALID_EDIT", "A hyperlink needs an address or a page target.");
@@ -1579,6 +1587,20 @@ function writeEditedPackage(parts, maxBytes, deadline, check) {
1579
1587
  });
1580
1588
  }
1581
1589
 
1590
+ // visio/xml-attribute-whitespace.ts
1591
+ function preserveAttributeWhitespace(xml) {
1592
+ return xml.replace(
1593
+ /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<\/?[^!?\s>][^"'>]*(?:(?:"[^"]*"|'[^']*')[^"'>]*)*>/g,
1594
+ (token) => {
1595
+ if (token.startsWith("<!") || token.startsWith("<?")) return token;
1596
+ return token.replace(
1597
+ /"[^"]*"|'[^']*'/g,
1598
+ (value) => value.replace(/[\t\r\n]/g, (character) => `&#${character.charCodeAt(0)};`)
1599
+ );
1600
+ }
1601
+ );
1602
+ }
1603
+
1582
1604
  // visio/cell-formula.ts
1583
1605
  function executableCellFormula(source) {
1584
1606
  return !source || source === "No Formula" || source === "Inh" ? void 0 : source;
@@ -1586,6 +1608,7 @@ function executableCellFormula(source) {
1586
1608
  function inertDoubleClickFormula(cell, source) {
1587
1609
  return cell === "EventDblClick" && /^\s*=?\s*(OPENTEXTWIN|DEFAULTEVENT)\(\s*\)\s*$/i.test(source);
1588
1610
  }
1611
+ var shapeDataFormulaSection = (name3) => name3 === "Property" ? "Prop" : name3;
1589
1612
 
1590
1613
  // visio/formula-theme.ts
1591
1614
  var themeInputs = [
@@ -2975,6 +2998,19 @@ function createBox(root2, document, edit) {
2975
2998
  value,
2976
2999
  name3 === "LocPinX" ? "Width*0.5" : name3 === "LocPinY" ? "Height*0.5" : void 0
2977
3000
  );
3001
+ if (edit.followShapeId !== void 0) {
3002
+ const owner = admitted(root2, edit.followShapeId);
3003
+ const local = cells(owner);
3004
+ if (isLineSheet(local))
3005
+ fail("UNSUPPORTED_GEOMETRY_EDIT", "Position followers require a 2D owner.");
3006
+ for (const [name3, value] of [
3007
+ ["PinX", edit.x],
3008
+ ["PinY", edit.y]
3009
+ ]) {
3010
+ const offset = value - numeric(local.get(name3));
3011
+ setCell(shape, name3, value, `Sheet.${edit.followShapeId}!${name3}+(${offset}IN)`);
3012
+ }
3013
+ }
2978
3014
  return shape;
2979
3015
  }
2980
3016
  function createRectangle(root2, document, edit) {
@@ -3558,7 +3594,7 @@ function indexCells(roots, options) {
3558
3594
  for (const node2 of children2(sheet.node, "Cell"))
3559
3595
  addNode(node2, attribute2(node2, "N") ?? "", false, false, glue);
3560
3596
  for (const section3 of children2(sheet.node, "Section")) {
3561
- const name3 = attribute2(section3, "N") ?? "";
3597
+ const name3 = shapeDataFormulaSection(attribute2(section3, "N") ?? "");
3562
3598
  const prefix2 = name3 === "Geometry" ? `Geometry${Number(attribute2(section3, "IX") ?? "0") + 1}` : name3;
3563
3599
  const deleted4 = ["1", "true"].includes(attribute2(section3, "Del") ?? "");
3564
3600
  for (const node2 of children2(section3, "Cell"))
@@ -4154,6 +4190,7 @@ function effectiveShapeCell(shape, document, name3, category, rows) {
4154
4190
  if (delegatedLocal && !(category === "TextStyle" && cellName && ["Character", "Paragraph"].includes(section3)))
4155
4191
  fail("EDIT_PROTECTED_CELL", "Inherited formatting cells cannot be overwritten.");
4156
4192
  if (local && !cellName) return local;
4193
+ if (/^ConLineJump(?:Code|Style|DirX|DirY)$/.test(name3)) return void 0;
4157
4194
  if (cellName) {
4158
4195
  const sources = rows?.source ?? effectiveFormattingRows(shape, document, section3);
4159
4196
  const cells4 = sources.get(index) ?? sources.get("0");
@@ -4394,14 +4431,9 @@ function serializeEditedXml(root2, limits, check) {
4394
4431
  const node2 = pending.pop();
4395
4432
  if ((node2.nodeType === 3 || node2.nodeType === 4) && node2.nodeValue?.includes("\r"))
4396
4433
  fail("UNSUPPORTED_XML_EDIT", "Carriage-return text cannot be preserved by this writer.");
4397
- if (node2.nodeType === 1) {
4398
- for (const attr2 of Array.from(node2.attributes))
4399
- if (/[\t\r\n]/.test(attr2.value))
4400
- fail("UNSUPPORTED_XML_EDIT", "Attribute whitespace cannot be preserved by this writer.");
4401
- }
4402
4434
  for (const child3 of Array.from(node2.childNodes)) pending.push(child3);
4403
4435
  }
4404
- let xml = buildXml(root2.ownerDocument);
4436
+ let xml = preserveAttributeWhitespace(buildXml(root2.ownerDocument));
4405
4437
  xml = xml.replace(
4406
4438
  /^<\?xml\s[^?]*\?>/,
4407
4439
  (declaration) => declaration.replace(/encoding\s*=\s*(['"])[^'"]*\1/, 'encoding="UTF-8"')
@@ -7269,10 +7301,10 @@ function orderedColorTransforms(channels, transforms) {
7269
7301
  else if (name3 === "inv") [r, g, b] = [255 - r, 255 - g, 255 - b];
7270
7302
  else if (name3 === "gray") r = g = b = 0.299 * r + 0.587 * g + 0.114 * b;
7271
7303
  else if ((name3 === "shade" || name3 === "tint") && fraction !== void 0) {
7272
- const mix2 = (channel) => linearToSrgb255(
7304
+ const mix3 = (channel) => linearToSrgb255(
7273
7305
  name3 === "shade" ? srgb255ToLinear(channel) * fraction : 1 - (1 - srgb255ToLinear(channel)) * fraction
7274
7306
  );
7275
- [r, g, b] = [mix2(r), mix2(g), mix2(b)];
7307
+ [r, g, b] = [mix3(r), mix3(g), mix3(b)];
7276
7308
  } else {
7277
7309
  const hsl = rgbToHsl(r, g, b);
7278
7310
  if (name3 === "comp") hsl.h = wrap(hsl.h + 180);
@@ -8625,6 +8657,230 @@ function characterExtras(cells4, report) {
8625
8657
  };
8626
8658
  }
8627
8659
 
8660
+ // visio/text-field-case.ts
8661
+ var LOWER = [
8662
+ [65, 90, 1, 32],
8663
+ [192, 214, 1, 32],
8664
+ [216, 222, 1, 32],
8665
+ [256, 302, 2, 1],
8666
+ [304, 304, 2, -199],
8667
+ [306, 310, 2, 1],
8668
+ [313, 327, 2, 1],
8669
+ [330, 374, 2, 1],
8670
+ [376, 376, 1, -121],
8671
+ [377, 381, 2, 1],
8672
+ [385, 385, 1, 210],
8673
+ [386, 388, 2, 1],
8674
+ [390, 390, 1, 206],
8675
+ [391, 391, 2, 1],
8676
+ [393, 394, 1, 205],
8677
+ [395, 395, 1, 1],
8678
+ [398, 398, 1, 79],
8679
+ [399, 399, 1, 202],
8680
+ [400, 400, 1, 203],
8681
+ [401, 401, 2, 1],
8682
+ [403, 403, 1, 205],
8683
+ [404, 404, 2, 207],
8684
+ [406, 406, 1, 211],
8685
+ [407, 407, 1, 209],
8686
+ [408, 408, 1, 1],
8687
+ [412, 412, 1, 211],
8688
+ [413, 413, 2, 213],
8689
+ [415, 415, 1, 214],
8690
+ [416, 420, 2, 1],
8691
+ [422, 422, 1, 218],
8692
+ [423, 423, 2, 1],
8693
+ [425, 425, 1, 218],
8694
+ [428, 428, 2, 1],
8695
+ [430, 430, 1, 218],
8696
+ [431, 431, 2, 1],
8697
+ [433, 434, 1, 217],
8698
+ [435, 437, 2, 1],
8699
+ [439, 439, 1, 219],
8700
+ [440, 440, 1, 1],
8701
+ [444, 444, 1, 1],
8702
+ [452, 452, 1, 2],
8703
+ [453, 453, 2, 1],
8704
+ [455, 455, 1, 2],
8705
+ [456, 456, 2, 1],
8706
+ [458, 458, 1, 2],
8707
+ [459, 475, 2, 1],
8708
+ [478, 494, 2, 1],
8709
+ [497, 497, 1, 2],
8710
+ [498, 500, 2, 1],
8711
+ [502, 502, 1, -97],
8712
+ [503, 503, 1, -56],
8713
+ [504, 542, 2, 1],
8714
+ [544, 544, 2, -130],
8715
+ [546, 562, 2, 1],
8716
+ [570, 570, 1, 10795],
8717
+ [571, 571, 2, 1],
8718
+ [573, 573, 1, -163],
8719
+ [574, 574, 1, 10792],
8720
+ [577, 577, 2, 1],
8721
+ [579, 579, 1, -195],
8722
+ [580, 580, 1, 69],
8723
+ [581, 581, 1, 71],
8724
+ [582, 590, 2, 1],
8725
+ [902, 902, 2, 38],
8726
+ [904, 906, 1, 37],
8727
+ [908, 908, 2, 64],
8728
+ [910, 911, 1, 63],
8729
+ [913, 929, 1, 32],
8730
+ [931, 939, 1, 32],
8731
+ [986, 1006, 2, 1],
8732
+ [1024, 1039, 1, 80],
8733
+ [1040, 1071, 1, 32],
8734
+ [1120, 1152, 2, 1],
8735
+ [1162, 1214, 2, 1],
8736
+ [1216, 1216, 1, 15],
8737
+ [1217, 1229, 2, 1],
8738
+ [1232, 1298, 2, 1],
8739
+ [1329, 1366, 1, 48],
8740
+ [4256, 4293, 1, 48],
8741
+ [7680, 7828, 2, 1],
8742
+ [7840, 7928, 2, 1],
8743
+ [8498, 8498, 1, 28],
8744
+ [8579, 8579, 1, 1],
8745
+ [9398, 9423, 1, 26],
8746
+ [11360, 11360, 2, 1],
8747
+ [11362, 11362, 1, -10743],
8748
+ [11363, 11363, 1, -3814],
8749
+ [11364, 11364, 1, -10727],
8750
+ [11367, 11371, 2, 1],
8751
+ [11381, 11381, 1, 1],
8752
+ [65313, 65338, 1, 32],
8753
+ [66560, 66599, 1, 40],
8754
+ [66736, 66771, 1, 40],
8755
+ [68736, 68786, 1, 64],
8756
+ [71840, 71871, 1, 32],
8757
+ [93760, 93791, 1, 32],
8758
+ [125184, 125217, 1, 34]
8759
+ ];
8760
+ var UPPER = [
8761
+ [97, 122, 1, -32],
8762
+ [224, 246, 1, -32],
8763
+ [248, 254, 1, -32],
8764
+ [255, 255, 2, 121],
8765
+ [257, 303, 2, -1],
8766
+ [305, 305, 2, -232],
8767
+ [307, 311, 2, -1],
8768
+ [314, 328, 2, -1],
8769
+ [331, 375, 2, -1],
8770
+ [378, 382, 2, -1],
8771
+ [384, 384, 1, 195],
8772
+ [387, 389, 2, -1],
8773
+ [392, 392, 1, -1],
8774
+ [396, 396, 1, -1],
8775
+ [402, 402, 1, -1],
8776
+ [405, 405, 1, 97],
8777
+ [409, 409, 1, -1],
8778
+ [410, 410, 1, 163],
8779
+ [414, 414, 1, 130],
8780
+ [417, 421, 2, -1],
8781
+ [424, 424, 1, -1],
8782
+ [429, 429, 1, -1],
8783
+ [432, 432, 1, -1],
8784
+ [436, 438, 2, -1],
8785
+ [441, 441, 1, -1],
8786
+ [445, 445, 2, -1],
8787
+ [447, 447, 1, 56],
8788
+ [453, 453, 1, -1],
8789
+ [454, 454, 2, -2],
8790
+ [456, 456, 1, -1],
8791
+ [457, 457, 2, -2],
8792
+ [459, 459, 1, -1],
8793
+ [460, 460, 2, -2],
8794
+ [462, 476, 2, -1],
8795
+ [477, 477, 2, -79],
8796
+ [479, 495, 2, -1],
8797
+ [498, 498, 1, -1],
8798
+ [499, 499, 2, -2],
8799
+ [501, 501, 1, -1],
8800
+ [505, 543, 2, -1],
8801
+ [547, 563, 2, -1],
8802
+ [572, 572, 1, -1],
8803
+ [578, 578, 1, -1],
8804
+ [583, 591, 2, -1],
8805
+ [595, 595, 1, -210],
8806
+ [596, 596, 2, -206],
8807
+ [598, 599, 1, -205],
8808
+ [601, 601, 2, -202],
8809
+ [603, 603, 1, -203],
8810
+ [608, 608, 1, -205],
8811
+ [611, 611, 1, -207],
8812
+ [616, 616, 1, -209],
8813
+ [617, 617, 2, -211],
8814
+ [619, 619, 1, 10743],
8815
+ [623, 623, 1, -211],
8816
+ [626, 626, 1, -213],
8817
+ [629, 629, 1, -214],
8818
+ [637, 637, 1, 10727],
8819
+ [640, 640, 1, -218],
8820
+ [643, 643, 1, -218],
8821
+ [648, 648, 1, -218],
8822
+ [649, 649, 1, -69],
8823
+ [650, 651, 1, -217],
8824
+ [652, 652, 1, -71],
8825
+ [658, 658, 1, -219],
8826
+ [912, 912, 1, 26],
8827
+ [940, 940, 1, -38],
8828
+ [941, 943, 1, -37],
8829
+ [944, 944, 1, -5],
8830
+ [945, 961, 1, -32],
8831
+ [962, 962, 1, -31],
8832
+ [963, 971, 1, -32],
8833
+ [972, 972, 1, -64],
8834
+ [973, 974, 1, -63],
8835
+ [976, 976, 1, -62],
8836
+ [977, 977, 1, -57],
8837
+ [981, 981, 1, -47],
8838
+ [982, 982, 1, -54],
8839
+ [987, 1007, 2, -1],
8840
+ [1008, 1008, 1, -86],
8841
+ [1009, 1009, 1, -80],
8842
+ [1072, 1103, 1, -32],
8843
+ [1104, 1119, 1, -80],
8844
+ [1121, 1153, 2, -1],
8845
+ [1163, 1215, 2, -1],
8846
+ [1218, 1230, 2, -1],
8847
+ [1231, 1231, 2, -15],
8848
+ [1233, 1299, 2, -1],
8849
+ [1377, 1414, 1, -48],
8850
+ [7549, 7549, 1, 3814],
8851
+ [7681, 7829, 2, -1],
8852
+ [7841, 7929, 2, -1],
8853
+ [8526, 8526, 1, -28],
8854
+ [8580, 8580, 1, -1],
8855
+ [9424, 9449, 1, -26],
8856
+ [11361, 11361, 1, -1],
8857
+ [11365, 11365, 1, -10795],
8858
+ [11366, 11366, 2, -10792],
8859
+ [11368, 11372, 2, -1],
8860
+ [11382, 11382, 1, -1],
8861
+ [65345, 65370, 1, -32],
8862
+ [66600, 66639, 1, -40],
8863
+ [66776, 66811, 1, -40],
8864
+ [68800, 68850, 1, -64],
8865
+ [71872, 71903, 1, -32],
8866
+ [93792, 93823, 1, -32],
8867
+ [125218, 125251, 1, -34]
8868
+ ];
8869
+ function visioFieldCase(text5, upper) {
8870
+ const ranges = upper ? UPPER : LOWER;
8871
+ return Array.from(text5, (character) => {
8872
+ const point2 = character.codePointAt(0);
8873
+ let low = 0, high = ranges.length;
8874
+ while (low < high) {
8875
+ const middle = low + high >>> 1;
8876
+ if (ranges[middle][1] < point2) low = middle + 1;
8877
+ else high = middle;
8878
+ }
8879
+ const range2 = ranges[low];
8880
+ return range2 && point2 >= range2[0] && (point2 - range2[0]) % range2[2] === 0 ? String.fromCodePoint(point2 + range2[3]) : character;
8881
+ }).join("");
8882
+ }
8883
+
8628
8884
  // visio/text-fields.ts
8629
8885
  var PROPERTY_FUNCTIONS = {
8630
8886
  TITLE: "title",
@@ -8661,7 +8917,6 @@ function visioWallClock(date2) {
8661
8917
  );
8662
8918
  }
8663
8919
  var EPOCH = Date.UTC(1899, 11, 30);
8664
- var visioDateSerial = (date2) => Number(((date2.getTime() - EPOCH) / 864e5).toFixed(8));
8665
8920
  var visioSerialDate = (serial) => Number.isFinite(serial) && Math.abs(serial) < 3e6 ? new Date(EPOCH + Math.round(serial * 864e5)) : void 0;
8666
8921
  function evaluateVisioTextField(formula, context) {
8667
8922
  let ast;
@@ -8772,7 +9027,10 @@ function formatNumber(value, picture) {
8772
9027
  if (!match) return void 0;
8773
9028
  const decimals = match[2]?.length ?? 0;
8774
9029
  const optional = match[2]?.startsWith("#") ?? false;
8775
- let text5 = value.toFixed(decimals);
9030
+ const [coefficient, exponent = "0"] = Math.abs(value).toString().split("e");
9031
+ const shifted = Number(coefficient + "e" + (Number(exponent) + decimals));
9032
+ const rounded = Math.floor(shifted + 0.5) / 10 ** decimals;
9033
+ let text5 = (Math.sign(value) * rounded).toFixed(decimals);
8776
9034
  if (optional && text5.includes(".")) text5 = text5.replace(/\.?0+$/, "");
8777
9035
  if (match[1]) {
8778
9036
  const [whole, fraction] = text5.split(".");
@@ -8782,6 +9040,7 @@ function formatNumber(value, picture) {
8782
9040
  }
8783
9041
  var VISIO_FIELD_FORMATS = {
8784
9042
  shortDate: "{{M/d/yyyy}}",
9043
+ isoDate: "{{yyyy-MM-dd}}",
8785
9044
  longDate: "{{dddd, MMMM d, yyyy}}",
8786
9045
  time: "{{h:mm tt}}",
8787
9046
  dateTime: "{{M/d/yyyy h:mm tt}}",
@@ -8811,12 +9070,147 @@ function formatVisioFieldValue(value, format4 = "") {
8811
9070
  return units2 || body === "" ? `${text5}${suffix}` : text5;
8812
9071
  }
8813
9072
 
9073
+ // visio/text-field-fraction.ts
9074
+ function fractionalFieldNumber(value, maxDenominator) {
9075
+ if (!Number.isFinite(value) || Math.abs(value) > 1e15) return void 0;
9076
+ const absolute = Math.abs(value);
9077
+ let whole = Math.floor(absolute);
9078
+ const remainder = absolute - whole;
9079
+ let numerator = 0, denominator = 1, error = remainder;
9080
+ for (let candidate = 1; candidate <= maxDenominator; candidate++) {
9081
+ const top = Math.round(remainder * candidate);
9082
+ const fraction = top / candidate;
9083
+ const distance4 = Math.abs(remainder - fraction);
9084
+ if (distance4 < error || distance4 === error && fraction > numerator / denominator) {
9085
+ numerator = top;
9086
+ denominator = candidate;
9087
+ error = distance4;
9088
+ }
9089
+ }
9090
+ if (numerator === denominator) {
9091
+ whole++;
9092
+ numerator = 0;
9093
+ }
9094
+ const text5 = numerator ? `${whole ? whole + " " : ""}${numerator}/${denominator}` : String(whole);
9095
+ return value < 0 && text5 !== "0" ? "-" + text5 : text5;
9096
+ }
9097
+
9098
+ // visio/text-field-numeric.ts
9099
+ function numericFieldPicture(value, code, displayUnit) {
9100
+ if (value.kind !== "number" || code < 0 || code > 18 || code > 9 && code < 15 || !Number.isInteger(code))
9101
+ return void 0;
9102
+ const unit3 = displayUnit?.toUpperCase() ?? "NUM";
9103
+ const units2 = {
9104
+ NUM: ["scalar", 1, ""],
9105
+ IN: ["length", 1, " in."],
9106
+ MM: ["length", 25.4, " mm."],
9107
+ CM: ["length", 2.54, " cm."],
9108
+ FT: ["length", 1 / 12, " ft."],
9109
+ DEG: ["angle", 180 / Math.PI, " deg."],
9110
+ RAD: ["angle", 1, " rad."]
9111
+ };
9112
+ const definition = Object.hasOwn(units2, unit3) ? units2[unit3] : void 0;
9113
+ if (!definition || definition[0] !== value.unit) return void 0;
9114
+ const general = code < 2;
9115
+ const decimals = general ? 4 : Math.floor((code - 2) / 2);
9116
+ const picture = general ? "0.####" : decimals ? `0.${"0".repeat(decimals)}` : "0";
9117
+ const displayed = value.value * definition[1];
9118
+ if (!Number.isFinite(displayed)) return void 0;
9119
+ if (code >= 15) {
9120
+ const fraction = fractionalFieldNumber(displayed, code < 17 ? 9 : 99);
9121
+ return fraction === void 0 ? void 0 : fraction + (code % 2 === 0 ? definition[2] : "");
9122
+ }
9123
+ if ((general || !decimals) && Math.abs(displayed) > 1e15) return void 0;
9124
+ const scientific = decimals > 0 && (Math.abs(displayed) >= 1e15 || displayed !== 0 && Math.abs(displayed) < 0.5 / 10 ** decimals);
9125
+ let text5;
9126
+ if (scientific) {
9127
+ const [coefficient, power] = displayed.toExponential().split("e");
9128
+ let exponent = Number(power);
9129
+ let precision = Math.abs(displayed) >= 1e15 ? decimals : decimals - 1;
9130
+ const mantissaPicture = precision ? `0.${"0".repeat(precision)}` : "0";
9131
+ let mantissa = formatVisioFieldValue(
9132
+ { kind: "number", value: Number(coefficient), unit: "scalar" },
9133
+ mantissaPicture
9134
+ );
9135
+ if (mantissa === void 0) return void 0;
9136
+ if (Math.abs(Number(mantissa)) >= 10) {
9137
+ exponent += 1;
9138
+ precision = decimals;
9139
+ mantissa = Math.sign(displayed).toFixed(precision);
9140
+ }
9141
+ if (general) mantissa = mantissa.replace(/\.?0+$/, "");
9142
+ else if (!mantissa.includes(".")) mantissa += ".";
9143
+ text5 = mantissa + (code % 2 ? "e" : "E") + exponent;
9144
+ } else {
9145
+ text5 = formatVisioFieldValue({ kind: "number", value: displayed, unit: "scalar" }, picture);
9146
+ }
9147
+ return text5 === void 0 ? void 0 : text5 + (code % 2 ? definition[2] : "");
9148
+ }
9149
+
9150
+ // visio/date-cache.ts
9151
+ function visioIsoDateSerial(text5) {
9152
+ const match = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?)?$/.exec(
9153
+ text5.trim()
9154
+ );
9155
+ if (!match) return void 0;
9156
+ const year = Number(match[1]), month = Number(match[2]), day = Number(match[3]);
9157
+ const hour = Number(match[4] ?? 0), minute = Number(match[5] ?? 0), second = Number(match[6] ?? 0);
9158
+ const millisecond = Number((match[7] ?? "").padEnd(3, "0").slice(0, 3));
9159
+ if (year < 1 || hour > 23 || minute > 59 || second > 59) return void 0;
9160
+ const date2 = /* @__PURE__ */ new Date(0);
9161
+ date2.setUTCFullYear(year, month - 1, day);
9162
+ date2.setUTCHours(hour, minute, second, millisecond);
9163
+ if (date2.getUTCFullYear() !== year || date2.getUTCMonth() !== month - 1 || date2.getUTCDate() !== day)
9164
+ return void 0;
9165
+ return (date2.getTime() - Date.UTC(1899, 11, 30)) / 864e5;
9166
+ }
9167
+
9168
+ // visio/text-field-system-date.ts
9169
+ var LONG_DATE = "{{dddd, MMMM d, yyyy}}";
9170
+ function englishLongDateProfile(cached5) {
9171
+ const match = /^[A-Za-z]+, [A-Za-z]+ ([1-9]|[12]\d|3[01]), (\d{4})$/.exec(cached5);
9172
+ if (!match) return false;
9173
+ for (let month = 0; month < 12; month++) {
9174
+ const candidate = /* @__PURE__ */ new Date(0);
9175
+ candidate.setUTCFullYear(Number(match[2]), month, Number(match[1]));
9176
+ if (candidate.getUTCMonth() === month && candidate.getTime() >= Date.UTC(1899, 11, 30) && formatVisioFieldValue({ kind: "date", date: candidate }, LONG_DATE) === cached5)
9177
+ return true;
9178
+ }
9179
+ return false;
9180
+ }
9181
+ function systemDatePicture(date2, code, cached5) {
9182
+ if (!Number.isFinite(date2.getTime()) || date2.getTime() < Date.UTC(1899, 11, 30) || date2.getUTCFullYear() > 9999)
9183
+ return void 0;
9184
+ if (code === "204") return formatVisioFieldValue({ kind: "date", date: date2 }, "{{yyyy-MM-dd}}");
9185
+ if (code === "21" || code === "201")
9186
+ return englishLongDateProfile(cached5) ? formatVisioFieldValue({ kind: "date", date: date2 }, LONG_DATE) : void 0;
9187
+ if (code === "20" || code === "200") {
9188
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(cached5) || visioIsoDateSerial(cached5) === void 0)
9189
+ return void 0;
9190
+ return formatVisioFieldValue({ kind: "date", date: date2 }, "{{yyyy-MM-dd}}");
9191
+ }
9192
+ if (code !== "211" && code !== "212") return void 0;
9193
+ const match = /^(\d{4}-\d{2}-\d{2}) ([1-9]|1[0-2]):([0-5]\d)(?::([0-5]\d))? (AM|PM)$/.exec(
9194
+ cached5
9195
+ );
9196
+ if (!match || code === "212" !== (match[4] !== void 0)) return void 0;
9197
+ const hour = Number(match[2]) % 12 + (match[5] === "PM" ? 12 : 0);
9198
+ if (visioIsoDateSerial(
9199
+ `${match[1]}T${String(hour).padStart(2, "0")}:${match[3]}:${match[4] ?? "00"}`
9200
+ ) === void 0)
9201
+ return void 0;
9202
+ return formatVisioFieldValue(
9203
+ { kind: "date", date: date2 },
9204
+ code === "211" ? "{{yyyy-MM-dd h:mm tt}}" : "{{yyyy-MM-dd h:mm:ss tt}}"
9205
+ );
9206
+ }
9207
+
8814
9208
  // visio/text-field-display.ts
8815
9209
  function cachedValue(value, unit3) {
8816
9210
  if (value === void 0) return void 0;
8817
9211
  if (unit3 === "STR") return { kind: "string", text: value };
8818
9212
  if (unit3 === "DATE") {
8819
- const date2 = visioSerialDate(Number(value));
9213
+ const date2 = visioSerialDate(visioIsoDateSerial(value) ?? Number(value));
8820
9214
  return date2 ? { kind: "date", date: date2 } : void 0;
8821
9215
  }
8822
9216
  try {
@@ -8833,11 +9227,23 @@ function textFieldDisplay(element2, sheet, context) {
8833
9227
  const value = row2?.cells.get("Value"), format4 = row2?.cells.get("Format");
8834
9228
  const formula = value?.formula && value.formula !== "Inh" ? value.formula : void 0;
8835
9229
  const result = { cached: cached5, ...formula ? { formula } : {} };
8836
- if (!row2 || !context || format4?.formula && /^\s*FIELDPICTURE\s*\(/i.test(format4.formula))
8837
- return { text: cached5, ...result };
9230
+ if (!row2 || !context) return { text: cached5, ...result };
8838
9231
  const picture = format4?.value ?? "";
8839
9232
  const evaluated = formula ? evaluateVisioTextField(formula, context) : void 0;
8840
9233
  const source = evaluated ?? cachedValue(value?.value, value?.unit);
9234
+ if (format4?.formula && /^\s*FIELDPICTURE\s*\(/i.test(format4.formula)) {
9235
+ const code = /^\s*FIELDPICTURE\s*\(\s*(\d+)\s*\)\s*$/i.exec(format4.formula)?.[1];
9236
+ let text6 = cached5;
9237
+ if (source?.kind === "string") {
9238
+ if (code === "0" || code === "37") text6 = source.text;
9239
+ else if (code === "38" || code === "39") text6 = visioFieldCase(source.text, code === "39");
9240
+ }
9241
+ if (source?.kind === "number" && code !== void 0)
9242
+ text6 = numericFieldPicture(source, Number(code), value?.unit) ?? cached5;
9243
+ if (source?.kind === "date" && code !== void 0)
9244
+ text6 = systemDatePicture(source.date, code, cached5) ?? cached5;
9245
+ return { text: text6, ...result };
9246
+ }
8841
9247
  const text5 = source ? formatVisioFieldValue(source, picture) : void 0;
8842
9248
  return { text: text5 ?? cached5, ...result };
8843
9249
  }
@@ -9432,7 +9838,7 @@ function geometryPaths(sheet, width, height, report, consume, consumeWork = () =
9432
9838
  else {
9433
9839
  const radius = chord * chord / (8 * Math.abs(bow)) + Math.abs(bow) / 2;
9434
9840
  commands.push(
9435
- `A ${point(radius, radius)} 0 ${Math.abs(bow) > chord / 2 ? 1 : 0} ${bow < 0 ? 1 : 0} ${point(x, y)}`
9841
+ `A ${point(radius, radius)} 0 ${Math.abs(bow) > chord / 2 ? 1 : 0} ${bow < 0 ? 0 : 1} ${point(x, y)}`
9436
9842
  );
9437
9843
  }
9438
9844
  break;
@@ -10292,15 +10698,6 @@ function booleanValue(text5) {
10292
10698
  const value = numeric3(text5);
10293
10699
  return value === void 0 ? void 0 : value !== 0;
10294
10700
  }
10295
- function isoSerialDays(text5) {
10296
- const match = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2}(?:\.\d+)?))?)?$/.exec(
10297
- text5.trim()
10298
- );
10299
- if (!match) return void 0;
10300
- const [year, month, day, hour, minute, second] = match.slice(1).map((part) => Number(part ?? 0));
10301
- const time = Date.UTC(year, month - 1, day, hour, minute, second);
10302
- return Number.isFinite(time) ? (time - Date.UTC(1899, 11, 30)) / 864e5 : void 0;
10303
- }
10304
10701
  function property(row2, budget, report) {
10305
10702
  const get = (key2) => cached(row2.cells, key2, budget, report);
10306
10703
  const rawType = get("Type"), rawValue = get("Value");
@@ -10311,7 +10708,7 @@ function property(row2, budget, report) {
10311
10708
  if (rawValue !== void 0 && row2.cells.get("Value")?.error === void 0) {
10312
10709
  if (type === 0 || type === 1 || type === 4) value = budget.retain(rawValue);
10313
10710
  else if (type === 3) value = booleanValue(rawValue);
10314
- else if (type === 5) value = numeric3(rawValue) ?? isoSerialDays(rawValue);
10711
+ else if (type === 5) value = numeric3(rawValue) ?? visioIsoDateSerial(rawValue);
10315
10712
  else if (valueKind !== "unparsed") value = numeric3(rawValue);
10316
10713
  }
10317
10714
  if (value === void 0) {
@@ -10408,6 +10805,21 @@ function hyperlink(row2, budget, report) {
10408
10805
  ...sortKey === void 0 ? {} : { sortKey }
10409
10806
  };
10410
10807
  }
10808
+ function alternativeTextMetadata(sheet, report, budget) {
10809
+ const result = {};
10810
+ for (const section3 of sheet.sections.values()) {
10811
+ if (section3.deleted || section3.name !== "User") continue;
10812
+ for (const row2 of section3.rows.values()) {
10813
+ if (row2.deleted || !["visAltText", "visAltDescription"].includes(row2.name ?? row2.index))
10814
+ continue;
10815
+ budget.consumeRow();
10816
+ const value = cached(row2.cells, "Value", budget, report);
10817
+ if (value !== void 0)
10818
+ result[(row2.name ?? row2.index) === "visAltText" ? "accessibilityTitle" : "alternativeText"] = value;
10819
+ }
10820
+ }
10821
+ return result;
10822
+ }
10411
10823
  function shapeMetadata(sheet, report, budget = createMetadataBudget()) {
10412
10824
  const shapeData = [], hyperlinks = [];
10413
10825
  let count = 0;
@@ -10424,7 +10836,12 @@ function shapeMetadata(sheet, report, budget = createMetadataBudget()) {
10424
10836
  }
10425
10837
  const comment = sheet.cells.get("Comment");
10426
10838
  const screenTip = comment?.value && comment.error === void 0 ? budget.retain(comment.value) : void 0;
10427
- return { shapeData, hyperlinks, ...screenTip === void 0 ? {} : { screenTip } };
10839
+ return {
10840
+ shapeData,
10841
+ hyperlinks,
10842
+ ...alternativeTextMetadata(sheet, report, budget),
10843
+ ...screenTip === void 0 ? {} : { screenTip }
10844
+ };
10428
10845
  }
10429
10846
 
10430
10847
  // visio/theme-root.ts
@@ -10783,6 +11200,31 @@ function shapeConnections(sheet, local, inheritedSheet, transform2, oneD, report
10783
11200
  return result;
10784
11201
  }
10785
11202
 
11203
+ // visio/connector-jumps.ts
11204
+ function readConnectorJumps(cells4, report) {
11205
+ const result = {};
11206
+ for (const [key2, name3, maximum] of [
11207
+ ["lineJumpCode", "ConLineJumpCode", 4],
11208
+ ["lineJumpStyle", "ConLineJumpStyle", 9],
11209
+ ["lineJumpDirectionX", "ConLineJumpDirX", 2],
11210
+ ["lineJumpDirectionY", "ConLineJumpDirY", 2]
11211
+ ]) {
11212
+ const cell = cells4.get(name3);
11213
+ if (!cell || cell.formula === "Inh") continue;
11214
+ const raw = cell.value?.trim();
11215
+ const value = raw && raw.length <= 64 && /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(raw) ? Number(raw) : NaN;
11216
+ if (cell.error !== void 0 || !Number.isInteger(value) || value < 0 || value > maximum) {
11217
+ report(
11218
+ "unsupported-connector-jump",
11219
+ `${name3} has no supported cached value; the page setting is used.`
11220
+ );
11221
+ continue;
11222
+ }
11223
+ result[key2] = value;
11224
+ }
11225
+ return result;
11226
+ }
11227
+
10786
11228
  // visio/shapes.ts
10787
11229
  function mergeShape(base2, local, context) {
10788
11230
  context.consumeExpansion();
@@ -10945,6 +11387,7 @@ function normalizeShapes(raw, context, depth = 0, masterStack = []) {
10945
11387
  report("missing-geometry", "Shape has no supported cached geometry.");
10946
11388
  return {
10947
11389
  ...shapeMetadata(sheet, report, context.metadataBudget),
11390
+ ...oneD ? readConnectorJumps(sheet.cells, report) : {},
10948
11391
  ...structureOf(sheet),
10949
11392
  id: shape.id,
10950
11393
  name: shape.attributes.get("Name") ?? shape.attributes.get("NameU") ?? `Shape ${shape.id}`,
@@ -11168,6 +11611,12 @@ var VISIO_RULER_DENSITIES = Object.freeze([8, 16, 32]);
11168
11611
  var VISIO_PAGE_LAYOUT_DEFAULTS = Object.freeze({
11169
11612
  lineJumpCode: 1,
11170
11613
  lineJumpStyle: 0,
11614
+ lineJumpDirectionX: 0,
11615
+ lineJumpDirectionY: 0,
11616
+ lineJumpFactorX: 2 / 3,
11617
+ lineJumpFactorY: 2 / 3,
11618
+ lineToLineX: 0.125,
11619
+ lineToLineY: 0.125,
11171
11620
  gridDensityX: 8,
11172
11621
  gridDensityY: 8,
11173
11622
  gridSpacingX: 0,
@@ -11182,6 +11631,12 @@ var VISIO_PAGE_LAYOUT_DEFAULTS = Object.freeze({
11182
11631
  var NAMES = {
11183
11632
  lineJumpCode: "LineJumpCode",
11184
11633
  lineJumpStyle: "LineJumpStyle",
11634
+ lineJumpDirectionX: "PageLineJumpDirX",
11635
+ lineJumpDirectionY: "PageLineJumpDirY",
11636
+ lineJumpFactorX: "LineJumpFactorX",
11637
+ lineJumpFactorY: "LineJumpFactorY",
11638
+ lineToLineX: "LineToLineX",
11639
+ lineToLineY: "LineToLineY",
11185
11640
  gridDensityX: "XGridDensity",
11186
11641
  gridDensityY: "YGridDensity",
11187
11642
  gridSpacingX: "XGridSpacing",
@@ -12043,6 +12498,7 @@ async function parseVsdx(input, options = {}) {
12043
12498
  localReport("dangling-connection", "A connection references a missing shape.");
12044
12499
  pages.push({
12045
12500
  id: id3,
12501
+ ...alternativeTextMetadata(sheet, localReport, context.metadataBudget),
12046
12502
  ...pageModes,
12047
12503
  ...drawingToPageScale === 1 ? {} : { drawingToPageScale },
12048
12504
  ...pageSetup ? { pageSetup } : {},
@@ -21580,6 +22036,9 @@ async function assertFormattingDependencies(pkg, pagePaths, roots, pageId2, shap
21580
22036
  indexCells(roots, { check });
21581
22037
  const shapeId2 = attribute2(shape, "ID");
21582
22038
  const changedNames = new Set([...changed.keys()].map((name3) => name3.toLowerCase()));
22039
+ const jumpOnly = [...changedNames].every(
22040
+ (name3) => /^conlinejump(code|style|dirx|diry)$/.test(name3)
22041
+ );
21583
22042
  const canonical2 = (name3) => name3.toLowerCase().replace(/^char\.([a-z]+)$/, "character.0.$1").replace(/^para\.([a-z]+)$/, "paragraph.0.$1");
21584
22043
  const replaced = new Set(changed.values());
21585
22044
  const textEdit = [...changedNames].some(
@@ -21600,6 +22059,9 @@ async function assertFormattingDependencies(pkg, pagePaths, roots, pageId2, shap
21600
22059
  if (!source || inertDoubleClickFormula(attribute2(node2, "N") ?? "", source)) continue;
21601
22060
  if (attribute2(node2, "V") === "Themed" && isThemeLookupFormula(source)) continue;
21602
22061
  if (isConnectedGlueCell(node2, source)) continue;
22062
+ const owner = node2.parentNode;
22063
+ if (jumpOnly && node2.localName === "Cell" && /^(BegTrigger|EndTrigger)$/.test(attribute2(node2, "N") ?? "") && owner?.localName === "Shape" && owner.parentNode?.parentNode?.localName === "PageContents" && visioGlueTriggerTarget(source) === attribute2(owner, "ID"))
22064
+ continue;
21603
22065
  let localShapeId;
21604
22066
  let parent = node2;
21605
22067
  while (parent?.nodeType === 1) {
@@ -21682,7 +22144,7 @@ function masterCells(sheet, charge = () => {
21682
22144
  };
21683
22145
  for (const node2 of children2(sheet, "Cell")) add(attribute2(node2, "N") ?? "", node2);
21684
22146
  for (const section3 of children2(sheet, "Section")) {
21685
- const name3 = attribute2(section3, "N") ?? "";
22147
+ const name3 = shapeDataFormulaSection(attribute2(section3, "N") ?? "");
21686
22148
  const prefix2 = name3 === "Geometry" ? `Geometry${Number(attribute2(section3, "IX") ?? "0") + 1}` : name3 === "Control" ? "Controls" : name3;
21687
22149
  for (const node2 of children2(section3, "Cell"))
21688
22150
  add(`${prefix2}.${attribute2(node2, "N") ?? ""}`, node2);
@@ -23224,6 +23686,99 @@ function connectorObstacles(root2, exclude) {
23224
23686
  return result;
23225
23687
  }
23226
23688
 
23689
+ // visio/connector-curve-aligned.ts
23690
+ function alignedVisioCurve(begin, end) {
23691
+ const a = begin.shape;
23692
+ const b = end.shape;
23693
+ if (!a || !b) return void 0;
23694
+ for (const shape of [a, b])
23695
+ if (shape.corners.some(
23696
+ (p) => Math.abs(p.x - shape.bounds.minX) > 1e-9 && Math.abs(p.x - shape.bounds.maxX) > 1e-9 || Math.abs(p.y - shape.bounds.minY) > 1e-9 && Math.abs(p.y - shape.bounds.maxY) > 1e-9
23697
+ ))
23698
+ return void 0;
23699
+ for (const axis of ["x", "y"]) {
23700
+ const horizontal2 = axis === "x";
23701
+ const low = horizontal2 ? "minY" : "minX";
23702
+ const high = horizontal2 ? "maxY" : "maxX";
23703
+ const overlapLow = Math.max(a.bounds[low], b.bounds[low]);
23704
+ const overlapHigh = Math.min(a.bounds[high], b.bounds[high]);
23705
+ if (overlapHigh - overlapLow <= 1e-9) continue;
23706
+ const forward = b.center[axis] > a.center[axis];
23707
+ const from = horizontal2 ? a.bounds[forward ? "maxX" : "minX"] : a.bounds[forward ? "maxY" : "minY"];
23708
+ const to = horizontal2 ? b.bounds[forward ? "minX" : "maxX"] : b.bounds[forward ? "minY" : "maxY"];
23709
+ if ((to - from) * (forward ? 1 : -1) <= 1e-9) continue;
23710
+ const middle = (overlapLow + overlapHigh) / 2;
23711
+ return [0, 0.25, 0.75, 1].map((t) => {
23712
+ const along = from + (to - from) * t;
23713
+ return horizontal2 ? { x: along, y: middle } : { x: middle, y: along };
23714
+ });
23715
+ }
23716
+ return void 0;
23717
+ }
23718
+
23719
+ // visio/connector-curve-spans.ts
23720
+ var mix = (a, b, t) => ({
23721
+ x: a.x + (b.x - a.x) * t,
23722
+ y: a.y + (b.y - a.y) * t
23723
+ });
23724
+ function cornerCurve(path) {
23725
+ const [begin, corner, end] = path;
23726
+ return [begin, mix(begin, corner, 0.25), corner, mix(corner, end, 0.75), end];
23727
+ }
23728
+ function cornerCurveKnots(points) {
23729
+ const distance4 = (a, b) => Math.hypot(points[b].x - points[a].x, points[b].y - points[a].y) / 3;
23730
+ const internal = distance4(0, 3);
23731
+ return [internal, internal + distance4(1, 4)];
23732
+ }
23733
+ function connectorCurveSpans(points) {
23734
+ if (points.length === 4) return [[...points]];
23735
+ if (points.length !== 5) return [];
23736
+ const [internal, last] = cornerCurveKnots(points);
23737
+ const ratio = internal / last;
23738
+ const left = mix(points[1], points[2], ratio);
23739
+ const right2 = mix(points[2], points[3], ratio);
23740
+ const join = mix(left, right2, ratio);
23741
+ return [
23742
+ [points[0], points[1], left, join],
23743
+ [join, right2, points[3], points[4]]
23744
+ ];
23745
+ }
23746
+ function connectorPolylineMiddle(points) {
23747
+ const lengths = points.slice(1).map((p, i) => Math.hypot(p.x - points[i].x, p.y - points[i].y));
23748
+ let remaining = lengths.reduce((sum, length) => sum + length, 0) / 2;
23749
+ for (const [i, length] of lengths.entries()) {
23750
+ if (remaining <= length && length > 0)
23751
+ return mix(points[i], points[i + 1], remaining / length);
23752
+ remaining -= length;
23753
+ }
23754
+ return points.at(-1);
23755
+ }
23756
+ function flattenCornerCurve(points) {
23757
+ const [internal, last] = cornerCurveKnots(points);
23758
+ const flattened = flattenNurbs(
23759
+ points.map((p) => ({ ...p, weight: 1 })),
23760
+ [0, 0, 0, 0, internal, last, last, last, last],
23761
+ 3,
23762
+ () => {
23763
+ },
23764
+ () => {
23765
+ }
23766
+ );
23767
+ return flattened ? [points[0], ...flattened] : void 0;
23768
+ }
23769
+ function connectorCurveMiddle(points) {
23770
+ const spans = connectorCurveSpans(points);
23771
+ if (points.length === 5) {
23772
+ const flattened = flattenCornerCurve(points);
23773
+ if (flattened) return connectorPolylineMiddle(flattened);
23774
+ return mix(points[0], points.at(-1), 0.5);
23775
+ }
23776
+ const row2 = [...spans[0]];
23777
+ for (let count = row2.length - 1; count > 0; count--)
23778
+ for (let i = 0; i < count; i++) row2[i] = mix(row2[i], row2[i + 1], 0.5);
23779
+ return row2[0];
23780
+ }
23781
+
23227
23782
  // visio/connector-route-walk.ts
23228
23783
  var EPSILON3 = 1e-9;
23229
23784
  var CHANNEL = 2 * VISIO_ROUTE_CLEARANCE;
@@ -23292,9 +23847,25 @@ function visioWalkRoute(begin, end, route, obstacles = []) {
23292
23847
  const q = end.shape ? exit(end.shape, center(begin)) : end.point;
23293
23848
  return Math.hypot(q.x - p.x, q.y - p.y) > EPSILON3 ? [p, q] : void 0;
23294
23849
  }
23850
+ if (route === "curved") {
23851
+ const aligned = alignedVisioCurve(begin, end);
23852
+ if (aligned && !routeCrossings(aligned, obstacles)) return aligned;
23853
+ }
23295
23854
  const path = visioWalkPath(begin, end);
23296
23855
  if (!path || routeCrossings(path, obstacles)) return void 0;
23297
23856
  if (route === "right-angle") return path;
23857
+ if (path.length === 3 && begin.shape && end.shape && [begin.shape, end.shape].every(
23858
+ (shape) => shape.sites.every(
23859
+ (site) => Math.abs(site.normal.x) < EPSILON3 || Math.abs(site.normal.y) < EPSILON3
23860
+ )
23861
+ )) {
23862
+ const curve = cornerCurve(path);
23863
+ if (obstacles.length) {
23864
+ const sampled = flattenCornerCurve(curve);
23865
+ if (!sampled || routeCrossings(sampled, obstacles)) return void 0;
23866
+ }
23867
+ return curve;
23868
+ }
23298
23869
  const unit3 = (p, q) => {
23299
23870
  const length = Math.hypot(q.x - p.x, q.y - p.y) || 1;
23300
23871
  return { x: (q.x - p.x) / length, y: (q.y - p.y) / length };
@@ -23343,26 +23914,6 @@ function put(parent, inherited, name3, value, formula) {
23343
23914
  node2.removeAttribute("E");
23344
23915
  if (formula !== void 0) node2.setAttribute("F", formula);
23345
23916
  }
23346
- function midpoint(points) {
23347
- const lengths = points.slice(1).map((point2, index) => Math.hypot(point2.x - points[index].x, point2.y - points[index].y));
23348
- let left = lengths.reduce((sum, value) => sum + value, 0) / 2;
23349
- for (const [index, length] of lengths.entries()) {
23350
- if (left <= length && length > 0) {
23351
- const from = points[index], to = points[index + 1];
23352
- return {
23353
- x: from.x + (to.x - from.x) * left / length,
23354
- y: from.y + (to.y - from.y) * left / length
23355
- };
23356
- }
23357
- left -= length;
23358
- }
23359
- return points.at(-1);
23360
- }
23361
- var bezier = (p, t) => {
23362
- const u = 1 - t;
23363
- const mix2 = (key2) => u * u * u * p[0][key2] + 3 * u * u * t * p[1][key2] + 3 * u * t * t * p[2][key2] + t * t * t * p[3][key2];
23364
- return { x: mix2("x"), y: mix2("y") };
23365
- };
23366
23917
  function section(shape, name3, index) {
23367
23918
  let node2 = children2(shape, "Section").find((item) => attribute2(item, "N") === name3);
23368
23919
  if (!node2) {
@@ -23418,8 +23969,9 @@ function writeStencilConnector(shape, route, vertices) {
23418
23969
  x: point2.x - (begin.x + end.x) / 2 + width / 2,
23419
23970
  y: point2.y - (begin.y + end.y) / 2 + height / 2
23420
23971
  });
23421
- const curved2 = route === "curved" && !flatX && !flatY && vertices.length === 4;
23972
+ const curved2 = route === "curved" && (vertices.length === 5 || !flatX && !flatY && vertices.length === 4);
23422
23973
  const local = (curved2 || route !== "curved" ? vertices : [begin, end]).map(at2);
23974
+ const [internalKnot, lastKnot] = local.length === 5 ? cornerCurveKnots(local) : [0, 1];
23423
23975
  const masterGeometry = children2(template, "Section").find(
23424
23976
  (item) => attribute2(item, "N") === "Geometry"
23425
23977
  );
@@ -23444,15 +23996,15 @@ function writeStencilConnector(shape, route, vertices) {
23444
23996
  {
23445
23997
  type: "NURBSTo",
23446
23998
  cells: [
23447
- ["X", local[3].x, flatX ? void 0 : "Width*1"],
23448
- ["Y", local[3].y, flatY ? void 0 : "Height*1"],
23449
- ["A", 0],
23999
+ ["X", local.at(-1).x, flatX ? void 0 : "Width*1"],
24000
+ ["Y", local.at(-1).y, flatY ? void 0 : "Height*1"],
24001
+ ["A", internalKnot],
23450
24002
  ["B", 1],
23451
24003
  ["C", 0],
23452
24004
  ["D", 1],
23453
24005
  [
23454
24006
  "E",
23455
- `NURBS(1,3,1,1,${text2(local[1].x - local[0].x)},${text2(local[1].y - local[0].y)},0,1,${text2(local[2].x - local[0].x)},${text2(local[2].y - local[0].y)},0,1)`
24007
+ `NURBS(${text2(lastKnot)},3,1,1,${local.slice(1, -1).map((point2) => `${text2(point2.x)},${text2(point2.y)},0,1`).join(",")})`
23456
24008
  ]
23457
24009
  ]
23458
24010
  }
@@ -23489,7 +24041,7 @@ function writeStencilConnector(shape, route, vertices) {
23489
24041
  }
23490
24042
  }
23491
24043
  drop(shape, geometry);
23492
- const middle = curved2 ? bezier(local, 0.5) : midpoint(local);
24044
+ const middle = curved2 ? connectorCurveMiddle(local) : connectorPolylineMiddle(local);
23493
24045
  const masterControl = children2(template, "Section").filter((item) => attribute2(item, "N") === "Control").flatMap((item) => children2(item, "Row")).find((row2) => attribute2(row2, "N") === "TextPosition");
23494
24046
  const control = section(shape, "Control");
23495
24047
  let position = children2(control, "Row").find((row2) => attribute2(row2, "N") === "TextPosition");
@@ -24619,6 +25171,344 @@ async function refreshTextSizes(targets, result, options, deadline) {
24619
25171
  return { ...result, diagnostics };
24620
25172
  }
24621
25173
 
25174
+ // visio/line-jumps.ts
25175
+ var VISIO_LINE_JUMP_WIDTH = 2 / 3 * 0.125;
25176
+ var VISIO_LINE_JUMP_LIMITS = Object.freeze({ connectors: 2e3, segments: 2e4 });
25177
+ var TOKEN = /([MLZmlz]|[A-Za-z])|([+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)/g;
25178
+ function polylines(path) {
25179
+ const result = [];
25180
+ let command2 = "";
25181
+ let pending;
25182
+ for (const match of path.matchAll(TOKEN)) {
25183
+ if (match[1]) {
25184
+ if (match[1] !== "M" && match[1] !== "L") return void 0;
25185
+ if (pending !== void 0) return void 0;
25186
+ command2 = match[1];
25187
+ continue;
25188
+ }
25189
+ const value = Number(match[2]);
25190
+ if (!Number.isFinite(value) || !command2) return void 0;
25191
+ if (pending === void 0) {
25192
+ pending = value;
25193
+ continue;
25194
+ }
25195
+ const point2 = { x: pending, y: value };
25196
+ pending = void 0;
25197
+ if (command2 === "M") {
25198
+ result.push([point2]);
25199
+ command2 = "L";
25200
+ } else result.at(-1)?.push(point2);
25201
+ }
25202
+ return pending === void 0 && result.every((line) => line.length > 1) ? result : void 0;
25203
+ }
25204
+ var apply2 = (m, p) => ({
25205
+ x: m[0] * p.x + m[2] * p.y + m[4],
25206
+ y: m[1] * p.x + m[3] * p.y + m[5]
25207
+ });
25208
+ function invert(m) {
25209
+ const det = m[0] * m[3] - m[1] * m[2];
25210
+ if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return void 0;
25211
+ return [
25212
+ m[3] / det,
25213
+ -m[1] / det,
25214
+ -m[2] / det,
25215
+ m[0] / det,
25216
+ (m[2] * m[5] - m[3] * m[4]) / det,
25217
+ (m[1] * m[4] - m[0] * m[5]) / det
25218
+ ];
25219
+ }
25220
+ var clean2 = (value) => Math.abs(value) < 1e-9 ? 0 : Number(value.toFixed(6));
25221
+ var text3 = (p) => `${clean2(p.x)} ${clean2(p.y)}`;
25222
+ var horizontal = (s) => Math.abs(s.b.x - s.a.x) > Math.abs(s.b.y - s.a.y);
25223
+ var vertical = (s) => Math.abs(s.b.y - s.a.y) > Math.abs(s.b.x - s.a.x);
25224
+ function crossing(s, other, margin) {
25225
+ const dx = s.b.x - s.a.x, dy = s.b.y - s.a.y, ox = other.b.x - other.a.x, oy = other.b.y - other.a.y;
25226
+ const det = dx * oy - dy * ox;
25227
+ const length = Math.hypot(dx, dy), otherLength = Math.hypot(ox, oy);
25228
+ if (Math.abs(det) < 1e-9 || Math.abs(det) / (length * otherLength) < 0.2) return void 0;
25229
+ const t = ((other.a.x - s.a.x) * oy - (other.a.y - s.a.y) * ox) / det;
25230
+ const u = ((other.a.x - s.a.x) * dy - (other.a.y - s.a.y) * dx) / det;
25231
+ if (u * otherLength < 1e-6 || (1 - u) * otherLength < 1e-6) return void 0;
25232
+ if (t * length < margin || (1 - t) * length < margin) return void 0;
25233
+ return t;
25234
+ }
25235
+ function jumps(code, s, other, shapes) {
25236
+ const own = shapes[s.owner]?.lineJumpCode ?? 0;
25237
+ const peer = shapes[other.owner]?.lineJumpCode ?? 0;
25238
+ if (own === 4 || peer === 4 || own === 1) return false;
25239
+ if (own !== peer) {
25240
+ if (own === 2 || peer === 3) return true;
25241
+ if (own === 3 || peer === 2) return false;
25242
+ }
25243
+ if (code === 1) return horizontal(s) && !horizontal(other);
25244
+ if (code === 2) return vertical(s) && !vertical(other);
25245
+ if (code === 3 || code === 4) return s.owner > other.owner;
25246
+ return code === 5 && s.owner < other.owner;
25247
+ }
25248
+ function jump(style2, from, to, local, reverse) {
25249
+ const half = Math.hypot(to.x - from.x, to.y - from.y) / 2;
25250
+ const ux = (to.x - from.x) / (2 * half), uy = (to.y - from.y) / (2 * half);
25251
+ let nx = -uy, ny = ux;
25252
+ if (ny < -1e-9 || Math.abs(ny) <= 1e-9 && nx > 0) {
25253
+ nx = -nx;
25254
+ ny = -ny;
25255
+ }
25256
+ if (reverse) {
25257
+ nx = -nx;
25258
+ ny = -ny;
25259
+ }
25260
+ const centre = { x: (from.x + to.x) / 2, y: (from.y + to.y) / 2 };
25261
+ const at2 = (along, out) => local({ x: centre.x + ux * along + nx * out, y: centre.y + uy * along + ny * out });
25262
+ const end = local(to);
25263
+ if (style2 === 1) return `M ${text3(end)}`;
25264
+ if (style2 === 2) return `L ${text3(at2(-half, half))} L ${text3(at2(half, half))} L ${text3(end)}`;
25265
+ if (style2 >= 3) {
25266
+ const sides = style2 - 1;
25267
+ let out = "";
25268
+ for (let index = 1; index < sides; ++index) {
25269
+ const angle = Math.PI - Math.PI * index / sides;
25270
+ out += `L ${text3(at2(Math.cos(angle) * half, Math.sin(angle) * half))} `;
25271
+ }
25272
+ return `${out}L ${text3(end)}`;
25273
+ }
25274
+ const start = local(from), top = at2(0, half);
25275
+ const radius = Math.hypot(end.x - start.x, end.y - start.y) / 2;
25276
+ const sweep = (end.x - start.x) * (top.y - start.y) - (end.y - start.y) * (top.x - start.x) > 0 ? 0 : 1;
25277
+ return `A ${clean2(radius)} ${clean2(radius)} 0 0 ${sweep} ${text3(end)}`;
25278
+ }
25279
+ var connector = (shape, glued) => shape.kind === "connector" && !shape.hidden && !shape.children.length && (shape.connectorRoute !== void 0 || glued.has(shape.id));
25280
+ function visioLineJumpPaths(page) {
25281
+ const result = /* @__PURE__ */ new Map();
25282
+ const layout = visioPageLayout(page);
25283
+ const code = layout.lineJumpCode;
25284
+ const glued = new Set(page.connectors.map((connection) => connection.fromShapeId));
25285
+ const shapes = page.shapes.filter((shape) => connector(shape, glued)).slice(0, VISIO_LINE_JUMP_LIMITS.connectors);
25286
+ for (const shape of shapes) {
25287
+ if (shape.connectorRoute !== "straight" || !shape.lineEnds) continue;
25288
+ if (shape.geometry.length !== 1) continue;
25289
+ const geometry = shape.geometry[0];
25290
+ if (!geometry.stroke || geometry.fill) continue;
25291
+ const { begin, end } = shape.lineEnds;
25292
+ if (![begin.x, begin.y, end.x, end.y].every(Number.isFinite)) continue;
25293
+ const path = `M ${text3(begin)} L ${text3(end)}`;
25294
+ if (geometry.path !== path) result.set(shape, [path]);
25295
+ }
25296
+ if (shapes.length < 2) return result;
25297
+ if ((code < 1 || code > 5) && !shapes.some((shape) => shape.lineJumpCode === 2 || shape.lineJumpCode === 3))
25298
+ return result;
25299
+ const lines2 = [];
25300
+ const segments = [];
25301
+ shapes.forEach((shape, owner) => {
25302
+ shape.geometry.forEach((geometry, index) => {
25303
+ if (!geometry.stroke || geometry.fill) return;
25304
+ for (const line of polylines(result.get(shape)?.[index] ?? geometry.path) ?? []) {
25305
+ const points = line.map((point2) => apply2(shape.transform, point2));
25306
+ lines2.push({ shape, owner, geometry: index, points });
25307
+ for (let i = 1; i < points.length; ++i)
25308
+ segments.push({ a: points[i - 1], b: points[i], owner });
25309
+ }
25310
+ });
25311
+ });
25312
+ if (segments.length > VISIO_LINE_JUMP_LIMITS.segments) return result;
25313
+ const bounded6 = (value, fallback, max) => typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= max ? value : fallback;
25314
+ const scale = bounded6(page.drawingToPageScale, 1, Number.MAX_VALUE);
25315
+ const halfX = bounded6(layout.lineJumpFactorX, 2 / 3, 10) * bounded6(layout.lineToLineX, 0.125, 1e4) * scale / 2;
25316
+ const halfY = bounded6(layout.lineJumpFactorY, 2 / 3, 10) * bounded6(layout.lineToLineY, 0.125, 1e4) * scale / 2;
25317
+ const paths = /* @__PURE__ */ new Map();
25318
+ const any = /* @__PURE__ */ new Set();
25319
+ for (const line of lines2) {
25320
+ const inverse = invert(line.shape.transform);
25321
+ if (!inverse) continue;
25322
+ const local = (point2) => apply2(inverse, point2);
25323
+ let out = `M ${text3(local(line.points[0]))}`;
25324
+ for (let i = 1; i < line.points.length; ++i) {
25325
+ const s = { a: line.points[i - 1], b: line.points[i], owner: line.owner };
25326
+ const length = Math.hypot(s.b.x - s.a.x, s.b.y - s.a.y);
25327
+ const half = vertical(s) ? halfY : halfX;
25328
+ if (half <= 0) {
25329
+ out += ` L ${text3(local(s.b))}`;
25330
+ continue;
25331
+ }
25332
+ const hits = segments.filter((other) => other.owner !== s.owner && jumps(code, s, other, shapes)).flatMap((other) => crossing(s, other, half * 1.5) ?? []).sort((a, b) => a - b);
25333
+ let last = -Infinity;
25334
+ for (const t of hits) {
25335
+ if ((t - last) * length < half * 2.5) continue;
25336
+ last = t;
25337
+ const at2 = (offset) => ({
25338
+ x: s.a.x + (s.b.x - s.a.x) * (t * length + offset) / length,
25339
+ y: s.a.y + (s.b.y - s.a.y) * (t * length + offset) / length
25340
+ });
25341
+ const override = line.shape.lineJumpStyle ?? 0;
25342
+ const savedStyle = override >= 1 && override <= 9 ? override : layout.lineJumpStyle;
25343
+ const style2 = savedStyle >= 1 && savedStyle <= 9 ? savedStyle - 1 : 0;
25344
+ const direction = horizontal(s) ? line.shape.lineJumpDirectionX || layout.lineJumpDirectionX : vertical(s) ? line.shape.lineJumpDirectionY || layout.lineJumpDirectionY : 0;
25345
+ out += ` L ${text3(local(at2(-half)))} ${jump(style2, at2(-half), at2(half), local, direction === 2)}`;
25346
+ any.add(line.shape);
25347
+ }
25348
+ out += ` L ${text3(local(s.b))}`;
25349
+ }
25350
+ const byGeometry = paths.get(line.shape) ?? /* @__PURE__ */ new Map();
25351
+ byGeometry.set(line.geometry, [...byGeometry.get(line.geometry) ?? [], out]);
25352
+ paths.set(line.shape, byGeometry);
25353
+ }
25354
+ for (const shape of any) {
25355
+ const byGeometry = paths.get(shape);
25356
+ result.set(
25357
+ shape,
25358
+ shape.geometry.map(
25359
+ (geometry, index) => byGeometry.get(index)?.join(" ") ?? result.get(shape)?.[index] ?? geometry.path
25360
+ )
25361
+ );
25362
+ }
25363
+ return result;
25364
+ }
25365
+
25366
+ // visio/edit-line-jump-cache.ts
25367
+ var jumpState = (page) => JSON.stringify([
25368
+ Object.entries(visioPageLayout(page)).filter(([key2]) => /^lineJump|^lineToLine/.test(key2)),
25369
+ page.shapes.map((shape) => [
25370
+ shape.id,
25371
+ shape.lineJumpCode,
25372
+ shape.lineJumpStyle,
25373
+ shape.lineJumpDirectionX,
25374
+ shape.lineJumpDirectionY
25375
+ ])
25376
+ ]);
25377
+ function plainRows(section3) {
25378
+ return children2(section3, "Row").every(
25379
+ (row2) => ["MoveTo", "LineTo", "ArcTo"].includes(attribute2(row2, "T") ?? "") && Array.from(row2.attributes).every((attr2) => ["IX", "T", "Del"].includes(attr2.name)) && Array.from(row2.children ?? row2.childNodes).filter((node2) => node2.nodeType === 1).every((node2) => {
25380
+ const cell = node2;
25381
+ return cell.localName === "Cell" && cell.namespaceURI === section3.namespaceURI && ["X", "Y", ...attribute2(row2, "T") === "ArcTo" ? ["A"] : []].includes(
25382
+ attribute2(cell, "N") ?? ""
25383
+ ) && Array.from(cell.attributes).every((attr2) => ["N", "V", "U", "F"].includes(attr2.name)) && !executableCellFormula(attribute2(cell, "F")) && !Array.from(cell.childNodes).some((child3) => child3.nodeType === 1);
25384
+ })
25385
+ );
25386
+ }
25387
+ function cacheRows(path) {
25388
+ const tokens2 = path.trim().split(/\s+/);
25389
+ const rows = [];
25390
+ while (tokens2.length) {
25391
+ const command2 = tokens2.shift();
25392
+ if (command2 === "M" || command2 === "L") {
25393
+ rows.push({
25394
+ type: command2 === "M" ? "MoveTo" : "LineTo",
25395
+ x: Number(tokens2.shift()),
25396
+ y: Number(tokens2.shift())
25397
+ });
25398
+ } else if (command2 === "A") {
25399
+ const [rx, ry, rotation, large, sweep, x, y] = tokens2.splice(0, 7).map(Number);
25400
+ if (rx === void 0 || ry !== rx || rotation !== 0 || large !== 0 || sweep !== 0 && sweep !== 1 || x === void 0 || y === void 0)
25401
+ return [];
25402
+ rows.push({ type: "ArcTo", x, y, bow: sweep ? rx : -rx });
25403
+ } else return [];
25404
+ if (rows.length > 1e4) return [];
25405
+ }
25406
+ return rows.every((row2) => Number.isFinite(row2.x) && Number.isFinite(row2.y)) ? rows : [];
25407
+ }
25408
+ async function refreshLineJumpCaches(pageIds2, source, result, options, deadline) {
25409
+ if (!pageIds2.size || !result.changedParts.length) return result;
25410
+ const check = () => {
25411
+ if (Date.now() >= deadline) fail("LIMIT_RUNTIME", "Visio edit deadline exceeded.");
25412
+ };
25413
+ const limits = {
25414
+ ...DEFAULTS,
25415
+ ...options.limits,
25416
+ maxRuntimeMs: Math.max(1, deadline - Date.now())
25417
+ };
25418
+ const { pkg, parts, pages } = await openEditablePackage(result.bytes, limits, check);
25419
+ const model2 = await parseVsdx(result.bytes, { limits });
25420
+ const before = source ? await parseVsdx(source, { limits }) : void 0;
25421
+ const template = masterTemplate(pkg);
25422
+ const changed = new Set(result.changedParts);
25423
+ const kept = [];
25424
+ let referenced = false;
25425
+ for (const path of pkg.paths()) {
25426
+ check();
25427
+ if (!/^visio\/.*\.xml$/i.test(path)) continue;
25428
+ const root2 = await pkg.readXml(path);
25429
+ for (const node2 of Array.from(root2.getElementsByTagName("*")))
25430
+ if (/\b(?:Geometry|Geom)\d*\./i.test(attribute2(node2, "F") ?? "")) referenced = true;
25431
+ }
25432
+ for (const page of model2.pages) {
25433
+ if (!pageIds2.has(page.id)) continue;
25434
+ const prior = before?.pages.find((item) => item.id === page.id);
25435
+ if (prior && jumpState(prior) === jumpState(page)) continue;
25436
+ const path = pages.get(page.id);
25437
+ const root2 = await visioXml(pkg, path, "PageContents");
25438
+ let dirty = false;
25439
+ for (const [shape, paths] of visioLineJumpPaths(page)) {
25440
+ check();
25441
+ if (shape.connectorRoute !== "straight" || paths.length !== 1) continue;
25442
+ const target2 = children2(children2(root2, "Shapes")[0], "Shape").find(
25443
+ (node2) => attribute2(node2, "ID") === shape.id
25444
+ );
25445
+ if (!target2) continue;
25446
+ const sections = children2(target2, "Section").filter(
25447
+ (node2) => attribute2(node2, "N") === "Geometry"
25448
+ );
25449
+ const section3 = sections[0];
25450
+ const rows = cacheRows(paths[0]);
25451
+ if (referenced || !section3 || sections.length !== 1 || !rows.length || !plainRows(section3) || Array.from(section3.getElementsByTagName("*")).some(
25452
+ (node2) => executableCellFormula(attribute2(node2, "F"))
25453
+ )) {
25454
+ kept.push(shape.id);
25455
+ continue;
25456
+ }
25457
+ const indices = /* @__PURE__ */ new Map();
25458
+ const masterId = attribute2(target2, "Master");
25459
+ if (masterId) {
25460
+ const master2 = await template(masterId, attribute2(target2, "MasterShape"));
25461
+ const base2 = children2(master2, "Section").find(
25462
+ (node2) => attribute2(node2, "N") === "Geometry" && attribute2(node2, "IX") === attribute2(section3, "IX")
25463
+ );
25464
+ for (const row2 of children2(base2, "Row"))
25465
+ indices.set(attribute2(row2, "IX"), attribute2(row2, "T"));
25466
+ }
25467
+ for (const row2 of children2(section3, "Row")) section3.removeChild(row2);
25468
+ for (const [index, value] of rows.entries()) {
25469
+ const row2 = root2.ownerDocument.createElementNS(root2.namespaceURI, "Row");
25470
+ row2.setAttribute("IX", String(index + 1));
25471
+ row2.setAttribute("T", value.type);
25472
+ setCell(row2, "X", value.x);
25473
+ setCell(row2, "Y", value.y);
25474
+ if (value.bow !== void 0) setCell(row2, "A", value.bow);
25475
+ section3.appendChild(row2);
25476
+ indices.delete(String(index + 1));
25477
+ }
25478
+ for (const [index, type] of indices) {
25479
+ const row2 = root2.ownerDocument.createElementNS(root2.namespaceURI, "Row");
25480
+ row2.setAttribute("IX", index);
25481
+ row2.setAttribute("T", type);
25482
+ row2.setAttribute("Del", "1");
25483
+ section3.appendChild(row2);
25484
+ }
25485
+ dirty = true;
25486
+ }
25487
+ if (dirty) {
25488
+ parts.set(path, serializeEditedXml(root2, limits, check).bytes);
25489
+ changed.add(path);
25490
+ }
25491
+ }
25492
+ return {
25493
+ bytes: await writeEditedPackage(
25494
+ parts,
25495
+ options.maxOutputBytes ?? limits.maxInputBytes,
25496
+ deadline,
25497
+ check
25498
+ ),
25499
+ changedParts: [...changed].sort(),
25500
+ diagnostics: [
25501
+ ...result.diagnostics,
25502
+ ...kept.length ? [
25503
+ {
25504
+ code: "edit-line-jump-cache-kept",
25505
+ message: `Connector ${kept.join(", ")} retains its saved geometry because formula dependencies prevent refreshing native jump caches.`
25506
+ }
25507
+ ] : []
25508
+ ]
25509
+ };
25510
+ }
25511
+
24622
25512
  // visio/resize-anchor.ts
24623
25513
  function snapshotResizeAnchor(value) {
24624
25514
  if (value === void 0) return void 0;
@@ -26036,7 +26926,8 @@ function shapeResolver(shape) {
26036
26926
  }
26037
26927
  function valueCell(value) {
26038
26928
  if (value.kind === "string") return { v: value.text, u: "STR", type: 0 };
26039
- if (value.kind === "date") return { v: String(visioDateSerial(value.date)), u: "DATE", type: 5 };
26929
+ if (value.kind === "date")
26930
+ return { v: value.date.toISOString().replace(/Z$/, ""), u: "DATE", type: 5 };
26040
26931
  const unit3 = value.unit === "length" ? "IN" : value.unit === "angle" ? "DEG" : void 0;
26041
26932
  return { v: String(Number(value.value.toFixed(10))), ...unit3 ? { u: unit3 } : {}, type: 2 };
26042
26933
  }
@@ -26123,7 +27014,8 @@ async function insertVisioTextField(pkg, pagePaths, roots, document, edit, check
26123
27014
  };
26124
27015
  const stored = valueCell(value);
26125
27016
  cell("Value", stored.v, { ...stored.u ? { U: stored.u } : {}, F: edit.formula });
26126
- if (edit.format) cell("Format", edit.format, { F: `"${edit.format.replaceAll('"', '""')}"` });
27017
+ if (edit.format)
27018
+ cell("Format", edit.format, { U: "STR", F: `"${edit.format.replaceAll('"', '""')}"` });
26127
27019
  cell("Type", String(stored.type));
26128
27020
  section3.appendChild(row2);
26129
27021
  const field2 = owner.createElementNS(ns, "fld");
@@ -26554,6 +27446,9 @@ function assertDependencies(roots, pagesPart, pages, pagePaths, pageId2, changed
26554
27446
  "gi"
26555
27447
  ) : void 0;
26556
27448
  const paths = new Map([...pagePaths].map(([id3, path]) => [path, id3]));
27449
+ const jumpDecorationOnly = changed.every(
27450
+ (name3) => /^(LineJumpCode|LineJumpStyle|PageLineJumpDir[XY]|LineJumpFactor[XY])$/.test(name3)
27451
+ );
26557
27452
  for (const [path, root2] of roots)
26558
27453
  for (const node2 of [root2, ...Array.from(root2.getElementsByTagName("*"))]) {
26559
27454
  check();
@@ -26574,8 +27469,10 @@ function assertDependencies(roots, pagesPart, pages, pagePaths, pageId2, changed
26574
27469
  const nativeGlue = paths.has(path) && connected && node2.localName === "Cell" && node2.namespaceURI === root2.namespaceURI && (/^(BeginX|BeginY|EndX|EndY)$/.test(name3) && /^\s*_WALKGLUE\((?:BegTrigger,EndTrigger|EndTrigger,BegTrigger),WalkPreference\)\s*$/i.test(
26575
27470
  code
26576
27471
  ) || /^(BegTrigger|EndTrigger)$/.test(name3) && /^\s*_XFTRIGGER\(Sheet\.[1-9]\d*!EventXFMod\)\s*$/i.test(code));
27472
+ const nativeJumpTrigger = jumpDecorationOnly && paths.has(path) && node2.localName === "Cell" && node2.namespaceURI === root2.namespaceURI && /^(BegTrigger|EndTrigger)$/.test(name3) && owner?.localName === "Shape" && owner.namespaceURI === root2.namespaceURI && container?.localName === "Shapes" && container.parentNode === root2 && !!ownerId2 && visioGlueTriggerTarget(formula) === ownerId2;
27473
+ const nativeJumpText = jumpDecorationOnly && node2.localName === "Cell" && node2.namespaceURI === root2.namespaceURI && (/^(TxtPinX|TxtPinY)$/.test(name3) && /^\s*SETATREF\(Controls\.TextPosition(?:\.Y)?\)\s*$/i.test(formula) || !!textSizeFormula(formula) || name3 === "XCon" && /^\s*IF\(OR\(STRSAME\(SHAPETEXT\(TheText\),""\),HideText\),5,0\)\s*$/i.test(formula));
26577
27474
  let dynamic2 = false;
26578
- if (!nativeGlue) {
27475
+ if (!nativeGlue && !nativeJumpTrigger && !nativeJumpText) {
26579
27476
  try {
26580
27477
  dynamic2 = analyzeVisioFormula(
26581
27478
  mapVisioFormulaSyntax(
@@ -26590,7 +27487,7 @@ function assertDependencies(roots, pagesPart, pages, pagePaths, pageId2, changed
26590
27487
  if (dynamic2)
26591
27488
  fail(
26592
27489
  "EDIT_UNSUPPORTED_PAGE_SIZE_DEPENDENCY",
26593
- "Dynamic or unknown page-size dependencies cannot be safely refreshed."
27490
+ `Dynamic or unknown page-size dependencies cannot be safely refreshed (${path}, ${name3}).`
26594
27491
  );
26595
27492
  let local = paths.get(path);
26596
27493
  if (path === pagesPart) {
@@ -26808,6 +27705,12 @@ function setVisioPageProperties(pagesPart, pages, dirty, command2) {
26808
27705
  var CELLS = [
26809
27706
  ["lineJumpCode", "LineJumpCode", false],
26810
27707
  ["lineJumpStyle", "LineJumpStyle", false],
27708
+ ["lineJumpDirectionX", "PageLineJumpDirX", false],
27709
+ ["lineJumpDirectionY", "PageLineJumpDirY", false],
27710
+ ["lineJumpFactorX", "LineJumpFactorX", false],
27711
+ ["lineJumpFactorY", "LineJumpFactorY", false],
27712
+ ["lineToLineX", "LineToLineX", true],
27713
+ ["lineToLineY", "LineToLineY", true],
26811
27714
  ["gridDensityX", "XGridDensity", false],
26812
27715
  ["gridDensityY", "YGridDensity", false],
26813
27716
  ["gridSpacingX", "XGridSpacing", true],
@@ -26821,8 +27724,13 @@ var CELLS = [
26821
27724
  ];
26822
27725
  function valid(key2, value) {
26823
27726
  const number5 = typeof value === "number" && Number.isFinite(value) ? value : Number.NaN;
27727
+ if (key2.startsWith("lineJumpFactor") || key2.startsWith("lineToLine")) {
27728
+ if (!(number5 >= 0 && number5 <= (key2.startsWith("lineJumpFactor") ? 10 : 1e4)))
27729
+ fail("INVALID_EDIT", `Invalid page layout value for ${key2}.`);
27730
+ return number5;
27731
+ }
26824
27732
  const integer3 = Number.isSafeInteger(number5);
26825
- const ok = key2 === "lineJumpCode" ? integer3 && number5 >= 0 && number5 <= 5 : key2 === "lineJumpStyle" ? integer3 && number5 >= 0 && number5 <= 8 : key2.startsWith("gridDensity") ? VISIO_GRID_DENSITIES.includes(number5) : key2.startsWith("rulerDensity") ? VISIO_RULER_DENSITIES.includes(number5) : key2.startsWith("gridSpacing") ? number5 >= 0 && number5 <= 1e4 : Math.abs(number5) <= 1e6;
27733
+ const ok = key2 === "lineJumpDirectionX" || key2 === "lineJumpDirectionY" ? integer3 && number5 >= 0 && number5 <= 2 : key2 === "lineJumpCode" ? integer3 && number5 >= 0 && number5 <= 5 : key2 === "lineJumpStyle" ? integer3 && number5 >= 0 && number5 <= 9 : key2.startsWith("gridDensity") ? VISIO_GRID_DENSITIES.includes(number5) : key2.startsWith("rulerDensity") ? VISIO_RULER_DENSITIES.includes(number5) : key2.startsWith("gridSpacing") ? number5 >= 0 && number5 <= 1e4 : Math.abs(number5) <= 1e6;
26826
27734
  if (!ok) fail("INVALID_EDIT", `Invalid page layout value for ${key2}.`);
26827
27735
  return number5;
26828
27736
  }
@@ -27049,7 +27957,7 @@ function visioBorderShapes(style2, width, height, title = VISIO_DEFAULT_TITLE) {
27049
27957
 
27050
27958
  // visio/edit-page-setup-commands.ts
27051
27959
  var VISIO_SCALE_UNITS = Object.freeze(["IN", "FT", "MM", "CM", "M"]);
27052
- var isVisioPageSetupEdit = (edit) => edit.type === "set-page-setup" || edit.type === "set-page-properties" || edit.type === "set-page-decoration" || edit.type === "set-page-layout" || edit.type === "set-snap-glue";
27960
+ var isVisioPageSetupEdit = (edit) => edit.type === "set-page-alt-text" || edit.type === "set-page-setup" || edit.type === "set-page-properties" || edit.type === "set-page-decoration" || edit.type === "set-page-layout" || edit.type === "set-snap-glue";
27053
27961
  var pageId = (value, label) => {
27054
27962
  if (typeof value !== "string" || !value || value.length > 256)
27055
27963
  fail("INVALID_EDIT", `Invalid ${label}.`);
@@ -27069,6 +27977,13 @@ function snapshotPageSetupEdit(edit) {
27069
27977
  if (edit.type === "set-page-layout") return snapshotPageLayoutEdit(edit);
27070
27978
  if (edit.type === "set-snap-glue") return snapshotSnapGlueEdit(edit);
27071
27979
  const id3 = pageId(edit.pageId, "page");
27980
+ if (edit.type === "set-page-alt-text")
27981
+ return {
27982
+ type: edit.type,
27983
+ pageId: id3,
27984
+ title: metadataText(edit.title, true),
27985
+ description: metadataText(edit.description, false)
27986
+ };
27072
27987
  if (edit.type === "set-page-setup") {
27073
27988
  const result = { type: edit.type, pageId: id3 };
27074
27989
  if (edit.printOrientation !== void 0) {
@@ -28762,7 +29677,7 @@ var OFFICE_FALLBACK = [
28762
29677
  "#4472c4",
28763
29678
  "#70ad47"
28764
29679
  ];
28765
- function mix(color2, target2, amount) {
29680
+ function mix2(color2, target2, amount) {
28766
29681
  return `#${[1, 3, 5].map((index) => {
28767
29682
  const value = parseInt(color2.slice(index, index + 2), 16);
28768
29683
  return Math.round(value + (target2 - value) * amount).toString(16).padStart(2, "0");
@@ -28775,15 +29690,15 @@ function visioFallbackQuickStyle(style2) {
28775
29690
  case 1:
28776
29691
  return { fill: light, line: base2, font: dark };
28777
29692
  case 2:
28778
- return { fill: mix(base2, 255, 0.8), line: base2, font: dark };
29693
+ return { fill: mix2(base2, 255, 0.8), line: base2, font: dark };
28779
29694
  case 3:
28780
- return { fill: mix(base2, 255, 0.6), line: base2, font: dark };
29695
+ return { fill: mix2(base2, 255, 0.6), line: base2, font: dark };
28781
29696
  case 4:
28782
- return { fill: base2, line: mix(base2, 0, 0.25), font: light };
29697
+ return { fill: base2, line: mix2(base2, 0, 0.25), font: light };
28783
29698
  case 5:
28784
- return { fill: mix(base2, 0, 0.25), line: mix(base2, 0, 0.5), font: light };
29699
+ return { fill: mix2(base2, 0, 0.25), line: mix2(base2, 0, 0.5), font: light };
28785
29700
  default:
28786
- return { fill: mix(base2, 0, 0.5), line: mix(base2, 0, 0.5), font: light };
29701
+ return { fill: mix2(base2, 0, 0.5), line: mix2(base2, 0, 0.5), font: light };
28787
29702
  }
28788
29703
  }
28789
29704
  var rgb = (color2) => `RGB(${[1, 3, 5].map((index) => parseInt(color2.slice(index, index + 2), 16)).join(",")})`;
@@ -29087,7 +30002,11 @@ function snapshotFormatting(edit) {
29087
30002
  ["endArrow", 45, "Arrowheads are numbered 0 to 45."],
29088
30003
  ["beginArrowSize", 6, "Arrowhead sizes are numbered 0 to 6."],
29089
30004
  ["endArrowSize", 6, "Arrowhead sizes are numbered 0 to 6."],
29090
- ["lineCap", 2, "Line caps are 0 (round), 1 (square) or 2 (extended)."]
30005
+ ["lineCap", 2, "Line caps are 0 (round), 1 (square) or 2 (extended)."],
30006
+ ["lineJumpCode", 4, "Connector jump policies are numbered 0 to 4."],
30007
+ ["lineJumpStyle", 9, "Connector jump styles are numbered 0 to 9."],
30008
+ ["lineJumpDirectionX", 2, "Connector jump directions are numbered 0 to 2."],
30009
+ ["lineJumpDirectionY", 2, "Connector jump directions are numbered 0 to 2."]
29091
30010
  ]) {
29092
30011
  const value = edit[name3];
29093
30012
  if (value === void 0) continue;
@@ -29166,6 +30085,12 @@ function geometryChangedCells(edit) {
29166
30085
  if (edit.type === "flip-shape") return ["Angle", edit.axis === "horizontal" ? "FlipX" : "FlipY"];
29167
30086
  return ["PinX", "PinY", "Width", "Height"];
29168
30087
  }
30088
+ function snapshotPositionFollower(value, own) {
30089
+ if (value === void 0) return {};
30090
+ if (typeof value !== "string" || !/^[1-9]\d{0,9}$/.test(value) || Number(value) > 4294967295 || value === own)
30091
+ fail("INVALID_EDIT", "A distinct numeric owner shape ID is required.");
30092
+ return { followShapeId: value };
30093
+ }
29169
30094
  function snapshotVisioEdits(edits, maxEdits, maxText) {
29170
30095
  if (!Array.isArray(edits) || edits.length > maxEdits)
29171
30096
  fail("LIMIT_EDITS", "Edit command count exceeds limit.");
@@ -29257,6 +30182,7 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
29257
30182
  case "create-text-box":
29258
30183
  return {
29259
30184
  ...target2,
30185
+ ...snapshotPositionFollower(edit.followShapeId, edit.shapeId),
29260
30186
  type: edit.type,
29261
30187
  x: numeric5(edit.x),
29262
30188
  y: numeric5(edit.y),
@@ -29288,6 +30214,7 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
29288
30214
  fail("INVALID_EDIT", "Unknown outline shape.");
29289
30215
  return {
29290
30216
  ...target2,
30217
+ ...snapshotPositionFollower(edit.followShapeId, edit.shapeId),
29291
30218
  type: edit.type,
29292
30219
  x: numeric5(edit.x),
29293
30220
  y: numeric5(edit.y),
@@ -30314,7 +31241,7 @@ function cells2(sheet) {
30314
31241
  };
30315
31242
  for (const node2 of children2(sheet, "Cell")) add(attribute2(node2, "N") ?? "", node2);
30316
31243
  for (const section3 of children2(sheet, "Section")) {
30317
- const name3 = attribute2(section3, "N") ?? "";
31244
+ const name3 = shapeDataFormulaSection(attribute2(section3, "N") ?? "");
30318
31245
  const prefix2 = name3 === "Geometry" ? `Geometry${Number(attribute2(section3, "IX") ?? "0") + 1}` : name3;
30319
31246
  for (const node2 of children2(section3, "Cell"))
30320
31247
  add(`${prefix2}.${attribute2(node2, "N") ?? ""}`, node2);
@@ -30678,7 +31605,7 @@ function localCell(node2) {
30678
31605
  const row2 = node2.parentNode;
30679
31606
  const section3 = row2?.parentNode;
30680
31607
  if (row2?.localName === "Row" && section3?.localName === "Section") {
30681
- const name3 = attribute2(section3, "N"), rowName = attribute2(row2, "N") ?? attribute2(row2, "IX");
31608
+ const name3 = shapeDataFormulaSection(attribute2(section3, "N") ?? ""), rowName = attribute2(row2, "N") ?? attribute2(row2, "IX");
30682
31609
  if (!name3 || !rowName) return void 0;
30683
31610
  return `${name3}.${rowName}${attribute2(node2, "N") === "Value" && ["User", "Prop"].includes(name3) ? "" : `.${attribute2(node2, "N")}`}`;
30684
31611
  }
@@ -31015,6 +31942,87 @@ function addReplacementPage(pagesPart, pages, rels, types, pagePaths, parts, dir
31015
31942
  );
31016
31943
  }
31017
31944
 
31945
+ // visio/edit-alt-text.ts
31946
+ function writeShapeAltText(shape, title, description, inherited = false) {
31947
+ const sections = children2(shape, "Section").filter(
31948
+ (section4) => attribute2(section4, "N") === "User"
31949
+ );
31950
+ if (sections.length > 1 || sections[0]?.hasAttribute("Del"))
31951
+ fail("UNSUPPORTED_METADATA_EDIT", "Ambiguous or deleted User sections cannot be edited.");
31952
+ let section3 = sections[0];
31953
+ let changed = false;
31954
+ for (const [name3, value] of [
31955
+ ["visAltText", title],
31956
+ ["visAltDescription", description]
31957
+ ]) {
31958
+ const rows = children2(section3, "Row").filter((row3) => attribute2(row3, "N") === name3);
31959
+ if (rows.length > 1 || rows[0]?.hasAttribute("Del"))
31960
+ fail(
31961
+ "UNSUPPORTED_METADATA_EDIT",
31962
+ "Ambiguous or deleted accessibility rows cannot be edited."
31963
+ );
31964
+ let row2 = rows[0];
31965
+ const cells4 = children2(row2, "Cell").filter((cell2) => attribute2(cell2, "N") === "Value");
31966
+ if (cells4.length > 1 || cells4[0]?.hasAttribute("E") || executableCellFormula(attribute2(cells4[0], "F")))
31967
+ fail("UNSUPPORTED_METADATA_EDIT", "Formula-driven alternative text cannot be replaced.");
31968
+ let cell = cells4[0];
31969
+ if (attribute2(cell, "V") === value || !row2 && !value && !inherited) continue;
31970
+ const create2 = (tag) => shape.ownerDocument.createElementNS(shape.namespaceURI, tag);
31971
+ if (!section3) {
31972
+ section3 = create2("Section");
31973
+ section3.setAttribute("N", "User");
31974
+ const after = Array.from(shape.childNodes).find(
31975
+ (node2) => node2.nodeType === 1 && ["Text", "Data1", "Data2", "Data3", "ForeignData", "Shapes"].includes(
31976
+ node2.localName
31977
+ )
31978
+ );
31979
+ shape.insertBefore(section3, after ?? null);
31980
+ }
31981
+ if (!row2) {
31982
+ row2 = create2("Row");
31983
+ row2.setAttribute("N", name3);
31984
+ section3.appendChild(row2);
31985
+ }
31986
+ if (!cell) {
31987
+ cell = create2("Cell");
31988
+ cell.setAttribute("N", "Value");
31989
+ row2.insertBefore(cell, row2.firstChild);
31990
+ }
31991
+ cell.setAttribute("V", value);
31992
+ cell.setAttribute("U", "STR");
31993
+ cell.removeAttribute("F");
31994
+ changed = true;
31995
+ }
31996
+ return changed;
31997
+ }
31998
+
31999
+ // visio/edit-page-alt-text.ts
32000
+ async function setVisioPageAltText(pkg, pagesPart, pages, dirty, command2, check) {
32001
+ const page = pageById(pages, command2.pageId);
32002
+ const sheets = children2(page, "PageSheet");
32003
+ if (sheets.length > 1) fail("UNSUPPORTED_METADATA_EDIT", "Ambiguous PageSheet metadata.");
32004
+ for (const path of pkg.paths()) {
32005
+ if (!/^visio\/.*\.xml$/i.test(path)) continue;
32006
+ const part = path === pagesPart ? pages : dirty.get(path) ?? await pkg.readXml(path);
32007
+ for (const cell of Array.from(part.getElementsByTagNameNS(part.namespaceURI, "Cell"))) {
32008
+ check();
32009
+ const formula = executableCellFormula(attribute2(cell, "F"));
32010
+ if (formula && /\bUser\s*\.\s*visAlt(?:Text|Description)\b/i.test(formula))
32011
+ fail(
32012
+ "UNSUPPORTED_METADATA_EDIT",
32013
+ "A formula reads alternative text; dependent caches cannot be recalculated."
32014
+ );
32015
+ }
32016
+ }
32017
+ let sheet = sheets[0];
32018
+ if (!sheet) {
32019
+ if (!command2.title && !command2.description) return;
32020
+ sheet = page.ownerDocument.createElementNS(page.namespaceURI, "PageSheet");
32021
+ page.insertBefore(sheet, page.firstChild);
32022
+ }
32023
+ if (writeShapeAltText(sheet, command2.title, command2.description)) dirty.set(pagesPart, pages);
32024
+ }
32025
+
31018
32026
  // visio/edit-page-create.ts
31019
32027
  var officeRel2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
31020
32028
  var pageType2 = "http://schemas.microsoft.com/visio/2010/relationships/page";
@@ -31096,7 +32104,7 @@ function removeDecoration(root2, pageName, kind, pageRoots, check) {
31096
32104
  for (const shape of targets) container.removeChild(shape);
31097
32105
  return true;
31098
32106
  }
31099
- function text3(shape, cellName, value) {
32107
+ function text4(shape, cellName, value) {
31100
32108
  const node2 = shape.ownerDocument.createElementNS(shape.namespaceURI, "Cell");
31101
32109
  node2.setAttribute("N", cellName);
31102
32110
  node2.setAttribute("V", value);
@@ -31132,10 +32140,10 @@ function decorationShape(root2, document, id3, spec, ratio) {
31132
32140
  setCell(shape, "LocPinY", height / 2, "Height*0.5");
31133
32141
  setCell(shape, "Angle", 0);
31134
32142
  setCell(shape, "FillPattern", spec.fill ? 1 : 0);
31135
- if (spec.fill) text3(shape, "FillForegnd", spec.fill);
32143
+ if (spec.fill) text4(shape, "FillForegnd", spec.fill);
31136
32144
  setCell(shape, "LinePattern", spec.line ? 1 : 0);
31137
32145
  if (spec.line) {
31138
- text3(shape, "LineColor", spec.line);
32146
+ text4(shape, "LineColor", spec.line);
31139
32147
  setCell(shape, "LineWeight", 1 / 72);
31140
32148
  }
31141
32149
  setCell(shape, "ShdwPattern", 0);
@@ -31292,6 +32300,10 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
31292
32300
  for (const command2 of commands) {
31293
32301
  check();
31294
32302
  const existing = children2(pages, "Page");
32303
+ if (command2.type === "set-page-alt-text") {
32304
+ await setVisioPageAltText(pkg, pagesPart, pages, dirty, command2, check);
32305
+ continue;
32306
+ }
31295
32307
  if (command2.type === "set-page-setup") {
31296
32308
  await setVisioPageSetup(pkg, pagesPart, pages, pagePaths, dirty, command2, check);
31297
32309
  continue;
@@ -31387,7 +32399,7 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
31387
32399
  return { bytes: original, changedParts: [], diagnostics: [] };
31388
32400
  }
31389
32401
  if (commands.some(
31390
- (command2) => command2.type !== "set-page-size" && command2.type !== "set-page-setup" && command2.type !== "set-page-layout" && command2.type !== "set-snap-glue"
32402
+ (command2) => command2.type !== "set-page-size" && command2.type !== "set-page-setup" && command2.type !== "set-page-layout" && command2.type !== "set-page-alt-text" && command2.type !== "set-snap-glue"
31391
32403
  )) {
31392
32404
  await updatePageAppProperties(pkg, pages, priorCount, dirty, limits, check);
31393
32405
  await recalculatePageFormulas(pkg, pagesPart, pages, pagePaths, dirty, check);
@@ -31715,7 +32727,11 @@ function shapeFormattingWrites(edit) {
31715
32727
  ["endArrow", "EndArrow"],
31716
32728
  ["beginArrowSize", "BeginArrowSize"],
31717
32729
  ["endArrowSize", "EndArrowSize"],
31718
- ["lineCap", "LineCap"]
32730
+ ["lineCap", "LineCap"],
32731
+ ["lineJumpCode", "ConLineJumpCode"],
32732
+ ["lineJumpStyle", "ConLineJumpStyle"],
32733
+ ["lineJumpDirectionX", "ConLineJumpDirX"],
32734
+ ["lineJumpDirectionY", "ConLineJumpDirY"]
31719
32735
  ])
31720
32736
  if (edit[name3] !== void 0) add(cell, edit[name3], "LineStyle");
31721
32737
  if (edit.rounding !== void 0) add("Rounding", edit.rounding / 72, "LineStyle", "PT");
@@ -31788,6 +32804,14 @@ async function applyFormattingEdit(pkg, pagePaths, roots, document, edit, check)
31788
32804
  }
31789
32805
  async function formatTarget(pkg, pagePaths, roots, document, edit, check, instance, root2, lenient) {
31790
32806
  const shape = instance?.view ?? targetShape(root2, edit.shapeId);
32807
+ if (edit.type === "format-shape" && [edit.lineJumpCode, edit.lineJumpStyle, edit.lineJumpDirectionX, edit.lineJumpDirectionY].some(
32808
+ (value) => value !== void 0
32809
+ ) && !(children2(shape, "Cell").some(
32810
+ (cell) => attribute2(cell, "N") === "OneD" && Number(attribute2(cell, "V")) === 1
32811
+ ) || ["BeginX", "EndX"].every(
32812
+ (name3) => children2(shape, "Cell").some((cell) => attribute2(cell, "N") === name3)
32813
+ )))
32814
+ fail("INVALID_EDIT", "Line jump settings require a connector.");
31791
32815
  if (instance) {
31792
32816
  const layers = children2(shape, "Cell").find((cell) => attribute2(cell, "N") === "LayerMember");
31793
32817
  await assertInstanceLayersUnlocked(pkg, edit.pageId, attribute2(layers, "V"));
@@ -31821,7 +32845,7 @@ async function formatTarget(pkg, pagePaths, roots, document, edit, check, instan
31821
32845
  continue;
31822
32846
  throw error;
31823
32847
  }
31824
- if (/^(LinePattern|FillPattern|FillGradientEnabled|LineGradientEnabled|LineColorTrans|FillForegndTrans|FillBkgndTrans|FillBkgnd|ShdwPattern|ShdwForegndTrans|ShapeShdwType|GlowColorTrans|ReflectionTrans|ReflectionSize|QuickStyle[A-Za-z]+)$/.test(
32848
+ if (/^(ConLineJump(?:Code|Style|DirX|DirY)|LinePattern|FillPattern|FillGradientEnabled|LineGradientEnabled|LineColorTrans|FillForegndTrans|FillBkgndTrans|FillBkgnd|ShdwPattern|ShdwForegndTrans|ShapeShdwType|GlowColorTrans|ReflectionTrans|ReflectionSize|QuickStyle[A-Za-z]+)$/.test(
31825
32849
  write2.name
31826
32850
  ) && effective?.hasAttribute("U") && visioFormulaCachedValue("0", attribute2(effective, "U")).unit !== "scalar")
31827
32851
  fail(
@@ -32713,6 +33737,56 @@ function applyMetadataEdit(roots, edit, check) {
32713
33737
  return true;
32714
33738
  }
32715
33739
 
33740
+ // visio/edit-alt-text-scope.ts
33741
+ async function applyShapeAltText(pkg, pagePaths, roots, edit, check) {
33742
+ const root2 = roots.get(edit.pageId);
33743
+ if (!root2) fail("EDIT_TARGET_NOT_FOUND", "Page does not exist.");
33744
+ const target2 = textTarget(root2, edit.shapeId, check);
33745
+ const inspect6 = (part) => {
33746
+ for (const cell of Array.from(part.getElementsByTagNameNS(part.namespaceURI, "Cell"))) {
33747
+ check();
33748
+ const formula = executableCellFormula(attribute2(cell, "F"));
33749
+ if (formula && /\bUser\s*\.\s*visAlt(?:Text|Description)\b/i.test(formula))
33750
+ fail(
33751
+ "UNSUPPORTED_METADATA_EDIT",
33752
+ "A formula reads alternative text; dependent caches cannot be recalculated."
33753
+ );
33754
+ }
33755
+ };
33756
+ for (const page of roots.values()) inspect6(page);
33757
+ for (const path of pkg.paths()) {
33758
+ if (/^visio\/.*\.xml$/i.test(path) && !pagePaths.has(path)) inspect6(await pkg.readXml(path));
33759
+ }
33760
+ if (target2.masterId !== void 0) {
33761
+ const template = await masterTemplate(pkg)(target2.masterId, target2.masterShapeId);
33762
+ if (template.hasAttribute("Master") || template.hasAttribute("MasterShape"))
33763
+ fail("UNSUPPORTED_METADATA_EDIT", "Chained master accessibility metadata is not supported.");
33764
+ const inherited = template.cloneNode(true);
33765
+ for (const section3 of children2(inherited, "Section").filter(
33766
+ (section4) => attribute2(section4, "N") === "User"
33767
+ )) {
33768
+ for (const row2 of children2(section3, "Row")) {
33769
+ const localRow = children2(target2.node, "Section").filter((s) => attribute2(s, "N") === "User").flatMap((s) => children2(s, "Row")).find((r) => attribute2(r, "N") === attribute2(row2, "N"));
33770
+ const local = children2(localRow, "Cell").find((cell) => attribute2(cell, "N") === "Value");
33771
+ if (local && attribute2(local, "F") !== "Inh") {
33772
+ for (const cell of children2(row2, "Cell").filter(
33773
+ (cell2) => attribute2(cell2, "N") === "Value"
33774
+ ))
33775
+ row2.removeChild(cell);
33776
+ row2.appendChild(local.cloneNode(true));
33777
+ }
33778
+ }
33779
+ }
33780
+ writeShapeAltText(inherited, edit.title, edit.description, true);
33781
+ }
33782
+ return writeShapeAltText(
33783
+ target2.node,
33784
+ edit.title,
33785
+ edit.description,
33786
+ target2.masterId !== void 0
33787
+ );
33788
+ }
33789
+
32716
33790
  // visio/edit-picture.ts
32717
33791
  var FORMATS = {
32718
33792
  "image/png": { extension: "png", compression: "PNG" },
@@ -32924,7 +33998,7 @@ function assertParentIndependent(facts, from, ids) {
32924
33998
  }
32925
33999
 
32926
34000
  // visio/edit-group.ts
32927
- var clean2 = (value) => Math.abs(value) < 1e-12 ? 0 : value;
34001
+ var clean3 = (value) => Math.abs(value) < 1e-12 ? 0 : value;
32928
34002
  var NONE = /* @__PURE__ */ new Map();
32929
34003
  function topLevel(root2) {
32930
34004
  const containers = children2(root2, "Shapes");
@@ -33044,7 +34118,7 @@ function groupVisioShapes(root2, document, edit, check, instances = NONE) {
33044
34118
  const topmost = members3[members3.length - 1];
33045
34119
  topmost.parentNode.insertBefore(group, topmost);
33046
34120
  for (const plan of plans) {
33047
- const x = clean2(plan.pinX - minX), y = clean2(plan.pinY - minY);
34121
+ const x = clean3(plan.pinX - minX), y = clean3(plan.pinY - minY);
33048
34122
  const instance = instances.get(plan.member);
33049
34123
  if (instance) placeInstance(instance, x, y, check);
33050
34124
  else {
@@ -33117,9 +34191,9 @@ function ungroupVisioShape(root2, document, edit, check, instances = NONE) {
33117
34191
  if (Math.abs(Math.abs(angle) - Math.PI) < 1e-12) angle = Math.PI;
33118
34192
  const plan = {
33119
34193
  member,
33120
- pinX: clean2(a * box4.pinX + c * box4.pinY + e),
33121
- pinY: clean2(b * box4.pinX + d * box4.pinY + f),
33122
- angle: clean2(angle),
34194
+ pinX: clean3(a * box4.pinX + c * box4.pinY + e),
34195
+ pinY: clean3(b * box4.pinX + d * box4.pinY + f),
34196
+ angle: clean3(angle),
33123
34197
  flipX: box4.flipX !== parent.flipX ? 1 : 0,
33124
34198
  flipY: box4.flipY !== parent.flipY ? 1 : 0,
33125
34199
  box: box4
@@ -34336,9 +35410,22 @@ function positive2(value) {
34336
35410
  return value;
34337
35411
  }
34338
35412
  async function editVsdx(input, edits, options = {}) {
34339
- const clock = { deadline: 0, autoSize: /* @__PURE__ */ new Set(), textSizes: [] };
35413
+ const clock = {
35414
+ deadline: 0,
35415
+ autoSize: /* @__PURE__ */ new Set(),
35416
+ textSizes: [],
35417
+ jumpPages: /* @__PURE__ */ new Set(),
35418
+ jumpSource: void 0
35419
+ };
34340
35420
  const edited = await editVsdxTransaction(input, edits, options, clock);
34341
- const result = await refreshTextSizes(clock.textSizes, edited, options, clock.deadline);
35421
+ const resized = await refreshTextSizes(clock.textSizes, edited, options, clock.deadline);
35422
+ const result = await refreshLineJumpCaches(
35423
+ clock.jumpPages,
35424
+ clock.jumpSource,
35425
+ resized,
35426
+ options,
35427
+ clock.deadline
35428
+ );
34342
35429
  return growAutoSizePages(
34343
35430
  clock.autoSize,
34344
35431
  result,
@@ -34348,7 +35435,13 @@ async function editVsdx(input, edits, options = {}) {
34348
35435
  })
34349
35436
  );
34350
35437
  }
34351
- async function editVsdxTransaction(input, edits, options, clock = { deadline: 0, autoSize: /* @__PURE__ */ new Set(), textSizes: [] }) {
35438
+ async function editVsdxTransaction(input, edits, options, clock = {
35439
+ deadline: 0,
35440
+ autoSize: /* @__PURE__ */ new Set(),
35441
+ textSizes: [],
35442
+ jumpPages: /* @__PURE__ */ new Set(),
35443
+ jumpSource: void 0
35444
+ }) {
34352
35445
  const limits = { ...DEFAULTS, ...options.limits };
34353
35446
  for (const value of Object.values(limits)) positive2(value);
34354
35447
  const maxEdits = positive2(options.maxEdits ?? 1e3);
@@ -34360,10 +35453,14 @@ async function editVsdxTransaction(input, edits, options, clock = { deadline: 0,
34360
35453
  if (Date.now() >= deadline) fail("LIMIT_RUNTIME", "Visio edit deadline exceeded.");
34361
35454
  };
34362
35455
  const allCommands = snapshotVisioEdits(edits, maxEdits, maxText);
35456
+ for (const command2 of allCommands)
35457
+ if ((command2.type === "set-page-layout" || command2.type === "format-shape") && Object.keys(command2).some((key2) => /^lineJump|^lineToLine/.test(key2)))
35458
+ clock.jumpPages.add(command2.pageId);
34363
35459
  const commands = allCommands.filter((command2) => !isVisioPageEdit(command2));
34364
35460
  const source = input instanceof Uint8Array ? input : new Uint8Array(input);
34365
35461
  if (source.length > limits.maxInputBytes) fail("LIMIT_INPUT", "ZIP input exceeds limit.");
34366
35462
  const original = new Uint8Array(source);
35463
+ if (clock.jumpPages.size) clock.jumpSource ??= original;
34367
35464
  const subprocess = allCommands.find((command2) => command2.type === "create-subprocess");
34368
35465
  if (subprocess) {
34369
35466
  if (allCommands.length !== 1)
@@ -34630,7 +35727,7 @@ async function editVsdxTransaction(input, edits, options, clock = { deadline: 0,
34630
35727
  if (command2.type === "format-text") await noteTextSize(command2, root2);
34631
35728
  }
34632
35729
  } else if (isVisioMetadataEdit(command2)) {
34633
- if (applyMetadataEdit(roots, command2, check)) {
35730
+ if (command2.type === "set-shape-alt-text" ? await applyShapeAltText(pkg, new Set(pages.values()), roots, command2, check) : applyMetadataEdit(roots, command2, check)) {
34634
35731
  dirty.set(path, root2);
34635
35732
  metadataChanged = true;
34636
35733
  }
@@ -35015,162 +36112,6 @@ async function createVsdx(options = {}) {
35015
36112
  return writeEditedPackage(parts, DEFAULTS.maxInputBytes, deadline, check);
35016
36113
  }
35017
36114
 
35018
- // visio/line-jumps.ts
35019
- var VISIO_LINE_JUMP_WIDTH = 2 / 3 * (1 / 6);
35020
- var VISIO_LINE_JUMP_LIMITS = Object.freeze({ connectors: 2e3, segments: 2e4 });
35021
- var TOKEN = /([MLZmlz]|[A-Za-z])|([+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)/g;
35022
- function polylines(path) {
35023
- const result = [];
35024
- let command2 = "";
35025
- let pending;
35026
- for (const match of path.matchAll(TOKEN)) {
35027
- if (match[1]) {
35028
- if (match[1] !== "M" && match[1] !== "L") return void 0;
35029
- if (pending !== void 0) return void 0;
35030
- command2 = match[1];
35031
- continue;
35032
- }
35033
- const value = Number(match[2]);
35034
- if (!Number.isFinite(value) || !command2) return void 0;
35035
- if (pending === void 0) {
35036
- pending = value;
35037
- continue;
35038
- }
35039
- const point2 = { x: pending, y: value };
35040
- pending = void 0;
35041
- if (command2 === "M") {
35042
- result.push([point2]);
35043
- command2 = "L";
35044
- } else result.at(-1)?.push(point2);
35045
- }
35046
- return pending === void 0 && result.every((line) => line.length > 1) ? result : void 0;
35047
- }
35048
- var apply2 = (m, p) => ({
35049
- x: m[0] * p.x + m[2] * p.y + m[4],
35050
- y: m[1] * p.x + m[3] * p.y + m[5]
35051
- });
35052
- function invert(m) {
35053
- const det = m[0] * m[3] - m[1] * m[2];
35054
- if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return void 0;
35055
- return [
35056
- m[3] / det,
35057
- -m[1] / det,
35058
- -m[2] / det,
35059
- m[0] / det,
35060
- (m[2] * m[5] - m[3] * m[4]) / det,
35061
- (m[1] * m[4] - m[0] * m[5]) / det
35062
- ];
35063
- }
35064
- var clean3 = (value) => Math.abs(value) < 1e-9 ? 0 : Number(value.toFixed(6));
35065
- var text4 = (p) => `${clean3(p.x)} ${clean3(p.y)}`;
35066
- var horizontal = (s) => Math.abs(s.a.y - s.b.y) < 1e-6 && Math.abs(s.a.x - s.b.x) > 1e-6;
35067
- var vertical = (s) => Math.abs(s.a.x - s.b.x) < 1e-6 && Math.abs(s.a.y - s.b.y) > 1e-6;
35068
- function crossing(s, other, margin) {
35069
- const dx = s.b.x - s.a.x, dy = s.b.y - s.a.y, ox = other.b.x - other.a.x, oy = other.b.y - other.a.y;
35070
- const det = dx * oy - dy * ox;
35071
- const length = Math.hypot(dx, dy), otherLength = Math.hypot(ox, oy);
35072
- if (Math.abs(det) < 1e-9 || Math.abs(det) / (length * otherLength) < 0.2) return void 0;
35073
- const t = ((other.a.x - s.a.x) * oy - (other.a.y - s.a.y) * ox) / det;
35074
- const u = ((other.a.x - s.a.x) * dy - (other.a.y - s.a.y) * dx) / det;
35075
- if (u * otherLength < 1e-6 || (1 - u) * otherLength < 1e-6) return void 0;
35076
- if (t * length < margin || (1 - t) * length < margin) return void 0;
35077
- return t;
35078
- }
35079
- function jumps(code, s, other) {
35080
- if (code === 1) return horizontal(s) && !horizontal(other);
35081
- if (code === 2) return vertical(s) && !vertical(other);
35082
- if (code === 3 || code === 4) return s.owner > other.owner;
35083
- return code === 5 && s.owner < other.owner;
35084
- }
35085
- function jump(style2, from, to, local) {
35086
- const half = Math.hypot(to.x - from.x, to.y - from.y) / 2;
35087
- const ux = (to.x - from.x) / (2 * half), uy = (to.y - from.y) / (2 * half);
35088
- let nx = -uy, ny = ux;
35089
- if (ny < -1e-9 || Math.abs(ny) <= 1e-9 && nx > 0) {
35090
- nx = -nx;
35091
- ny = -ny;
35092
- }
35093
- const centre = { x: (from.x + to.x) / 2, y: (from.y + to.y) / 2 };
35094
- const at2 = (along, out) => local({ x: centre.x + ux * along + nx * out, y: centre.y + uy * along + ny * out });
35095
- const end = local(to);
35096
- if (style2 === 1) return `M ${text4(end)}`;
35097
- if (style2 === 2) return `L ${text4(at2(-half, half))} L ${text4(at2(half, half))} L ${text4(end)}`;
35098
- if (style2 >= 3) {
35099
- const sides = style2 - 1;
35100
- let out = "";
35101
- for (let index = 1; index < sides; ++index) {
35102
- const angle = Math.PI - Math.PI * index / sides;
35103
- out += `L ${text4(at2(Math.cos(angle) * half, Math.sin(angle) * half))} `;
35104
- }
35105
- return `${out}L ${text4(end)}`;
35106
- }
35107
- const start = local(from), top = at2(0, half);
35108
- const radius = Math.hypot(end.x - start.x, end.y - start.y) / 2;
35109
- const sweep = (end.x - start.x) * (top.y - start.y) - (end.y - start.y) * (top.x - start.x) > 0 ? 0 : 1;
35110
- return `A ${clean3(radius)} ${clean3(radius)} 0 0 ${sweep} ${text4(end)}`;
35111
- }
35112
- var connector = (shape, glued) => shape.kind === "connector" && !shape.hidden && !shape.children.length && (shape.connectorRoute !== void 0 || glued.has(shape.id));
35113
- function visioLineJumpPaths(page) {
35114
- const result = /* @__PURE__ */ new Map();
35115
- const layout = visioPageLayout(page);
35116
- const code = layout.lineJumpCode;
35117
- if (code < 1 || code > 5) return result;
35118
- const glued = new Set(page.connectors.map((connection) => connection.fromShapeId));
35119
- const shapes = page.shapes.filter((shape) => connector(shape, glued)).slice(0, VISIO_LINE_JUMP_LIMITS.connectors);
35120
- if (shapes.length < 2) return result;
35121
- const lines2 = [];
35122
- const segments = [];
35123
- shapes.forEach((shape, owner) => {
35124
- shape.geometry.forEach((geometry, index) => {
35125
- if (!geometry.stroke || geometry.fill) return;
35126
- for (const line of polylines(geometry.path) ?? []) {
35127
- const points = line.map((point2) => apply2(shape.transform, point2));
35128
- lines2.push({ shape, owner, geometry: index, points });
35129
- for (let i = 1; i < points.length; ++i)
35130
- segments.push({ a: points[i - 1], b: points[i], owner });
35131
- }
35132
- });
35133
- });
35134
- if (segments.length > VISIO_LINE_JUMP_LIMITS.segments) return result;
35135
- const half = VISIO_LINE_JUMP_WIDTH / 2;
35136
- const paths = /* @__PURE__ */ new Map();
35137
- const any = /* @__PURE__ */ new Set();
35138
- for (const line of lines2) {
35139
- const inverse = invert(line.shape.transform);
35140
- if (!inverse) continue;
35141
- const local = (point2) => apply2(inverse, point2);
35142
- let out = `M ${text4(local(line.points[0]))}`;
35143
- for (let i = 1; i < line.points.length; ++i) {
35144
- const s = { a: line.points[i - 1], b: line.points[i], owner: line.owner };
35145
- const length = Math.hypot(s.b.x - s.a.x, s.b.y - s.a.y);
35146
- const hits = segments.filter((other) => other.owner !== s.owner && jumps(code, s, other)).flatMap((other) => crossing(s, other, half * 1.5) ?? []).sort((a, b) => a - b);
35147
- let last = -Infinity;
35148
- for (const t of hits) {
35149
- if ((t - last) * length < half * 2.5) continue;
35150
- last = t;
35151
- const at2 = (offset) => ({
35152
- x: s.a.x + (s.b.x - s.a.x) * (t * length + offset) / length,
35153
- y: s.a.y + (s.b.y - s.a.y) * (t * length + offset) / length
35154
- });
35155
- out += ` L ${text4(local(at2(-half)))} ${jump(layout.lineJumpStyle, at2(-half), at2(half), local)}`;
35156
- any.add(line.shape);
35157
- }
35158
- out += ` L ${text4(local(s.b))}`;
35159
- }
35160
- const byGeometry = paths.get(line.shape) ?? /* @__PURE__ */ new Map();
35161
- byGeometry.set(line.geometry, [...byGeometry.get(line.geometry) ?? [], out]);
35162
- paths.set(line.shape, byGeometry);
35163
- }
35164
- for (const shape of any) {
35165
- const byGeometry = paths.get(shape);
35166
- result.set(
35167
- shape,
35168
- shape.geometry.map((geometry, index) => byGeometry.get(index)?.join(" ") ?? geometry.path)
35169
- );
35170
- }
35171
- return result;
35172
- }
35173
-
35174
36115
  // visio/open-arrow.ts
35175
36116
  function visioOpenArrowExtent(size3, lineWidth) {
35176
36117
  const index = Number.isFinite(size3) ? Math.max(0, Math.min(6, Math.trunc(size3))) : 2;
@@ -35263,6 +36204,31 @@ function trimVisioArrowLine(path, start, end, beginExtension = 0) {
35263
36204
  return `M ${point2(start)}${base2 > start ? ` L ${point2(base2)}` : ""} L ${point2(length - end)}`;
35264
36205
  }
35265
36206
 
36207
+ // visio/accessibility.ts
36208
+ function checkVisioAlternativeText(document) {
36209
+ const issues = [];
36210
+ for (const page of document.pages) {
36211
+ const visit = (shapes) => {
36212
+ for (const shape of shapes) {
36213
+ if (shape.hidden) continue;
36214
+ const named2 = [shape.accessibilityTitle, shape.alternativeText, shape.text.plainText].some(
36215
+ (value) => value?.trim()
36216
+ );
36217
+ if (!named2 && shape.kind !== "group")
36218
+ issues.push({
36219
+ pageId: page.id,
36220
+ shapeId: shape.id,
36221
+ shapeName: shape.name,
36222
+ code: "missing-alternative-text"
36223
+ });
36224
+ if (!named2) visit(shape.children);
36225
+ }
36226
+ };
36227
+ visit(page.shapes);
36228
+ }
36229
+ return issues;
36230
+ }
36231
+
35266
36232
  exports.VISIO_ARROW_SHAPES = VISIO_ARROW_SHAPES;
35267
36233
  exports.VISIO_BACKGROUND_STYLES = VISIO_BACKGROUND_STYLES;
35268
36234
  exports.VISIO_BASIC_SHAPES = VISIO_BASIC_SHAPES;
@@ -35324,6 +36290,7 @@ exports.VisioPackageError = VisioPackageError;
35324
36290
  exports.analyzeVisioFormula = analyzeVisioFormula;
35325
36291
  exports.canonicalShapeDataValue = canonicalShapeDataValue;
35326
36292
  exports.captureVisioClipboard = captureVisioClipboard;
36293
+ exports.checkVisioAlternativeText = checkVisioAlternativeText;
35327
36294
  exports.convertVisioMetafile = convertVisioMetafile;
35328
36295
  exports.createVsdx = createVsdx;
35329
36296
  exports.deserializeVisioClipboard = deserializeVisioClipboard;