open-agreements 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. package/content/templates/closing-checklist/template.docx +0 -0
  2. package/dist/core/checklist/docx-import.d.ts +50 -0
  3. package/dist/core/checklist/docx-import.d.ts.map +1 -0
  4. package/dist/core/checklist/docx-import.js +613 -0
  5. package/dist/core/checklist/docx-import.js.map +1 -0
  6. package/dist/core/checklist/docx-table-helpers.d.ts +33 -0
  7. package/dist/core/checklist/docx-table-helpers.d.ts.map +1 -0
  8. package/dist/core/checklist/docx-table-helpers.js +154 -0
  9. package/dist/core/checklist/docx-table-helpers.js.map +1 -0
  10. package/dist/core/checklist/format-checklist-docx.d.ts.map +1 -1
  11. package/dist/core/checklist/format-checklist-docx.js +37 -88
  12. package/dist/core/checklist/format-checklist-docx.js.map +1 -1
  13. package/dist/core/checklist/index.d.ts +15 -12
  14. package/dist/core/checklist/index.d.ts.map +1 -1
  15. package/dist/core/checklist/index.js +48 -30
  16. package/dist/core/checklist/index.js.map +1 -1
  17. package/dist/core/checklist/status-labels.d.ts +6 -0
  18. package/dist/core/checklist/status-labels.d.ts.map +1 -1
  19. package/dist/core/checklist/status-labels.js +8 -0
  20. package/dist/core/checklist/status-labels.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/node_modules/@usejunior/docx-core/dist/atomizer.d.ts +218 -0
  26. package/node_modules/@usejunior/docx-core/dist/atomizer.d.ts.map +1 -0
  27. package/node_modules/@usejunior/docx-core/dist/atomizer.js +869 -0
  28. package/node_modules/@usejunior/docx-core/dist/atomizer.js.map +1 -0
  29. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/atomLcs.d.ts +96 -0
  30. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/atomLcs.d.ts.map +1 -0
  31. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/atomLcs.js +347 -0
  32. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/atomLcs.js.map +1 -0
  33. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/consumerCompatibility.d.ts +2 -0
  34. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/consumerCompatibility.d.ts.map +1 -0
  35. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/consumerCompatibility.js +188 -0
  36. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/consumerCompatibility.js.map +1 -0
  37. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/debug.d.ts +41 -0
  38. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/debug.d.ts.map +1 -0
  39. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/debug.js +85 -0
  40. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/debug.js.map +1 -0
  41. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/documentReconstructor.d.ts +64 -0
  42. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/documentReconstructor.d.ts.map +1 -0
  43. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/documentReconstructor.js +985 -0
  44. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/documentReconstructor.js.map +1 -0
  45. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/hierarchicalLcs.d.ts +111 -0
  46. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/hierarchicalLcs.d.ts.map +1 -0
  47. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/hierarchicalLcs.js +469 -0
  48. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/hierarchicalLcs.js.map +1 -0
  49. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/inPlaceModifier.d.ts +277 -0
  50. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/inPlaceModifier.d.ts.map +1 -0
  51. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/inPlaceModifier.js +2279 -0
  52. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/inPlaceModifier.js.map +1 -0
  53. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/numberingIntegration.d.ts +59 -0
  54. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/numberingIntegration.d.ts.map +1 -0
  55. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/numberingIntegration.js +209 -0
  56. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/numberingIntegration.js.map +1 -0
  57. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/pipeline.d.ts +69 -0
  58. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/pipeline.d.ts.map +1 -0
  59. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/pipeline.js +910 -0
  60. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/pipeline.js.map +1 -0
  61. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/premergeRuns.d.ts +26 -0
  62. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/premergeRuns.d.ts.map +1 -0
  63. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/premergeRuns.js +153 -0
  64. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/premergeRuns.js.map +1 -0
  65. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptor.d.ts +63 -0
  66. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptor.d.ts.map +1 -0
  67. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptor.js +254 -0
  68. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptor.js.map +1 -0
  69. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts +64 -0
  70. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts.map +1 -0
  71. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptorAst.js +616 -0
  72. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/trackChangesAcceptorAst.js.map +1 -0
  73. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/xmlToWmlElement.d.ts +65 -0
  74. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/xmlToWmlElement.d.ts.map +1 -0
  75. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/xmlToWmlElement.js +95 -0
  76. package/node_modules/@usejunior/docx-core/dist/baselines/atomizer/xmlToWmlElement.js.map +1 -0
  77. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DocxodusWasm.d.ts +51 -0
  78. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DocxodusWasm.d.ts.map +1 -0
  79. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DocxodusWasm.js +83 -0
  80. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DocxodusWasm.js.map +1 -0
  81. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DotnetCli.d.ts +40 -0
  82. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DotnetCli.d.ts.map +1 -0
  83. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DotnetCli.js +135 -0
  84. package/node_modules/@usejunior/docx-core/dist/baselines/wmlcomparer/DotnetCli.js.map +1 -0
  85. package/node_modules/@usejunior/docx-core/dist/cli/compare-two.d.ts +28 -0
  86. package/node_modules/@usejunior/docx-core/dist/cli/compare-two.d.ts.map +1 -0
  87. package/node_modules/@usejunior/docx-core/dist/cli/compare-two.js +110 -0
  88. package/node_modules/@usejunior/docx-core/dist/cli/compare-two.js.map +1 -0
  89. package/node_modules/@usejunior/docx-core/dist/cli/index.d.ts +3 -0
  90. package/node_modules/@usejunior/docx-core/dist/cli/index.d.ts.map +1 -0
  91. package/node_modules/@usejunior/docx-core/dist/cli/index.js +21 -0
  92. package/node_modules/@usejunior/docx-core/dist/cli/index.js.map +1 -0
  93. package/node_modules/@usejunior/docx-core/dist/core-types.d.ts +296 -0
  94. package/node_modules/@usejunior/docx-core/dist/core-types.d.ts.map +1 -0
  95. package/node_modules/@usejunior/docx-core/dist/core-types.js +122 -0
  96. package/node_modules/@usejunior/docx-core/dist/core-types.js.map +1 -0
  97. package/node_modules/@usejunior/docx-core/dist/footnotes.d.ts +144 -0
  98. package/node_modules/@usejunior/docx-core/dist/footnotes.d.ts.map +1 -0
  99. package/node_modules/@usejunior/docx-core/dist/footnotes.js +291 -0
  100. package/node_modules/@usejunior/docx-core/dist/footnotes.js.map +1 -0
  101. package/node_modules/@usejunior/docx-core/dist/format-detection.d.ts +120 -0
  102. package/node_modules/@usejunior/docx-core/dist/format-detection.d.ts.map +1 -0
  103. package/node_modules/@usejunior/docx-core/dist/format-detection.js +338 -0
  104. package/node_modules/@usejunior/docx-core/dist/format-detection.js.map +1 -0
  105. package/node_modules/@usejunior/docx-core/dist/index.d.ts +177 -0
  106. package/node_modules/@usejunior/docx-core/dist/index.d.ts.map +1 -0
  107. package/node_modules/@usejunior/docx-core/dist/index.js +55 -0
  108. package/node_modules/@usejunior/docx-core/dist/index.js.map +1 -0
  109. package/node_modules/@usejunior/docx-core/dist/integration/output-artifacts.d.ts +6 -0
  110. package/node_modules/@usejunior/docx-core/dist/integration/output-artifacts.d.ts.map +1 -0
  111. package/node_modules/@usejunior/docx-core/dist/integration/output-artifacts.js +30 -0
  112. package/node_modules/@usejunior/docx-core/dist/integration/output-artifacts.js.map +1 -0
  113. package/node_modules/@usejunior/docx-core/dist/move-detection.d.ts +211 -0
  114. package/node_modules/@usejunior/docx-core/dist/move-detection.d.ts.map +1 -0
  115. package/node_modules/@usejunior/docx-core/dist/move-detection.js +391 -0
  116. package/node_modules/@usejunior/docx-core/dist/move-detection.js.map +1 -0
  117. package/node_modules/@usejunior/docx-core/dist/numbering.d.ts +136 -0
  118. package/node_modules/@usejunior/docx-core/dist/numbering.d.ts.map +1 -0
  119. package/node_modules/@usejunior/docx-core/dist/numbering.js +446 -0
  120. package/node_modules/@usejunior/docx-core/dist/numbering.js.map +1 -0
  121. package/node_modules/@usejunior/docx-core/dist/primitives/accept_changes.d.ts +30 -0
  122. package/node_modules/@usejunior/docx-core/dist/primitives/accept_changes.d.ts.map +1 -0
  123. package/node_modules/@usejunior/docx-core/dist/primitives/accept_changes.js +241 -0
  124. package/node_modules/@usejunior/docx-core/dist/primitives/accept_changes.js.map +1 -0
  125. package/node_modules/@usejunior/docx-core/dist/primitives/bookmarks.d.ts +12 -0
  126. package/node_modules/@usejunior/docx-core/dist/primitives/bookmarks.d.ts.map +1 -0
  127. package/node_modules/@usejunior/docx-core/dist/primitives/bookmarks.js +248 -0
  128. package/node_modules/@usejunior/docx-core/dist/primitives/bookmarks.js.map +1 -0
  129. package/node_modules/@usejunior/docx-core/dist/primitives/comments.d.ts +88 -0
  130. package/node_modules/@usejunior/docx-core/dist/primitives/comments.d.ts.map +1 -0
  131. package/node_modules/@usejunior/docx-core/dist/primitives/comments.js +703 -0
  132. package/node_modules/@usejunior/docx-core/dist/primitives/comments.js.map +1 -0
  133. package/node_modules/@usejunior/docx-core/dist/primitives/document.d.ts +186 -0
  134. package/node_modules/@usejunior/docx-core/dist/primitives/document.d.ts.map +1 -0
  135. package/node_modules/@usejunior/docx-core/dist/primitives/document.js +555 -0
  136. package/node_modules/@usejunior/docx-core/dist/primitives/document.js.map +1 -0
  137. package/node_modules/@usejunior/docx-core/dist/primitives/document_view.d.ts +97 -0
  138. package/node_modules/@usejunior/docx-core/dist/primitives/document_view.d.ts.map +1 -0
  139. package/node_modules/@usejunior/docx-core/dist/primitives/document_view.js +749 -0
  140. package/node_modules/@usejunior/docx-core/dist/primitives/document_view.js.map +1 -0
  141. package/node_modules/@usejunior/docx-core/dist/primitives/dom-helpers.d.ts +94 -0
  142. package/node_modules/@usejunior/docx-core/dist/primitives/dom-helpers.d.ts.map +1 -0
  143. package/node_modules/@usejunior/docx-core/dist/primitives/dom-helpers.js +219 -0
  144. package/node_modules/@usejunior/docx-core/dist/primitives/dom-helpers.js.map +1 -0
  145. package/node_modules/@usejunior/docx-core/dist/primitives/errors.d.ts +7 -0
  146. package/node_modules/@usejunior/docx-core/dist/primitives/errors.d.ts.map +1 -0
  147. package/node_modules/@usejunior/docx-core/dist/primitives/errors.js +10 -0
  148. package/node_modules/@usejunior/docx-core/dist/primitives/errors.js.map +1 -0
  149. package/node_modules/@usejunior/docx-core/dist/primitives/extract_revisions.d.ts +50 -0
  150. package/node_modules/@usejunior/docx-core/dist/primitives/extract_revisions.d.ts.map +1 -0
  151. package/node_modules/@usejunior/docx-core/dist/primitives/extract_revisions.js +340 -0
  152. package/node_modules/@usejunior/docx-core/dist/primitives/extract_revisions.js.map +1 -0
  153. package/node_modules/@usejunior/docx-core/dist/primitives/footnotes.d.ts +37 -0
  154. package/node_modules/@usejunior/docx-core/dist/primitives/footnotes.d.ts.map +1 -0
  155. package/node_modules/@usejunior/docx-core/dist/primitives/footnotes.js +552 -0
  156. package/node_modules/@usejunior/docx-core/dist/primitives/footnotes.js.map +1 -0
  157. package/node_modules/@usejunior/docx-core/dist/primitives/formatting_tags.d.ts +43 -0
  158. package/node_modules/@usejunior/docx-core/dist/primitives/formatting_tags.d.ts.map +1 -0
  159. package/node_modules/@usejunior/docx-core/dist/primitives/formatting_tags.js +291 -0
  160. package/node_modules/@usejunior/docx-core/dist/primitives/formatting_tags.js.map +1 -0
  161. package/node_modules/@usejunior/docx-core/dist/primitives/index.d.ts +27 -0
  162. package/node_modules/@usejunior/docx-core/dist/primitives/index.d.ts.map +1 -0
  163. package/node_modules/@usejunior/docx-core/dist/primitives/index.js +27 -0
  164. package/node_modules/@usejunior/docx-core/dist/primitives/index.js.map +1 -0
  165. package/node_modules/@usejunior/docx-core/dist/primitives/layout.d.ts +53 -0
  166. package/node_modules/@usejunior/docx-core/dist/primitives/layout.d.ts.map +1 -0
  167. package/node_modules/@usejunior/docx-core/dist/primitives/layout.js +178 -0
  168. package/node_modules/@usejunior/docx-core/dist/primitives/layout.js.map +1 -0
  169. package/node_modules/@usejunior/docx-core/dist/primitives/list_labels.d.ts +19 -0
  170. package/node_modules/@usejunior/docx-core/dist/primitives/list_labels.d.ts.map +1 -0
  171. package/node_modules/@usejunior/docx-core/dist/primitives/list_labels.js +57 -0
  172. package/node_modules/@usejunior/docx-core/dist/primitives/list_labels.js.map +1 -0
  173. package/node_modules/@usejunior/docx-core/dist/primitives/matching.d.ts +31 -0
  174. package/node_modules/@usejunior/docx-core/dist/primitives/matching.d.ts.map +1 -0
  175. package/node_modules/@usejunior/docx-core/dist/primitives/matching.js +223 -0
  176. package/node_modules/@usejunior/docx-core/dist/primitives/matching.js.map +1 -0
  177. package/node_modules/@usejunior/docx-core/dist/primitives/merge_runs.d.ts +23 -0
  178. package/node_modules/@usejunior/docx-core/dist/primitives/merge_runs.d.ts.map +1 -0
  179. package/node_modules/@usejunior/docx-core/dist/primitives/merge_runs.js +243 -0
  180. package/node_modules/@usejunior/docx-core/dist/primitives/merge_runs.js.map +1 -0
  181. package/node_modules/@usejunior/docx-core/dist/primitives/namespaces.d.ts +91 -0
  182. package/node_modules/@usejunior/docx-core/dist/primitives/namespaces.d.ts.map +1 -0
  183. package/node_modules/@usejunior/docx-core/dist/primitives/namespaces.js +108 -0
  184. package/node_modules/@usejunior/docx-core/dist/primitives/namespaces.js.map +1 -0
  185. package/node_modules/@usejunior/docx-core/dist/primitives/numbering.d.ts +27 -0
  186. package/node_modules/@usejunior/docx-core/dist/primitives/numbering.d.ts.map +1 -0
  187. package/node_modules/@usejunior/docx-core/dist/primitives/numbering.js +182 -0
  188. package/node_modules/@usejunior/docx-core/dist/primitives/numbering.js.map +1 -0
  189. package/node_modules/@usejunior/docx-core/dist/primitives/prevent_double_elevation.d.ts +18 -0
  190. package/node_modules/@usejunior/docx-core/dist/primitives/prevent_double_elevation.d.ts.map +1 -0
  191. package/node_modules/@usejunior/docx-core/dist/primitives/prevent_double_elevation.js +190 -0
  192. package/node_modules/@usejunior/docx-core/dist/primitives/prevent_double_elevation.js.map +1 -0
  193. package/node_modules/@usejunior/docx-core/dist/primitives/reject_changes.d.ts +27 -0
  194. package/node_modules/@usejunior/docx-core/dist/primitives/reject_changes.d.ts.map +1 -0
  195. package/node_modules/@usejunior/docx-core/dist/primitives/reject_changes.js +371 -0
  196. package/node_modules/@usejunior/docx-core/dist/primitives/reject_changes.js.map +1 -0
  197. package/node_modules/@usejunior/docx-core/dist/primitives/relationships.d.ts +7 -0
  198. package/node_modules/@usejunior/docx-core/dist/primitives/relationships.d.ts.map +1 -0
  199. package/node_modules/@usejunior/docx-core/dist/primitives/relationships.js +24 -0
  200. package/node_modules/@usejunior/docx-core/dist/primitives/relationships.js.map +1 -0
  201. package/node_modules/@usejunior/docx-core/dist/primitives/semantic_tags.d.ts +17 -0
  202. package/node_modules/@usejunior/docx-core/dist/primitives/semantic_tags.d.ts.map +1 -0
  203. package/node_modules/@usejunior/docx-core/dist/primitives/semantic_tags.js +58 -0
  204. package/node_modules/@usejunior/docx-core/dist/primitives/semantic_tags.js.map +1 -0
  205. package/node_modules/@usejunior/docx-core/dist/primitives/simplify_redlines.d.ts +19 -0
  206. package/node_modules/@usejunior/docx-core/dist/primitives/simplify_redlines.d.ts.map +1 -0
  207. package/node_modules/@usejunior/docx-core/dist/primitives/simplify_redlines.js +94 -0
  208. package/node_modules/@usejunior/docx-core/dist/primitives/simplify_redlines.js.map +1 -0
  209. package/node_modules/@usejunior/docx-core/dist/primitives/styles.d.ts +36 -0
  210. package/node_modules/@usejunior/docx-core/dist/primitives/styles.d.ts.map +1 -0
  211. package/node_modules/@usejunior/docx-core/dist/primitives/styles.js +205 -0
  212. package/node_modules/@usejunior/docx-core/dist/primitives/styles.js.map +1 -0
  213. package/node_modules/@usejunior/docx-core/dist/primitives/tables.d.ts +54 -0
  214. package/node_modules/@usejunior/docx-core/dist/primitives/tables.d.ts.map +1 -0
  215. package/node_modules/@usejunior/docx-core/dist/primitives/tables.js +205 -0
  216. package/node_modules/@usejunior/docx-core/dist/primitives/tables.js.map +1 -0
  217. package/node_modules/@usejunior/docx-core/dist/primitives/text.d.ts +30 -0
  218. package/node_modules/@usejunior/docx-core/dist/primitives/text.d.ts.map +1 -0
  219. package/node_modules/@usejunior/docx-core/dist/primitives/text.js +461 -0
  220. package/node_modules/@usejunior/docx-core/dist/primitives/text.js.map +1 -0
  221. package/node_modules/@usejunior/docx-core/dist/primitives/validate_document.d.ts +24 -0
  222. package/node_modules/@usejunior/docx-core/dist/primitives/validate_document.d.ts.map +1 -0
  223. package/node_modules/@usejunior/docx-core/dist/primitives/validate_document.js +147 -0
  224. package/node_modules/@usejunior/docx-core/dist/primitives/validate_document.js.map +1 -0
  225. package/node_modules/@usejunior/docx-core/dist/primitives/xml.d.ts +5 -0
  226. package/node_modules/@usejunior/docx-core/dist/primitives/xml.d.ts.map +1 -0
  227. package/node_modules/@usejunior/docx-core/dist/primitives/xml.js +19 -0
  228. package/node_modules/@usejunior/docx-core/dist/primitives/xml.js.map +1 -0
  229. package/node_modules/@usejunior/docx-core/dist/primitives/zip.d.ts +25 -0
  230. package/node_modules/@usejunior/docx-core/dist/primitives/zip.d.ts.map +1 -0
  231. package/node_modules/@usejunior/docx-core/dist/primitives/zip.js +78 -0
  232. package/node_modules/@usejunior/docx-core/dist/primitives/zip.js.map +1 -0
  233. package/node_modules/@usejunior/docx-core/dist/shared/docx/DocxArchive.d.ts +94 -0
  234. package/node_modules/@usejunior/docx-core/dist/shared/docx/DocxArchive.d.ts.map +1 -0
  235. package/node_modules/@usejunior/docx-core/dist/shared/docx/DocxArchive.js +169 -0
  236. package/node_modules/@usejunior/docx-core/dist/shared/docx/DocxArchive.js.map +1 -0
  237. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/namespaces.d.ts +149 -0
  238. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/namespaces.d.ts.map +1 -0
  239. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/namespaces.js +224 -0
  240. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/namespaces.js.map +1 -0
  241. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/types.d.ts +136 -0
  242. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/types.d.ts.map +1 -0
  243. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/types.js +7 -0
  244. package/node_modules/@usejunior/docx-core/dist/shared/ooxml/types.js.map +1 -0
  245. package/node_modules/@usejunior/docx-core/dist/shared/validators/structural.d.ts +31 -0
  246. package/node_modules/@usejunior/docx-core/dist/shared/validators/structural.d.ts.map +1 -0
  247. package/node_modules/@usejunior/docx-core/dist/shared/validators/structural.js +110 -0
  248. package/node_modules/@usejunior/docx-core/dist/shared/validators/structural.js.map +1 -0
  249. package/node_modules/@usejunior/docx-core/package.json +26 -0
  250. package/node_modules/core-util-is/LICENSE +19 -0
  251. package/node_modules/core-util-is/README.md +3 -0
  252. package/node_modules/core-util-is/lib/util.js +107 -0
  253. package/node_modules/core-util-is/package.json +38 -0
  254. package/node_modules/diff-match-patch/LICENSE +202 -0
  255. package/node_modules/diff-match-patch/README.md +94 -0
  256. package/node_modules/diff-match-patch/index.js +2218 -0
  257. package/node_modules/diff-match-patch/package.json +22 -0
  258. package/node_modules/immediate/LICENSE.txt +20 -0
  259. package/node_modules/immediate/README.md +93 -0
  260. package/node_modules/immediate/dist/immediate.js +75 -0
  261. package/node_modules/immediate/dist/immediate.min.js +1 -0
  262. package/node_modules/immediate/lib/browser.js +69 -0
  263. package/node_modules/immediate/lib/index.js +73 -0
  264. package/node_modules/immediate/package.json +42 -0
  265. package/node_modules/inherits/LICENSE +16 -0
  266. package/node_modules/inherits/README.md +42 -0
  267. package/node_modules/inherits/inherits.js +9 -0
  268. package/node_modules/inherits/inherits_browser.js +27 -0
  269. package/node_modules/inherits/package.json +29 -0
  270. package/node_modules/isarray/.npmignore +1 -0
  271. package/node_modules/isarray/.travis.yml +4 -0
  272. package/node_modules/isarray/Makefile +6 -0
  273. package/node_modules/isarray/README.md +60 -0
  274. package/node_modules/isarray/component.json +19 -0
  275. package/node_modules/isarray/index.js +5 -0
  276. package/node_modules/isarray/package.json +45 -0
  277. package/node_modules/isarray/test.js +20 -0
  278. package/node_modules/jszip/.codeclimate.yml +16 -0
  279. package/node_modules/jszip/.editorconfig +8 -0
  280. package/node_modules/jszip/.eslintrc.js +43 -0
  281. package/node_modules/jszip/.github/workflows/pr.yaml +58 -0
  282. package/node_modules/jszip/.jekyll-metadata +0 -0
  283. package/node_modules/jszip/.travis.yml +17 -0
  284. package/node_modules/jszip/CHANGES.md +204 -0
  285. package/node_modules/jszip/LICENSE.markdown +651 -0
  286. package/node_modules/jszip/README.markdown +33 -0
  287. package/node_modules/jszip/deps.js +37 -0
  288. package/node_modules/jszip/dist/jszip.js +11577 -0
  289. package/node_modules/jszip/dist/jszip.min.js +13 -0
  290. package/node_modules/jszip/graph.svg +601 -0
  291. package/node_modules/jszip/index.d.ts +330 -0
  292. package/node_modules/jszip/lib/base64.js +106 -0
  293. package/node_modules/jszip/lib/compressedObject.js +74 -0
  294. package/node_modules/jszip/lib/compressions.js +14 -0
  295. package/node_modules/jszip/lib/crc32.js +77 -0
  296. package/node_modules/jszip/lib/defaults.js +11 -0
  297. package/node_modules/jszip/lib/external.js +18 -0
  298. package/node_modules/jszip/lib/flate.js +85 -0
  299. package/node_modules/jszip/lib/generate/ZipFileWorker.js +539 -0
  300. package/node_modules/jszip/lib/generate/index.js +57 -0
  301. package/node_modules/jszip/lib/index.js +55 -0
  302. package/node_modules/jszip/lib/license_header.js +11 -0
  303. package/node_modules/jszip/lib/load.js +88 -0
  304. package/node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js +74 -0
  305. package/node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js +42 -0
  306. package/node_modules/jszip/lib/nodejsUtils.js +57 -0
  307. package/node_modules/jszip/lib/object.js +384 -0
  308. package/node_modules/jszip/lib/readable-stream-browser.js +10 -0
  309. package/node_modules/jszip/lib/reader/ArrayReader.js +57 -0
  310. package/node_modules/jszip/lib/reader/DataReader.js +116 -0
  311. package/node_modules/jszip/lib/reader/NodeBufferReader.js +19 -0
  312. package/node_modules/jszip/lib/reader/StringReader.js +38 -0
  313. package/node_modules/jszip/lib/reader/Uint8ArrayReader.js +22 -0
  314. package/node_modules/jszip/lib/reader/readerFor.js +28 -0
  315. package/node_modules/jszip/lib/signature.js +7 -0
  316. package/node_modules/jszip/lib/stream/ConvertWorker.js +26 -0
  317. package/node_modules/jszip/lib/stream/Crc32Probe.js +24 -0
  318. package/node_modules/jszip/lib/stream/DataLengthProbe.js +29 -0
  319. package/node_modules/jszip/lib/stream/DataWorker.js +116 -0
  320. package/node_modules/jszip/lib/stream/GenericWorker.js +263 -0
  321. package/node_modules/jszip/lib/stream/StreamHelper.js +214 -0
  322. package/node_modules/jszip/lib/support.js +38 -0
  323. package/node_modules/jszip/lib/utf8.js +275 -0
  324. package/node_modules/jszip/lib/utils.js +501 -0
  325. package/node_modules/jszip/lib/zipEntries.js +261 -0
  326. package/node_modules/jszip/lib/zipEntry.js +293 -0
  327. package/node_modules/jszip/lib/zipObject.js +133 -0
  328. package/node_modules/jszip/package.json +67 -0
  329. package/node_modules/jszip/sponsors.md +21 -0
  330. package/node_modules/jszip/tsconfig.json +101 -0
  331. package/node_modules/jszip/vendor/FileSaver.js +247 -0
  332. package/node_modules/lie/README.md +62 -0
  333. package/node_modules/lie/dist/lie.js +350 -0
  334. package/node_modules/lie/dist/lie.min.js +1 -0
  335. package/node_modules/lie/dist/lie.polyfill.js +358 -0
  336. package/node_modules/lie/dist/lie.polyfill.min.js +1 -0
  337. package/node_modules/lie/lib/browser.js +273 -0
  338. package/node_modules/lie/lib/index.js +298 -0
  339. package/node_modules/lie/license.md +7 -0
  340. package/node_modules/lie/lie.d.ts +244 -0
  341. package/node_modules/lie/package.json +69 -0
  342. package/node_modules/lie/polyfill.js +4 -0
  343. package/node_modules/pako/LICENSE +21 -0
  344. package/node_modules/pako/README.md +191 -0
  345. package/node_modules/pako/dist/pako.js +6818 -0
  346. package/node_modules/pako/dist/pako.min.js +1 -0
  347. package/node_modules/pako/dist/pako_deflate.js +3997 -0
  348. package/node_modules/pako/dist/pako_deflate.min.js +1 -0
  349. package/node_modules/pako/dist/pako_inflate.js +3300 -0
  350. package/node_modules/pako/dist/pako_inflate.min.js +1 -0
  351. package/node_modules/pako/index.js +14 -0
  352. package/node_modules/pako/lib/deflate.js +400 -0
  353. package/node_modules/pako/lib/inflate.js +423 -0
  354. package/node_modules/pako/lib/utils/common.js +105 -0
  355. package/node_modules/pako/lib/utils/strings.js +187 -0
  356. package/node_modules/pako/lib/zlib/README +59 -0
  357. package/node_modules/pako/lib/zlib/adler32.js +51 -0
  358. package/node_modules/pako/lib/zlib/constants.js +68 -0
  359. package/node_modules/pako/lib/zlib/crc32.js +59 -0
  360. package/node_modules/pako/lib/zlib/deflate.js +1874 -0
  361. package/node_modules/pako/lib/zlib/gzheader.js +58 -0
  362. package/node_modules/pako/lib/zlib/inffast.js +345 -0
  363. package/node_modules/pako/lib/zlib/inflate.js +1556 -0
  364. package/node_modules/pako/lib/zlib/inftrees.js +343 -0
  365. package/node_modules/pako/lib/zlib/messages.js +32 -0
  366. package/node_modules/pako/lib/zlib/trees.js +1222 -0
  367. package/node_modules/pako/lib/zlib/zstream.js +47 -0
  368. package/node_modules/pako/package.json +44 -0
  369. package/node_modules/process-nextick-args/index.js +45 -0
  370. package/node_modules/process-nextick-args/license.md +19 -0
  371. package/node_modules/process-nextick-args/package.json +25 -0
  372. package/node_modules/process-nextick-args/readme.md +18 -0
  373. package/node_modules/readable-stream/.travis.yml +34 -0
  374. package/node_modules/readable-stream/CONTRIBUTING.md +38 -0
  375. package/node_modules/readable-stream/GOVERNANCE.md +136 -0
  376. package/node_modules/readable-stream/LICENSE +47 -0
  377. package/node_modules/readable-stream/README.md +58 -0
  378. package/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +60 -0
  379. package/node_modules/readable-stream/duplex-browser.js +1 -0
  380. package/node_modules/readable-stream/duplex.js +1 -0
  381. package/node_modules/readable-stream/lib/_stream_duplex.js +131 -0
  382. package/node_modules/readable-stream/lib/_stream_passthrough.js +47 -0
  383. package/node_modules/readable-stream/lib/_stream_readable.js +1019 -0
  384. package/node_modules/readable-stream/lib/_stream_transform.js +214 -0
  385. package/node_modules/readable-stream/lib/_stream_writable.js +685 -0
  386. package/node_modules/readable-stream/lib/internal/streams/BufferList.js +78 -0
  387. package/node_modules/readable-stream/lib/internal/streams/destroy.js +84 -0
  388. package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
  389. package/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
  390. package/node_modules/readable-stream/package.json +52 -0
  391. package/node_modules/readable-stream/passthrough.js +1 -0
  392. package/node_modules/readable-stream/readable-browser.js +7 -0
  393. package/node_modules/readable-stream/readable.js +19 -0
  394. package/node_modules/readable-stream/transform.js +1 -0
  395. package/node_modules/readable-stream/writable-browser.js +1 -0
  396. package/node_modules/readable-stream/writable.js +8 -0
  397. package/node_modules/safe-buffer/LICENSE +21 -0
  398. package/node_modules/safe-buffer/README.md +584 -0
  399. package/node_modules/safe-buffer/index.d.ts +187 -0
  400. package/node_modules/safe-buffer/index.js +62 -0
  401. package/node_modules/safe-buffer/package.json +37 -0
  402. package/node_modules/setimmediate/LICENSE.txt +20 -0
  403. package/node_modules/setimmediate/package.json +30 -0
  404. package/node_modules/setimmediate/setImmediate.js +186 -0
  405. package/node_modules/string_decoder/.travis.yml +50 -0
  406. package/node_modules/string_decoder/LICENSE +48 -0
  407. package/node_modules/string_decoder/README.md +47 -0
  408. package/node_modules/string_decoder/lib/string_decoder.js +296 -0
  409. package/node_modules/string_decoder/package.json +31 -0
  410. package/node_modules/util-deprecate/History.md +16 -0
  411. package/node_modules/util-deprecate/LICENSE +24 -0
  412. package/node_modules/util-deprecate/README.md +53 -0
  413. package/node_modules/util-deprecate/browser.js +67 -0
  414. package/node_modules/util-deprecate/node.js +6 -0
  415. package/node_modules/util-deprecate/package.json +27 -0
  416. package/package.json +9 -4
  417. package/packages/docx-core/node_modules/@xmldom/xmldom/CHANGELOG.md +468 -0
  418. package/packages/docx-core/node_modules/@xmldom/xmldom/LICENSE +8 -0
  419. package/packages/docx-core/node_modules/@xmldom/xmldom/SECURITY.md +50 -0
  420. package/packages/docx-core/node_modules/@xmldom/xmldom/index.d.ts +43 -0
  421. package/packages/docx-core/node_modules/@xmldom/xmldom/lib/.eslintrc.yml +2 -0
  422. package/packages/docx-core/node_modules/@xmldom/xmldom/lib/conventions.js +203 -0
  423. package/packages/docx-core/node_modules/@xmldom/xmldom/lib/dom-parser.js +322 -0
  424. package/packages/docx-core/node_modules/@xmldom/xmldom/lib/dom.js +1879 -0
  425. package/packages/docx-core/node_modules/@xmldom/xmldom/lib/entities.js +2166 -0
  426. package/packages/docx-core/node_modules/@xmldom/xmldom/lib/index.js +4 -0
  427. package/packages/docx-core/node_modules/@xmldom/xmldom/lib/sax.js +662 -0
  428. package/packages/docx-core/node_modules/@xmldom/xmldom/package.json +71 -0
  429. package/packages/docx-core/node_modules/@xmldom/xmldom/readme.md +356 -0
@@ -0,0 +1,985 @@
1
+ /**
2
+ * Document Reconstructor
3
+ *
4
+ * Rebuilds document.xml from marked atoms with track changes.
5
+ * Generates w:ins, w:del, w:moveFrom, w:moveTo elements as appropriate.
6
+ */
7
+ import { DOMParser } from '@xmldom/xmldom';
8
+ import { CorrelationStatus } from '../../core-types.js';
9
+ import { getLeafText, childElements, findChildByTagName } from '../../primitives/index.js';
10
+ import { serializeToXml, cloneElement } from './xmlToWmlElement.js';
11
+ import { EMPTY_PARAGRAPH_TAG } from '../../atomizer.js';
12
+ import { areRunPropertiesEqual } from '../../format-detection.js';
13
+ import { debug } from './debug.js';
14
+ const SYNTHETIC_DOC = new DOMParser().parseFromString('<root xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"/>', 'application/xml');
15
+ const W_NS = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
16
+ function createEl(tag, attrs) {
17
+ const el = SYNTHETIC_DOC.createElementNS(W_NS, tag);
18
+ if (attrs)
19
+ for (const [k, v] of Object.entries(attrs))
20
+ el.setAttribute(k, v);
21
+ return el;
22
+ }
23
+ /**
24
+ * Create initial revision ID state.
25
+ */
26
+ function createRevisionIdState() {
27
+ return {
28
+ nextId: 1,
29
+ moveRangeIds: new Map(),
30
+ };
31
+ }
32
+ /**
33
+ * Allocate a new revision ID.
34
+ */
35
+ function allocateRevisionId(state) {
36
+ return state.nextId++;
37
+ }
38
+ /**
39
+ * Get or allocate move range IDs for a move name.
40
+ */
41
+ function getMoveRangeIds(state, moveName) {
42
+ let ids = state.moveRangeIds.get(moveName);
43
+ if (!ids) {
44
+ ids = {
45
+ sourceRangeId: allocateRevisionId(state),
46
+ destRangeId: allocateRevisionId(state),
47
+ };
48
+ state.moveRangeIds.set(moveName, ids);
49
+ }
50
+ return ids;
51
+ }
52
+ /**
53
+ * Format date for OOXML (ISO 8601).
54
+ */
55
+ function formatDate(date) {
56
+ return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
57
+ }
58
+ /**
59
+ * Reconstruct document.xml from merged atoms with track changes.
60
+ *
61
+ * @param mergedAtoms - Atoms with correlation status set
62
+ * @param originalXml - Original document.xml for structure preservation
63
+ * @param options - Reconstruction options
64
+ * @returns New document.xml with track changes
65
+ */
66
+ export function reconstructDocument(mergedAtoms, originalXml, options) {
67
+ const { author, date } = options;
68
+ const dateStr = formatDate(date);
69
+ const revState = createRevisionIdState();
70
+ // Group atoms by paragraph
71
+ const rawParagraphGroups = groupAtomsByParagraph(mergedAtoms);
72
+ // Consolidate adjacent same-status changes for better readability
73
+ const paragraphGroups = consolidateAdjacentChanges(rawParagraphGroups);
74
+ // Reset debug counters
75
+ resetDebugCounters();
76
+ resetEmptyParagraphCounters();
77
+ debug('reconstructor', `${mergedAtoms.length} atoms -> ${paragraphGroups.length} paragraphs`);
78
+ // Build track changes XML for each paragraph
79
+ const paragraphXmls = [];
80
+ for (const group of paragraphGroups) {
81
+ const paragraphXml = buildParagraphXml(group, author, dateStr, revState);
82
+ paragraphXmls.push(paragraphXml);
83
+ }
84
+ const counters = getDebugCounters();
85
+ debug('reconstructor', `buildRunContent processed: ${counters.atoms} atoms, ${counters.wt} w:t elements`);
86
+ const emptyCounters = getEmptyParagraphCounters();
87
+ debug('reconstructor', `Empty paragraphs: inserted=${emptyCounters.inserted}, deleted=${emptyCounters.deleted}, equal=${emptyCounters.equal}, other=${emptyCounters.other}`);
88
+ // Reconstruct the document
89
+ return buildDocument(originalXml, paragraphXmls);
90
+ }
91
+ /**
92
+ * Group atoms by paragraph based on their ancestor chain.
93
+ *
94
+ * First sorts atoms by paragraphIndex to ensure all atoms belonging to the same
95
+ * paragraph are contiguous, then groups them sequentially.
96
+ */
97
+ function groupAtomsByParagraph(atoms) {
98
+ const groups = [];
99
+ let currentGroup = null;
100
+ let currentRunGroup = null;
101
+ const uniqueIndices = new Set(atoms.map(a => a.paragraphIndex));
102
+ debug('reconstructor', `groupAtomsByParagraph: ${atoms.length} atoms, ${uniqueIndices.size} unique paragraphIndices`);
103
+ // Sort atoms by paragraphIndex to ensure all atoms with the same index are contiguous.
104
+ // Use stable sort to preserve relative order within the same paragraph (deleted before inserted).
105
+ const sortedAtoms = [...atoms].sort((a, b) => {
106
+ const aIdx = a.paragraphIndex ?? Number.MAX_SAFE_INTEGER;
107
+ const bIdx = b.paragraphIndex ?? Number.MAX_SAFE_INTEGER;
108
+ return aIdx - bIdx;
109
+ });
110
+ for (const atom of sortedAtoms) {
111
+ // Find paragraph ancestor
112
+ const pAncestor = findAncestorByTag(atom, 'w:p');
113
+ const rAncestor = findAncestorByTag(atom, 'w:r');
114
+ // Check if we need a new paragraph
115
+ const pPr = pAncestor ? findChildByTag(pAncestor, 'w:pPr') : null;
116
+ // Pass currentRunGroup and current atom to check if we should start a new paragraph
117
+ // Uses paragraphIndex for comparison instead of object references
118
+ if (!currentGroup || shouldStartNewParagraph(currentGroup, currentRunGroup, atom)) {
119
+ if (currentRunGroup && currentGroup) {
120
+ currentGroup.runGroups.push(currentRunGroup);
121
+ }
122
+ currentRunGroup = null;
123
+ currentGroup = {
124
+ pPr: pPr ? cloneElement(pPr) : null,
125
+ runGroups: [],
126
+ };
127
+ groups.push(currentGroup);
128
+ }
129
+ // Check if we need a new run group
130
+ // Use the first-class rPr field from the atom when available,
131
+ // falling back to ancestor walk for atoms created before rPr was populated.
132
+ const atomRPr = getEffectiveAtomRPr(atom);
133
+ const rPr = atomRPr ?? (rAncestor ? findChildByTag(rAncestor, 'w:rPr') : null);
134
+ if (!currentRunGroup || shouldStartNewRunGroup(currentRunGroup, atom)) {
135
+ if (currentRunGroup) {
136
+ currentGroup.runGroups.push(currentRunGroup);
137
+ }
138
+ currentRunGroup = {
139
+ status: atom.correlationStatus,
140
+ atoms: [atom],
141
+ rPr: rPr ? cloneElement(rPr) : null,
142
+ moveName: atom.moveName,
143
+ };
144
+ }
145
+ else {
146
+ currentRunGroup.atoms.push(atom);
147
+ }
148
+ }
149
+ // Don't forget the last groups
150
+ if (currentRunGroup && currentGroup) {
151
+ currentGroup.runGroups.push(currentRunGroup);
152
+ }
153
+ return groups;
154
+ }
155
+ /**
156
+ * Check if a RunGroup contains only whitespace.
157
+ */
158
+ function isWhitespaceOnlyGroup(group) {
159
+ return group.atoms.every(atom => {
160
+ const text = getLeafText(atom.contentElement) ?? '';
161
+ return text.trim() === '';
162
+ });
163
+ }
164
+ /**
165
+ * Reorder atoms within change blocks.
166
+ *
167
+ * Identifies "change blocks" (contiguous regions with Del/Ins) and reorders
168
+ * to put all deletions first, then all insertions.
169
+ * Whitespace between changes is duplicated into both groups to preserve it
170
+ * regardless of accept/reject.
171
+ */
172
+ function reorderChangeBlocks(groups) {
173
+ for (const paraGroup of groups) {
174
+ const runGroups = paraGroup.runGroups;
175
+ const result = [];
176
+ let i = 0;
177
+ while (i < runGroups.length) {
178
+ const current = runGroups[i];
179
+ // Check if we're entering a change block
180
+ const isChange = current.status === CorrelationStatus.Deleted ||
181
+ current.status === CorrelationStatus.Inserted;
182
+ if (!isChange) {
183
+ result.push(current);
184
+ i++;
185
+ continue;
186
+ }
187
+ // Collect the entire change block
188
+ const deletions = [];
189
+ const insertions = [];
190
+ while (i < runGroups.length) {
191
+ const group = runGroups[i];
192
+ if (group.status === CorrelationStatus.Deleted) {
193
+ deletions.push(...group.atoms);
194
+ i++;
195
+ }
196
+ else if (group.status === CorrelationStatus.Inserted) {
197
+ insertions.push(...group.atoms);
198
+ i++;
199
+ }
200
+ else if (group.status === CorrelationStatus.Equal && isWhitespaceOnlyGroup(group)) {
201
+ // Duplicate whitespace into both deletions and insertions
202
+ // so it's preserved regardless of accept/reject
203
+ for (const atom of group.atoms) {
204
+ // Clone for deletions (mark as deleted)
205
+ const delAtom = {
206
+ ...atom,
207
+ correlationStatus: CorrelationStatus.Deleted,
208
+ };
209
+ deletions.push(delAtom);
210
+ // Clone for insertions (mark as inserted)
211
+ const insAtom = {
212
+ ...atom,
213
+ correlationStatus: CorrelationStatus.Inserted,
214
+ };
215
+ insertions.push(insAtom);
216
+ }
217
+ i++;
218
+ }
219
+ else {
220
+ // Non-whitespace Equal or other status - end of block
221
+ break;
222
+ }
223
+ }
224
+ // Output reordered: all deletions first, then all insertions
225
+ // rPr is set to null — buildRunContent will sub-group atoms by rPr
226
+ if (deletions.length > 0) {
227
+ result.push({
228
+ status: CorrelationStatus.Deleted,
229
+ atoms: deletions,
230
+ rPr: null,
231
+ });
232
+ }
233
+ if (insertions.length > 0) {
234
+ result.push({
235
+ status: CorrelationStatus.Inserted,
236
+ atoms: insertions,
237
+ rPr: null,
238
+ });
239
+ }
240
+ }
241
+ paraGroup.runGroups = result;
242
+ }
243
+ return groups;
244
+ }
245
+ /**
246
+ * Consolidate adjacent RunGroups with the same status within each paragraph.
247
+ *
248
+ * This makes change tracking more readable by grouping consecutive deletions
249
+ * together and consecutive insertions together, rather than interleaving them
250
+ * at the word level.
251
+ *
252
+ * For example, instead of:
253
+ * <del>word1</del><ins>word2</ins> <del>word3</del><ins>word4</ins>
254
+ *
255
+ * We get:
256
+ * <del>word1 word3</del><ins>word2 word4</ins>
257
+ */
258
+ function consolidateAdjacentChanges(groups) {
259
+ return reorderChangeBlocks(groups);
260
+ }
261
+ /**
262
+ * Find an ancestor element by tag name.
263
+ */
264
+ function findAncestorByTag(atom, tagName) {
265
+ for (let i = atom.ancestorElements.length - 1; i >= 0; i--) {
266
+ if (atom.ancestorElements[i].tagName === tagName) {
267
+ return atom.ancestorElements[i];
268
+ }
269
+ }
270
+ return null;
271
+ }
272
+ /**
273
+ * Find a child element by tag name.
274
+ */
275
+ function findChildByTag(element, tagName) {
276
+ for (let i = 0; i < element.childNodes.length; i++) {
277
+ const child = element.childNodes[i];
278
+ if (child.nodeType === 1 && child.tagName === tagName) {
279
+ return child;
280
+ }
281
+ }
282
+ return null;
283
+ }
284
+ /**
285
+ * Determine if we should start a new paragraph.
286
+ *
287
+ * Uses paragraphIndex for comparison instead of object references, because
288
+ * atoms from original and revised documents have different tree objects.
289
+ *
290
+ * @param currentGroup - The current paragraph group being built
291
+ * @param currentRunGroup - The current run group (may not be pushed to currentGroup yet)
292
+ * @param currentAtom - The current atom being processed
293
+ */
294
+ function shouldStartNewParagraph(currentGroup, currentRunGroup, currentAtom) {
295
+ const currentParagraphIndex = currentAtom.paragraphIndex;
296
+ // If no paragraph index, fall back to false (stay in current paragraph)
297
+ if (currentParagraphIndex === undefined)
298
+ return false;
299
+ // First check currentRunGroup (which may not be pushed to runGroups yet)
300
+ if (currentRunGroup && currentRunGroup.atoms.length > 0) {
301
+ const lastAtom = currentRunGroup.atoms[currentRunGroup.atoms.length - 1];
302
+ const lastParagraphIndex = lastAtom.paragraphIndex;
303
+ // Same paragraph index means same paragraph, even if from different trees
304
+ if (lastParagraphIndex !== undefined) {
305
+ return currentParagraphIndex !== lastParagraphIndex;
306
+ }
307
+ }
308
+ // Fall back to checking runGroups
309
+ if (currentGroup.runGroups.length === 0) {
310
+ return false;
311
+ }
312
+ // Check last atom's paragraph index
313
+ const lastRunGroup = currentGroup.runGroups[currentGroup.runGroups.length - 1];
314
+ if (!lastRunGroup || lastRunGroup.atoms.length === 0) {
315
+ return false;
316
+ }
317
+ const lastAtom = lastRunGroup.atoms[lastRunGroup.atoms.length - 1];
318
+ const lastParagraphIndex = lastAtom.paragraphIndex;
319
+ if (lastParagraphIndex !== undefined) {
320
+ return currentParagraphIndex !== lastParagraphIndex;
321
+ }
322
+ // No paragraph indices available, stay in current paragraph
323
+ return false;
324
+ }
325
+ /**
326
+ * Get the effective rPr for an atom — uses the first-class `rPr` field
327
+ * when available, otherwise returns null.
328
+ */
329
+ function getEffectiveAtomRPr(atom) {
330
+ return atom.rPr ?? null;
331
+ }
332
+ /**
333
+ * Determine if we should start a new run group.
334
+ */
335
+ function shouldStartNewRunGroup(currentGroup, atom) {
336
+ // Different status = new group
337
+ if (currentGroup.status !== atom.correlationStatus) {
338
+ return true;
339
+ }
340
+ // Different move name = new group
341
+ if (currentGroup.moveName !== atom.moveName) {
342
+ return true;
343
+ }
344
+ // Skip rPr splitting for MovedSource/MovedDestination to avoid
345
+ // duplicate move range markers (moveFromRangeStart/End)
346
+ if (currentGroup.status === CorrelationStatus.MovedSource ||
347
+ currentGroup.status === CorrelationStatus.MovedDestination) {
348
+ return false;
349
+ }
350
+ // Different rPr = new group (prevents formatting bleed between runs)
351
+ const currentRPr = getEffectiveAtomRPr(currentGroup.atoms[currentGroup.atoms.length - 1]);
352
+ const newRPr = getEffectiveAtomRPr(atom);
353
+ // Fast path: reference equality or both null
354
+ if (currentRPr === newRPr)
355
+ return false;
356
+ if (currentRPr === null && newRPr === null)
357
+ return false;
358
+ return !areRunPropertiesEqual(currentRPr, newRPr);
359
+ }
360
+ /**
361
+ * Check if a paragraph group represents an empty paragraph with a specific status.
362
+ *
363
+ * @param group - The paragraph group to check
364
+ * @param status - The correlation status to check for
365
+ * @returns True if all atoms are empty paragraph markers with the given status
366
+ */
367
+ function isEmptyParagraphWithStatus(group, status) {
368
+ // Check if all run groups contain only empty paragraph atoms with the given status
369
+ for (const runGroup of group.runGroups) {
370
+ // If any atom is not an empty paragraph marker, this is not an empty paragraph
371
+ const hasNonEmptyAtom = runGroup.atoms.some((atom) => atom.contentElement.tagName !== EMPTY_PARAGRAPH_TAG);
372
+ if (hasNonEmptyAtom) {
373
+ return false;
374
+ }
375
+ // If any atom doesn't have the expected status, return false
376
+ const hasWrongStatus = runGroup.atoms.some((atom) => atom.correlationStatus !== status);
377
+ if (hasWrongStatus) {
378
+ return false;
379
+ }
380
+ }
381
+ // All atoms are empty paragraph markers with the expected status
382
+ return group.runGroups.length > 0;
383
+ }
384
+ // Debug counters for empty paragraphs
385
+ let debugEmptyParaInserted = 0;
386
+ let debugEmptyParaDeleted = 0;
387
+ let debugEmptyParaEqual = 0;
388
+ let debugEmptyParaOther = 0;
389
+ /**
390
+ * Reset empty paragraph debug counters.
391
+ */
392
+ export function resetEmptyParagraphCounters() {
393
+ debugEmptyParaInserted = 0;
394
+ debugEmptyParaDeleted = 0;
395
+ debugEmptyParaEqual = 0;
396
+ debugEmptyParaOther = 0;
397
+ }
398
+ /**
399
+ * Get empty paragraph debug counters.
400
+ */
401
+ export function getEmptyParagraphCounters() {
402
+ return {
403
+ inserted: debugEmptyParaInserted,
404
+ deleted: debugEmptyParaDeleted,
405
+ equal: debugEmptyParaEqual,
406
+ other: debugEmptyParaOther,
407
+ };
408
+ }
409
+ /**
410
+ * Check if a paragraph group contains only empty paragraph atoms.
411
+ */
412
+ function isEmptyParagraphGroup(group) {
413
+ for (const runGroup of group.runGroups) {
414
+ const hasNonEmptyAtom = runGroup.atoms.some((atom) => atom.contentElement.tagName !== EMPTY_PARAGRAPH_TAG);
415
+ if (hasNonEmptyAtom) {
416
+ return false;
417
+ }
418
+ }
419
+ return group.runGroups.length > 0;
420
+ }
421
+ /**
422
+ * Build XML for a single paragraph with track changes.
423
+ */
424
+ function buildParagraphXml(group, author, dateStr, revState) {
425
+ // Track empty paragraph statuses for debugging
426
+ if (isEmptyParagraphGroup(group)) {
427
+ const status = group.runGroups[0]?.atoms[0]?.correlationStatus;
428
+ if (status === CorrelationStatus.Inserted) {
429
+ debugEmptyParaInserted++;
430
+ }
431
+ else if (status === CorrelationStatus.Deleted) {
432
+ debugEmptyParaDeleted++;
433
+ }
434
+ else if (status === CorrelationStatus.Equal) {
435
+ debugEmptyParaEqual++;
436
+ }
437
+ else {
438
+ debugEmptyParaOther++;
439
+ }
440
+ // Debug: log the first few empty paragraphs for investigation
441
+ const debugLimit = 5;
442
+ const totalEmpty = debugEmptyParaInserted + debugEmptyParaDeleted + debugEmptyParaEqual + debugEmptyParaOther;
443
+ if (totalEmpty <= debugLimit) {
444
+ const atoms = group.runGroups.flatMap(rg => rg.atoms);
445
+ const statuses = atoms.map(a => a.correlationStatus).join(', ');
446
+ debug('reconstructor', `Empty paragraph #${totalEmpty}: status=${status}, atomCount=${atoms.length}, atomStatuses=[${statuses}]`);
447
+ }
448
+ }
449
+ // Whole-paragraph insert/delete encoding must match Word/Aspose behavior.
450
+ //
451
+ // IMPORTANT: <w:ins> is not a container for <w:p> in WordprocessingML.
452
+ // Aspose encodes a paragraph insertion like:
453
+ // <w:p>
454
+ // <w:pPr><w:rPr><w:ins .../></w:rPr></w:pPr>
455
+ // <w:ins ...><w:r>...</w:r></w:ins>
456
+ // </w:p>
457
+ //
458
+ // That structure both renders in Word and allows Reject All to remove the paragraph
459
+ // entirely (instead of leaving behind a stub <w:p> break).
460
+ if (isEntireParagraphWithStatus(group, CorrelationStatus.Inserted)) {
461
+ const paraId = allocateRevisionId(revState);
462
+ const runId = allocateRevisionId(revState);
463
+ const pPrChangeEl = buildPPrChangeElement(group.pPr, author, dateStr, revState);
464
+ const parts = [];
465
+ parts.push('<w:p>');
466
+ parts.push(serializePPrWithParaRevisionMarker(group.pPr, 'w:ins', paraId, author, dateStr, pPrChangeEl));
467
+ parts.push(`<w:ins w:id="${runId}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}">`);
468
+ for (const runGroup of group.runGroups) {
469
+ parts.push(buildRunContentAsPlainRun(runGroup));
470
+ }
471
+ parts.push('</w:ins>');
472
+ parts.push('</w:p>');
473
+ return parts.join('');
474
+ }
475
+ if (isEntireParagraphWithStatus(group, CorrelationStatus.Deleted)) {
476
+ const paraId = allocateRevisionId(revState);
477
+ const runId = allocateRevisionId(revState);
478
+ const parts = [];
479
+ parts.push('<w:p>');
480
+ parts.push(serializePPrWithParaRevisionMarker(group.pPr, 'w:del', paraId, author, dateStr));
481
+ parts.push(`<w:del w:id="${runId}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}">`);
482
+ for (const runGroup of group.runGroups) {
483
+ const plainRun = buildRunContentAsPlainRun(runGroup);
484
+ parts.push(plainRun
485
+ .replace(/<w:t([^>]*)>([^<]*)<\/w:t>/g, '<w:delText$1>$2</w:delText>')
486
+ .replace(/<w:instrText([^>]*)>([^<]*)<\/w:instrText>/g, '<w:delInstrText$1>$2</w:delInstrText>'));
487
+ }
488
+ parts.push('</w:del>');
489
+ parts.push('</w:p>');
490
+ return parts.join('');
491
+ }
492
+ // Empty inserted paragraphs — use paragraph-mark revision marker (same as whole-paragraph).
493
+ // In OOXML, <w:ins> is NOT a valid container for <w:p>. The correct encoding places the
494
+ // marker inside w:pPr > w:rPr.
495
+ if (isEmptyParagraphWithStatus(group, CorrelationStatus.Inserted)) {
496
+ const paraId = allocateRevisionId(revState);
497
+ const pPrChangeEl = buildPPrChangeElement(group.pPr, author, dateStr, revState);
498
+ const pPrXml = serializePPrWithParaRevisionMarker(group.pPr, 'w:ins', paraId, author, dateStr, pPrChangeEl);
499
+ return `<w:p>${pPrXml}</w:p>`;
500
+ }
501
+ // Empty deleted paragraphs — use paragraph-mark revision marker.
502
+ if (isEmptyParagraphWithStatus(group, CorrelationStatus.Deleted)) {
503
+ const paraId = allocateRevisionId(revState);
504
+ const pPrXml = serializePPrWithParaRevisionMarker(group.pPr, 'w:del', paraId, author, dateStr);
505
+ return `<w:p>${pPrXml}</w:p>`;
506
+ }
507
+ const parts = [];
508
+ parts.push('<w:p>');
509
+ // Add paragraph properties
510
+ if (group.pPr) {
511
+ parts.push(serializeToXml(group.pPr));
512
+ }
513
+ // Add run groups with track changes
514
+ for (const runGroup of group.runGroups) {
515
+ const runXml = buildRunGroupXml(runGroup, author, dateStr, revState);
516
+ parts.push(runXml);
517
+ }
518
+ parts.push('</w:p>');
519
+ return parts.join('');
520
+ }
521
+ /**
522
+ * Serialize paragraph properties with a paragraph-level revision marker (w:ins or w:del)
523
+ * placed inside w:pPr > w:rPr, per OOXML spec.
524
+ *
525
+ * DOM-based implementation — replaces the former regex-based approach.
526
+ */
527
+ function serializePPrWithParaRevisionMarker(pPr, markerTag, id, author, dateStr, pPrChangeEl) {
528
+ // Clone pPr or synthesize empty one.
529
+ const effectivePPr = pPr ? cloneElement(pPr) : createEl('w:pPr');
530
+ // Find or create w:rPr at schema-correct position.
531
+ let rPr = findChildByTagName(effectivePPr, 'w:rPr');
532
+ if (!rPr) {
533
+ rPr = createEl('w:rPr');
534
+ const sectPr = findChildByTagName(effectivePPr, 'w:sectPr');
535
+ const existingPPrChange = findChildByTagName(effectivePPr, 'w:pPrChange');
536
+ const insertBefore = sectPr ?? existingPPrChange ?? null;
537
+ if (insertBefore) {
538
+ effectivePPr.insertBefore(rPr, insertBefore);
539
+ }
540
+ else {
541
+ effectivePPr.appendChild(rPr);
542
+ }
543
+ }
544
+ // Insert revision marker at start of rPr.
545
+ const marker = createEl(markerTag, {
546
+ 'w:id': String(id),
547
+ 'w:author': author,
548
+ 'w:date': dateStr,
549
+ });
550
+ rPr.insertBefore(marker, rPr.firstChild);
551
+ // Append pPrChange at end if provided.
552
+ if (pPrChangeEl) {
553
+ effectivePPr.appendChild(pPrChangeEl);
554
+ }
555
+ return serializeToXml(effectivePPr);
556
+ }
557
+ /**
558
+ * Build a `<w:pPrChange>` Element from a pPr DOM element.
559
+ *
560
+ * The child `<w:pPr>` conforms to CT_PPrBase — it excludes w:rPr, w:sectPr,
561
+ * w:rPrChange, and w:pPrChange.
562
+ */
563
+ function buildPPrChangeElement(pPr, author, dateStr, revState) {
564
+ const id = allocateRevisionId(revState);
565
+ const EXCLUDED = new Set(['w:rPr', 'w:rPrChange', 'w:pPrChange', 'w:sectPr']);
566
+ const pPrChange = createEl('w:pPrChange', {
567
+ 'w:id': String(id),
568
+ 'w:author': author,
569
+ 'w:date': dateStr,
570
+ });
571
+ const oldPPr = createEl('w:pPr');
572
+ if (pPr) {
573
+ for (const child of childElements(pPr)) {
574
+ if (!EXCLUDED.has(child.tagName))
575
+ oldPPr.appendChild(child.cloneNode(true));
576
+ }
577
+ }
578
+ pPrChange.appendChild(oldPPr);
579
+ return pPrChange;
580
+ }
581
+ /**
582
+ * Returns true if every atom in the paragraph is of the specified status
583
+ * (ignoring EMPTY_PARAGRAPH_TAG markers).
584
+ */
585
+ function isEntireParagraphWithStatus(group, status) {
586
+ let sawAnyContent = false;
587
+ let sawTargetStatus = false;
588
+ for (const runGroup of group.runGroups) {
589
+ for (const atom of runGroup.atoms) {
590
+ const el = atom.contentElement;
591
+ if (el.tagName === EMPTY_PARAGRAPH_TAG)
592
+ continue;
593
+ sawAnyContent = true;
594
+ // A whole-paragraph wrap should still apply even if there are "noise" atoms
595
+ // (pure whitespace runs, tabs, breaks) marked Equal due to normalization or
596
+ // LCS alignment. Those atoms would otherwise prevent wrapping and Word would
597
+ // leave an empty <w:p> stub on Reject All.
598
+ const isWhitespaceOnlyText = el.tagName === 'w:t' && ((getLeafText(el) ?? '').trim() === '');
599
+ const isWhitespaceAtom = isWhitespaceOnlyText || el.tagName === 'w:tab' || el.tagName === 'w:br' || el.tagName === 'w:cr';
600
+ if (atom.correlationStatus === status) {
601
+ sawTargetStatus = true;
602
+ continue;
603
+ }
604
+ if (isWhitespaceAtom) {
605
+ continue; // ignore for whole-paragraph classification
606
+ }
607
+ return false;
608
+ }
609
+ }
610
+ // If there's no content at all, let the empty-paragraph handlers deal with it.
611
+ // Also require at least one atom with the target status so we don't wrap equal-only paragraphs.
612
+ return sawAnyContent && sawTargetStatus;
613
+ }
614
+ /**
615
+ * Build a <w:r> without track-change wrappers. Used when the whole paragraph is already
616
+ * wrapped (paragraph-level <w:ins>/<w:del>).
617
+ *
618
+ * When group.rPr is null, sub-groups atoms by per-atom rPr to prevent formatting bleed.
619
+ */
620
+ function buildRunContentAsPlainRun(group) {
621
+ const contentAtoms = group.atoms.filter((atom) => atom.contentElement.tagName !== EMPTY_PARAGRAPH_TAG);
622
+ if (contentAtoms.length === 0)
623
+ return '';
624
+ // If group has explicit rPr, emit a single run
625
+ if (group.rPr !== null) {
626
+ return buildSingleRun(group.atoms, group.rPr);
627
+ }
628
+ // No group-level rPr — sub-group by per-atom rPr
629
+ const subGroups = subGroupByRPr(contentAtoms);
630
+ return subGroups.map(sg => buildSingleRun(sg.atoms, sg.rPr)).join('');
631
+ }
632
+ /**
633
+ * Build XML for a run group with appropriate track changes wrapper.
634
+ */
635
+ function buildRunGroupXml(group, author, dateStr, revState) {
636
+ const runContent = buildRunContent(group);
637
+ // If run content is empty (e.g., only empty paragraph atoms), return empty string
638
+ // This avoids generating empty track changes wrappers
639
+ if (!runContent) {
640
+ return '';
641
+ }
642
+ switch (group.status) {
643
+ case CorrelationStatus.Equal:
644
+ case CorrelationStatus.Unknown:
645
+ return runContent;
646
+ case CorrelationStatus.Inserted:
647
+ return wrapWithIns(runContent, author, dateStr, revState);
648
+ case CorrelationStatus.Deleted:
649
+ return wrapWithDel(runContent, author, dateStr, revState);
650
+ case CorrelationStatus.MovedSource:
651
+ return wrapWithMoveFrom(runContent, author, dateStr, group.moveName || 'move1', revState);
652
+ case CorrelationStatus.MovedDestination:
653
+ return wrapWithMoveTo(runContent, author, dateStr, group.moveName || 'move1', revState);
654
+ case CorrelationStatus.FormatChanged:
655
+ // For format changes, we include the run with rPrChange
656
+ return buildFormatChangeRun(group, author, dateStr, revState);
657
+ default:
658
+ return runContent;
659
+ }
660
+ }
661
+ // Debug counter for atoms processed
662
+ let debugAtomCounter = 0;
663
+ let debugWtCounter = 0;
664
+ /**
665
+ * Reset debug counters (for testing).
666
+ */
667
+ export function resetDebugCounters() {
668
+ debugAtomCounter = 0;
669
+ debugWtCounter = 0;
670
+ }
671
+ /**
672
+ * Get debug counters (for testing).
673
+ */
674
+ export function getDebugCounters() {
675
+ return { atoms: debugAtomCounter, wt: debugWtCounter };
676
+ }
677
+ /**
678
+ * Sub-group atoms by contiguous rPr — atoms with the same effective rPr
679
+ * stay in one sub-group, a change in rPr starts a new sub-group.
680
+ */
681
+ function subGroupByRPr(atoms) {
682
+ if (atoms.length === 0)
683
+ return [];
684
+ const result = [];
685
+ let currentRPr = getEffectiveAtomRPr(atoms[0]);
686
+ let currentAtoms = [atoms[0]];
687
+ for (let i = 1; i < atoms.length; i++) {
688
+ const atomRPr = getEffectiveAtomRPr(atoms[i]);
689
+ // Fast path: reference equality or both null
690
+ let same = currentRPr === atomRPr;
691
+ if (!same && currentRPr === null && atomRPr === null) {
692
+ same = true;
693
+ }
694
+ if (!same) {
695
+ same = areRunPropertiesEqual(currentRPr, atomRPr);
696
+ }
697
+ if (same) {
698
+ currentAtoms.push(atoms[i]);
699
+ }
700
+ else {
701
+ result.push({ rPr: currentRPr, atoms: currentAtoms });
702
+ currentRPr = atomRPr;
703
+ currentAtoms = [atoms[i]];
704
+ }
705
+ }
706
+ result.push({ rPr: currentRPr, atoms: currentAtoms });
707
+ return result;
708
+ }
709
+ /**
710
+ * Build a single <w:r> element from a set of atoms with the given rPr.
711
+ * Preserves pendingText coalescing, collapsedFieldAtoms expansion,
712
+ * and debug counter increments.
713
+ */
714
+ function buildSingleRun(atoms, rPr) {
715
+ const contentAtoms = atoms.filter((atom) => atom.contentElement.tagName !== EMPTY_PARAGRAPH_TAG);
716
+ if (contentAtoms.length === 0)
717
+ return '';
718
+ const parts = [];
719
+ parts.push('<w:r>');
720
+ if (rPr)
721
+ parts.push(serializeToXml(rPr));
722
+ let pendingText = '';
723
+ const flushPendingText = () => {
724
+ if (!pendingText)
725
+ return;
726
+ const escaped = escapeXmlText(pendingText);
727
+ const needsPreserve = pendingText.startsWith(' ') ||
728
+ pendingText.endsWith(' ') ||
729
+ pendingText.includes(' ');
730
+ parts.push(needsPreserve
731
+ ? `<w:t xml:space="preserve">${escaped}</w:t>`
732
+ : `<w:t>${escaped}</w:t>`);
733
+ pendingText = '';
734
+ };
735
+ for (const atom of contentAtoms) {
736
+ debugAtomCounter++;
737
+ if (atom.collapsedFieldAtoms && atom.collapsedFieldAtoms.length > 0) {
738
+ flushPendingText();
739
+ for (const fieldAtom of atom.collapsedFieldAtoms) {
740
+ parts.push(serializeAtomElement(fieldAtom.contentElement));
741
+ }
742
+ continue;
743
+ }
744
+ const el = atom.contentElement;
745
+ if (el.tagName === 'w:t') {
746
+ pendingText += getLeafText(el) ?? '';
747
+ continue;
748
+ }
749
+ flushPendingText();
750
+ parts.push(serializeAtomElement(el));
751
+ }
752
+ flushPendingText();
753
+ parts.push('</w:r>');
754
+ return parts.join('');
755
+ }
756
+ /**
757
+ * Serialize an atom's content element to XML string.
758
+ */
759
+ function serializeAtomElement(element) {
760
+ if (element.tagName === 'w:t') {
761
+ debugWtCounter++;
762
+ // Text element - preserve xml:space if needed
763
+ const text = escapeXmlText(getLeafText(element) ?? '');
764
+ if (text.startsWith(' ') || text.endsWith(' ') || text.includes(' ')) {
765
+ return `<w:t xml:space="preserve">${text}</w:t>`;
766
+ }
767
+ else {
768
+ return `<w:t>${text}</w:t>`;
769
+ }
770
+ }
771
+ else if (element.tagName === 'w:br') {
772
+ return '<w:br/>';
773
+ }
774
+ else if (element.tagName === 'w:tab') {
775
+ return '<w:tab/>';
776
+ }
777
+ else if (element.tagName === 'w:cr') {
778
+ return '<w:cr/>';
779
+ }
780
+ else {
781
+ // Other elements (including field chars, instrText) - serialize as-is
782
+ return serializeToXml(element);
783
+ }
784
+ }
785
+ /**
786
+ * Build the content of a run from atoms.
787
+ *
788
+ * Returns empty string if all atoms are empty paragraph markers,
789
+ * which ensures no empty <w:r> elements are generated.
790
+ *
791
+ * When group.rPr is non-null, emits a single <w:r> with that rPr.
792
+ * When group.rPr is null (e.g., after reorderChangeBlocks merges atoms
793
+ * from multiple original RunGroups), sub-groups atoms by their per-atom
794
+ * rPr and emits one <w:r> per sub-group to prevent formatting bleed.
795
+ */
796
+ function buildRunContent(group) {
797
+ // Check if this run group contains only empty paragraph atoms
798
+ const contentAtoms = group.atoms.filter((atom) => atom.contentElement.tagName !== EMPTY_PARAGRAPH_TAG);
799
+ // If no content atoms, return empty string (don't generate empty run)
800
+ if (contentAtoms.length === 0) {
801
+ return '';
802
+ }
803
+ // If group has explicit rPr, emit a single run
804
+ if (group.rPr !== null) {
805
+ return buildSingleRun(group.atoms, group.rPr);
806
+ }
807
+ // No group-level rPr — sub-group by per-atom rPr
808
+ const subGroups = subGroupByRPr(contentAtoms);
809
+ return subGroups.map(sg => buildSingleRun(sg.atoms, sg.rPr)).join('');
810
+ }
811
+ /**
812
+ * Wrap content with w:ins element.
813
+ */
814
+ function wrapWithIns(content, author, dateStr, revState) {
815
+ const id = allocateRevisionId(revState);
816
+ return `<w:ins w:id="${id}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}">${content}</w:ins>`;
817
+ }
818
+ /**
819
+ * Wrap content with w:del element.
820
+ */
821
+ function wrapWithDel(content, author, dateStr, revState) {
822
+ const id = allocateRevisionId(revState);
823
+ // For deletions, convert w:t to w:delText and w:instrText to w:delInstrText
824
+ const delContent = content
825
+ .replace(/<w:t([^>]*)>([^<]*)<\/w:t>/g, '<w:delText$1>$2</w:delText>')
826
+ .replace(/<w:instrText([^>]*)>([^<]*)<\/w:instrText>/g, '<w:delInstrText$1>$2</w:delInstrText>');
827
+ return `<w:del w:id="${id}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}">${delContent}</w:del>`;
828
+ }
829
+ /**
830
+ * Wrap content with w:moveFrom elements.
831
+ */
832
+ function wrapWithMoveFrom(content, author, dateStr, moveName, revState) {
833
+ const ids = getMoveRangeIds(revState, moveName);
834
+ const moveId = allocateRevisionId(revState);
835
+ // Convert w:t to w:delText and w:instrText to w:delInstrText for moved-from content
836
+ const delContent = content
837
+ .replace(/<w:t([^>]*)>([^<]*)<\/w:t>/g, '<w:delText$1>$2</w:delText>')
838
+ .replace(/<w:instrText([^>]*)>([^<]*)<\/w:instrText>/g, '<w:delInstrText$1>$2</w:delInstrText>');
839
+ return (`<w:moveFromRangeStart w:id="${ids.sourceRangeId}" w:name="${moveName}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}"/>` +
840
+ `<w:moveFrom w:id="${moveId}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}">${delContent}</w:moveFrom>` +
841
+ `<w:moveFromRangeEnd w:id="${ids.sourceRangeId}"/>`);
842
+ }
843
+ /**
844
+ * Wrap content with w:moveTo elements.
845
+ */
846
+ function wrapWithMoveTo(content, author, dateStr, moveName, revState) {
847
+ const ids = getMoveRangeIds(revState, moveName);
848
+ const moveId = allocateRevisionId(revState);
849
+ return (`<w:moveToRangeStart w:id="${ids.destRangeId}" w:name="${moveName}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}"/>` +
850
+ `<w:moveTo w:id="${moveId}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}">${content}</w:moveTo>` +
851
+ `<w:moveToRangeEnd w:id="${ids.destRangeId}"/>`);
852
+ }
853
+ /**
854
+ * Build run with format change tracking (w:rPrChange).
855
+ */
856
+ function buildFormatChangeRun(group, author, dateStr, revState) {
857
+ const parts = [];
858
+ parts.push('<w:r>');
859
+ // Build rPr with rPrChange
860
+ const effectiveRPr = group.rPr ?? group.atoms[0]?.rPr ?? null;
861
+ if (effectiveRPr || group.atoms[0]?.formatChange) {
862
+ parts.push('<w:rPr>');
863
+ // Current properties
864
+ if (effectiveRPr) {
865
+ for (const child of childElements(effectiveRPr)) {
866
+ if (child.tagName !== 'w:rPrChange') {
867
+ parts.push(serializeToXml(child));
868
+ }
869
+ }
870
+ }
871
+ // Add rPrChange with old properties (wrapped in w:rPr per OOXML spec)
872
+ const formatChange = group.atoms[0]?.formatChange;
873
+ if (formatChange?.oldRunProperties) {
874
+ const id = allocateRevisionId(revState);
875
+ parts.push(`<w:rPrChange w:id="${id}" w:author="${escapeXmlAttr(author)}" w:date="${dateStr}">`);
876
+ parts.push('<w:rPr>');
877
+ for (const child of childElements(formatChange.oldRunProperties)) {
878
+ parts.push(serializeToXml(child));
879
+ }
880
+ parts.push('</w:rPr>');
881
+ parts.push('</w:rPrChange>');
882
+ }
883
+ parts.push('</w:rPr>');
884
+ }
885
+ // Add atom content
886
+ for (const atom of group.atoms) {
887
+ const element = atom.contentElement;
888
+ if (element.tagName === 'w:t') {
889
+ const text = escapeXmlText(getLeafText(element) ?? '');
890
+ if (text.startsWith(' ') || text.endsWith(' ') || text.includes(' ')) {
891
+ parts.push(`<w:t xml:space="preserve">${text}</w:t>`);
892
+ }
893
+ else {
894
+ parts.push(`<w:t>${text}</w:t>`);
895
+ }
896
+ }
897
+ else {
898
+ parts.push(serializeToXml(element));
899
+ }
900
+ }
901
+ parts.push('</w:r>');
902
+ return parts.join('');
903
+ }
904
+ /**
905
+ * Build the final document by replacing body content.
906
+ *
907
+ * Note: sectPr elements are NOT extracted and appended separately because:
908
+ * 1. Section properties inside pPr elements are already preserved in the reconstructed paragraphs
909
+ * 2. The regex to extract "final sectPr" was incorrectly matching sectPr inside pPr elements
910
+ * and capturing large amounts of body content, causing duplicate text.
911
+ */
912
+ function buildDocument(originalXml, paragraphXmls) {
913
+ // Extract document structure
914
+ const bodyMatch = originalXml.match(/(<w:body[^>]*>)([\s\S]*?)(<\/w:body>)/);
915
+ if (!bodyMatch) {
916
+ throw new Error('Could not find w:body in document');
917
+ }
918
+ const beforeBody = originalXml.slice(0, originalXml.indexOf(bodyMatch[0]));
919
+ const bodyOpenTag = bodyMatch[1];
920
+ const bodyCloseTag = bodyMatch[3];
921
+ const afterBody = originalXml.slice(originalXml.indexOf(bodyMatch[0]) + bodyMatch[0].length);
922
+ // Build new body (no separate sectPr extraction - it's in the paragraphs' pPr)
923
+ const newBodyContent = paragraphXmls.join('\n');
924
+ return beforeBody + bodyOpenTag + '\n' + newBodyContent + '\n' + bodyCloseTag + afterBody;
925
+ }
926
+ /**
927
+ * Escape XML text content.
928
+ */
929
+ function escapeXmlText(text) {
930
+ return text
931
+ .replace(/&/g, '&amp;')
932
+ .replace(/</g, '&lt;')
933
+ .replace(/>/g, '&gt;');
934
+ }
935
+ /**
936
+ * Escape XML attribute value.
937
+ */
938
+ function escapeXmlAttr(text) {
939
+ return text
940
+ .replace(/&/g, '&amp;')
941
+ .replace(/</g, '&lt;')
942
+ .replace(/>/g, '&gt;')
943
+ .replace(/"/g, '&quot;');
944
+ }
945
+ /**
946
+ * Count statistics from merged atoms.
947
+ */
948
+ export function computeReconstructionStats(mergedAtoms) {
949
+ let insertions = 0;
950
+ let deletions = 0;
951
+ let moves = 0;
952
+ let formatChanges = 0;
953
+ const paragraphs = new Set();
954
+ for (const atom of mergedAtoms) {
955
+ // Count paragraph
956
+ const pAncestor = findAncestorByTag(atom, 'w:p');
957
+ if (pAncestor) {
958
+ paragraphs.add(pAncestor);
959
+ }
960
+ // Count by status
961
+ switch (atom.correlationStatus) {
962
+ case CorrelationStatus.Inserted:
963
+ insertions++;
964
+ break;
965
+ case CorrelationStatus.Deleted:
966
+ deletions++;
967
+ break;
968
+ case CorrelationStatus.MovedSource:
969
+ case CorrelationStatus.MovedDestination:
970
+ moves++;
971
+ break;
972
+ case CorrelationStatus.FormatChanged:
973
+ formatChanges++;
974
+ break;
975
+ }
976
+ }
977
+ return {
978
+ paragraphs: paragraphs.size,
979
+ insertions,
980
+ deletions,
981
+ moves: Math.floor(moves / 2), // Source and destination counted separately
982
+ formatChanges,
983
+ };
984
+ }
985
+ //# sourceMappingURL=documentReconstructor.js.map