@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,338 @@
1
+ /**
2
+ * Format Change Detection Module
3
+ *
4
+ * Detects formatting changes (bold, italic, font size, etc.) between
5
+ * documents after LCS comparison. Runs on atoms marked as Equal to
6
+ * identify text that matches but has different formatting.
7
+ *
8
+ * Pipeline position:
9
+ * LCS() → FlattenToAtomList() → detectMovesInAtomList() → detectFormatChangesInAtomList() → CoalesceRecurse()
10
+ *
11
+ * @see design.md Decision 10: Format Change Detection as Post-LCS Phase
12
+ */
13
+ import { CorrelationStatus, DEFAULT_FORMAT_DETECTION_SETTINGS, RUN_PROPERTY_FRIENDLY_NAMES, } from './core-types.js';
14
+ import { getLeafText, childElements } from './primitives/index.js';
15
+ // =============================================================================
16
+ // Run Property Extraction
17
+ // =============================================================================
18
+ /**
19
+ * Extract run properties (w:rPr) from an atom's ancestor elements.
20
+ *
21
+ * Finds the w:r (run) element in ancestors and extracts its w:rPr child.
22
+ *
23
+ * @param atom - The atom to extract properties from
24
+ * @returns The w:rPr element, or null if not found
25
+ *
26
+ * @example
27
+ * // For an atom inside <w:r><w:rPr><w:b/></w:rPr><w:t>text</w:t></w:r>
28
+ * // Returns the <w:rPr><w:b/></w:rPr> element
29
+ */
30
+ export function getRunPropertiesFromAtom(atom) {
31
+ // Find the w:r ancestor element
32
+ const runElement = atom.ancestorElements?.find((a) => a.tagName === 'w:r');
33
+ if (!runElement) {
34
+ return null;
35
+ }
36
+ // Get the rPr child element
37
+ for (const child of childElements(runElement)) {
38
+ if (child.tagName === 'w:rPr')
39
+ return child;
40
+ }
41
+ return null;
42
+ }
43
+ function extractNormalizedProperties(rPr) {
44
+ if (!rPr) {
45
+ return { children: [] };
46
+ }
47
+ const normalizedChildren = childElements(rPr)
48
+ // Remove revision tracking elements
49
+ .filter((e) => e.tagName !== 'w:rPrChange')
50
+ // Sort by tag name for deterministic comparison
51
+ .sort((a, b) => a.tagName.localeCompare(b.tagName))
52
+ // Normalize each child
53
+ .map((e) => {
54
+ const attrs = [];
55
+ for (let i = 0; i < e.attributes.length; i++) {
56
+ const attr = e.attributes[i];
57
+ attrs.push([attr.name, attr.value]);
58
+ }
59
+ attrs.sort(([a], [b]) => a.localeCompare(b));
60
+ const text = getLeafText(e);
61
+ const prop = { tagName: e.tagName, attrs };
62
+ if (text !== undefined)
63
+ prop.text = text;
64
+ return prop;
65
+ });
66
+ return { children: normalizedChildren };
67
+ }
68
+ // =============================================================================
69
+ // Run Property Comparison
70
+ // =============================================================================
71
+ /**
72
+ * Serialize normalized properties to a string for comparison.
73
+ */
74
+ function serializeNormalizedProperties(rPr) {
75
+ const parts = [];
76
+ for (const child of rPr.children) {
77
+ const attrs = child.attrs
78
+ .map(([k, v]) => `${k}="${v}"`)
79
+ .join(' ');
80
+ const textPart = child.text ? `|${child.text}` : '';
81
+ parts.push(`<${child.tagName} ${attrs}${textPart}/>`);
82
+ }
83
+ return parts.join('');
84
+ }
85
+ /**
86
+ * Check if two run properties are equal after normalization.
87
+ */
88
+ export function areRunPropertiesEqual(rPr1, rPr2) {
89
+ const norm1 = extractNormalizedProperties(rPr1);
90
+ const norm2 = extractNormalizedProperties(rPr2);
91
+ return serializeNormalizedProperties(norm1) === serializeNormalizedProperties(norm2);
92
+ }
93
+ // Keep legacy overload for callers that pass WmlElement (= Element)
94
+ export { areRunPropertiesEqual as areNormalizedRunPropertiesEqual };
95
+ // =============================================================================
96
+ // Changed Property Detection
97
+ // =============================================================================
98
+ /**
99
+ * Get the set of property tag names from a normalized rPr.
100
+ */
101
+ function getPropertyTagNames(rPr) {
102
+ return new Set(rPr.children.map((c) => c.tagName));
103
+ }
104
+ /**
105
+ * Find a property element by tag name in a normalized rPr.
106
+ */
107
+ function findPropertyByTag(rPr, tagName) {
108
+ return rPr.children.find((c) => c.tagName === tagName);
109
+ }
110
+ /**
111
+ * Check if two property elements have the same value.
112
+ */
113
+ function arePropertiesValueEqual(prop1, prop2) {
114
+ if (!prop1 && !prop2)
115
+ return true;
116
+ if (!prop1 || !prop2)
117
+ return false;
118
+ const str1 = serializeNormalizedProperties({ children: [prop1] });
119
+ const str2 = serializeNormalizedProperties({ children: [prop2] });
120
+ return str1 === str2;
121
+ }
122
+ /**
123
+ * Get the list of property names that changed between two run properties.
124
+ *
125
+ * Returns friendly names (e.g., "bold", "italic") when available,
126
+ * otherwise returns the OOXML tag name.
127
+ *
128
+ * @param oldRPr - Old run properties element (or null)
129
+ * @param newRPr - New run properties element (or null)
130
+ * @returns Array of changed property names
131
+ */
132
+ export function getChangedPropertyNames(oldRPr, newRPr) {
133
+ const changed = [];
134
+ const normalizedOld = extractNormalizedProperties(oldRPr);
135
+ const normalizedNew = extractNormalizedProperties(newRPr);
136
+ const oldTags = getPropertyTagNames(normalizedOld);
137
+ const newTags = getPropertyTagNames(normalizedNew);
138
+ // All unique tags from both
139
+ const allTags = new Set([...oldTags, ...newTags]);
140
+ for (const tag of allTags) {
141
+ const oldProp = findPropertyByTag(normalizedOld, tag);
142
+ const newProp = findPropertyByTag(normalizedNew, tag);
143
+ if (!arePropertiesValueEqual(oldProp, newProp)) {
144
+ // Use friendly name if available
145
+ const friendlyName = RUN_PROPERTY_FRIENDLY_NAMES[tag] ?? tag;
146
+ changed.push(friendlyName);
147
+ }
148
+ }
149
+ return changed.sort();
150
+ }
151
+ /**
152
+ * Categorize changed properties into added, removed, and modified.
153
+ *
154
+ * @param oldRPr - Old run properties element (or null)
155
+ * @param newRPr - New run properties element (or null)
156
+ * @returns Object with added, removed, and changed arrays
157
+ */
158
+ export function categorizePropertyChanges(oldRPr, newRPr) {
159
+ const added = [];
160
+ const removed = [];
161
+ const changed = [];
162
+ const normalizedOld = extractNormalizedProperties(oldRPr);
163
+ const normalizedNew = extractNormalizedProperties(newRPr);
164
+ const oldTags = getPropertyTagNames(normalizedOld);
165
+ const newTags = getPropertyTagNames(normalizedNew);
166
+ // Check for added properties (in new but not old)
167
+ for (const tag of newTags) {
168
+ if (!oldTags.has(tag)) {
169
+ const friendlyName = RUN_PROPERTY_FRIENDLY_NAMES[tag] ?? tag;
170
+ added.push(friendlyName);
171
+ }
172
+ }
173
+ // Check for removed properties (in old but not new)
174
+ for (const tag of oldTags) {
175
+ if (!newTags.has(tag)) {
176
+ const friendlyName = RUN_PROPERTY_FRIENDLY_NAMES[tag] ?? tag;
177
+ removed.push(friendlyName);
178
+ }
179
+ }
180
+ // Check for changed properties (in both but different value)
181
+ for (const tag of oldTags) {
182
+ if (newTags.has(tag)) {
183
+ const oldProp = findPropertyByTag(normalizedOld, tag);
184
+ const newProp = findPropertyByTag(normalizedNew, tag);
185
+ if (!arePropertiesValueEqual(oldProp, newProp)) {
186
+ const friendlyName = RUN_PROPERTY_FRIENDLY_NAMES[tag] ?? tag;
187
+ changed.push(friendlyName);
188
+ }
189
+ }
190
+ }
191
+ return {
192
+ added: added.sort(),
193
+ removed: removed.sort(),
194
+ changed: changed.sort(),
195
+ };
196
+ }
197
+ // =============================================================================
198
+ // Main Algorithm
199
+ // =============================================================================
200
+ /**
201
+ * Detect format changes in a flat list of atoms.
202
+ *
203
+ * Runs after LCS and move detection to identify Equal atoms where the text
204
+ * matches but formatting differs. Updates atoms in place with format change status.
205
+ *
206
+ * @param atoms - The atom list to process (modified in place)
207
+ * @param settings - Format detection settings (optional, uses defaults)
208
+ */
209
+ export function detectFormatChangesInAtomList(atoms, settings = DEFAULT_FORMAT_DETECTION_SETTINGS) {
210
+ if (!settings.detectFormatChanges) {
211
+ return;
212
+ }
213
+ for (const atom of atoms) {
214
+ // Only check Equal atoms that have a "before" reference
215
+ if (atom.correlationStatus !== CorrelationStatus.Equal) {
216
+ continue;
217
+ }
218
+ if (!atom.comparisonUnitAtomBefore) {
219
+ continue;
220
+ }
221
+ // Extract rPr from both documents
222
+ const oldRPr = getRunPropertiesFromAtom(atom.comparisonUnitAtomBefore);
223
+ const newRPr = getRunPropertiesFromAtom(atom);
224
+ // Compare run properties
225
+ if (!areRunPropertiesEqual(oldRPr, newRPr)) {
226
+ atom.correlationStatus = CorrelationStatus.FormatChanged;
227
+ atom.formatChange = {
228
+ oldRunProperties: oldRPr,
229
+ newRunProperties: newRPr,
230
+ changedProperties: getChangedPropertyNames(oldRPr, newRPr),
231
+ };
232
+ }
233
+ }
234
+ }
235
+ /**
236
+ * Merge format change markup into a run's existing rPr element.
237
+ *
238
+ * Adds the w:rPrChange element as the last child of w:rPr.
239
+ *
240
+ * @param runElement - The w:r element to modify
241
+ * @param rPrChange - The w:rPrChange element to insert
242
+ */
243
+ export function mergeFormatChangeIntoRun(runElement, rPrChange) {
244
+ if (runElement.tagName !== 'w:r') {
245
+ return;
246
+ }
247
+ // Find existing rPr
248
+ let rPr = null;
249
+ for (const child of childElements(runElement)) {
250
+ if (child.tagName === 'w:rPr') {
251
+ rPr = child;
252
+ break;
253
+ }
254
+ }
255
+ if (!rPr) {
256
+ // Create rPr as first child
257
+ const doc = runElement.ownerDocument;
258
+ rPr = doc.createElementNS('http://schemas.openxmlformats.org/wordprocessingml/2006/main', 'w:rPr');
259
+ runElement.insertBefore(rPr, runElement.firstChild);
260
+ }
261
+ // Add rPrChange as last child of rPr
262
+ rPr.appendChild(rPrChange);
263
+ }
264
+ // =============================================================================
265
+ // Paragraph Property Change Support (Future Enhancement)
266
+ // =============================================================================
267
+ /**
268
+ * Extract paragraph properties (w:pPr) from an element.
269
+ *
270
+ * @param paragraphElement - The w:p element
271
+ * @returns The w:pPr element, or null if not found
272
+ */
273
+ export function getParagraphProperties(paragraphElement) {
274
+ if (paragraphElement.tagName !== 'w:p') {
275
+ return null;
276
+ }
277
+ for (const child of childElements(paragraphElement)) {
278
+ if (child.tagName === 'w:pPr')
279
+ return child;
280
+ }
281
+ return null;
282
+ }
283
+ /**
284
+ * Paragraph property friendly names.
285
+ */
286
+ export const PARAGRAPH_PROPERTY_FRIENDLY_NAMES = {
287
+ 'w:jc': 'alignment',
288
+ 'w:ind': 'indentation',
289
+ 'w:spacing': 'spacing',
290
+ 'w:pStyle': 'style',
291
+ 'w:numPr': 'numbering',
292
+ 'w:pBdr': 'borders',
293
+ 'w:shd': 'shading',
294
+ 'w:tabs': 'tabs',
295
+ 'w:keepNext': 'keepWithNext',
296
+ 'w:keepLines': 'keepLinesTogether',
297
+ 'w:pageBreakBefore': 'pageBreakBefore',
298
+ 'w:widowControl': 'widowControl',
299
+ 'w:outlineLvl': 'outlineLevel',
300
+ };
301
+ // =============================================================================
302
+ // Legacy API — kept for backward compatibility during migration
303
+ // =============================================================================
304
+ /**
305
+ * @deprecated Use areRunPropertiesEqual directly with Element params
306
+ */
307
+ export function normalizeRunProperties(rPr) {
308
+ return extractNormalizedProperties(rPr);
309
+ }
310
+ /**
311
+ * @deprecated Use getParagraphProperties directly
312
+ */
313
+ export function normalizeParagraphProperties(pPr) {
314
+ return extractNormalizedProperties(pPr);
315
+ }
316
+ /**
317
+ * @deprecated Removed — use generateFormatChangeMarkup with DOM approach
318
+ */
319
+ export function generateFormatChangeMarkup(formatChange, options) {
320
+ const doc = new (require('@xmldom/xmldom').DOMParser)().parseFromString('<root/>', 'application/xml');
321
+ const dateStr = options.dateTime.toISOString();
322
+ const W_NS = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
323
+ const rPrChange = doc.createElementNS(W_NS, 'w:rPrChange');
324
+ rPrChange.setAttribute('w:id', options.id.toString());
325
+ rPrChange.setAttribute('w:author', options.author);
326
+ rPrChange.setAttribute('w:date', dateStr);
327
+ const rPr = doc.createElementNS(W_NS, 'w:rPr');
328
+ rPrChange.appendChild(rPr);
329
+ if (formatChange.oldRunProperties) {
330
+ for (const child of childElements(formatChange.oldRunProperties)) {
331
+ if (child.tagName === 'w:rPrChange')
332
+ continue;
333
+ rPr.appendChild(child.cloneNode(true));
334
+ }
335
+ }
336
+ return rPrChange;
337
+ }
338
+ //# sourceMappingURL=format-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-detection.js","sourceRoot":"","sources":["../src/format-detection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Document Comparison Engine
3
+ *
4
+ * Provides multiple comparison approaches:
5
+ * - Baseline A: WmlComparer wrapper (Docxodus WASM or dotnet CLI)
6
+ * - Baseline B: Pure TypeScript (diff-match-patch + OOXML renderer) - paragraph level
7
+ * - Atomizer: Pure TypeScript with atom-level comparison, move detection, format detection
8
+ */
9
+ export interface CompareOptions {
10
+ /** Author name for revision tracking. Default: "Comparison" */
11
+ author?: string;
12
+ /**
13
+ * Revision timestamp used for generated track changes (`w:date`).
14
+ * Default: current time.
15
+ */
16
+ date?: Date;
17
+ /** Ignore formatting differences. Default: true (v1) */
18
+ ignoreFormatting?: boolean;
19
+ /**
20
+ * Atomizer-only normalization: merge adjacent <w:r> siblings with identical formatting
21
+ * prior to comparison. This can reduce overly-granular diffs for heavily-fragmented docs.
22
+ *
23
+ * Default: false.
24
+ */
25
+ premergeRuns?: boolean;
26
+ /**
27
+ * How to reconstruct the output DOCX when using the atomizer engine:
28
+ * - 'rebuild': rebuild document.xml from scratch (more reject/accept stable)
29
+ * - 'inplace': modify the revised document AST in place (more experimental)
30
+ *
31
+ * Default: 'rebuild'
32
+ */
33
+ reconstructionMode?: ReconstructionMode;
34
+ /**
35
+ * Comparison engine to use:
36
+ * - 'atomizer': Character-level comparison with move detection (recommended)
37
+ * - 'diffmatch': Paragraph-level comparison (faster, less precise)
38
+ * - 'wmlcomparer': .NET WmlComparer (requires external runtime)
39
+ * - 'auto': Automatically select best available engine (currently 'atomizer')
40
+ *
41
+ * Default: 'auto'
42
+ */
43
+ engine?: 'wmlcomparer' | 'diffmatch' | 'atomizer' | 'auto';
44
+ }
45
+ export interface CompareStats {
46
+ insertions: number;
47
+ deletions: number;
48
+ modifications: number;
49
+ }
50
+ export type ReconstructionMode = 'rebuild' | 'inplace';
51
+ export type ReconstructionFallbackReason = 'round_trip_safety_check_failed';
52
+ export type ReconstructionSafetyCheckName = 'acceptText' | 'rejectText' | 'acceptBookmarks' | 'rejectBookmarks';
53
+ export interface ReconstructionSafetyChecks {
54
+ acceptText: boolean;
55
+ rejectText: boolean;
56
+ acceptBookmarks: boolean;
57
+ rejectBookmarks: boolean;
58
+ }
59
+ export interface ReconstructionTextMismatchDetails {
60
+ expectedLength: number;
61
+ actualLength: number;
62
+ firstDifferingParagraphIndex: number;
63
+ expectedParagraph: string;
64
+ actualParagraph: string;
65
+ differenceSample: string[];
66
+ }
67
+ export interface ReconstructionIdDelta {
68
+ missing: string[];
69
+ unexpected: string[];
70
+ }
71
+ export interface ReconstructionBookmarkMismatchDetails {
72
+ startNames: ReconstructionIdDelta;
73
+ referencedBookmarkNames: ReconstructionIdDelta;
74
+ unresolvedReferenceNames: ReconstructionIdDelta;
75
+ startIds: ReconstructionIdDelta;
76
+ endIds: ReconstructionIdDelta;
77
+ expectedDuplicateStartNames: string[];
78
+ actualDuplicateStartNames: string[];
79
+ expectedDuplicateStartIds: string[];
80
+ actualDuplicateStartIds: string[];
81
+ expectedDuplicateEndIds: string[];
82
+ actualDuplicateEndIds: string[];
83
+ expectedUnmatchedStartIds: string[];
84
+ actualUnmatchedStartIds: string[];
85
+ expectedUnmatchedEndIds: string[];
86
+ actualUnmatchedEndIds: string[];
87
+ }
88
+ export interface ReconstructionSafetyFailureDetails {
89
+ acceptText?: ReconstructionTextMismatchDetails;
90
+ rejectText?: ReconstructionTextMismatchDetails;
91
+ acceptBookmarks?: ReconstructionBookmarkMismatchDetails;
92
+ rejectBookmarks?: ReconstructionBookmarkMismatchDetails;
93
+ }
94
+ export interface ReconstructionIdDeltaSummary {
95
+ missingCount: number;
96
+ unexpectedCount: number;
97
+ firstMissing?: string;
98
+ firstUnexpected?: string;
99
+ }
100
+ export interface ReconstructionTextMismatchSummary {
101
+ firstDifferingParagraphIndex: number;
102
+ expectedParagraph: string;
103
+ actualParagraph: string;
104
+ firstDifference: string;
105
+ }
106
+ export interface ReconstructionBookmarkMismatchSummary {
107
+ startNames: ReconstructionIdDeltaSummary;
108
+ referencedBookmarkNames: ReconstructionIdDeltaSummary;
109
+ unresolvedReferenceNames: ReconstructionIdDeltaSummary;
110
+ startIds: ReconstructionIdDeltaSummary;
111
+ endIds: ReconstructionIdDeltaSummary;
112
+ unmatchedStartCount: number;
113
+ unmatchedEndCount: number;
114
+ firstUnmatchedStartId?: string;
115
+ firstUnmatchedEndId?: string;
116
+ }
117
+ export interface ReconstructionSafetyFailureSummary {
118
+ acceptText?: ReconstructionTextMismatchSummary;
119
+ rejectText?: ReconstructionTextMismatchSummary;
120
+ acceptBookmarks?: ReconstructionBookmarkMismatchSummary;
121
+ rejectBookmarks?: ReconstructionBookmarkMismatchSummary;
122
+ }
123
+ export interface ReconstructionAttemptDiagnostics {
124
+ pass: 'inplace_word_split' | 'inplace_run_level' | 'inplace_word_split_cross_run' | 'inplace_run_level_cross_run';
125
+ checks: ReconstructionSafetyChecks;
126
+ failedChecks: ReconstructionSafetyCheckName[];
127
+ failureDetails?: ReconstructionSafetyFailureDetails;
128
+ firstDiffSummary?: ReconstructionSafetyFailureSummary;
129
+ }
130
+ export interface ReconstructionFallbackDiagnostics {
131
+ attempts: ReconstructionAttemptDiagnostics[];
132
+ }
133
+ export interface CompareResult {
134
+ /** The resulting DOCX with track changes */
135
+ document: Buffer;
136
+ /** Statistics about the comparison */
137
+ stats: CompareStats;
138
+ /** Which engine was used */
139
+ engine: 'wmlcomparer' | 'diffmatch' | 'atomizer';
140
+ /**
141
+ * Requested reconstruction mode. Present for atomizer outputs.
142
+ */
143
+ reconstructionModeRequested?: ReconstructionMode;
144
+ /**
145
+ * Actual reconstruction mode used to produce the output. Present for atomizer outputs.
146
+ */
147
+ reconstructionModeUsed?: ReconstructionMode;
148
+ /**
149
+ * Why the requested reconstruction mode could not be used.
150
+ * Present only when atomizer falls back.
151
+ */
152
+ fallbackReason?: ReconstructionFallbackReason;
153
+ /**
154
+ * Detailed safety-check diagnostics for fallback decisions.
155
+ * Present only when atomizer falls back.
156
+ */
157
+ fallbackDiagnostics?: ReconstructionFallbackDiagnostics;
158
+ }
159
+ /**
160
+ * Compare two DOCX documents and produce a document with track changes.
161
+ *
162
+ * @param original - The original document (Buffer)
163
+ * @param revised - The revised document (Buffer)
164
+ * @param options - Comparison options
165
+ * @returns The comparison result with track changes markup
166
+ */
167
+ export declare function compareDocuments(original: Buffer, revised: Buffer, options?: CompareOptions): Promise<CompareResult>;
168
+ export * from './shared/ooxml/namespaces.js';
169
+ export * from './shared/ooxml/types.js';
170
+ export * from './core-types.js';
171
+ export * from './atomizer.js';
172
+ export * from './move-detection.js';
173
+ export * from './format-detection.js';
174
+ export * from './numbering.js';
175
+ export * from './footnotes.js';
176
+ export * from './primitives/index.js';
177
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Document Comparison Engine
3
+ *
4
+ * Provides multiple comparison approaches:
5
+ * - Baseline A: WmlComparer wrapper (Docxodus WASM or dotnet CLI)
6
+ * - Baseline B: Pure TypeScript (diff-match-patch + OOXML renderer) - paragraph level
7
+ * - Atomizer: Pure TypeScript with atom-level comparison, move detection, format detection
8
+ */
9
+ import { compareDocumentsBaselineB } from './baselines/diffmatch/pipeline.js';
10
+ import { compareDocumentsAtomizer } from './baselines/atomizer/pipeline.js';
11
+ /**
12
+ * Compare two DOCX documents and produce a document with track changes.
13
+ *
14
+ * @param original - The original document (Buffer)
15
+ * @param revised - The revised document (Buffer)
16
+ * @param options - Comparison options
17
+ * @returns The comparison result with track changes markup
18
+ */
19
+ export async function compareDocuments(original, revised, options = {}) {
20
+ const { engine = 'auto', author, date, reconstructionMode, premergeRuns } = options;
21
+ // Atomizer engine (recommended) - character-level with move detection
22
+ if (engine === 'atomizer' || engine === 'auto') {
23
+ return compareDocumentsAtomizer(original, revised, {
24
+ author,
25
+ date,
26
+ reconstructionMode,
27
+ premergeRuns,
28
+ });
29
+ }
30
+ // Diffmatch engine - paragraph-level (fallback)
31
+ if (engine === 'diffmatch') {
32
+ return compareDocumentsBaselineB(original, revised, { author, date });
33
+ }
34
+ // WmlComparer engine requires --docxodus option at CLI level
35
+ throw new Error('WmlComparer engine is only available through the benchmark CLI. ' +
36
+ 'Use engine: "diffmatch" or "atomizer" for programmatic access.');
37
+ }
38
+ // Re-export shared utilities
39
+ export * from './shared/ooxml/namespaces.js';
40
+ export * from './shared/ooxml/types.js';
41
+ // Re-export core WmlComparer types
42
+ export * from './core-types.js';
43
+ // Re-export atomizer functions
44
+ export * from './atomizer.js';
45
+ // Re-export move detection
46
+ export * from './move-detection.js';
47
+ // Re-export format detection
48
+ export * from './format-detection.js';
49
+ // Re-export numbering utilities
50
+ export * from './numbering.js';
51
+ // Re-export footnote utilities
52
+ export * from './footnotes.js';
53
+ // Re-export primitives (editing, DOM helpers, document operations)
54
+ export * from './primitives/index.js';
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAiL5E;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,OAAe,EACf,UAA0B,EAAE;IAE5B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEpF,sEAAsE;IACtE,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAC/C,OAAO,wBAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE;YACjD,MAAM;YACN,IAAI;YACJ,kBAAkB;YAClB,YAAY;SACb,CAAC,CAAC;IACL,CAAC;IAED,gDAAgD;IAChD,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3B,OAAO,yBAAyB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,6DAA6D;IAC7D,MAAM,IAAI,KAAK,CACb,kEAAkE;QAClE,gEAAgE,CACjE,CAAC;AACJ,CAAC;AAED,6BAA6B;AAC7B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AAExC,mCAAmC;AACnC,cAAc,iBAAiB,CAAC;AAEhC,+BAA+B;AAC/B,cAAc,eAAe,CAAC;AAE9B,2BAA2B;AAC3B,cAAc,qBAAqB,CAAC;AAEpC,6BAA6B;AAC7B,cAAc,uBAAuB,CAAC;AAEtC,gCAAgC;AAChC,cAAc,gBAAgB,CAAC;AAE/B,+BAA+B;AAC/B,cAAc,gBAAgB,CAAC;AAE/B,mEAAmE;AACnE,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const WRITE_TRACKED_OUTPUT_FIXTURES: boolean;
2
+ export declare const FIXTURE_STABLE_DATE: Date;
3
+ export declare function getIntegrationOutputDir(): string;
4
+ export declare function getIntegrationOutputModeLabel(): string;
5
+ export declare function writeIntegrationArtifact(fileName: string, data: string | NodeJS.ArrayBufferView): Promise<string>;
6
+ //# sourceMappingURL=output-artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-artifacts.d.ts","sourceRoot":"","sources":["../../src/integration/output-artifacts.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,6BAA6B,SAA0C,CAAC;AACrF,eAAO,MAAM,mBAAmB,MAAmC,CAAC;AAEpE,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAEtD;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,eAAe,GACpC,OAAO,CAAC,MAAM,CAAC,CAMjB"}
@@ -0,0 +1,30 @@
1
+ import { mkdir, writeFile } from 'fs/promises';
2
+ import { tmpdir } from 'os';
3
+ import { dirname, join } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ const integrationDir = dirname(fileURLToPath(import.meta.url));
6
+ const trackedOutputDir = join(integrationDir, '../testing/outputs');
7
+ const tempOutputDir = join(tmpdir(), 'safe-docx', 'docx-comparison', 'integration-outputs');
8
+ function envEnabled(name) {
9
+ const value = process.env[name];
10
+ if (!value)
11
+ return false;
12
+ const normalized = value.trim().toLowerCase();
13
+ return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
14
+ }
15
+ export const WRITE_TRACKED_OUTPUT_FIXTURES = envEnabled('SDX_WRITE_OUTPUT_FIXTURES');
16
+ export const FIXTURE_STABLE_DATE = new Date('2024-01-01T00:00:00Z');
17
+ export function getIntegrationOutputDir() {
18
+ return WRITE_TRACKED_OUTPUT_FIXTURES ? trackedOutputDir : tempOutputDir;
19
+ }
20
+ export function getIntegrationOutputModeLabel() {
21
+ return WRITE_TRACKED_OUTPUT_FIXTURES ? 'tracked fixtures' : 'temporary outputs';
22
+ }
23
+ export async function writeIntegrationArtifact(fileName, data) {
24
+ const outputDir = getIntegrationOutputDir();
25
+ await mkdir(outputDir, { recursive: true });
26
+ const outputPath = join(outputDir, fileName);
27
+ await writeFile(outputPath, data);
28
+ return outputPath;
29
+ }
30
+ //# sourceMappingURL=output-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-artifacts.js","sourceRoot":"","sources":["../../src/integration/output-artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAC;AACpE,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;AAE5F,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,IAAI,CAAC;AACpG,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAG,UAAU,CAAC,2BAA2B,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAEpE,MAAM,UAAU,uBAAuB;IACrC,OAAO,6BAA6B,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,OAAO,6BAA6B,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,mBAAmB,CAAC;AAClF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,QAAgB,EAChB,IAAqC;IAErC,MAAM,SAAS,GAAG,uBAAuB,EAAE,CAAC;IAC5C,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,UAAU,CAAC;AACpB,CAAC"}