@usejunior/docx-core 0.0.1 → 0.1.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 (252) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -28
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/atomizer.d.ts +218 -0
  5. package/dist/atomizer.d.ts.map +1 -0
  6. package/dist/atomizer.js +856 -0
  7. package/dist/atomizer.js.map +1 -0
  8. package/dist/baselines/atomizer/atomLcs.d.ts +96 -0
  9. package/dist/baselines/atomizer/atomLcs.d.ts.map +1 -0
  10. package/dist/baselines/atomizer/atomLcs.js +347 -0
  11. package/dist/baselines/atomizer/atomLcs.js.map +1 -0
  12. package/dist/baselines/atomizer/debug.d.ts +41 -0
  13. package/dist/baselines/atomizer/debug.d.ts.map +1 -0
  14. package/dist/baselines/atomizer/debug.js +85 -0
  15. package/dist/baselines/atomizer/debug.js.map +1 -0
  16. package/dist/baselines/atomizer/documentReconstructor.d.ts +64 -0
  17. package/dist/baselines/atomizer/documentReconstructor.d.ts.map +1 -0
  18. package/dist/baselines/atomizer/documentReconstructor.js +939 -0
  19. package/dist/baselines/atomizer/documentReconstructor.js.map +1 -0
  20. package/dist/baselines/atomizer/hierarchicalLcs.d.ts +111 -0
  21. package/dist/baselines/atomizer/hierarchicalLcs.d.ts.map +1 -0
  22. package/dist/baselines/atomizer/hierarchicalLcs.js +469 -0
  23. package/dist/baselines/atomizer/hierarchicalLcs.js.map +1 -0
  24. package/dist/baselines/atomizer/inPlaceModifier.d.ts +183 -0
  25. package/dist/baselines/atomizer/inPlaceModifier.d.ts.map +1 -0
  26. package/dist/baselines/atomizer/inPlaceModifier.js +1600 -0
  27. package/dist/baselines/atomizer/inPlaceModifier.js.map +1 -0
  28. package/dist/baselines/atomizer/numberingIntegration.d.ts +59 -0
  29. package/dist/baselines/atomizer/numberingIntegration.d.ts.map +1 -0
  30. package/dist/baselines/atomizer/numberingIntegration.js +209 -0
  31. package/dist/baselines/atomizer/numberingIntegration.js.map +1 -0
  32. package/dist/baselines/atomizer/pipeline.d.ts +65 -0
  33. package/dist/baselines/atomizer/pipeline.d.ts.map +1 -0
  34. package/dist/baselines/atomizer/pipeline.js +510 -0
  35. package/dist/baselines/atomizer/pipeline.js.map +1 -0
  36. package/dist/baselines/atomizer/premergeRuns.d.ts +26 -0
  37. package/dist/baselines/atomizer/premergeRuns.d.ts.map +1 -0
  38. package/dist/baselines/atomizer/premergeRuns.js +150 -0
  39. package/dist/baselines/atomizer/premergeRuns.js.map +1 -0
  40. package/dist/baselines/atomizer/trackChangesAcceptor.d.ts +63 -0
  41. package/dist/baselines/atomizer/trackChangesAcceptor.d.ts.map +1 -0
  42. package/dist/baselines/atomizer/trackChangesAcceptor.js +254 -0
  43. package/dist/baselines/atomizer/trackChangesAcceptor.js.map +1 -0
  44. package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts +64 -0
  45. package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts.map +1 -0
  46. package/dist/baselines/atomizer/trackChangesAcceptorAst.js +586 -0
  47. package/dist/baselines/atomizer/trackChangesAcceptorAst.js.map +1 -0
  48. package/dist/baselines/atomizer/xmlToWmlElement.d.ts +65 -0
  49. package/dist/baselines/atomizer/xmlToWmlElement.d.ts.map +1 -0
  50. package/dist/baselines/atomizer/xmlToWmlElement.js +95 -0
  51. package/dist/baselines/atomizer/xmlToWmlElement.js.map +1 -0
  52. package/dist/baselines/diffmatch/documentBuilder.d.ts +44 -0
  53. package/dist/baselines/diffmatch/documentBuilder.d.ts.map +1 -0
  54. package/dist/baselines/diffmatch/documentBuilder.js +227 -0
  55. package/dist/baselines/diffmatch/documentBuilder.js.map +1 -0
  56. package/dist/baselines/diffmatch/paragraphAlignment.d.ts +75 -0
  57. package/dist/baselines/diffmatch/paragraphAlignment.d.ts.map +1 -0
  58. package/dist/baselines/diffmatch/paragraphAlignment.js +206 -0
  59. package/dist/baselines/diffmatch/paragraphAlignment.js.map +1 -0
  60. package/dist/baselines/diffmatch/pipeline.d.ts +33 -0
  61. package/dist/baselines/diffmatch/pipeline.d.ts.map +1 -0
  62. package/dist/baselines/diffmatch/pipeline.js +84 -0
  63. package/dist/baselines/diffmatch/pipeline.js.map +1 -0
  64. package/dist/baselines/diffmatch/runDiff.d.ts +53 -0
  65. package/dist/baselines/diffmatch/runDiff.d.ts.map +1 -0
  66. package/dist/baselines/diffmatch/runDiff.js +253 -0
  67. package/dist/baselines/diffmatch/runDiff.js.map +1 -0
  68. package/dist/baselines/diffmatch/trackChangesRenderer.d.ts +64 -0
  69. package/dist/baselines/diffmatch/trackChangesRenderer.d.ts.map +1 -0
  70. package/dist/baselines/diffmatch/trackChangesRenderer.js +178 -0
  71. package/dist/baselines/diffmatch/trackChangesRenderer.js.map +1 -0
  72. package/dist/baselines/diffmatch/xmlParser.d.ts +45 -0
  73. package/dist/baselines/diffmatch/xmlParser.d.ts.map +1 -0
  74. package/dist/baselines/diffmatch/xmlParser.js +344 -0
  75. package/dist/baselines/diffmatch/xmlParser.js.map +1 -0
  76. package/dist/baselines/wmlcomparer/DocxodusWasm.d.ts +51 -0
  77. package/dist/baselines/wmlcomparer/DocxodusWasm.d.ts.map +1 -0
  78. package/dist/baselines/wmlcomparer/DocxodusWasm.js +83 -0
  79. package/dist/baselines/wmlcomparer/DocxodusWasm.js.map +1 -0
  80. package/dist/baselines/wmlcomparer/DotnetCli.d.ts +40 -0
  81. package/dist/baselines/wmlcomparer/DotnetCli.d.ts.map +1 -0
  82. package/dist/baselines/wmlcomparer/DotnetCli.js +135 -0
  83. package/dist/baselines/wmlcomparer/DotnetCli.js.map +1 -0
  84. package/dist/benchmark/metrics.d.ts +72 -0
  85. package/dist/benchmark/metrics.d.ts.map +1 -0
  86. package/dist/benchmark/metrics.js +45 -0
  87. package/dist/benchmark/metrics.js.map +1 -0
  88. package/dist/benchmark/reporter.d.ts +23 -0
  89. package/dist/benchmark/reporter.d.ts.map +1 -0
  90. package/dist/benchmark/reporter.js +147 -0
  91. package/dist/benchmark/reporter.js.map +1 -0
  92. package/dist/benchmark/runner.d.ts +30 -0
  93. package/dist/benchmark/runner.d.ts.map +1 -0
  94. package/dist/benchmark/runner.js +233 -0
  95. package/dist/benchmark/runner.js.map +1 -0
  96. package/dist/cli/compare-two.d.ts +28 -0
  97. package/dist/cli/compare-two.d.ts.map +1 -0
  98. package/dist/cli/compare-two.js +110 -0
  99. package/dist/cli/compare-two.js.map +1 -0
  100. package/dist/cli/index.d.ts +3 -0
  101. package/dist/cli/index.d.ts.map +1 -0
  102. package/dist/cli/index.js +21 -0
  103. package/dist/cli/index.js.map +1 -0
  104. package/dist/core-types.d.ts +296 -0
  105. package/dist/core-types.d.ts.map +1 -0
  106. package/dist/core-types.js +122 -0
  107. package/dist/core-types.js.map +1 -0
  108. package/dist/footnotes.d.ts +144 -0
  109. package/dist/footnotes.d.ts.map +1 -0
  110. package/dist/footnotes.js +291 -0
  111. package/dist/footnotes.js.map +1 -0
  112. package/dist/format-detection.d.ts +120 -0
  113. package/dist/format-detection.d.ts.map +1 -0
  114. package/dist/format-detection.js +338 -0
  115. package/dist/format-detection.js.map +1 -0
  116. package/dist/index.d.ts +177 -0
  117. package/dist/index.d.ts.map +1 -0
  118. package/dist/index.js +55 -0
  119. package/dist/index.js.map +1 -0
  120. package/dist/integration/output-artifacts.d.ts +6 -0
  121. package/dist/integration/output-artifacts.d.ts.map +1 -0
  122. package/dist/integration/output-artifacts.js +30 -0
  123. package/dist/integration/output-artifacts.js.map +1 -0
  124. package/dist/move-detection.d.ts +211 -0
  125. package/dist/move-detection.d.ts.map +1 -0
  126. package/dist/move-detection.js +391 -0
  127. package/dist/move-detection.js.map +1 -0
  128. package/dist/numbering.d.ts +136 -0
  129. package/dist/numbering.d.ts.map +1 -0
  130. package/dist/numbering.js +446 -0
  131. package/dist/numbering.js.map +1 -0
  132. package/dist/primitives/accept_changes.d.ts +30 -0
  133. package/dist/primitives/accept_changes.d.ts.map +1 -0
  134. package/dist/primitives/accept_changes.js +241 -0
  135. package/dist/primitives/accept_changes.js.map +1 -0
  136. package/dist/primitives/bookmarks.d.ts +12 -0
  137. package/dist/primitives/bookmarks.d.ts.map +1 -0
  138. package/dist/primitives/bookmarks.js +248 -0
  139. package/dist/primitives/bookmarks.js.map +1 -0
  140. package/dist/primitives/comments.d.ts +88 -0
  141. package/dist/primitives/comments.d.ts.map +1 -0
  142. package/dist/primitives/comments.js +703 -0
  143. package/dist/primitives/comments.js.map +1 -0
  144. package/dist/primitives/document.d.ts +168 -0
  145. package/dist/primitives/document.d.ts.map +1 -0
  146. package/dist/primitives/document.js +532 -0
  147. package/dist/primitives/document.js.map +1 -0
  148. package/dist/primitives/document_view.d.ts +93 -0
  149. package/dist/primitives/document_view.d.ts.map +1 -0
  150. package/dist/primitives/document_view.js +722 -0
  151. package/dist/primitives/document_view.js.map +1 -0
  152. package/dist/primitives/dom-helpers.d.ts +94 -0
  153. package/dist/primitives/dom-helpers.d.ts.map +1 -0
  154. package/dist/primitives/dom-helpers.js +219 -0
  155. package/dist/primitives/dom-helpers.js.map +1 -0
  156. package/dist/primitives/errors.d.ts +7 -0
  157. package/dist/primitives/errors.d.ts.map +1 -0
  158. package/dist/primitives/errors.js +10 -0
  159. package/dist/primitives/errors.js.map +1 -0
  160. package/dist/primitives/extract_revisions.d.ts +50 -0
  161. package/dist/primitives/extract_revisions.d.ts.map +1 -0
  162. package/dist/primitives/extract_revisions.js +340 -0
  163. package/dist/primitives/extract_revisions.js.map +1 -0
  164. package/dist/primitives/footnotes.d.ts +37 -0
  165. package/dist/primitives/footnotes.d.ts.map +1 -0
  166. package/dist/primitives/footnotes.js +552 -0
  167. package/dist/primitives/footnotes.js.map +1 -0
  168. package/dist/primitives/formatting_tags.d.ts +30 -0
  169. package/dist/primitives/formatting_tags.d.ts.map +1 -0
  170. package/dist/primitives/formatting_tags.js +217 -0
  171. package/dist/primitives/formatting_tags.js.map +1 -0
  172. package/dist/primitives/index.d.ts +26 -0
  173. package/dist/primitives/index.d.ts.map +1 -0
  174. package/dist/primitives/index.js +26 -0
  175. package/dist/primitives/index.js.map +1 -0
  176. package/dist/primitives/layout.d.ts +53 -0
  177. package/dist/primitives/layout.d.ts.map +1 -0
  178. package/dist/primitives/layout.js +178 -0
  179. package/dist/primitives/layout.js.map +1 -0
  180. package/dist/primitives/list_labels.d.ts +19 -0
  181. package/dist/primitives/list_labels.d.ts.map +1 -0
  182. package/dist/primitives/list_labels.js +57 -0
  183. package/dist/primitives/list_labels.js.map +1 -0
  184. package/dist/primitives/matching.d.ts +17 -0
  185. package/dist/primitives/matching.d.ts.map +1 -0
  186. package/dist/primitives/matching.js +144 -0
  187. package/dist/primitives/matching.js.map +1 -0
  188. package/dist/primitives/merge_runs.d.ts +23 -0
  189. package/dist/primitives/merge_runs.d.ts.map +1 -0
  190. package/dist/primitives/merge_runs.js +195 -0
  191. package/dist/primitives/merge_runs.js.map +1 -0
  192. package/dist/primitives/namespaces.d.ts +90 -0
  193. package/dist/primitives/namespaces.d.ts.map +1 -0
  194. package/dist/primitives/namespaces.js +107 -0
  195. package/dist/primitives/namespaces.js.map +1 -0
  196. package/dist/primitives/numbering.d.ts +27 -0
  197. package/dist/primitives/numbering.d.ts.map +1 -0
  198. package/dist/primitives/numbering.js +182 -0
  199. package/dist/primitives/numbering.js.map +1 -0
  200. package/dist/primitives/prevent_double_elevation.d.ts +18 -0
  201. package/dist/primitives/prevent_double_elevation.d.ts.map +1 -0
  202. package/dist/primitives/prevent_double_elevation.js +190 -0
  203. package/dist/primitives/prevent_double_elevation.js.map +1 -0
  204. package/dist/primitives/reject_changes.d.ts +27 -0
  205. package/dist/primitives/reject_changes.d.ts.map +1 -0
  206. package/dist/primitives/reject_changes.js +371 -0
  207. package/dist/primitives/reject_changes.js.map +1 -0
  208. package/dist/primitives/relationships.d.ts +7 -0
  209. package/dist/primitives/relationships.d.ts.map +1 -0
  210. package/dist/primitives/relationships.js +24 -0
  211. package/dist/primitives/relationships.js.map +1 -0
  212. package/dist/primitives/semantic_tags.d.ts +32 -0
  213. package/dist/primitives/semantic_tags.d.ts.map +1 -0
  214. package/dist/primitives/semantic_tags.js +139 -0
  215. package/dist/primitives/semantic_tags.js.map +1 -0
  216. package/dist/primitives/simplify_redlines.d.ts +19 -0
  217. package/dist/primitives/simplify_redlines.d.ts.map +1 -0
  218. package/dist/primitives/simplify_redlines.js +94 -0
  219. package/dist/primitives/simplify_redlines.js.map +1 -0
  220. package/dist/primitives/styles.d.ts +36 -0
  221. package/dist/primitives/styles.d.ts.map +1 -0
  222. package/dist/primitives/styles.js +190 -0
  223. package/dist/primitives/styles.js.map +1 -0
  224. package/dist/primitives/text.d.ts +27 -0
  225. package/dist/primitives/text.d.ts.map +1 -0
  226. package/dist/primitives/text.js +416 -0
  227. package/dist/primitives/text.js.map +1 -0
  228. package/dist/primitives/validate_document.d.ts +24 -0
  229. package/dist/primitives/validate_document.d.ts.map +1 -0
  230. package/dist/primitives/validate_document.js +147 -0
  231. package/dist/primitives/validate_document.js.map +1 -0
  232. package/dist/primitives/xml.d.ts +5 -0
  233. package/dist/primitives/xml.d.ts.map +1 -0
  234. package/dist/primitives/xml.js +19 -0
  235. package/dist/primitives/xml.js.map +1 -0
  236. package/dist/primitives/zip.d.ts +25 -0
  237. package/dist/primitives/zip.d.ts.map +1 -0
  238. package/dist/primitives/zip.js +78 -0
  239. package/dist/primitives/zip.js.map +1 -0
  240. package/dist/shared/docx/DocxArchive.d.ts +94 -0
  241. package/dist/shared/docx/DocxArchive.d.ts.map +1 -0
  242. package/dist/shared/docx/DocxArchive.js +169 -0
  243. package/dist/shared/docx/DocxArchive.js.map +1 -0
  244. package/dist/shared/ooxml/namespaces.d.ts +149 -0
  245. package/dist/shared/ooxml/namespaces.d.ts.map +1 -0
  246. package/dist/shared/ooxml/namespaces.js +224 -0
  247. package/dist/shared/ooxml/namespaces.js.map +1 -0
  248. package/dist/shared/ooxml/types.d.ts +136 -0
  249. package/dist/shared/ooxml/types.d.ts.map +1 -0
  250. package/dist/shared/ooxml/types.js +7 -0
  251. package/dist/shared/ooxml/types.js.map +1 -0
  252. package/package.json +63 -6
@@ -0,0 +1,241 @@
1
+ /**
2
+ * accept_changes — accept all tracked changes in a OOXML document body.
3
+ *
4
+ * Produces a clean document with no revision markup by:
5
+ * - Removing w:del elements and their content
6
+ * - Unwrapping w:ins elements (promoting children)
7
+ * - Removing w:moveFrom (source), unwrapping w:moveTo (destination)
8
+ * - Removing all *PrChange property change records
9
+ * - Stripping paragraph-level revision markers
10
+ * - Cleaning up move range markers and rsidDel attributes
11
+ *
12
+ * Operates on the W3C DOM (`@xmldom/xmldom`) — the same API used
13
+ * throughout docx-primitives-ts (contrast with docx-comparison's
14
+ * custom WmlElement AST).
15
+ */
16
+ import { OOXML } from './namespaces.js';
17
+ const W_NS = OOXML.W_NS;
18
+ // ── DOM helpers (internal) ──────────────────────────────────────────
19
+ function isW(node, localName) {
20
+ return (node.nodeType === 1 &&
21
+ node.namespaceURI === W_NS &&
22
+ node.localName === localName);
23
+ }
24
+ function isWElement(node) {
25
+ return node.nodeType === 1 && node.namespaceURI === W_NS;
26
+ }
27
+ function getDepth(node) {
28
+ let depth = 0;
29
+ let cur = node.parentNode;
30
+ while (cur) {
31
+ depth++;
32
+ cur = cur.parentNode;
33
+ }
34
+ return depth;
35
+ }
36
+ function collectByLocalName(container, localName) {
37
+ return Array.from(container.getElementsByTagNameNS(W_NS, localName));
38
+ }
39
+ function removeAllByLocalName(container, localName) {
40
+ const elements = collectByLocalName(container, localName);
41
+ let count = 0;
42
+ for (const el of elements) {
43
+ if (el.parentNode) {
44
+ el.parentNode.removeChild(el);
45
+ count++;
46
+ }
47
+ }
48
+ return count;
49
+ }
50
+ function unwrapAllByLocalName(container, localName) {
51
+ const elements = collectByLocalName(container, localName);
52
+ // Sort deepest-first to handle nested wrappers correctly
53
+ elements.sort((a, b) => getDepth(b) - getDepth(a));
54
+ let count = 0;
55
+ for (const el of elements) {
56
+ const parent = el.parentNode;
57
+ if (!parent)
58
+ continue;
59
+ // Promote all children to the parent
60
+ while (el.firstChild) {
61
+ parent.insertBefore(el.firstChild, el);
62
+ }
63
+ parent.removeChild(el);
64
+ count++;
65
+ }
66
+ return count;
67
+ }
68
+ /**
69
+ * Check if a paragraph has a paragraph-level revision marker.
70
+ * Pattern: w:p > w:pPr > w:rPr > w:del (or w:ins)
71
+ */
72
+ function paragraphHasParaMarker(p, markerLocalName) {
73
+ for (let i = 0; i < p.childNodes.length; i++) {
74
+ const child = p.childNodes[i];
75
+ if (!isW(child, 'pPr'))
76
+ continue;
77
+ for (let j = 0; j < child.childNodes.length; j++) {
78
+ const pPrChild = child.childNodes[j];
79
+ if (!isW(pPrChild, 'rPr'))
80
+ continue;
81
+ for (let k = 0; k < pPrChild.childNodes.length; k++) {
82
+ const rPrChild = pPrChild.childNodes[k];
83
+ if (isW(rPrChild, markerLocalName))
84
+ return true;
85
+ }
86
+ }
87
+ }
88
+ return false;
89
+ }
90
+ /**
91
+ * Check if a node (or its descendants) contains any w:r elements.
92
+ */
93
+ function containsRun(node) {
94
+ if (isW(node, 'r'))
95
+ return true;
96
+ for (let i = 0; i < node.childNodes.length; i++) {
97
+ if (containsRun(node.childNodes[i]))
98
+ return true;
99
+ }
100
+ return false;
101
+ }
102
+ // Tags that are "removed" content — should not count as live content
103
+ const REMOVED_LOCALS = new Set(['del', 'moveFrom']);
104
+ // Tags that are "kept" content — their presence means the paragraph has live content
105
+ const KEPT_LOCALS = new Set(['ins', 'moveTo']);
106
+ // Range marker tags to ignore when scanning paragraph children
107
+ const RANGE_MARKER_LOCALS = new Set([
108
+ 'moveFromRangeStart', 'moveFromRangeEnd',
109
+ 'moveToRangeStart', 'moveToRangeEnd',
110
+ ]);
111
+ /**
112
+ * Determine if a paragraph's only content lives inside w:del or w:moveFrom
113
+ * (no w:r outside those wrappers, and no w:ins/w:moveTo siblings).
114
+ */
115
+ function paragraphHasOnlyRemovedContent(p) {
116
+ for (let i = 0; i < p.childNodes.length; i++) {
117
+ const child = p.childNodes[i];
118
+ if (child.nodeType !== 1)
119
+ continue;
120
+ const el = child;
121
+ if (el.namespaceURI !== W_NS)
122
+ continue;
123
+ const local = el.localName;
124
+ // If the paragraph has kept content wrappers, it stays
125
+ if (KEPT_LOCALS.has(local))
126
+ return false;
127
+ // Skip pPr, range markers, and removed wrappers — they don't contribute live content
128
+ if (local === 'pPr' || RANGE_MARKER_LOCALS.has(local) || REMOVED_LOCALS.has(local))
129
+ continue;
130
+ // A bare w:r or any other element that contains runs means live content
131
+ if (local === 'r' || containsRun(el))
132
+ return false;
133
+ }
134
+ // We passed all children without finding live content — but there must be
135
+ // at least one removed wrapper for this to be a "removed content" paragraph
136
+ for (let i = 0; i < p.childNodes.length; i++) {
137
+ const child = p.childNodes[i];
138
+ if (child.nodeType === 1 && isWElement(child) && REMOVED_LOCALS.has(child.localName)) {
139
+ return true;
140
+ }
141
+ }
142
+ return false;
143
+ }
144
+ // Property change element local names (all 6 types)
145
+ const PR_CHANGE_LOCALS = [
146
+ 'rPrChange', 'pPrChange', 'sectPrChange',
147
+ 'tblPrChange', 'trPrChange', 'tcPrChange',
148
+ ];
149
+ // ── Public API ──────────────────────────────────────────────────────
150
+ /**
151
+ * Accept all tracked changes in the document body, producing a clean
152
+ * document with no revision markup.
153
+ *
154
+ * Mutates the Document in place (same convention as simplifyRedlines
155
+ * and mergeRuns).
156
+ */
157
+ export function acceptChanges(doc) {
158
+ const body = doc.getElementsByTagNameNS(W_NS, 'body').item(0);
159
+ if (!body) {
160
+ return { insertionsAccepted: 0, deletionsAccepted: 0, movesResolved: 0, propertyChangesResolved: 0 };
161
+ }
162
+ // Phase A — Identify paragraphs to remove
163
+ const paragraphsToRemove = new Set();
164
+ const allParagraphs = collectByLocalName(body, 'p');
165
+ for (const p of allParagraphs) {
166
+ // Paragraph-level deletion marker: w:p > w:pPr > w:rPr > w:del
167
+ if (paragraphHasParaMarker(p, 'del')) {
168
+ paragraphsToRemove.add(p);
169
+ continue;
170
+ }
171
+ // Paragraphs whose only content is inside w:del or w:moveFrom
172
+ if (paragraphHasOnlyRemovedContent(p)) {
173
+ paragraphsToRemove.add(p);
174
+ }
175
+ }
176
+ // Phase B — Remove deletions and move sources
177
+ const deletionsAccepted = removeAllByLocalName(body, 'del');
178
+ const moveFromRemoved = removeAllByLocalName(body, 'moveFrom');
179
+ removeAllByLocalName(body, 'moveFromRangeStart');
180
+ removeAllByLocalName(body, 'moveFromRangeEnd');
181
+ removeAllByLocalName(body, 'moveToRangeStart');
182
+ removeAllByLocalName(body, 'moveToRangeEnd');
183
+ // Phase C — Unwrap insertions and move destinations (depth-sorted)
184
+ const insertionsAccepted = unwrapAllByLocalName(body, 'ins');
185
+ const moveToUnwrapped = unwrapAllByLocalName(body, 'moveTo');
186
+ // Phase D — Remove property change records
187
+ let propertyChangesResolved = 0;
188
+ for (const localName of PR_CHANGE_LOCALS) {
189
+ propertyChangesResolved += removeAllByLocalName(body, localName);
190
+ }
191
+ // Phase E — Cleanup
192
+ // Strip paragraph-level revision markers from w:pPr/w:rPr
193
+ for (const p of collectByLocalName(body, 'p')) {
194
+ for (let i = 0; i < p.childNodes.length; i++) {
195
+ const child = p.childNodes[i];
196
+ if (!isW(child, 'pPr'))
197
+ continue;
198
+ for (let j = 0; j < child.childNodes.length; j++) {
199
+ const pPrChild = child.childNodes[j];
200
+ if (!isW(pPrChild, 'rPr'))
201
+ continue;
202
+ // Remove w:ins and w:del marker elements inside pPr > rPr
203
+ const toRemove = [];
204
+ for (let k = 0; k < pPrChild.childNodes.length; k++) {
205
+ const rPrChild = pPrChild.childNodes[k];
206
+ if (isW(rPrChild, 'ins') || isW(rPrChild, 'del')) {
207
+ toRemove.push(rPrChild);
208
+ }
209
+ }
210
+ for (const el of toRemove) {
211
+ pPrChild.removeChild(el);
212
+ }
213
+ }
214
+ }
215
+ }
216
+ // Remove paragraphs collected in Phase A (check parentNode still exists)
217
+ for (const p of paragraphsToRemove) {
218
+ if (p.parentNode) {
219
+ p.parentNode.removeChild(p);
220
+ }
221
+ }
222
+ // Strip w:rsidDel attributes on remaining elements
223
+ const allElements = body.getElementsByTagNameNS(W_NS, '*');
224
+ for (let i = 0; i < allElements.length; i++) {
225
+ const el = allElements[i];
226
+ if (el.hasAttributeNS(W_NS, 'rsidDel')) {
227
+ el.removeAttributeNS(W_NS, 'rsidDel');
228
+ }
229
+ // Also check prefixed form
230
+ if (el.hasAttribute('w:rsidDel')) {
231
+ el.removeAttribute('w:rsidDel');
232
+ }
233
+ }
234
+ return {
235
+ insertionsAccepted,
236
+ deletionsAccepted,
237
+ movesResolved: moveFromRemoved + moveToUnwrapped,
238
+ propertyChangesResolved,
239
+ };
240
+ }
241
+ //# sourceMappingURL=accept_changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept_changes.js","sourceRoot":"","sources":["../../src/primitives/accept_changes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export type ParagraphBookmark = {
2
+ name: string;
3
+ numericId: number;
4
+ };
5
+ export declare function getParagraphBookmarkId(p: Element): string | null;
6
+ export declare function cleanupInternalBookmarks(doc: Document): number;
7
+ export declare function insertParagraphBookmarks(doc: Document, _attachmentId: string): {
8
+ indexedParagraphs: number;
9
+ };
10
+ export declare function insertSingleParagraphBookmark(doc: Document, p: Element): string;
11
+ export declare function findParagraphByBookmarkId(doc: Document, bookmarkId: string): Element | null;
12
+ //# sourceMappingURL=bookmarks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bookmarks.d.ts","sourceRoot":"","sources":["../../src/primitives/bookmarks.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAwHF,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CA+BhE;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAuB9D;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,GAAG;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAkD5G;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,GAAG,MAAM,CAoC/E;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAO3F"}
@@ -0,0 +1,248 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { OOXML, W } from './namespaces.js';
3
+ import { getParagraphText } from './text.js';
4
+ const W14_NS = 'http://schemas.microsoft.com/office/word/2010/wordml';
5
+ function sha12(input) {
6
+ return createHash('sha1').update(input).digest('hex').slice(0, 12);
7
+ }
8
+ function normalizeText(value) {
9
+ return (value ?? '').replace(/\s+/g, ' ').trim().toLowerCase();
10
+ }
11
+ function ancestorSignature(p) {
12
+ const parts = [];
13
+ let cur = p.parentElement;
14
+ while (cur) {
15
+ parts.push(cur.localName ?? cur.nodeName);
16
+ // Body/document boundary is enough context.
17
+ if (cur.namespaceURI === OOXML.W_NS && (cur.localName === W.body || cur.localName === W.document))
18
+ break;
19
+ cur = cur.parentElement;
20
+ }
21
+ return parts.join('/');
22
+ }
23
+ function getW14ParaId(p) {
24
+ const namespaced = p.getAttributeNS(W14_NS, 'paraId');
25
+ if (namespaced)
26
+ return namespaced.toLowerCase();
27
+ // Fallbacks for XML libraries that may not expose namespaced attributes consistently.
28
+ const prefixed = p.getAttribute('w14:paraId');
29
+ if (prefixed)
30
+ return prefixed.toLowerCase();
31
+ const plain = p.getAttribute('paraId');
32
+ if (plain)
33
+ return plain.toLowerCase();
34
+ return null;
35
+ }
36
+ function buildParagraphSeed(params) {
37
+ const { paragraph, prevText, nextText } = params;
38
+ const intrinsic = getW14ParaId(paragraph);
39
+ if (intrinsic)
40
+ return `intrinsic:w14:${intrinsic}`;
41
+ const text = normalizeText(getParagraphText(paragraph));
42
+ const prev = normalizeText(prevText);
43
+ const next = normalizeText(nextText);
44
+ const ancestors = ancestorSignature(paragraph);
45
+ return `fallback:text=${text}|prev=${prev}|next=${next}|ancestors=${ancestors}`;
46
+ }
47
+ function deriveDeterministicJrParaName(params) {
48
+ const seed = buildParagraphSeed({
49
+ paragraph: params.paragraph,
50
+ prevText: params.prevText,
51
+ nextText: params.nextText,
52
+ });
53
+ let attempt = 0;
54
+ while (attempt < 10_000) {
55
+ const salt = attempt === 0 ? '' : `|salt:${attempt}`;
56
+ const candidate = `_bk_${sha12(`${seed}${salt}`)}`;
57
+ if (!params.usedNames.has(candidate)) {
58
+ params.usedNames.add(candidate);
59
+ return candidate;
60
+ }
61
+ attempt += 1;
62
+ }
63
+ throw new Error('Unable to allocate deterministic _bk_ bookmark name');
64
+ }
65
+ function collectUsedJrParaNames(doc) {
66
+ const used = new Set();
67
+ const starts = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.bookmarkStart));
68
+ for (const s of starts) {
69
+ const name = getAttr(s, 'name');
70
+ if (name && name.startsWith('_bk_'))
71
+ used.add(name);
72
+ }
73
+ return used;
74
+ }
75
+ function getAttr(el, localName) {
76
+ return el.getAttributeNS(OOXML.W_NS, localName) ?? el.getAttribute(`w:${localName}`);
77
+ }
78
+ function prevElementSibling(node) {
79
+ let cur = node?.previousSibling ?? null;
80
+ while (cur) {
81
+ if (cur.nodeType === 1)
82
+ return cur;
83
+ cur = cur.previousSibling;
84
+ }
85
+ return null;
86
+ }
87
+ function nextElementSibling(node) {
88
+ let cur = node?.nextSibling ?? null;
89
+ while (cur) {
90
+ if (cur.nodeType === 1)
91
+ return cur;
92
+ cur = cur.nextSibling;
93
+ }
94
+ return null;
95
+ }
96
+ function isBookmarkStart(el) {
97
+ return el.namespaceURI === OOXML.W_NS && el.localName === W.bookmarkStart;
98
+ }
99
+ function isBookmarkEnd(el) {
100
+ return el.namespaceURI === OOXML.W_NS && el.localName === W.bookmarkEnd;
101
+ }
102
+ function isParagraph(el) {
103
+ return el.namespaceURI === OOXML.W_NS && el.localName === W.p;
104
+ }
105
+ export function getParagraphBookmarkId(p) {
106
+ // Supports:
107
+ // 1) sibling style: <w:bookmarkStart/> <w:p/> <w:bookmarkEnd/>
108
+ // 2) inside style: <w:p><w:bookmarkStart/> ... </w:p>
109
+ // 1) Sibling style lookup.
110
+ // Handle stacked bookmarks (e.g. _bk_* plus edit-*) around the same paragraph.
111
+ // We scan backward across adjacent bookmark nodes until we hit another paragraph.
112
+ const prev = prevElementSibling(p);
113
+ const next = nextElementSibling(p);
114
+ if (prev && next && isBookmarkEnd(next)) {
115
+ let cur = prev;
116
+ while (cur) {
117
+ if (isParagraph(cur))
118
+ break;
119
+ if (isBookmarkStart(cur)) {
120
+ const name = getAttr(cur, 'name');
121
+ if (name && name.startsWith('_bk_'))
122
+ return name;
123
+ }
124
+ cur = prevElementSibling(cur);
125
+ }
126
+ }
127
+ // 2) Inside paragraph lookup (best-effort).
128
+ const starts = p.getElementsByTagNameNS(OOXML.W_NS, W.bookmarkStart);
129
+ for (let i = 0; i < starts.length; i++) {
130
+ const el = starts.item(i);
131
+ const name = el ? getAttr(el, 'name') : null;
132
+ if (name && name.startsWith('_bk_'))
133
+ return name;
134
+ }
135
+ return null;
136
+ }
137
+ export function cleanupInternalBookmarks(doc) {
138
+ // Remove paragraph bookmarks (_bk_*) and edit span bookmarks (edit-*).
139
+ const starts = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.bookmarkStart));
140
+ const ends = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.bookmarkEnd));
141
+ const idsToRemove = new Set();
142
+ for (const s of starts) {
143
+ const name = getAttr(s, 'name') ?? '';
144
+ if (name.startsWith('_bk_') || name.startsWith('edit-')) {
145
+ const id = getAttr(s, 'id') ?? '';
146
+ if (id)
147
+ idsToRemove.add(id);
148
+ s.parentNode?.removeChild(s);
149
+ }
150
+ }
151
+ for (const e of ends) {
152
+ const id = getAttr(e, 'id') ?? '';
153
+ if (id && idsToRemove.has(id)) {
154
+ e.parentNode?.removeChild(e);
155
+ }
156
+ }
157
+ return idsToRemove.size;
158
+ }
159
+ export function insertParagraphBookmarks(doc, _attachmentId) {
160
+ // Insert _bk_* bookmarks around ALL paragraphs (including empty), using sibling style.
161
+ // This avoids moving paragraphs out of tables by inserting into the paragraph's parent.
162
+ const paragraphs = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.p));
163
+ if (paragraphs.length === 0)
164
+ return { indexedParagraphs: 0 };
165
+ const usedNames = collectUsedJrParaNames(doc);
166
+ let maxNumeric = 0;
167
+ const existingStarts = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.bookmarkStart));
168
+ for (const s of existingStarts) {
169
+ const n = getAttr(s, 'id');
170
+ const val = n ? Number.parseInt(n, 10) : NaN;
171
+ if (!Number.isNaN(val))
172
+ maxNumeric = Math.max(maxNumeric, val);
173
+ }
174
+ for (let i = 0; i < paragraphs.length; i++) {
175
+ const p = paragraphs[i];
176
+ if (!isParagraph(p))
177
+ continue;
178
+ const existingName = getParagraphBookmarkId(p);
179
+ if (existingName) {
180
+ usedNames.add(existingName);
181
+ continue;
182
+ }
183
+ const parent = p.parentNode;
184
+ if (!parent)
185
+ continue;
186
+ const numericId = ++maxNumeric;
187
+ const prevText = i > 0 ? getParagraphText(paragraphs[i - 1]) : '';
188
+ const nextText = i + 1 < paragraphs.length ? getParagraphText(paragraphs[i + 1]) : '';
189
+ const name = deriveDeterministicJrParaName({
190
+ paragraph: p,
191
+ prevText,
192
+ nextText,
193
+ usedNames,
194
+ });
195
+ const start = doc.createElementNS(OOXML.W_NS, 'w:bookmarkStart');
196
+ start.setAttributeNS(OOXML.W_NS, 'w:id', String(numericId));
197
+ start.setAttributeNS(OOXML.W_NS, 'w:name', name);
198
+ const end = doc.createElementNS(OOXML.W_NS, 'w:bookmarkEnd');
199
+ end.setAttributeNS(OOXML.W_NS, 'w:id', String(numericId));
200
+ parent.insertBefore(start, p);
201
+ parent.insertBefore(end, p.nextSibling);
202
+ }
203
+ return { indexedParagraphs: paragraphs.length };
204
+ }
205
+ export function insertSingleParagraphBookmark(doc, p) {
206
+ const parent = p.parentNode;
207
+ if (!parent)
208
+ throw new Error('Paragraph has no parent');
209
+ const paragraphs = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.p));
210
+ const idx = paragraphs.indexOf(p);
211
+ const prevText = idx > 0 ? getParagraphText(paragraphs[idx - 1]) : '';
212
+ const nextText = idx >= 0 && idx + 1 < paragraphs.length ? getParagraphText(paragraphs[idx + 1]) : '';
213
+ const usedNames = collectUsedJrParaNames(doc);
214
+ let maxNumeric = 0;
215
+ const existingStarts = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.bookmarkStart));
216
+ for (const s of existingStarts) {
217
+ const n = getAttr(s, 'id');
218
+ const val = n ? Number.parseInt(n, 10) : NaN;
219
+ if (!Number.isNaN(val))
220
+ maxNumeric = Math.max(maxNumeric, val);
221
+ }
222
+ const numericId = maxNumeric + 1;
223
+ const name = deriveDeterministicJrParaName({
224
+ paragraph: p,
225
+ prevText,
226
+ nextText,
227
+ usedNames,
228
+ });
229
+ const start = doc.createElementNS(OOXML.W_NS, 'w:bookmarkStart');
230
+ start.setAttributeNS(OOXML.W_NS, 'w:id', String(numericId));
231
+ start.setAttributeNS(OOXML.W_NS, 'w:name', name);
232
+ const end = doc.createElementNS(OOXML.W_NS, 'w:bookmarkEnd');
233
+ end.setAttributeNS(OOXML.W_NS, 'w:id', String(numericId));
234
+ parent.insertBefore(start, p);
235
+ parent.insertBefore(end, p.nextSibling);
236
+ return name;
237
+ }
238
+ export function findParagraphByBookmarkId(doc, bookmarkId) {
239
+ const paragraphs = Array.from(doc.getElementsByTagNameNS(OOXML.W_NS, W.p));
240
+ for (const p of paragraphs) {
241
+ if (!isParagraph(p))
242
+ continue;
243
+ if (getParagraphBookmarkId(p) === bookmarkId)
244
+ return p;
245
+ }
246
+ return null;
247
+ }
248
+ //# sourceMappingURL=bookmarks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bookmarks.js","sourceRoot":"","sources":["../../src/primitives/bookmarks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAO7C,MAAM,MAAM,GAAG,sDAAsD,CAAC;AAEtE,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,aAAa,CAAC,KAAgC;IACrD,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAU;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,GAAG,GAAmB,CAAC,CAAC,aAAa,CAAC;IAC1C,OAAO,GAAG,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1C,4CAA4C;QAC5C,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,SAAS,KAAK,CAAC,CAAC,QAAQ,CAAC;YAAE,MAAM;QACzG,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC;IAC1B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,CAAU;IAC9B,MAAM,UAAU,GAAG,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtD,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC,WAAW,EAAE,CAAC;IAEhD,sFAAsF;IACtF,MAAM,QAAQ,GAAG,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,MAI3B;IACC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IACjD,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,SAAS;QAAE,OAAO,iBAAiB,SAAS,EAAE,CAAC;IAEnD,MAAM,IAAI,GAAG,aAAa,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC/C,OAAO,iBAAiB,IAAI,SAAS,IAAI,SAAS,IAAI,cAAc,SAAS,EAAE,CAAC;AAClF,CAAC;AAED,SAAS,6BAA6B,CAAC,MAKtC;IACC,MAAM,IAAI,GAAG,kBAAkB,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CAAC;IACH,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,OAAO,GAAG,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACrC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChC,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,CAAC,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAa;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IACnF,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,OAAO,CAAC,EAAW,EAAE,SAAiB;IAC7C,OAAO,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAiB;IAC3C,IAAI,GAAG,GAAgB,IAAI,EAAE,eAAe,IAAI,IAAI,CAAC;IACrD,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAO,GAAc,CAAC;QAC9C,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAiB;IAC3C,IAAI,GAAG,GAAgB,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC;IACjD,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAO,GAAc,CAAC;QAC9C,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC;IACxB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,EAAW;IAClC,OAAO,EAAE,CAAC,YAAY,KAAK,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,aAAa,CAAC;AAC5E,CAAC;AAED,SAAS,aAAa,CAAC,EAAW;IAChC,OAAO,EAAE,CAAC,YAAY,KAAK,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,WAAW,CAAC;AAC1E,CAAC;AAED,SAAS,WAAW,CAAC,EAAW;IAC9B,OAAO,EAAE,CAAC,YAAY,KAAK,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,CAAU;IAC/C,YAAY;IACZ,+DAA+D;IAC/D,sDAAsD;IAEtD,2BAA2B;IAC3B,+EAA+E;IAC/E,kFAAkF;IAClF,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,IAAI,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,GAAG,GAAmB,IAAI,CAAC;QAC/B,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,WAAW,CAAC,GAAG,CAAC;gBAAE,MAAM;YAC5B,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAClC,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,OAAO,IAAI,CAAC;YACnD,CAAC;YACD,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC;IACrE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7C,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;IACnD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAa;IACpD,uEAAuE;IACvE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxD,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,EAAE;gBAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5B,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,EAAE,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9B,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC,IAAI,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAa,EAAE,aAAqB;IAC3E,uFAAuF;IACvF,wFAAwF;IAExF,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAE9C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAC3F,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAAE,SAAS;QAC9B,MAAM,YAAY,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,YAAY,EAAE,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC5B,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC;QAC5B,IAAI,CAAC,MAAM;YAAE,SAAS;QAEtB,MAAM,SAAS,GAAG,EAAE,UAAU,CAAC;QAC/B,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,GAAG,6BAA6B,CAAC;YACzC,SAAS,EAAE,CAAC;YACZ,QAAQ;YACR,QAAQ;YACR,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QACjE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5D,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEjD,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAC7D,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAE1D,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,EAAE,iBAAiB,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,GAAa,EAAE,CAAU;IACrE,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC;IAC5B,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvG,MAAM,SAAS,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAE9C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAC3F,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,GAAG,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,6BAA6B,CAAC;QACzC,SAAS,EAAE,CAAC;QACZ,QAAQ;QACR,QAAQ;QACR,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACjE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEjD,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC7D,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAE1D,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9B,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;IAExC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,GAAa,EAAE,UAAkB;IACzE,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAAE,SAAS;QAC9B,IAAI,sBAAsB,CAAC,CAAC,CAAC,KAAK,UAAU;YAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * comments — OOXML comment insertion, threaded replies, and part bootstrapping.
3
+ *
4
+ * Creates comment XML parts when missing, inserts comment range markers,
5
+ * and supports threaded replies via commentsExtended.xml.
6
+ */
7
+ import { DocxZip } from './zip.js';
8
+ export type BootstrapResult = {
9
+ partsCreated: string[];
10
+ };
11
+ /**
12
+ * Create missing comment XML parts when a DOCX has no comment infrastructure.
13
+ * Idempotent — skips parts that already exist.
14
+ */
15
+ export declare function bootstrapCommentParts(zip: DocxZip): Promise<BootstrapResult>;
16
+ export type AddCommentParams = {
17
+ paragraphEl: Element;
18
+ start: number;
19
+ end: number;
20
+ author: string;
21
+ text: string;
22
+ initials?: string;
23
+ };
24
+ export type AddCommentResult = {
25
+ commentId: number;
26
+ };
27
+ /**
28
+ * Insert a root comment anchored to a text range within a paragraph.
29
+ *
30
+ * - Allocates next comment ID from existing comments.xml
31
+ * - Inserts commentRangeStart/commentRangeEnd markers in document body
32
+ * - Inserts commentReference run after range end
33
+ * - Adds comment entry to comments.xml
34
+ * - Adds author to people.xml if not present
35
+ */
36
+ export declare function addComment(documentXml: Document, zip: DocxZip, params: AddCommentParams): Promise<AddCommentResult>;
37
+ export type AddCommentReplyParams = {
38
+ parentCommentId: number;
39
+ author: string;
40
+ text: string;
41
+ initials?: string;
42
+ };
43
+ export type AddCommentReplyResult = {
44
+ commentId: number;
45
+ parentCommentId: number;
46
+ };
47
+ /**
48
+ * Add a threaded reply to an existing comment.
49
+ *
50
+ * Replies don't have range markers in the document body.
51
+ * Thread linkage is stored in commentsExtended.xml via paraIdParent.
52
+ */
53
+ export declare function addCommentReply(_documentXml: Document, zip: DocxZip, params: AddCommentReplyParams): Promise<AddCommentReplyResult>;
54
+ export type Comment = {
55
+ id: number;
56
+ author: string;
57
+ date: string;
58
+ initials: string;
59
+ text: string;
60
+ paragraphId: string | null;
61
+ anchoredParagraphId: string | null;
62
+ replies: Comment[];
63
+ };
64
+ /**
65
+ * Read all comments from a document, building a threaded tree.
66
+ *
67
+ * Root comments are returned at the top level; replies are nested under
68
+ * their parent's `replies` array. Thread linkage is resolved via
69
+ * commentsExtended.xml paraIdParent relationships.
70
+ */
71
+ export declare function getComments(zip: DocxZip, documentXml: Document): Promise<Comment[]>;
72
+ /**
73
+ * Get a single comment by ID, searching the full tree including replies.
74
+ */
75
+ export declare function getComment(zip: DocxZip, documentXml: Document, commentId: number): Promise<Comment | null>;
76
+ /**
77
+ * Delete a comment and all its descendants from the document.
78
+ *
79
+ * - Removes comment elements from comments.xml
80
+ * - Removes commentEx entries from commentsExtended.xml (if present)
81
+ * - For root comments: removes commentRangeStart, commentRangeEnd, and
82
+ * commentReference from document.xml (element-level; run removed only if empty)
83
+ * - Transitive cascade: deleting any node also deletes all descendants
84
+ */
85
+ export declare function deleteComment(documentXml: Document, zip: DocxZip, params: {
86
+ commentId: number;
87
+ }): Promise<void>;
88
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/primitives/comments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AA+CnC,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CA0BlF;AA2FD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,WAAW,EAAE,QAAQ,EACrB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA4B3B;AAID,MAAM,MAAM,qBAAqB,GAAG;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,QAAQ,EACtB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAmChC;AA2MD,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAgHzF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAGhH;AAaD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,QAAQ,EACrB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAoGf"}