@cj-tech-master/excelts 9.5.4 → 9.5.5

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 (767) hide show
  1. package/dist/browser/modules/archive/compression/streaming-compress.browser.js +29 -0
  2. package/dist/browser/modules/archive/compression/streaming-compress.js +9 -0
  3. package/dist/browser/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  4. package/dist/browser/modules/archive/fs/archive-file.d.ts +8 -5
  5. package/dist/browser/modules/archive/fs/archive-file.js +78 -16
  6. package/dist/browser/modules/archive/unzip/stream.browser.js +43 -2
  7. package/dist/browser/modules/excel/chart/chart-ex-builder.js +7 -2
  8. package/dist/browser/modules/excel/chart/chart-ex-renderer.js +4 -9
  9. package/dist/browser/modules/excel/chart/chart-ex-types.d.ts +0 -12
  10. package/dist/browser/modules/excel/chart/chart.d.ts +1 -5
  11. package/dist/browser/modules/excel/chart/chart.js +1 -7
  12. package/dist/browser/modules/excel/chart/types.d.ts +0 -6
  13. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +25 -1
  14. package/dist/browser/modules/excel/stream/workbook-reader.js +9 -0
  15. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
  16. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +228 -13
  17. package/dist/browser/modules/excel/utils/string-buf.d.ts +5 -26
  18. package/dist/browser/modules/excel/utils/string-buf.js +4 -81
  19. package/dist/browser/modules/excel/workbook.browser.js +135 -25
  20. package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  21. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
  22. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +32 -8
  23. package/dist/browser/modules/excel/xlsx/xlsx.d.ts +10 -2
  24. package/dist/browser/modules/excel/xlsx/xlsx.js +9 -1
  25. package/dist/browser/modules/pdf/excel-bridge.d.ts +30 -1
  26. package/dist/browser/modules/pdf/excel-bridge.js +32 -0
  27. package/dist/browser/modules/pdf/font/metrics.d.ts +3 -52
  28. package/dist/browser/modules/pdf/font/metrics.js +3 -237
  29. package/dist/browser/modules/pdf/index.d.ts +1 -1
  30. package/dist/browser/modules/pdf/index.js +1 -1
  31. package/dist/browser/modules/pdf/render-layout-to-pdf.d.ts +66 -0
  32. package/dist/browser/modules/pdf/render-layout-to-pdf.js +647 -0
  33. package/dist/browser/modules/pdf/word-bridge.d.ts +80 -12
  34. package/dist/browser/modules/pdf/word-bridge.js +122 -274
  35. package/dist/browser/modules/stream/index.base.d.ts +2 -0
  36. package/dist/browser/modules/stream/index.base.js +2 -1
  37. package/dist/browser/modules/stream/internal/sink-adapter.d.ts +65 -0
  38. package/dist/browser/modules/stream/internal/sink-adapter.js +198 -0
  39. package/dist/browser/modules/stream/pull-stream.d.ts +19 -2
  40. package/dist/browser/modules/stream/pull-stream.js +51 -5
  41. package/dist/browser/modules/stream/types.d.ts +13 -1
  42. package/dist/browser/modules/word/advanced/diff.d.ts +61 -0
  43. package/dist/browser/modules/word/advanced/diff.js +167 -0
  44. package/dist/browser/modules/word/advanced/drawing-shapes.d.ts +269 -0
  45. package/dist/browser/modules/word/advanced/drawing-shapes.js +268 -0
  46. package/dist/browser/modules/word/advanced/field-engine.d.ts +43 -0
  47. package/dist/browser/modules/word/advanced/field-engine.js +1225 -0
  48. package/dist/browser/modules/word/advanced/glossary.d.ts +86 -0
  49. package/dist/browser/modules/word/advanced/glossary.js +79 -0
  50. package/dist/browser/modules/word/advanced/math-convert.d.ts +30 -0
  51. package/dist/browser/modules/word/advanced/math-convert.js +595 -0
  52. package/dist/browser/modules/word/advanced/ole-objects.d.ts +115 -0
  53. package/dist/browser/modules/word/advanced/ole-objects.js +271 -0
  54. package/dist/browser/modules/word/advanced/style-map.d.ts +105 -0
  55. package/dist/browser/modules/word/advanced/style-map.js +322 -0
  56. package/dist/browser/modules/word/advanced/validation.d.ts +56 -0
  57. package/dist/browser/modules/word/advanced/validation.js +1065 -0
  58. package/dist/browser/modules/word/advanced/vba-project.d.ts +91 -0
  59. package/dist/browser/modules/word/advanced/vba-project.js +265 -0
  60. package/dist/browser/modules/word/bridge/excel-bridge.d.ts +127 -0
  61. package/dist/browser/modules/word/bridge/excel-bridge.js +980 -0
  62. package/dist/browser/modules/word/builder/document-handle.d.ts +151 -0
  63. package/dist/browser/modules/word/builder/document-handle.js +664 -0
  64. package/dist/browser/modules/word/builder/paragraph-builders.d.ts +61 -0
  65. package/dist/browser/modules/word/builder/paragraph-builders.js +90 -0
  66. package/dist/browser/modules/word/builder/run-builders.d.ts +374 -0
  67. package/dist/browser/modules/word/builder/run-builders.js +600 -0
  68. package/dist/browser/modules/word/builder/table-builders.d.ts +23 -0
  69. package/dist/browser/modules/word/builder/table-builders.js +45 -0
  70. package/dist/browser/modules/word/constants.d.ts +39 -1
  71. package/dist/browser/modules/word/constants.js +109 -1
  72. package/dist/browser/modules/word/convert/conversion-ir.d.ts +210 -0
  73. package/dist/browser/modules/word/convert/conversion-ir.js +31 -0
  74. package/dist/browser/modules/word/convert/docx-to-semantic.d.ts +39 -0
  75. package/dist/browser/modules/word/convert/docx-to-semantic.js +499 -0
  76. package/dist/browser/modules/word/convert/flat-opc.d.ts +44 -0
  77. package/dist/browser/modules/word/convert/flat-opc.js +385 -0
  78. package/dist/browser/modules/word/convert/html/html-import.d.ts +50 -0
  79. package/dist/browser/modules/word/convert/html/html-import.js +1907 -0
  80. package/dist/{types/modules/word → browser/modules/word/convert/html}/html-renderer.d.ts +14 -1
  81. package/dist/{esm/modules/word → browser/modules/word/convert/html}/html-renderer.js +420 -69
  82. package/dist/browser/modules/word/convert/html/html.d.ts +15 -0
  83. package/dist/browser/modules/word/convert/html/html.js +15 -0
  84. package/dist/browser/modules/word/convert/markdown/markdown-import.d.ts +68 -0
  85. package/dist/browser/modules/word/convert/markdown/markdown-import.js +1325 -0
  86. package/dist/browser/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
  87. package/dist/browser/modules/word/convert/markdown/markdown-renderer.js +634 -0
  88. package/dist/browser/modules/word/convert/markdown/markdown.d.ts +15 -0
  89. package/dist/browser/modules/word/convert/markdown/markdown.js +15 -0
  90. package/dist/browser/modules/word/convert/odt/odt.d.ts +41 -0
  91. package/dist/browser/modules/word/convert/odt/odt.js +1932 -0
  92. package/dist/browser/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
  93. package/dist/browser/modules/word/core/color-utils.js +43 -0
  94. package/dist/browser/modules/word/core/internal-utils.d.ts +90 -0
  95. package/dist/browser/modules/word/core/internal-utils.js +209 -0
  96. package/dist/browser/modules/word/core/mapper.d.ts +44 -0
  97. package/dist/browser/modules/word/core/mapper.js +427 -0
  98. package/dist/browser/modules/word/core/opc-paths.d.ts +33 -0
  99. package/dist/browser/modules/word/core/opc-paths.js +48 -0
  100. package/dist/browser/modules/word/core/text-utils.d.ts +38 -0
  101. package/dist/browser/modules/word/core/text-utils.js +202 -0
  102. package/dist/browser/modules/word/core/walker.d.ts +119 -0
  103. package/dist/browser/modules/word/core/walker.js +570 -0
  104. package/dist/browser/modules/word/crypto.d.ts +14 -9
  105. package/dist/browser/modules/word/crypto.js +13 -7
  106. package/dist/browser/modules/word/document-io.d.ts +59 -27
  107. package/dist/browser/modules/word/document-io.js +80 -197
  108. package/dist/browser/modules/word/errors.d.ts +44 -1
  109. package/dist/browser/modules/word/errors.js +54 -2
  110. package/dist/browser/modules/word/excel.d.ts +14 -0
  111. package/dist/browser/modules/word/excel.js +13 -0
  112. package/dist/browser/modules/word/font/font-embed.d.ts +112 -0
  113. package/dist/browser/modules/word/font/font-embed.js +646 -0
  114. package/dist/{esm/modules/word → browser/modules/word/font}/font-obfuscation.js +4 -9
  115. package/dist/browser/modules/word/font/hyphenation.d.ts +65 -0
  116. package/dist/browser/modules/word/font/hyphenation.js +4210 -0
  117. package/dist/browser/modules/word/font/text-shaping.d.ts +58 -0
  118. package/dist/browser/modules/word/font/text-shaping.js +635 -0
  119. package/dist/browser/modules/word/html.d.ts +7 -6
  120. package/dist/browser/modules/word/html.js +6 -5
  121. package/dist/browser/modules/word/incremental-edit.d.ts +123 -0
  122. package/dist/browser/modules/word/incremental-edit.js +361 -0
  123. package/dist/browser/modules/word/index.base.d.ts +194 -10
  124. package/dist/browser/modules/word/index.base.js +138 -29
  125. package/dist/browser/modules/word/layout/layout-constants.d.ts +17 -0
  126. package/dist/browser/modules/word/layout/layout-constants.js +17 -0
  127. package/dist/browser/modules/word/layout/layout-full.d.ts +53 -0
  128. package/dist/browser/modules/word/layout/layout-full.js +1696 -0
  129. package/dist/browser/modules/word/layout/layout-model.d.ts +344 -0
  130. package/dist/browser/modules/word/layout/layout-model.js +16 -0
  131. package/dist/browser/modules/word/layout/layout.d.ts +63 -0
  132. package/dist/browser/modules/word/layout/layout.js +1167 -0
  133. package/dist/browser/modules/word/layout/render-page.d.ts +57 -0
  134. package/dist/browser/modules/word/layout/render-page.js +1238 -0
  135. package/dist/browser/modules/word/markdown.d.ts +14 -0
  136. package/dist/browser/modules/word/markdown.js +13 -0
  137. package/dist/browser/modules/word/patcher.d.ts +62 -0
  138. package/dist/browser/modules/word/patcher.js +537 -0
  139. package/dist/browser/modules/word/query/compat.d.ts +25 -0
  140. package/dist/browser/modules/word/query/compat.js +58 -0
  141. package/dist/browser/modules/word/query/data-binding.d.ts +22 -0
  142. package/dist/browser/modules/word/query/data-binding.js +392 -0
  143. package/dist/browser/modules/word/query/form-fields.d.ts +41 -0
  144. package/dist/browser/modules/word/query/form-fields.js +268 -0
  145. package/dist/browser/modules/word/query/format-search.d.ts +99 -0
  146. package/dist/browser/modules/word/query/format-search.js +329 -0
  147. package/dist/browser/modules/word/query/mail-merge.d.ts +25 -0
  148. package/dist/browser/modules/word/query/mail-merge.js +111 -0
  149. package/dist/browser/modules/word/query/merge.d.ts +50 -0
  150. package/dist/browser/modules/word/query/merge.js +617 -0
  151. package/dist/browser/modules/word/query/replace.d.ts +47 -0
  152. package/dist/browser/modules/word/query/replace.js +301 -0
  153. package/dist/browser/modules/word/query/revisions.d.ts +67 -0
  154. package/dist/browser/modules/word/query/revisions.js +879 -0
  155. package/dist/browser/modules/word/query/search.d.ts +129 -0
  156. package/dist/browser/modules/word/query/search.js +346 -0
  157. package/dist/browser/modules/word/query/split.d.ts +44 -0
  158. package/dist/browser/modules/word/query/split.js +135 -0
  159. package/dist/browser/modules/word/query/style-resolve.d.ts +104 -0
  160. package/dist/browser/modules/word/query/style-resolve.js +368 -0
  161. package/dist/browser/modules/word/reader/chart-parser.d.ts +20 -0
  162. package/dist/browser/modules/word/reader/chart-parser.js +810 -0
  163. package/dist/browser/modules/word/reader/comments-parser.d.ts +26 -0
  164. package/dist/browser/modules/word/reader/comments-parser.js +92 -0
  165. package/dist/browser/modules/word/reader/doc-props-parsers.d.ts +15 -0
  166. package/dist/browser/modules/word/reader/doc-props-parsers.js +190 -0
  167. package/dist/browser/modules/word/reader/docx-reader.d.ts +27 -0
  168. package/dist/browser/modules/word/reader/docx-reader.js +2557 -0
  169. package/dist/browser/modules/word/reader/drawing-helpers.d.ts +27 -0
  170. package/dist/browser/modules/word/reader/drawing-helpers.js +84 -0
  171. package/dist/browser/modules/word/reader/form-field-parser.d.ts +21 -0
  172. package/dist/browser/modules/word/reader/form-field-parser.js +82 -0
  173. package/dist/browser/modules/word/reader/image-parsers.d.ts +11 -0
  174. package/dist/browser/modules/word/reader/image-parsers.js +291 -0
  175. package/dist/browser/modules/word/reader/math-parser.d.ts +12 -0
  176. package/dist/browser/modules/word/reader/math-parser.js +422 -0
  177. package/dist/browser/modules/word/reader/metadata-parsers.d.ts +17 -0
  178. package/dist/browser/modules/word/reader/metadata-parsers.js +87 -0
  179. package/dist/browser/modules/word/reader/numbering-parser.d.ts +13 -0
  180. package/dist/browser/modules/word/reader/numbering-parser.js +166 -0
  181. package/dist/browser/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
  182. package/dist/browser/modules/word/reader/paragraph-section-parsers.js +503 -0
  183. package/dist/browser/modules/word/reader/parse-utils.d.ts +91 -0
  184. package/dist/browser/modules/word/reader/parse-utils.js +249 -0
  185. package/dist/browser/modules/word/reader/properties-parsers.d.ts +21 -0
  186. package/dist/browser/modules/word/reader/properties-parsers.js +332 -0
  187. package/dist/browser/modules/word/reader/reader-context.d.ts +69 -0
  188. package/dist/browser/modules/word/reader/reader-context.js +61 -0
  189. package/dist/browser/modules/word/reader/sdt-helpers.d.ts +29 -0
  190. package/dist/browser/modules/word/reader/sdt-helpers.js +111 -0
  191. package/dist/browser/modules/word/reader/settings-parser.d.ts +8 -0
  192. package/dist/browser/modules/word/reader/settings-parser.js +263 -0
  193. package/dist/browser/modules/word/reader/styles-parser.d.ts +12 -0
  194. package/dist/browser/modules/word/reader/styles-parser.js +147 -0
  195. package/dist/browser/modules/word/reader/table-properties-parsers.d.ts +12 -0
  196. package/dist/browser/modules/word/reader/table-properties-parsers.js +234 -0
  197. package/dist/browser/modules/word/reader/theme-parser.d.ts +8 -0
  198. package/dist/browser/modules/word/reader/theme-parser.js +167 -0
  199. package/dist/browser/modules/word/reader/watermark-parser.d.ts +15 -0
  200. package/dist/browser/modules/word/reader/watermark-parser.js +110 -0
  201. package/dist/browser/modules/word/security/cfb-reader.d.ts +37 -0
  202. package/dist/browser/modules/word/security/cfb-reader.js +410 -0
  203. package/dist/browser/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
  204. package/dist/browser/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  205. package/dist/browser/modules/word/security/document-protection.d.ts +93 -0
  206. package/dist/browser/modules/word/security/document-protection.js +201 -0
  207. package/dist/{types/modules/word → browser/modules/word/security}/encryption.d.ts +51 -4
  208. package/dist/browser/modules/word/security/encryption.js +602 -0
  209. package/dist/browser/modules/word/security/policy.d.ts +80 -0
  210. package/dist/browser/modules/word/security/policy.js +102 -0
  211. package/dist/browser/modules/word/template/template-chart.d.ts +56 -0
  212. package/dist/browser/modules/word/template/template-chart.js +167 -0
  213. package/dist/browser/modules/word/template/template-datasource.d.ts +154 -0
  214. package/dist/browser/modules/word/template/template-datasource.js +541 -0
  215. package/dist/browser/modules/word/template/template-engine.d.ts +121 -0
  216. package/dist/browser/modules/word/template/template-engine.js +1435 -0
  217. package/dist/browser/modules/word/types.d.ts +224 -25
  218. package/dist/browser/modules/word/units.d.ts +26 -0
  219. package/dist/browser/modules/word/units.js +43 -14
  220. package/dist/browser/modules/word/{writers → writer}/chart-writer.js +164 -23
  221. package/dist/browser/modules/word/writer/checkbox-writer.d.ts +17 -0
  222. package/dist/browser/modules/word/writer/checkbox-writer.js +79 -0
  223. package/dist/{types/modules/word/writers → browser/modules/word/writer}/comment-writer.d.ts +2 -1
  224. package/dist/browser/modules/word/{writers → writer}/comment-writer.js +8 -6
  225. package/dist/browser/modules/word/writer/common-parts.d.ts +57 -0
  226. package/dist/browser/modules/word/writer/common-parts.js +101 -0
  227. package/dist/{types/modules/word → browser/modules/word/writer}/content-types.d.ts +2 -2
  228. package/dist/{esm/modules/word → browser/modules/word/writer}/content-types.js +14 -6
  229. package/dist/browser/modules/word/writer/document-writer.d.ts +24 -0
  230. package/dist/browser/modules/word/writer/document-writer.js +473 -0
  231. package/dist/browser/modules/word/writer/docx-packager.d.ts +35 -0
  232. package/dist/browser/modules/word/writer/docx-packager.js +1515 -0
  233. package/dist/{types/modules/word/writers → browser/modules/word/writer}/footnote-writer.d.ts +3 -2
  234. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/footnote-writer.js +13 -10
  235. package/dist/{types/modules/word/writers → browser/modules/word/writer}/header-footer-writer.d.ts +3 -2
  236. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/header-footer-writer.js +39 -21
  237. package/dist/{types/modules/word/writers → browser/modules/word/writer}/image-writer.d.ts +1 -1
  238. package/dist/browser/modules/word/{writers → writer}/image-writer.js +11 -7
  239. package/dist/browser/modules/word/writer/math-writer.d.ts +20 -0
  240. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/math-writer.js +21 -1
  241. package/dist/browser/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
  242. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/numbering-writer.js +11 -4
  243. package/dist/browser/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
  244. package/dist/browser/modules/word/{writers → writer}/paragraph-writer.js +73 -38
  245. package/dist/browser/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
  246. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/parts-writer.js +91 -12
  247. package/dist/browser/modules/word/writer/reference-scanners.d.ts +42 -0
  248. package/dist/browser/modules/word/writer/reference-scanners.js +111 -0
  249. package/dist/browser/modules/word/writer/relationships.d.ts +52 -0
  250. package/dist/browser/modules/word/writer/relationships.js +117 -0
  251. package/dist/browser/modules/word/writer/render-context.d.ts +124 -0
  252. package/dist/browser/modules/word/writer/render-context.js +46 -0
  253. package/dist/browser/modules/word/{writers → writer}/run-writer.d.ts +10 -1
  254. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/run-writer.js +126 -24
  255. package/dist/browser/modules/word/writer/sdt-writer.d.ts +25 -0
  256. package/dist/browser/modules/word/writer/sdt-writer.js +189 -0
  257. package/dist/browser/modules/word/writer/stream-buf.d.ts +37 -0
  258. package/dist/browser/modules/word/writer/stream-buf.js +73 -0
  259. package/dist/browser/modules/word/writer/streaming-writer.d.ts +344 -0
  260. package/dist/browser/modules/word/writer/streaming-writer.js +1382 -0
  261. package/dist/browser/modules/word/writer/string-buf.d.ts +8 -0
  262. package/dist/browser/modules/word/writer/string-buf.js +7 -0
  263. package/dist/browser/modules/word/{writers → writer}/styles-writer.js +32 -1
  264. package/dist/browser/modules/word/{writers → writer}/table-writer.d.ts +2 -1
  265. package/dist/browser/modules/word/{writers → writer}/table-writer.js +94 -11
  266. package/dist/browser/modules/xml/types.d.ts +22 -0
  267. package/dist/browser/utils/crypto.browser.d.ts +3 -1
  268. package/dist/browser/utils/crypto.browser.js +3 -1
  269. package/dist/browser/utils/crypto.d.ts +4 -1
  270. package/dist/browser/utils/crypto.js +4 -1
  271. package/dist/browser/utils/font-metrics.d.ts +63 -0
  272. package/dist/browser/utils/font-metrics.js +293 -0
  273. package/dist/browser/utils/string-buf.d.ts +42 -0
  274. package/dist/browser/utils/string-buf.js +89 -0
  275. package/dist/browser/utils/theme-colors.d.ts +55 -0
  276. package/dist/browser/utils/theme-colors.js +120 -0
  277. package/dist/cjs/modules/archive/compression/streaming-compress.browser.js +29 -0
  278. package/dist/cjs/modules/archive/compression/streaming-compress.js +9 -0
  279. package/dist/cjs/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  280. package/dist/cjs/modules/archive/fs/archive-file.js +78 -16
  281. package/dist/cjs/modules/archive/unzip/stream.browser.js +43 -2
  282. package/dist/cjs/modules/excel/chart/chart-ex-builder.js +7 -2
  283. package/dist/cjs/modules/excel/chart/chart-ex-renderer.js +4 -9
  284. package/dist/cjs/modules/excel/chart/chart.js +1 -7
  285. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +25 -1
  286. package/dist/cjs/modules/excel/stream/workbook-reader.js +9 -0
  287. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +228 -13
  288. package/dist/cjs/modules/excel/utils/string-buf.js +5 -81
  289. package/dist/cjs/modules/excel/workbook.browser.js +135 -25
  290. package/dist/cjs/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  291. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +32 -8
  292. package/dist/cjs/modules/excel/xlsx/xlsx.js +9 -1
  293. package/dist/cjs/modules/pdf/excel-bridge.js +33 -0
  294. package/dist/cjs/modules/pdf/font/metrics.js +11 -244
  295. package/dist/cjs/modules/pdf/index.js +2 -1
  296. package/dist/cjs/modules/pdf/render-layout-to-pdf.js +651 -0
  297. package/dist/cjs/modules/pdf/word-bridge.js +155 -274
  298. package/dist/cjs/modules/stream/index.base.js +4 -2
  299. package/dist/cjs/modules/stream/internal/sink-adapter.js +202 -0
  300. package/dist/cjs/modules/stream/pull-stream.js +51 -5
  301. package/dist/cjs/modules/word/advanced/diff.js +170 -0
  302. package/dist/cjs/modules/word/advanced/drawing-shapes.js +279 -0
  303. package/dist/cjs/modules/word/advanced/field-engine.js +1229 -0
  304. package/dist/cjs/modules/word/advanced/glossary.js +87 -0
  305. package/dist/cjs/modules/word/advanced/math-convert.js +599 -0
  306. package/dist/cjs/modules/word/advanced/ole-objects.js +277 -0
  307. package/dist/cjs/modules/word/advanced/style-map.js +329 -0
  308. package/dist/cjs/modules/word/advanced/validation.js +1068 -0
  309. package/dist/cjs/modules/word/advanced/vba-project.js +274 -0
  310. package/dist/cjs/modules/word/bridge/excel-bridge.js +1020 -0
  311. package/dist/cjs/modules/word/builder/document-handle.js +667 -0
  312. package/dist/cjs/modules/word/builder/paragraph-builders.js +109 -0
  313. package/dist/cjs/modules/word/builder/run-builders.js +676 -0
  314. package/dist/cjs/modules/word/builder/table-builders.js +53 -0
  315. package/dist/cjs/modules/word/constants.js +111 -2
  316. package/dist/cjs/modules/word/convert/conversion-ir.js +34 -0
  317. package/dist/cjs/modules/word/convert/docx-to-semantic.js +502 -0
  318. package/dist/cjs/modules/word/convert/flat-opc.js +390 -0
  319. package/dist/cjs/modules/word/convert/html/html-import.js +1910 -0
  320. package/dist/cjs/modules/word/{html-renderer.js → convert/html/html-renderer.js} +420 -69
  321. package/dist/cjs/modules/word/convert/html/html.js +20 -0
  322. package/dist/cjs/modules/word/convert/markdown/markdown-import.js +1329 -0
  323. package/dist/cjs/modules/word/convert/markdown/markdown-renderer.js +637 -0
  324. package/dist/cjs/modules/word/convert/markdown/markdown.js +21 -0
  325. package/dist/cjs/modules/word/convert/odt/odt.js +1936 -0
  326. package/dist/cjs/modules/word/core/color-utils.js +47 -0
  327. package/dist/cjs/modules/word/core/internal-utils.js +219 -0
  328. package/dist/cjs/modules/word/core/mapper.js +430 -0
  329. package/dist/cjs/modules/word/core/opc-paths.js +53 -0
  330. package/dist/cjs/modules/word/core/text-utils.js +210 -0
  331. package/dist/cjs/modules/word/core/walker.js +577 -0
  332. package/dist/cjs/modules/word/crypto.js +19 -8
  333. package/dist/cjs/modules/word/document-io.js +117 -197
  334. package/dist/cjs/modules/word/errors.js +59 -13
  335. package/dist/cjs/modules/word/excel.js +22 -0
  336. package/dist/cjs/modules/word/font/font-embed.js +652 -0
  337. package/dist/cjs/modules/word/{font-obfuscation.js → font/font-obfuscation.js} +4 -9
  338. package/dist/cjs/modules/word/font/hyphenation.js +4216 -0
  339. package/dist/cjs/modules/word/font/text-shaping.js +640 -0
  340. package/dist/cjs/modules/word/html.js +9 -7
  341. package/dist/cjs/modules/word/incremental-edit.js +366 -0
  342. package/dist/cjs/modules/word/index.base.js +370 -137
  343. package/dist/cjs/modules/word/layout/layout-constants.js +20 -0
  344. package/dist/cjs/modules/word/layout/layout-full.js +1699 -0
  345. package/dist/cjs/modules/word/layout/layout-model.js +17 -0
  346. package/dist/cjs/modules/word/layout/layout.js +1170 -0
  347. package/dist/cjs/modules/word/layout/render-page.js +1243 -0
  348. package/dist/cjs/modules/word/markdown.js +19 -0
  349. package/dist/cjs/modules/word/patcher.js +539 -0
  350. package/dist/cjs/modules/word/query/compat.js +61 -0
  351. package/dist/cjs/modules/word/query/data-binding.js +395 -0
  352. package/dist/cjs/modules/word/query/form-fields.js +272 -0
  353. package/dist/cjs/modules/word/query/format-search.js +334 -0
  354. package/dist/cjs/modules/word/query/mail-merge.js +114 -0
  355. package/dist/cjs/modules/word/query/merge.js +620 -0
  356. package/dist/cjs/modules/word/query/replace.js +304 -0
  357. package/dist/cjs/modules/word/query/revisions.js +885 -0
  358. package/dist/cjs/modules/word/query/search.js +361 -0
  359. package/dist/cjs/modules/word/query/split.js +138 -0
  360. package/dist/cjs/modules/word/query/style-resolve.js +374 -0
  361. package/dist/cjs/modules/word/reader/chart-parser.js +814 -0
  362. package/dist/cjs/modules/word/reader/comments-parser.js +96 -0
  363. package/dist/cjs/modules/word/reader/doc-props-parsers.js +194 -0
  364. package/dist/cjs/modules/word/reader/docx-reader.js +2560 -0
  365. package/dist/cjs/modules/word/reader/drawing-helpers.js +90 -0
  366. package/dist/cjs/modules/word/reader/form-field-parser.js +85 -0
  367. package/dist/cjs/modules/word/reader/image-parsers.js +293 -0
  368. package/dist/cjs/modules/word/reader/math-parser.js +424 -0
  369. package/dist/cjs/modules/word/reader/metadata-parsers.js +93 -0
  370. package/dist/cjs/modules/word/reader/numbering-parser.js +168 -0
  371. package/dist/cjs/modules/word/reader/paragraph-section-parsers.js +505 -0
  372. package/dist/cjs/modules/word/reader/parse-utils.js +271 -0
  373. package/dist/cjs/modules/word/reader/properties-parsers.js +338 -0
  374. package/dist/cjs/modules/word/reader/reader-context.js +66 -0
  375. package/dist/cjs/modules/word/reader/sdt-helpers.js +114 -0
  376. package/dist/cjs/modules/word/reader/settings-parser.js +265 -0
  377. package/dist/cjs/modules/word/reader/styles-parser.js +149 -0
  378. package/dist/cjs/modules/word/reader/table-properties-parsers.js +237 -0
  379. package/dist/cjs/modules/word/reader/theme-parser.js +169 -0
  380. package/dist/cjs/modules/word/reader/watermark-parser.js +113 -0
  381. package/dist/cjs/modules/word/security/cfb-reader.js +414 -0
  382. package/dist/cjs/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  383. package/dist/cjs/modules/word/security/document-protection.js +208 -0
  384. package/dist/cjs/modules/word/security/encryption.js +612 -0
  385. package/dist/cjs/modules/word/security/policy.js +106 -0
  386. package/dist/cjs/modules/word/template/template-chart.js +170 -0
  387. package/dist/cjs/modules/word/template/template-datasource.js +549 -0
  388. package/dist/cjs/modules/word/template/template-engine.js +1430 -0
  389. package/dist/cjs/modules/word/units.js +44 -14
  390. package/dist/cjs/modules/word/{writers → writer}/chart-writer.js +163 -22
  391. package/dist/cjs/modules/word/writer/checkbox-writer.js +82 -0
  392. package/dist/cjs/modules/word/{writers → writer}/comment-writer.js +8 -6
  393. package/dist/cjs/modules/word/writer/common-parts.js +104 -0
  394. package/dist/cjs/modules/word/{content-types.js → writer/content-types.js} +14 -6
  395. package/dist/cjs/modules/word/writer/document-writer.js +478 -0
  396. package/dist/cjs/modules/word/writer/docx-packager.js +1551 -0
  397. package/dist/cjs/modules/word/{writers → writer}/footnote-writer.js +13 -10
  398. package/dist/cjs/modules/word/{writers → writer}/header-footer-writer.js +38 -20
  399. package/dist/cjs/modules/word/{writers → writer}/image-writer.js +11 -7
  400. package/dist/cjs/modules/word/{writers → writer}/math-writer.js +21 -1
  401. package/dist/cjs/modules/word/{writers → writer}/numbering-writer.js +11 -4
  402. package/dist/cjs/modules/word/{writers → writer}/paragraph-writer.js +72 -37
  403. package/dist/cjs/modules/word/{writers → writer}/parts-writer.js +91 -12
  404. package/dist/cjs/modules/word/writer/reference-scanners.js +120 -0
  405. package/dist/cjs/modules/word/writer/relationships.js +124 -0
  406. package/dist/cjs/modules/word/writer/render-context.js +51 -0
  407. package/dist/cjs/modules/word/{writers → writer}/run-writer.js +127 -24
  408. package/dist/cjs/modules/word/writer/sdt-writer.js +192 -0
  409. package/dist/cjs/modules/word/writer/stream-buf.js +76 -0
  410. package/dist/cjs/modules/word/writer/streaming-writer.js +1387 -0
  411. package/dist/cjs/modules/word/writer/string-buf.js +11 -0
  412. package/dist/cjs/modules/word/{writers → writer}/styles-writer.js +32 -1
  413. package/dist/cjs/modules/word/{writers → writer}/table-writer.js +94 -11
  414. package/dist/cjs/utils/crypto.browser.js +3 -1
  415. package/dist/cjs/utils/crypto.js +4 -1
  416. package/dist/cjs/utils/font-metrics.js +303 -0
  417. package/dist/cjs/utils/string-buf.js +92 -0
  418. package/dist/cjs/utils/theme-colors.js +126 -0
  419. package/dist/esm/modules/archive/compression/streaming-compress.browser.js +29 -0
  420. package/dist/esm/modules/archive/compression/streaming-compress.js +9 -0
  421. package/dist/esm/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  422. package/dist/esm/modules/archive/fs/archive-file.js +78 -16
  423. package/dist/esm/modules/archive/unzip/stream.browser.js +43 -2
  424. package/dist/esm/modules/excel/chart/chart-ex-builder.js +7 -2
  425. package/dist/esm/modules/excel/chart/chart-ex-renderer.js +4 -9
  426. package/dist/esm/modules/excel/chart/chart.js +1 -7
  427. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +25 -1
  428. package/dist/esm/modules/excel/stream/workbook-reader.js +9 -0
  429. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +228 -13
  430. package/dist/esm/modules/excel/utils/string-buf.js +4 -81
  431. package/dist/esm/modules/excel/workbook.browser.js +135 -25
  432. package/dist/esm/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  433. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +32 -8
  434. package/dist/esm/modules/excel/xlsx/xlsx.js +9 -1
  435. package/dist/esm/modules/pdf/excel-bridge.js +32 -0
  436. package/dist/esm/modules/pdf/font/metrics.js +3 -237
  437. package/dist/esm/modules/pdf/index.js +1 -1
  438. package/dist/esm/modules/pdf/render-layout-to-pdf.js +647 -0
  439. package/dist/esm/modules/pdf/word-bridge.js +122 -274
  440. package/dist/esm/modules/stream/index.base.js +2 -1
  441. package/dist/esm/modules/stream/internal/sink-adapter.js +198 -0
  442. package/dist/esm/modules/stream/pull-stream.js +51 -5
  443. package/dist/esm/modules/word/advanced/diff.js +167 -0
  444. package/dist/esm/modules/word/advanced/drawing-shapes.js +268 -0
  445. package/dist/esm/modules/word/advanced/field-engine.js +1225 -0
  446. package/dist/esm/modules/word/advanced/glossary.js +79 -0
  447. package/dist/esm/modules/word/advanced/math-convert.js +595 -0
  448. package/dist/esm/modules/word/advanced/ole-objects.js +271 -0
  449. package/dist/esm/modules/word/advanced/style-map.js +322 -0
  450. package/dist/esm/modules/word/advanced/validation.js +1065 -0
  451. package/dist/esm/modules/word/advanced/vba-project.js +265 -0
  452. package/dist/esm/modules/word/bridge/excel-bridge.js +980 -0
  453. package/dist/esm/modules/word/builder/document-handle.js +664 -0
  454. package/dist/esm/modules/word/builder/paragraph-builders.js +90 -0
  455. package/dist/esm/modules/word/builder/run-builders.js +600 -0
  456. package/dist/esm/modules/word/builder/table-builders.js +45 -0
  457. package/dist/esm/modules/word/constants.js +109 -1
  458. package/dist/esm/modules/word/convert/conversion-ir.js +31 -0
  459. package/dist/esm/modules/word/convert/docx-to-semantic.js +499 -0
  460. package/dist/esm/modules/word/convert/flat-opc.js +385 -0
  461. package/dist/esm/modules/word/convert/html/html-import.js +1907 -0
  462. package/dist/{browser/modules/word → esm/modules/word/convert/html}/html-renderer.js +420 -69
  463. package/dist/esm/modules/word/convert/html/html.js +15 -0
  464. package/dist/esm/modules/word/convert/markdown/markdown-import.js +1325 -0
  465. package/dist/esm/modules/word/convert/markdown/markdown-renderer.js +634 -0
  466. package/dist/esm/modules/word/convert/markdown/markdown.js +15 -0
  467. package/dist/esm/modules/word/convert/odt/odt.js +1932 -0
  468. package/dist/esm/modules/word/core/color-utils.js +43 -0
  469. package/dist/esm/modules/word/core/internal-utils.js +209 -0
  470. package/dist/esm/modules/word/core/mapper.js +427 -0
  471. package/dist/esm/modules/word/core/opc-paths.js +48 -0
  472. package/dist/esm/modules/word/core/text-utils.js +202 -0
  473. package/dist/esm/modules/word/core/walker.js +570 -0
  474. package/dist/esm/modules/word/crypto.js +13 -7
  475. package/dist/esm/modules/word/document-io.js +80 -197
  476. package/dist/esm/modules/word/errors.js +54 -2
  477. package/dist/esm/modules/word/excel.js +13 -0
  478. package/dist/esm/modules/word/font/font-embed.js +646 -0
  479. package/dist/{browser/modules/word → esm/modules/word/font}/font-obfuscation.js +4 -9
  480. package/dist/esm/modules/word/font/hyphenation.js +4210 -0
  481. package/dist/esm/modules/word/font/text-shaping.js +635 -0
  482. package/dist/esm/modules/word/html.js +6 -5
  483. package/dist/esm/modules/word/incremental-edit.js +361 -0
  484. package/dist/esm/modules/word/index.base.js +138 -29
  485. package/dist/esm/modules/word/layout/layout-constants.js +17 -0
  486. package/dist/esm/modules/word/layout/layout-full.js +1696 -0
  487. package/dist/esm/modules/word/layout/layout-model.js +16 -0
  488. package/dist/esm/modules/word/layout/layout.js +1167 -0
  489. package/dist/esm/modules/word/layout/render-page.js +1238 -0
  490. package/dist/esm/modules/word/markdown.js +13 -0
  491. package/dist/esm/modules/word/patcher.js +537 -0
  492. package/dist/esm/modules/word/query/compat.js +58 -0
  493. package/dist/esm/modules/word/query/data-binding.js +392 -0
  494. package/dist/esm/modules/word/query/form-fields.js +268 -0
  495. package/dist/esm/modules/word/query/format-search.js +329 -0
  496. package/dist/esm/modules/word/query/mail-merge.js +111 -0
  497. package/dist/esm/modules/word/query/merge.js +617 -0
  498. package/dist/esm/modules/word/query/replace.js +301 -0
  499. package/dist/esm/modules/word/query/revisions.js +879 -0
  500. package/dist/esm/modules/word/query/search.js +346 -0
  501. package/dist/esm/modules/word/query/split.js +135 -0
  502. package/dist/esm/modules/word/query/style-resolve.js +368 -0
  503. package/dist/esm/modules/word/reader/chart-parser.js +810 -0
  504. package/dist/esm/modules/word/reader/comments-parser.js +92 -0
  505. package/dist/esm/modules/word/reader/doc-props-parsers.js +190 -0
  506. package/dist/esm/modules/word/reader/docx-reader.js +2557 -0
  507. package/dist/esm/modules/word/reader/drawing-helpers.js +84 -0
  508. package/dist/esm/modules/word/reader/form-field-parser.js +82 -0
  509. package/dist/esm/modules/word/reader/image-parsers.js +291 -0
  510. package/dist/esm/modules/word/reader/math-parser.js +422 -0
  511. package/dist/esm/modules/word/reader/metadata-parsers.js +87 -0
  512. package/dist/esm/modules/word/reader/numbering-parser.js +166 -0
  513. package/dist/esm/modules/word/reader/paragraph-section-parsers.js +503 -0
  514. package/dist/esm/modules/word/reader/parse-utils.js +249 -0
  515. package/dist/esm/modules/word/reader/properties-parsers.js +332 -0
  516. package/dist/esm/modules/word/reader/reader-context.js +61 -0
  517. package/dist/esm/modules/word/reader/sdt-helpers.js +111 -0
  518. package/dist/esm/modules/word/reader/settings-parser.js +263 -0
  519. package/dist/esm/modules/word/reader/styles-parser.js +147 -0
  520. package/dist/esm/modules/word/reader/table-properties-parsers.js +234 -0
  521. package/dist/esm/modules/word/reader/theme-parser.js +167 -0
  522. package/dist/esm/modules/word/reader/watermark-parser.js +110 -0
  523. package/dist/esm/modules/word/security/cfb-reader.js +410 -0
  524. package/dist/esm/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  525. package/dist/esm/modules/word/security/document-protection.js +201 -0
  526. package/dist/esm/modules/word/security/encryption.js +602 -0
  527. package/dist/esm/modules/word/security/policy.js +102 -0
  528. package/dist/esm/modules/word/template/template-chart.js +167 -0
  529. package/dist/esm/modules/word/template/template-datasource.js +541 -0
  530. package/dist/esm/modules/word/template/template-engine.js +1435 -0
  531. package/dist/esm/modules/word/units.js +43 -14
  532. package/dist/esm/modules/word/{writers → writer}/chart-writer.js +164 -23
  533. package/dist/esm/modules/word/writer/checkbox-writer.js +79 -0
  534. package/dist/esm/modules/word/{writers → writer}/comment-writer.js +8 -6
  535. package/dist/esm/modules/word/writer/common-parts.js +101 -0
  536. package/dist/{browser/modules/word → esm/modules/word/writer}/content-types.js +14 -6
  537. package/dist/esm/modules/word/writer/document-writer.js +473 -0
  538. package/dist/esm/modules/word/writer/docx-packager.js +1515 -0
  539. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/footnote-writer.js +13 -10
  540. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/header-footer-writer.js +39 -21
  541. package/dist/esm/modules/word/{writers → writer}/image-writer.js +11 -7
  542. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/math-writer.js +21 -1
  543. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/numbering-writer.js +11 -4
  544. package/dist/esm/modules/word/{writers → writer}/paragraph-writer.js +73 -38
  545. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/parts-writer.js +91 -12
  546. package/dist/esm/modules/word/writer/reference-scanners.js +111 -0
  547. package/dist/esm/modules/word/writer/relationships.js +117 -0
  548. package/dist/esm/modules/word/writer/render-context.js +46 -0
  549. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/run-writer.js +126 -24
  550. package/dist/esm/modules/word/writer/sdt-writer.js +189 -0
  551. package/dist/esm/modules/word/writer/stream-buf.js +73 -0
  552. package/dist/esm/modules/word/writer/streaming-writer.js +1382 -0
  553. package/dist/esm/modules/word/writer/string-buf.js +7 -0
  554. package/dist/esm/modules/word/{writers → writer}/styles-writer.js +32 -1
  555. package/dist/esm/modules/word/{writers → writer}/table-writer.js +94 -11
  556. package/dist/esm/utils/crypto.browser.js +3 -1
  557. package/dist/esm/utils/crypto.js +4 -1
  558. package/dist/esm/utils/font-metrics.js +293 -0
  559. package/dist/esm/utils/string-buf.js +89 -0
  560. package/dist/esm/utils/theme-colors.js +120 -0
  561. package/dist/iife/excelts.iife.js +70692 -70337
  562. package/dist/iife/excelts.iife.js.map +1 -1
  563. package/dist/iife/excelts.iife.min.js +57 -57
  564. package/dist/types/modules/archive/fs/archive-file.d.ts +8 -5
  565. package/dist/types/modules/excel/chart/chart-ex-types.d.ts +0 -12
  566. package/dist/types/modules/excel/chart/chart.d.ts +1 -5
  567. package/dist/types/modules/excel/chart/types.d.ts +0 -6
  568. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
  569. package/dist/types/modules/excel/utils/string-buf.d.ts +5 -26
  570. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
  571. package/dist/types/modules/excel/xlsx/xlsx.d.ts +10 -2
  572. package/dist/types/modules/pdf/excel-bridge.d.ts +30 -1
  573. package/dist/types/modules/pdf/font/metrics.d.ts +3 -52
  574. package/dist/types/modules/pdf/index.d.ts +1 -1
  575. package/dist/types/modules/pdf/render-layout-to-pdf.d.ts +66 -0
  576. package/dist/types/modules/pdf/word-bridge.d.ts +80 -12
  577. package/dist/types/modules/stream/index.base.d.ts +2 -0
  578. package/dist/types/modules/stream/internal/sink-adapter.d.ts +65 -0
  579. package/dist/types/modules/stream/pull-stream.d.ts +19 -2
  580. package/dist/types/modules/stream/types.d.ts +13 -1
  581. package/dist/types/modules/word/advanced/diff.d.ts +61 -0
  582. package/dist/types/modules/word/advanced/drawing-shapes.d.ts +269 -0
  583. package/dist/types/modules/word/advanced/field-engine.d.ts +43 -0
  584. package/dist/types/modules/word/advanced/glossary.d.ts +86 -0
  585. package/dist/types/modules/word/advanced/math-convert.d.ts +30 -0
  586. package/dist/types/modules/word/advanced/ole-objects.d.ts +115 -0
  587. package/dist/types/modules/word/advanced/style-map.d.ts +105 -0
  588. package/dist/types/modules/word/advanced/validation.d.ts +56 -0
  589. package/dist/types/modules/word/advanced/vba-project.d.ts +91 -0
  590. package/dist/types/modules/word/bridge/excel-bridge.d.ts +127 -0
  591. package/dist/types/modules/word/builder/document-handle.d.ts +151 -0
  592. package/dist/types/modules/word/builder/paragraph-builders.d.ts +61 -0
  593. package/dist/types/modules/word/builder/run-builders.d.ts +374 -0
  594. package/dist/types/modules/word/builder/table-builders.d.ts +23 -0
  595. package/dist/types/modules/word/constants.d.ts +39 -1
  596. package/dist/types/modules/word/convert/conversion-ir.d.ts +210 -0
  597. package/dist/types/modules/word/convert/docx-to-semantic.d.ts +39 -0
  598. package/dist/types/modules/word/convert/flat-opc.d.ts +44 -0
  599. package/dist/types/modules/word/convert/html/html-import.d.ts +50 -0
  600. package/dist/{browser/modules/word → types/modules/word/convert/html}/html-renderer.d.ts +14 -1
  601. package/dist/types/modules/word/convert/html/html.d.ts +15 -0
  602. package/dist/types/modules/word/convert/markdown/markdown-import.d.ts +68 -0
  603. package/dist/types/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
  604. package/dist/types/modules/word/convert/markdown/markdown.d.ts +15 -0
  605. package/dist/types/modules/word/convert/odt/odt.d.ts +41 -0
  606. package/dist/types/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
  607. package/dist/types/modules/word/core/internal-utils.d.ts +90 -0
  608. package/dist/types/modules/word/core/mapper.d.ts +44 -0
  609. package/dist/types/modules/word/core/opc-paths.d.ts +33 -0
  610. package/dist/types/modules/word/core/text-utils.d.ts +38 -0
  611. package/dist/types/modules/word/core/walker.d.ts +119 -0
  612. package/dist/types/modules/word/crypto.d.ts +14 -9
  613. package/dist/types/modules/word/document-io.d.ts +59 -27
  614. package/dist/types/modules/word/errors.d.ts +44 -1
  615. package/dist/types/modules/word/excel.d.ts +14 -0
  616. package/dist/types/modules/word/font/font-embed.d.ts +112 -0
  617. package/dist/types/modules/word/font/hyphenation.d.ts +65 -0
  618. package/dist/types/modules/word/font/text-shaping.d.ts +58 -0
  619. package/dist/types/modules/word/html.d.ts +7 -6
  620. package/dist/types/modules/word/incremental-edit.d.ts +123 -0
  621. package/dist/types/modules/word/index.base.d.ts +194 -10
  622. package/dist/types/modules/word/layout/layout-constants.d.ts +17 -0
  623. package/dist/types/modules/word/layout/layout-full.d.ts +53 -0
  624. package/dist/types/modules/word/layout/layout-model.d.ts +344 -0
  625. package/dist/types/modules/word/layout/layout.d.ts +63 -0
  626. package/dist/types/modules/word/layout/render-page.d.ts +57 -0
  627. package/dist/types/modules/word/markdown.d.ts +14 -0
  628. package/dist/types/modules/word/patcher.d.ts +62 -0
  629. package/dist/types/modules/word/query/compat.d.ts +25 -0
  630. package/dist/types/modules/word/query/data-binding.d.ts +22 -0
  631. package/dist/types/modules/word/query/form-fields.d.ts +41 -0
  632. package/dist/types/modules/word/query/format-search.d.ts +99 -0
  633. package/dist/types/modules/word/query/mail-merge.d.ts +25 -0
  634. package/dist/types/modules/word/query/merge.d.ts +50 -0
  635. package/dist/types/modules/word/query/replace.d.ts +47 -0
  636. package/dist/types/modules/word/query/revisions.d.ts +67 -0
  637. package/dist/types/modules/word/query/search.d.ts +129 -0
  638. package/dist/types/modules/word/query/split.d.ts +44 -0
  639. package/dist/types/modules/word/query/style-resolve.d.ts +104 -0
  640. package/dist/types/modules/word/reader/chart-parser.d.ts +20 -0
  641. package/dist/types/modules/word/reader/comments-parser.d.ts +26 -0
  642. package/dist/types/modules/word/reader/doc-props-parsers.d.ts +15 -0
  643. package/dist/types/modules/word/reader/docx-reader.d.ts +27 -0
  644. package/dist/types/modules/word/reader/drawing-helpers.d.ts +27 -0
  645. package/dist/types/modules/word/reader/form-field-parser.d.ts +21 -0
  646. package/dist/types/modules/word/reader/image-parsers.d.ts +11 -0
  647. package/dist/types/modules/word/reader/math-parser.d.ts +12 -0
  648. package/dist/types/modules/word/reader/metadata-parsers.d.ts +17 -0
  649. package/dist/types/modules/word/reader/numbering-parser.d.ts +13 -0
  650. package/dist/types/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
  651. package/dist/types/modules/word/reader/parse-utils.d.ts +91 -0
  652. package/dist/types/modules/word/reader/properties-parsers.d.ts +21 -0
  653. package/dist/types/modules/word/reader/reader-context.d.ts +69 -0
  654. package/dist/types/modules/word/reader/sdt-helpers.d.ts +29 -0
  655. package/dist/types/modules/word/reader/settings-parser.d.ts +8 -0
  656. package/dist/types/modules/word/reader/styles-parser.d.ts +12 -0
  657. package/dist/types/modules/word/reader/table-properties-parsers.d.ts +12 -0
  658. package/dist/types/modules/word/reader/theme-parser.d.ts +8 -0
  659. package/dist/types/modules/word/reader/watermark-parser.d.ts +15 -0
  660. package/dist/types/modules/word/security/cfb-reader.d.ts +37 -0
  661. package/dist/types/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
  662. package/dist/types/modules/word/security/document-protection.d.ts +93 -0
  663. package/dist/{browser/modules/word → types/modules/word/security}/encryption.d.ts +51 -4
  664. package/dist/types/modules/word/security/policy.d.ts +80 -0
  665. package/dist/types/modules/word/template/template-chart.d.ts +56 -0
  666. package/dist/types/modules/word/template/template-datasource.d.ts +154 -0
  667. package/dist/types/modules/word/template/template-engine.d.ts +121 -0
  668. package/dist/types/modules/word/types.d.ts +224 -25
  669. package/dist/types/modules/word/units.d.ts +26 -0
  670. package/dist/types/modules/word/writer/checkbox-writer.d.ts +17 -0
  671. package/dist/{browser/modules/word/writers → types/modules/word/writer}/comment-writer.d.ts +2 -1
  672. package/dist/types/modules/word/writer/common-parts.d.ts +57 -0
  673. package/dist/{browser/modules/word → types/modules/word/writer}/content-types.d.ts +2 -2
  674. package/dist/types/modules/word/writer/document-writer.d.ts +24 -0
  675. package/dist/types/modules/word/writer/docx-packager.d.ts +35 -0
  676. package/dist/{browser/modules/word/writers → types/modules/word/writer}/footnote-writer.d.ts +3 -2
  677. package/dist/{browser/modules/word/writers → types/modules/word/writer}/header-footer-writer.d.ts +3 -2
  678. package/dist/{browser/modules/word/writers → types/modules/word/writer}/image-writer.d.ts +1 -1
  679. package/dist/types/modules/word/writer/math-writer.d.ts +20 -0
  680. package/dist/types/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
  681. package/dist/types/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
  682. package/dist/types/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
  683. package/dist/types/modules/word/writer/reference-scanners.d.ts +42 -0
  684. package/dist/types/modules/word/writer/relationships.d.ts +52 -0
  685. package/dist/types/modules/word/writer/render-context.d.ts +124 -0
  686. package/dist/types/modules/word/{writers → writer}/run-writer.d.ts +10 -1
  687. package/dist/types/modules/word/writer/sdt-writer.d.ts +25 -0
  688. package/dist/types/modules/word/writer/stream-buf.d.ts +37 -0
  689. package/dist/types/modules/word/writer/streaming-writer.d.ts +344 -0
  690. package/dist/types/modules/word/writer/string-buf.d.ts +8 -0
  691. package/dist/types/modules/word/{writers → writer}/table-writer.d.ts +2 -1
  692. package/dist/types/modules/xml/types.d.ts +22 -0
  693. package/dist/types/utils/crypto.browser.d.ts +3 -1
  694. package/dist/types/utils/crypto.d.ts +4 -1
  695. package/dist/types/utils/font-metrics.d.ts +63 -0
  696. package/dist/types/utils/string-buf.d.ts +42 -0
  697. package/dist/types/utils/theme-colors.d.ts +55 -0
  698. package/package.json +121 -39
  699. package/dist/browser/modules/word/color-utils.js +0 -94
  700. package/dist/browser/modules/word/document.d.ts +0 -657
  701. package/dist/browser/modules/word/document.js +0 -1533
  702. package/dist/browser/modules/word/docx-packager.d.ts +0 -14
  703. package/dist/browser/modules/word/docx-packager.js +0 -822
  704. package/dist/browser/modules/word/docx-reader.d.ts +0 -11
  705. package/dist/browser/modules/word/docx-reader.js +0 -4929
  706. package/dist/browser/modules/word/encryption.js +0 -274
  707. package/dist/browser/modules/word/internal-utils.d.ts +0 -23
  708. package/dist/browser/modules/word/internal-utils.js +0 -54
  709. package/dist/browser/modules/word/namespaces.d.ts +0 -159
  710. package/dist/browser/modules/word/namespaces.js +0 -189
  711. package/dist/browser/modules/word/relationships.d.ts +0 -30
  712. package/dist/browser/modules/word/relationships.js +0 -48
  713. package/dist/browser/modules/word/writers/checkbox-writer.d.ts +0 -9
  714. package/dist/browser/modules/word/writers/checkbox-writer.js +0 -42
  715. package/dist/browser/modules/word/writers/document-writer.d.ts +0 -16
  716. package/dist/browser/modules/word/writers/document-writer.js +0 -461
  717. package/dist/browser/modules/word/writers/math-writer.d.ts +0 -9
  718. package/dist/cjs/modules/word/color-utils.js +0 -97
  719. package/dist/cjs/modules/word/document.js +0 -1645
  720. package/dist/cjs/modules/word/docx-packager.js +0 -825
  721. package/dist/cjs/modules/word/docx-reader.js +0 -4932
  722. package/dist/cjs/modules/word/encryption.js +0 -282
  723. package/dist/cjs/modules/word/internal-utils.js +0 -59
  724. package/dist/cjs/modules/word/namespaces.js +0 -192
  725. package/dist/cjs/modules/word/relationships.js +0 -55
  726. package/dist/cjs/modules/word/writers/checkbox-writer.js +0 -45
  727. package/dist/cjs/modules/word/writers/document-writer.js +0 -465
  728. package/dist/esm/modules/word/color-utils.js +0 -94
  729. package/dist/esm/modules/word/document.js +0 -1533
  730. package/dist/esm/modules/word/docx-packager.js +0 -822
  731. package/dist/esm/modules/word/docx-reader.js +0 -4929
  732. package/dist/esm/modules/word/encryption.js +0 -274
  733. package/dist/esm/modules/word/internal-utils.js +0 -54
  734. package/dist/esm/modules/word/namespaces.js +0 -189
  735. package/dist/esm/modules/word/relationships.js +0 -48
  736. package/dist/esm/modules/word/writers/checkbox-writer.js +0 -42
  737. package/dist/esm/modules/word/writers/document-writer.js +0 -461
  738. package/dist/types/modules/word/document.d.ts +0 -657
  739. package/dist/types/modules/word/docx-packager.d.ts +0 -14
  740. package/dist/types/modules/word/docx-reader.d.ts +0 -11
  741. package/dist/types/modules/word/internal-utils.d.ts +0 -23
  742. package/dist/types/modules/word/namespaces.d.ts +0 -159
  743. package/dist/types/modules/word/relationships.d.ts +0 -30
  744. package/dist/types/modules/word/writers/checkbox-writer.d.ts +0 -9
  745. package/dist/types/modules/word/writers/document-writer.d.ts +0 -16
  746. package/dist/types/modules/word/writers/math-writer.d.ts +0 -9
  747. /package/dist/browser/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
  748. /package/dist/browser/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
  749. /package/dist/browser/modules/word/{writers → writer}/section-writer.d.ts +0 -0
  750. /package/dist/browser/modules/word/{writers → writer}/section-writer.js +0 -0
  751. /package/dist/browser/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
  752. /package/dist/browser/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
  753. /package/dist/browser/modules/word/{writers → writer}/textbox-writer.js +0 -0
  754. /package/dist/browser/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
  755. /package/dist/browser/modules/word/{writers → writer}/toc-writer.js +0 -0
  756. /package/dist/cjs/modules/word/{writers → writer}/section-writer.js +0 -0
  757. /package/dist/cjs/modules/word/{writers → writer}/textbox-writer.js +0 -0
  758. /package/dist/cjs/modules/word/{writers → writer}/toc-writer.js +0 -0
  759. /package/dist/esm/modules/word/{writers → writer}/section-writer.js +0 -0
  760. /package/dist/esm/modules/word/{writers → writer}/textbox-writer.js +0 -0
  761. /package/dist/esm/modules/word/{writers → writer}/toc-writer.js +0 -0
  762. /package/dist/types/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
  763. /package/dist/types/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
  764. /package/dist/types/modules/word/{writers → writer}/section-writer.d.ts +0 -0
  765. /package/dist/types/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
  766. /package/dist/types/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
  767. /package/dist/types/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
@@ -0,0 +1,1065 @@
1
+ /**
2
+ * DOCX Module - Document Validation (Schema Validation)
3
+ *
4
+ * Provides structural validation of DocxDocument models against the
5
+ * OOXML WordprocessingML constraints. This validates the document model
6
+ * at a semantic level (not XML schema validation) to ensure the generated
7
+ * DOCX will be well-formed and compliant.
8
+ *
9
+ * Validation rules are based on:
10
+ * - ECMA-376 Part 1, Chapter 17 (WordprocessingML)
11
+ * - Practical interoperability constraints from Word/LibreOffice
12
+ */
13
+ import { walkBlocks } from "../core/walker.js";
14
+ // =============================================================================
15
+ // Validation Engine
16
+ // =============================================================================
17
+ /**
18
+ * Validate a DocxDocument model for structural correctness and OOXML compliance.
19
+ *
20
+ * @param doc - The document model to validate.
21
+ * @param options - Validation options.
22
+ * @returns Validation result with all issues found.
23
+ */
24
+ export function validateDocument(doc, options = {}) {
25
+ const issues = [];
26
+ const maxErrors = options.maxErrors ?? Infinity;
27
+ const addIssue = (severity, message, path, rule) => {
28
+ if (options.maxSeverity === "error" && severity !== "error") {
29
+ return;
30
+ }
31
+ if (options.maxSeverity === "warning" && severity === "info") {
32
+ return;
33
+ }
34
+ issues.push({ severity, message, path, rule });
35
+ };
36
+ const errorCount = () => issues.filter(i => i.severity === "error").length;
37
+ // --- Document-level checks ---
38
+ validateBody(doc.body, addIssue, errorCount, maxErrors);
39
+ validateStyles(doc.styles, doc.docDefaults, addIssue);
40
+ validateNumberings(doc.abstractNumberings, doc.numberingInstances, addIssue);
41
+ validateHeaders(doc.headers, addIssue);
42
+ validateFooters(doc.footers, addIssue);
43
+ validateImages(doc.images, doc.body, addIssue);
44
+ validateComments(doc.comments, addIssue);
45
+ validateFootnotes(doc.footnotes, addIssue);
46
+ validateEndnotes(doc.endnotes, addIssue);
47
+ validateSectionProperties(doc.sectionProperties, addIssue);
48
+ validateSettings(doc, addIssue);
49
+ validateCrossReferences(doc, addIssue);
50
+ // --- OpenXML compliance checks ---
51
+ validateRelationshipConsistency(doc, addIssue);
52
+ validateContentTypeConsistency(doc, addIssue);
53
+ validateStructuralIntegrity(doc, addIssue);
54
+ validateNamespaceCompliance(doc, addIssue);
55
+ // --- Enhanced validation rules ---
56
+ validateNumberingAbstractConsistency(doc.abstractNumberings, doc.numberingInstances, addIssue);
57
+ validateStyleBasedOnReferences(doc.styles, addIssue);
58
+ validateHeaderFooterReferences(doc.sectionProperties, doc.headers, doc.footers, addIssue);
59
+ validateCommentIdUniqueness(doc.comments, addIssue);
60
+ validateNoteAndCommentReferences(doc, addIssue);
61
+ validateBookmarkNameUniqueness(doc.body, addIssue);
62
+ validateTableCellContent(doc.body, addIssue);
63
+ validateCustomXmlPartItemIds(doc.customXmlParts, addIssue);
64
+ validateImageExtensionMediaType(doc.images, addIssue);
65
+ const errors = issues.filter(i => i.severity === "error").length;
66
+ const warnings = issues.filter(i => i.severity === "warning").length;
67
+ return {
68
+ valid: options.strict ? errors === 0 && warnings === 0 : errors === 0,
69
+ issues,
70
+ errorCount: errors,
71
+ warningCount: warnings
72
+ };
73
+ }
74
+ // =============================================================================
75
+ // Body Validation
76
+ // =============================================================================
77
+ function validateBody(body, addIssue, errorCount, maxErrors) {
78
+ if (!body || body.length === 0) {
79
+ addIssue("warning", "Document body is empty", "body", "empty-body");
80
+ return;
81
+ }
82
+ for (let i = 0; i < body.length; i++) {
83
+ if (errorCount() >= maxErrors) {
84
+ return;
85
+ }
86
+ const element = body[i];
87
+ const path = `body[${i}]`;
88
+ if (!("type" in element)) {
89
+ addIssue("error", "Body element missing 'type' field", path, "missing-type");
90
+ continue;
91
+ }
92
+ switch (element.type) {
93
+ case "paragraph":
94
+ validateParagraph(element, path, addIssue);
95
+ break;
96
+ case "table":
97
+ validateTable(element, path, addIssue);
98
+ break;
99
+ case "floatingImage":
100
+ validateFloatingImage(element, path, addIssue);
101
+ break;
102
+ case "tableOfContents":
103
+ case "math":
104
+ case "textBox":
105
+ case "checkBox":
106
+ case "drawingShape":
107
+ case "opaqueDrawing":
108
+ case "chart":
109
+ case "altChunk":
110
+ case "sdt":
111
+ // These are valid body content types
112
+ break;
113
+ default:
114
+ addIssue("error", `Unknown body content type: "${element.type}"`, path, "unknown-body-type");
115
+ }
116
+ }
117
+ }
118
+ function validateParagraph(p, path, addIssue) {
119
+ if (!p.children || !Array.isArray(p.children)) {
120
+ addIssue("error", "Paragraph missing 'children' array", path, "paragraph-no-children");
121
+ return;
122
+ }
123
+ for (let i = 0; i < p.children.length; i++) {
124
+ const child = p.children[i];
125
+ const childPath = `${path}.children[${i}]`;
126
+ if ("type" in child) {
127
+ // Typed children: hyperlink, bookmarkStart, bookmarkEnd, commentRangeStart, etc.
128
+ const validTypes = [
129
+ "hyperlink",
130
+ "bookmarkStart",
131
+ "bookmarkEnd",
132
+ "commentRangeStart",
133
+ "commentRangeEnd",
134
+ "commentReference",
135
+ "insertedRun",
136
+ "deletedRun",
137
+ "movedFromRun",
138
+ "movedToRun",
139
+ "moveFromRangeStart",
140
+ "moveFromRangeEnd",
141
+ "moveToRangeStart",
142
+ "moveToRangeEnd",
143
+ "formField"
144
+ ];
145
+ if (!validTypes.includes(child.type)) {
146
+ // Could be an unknown type — just warn
147
+ addIssue("info", `Paragraph child has unusual type: "${child.type}"`, childPath, "unusual-para-child");
148
+ }
149
+ }
150
+ else {
151
+ // It should be a Run
152
+ validateRun(child, childPath, addIssue);
153
+ }
154
+ }
155
+ // Validate paragraph properties
156
+ if (p.properties) {
157
+ if (p.properties.numbering) {
158
+ if (typeof p.properties.numbering.numId !== "number") {
159
+ addIssue("warning", "Paragraph numbering reference missing numId", `${path}.properties.numbering`, "numbering-no-numid");
160
+ }
161
+ }
162
+ }
163
+ }
164
+ function validateRun(run, path, addIssue) {
165
+ if (!run.content || !Array.isArray(run.content)) {
166
+ addIssue("error", "Run missing 'content' array", path, "run-no-content");
167
+ return;
168
+ }
169
+ for (let i = 0; i < run.content.length; i++) {
170
+ const rc = run.content[i];
171
+ const rcPath = `${path}.content[${i}]`;
172
+ if (!rc.type) {
173
+ addIssue("error", "RunContent missing 'type' field", rcPath, "rc-no-type");
174
+ }
175
+ }
176
+ }
177
+ function validateTable(t, path, addIssue) {
178
+ if (!t.rows || !Array.isArray(t.rows)) {
179
+ addIssue("error", "Table missing 'rows' array", path, "table-no-rows");
180
+ return;
181
+ }
182
+ if (t.rows.length === 0) {
183
+ addIssue("warning", "Table has no rows", path, "table-empty");
184
+ return;
185
+ }
186
+ // Check consistent column count
187
+ let expectedCols;
188
+ for (let ri = 0; ri < t.rows.length; ri++) {
189
+ const row = t.rows[ri];
190
+ const rowPath = `${path}.rows[${ri}]`;
191
+ if (!row.cells || !Array.isArray(row.cells)) {
192
+ addIssue("error", "TableRow missing 'cells' array", rowPath, "row-no-cells");
193
+ continue;
194
+ }
195
+ // Count effective columns (accounting for gridSpan)
196
+ let colCount = 0;
197
+ for (const cell of row.cells) {
198
+ colCount += cell.properties?.gridSpan ?? 1;
199
+ }
200
+ if (expectedCols === undefined) {
201
+ expectedCols = colCount;
202
+ }
203
+ else if (colCount !== expectedCols && !hasVerticalMerge(row)) {
204
+ addIssue("warning", `Row ${ri} has ${colCount} effective columns, expected ${expectedCols}`, rowPath, "table-col-mismatch");
205
+ }
206
+ // Validate cells
207
+ for (let ci = 0; ci < row.cells.length; ci++) {
208
+ const cell = row.cells[ci];
209
+ const cellPath = `${rowPath}.cells[${ci}]`;
210
+ if (!cell.content || !Array.isArray(cell.content)) {
211
+ addIssue("error", "TableCell missing 'content' array", cellPath, "cell-no-content");
212
+ }
213
+ else if (cell.content.length === 0) {
214
+ addIssue("warning", "TableCell has no content (Word requires at least one paragraph)", cellPath, "cell-empty");
215
+ }
216
+ }
217
+ }
218
+ }
219
+ function hasVerticalMerge(row) {
220
+ return row.cells.some(c => c.properties?.verticalMerge !== undefined);
221
+ }
222
+ function validateFloatingImage(fi, path, addIssue) {
223
+ if (!fi.rId) {
224
+ addIssue("warning", "FloatingImage missing rId (will be assigned during packaging)", path, "fi-no-rid");
225
+ }
226
+ if (!fi.width || fi.width <= 0) {
227
+ addIssue("error", "FloatingImage must have positive width (EMU)", path, "fi-no-width");
228
+ }
229
+ if (!fi.height || fi.height <= 0) {
230
+ addIssue("error", "FloatingImage must have positive height (EMU)", path, "fi-no-height");
231
+ }
232
+ }
233
+ // =============================================================================
234
+ // Style Validation
235
+ // =============================================================================
236
+ function validateStyles(styles, docDefaults, addIssue) {
237
+ if (!styles) {
238
+ return;
239
+ }
240
+ const styleIds = new Set();
241
+ for (let i = 0; i < styles.length; i++) {
242
+ const style = styles[i];
243
+ const path = `styles[${i}]`;
244
+ if (!style.styleId) {
245
+ addIssue("error", "Style missing 'styleId'", path, "style-no-id");
246
+ continue;
247
+ }
248
+ if (styleIds.has(style.styleId)) {
249
+ addIssue("error", `Duplicate style ID: "${style.styleId}"`, path, "style-dup-id");
250
+ }
251
+ styleIds.add(style.styleId);
252
+ if (!style.name) {
253
+ addIssue("warning", `Style "${style.styleId}" missing display name`, path, "style-no-name");
254
+ }
255
+ if (!style.type) {
256
+ addIssue("error", `Style "${style.styleId}" missing type`, path, "style-no-type");
257
+ }
258
+ // basedOn cross-reference is validated in validateCrossReferences (second pass)
259
+ }
260
+ }
261
+ // =============================================================================
262
+ // Numbering Validation
263
+ // =============================================================================
264
+ function validateNumberings(abstractNums, instances, addIssue) {
265
+ if (!abstractNums && !instances) {
266
+ return;
267
+ }
268
+ const abstractIds = new Set();
269
+ if (abstractNums) {
270
+ for (let i = 0; i < abstractNums.length; i++) {
271
+ const an = abstractNums[i];
272
+ if (abstractIds.has(an.abstractNumId)) {
273
+ addIssue("error", `Duplicate abstractNumId: ${an.abstractNumId}`, `abstractNumberings[${i}]`, "num-dup-abstract");
274
+ }
275
+ abstractIds.add(an.abstractNumId);
276
+ if (!an.levels || an.levels.length === 0) {
277
+ addIssue("warning", `AbstractNumbering ${an.abstractNumId} has no levels`, `abstractNumberings[${i}]`, "num-no-levels");
278
+ }
279
+ }
280
+ }
281
+ if (instances) {
282
+ const numIds = new Set();
283
+ for (let i = 0; i < instances.length; i++) {
284
+ const inst = instances[i];
285
+ if (numIds.has(inst.numId)) {
286
+ addIssue("error", `Duplicate numId: ${inst.numId}`, `numberingInstances[${i}]`, "num-dup-instance");
287
+ }
288
+ numIds.add(inst.numId);
289
+ if (!abstractIds.has(inst.abstractNumId)) {
290
+ addIssue("error", `NumberingInstance ${inst.numId} references non-existent abstractNumId ${inst.abstractNumId}`, `numberingInstances[${i}]`, "num-missing-abstract");
291
+ }
292
+ }
293
+ }
294
+ }
295
+ // =============================================================================
296
+ // Header / Footer Validation
297
+ // =============================================================================
298
+ function validateHeaders(headers, addIssue) {
299
+ if (!headers) {
300
+ return;
301
+ }
302
+ for (const [key, header] of headers) {
303
+ if (!header.content || !header.content.children) {
304
+ addIssue("error", `Header "${key}" missing content.children`, `headers["${key}"]`, "header-no-content");
305
+ }
306
+ }
307
+ }
308
+ function validateFooters(footers, addIssue) {
309
+ if (!footers) {
310
+ return;
311
+ }
312
+ for (const [key, footer] of footers) {
313
+ if (!footer.content || !footer.content.children) {
314
+ addIssue("error", `Footer "${key}" missing content.children`, `footers["${key}"]`, "footer-no-content");
315
+ }
316
+ }
317
+ }
318
+ // =============================================================================
319
+ // Image Validation
320
+ // =============================================================================
321
+ function validateImages(images, body, addIssue) {
322
+ if (!images) {
323
+ return;
324
+ }
325
+ const fileNames = new Set();
326
+ for (let i = 0; i < images.length; i++) {
327
+ const img = images[i];
328
+ const path = `images[${i}]`;
329
+ if (!img.data || img.data.length === 0) {
330
+ addIssue("error", "Image has empty data", path, "image-empty-data");
331
+ }
332
+ if (!img.fileName) {
333
+ addIssue("error", "Image missing fileName", path, "image-no-filename");
334
+ }
335
+ else if (fileNames.has(img.fileName)) {
336
+ addIssue("error", `Duplicate image fileName: "${img.fileName}"`, path, "image-dup-filename");
337
+ }
338
+ else {
339
+ fileNames.add(img.fileName);
340
+ }
341
+ if (!img.mediaType) {
342
+ addIssue("warning", "Image missing mediaType", path, "image-no-mediatype");
343
+ }
344
+ }
345
+ }
346
+ // =============================================================================
347
+ // Comment / Note Validation
348
+ // =============================================================================
349
+ function validateComments(comments, addIssue) {
350
+ if (!comments) {
351
+ return;
352
+ }
353
+ const ids = new Set();
354
+ for (let i = 0; i < comments.length; i++) {
355
+ const c = comments[i];
356
+ if (ids.has(c.id)) {
357
+ addIssue("error", `Duplicate comment ID: ${c.id}`, `comments[${i}]`, "comment-dup-id");
358
+ }
359
+ ids.add(c.id);
360
+ if (!c.author) {
361
+ addIssue("warning", `Comment ${c.id} missing author`, `comments[${i}]`, "comment-no-author");
362
+ }
363
+ }
364
+ }
365
+ function validateFootnotes(footnotes, addIssue) {
366
+ if (!footnotes) {
367
+ return;
368
+ }
369
+ const ids = new Set();
370
+ for (let i = 0; i < footnotes.length; i++) {
371
+ const fn = footnotes[i];
372
+ if (ids.has(fn.id)) {
373
+ addIssue("error", `Duplicate footnote ID: ${fn.id}`, `footnotes[${i}]`, "footnote-dup-id");
374
+ }
375
+ ids.add(fn.id);
376
+ }
377
+ }
378
+ function validateEndnotes(endnotes, addIssue) {
379
+ if (!endnotes) {
380
+ return;
381
+ }
382
+ const ids = new Set();
383
+ for (let i = 0; i < endnotes.length; i++) {
384
+ const en = endnotes[i];
385
+ if (ids.has(en.id)) {
386
+ addIssue("error", `Duplicate endnote ID: ${en.id}`, `endnotes[${i}]`, "endnote-dup-id");
387
+ }
388
+ ids.add(en.id);
389
+ }
390
+ }
391
+ // =============================================================================
392
+ // Section Properties Validation
393
+ // =============================================================================
394
+ function validateSectionProperties(sp, addIssue) {
395
+ if (!sp) {
396
+ return;
397
+ }
398
+ if (sp.pageSize) {
399
+ if (sp.pageSize.width && sp.pageSize.width <= 0) {
400
+ addIssue("error", "Page width must be positive", "sectionProperties.pageSize", "section-bad-width");
401
+ }
402
+ if (sp.pageSize.height && sp.pageSize.height <= 0) {
403
+ addIssue("error", "Page height must be positive", "sectionProperties.pageSize", "section-bad-height");
404
+ }
405
+ }
406
+ if (sp.columns && sp.columns.count !== undefined && sp.columns.count < 1) {
407
+ addIssue("error", "Column count must be at least 1", "sectionProperties.columns", "section-bad-cols");
408
+ }
409
+ }
410
+ // =============================================================================
411
+ // Settings Validation
412
+ // =============================================================================
413
+ function validateSettings(doc, addIssue) {
414
+ if (doc.settings?.documentProtection) {
415
+ const dp = doc.settings.documentProtection;
416
+ if (dp.enforcement && !dp.edit) {
417
+ addIssue("warning", "Document protection enforced but no edit restriction type specified", "settings.documentProtection", "protection-no-edit");
418
+ }
419
+ }
420
+ }
421
+ // =============================================================================
422
+ // Cross-Reference Validation
423
+ // =============================================================================
424
+ function validateCrossReferences(doc, addIssue) {
425
+ // Collect valid numbering IDs
426
+ const validNumIds = new Set();
427
+ if (doc.numberingInstances) {
428
+ for (const inst of doc.numberingInstances) {
429
+ validNumIds.add(inst.numId);
430
+ }
431
+ }
432
+ // Collect valid style IDs
433
+ const validStyleIds = new Set();
434
+ if (doc.styles) {
435
+ for (const style of doc.styles) {
436
+ if (style.styleId) {
437
+ validStyleIds.add(style.styleId);
438
+ }
439
+ }
440
+ }
441
+ // Validate paragraph numbering references
442
+ let paraIdx = 0;
443
+ for (const element of doc.body) {
444
+ if (element.type === "paragraph") {
445
+ const numRef = element.properties?.numbering;
446
+ if (numRef && typeof numRef.numId === "number" && validNumIds.size > 0) {
447
+ if (!validNumIds.has(numRef.numId)) {
448
+ addIssue("warning", `Paragraph references numId ${numRef.numId} which does not exist in numberingInstances`, `body[${paraIdx}].properties.numbering`, "xref-numbering-missing");
449
+ }
450
+ }
451
+ // Validate style reference
452
+ if (element.properties?.style && validStyleIds.size > 0) {
453
+ if (!validStyleIds.has(element.properties.style)) {
454
+ addIssue("info", `Paragraph references style "${element.properties.style}" which is not defined`, `body[${paraIdx}].properties.style`, "xref-style-missing");
455
+ }
456
+ }
457
+ }
458
+ paraIdx++;
459
+ }
460
+ // Validate basedOn style references (second pass — all styles now collected)
461
+ if (doc.styles) {
462
+ for (let i = 0; i < doc.styles.length; i++) {
463
+ const style = doc.styles[i];
464
+ if (style.basedOn && !validStyleIds.has(style.basedOn)) {
465
+ addIssue("warning", `Style "${style.styleId}" references basedOn style "${style.basedOn}" which does not exist`, `styles[${i}]`, "xref-basedOn-missing");
466
+ }
467
+ }
468
+ }
469
+ }
470
+ // =============================================================================
471
+ // Relationship Consistency Validation
472
+ // =============================================================================
473
+ function validateRelationshipConsistency(doc, addIssue) {
474
+ // Collect all valid image rIds
475
+ const validImageRIds = new Set();
476
+ if (doc.images) {
477
+ for (const img of doc.images) {
478
+ if (img.rId) {
479
+ validImageRIds.add(img.rId);
480
+ }
481
+ }
482
+ }
483
+ // Validate body image references (InlineImageContent and FloatingImage)
484
+ for (let i = 0; i < doc.body.length; i++) {
485
+ const element = doc.body[i];
486
+ const path = `body[${i}]`;
487
+ if (element.type === "floatingImage") {
488
+ const fi = element;
489
+ if (fi.rId && doc.images && doc.images.length > 0 && !validImageRIds.has(fi.rId)) {
490
+ addIssue("error", `FloatingImage references rId "${fi.rId}" which does not exist in images`, path, "rel-image-missing");
491
+ }
492
+ }
493
+ else if (element.type === "paragraph") {
494
+ const para = element;
495
+ validateParagraphImageRefs(para, path, validImageRIds, doc.images, addIssue);
496
+ validateParagraphHyperlinkRefs(para, path, addIssue);
497
+ }
498
+ }
499
+ // Validate header/footer content image references
500
+ if (doc.headers) {
501
+ for (const [key, header] of doc.headers) {
502
+ if (header.content && header.content.children) {
503
+ validateHeaderFooterContentImageRefs(header.content.children, `headers["${key}"]`, validImageRIds, doc.images, addIssue);
504
+ }
505
+ }
506
+ }
507
+ if (doc.footers) {
508
+ for (const [key, footer] of doc.footers) {
509
+ if (footer.content && footer.content.children) {
510
+ validateHeaderFooterContentImageRefs(footer.content.children, `footers["${key}"]`, validImageRIds, doc.images, addIssue);
511
+ }
512
+ }
513
+ }
514
+ }
515
+ function validateParagraphImageRefs(para, path, validImageRIds, images, addIssue) {
516
+ if (!para.children) {
517
+ return;
518
+ }
519
+ for (let ci = 0; ci < para.children.length; ci++) {
520
+ const child = para.children[ci];
521
+ const childPath = `${path}.children[${ci}]`;
522
+ if ("type" in child && child.type === "hyperlink") {
523
+ const hl = child;
524
+ validateRunsImageRefs(hl.children, childPath, validImageRIds, images, addIssue);
525
+ }
526
+ else if (!("type" in child)) {
527
+ // It's a Run
528
+ validateRunImageRefs(child, childPath, validImageRIds, images, addIssue);
529
+ }
530
+ }
531
+ }
532
+ function validateRunsImageRefs(runs, path, validImageRIds, images, addIssue) {
533
+ for (let i = 0; i < runs.length; i++) {
534
+ validateRunImageRefs(runs[i], `${path}.children[${i}]`, validImageRIds, images, addIssue);
535
+ }
536
+ }
537
+ function validateRunImageRefs(run, path, validImageRIds, images, addIssue) {
538
+ if (!run.content) {
539
+ return;
540
+ }
541
+ for (let i = 0; i < run.content.length; i++) {
542
+ const rc = run.content[i];
543
+ if (rc.type === "image") {
544
+ const img = rc;
545
+ if (img.rId && images && images.length > 0 && !validImageRIds.has(img.rId)) {
546
+ addIssue("error", `InlineImage references rId "${img.rId}" which does not exist in images`, `${path}.content[${i}]`, "rel-image-missing");
547
+ }
548
+ }
549
+ }
550
+ }
551
+ function validateParagraphHyperlinkRefs(para, path, addIssue) {
552
+ if (!para.children) {
553
+ return;
554
+ }
555
+ for (let ci = 0; ci < para.children.length; ci++) {
556
+ const child = para.children[ci];
557
+ if ("type" in child && child.type === "hyperlink") {
558
+ const hl = child;
559
+ if (hl.rId && !hl.url && !hl.anchor) {
560
+ addIssue("warning", `Hyperlink has rId "${hl.rId}" but no url or anchor`, `${path}.children[${ci}]`, "rel-hyperlink-no-url");
561
+ }
562
+ }
563
+ }
564
+ }
565
+ function validateHeaderFooterContentImageRefs(children, basePath, validImageRIds, images, addIssue) {
566
+ walkBlocks(children, {
567
+ visitRunContent(content, _run, path) {
568
+ if (content.type === "image") {
569
+ const img = content;
570
+ if (img.rId && images && images.length > 0 && !validImageRIds.has(img.rId)) {
571
+ addIssue("error", `InlineImage references rId "${img.rId}" which does not exist in images`, `${basePath}:depth${path.depth}`, "rel-image-missing");
572
+ }
573
+ }
574
+ }
575
+ });
576
+ }
577
+ // =============================================================================
578
+ // Content Type Consistency Validation
579
+ // =============================================================================
580
+ /** Valid image media types per OOXML spec. */
581
+ const VALID_IMAGE_MEDIA_TYPES = [
582
+ "png",
583
+ "jpeg",
584
+ "jpg",
585
+ "gif",
586
+ "bmp",
587
+ "tiff",
588
+ "tif",
589
+ "svg",
590
+ "webp",
591
+ "emf",
592
+ "wmf"
593
+ ];
594
+ function validateContentTypeConsistency(doc, addIssue) {
595
+ // Validate image media types
596
+ if (doc.images) {
597
+ for (let i = 0; i < doc.images.length; i++) {
598
+ const img = doc.images[i];
599
+ if (img.mediaType && !VALID_IMAGE_MEDIA_TYPES.includes(img.mediaType)) {
600
+ addIssue("error", `Image has invalid mediaType "${img.mediaType}". Valid types: ${VALID_IMAGE_MEDIA_TYPES.join(", ")}`, `images[${i}]`, "content-type-invalid-media");
601
+ }
602
+ }
603
+ }
604
+ // Validate embedded fonts: if a font references an embed rId, there should be
605
+ // a corresponding entry in embeddedFonts
606
+ if (doc.fonts) {
607
+ const embeddedRIds = new Set();
608
+ if (doc.embeddedFonts) {
609
+ for (const ef of doc.embeddedFonts) {
610
+ embeddedRIds.add(ef.rId);
611
+ }
612
+ }
613
+ for (let i = 0; i < doc.fonts.length; i++) {
614
+ const font = doc.fonts[i];
615
+ const fontPath = `fonts[${i}]`;
616
+ const embedRIds = collectFontEmbedRIds(font);
617
+ for (const rId of embedRIds) {
618
+ if (!embeddedRIds.has(rId)) {
619
+ addIssue("warning", `Font "${font.name}" references embed rId "${rId}" but no corresponding embeddedFont exists`, fontPath, "content-type-font-embed-missing");
620
+ }
621
+ }
622
+ }
623
+ }
624
+ }
625
+ function collectFontEmbedRIds(font) {
626
+ const rIds = [];
627
+ if (font.embedRegular) {
628
+ rIds.push(font.embedRegular);
629
+ }
630
+ if (font.embedBold) {
631
+ rIds.push(font.embedBold);
632
+ }
633
+ if (font.embedItalic) {
634
+ rIds.push(font.embedItalic);
635
+ }
636
+ if (font.embedBoldItalic) {
637
+ rIds.push(font.embedBoldItalic);
638
+ }
639
+ return rIds;
640
+ }
641
+ // =============================================================================
642
+ // Structural Integrity Validation
643
+ // =============================================================================
644
+ function validateStructuralIntegrity(doc, addIssue) {
645
+ // Collect valid numbering IDs
646
+ const validNumIds = new Set();
647
+ if (doc.numberingInstances) {
648
+ for (const inst of doc.numberingInstances) {
649
+ validNumIds.add(inst.numId);
650
+ }
651
+ }
652
+ // Collect valid style IDs
653
+ const validStyleIds = new Set();
654
+ if (doc.styles) {
655
+ for (const style of doc.styles) {
656
+ if (style.styleId) {
657
+ validStyleIds.add(style.styleId);
658
+ }
659
+ }
660
+ }
661
+ // Validate body content structural integrity
662
+ for (let i = 0; i < doc.body.length; i++) {
663
+ const element = doc.body[i];
664
+ const path = `body[${i}]`;
665
+ if (element.type === "table") {
666
+ validateTableColumnConsistency(element, path, addIssue);
667
+ }
668
+ else if (element.type === "paragraph") {
669
+ const para = element;
670
+ // Validate numbering references
671
+ if (para.properties?.numbering && typeof para.properties.numbering.numId === "number") {
672
+ if (doc.numberingInstances && !validNumIds.has(para.properties.numbering.numId)) {
673
+ addIssue("error", `Paragraph references numId ${para.properties.numbering.numId} which has no corresponding numberingInstance`, `${path}.properties.numbering`, "struct-numbering-missing");
674
+ }
675
+ }
676
+ // Validate paragraph style references
677
+ if (para.properties?.style && doc.styles) {
678
+ if (!validStyleIds.has(para.properties.style)) {
679
+ addIssue("warning", `Paragraph references style "${para.properties.style}" which is not defined in styles`, `${path}.properties.style`, "struct-style-missing");
680
+ }
681
+ }
682
+ // Validate run style references
683
+ if (para.children) {
684
+ validateRunStyleRefs(para.children, path, validStyleIds, doc.styles, addIssue);
685
+ }
686
+ }
687
+ }
688
+ }
689
+ function validateTableColumnConsistency(table, path, addIssue) {
690
+ if (!table.rows || table.rows.length === 0) {
691
+ return;
692
+ }
693
+ let expectedCols;
694
+ for (let ri = 0; ri < table.rows.length; ri++) {
695
+ const row = table.rows[ri];
696
+ if (!row.cells || !Array.isArray(row.cells)) {
697
+ continue;
698
+ }
699
+ // Count effective columns (accounting for gridSpan)
700
+ let colCount = 0;
701
+ for (const cell of row.cells) {
702
+ colCount += cell.properties?.gridSpan ?? 1;
703
+ }
704
+ if (expectedCols === undefined) {
705
+ expectedCols = colCount;
706
+ }
707
+ else if (colCount !== expectedCols && !hasVerticalMerge(row)) {
708
+ addIssue("error", `Table row ${ri} has ${colCount} effective columns (gridSpan-weighted), expected ${expectedCols}`, `${path}.rows[${ri}]`, "struct-table-col-mismatch");
709
+ }
710
+ }
711
+ }
712
+ function validateRunStyleRefs(children, path, validStyleIds, styles, addIssue) {
713
+ if (!styles) {
714
+ return;
715
+ }
716
+ for (let ci = 0; ci < children.length; ci++) {
717
+ const child = children[ci];
718
+ const childPath = `${path}.children[${ci}]`;
719
+ if ("type" in child && child.type === "hyperlink") {
720
+ const hl = child;
721
+ for (let ri = 0; ri < hl.children.length; ri++) {
722
+ const run = hl.children[ri];
723
+ if (run.properties?.style && !validStyleIds.has(run.properties.style)) {
724
+ addIssue("warning", `Run references style "${run.properties.style}" which is not defined in styles`, `${childPath}.children[${ri}].properties.style`, "struct-run-style-missing");
725
+ }
726
+ }
727
+ }
728
+ else if (!("type" in child)) {
729
+ const run = child;
730
+ if (run.properties?.style && !validStyleIds.has(run.properties.style)) {
731
+ addIssue("warning", `Run references style "${run.properties.style}" which is not defined in styles`, `${childPath}.properties.style`, "struct-run-style-missing");
732
+ }
733
+ }
734
+ }
735
+ }
736
+ // =============================================================================
737
+ // Namespace / Standard Compliance Validation
738
+ // =============================================================================
739
+ /** Maximum reasonable page size in twips (50000 twips ≈ 34.7 inches). */
740
+ const MAX_PAGE_SIZE_TWIPS = 50000;
741
+ /** Valid header/footer type values per OOXML spec. */
742
+ const VALID_HEADER_FOOTER_TYPES = ["default", "first", "even"];
743
+ function validateNamespaceCompliance(doc, addIssue) {
744
+ // Validate page size range
745
+ if (doc.sectionProperties?.pageSize) {
746
+ const ps = doc.sectionProperties.pageSize;
747
+ if (ps.width <= 0) {
748
+ addIssue("error", "Page width must be greater than 0", "sectionProperties.pageSize.width", "ns-page-width-invalid");
749
+ }
750
+ else if (ps.width >= MAX_PAGE_SIZE_TWIPS) {
751
+ addIssue("warning", `Page width ${ps.width} twips exceeds reasonable maximum (${MAX_PAGE_SIZE_TWIPS})`, "sectionProperties.pageSize.width", "ns-page-width-excessive");
752
+ }
753
+ if (ps.height <= 0) {
754
+ addIssue("error", "Page height must be greater than 0", "sectionProperties.pageSize.height", "ns-page-height-invalid");
755
+ }
756
+ else if (ps.height >= MAX_PAGE_SIZE_TWIPS) {
757
+ addIssue("warning", `Page height ${ps.height} twips exceeds reasonable maximum (${MAX_PAGE_SIZE_TWIPS})`, "sectionProperties.pageSize.height", "ns-page-height-excessive");
758
+ }
759
+ }
760
+ // Validate header/footer type values in section references
761
+ if (doc.sectionProperties?.headers) {
762
+ for (let i = 0; i < doc.sectionProperties.headers.length; i++) {
763
+ const ref = doc.sectionProperties.headers[i];
764
+ if (!VALID_HEADER_FOOTER_TYPES.includes(ref.type)) {
765
+ addIssue("error", `Header reference has invalid type "${ref.type}". Valid types: ${VALID_HEADER_FOOTER_TYPES.join(", ")}`, `sectionProperties.headers[${i}]`, "ns-header-type-invalid");
766
+ }
767
+ }
768
+ }
769
+ if (doc.sectionProperties?.footers) {
770
+ for (let i = 0; i < doc.sectionProperties.footers.length; i++) {
771
+ const ref = doc.sectionProperties.footers[i];
772
+ if (!VALID_HEADER_FOOTER_TYPES.includes(ref.type)) {
773
+ addIssue("error", `Footer reference has invalid type "${ref.type}". Valid types: ${VALID_HEADER_FOOTER_TYPES.join(", ")}`, `sectionProperties.footers[${i}]`, "ns-footer-type-invalid");
774
+ }
775
+ }
776
+ }
777
+ }
778
+ // =============================================================================
779
+ // Numbering Instance / Abstract Consistency (Enhanced)
780
+ // =============================================================================
781
+ function validateNumberingAbstractConsistency(abstractNums, instances, addIssue) {
782
+ if (!instances || !abstractNums) {
783
+ return;
784
+ }
785
+ const abstractIds = new Set();
786
+ for (const an of abstractNums) {
787
+ abstractIds.add(an.abstractNumId);
788
+ }
789
+ for (let i = 0; i < instances.length; i++) {
790
+ const inst = instances[i];
791
+ if (!abstractIds.has(inst.abstractNumId)) {
792
+ addIssue("error", `NumberingInstance numId=${inst.numId} references abstractNumId ${inst.abstractNumId} which does not exist in abstractNumberings`, `numberingInstances[${i}]`, "num-abstract-ref-missing");
793
+ }
794
+ }
795
+ }
796
+ // =============================================================================
797
+ // Style basedOn Reference Validation
798
+ // =============================================================================
799
+ function validateStyleBasedOnReferences(styles, addIssue) {
800
+ if (!styles) {
801
+ return;
802
+ }
803
+ const styleIds = new Set();
804
+ for (const style of styles) {
805
+ if (style.styleId) {
806
+ styleIds.add(style.styleId);
807
+ }
808
+ }
809
+ for (let i = 0; i < styles.length; i++) {
810
+ const style = styles[i];
811
+ if (style.basedOn && !styleIds.has(style.basedOn)) {
812
+ addIssue("error", `Style "${style.styleId}" has basedOn="${style.basedOn}" which does not exist in defined styles`, `styles[${i}].basedOn`, "style-basedOn-ref-missing");
813
+ }
814
+ }
815
+ }
816
+ // =============================================================================
817
+ // Header/Footer Reference Validation
818
+ // =============================================================================
819
+ function validateHeaderFooterReferences(sp, headers, footers, addIssue) {
820
+ if (!sp) {
821
+ return;
822
+ }
823
+ if (sp.headers && headers) {
824
+ for (let i = 0; i < sp.headers.length; i++) {
825
+ const ref = sp.headers[i];
826
+ if (ref.rId && !headers.has(ref.rId)) {
827
+ addIssue("error", `Section header reference rId="${ref.rId}" (type="${ref.type}") does not exist in headers map`, `sectionProperties.headers[${i}]`, "hf-ref-header-missing");
828
+ }
829
+ }
830
+ }
831
+ if (sp.footers && footers) {
832
+ for (let i = 0; i < sp.footers.length; i++) {
833
+ const ref = sp.footers[i];
834
+ if (ref.rId && !footers.has(ref.rId)) {
835
+ addIssue("error", `Section footer reference rId="${ref.rId}" (type="${ref.type}") does not exist in footers map`, `sectionProperties.footers[${i}]`, "hf-ref-footer-missing");
836
+ }
837
+ }
838
+ }
839
+ }
840
+ // =============================================================================
841
+ // Comment ID Uniqueness
842
+ // =============================================================================
843
+ function validateCommentIdUniqueness(comments, addIssue) {
844
+ if (!comments) {
845
+ return;
846
+ }
847
+ const ids = new Set();
848
+ for (let i = 0; i < comments.length; i++) {
849
+ const c = comments[i];
850
+ if (ids.has(c.id)) {
851
+ addIssue("error", `Comment ID ${c.id} is not unique — duplicates found`, `comments[${i}]`, "comment-id-not-unique");
852
+ }
853
+ ids.add(c.id);
854
+ }
855
+ }
856
+ // =============================================================================
857
+ // Reference Closure (footnote/endnote/comment IDs referenced in body)
858
+ // =============================================================================
859
+ /**
860
+ * Walk every Run.content in the document and ensure that any
861
+ * `footnoteRef` / `endnoteRef` / `commentReference` ids are actually
862
+ * defined in `doc.footnotes` / `doc.endnotes` / `doc.comments`.
863
+ *
864
+ * A dangling reference produces an XML document that opens in Word but
865
+ * shows a broken reference number, which is one of the more confusing
866
+ * failure modes for downstream tooling. We surface it as an error.
867
+ */
868
+ function validateNoteAndCommentReferences(doc, addIssue) {
869
+ // Build the id sets once.
870
+ const footnoteIds = new Set();
871
+ if (doc.footnotes) {
872
+ for (const fn of doc.footnotes) {
873
+ footnoteIds.add(fn.id);
874
+ }
875
+ }
876
+ const endnoteIds = new Set();
877
+ if (doc.endnotes) {
878
+ for (const en of doc.endnotes) {
879
+ endnoteIds.add(en.id);
880
+ }
881
+ }
882
+ const commentIds = new Set();
883
+ if (doc.comments) {
884
+ for (const c of doc.comments) {
885
+ commentIds.add(c.id);
886
+ }
887
+ }
888
+ // Visit every run in body / headers / footers / footnotes / endnotes
889
+ // / comments. Footnotes themselves can reference other footnotes in
890
+ // theory but Word does not allow it, so we only scan the obvious
891
+ // surfaces.
892
+ const checkRun = (run, path) => {
893
+ for (const c of run.content) {
894
+ if (c.type === "footnoteRef") {
895
+ if (footnoteIds.size > 0 && !footnoteIds.has(c.id)) {
896
+ addIssue("error", `footnoteRef points at id=${c.id} which is not defined in doc.footnotes`, path, "ref-footnote-missing");
897
+ }
898
+ }
899
+ else if (c.type === "endnoteRef") {
900
+ if (endnoteIds.size > 0 && !endnoteIds.has(c.id)) {
901
+ addIssue("error", `endnoteRef points at id=${c.id} which is not defined in doc.endnotes`, path, "ref-endnote-missing");
902
+ }
903
+ }
904
+ }
905
+ };
906
+ // CommentReference / commentRangeStart / commentRangeEnd live as
907
+ // ParagraphChild siblings (alongside runs) — scan paragraph children
908
+ // directly. We use the existing walker to keep dispatch consistent.
909
+ walkBlocks(doc.body, {
910
+ enterParagraph(para, path) {
911
+ const basePath = `body[${path.index}]`;
912
+ for (let i = 0; i < para.children.length; i++) {
913
+ const child = para.children[i];
914
+ const childPath = `${basePath}.children[${i}]`;
915
+ if ("type" in child) {
916
+ if (child.type === "commentReference") {
917
+ if (commentIds.size > 0 && !commentIds.has(child.id)) {
918
+ addIssue("error", `commentReference points at id=${child.id} which is not defined in doc.comments`, childPath, "ref-comment-missing");
919
+ }
920
+ }
921
+ else if (child.type === "commentRangeStart" || child.type === "commentRangeEnd") {
922
+ if (commentIds.size > 0 && !commentIds.has(child.id)) {
923
+ addIssue("error", `${child.type} points at id=${child.id} which is not defined in doc.comments`, childPath, "ref-comment-range-missing");
924
+ }
925
+ }
926
+ else if (child.type === "hyperlink") {
927
+ // Hyperlink children are runs.
928
+ for (const r of child.children) {
929
+ checkRun(r, `${childPath}.children`);
930
+ }
931
+ }
932
+ else if (child.type === "insertedRun" ||
933
+ child.type === "deletedRun" ||
934
+ child.type === "movedFromRun" ||
935
+ child.type === "movedToRun") {
936
+ checkRun(child.run, `${childPath}.run`);
937
+ }
938
+ }
939
+ else {
940
+ // Bare run.
941
+ checkRun(child, childPath);
942
+ }
943
+ }
944
+ }
945
+ });
946
+ }
947
+ // =============================================================================
948
+ // Bookmark Name Uniqueness
949
+ // =============================================================================
950
+ function validateBookmarkNameUniqueness(body, addIssue) {
951
+ const bookmarkNames = new Map();
952
+ walkBlocks(body, {
953
+ visitBookmarkStart(bm, path) {
954
+ const pathStr = `body[${path.index}]:depth${path.depth}`;
955
+ if (bookmarkNames.has(bm.name)) {
956
+ addIssue("error", `Bookmark name "${bm.name}" is not unique — first defined at ${bookmarkNames.get(bm.name)}`, pathStr, "bookmark-name-not-unique");
957
+ }
958
+ else {
959
+ bookmarkNames.set(bm.name, pathStr);
960
+ }
961
+ }
962
+ });
963
+ }
964
+ // =============================================================================
965
+ // Table Cell Content Validation (OOXML requires at least one paragraph)
966
+ // =============================================================================
967
+ function validateTableCellContent(body, addIssue) {
968
+ for (let i = 0; i < body.length; i++) {
969
+ const element = body[i];
970
+ if (element.type === "table") {
971
+ validateTableCellParagraphs(element, `body[${i}]`, addIssue);
972
+ }
973
+ }
974
+ }
975
+ function validateTableCellParagraphs(table, basePath, addIssue) {
976
+ if (!table.rows) {
977
+ return;
978
+ }
979
+ for (let ri = 0; ri < table.rows.length; ri++) {
980
+ const row = table.rows[ri];
981
+ if (!row.cells) {
982
+ continue;
983
+ }
984
+ for (let ci = 0; ci < row.cells.length; ci++) {
985
+ const cell = row.cells[ci];
986
+ const cellPath = `${basePath}.rows[${ri}].cells[${ci}]`;
987
+ if (!cell.content || cell.content.length === 0) {
988
+ addIssue("error", "Table cell must contain at least one paragraph (OOXML requirement)", cellPath, "cell-no-paragraph");
989
+ continue;
990
+ }
991
+ // Check that at least one paragraph exists in content
992
+ const hasParagraph = cell.content.some(c => c.type === "paragraph");
993
+ if (!hasParagraph) {
994
+ addIssue("error", "Table cell must contain at least one paragraph (OOXML requirement)", cellPath, "cell-no-paragraph");
995
+ }
996
+ // Recursively validate nested tables
997
+ for (let pi = 0; pi < cell.content.length; pi++) {
998
+ const element = cell.content[pi];
999
+ if (element.type === "table") {
1000
+ validateTableCellParagraphs(element, `${cellPath}.content[${pi}]`, addIssue);
1001
+ }
1002
+ }
1003
+ }
1004
+ }
1005
+ }
1006
+ // =============================================================================
1007
+ // Custom XML Part itemId Uniqueness
1008
+ // =============================================================================
1009
+ function validateCustomXmlPartItemIds(customXmlParts, addIssue) {
1010
+ if (!customXmlParts) {
1011
+ return;
1012
+ }
1013
+ const itemIds = new Set();
1014
+ for (let i = 0; i < customXmlParts.length; i++) {
1015
+ const part = customXmlParts[i];
1016
+ // Normalize itemId by stripping braces and lowercasing for comparison
1017
+ const normalizedId = part.itemId.replace(/[{}]/g, "").toLowerCase();
1018
+ if (itemIds.has(normalizedId)) {
1019
+ addIssue("error", `CustomXmlPart itemId "${part.itemId}" is not unique`, `customXmlParts[${i}]`, "custom-xml-itemid-not-unique");
1020
+ }
1021
+ itemIds.add(normalizedId);
1022
+ }
1023
+ }
1024
+ // =============================================================================
1025
+ // Image File Extension / MediaType Consistency
1026
+ // =============================================================================
1027
+ /** Mapping from file extensions to expected media types. */
1028
+ const EXTENSION_MEDIA_TYPE_MAP = new Map([
1029
+ ["png", ["png"]],
1030
+ ["jpg", ["jpeg"]],
1031
+ ["jpeg", ["jpeg"]],
1032
+ ["gif", ["gif"]],
1033
+ ["bmp", ["bmp"]],
1034
+ ["tiff", ["tiff"]],
1035
+ ["tif", ["tiff"]],
1036
+ ["svg", ["svg"]],
1037
+ ["webp", ["webp"]],
1038
+ ["emf", ["emf"]],
1039
+ ["wmf", ["wmf"]]
1040
+ ]);
1041
+ function validateImageExtensionMediaType(images, addIssue) {
1042
+ if (!images) {
1043
+ return;
1044
+ }
1045
+ for (let i = 0; i < images.length; i++) {
1046
+ const img = images[i];
1047
+ if (!img.fileName || !img.mediaType) {
1048
+ continue;
1049
+ }
1050
+ const dotIdx = img.fileName.lastIndexOf(".");
1051
+ if (dotIdx === -1) {
1052
+ addIssue("warning", `Image fileName "${img.fileName}" has no file extension`, `images[${i}]`, "image-no-extension");
1053
+ continue;
1054
+ }
1055
+ const ext = img.fileName.slice(dotIdx + 1).toLowerCase();
1056
+ const expectedTypes = EXTENSION_MEDIA_TYPE_MAP.get(ext);
1057
+ if (!expectedTypes) {
1058
+ addIssue("warning", `Image fileName "${img.fileName}" has unrecognized extension ".${ext}"`, `images[${i}]`, "image-unknown-extension");
1059
+ continue;
1060
+ }
1061
+ if (!expectedTypes.includes(img.mediaType)) {
1062
+ addIssue("error", `Image fileName "${img.fileName}" has extension ".${ext}" but mediaType is "${img.mediaType}" (expected: ${expectedTypes.join(" or ")})`, `images[${i}]`, "image-ext-mediatype-mismatch");
1063
+ }
1064
+ }
1065
+ }