@beyondwork/docx-react-component 1.0.67 → 1.0.70

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 (384) hide show
  1. package/README.md +75 -932
  2. package/package.json +26 -27
  3. package/src/api/anchor-conversion.ts +43 -0
  4. package/src/api/editor-state-types.ts +2 -1
  5. package/src/api/public-types.ts +504 -101
  6. package/src/api/session-state.ts +4 -0
  7. package/src/api/v3/README.md +91 -0
  8. package/src/api/v3/_create.ts +146 -0
  9. package/src/api/v3/_layer-metadata.ts +362 -0
  10. package/src/api/v3/_mocks.ts +84 -0
  11. package/src/api/v3/_runtime-handle.ts +162 -0
  12. package/src/api/v3/_ux-response.ts +73 -0
  13. package/src/api/v3/ai/_metadata-audit.ts +225 -0
  14. package/src/api/v3/ai/attach.ts +235 -0
  15. package/src/api/v3/ai/bundle.ts +132 -0
  16. package/src/api/v3/ai/explain.ts +144 -0
  17. package/src/api/v3/ai/export.ts +54 -0
  18. package/src/api/v3/ai/inspect.ts +118 -0
  19. package/src/api/v3/ai/policy.ts +77 -0
  20. package/src/api/v3/ai/replacement.ts +341 -0
  21. package/src/api/v3/ai/resolve.ts +133 -0
  22. package/src/api/v3/index.ts +79 -0
  23. package/src/api/v3/runtime/chart.ts +310 -0
  24. package/src/api/v3/runtime/clipboard.ts +81 -0
  25. package/src/api/v3/runtime/collab.ts +331 -0
  26. package/src/api/v3/runtime/content.ts +236 -0
  27. package/src/api/v3/runtime/document.ts +282 -0
  28. package/src/api/v3/runtime/formatting.ts +186 -0
  29. package/src/api/v3/runtime/geometry.ts +349 -0
  30. package/src/api/v3/runtime/layout.ts +108 -0
  31. package/src/api/v3/runtime/review.ts +129 -0
  32. package/src/api/v3/runtime/search.ts +74 -0
  33. package/src/api/v3/runtime/table.ts +63 -0
  34. package/src/api/v3/runtime/workflow.ts +434 -0
  35. package/src/api/v3/ui/_context.ts +86 -0
  36. package/src/api/v3/ui/_create.ts +65 -0
  37. package/src/api/v3/ui/_types.ts +520 -0
  38. package/src/api/v3/ui/chrome-composition.ts +342 -0
  39. package/src/{ui-tailwind/chrome → api/v3/ui}/chrome-preset-model.ts +11 -1
  40. package/src/api/v3/ui/chrome.ts +476 -0
  41. package/src/api/v3/ui/debug.ts +124 -0
  42. package/src/api/v3/ui/index.ts +64 -0
  43. package/src/api/v3/ui/overlays-visibility.ts +170 -0
  44. package/src/api/v3/ui/overlays.ts +427 -0
  45. package/src/api/v3/ui/scope.ts +71 -0
  46. package/src/api/v3/ui/session.ts +100 -0
  47. package/src/api/v3/ui/surface.ts +170 -0
  48. package/src/api/v3/ui/viewport.ts +303 -0
  49. package/src/core/commands/index.ts +28 -6
  50. package/src/core/commands/list-commands.ts +3 -2
  51. package/src/core/commands/section-layout-commands.ts +9 -8
  52. package/src/core/schema/text-schema.ts +16 -0
  53. package/src/core/selection/mapping.ts +33 -72
  54. package/src/core/state/editor-state.ts +96 -189
  55. package/src/index.ts +23 -4
  56. package/src/io/chart-preview-resolver.ts +1 -1
  57. package/src/io/docx-session.ts +36 -4797
  58. package/src/io/export/build-app-properties-xml.ts +1 -1
  59. package/src/io/export/serialize-comments.ts +1 -1
  60. package/src/io/export/serialize-headers-footers.ts +6 -1
  61. package/src/io/export/serialize-main-document.ts +45 -0
  62. package/src/io/export/serialize-run-formatting.ts +17 -2
  63. package/src/io/export/twip.ts +1 -1
  64. package/src/io/normalize/normalize-text.ts +27 -20
  65. package/src/io/ooxml/chart/parse-series.ts +1 -1
  66. package/src/io/ooxml/chart/resolve-color.ts +2 -2
  67. package/src/io/ooxml/chart/types.ts +1 -1
  68. package/src/io/ooxml/classify-embedding.ts +83 -33
  69. package/src/io/ooxml/parse-fill.ts +1 -1
  70. package/src/io/ooxml/parse-main-document.ts +71 -1
  71. package/src/io/ooxml/parse-object.ts +14 -10
  72. package/src/io/ooxml/parse-run-formatting.ts +47 -1
  73. package/src/io/ooxml/property-grab-bag.ts +2 -2
  74. package/src/io/ooxml/units.ts +11 -0
  75. package/src/io/ooxml/workflow-payload.ts +282 -7
  76. package/src/model/anchor.ts +85 -0
  77. package/src/model/canonical-document.ts +351 -15
  78. package/src/model/chart-types.ts +1 -1
  79. package/src/model/layout/index.ts +83 -0
  80. package/src/model/layout/page-graph-types.ts +181 -0
  81. package/src/model/layout/page-layout-snapshot.ts +105 -0
  82. package/src/model/layout/resolved-layout-types.ts +47 -0
  83. package/src/model/layout/runtime-page-graph-types.ts +102 -0
  84. package/src/model/paragraph-scope-ids.ts +72 -0
  85. package/src/model/review/comment-types.ts +112 -0
  86. package/src/model/review/index.ts +2 -0
  87. package/src/model/review/revision-types.ts +215 -0
  88. package/src/model/snapshot.ts +32 -0
  89. package/src/review/store/comment-store.ts +21 -47
  90. package/src/review/store/revision-types.ts +40 -198
  91. package/src/runtime/collab/base-doc-fingerprint.ts +6 -1
  92. package/src/runtime/collab/runtime-collab-sync.ts +13 -3
  93. package/src/runtime/collab-session.ts +1 -1
  94. package/src/runtime/debug/build-debug-inspector-snapshot.ts +686 -0
  95. package/src/runtime/debug/event-ring-buffer.ts +64 -0
  96. package/src/runtime/debug/probability-sampler.ts +18 -0
  97. package/src/runtime/debug/runtime-debug-facet.ts +67 -0
  98. package/src/runtime/debug/stage-tokens.ts +31 -0
  99. package/src/runtime/debug/telemetry-bus.ts +271 -0
  100. package/src/runtime/debug/types.ts +275 -0
  101. package/src/runtime/debug/wrap-ref-for-telemetry.ts +118 -0
  102. package/src/runtime/document-layout.ts +8 -6
  103. package/src/runtime/document-runtime.ts +843 -1141
  104. package/src/runtime/document-search.ts +1 -1
  105. package/src/runtime/edit-ops/index.ts +1 -1
  106. package/src/runtime/external-send-runtime.ts +1 -1
  107. package/src/runtime/formatting/document-lookup.ts +235 -0
  108. package/src/runtime/formatting/field/registry.ts +41 -0
  109. package/src/runtime/{field-resolver.ts → formatting/field/resolver.ts} +27 -2
  110. package/src/runtime/formatting/font-resolution.ts +83 -0
  111. package/src/runtime/formatting/formatting-context.ts +903 -0
  112. package/src/runtime/formatting/formatting-types.ts +157 -0
  113. package/src/runtime/{hyperlink-color-resolver.ts → formatting/hyperlink-color.ts} +2 -2
  114. package/src/runtime/formatting/index.ts +125 -0
  115. package/src/runtime/{resolved-numbering-geometry.ts → formatting/numbering/geometry.ts} +1 -1
  116. package/src/runtime/{numbering-prefix.ts → formatting/numbering/prefix.ts} +170 -3
  117. package/src/runtime/formatting/paragraph-style-resolver.ts +92 -0
  118. package/src/runtime/formatting/projector.ts +75 -0
  119. package/src/runtime/formatting/resolve-effective.ts +407 -0
  120. package/src/runtime/formatting/revision-display.ts +105 -0
  121. package/src/runtime/{paragraph-style-resolver.ts → formatting/style-cascade.ts} +84 -141
  122. package/src/runtime/{table-style-resolver.ts → formatting/table-style-resolver.ts} +1 -1
  123. package/src/runtime/formatting/telemetry-bridge.ts +106 -0
  124. package/src/runtime/{theme-color-resolver.ts → formatting/theme-color.ts} +2 -30
  125. package/src/runtime/geometry/caret-geometry.ts +164 -0
  126. package/src/runtime/geometry/geometry-facet.ts +364 -0
  127. package/src/runtime/geometry/geometry-types.ts +256 -0
  128. package/src/runtime/geometry/hit-test.ts +125 -0
  129. package/src/runtime/geometry/index.ts +71 -0
  130. package/src/runtime/geometry/inert-geometry-facet.ts +43 -0
  131. package/src/runtime/geometry/invalidation.ts +35 -0
  132. package/src/runtime/geometry/object-handles.ts +77 -0
  133. package/src/runtime/geometry/overlay-rects.ts +85 -0
  134. package/src/runtime/geometry/project-anchors.ts +100 -0
  135. package/src/runtime/geometry/project-fragments.ts +216 -0
  136. package/src/runtime/geometry/projector.ts +129 -0
  137. package/src/runtime/geometry/replacement-envelope.ts +130 -0
  138. package/src/runtime/geometry/viewport.ts +218 -0
  139. package/src/runtime/layout/compat-input-ledger.ts +211 -0
  140. package/src/runtime/layout/index.ts +6 -1
  141. package/src/runtime/layout/inert-layout-facet.ts +12 -7
  142. package/src/runtime/layout/layout-engine-instance.ts +189 -11
  143. package/src/runtime/layout/layout-engine-version.ts +450 -1
  144. package/src/runtime/layout/layout-facet-types.ts +60 -0
  145. package/src/runtime/layout/layout-measurement-provider.ts +13 -0
  146. package/src/runtime/layout/measurement-backend-canvas.ts +14 -2
  147. package/src/runtime/layout/measurement-backend-empirical.ts +23 -4
  148. package/src/runtime/layout/page-graph.ts +62 -209
  149. package/src/runtime/layout/page-story-resolver.ts +7 -12
  150. package/src/runtime/layout/paginated-layout-engine.ts +186 -11
  151. package/src/runtime/layout/project-block-fragments.ts +11 -0
  152. package/src/runtime/layout/projector.ts +90 -0
  153. package/src/runtime/layout/public-facet.ts +187 -442
  154. package/src/runtime/layout/resolved-formatting-state.ts +158 -26
  155. package/src/runtime/layout/table-render-plan.ts +1 -1
  156. package/src/runtime/prerender/cache-envelope.ts +6 -1
  157. package/src/runtime/prerender/prerender-document.ts +18 -23
  158. package/src/runtime/render/decoration-resolver.ts +1 -1
  159. package/src/runtime/render/render-frame-types.ts +20 -0
  160. package/src/runtime/render/render-kernel.ts +94 -25
  161. package/src/runtime/scopes/_formatting-seam.ts +262 -0
  162. package/src/runtime/scopes/_scope-dependencies.ts +49 -0
  163. package/src/runtime/scopes/action-validation.ts +356 -0
  164. package/src/runtime/scopes/attach-explanation.ts +102 -0
  165. package/src/runtime/scopes/audit-bundle.ts +71 -0
  166. package/src/runtime/scopes/compile-scope-bundle.ts +163 -0
  167. package/src/runtime/scopes/compile-scope.ts +262 -0
  168. package/src/runtime/scopes/compiler-service.ts +431 -0
  169. package/src/runtime/scopes/create-issue.ts +107 -0
  170. package/src/runtime/scopes/enumerate-scopes.ts +543 -0
  171. package/src/runtime/scopes/evidence.ts +233 -0
  172. package/src/runtime/scopes/index.ts +150 -0
  173. package/src/runtime/scopes/position-map.ts +214 -0
  174. package/src/runtime/scopes/preservation-boundary.ts +91 -0
  175. package/src/runtime/scopes/projector.ts +49 -0
  176. package/src/runtime/scopes/replaceability.ts +87 -0
  177. package/src/runtime/scopes/replacement/apply.ts +228 -0
  178. package/src/runtime/scopes/replacement/compile.ts +59 -0
  179. package/src/runtime/scopes/replacement/propose.ts +42 -0
  180. package/src/runtime/scopes/resolve-reference.ts +347 -0
  181. package/src/runtime/scopes/review-bundle.ts +141 -0
  182. package/src/runtime/scopes/scope-kinds/_paragraph-text.ts +57 -0
  183. package/src/runtime/scopes/scope-kinds/_table-text.ts +42 -0
  184. package/src/runtime/scopes/scope-kinds/comment-thread.ts +59 -0
  185. package/src/runtime/scopes/scope-kinds/field.ts +65 -0
  186. package/src/runtime/scopes/scope-kinds/heading.ts +84 -0
  187. package/src/runtime/scopes/scope-kinds/list-item.ts +77 -0
  188. package/src/runtime/scopes/scope-kinds/paragraph.ts +182 -0
  189. package/src/runtime/scopes/scope-kinds/revision.ts +62 -0
  190. package/src/runtime/scopes/scope-kinds/table-cell.ts +57 -0
  191. package/src/runtime/scopes/scope-kinds/table-row.ts +61 -0
  192. package/src/runtime/scopes/scope-kinds/table.ts +55 -0
  193. package/src/runtime/scopes/scope-range.ts +208 -0
  194. package/src/runtime/scopes/semantic-scope-types.ts +454 -0
  195. package/src/runtime/scopes/workflow-overlap.ts +92 -0
  196. package/src/runtime/selection/index.ts +1 -1
  197. package/src/runtime/structure-ops/fragment-insert.ts +1 -1
  198. package/src/runtime/structure-ops/index.ts +1 -1
  199. package/src/runtime/surface-projection.ts +232 -262
  200. package/src/runtime/units.ts +4 -2
  201. package/src/runtime/workflow/coordinator.ts +1348 -0
  202. package/src/runtime/workflow/derived-scope-resolver.ts +125 -0
  203. package/src/runtime/workflow/index.ts +25 -0
  204. package/src/runtime/workflow/markup-mode-policy.ts +98 -0
  205. package/src/runtime/{workflow-markup.ts → workflow/markup.ts} +6 -6
  206. package/src/runtime/workflow/metadata-persistence.ts +306 -0
  207. package/src/runtime/workflow/metadata-writer.ts +123 -0
  208. package/src/runtime/workflow/overlay-store.ts +690 -0
  209. package/src/runtime/workflow/projector.ts +127 -0
  210. package/src/runtime/{query-scopes.ts → workflow/query-scopes.ts} +3 -3
  211. package/src/runtime/{workflow-rail-segments.ts → workflow/rail/compose.ts} +60 -165
  212. package/src/runtime/workflow/rail/types.ts +198 -0
  213. package/src/runtime/workflow/scope-rail-composer.ts +39 -0
  214. package/src/runtime/{scope-resolver.ts → workflow/scope-resolver.ts} +3 -3
  215. package/src/runtime/workflow/scope-writer.ts +188 -0
  216. package/src/runtime/{tamper-gate.ts → workflow/tamper-gate.ts} +1 -1
  217. package/src/runtime/workflow/visibility-policy.ts +129 -0
  218. package/src/session/_sync-legacy.ts +66 -0
  219. package/src/session/export/embedded-reconstitute.ts +104 -0
  220. package/src/session/export/export-diagnostics.ts +85 -0
  221. package/src/session/export/export-validation.ts +110 -0
  222. package/src/session/export/index.ts +34 -0
  223. package/src/session/export/preservation-reattach.ts +30 -0
  224. package/src/session/export/serialize-dispatch.ts +165 -0
  225. package/src/session/export/stateful-export-pipeline.ts +432 -0
  226. package/src/session/export/stateful-export.ts +684 -0
  227. package/src/session/import/canonical-assembly.ts +227 -0
  228. package/src/session/import/diagnostics-session.ts +54 -0
  229. package/src/session/import/embedded-discovery.ts +225 -0
  230. package/src/session/import/embedded-offload.ts +337 -0
  231. package/src/session/import/import-diagnostics.ts +69 -0
  232. package/src/session/import/loader-types.ts +313 -0
  233. package/src/session/import/loader.ts +1834 -0
  234. package/src/session/import/normalize.ts +195 -0
  235. package/src/session/import/package-parts.ts +217 -0
  236. package/src/session/import/package-read.ts +195 -0
  237. package/src/session/import/parse-orchestration.ts +105 -0
  238. package/src/session/import/part-constants.ts +70 -0
  239. package/src/session/import/part-discovery.ts +94 -0
  240. package/src/session/import/preservation-index.ts +46 -0
  241. package/src/{runtime/read-only-diagnostics-runtime.ts → session/import/read-only-diagnostics.ts} +24 -3
  242. package/src/session/import/review-import.ts +508 -0
  243. package/src/session/import/styles-consolidation.ts +281 -0
  244. package/src/session/import/workflow-scope-import.ts +256 -0
  245. package/src/session/index.ts +37 -0
  246. package/src/session/session-state.ts +69 -0
  247. package/src/session/session.ts +532 -0
  248. package/src/session/shared/protection.ts +228 -0
  249. package/src/session/shared/session-utils.ts +82 -0
  250. package/src/session/types.ts +499 -0
  251. package/src/shell/chart-snapshots.ts +96 -0
  252. package/src/shell/media-previews.ts +85 -0
  253. package/src/shell/overlay-anchor-bridge.ts +53 -0
  254. package/src/shell/paste-adapter.ts +23 -0
  255. package/src/shell/ref-commands.ts +1697 -0
  256. package/src/shell/ref-utilities.ts +48 -0
  257. package/src/shell/search.ts +51 -0
  258. package/src/{ui/editor-runtime-boundary.ts → shell/session-bootstrap.ts} +243 -67
  259. package/src/shell/ui-subscriber-channels.ts +81 -0
  260. package/src/shell/use-collab-sync.ts +116 -0
  261. package/src/ui/WordReviewEditor.tsx +496 -2051
  262. package/src/ui/editor-shell-view.tsx +30 -1
  263. package/src/ui/editor-surface-controller.tsx +49 -1
  264. package/src/ui/headless/revision-decoration-model.ts +83 -0
  265. package/src/{ui-tailwind/chrome → ui/headless}/role-action-sets.ts +1 -1
  266. package/src/ui/headless/scoped-chrome-policy.ts +2 -2
  267. package/src/ui/headless/selection-tool-context.ts +1 -1
  268. package/src/ui/headless/selection-tool-resolver.ts +1 -1
  269. package/src/ui/runtime-shortcut-dispatch.ts +46 -1
  270. package/src/ui/ui-controller-factory.ts +221 -0
  271. package/src/ui-tailwind/chart/ChartSurface.tsx +2 -2
  272. package/src/ui-tailwind/chart/layout/legend-layout.ts +1 -1
  273. package/src/ui-tailwind/chart/layout/plot-area.ts +2 -2
  274. package/src/ui-tailwind/chart/layout/title-layout.ts +1 -1
  275. package/src/ui-tailwind/chart/render/area.tsx +3 -3
  276. package/src/ui-tailwind/chart/render/bar-column.tsx +3 -3
  277. package/src/ui-tailwind/chart/render/bubble.tsx +3 -3
  278. package/src/ui-tailwind/chart/render/combo.tsx +2 -2
  279. package/src/ui-tailwind/chart/render/data-labels.tsx +2 -2
  280. package/src/ui-tailwind/chart/render/font-metrics.ts +2 -2
  281. package/src/ui-tailwind/chart/render/line.tsx +3 -3
  282. package/src/ui-tailwind/chart/render/pie.tsx +6 -6
  283. package/src/ui-tailwind/chart/render/scatter.tsx +3 -3
  284. package/src/ui-tailwind/chart/render/svg-primitives.ts +3 -3
  285. package/src/ui-tailwind/chart/render/unsupported.tsx +2 -2
  286. package/src/ui-tailwind/chrome/build-context-menu-entries.ts +88 -0
  287. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +1 -1
  288. package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +1 -1
  289. package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +1 -1
  290. package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +1 -1
  291. package/src/ui-tailwind/chrome/editor-action-registry.ts +553 -0
  292. package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +182 -0
  293. package/src/ui-tailwind/chrome/local-surface-arbiter.ts +534 -0
  294. package/src/ui-tailwind/chrome/resolve-target-kind.ts +226 -0
  295. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +38 -4
  296. package/src/ui-tailwind/chrome/tw-context-band.tsx +125 -0
  297. package/src/ui-tailwind/chrome/tw-context-menu-portal.tsx +248 -0
  298. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +42 -1
  299. package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +8 -7
  300. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +38 -4
  301. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +104 -6
  302. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +66 -7
  303. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +54 -8
  304. package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +7 -1
  305. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +33 -0
  306. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +78 -1
  307. package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +16 -8
  308. package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +276 -0
  309. package/src/ui-tailwind/chrome/use-context-menu-controller.ts +201 -0
  310. package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +1 -1
  311. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +22 -4
  312. package/src/ui-tailwind/chrome-overlay/tw-comment-balloon-layer.tsx +1 -1
  313. package/src/ui-tailwind/chrome-overlay/tw-locked-block-layer.tsx +1 -1
  314. package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +11 -5
  315. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +197 -3
  316. package/src/ui-tailwind/chrome-overlay/tw-revision-margin-bar-layer.tsx +1 -1
  317. package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +35 -6
  318. package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +24 -16
  319. package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +1 -1
  320. package/src/ui-tailwind/debug/README.md +57 -0
  321. package/src/ui-tailwind/debug/index.ts +3 -0
  322. package/src/ui-tailwind/debug/tw-debug-overlay.tsx +186 -0
  323. package/src/ui-tailwind/debug/tw-debug-presentation.tsx +80 -0
  324. package/src/ui-tailwind/debug/tw-debug-top-bar.tsx +83 -0
  325. package/src/ui-tailwind/editor-surface/chart-node-view.tsx +2 -2
  326. package/src/ui-tailwind/editor-surface/float-wrap-resolver.ts +1 -1
  327. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +135 -10
  328. package/src/ui-tailwind/editor-surface/pm-decorations.ts +40 -13
  329. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +1 -1
  330. package/src/ui-tailwind/editor-surface/pm-schema.ts +1 -1
  331. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +3 -3
  332. package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +1 -1
  333. package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +2 -2
  334. package/src/ui-tailwind/editor-surface/scroll-anchor.ts +91 -9
  335. package/src/ui-tailwind/editor-surface/shape-renderer.ts +1 -1
  336. package/src/ui-tailwind/editor-surface/surface-layer.ts +1 -1
  337. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +1 -1
  338. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +23 -6
  339. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +132 -22
  340. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +1 -1
  341. package/src/ui-tailwind/index.ts +0 -5
  342. package/src/ui-tailwind/overlay-anchor-bridge-context.tsx +33 -0
  343. package/src/ui-tailwind/page-stack/floating-image-overlay-model.ts +66 -29
  344. package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +25 -2
  345. package/src/ui-tailwind/review/comment-markdown-renderer.tsx +15 -0
  346. package/src/ui-tailwind/review/tw-review-rail.tsx +92 -4
  347. package/src/ui-tailwind/review/tw-workflow-tab.tsx +1 -1
  348. package/src/ui-tailwind/review-workspace/page-chrome.ts +210 -0
  349. package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +101 -0
  350. package/src/ui-tailwind/review-workspace/paragraph-layout.ts +115 -0
  351. package/src/ui-tailwind/review-workspace/selection-toolbar-placement.ts +97 -0
  352. package/src/ui-tailwind/review-workspace/tw-review-workspace-navigator.tsx +130 -0
  353. package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +240 -0
  354. package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +59 -0
  355. package/src/ui-tailwind/review-workspace/types.ts +408 -0
  356. package/src/ui-tailwind/review-workspace/use-chrome-policy.ts +104 -0
  357. package/src/ui-tailwind/review-workspace/use-derived-view-state.ts +151 -0
  358. package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +70 -0
  359. package/src/ui-tailwind/review-workspace/use-grabbed-segment-offsets.ts +40 -0
  360. package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +55 -0
  361. package/src/ui-tailwind/review-workspace/use-page-markers.ts +130 -0
  362. package/src/ui-tailwind/review-workspace/use-pm-surface-capture.ts +60 -0
  363. package/src/ui-tailwind/review-workspace/use-review-rail-state.ts +63 -0
  364. package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +170 -0
  365. package/src/ui-tailwind/review-workspace/use-scroll-root-capture.ts +28 -0
  366. package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +113 -0
  367. package/src/ui-tailwind/review-workspace/use-shell-selection-anchor-bridge.ts +120 -0
  368. package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +55 -0
  369. package/src/ui-tailwind/review-workspace/use-viewport-dimensions.ts +43 -0
  370. package/src/ui-tailwind/review-workspace/use-workspace-arbiter.ts +25 -0
  371. package/src/ui-tailwind/review-workspace/use-workspace-composition.ts +86 -0
  372. package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +150 -0
  373. package/src/ui-tailwind/theme/editor-theme.css +25 -0
  374. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -2
  375. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +61 -98
  376. package/src/ui-tailwind/tw-review-workspace.tsx +521 -1802
  377. package/src/ui-tailwind/ui-api-context.tsx +43 -0
  378. package/src/ui-tailwind/ui-shell-channels-context.tsx +49 -0
  379. package/src/validation/compatibility-engine.ts +6 -6
  380. package/src/runtime/styles-cascade.ts +0 -33
  381. package/src/ui-tailwind/chrome/tw-mode-dock.tsx +0 -85
  382. /package/src/runtime/{page-number-format.ts → formatting/field/page-number-format.ts} +0 -0
  383. /package/src/runtime/{ai-action-policy.ts → workflow/ai-action-policy.ts} +0 -0
  384. /package/src/runtime/{scope-tag-registry.ts → workflow/scope-tag-registry.ts} +0 -0
@@ -0,0 +1,508 @@
1
+ /**
2
+ * Review-side import helpers extracted from `src/io/docx-session.ts`
3
+ * (slice 5e-6d). These functions translate parsed OOXML revisions +
4
+ * comments into the canonical review shapes and back into the runtime-
5
+ * facing record map — they are part of the package/session integration
6
+ * surface, not review-layer state management.
7
+ *
8
+ * The module is P6-clean: every cross-layer type reaches through
9
+ * `src/model/**`, never through `src/review/**` or `src/core/**`.
10
+ * Anchor mechanics used here (`createDetachedAnchor`) come from
11
+ * `src/model/anchor.ts`; revision / comment shapes + the pure
12
+ * `getRevisionActionability` predicate come from `src/model/review/`.
13
+ */
14
+
15
+ import { createDetachedAnchor } from "../../model/anchor.ts";
16
+ import type {
17
+ CanonicalDocument,
18
+ CommentThread as CommentThreadRecord,
19
+ OpaqueFragmentRecord,
20
+ RevisionRecord as RuntimeRevisionRecord,
21
+ } from "../../model/canonical-document.ts";
22
+ import type { CommentThread } from "../../model/review/comment-types.ts";
23
+ import {
24
+ getRevisionActionability,
25
+ type RevisionRecord as ReviewRevisionRecord,
26
+ } from "../../model/review/revision-types.ts";
27
+ import type {
28
+ CommentImportDiagnostic,
29
+ ImportedCommentDefinition,
30
+ ParsedCommentsResult,
31
+ } from "../../io/ooxml/parse-comments.ts";
32
+ import type { ParsedRevisionsResult } from "../../io/ooxml/parse-revisions.ts";
33
+ import { serializeRuntimeRevisionsIntoStoryXml } from "../../io/export/serialize-runtime-revisions.ts";
34
+
35
+ type CanonicalDocumentEnvelope = CanonicalDocument;
36
+
37
+ export interface NormalizedImportedCommentsResult extends ParsedCommentsResult {
38
+ preservedDefinitions: readonly ImportedCommentDefinition[];
39
+ }
40
+
41
+ export function normalizeImportedRevisionRecords(
42
+ parsed: ParsedRevisionsResult,
43
+ content: CanonicalDocumentEnvelope["content"],
44
+ opaqueFragments: Record<string, OpaqueFragmentRecord>,
45
+ ): ParsedRevisionsResult {
46
+ const opaqueRanges = Object.values(opaqueFragments).map((fragment) => fragment.lastKnownRange);
47
+ const paragraphRanges = collectCanonicalParagraphRanges(content);
48
+ if (opaqueRanges.length === 0) {
49
+ return {
50
+ ...parsed,
51
+ revisions: parsed.revisions.map((revision) => {
52
+ if (revision.anchor.kind !== "range" || revision.metadata.preserveOnlyReason) {
53
+ return revision;
54
+ }
55
+
56
+ const preserveOnlyReason = getStructuralPreserveOnlyReason(
57
+ revision,
58
+ paragraphRanges,
59
+ );
60
+ if (!preserveOnlyReason) {
61
+ return revision;
62
+ }
63
+
64
+ return {
65
+ ...revision,
66
+ metadata: {
67
+ ...revision.metadata,
68
+ preserveOnlyReason,
69
+ },
70
+ };
71
+ }),
72
+ };
73
+ }
74
+
75
+ return {
76
+ ...parsed,
77
+ revisions: parsed.revisions.map((revision) => {
78
+ const { anchor } = revision;
79
+ if (anchor.kind !== "range" || revision.metadata.preserveOnlyReason) {
80
+ return revision;
81
+ }
82
+
83
+ const preserveOnlyReason =
84
+ getStructuralPreserveOnlyReason(revision, paragraphRanges) ??
85
+ (opaqueRanges.some((range) => rangesIntersect(range, anchor.range))
86
+ ? "Imported revision overlaps preserve-only OOXML and remains preserve-only."
87
+ : undefined);
88
+
89
+ if (!preserveOnlyReason) {
90
+ return revision;
91
+ }
92
+
93
+ return {
94
+ ...revision,
95
+ metadata: {
96
+ ...revision.metadata,
97
+ preserveOnlyReason,
98
+ },
99
+ };
100
+ }),
101
+ };
102
+ }
103
+
104
+ export function normalizeImportedCommentThreads(
105
+ parsed: ParsedCommentsResult,
106
+ opaqueFragments: Record<string, OpaqueFragmentRecord>,
107
+ revisions: readonly ReviewRevisionRecord[],
108
+ ): NormalizedImportedCommentsResult {
109
+ const opaqueRanges = Object.values(opaqueFragments).map((fragment) => fragment.lastKnownRange);
110
+ // Use getRevisionActionability() — not the raw preserveOnlyReason flag — so
111
+ // Lane 7b-promoted shapes (cellIns/cellDel/cellMerge, linked-pair moves) that
112
+ // still carry a default preserveOnlyReason aren't treated as preserve-only
113
+ // for comment-anchor detachment. See revision-types.ts:192-200.
114
+ const preserveOnlyRevisionRanges = revisions.flatMap((revision) => {
115
+ if (
116
+ revision.anchor.kind !== "range" ||
117
+ getRevisionActionability(revision) !== "preserve-only"
118
+ ) {
119
+ return [];
120
+ }
121
+ return [revision.anchor.range];
122
+ });
123
+ const preserveOnlyCommentIds = new Set(parsed.diagnostics.map((diagnostic) => diagnostic.commentId));
124
+ const additionalDiagnostics: CommentImportDiagnostic[] = [];
125
+ const normalizedThreads: CommentThread[] = parsed.threads.map((thread) => {
126
+ const { anchor } = thread;
127
+ if (anchor.kind !== "range") {
128
+ preserveOnlyCommentIds.add(thread.commentId);
129
+ return thread;
130
+ }
131
+
132
+ const opaqueOverlap = opaqueRanges.some((range) => rangesIntersect(range, anchor.range));
133
+ if (opaqueOverlap) {
134
+ preserveOnlyCommentIds.add(thread.commentId);
135
+ additionalDiagnostics.push({
136
+ commentId: thread.commentId,
137
+ code: "opaque_anchor_preserve_only",
138
+ message:
139
+ "Comment anchor intersects preserve-only OOXML content. Thread is visible but detached; anchor cannot be safely remapped.",
140
+ featureClass: "preserve-only",
141
+ detachedReason: "opaque-region" as const,
142
+ actionabilityNote: "The comment body is preserved. The anchor overlaps opaque content that the editor cannot safely modify.",
143
+ });
144
+ return {
145
+ ...thread,
146
+ anchor: createDetachedAnchor(anchor.range, "importAmbiguity"),
147
+ status: "detached",
148
+ metadata: {
149
+ ...thread.metadata,
150
+ detachedReason: "opaque-region",
151
+ actionabilityNote:
152
+ "The comment body is preserved. The anchor overlaps opaque content that the editor cannot safely modify.",
153
+ },
154
+ };
155
+ }
156
+
157
+ const preserveOnlyRevisionOverlap = preserveOnlyRevisionRanges.some((range) =>
158
+ rangesIntersect(range, anchor.range),
159
+ );
160
+ if (preserveOnlyRevisionOverlap) {
161
+ preserveOnlyCommentIds.add(thread.commentId);
162
+ additionalDiagnostics.push({
163
+ commentId: thread.commentId,
164
+ code: "preserve_only_revision_overlap",
165
+ message:
166
+ "Comment anchor overlaps preserve-only review markup. Thread is visible but detached; anchor cannot be safely remapped during editing.",
167
+ featureClass: "preserve-only",
168
+ detachedReason: "revision-overlap" as const,
169
+ actionabilityNote: "The comment body is preserved. The anchor overlaps preserve-only revision markup that the editor cannot safely modify.",
170
+ });
171
+ return {
172
+ ...thread,
173
+ anchor: createDetachedAnchor(anchor.range, "importAmbiguity"),
174
+ status: "detached",
175
+ metadata: {
176
+ ...thread.metadata,
177
+ detachedReason: "revision-overlap",
178
+ actionabilityNote:
179
+ "The comment body is preserved. The anchor overlaps preserve-only revision markup that the editor cannot safely modify.",
180
+ },
181
+ };
182
+ }
183
+
184
+ return thread;
185
+ });
186
+
187
+ return {
188
+ ...parsed,
189
+ threads: normalizedThreads,
190
+ diagnostics: [...parsed.diagnostics, ...additionalDiagnostics],
191
+ definitions: parsed.definitions,
192
+ preservedDefinitions: parsed.definitions.filter((definition) =>
193
+ preserveOnlyCommentIds.has(
194
+ resolveDefinitionRootCommentId(definition, parsed.definitions),
195
+ ),
196
+ ),
197
+ };
198
+ }
199
+
200
+ export function resolveImportedCommentThreadOnTranslation(
201
+ thread: CommentThread,
202
+ timestamp: string,
203
+ ): CommentThread {
204
+ if (thread.status === "resolved") {
205
+ return thread;
206
+ }
207
+ return {
208
+ ...thread,
209
+ status: thread.status === "detached" ? "detached" : "resolved",
210
+ resolution: thread.resolution ?? {
211
+ resolvedAt: timestamp,
212
+ resolvedBy: thread.entries[thread.entries.length - 1]?.authorId ?? thread.createdBy,
213
+ },
214
+ };
215
+ }
216
+
217
+ export function resolveDefinitionRootCommentId(
218
+ definition: ImportedCommentDefinition,
219
+ definitions: readonly ImportedCommentDefinition[],
220
+ ): string {
221
+ if (!definition.parentParaId) {
222
+ return definition.commentId;
223
+ }
224
+
225
+ const definitionsByParaId = new Map(
226
+ definitions
227
+ .filter((candidate) => typeof candidate.paraId === "string")
228
+ .map((candidate) => [candidate.paraId!, candidate]),
229
+ );
230
+ const visited = new Set<string>();
231
+ let current: ImportedCommentDefinition | undefined = definition;
232
+
233
+ while (current?.parentParaId) {
234
+ if (visited.has(current.parentParaId)) {
235
+ break;
236
+ }
237
+ visited.add(current.parentParaId);
238
+ const parent = definitionsByParaId.get(current.parentParaId);
239
+ if (!parent) {
240
+ break;
241
+ }
242
+ current = parent;
243
+ }
244
+
245
+ return current?.commentId ?? definition.commentId;
246
+ }
247
+
248
+ export function getStructuralPreserveOnlyReason(
249
+ revision: ReviewRevisionRecord,
250
+ paragraphRanges: ReadonlyArray<{ start: number; end: number }>,
251
+ ): string | undefined {
252
+ const form = revision.metadata.importedRevisionForm;
253
+ const { anchor } = revision;
254
+ if (!form || anchor.kind !== "range") {
255
+ return undefined;
256
+ }
257
+
258
+ if (
259
+ (form === "run-insertion" || form === "run-deletion") &&
260
+ anchor.range.from === anchor.range.to
261
+ ) {
262
+ return "Imported zero-width run revision remains preserve-only.";
263
+ }
264
+
265
+ if (form === "paragraph-insertion" || form === "paragraph-deletion") {
266
+ const paragraphBoundary = paragraphRanges.find(
267
+ (boundary) =>
268
+ boundary.end === anchor.range.from ||
269
+ (anchor.range.from >= boundary.start &&
270
+ anchor.range.from <= boundary.end),
271
+ );
272
+ return paragraphBoundary
273
+ ? undefined
274
+ : "Imported revision spans paragraph-level structure and remains preserve-only.";
275
+ }
276
+
277
+ const paragraphBoundary = paragraphRanges.find(
278
+ (boundary) =>
279
+ anchor.range.from >= boundary.start &&
280
+ anchor.range.to <= boundary.end,
281
+ );
282
+ return paragraphBoundary
283
+ ? undefined
284
+ : "Imported revision spans structural boundaries and remains preserve-only.";
285
+ }
286
+
287
+ export function collectCanonicalParagraphRanges(
288
+ content: CanonicalDocumentEnvelope["content"],
289
+ ): Array<{ start: number; end: number }> {
290
+ const ranges: Array<{ start: number; end: number }> = [];
291
+ let cursor = 0;
292
+ let previousWasParagraph = false;
293
+
294
+ for (const block of content.children) {
295
+ if (block.type === "paragraph") {
296
+ if (previousWasParagraph) {
297
+ cursor += 1;
298
+ }
299
+ const start = cursor;
300
+ cursor += measureCanonicalParagraph(block);
301
+ ranges.push({ start, end: cursor });
302
+ previousWasParagraph = true;
303
+ continue;
304
+ }
305
+
306
+ cursor += 1;
307
+ previousWasParagraph = false;
308
+ }
309
+
310
+ return ranges;
311
+ }
312
+
313
+ export function measureCanonicalParagraph(
314
+ paragraph: CanonicalDocumentEnvelope["content"]["children"][number] & { type: "paragraph" },
315
+ ): number {
316
+ return paragraph.children.reduce<number>((size, child) => {
317
+ if (child.type === "text") {
318
+ return size + Array.from(child.text).length;
319
+ }
320
+ if (child.type === "hyperlink") {
321
+ return (
322
+ size +
323
+ child.children.reduce<number>((childSize, entry) => {
324
+ if (entry.type === "text") {
325
+ return childSize + Array.from(entry.text).length;
326
+ }
327
+ return childSize + 1;
328
+ }, 0)
329
+ );
330
+ }
331
+ return size + 1;
332
+ }, 0);
333
+ }
334
+
335
+ export function rangesIntersect(
336
+ left: { from: number; to: number },
337
+ right: { from: number; to: number },
338
+ ): boolean {
339
+ return left.from < right.to && right.from < left.to;
340
+ }
341
+
342
+ export function toRuntimeCommentRecords(
343
+ threads: readonly CommentThread[],
344
+ ): Record<string, CommentThreadRecord> {
345
+ return Object.fromEntries(
346
+ threads.map((thread) => {
347
+ return [
348
+ thread.commentId,
349
+ {
350
+ commentId: thread.commentId,
351
+ body: thread.entries.map((entry) => entry.body).join("\n"),
352
+ anchor: thread.anchor,
353
+ createdBy: thread.createdBy,
354
+ authorId: thread.createdBy,
355
+ createdAt: thread.createdAt,
356
+ entries: thread.entries.map((entry) => ({
357
+ entryId: entry.entryId,
358
+ authorId: entry.authorId,
359
+ body: entry.body,
360
+ createdAt: entry.createdAt,
361
+ metadata: entry.metadata
362
+ ? {
363
+ ooxmlCommentId: entry.metadata.ooxmlCommentId,
364
+ paraId: entry.metadata.paraId,
365
+ parentParaId: entry.metadata.parentParaId,
366
+ durableId: entry.metadata.durableId,
367
+ initials: entry.metadata.initials,
368
+ }
369
+ : undefined,
370
+ })),
371
+ status: thread.status,
372
+ resolution: thread.resolution
373
+ ? {
374
+ resolvedAt: thread.resolution.resolvedAt,
375
+ resolvedBy: thread.resolution.resolvedBy,
376
+ }
377
+ : undefined,
378
+ resolvedAt: thread.resolution?.resolvedAt,
379
+ warningIds: [...thread.warningIds],
380
+ isResolved: thread.status === "resolved",
381
+ metadata: thread.metadata
382
+ ? {
383
+ source: thread.metadata.source,
384
+ rootOoxmlCommentId: thread.metadata.rootOoxmlCommentId,
385
+ rootParaId: thread.metadata.rootParaId,
386
+ }
387
+ : undefined,
388
+ } satisfies CommentThreadRecord,
389
+ ];
390
+ }),
391
+ );
392
+ }
393
+
394
+ export function toRuntimeRevisionRecords(
395
+ revisions: readonly ReviewRevisionRecord[],
396
+ ): Record<string, RuntimeRevisionRecord> {
397
+ return Object.fromEntries(
398
+ revisions.map((revision) => [
399
+ revision.revisionId,
400
+ {
401
+ changeId: revision.revisionId,
402
+ kind: revision.kind,
403
+ anchor: revision.anchor,
404
+ authorId: revision.authorId,
405
+ createdAt: revision.createdAt,
406
+ warningIds: [...revision.warningIds],
407
+ metadata: {
408
+ source: revision.metadata.source,
409
+ storyTarget: revision.metadata.storyTarget,
410
+ preserveOnlyReason: revision.metadata.preserveOnlyReason,
411
+ suggestionId: revision.metadata.suggestionId,
412
+ semanticKind: revision.metadata.semanticKind,
413
+ linkedRevisionIds: revision.metadata.linkedRevisionIds,
414
+ predecessorSuggestionId: revision.metadata.predecessorSuggestionId,
415
+ importedRevisionForm: revision.metadata.importedRevisionForm,
416
+ originalRevisionType: revision.metadata.originalRevisionType,
417
+ ooxmlRevisionId: revision.metadata.ooxmlRevisionId,
418
+ propertyChangeData: revision.metadata.propertyChangeData,
419
+ moveData: revision.metadata.moveData,
420
+ },
421
+ status: revision.status === "active" ? "open" : revision.status,
422
+ } satisfies RuntimeRevisionRecord,
423
+ ]),
424
+ );
425
+ }
426
+
427
+ export function toReviewRevisionRecords(
428
+ revisions: CanonicalDocumentEnvelope["review"]["revisions"],
429
+ ): ReviewRevisionRecord[] {
430
+ return Object.values(revisions).map((revision) => ({
431
+ revisionId: revision.changeId,
432
+ kind: revision.kind,
433
+ anchor: revision.anchor,
434
+ authorId: revision.authorId ?? "unknown",
435
+ createdAt: revision.createdAt,
436
+ warningIds: [...(revision.warningIds ?? [])],
437
+ metadata: {
438
+ source: revision.metadata?.source ?? "runtime",
439
+ storyTarget: revision.metadata?.storyTarget,
440
+ preserveOnlyReason: revision.metadata?.preserveOnlyReason,
441
+ suggestionId: revision.metadata?.suggestionId,
442
+ semanticKind: revision.metadata?.semanticKind,
443
+ linkedRevisionIds: revision.metadata?.linkedRevisionIds,
444
+ predecessorSuggestionId: revision.metadata?.predecessorSuggestionId,
445
+ importedRevisionForm: revision.metadata?.importedRevisionForm,
446
+ originalRevisionType: revision.metadata?.originalRevisionType,
447
+ ooxmlRevisionId: revision.metadata?.ooxmlRevisionId,
448
+ propertyChangeData: revision.metadata?.propertyChangeData,
449
+ moveData: revision.metadata?.moveData,
450
+ },
451
+ status: revision.status === "open" ? "active" : revision.status,
452
+ }));
453
+ }
454
+
455
+ export function serializeSecondaryStoryWithRuntimeRevisions(
456
+ xml: string,
457
+ revisions: readonly ReviewRevisionRecord[],
458
+ label: string,
459
+ ): string {
460
+ if (revisions.length === 0) {
461
+ return xml;
462
+ }
463
+
464
+ const serialized = serializeRuntimeRevisionsIntoStoryXml(xml, revisions);
465
+ if (serialized.skippedRevisionIds.length > 0) {
466
+ throw new Error(
467
+ `DOCX export is blocked because ${serialized.skippedRevisionIds.length} active revisions overlap unsupported serialization boundaries in ${label}.`,
468
+ );
469
+ }
470
+ return serialized.documentXml;
471
+ }
472
+
473
+ export function stripCommentMarkup(
474
+ documentXml: string,
475
+ ownedCommentIds: readonly string[],
476
+ ): string {
477
+ if (ownedCommentIds.length === 0) {
478
+ return documentXml;
479
+ }
480
+
481
+ let output = documentXml;
482
+ for (const commentId of ownedCommentIds) {
483
+ const escapedCommentId = escapeRegExp(commentId);
484
+ const attributePattern = `(?:w:id|id)=["']${escapedCommentId}["']`;
485
+ output = output
486
+ .replace(
487
+ new RegExp(`<w:commentRangeStart\\b[^>]*${attributePattern}[^>]*/>`, "gu"),
488
+ "",
489
+ )
490
+ .replace(
491
+ new RegExp(`<w:commentRangeEnd\\b[^>]*${attributePattern}[^>]*/>`, "gu"),
492
+ "",
493
+ )
494
+ .replace(
495
+ new RegExp(
496
+ `<w:r\\b[^>]*>(?:(?!<w:t\\b|</w:r>)[\\s\\S])*?<w:commentReference\\b[^>]*${attributePattern}[^>]*/>(?:(?!<w:t\\b|</w:r>)[\\s\\S])*?</w:r>`,
497
+ "gu",
498
+ ),
499
+ "",
500
+ );
501
+ }
502
+
503
+ return output;
504
+ }
505
+
506
+ function escapeRegExp(value: string): string {
507
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
508
+ }