docxmlater 11.0.9 → 12.0.1

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 (354) hide show
  1. package/README.md +51 -13
  2. package/dist/core/Document.d.ts +28 -2
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +725 -170
  5. package/dist/core/Document.js.map +1 -1
  6. package/dist/core/DocumentGenerator.d.ts +1 -0
  7. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  8. package/dist/core/DocumentGenerator.js +77 -25
  9. package/dist/core/DocumentGenerator.js.map +1 -1
  10. package/dist/core/DocumentParser.d.ts +7 -3
  11. package/dist/core/DocumentParser.d.ts.map +1 -1
  12. package/dist/core/DocumentParser.js +431 -85
  13. package/dist/core/DocumentParser.js.map +1 -1
  14. package/dist/core/RelationshipManager.d.ts.map +1 -1
  15. package/dist/core/RelationshipManager.js +2 -2
  16. package/dist/core/RelationshipManager.js.map +1 -1
  17. package/dist/elements/Comment.d.ts +15 -1
  18. package/dist/elements/Comment.d.ts.map +1 -1
  19. package/dist/elements/Comment.js +67 -12
  20. package/dist/elements/Comment.js.map +1 -1
  21. package/dist/elements/CommentManager.d.ts +4 -0
  22. package/dist/elements/CommentManager.d.ts.map +1 -1
  23. package/dist/elements/CommentManager.js +74 -16
  24. package/dist/elements/CommentManager.js.map +1 -1
  25. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  26. package/dist/elements/EndnoteManager.js.map +1 -1
  27. package/dist/elements/Field.d.ts +10 -1
  28. package/dist/elements/Field.d.ts.map +1 -1
  29. package/dist/elements/Field.js +76 -34
  30. package/dist/elements/Field.js.map +1 -1
  31. package/dist/elements/FieldHelpers.d.ts +1 -0
  32. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  33. package/dist/elements/FieldHelpers.js +8 -4
  34. package/dist/elements/FieldHelpers.js.map +1 -1
  35. package/dist/elements/Footer.d.ts +3 -1
  36. package/dist/elements/Footer.d.ts.map +1 -1
  37. package/dist/elements/Footer.js +39 -53
  38. package/dist/elements/Footer.js.map +1 -1
  39. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  40. package/dist/elements/FootnoteManager.js.map +1 -1
  41. package/dist/elements/Header.d.ts +3 -1
  42. package/dist/elements/Header.d.ts.map +1 -1
  43. package/dist/elements/Header.js +39 -53
  44. package/dist/elements/Header.js.map +1 -1
  45. package/dist/elements/HeaderFooterManager.d.ts +4 -2
  46. package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
  47. package/dist/elements/HeaderFooterManager.js +36 -6
  48. package/dist/elements/HeaderFooterManager.js.map +1 -1
  49. package/dist/elements/Hyperlink.d.ts +6 -1
  50. package/dist/elements/Hyperlink.d.ts.map +1 -1
  51. package/dist/elements/Hyperlink.js +69 -44
  52. package/dist/elements/Hyperlink.js.map +1 -1
  53. package/dist/elements/Image.d.ts.map +1 -1
  54. package/dist/elements/Image.js +33 -6
  55. package/dist/elements/Image.js.map +1 -1
  56. package/dist/elements/ImageManager.d.ts +1 -0
  57. package/dist/elements/ImageManager.d.ts.map +1 -1
  58. package/dist/elements/ImageManager.js +11 -0
  59. package/dist/elements/ImageManager.js.map +1 -1
  60. package/dist/elements/Paragraph.d.ts +3 -0
  61. package/dist/elements/Paragraph.d.ts.map +1 -1
  62. package/dist/elements/Paragraph.js +91 -26
  63. package/dist/elements/Paragraph.js.map +1 -1
  64. package/dist/elements/Revision.d.ts +4 -0
  65. package/dist/elements/Revision.d.ts.map +1 -1
  66. package/dist/elements/Revision.js +369 -29
  67. package/dist/elements/Revision.js.map +1 -1
  68. package/dist/elements/Run.d.ts +1 -0
  69. package/dist/elements/Run.d.ts.map +1 -1
  70. package/dist/elements/Run.js +24 -4
  71. package/dist/elements/Run.js.map +1 -1
  72. package/dist/elements/Section.d.ts.map +1 -1
  73. package/dist/elements/Section.js +17 -7
  74. package/dist/elements/Section.js.map +1 -1
  75. package/dist/elements/Shape.d.ts.map +1 -1
  76. package/dist/elements/Shape.js +50 -42
  77. package/dist/elements/Shape.js.map +1 -1
  78. package/dist/elements/StructuredDocumentTag.d.ts +9 -1
  79. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  80. package/dist/elements/StructuredDocumentTag.js +46 -6
  81. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  82. package/dist/elements/Table.d.ts +2 -0
  83. package/dist/elements/Table.d.ts.map +1 -1
  84. package/dist/elements/Table.js +90 -42
  85. package/dist/elements/Table.js.map +1 -1
  86. package/dist/elements/TableCell.d.ts +1 -0
  87. package/dist/elements/TableCell.d.ts.map +1 -1
  88. package/dist/elements/TableCell.js +32 -13
  89. package/dist/elements/TableCell.js.map +1 -1
  90. package/dist/elements/TableOfContents.d.ts.map +1 -1
  91. package/dist/elements/TableOfContents.js +5 -7
  92. package/dist/elements/TableOfContents.js.map +1 -1
  93. package/dist/elements/TableRow.d.ts +1 -0
  94. package/dist/elements/TableRow.d.ts.map +1 -1
  95. package/dist/elements/TableRow.js +16 -1
  96. package/dist/elements/TableRow.js.map +1 -1
  97. package/dist/elements/TextBox.d.ts.map +1 -1
  98. package/dist/elements/TextBox.js +55 -42
  99. package/dist/elements/TextBox.js.map +1 -1
  100. package/dist/esm/core/Document.js +726 -171
  101. package/dist/esm/core/Document.js.map +1 -1
  102. package/dist/esm/core/DocumentGenerator.js +77 -25
  103. package/dist/esm/core/DocumentGenerator.js.map +1 -1
  104. package/dist/esm/core/DocumentParser.js +431 -85
  105. package/dist/esm/core/DocumentParser.js.map +1 -1
  106. package/dist/esm/core/RelationshipManager.js +2 -2
  107. package/dist/esm/core/RelationshipManager.js.map +1 -1
  108. package/dist/esm/elements/Comment.js +67 -12
  109. package/dist/esm/elements/Comment.js.map +1 -1
  110. package/dist/esm/elements/CommentManager.js +74 -16
  111. package/dist/esm/elements/CommentManager.js.map +1 -1
  112. package/dist/esm/elements/EndnoteManager.js.map +1 -1
  113. package/dist/esm/elements/Field.js +77 -35
  114. package/dist/esm/elements/Field.js.map +1 -1
  115. package/dist/esm/elements/FieldHelpers.js +7 -4
  116. package/dist/esm/elements/FieldHelpers.js.map +1 -1
  117. package/dist/esm/elements/Footer.js +39 -53
  118. package/dist/esm/elements/Footer.js.map +1 -1
  119. package/dist/esm/elements/FootnoteManager.js.map +1 -1
  120. package/dist/esm/elements/Header.js +39 -53
  121. package/dist/esm/elements/Header.js.map +1 -1
  122. package/dist/esm/elements/HeaderFooterManager.js +36 -6
  123. package/dist/esm/elements/HeaderFooterManager.js.map +1 -1
  124. package/dist/esm/elements/Hyperlink.js +69 -44
  125. package/dist/esm/elements/Hyperlink.js.map +1 -1
  126. package/dist/esm/elements/Image.js +33 -6
  127. package/dist/esm/elements/Image.js.map +1 -1
  128. package/dist/esm/elements/ImageManager.js +11 -0
  129. package/dist/esm/elements/ImageManager.js.map +1 -1
  130. package/dist/esm/elements/Paragraph.js +91 -26
  131. package/dist/esm/elements/Paragraph.js.map +1 -1
  132. package/dist/esm/elements/Revision.js +369 -29
  133. package/dist/esm/elements/Revision.js.map +1 -1
  134. package/dist/esm/elements/Run.js +24 -4
  135. package/dist/esm/elements/Run.js.map +1 -1
  136. package/dist/esm/elements/Section.js +17 -7
  137. package/dist/esm/elements/Section.js.map +1 -1
  138. package/dist/esm/elements/Shape.js +50 -42
  139. package/dist/esm/elements/Shape.js.map +1 -1
  140. package/dist/esm/elements/StructuredDocumentTag.js +46 -6
  141. package/dist/esm/elements/StructuredDocumentTag.js.map +1 -1
  142. package/dist/esm/elements/Table.js +90 -42
  143. package/dist/esm/elements/Table.js.map +1 -1
  144. package/dist/esm/elements/TableCell.js +32 -13
  145. package/dist/esm/elements/TableCell.js.map +1 -1
  146. package/dist/esm/elements/TableOfContents.js +5 -7
  147. package/dist/esm/elements/TableOfContents.js.map +1 -1
  148. package/dist/esm/elements/TableRow.js +16 -1
  149. package/dist/esm/elements/TableRow.js.map +1 -1
  150. package/dist/esm/elements/TextBox.js +55 -42
  151. package/dist/esm/elements/TextBox.js.map +1 -1
  152. package/dist/esm/formatting/AbstractNumbering.js +1 -1
  153. package/dist/esm/formatting/AbstractNumbering.js.map +1 -1
  154. package/dist/esm/formatting/NumberingLevel.js +8 -6
  155. package/dist/esm/formatting/NumberingLevel.js.map +1 -1
  156. package/dist/esm/formatting/NumberingManager.js +16 -1
  157. package/dist/esm/formatting/NumberingManager.js.map +1 -1
  158. package/dist/esm/formatting/Style.js +14 -0
  159. package/dist/esm/formatting/Style.js.map +1 -1
  160. package/dist/esm/formatting/StylesManager.js +14 -2
  161. package/dist/esm/formatting/StylesManager.js.map +1 -1
  162. package/dist/esm/helpers/CleanupHelper.js +103 -26
  163. package/dist/esm/helpers/CleanupHelper.js.map +1 -1
  164. package/dist/esm/images/ImageOptimizer.js +52 -4
  165. package/dist/esm/images/ImageOptimizer.js.map +1 -1
  166. package/dist/esm/index.js +1 -0
  167. package/dist/esm/index.js.map +1 -1
  168. package/dist/esm/internal.js +1 -1
  169. package/dist/esm/internal.js.map +1 -1
  170. package/dist/esm/processors/CompatibilityUpgrader.js +7 -1
  171. package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -1
  172. package/dist/esm/processors/InMemoryRevisionAcceptor.js +134 -13
  173. package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -1
  174. package/dist/esm/processors/RevisionWalker.js +58 -8
  175. package/dist/esm/processors/RevisionWalker.js.map +1 -1
  176. package/dist/esm/processors/SelectiveRevisionAcceptor.js +116 -17
  177. package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -1
  178. package/dist/esm/processors/cnfStyleDecoder.js +7 -7
  179. package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
  180. package/dist/esm/processors/stripTrackedChanges.js +16 -5
  181. package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
  182. package/dist/esm/utils/deepClone.js +24 -11
  183. package/dist/esm/utils/deepClone.js.map +1 -1
  184. package/dist/esm/utils/units.js +1 -1
  185. package/dist/esm/utils/units.js.map +1 -1
  186. package/dist/esm/utils/validation.js +11 -23
  187. package/dist/esm/utils/validation.js.map +1 -1
  188. package/dist/esm/utils/xmlSanitization.js +131 -7
  189. package/dist/esm/utils/xmlSanitization.js.map +1 -1
  190. package/dist/esm/validation/RevisionAutoFixer.js +69 -55
  191. package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
  192. package/dist/esm/validation/RevisionValidator.js +24 -20
  193. package/dist/esm/validation/RevisionValidator.js.map +1 -1
  194. package/dist/esm/xml/XMLBuilder.js +52 -20
  195. package/dist/esm/xml/XMLBuilder.js.map +1 -1
  196. package/dist/esm/xml/XMLParser.js +55 -13
  197. package/dist/esm/xml/XMLParser.js.map +1 -1
  198. package/dist/esm/zip/ZipHandler.js +37 -13
  199. package/dist/esm/zip/ZipHandler.js.map +1 -1
  200. package/dist/esm/zip/ZipReader.js +53 -6
  201. package/dist/esm/zip/ZipReader.js.map +1 -1
  202. package/dist/esm/zip/errors.js +7 -0
  203. package/dist/esm/zip/errors.js.map +1 -1
  204. package/dist/esm/zip/types.js +4 -0
  205. package/dist/esm/zip/types.js.map +1 -1
  206. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  207. package/dist/formatting/AbstractNumbering.js +1 -1
  208. package/dist/formatting/AbstractNumbering.js.map +1 -1
  209. package/dist/formatting/NumberingLevel.d.ts +1 -1
  210. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  211. package/dist/formatting/NumberingLevel.js +8 -6
  212. package/dist/formatting/NumberingLevel.js.map +1 -1
  213. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  214. package/dist/formatting/NumberingManager.js +16 -1
  215. package/dist/formatting/NumberingManager.js.map +1 -1
  216. package/dist/formatting/Style.d.ts.map +1 -1
  217. package/dist/formatting/Style.js +14 -0
  218. package/dist/formatting/Style.js.map +1 -1
  219. package/dist/formatting/StylesManager.d.ts +2 -0
  220. package/dist/formatting/StylesManager.d.ts.map +1 -1
  221. package/dist/formatting/StylesManager.js +14 -2
  222. package/dist/formatting/StylesManager.js.map +1 -1
  223. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  224. package/dist/helpers/CleanupHelper.js +103 -26
  225. package/dist/helpers/CleanupHelper.js.map +1 -1
  226. package/dist/images/ImageOptimizer.d.ts.map +1 -1
  227. package/dist/images/ImageOptimizer.js +52 -4
  228. package/dist/images/ImageOptimizer.js.map +1 -1
  229. package/dist/index.d.ts +3 -1
  230. package/dist/index.d.ts.map +1 -1
  231. package/dist/index.js +4 -2
  232. package/dist/index.js.map +1 -1
  233. package/dist/internal.d.ts +1 -1
  234. package/dist/internal.d.ts.map +1 -1
  235. package/dist/internal.js +2 -1
  236. package/dist/internal.js.map +1 -1
  237. package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
  238. package/dist/processors/CompatibilityUpgrader.js +7 -1
  239. package/dist/processors/CompatibilityUpgrader.js.map +1 -1
  240. package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
  241. package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
  242. package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
  243. package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
  244. package/dist/processors/RevisionWalker.d.ts +2 -0
  245. package/dist/processors/RevisionWalker.d.ts.map +1 -1
  246. package/dist/processors/RevisionWalker.js +58 -8
  247. package/dist/processors/RevisionWalker.js.map +1 -1
  248. package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
  249. package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
  250. package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
  251. package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
  252. package/dist/processors/cnfStyleDecoder.js +7 -7
  253. package/dist/processors/cnfStyleDecoder.js.map +1 -1
  254. package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
  255. package/dist/processors/stripTrackedChanges.js +16 -5
  256. package/dist/processors/stripTrackedChanges.js.map +1 -1
  257. package/dist/utils/deepClone.d.ts.map +1 -1
  258. package/dist/utils/deepClone.js +24 -11
  259. package/dist/utils/deepClone.js.map +1 -1
  260. package/dist/utils/units.d.ts.map +1 -1
  261. package/dist/utils/units.js +1 -1
  262. package/dist/utils/units.js.map +1 -1
  263. package/dist/utils/validation.d.ts.map +1 -1
  264. package/dist/utils/validation.js +11 -23
  265. package/dist/utils/validation.js.map +1 -1
  266. package/dist/utils/xmlSanitization.d.ts +2 -0
  267. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  268. package/dist/utils/xmlSanitization.js +133 -7
  269. package/dist/utils/xmlSanitization.js.map +1 -1
  270. package/dist/validation/RevisionAutoFixer.d.ts +6 -2
  271. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  272. package/dist/validation/RevisionAutoFixer.js +68 -54
  273. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  274. package/dist/validation/RevisionValidator.d.ts +2 -0
  275. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  276. package/dist/validation/RevisionValidator.js +26 -21
  277. package/dist/validation/RevisionValidator.js.map +1 -1
  278. package/dist/xml/XMLBuilder.d.ts +1 -0
  279. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  280. package/dist/xml/XMLBuilder.js +52 -20
  281. package/dist/xml/XMLBuilder.js.map +1 -1
  282. package/dist/xml/XMLParser.d.ts +1 -0
  283. package/dist/xml/XMLParser.d.ts.map +1 -1
  284. package/dist/xml/XMLParser.js +55 -13
  285. package/dist/xml/XMLParser.js.map +1 -1
  286. package/dist/zip/ZipHandler.d.ts.map +1 -1
  287. package/dist/zip/ZipHandler.js +37 -13
  288. package/dist/zip/ZipHandler.js.map +1 -1
  289. package/dist/zip/ZipReader.d.ts.map +1 -1
  290. package/dist/zip/ZipReader.js +52 -5
  291. package/dist/zip/ZipReader.js.map +1 -1
  292. package/dist/zip/errors.d.ts +3 -0
  293. package/dist/zip/errors.d.ts.map +1 -1
  294. package/dist/zip/errors.js +9 -1
  295. package/dist/zip/errors.js.map +1 -1
  296. package/dist/zip/types.d.ts +4 -0
  297. package/dist/zip/types.d.ts.map +1 -1
  298. package/dist/zip/types.js +4 -0
  299. package/dist/zip/types.js.map +1 -1
  300. package/package.json +2 -2
  301. package/src/core/Document.ts +1159 -240
  302. package/src/core/DocumentGenerator.ts +106 -26
  303. package/src/core/DocumentParser.ts +692 -120
  304. package/src/core/RelationshipManager.ts +446 -442
  305. package/src/elements/Comment.ts +123 -18
  306. package/src/elements/CommentManager.ts +121 -22
  307. package/src/elements/EndnoteManager.ts +4 -1
  308. package/src/elements/Field.ts +134 -43
  309. package/src/elements/FieldHelpers.ts +20 -4
  310. package/src/elements/Footer.ts +62 -67
  311. package/src/elements/FootnoteManager.ts +4 -1
  312. package/src/elements/Header.ts +62 -67
  313. package/src/elements/HeaderFooterManager.ts +56 -8
  314. package/src/elements/Hyperlink.ts +150 -55
  315. package/src/elements/Image.ts +51 -7
  316. package/src/elements/ImageManager.ts +24 -0
  317. package/src/elements/Paragraph.ts +161 -40
  318. package/src/elements/Revision.ts +446 -47
  319. package/src/elements/Run.ts +44 -6
  320. package/src/elements/Section.ts +25 -9
  321. package/src/elements/Shape.ts +52 -44
  322. package/src/elements/StructuredDocumentTag.ts +83 -8
  323. package/src/elements/Table.ts +151 -50
  324. package/src/elements/TableCell.ts +57 -17
  325. package/src/elements/TableOfContents.ts +10 -9
  326. package/src/elements/TableRow.ts +35 -3
  327. package/src/elements/TextBox.ts +58 -43
  328. package/src/formatting/AbstractNumbering.ts +4 -2
  329. package/src/formatting/NumberingLevel.ts +50 -12
  330. package/src/formatting/NumberingManager.ts +32 -3
  331. package/src/formatting/Style.ts +14 -0
  332. package/src/formatting/StylesManager.ts +29 -2
  333. package/src/helpers/CleanupHelper.ts +122 -30
  334. package/src/images/ImageOptimizer.ts +64 -5
  335. package/src/index.ts +7 -0
  336. package/src/internal.ts +1 -0
  337. package/src/processors/CompatibilityUpgrader.ts +15 -2
  338. package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
  339. package/src/processors/RevisionWalker.ts +83 -7
  340. package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
  341. package/src/processors/cnfStyleDecoder.ts +18 -12
  342. package/src/processors/stripTrackedChanges.ts +47 -10
  343. package/src/utils/deepClone.ts +48 -14
  344. package/src/utils/units.ts +3 -1
  345. package/src/utils/validation.ts +30 -32
  346. package/src/utils/xmlSanitization.ts +218 -22
  347. package/src/validation/RevisionAutoFixer.ts +109 -65
  348. package/src/validation/RevisionValidator.ts +48 -23
  349. package/src/xml/XMLBuilder.ts +82 -22
  350. package/src/xml/XMLParser.ts +87 -20
  351. package/src/zip/ZipHandler.ts +61 -21
  352. package/src/zip/ZipReader.ts +135 -13
  353. package/src/zip/errors.ts +15 -0
  354. package/src/zip/types.ts +44 -2
@@ -1 +1 @@
1
- {"version":3,"file":"CleanupHelper.js","sourceRoot":"","sources":["../../../src/helpers/CleanupHelper.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CleanupHelper - Comprehensive document cleanup utilities\n *\n * Provides methods to clean up common issues in DOCX documents, including:\n * - Unlocking and removing SDTs\n * - Clearing preserve flags\n * - Defragmenting hyperlinks\n * - Cleaning unused elements\n * - Removing customXML\n * - Unlocking fields and frames\n * - Sanitizing tables\n *\n * Usage:\n * const cleanup = new CleanupHelper(doc);\n * cleanup.all(); // Run all cleanups\n */\n\nimport type { Document } from '../core/Document.js';\nimport { Field, ComplexField } from '../elements/Field.js';\nimport { Hyperlink } from '../elements/Hyperlink.js';\nimport { Paragraph } from '../elements/Paragraph.js';\nimport { Table } from '../elements/Table.js';\nimport { StructuredDocumentTag } from '../elements/StructuredDocumentTag.js';\n\nexport interface CleanupOptions {\n /** Unlock all SDTs to enable editing */\n unlockSDTs?: boolean;\n /** Remove all SDTs (unwrap content) */\n removeSDTs?: boolean;\n /** Clear paragraph preserve flags */\n clearPreserveFlags?: boolean;\n /** Merge fragmented hyperlinks */\n defragmentHyperlinks?: boolean;\n /** Reset hyperlink formatting to standard */\n resetHyperlinkFormatting?: boolean;\n /** Remove unused numbering definitions */\n cleanupNumbering?: boolean;\n /** Remove unused styles */\n cleanupStyles?: boolean;\n /** Remove orphaned relationships */\n cleanupRelationships?: boolean;\n /** Remove customXML elements */\n removeCustomXML?: boolean;\n /** Unlock field locks (enable field updates) */\n unlockFields?: boolean;\n /** Remove frame/text box locks */\n unlockFrames?: boolean;\n /** Sanitize table property exceptions (tblPrEx) */\n sanitizeTables?: boolean;\n /** Format internal anchor hyperlinks with standard styling (Verdana 12pt blue underlined) */\n formatInternalHyperlinks?: boolean;\n /** Format ALL hyperlinks (internal, external, and HYPERLINK fields) with standard styling (Verdana 12pt #0000FF underlined) */\n formatAllHyperlinks?: boolean;\n}\n\nexport interface CleanupReport {\n sdtsUnlocked: number;\n sdtsRemoved: number;\n preserveFlagsCleared: number;\n hyperlinksDefragmented: number;\n numberingRemoved: number;\n stylesRemoved: number;\n relationshipsRemoved: number;\n customXMLRemoved: number;\n fieldsUnlocked: number;\n framesUnlocked: number;\n tablesProcessed: number;\n internalHyperlinksFormatted: number;\n allHyperlinksFormatted: number;\n warnings: string[];\n}\n\nexport class CleanupHelper {\n private doc: Document;\n\n constructor(doc: Document) {\n this.doc = doc;\n }\n\n /**\n * Run all cleanup operations with default settings\n * @returns Cleanup report\n */\n all(): CleanupReport {\n return this.run({\n unlockSDTs: true,\n removeSDTs: true,\n clearPreserveFlags: true,\n defragmentHyperlinks: true,\n resetHyperlinkFormatting: true,\n cleanupNumbering: true,\n cleanupStyles: true,\n cleanupRelationships: true,\n removeCustomXML: true,\n unlockFields: true,\n unlockFrames: true,\n sanitizeTables: true,\n formatAllHyperlinks: true,\n });\n }\n\n /**\n * Run selective cleanup operations\n * @param options Cleanup options\n * @returns Cleanup report\n */\n run(options: CleanupOptions): CleanupReport {\n const report: CleanupReport = {\n sdtsUnlocked: 0,\n sdtsRemoved: 0,\n preserveFlagsCleared: 0,\n hyperlinksDefragmented: 0,\n numberingRemoved: 0,\n stylesRemoved: 0,\n relationshipsRemoved: 0,\n customXMLRemoved: 0,\n fieldsUnlocked: 0,\n framesUnlocked: 0,\n tablesProcessed: 0,\n internalHyperlinksFormatted: 0,\n allHyperlinksFormatted: 0,\n warnings: [],\n };\n\n if (options.unlockSDTs) {\n report.sdtsUnlocked = this.unlockSDTs();\n }\n\n if (options.removeSDTs) {\n report.sdtsRemoved = this.removeSDTs();\n }\n\n if (options.clearPreserveFlags) {\n report.preserveFlagsCleared = this.clearPreserveFlags();\n }\n\n if (options.defragmentHyperlinks) {\n report.hyperlinksDefragmented = this.defragmentHyperlinks(\n options.resetHyperlinkFormatting ?? false\n );\n }\n\n if (options.cleanupNumbering) {\n report.numberingRemoved = this.cleanupNumbering();\n }\n\n if (options.cleanupStyles) {\n report.stylesRemoved = this.cleanupStyles();\n }\n\n if (options.cleanupRelationships) {\n report.relationshipsRemoved = this.cleanupRelationships();\n }\n\n if (options.removeCustomXML) {\n report.customXMLRemoved = this.removeCustomXML();\n }\n\n if (options.unlockFields) {\n report.fieldsUnlocked = this.unlockFields();\n }\n\n if (options.unlockFrames) {\n report.framesUnlocked = this.unlockFrames();\n }\n\n if (options.sanitizeTables) {\n report.tablesProcessed = this.sanitizeTables();\n }\n\n if (options.formatInternalHyperlinks) {\n report.internalHyperlinksFormatted = this.formatInternalHyperlinks();\n }\n\n if (options.formatAllHyperlinks) {\n report.allHyperlinksFormatted = this.formatAllHyperlinks();\n }\n\n return report;\n }\n\n private unlockSDTs(): number {\n let count = 0;\n const bodyElements = this.doc.getBodyElements();\n\n for (const element of bodyElements) {\n if (element instanceof StructuredDocumentTag && element.isLocked()) {\n element.unlock();\n count++;\n }\n }\n\n // Also unlock in tables\n for (const table of this.doc.getAllTables()) {\n for (const row of table.getRows()) {\n for (const cell of row.getCells()) {\n for (const para of cell.getParagraphs()) {\n // SDTs can wrap paragraphs in cells\n const content = para.getContent();\n for (const item of content) {\n if (item instanceof StructuredDocumentTag && item.isLocked()) {\n item.unlock();\n count++;\n }\n }\n }\n }\n }\n }\n\n return count;\n }\n\n private removeSDTs(): number {\n // Unwrap SDT wrappers, preserving their content\n const bodyElements = this.doc.getBodyElements();\n type BodyElement = Paragraph | Table | StructuredDocumentTag;\n const unwrapped: BodyElement[] = [];\n let sdtCount = 0;\n\n const unwrapSDT = (sdt: StructuredDocumentTag, target: BodyElement[]) => {\n sdtCount++;\n for (const item of sdt.getContent()) {\n if (item instanceof Paragraph || item instanceof Table) {\n target.push(item);\n } else if (item instanceof StructuredDocumentTag) {\n unwrapSDT(item, target);\n }\n }\n };\n\n for (const element of bodyElements) {\n if (element instanceof StructuredDocumentTag) {\n unwrapSDT(element, unwrapped);\n } else {\n unwrapped.push(element as BodyElement);\n }\n }\n\n this.doc.setBodyElements(unwrapped);\n return sdtCount;\n }\n\n private clearPreserveFlags(): number {\n let cleared = 0;\n for (const para of this.doc.getAllParagraphs()) {\n if (para.isPreserved()) {\n para.setPreserved(false);\n cleared++;\n }\n }\n return cleared;\n }\n\n private defragmentHyperlinks(resetFormatting: boolean): number {\n return this.doc.defragmentHyperlinks({ resetFormatting, cleanupRelationships: true });\n }\n\n private cleanupNumbering(): number {\n const before = this.doc.getNumberingManager().getAllInstances().length;\n this.doc.cleanupUnusedNumbering();\n const after = this.doc.getNumberingManager().getAllInstances().length;\n return before - after;\n }\n\n private cleanupStyles(): number {\n // Implementation for unused styles removal\n // Scan all paragraphs and runs for used styles\n const usedStyles = new Set<string>();\n for (const para of this.doc.getAllParagraphs()) {\n const paraStyle = para.getFormatting().style;\n if (paraStyle) usedStyles.add(paraStyle);\n for (const run of para.getRuns()) {\n const runStyle = run.getFormatting().characterStyle;\n if (runStyle) usedStyles.add(runStyle);\n }\n }\n\n // Remove unused styles\n let removed = 0;\n const allStyles = this.doc.getStylesManager().getAllStyles();\n for (const style of allStyles) {\n if (!usedStyles.has(style.getStyleId())) {\n this.doc.getStylesManager().removeStyle(style.getStyleId());\n removed++;\n }\n }\n\n return removed;\n }\n\n private cleanupRelationships(): number {\n // Use comprehensive scanning that includes raw nested content (nested tables),\n // headers/footers, footnotes, and endnotes — not just in-memory hyperlinks\n const referencedIds = this.doc.collectAllReferencedHyperlinkIds();\n\n // Remove orphaned hyperlink relationships\n return this.doc.getRelationshipManager().removeOrphanedHyperlinks(referencedIds);\n }\n\n private removeCustomXML(): number {\n const zipHandler = this.doc.getZipHandler();\n let removed = 0;\n\n // Remove customXML files\n const files = zipHandler.getFilePaths();\n for (const file of files) {\n if (file.startsWith('customXml/') || file.startsWith('customXML/')) {\n zipHandler.removeFile(file);\n removed++;\n }\n }\n\n // Remove customXML relationships\n const relManager = this.doc.getRelationshipManager();\n const customRels = relManager.getRelationshipsByType(\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml'\n );\n for (const rel of customRels) {\n relManager.removeRelationship(rel.getId());\n removed++;\n }\n\n // Remove custom.xml if present (docProps/custom.xml)\n if (zipHandler.hasFile('docProps/custom.xml')) {\n zipHandler.removeFile('docProps/custom.xml');\n removed++;\n }\n\n return removed;\n }\n\n private unlockFields(): number {\n const zipHandler = this.doc.getZipHandler();\n const docXml = zipHandler.getFileAsString('word/document.xml');\n if (!docXml) return 0;\n\n // Count matches first, then replace (avoid regex re-execution)\n const pattern = /w:fldLock=\"(1|true)\"/g;\n const matches = docXml.match(pattern) || [];\n if (matches.length === 0) return 0;\n\n // Remove w:fldLock=\"1\" or w:fldLock=\"true\"\n const updatedXml = docXml.replace(pattern, '');\n zipHandler.updateFile('word/document.xml', updatedXml);\n\n return matches.length;\n }\n\n private unlockFrames(): number {\n const zipHandler = this.doc.getZipHandler();\n const docXml = zipHandler.getFileAsString('word/document.xml');\n if (!docXml) return 0;\n\n // Count matches first, then replace (avoid regex re-execution)\n const pattern = /w:anchorLock=\"(1|true)\"/g;\n const matches = docXml.match(pattern) || [];\n if (matches.length === 0) return 0;\n\n // Remove w:anchorLock=\"1\" or w:anchorLock=\"true\"\n const updatedXml = docXml.replace(pattern, '');\n zipHandler.updateFile('word/document.xml', updatedXml);\n\n return matches.length;\n }\n\n private sanitizeTables(): number {\n const tables = this.doc.getAllTables();\n let processed = 0;\n for (const table of tables) {\n for (const row of table.getRows()) {\n const exceptions = row.getTablePropertyExceptions();\n if (exceptions && Object.keys(exceptions).length > 0) {\n row.setTablePropertyExceptions(undefined as any);\n }\n }\n processed++;\n }\n return processed;\n }\n\n private formatInternalHyperlinks(): number {\n let count = 0;\n const formatting = {\n font: 'Verdana',\n size: 12,\n color: '0000FF',\n underline: 'single' as const,\n };\n\n // Process body paragraphs\n for (const paragraph of this.doc.getAllParagraphs()) {\n for (const item of paragraph.getContent()) {\n if (item instanceof Hyperlink && item.isInternal()) {\n item.setFormatting(formatting, { replace: true });\n count++;\n }\n }\n }\n\n // Process table paragraphs\n for (const table of this.doc.getAllTables()) {\n for (const row of table.getRows()) {\n for (const cell of row.getCells()) {\n for (const para of cell.getParagraphs()) {\n for (const item of para.getContent()) {\n if (item instanceof Hyperlink && item.isInternal()) {\n item.setFormatting(formatting, { replace: true });\n count++;\n }\n }\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Formats ALL hyperlinks in the document with standard styling\n * This includes:\n * - Internal w:hyperlink elements (bookmarks)\n * - External w:hyperlink elements (URLs)\n * - HYPERLINK fields (both simple w:fldSimple and complex fields)\n *\n * Standard formatting: Verdana 12pt, #0000FF blue, single underline\n * @returns Number of hyperlinks formatted\n */\n private formatAllHyperlinks(): number {\n let count = 0;\n const formatting = {\n font: 'Verdana',\n size: 12,\n color: '0000FF',\n underline: 'single' as const,\n };\n\n // Helper to process paragraph content\n const processParagraph = (paragraph: Paragraph): void => {\n for (const item of paragraph.getContent()) {\n // Process all Hyperlink instances (both internal AND external)\n if (item instanceof Hyperlink) {\n item.setFormatting(formatting, { replace: true });\n count++;\n }\n // Process simple HYPERLINK fields\n if (item instanceof Field && item.isHyperlinkField()) {\n item.setFormatting(formatting);\n count++;\n }\n // Process complex HYPERLINK fields\n if (item instanceof ComplexField && item.isHyperlinkField()) {\n item.setResultFormatting(formatting);\n count++;\n }\n }\n };\n\n // Process body paragraphs\n for (const paragraph of this.doc.getAllParagraphs()) {\n processParagraph(paragraph);\n }\n\n // Process table paragraphs\n for (const table of this.doc.getAllTables()) {\n for (const row of table.getRows()) {\n for (const cell of row.getCells()) {\n for (const para of cell.getParagraphs()) {\n processParagraph(para);\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Preset: Google Docs cleanup\n */\n static googleDocsPreset(): CleanupOptions {\n return {\n unlockSDTs: true,\n removeSDTs: true,\n defragmentHyperlinks: true,\n resetHyperlinkFormatting: true,\n cleanupRelationships: true,\n removeCustomXML: true,\n sanitizeTables: true,\n };\n }\n\n /**\n * Preset: Full cleanup\n */\n static fullCleanupPreset(): CleanupOptions {\n return {\n unlockSDTs: true,\n removeSDTs: true,\n clearPreserveFlags: true,\n defragmentHyperlinks: true,\n resetHyperlinkFormatting: true,\n cleanupNumbering: true,\n cleanupStyles: true,\n cleanupRelationships: true,\n removeCustomXML: true,\n unlockFields: true,\n unlockFrames: true,\n sanitizeTables: true,\n formatAllHyperlinks: true,\n };\n }\n\n /**\n * Preset: Minimal cleanup\n */\n static minimalPreset(): CleanupOptions {\n return {\n cleanupRelationships: true,\n removeCustomXML: true,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"CleanupHelper.js","sourceRoot":"","sources":["../../../src/helpers/CleanupHelper.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CleanupHelper - Comprehensive document cleanup utilities\n *\n * Provides methods to clean up common issues in DOCX documents, including:\n * - Unlocking and removing SDTs\n * - Clearing preserve flags\n * - Defragmenting hyperlinks\n * - Cleaning unused elements\n * - Removing customXML\n * - Unlocking fields and frames\n * - Sanitizing tables\n *\n * Usage:\n * const cleanup = new CleanupHelper(doc);\n * cleanup.all(); // Run all cleanups\n */\n\nimport type { Document } from '../core/Document.js';\nimport { Field, ComplexField } from '../elements/Field.js';\nimport { Hyperlink } from '../elements/Hyperlink.js';\nimport { Paragraph } from '../elements/Paragraph.js';\nimport { Table } from '../elements/Table.js';\nimport { StructuredDocumentTag } from '../elements/StructuredDocumentTag.js';\nimport { StylesManager } from '../formatting/StylesManager.js';\n\nexport interface CleanupOptions {\n /** Unlock all SDTs to enable editing */\n unlockSDTs?: boolean;\n /** Remove all SDTs (unwrap content) */\n removeSDTs?: boolean;\n /** Clear paragraph preserve flags */\n clearPreserveFlags?: boolean;\n /** Merge fragmented hyperlinks */\n defragmentHyperlinks?: boolean;\n /** Reset hyperlink formatting to standard */\n resetHyperlinkFormatting?: boolean;\n /** Remove unused numbering definitions */\n cleanupNumbering?: boolean;\n /** Remove unused styles */\n cleanupStyles?: boolean;\n /** Remove orphaned relationships */\n cleanupRelationships?: boolean;\n /** Remove customXML elements */\n removeCustomXML?: boolean;\n /** Unlock field locks (enable field updates) */\n unlockFields?: boolean;\n /** Remove frame/text box locks */\n unlockFrames?: boolean;\n /** Sanitize table property exceptions (tblPrEx) */\n sanitizeTables?: boolean;\n /** Format internal anchor hyperlinks with standard styling (Verdana 12pt blue underlined) */\n formatInternalHyperlinks?: boolean;\n /** Format ALL hyperlinks (internal, external, and HYPERLINK fields) with standard styling (Verdana 12pt #0000FF underlined) */\n formatAllHyperlinks?: boolean;\n}\n\nexport interface CleanupReport {\n sdtsUnlocked: number;\n sdtsRemoved: number;\n preserveFlagsCleared: number;\n hyperlinksDefragmented: number;\n numberingRemoved: number;\n stylesRemoved: number;\n relationshipsRemoved: number;\n customXMLRemoved: number;\n fieldsUnlocked: number;\n framesUnlocked: number;\n tablesProcessed: number;\n internalHyperlinksFormatted: number;\n allHyperlinksFormatted: number;\n warnings: string[];\n}\n\nexport class CleanupHelper {\n private doc: Document;\n\n constructor(doc: Document) {\n this.doc = doc;\n }\n\n /**\n * Run all cleanup operations with default settings\n * @returns Cleanup report\n */\n all(): CleanupReport {\n return this.run({\n unlockSDTs: true,\n removeSDTs: true,\n clearPreserveFlags: true,\n defragmentHyperlinks: true,\n resetHyperlinkFormatting: true,\n cleanupNumbering: true,\n cleanupStyles: true,\n cleanupRelationships: true,\n removeCustomXML: true,\n unlockFields: true,\n unlockFrames: true,\n sanitizeTables: true,\n formatAllHyperlinks: true,\n });\n }\n\n /**\n * Run selective cleanup operations\n * @param options Cleanup options\n * @returns Cleanup report\n */\n run(options: CleanupOptions): CleanupReport {\n const report: CleanupReport = {\n sdtsUnlocked: 0,\n sdtsRemoved: 0,\n preserveFlagsCleared: 0,\n hyperlinksDefragmented: 0,\n numberingRemoved: 0,\n stylesRemoved: 0,\n relationshipsRemoved: 0,\n customXMLRemoved: 0,\n fieldsUnlocked: 0,\n framesUnlocked: 0,\n tablesProcessed: 0,\n internalHyperlinksFormatted: 0,\n allHyperlinksFormatted: 0,\n warnings: [],\n };\n\n if (options.unlockSDTs) {\n report.sdtsUnlocked = this.unlockSDTs();\n }\n\n if (options.removeSDTs) {\n report.sdtsRemoved = this.removeSDTs();\n }\n\n if (options.clearPreserveFlags) {\n report.preserveFlagsCleared = this.clearPreserveFlags();\n }\n\n if (options.defragmentHyperlinks) {\n report.hyperlinksDefragmented = this.defragmentHyperlinks(\n options.resetHyperlinkFormatting ?? false\n );\n }\n\n if (options.cleanupNumbering) {\n report.numberingRemoved = this.cleanupNumbering();\n }\n\n if (options.cleanupStyles) {\n report.stylesRemoved = this.cleanupStyles();\n }\n\n if (options.cleanupRelationships) {\n report.relationshipsRemoved = this.cleanupRelationships();\n }\n\n if (options.removeCustomXML) {\n report.customXMLRemoved = this.removeCustomXML();\n }\n\n if (options.unlockFields) {\n report.fieldsUnlocked = this.unlockFields();\n }\n\n if (options.unlockFrames) {\n report.framesUnlocked = this.unlockFrames();\n }\n\n if (options.sanitizeTables) {\n report.tablesProcessed = this.sanitizeTables();\n }\n\n if (options.formatInternalHyperlinks) {\n report.internalHyperlinksFormatted = this.formatInternalHyperlinks();\n }\n\n if (options.formatAllHyperlinks) {\n report.allHyperlinksFormatted = this.formatAllHyperlinks();\n }\n\n return report;\n }\n\n private unlockSDTs(): number {\n let count = 0;\n const bodyElements = this.doc.getBodyElements();\n\n for (const element of bodyElements) {\n if (element instanceof StructuredDocumentTag && element.isLocked()) {\n element.unlock();\n count++;\n }\n }\n\n // Also unlock in tables\n for (const table of this.doc.getAllTables()) {\n for (const row of table.getRows()) {\n for (const cell of row.getCells()) {\n for (const para of cell.getParagraphs()) {\n // SDTs can wrap paragraphs in cells\n const content = para.getContent();\n for (const item of content) {\n if (item instanceof StructuredDocumentTag && item.isLocked()) {\n item.unlock();\n count++;\n }\n }\n }\n }\n }\n }\n\n return count;\n }\n\n private removeSDTs(): number {\n // Unwrap SDT wrappers, preserving their content\n const bodyElements = this.doc.getBodyElements();\n type BodyElement = Paragraph | Table | StructuredDocumentTag;\n const unwrapped: BodyElement[] = [];\n let sdtCount = 0;\n\n const unwrapSDT = (sdt: StructuredDocumentTag, target: BodyElement[]) => {\n sdtCount++;\n for (const item of sdt.getContent()) {\n if (item instanceof Paragraph || item instanceof Table) {\n target.push(item);\n } else if (item instanceof StructuredDocumentTag) {\n unwrapSDT(item, target);\n }\n }\n };\n\n for (const element of bodyElements) {\n if (element instanceof StructuredDocumentTag) {\n unwrapSDT(element, unwrapped);\n } else {\n unwrapped.push(element as BodyElement);\n }\n }\n\n this.doc.setBodyElements(unwrapped);\n return sdtCount;\n }\n\n private clearPreserveFlags(): number {\n let cleared = 0;\n for (const para of this.doc.getAllParagraphs()) {\n if (para.isPreserved()) {\n para.setPreserved(false);\n cleared++;\n }\n }\n return cleared;\n }\n\n private defragmentHyperlinks(resetFormatting: boolean): number {\n return this.doc.defragmentHyperlinks({ resetFormatting, cleanupRelationships: true });\n }\n\n private cleanupNumbering(): number {\n const before = this.doc.getNumberingManager().getAllInstances().length;\n this.doc.cleanupUnusedNumbering();\n const after = this.doc.getNumberingManager().getAllInstances().length;\n return before - after;\n }\n\n private cleanupStyles(): number {\n const stylesManager = this.doc.getStylesManager();\n const usedStyles = new Set<string>();\n\n const collectParagraph = (para: Paragraph): void => {\n const paraStyle = para.getFormatting().style;\n if (paraStyle) usedStyles.add(paraStyle);\n for (const run of para.getRuns()) {\n const runStyle = run.getFormatting().characterStyle;\n if (runStyle) usedStyles.add(runStyle);\n }\n };\n\n // Body paragraphs (getAllParagraphs walks table cells and nested SDTs)\n for (const para of this.doc.getAllParagraphs()) {\n collectParagraph(para);\n }\n\n // Table styles (w:tblStyle) — tables reference styles without any\n // paragraph carrying the ID, so a paragraph-only scan misses them\n for (const table of this.doc.getAllTables()) {\n const tableStyle = table.getFormatting().style;\n if (tableStyle) usedStyles.add(tableStyle);\n }\n\n // Headers and footers live outside the body walk\n const headerFooterManager = this.doc.getHeaderFooterManager();\n const headerFooterElements = [\n ...headerFooterManager.getAllHeaders().flatMap((entry) => entry.header.getElements()),\n ...headerFooterManager.getAllFooters().flatMap((entry) => entry.footer.getElements()),\n ];\n for (const element of headerFooterElements) {\n if (element instanceof Paragraph) {\n collectParagraph(element);\n } else if (element instanceof Table) {\n const tableStyle = element.getFormatting().style;\n if (tableStyle) usedStyles.add(tableStyle);\n for (const row of element.getRows()) {\n for (const cell of row.getCells()) {\n for (const para of cell.getParagraphs()) {\n collectParagraph(para);\n }\n }\n }\n }\n }\n\n // Footnotes and endnotes also live outside the body walk\n for (const footnote of this.doc.getFootnoteManager().getAllFootnotes()) {\n for (const para of footnote.getParagraphs()) {\n collectParagraph(para);\n }\n }\n for (const endnote of this.doc.getEndnoteManager().getAllEndnotes()) {\n for (const para of endnote.getParagraphs()) {\n collectParagraph(para);\n }\n }\n\n // Numbering levels can bind a paragraph style (w:pStyle, ECMA-376 §17.9.23)\n for (const abstractNum of this.doc.getNumberingManager().getAllAbstractNumberings()) {\n for (const level of abstractNum.getAllLevels()) {\n const pStyle = level.getParagraphStyle();\n if (pStyle) usedStyles.add(pStyle);\n }\n }\n\n // Expand to basedOn/link/next ancestors transitively — removing a chain\n // member leaves dangling references that break style resolution in Word\n const allStyles = stylesManager.getAllStyles();\n const stylesById = new Map(allStyles.map((style) => [style.getStyleId(), style]));\n const pending = [...usedStyles];\n while (pending.length > 0) {\n const style = stylesById.get(pending.pop()!);\n if (!style) continue;\n const props = style.getProperties();\n for (const ref of [props.basedOn, props.link, props.next]) {\n if (ref && !usedStyles.has(ref)) {\n usedStyles.add(ref);\n pending.push(ref);\n }\n }\n }\n\n // Remove unused styles — but never built-ins or part defaults, which\n // apply without being referenced (mirrors StylesManager.cleanupUnusedStyles)\n let removed = 0;\n for (const style of allStyles) {\n const styleId = style.getStyleId();\n if (usedStyles.has(styleId)) continue;\n if (StylesManager.isBuiltInStyle(styleId)) continue;\n if (style.getProperties().isDefault) continue;\n if (stylesManager.removeStyle(styleId)) {\n removed++;\n }\n }\n\n return removed;\n }\n\n private cleanupRelationships(): number {\n // Use comprehensive scanning that includes raw nested content (nested tables),\n // headers/footers, footnotes, and endnotes — not just in-memory hyperlinks\n const referencedIds = this.doc.collectAllReferencedHyperlinkIds();\n\n // Remove orphaned hyperlink relationships\n return this.doc.getRelationshipManager().removeOrphanedHyperlinks(referencedIds);\n }\n\n private removeCustomXML(): number {\n const zipHandler = this.doc.getZipHandler();\n let removed = 0;\n\n // Remove customXML files\n const files = zipHandler.getFilePaths();\n for (const file of files) {\n if (file.startsWith('customXml/') || file.startsWith('customXML/')) {\n zipHandler.removeFile(file);\n removed++;\n }\n }\n\n // Remove customXML relationships\n const relManager = this.doc.getRelationshipManager();\n const customRels = relManager.getRelationshipsByType(\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml'\n );\n for (const rel of customRels) {\n relManager.removeRelationship(rel.getId());\n removed++;\n }\n\n // Remove custom.xml if present (docProps/custom.xml)\n if (zipHandler.hasFile('docProps/custom.xml')) {\n zipHandler.removeFile('docProps/custom.xml');\n removed++;\n }\n\n return removed;\n }\n\n // Lock state must be cleared on the in-memory model, not the ZIP copy of\n // word/document.xml: prepareSave() regenerates document.xml from the model,\n // so raw-XML edits here would be overwritten and the locks re-emitted.\n private unlockFields(): number {\n let count = 0;\n\n for (const para of this.doc.getAllParagraphs()) {\n // w:fldChar w:fldLock on complex-field runs (ECMA-376 §17.16.18).\n // getRuns() includes runs inside revisions and hyperlinks; the\n // returned content elements are live references, so clearing the\n // flag mutates the run itself.\n for (const run of para.getRuns()) {\n for (const item of run.getContent()) {\n if (item.type === 'fieldChar' && item.fieldCharLocked === true) {\n item.fieldCharLocked = undefined;\n count++;\n }\n }\n }\n\n // w:fldLock on simple fields (w:fldSimple, ECMA-376 §17.16.16).\n // Field keeps the flag private with no mutator, so clear it\n // structurally — the regenerated fldSimple then omits the attribute.\n for (const item of para.getContent()) {\n if (item instanceof Field) {\n const lockable = item as unknown as { fldLock?: boolean };\n if (lockable.fldLock === true) {\n lockable.fldLock = undefined;\n count++;\n }\n }\n }\n }\n\n return count;\n }\n\n private unlockFrames(): number {\n let count = 0;\n\n for (const para of this.doc.getAllParagraphs()) {\n const framePr = para.getFormatting().framePr;\n if (framePr?.anchorLock === true) {\n para.setFrameProperties({ ...framePr, anchorLock: undefined });\n count++;\n }\n }\n\n return count;\n }\n\n private sanitizeTables(): number {\n const tables = this.doc.getAllTables();\n let processed = 0;\n for (const table of tables) {\n for (const row of table.getRows()) {\n const exceptions = row.getTablePropertyExceptions();\n if (exceptions && Object.keys(exceptions).length > 0) {\n row.setTablePropertyExceptions(undefined as any);\n }\n }\n processed++;\n }\n return processed;\n }\n\n private formatInternalHyperlinks(): number {\n let count = 0;\n const formatting = {\n font: 'Verdana',\n size: 12,\n color: '0000FF',\n underline: 'single' as const,\n };\n\n // Process body paragraphs\n for (const paragraph of this.doc.getAllParagraphs()) {\n for (const item of paragraph.getContent()) {\n if (item instanceof Hyperlink && item.isInternal()) {\n item.setFormatting(formatting, { replace: true });\n count++;\n }\n }\n }\n\n // Process table paragraphs\n for (const table of this.doc.getAllTables()) {\n for (const row of table.getRows()) {\n for (const cell of row.getCells()) {\n for (const para of cell.getParagraphs()) {\n for (const item of para.getContent()) {\n if (item instanceof Hyperlink && item.isInternal()) {\n item.setFormatting(formatting, { replace: true });\n count++;\n }\n }\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Formats ALL hyperlinks in the document with standard styling\n * This includes:\n * - Internal w:hyperlink elements (bookmarks)\n * - External w:hyperlink elements (URLs)\n * - HYPERLINK fields (both simple w:fldSimple and complex fields)\n *\n * Standard formatting: Verdana 12pt, #0000FF blue, single underline\n * @returns Number of hyperlinks formatted\n */\n private formatAllHyperlinks(): number {\n let count = 0;\n const formatting = {\n font: 'Verdana',\n size: 12,\n color: '0000FF',\n underline: 'single' as const,\n };\n\n // Helper to process paragraph content\n const processParagraph = (paragraph: Paragraph): void => {\n for (const item of paragraph.getContent()) {\n // Process all Hyperlink instances (both internal AND external)\n if (item instanceof Hyperlink) {\n item.setFormatting(formatting, { replace: true });\n count++;\n }\n // Process simple HYPERLINK fields\n if (item instanceof Field && item.isHyperlinkField()) {\n item.setFormatting(formatting);\n count++;\n }\n // Process complex HYPERLINK fields\n if (item instanceof ComplexField && item.isHyperlinkField()) {\n item.setResultFormatting(formatting);\n count++;\n }\n }\n };\n\n // Process body paragraphs\n for (const paragraph of this.doc.getAllParagraphs()) {\n processParagraph(paragraph);\n }\n\n // Process table paragraphs\n for (const table of this.doc.getAllTables()) {\n for (const row of table.getRows()) {\n for (const cell of row.getCells()) {\n for (const para of cell.getParagraphs()) {\n processParagraph(para);\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Preset: Google Docs cleanup\n */\n static googleDocsPreset(): CleanupOptions {\n return {\n unlockSDTs: true,\n removeSDTs: true,\n defragmentHyperlinks: true,\n resetHyperlinkFormatting: true,\n cleanupRelationships: true,\n removeCustomXML: true,\n sanitizeTables: true,\n };\n }\n\n /**\n * Preset: Full cleanup\n */\n static fullCleanupPreset(): CleanupOptions {\n return {\n unlockSDTs: true,\n removeSDTs: true,\n clearPreserveFlags: true,\n defragmentHyperlinks: true,\n resetHyperlinkFormatting: true,\n cleanupNumbering: true,\n cleanupStyles: true,\n cleanupRelationships: true,\n removeCustomXML: true,\n unlockFields: true,\n unlockFrames: true,\n sanitizeTables: true,\n formatAllHyperlinks: true,\n };\n }\n\n /**\n * Preset: Minimal cleanup\n */\n static minimalPreset(): CleanupOptions {\n return {\n cleanupRelationships: true,\n removeCustomXML: true,\n };\n }\n}\n"]}
@@ -80,6 +80,20 @@ export function optimizePng(buffer) {
80
80
  resultParts.push(buildPngChunk('IEND', Buffer.alloc(0)));
81
81
  return Buffer.concat(resultParts);
82
82
  }
83
+ function maskToByteIndex(mask) {
84
+ switch (mask) {
85
+ case 0x000000ff:
86
+ return 0;
87
+ case 0x0000ff00:
88
+ return 1;
89
+ case 0x00ff0000:
90
+ return 2;
91
+ case 0xff000000:
92
+ return 3;
93
+ default:
94
+ return null;
95
+ }
96
+ }
83
97
  export function convertBmpToPng(buffer) {
84
98
  if (buffer.length < 54 || buffer[0] !== 0x42 || buffer[1] !== 0x4d) {
85
99
  return null;
@@ -106,6 +120,40 @@ export function convertBmpToPng(buffer) {
106
120
  const rowSize = Math.ceil((width * bytesPerPixel) / 4) * 4;
107
121
  if (pixelDataOffset + absHeight * rowSize > buffer.length)
108
122
  return null;
123
+ let rOff = 2;
124
+ let gOff = 1;
125
+ let bOff = 0;
126
+ let aOff = 3;
127
+ let forceOpaqueAlpha = false;
128
+ if (bitsPerPixel === 32) {
129
+ if (compression === 3) {
130
+ if (buffer.length < 66)
131
+ return null;
132
+ const rIdx = maskToByteIndex(buffer.readUInt32LE(54));
133
+ const gIdx = maskToByteIndex(buffer.readUInt32LE(58));
134
+ const bIdx = maskToByteIndex(buffer.readUInt32LE(62));
135
+ if (rIdx === null || gIdx === null || bIdx === null)
136
+ return null;
137
+ if (rIdx === gIdx || rIdx === bIdx || gIdx === bIdx)
138
+ return null;
139
+ rOff = rIdx;
140
+ gOff = gIdx;
141
+ bOff = bIdx;
142
+ aOff = 6 - rIdx - gIdx - bIdx;
143
+ }
144
+ else {
145
+ forceOpaqueAlpha = true;
146
+ for (let y = 0; forceOpaqueAlpha && y < absHeight; y++) {
147
+ const rowOffset = pixelDataOffset + y * rowSize;
148
+ for (let x = 0; x < width; x++) {
149
+ if (buffer[rowOffset + x * 4 + 3] !== 0) {
150
+ forceOpaqueAlpha = false;
151
+ break;
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
109
157
  const colorType = bitsPerPixel === 32 ? 6 : 2;
110
158
  const pngBytesPerPixel = bitsPerPixel === 32 ? 4 : 3;
111
159
  const ihdrData = Buffer.alloc(13);
@@ -126,11 +174,11 @@ export function convertBmpToPng(buffer) {
126
174
  for (let x = 0; x < width; x++) {
127
175
  const bmpPixelOffset = bmpRowOffset + x * bytesPerPixel;
128
176
  const pngPixelOffset = pngRowOffset + 1 + x * pngBytesPerPixel;
129
- rawData[pngPixelOffset] = buffer[bmpPixelOffset + 2];
130
- rawData[pngPixelOffset + 1] = buffer[bmpPixelOffset + 1];
131
- rawData[pngPixelOffset + 2] = buffer[bmpPixelOffset];
177
+ rawData[pngPixelOffset] = buffer[bmpPixelOffset + rOff];
178
+ rawData[pngPixelOffset + 1] = buffer[bmpPixelOffset + gOff];
179
+ rawData[pngPixelOffset + 2] = buffer[bmpPixelOffset + bOff];
132
180
  if (bitsPerPixel === 32) {
133
- rawData[pngPixelOffset + 3] = buffer[bmpPixelOffset + 3];
181
+ rawData[pngPixelOffset + 3] = forceOpaqueAlpha ? 0xff : buffer[bmpPixelOffset + aOff];
134
182
  }
135
183
  }
136
184
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ImageOptimizer.js","sourceRoot":"","sources":["../../../src/images/ImageOptimizer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ImageOptimizer - Lossless image optimization for DOCX documents\n *\n * Two techniques using only Node.js built-in zlib (zero dependencies):\n * 1. PNG re-compression — Re-compress IDAT chunks at zlib level 9 + strip metadata\n * 2. BMP → PNG conversion — Lossless format change, typically 10-50x smaller\n */\n\nimport * as zlib from 'zlib';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ImageOptimizationResult {\n optimizedCount: number;\n totalSavedBytes: number;\n}\n\n// =============================================================================\n// CRC-32 (IEEE polynomial)\n// =============================================================================\n\nconst CRC_TABLE: Uint32Array = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c;\n }\n return table;\n})();\n\nfunction crc32(buf: Buffer): number {\n let crc = 0xffffffff;\n for (let i = 0; i < buf.length; i++) {\n crc = CRC_TABLE[(crc ^ buf[i]!) & 0xff]! ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n// =============================================================================\n// PNG Chunk Builder\n// =============================================================================\n\nconst PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n\n/**\n * Builds a PNG chunk: [4-byte length][4-byte type][data][4-byte CRC]\n * CRC covers type + data bytes\n */\nfunction buildPngChunk(type: string, data: Buffer): Buffer {\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length, 0);\n\n const typeBuffer = Buffer.from(type, 'ascii');\n\n const crcInput = Buffer.concat([typeBuffer, data]);\n const crcValue = crc32(crcInput);\n const crcBuffer = Buffer.alloc(4);\n crcBuffer.writeUInt32BE(crcValue, 0);\n\n return Buffer.concat([length, typeBuffer, data, crcBuffer]);\n}\n\n// =============================================================================\n// PNG Re-compression\n// =============================================================================\n\n/**\n * Re-compresses a PNG buffer at zlib level 9 and strips non-essential metadata chunks.\n * Returns the optimized buffer, or null if the PNG is invalid/cannot be optimized.\n * The caller should compare sizes to decide whether to use the result.\n */\nexport function optimizePng(buffer: Buffer): Buffer | null {\n // Verify PNG signature\n if (buffer.length < 8 || !buffer.subarray(0, 8).equals(PNG_SIGNATURE)) {\n return null;\n }\n\n // Parse chunks\n let ihdrData: Buffer | null = null;\n let plteData: Buffer | null = null;\n let trnsData: Buffer | null = null;\n const idatBuffers: Buffer[] = [];\n\n let offset = 8; // Skip signature\n while (offset + 12 <= buffer.length) {\n const chunkLength = buffer.readUInt32BE(offset);\n const chunkType = buffer.subarray(offset + 4, offset + 8).toString('ascii');\n\n // Bounds check: length + type(4) + data + crc(4) = 12 + chunkLength\n if (offset + 12 + chunkLength > buffer.length) break;\n\n const chunkData = buffer.subarray(offset + 8, offset + 8 + chunkLength);\n\n if (chunkType === 'IHDR') {\n ihdrData = Buffer.from(chunkData);\n } else if (chunkType === 'PLTE') {\n plteData = Buffer.from(chunkData);\n } else if (chunkType === 'tRNS') {\n trnsData = Buffer.from(chunkData);\n } else if (chunkType === 'IDAT') {\n idatBuffers.push(chunkData);\n }\n // Non-essential chunks (tEXt, iTXt, zTXt, iCCP, sRGB, gAMA, cHRM, tIME, pHYs, etc.)\n // are intentionally discarded\n\n offset += 12 + chunkLength;\n\n // Stop after IEND\n if (chunkType === 'IEND') break;\n }\n\n if (!ihdrData || idatBuffers.length === 0) return null;\n\n // Decompress all IDAT data\n const combinedIdat = Buffer.concat(idatBuffers);\n let decompressed: Buffer;\n try {\n decompressed = zlib.inflateSync(combinedIdat);\n } catch {\n return null; // Corrupted IDAT data\n }\n\n // Re-compress at maximum level\n const recompressed = zlib.deflateSync(decompressed, { level: 9 });\n\n // Rebuild PNG: signature + IHDR + [PLTE] + [tRNS] + IDAT + IEND\n const resultParts: Buffer[] = [Buffer.from(PNG_SIGNATURE)];\n\n resultParts.push(buildPngChunk('IHDR', ihdrData));\n if (plteData) resultParts.push(buildPngChunk('PLTE', plteData));\n if (trnsData) resultParts.push(buildPngChunk('tRNS', trnsData));\n resultParts.push(buildPngChunk('IDAT', recompressed));\n resultParts.push(buildPngChunk('IEND', Buffer.alloc(0)));\n\n return Buffer.concat(resultParts);\n}\n\n// =============================================================================\n// BMP → PNG Conversion\n// =============================================================================\n\n/**\n * Converts a BMP buffer to PNG format. Lossless conversion.\n * Supports 24-bit (RGB) and 32-bit (RGBA) uncompressed BMPs.\n * Returns null for unsupported variants (indexed, 16-bit, RLE-compressed).\n */\nexport function convertBmpToPng(buffer: Buffer): Buffer | null {\n // Minimum BMP size: 14 (file header) + 40 (BITMAPINFOHEADER) = 54 bytes\n if (buffer.length < 54 || buffer[0] !== 0x42 || buffer[1] !== 0x4d) {\n return null;\n }\n\n // Parse BMP file header (14 bytes)\n const pixelDataOffset = buffer.readUInt32LE(10);\n\n // Parse DIB header (BITMAPINFOHEADER)\n const dibHeaderSize = buffer.readUInt32LE(14);\n if (dibHeaderSize < 40) return null; // Only support BITMAPINFOHEADER and larger\n\n const width = buffer.readInt32LE(18);\n const height = buffer.readInt32LE(22);\n const bitsPerPixel = buffer.readUInt16LE(28);\n const compression = buffer.readUInt32LE(30);\n\n // Only support uncompressed (0) and BI_BITFIELDS (3) for 32-bit\n if (compression !== 0 && !(compression === 3 && bitsPerPixel === 32)) return null;\n\n // Only support 24-bit and 32-bit\n if (bitsPerPixel !== 24 && bitsPerPixel !== 32) return null;\n\n if (width <= 0) return null;\n const absHeight = Math.abs(height);\n if (absHeight === 0) return null;\n const isTopDown = height < 0;\n\n const bytesPerPixel = bitsPerPixel / 8;\n\n // BMP rows are padded to 4-byte boundaries\n const rowSize = Math.ceil((width * bytesPerPixel) / 4) * 4;\n\n // Validate buffer has enough pixel data\n if (pixelDataOffset + absHeight * rowSize > buffer.length) return null;\n\n // PNG color type: 2 = RGB (24-bit), 6 = RGBA (32-bit)\n const colorType = bitsPerPixel === 32 ? 6 : 2;\n const pngBytesPerPixel = bitsPerPixel === 32 ? 4 : 3;\n\n // Build IHDR data (13 bytes)\n const ihdrData = Buffer.alloc(13);\n ihdrData.writeUInt32BE(width, 0);\n ihdrData.writeUInt32BE(absHeight, 4);\n ihdrData[8] = 8; // bit depth\n ihdrData[9] = colorType; // color type\n ihdrData[10] = 0; // compression method (deflate)\n ihdrData[11] = 0; // filter method (adaptive)\n ihdrData[12] = 0; // interlace method (none)\n\n // Build raw image data: filter byte (0 = None) + pixel data per row\n const rawDataSize = absHeight * (1 + width * pngBytesPerPixel);\n const rawData = Buffer.alloc(rawDataSize);\n\n for (let y = 0; y < absHeight; y++) {\n // BMP stores rows bottom-up by default; top-down if height is negative\n const bmpRow = isTopDown ? y : absHeight - 1 - y;\n const bmpRowOffset = pixelDataOffset + bmpRow * rowSize;\n\n const pngRowOffset = y * (1 + width * pngBytesPerPixel);\n rawData[pngRowOffset] = 0; // Filter type: None\n\n for (let x = 0; x < width; x++) {\n const bmpPixelOffset = bmpRowOffset + x * bytesPerPixel;\n const pngPixelOffset = pngRowOffset + 1 + x * pngBytesPerPixel;\n\n // Convert BGR(A) → RGB(A)\n rawData[pngPixelOffset] = buffer[bmpPixelOffset + 2]!; // R\n rawData[pngPixelOffset + 1] = buffer[bmpPixelOffset + 1]!; // G\n rawData[pngPixelOffset + 2] = buffer[bmpPixelOffset]!; // B\n\n if (bitsPerPixel === 32) {\n rawData[pngPixelOffset + 3] = buffer[bmpPixelOffset + 3]!; // A\n }\n }\n }\n\n // Compress pixel data\n const compressedData = zlib.deflateSync(rawData, { level: 9 });\n\n // Assemble PNG file\n return Buffer.concat([\n Buffer.from(PNG_SIGNATURE),\n buildPngChunk('IHDR', ihdrData),\n buildPngChunk('IDAT', compressedData),\n buildPngChunk('IEND', Buffer.alloc(0)),\n ]);\n}\n\n// =============================================================================\n// Router\n// =============================================================================\n\n/**\n * Optimizes an image buffer based on its format.\n * - PNG: re-compresses at zlib level 9 and strips metadata. Only returns result if smaller.\n * - BMP: converts to PNG (always smaller than uncompressed BMP).\n * - Other formats: returns null (unsupported / cannot be losslessly optimized further).\n */\nexport function optimizeImage(\n buffer: Buffer,\n extension: string\n): { data: Buffer; newExtension: string } | null {\n const ext = extension.toLowerCase();\n\n if (ext === 'png') {\n const optimized = optimizePng(buffer);\n if (!optimized || optimized.length >= buffer.length) return null;\n return { data: optimized, newExtension: 'png' };\n }\n\n if (ext === 'bmp') {\n const converted = convertBmpToPng(buffer);\n if (!converted) return null;\n return { data: converted, newExtension: 'png' };\n }\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"ImageOptimizer.js","sourceRoot":"","sources":["../../../src/images/ImageOptimizer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ImageOptimizer - Lossless image optimization for DOCX documents\n *\n * Two techniques using only Node.js built-in zlib (zero dependencies):\n * 1. PNG re-compression — Re-compress IDAT chunks at zlib level 9 + strip metadata\n * 2. BMP → PNG conversion — Lossless format change, typically 10-50x smaller\n */\n\nimport * as zlib from 'zlib';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ImageOptimizationResult {\n optimizedCount: number;\n totalSavedBytes: number;\n}\n\n// =============================================================================\n// CRC-32 (IEEE polynomial)\n// =============================================================================\n\nconst CRC_TABLE: Uint32Array = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c;\n }\n return table;\n})();\n\nfunction crc32(buf: Buffer): number {\n let crc = 0xffffffff;\n for (let i = 0; i < buf.length; i++) {\n crc = CRC_TABLE[(crc ^ buf[i]!) & 0xff]! ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n// =============================================================================\n// PNG Chunk Builder\n// =============================================================================\n\nconst PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n\n/**\n * Builds a PNG chunk: [4-byte length][4-byte type][data][4-byte CRC]\n * CRC covers type + data bytes\n */\nfunction buildPngChunk(type: string, data: Buffer): Buffer {\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length, 0);\n\n const typeBuffer = Buffer.from(type, 'ascii');\n\n const crcInput = Buffer.concat([typeBuffer, data]);\n const crcValue = crc32(crcInput);\n const crcBuffer = Buffer.alloc(4);\n crcBuffer.writeUInt32BE(crcValue, 0);\n\n return Buffer.concat([length, typeBuffer, data, crcBuffer]);\n}\n\n// =============================================================================\n// PNG Re-compression\n// =============================================================================\n\n/**\n * Re-compresses a PNG buffer at zlib level 9 and strips non-essential metadata chunks.\n * Returns the optimized buffer, or null if the PNG is invalid/cannot be optimized.\n * The caller should compare sizes to decide whether to use the result.\n */\nexport function optimizePng(buffer: Buffer): Buffer | null {\n // Verify PNG signature\n if (buffer.length < 8 || !buffer.subarray(0, 8).equals(PNG_SIGNATURE)) {\n return null;\n }\n\n // Parse chunks\n let ihdrData: Buffer | null = null;\n let plteData: Buffer | null = null;\n let trnsData: Buffer | null = null;\n const idatBuffers: Buffer[] = [];\n\n let offset = 8; // Skip signature\n while (offset + 12 <= buffer.length) {\n const chunkLength = buffer.readUInt32BE(offset);\n const chunkType = buffer.subarray(offset + 4, offset + 8).toString('ascii');\n\n // Bounds check: length + type(4) + data + crc(4) = 12 + chunkLength\n if (offset + 12 + chunkLength > buffer.length) break;\n\n const chunkData = buffer.subarray(offset + 8, offset + 8 + chunkLength);\n\n if (chunkType === 'IHDR') {\n ihdrData = Buffer.from(chunkData);\n } else if (chunkType === 'PLTE') {\n plteData = Buffer.from(chunkData);\n } else if (chunkType === 'tRNS') {\n trnsData = Buffer.from(chunkData);\n } else if (chunkType === 'IDAT') {\n idatBuffers.push(chunkData);\n }\n // Non-essential chunks (tEXt, iTXt, zTXt, iCCP, sRGB, gAMA, cHRM, tIME, pHYs, etc.)\n // are intentionally discarded\n\n offset += 12 + chunkLength;\n\n // Stop after IEND\n if (chunkType === 'IEND') break;\n }\n\n if (!ihdrData || idatBuffers.length === 0) return null;\n\n // Decompress all IDAT data\n const combinedIdat = Buffer.concat(idatBuffers);\n let decompressed: Buffer;\n try {\n decompressed = zlib.inflateSync(combinedIdat);\n } catch {\n return null; // Corrupted IDAT data\n }\n\n // Re-compress at maximum level\n const recompressed = zlib.deflateSync(decompressed, { level: 9 });\n\n // Rebuild PNG: signature + IHDR + [PLTE] + [tRNS] + IDAT + IEND\n const resultParts: Buffer[] = [Buffer.from(PNG_SIGNATURE)];\n\n resultParts.push(buildPngChunk('IHDR', ihdrData));\n if (plteData) resultParts.push(buildPngChunk('PLTE', plteData));\n if (trnsData) resultParts.push(buildPngChunk('tRNS', trnsData));\n resultParts.push(buildPngChunk('IDAT', recompressed));\n resultParts.push(buildPngChunk('IEND', Buffer.alloc(0)));\n\n return Buffer.concat(resultParts);\n}\n\n// =============================================================================\n// BMP → PNG Conversion\n// =============================================================================\n\n/**\n * Maps a 32-bit BI_BITFIELDS channel mask to its byte index within a\n * little-endian pixel. Only byte-aligned 8-bit masks map losslessly onto\n * PNG's 8-bit channels; anything else returns null.\n */\nfunction maskToByteIndex(mask: number): number | null {\n switch (mask) {\n case 0x000000ff:\n return 0;\n case 0x0000ff00:\n return 1;\n case 0x00ff0000:\n return 2;\n case 0xff000000:\n return 3;\n default:\n return null;\n }\n}\n\n/**\n * Converts a BMP buffer to PNG format. Lossless conversion.\n * Supports 24-bit (RGB) and 32-bit (RGBA) uncompressed BMPs.\n * Returns null for unsupported variants (indexed, 16-bit, RLE-compressed).\n */\nexport function convertBmpToPng(buffer: Buffer): Buffer | null {\n // Minimum BMP size: 14 (file header) + 40 (BITMAPINFOHEADER) = 54 bytes\n if (buffer.length < 54 || buffer[0] !== 0x42 || buffer[1] !== 0x4d) {\n return null;\n }\n\n // Parse BMP file header (14 bytes)\n const pixelDataOffset = buffer.readUInt32LE(10);\n\n // Parse DIB header (BITMAPINFOHEADER)\n const dibHeaderSize = buffer.readUInt32LE(14);\n if (dibHeaderSize < 40) return null; // Only support BITMAPINFOHEADER and larger\n\n const width = buffer.readInt32LE(18);\n const height = buffer.readInt32LE(22);\n const bitsPerPixel = buffer.readUInt16LE(28);\n const compression = buffer.readUInt32LE(30);\n\n // Only support uncompressed (0) and BI_BITFIELDS (3) for 32-bit\n if (compression !== 0 && !(compression === 3 && bitsPerPixel === 32)) return null;\n\n // Only support 24-bit and 32-bit\n if (bitsPerPixel !== 24 && bitsPerPixel !== 32) return null;\n\n if (width <= 0) return null;\n const absHeight = Math.abs(height);\n if (absHeight === 0) return null;\n const isTopDown = height < 0;\n\n const bytesPerPixel = bitsPerPixel / 8;\n\n // BMP rows are padded to 4-byte boundaries\n const rowSize = Math.ceil((width * bytesPerPixel) / 4) * 4;\n\n // Validate buffer has enough pixel data\n if (pixelDataOffset + absHeight * rowSize > buffer.length) return null;\n\n // Channel byte offsets within a pixel; defaults match the standard BGR(A) layout\n let rOff = 2;\n let gOff = 1;\n let bOff = 0;\n let aOff = 3;\n let forceOpaqueAlpha = false;\n\n if (bitsPerPixel === 32) {\n if (compression === 3) {\n // BI_BITFIELDS: channel masks follow BITMAPINFOHEADER (the same file\n // offsets hold the masks inside V4/V5 headers), so they must be honored\n // to keep the conversion lossless\n if (buffer.length < 66) return null;\n const rIdx = maskToByteIndex(buffer.readUInt32LE(54));\n const gIdx = maskToByteIndex(buffer.readUInt32LE(58));\n const bIdx = maskToByteIndex(buffer.readUInt32LE(62));\n if (rIdx === null || gIdx === null || bIdx === null) return null;\n if (rIdx === gIdx || rIdx === bIdx || gIdx === bIdx) return null;\n rOff = rIdx;\n gOff = gIdx;\n bOff = bIdx;\n aOff = 6 - rIdx - gIdx - bIdx; // the byte not claimed by R/G/B carries alpha\n } else {\n // BI_RGB: the 4th byte is reserved and writers commonly zero it, so\n // copying it as alpha would render the whole image transparent. Treat it\n // as alpha only when at least one pixel carries a non-zero value.\n forceOpaqueAlpha = true;\n for (let y = 0; forceOpaqueAlpha && y < absHeight; y++) {\n const rowOffset = pixelDataOffset + y * rowSize;\n for (let x = 0; x < width; x++) {\n if (buffer[rowOffset + x * 4 + 3] !== 0) {\n forceOpaqueAlpha = false;\n break;\n }\n }\n }\n }\n }\n\n // PNG color type: 2 = RGB (24-bit), 6 = RGBA (32-bit)\n const colorType = bitsPerPixel === 32 ? 6 : 2;\n const pngBytesPerPixel = bitsPerPixel === 32 ? 4 : 3;\n\n // Build IHDR data (13 bytes)\n const ihdrData = Buffer.alloc(13);\n ihdrData.writeUInt32BE(width, 0);\n ihdrData.writeUInt32BE(absHeight, 4);\n ihdrData[8] = 8; // bit depth\n ihdrData[9] = colorType; // color type\n ihdrData[10] = 0; // compression method (deflate)\n ihdrData[11] = 0; // filter method (adaptive)\n ihdrData[12] = 0; // interlace method (none)\n\n // Build raw image data: filter byte (0 = None) + pixel data per row\n const rawDataSize = absHeight * (1 + width * pngBytesPerPixel);\n const rawData = Buffer.alloc(rawDataSize);\n\n for (let y = 0; y < absHeight; y++) {\n // BMP stores rows bottom-up by default; top-down if height is negative\n const bmpRow = isTopDown ? y : absHeight - 1 - y;\n const bmpRowOffset = pixelDataOffset + bmpRow * rowSize;\n\n const pngRowOffset = y * (1 + width * pngBytesPerPixel);\n rawData[pngRowOffset] = 0; // Filter type: None\n\n for (let x = 0; x < width; x++) {\n const bmpPixelOffset = bmpRowOffset + x * bytesPerPixel;\n const pngPixelOffset = pngRowOffset + 1 + x * pngBytesPerPixel;\n\n // Route channels by resolved byte offsets (BGR(A) unless masks say otherwise)\n rawData[pngPixelOffset] = buffer[bmpPixelOffset + rOff]!; // R\n rawData[pngPixelOffset + 1] = buffer[bmpPixelOffset + gOff]!; // G\n rawData[pngPixelOffset + 2] = buffer[bmpPixelOffset + bOff]!; // B\n\n if (bitsPerPixel === 32) {\n rawData[pngPixelOffset + 3] = forceOpaqueAlpha ? 0xff : buffer[bmpPixelOffset + aOff]!; // A\n }\n }\n }\n\n // Compress pixel data\n const compressedData = zlib.deflateSync(rawData, { level: 9 });\n\n // Assemble PNG file\n return Buffer.concat([\n Buffer.from(PNG_SIGNATURE),\n buildPngChunk('IHDR', ihdrData),\n buildPngChunk('IDAT', compressedData),\n buildPngChunk('IEND', Buffer.alloc(0)),\n ]);\n}\n\n// =============================================================================\n// Router\n// =============================================================================\n\n/**\n * Optimizes an image buffer based on its format.\n * - PNG: re-compresses at zlib level 9 and strips metadata. Only returns result if smaller.\n * - BMP: converts to PNG (always smaller than uncompressed BMP).\n * - Other formats: returns null (unsupported / cannot be losslessly optimized further).\n */\nexport function optimizeImage(\n buffer: Buffer,\n extension: string\n): { data: Buffer; newExtension: string } | null {\n const ext = extension.toLowerCase();\n\n if (ext === 'png') {\n const optimized = optimizePng(buffer);\n if (!optimized || optimized.length >= buffer.length) return null;\n return { data: optimized, newExtension: 'png' };\n }\n\n if (ext === 'bmp') {\n const converted = convertBmpToPng(buffer);\n if (!converted) return null;\n return { data: converted, newExtension: 'png' };\n }\n\n return null;\n}\n"]}
package/dist/esm/index.js CHANGED
@@ -58,6 +58,7 @@ export { STANDARD_DPI, UNITS, PAGE_SIZES, COMMON_MARGINS, twipsToPoints, twipsTo
58
58
  export { validateDocxStructure, isBinaryFile, normalizePath, isValidZipBuffer, isTextContent, validateTwips, validateColor, validateHexColor, normalizeColor, validateNumberingId, validateLevel, validateAlignment, validateFontSize, validateNonEmptyString, validatePercentage, validateEmus, detectXmlInText, cleanXmlFromText, validateRunText, sanitizeHyperlinkUrl, } from './utils/validation.js';
59
59
  export { detectCorruptionInDocument, detectCorruptionInText, suggestFix, looksCorrupted, } from './utils/corruptionDetection.js';
60
60
  export { isError, toError, wrapError, getErrorMessage } from './utils/errorHandling.js';
61
+ export { ResourceLimitError } from './zip/errors.js';
61
62
  export { REVISION_RULES, createIssueFromRule, getRuleByCode, getRulesBySeverity, getAutoFixableRules, RevisionValidator, RevisionAutoFixer, } from './validation/index.js';
62
63
  export { mergeFormatting, cloneFormatting, hasFormatting, cleanFormatting, isEqualFormatting, applyDefaults, } from './utils/formatting.js';
63
64
  export { safeParseInt, parseOoxmlBoolean, isExplicitlySet, parseNumericAttribute, parseOnOffAttribute, } from './utils/parsingHelpers.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DocXML - DOCX Editing Framework\n * Main entry point\n */\n\n// =============================================================================\n// PUBLIC API — Core Document Classes\n// =============================================================================\n\nexport {\n Document,\n DocumentProperties,\n DocumentOptions,\n DocumentLoadOptions,\n DocumentPart,\n} from './core/Document.js';\n\n// =============================================================================\n// PUBLIC API — Document Elements\n// =============================================================================\n\nexport {\n Paragraph,\n ParagraphAlignment,\n ParagraphFormatting,\n ParagraphContent,\n FieldLike,\n isRun,\n isField,\n isSimpleField,\n isComplexField,\n isHyperlink,\n isRevision,\n isRangeMarker,\n isShape,\n isTextBox,\n} from './elements/Paragraph.js';\nexport { Run, RunFormatting, ThemeColorValue, LanguageConfig } from './elements/Run.js';\nexport {\n Section,\n PageOrientation,\n SectionType,\n PageNumberFormat,\n PageSize,\n Margins,\n Columns,\n PageNumbering,\n SectionProperties,\n LineNumbering,\n LineNumberingRestart,\n} from './elements/Section.js';\nexport {\n Table,\n TableAlignment,\n TableLayout,\n TableBorder,\n TableBorders,\n TableFormatting,\n} from './elements/Table.js';\nexport { TableRow, RowFormatting } from './elements/TableRow.js';\nexport {\n TableCell,\n CellBorder,\n CellBorders,\n CellShading,\n CellFormatting,\n} from './elements/TableCell.js';\nexport {\n TableGridChange,\n GridColumn,\n TableGridChangeProperties,\n} from './elements/TableGridChange.js';\nexport {\n Image,\n ImageFormat,\n ImageProperties,\n ImageBorder,\n ImageEffects,\n PresetGeometry,\n BlipCompressionState,\n PicLockAttribute,\n PicNonVisualProperties,\n} from './elements/Image.js';\nexport { ImageRun } from './elements/ImageRun.js';\nexport { Shape, ShapeType, ShapeProperties, ShapeFill, ShapeOutline } from './elements/Shape.js';\nexport { TextBox, TextBoxProperties, TextBoxFill, TextBoxMargins } from './elements/TextBox.js';\nexport { Header, HeaderType, HeaderProperties } from './elements/Header.js';\nexport { Footer, FooterType, FooterProperties } from './elements/Footer.js';\nexport { Hyperlink, HyperlinkProperties } from './elements/Hyperlink.js';\nexport { Bookmark, BookmarkProperties } from './elements/Bookmark.js';\nexport { RangeMarker, RangeMarkerType, RangeMarkerProperties } from './elements/RangeMarker.js';\nexport { Comment, CommentProperties } from './elements/Comment.js';\nexport { Footnote, FootnoteType, FootnoteProperties } from './elements/Footnote.js';\nexport { Endnote, EndnoteType, EndnoteProperties } from './elements/Endnote.js';\nexport {\n Field,\n FieldType,\n FieldProperties,\n ComplexField,\n ComplexFieldProperties,\n FieldCharType,\n TOCFieldOptions,\n createTOCField,\n} from './elements/Field.js';\nexport {\n createNestedIFMergeField,\n createMergeField,\n createRefField,\n createIFField,\n createNestedField,\n parseHyperlinkInstruction,\n buildHyperlinkInstruction,\n isHyperlinkInstruction,\n ParsedHyperlinkInstruction,\n} from './elements/FieldHelpers.js';\nexport {\n StructuredDocumentTag,\n SDTProperties,\n SDTLockType,\n SDTContent,\n SDTPlaceholder,\n SDTDataBinding,\n ContentControlType,\n} from './elements/StructuredDocumentTag.js';\nexport { TableOfContents, TOCProperties } from './elements/TableOfContents.js';\nexport { TableOfContentsElement } from './elements/TableOfContentsElement.js';\nexport { AlternateContent } from './elements/AlternateContent.js';\nexport { MathParagraph, MathExpression } from './elements/MathElement.js';\nexport { CustomXmlBlock } from './elements/CustomXml.js';\nexport { PreservedElement, PreservedElementContext } from './elements/PreservedElement.js';\n\n// =============================================================================\n// PUBLIC API — Track Changes / Revisions\n// =============================================================================\n\nexport { Revision, RevisionType, RevisionProperties, FieldContext } from './elements/Revision.js';\nexport { RevisionContent, isRunContent, isHyperlinkContent } from './elements/RevisionContent.js';\nexport {\n RevisionLocation,\n RunPropertyChange,\n ParagraphPropertyChange,\n ParagraphFormattingPartial,\n ParagraphBorderDef,\n ParagraphBorders,\n ParagraphShading,\n TabStopDef,\n PropertyChangeBase,\n TablePropertyChange,\n TablePropertyChangeType,\n SectionPropertyChange,\n NumberingChange,\n AnyPropertyChange,\n isRunPropertyChange,\n isParagraphPropertyChange,\n isTablePropertyChange,\n isSectionPropertyChange,\n isNumberingChange,\n} from './elements/PropertyChangeTypes.js';\nexport {\n acceptRevisionsInMemory,\n AcceptRevisionsOptions,\n AcceptRevisionsResult,\n paragraphHasRevisions,\n getRevisionsFromParagraph,\n countRevisionsByType,\n stripRevisionsFromXml,\n} from './processors/InMemoryRevisionAcceptor.js';\nexport {\n MoveOperationHelper,\n MoveOperationOptions,\n MoveOperationResult,\n} from './processors/MoveOperationHelper.js';\nexport {\n SelectiveRevisionAcceptor,\n SelectiveAcceptResult,\n} from './processors/SelectiveRevisionAcceptor.js';\nexport {\n RevisionAwareProcessor,\n RevisionHandlingMode,\n RevisionProcessingOptions,\n SelectionCriteria,\n RevisionProcessingResult,\n ConflictInfo,\n ProcessingLogEntry,\n} from './processors/RevisionAwareProcessor.js';\nexport {\n ChangelogGenerator,\n ChangeEntry,\n ChangeCategory,\n ChangeLocation,\n ChangelogOptions,\n ChangelogFormat,\n ConsolidatedChange,\n ChangelogSummary,\n} from './processors/ChangelogGenerator.js';\n\n// =============================================================================\n// PUBLIC API — Formatting / Styles / Numbering\n// =============================================================================\n\nexport { Style, StyleType, StyleProperties } from './formatting/Style.js';\nexport {\n StylesManager,\n ValidationResult,\n LatentStylesConfig,\n LatentStyleException,\n} from './formatting/StylesManager.js';\nexport {\n NumberingLevel,\n NumberFormat,\n NumberAlignment,\n NumberingLevelProperties,\n WORD_NATIVE_BULLETS,\n WordNativeBullet,\n} from './formatting/NumberingLevel.js';\nexport { AbstractNumbering, AbstractNumberingProperties } from './formatting/AbstractNumbering.js';\nexport { NumberingInstance, NumberingInstanceProperties } from './formatting/NumberingInstance.js';\nexport {\n NumberingManager,\n NumberingConsolidationOptions,\n NumberingConsolidationResult,\n} from './formatting/NumberingManager.js';\nexport {\n StyleRunFormatting,\n StyleParagraphFormatting,\n Heading2TableOptions,\n StyleConfig,\n Heading2Config,\n ApplyCustomFormattingOptions,\n} from './types/styleConfig.js';\nexport { FormatOptions, StyleApplyOptions, EmphasisType, ListPrefix } from './types/formatting.js';\n\n// =============================================================================\n// PUBLIC API — Managers\n// =============================================================================\n\nexport { RevisionManager, RevisionCategory, RevisionSummary } from './elements/RevisionManager.js';\nexport { ImageManager } from './elements/ImageManager.js';\nexport { BookmarkManager } from './elements/BookmarkManager.js';\nexport { CommentManager } from './elements/CommentManager.js';\nexport { FootnoteManager } from './elements/FootnoteManager.js';\nexport { EndnoteManager } from './elements/EndnoteManager.js';\nexport { HeaderFooterManager } from './elements/HeaderFooterManager.js';\nexport { FontManager, FontFormat, FontEntry } from './elements/FontManager.js';\nexport {\n DrawingManager,\n DrawingElement,\n DrawingType,\n PreservedDrawing,\n} from './managers/DrawingManager.js';\n\n// =============================================================================\n// PUBLIC API — Image Optimization\n// =============================================================================\n\nexport type { ImageOptimizationResult } from './images/ImageOptimizer.js';\n\n// =============================================================================\n// TYPES — Common / Shared Type Definitions\n// =============================================================================\n\nexport {\n ShadingPattern,\n BasicShadingPattern,\n BorderStyle,\n ExtendedBorderStyle,\n FullBorderStyle,\n BorderDefinition,\n FourSidedBorders,\n TableBorderDefinitions,\n HorizontalAlignment,\n VerticalAlignment,\n PageVerticalAlignment,\n CellVerticalAlignment,\n ParagraphAlignment as CommonParagraphAlignment,\n TableAlignment as CommonTableAlignment,\n RowJustification,\n TextVerticalAlignment,\n TabAlignment,\n PositionAnchor,\n HorizontalAnchor,\n VerticalAnchor,\n TextDirection,\n SectionTextDirection,\n WidthType,\n ShadingConfig,\n buildShadingAttributes,\n TabLeader,\n TabStop,\n isShadingPattern,\n isBorderStyle,\n isHorizontalAlignment,\n isVerticalAlignment,\n isParagraphAlignment,\n isWidthType,\n DEFAULT_BORDER,\n NO_BORDER,\n} from './elements/CommonTypes.js';\nexport {\n ListCategory,\n NumberFormat as ListNumberFormat,\n BulletFormat,\n ListDetectionResult,\n ListAnalysis,\n ListNormalizationOptions,\n ListNormalizationReport,\n IndentationLevel,\n} from './types/list-types.js';\n\nexport {\n CompatibilityMode,\n CompatibilityInfo,\n CompatSetting,\n} from './types/compatibility-types.js';\n\nexport {\n DocumentProtection,\n RevisionViewSettings,\n TrackChangesSettings,\n WebSettingsInfo,\n} from './types/settings-types.js';\n\n// =============================================================================\n// TYPES — Compatibility Upgrade\n// =============================================================================\n\nexport { CompatibilityUpgrader, UpgradeReport } from './processors/CompatibilityUpgrader.js';\nexport {\n LEGACY_COMPAT_ELEMENTS,\n LEGACY_COMPAT_ELEMENT_NAMES,\n MODERN_COMPAT_SETTINGS,\n MS_WORD_COMPAT_URI,\n} from './constants/legacyCompatFlags.js';\n\n// =============================================================================\n// UTILITIES — Unit Conversions\n// =============================================================================\n\nexport {\n STANDARD_DPI,\n UNITS,\n PAGE_SIZES,\n COMMON_MARGINS,\n twipsToPoints,\n twipsToInches,\n twipsToCm,\n twipsToEmus,\n emusToTwips,\n emusToInches,\n emusToCm,\n emusToPoints,\n emusToPixels,\n pointsToTwips,\n pointsToEmus,\n pointsToInches,\n pointsToCm,\n pointsToHalfPoints,\n halfPointsToPoints,\n inchesToTwips,\n inchesToEmus,\n inchesToPoints,\n inchesToCm,\n inchesToPixels,\n cmToTwips,\n cmToEmus,\n cmToInches,\n cmToPoints,\n cmToPixels,\n pixelsToEmus,\n pixelsToInches,\n pixelsToTwips,\n pixelsToCm,\n pixelsToPoints,\n} from './utils/units.js';\n\n// =============================================================================\n// UTILITIES — Validation, Corruption Detection, Error Handling\n// =============================================================================\n\nexport {\n validateDocxStructure,\n isBinaryFile,\n normalizePath,\n isValidZipBuffer,\n isTextContent,\n validateTwips,\n validateColor,\n validateHexColor,\n normalizeColor,\n validateNumberingId,\n validateLevel,\n validateAlignment,\n validateFontSize,\n validateNonEmptyString,\n validatePercentage,\n validateEmus,\n detectXmlInText,\n cleanXmlFromText,\n validateRunText,\n sanitizeHyperlinkUrl,\n SanitizeHyperlinkUrlResult,\n TextValidationResult,\n} from './utils/validation.js';\nexport {\n detectCorruptionInDocument,\n detectCorruptionInText,\n suggestFix,\n looksCorrupted,\n CorruptionReport,\n CorruptionLocation,\n CorruptionType,\n} from './utils/corruptionDetection.js';\nexport { isError, toError, wrapError, getErrorMessage } from './utils/errorHandling.js';\nexport {\n REVISION_RULES,\n ValidationSeverity,\n ValidationIssue,\n ValidationRule,\n ValidationOptions,\n AutoFixOptions,\n ValidationResult as RevisionValidationResult,\n FixAction,\n AutoFixResult,\n createIssueFromRule,\n getRuleByCode,\n getRulesBySeverity,\n getAutoFixableRules,\n RevisionValidator,\n RevisionAutoFixer,\n} from './validation/index.js';\n\n// =============================================================================\n// UTILITIES — Formatting, Parsing, Sanitization\n// =============================================================================\n\nexport {\n mergeFormatting,\n cloneFormatting,\n hasFormatting,\n cleanFormatting,\n isEqualFormatting,\n applyDefaults,\n} from './utils/formatting.js';\nexport {\n safeParseInt,\n parseOoxmlBoolean,\n isExplicitlySet,\n parseNumericAttribute,\n parseOnOffAttribute,\n} from './utils/parsingHelpers.js';\nexport {\n removeInvalidXmlChars,\n findInvalidXmlChars,\n hasInvalidXmlChars,\n XML_CONTROL_CHARS,\n} from './utils/xmlSanitization.js';\n\n// =============================================================================\n// UTILITIES — List Detection (kept for basic detection; normalization moved to consumer)\n// =============================================================================\n\nexport {\n detectTypedPrefix,\n detectListType,\n inferLevelFromIndentation,\n getParagraphIndentation,\n validateListSequence,\n getListCategoryFromFormat,\n getLevelFromFormat,\n TYPED_LIST_PATTERNS,\n PATTERN_TO_CATEGORY,\n FORMAT_TO_LEVEL,\n} from './utils/list-detection.js';\n\n// =============================================================================\n// UTILITIES — Logging\n// =============================================================================\n\nexport {\n ILogger,\n LogLevel,\n LogEntry,\n ConsoleLogger,\n SilentLogger,\n CollectingLogger,\n defaultLogger,\n createScopedLogger,\n createComponentLogger,\n getGlobalLogger,\n setGlobalLogger,\n resetGlobalLogger,\n} from './utils/logger.js';\n\n// =============================================================================\n// UTILITIES — Revision Walker\n// =============================================================================\n\nexport { RevisionWalker, RevisionWalkerOptions } from './processors/RevisionWalker.js';\nexport { resolveCellShading } from './processors/ShadingResolver.js';\nexport {\n decodeCnfStyle,\n getActiveConditionalsInPriorityOrder,\n} from './processors/cnfStyleDecoder.js';\n\n// =============================================================================\n// UTILITIES — Cleanup\n// =============================================================================\n\nexport { CleanupHelper, CleanupOptions, CleanupReport } from './helpers/CleanupHelper.js';\n\n// =============================================================================\n// PUBLIC — Type unions consumers see when iterating doc.getBodyElements()\n// =============================================================================\n\nexport type { BodyElement } from './core/DocumentContent.js';\nexport {\n RelationshipType,\n type Relationship,\n type RelationshipProperties,\n} from './core/Relationship.js';\n\n// =============================================================================\n// EXTENSIBILITY — Plugin Registries and Document Events\n// =============================================================================\n\nexport {\n ElementRegistry,\n type ElementHandler,\n type ElementParseContext,\n type ElementSerializeContext,\n} from './core/ElementRegistry.js';\nexport { RegisteredBodyElement } from './elements/RegisteredBodyElement.js';\nexport {\n ValidationRuleRegistry,\n type CustomValidationRule,\n type CustomValidationIssue,\n type CustomValidationSeverity,\n} from './validation/ValidationRuleRegistry.js';\nexport type {\n DocumentEventMap,\n DocumentEventType,\n DocumentEventListener,\n} from './core/DocumentEvents.js';\n\n// Low-level building blocks — XMLBuilder, XMLParser, ZipHandler,\n// ZipReader, ZipWriter, DocumentParser, DocumentGenerator,\n// DocumentValidator, DocumentIdManager, DocumentContent,\n// RelationshipManager, DocumentEventEmitter, plus zip/xml types and\n// DocxError hierarchy — moved to the `docxmlater/internal` subpath in\n// 11.0.0. Migrate via:\n// import { XMLParser, ZipHandler } from 'docxmlater/internal';\n// The internal subpath has relaxed semver — pin an exact version.\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DocXML - DOCX Editing Framework\n * Main entry point\n */\n\n// =============================================================================\n// PUBLIC API — Core Document Classes\n// =============================================================================\n\nexport {\n Document,\n DocumentProperties,\n DocumentOptions,\n DocumentLoadOptions,\n DocumentPart,\n MarkdownConversionOptions,\n} from './core/Document.js';\n\n// =============================================================================\n// PUBLIC API — Document Elements\n// =============================================================================\n\nexport {\n Paragraph,\n ParagraphAlignment,\n ParagraphFormatting,\n ParagraphContent,\n FieldLike,\n isRun,\n isField,\n isSimpleField,\n isComplexField,\n isHyperlink,\n isRevision,\n isRangeMarker,\n isShape,\n isTextBox,\n} from './elements/Paragraph.js';\nexport { Run, RunFormatting, ThemeColorValue, LanguageConfig } from './elements/Run.js';\nexport {\n Section,\n PageOrientation,\n SectionType,\n PageNumberFormat,\n PageSize,\n Margins,\n Columns,\n PageNumbering,\n SectionProperties,\n LineNumbering,\n LineNumberingRestart,\n} from './elements/Section.js';\nexport {\n Table,\n TableAlignment,\n TableLayout,\n TableBorder,\n TableBorders,\n TableFormatting,\n} from './elements/Table.js';\nexport { TableRow, RowFormatting } from './elements/TableRow.js';\nexport {\n TableCell,\n CellBorder,\n CellBorders,\n CellShading,\n CellFormatting,\n} from './elements/TableCell.js';\nexport {\n TableGridChange,\n GridColumn,\n TableGridChangeProperties,\n} from './elements/TableGridChange.js';\nexport {\n Image,\n ImageFormat,\n ImageProperties,\n ImageBorder,\n ImageEffects,\n PresetGeometry,\n BlipCompressionState,\n PicLockAttribute,\n PicNonVisualProperties,\n} from './elements/Image.js';\nexport { ImageRun } from './elements/ImageRun.js';\nexport { Shape, ShapeType, ShapeProperties, ShapeFill, ShapeOutline } from './elements/Shape.js';\nexport { TextBox, TextBoxProperties, TextBoxFill, TextBoxMargins } from './elements/TextBox.js';\nexport { Header, HeaderType, HeaderProperties } from './elements/Header.js';\nexport { Footer, FooterType, FooterProperties } from './elements/Footer.js';\nexport { Hyperlink, HyperlinkProperties } from './elements/Hyperlink.js';\nexport { Bookmark, BookmarkProperties } from './elements/Bookmark.js';\nexport { RangeMarker, RangeMarkerType, RangeMarkerProperties } from './elements/RangeMarker.js';\nexport { Comment, CommentProperties } from './elements/Comment.js';\nexport { Footnote, FootnoteType, FootnoteProperties } from './elements/Footnote.js';\nexport { Endnote, EndnoteType, EndnoteProperties } from './elements/Endnote.js';\nexport {\n Field,\n FieldType,\n FieldProperties,\n ComplexField,\n ComplexFieldProperties,\n FieldCharType,\n TOCFieldOptions,\n createTOCField,\n} from './elements/Field.js';\nexport {\n createNestedIFMergeField,\n createMergeField,\n createRefField,\n createIFField,\n createNestedField,\n parseHyperlinkInstruction,\n buildHyperlinkInstruction,\n isHyperlinkInstruction,\n ParsedHyperlinkInstruction,\n} from './elements/FieldHelpers.js';\nexport {\n StructuredDocumentTag,\n SDTProperties,\n SDTLockType,\n SDTContent,\n SDTPlaceholder,\n SDTDataBinding,\n ContentControlType,\n} from './elements/StructuredDocumentTag.js';\nexport { TableOfContents, TOCProperties } from './elements/TableOfContents.js';\nexport { TableOfContentsElement } from './elements/TableOfContentsElement.js';\nexport { AlternateContent } from './elements/AlternateContent.js';\nexport { MathParagraph, MathExpression } from './elements/MathElement.js';\nexport { CustomXmlBlock } from './elements/CustomXml.js';\nexport { PreservedElement, PreservedElementContext } from './elements/PreservedElement.js';\n\n// =============================================================================\n// PUBLIC API — Track Changes / Revisions\n// =============================================================================\n\nexport { Revision, RevisionType, RevisionProperties, FieldContext } from './elements/Revision.js';\nexport { RevisionContent, isRunContent, isHyperlinkContent } from './elements/RevisionContent.js';\nexport {\n RevisionLocation,\n RunPropertyChange,\n ParagraphPropertyChange,\n ParagraphFormattingPartial,\n ParagraphBorderDef,\n ParagraphBorders,\n ParagraphShading,\n TabStopDef,\n PropertyChangeBase,\n TablePropertyChange,\n TablePropertyChangeType,\n SectionPropertyChange,\n NumberingChange,\n AnyPropertyChange,\n isRunPropertyChange,\n isParagraphPropertyChange,\n isTablePropertyChange,\n isSectionPropertyChange,\n isNumberingChange,\n} from './elements/PropertyChangeTypes.js';\nexport {\n acceptRevisionsInMemory,\n AcceptRevisionsOptions,\n AcceptRevisionsResult,\n paragraphHasRevisions,\n getRevisionsFromParagraph,\n countRevisionsByType,\n stripRevisionsFromXml,\n} from './processors/InMemoryRevisionAcceptor.js';\nexport {\n MoveOperationHelper,\n MoveOperationOptions,\n MoveOperationResult,\n} from './processors/MoveOperationHelper.js';\nexport {\n SelectiveRevisionAcceptor,\n SelectiveAcceptResult,\n} from './processors/SelectiveRevisionAcceptor.js';\nexport {\n RevisionAwareProcessor,\n RevisionHandlingMode,\n RevisionProcessingOptions,\n SelectionCriteria,\n RevisionProcessingResult,\n ConflictInfo,\n ProcessingLogEntry,\n} from './processors/RevisionAwareProcessor.js';\nexport {\n ChangelogGenerator,\n ChangeEntry,\n ChangeCategory,\n ChangeLocation,\n ChangelogOptions,\n ChangelogFormat,\n ConsolidatedChange,\n ChangelogSummary,\n} from './processors/ChangelogGenerator.js';\n\n// =============================================================================\n// PUBLIC API — Formatting / Styles / Numbering\n// =============================================================================\n\nexport { Style, StyleType, StyleProperties } from './formatting/Style.js';\nexport {\n StylesManager,\n ValidationResult,\n LatentStylesConfig,\n LatentStyleException,\n} from './formatting/StylesManager.js';\nexport {\n NumberingLevel,\n NumberFormat,\n NumberAlignment,\n NumberingLevelProperties,\n WORD_NATIVE_BULLETS,\n WordNativeBullet,\n} from './formatting/NumberingLevel.js';\nexport { AbstractNumbering, AbstractNumberingProperties } from './formatting/AbstractNumbering.js';\nexport { NumberingInstance, NumberingInstanceProperties } from './formatting/NumberingInstance.js';\nexport {\n NumberingManager,\n NumberingConsolidationOptions,\n NumberingConsolidationResult,\n} from './formatting/NumberingManager.js';\nexport {\n StyleRunFormatting,\n StyleParagraphFormatting,\n Heading2TableOptions,\n StyleConfig,\n Heading2Config,\n ApplyCustomFormattingOptions,\n} from './types/styleConfig.js';\nexport { FormatOptions, StyleApplyOptions, EmphasisType, ListPrefix } from './types/formatting.js';\n\n// =============================================================================\n// PUBLIC API — Managers\n// =============================================================================\n\nexport { RevisionManager, RevisionCategory, RevisionSummary } from './elements/RevisionManager.js';\nexport { ImageManager } from './elements/ImageManager.js';\nexport { BookmarkManager } from './elements/BookmarkManager.js';\nexport { CommentManager } from './elements/CommentManager.js';\nexport { FootnoteManager } from './elements/FootnoteManager.js';\nexport { EndnoteManager } from './elements/EndnoteManager.js';\nexport { HeaderFooterManager } from './elements/HeaderFooterManager.js';\nexport { FontManager, FontFormat, FontEntry } from './elements/FontManager.js';\nexport {\n DrawingManager,\n DrawingElement,\n DrawingType,\n PreservedDrawing,\n} from './managers/DrawingManager.js';\n\n// =============================================================================\n// PUBLIC API — Image Optimization\n// =============================================================================\n\nexport type { ImageOptimizationResult } from './images/ImageOptimizer.js';\n\n// =============================================================================\n// TYPES — Common / Shared Type Definitions\n// =============================================================================\n\nexport {\n ShadingPattern,\n BasicShadingPattern,\n BorderStyle,\n ExtendedBorderStyle,\n FullBorderStyle,\n BorderDefinition,\n FourSidedBorders,\n TableBorderDefinitions,\n HorizontalAlignment,\n VerticalAlignment,\n PageVerticalAlignment,\n CellVerticalAlignment,\n ParagraphAlignment as CommonParagraphAlignment,\n TableAlignment as CommonTableAlignment,\n RowJustification,\n TextVerticalAlignment,\n TabAlignment,\n PositionAnchor,\n HorizontalAnchor,\n VerticalAnchor,\n TextDirection,\n SectionTextDirection,\n WidthType,\n ShadingConfig,\n buildShadingAttributes,\n TabLeader,\n TabStop,\n isShadingPattern,\n isBorderStyle,\n isHorizontalAlignment,\n isVerticalAlignment,\n isParagraphAlignment,\n isWidthType,\n DEFAULT_BORDER,\n NO_BORDER,\n} from './elements/CommonTypes.js';\nexport {\n ListCategory,\n NumberFormat as ListNumberFormat,\n BulletFormat,\n ListDetectionResult,\n ListAnalysis,\n ListNormalizationOptions,\n ListNormalizationReport,\n IndentationLevel,\n} from './types/list-types.js';\n\nexport {\n CompatibilityMode,\n CompatibilityInfo,\n CompatSetting,\n} from './types/compatibility-types.js';\n\nexport {\n DocumentProtection,\n RevisionViewSettings,\n TrackChangesSettings,\n WebSettingsInfo,\n} from './types/settings-types.js';\n\n// =============================================================================\n// TYPES — Compatibility Upgrade\n// =============================================================================\n\nexport { CompatibilityUpgrader, UpgradeReport } from './processors/CompatibilityUpgrader.js';\nexport {\n LEGACY_COMPAT_ELEMENTS,\n LEGACY_COMPAT_ELEMENT_NAMES,\n MODERN_COMPAT_SETTINGS,\n MS_WORD_COMPAT_URI,\n} from './constants/legacyCompatFlags.js';\n\n// =============================================================================\n// UTILITIES — Unit Conversions\n// =============================================================================\n\nexport {\n STANDARD_DPI,\n UNITS,\n PAGE_SIZES,\n COMMON_MARGINS,\n twipsToPoints,\n twipsToInches,\n twipsToCm,\n twipsToEmus,\n emusToTwips,\n emusToInches,\n emusToCm,\n emusToPoints,\n emusToPixels,\n pointsToTwips,\n pointsToEmus,\n pointsToInches,\n pointsToCm,\n pointsToHalfPoints,\n halfPointsToPoints,\n inchesToTwips,\n inchesToEmus,\n inchesToPoints,\n inchesToCm,\n inchesToPixels,\n cmToTwips,\n cmToEmus,\n cmToInches,\n cmToPoints,\n cmToPixels,\n pixelsToEmus,\n pixelsToInches,\n pixelsToTwips,\n pixelsToCm,\n pixelsToPoints,\n} from './utils/units.js';\n\n// =============================================================================\n// UTILITIES — Validation, Corruption Detection, Error Handling\n// =============================================================================\n\nexport {\n validateDocxStructure,\n isBinaryFile,\n normalizePath,\n isValidZipBuffer,\n isTextContent,\n validateTwips,\n validateColor,\n validateHexColor,\n normalizeColor,\n validateNumberingId,\n validateLevel,\n validateAlignment,\n validateFontSize,\n validateNonEmptyString,\n validatePercentage,\n validateEmus,\n detectXmlInText,\n cleanXmlFromText,\n validateRunText,\n sanitizeHyperlinkUrl,\n SanitizeHyperlinkUrlResult,\n TextValidationResult,\n} from './utils/validation.js';\nexport {\n detectCorruptionInDocument,\n detectCorruptionInText,\n suggestFix,\n looksCorrupted,\n CorruptionReport,\n CorruptionLocation,\n CorruptionType,\n} from './utils/corruptionDetection.js';\nexport { isError, toError, wrapError, getErrorMessage } from './utils/errorHandling.js';\n// Deliberately on the stable path: ResourceLimitError is the security-relevant,\n// catchable error thrown by Document.load/loadFromBuffer for oversized/zip-bomb\n// untrusted input, and SizeLimitOptions is its tuning type. The rest of the\n// DocxError hierarchy stays on the `docxmlater/internal` subpath.\nexport { ResourceLimitError } from './zip/errors.js';\nexport type { SizeLimitOptions } from './zip/types.js';\nexport {\n REVISION_RULES,\n ValidationSeverity,\n ValidationIssue,\n ValidationRule,\n ValidationOptions,\n AutoFixOptions,\n ValidationResult as RevisionValidationResult,\n FixAction,\n AutoFixResult,\n createIssueFromRule,\n getRuleByCode,\n getRulesBySeverity,\n getAutoFixableRules,\n RevisionValidator,\n RevisionAutoFixer,\n} from './validation/index.js';\n\n// =============================================================================\n// UTILITIES — Formatting, Parsing, Sanitization\n// =============================================================================\n\nexport {\n mergeFormatting,\n cloneFormatting,\n hasFormatting,\n cleanFormatting,\n isEqualFormatting,\n applyDefaults,\n} from './utils/formatting.js';\nexport {\n safeParseInt,\n parseOoxmlBoolean,\n isExplicitlySet,\n parseNumericAttribute,\n parseOnOffAttribute,\n} from './utils/parsingHelpers.js';\nexport {\n removeInvalidXmlChars,\n findInvalidXmlChars,\n hasInvalidXmlChars,\n XML_CONTROL_CHARS,\n} from './utils/xmlSanitization.js';\n\n// =============================================================================\n// UTILITIES — List Detection (kept for basic detection; normalization moved to consumer)\n// =============================================================================\n\nexport {\n detectTypedPrefix,\n detectListType,\n inferLevelFromIndentation,\n getParagraphIndentation,\n validateListSequence,\n getListCategoryFromFormat,\n getLevelFromFormat,\n TYPED_LIST_PATTERNS,\n PATTERN_TO_CATEGORY,\n FORMAT_TO_LEVEL,\n} from './utils/list-detection.js';\n\n// =============================================================================\n// UTILITIES — Logging\n// =============================================================================\n\nexport {\n ILogger,\n LogLevel,\n LogEntry,\n ConsoleLogger,\n SilentLogger,\n CollectingLogger,\n defaultLogger,\n createScopedLogger,\n createComponentLogger,\n getGlobalLogger,\n setGlobalLogger,\n resetGlobalLogger,\n} from './utils/logger.js';\n\n// =============================================================================\n// UTILITIES — Revision Walker\n// =============================================================================\n\nexport { RevisionWalker, RevisionWalkerOptions } from './processors/RevisionWalker.js';\nexport { resolveCellShading } from './processors/ShadingResolver.js';\nexport {\n decodeCnfStyle,\n getActiveConditionalsInPriorityOrder,\n} from './processors/cnfStyleDecoder.js';\n\n// =============================================================================\n// UTILITIES — Cleanup\n// =============================================================================\n\nexport { CleanupHelper, CleanupOptions, CleanupReport } from './helpers/CleanupHelper.js';\n\n// =============================================================================\n// PUBLIC — Type unions consumers see when iterating doc.getBodyElements()\n// =============================================================================\n\nexport type { BodyElement } from './core/DocumentContent.js';\nexport {\n RelationshipType,\n type Relationship,\n type RelationshipProperties,\n} from './core/Relationship.js';\n\n// =============================================================================\n// EXTENSIBILITY — Plugin Registries and Document Events\n// =============================================================================\n\nexport {\n ElementRegistry,\n type ElementHandler,\n type ElementParseContext,\n type ElementSerializeContext,\n} from './core/ElementRegistry.js';\nexport { RegisteredBodyElement } from './elements/RegisteredBodyElement.js';\nexport {\n ValidationRuleRegistry,\n type CustomValidationRule,\n type CustomValidationIssue,\n type CustomValidationSeverity,\n} from './validation/ValidationRuleRegistry.js';\nexport type {\n DocumentEventMap,\n DocumentEventType,\n DocumentEventListener,\n} from './core/DocumentEvents.js';\n\n// Low-level building blocks — XMLBuilder, XMLParser, ZipHandler,\n// ZipReader, ZipWriter, DocumentParser, DocumentGenerator,\n// DocumentValidator, DocumentIdManager, DocumentContent,\n// RelationshipManager, DocumentEventEmitter, plus zip/xml types and\n// DocxError hierarchy — moved to the `docxmlater/internal` subpath in\n// 11.0.0. Migrate via:\n// import { XMLParser, ZipHandler } from 'docxmlater/internal';\n// The internal subpath has relaxed semver — pin an exact version.\n"]}
@@ -2,7 +2,7 @@ export { ZipHandler } from './zip/ZipHandler.js';
2
2
  export { ZipReader } from './zip/ZipReader.js';
3
3
  export { ZipWriter } from './zip/ZipWriter.js';
4
4
  export { DEFAULT_SIZE_LIMITS, REQUIRED_DOCX_FILES, DOCX_PATHS, } from './zip/types.js';
5
- export { DocxError, DocxNotFoundError, InvalidDocxError, CorruptedArchiveError, MissingRequiredFileError, FileOperationError, } from './zip/errors.js';
5
+ export { DocxError, DocxNotFoundError, InvalidDocxError, CorruptedArchiveError, MissingRequiredFileError, FileOperationError, ResourceLimitError, } from './zip/errors.js';
6
6
  export { XMLBuilder } from './xml/XMLBuilder.js';
7
7
  export { XMLParser, DEFAULT_MAX_NESTING_DEPTH, } from './xml/XMLParser.js';
8
8
  export { RelationshipManager } from './core/RelationshipManager.js';
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","sourceRoot":"","sources":["../../src/internal.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAOL,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,UAAU,EAAmB,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,SAAS,EAIT,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAc,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAA0B,MAAM,6BAA6B,CAAC;AACxF,OAAO,EACL,iBAAiB,GAGlB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAK5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["/**\n * docxmlater INTERNAL API\n *\n * Subpath export consumed via `import { ... } from 'docxmlater/internal'`.\n * Surfaces low-level building blocks for advanced consumers writing\n * tooling that needs raw XML / ZIP / parser access:\n * - ZipHandler, ZipReader, ZipWriter (+ types and DocxError hierarchy)\n * - XMLBuilder, XMLParser (+ ParseToObjectOptions etc.)\n * - DocumentParser, DocumentGenerator, DocumentValidator\n * - DocumentIdManager, DocumentContent, RelationshipManager\n * - DocumentEventEmitter (the emitter class itself)\n * - LIMITS constants\n *\n * **Stability:** these exports follow a relaxed semver — minor version\n * bumps may change signatures. Pin an exact docxmlater version when\n * consuming the internal subpath. The main API (`from 'docxmlater'`)\n * follows full semver.\n *\n * Symbols moved out of the main API in 11.0.0 — see CHANGELOG.\n *\n * The plugin registries (`ElementRegistry`, `ValidationRuleRegistry`)\n * and event types (`DocumentEventMap`, `DocumentEventListener`,\n * `DocumentEventType`) are NOT re-exported here — they belong in the\n * main API as stable extension points.\n */\n\n// ZIP layer\nexport { ZipHandler } from './zip/ZipHandler.js';\nexport { ZipReader } from './zip/ZipReader.js';\nexport { ZipWriter } from './zip/ZipWriter.js';\nexport {\n type ZipFile,\n type FileMap,\n type LoadOptions,\n type SaveOptions,\n type AddFileOptions,\n type SizeLimitOptions,\n DEFAULT_SIZE_LIMITS,\n REQUIRED_DOCX_FILES,\n DOCX_PATHS,\n} from './zip/types.js';\nexport {\n DocxError,\n DocxNotFoundError,\n InvalidDocxError,\n CorruptedArchiveError,\n MissingRequiredFileError,\n FileOperationError,\n} from './zip/errors.js';\n\n// XML layer\nexport { XMLBuilder, type XMLElement } from './xml/XMLBuilder.js';\nexport {\n XMLParser,\n type ParseToObjectOptions,\n type ParsedXMLValue,\n type ParsedXMLObject,\n DEFAULT_MAX_NESTING_DEPTH,\n} from './xml/XMLParser.js';\n\n// Core orchestration\nexport { RelationshipManager } from './core/RelationshipManager.js';\nexport { DocumentParser, ParseError } from './core/DocumentParser.js';\nexport { DocumentGenerator, type IZipHandlerReader } from './core/DocumentGenerator.js';\nexport {\n DocumentValidator,\n type SizeEstimate,\n type MemoryOptions,\n} from './core/DocumentValidator.js';\nexport { DocumentIdManager } from './core/DocumentIdManager.js';\nexport { DocumentContent } from './core/DocumentContent.js';\n\n// Document events — the emitter class is internal; the type aliases\n// (DocumentEventMap, DocumentEventListener, DocumentEventType) live in\n// the main API.\nexport { DocumentEventEmitter } from './core/DocumentEvents.js';\n\n// Constants\nexport { LIMITS } from './constants/limits.js';\n"]}
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../../src/internal.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAOL,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,UAAU,EAAmB,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,SAAS,EAIT,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAc,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAA0B,MAAM,6BAA6B,CAAC;AACxF,OAAO,EACL,iBAAiB,GAGlB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAK5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["/**\n * docxmlater INTERNAL API\n *\n * Subpath export consumed via `import { ... } from 'docxmlater/internal'`.\n * Surfaces low-level building blocks for advanced consumers writing\n * tooling that needs raw XML / ZIP / parser access:\n * - ZipHandler, ZipReader, ZipWriter (+ types and DocxError hierarchy)\n * - XMLBuilder, XMLParser (+ ParseToObjectOptions etc.)\n * - DocumentParser, DocumentGenerator, DocumentValidator\n * - DocumentIdManager, DocumentContent, RelationshipManager\n * - DocumentEventEmitter (the emitter class itself)\n * - LIMITS constants\n *\n * **Stability:** these exports follow a relaxed semver — minor version\n * bumps may change signatures. Pin an exact docxmlater version when\n * consuming the internal subpath. The main API (`from 'docxmlater'`)\n * follows full semver.\n *\n * Symbols moved out of the main API in 11.0.0 — see CHANGELOG.\n *\n * The plugin registries (`ElementRegistry`, `ValidationRuleRegistry`)\n * and event types (`DocumentEventMap`, `DocumentEventListener`,\n * `DocumentEventType`) are NOT re-exported here — they belong in the\n * main API as stable extension points.\n */\n\n// ZIP layer\nexport { ZipHandler } from './zip/ZipHandler.js';\nexport { ZipReader } from './zip/ZipReader.js';\nexport { ZipWriter } from './zip/ZipWriter.js';\nexport {\n type ZipFile,\n type FileMap,\n type LoadOptions,\n type SaveOptions,\n type AddFileOptions,\n type SizeLimitOptions,\n DEFAULT_SIZE_LIMITS,\n REQUIRED_DOCX_FILES,\n DOCX_PATHS,\n} from './zip/types.js';\nexport {\n DocxError,\n DocxNotFoundError,\n InvalidDocxError,\n CorruptedArchiveError,\n MissingRequiredFileError,\n FileOperationError,\n ResourceLimitError,\n} from './zip/errors.js';\n\n// XML layer\nexport { XMLBuilder, type XMLElement } from './xml/XMLBuilder.js';\nexport {\n XMLParser,\n type ParseToObjectOptions,\n type ParsedXMLValue,\n type ParsedXMLObject,\n DEFAULT_MAX_NESTING_DEPTH,\n} from './xml/XMLParser.js';\n\n// Core orchestration\nexport { RelationshipManager } from './core/RelationshipManager.js';\nexport { DocumentParser, ParseError } from './core/DocumentParser.js';\nexport { DocumentGenerator, type IZipHandlerReader } from './core/DocumentGenerator.js';\nexport {\n DocumentValidator,\n type SizeEstimate,\n type MemoryOptions,\n} from './core/DocumentValidator.js';\nexport { DocumentIdManager } from './core/DocumentIdManager.js';\nexport { DocumentContent } from './core/DocumentContent.js';\n\n// Document events — the emitter class is internal; the type aliases\n// (DocumentEventMap, DocumentEventListener, DocumentEventType) live in\n// the main API.\nexport { DocumentEventEmitter } from './core/DocumentEvents.js';\n\n// Constants\nexport { LIMITS } from './constants/limits.js';\n"]}
@@ -7,7 +7,13 @@ export class CompatibilityUpgrader {
7
7
  const selfClosingCompat = /<w:compat\s*\/>/.exec(settingsXml);
8
8
  if (!compatBlockMatch && !selfClosingCompat) {
9
9
  const modernBlock = CompatibilityUpgrader.buildModernCompatBlock(MODERN_COMPAT_SETTINGS);
10
- const xml = settingsXml.replace(/<\/w:settings>/, modernBlock + '\n</w:settings>');
10
+ const followingSibling = /<(?:w:rsids|m:mathPr|w:themeFontLang|w:clrSchemeMapping|w:shapeDefaults|w:decimalSymbol|w:listSeparator)[\s/>]/.exec(settingsXml);
11
+ const xml = followingSibling
12
+ ? settingsXml.slice(0, followingSibling.index) +
13
+ modernBlock +
14
+ '\n ' +
15
+ settingsXml.slice(followingSibling.index)
16
+ : settingsXml.replace(/<\/w:settings>/, modernBlock + '\n</w:settings>');
11
17
  for (const s of MODERN_COMPAT_SETTINGS) {
12
18
  addedSettings.push(s.name);
13
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CompatibilityUpgrader.js","sourceRoot":"","sources":["../../../src/processors/CompatibilityUpgrader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CompatibilityUpgrader — Upgrades w:compat block in settings.xml to modern format.\n *\n * Equivalent to Word's File > Info > Convert operation for the compatibility\n * settings portion. Removes legacy boolean compat flags, updates compatSetting\n * entries, and manages modern namespaces.\n *\n * @module\n */\n\nimport {\n LEGACY_COMPAT_ELEMENT_NAMES,\n MODERN_COMPAT_SETTINGS,\n MS_WORD_COMPAT_URI,\n} from '../constants/legacyCompatFlags.js';\nimport type { CompatSetting } from '../types/compatibility-types.js';\n\n/**\n * Report of what changed during an upgrade operation.\n */\nexport interface UpgradeReport {\n /** Previous compatibility mode value (11, 12, 14, or 15) */\n previousMode: number;\n\n /** New compatibility mode (always 15 after upgrade) */\n newMode: number;\n\n /** Legacy compat flags that were removed (without w: prefix) */\n removedFlags: string[];\n\n /** Modern settings that were added (setting names) */\n addedSettings: string[];\n\n /** Whether namespaces were expanded */\n namespacesExpanded: boolean;\n\n /** Whether any changes were actually made (false if already mode 15 with no legacy flags) */\n changed: boolean;\n}\n\n/**\n * Upgrades w:compat blocks in settings.xml to modern Word 2013+ format.\n */\nexport class CompatibilityUpgrader {\n /**\n * Upgrades the w:compat block in settings.xml to mode 15.\n *\n * Operations performed:\n * 1. Remove all legacy boolean compat elements\n * 2. Remove existing Microsoft-URI w:compatSetting entries\n * 3. Insert modern w:compatSetting entries\n * 4. Preserve non-Microsoft w:compatSetting entries (custom URIs)\n *\n * @param settingsXml - The raw settings.xml content\n * @param previousMode - The current compatibility mode value (for the report)\n * @returns Object with upgraded XML and an UpgradeReport\n */\n static upgradeCompatBlock(\n settingsXml: string,\n previousMode = 12\n ): { xml: string; report: UpgradeReport } {\n const removedFlags: string[] = [];\n const addedSettings: string[] = [];\n\n // Check if already mode 15 with no legacy flags\n const compatBlockMatch = /<w:compat>([\\s\\S]*?)<\\/w:compat>/.exec(settingsXml);\n const selfClosingCompat = /<w:compat\\s*\\/>/.exec(settingsXml);\n\n if (!compatBlockMatch && !selfClosingCompat) {\n // No w:compat block — insert a full modern block before </w:settings>\n const modernBlock = CompatibilityUpgrader.buildModernCompatBlock(MODERN_COMPAT_SETTINGS);\n const xml = settingsXml.replace(/<\\/w:settings>/, modernBlock + '\\n</w:settings>');\n\n for (const s of MODERN_COMPAT_SETTINGS) {\n addedSettings.push(s.name);\n }\n\n return {\n xml,\n report: {\n previousMode,\n newMode: 15,\n removedFlags,\n addedSettings,\n namespacesExpanded: false,\n changed: true,\n },\n };\n }\n\n // Handle self-closing <w:compat/>\n if (selfClosingCompat) {\n const modernBlock = CompatibilityUpgrader.buildModernCompatBlock(MODERN_COMPAT_SETTINGS);\n const xml = settingsXml.replace(/<w:compat\\s*\\/>/, modernBlock);\n\n for (const s of MODERN_COMPAT_SETTINGS) {\n addedSettings.push(s.name);\n }\n\n return {\n xml,\n report: {\n previousMode,\n newMode: 15,\n removedFlags,\n addedSettings,\n namespacesExpanded: false,\n changed: true,\n },\n };\n }\n\n // Process existing w:compat block\n const compatBlock = compatBlockMatch![1] ?? '';\n\n // 1. Find and record legacy flags that will be removed\n const legacyFlagRegex = /<w:(\\w+)(?:\\s[^>]*)?\\/?>/g;\n let flagMatch;\n while ((flagMatch = legacyFlagRegex.exec(compatBlock)) !== null) {\n const tagName = flagMatch[1];\n if (tagName && tagName !== 'compatSetting' && LEGACY_COMPAT_ELEMENT_NAMES.has(tagName)) {\n removedFlags.push(tagName);\n }\n }\n\n // 2. Collect non-Microsoft compatSetting entries to preserve\n const preservedSettings: CompatSetting[] = [];\n const settingRegex = /<w:compatSetting\\s+([^>]*)\\/?\\s*>/g;\n let settingMatch;\n while ((settingMatch = settingRegex.exec(compatBlock)) !== null) {\n const attrs = settingMatch[1] ?? '';\n const nameMatch = /w:name\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n const uriMatch = /w:uri\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n const valMatch = /w:val\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n\n if (nameMatch?.[1] && uriMatch?.[1] && valMatch?.[1]) {\n // Preserve settings with non-Microsoft URIs\n if (uriMatch[1] !== MS_WORD_COMPAT_URI) {\n preservedSettings.push({\n name: nameMatch[1],\n uri: uriMatch[1],\n val: valMatch[1],\n });\n }\n }\n }\n\n // 3. Determine which modern settings are actually new\n const existingMsSettings = new Set<string>();\n const existingSettingRegex = /<w:compatSetting\\s+([^>]*)\\/?\\s*>/g;\n let existingMatch;\n while ((existingMatch = existingSettingRegex.exec(compatBlock)) !== null) {\n const attrs = existingMatch[1] ?? '';\n const nameMatch = /w:name\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n const uriMatch = /w:uri\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n if (nameMatch?.[1] && uriMatch?.[1] && uriMatch[1] === MS_WORD_COMPAT_URI) {\n existingMsSettings.add(nameMatch[1]);\n }\n }\n\n for (const s of MODERN_COMPAT_SETTINGS) {\n if (!existingMsSettings.has(s.name)) {\n addedSettings.push(s.name);\n }\n }\n // compatibilityMode value change counts as \"added\" if it existed but with different val\n if (existingMsSettings.has('compatibilityMode') && previousMode !== 15) {\n if (!addedSettings.includes('compatibilityMode')) {\n addedSettings.push('compatibilityMode');\n }\n }\n\n // 4. Build the new compat block\n const allSettings = [...MODERN_COMPAT_SETTINGS, ...preservedSettings];\n const modernBlock = CompatibilityUpgrader.buildModernCompatBlock(allSettings);\n\n // 5. Replace the old block\n const changed = removedFlags.length > 0 || addedSettings.length > 0 || previousMode !== 15;\n const xml = settingsXml.replace(/<w:compat>[\\s\\S]*?<\\/w:compat>/, modernBlock);\n\n return {\n xml,\n report: {\n previousMode,\n newMode: 15,\n removedFlags,\n addedSettings,\n namespacesExpanded: false,\n changed,\n },\n };\n }\n\n /**\n * Ensures namespace declarations include all modern extended namespaces\n * (w14, w15, w16se, w16cid, etc.) and returns the expanded set.\n *\n * @param namespaces - Current namespace record from document\n * @returns Updated namespace record with modern namespaces added\n */\n static ensureModernNamespaces(namespaces: Record<string, string>): {\n namespaces: Record<string, string>;\n expanded: boolean;\n } {\n const result = { ...namespaces };\n let expanded = false;\n\n const modernNamespaces: Record<string, string> = {\n 'xmlns:w14': 'http://schemas.microsoft.com/office/word/2010/wordml',\n 'xmlns:w15': 'http://schemas.microsoft.com/office/word/2012/wordml',\n 'xmlns:w16se': 'http://schemas.microsoft.com/office/word/2015/wordml/symex',\n 'xmlns:w16cid': 'http://schemas.microsoft.com/office/word/2016/wordml/cid',\n };\n\n for (const [key, value] of Object.entries(modernNamespaces)) {\n if (!result[key]) {\n result[key] = value;\n expanded = true;\n }\n }\n\n return { namespaces: result, expanded };\n }\n\n /**\n * Builds a <w:compat> block XML string from an array of compat settings.\n * Does not include legacy boolean flags (they are stripped during upgrade).\n */\n private static buildModernCompatBlock(settings: CompatSetting[]): string {\n const entries = settings.map(\n (s) => ` <w:compatSetting w:name=\"${s.name}\" w:uri=\"${s.uri}\" w:val=\"${s.val}\"/>`\n );\n return `<w:compat>\\n${entries.join('\\n')}\\n </w:compat>`;\n }\n}\n"]}
1
+ {"version":3,"file":"CompatibilityUpgrader.js","sourceRoot":"","sources":["../../../src/processors/CompatibilityUpgrader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CompatibilityUpgrader — Upgrades w:compat block in settings.xml to modern format.\n *\n * Equivalent to Word's File > Info > Convert operation for the compatibility\n * settings portion. Removes legacy boolean compat flags, updates compatSetting\n * entries, and manages modern namespaces.\n *\n * @module\n */\n\nimport {\n LEGACY_COMPAT_ELEMENT_NAMES,\n MODERN_COMPAT_SETTINGS,\n MS_WORD_COMPAT_URI,\n} from '../constants/legacyCompatFlags.js';\nimport type { CompatSetting } from '../types/compatibility-types.js';\n\n/**\n * Report of what changed during an upgrade operation.\n */\nexport interface UpgradeReport {\n /** Previous compatibility mode value (11, 12, 14, or 15) */\n previousMode: number;\n\n /** New compatibility mode (always 15 after upgrade) */\n newMode: number;\n\n /** Legacy compat flags that were removed (without w: prefix) */\n removedFlags: string[];\n\n /** Modern settings that were added (setting names) */\n addedSettings: string[];\n\n /** Whether namespaces were expanded */\n namespacesExpanded: boolean;\n\n /** Whether any changes were actually made (false if already mode 15 with no legacy flags) */\n changed: boolean;\n}\n\n/**\n * Upgrades w:compat blocks in settings.xml to modern Word 2013+ format.\n */\nexport class CompatibilityUpgrader {\n /**\n * Upgrades the w:compat block in settings.xml to mode 15.\n *\n * Operations performed:\n * 1. Remove all legacy boolean compat elements\n * 2. Remove existing Microsoft-URI w:compatSetting entries\n * 3. Insert modern w:compatSetting entries\n * 4. Preserve non-Microsoft w:compatSetting entries (custom URIs)\n *\n * @param settingsXml - The raw settings.xml content\n * @param previousMode - The current compatibility mode value (for the report)\n * @returns Object with upgraded XML and an UpgradeReport\n */\n static upgradeCompatBlock(\n settingsXml: string,\n previousMode = 12\n ): { xml: string; report: UpgradeReport } {\n const removedFlags: string[] = [];\n const addedSettings: string[] = [];\n\n // Check if already mode 15 with no legacy flags\n const compatBlockMatch = /<w:compat>([\\s\\S]*?)<\\/w:compat>/.exec(settingsXml);\n const selfClosingCompat = /<w:compat\\s*\\/>/.exec(settingsXml);\n\n if (!compatBlockMatch && !selfClosingCompat) {\n // No w:compat block — insert a full modern block. CT_Settings is an\n // xsd:sequence where w:compat must precede rsids, mathPr, themeFontLang,\n // clrSchemeMapping, shapeDefaults, decimalSymbol, and listSeparator, so\n // anchor before the earliest of those; append before </w:settings> only\n // when none are present.\n const modernBlock = CompatibilityUpgrader.buildModernCompatBlock(MODERN_COMPAT_SETTINGS);\n const followingSibling =\n /<(?:w:rsids|m:mathPr|w:themeFontLang|w:clrSchemeMapping|w:shapeDefaults|w:decimalSymbol|w:listSeparator)[\\s/>]/.exec(\n settingsXml\n );\n const xml = followingSibling\n ? settingsXml.slice(0, followingSibling.index) +\n modernBlock +\n '\\n ' +\n settingsXml.slice(followingSibling.index)\n : settingsXml.replace(/<\\/w:settings>/, modernBlock + '\\n</w:settings>');\n\n for (const s of MODERN_COMPAT_SETTINGS) {\n addedSettings.push(s.name);\n }\n\n return {\n xml,\n report: {\n previousMode,\n newMode: 15,\n removedFlags,\n addedSettings,\n namespacesExpanded: false,\n changed: true,\n },\n };\n }\n\n // Handle self-closing <w:compat/>\n if (selfClosingCompat) {\n const modernBlock = CompatibilityUpgrader.buildModernCompatBlock(MODERN_COMPAT_SETTINGS);\n const xml = settingsXml.replace(/<w:compat\\s*\\/>/, modernBlock);\n\n for (const s of MODERN_COMPAT_SETTINGS) {\n addedSettings.push(s.name);\n }\n\n return {\n xml,\n report: {\n previousMode,\n newMode: 15,\n removedFlags,\n addedSettings,\n namespacesExpanded: false,\n changed: true,\n },\n };\n }\n\n // Process existing w:compat block\n const compatBlock = compatBlockMatch![1] ?? '';\n\n // 1. Find and record legacy flags that will be removed\n const legacyFlagRegex = /<w:(\\w+)(?:\\s[^>]*)?\\/?>/g;\n let flagMatch;\n while ((flagMatch = legacyFlagRegex.exec(compatBlock)) !== null) {\n const tagName = flagMatch[1];\n if (tagName && tagName !== 'compatSetting' && LEGACY_COMPAT_ELEMENT_NAMES.has(tagName)) {\n removedFlags.push(tagName);\n }\n }\n\n // 2. Collect non-Microsoft compatSetting entries to preserve\n const preservedSettings: CompatSetting[] = [];\n const settingRegex = /<w:compatSetting\\s+([^>]*)\\/?\\s*>/g;\n let settingMatch;\n while ((settingMatch = settingRegex.exec(compatBlock)) !== null) {\n const attrs = settingMatch[1] ?? '';\n const nameMatch = /w:name\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n const uriMatch = /w:uri\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n const valMatch = /w:val\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n\n if (nameMatch?.[1] && uriMatch?.[1] && valMatch?.[1]) {\n // Preserve settings with non-Microsoft URIs\n if (uriMatch[1] !== MS_WORD_COMPAT_URI) {\n preservedSettings.push({\n name: nameMatch[1],\n uri: uriMatch[1],\n val: valMatch[1],\n });\n }\n }\n }\n\n // 3. Determine which modern settings are actually new\n const existingMsSettings = new Set<string>();\n const existingSettingRegex = /<w:compatSetting\\s+([^>]*)\\/?\\s*>/g;\n let existingMatch;\n while ((existingMatch = existingSettingRegex.exec(compatBlock)) !== null) {\n const attrs = existingMatch[1] ?? '';\n const nameMatch = /w:name\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n const uriMatch = /w:uri\\s*=\\s*\"([^\"]*)\"/.exec(attrs);\n if (nameMatch?.[1] && uriMatch?.[1] && uriMatch[1] === MS_WORD_COMPAT_URI) {\n existingMsSettings.add(nameMatch[1]);\n }\n }\n\n for (const s of MODERN_COMPAT_SETTINGS) {\n if (!existingMsSettings.has(s.name)) {\n addedSettings.push(s.name);\n }\n }\n // compatibilityMode value change counts as \"added\" if it existed but with different val\n if (existingMsSettings.has('compatibilityMode') && previousMode !== 15) {\n if (!addedSettings.includes('compatibilityMode')) {\n addedSettings.push('compatibilityMode');\n }\n }\n\n // 4. Build the new compat block\n const allSettings = [...MODERN_COMPAT_SETTINGS, ...preservedSettings];\n const modernBlock = CompatibilityUpgrader.buildModernCompatBlock(allSettings);\n\n // 5. Replace the old block\n const changed = removedFlags.length > 0 || addedSettings.length > 0 || previousMode !== 15;\n const xml = settingsXml.replace(/<w:compat>[\\s\\S]*?<\\/w:compat>/, modernBlock);\n\n return {\n xml,\n report: {\n previousMode,\n newMode: 15,\n removedFlags,\n addedSettings,\n namespacesExpanded: false,\n changed,\n },\n };\n }\n\n /**\n * Ensures namespace declarations include all modern extended namespaces\n * (w14, w15, w16se, w16cid, etc.) and returns the expanded set.\n *\n * @param namespaces - Current namespace record from document\n * @returns Updated namespace record with modern namespaces added\n */\n static ensureModernNamespaces(namespaces: Record<string, string>): {\n namespaces: Record<string, string>;\n expanded: boolean;\n } {\n const result = { ...namespaces };\n let expanded = false;\n\n const modernNamespaces: Record<string, string> = {\n 'xmlns:w14': 'http://schemas.microsoft.com/office/word/2010/wordml',\n 'xmlns:w15': 'http://schemas.microsoft.com/office/word/2012/wordml',\n 'xmlns:w16se': 'http://schemas.microsoft.com/office/word/2015/wordml/symex',\n 'xmlns:w16cid': 'http://schemas.microsoft.com/office/word/2016/wordml/cid',\n };\n\n for (const [key, value] of Object.entries(modernNamespaces)) {\n if (!result[key]) {\n result[key] = value;\n expanded = true;\n }\n }\n\n return { namespaces: result, expanded };\n }\n\n /**\n * Builds a <w:compat> block XML string from an array of compat settings.\n * Does not include legacy boolean flags (they are stripped during upgrade).\n */\n private static buildModernCompatBlock(settings: CompatSetting[]): string {\n const entries = settings.map(\n (s) => ` <w:compatSetting w:name=\"${s.name}\" w:uri=\"${s.uri}\" w:val=\"${s.val}\"/>`\n );\n return `<w:compat>\\n${entries.join('\\n')}\\n </w:compat>`;\n }\n}\n"]}