@beyondwork/docx-react-component 1.0.29 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/package.json +65 -96
  2. package/src/README.md +85 -0
  3. package/src/api/README.md +26 -0
  4. package/src/api/public-types.ts +1952 -0
  5. package/src/api/session-state.ts +62 -0
  6. package/src/compare/diff-engine.ts +623 -0
  7. package/src/compare/export-redlines.ts +280 -0
  8. package/src/compare/index.ts +25 -0
  9. package/src/compare/snapshot.ts +97 -0
  10. package/src/component-inventory.md +99 -0
  11. package/src/core/README.md +10 -0
  12. package/src/core/commands/README.md +3 -0
  13. package/{dist/chunk-TJBP2K4T.js → src/core/commands/formatting-commands.ts} +536 -196
  14. package/src/core/commands/image-commands.ts +373 -0
  15. package/src/core/commands/index.ts +1879 -0
  16. package/src/core/commands/list-commands.ts +565 -0
  17. package/src/core/commands/paragraph-layout-commands.ts +339 -0
  18. package/src/core/commands/review-commands.ts +108 -0
  19. package/{dist/core/commands/section-layout-commands.cjs → src/core/commands/section-layout-commands.ts} +340 -137
  20. package/src/core/commands/structural-helpers.ts +309 -0
  21. package/{dist/core/commands/style-commands.cjs → src/core/commands/style-commands.ts} +113 -65
  22. package/src/core/commands/table-structure-commands.ts +854 -0
  23. package/{dist/chunk-UZXBISGO.js → src/core/commands/text-commands.ts} +142 -86
  24. package/src/core/schema/README.md +3 -0
  25. package/src/core/schema/text-schema.ts +516 -0
  26. package/src/core/search/search-text.ts +357 -0
  27. package/src/core/selection/README.md +3 -0
  28. package/src/core/selection/mapping.ts +289 -0
  29. package/src/core/selection/review-anchors.ts +183 -0
  30. package/src/core/state/README.md +3 -0
  31. package/src/core/state/editor-state.ts +892 -0
  32. package/src/core/state/text-transaction.ts +869 -0
  33. package/src/formats/xlsx/io/parse-shared-strings.ts +41 -0
  34. package/src/formats/xlsx/io/parse-sheet.ts +459 -0
  35. package/src/formats/xlsx/io/parse-styles.ts +59 -0
  36. package/src/formats/xlsx/io/parse-workbook.ts +75 -0
  37. package/src/formats/xlsx/io/serialize-shared-strings.ts +72 -0
  38. package/src/formats/xlsx/io/serialize-sheet.ts +333 -0
  39. package/src/formats/xlsx/io/serialize-styles.ts +98 -0
  40. package/src/formats/xlsx/io/serialize-workbook.ts +429 -0
  41. package/src/formats/xlsx/io/xlsx-session.ts +314 -0
  42. package/src/formats/xlsx/model/cell.ts +189 -0
  43. package/src/formats/xlsx/model/sheet.ts +326 -0
  44. package/src/formats/xlsx/model/styles.ts +118 -0
  45. package/src/formats/xlsx/model/workbook.ts +453 -0
  46. package/src/formats/xlsx/runtime/cell-commands.ts +567 -0
  47. package/src/formats/xlsx/runtime/sheet-commands.ts +206 -0
  48. package/src/formats/xlsx/runtime/workbook-runtime.ts +177 -0
  49. package/src/formats/xlsx/runtime/workbook-transaction.ts +822 -0
  50. package/src/index.ts +142 -0
  51. package/src/io/README.md +10 -0
  52. package/src/io/docx-session.ts +3175 -0
  53. package/src/io/export/README.md +3 -0
  54. package/src/io/export/export-session.ts +220 -0
  55. package/src/io/export/minimal-docx.ts +115 -0
  56. package/src/io/export/reattach-preserved-parts.ts +54 -0
  57. package/src/io/export/serialize-comments.ts +947 -0
  58. package/src/io/export/serialize-footnotes.ts +394 -0
  59. package/src/io/export/serialize-headers-footers.ts +368 -0
  60. package/src/io/export/serialize-main-document.ts +1342 -0
  61. package/src/io/export/serialize-numbering.ts +218 -0
  62. package/src/io/export/serialize-revisions.ts +389 -0
  63. package/src/io/export/serialize-runtime-revisions.ts +463 -0
  64. package/src/io/export/serialize-tables.ts +174 -0
  65. package/src/io/export/split-review-boundaries.ts +356 -0
  66. package/src/io/export/split-story-blocks-for-runtime-revisions.ts +252 -0
  67. package/src/io/export/table-properties-xml.ts +318 -0
  68. package/src/io/normalize/README.md +3 -0
  69. package/src/io/normalize/normalize-text.ts +670 -0
  70. package/src/io/ooxml/README.md +3 -0
  71. package/src/io/ooxml/highlight-colors.ts +39 -0
  72. package/src/io/ooxml/numbering-sentinels.ts +44 -0
  73. package/src/io/ooxml/parse-comments.ts +852 -0
  74. package/src/io/ooxml/parse-complex-content.ts +287 -0
  75. package/src/io/ooxml/parse-fields.ts +834 -0
  76. package/src/io/ooxml/parse-footnotes.ts +952 -0
  77. package/src/io/ooxml/parse-headers-footers.ts +1212 -0
  78. package/src/io/ooxml/parse-inline-media.ts +461 -0
  79. package/src/io/ooxml/parse-main-document.ts +2947 -0
  80. package/src/io/ooxml/parse-numbering.ts +747 -0
  81. package/src/io/ooxml/parse-revisions.ts +1045 -0
  82. package/src/io/ooxml/parse-settings.ts +184 -0
  83. package/src/io/ooxml/parse-shapes.ts +296 -0
  84. package/src/io/ooxml/parse-styles.ts +639 -0
  85. package/src/io/ooxml/parse-tables.ts +627 -0
  86. package/src/io/ooxml/parse-theme.ts +346 -0
  87. package/src/io/ooxml/part-manifest.ts +136 -0
  88. package/src/io/ooxml/revision-boundaries.ts +475 -0
  89. package/src/io/ooxml/workflow-payload.ts +544 -0
  90. package/src/io/opc/README.md +3 -0
  91. package/src/io/opc/corrupt-package.ts +166 -0
  92. package/src/io/opc/docx-package.ts +74 -0
  93. package/src/io/opc/package-reader.ts +325 -0
  94. package/src/io/opc/package-writer.ts +273 -0
  95. package/src/io/source-package-provenance.ts +241 -0
  96. package/{dist/chunk-RMH72RZI.js → src/legal/bookmarks.ts} +130 -44
  97. package/src/legal/cross-references.ts +414 -0
  98. package/src/legal/defined-terms.ts +203 -0
  99. package/src/legal/index.ts +32 -0
  100. package/src/legal/signature-blocks.ts +259 -0
  101. package/src/model/README.md +3 -0
  102. package/src/model/canonical-document.ts +2722 -0
  103. package/src/model/cds-1.0.0.ts +212 -0
  104. package/src/model/snapshot.ts +760 -0
  105. package/src/preservation/README.md +3 -0
  106. package/src/preservation/markup-compatibility.ts +48 -0
  107. package/src/preservation/opaque-fragment-store.ts +89 -0
  108. package/src/preservation/opaque-region.ts +233 -0
  109. package/src/preservation/package-preservation.ts +113 -0
  110. package/src/preservation/preserved-part-manifest.ts +56 -0
  111. package/src/preservation/relationship-retention.ts +57 -0
  112. package/src/preservation/store.ts +255 -0
  113. package/src/review/README.md +16 -0
  114. package/src/review/store/README.md +3 -0
  115. package/src/review/store/comment-anchors.ts +70 -0
  116. package/src/review/store/comment-remapping.ts +154 -0
  117. package/src/review/store/comment-store.ts +349 -0
  118. package/src/review/store/comment-thread.ts +109 -0
  119. package/src/review/store/revision-actions.ts +423 -0
  120. package/src/review/store/revision-store.ts +323 -0
  121. package/src/review/store/revision-types.ts +182 -0
  122. package/src/review/store/runtime-comment-store.ts +43 -0
  123. package/src/runtime/README.md +3 -0
  124. package/src/runtime/ai-action-policy.ts +764 -0
  125. package/src/runtime/context-analytics.ts +824 -0
  126. package/src/runtime/document-layout.ts +332 -0
  127. package/src/runtime/document-locations.ts +521 -0
  128. package/src/runtime/document-navigation.ts +616 -0
  129. package/src/runtime/document-outline.ts +440 -0
  130. package/src/runtime/document-runtime.ts +4055 -0
  131. package/src/runtime/document-search.ts +145 -0
  132. package/src/runtime/event-refresh-hints.ts +137 -0
  133. package/src/runtime/numbering-prefix.ts +244 -0
  134. package/src/runtime/page-layout-estimation.ts +305 -0
  135. package/src/runtime/read-only-diagnostics-runtime.ts +241 -0
  136. package/src/runtime/resolved-numbering-geometry.ts +293 -0
  137. package/src/runtime/review-runtime.ts +44 -0
  138. package/src/runtime/revision-runtime.ts +107 -0
  139. package/src/runtime/session-capabilities.ts +192 -0
  140. package/src/runtime/story-context.ts +164 -0
  141. package/src/runtime/story-targeting.ts +162 -0
  142. package/src/runtime/suggestions-snapshot.ts +137 -0
  143. package/src/runtime/surface-projection.ts +1553 -0
  144. package/src/runtime/table-commands.ts +173 -0
  145. package/src/runtime/table-schema.ts +309 -0
  146. package/src/runtime/table-style-resolver.ts +409 -0
  147. package/src/runtime/view-state.ts +493 -0
  148. package/src/runtime/virtualized-rendering.ts +258 -0
  149. package/src/runtime/workflow-markup.ts +393 -0
  150. package/src/ui/README.md +30 -0
  151. package/src/ui/WordReviewEditor.tsx +5268 -0
  152. package/src/ui/browser-export.ts +52 -0
  153. package/src/ui/comments/README.md +3 -0
  154. package/src/ui/compatibility/README.md +3 -0
  155. package/src/ui/editor-command-bag.ts +127 -0
  156. package/src/ui/editor-runtime-boundary.ts +1558 -0
  157. package/src/ui/editor-shell-view.tsx +144 -0
  158. package/src/ui/editor-surface/README.md +3 -0
  159. package/src/ui/editor-surface-controller.tsx +66 -0
  160. package/src/ui/headless/comment-decoration-model.ts +124 -0
  161. package/src/ui/headless/preserve-editor-selection.ts +5 -0
  162. package/src/ui/headless/revision-decoration-model.ts +128 -0
  163. package/src/ui/headless/selection-helpers.ts +54 -0
  164. package/src/ui/headless/selection-tool-context.ts +19 -0
  165. package/src/ui/headless/selection-tool-resolver.ts +752 -0
  166. package/src/ui/headless/selection-tool-types.ts +129 -0
  167. package/src/ui/headless/selection-toolbar-model.ts +11 -0
  168. package/src/ui/headless/use-editor-keyboard.ts +103 -0
  169. package/src/ui/review/README.md +3 -0
  170. package/src/ui/runtime-shortcut-dispatch.ts +365 -0
  171. package/src/ui/runtime-snapshot-selectors.ts +197 -0
  172. package/src/ui/shared/revision-filters.ts +31 -0
  173. package/src/ui/status/README.md +3 -0
  174. package/src/ui/theme/README.md +3 -0
  175. package/src/ui/toolbar/README.md +3 -0
  176. package/src/ui/workflow-surface-blocked-rails.ts +94 -0
  177. package/src/ui-tailwind/chrome/chrome-preset-model.ts +107 -0
  178. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +15 -0
  179. package/src/ui-tailwind/chrome/responsive-chrome.ts +46 -0
  180. package/src/ui-tailwind/chrome/review-queue-bar.tsx +97 -0
  181. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +64 -0
  182. package/src/ui-tailwind/chrome/tw-context-analytics-summary.tsx +122 -0
  183. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +121 -0
  184. package/src/ui-tailwind/chrome/tw-layout-panel.tsx +114 -0
  185. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +30 -0
  186. package/src/ui-tailwind/chrome/tw-page-ruler.tsx +365 -0
  187. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +23 -0
  188. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +35 -0
  189. package/src/ui-tailwind/chrome/tw-selection-tool-formatting.tsx +37 -0
  190. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +303 -0
  191. package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +116 -0
  192. package/src/ui-tailwind/chrome/tw-selection-tool-suggestion.tsx +29 -0
  193. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +27 -0
  194. package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +186 -0
  195. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +139 -0
  196. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +250 -0
  197. package/src/ui-tailwind/chrome/tw-unsaved-modal.tsx +58 -0
  198. package/src/ui-tailwind/chrome/use-before-unload.ts +20 -0
  199. package/src/ui-tailwind/editor-surface/perf-probe.ts +179 -0
  200. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +189 -0
  201. package/src/ui-tailwind/editor-surface/pm-contextual-ui.ts +31 -0
  202. package/src/ui-tailwind/editor-surface/pm-decorations.ts +411 -0
  203. package/src/ui-tailwind/editor-surface/pm-position-map.ts +123 -0
  204. package/src/ui-tailwind/editor-surface/pm-schema.ts +927 -0
  205. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +567 -0
  206. package/src/ui-tailwind/editor-surface/search-plugin.ts +168 -0
  207. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +63 -0
  208. package/src/ui-tailwind/editor-surface/tw-caret.tsx +12 -0
  209. package/src/ui-tailwind/editor-surface/tw-editor-surface.tsx +150 -0
  210. package/src/ui-tailwind/editor-surface/tw-inline-token.tsx +129 -0
  211. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +58 -0
  212. package/src/ui-tailwind/editor-surface/tw-paragraph-block.tsx +151 -0
  213. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +1047 -0
  214. package/src/ui-tailwind/editor-surface/tw-segment-view.tsx +111 -0
  215. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +503 -0
  216. package/src/ui-tailwind/index.ts +62 -0
  217. package/src/ui-tailwind/page-chrome-model.ts +27 -0
  218. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +406 -0
  219. package/src/ui-tailwind/review/tw-health-panel.tsx +149 -0
  220. package/src/ui-tailwind/review/tw-review-rail.tsx +130 -0
  221. package/src/ui-tailwind/review/tw-revision-sidebar.tsx +164 -0
  222. package/src/ui-tailwind/status/tw-status-bar.tsx +65 -0
  223. package/{dist → src}/ui-tailwind/theme/editor-theme.css +58 -40
  224. package/src/ui-tailwind/toolbar/toolbar-layout.ts +47 -0
  225. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +52 -0
  226. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +1478 -0
  227. package/src/ui-tailwind/tw-review-workspace.tsx +1587 -0
  228. package/src/validation/README.md +3 -0
  229. package/src/validation/compatibility-engine.ts +878 -0
  230. package/src/validation/compatibility-report.ts +161 -0
  231. package/src/validation/diagnostics.ts +204 -0
  232. package/src/validation/docx-comment-proof.ts +720 -0
  233. package/src/validation/import-diagnostics.ts +128 -0
  234. package/src/validation/low-priority-word-surfaces.ts +373 -0
  235. package/dist/canonical-document-BLEbzL2J.d.cts +0 -844
  236. package/dist/canonical-document-BLEbzL2J.d.ts +0 -844
  237. package/dist/chunk-2FJS5GZM.js +0 -763
  238. package/dist/chunk-2FJS5GZM.js.map +0 -1
  239. package/dist/chunk-2OQBZS3F.js +0 -446
  240. package/dist/chunk-2OQBZS3F.js.map +0 -1
  241. package/dist/chunk-2S7W4KFO.js +0 -127
  242. package/dist/chunk-2S7W4KFO.js.map +0 -1
  243. package/dist/chunk-2TG72QSW.js +0 -3874
  244. package/dist/chunk-2TG72QSW.js.map +0 -1
  245. package/dist/chunk-36QNIZBO.js +0 -532
  246. package/dist/chunk-36QNIZBO.js.map +0 -1
  247. package/dist/chunk-4AQOYAW4.js +0 -3069
  248. package/dist/chunk-4AQOYAW4.js.map +0 -1
  249. package/dist/chunk-4D5EWJ3P.js +0 -77
  250. package/dist/chunk-4D5EWJ3P.js.map +0 -1
  251. package/dist/chunk-5FN54NDH.js +0 -2257
  252. package/dist/chunk-5FN54NDH.js.map +0 -1
  253. package/dist/chunk-BOYGQYRQ.js +0 -7306
  254. package/dist/chunk-BOYGQYRQ.js.map +0 -1
  255. package/dist/chunk-CN3XMECL.js +0 -212
  256. package/dist/chunk-CN3XMECL.js.map +0 -1
  257. package/dist/chunk-EBI3BX6U.js +0 -164
  258. package/dist/chunk-EBI3BX6U.js.map +0 -1
  259. package/dist/chunk-EILUG3VB.js +0 -1275
  260. package/dist/chunk-EILUG3VB.js.map +0 -1
  261. package/dist/chunk-FUDY333O.js +0 -70
  262. package/dist/chunk-FUDY333O.js.map +0 -1
  263. package/dist/chunk-GBVOWFIK.js +0 -1237
  264. package/dist/chunk-GBVOWFIK.js.map +0 -1
  265. package/dist/chunk-H4TQ3H3Y.js +0 -262
  266. package/dist/chunk-H4TQ3H3Y.js.map +0 -1
  267. package/dist/chunk-JGB3IXZO.js +0 -189
  268. package/dist/chunk-JGB3IXZO.js.map +0 -1
  269. package/dist/chunk-KD2QRQPY.js +0 -4342
  270. package/dist/chunk-KD2QRQPY.js.map +0 -1
  271. package/dist/chunk-KLMXQVYK.js +0 -369
  272. package/dist/chunk-KLMXQVYK.js.map +0 -1
  273. package/dist/chunk-KZUG5KFQ.js +0 -214
  274. package/dist/chunk-KZUG5KFQ.js.map +0 -1
  275. package/dist/chunk-QDAQ4CJU.js +0 -345
  276. package/dist/chunk-QDAQ4CJU.js.map +0 -1
  277. package/dist/chunk-RMH72RZI.js.map +0 -1
  278. package/dist/chunk-SWKWQZXM.js +0 -117
  279. package/dist/chunk-SWKWQZXM.js.map +0 -1
  280. package/dist/chunk-TJBP2K4T.js.map +0 -1
  281. package/dist/chunk-TLCEAQDQ.js +0 -542
  282. package/dist/chunk-TLCEAQDQ.js.map +0 -1
  283. package/dist/chunk-UZXBISGO.js.map +0 -1
  284. package/dist/chunk-WGBAKP3Q.js +0 -3220
  285. package/dist/chunk-WGBAKP3Q.js.map +0 -1
  286. package/dist/compare/index.cjs +0 -5475
  287. package/dist/compare/index.cjs.map +0 -1
  288. package/dist/compare/index.d.cts +0 -114
  289. package/dist/compare/index.d.ts +0 -114
  290. package/dist/compare/index.js +0 -731
  291. package/dist/compare/index.js.map +0 -1
  292. package/dist/core/commands/formatting-commands.cjs +0 -828
  293. package/dist/core/commands/formatting-commands.cjs.map +0 -1
  294. package/dist/core/commands/formatting-commands.d.cts +0 -63
  295. package/dist/core/commands/formatting-commands.d.ts +0 -63
  296. package/dist/core/commands/formatting-commands.js +0 -37
  297. package/dist/core/commands/formatting-commands.js.map +0 -1
  298. package/dist/core/commands/image-commands.cjs +0 -2023
  299. package/dist/core/commands/image-commands.cjs.map +0 -1
  300. package/dist/core/commands/image-commands.d.cts +0 -58
  301. package/dist/core/commands/image-commands.d.ts +0 -58
  302. package/dist/core/commands/image-commands.js +0 -18
  303. package/dist/core/commands/image-commands.js.map +0 -1
  304. package/dist/core/commands/section-layout-commands.cjs.map +0 -1
  305. package/dist/core/commands/section-layout-commands.d.cts +0 -62
  306. package/dist/core/commands/section-layout-commands.d.ts +0 -62
  307. package/dist/core/commands/section-layout-commands.js +0 -21
  308. package/dist/core/commands/section-layout-commands.js.map +0 -1
  309. package/dist/core/commands/style-commands.cjs.map +0 -1
  310. package/dist/core/commands/style-commands.d.cts +0 -13
  311. package/dist/core/commands/style-commands.d.ts +0 -13
  312. package/dist/core/commands/style-commands.js +0 -9
  313. package/dist/core/commands/style-commands.js.map +0 -1
  314. package/dist/core/commands/table-structure-commands.cjs +0 -1883
  315. package/dist/core/commands/table-structure-commands.cjs.map +0 -1
  316. package/dist/core/commands/table-structure-commands.d.cts +0 -59
  317. package/dist/core/commands/table-structure-commands.d.ts +0 -59
  318. package/dist/core/commands/table-structure-commands.js +0 -12
  319. package/dist/core/commands/table-structure-commands.js.map +0 -1
  320. package/dist/core/commands/text-commands.cjs +0 -2391
  321. package/dist/core/commands/text-commands.cjs.map +0 -1
  322. package/dist/core/commands/text-commands.d.cts +0 -24
  323. package/dist/core/commands/text-commands.d.ts +0 -24
  324. package/dist/core/commands/text-commands.js +0 -28
  325. package/dist/core/commands/text-commands.js.map +0 -1
  326. package/dist/core/selection/mapping.cjs +0 -200
  327. package/dist/core/selection/mapping.cjs.map +0 -1
  328. package/dist/core/selection/mapping.d.cts +0 -2
  329. package/dist/core/selection/mapping.d.ts +0 -2
  330. package/dist/core/selection/mapping.js +0 -31
  331. package/dist/core/selection/mapping.js.map +0 -1
  332. package/dist/core/state/editor-state.cjs +0 -2278
  333. package/dist/core/state/editor-state.cjs.map +0 -1
  334. package/dist/core/state/editor-state.d.cts +0 -2
  335. package/dist/core/state/editor-state.d.ts +0 -2
  336. package/dist/core/state/editor-state.js +0 -26
  337. package/dist/core/state/editor-state.js.map +0 -1
  338. package/dist/index.cjs +0 -38553
  339. package/dist/index.cjs.map +0 -1
  340. package/dist/index.d.cts +0 -15
  341. package/dist/index.d.ts +0 -15
  342. package/dist/index.js +0 -7856
  343. package/dist/index.js.map +0 -1
  344. package/dist/io/docx-session.cjs +0 -16236
  345. package/dist/io/docx-session.cjs.map +0 -1
  346. package/dist/io/docx-session.d.cts +0 -21
  347. package/dist/io/docx-session.d.ts +0 -21
  348. package/dist/io/docx-session.js +0 -18
  349. package/dist/io/docx-session.js.map +0 -1
  350. package/dist/legal/index.cjs +0 -3900
  351. package/dist/legal/index.cjs.map +0 -1
  352. package/dist/legal/index.d.cts +0 -86
  353. package/dist/legal/index.d.ts +0 -86
  354. package/dist/legal/index.js +0 -616
  355. package/dist/legal/index.js.map +0 -1
  356. package/dist/public-types-7ZL_94cz.d.ts +0 -1573
  357. package/dist/public-types-CeMaDueh.d.cts +0 -1573
  358. package/dist/public-types.cjs +0 -19
  359. package/dist/public-types.cjs.map +0 -1
  360. package/dist/public-types.d.cts +0 -2
  361. package/dist/public-types.d.ts +0 -2
  362. package/dist/public-types.js +0 -1
  363. package/dist/public-types.js.map +0 -1
  364. package/dist/runtime/document-runtime.cjs +0 -11140
  365. package/dist/runtime/document-runtime.cjs.map +0 -1
  366. package/dist/runtime/document-runtime.d.cts +0 -231
  367. package/dist/runtime/document-runtime.d.ts +0 -231
  368. package/dist/runtime/document-runtime.js +0 -21
  369. package/dist/runtime/document-runtime.js.map +0 -1
  370. package/dist/structural-helpers-CilgOVhh.d.cts +0 -10
  371. package/dist/structural-helpers-q0Gd-eBN.d.ts +0 -10
  372. package/dist/ui-tailwind/editor-surface/search-plugin.cjs +0 -313
  373. package/dist/ui-tailwind/editor-surface/search-plugin.cjs.map +0 -1
  374. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +0 -67
  375. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +0 -67
  376. package/dist/ui-tailwind/editor-surface/search-plugin.js +0 -23
  377. package/dist/ui-tailwind/editor-surface/search-plugin.js.map +0 -1
  378. package/dist/ui-tailwind/index.cjs +0 -4833
  379. package/dist/ui-tailwind/index.cjs.map +0 -1
  380. package/dist/ui-tailwind/index.d.cts +0 -617
  381. package/dist/ui-tailwind/index.d.ts +0 -617
  382. package/dist/ui-tailwind/index.js +0 -575
  383. package/dist/ui-tailwind/index.js.map +0 -1
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Parses xl/sharedStrings.xml and returns the shared string table as an ordered array.
3
+ *
4
+ * Handles both simple text (<si><t>...</t></si>) and rich text runs
5
+ * (<si><r><t>...</t></r></si>) by concatenating all <t> content within each <si>.
6
+ */
7
+ export function parseSharedStringsXml(xml: string): string[] {
8
+ const result: string[] = [];
9
+ const siPattern = /<si>([\s\S]*?)<\/si>/g;
10
+ let siMatch: RegExpExecArray | null;
11
+
12
+ while ((siMatch = siPattern.exec(xml)) !== null) {
13
+ const siContent = siMatch[1] ?? "";
14
+ result.push(extractSharedStringText(siContent));
15
+ }
16
+
17
+ return result;
18
+ }
19
+
20
+ function extractSharedStringText(siContent: string): string {
21
+ // Collect text from all <t> elements (handles plain and rich text runs).
22
+ // The xml:space="preserve" attribute is not significant for the string value.
23
+ const tPattern = /<t(?:\s[^>]*)?>([^<]*)<\/t>/g;
24
+ const parts: string[] = [];
25
+ let tMatch: RegExpExecArray | null;
26
+
27
+ while ((tMatch = tPattern.exec(siContent)) !== null) {
28
+ parts.push(decodeXmlEntities(tMatch[1] ?? ""));
29
+ }
30
+
31
+ return parts.join("");
32
+ }
33
+
34
+ export function decodeXmlEntities(value: string): string {
35
+ return value
36
+ .replace(/&quot;/g, '"')
37
+ .replace(/&apos;/g, "'")
38
+ .replace(/&lt;/g, "<")
39
+ .replace(/&gt;/g, ">")
40
+ .replace(/&amp;/g, "&");
41
+ }
@@ -0,0 +1,459 @@
1
+ import { decodeXmlEntities } from "./parse-shared-strings.ts";
2
+ import { parseXmlAttributes } from "./parse-styles.ts";
3
+
4
+ // Re-export for external use
5
+ export { decodeXmlEntities };
6
+
7
+ /**
8
+ * A parsed cell from a SpreadsheetML worksheet.
9
+ *
10
+ * Row and col are zero-based indices. The value discriminated union covers all
11
+ * SpreadsheetML cell type codes: s (shared string), inlineStr, n/absent (number),
12
+ * b (boolean), e (error), str (formula string result), and blank.
13
+ */
14
+ export type XlsxParsedCellValue =
15
+ | { type: "blank" }
16
+ | { type: "text"; value: string; fromSharedString: boolean }
17
+ | { type: "number"; value: number }
18
+ | { type: "boolean"; value: boolean }
19
+ | {
20
+ type: "formula";
21
+ formula: string;
22
+ referenceTokens: string[];
23
+ cachedValue: XlsxParsedFormulaCachedValue | null;
24
+ }
25
+ | { type: "error"; errorCode: string };
26
+
27
+ export type XlsxParsedFormulaCachedValue =
28
+ | { type: "blank" }
29
+ | { type: "text"; value: string }
30
+ | { type: "number"; value: number }
31
+ | { type: "boolean"; value: boolean }
32
+ | { type: "error"; errorCode: string };
33
+
34
+ export interface XlsxParsedCell {
35
+ row: number;
36
+ col: number;
37
+ value: XlsxParsedCellValue;
38
+ styleIndex: number | null;
39
+ }
40
+
41
+ /**
42
+ * A parsed merge range from the <mergeCells> section.
43
+ * All indices are zero-based.
44
+ */
45
+ export interface XlsxParsedMerge {
46
+ startRow: number;
47
+ startCol: number;
48
+ endRow: number;
49
+ endCol: number;
50
+ }
51
+
52
+ export interface XlsxParsedDimension {
53
+ startRow: number;
54
+ startCol: number;
55
+ endRow: number;
56
+ endCol: number;
57
+ }
58
+
59
+ export interface SheetParseResult {
60
+ cells: XlsxParsedCell[];
61
+ merges: XlsxParsedMerge[];
62
+ dimension: XlsxParsedDimension | null;
63
+ }
64
+
65
+ /**
66
+ * Parses xl/worksheets/sheetN.xml.
67
+ *
68
+ * @param xml - Raw XML string of the worksheet part.
69
+ * @param sharedStrings - The shared string table from parseSharedStringsXml.
70
+ */
71
+ export function parseSheetXml(
72
+ xml: string,
73
+ sharedStrings: readonly string[],
74
+ ): SheetParseResult {
75
+ const cells: XlsxParsedCell[] = [];
76
+ const merges: XlsxParsedMerge[] = [];
77
+ const dimension = parseSheetDimension(xml);
78
+
79
+ const sheetDataMatch = /<sheetData>([\s\S]*?)<\/sheetData>/i.exec(xml);
80
+ if (sheetDataMatch) {
81
+ parseSheetData(sheetDataMatch[1] ?? "", sharedStrings, cells);
82
+ }
83
+
84
+ const mergeCellsMatch = /<mergeCells\b[^>]*>([\s\S]*?)<\/mergeCells>/i.exec(xml);
85
+ if (mergeCellsMatch) {
86
+ parseMergeCells(mergeCellsMatch[1] ?? "", merges);
87
+ }
88
+
89
+ return { cells, merges, dimension };
90
+ }
91
+
92
+ function parseSheetData(
93
+ sheetDataXml: string,
94
+ sharedStrings: readonly string[],
95
+ out: XlsxParsedCell[],
96
+ ): void {
97
+ // Match non-empty rows (<row ...>...</row>)
98
+ const rowPattern = /<row\b([^>]*)>([\s\S]*?)<\/row>/g;
99
+ let rowMatch: RegExpExecArray | null;
100
+
101
+ while ((rowMatch = rowPattern.exec(sheetDataXml)) !== null) {
102
+ const rowContent = rowMatch[2] ?? "";
103
+ parseRowCells(rowContent, sharedStrings, out);
104
+ }
105
+ }
106
+
107
+ function parseRowCells(
108
+ rowXml: string,
109
+ sharedStrings: readonly string[],
110
+ out: XlsxParsedCell[],
111
+ ): void {
112
+ // Match cells: both non-empty (<c ...>...</c>) and self-closing (<c .../>)
113
+ const cellPattern = /<c\b([^>]*)(?:>([\s\S]*?)<\/c>|\/>)/g;
114
+ let cellMatch: RegExpExecArray | null;
115
+
116
+ while ((cellMatch = cellPattern.exec(rowXml)) !== null) {
117
+ const attrs = parseXmlAttributes(cellMatch[1] ?? "");
118
+ const content = cellMatch[2] ?? "";
119
+ const cell = parseCell(attrs, content, sharedStrings);
120
+ if (cell !== null) {
121
+ out.push(cell);
122
+ }
123
+ }
124
+ }
125
+
126
+ function parseCell(
127
+ attrs: Record<string, string>,
128
+ content: string,
129
+ sharedStrings: readonly string[],
130
+ ): XlsxParsedCell | null {
131
+ const ref = attrs["r"];
132
+ if (!ref) {
133
+ return null;
134
+ }
135
+
136
+ const cellRef = parseCellRef(ref);
137
+ if (cellRef === null) {
138
+ return null;
139
+ }
140
+
141
+ const styleIndexAttr = attrs["s"];
142
+ const styleIndex =
143
+ styleIndexAttr !== undefined ? parseInt(styleIndexAttr, 10) : null;
144
+
145
+ const typeCode = attrs["t"] ?? "n";
146
+ const rawValue = extractTextContent(content, "v");
147
+ const formulaText = extractTextContent(content, "f");
148
+ const inlineText = extractInlineStringText(content);
149
+
150
+ const value = resolveCellValue(typeCode, rawValue, formulaText, inlineText, sharedStrings);
151
+
152
+ return {
153
+ row: cellRef.row,
154
+ col: cellRef.col,
155
+ value,
156
+ styleIndex: styleIndex !== null && !Number.isNaN(styleIndex) ? styleIndex : null,
157
+ };
158
+ }
159
+
160
+ function resolveCellValue(
161
+ typeCode: string,
162
+ rawValue: string | null,
163
+ formulaText: string | null,
164
+ inlineText: string | null,
165
+ sharedStrings: readonly string[],
166
+ ): XlsxParsedCellValue {
167
+ // Formula cells may have any result type; store formula + cached value.
168
+ if (formulaText !== null) {
169
+ const decodedFormula = decodeXmlEntities(formulaText);
170
+ return {
171
+ type: "formula",
172
+ formula: decodedFormula,
173
+ referenceTokens: extractFormulaReferenceTokens(decodedFormula),
174
+ cachedValue: resolveFormulaCachedValue(typeCode, rawValue, inlineText, sharedStrings),
175
+ };
176
+ }
177
+
178
+ switch (typeCode) {
179
+ case "s": {
180
+ // Shared string reference
181
+ const index = rawValue !== null ? parseInt(rawValue, 10) : NaN;
182
+ const text =
183
+ !Number.isNaN(index) && index >= 0 && index < sharedStrings.length
184
+ ? (sharedStrings[index] ?? "")
185
+ : "";
186
+ return { type: "text", value: text, fromSharedString: true };
187
+ }
188
+
189
+ case "inlineStr": {
190
+ return { type: "text", value: inlineText ?? "", fromSharedString: false };
191
+ }
192
+
193
+ case "str": {
194
+ // Formula result is a string; formula text would have been captured above.
195
+ // Here the cell carries only the cached string value (no formula tag).
196
+ return {
197
+ type: "text",
198
+ value: rawValue !== null ? decodeXmlEntities(rawValue) : "",
199
+ fromSharedString: false,
200
+ };
201
+ }
202
+
203
+ case "b": {
204
+ return { type: "boolean", value: rawValue === "1" };
205
+ }
206
+
207
+ case "e": {
208
+ return {
209
+ type: "error",
210
+ errorCode:
211
+ rawValue !== null ? decodeXmlEntities(rawValue) : "#ERROR!",
212
+ };
213
+ }
214
+
215
+ default: {
216
+ // "n" or absent — numeric value
217
+ if (rawValue === null || rawValue === "") {
218
+ return { type: "blank" };
219
+ }
220
+
221
+ const numericValue = parseFloat(rawValue);
222
+ return Number.isNaN(numericValue)
223
+ ? { type: "blank" }
224
+ : { type: "number", value: numericValue };
225
+ }
226
+ }
227
+ }
228
+
229
+ function resolveFormulaCachedValue(
230
+ typeCode: string,
231
+ rawValue: string | null,
232
+ inlineText: string | null,
233
+ sharedStrings: readonly string[],
234
+ ): XlsxParsedFormulaCachedValue | null {
235
+ switch (typeCode) {
236
+ case "s": {
237
+ const index = rawValue !== null ? parseInt(rawValue, 10) : NaN;
238
+ return {
239
+ type: "text",
240
+ value:
241
+ !Number.isNaN(index) && index >= 0 && index < sharedStrings.length
242
+ ? (sharedStrings[index] ?? "")
243
+ : "",
244
+ };
245
+ }
246
+
247
+ case "inlineStr":
248
+ return { type: "text", value: inlineText ?? "" };
249
+
250
+ case "str":
251
+ return rawValue === null
252
+ ? { type: "blank" }
253
+ : { type: "text", value: decodeXmlEntities(rawValue) };
254
+
255
+ case "b":
256
+ return rawValue === null
257
+ ? { type: "blank" }
258
+ : { type: "boolean", value: rawValue === "1" };
259
+
260
+ case "e":
261
+ return rawValue === null
262
+ ? { type: "blank" }
263
+ : { type: "error", errorCode: decodeXmlEntities(rawValue) };
264
+
265
+ default: {
266
+ if (rawValue === null || rawValue === "") {
267
+ return { type: "blank" };
268
+ }
269
+
270
+ const numericValue = Number(rawValue);
271
+ if (!Number.isNaN(numericValue)) {
272
+ return { type: "number", value: numericValue };
273
+ }
274
+
275
+ if (rawValue === "TRUE" || rawValue === "FALSE") {
276
+ return { type: "boolean", value: rawValue === "TRUE" };
277
+ }
278
+
279
+ return { type: "text", value: decodeXmlEntities(rawValue) };
280
+ }
281
+ }
282
+ }
283
+
284
+ function extractTextContent(xml: string, tagName: string): string | null {
285
+ const pattern = new RegExp(`<${tagName}(?:\\s[^>]*)?>([^<]*)</${tagName}>`, "i");
286
+ const match = pattern.exec(xml);
287
+ return match ? (match[1] ?? null) : null;
288
+ }
289
+
290
+ function extractInlineStringText(cellContent: string): string | null {
291
+ // <is> contains rich text identical to shared string runs
292
+ const isMatch = /<is>([\s\S]*?)<\/is>/i.exec(cellContent);
293
+ if (!isMatch) {
294
+ return null;
295
+ }
296
+
297
+ const tPattern = /<t(?:\s[^>]*)?>([^<]*)<\/t>/g;
298
+ const parts: string[] = [];
299
+ let tMatch: RegExpExecArray | null;
300
+
301
+ while ((tMatch = tPattern.exec(isMatch[1] ?? "")) !== null) {
302
+ parts.push(decodeXmlEntities(tMatch[1] ?? ""));
303
+ }
304
+
305
+ return parts.join("");
306
+ }
307
+
308
+ function parseMergeCells(mergeCellsXml: string, out: XlsxParsedMerge[]): void {
309
+ const mergePattern = /<mergeCell\b([^>]*?)(?:\/>|>[\s\S]*?<\/mergeCell>)/g;
310
+ let match: RegExpExecArray | null;
311
+
312
+ while ((match = mergePattern.exec(mergeCellsXml)) !== null) {
313
+ const attrs = parseXmlAttributes(match[1] ?? "");
314
+ const ref = attrs["ref"] ?? "";
315
+ const merge = parseMergeRef(ref);
316
+ if (merge !== null) {
317
+ out.push(merge);
318
+ }
319
+ }
320
+ }
321
+
322
+ function parseMergeRef(ref: string): XlsxParsedMerge | null {
323
+ const parts = ref.split(":");
324
+ if (parts.length !== 2) {
325
+ return null;
326
+ }
327
+
328
+ const start = parseCellRef(parts[0] ?? "");
329
+ const end = parseCellRef(parts[1] ?? "");
330
+ if (start === null || end === null) {
331
+ return null;
332
+ }
333
+
334
+ return {
335
+ startRow: start.row,
336
+ startCol: start.col,
337
+ endRow: end.row,
338
+ endCol: end.col,
339
+ };
340
+ }
341
+
342
+ function parseSheetDimension(xml: string): XlsxParsedDimension | null {
343
+ const dimensionMatch = /<dimension\b([^>]*?)(?:\/>|>)/i.exec(xml);
344
+ if (!dimensionMatch) {
345
+ return null;
346
+ }
347
+
348
+ const attrs = parseXmlAttributes(dimensionMatch[1] ?? "");
349
+ const ref = attrs["ref"];
350
+ if (!ref) {
351
+ return null;
352
+ }
353
+
354
+ return parseDimensionRef(ref);
355
+ }
356
+
357
+ const SHEET_PREFIX_PATTERN =
358
+ "(?:'(?:[^']|'')+'|[A-Za-z_][A-Za-z0-9_.]*)!";
359
+ const CELL_REFERENCE_PATTERN = "\\$?[A-Z]{1,3}\\$?[1-9][0-9]*";
360
+ const RANGE_REFERENCE_PATTERN =
361
+ `${CELL_REFERENCE_PATTERN}(?::${CELL_REFERENCE_PATTERN})?`;
362
+ const FORMULA_REFERENCE_PATTERN = new RegExp(
363
+ String.raw`(?<![A-Za-z0-9_.$])(?:${SHEET_PREFIX_PATTERN})?${RANGE_REFERENCE_PATTERN}(?![A-Za-z0-9_])`,
364
+ "g",
365
+ );
366
+
367
+ function extractFormulaReferenceTokens(formula: string): string[] {
368
+ const maskedFormula = maskQuotedFormulaStrings(formula);
369
+ const tokens: string[] = [];
370
+ const seen = new Set<string>();
371
+
372
+ for (const match of maskedFormula.matchAll(FORMULA_REFERENCE_PATTERN)) {
373
+ const index = match.index ?? -1;
374
+ if (index < 0) {
375
+ continue;
376
+ }
377
+ const token = formula.slice(index, index + match[0].length);
378
+ if (seen.has(token)) {
379
+ continue;
380
+ }
381
+ seen.add(token);
382
+ tokens.push(token);
383
+ }
384
+
385
+ return tokens;
386
+ }
387
+
388
+ function maskQuotedFormulaStrings(formula: string): string {
389
+ let output = "";
390
+ let inString = false;
391
+
392
+ for (let index = 0; index < formula.length; index += 1) {
393
+ const char = formula[index];
394
+ const next = formula[index + 1];
395
+
396
+ if (char === "\"") {
397
+ output += char;
398
+ if (inString && next === "\"") {
399
+ output += " ";
400
+ index += 1;
401
+ continue;
402
+ }
403
+ inString = !inString;
404
+ continue;
405
+ }
406
+
407
+ output += inString ? " " : char;
408
+ }
409
+
410
+ return output;
411
+ }
412
+
413
+ function parseDimensionRef(ref: string): XlsxParsedDimension | null {
414
+ const [startRef, endRef = startRef] = ref.split(":");
415
+ if (!startRef || !endRef) {
416
+ return null;
417
+ }
418
+
419
+ const start = parseCellRef(startRef);
420
+ const end = parseCellRef(endRef);
421
+ if (start === null || end === null) {
422
+ return null;
423
+ }
424
+
425
+ return {
426
+ startRow: start.row,
427
+ startCol: start.col,
428
+ endRow: end.row,
429
+ endCol: end.col,
430
+ };
431
+ }
432
+
433
+ function parseCellRef(ref: string): { row: number; col: number } | null {
434
+ const match = /^([A-Z]+)([0-9]+)$/i.exec(ref.trim());
435
+ if (!match) {
436
+ return null;
437
+ }
438
+
439
+ return {
440
+ col: colLettersToIndex(match[1] ?? ""),
441
+ row: parseInt(match[2] ?? "1", 10) - 1,
442
+ };
443
+ }
444
+
445
+ /**
446
+ * Converts a column letter sequence to a zero-based column index.
447
+ * "A" -> 0, "Z" -> 25, "AA" -> 26, "AZ" -> 51, "BA" -> 52.
448
+ */
449
+ function colLettersToIndex(letters: string): number {
450
+ let result = 0;
451
+
452
+ for (const char of letters.toUpperCase()) {
453
+ result = result * 26 + (char.charCodeAt(0) - 64);
454
+ }
455
+
456
+ return result - 1;
457
+ }
458
+
459
+ export { parseCellRef, colLettersToIndex };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Parses xl/styles.xml for the cellXfs table (cell format entries).
3
+ *
4
+ * Each entry provides style references (numFmtId, fontId, fillId, borderId)
5
+ * that cells reference by zero-based index via the s= attribute.
6
+ */
7
+ export interface XlsxStyleEntry {
8
+ numFmtId: number;
9
+ fontId: number;
10
+ fillId: number;
11
+ borderId: number;
12
+ rawAttributes: Record<string, string>;
13
+ }
14
+
15
+ export function parseStylesXml(xml: string): XlsxStyleEntry[] {
16
+ const cellXfsMatch = /<cellXfs\b[^>]*>([\s\S]*?)<\/cellXfs>/i.exec(xml);
17
+ if (!cellXfsMatch) {
18
+ return [];
19
+ }
20
+
21
+ const cellXfsContent = cellXfsMatch[1] ?? "";
22
+ const xfPattern = /<xf\b([^>]*?)(?:\/>|>[\s\S]*?<\/xf>)/g;
23
+ const entries: XlsxStyleEntry[] = [];
24
+ let xfMatch: RegExpExecArray | null;
25
+
26
+ while ((xfMatch = xfPattern.exec(cellXfsContent)) !== null) {
27
+ const attrs = parseXmlAttributes(xfMatch[1] ?? "");
28
+ entries.push({
29
+ numFmtId: parseIntAttr(attrs["numFmtId"], 0),
30
+ fontId: parseIntAttr(attrs["fontId"], 0),
31
+ fillId: parseIntAttr(attrs["fillId"], 0),
32
+ borderId: parseIntAttr(attrs["borderId"], 0),
33
+ rawAttributes: attrs,
34
+ });
35
+ }
36
+
37
+ return entries;
38
+ }
39
+
40
+ function parseIntAttr(value: string | undefined, defaultValue: number): number {
41
+ if (value === undefined || value === "") {
42
+ return defaultValue;
43
+ }
44
+
45
+ const parsed = parseInt(value, 10);
46
+ return Number.isNaN(parsed) ? defaultValue : parsed;
47
+ }
48
+
49
+ export function parseXmlAttributes(rawAttributes: string): Record<string, string> {
50
+ const attributes: Record<string, string> = {};
51
+ const attributePattern = /([A-Za-z_][\w:.-]*)="([^"]*)"/g;
52
+ let match: RegExpExecArray | null;
53
+
54
+ while ((match = attributePattern.exec(rawAttributes)) !== null) {
55
+ attributes[match[1]] = match[2];
56
+ }
57
+
58
+ return attributes;
59
+ }
@@ -0,0 +1,75 @@
1
+ import { parseXmlAttributes } from "./parse-styles.ts";
2
+
3
+ /**
4
+ * Represents a single sheet entry from the workbook's sheet registry.
5
+ */
6
+ export interface WorkbookSheetEntry {
7
+ /** Human-readable sheet name. */
8
+ name: string;
9
+ /** Workbook-internal numeric sheet ID string. */
10
+ sheetId: string;
11
+ /** Relationship ID used to look up the sheet part path. */
12
+ relationshipId: string;
13
+ /** Visibility state; defaults to "visible" when absent. */
14
+ state: "visible" | "hidden" | "veryHidden";
15
+ }
16
+
17
+ export interface WorkbookParseResult {
18
+ sheets: WorkbookSheetEntry[];
19
+ /**
20
+ * Whether the workbook uses the 1904 date base.
21
+ * Most xlsx files use 1900 (false). Mac-originated files may use 1904 (true).
22
+ */
23
+ date1904: boolean;
24
+ }
25
+
26
+ /**
27
+ * Parses xl/workbook.xml and returns the ordered sheet registry.
28
+ *
29
+ * The r:id attribute in <sheet> elements uses the XML namespace prefix r.
30
+ * The attribute parser handles namespace-prefixed names (e.g. "r:id") correctly.
31
+ */
32
+ export function parseWorkbookXml(xml: string): WorkbookParseResult {
33
+ const sheets: WorkbookSheetEntry[] = [];
34
+ const sheetPattern = /<sheet\b([^>]*?)(?:\/>|>[\s\S]*?<\/sheet>)/g;
35
+ let match: RegExpExecArray | null;
36
+
37
+ while ((match = sheetPattern.exec(xml)) !== null) {
38
+ const attrs = parseXmlAttributes(match[1] ?? "");
39
+ const name = attrs["name"] ?? "";
40
+ const sheetId = attrs["sheetId"] ?? "";
41
+ const relationshipId = attrs["r:id"] ?? attrs["id"] ?? "";
42
+
43
+ if (!name || !sheetId || !relationshipId) {
44
+ continue;
45
+ }
46
+
47
+ const stateAttr = attrs["state"];
48
+ const state: WorkbookSheetEntry["state"] =
49
+ stateAttr === "hidden"
50
+ ? "hidden"
51
+ : stateAttr === "veryHidden"
52
+ ? "veryHidden"
53
+ : "visible";
54
+
55
+ sheets.push({ name, sheetId, relationshipId, state });
56
+ }
57
+
58
+ const date1904 = parseDate1904(xml);
59
+
60
+ return { sheets, date1904 };
61
+ }
62
+
63
+ /**
64
+ * Extracts the date1904 flag from the <workbookPr> element.
65
+ * Returns false (1900 base) if the attribute is absent or not "1" or "true".
66
+ */
67
+ function parseDate1904(xml: string): boolean {
68
+ const workbookPrMatch = /<workbookPr\b([^>]*?)(?:\/>|>)/i.exec(xml);
69
+ if (!workbookPrMatch) {
70
+ return false;
71
+ }
72
+ const attrs = parseXmlAttributes(workbookPrMatch[1] ?? "");
73
+ const val = attrs["date1904"];
74
+ return val === "1" || val === "true";
75
+ }
@@ -0,0 +1,72 @@
1
+ import type { CanonicalWorkbook } from "../model/workbook.ts";
2
+ import { listSheets } from "../model/workbook.ts";
3
+
4
+ const SHARED_STRINGS_NAMESPACE = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
5
+
6
+ export interface SharedStringTableSerialization {
7
+ xml: string;
8
+ strings: string[];
9
+ indexByValue: Map<string, number>;
10
+ totalCount: number;
11
+ }
12
+
13
+ export function buildSharedStringsTable(
14
+ workbook: CanonicalWorkbook,
15
+ ): SharedStringTableSerialization {
16
+ const strings: string[] = [];
17
+ const indexByValue = new Map<string, number>();
18
+ let totalCount = 0;
19
+
20
+ for (const sheet of listSheets(workbook)) {
21
+ for (const cell of sheet.cells.values()) {
22
+ if (cell.kind !== "text") {
23
+ continue;
24
+ }
25
+
26
+ totalCount += 1;
27
+
28
+ if (!indexByValue.has(cell.value)) {
29
+ indexByValue.set(cell.value, strings.length);
30
+ strings.push(cell.value);
31
+ }
32
+ }
33
+ }
34
+
35
+ return {
36
+ xml: serializeSharedStringsXml(strings, totalCount),
37
+ strings,
38
+ indexByValue,
39
+ totalCount,
40
+ };
41
+ }
42
+
43
+ export function serializeSharedStringsXml(
44
+ strings: readonly string[],
45
+ totalCount: number = strings.length,
46
+ ): string {
47
+ const items = strings.map(serializeSharedStringItem);
48
+ const body = items.length > 0 ? `\n${items.join("\n")}\n` : "";
49
+
50
+ return [
51
+ `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>`,
52
+ `<sst xmlns="${SHARED_STRINGS_NAMESPACE}" count="${totalCount}" uniqueCount="${strings.length}">${body}</sst>`,
53
+ ].join("\n");
54
+ }
55
+
56
+ function serializeSharedStringItem(value: string): string {
57
+ const preserveSpace = requiresPreservedSpace(value) ? ` xml:space="preserve"` : "";
58
+ return ` <si><t${preserveSpace}>${escapeXml(value)}</t></si>`;
59
+ }
60
+
61
+ function requiresPreservedSpace(value: string): boolean {
62
+ return /^\s/.test(value) || /\s$/.test(value);
63
+ }
64
+
65
+ function escapeXml(value: string): string {
66
+ return value
67
+ .replace(/&/g, "&amp;")
68
+ .replace(/"/g, "&quot;")
69
+ .replace(/</g, "&lt;")
70
+ .replace(/>/g, "&gt;")
71
+ .replace(/'/g, "&apos;");
72
+ }