@openclaw/diffs 2026.9.3 → 2026.9.5

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 (950) hide show
  1. package/assets/activity.svg +3 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/{browser.runtime-DTKAejqd.js → .setup/browser.runtime-VjaO3wrj.mjs} +1 -1
  4. package/dist/assets/viewer-runtime.js +48 -54
  5. package/dist/index.js +4 -4
  6. package/node_modules/@pierre/diffs/dist/components/CodeView.d.ts +115 -68
  7. package/node_modules/@pierre/diffs/dist/components/CodeView.d.ts.map +1 -1
  8. package/node_modules/@pierre/diffs/dist/components/CodeView.js +189 -59
  9. package/node_modules/@pierre/diffs/dist/components/CodeView.js.map +1 -1
  10. package/node_modules/@pierre/diffs/dist/components/File.d.ts +79 -15
  11. package/node_modules/@pierre/diffs/dist/components/File.d.ts.map +1 -1
  12. package/node_modules/@pierre/diffs/dist/components/File.js +244 -66
  13. package/node_modules/@pierre/diffs/dist/components/File.js.map +1 -1
  14. package/node_modules/@pierre/diffs/dist/components/FileDiff.d.ts +101 -21
  15. package/node_modules/@pierre/diffs/dist/components/FileDiff.d.ts.map +1 -1
  16. package/node_modules/@pierre/diffs/dist/components/FileDiff.js +432 -102
  17. package/node_modules/@pierre/diffs/dist/components/FileDiff.js.map +1 -1
  18. package/node_modules/@pierre/diffs/dist/components/FileStream.js +1 -1
  19. package/node_modules/@pierre/diffs/dist/components/UnresolvedFile.d.ts +2 -2
  20. package/node_modules/@pierre/diffs/dist/components/UnresolvedFile.d.ts.map +1 -1
  21. package/node_modules/@pierre/diffs/dist/components/UnresolvedFile.js +2 -2
  22. package/node_modules/@pierre/diffs/dist/components/UnresolvedFile.js.map +1 -1
  23. package/node_modules/@pierre/diffs/dist/components/VirtualizedFile.d.ts +17 -7
  24. package/node_modules/@pierre/diffs/dist/components/VirtualizedFile.d.ts.map +1 -1
  25. package/node_modules/@pierre/diffs/dist/components/VirtualizedFile.js +142 -53
  26. package/node_modules/@pierre/diffs/dist/components/VirtualizedFile.js.map +1 -1
  27. package/node_modules/@pierre/diffs/dist/components/VirtualizedFileDiff.d.ts +15 -8
  28. package/node_modules/@pierre/diffs/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  29. package/node_modules/@pierre/diffs/dist/components/VirtualizedFileDiff.js +186 -96
  30. package/node_modules/@pierre/diffs/dist/components/VirtualizedFileDiff.js.map +1 -1
  31. package/node_modules/@pierre/diffs/dist/components/VirtulizerDevelopment.d.ts +1 -1
  32. package/node_modules/@pierre/diffs/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
  33. package/node_modules/@pierre/diffs/dist/edit/index.d.ts +7 -4
  34. package/node_modules/@pierre/diffs/dist/edit/index.js +5 -1
  35. package/node_modules/@pierre/diffs/dist/editor/EditStateManager.d.ts +56 -0
  36. package/node_modules/@pierre/diffs/dist/editor/EditStateManager.d.ts.map +1 -0
  37. package/node_modules/@pierre/diffs/dist/editor/EditStateManager.js +135 -0
  38. package/node_modules/@pierre/diffs/dist/editor/EditStateManager.js.map +1 -0
  39. package/node_modules/@pierre/diffs/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts +7 -0
  40. package/node_modules/@pierre/diffs/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts.map +1 -0
  41. package/node_modules/@pierre/diffs/dist/editor/cloneRetainedDiffSessionSnapshot.js +16 -0
  42. package/node_modules/@pierre/diffs/dist/editor/cloneRetainedDiffSessionSnapshot.js.map +1 -0
  43. package/node_modules/@pierre/diffs/dist/editor/editPrediction.d.ts +76 -0
  44. package/node_modules/@pierre/diffs/dist/editor/editPrediction.d.ts.map +1 -0
  45. package/node_modules/@pierre/diffs/dist/editor/editPrediction.js +365 -0
  46. package/node_modules/@pierre/diffs/dist/editor/editPrediction.js.map +1 -0
  47. package/node_modules/@pierre/diffs/dist/editor/editStack.d.ts +19 -40
  48. package/node_modules/@pierre/diffs/dist/editor/editStack.d.ts.map +1 -1
  49. package/node_modules/@pierre/diffs/dist/editor/editStack.js +67 -4
  50. package/node_modules/@pierre/diffs/dist/editor/editStack.js.map +1 -1
  51. package/node_modules/@pierre/diffs/dist/editor/editor.d.ts +118 -29
  52. package/node_modules/@pierre/diffs/dist/editor/editor.d.ts.map +1 -1
  53. package/node_modules/@pierre/diffs/dist/editor/editor.js +1108 -384
  54. package/node_modules/@pierre/diffs/dist/editor/editor.js.map +1 -1
  55. package/node_modules/@pierre/diffs/dist/editor/editor2.js +1 -1
  56. package/node_modules/@pierre/diffs/dist/editor/languages.d.ts +3 -3
  57. package/node_modules/@pierre/diffs/dist/editor/languages.d.ts.map +1 -1
  58. package/node_modules/@pierre/diffs/dist/editor/languages.js.map +1 -1
  59. package/node_modules/@pierre/diffs/dist/editor/lineAnnotations.d.ts +3 -3
  60. package/node_modules/@pierre/diffs/dist/editor/lineAnnotations.d.ts.map +1 -1
  61. package/node_modules/@pierre/diffs/dist/editor/lineAnnotations.js +16 -7
  62. package/node_modules/@pierre/diffs/dist/editor/lineAnnotations.js.map +1 -1
  63. package/node_modules/@pierre/diffs/dist/editor/marker.d.ts +2 -2
  64. package/node_modules/@pierre/diffs/dist/editor/marker.d.ts.map +1 -1
  65. package/node_modules/@pierre/diffs/dist/editor/marker.js.map +1 -1
  66. package/node_modules/@pierre/diffs/dist/editor/matchBrackets.d.ts +2 -2
  67. package/node_modules/@pierre/diffs/dist/editor/matchBrackets.d.ts.map +1 -1
  68. package/node_modules/@pierre/diffs/dist/editor/matchBrackets.js.map +1 -1
  69. package/node_modules/@pierre/diffs/dist/editor/pieceTable.d.ts +1 -1
  70. package/node_modules/@pierre/diffs/dist/editor/pieceTable.js.map +1 -1
  71. package/node_modules/@pierre/diffs/dist/editor/searchPanel.d.ts +2 -2
  72. package/node_modules/@pierre/diffs/dist/editor/searchPanel.js +1 -1
  73. package/node_modules/@pierre/diffs/dist/editor/searchPanel.js.map +1 -1
  74. package/node_modules/@pierre/diffs/dist/editor/selection.d.ts +32 -23
  75. package/node_modules/@pierre/diffs/dist/editor/selection.d.ts.map +1 -1
  76. package/node_modules/@pierre/diffs/dist/editor/selection.js +3 -3
  77. package/node_modules/@pierre/diffs/dist/editor/selection.js.map +1 -1
  78. package/node_modules/@pierre/diffs/dist/editor/selectionAction.d.ts +3 -3
  79. package/node_modules/@pierre/diffs/dist/editor/selectionAction.d.ts.map +1 -1
  80. package/node_modules/@pierre/diffs/dist/editor/selectionAction.js.map +1 -1
  81. package/node_modules/@pierre/diffs/dist/editor/textDocument.d.ts +11 -8
  82. package/node_modules/@pierre/diffs/dist/editor/textDocument.d.ts.map +1 -1
  83. package/node_modules/@pierre/diffs/dist/editor/textDocument.js +28 -5
  84. package/node_modules/@pierre/diffs/dist/editor/textDocument.js.map +1 -1
  85. package/node_modules/@pierre/diffs/dist/editor/textDocumentChangeTransaction.d.ts +15 -0
  86. package/node_modules/@pierre/diffs/dist/editor/textDocumentChangeTransaction.d.ts.map +1 -0
  87. package/node_modules/@pierre/diffs/dist/editor/textDocumentChangeTransaction.js +12 -0
  88. package/node_modules/@pierre/diffs/dist/editor/textDocumentChangeTransaction.js.map +1 -0
  89. package/node_modules/@pierre/diffs/dist/editor/textMeasure.d.ts +5 -0
  90. package/node_modules/@pierre/diffs/dist/editor/textMeasure.d.ts.map +1 -1
  91. package/node_modules/@pierre/diffs/dist/editor/textMeasure.js +10 -0
  92. package/node_modules/@pierre/diffs/dist/editor/textMeasure.js.map +1 -1
  93. package/node_modules/@pierre/diffs/dist/editor/tokenizer.d.ts +1 -1
  94. package/node_modules/@pierre/diffs/dist/editor/tokenizer.js.map +1 -1
  95. package/node_modules/@pierre/diffs/dist/editor/types.d.ts +267 -0
  96. package/node_modules/@pierre/diffs/dist/editor/types.d.ts.map +1 -0
  97. package/node_modules/@pierre/diffs/dist/editor/types.js +0 -0
  98. package/node_modules/@pierre/diffs/dist/editor/utils.d.ts +2 -1
  99. package/node_modules/@pierre/diffs/dist/editor/utils.d.ts.map +1 -1
  100. package/node_modules/@pierre/diffs/dist/editor/utils.js +4 -1
  101. package/node_modules/@pierre/diffs/dist/editor/utils.js.map +1 -1
  102. package/node_modules/@pierre/diffs/dist/highlighter/shared_highlighter.d.ts +6 -2
  103. package/node_modules/@pierre/diffs/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  104. package/node_modules/@pierre/diffs/dist/highlighter/shared_highlighter.js +7 -3
  105. package/node_modules/@pierre/diffs/dist/highlighter/shared_highlighter.js.map +1 -1
  106. package/node_modules/@pierre/diffs/dist/highlighter/themes/areThemesAttached.js +1 -1
  107. package/node_modules/@pierre/diffs/dist/index.d.ts +8 -6
  108. package/node_modules/@pierre/diffs/dist/index.js +22 -21
  109. package/node_modules/@pierre/diffs/dist/managers/InteractionManager.d.ts.map +1 -1
  110. package/node_modules/@pierre/diffs/dist/managers/InteractionManager.js +7 -0
  111. package/node_modules/@pierre/diffs/dist/managers/InteractionManager.js.map +1 -1
  112. package/node_modules/@pierre/diffs/dist/react/CodeView.d.ts +36 -25
  113. package/node_modules/@pierre/diffs/dist/react/CodeView.d.ts.map +1 -1
  114. package/node_modules/@pierre/diffs/dist/react/CodeView.js +15 -14
  115. package/node_modules/@pierre/diffs/dist/react/CodeView.js.map +1 -1
  116. package/node_modules/@pierre/diffs/dist/react/EditContext.d.ts +8 -11
  117. package/node_modules/@pierre/diffs/dist/react/EditContext.d.ts.map +1 -1
  118. package/node_modules/@pierre/diffs/dist/react/EditContext.js +2 -9
  119. package/node_modules/@pierre/diffs/dist/react/EditContext.js.map +1 -1
  120. package/node_modules/@pierre/diffs/dist/react/File.d.ts +10 -6
  121. package/node_modules/@pierre/diffs/dist/react/File.d.ts.map +1 -1
  122. package/node_modules/@pierre/diffs/dist/react/File.js +8 -4
  123. package/node_modules/@pierre/diffs/dist/react/File.js.map +1 -1
  124. package/node_modules/@pierre/diffs/dist/react/FileDiff.d.ts +10 -5
  125. package/node_modules/@pierre/diffs/dist/react/FileDiff.d.ts.map +1 -1
  126. package/node_modules/@pierre/diffs/dist/react/FileDiff.js +8 -4
  127. package/node_modules/@pierre/diffs/dist/react/FileDiff.js.map +1 -1
  128. package/node_modules/@pierre/diffs/dist/react/MultiFileDiff.d.ts +8 -5
  129. package/node_modules/@pierre/diffs/dist/react/MultiFileDiff.d.ts.map +1 -1
  130. package/node_modules/@pierre/diffs/dist/react/MultiFileDiff.js +8 -12
  131. package/node_modules/@pierre/diffs/dist/react/MultiFileDiff.js.map +1 -1
  132. package/node_modules/@pierre/diffs/dist/react/PatchDiff.d.ts +7 -4
  133. package/node_modules/@pierre/diffs/dist/react/PatchDiff.d.ts.map +1 -1
  134. package/node_modules/@pierre/diffs/dist/react/PatchDiff.js +8 -4
  135. package/node_modules/@pierre/diffs/dist/react/PatchDiff.js.map +1 -1
  136. package/node_modules/@pierre/diffs/dist/react/UnresolvedFile.d.ts +3 -3
  137. package/node_modules/@pierre/diffs/dist/react/UnresolvedFile.d.ts.map +1 -1
  138. package/node_modules/@pierre/diffs/dist/react/UnresolvedFile.js.map +1 -1
  139. package/node_modules/@pierre/diffs/dist/react/index.d.ts +8 -5
  140. package/node_modules/@pierre/diffs/dist/react/types.d.ts +46 -9
  141. package/node_modules/@pierre/diffs/dist/react/types.d.ts.map +1 -1
  142. package/node_modules/@pierre/diffs/dist/react/utils/renderDiffChildren.d.ts +14 -12
  143. package/node_modules/@pierre/diffs/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  144. package/node_modules/@pierre/diffs/dist/react/utils/renderDiffChildren.js +2 -2
  145. package/node_modules/@pierre/diffs/dist/react/utils/renderDiffChildren.js.map +1 -1
  146. package/node_modules/@pierre/diffs/dist/react/utils/renderFileChildren.d.ts +14 -12
  147. package/node_modules/@pierre/diffs/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  148. package/node_modules/@pierre/diffs/dist/react/utils/renderFileChildren.js +2 -2
  149. package/node_modules/@pierre/diffs/dist/react/utils/renderFileChildren.js.map +1 -1
  150. package/node_modules/@pierre/diffs/dist/react/utils/useFileDiffInstance.d.ts +22 -10
  151. package/node_modules/@pierre/diffs/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  152. package/node_modules/@pierre/diffs/dist/react/utils/useFileDiffInstance.js +112 -22
  153. package/node_modules/@pierre/diffs/dist/react/utils/useFileDiffInstance.js.map +1 -1
  154. package/node_modules/@pierre/diffs/dist/react/utils/useFileInstance.d.ts +15 -9
  155. package/node_modules/@pierre/diffs/dist/react/utils/useFileInstance.d.ts.map +1 -1
  156. package/node_modules/@pierre/diffs/dist/react/utils/useFileInstance.js +84 -25
  157. package/node_modules/@pierre/diffs/dist/react/utils/useFileInstance.js.map +1 -1
  158. package/node_modules/@pierre/diffs/dist/renderers/DiffHunksRenderer.d.ts +30 -15
  159. package/node_modules/@pierre/diffs/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  160. package/node_modules/@pierre/diffs/dist/renderers/DiffHunksRenderer.js +172 -109
  161. package/node_modules/@pierre/diffs/dist/renderers/DiffHunksRenderer.js.map +1 -1
  162. package/node_modules/@pierre/diffs/dist/renderers/FileRenderer.d.ts +27 -11
  163. package/node_modules/@pierre/diffs/dist/renderers/FileRenderer.d.ts.map +1 -1
  164. package/node_modules/@pierre/diffs/dist/renderers/FileRenderer.js +141 -67
  165. package/node_modules/@pierre/diffs/dist/renderers/FileRenderer.js.map +1 -1
  166. package/node_modules/@pierre/diffs/dist/renderers/UnresolvedFileHunksRenderer.d.ts +2 -2
  167. package/node_modules/@pierre/diffs/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
  168. package/node_modules/@pierre/diffs/dist/renderers/UnresolvedFileHunksRenderer.js +2 -2
  169. package/node_modules/@pierre/diffs/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
  170. package/node_modules/@pierre/diffs/dist/shiki-stream/tokenizer.d.ts.map +1 -1
  171. package/node_modules/@pierre/diffs/dist/shiki-stream/tokenizer.js +2 -1
  172. package/node_modules/@pierre/diffs/dist/shiki-stream/tokenizer.js.map +1 -1
  173. package/node_modules/@pierre/diffs/dist/ssr/index.d.ts +2 -2
  174. package/node_modules/@pierre/diffs/dist/ssr/preloadDiffs.d.ts +21 -21
  175. package/node_modules/@pierre/diffs/dist/ssr/preloadDiffs.d.ts.map +1 -1
  176. package/node_modules/@pierre/diffs/dist/ssr/preloadDiffs.js +1 -1
  177. package/node_modules/@pierre/diffs/dist/ssr/preloadDiffs.js.map +1 -1
  178. package/node_modules/@pierre/diffs/dist/ssr/preloadFile.d.ts +6 -6
  179. package/node_modules/@pierre/diffs/dist/ssr/preloadFile.d.ts.map +1 -1
  180. package/node_modules/@pierre/diffs/dist/ssr/preloadFile.js.map +1 -1
  181. package/node_modules/@pierre/diffs/dist/ssr/preloadPatchFile.d.ts +4 -4
  182. package/node_modules/@pierre/diffs/dist/ssr/preloadPatchFile.d.ts.map +1 -1
  183. package/node_modules/@pierre/diffs/dist/ssr/preloadPatchFile.js.map +1 -1
  184. package/node_modules/@pierre/diffs/dist/style.js +1 -1
  185. package/node_modules/@pierre/diffs/dist/types.d.ts +13 -263
  186. package/node_modules/@pierre/diffs/dist/types.d.ts.map +1 -1
  187. package/node_modules/@pierre/diffs/dist/utils/appendItems.d.ts +5 -0
  188. package/node_modules/@pierre/diffs/dist/utils/appendItems.d.ts.map +1 -0
  189. package/node_modules/@pierre/diffs/dist/utils/appendItems.js +8 -0
  190. package/node_modules/@pierre/diffs/dist/utils/appendItems.js.map +1 -0
  191. package/node_modules/@pierre/diffs/dist/utils/areDiffTargetsEqual.js +1 -1
  192. package/node_modules/@pierre/diffs/dist/utils/areDiffTargetsEqual.js.map +1 -1
  193. package/node_modules/@pierre/diffs/dist/utils/areFileTargetsEqual.d.ts +7 -0
  194. package/node_modules/@pierre/diffs/dist/utils/areFileTargetsEqual.d.ts.map +1 -0
  195. package/node_modules/@pierre/diffs/dist/utils/areFileTargetsEqual.js +8 -0
  196. package/node_modules/@pierre/diffs/dist/utils/areFileTargetsEqual.js.map +1 -0
  197. package/node_modules/@pierre/diffs/dist/utils/areManagedSnapshotsEqual.d.ts +1 -1
  198. package/node_modules/@pierre/diffs/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  199. package/node_modules/@pierre/diffs/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  200. package/node_modules/@pierre/diffs/dist/utils/areOptionsEqual.d.ts +3 -3
  201. package/node_modules/@pierre/diffs/dist/utils/areOptionsEqual.d.ts.map +1 -1
  202. package/node_modules/@pierre/diffs/dist/utils/areOptionsEqual.js.map +1 -1
  203. package/node_modules/@pierre/diffs/dist/utils/cloneFileDiffMetadata.d.ts +3 -2
  204. package/node_modules/@pierre/diffs/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -1
  205. package/node_modules/@pierre/diffs/dist/utils/cloneFileDiffMetadata.js +8 -5
  206. package/node_modules/@pierre/diffs/dist/utils/cloneFileDiffMetadata.js.map +1 -1
  207. package/node_modules/@pierre/diffs/dist/utils/composeCacheKey.d.ts +6 -0
  208. package/node_modules/@pierre/diffs/dist/utils/composeCacheKey.d.ts.map +1 -0
  209. package/node_modules/@pierre/diffs/dist/utils/composeCacheKey.js +10 -0
  210. package/node_modules/@pierre/diffs/dist/utils/composeCacheKey.js.map +1 -0
  211. package/node_modules/@pierre/diffs/dist/utils/editSessionAnnotations.d.ts +69 -0
  212. package/node_modules/@pierre/diffs/dist/utils/editSessionAnnotations.d.ts.map +1 -0
  213. package/node_modules/@pierre/diffs/dist/utils/editSessionAnnotations.js +64 -0
  214. package/node_modules/@pierre/diffs/dist/utils/editSessionAnnotations.js.map +1 -0
  215. package/node_modules/@pierre/diffs/dist/utils/editSessionHunks.d.ts +5 -3
  216. package/node_modules/@pierre/diffs/dist/utils/editSessionHunks.d.ts.map +1 -1
  217. package/node_modules/@pierre/diffs/dist/utils/editSessionHunks.js +7 -5
  218. package/node_modules/@pierre/diffs/dist/utils/editSessionHunks.js.map +1 -1
  219. package/node_modules/@pierre/diffs/dist/utils/getDiffHunksRendererOptions.d.ts +1 -1
  220. package/node_modules/@pierre/diffs/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -1
  221. package/node_modules/@pierre/diffs/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  222. package/node_modules/@pierre/diffs/dist/utils/getFileRendererOptions.d.ts +1 -1
  223. package/node_modules/@pierre/diffs/dist/utils/getFileRendererOptions.d.ts.map +1 -1
  224. package/node_modules/@pierre/diffs/dist/utils/getFileRendererOptions.js.map +1 -1
  225. package/node_modules/@pierre/diffs/dist/utils/hydratePartialDiff.d.ts.map +1 -1
  226. package/node_modules/@pierre/diffs/dist/utils/hydratePartialDiff.js +2 -1
  227. package/node_modules/@pierre/diffs/dist/utils/hydratePartialDiff.js.map +1 -1
  228. package/node_modules/@pierre/diffs/dist/utils/lineAnnotationIdentity.d.ts +16 -0
  229. package/node_modules/@pierre/diffs/dist/utils/lineAnnotationIdentity.d.ts.map +1 -0
  230. package/node_modules/@pierre/diffs/dist/utils/lineAnnotationIdentity.js +17 -0
  231. package/node_modules/@pierre/diffs/dist/utils/lineAnnotationIdentity.js.map +1 -0
  232. package/node_modules/@pierre/diffs/dist/utils/parseDiffFromFile.d.ts +2 -2
  233. package/node_modules/@pierre/diffs/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  234. package/node_modules/@pierre/diffs/dist/utils/parseDiffFromFile.js +6 -6
  235. package/node_modules/@pierre/diffs/dist/utils/parseDiffFromFile.js.map +1 -1
  236. package/node_modules/@pierre/diffs/dist/utils/parsePatchFiles.d.ts +6 -3
  237. package/node_modules/@pierre/diffs/dist/utils/parsePatchFiles.d.ts.map +1 -1
  238. package/node_modules/@pierre/diffs/dist/utils/parsePatchFiles.js +34 -9
  239. package/node_modules/@pierre/diffs/dist/utils/parsePatchFiles.js.map +1 -1
  240. package/node_modules/@pierre/diffs/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  241. package/node_modules/@pierre/diffs/dist/utils/renderDiffWithHighlighter.js +6 -5
  242. package/node_modules/@pierre/diffs/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  243. package/node_modules/@pierre/diffs/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  244. package/node_modules/@pierre/diffs/dist/utils/renderFileWithHighlighter.js +7 -4
  245. package/node_modules/@pierre/diffs/dist/utils/renderFileWithHighlighter.js.map +1 -1
  246. package/node_modules/@pierre/diffs/dist/utils/trimPatchContext.d.ts.map +1 -1
  247. package/node_modules/@pierre/diffs/dist/utils/trimPatchContext.js +3 -2
  248. package/node_modules/@pierre/diffs/dist/utils/trimPatchContext.js.map +1 -1
  249. package/node_modules/@pierre/diffs/dist/utils/updateDiffHunks.js +1 -1
  250. package/node_modules/@pierre/diffs/dist/utils/virtualDiffLayout.js +1 -1
  251. package/node_modules/@pierre/diffs/dist/worker/WorkerPoolManager.d.ts +4 -3
  252. package/node_modules/@pierre/diffs/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  253. package/node_modules/@pierre/diffs/dist/worker/WorkerPoolManager.js +44 -6
  254. package/node_modules/@pierre/diffs/dist/worker/WorkerPoolManager.js.map +1 -1
  255. package/node_modules/@pierre/diffs/dist/worker/types.d.ts +5 -0
  256. package/node_modules/@pierre/diffs/dist/worker/types.d.ts.map +1 -1
  257. package/node_modules/@pierre/diffs/dist/worker/worker-portable.js +14 -6
  258. package/node_modules/@pierre/diffs/dist/worker/worker-portable.js.map +1 -1
  259. package/node_modules/@pierre/diffs/dist/worker/worker.js +14 -6
  260. package/node_modules/@pierre/diffs/dist/worker/worker.js.map +1 -1
  261. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/cjs/deserialize.js +12 -2
  262. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/cjs/serialize.js +5 -1
  263. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/esm/deserialize.js +12 -2
  264. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/esm/serialize.js +5 -1
  265. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/package.json +1 -1
  266. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/structured-json.js +1 -1
  267. package/node_modules/@pierre/diffs/package.json +9 -1
  268. package/node_modules/playwright-core/browsers.json +9 -32
  269. package/node_modules/playwright-core/lib/coreBundle.js +5402 -4419
  270. package/node_modules/playwright-core/lib/server/electron/loader.js +0 -2
  271. package/node_modules/playwright-core/lib/serverRegistry.js +1674 -7082
  272. package/node_modules/playwright-core/lib/serverRegistry.js.LICENSE +8 -297
  273. package/node_modules/playwright-core/lib/tools/cli-client/help.json +19 -6
  274. package/node_modules/playwright-core/lib/tools/cli-client/minimist.js +1 -1
  275. package/node_modules/playwright-core/lib/tools/cli-client/output.js +9 -1
  276. package/node_modules/playwright-core/lib/tools/cli-client/program.js +17 -3
  277. package/node_modules/playwright-core/lib/tools/cli-client/registry.js +9 -5
  278. package/node_modules/playwright-core/lib/tools/cli-client/session.js +2 -1
  279. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/SKILL.md +5 -0
  280. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/tracing.md +1 -1
  281. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/SKILL.md +4 -11
  282. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/migration.md +6 -2
  283. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/react.md +2 -0
  284. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/typing.md +173 -0
  285. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/vue.md +2 -0
  286. package/node_modules/playwright-core/lib/tools/skills/playwright-trace/SKILL.md +6 -3
  287. package/node_modules/playwright-core/lib/tools/utils/extension.js +13 -2
  288. package/node_modules/playwright-core/lib/utilsBundle.js +1934 -7341
  289. package/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +8 -297
  290. package/node_modules/playwright-core/lib/vite/dashboard/assets/codeMirrorModule--QdMvsKi.css +1 -0
  291. package/node_modules/playwright-core/lib/vite/{recorder/assets/codeMirrorModule-CwYYHbcZ.js → dashboard/assets/codeMirrorModule-CQ8RZGBm.js} +1 -1
  292. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-AwgwcYie.css +1 -0
  293. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-hRvO4yU2.js +12 -0
  294. package/node_modules/playwright-core/lib/vite/dashboard/index.html +2 -2
  295. package/node_modules/playwright-core/lib/vite/htmlReport/report.css +1 -1
  296. package/node_modules/playwright-core/lib/vite/htmlReport/report.js +4 -4
  297. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-CVQWJZAA.js +32 -0
  298. package/node_modules/playwright-core/lib/vite/recorder/assets/index-BZpYJZ-P.css +1 -0
  299. package/node_modules/playwright-core/lib/vite/recorder/assets/index-hrlLqLtq.js +129 -0
  300. package/node_modules/playwright-core/lib/vite/recorder/index.html +2 -2
  301. package/node_modules/playwright-core/lib/vite/traceViewer/assets/{codeMirrorModule-rXmQmLUY.js → codeMirrorModule-BbkfBe3n.js} +1 -1
  302. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-Ds6CBOo0.js +182 -0
  303. package/node_modules/playwright-core/lib/vite/traceViewer/assets/{xtermModule-BuZfJS5v.js → xtermModule-DywYcAf8.js} +1 -1
  304. package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.Bqk9acqE.css +1 -0
  305. package/node_modules/playwright-core/lib/vite/traceViewer/index.B4cLoZK3.js +1 -0
  306. package/node_modules/playwright-core/lib/vite/traceViewer/index.html +3 -3
  307. package/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +3 -3
  308. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.CU5KtEkS.js +5 -0
  309. package/node_modules/playwright-core/lib/vite/traceViewer/{uiMode.C7UW1sC9.css → uiMode.CyMfwkXJ.css} +1 -1
  310. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +4 -4
  311. package/node_modules/playwright-core/package.json +1 -1
  312. package/node_modules/playwright-core/types/protocol.d.ts +201 -398
  313. package/node_modules/playwright-core/types/types.d.ts +771 -327
  314. package/node_modules/typebox/build/compile/validator.d.mts +1 -1
  315. package/node_modules/typebox/build/compile/validator.mjs +1 -1
  316. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +7 -5
  317. package/node_modules/typebox/build/format/iri.mjs +5 -1
  318. package/node_modules/typebox/build/guard/emit.mjs +2 -4
  319. package/node_modules/typebox/build/guard/guard.mjs +6 -18
  320. package/node_modules/typebox/build/guard/string.mjs +16 -24
  321. package/node_modules/typebox/build/schema/build.mjs +2 -2
  322. package/node_modules/typebox/build/schema/check.mjs +1 -1
  323. package/node_modules/typebox/build/schema/compile.d.mts +3 -2
  324. package/node_modules/typebox/build/schema/compile.mjs +8 -8
  325. package/node_modules/typebox/build/schema/engine/_context.d.mts +6 -7
  326. package/node_modules/typebox/build/schema/engine/_context.mjs +23 -15
  327. package/node_modules/typebox/build/schema/engine/_functions.d.mts +2 -2
  328. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -1
  329. package/node_modules/typebox/build/schema/engine/_reducer.d.mts +3 -3
  330. package/node_modules/typebox/build/schema/engine/_refine.d.mts +5 -5
  331. package/node_modules/typebox/build/schema/engine/_refine.mjs +4 -7
  332. package/node_modules/typebox/build/schema/engine/_stack.d.mts +34 -16
  333. package/node_modules/typebox/build/schema/engine/_stack.mjs +148 -104
  334. package/node_modules/typebox/build/schema/engine/additionalItems.d.mts +4 -4
  335. package/node_modules/typebox/build/schema/engine/additionalProperties.d.mts +8 -8
  336. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +26 -18
  337. package/node_modules/typebox/build/schema/engine/allOf.d.mts +4 -4
  338. package/node_modules/typebox/build/schema/engine/allOf.mjs +3 -3
  339. package/node_modules/typebox/build/schema/engine/anyOf.d.mts +4 -4
  340. package/node_modules/typebox/build/schema/engine/anyOf.mjs +5 -10
  341. package/node_modules/typebox/build/schema/engine/boolean.d.mts +4 -4
  342. package/node_modules/typebox/build/schema/engine/boolean.mjs +2 -6
  343. package/node_modules/typebox/build/schema/engine/const.d.mts +4 -4
  344. package/node_modules/typebox/build/schema/engine/const.mjs +2 -6
  345. package/node_modules/typebox/build/schema/engine/contains.d.mts +4 -4
  346. package/node_modules/typebox/build/schema/engine/contains.mjs +2 -6
  347. package/node_modules/typebox/build/schema/engine/dependencies.d.mts +4 -4
  348. package/node_modules/typebox/build/schema/engine/dependencies.mjs +3 -6
  349. package/node_modules/typebox/build/schema/engine/dependentRequired.d.mts +4 -4
  350. package/node_modules/typebox/build/schema/engine/dependentRequired.mjs +2 -6
  351. package/node_modules/typebox/build/schema/engine/dependentSchemas.d.mts +4 -4
  352. package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +4 -4
  353. package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +11 -7
  354. package/node_modules/typebox/build/schema/engine/enum.d.mts +4 -4
  355. package/node_modules/typebox/build/schema/engine/enum.mjs +2 -6
  356. package/node_modules/typebox/build/schema/engine/exclusiveMaximum.d.mts +4 -4
  357. package/node_modules/typebox/build/schema/engine/exclusiveMaximum.mjs +2 -6
  358. package/node_modules/typebox/build/schema/engine/exclusiveMinimum.d.mts +4 -4
  359. package/node_modules/typebox/build/schema/engine/exclusiveMinimum.mjs +2 -6
  360. package/node_modules/typebox/build/schema/engine/format.d.mts +4 -4
  361. package/node_modules/typebox/build/schema/engine/format.mjs +2 -6
  362. package/node_modules/typebox/build/schema/engine/if.d.mts +4 -4
  363. package/node_modules/typebox/build/schema/engine/if.mjs +7 -15
  364. package/node_modules/typebox/build/schema/engine/items.d.mts +4 -4
  365. package/node_modules/typebox/build/schema/engine/items.mjs +1 -1
  366. package/node_modules/typebox/build/schema/engine/maxContains.d.mts +4 -4
  367. package/node_modules/typebox/build/schema/engine/maxContains.mjs +2 -6
  368. package/node_modules/typebox/build/schema/engine/maxItems.d.mts +4 -4
  369. package/node_modules/typebox/build/schema/engine/maxItems.mjs +2 -6
  370. package/node_modules/typebox/build/schema/engine/maxLength.d.mts +4 -4
  371. package/node_modules/typebox/build/schema/engine/maxLength.mjs +2 -6
  372. package/node_modules/typebox/build/schema/engine/maxProperties.d.mts +4 -4
  373. package/node_modules/typebox/build/schema/engine/maxProperties.mjs +2 -6
  374. package/node_modules/typebox/build/schema/engine/maximum.d.mts +4 -4
  375. package/node_modules/typebox/build/schema/engine/maximum.mjs +2 -6
  376. package/node_modules/typebox/build/schema/engine/minContains.d.mts +4 -4
  377. package/node_modules/typebox/build/schema/engine/minContains.mjs +2 -6
  378. package/node_modules/typebox/build/schema/engine/minItems.d.mts +5 -5
  379. package/node_modules/typebox/build/schema/engine/minItems.mjs +2 -6
  380. package/node_modules/typebox/build/schema/engine/minLength.d.mts +4 -4
  381. package/node_modules/typebox/build/schema/engine/minLength.mjs +2 -6
  382. package/node_modules/typebox/build/schema/engine/minProperties.d.mts +4 -4
  383. package/node_modules/typebox/build/schema/engine/minProperties.mjs +2 -6
  384. package/node_modules/typebox/build/schema/engine/minimum.d.mts +4 -4
  385. package/node_modules/typebox/build/schema/engine/minimum.mjs +2 -6
  386. package/node_modules/typebox/build/schema/engine/multipleOf.d.mts +4 -4
  387. package/node_modules/typebox/build/schema/engine/multipleOf.mjs +2 -6
  388. package/node_modules/typebox/build/schema/engine/not.d.mts +4 -4
  389. package/node_modules/typebox/build/schema/engine/not.mjs +4 -8
  390. package/node_modules/typebox/build/schema/engine/oneOf.d.mts +4 -4
  391. package/node_modules/typebox/build/schema/engine/oneOf.mjs +6 -11
  392. package/node_modules/typebox/build/schema/engine/pattern.d.mts +4 -4
  393. package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -7
  394. package/node_modules/typebox/build/schema/engine/patternProperties.d.mts +4 -4
  395. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +1 -1
  396. package/node_modules/typebox/build/schema/engine/prefixItems.d.mts +4 -4
  397. package/node_modules/typebox/build/schema/engine/prefixItems.mjs +1 -1
  398. package/node_modules/typebox/build/schema/engine/properties.d.mts +4 -4
  399. package/node_modules/typebox/build/schema/engine/properties.mjs +1 -1
  400. package/node_modules/typebox/build/schema/engine/propertyNames.d.mts +4 -4
  401. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +4 -10
  402. package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +4 -4
  403. package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +11 -7
  404. package/node_modules/typebox/build/schema/engine/ref.d.mts +4 -4
  405. package/node_modules/typebox/build/schema/engine/ref.mjs +19 -15
  406. package/node_modules/typebox/build/schema/engine/required.d.mts +4 -4
  407. package/node_modules/typebox/build/schema/engine/required.mjs +2 -6
  408. package/node_modules/typebox/build/schema/engine/schema.d.mts +7 -7
  409. package/node_modules/typebox/build/schema/engine/schema.mjs +137 -133
  410. package/node_modules/typebox/build/schema/engine/type.d.mts +4 -4
  411. package/node_modules/typebox/build/schema/engine/type.mjs +2 -6
  412. package/node_modules/typebox/build/schema/engine/unevaluatedItems.d.mts +4 -4
  413. package/node_modules/typebox/build/schema/engine/unevaluatedItems.mjs +5 -9
  414. package/node_modules/typebox/build/schema/engine/unevaluatedProperties.d.mts +4 -4
  415. package/node_modules/typebox/build/schema/engine/unevaluatedProperties.mjs +5 -9
  416. package/node_modules/typebox/build/schema/engine/uniqueItems.d.mts +4 -4
  417. package/node_modules/typebox/build/schema/engine/uniqueItems.mjs +2 -6
  418. package/node_modules/typebox/build/schema/errors.d.mts +2 -2
  419. package/node_modules/typebox/build/schema/errors.mjs +8 -14
  420. package/node_modules/typebox/build/schema/intern/index.d.mts +1 -0
  421. package/node_modules/typebox/build/schema/intern/index.mjs +1 -0
  422. package/node_modules/typebox/build/schema/intern/intern.d.mts +11 -0
  423. package/node_modules/typebox/build/schema/intern/intern.mjs +293 -0
  424. package/node_modules/typebox/build/schema/meta/draft_2019_09.d.mts +2 -0
  425. package/node_modules/typebox/build/schema/meta/draft_2019_09.mjs +288 -0
  426. package/node_modules/typebox/build/schema/meta/draft_2020_12.d.mts +2 -0
  427. package/node_modules/typebox/build/schema/meta/draft_2020_12.mjs +300 -0
  428. package/node_modules/typebox/build/schema/meta/draft_3.d.mts +2 -0
  429. package/node_modules/typebox/build/schema/meta/draft_3.mjs +143 -0
  430. package/node_modules/typebox/build/schema/meta/draft_4.d.mts +2 -0
  431. package/node_modules/typebox/build/schema/meta/draft_4.mjs +149 -0
  432. package/node_modules/typebox/build/schema/meta/draft_6.d.mts +2 -0
  433. package/node_modules/typebox/build/schema/meta/draft_6.mjs +155 -0
  434. package/node_modules/typebox/build/schema/meta/draft_7.d.mts +2 -0
  435. package/node_modules/typebox/build/schema/meta/draft_7.mjs +172 -0
  436. package/node_modules/typebox/build/schema/meta/index.d.mts +2 -0
  437. package/node_modules/typebox/build/schema/meta/index.mjs +2 -0
  438. package/node_modules/typebox/build/schema/meta/meta.d.mts +9 -0
  439. package/node_modules/typebox/build/schema/meta/meta.mjs +15 -0
  440. package/node_modules/typebox/build/schema/meta/schema.d.mts +6 -0
  441. package/node_modules/typebox/build/schema/meta/schema.mjs +1 -0
  442. package/node_modules/typebox/build/schema/parse.d.mts +1 -0
  443. package/node_modules/typebox/build/schema/parse.mjs +10 -5
  444. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +8 -3
  445. package/node_modules/typebox/build/schema/resolve/resolve.mjs +268 -139
  446. package/node_modules/typebox/build/schema/schema.d.mts +2 -0
  447. package/node_modules/typebox/build/schema/schema.mjs +2 -0
  448. package/node_modules/typebox/build/value/errors/errors.d.mts +2 -12
  449. package/node_modules/typebox/build/value/errors/errors.mjs +2 -7
  450. package/node_modules/typebox/package.json +1 -1
  451. package/node_modules/typebox/readme.md +59 -89
  452. package/node_modules/zod/README.md +27 -0
  453. package/node_modules/zod/compile.cjs +77 -0
  454. package/node_modules/zod/compile.d.cts +1 -0
  455. package/node_modules/zod/compile.d.ts +1 -0
  456. package/node_modules/zod/compile.js +52 -0
  457. package/node_modules/zod/index.cjs +2 -2
  458. package/node_modules/zod/index.d.cts +1 -2
  459. package/node_modules/zod/index.d.ts +1 -2
  460. package/node_modules/zod/index.js +5 -2
  461. package/node_modules/zod/package.json +13 -2
  462. package/node_modules/zod/src/compile.ts +56 -0
  463. package/node_modules/zod/src/index.ts +5 -2
  464. package/node_modules/zod/src/v3/ZodError.ts +22 -12
  465. package/node_modules/zod/src/v3/tests/error.test.ts +35 -0
  466. package/node_modules/zod/src/v3/tests/intersection.test.ts +18 -0
  467. package/node_modules/zod/src/v3/tests/language-server.test.ts +1 -2
  468. package/node_modules/zod/src/v3/tests/object.test.ts +3 -6
  469. package/node_modules/zod/src/v3/tests/readonly.test.ts +0 -80
  470. package/node_modules/zod/src/v3/tests/string.test.ts +6 -0
  471. package/node_modules/zod/src/v3/types.ts +5 -5
  472. package/node_modules/zod/src/v4/classic/checks.ts +1 -0
  473. package/node_modules/zod/src/v4/classic/compat.ts +26 -18
  474. package/node_modules/zod/src/v4/classic/deep-partial.ts +76 -0
  475. package/node_modules/zod/src/v4/classic/errors.ts +59 -44
  476. package/node_modules/zod/src/v4/classic/external.ts +12 -9
  477. package/node_modules/zod/src/v4/classic/from-json-schema.ts +140 -78
  478. package/node_modules/zod/src/v4/classic/in-out.ts +45 -0
  479. package/node_modules/zod/src/v4/classic/index.ts +2 -2
  480. package/node_modules/zod/src/v4/classic/iso.ts +2 -72
  481. package/node_modules/zod/src/v4/classic/parse.ts +10 -4
  482. package/node_modules/zod/src/v4/classic/schemas.ts +452 -262
  483. package/node_modules/zod/src/v4/classic/tests/apply.test.ts +27 -0
  484. package/node_modules/zod/src/v4/classic/tests/array.test.ts +2 -2
  485. package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +135 -0
  486. package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +30 -1
  487. package/node_modules/zod/src/v4/classic/tests/catch.test.ts +278 -0
  488. package/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +1 -2
  489. package/node_modules/zod/src/v4/classic/tests/codec.test.ts +2 -1
  490. package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +2 -2
  491. package/node_modules/zod/src/v4/classic/tests/credit-card.test.ts +76 -0
  492. package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +720 -0
  493. package/node_modules/zod/src/v4/classic/tests/date.test.ts +30 -0
  494. package/node_modules/zod/src/v4/classic/tests/datetime.test.ts +32 -18
  495. package/node_modules/zod/src/v4/classic/tests/deep-partial.test.ts +380 -0
  496. package/node_modules/zod/src/v4/classic/tests/default-locale.test.ts +32 -0
  497. package/node_modules/zod/src/v4/classic/tests/default.test.ts +46 -0
  498. package/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +31 -7
  499. package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +155 -13
  500. package/node_modules/zod/src/v4/classic/tests/enum.test.ts +11 -0
  501. package/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +112 -2
  502. package/node_modules/zod/src/v4/classic/tests/error.test.ts +274 -6
  503. package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +425 -10
  504. package/node_modules/zod/src/v4/classic/tests/function.test.ts +31 -0
  505. package/node_modules/zod/src/v4/classic/tests/global-config.test.ts +2 -9
  506. package/node_modules/zod/src/v4/classic/tests/hash.test.ts +1 -2
  507. package/node_modules/zod/src/v4/classic/tests/in-out.test.ts +159 -0
  508. package/node_modules/zod/src/v4/classic/tests/index.test.ts +21 -2
  509. package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +281 -0
  510. package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +47 -0
  511. package/node_modules/zod/src/v4/classic/tests/intersection.test.ts +136 -0
  512. package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +183 -0
  513. package/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +3 -10
  514. package/node_modules/zod/src/v4/classic/tests/lazy.test.ts +36 -1
  515. package/node_modules/zod/src/v4/classic/tests/literal.test.ts +12 -1
  516. package/node_modules/zod/src/v4/classic/tests/map.test.ts +12 -0
  517. package/node_modules/zod/src/v4/classic/tests/number.test.ts +46 -9
  518. package/node_modules/zod/src/v4/classic/tests/object.test.ts +245 -12
  519. package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +234 -0
  520. package/node_modules/zod/src/v4/classic/tests/optional.test.ts +49 -16
  521. package/node_modules/zod/src/v4/classic/tests/partial.test.ts +51 -4
  522. package/node_modules/zod/src/v4/classic/tests/preprocess-types.test.ts +20 -2
  523. package/node_modules/zod/src/v4/classic/tests/readonly.test.ts +0 -68
  524. package/node_modules/zod/src/v4/classic/tests/record.test.ts +186 -18
  525. package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +33 -2
  526. package/node_modules/zod/src/v4/classic/tests/redos.test.ts +68 -0
  527. package/node_modules/zod/src/v4/classic/tests/refine.test.ts +60 -0
  528. package/node_modules/zod/src/v4/classic/tests/set.test.ts +9 -0
  529. package/node_modules/zod/src/v4/classic/tests/string.test.ts +127 -5
  530. package/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +18 -0
  531. package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +11 -2
  532. package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +1585 -173
  533. package/node_modules/zod/src/v4/classic/tests/tuple.test.ts +45 -30
  534. package/node_modules/zod/src/v4/classic/tests/union.test.ts +39 -2
  535. package/node_modules/zod/src/v4/classic/tests/validate.test.ts +76 -0
  536. package/node_modules/zod/src/v4/classic/tests/validations.test.ts +2 -2
  537. package/node_modules/zod/src/v4/core/api.ts +48 -12
  538. package/node_modules/zod/src/v4/core/checks.ts +57 -44
  539. package/node_modules/zod/src/v4/core/compile.ts +2188 -0
  540. package/node_modules/zod/src/v4/core/core.ts +98 -19
  541. package/node_modules/zod/src/v4/core/doc.ts +11 -7
  542. package/node_modules/zod/src/v4/core/errors.ts +115 -24
  543. package/node_modules/zod/src/v4/core/index.ts +3 -0
  544. package/node_modules/zod/src/v4/core/json-schema-generator.ts +6 -1
  545. package/node_modules/zod/src/v4/core/json-schema-processors.ts +257 -93
  546. package/node_modules/zod/src/v4/core/json-schema.ts +2 -1
  547. package/node_modules/zod/src/v4/core/memoizer.ts +284 -0
  548. package/node_modules/zod/src/v4/core/parse.ts +131 -38
  549. package/node_modules/zod/src/v4/core/regexes.ts +30 -13
  550. package/node_modules/zod/src/v4/core/registries.ts +2 -2
  551. package/node_modules/zod/src/v4/core/schemas.ts +759 -461
  552. package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +969 -0
  553. package/node_modules/zod/src/v4/core/tests/compile-global.test.ts +89 -0
  554. package/node_modules/zod/src/v4/core/tests/compile-off-by-default.test.ts +26 -0
  555. package/node_modules/zod/src/v4/core/tests/compile-stats.test.ts +34 -0
  556. package/node_modules/zod/src/v4/core/tests/compile.test.ts +1639 -0
  557. package/node_modules/zod/src/v4/core/tests/locales/el.test.ts +1 -2
  558. package/node_modules/zod/src/v4/core/tests/locales/es.test.ts +1 -2
  559. package/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +3 -3
  560. package/node_modules/zod/src/v4/core/tests/locales/parity.test.ts +42 -0
  561. package/node_modules/zod/src/v4/core/tests/locales/tk.test.ts +69 -0
  562. package/node_modules/zod/src/v4/core/tests/treeshake.test.ts +51 -0
  563. package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +31 -0
  564. package/node_modules/zod/src/v4/core/to-json-schema.ts +275 -42
  565. package/node_modules/zod/src/v4/core/util.ts +268 -42
  566. package/node_modules/zod/src/v4/core/versions.ts +2 -2
  567. package/node_modules/zod/src/v4/core/visit.ts +193 -0
  568. package/node_modules/zod/src/v4/index.ts +3 -3
  569. package/node_modules/zod/src/v4/locales/ar.ts +3 -0
  570. package/node_modules/zod/src/v4/locales/az.ts +3 -0
  571. package/node_modules/zod/src/v4/locales/be.ts +10 -0
  572. package/node_modules/zod/src/v4/locales/bg.ts +3 -0
  573. package/node_modules/zod/src/v4/locales/bn.ts +121 -0
  574. package/node_modules/zod/src/v4/locales/ca.ts +3 -0
  575. package/node_modules/zod/src/v4/locales/ckb.ts +138 -0
  576. package/node_modules/zod/src/v4/locales/cs.ts +3 -0
  577. package/node_modules/zod/src/v4/locales/da.ts +5 -2
  578. package/node_modules/zod/src/v4/locales/de.ts +3 -0
  579. package/node_modules/zod/src/v4/locales/el.ts +1 -0
  580. package/node_modules/zod/src/v4/locales/en.ts +15 -4
  581. package/node_modules/zod/src/v4/locales/eo.ts +3 -0
  582. package/node_modules/zod/src/v4/locales/es.ts +2 -0
  583. package/node_modules/zod/src/v4/locales/fa.ts +3 -0
  584. package/node_modules/zod/src/v4/locales/fi.ts +3 -0
  585. package/node_modules/zod/src/v4/locales/fr-CA.ts +3 -0
  586. package/node_modules/zod/src/v4/locales/fr.ts +19 -14
  587. package/node_modules/zod/src/v4/locales/gu.ts +121 -0
  588. package/node_modules/zod/src/v4/locales/he.ts +6 -1
  589. package/node_modules/zod/src/v4/locales/hi.ts +124 -0
  590. package/node_modules/zod/src/v4/locales/hr.ts +2 -0
  591. package/node_modules/zod/src/v4/locales/hu.ts +3 -0
  592. package/node_modules/zod/src/v4/locales/hy.ts +9 -0
  593. package/node_modules/zod/src/v4/locales/id.ts +3 -0
  594. package/node_modules/zod/src/v4/locales/index.ts +10 -0
  595. package/node_modules/zod/src/v4/locales/is.ts +3 -0
  596. package/node_modules/zod/src/v4/locales/it.ts +3 -0
  597. package/node_modules/zod/src/v4/locales/ja.ts +3 -0
  598. package/node_modules/zod/src/v4/locales/ka.ts +3 -0
  599. package/node_modules/zod/src/v4/locales/km.ts +3 -0
  600. package/node_modules/zod/src/v4/locales/kn.ts +124 -0
  601. package/node_modules/zod/src/v4/locales/ko.ts +3 -0
  602. package/node_modules/zod/src/v4/locales/lt.ts +2 -0
  603. package/node_modules/zod/src/v4/locales/mk.ts +3 -0
  604. package/node_modules/zod/src/v4/locales/ms.ts +3 -0
  605. package/node_modules/zod/src/v4/locales/ne.ts +126 -0
  606. package/node_modules/zod/src/v4/locales/nl.ts +3 -0
  607. package/node_modules/zod/src/v4/locales/nn.ts +119 -0
  608. package/node_modules/zod/src/v4/locales/no.ts +5 -2
  609. package/node_modules/zod/src/v4/locales/ota.ts +3 -0
  610. package/node_modules/zod/src/v4/locales/pl.ts +3 -0
  611. package/node_modules/zod/src/v4/locales/ps.ts +3 -0
  612. package/node_modules/zod/src/v4/locales/pt-BR.ts +159 -0
  613. package/node_modules/zod/src/v4/locales/pt.ts +99 -58
  614. package/node_modules/zod/src/v4/locales/ro.ts +1 -0
  615. package/node_modules/zod/src/v4/locales/ru.ts +10 -0
  616. package/node_modules/zod/src/v4/locales/sk.ts +121 -0
  617. package/node_modules/zod/src/v4/locales/sl.ts +3 -0
  618. package/node_modules/zod/src/v4/locales/sv.ts +5 -2
  619. package/node_modules/zod/src/v4/locales/ta.ts +3 -0
  620. package/node_modules/zod/src/v4/locales/th.ts +3 -0
  621. package/node_modules/zod/src/v4/locales/tk.ts +111 -0
  622. package/node_modules/zod/src/v4/locales/tr.ts +3 -0
  623. package/node_modules/zod/src/v4/locales/uk.ts +3 -0
  624. package/node_modules/zod/src/v4/locales/ur.ts +3 -0
  625. package/node_modules/zod/src/v4/locales/uz.ts +1 -0
  626. package/node_modules/zod/src/v4/locales/vi.ts +3 -0
  627. package/node_modules/zod/src/v4/locales/yo.ts +3 -0
  628. package/node_modules/zod/src/v4/locales/zh-CN.ts +3 -0
  629. package/node_modules/zod/src/v4/locales/zh-TW.ts +3 -0
  630. package/node_modules/zod/src/v4/mini/checks.ts +1 -0
  631. package/node_modules/zod/src/v4/mini/deep-partial.ts +73 -0
  632. package/node_modules/zod/src/v4/mini/external.ts +10 -1
  633. package/node_modules/zod/src/v4/mini/in-out.ts +45 -0
  634. package/node_modules/zod/src/v4/mini/parse.ts +2 -0
  635. package/node_modules/zod/src/v4/mini/schemas.ts +135 -56
  636. package/node_modules/zod/src/v4/mini/tests/apply.test.ts +33 -0
  637. package/node_modules/zod/src/v4/mini/tests/assignability.test.ts +62 -1
  638. package/node_modules/zod/src/v4/mini/tests/checks.test.ts +14 -0
  639. package/node_modules/zod/src/v4/mini/tests/codec.test.ts +35 -1
  640. package/node_modules/zod/src/v4/mini/tests/cyclic-data.test.ts +84 -0
  641. package/node_modules/zod/src/v4/mini/tests/deep-partial.test.ts +54 -0
  642. package/node_modules/zod/src/v4/mini/tests/error.test.ts +23 -4
  643. package/node_modules/zod/src/v4/mini/tests/functions.test.ts +9 -0
  644. package/node_modules/zod/src/v4/mini/tests/index.test.ts +72 -5
  645. package/node_modules/zod/src/v4/mini/tests/number.test.ts +14 -0
  646. package/node_modules/zod/src/v4/mini/tests/object.test.ts +65 -0
  647. package/node_modules/zod/src/v4/mini/tests/string.test.ts +21 -0
  648. package/node_modules/zod/v3/ZodError.cjs +22 -12
  649. package/node_modules/zod/v3/ZodError.d.cts +1 -1
  650. package/node_modules/zod/v3/ZodError.d.ts +1 -1
  651. package/node_modules/zod/v3/ZodError.js +22 -12
  652. package/node_modules/zod/v3/types.cjs +7 -5
  653. package/node_modules/zod/v3/types.js +7 -5
  654. package/node_modules/zod/v4/classic/checks.cjs +2 -1
  655. package/node_modules/zod/v4/classic/checks.d.cts +1 -1
  656. package/node_modules/zod/v4/classic/checks.d.ts +1 -1
  657. package/node_modules/zod/v4/classic/checks.js +1 -1
  658. package/node_modules/zod/v4/classic/compat.d.cts +9 -11
  659. package/node_modules/zod/v4/classic/compat.d.ts +9 -11
  660. package/node_modules/zod/v4/classic/deep-partial.cjs +39 -0
  661. package/node_modules/zod/v4/classic/deep-partial.d.cts +14 -0
  662. package/node_modules/zod/v4/classic/deep-partial.d.ts +14 -0
  663. package/node_modules/zod/v4/classic/deep-partial.js +13 -0
  664. package/node_modules/zod/v4/classic/errors.cjs +43 -34
  665. package/node_modules/zod/v4/classic/errors.d.cts +3 -4
  666. package/node_modules/zod/v4/classic/errors.d.ts +3 -4
  667. package/node_modules/zod/v4/classic/errors.js +43 -34
  668. package/node_modules/zod/v4/classic/external.cjs +30 -27
  669. package/node_modules/zod/v4/classic/external.d.cts +5 -2
  670. package/node_modules/zod/v4/classic/external.d.ts +5 -2
  671. package/node_modules/zod/v4/classic/external.js +5 -8
  672. package/node_modules/zod/v4/classic/from-json-schema.cjs +136 -75
  673. package/node_modules/zod/v4/classic/from-json-schema.js +136 -75
  674. package/node_modules/zod/v4/classic/in-out.cjs +63 -0
  675. package/node_modules/zod/v4/classic/in-out.d.cts +8 -0
  676. package/node_modules/zod/v4/classic/in-out.d.ts +8 -0
  677. package/node_modules/zod/v4/classic/in-out.js +36 -0
  678. package/node_modules/zod/v4/classic/index.cjs +2 -2
  679. package/node_modules/zod/v4/classic/index.d.cts +1 -2
  680. package/node_modules/zod/v4/classic/index.d.ts +1 -2
  681. package/node_modules/zod/v4/classic/index.js +2 -2
  682. package/node_modules/zod/v4/classic/iso.cjs +11 -22
  683. package/node_modules/zod/v4/classic/iso.d.cts +2 -17
  684. package/node_modules/zod/v4/classic/iso.d.ts +2 -17
  685. package/node_modules/zod/v4/classic/iso.js +2 -17
  686. package/node_modules/zod/v4/classic/parse.cjs +4 -1
  687. package/node_modules/zod/v4/classic/parse.d.cts +17 -4
  688. package/node_modules/zod/v4/classic/parse.d.ts +17 -4
  689. package/node_modules/zod/v4/classic/parse.js +1 -0
  690. package/node_modules/zod/v4/classic/schemas.cjs +498 -398
  691. package/node_modules/zod/v4/classic/schemas.d.cts +53 -18
  692. package/node_modules/zod/v4/classic/schemas.d.ts +53 -18
  693. package/node_modules/zod/v4/classic/schemas.js +492 -396
  694. package/node_modules/zod/v4/core/api.cjs +23 -4
  695. package/node_modules/zod/v4/core/api.d.cts +13 -9
  696. package/node_modules/zod/v4/core/api.d.ts +13 -9
  697. package/node_modules/zod/v4/core/api.js +21 -4
  698. package/node_modules/zod/v4/core/checks.cjs +37 -31
  699. package/node_modules/zod/v4/core/checks.d.cts +13 -13
  700. package/node_modules/zod/v4/core/checks.d.ts +13 -13
  701. package/node_modules/zod/v4/core/checks.js +37 -31
  702. package/node_modules/zod/v4/core/compile.cjs +1813 -0
  703. package/node_modules/zod/v4/core/compile.d.cts +51 -0
  704. package/node_modules/zod/v4/core/compile.d.ts +51 -0
  705. package/node_modules/zod/v4/core/compile.js +1783 -0
  706. package/node_modules/zod/v4/core/core.cjs +81 -18
  707. package/node_modules/zod/v4/core/core.d.cts +16 -4
  708. package/node_modules/zod/v4/core/core.d.ts +16 -4
  709. package/node_modules/zod/v4/core/core.js +82 -19
  710. package/node_modules/zod/v4/core/doc.cjs +5 -7
  711. package/node_modules/zod/v4/core/doc.d.cts +3 -1
  712. package/node_modules/zod/v4/core/doc.d.ts +3 -1
  713. package/node_modules/zod/v4/core/doc.js +5 -7
  714. package/node_modules/zod/v4/core/errors.cjs +110 -25
  715. package/node_modules/zod/v4/core/errors.d.cts +4 -0
  716. package/node_modules/zod/v4/core/errors.d.ts +4 -0
  717. package/node_modules/zod/v4/core/errors.js +110 -25
  718. package/node_modules/zod/v4/core/index.cjs +5 -1
  719. package/node_modules/zod/v4/core/index.d.cts +3 -0
  720. package/node_modules/zod/v4/core/index.d.ts +3 -0
  721. package/node_modules/zod/v4/core/index.js +3 -0
  722. package/node_modules/zod/v4/core/json-schema-generator.cjs +4 -0
  723. package/node_modules/zod/v4/core/json-schema-generator.d.cts +2 -2
  724. package/node_modules/zod/v4/core/json-schema-generator.d.ts +2 -2
  725. package/node_modules/zod/v4/core/json-schema-generator.js +4 -0
  726. package/node_modules/zod/v4/core/json-schema-processors.cjs +264 -95
  727. package/node_modules/zod/v4/core/json-schema-processors.js +243 -97
  728. package/node_modules/zod/v4/core/json-schema.d.cts +2 -1
  729. package/node_modules/zod/v4/core/json-schema.d.ts +2 -1
  730. package/node_modules/zod/v4/core/memoizer.cjs +272 -0
  731. package/node_modules/zod/v4/core/memoizer.d.cts +15 -0
  732. package/node_modules/zod/v4/core/memoizer.d.ts +15 -0
  733. package/node_modules/zod/v4/core/memoizer.js +265 -0
  734. package/node_modules/zod/v4/core/parse.cjs +96 -34
  735. package/node_modules/zod/v4/core/parse.d.cts +14 -11
  736. package/node_modules/zod/v4/core/parse.d.ts +14 -11
  737. package/node_modules/zod/v4/core/parse.js +94 -33
  738. package/node_modules/zod/v4/core/regexes.cjs +27 -15
  739. package/node_modules/zod/v4/core/regexes.d.cts +2 -0
  740. package/node_modules/zod/v4/core/regexes.d.ts +2 -0
  741. package/node_modules/zod/v4/core/regexes.js +24 -13
  742. package/node_modules/zod/v4/core/registries.js +2 -2
  743. package/node_modules/zod/v4/core/schemas.cjs +537 -326
  744. package/node_modules/zod/v4/core/schemas.d.cts +100 -31
  745. package/node_modules/zod/v4/core/schemas.d.ts +100 -31
  746. package/node_modules/zod/v4/core/schemas.js +526 -325
  747. package/node_modules/zod/v4/core/to-json-schema.cjs +242 -39
  748. package/node_modules/zod/v4/core/to-json-schema.d.cts +42 -3
  749. package/node_modules/zod/v4/core/to-json-schema.d.ts +42 -3
  750. package/node_modules/zod/v4/core/to-json-schema.js +241 -39
  751. package/node_modules/zod/v4/core/util.cjs +212 -31
  752. package/node_modules/zod/v4/core/util.d.cts +58 -1
  753. package/node_modules/zod/v4/core/util.d.ts +58 -1
  754. package/node_modules/zod/v4/core/util.js +202 -30
  755. package/node_modules/zod/v4/core/versions.cjs +2 -2
  756. package/node_modules/zod/v4/core/versions.d.cts +1 -1
  757. package/node_modules/zod/v4/core/versions.d.ts +1 -1
  758. package/node_modules/zod/v4/core/versions.js +2 -2
  759. package/node_modules/zod/v4/core/visit.cjs +195 -0
  760. package/node_modules/zod/v4/core/visit.d.cts +30 -0
  761. package/node_modules/zod/v4/core/visit.d.ts +30 -0
  762. package/node_modules/zod/v4/core/visit.js +169 -0
  763. package/node_modules/zod/v4/index.cjs +15 -5
  764. package/node_modules/zod/v4/index.d.cts +2 -2
  765. package/node_modules/zod/v4/index.d.ts +2 -2
  766. package/node_modules/zod/v4/index.js +3 -2
  767. package/node_modules/zod/v4/locales/ar.cjs +3 -0
  768. package/node_modules/zod/v4/locales/ar.js +3 -0
  769. package/node_modules/zod/v4/locales/az.cjs +3 -0
  770. package/node_modules/zod/v4/locales/az.js +3 -0
  771. package/node_modules/zod/v4/locales/be.cjs +10 -0
  772. package/node_modules/zod/v4/locales/be.js +10 -0
  773. package/node_modules/zod/v4/locales/bg.cjs +3 -0
  774. package/node_modules/zod/v4/locales/bg.js +3 -0
  775. package/node_modules/zod/v4/locales/bn.cjs +138 -0
  776. package/node_modules/zod/v4/locales/bn.d.cts +5 -0
  777. package/node_modules/zod/v4/locales/bn.d.ts +4 -0
  778. package/node_modules/zod/v4/locales/bn.js +111 -0
  779. package/node_modules/zod/v4/locales/ca.cjs +3 -0
  780. package/node_modules/zod/v4/locales/ca.js +3 -0
  781. package/node_modules/zod/v4/locales/ckb.cjs +158 -0
  782. package/node_modules/zod/v4/locales/ckb.d.cts +5 -0
  783. package/node_modules/zod/v4/locales/ckb.d.ts +4 -0
  784. package/node_modules/zod/v4/locales/ckb.js +131 -0
  785. package/node_modules/zod/v4/locales/cs.cjs +3 -0
  786. package/node_modules/zod/v4/locales/cs.js +3 -0
  787. package/node_modules/zod/v4/locales/da.cjs +5 -2
  788. package/node_modules/zod/v4/locales/da.js +5 -2
  789. package/node_modules/zod/v4/locales/de.cjs +3 -0
  790. package/node_modules/zod/v4/locales/de.js +3 -0
  791. package/node_modules/zod/v4/locales/el.cjs +1 -0
  792. package/node_modules/zod/v4/locales/el.js +1 -0
  793. package/node_modules/zod/v4/locales/en.cjs +14 -4
  794. package/node_modules/zod/v4/locales/en.js +14 -4
  795. package/node_modules/zod/v4/locales/eo.cjs +3 -0
  796. package/node_modules/zod/v4/locales/eo.js +3 -0
  797. package/node_modules/zod/v4/locales/es.cjs +2 -0
  798. package/node_modules/zod/v4/locales/es.js +2 -0
  799. package/node_modules/zod/v4/locales/fa.cjs +3 -0
  800. package/node_modules/zod/v4/locales/fa.js +3 -0
  801. package/node_modules/zod/v4/locales/fi.cjs +3 -0
  802. package/node_modules/zod/v4/locales/fi.js +3 -0
  803. package/node_modules/zod/v4/locales/fr-CA.cjs +3 -0
  804. package/node_modules/zod/v4/locales/fr-CA.js +3 -0
  805. package/node_modules/zod/v4/locales/fr.cjs +16 -14
  806. package/node_modules/zod/v4/locales/fr.js +16 -14
  807. package/node_modules/zod/v4/locales/gu.cjs +138 -0
  808. package/node_modules/zod/v4/locales/gu.d.cts +5 -0
  809. package/node_modules/zod/v4/locales/gu.d.ts +4 -0
  810. package/node_modules/zod/v4/locales/gu.js +111 -0
  811. package/node_modules/zod/v4/locales/he.cjs +5 -0
  812. package/node_modules/zod/v4/locales/he.js +5 -0
  813. package/node_modules/zod/v4/locales/hi.cjs +136 -0
  814. package/node_modules/zod/v4/locales/hi.d.cts +5 -0
  815. package/node_modules/zod/v4/locales/hi.d.ts +4 -0
  816. package/node_modules/zod/v4/locales/hi.js +109 -0
  817. package/node_modules/zod/v4/locales/hr.cjs +2 -0
  818. package/node_modules/zod/v4/locales/hr.js +2 -0
  819. package/node_modules/zod/v4/locales/hu.cjs +3 -0
  820. package/node_modules/zod/v4/locales/hu.js +3 -0
  821. package/node_modules/zod/v4/locales/hy.cjs +9 -0
  822. package/node_modules/zod/v4/locales/hy.js +9 -0
  823. package/node_modules/zod/v4/locales/id.cjs +3 -0
  824. package/node_modules/zod/v4/locales/id.js +3 -0
  825. package/node_modules/zod/v4/locales/index.cjs +22 -2
  826. package/node_modules/zod/v4/locales/index.d.cts +10 -0
  827. package/node_modules/zod/v4/locales/index.d.ts +10 -0
  828. package/node_modules/zod/v4/locales/index.js +10 -0
  829. package/node_modules/zod/v4/locales/is.cjs +3 -0
  830. package/node_modules/zod/v4/locales/is.js +3 -0
  831. package/node_modules/zod/v4/locales/it.cjs +3 -0
  832. package/node_modules/zod/v4/locales/it.js +3 -0
  833. package/node_modules/zod/v4/locales/ja.cjs +3 -0
  834. package/node_modules/zod/v4/locales/ja.js +3 -0
  835. package/node_modules/zod/v4/locales/ka.cjs +3 -0
  836. package/node_modules/zod/v4/locales/ka.js +3 -0
  837. package/node_modules/zod/v4/locales/km.cjs +3 -0
  838. package/node_modules/zod/v4/locales/km.js +3 -0
  839. package/node_modules/zod/v4/locales/kn.cjs +141 -0
  840. package/node_modules/zod/v4/locales/kn.d.cts +5 -0
  841. package/node_modules/zod/v4/locales/kn.d.ts +4 -0
  842. package/node_modules/zod/v4/locales/kn.js +114 -0
  843. package/node_modules/zod/v4/locales/ko.cjs +3 -0
  844. package/node_modules/zod/v4/locales/ko.js +3 -0
  845. package/node_modules/zod/v4/locales/lt.cjs +2 -0
  846. package/node_modules/zod/v4/locales/lt.js +2 -0
  847. package/node_modules/zod/v4/locales/mk.cjs +3 -0
  848. package/node_modules/zod/v4/locales/mk.js +3 -0
  849. package/node_modules/zod/v4/locales/ms.cjs +3 -0
  850. package/node_modules/zod/v4/locales/ms.js +3 -0
  851. package/node_modules/zod/v4/locales/ne.cjs +136 -0
  852. package/node_modules/zod/v4/locales/ne.d.cts +5 -0
  853. package/node_modules/zod/v4/locales/ne.d.ts +4 -0
  854. package/node_modules/zod/v4/locales/ne.js +109 -0
  855. package/node_modules/zod/v4/locales/nl.cjs +3 -0
  856. package/node_modules/zod/v4/locales/nl.js +3 -0
  857. package/node_modules/zod/v4/locales/nn.cjs +138 -0
  858. package/node_modules/zod/v4/locales/nn.d.cts +5 -0
  859. package/node_modules/zod/v4/locales/nn.d.ts +4 -0
  860. package/node_modules/zod/v4/locales/nn.js +111 -0
  861. package/node_modules/zod/v4/locales/no.cjs +5 -2
  862. package/node_modules/zod/v4/locales/no.js +5 -2
  863. package/node_modules/zod/v4/locales/ota.cjs +3 -0
  864. package/node_modules/zod/v4/locales/ota.js +3 -0
  865. package/node_modules/zod/v4/locales/pl.cjs +3 -0
  866. package/node_modules/zod/v4/locales/pl.js +3 -0
  867. package/node_modules/zod/v4/locales/ps.cjs +3 -0
  868. package/node_modules/zod/v4/locales/ps.js +3 -0
  869. package/node_modules/zod/v4/locales/pt-BR.cjs +168 -0
  870. package/node_modules/zod/v4/locales/pt-BR.d.cts +5 -0
  871. package/node_modules/zod/v4/locales/pt-BR.d.ts +4 -0
  872. package/node_modules/zod/v4/locales/pt-BR.js +141 -0
  873. package/node_modules/zod/v4/locales/pt.cjs +87 -55
  874. package/node_modules/zod/v4/locales/pt.js +87 -55
  875. package/node_modules/zod/v4/locales/ro.cjs +1 -0
  876. package/node_modules/zod/v4/locales/ro.js +1 -0
  877. package/node_modules/zod/v4/locales/ru.cjs +10 -0
  878. package/node_modules/zod/v4/locales/ru.js +10 -0
  879. package/node_modules/zod/v4/locales/sk.cjs +141 -0
  880. package/node_modules/zod/v4/locales/sk.d.cts +5 -0
  881. package/node_modules/zod/v4/locales/sk.d.ts +4 -0
  882. package/node_modules/zod/v4/locales/sk.js +114 -0
  883. package/node_modules/zod/v4/locales/sl.cjs +3 -0
  884. package/node_modules/zod/v4/locales/sl.js +3 -0
  885. package/node_modules/zod/v4/locales/sv.cjs +5 -2
  886. package/node_modules/zod/v4/locales/sv.js +5 -2
  887. package/node_modules/zod/v4/locales/ta.cjs +3 -0
  888. package/node_modules/zod/v4/locales/ta.js +3 -0
  889. package/node_modules/zod/v4/locales/th.cjs +3 -0
  890. package/node_modules/zod/v4/locales/th.js +3 -0
  891. package/node_modules/zod/v4/locales/tk.cjs +132 -0
  892. package/node_modules/zod/v4/locales/tk.d.cts +5 -0
  893. package/node_modules/zod/v4/locales/tk.d.ts +4 -0
  894. package/node_modules/zod/v4/locales/tk.js +105 -0
  895. package/node_modules/zod/v4/locales/tr.cjs +3 -0
  896. package/node_modules/zod/v4/locales/tr.js +3 -0
  897. package/node_modules/zod/v4/locales/uk.cjs +3 -0
  898. package/node_modules/zod/v4/locales/uk.js +3 -0
  899. package/node_modules/zod/v4/locales/ur.cjs +3 -0
  900. package/node_modules/zod/v4/locales/ur.js +3 -0
  901. package/node_modules/zod/v4/locales/uz.cjs +1 -0
  902. package/node_modules/zod/v4/locales/uz.js +1 -0
  903. package/node_modules/zod/v4/locales/vi.cjs +3 -0
  904. package/node_modules/zod/v4/locales/vi.js +3 -0
  905. package/node_modules/zod/v4/locales/yo.cjs +3 -0
  906. package/node_modules/zod/v4/locales/yo.js +3 -0
  907. package/node_modules/zod/v4/locales/zh-CN.cjs +3 -0
  908. package/node_modules/zod/v4/locales/zh-CN.js +3 -0
  909. package/node_modules/zod/v4/locales/zh-TW.cjs +3 -0
  910. package/node_modules/zod/v4/locales/zh-TW.js +3 -0
  911. package/node_modules/zod/v4/mini/checks.cjs +2 -1
  912. package/node_modules/zod/v4/mini/checks.d.cts +1 -1
  913. package/node_modules/zod/v4/mini/checks.d.ts +1 -1
  914. package/node_modules/zod/v4/mini/checks.js +1 -1
  915. package/node_modules/zod/v4/mini/deep-partial.cjs +39 -0
  916. package/node_modules/zod/v4/mini/deep-partial.d.cts +14 -0
  917. package/node_modules/zod/v4/mini/deep-partial.d.ts +14 -0
  918. package/node_modules/zod/v4/mini/deep-partial.js +13 -0
  919. package/node_modules/zod/v4/mini/external.cjs +12 -1
  920. package/node_modules/zod/v4/mini/external.d.cts +5 -2
  921. package/node_modules/zod/v4/mini/external.d.ts +5 -2
  922. package/node_modules/zod/v4/mini/external.js +3 -1
  923. package/node_modules/zod/v4/mini/in-out.cjs +63 -0
  924. package/node_modules/zod/v4/mini/in-out.d.cts +8 -0
  925. package/node_modules/zod/v4/mini/in-out.d.ts +8 -0
  926. package/node_modules/zod/v4/mini/in-out.js +36 -0
  927. package/node_modules/zod/v4/mini/parse.cjs +3 -1
  928. package/node_modules/zod/v4/mini/parse.d.cts +1 -1
  929. package/node_modules/zod/v4/mini/parse.d.ts +1 -1
  930. package/node_modules/zod/v4/mini/parse.js +1 -1
  931. package/node_modules/zod/v4/mini/schemas.cjs +75 -47
  932. package/node_modules/zod/v4/mini/schemas.d.cts +43 -13
  933. package/node_modules/zod/v4/mini/schemas.d.ts +43 -13
  934. package/node_modules/zod/v4/mini/schemas.js +71 -45
  935. package/openclaw.plugin.json +15 -0
  936. package/package.json +10 -8
  937. package/node_modules/@pierre/diffs/dist/editor/stateStorage.d.ts +0 -15
  938. package/node_modules/@pierre/diffs/dist/editor/stateStorage.d.ts.map +0 -1
  939. package/node_modules/@pierre/diffs/dist/editor/stateStorage.js +0 -65
  940. package/node_modules/@pierre/diffs/dist/editor/stateStorage.js.map +0 -1
  941. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-CyWAfh-p.js +0 -11
  942. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-DhC616m4.css +0 -1
  943. package/node_modules/playwright-core/lib/vite/recorder/assets/index-DYjdXIbE.js +0 -129
  944. package/node_modules/playwright-core/lib/vite/recorder/assets/index-l_lX622x.css +0 -1
  945. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-B-dXF5JN.js +0 -181
  946. package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.BLFoOugd.css +0 -1
  947. package/node_modules/playwright-core/lib/vite/traceViewer/index.KZ4wOW1K.js +0 -1
  948. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.Dzuouizj.js +0 -5
  949. package/node_modules/zod/src/v4/core/config.ts +0 -15
  950. /package/dist/{viewer-assets-D3qrnaxI.js → .setup/viewer-assets-D3qrnaxI.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"editor.js","names":["#fileInstance","#renderRange","#textDocument","#getLineElement","#options","#fileInfo","#textDocumentCache","#stateRestoreGeneration","#restoreStateOnNextSync","#stateStorage","#stateStorageOption","#pendingStateWrites","#invalidateOnAttach","#initialize","#detach","#contentHasFocus","#selections","#applyChange","#applyChangeToLineAnnotations","#runCommand","#getViewportScrollTop","#canMountSelectionAction","#updateSelections","#setViewportScrollTop","#scrollToPrimaryCaret","#revealLineIfCollapsed","#markerRenderer","#getPopoverManager","#metrics","#overlayElement","#getGutterWidth","#getCharX","#getLineY","#isContentMouseDown","#isGutterMouseDown","#contentElement","#getFirstVisibleLineNumber","#focusAtPosition","#focus","#replacementFocusRequest","#shouldIgnoreSelectionChange","#attachState","#persistCurrentState","#handleCustomPasteEvent","#tokenizer","#globalEventDisposes","#editorEventDisposes","#gutterWidthCache","#contentWidthCache","#lineYCache","#wrapLineOffsetsCache","#lineElementsCache","#lastAccessedCharX","#globalStyleElement","#editorStyleElement","#themeStyleElement","#spriteElement","#fileContainer","#popoverManager","#gutterElement","#resizeObserver","#fontRemeasureScheduled","#themeSelectionRefreshFrame","#resetState","#getCachedTextDocument","#initSelections","#onDeferTokenize","#scheduleThemeSelectionRefresh","#remeasureMetricsOnFontLoad","#listenContentElement","#isDiff","#resetCache","#lineAnnotations","#viewportWindowLines","#matches","#primaryCaretElement","#scrollingToLine","#scrollToLine","#scrollingToLineChar","#scrollingToLineNoFocus","#restoreReplacementFocus","#retainSearchPanelFocus","#searchPanel","#restorePersistedState","#scheduleOnAttach","#getStateStorage","#pendingStateRestore","#writeState","#trackStateWrite","#watchViewportUserInput","#getScrollViewport","#resolveRenderableLine","#isLineRenderable","#diffSyle","#isWrap","#selectionAction","#updateSelectionActionPopover","#setEditorActiveLineSafe","#resetSelectionGesture","#suppressNativeSelectionSync","#overlayElements","editorCSS","#rangeBelongsToEditor","#shiftKeyPressed","#selectionStart","#altColumnDrag","#updateAltColumnSelections","#reservedSelections","#selectEventDisposes","#setWindowSelection","#isDeletedLineTarget","#setDeletedTextSelectionActive","#replaceSelectEventListeners","#wrapLineTextOrWholeLine","#isDeletedTextSelectionActive","#deletedTextForClipboard","#writeSelectionClipboardData","#getSelectionText","#getSelectionClipboardTexts","#cutSelectionText","#replaceSelectionText","#handleInput","#isComposing","#preserveEditorSelectionsForGutterGesture","#isLineSelectionEnabled","#beginDeletionGutterSelection","#spanLineSelection","#handleLayoutResize","#computeContentOffset","#contentOffset","#activeContentOffset","#openSearchPanel","#moveSelectedLines","#copySelectedLines","#insertBlankLine","#deleteHardLineForward","#applyCommandEdits","#getRenderedEditableLineRanges","#applyHistoryChange","#getContentWidth","#deleteSelectionText","#deleteSoftLineBackward","#deleteWordBackward","#insertTranspose","#replacementFocusIsAvailable","#getScrollMargin","#scrollingToLineFixed","#deletedSelectionText","#contentRowForGutterRow","#selectDeletedLines","#renderSelection","#renderCaret","#isLineVisible","#renderWrappedSelection","#renderSelectionBlock","#segmentTextWidth","#renderSearchPanel","#applySelectionCutEdits","#rerender","#wrapLineText"],"sources":["../../src/editor/editor.ts"],"sourcesContent":["import {\n dequeueRender,\n queueRender,\n} from '../managers/UniversalRenderingManager';\nimport type {\n DiffLineAnnotation,\n DiffsEditableComponent,\n DiffsEditor,\n DiffsHighlighter,\n EditableInstance,\n EditorChangeEvent,\n EditorSelection,\n EditorState,\n FileContents,\n FileDiffMetadata,\n HighlightedToken,\n LineAnnotation,\n Position,\n Range,\n RenderRange,\n ResolvedTextEdit,\n SelectionSide,\n TextEdit,\n} from '../types';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { isGutterUtilityPath } from '../utils/isGutterUtilityPath';\nimport {\n type EditorCommand,\n type EditorKeymap,\n resolveEditorCommandFromKeyboardEvent,\n resolveFindAgainShortcut,\n} from './command';\nimport editorCSS from './editor.css?inline';\nimport { EditStack } from './editStack';\nimport {\n type LanguageConfigMap,\n resolveBlockCommentEdits,\n resolveCommentConfig,\n resolveLineCommentEdits,\n} from './languages';\nimport {\n applyDocumentChangeToLineAnnotations,\n renderLineAnnotations,\n} from './lineAnnotations';\nimport {\n type Marker,\n MarkerRenderer,\n markerSeverityDatasetKey,\n} from './marker';\nimport { findBracketMatchRanges } from './matchBrackets';\nimport { isMoveCursorShortcut, isPrimaryModifier, isSafari } from './platform';\nimport {\n POPOVER_BOUNDARY_LINES,\n PopoverManager,\n type PopoverPlacementBounds,\n} from './popover';\nimport {\n type MatchRange,\n type SearchPanelMode,\n SearchPanelWidget,\n} from './searchPanel';\nimport type {\n AutoSurround,\n CursorMoveOptions,\n ResolveRenderableLine,\n} from './selection';\nimport {\n applyDeleteCharacterToSelections,\n applyDeleteHardLineForwardToSelections,\n applyDeleteSoftLineBackwardToSelections,\n applyDeleteWordBackwardToSelections,\n applyTextChangeToSelections,\n applyTextReplaceToSelections,\n applyTransposeToSelections,\n comparePosition,\n convertSelection,\n createSelectionFrom,\n createSelectionFromAnchorAndFocusOffsets,\n DirectionBackward,\n DirectionForward,\n DirectionNone,\n expandCollapsedSelectionToWord,\n extendSelection,\n extendSelections,\n findNextMatch,\n getAutoSurroundReplacementTexts,\n getCaretPosition,\n getDocumentBoundarySelection,\n getDocumentFullSelection,\n getSelectedLineBlocks,\n getSelectionAnchor,\n getSelectionClipboardTexts,\n getSelectionText,\n isCollapsedSelection,\n isLineEditable,\n mapCursorMove,\n mapSelectionShift,\n mergeOverlappingSelections,\n remapSelectionsAfterEdits,\n resolveIndentEdits,\n resolveSelectionCut,\n selectionIntersects,\n shiftSelectionLines,\n snapCharacterToGraphemeBoundary,\n} from './selection';\nimport {\n type SelectionActionContext,\n SelectionActionWidget,\n} from './selectionAction';\nimport { createSpriteElement } from './sprite';\nimport {\n cloneEditorState,\n createStateStorage,\n type IStateStorage,\n type PersistStateStorage,\n} from './stateStorage';\nimport { TextDocument, type TextDocumentChange } from './textDocument';\nimport {\n getExpandedAsciiTextColumns,\n getUnicodeMeasurementOffsets,\n Metrics,\n snapTextOffsetToUnicodeBoundary,\n} from './textMeasure';\nimport { EditorTokenizer, renderLineTokens } from './tokenizer';\nimport {\n addEventListener,\n clampDomOffset,\n extend,\n getLineNumberAttr,\n h,\n lookupScrollContainer,\n round,\n} from './utils';\n\n// ShadowRoot.getSelection is a non-standard Blink/WebKit method (predates the\n// spec'd Selection.getComposedRanges) and is missing from the DOM lib types.\ntype ShadowRootWithSelection = ShadowRoot & {\n getSelection?: () => Selection | null;\n};\n\n// Fallback for browsers without Selection.getComposedRanges: read the first\n// range from the shadow root's own selection so the editor can still map a\n// caret placed by a click inside its shadow tree. Normalized to a StaticRange\n// so it matches the getComposedRanges return shape the callers expect. Returns\n// undefined when the API or a live range is unavailable.\nfunction getShadowRootRange(shadowRoot: ShadowRoot): StaticRange | undefined {\n const selection = (shadowRoot as ShadowRootWithSelection).getSelection?.();\n if (selection == null || selection.rangeCount === 0) {\n return undefined;\n }\n const range = selection.getRangeAt(0);\n return {\n collapsed: range.collapsed,\n startContainer: range.startContainer,\n startOffset: range.startOffset,\n endContainer: range.endContainer,\n endOffset: range.endOffset,\n };\n}\n\nfunction requirePersistedCacheKey(\n file: Pick<FileContents, 'cacheKey' | 'name'>\n): string {\n if (typeof file.cacheKey !== 'string' || file.cacheKey.length === 0) {\n throw new Error(\n `Editor persistState requires a non-empty file.cacheKey for \"${file.name}\". Provide a unique, stable cacheKey for every editable file.`\n );\n }\n return file.cacheKey;\n}\n\nfunction isPromise<T>(value: T | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function'\n );\n}\n\ninterface EditorAttachState {\n generation: number;\n callback: (() => void) | undefined;\n delivered: boolean;\n}\n\ninterface ViewportInputWatch {\n userScrolled(): boolean;\n dispose(): void;\n}\n\ninterface AltColumnDrag {\n pointerId: number;\n startClientX: number;\n clientX: number;\n startScrollLeft: number;\n focusLine?: number;\n renderedGoal?: Position;\n}\n\nexport interface EditorOptions<LAnnotation> {\n /** The maximum number of entries to keep in the undo stack. */\n historyMaxEntries?: number;\n /** Custom keymap groups checked before defaults; later groups take precedence. */\n keymap?: EditorKeymap;\n /**\n * Preserve each file's document and item-local editor state when switching files.\n * Every editable file must provide a unique, stable `cacheKey`.\n */\n persistState?: boolean;\n /**\n * Storage for serializable editor state. Text documents stay in this Editor's\n * in-memory cache. Defaults to `\"inMemory\"`.\n */\n persistStateStorage?: PersistStateStorage;\n /** Render rounded corners for selection ranges, default is true. */\n roundedSelection?: boolean;\n /** Highlight matching brackets near the caret, default is true. */\n matchBrackets?: boolean;\n /**\n * Controls auto-surround when typing quotes or brackets over a selection.\n * Default is `\"default\"` (both quotes and brackets).\n */\n autoSurround?: AutoSurround;\n /** Per-language comment tokens used by the comment commands. */\n languageCommentConfig?: LanguageConfigMap;\n /**\n * Show a floating selection action popover after a user-created selection,\n * default is disabled. Programmatic selection updates do not open it.\n */\n enabledSelectionAction?: boolean;\n /**\n * Custom clipboard provider.\n * Highly recommended to use native clipboard API if you are building an electron app.\n * see https://www.electronjs.org/docs/latest/api/clipboard\n */\n clipboard?: {\n readText: (type?: string) => Promise<string> | string;\n };\n /** Render the selection action widget element. */\n renderSelectionAction?: (\n context: SelectionActionContext<LAnnotation>\n ) => HTMLElement;\n /** Callback when the editor is attached to a file. */\n onAttach?: (\n editor: Editor<LAnnotation>,\n fileInstance: DiffsEditableComponent<LAnnotation>\n ) => void;\n /** Callback when the editor document changes. */\n onChange?: (\n file: FileContents,\n lineAnnotations:\n | LineAnnotation<LAnnotation>[]\n | DiffLineAnnotation<LAnnotation>[]\n | undefined,\n event: EditorChangeEvent<LAnnotation>\n ) => void;\n /** Callback when the editor gains focus. */\n onFocus?: () => void;\n /** Callback when the editor loses focus. */\n onBlur?: () => void;\n // debug flag\n __debug?: boolean;\n}\n\nexport interface EditorFocusOptions extends FocusOptions {\n /** One-based document line number or first editable line with a visible top. */\n lineNumber?: number | 'first-visible';\n /** Zero-based character offset for a numeric line. Defaults to 0. */\n character?: number;\n /** Non-negative CSS pixels below the viewport or sticky header. */\n offset?: number;\n}\n\n// Cap on how far an edit may widen the virtualized render window, as a multiple\n// of the bounded window the virtualizer last synced (~viewport + 2*hunkLineCount).\n// Edits within this many lines of the window bottom widen so their caret renders;\n// larger inserts fall back to the bounded buffer-only path instead of building a\n// row per inserted line. A safety bound, not a correctness-critical value.\nconst MAX_EDIT_WIDEN_WINDOW_MULTIPLE = 2;\n\n// Wrap offsets persist across render-range syncs (see #resetCache), so\n// scrolling through a very large file could otherwise accumulate an entry per\n// line. Past this many lines the cache resets and refills lazily for whatever\n// is measured next. A memory bound, not a correctness-critical value.\nconst MAX_WRAP_OFFSETS_CACHE_LINES = 10_000;\nconst SELECTION_ACTION_POPOVER_PLACEMENT_KEY = 'selection-action';\nconst MULTI_SELECTION_CLIPBOARD_TYPE =\n 'application/vnd.pierre.diffs-selections+json';\n\nexport class Editor<LAnnotation> implements DiffsEditor<LAnnotation> {\n #options: EditorOptions<LAnnotation>;\n #metrics = new Metrics();\n #tokenizer?: EditorTokenizer;\n #popoverManager?: PopoverManager;\n #textDocumentCache = new Map<string, TextDocument<LAnnotation>>();\n #stateStorage?: IStateStorage;\n #stateStorageOption?: PersistStateStorage;\n #pendingStateWrites = new Map<string, Promise<void>>();\n #pendingStateRestore?: {\n cacheKey: string;\n textDocument: TextDocument<LAnnotation>;\n documentVersion: number;\n selections: EditorSelection[] | undefined;\n view: EditorState['view'];\n completion: Promise<void>;\n };\n #stateRestoreGeneration = 0;\n #restoreStateOnNextSync = false;\n\n // event disposes\n #editorEventDisposes?: (() => void)[];\n #globalEventDisposes?: (() => void)[];\n #selectEventDisposes?: (() => void)[];\n #detach?: (recycle?: boolean) => void;\n // onAttach is deferred until the synchronized document and DOM are usable.\n // Track the state so cleanup cannot notify an editor from an ended session.\n #attachState: EditorAttachState = {\n generation: 0,\n callback: undefined,\n delivered: false,\n };\n\n // cache\n #contentOffset?: { left: number; top: number };\n #gutterWidthCache?: number;\n #contentWidthCache?: number;\n #lineYCache = new Map<number, number>();\n #wrapLineOffsetsCache = new Map<number, Uint32Array>();\n #lineElementsCache = new Map<number, HTMLElement | null>();\n #lastAccessedCharX?: [\n line: number,\n character: number,\n x: number,\n wrapLine: number,\n ];\n\n // dom\n #globalStyleElement?: HTMLStyleElement;\n #editorStyleElement?: HTMLStyleElement;\n #themeStyleElement?: HTMLStyleElement;\n #spriteElement?: SVGSVGElement;\n #fileContainer?: HTMLElement;\n #gutterElement?: HTMLElement;\n #contentElement?: HTMLElement;\n #overlayElement?: HTMLElement;\n #overlayElements?: Map<string, HTMLElement>;\n #primaryCaretElement?: HTMLElement;\n #resizeObserver?: ResizeObserver;\n\n // state\n #fileInstance?: DiffsEditableComponent<LAnnotation>;\n #fileInfo?: Omit<FileContents, 'contents' | 'header'>;\n #lineAnnotations?: DiffLineAnnotation<LAnnotation>[];\n #textDocument?: TextDocument<LAnnotation>;\n #renderRange?: RenderRange;\n // Bounded render-window size (~viewport + 2*hunkLineCount) from the last view\n // sync. Used to cap how far #applyChange widens the window for an edit, so a\n // large insert can't materialize an unbounded number of rows. Captured at sync\n // time so consecutive edits that grow #renderRange can't ratchet the cap up.\n // undefined until the first sync; Infinity for non-virtualized (whole-file)\n // windows, where no cap is needed.\n #viewportWindowLines?: number;\n #markerRenderer?: MarkerRenderer;\n #searchPanel?: SearchPanelWidget;\n #selectionAction?: SelectionActionWidget;\n // Programmatic ranges stay passive until the user interacts with the editor.\n #canMountSelectionAction = true;\n #shouldIgnoreSelectionChange = false;\n // Set when the browser's native Selection is temporarily not the source of\n // truth for editor text selections. Select-all can only mirror rendered\n // lines, while diff line-selection and gutter-utility gestures can move the\n // native range without selecting editor text. Gutter gestures only enable\n // this when an editor selection exists to preserve; otherwise refocus must\n // remain free to seed a caret. The next direct content pointerdown or keydown\n // clears this, and keeping it through gutter pointerup also protects against\n // a queued selectionchange.\n #suppressNativeSelectionSync = false;\n // Whether the contenteditable holds (or is claiming) focus. Synced by\n // focus/blur listeners and set eagerly by #focus(), whose real focus() call is\n // deferred to a rAF. Lets applyEdits skip focus/scroll only on unfocused\n // editors, without regressing a same-tick setSelections-then-applyEdits flow.\n #contentHasFocus = false;\n // A render-owned request object prevents an older deferred frame from\n // consuming a newer replacement's focus intent. Once synchronized, target\n // identifies the new content so a subsequent user blur can cancel it.\n #replacementFocusRequest?: { target?: HTMLElement };\n #isComposing = false;\n #isGutterMouseDown = false;\n #isContentMouseDown = false;\n #altColumnDrag?: AltColumnDrag;\n #shiftKeyPressed = false;\n #selectionStart: EditorSelection | undefined;\n // The full text of a read-only deleted-line selection built from the gutter,\n // captured when the selection is made. Deleted lines are separate read-only\n // hosts, so window.getSelection() only spans the first line; the copy/cut\n // handlers prefer this. Empty for a direct content drag (no gutter range).\n #deletedSelectionText = '';\n #reservedSelections?: EditorSelection[];\n #initSelections?: EditorSelection[];\n #selections?: EditorSelection[];\n #matches?: MatchRange[];\n #scrollingToLine?: number;\n #scrollingToLineChar?: number;\n #scrollingToLineFixed = false;\n #scrollingToLineNoFocus = false;\n #retainSearchPanelFocus = false;\n #fontRemeasureScheduled = false;\n #themeSelectionRefreshFrame?: number;\n\n #onDeferTokenize = (\n lines: Map<number, Array<HighlightedToken>>,\n themeType: 'light' | 'dark'\n ) => {\n this.#fileInstance?.updateRenderCache(lines, themeType);\n // update the view if the render range is updated by scrolling\n // and the deferred tokenized lines inside the render range\n if (\n this.#renderRange !== undefined &&\n this.#renderRange.totalLines !== Infinity\n ) {\n const { startingLine, totalLines } = this.#renderRange;\n const endLine = Math.min(\n startingLine + totalLines,\n this.#textDocument?.lineCount ?? 0\n );\n for (const [line, tokens] of lines) {\n if (line >= startingLine && line < endLine) {\n const lineElement = this.#getLineElement(line);\n if (lineElement !== undefined) {\n lineElement.replaceChildren(...renderLineTokens(tokens));\n }\n }\n }\n }\n };\n\n constructor(options: EditorOptions<LAnnotation> = {}) {\n this.#options = options;\n }\n\n setOptions(options: EditorOptions<LAnnotation>): void {\n const previousStorageOption =\n this.#options.persistStateStorage ?? 'inMemory';\n const nextOptions = {\n ...this.#options,\n ...options,\n };\n if (\n nextOptions.persistState === true &&\n this.#fileInstance?.type === 'file'\n ) {\n const file = this.#fileInstance.__getCurrentFile?.() ?? this.#fileInfo;\n if (file !== undefined) {\n requirePersistedCacheKey(file);\n }\n }\n this.#options = nextOptions;\n if (this.#options.persistState !== true) {\n this.#textDocumentCache.clear();\n this.#stateRestoreGeneration++;\n this.#restoreStateOnNextSync = false;\n }\n if (\n (this.#options.persistStateStorage ?? 'inMemory') !==\n previousStorageOption\n ) {\n this.#stateRestoreGeneration++;\n this.#stateStorage = undefined;\n this.#stateStorageOption = undefined;\n this.#pendingStateWrites.clear();\n }\n }\n\n // Small typescript hack to prevent UnresolvedFile from being editable.\n edit<T extends DiffsEditableComponent<LAnnotation>>(\n fileInstance: EditableInstance<T>\n ): () => void;\n edit(fileInstance: DiffsEditableComponent<LAnnotation>): () => void {\n if (this.#options.persistState === true && fileInstance.type === 'file') {\n const file = fileInstance.__getCurrentFile?.();\n if (file !== undefined) {\n requirePersistedCacheKey(file);\n }\n }\n this.#invalidateOnAttach();\n this.#fileInstance = fileInstance;\n this.#initialize();\n this.#detach = fileInstance.attachEditor(this);\n return () => this.cleanUp();\n }\n\n /**\n * Apply edits to current attached file. Every edit joins the undo timeline:\n * a programmatic edit must leave the document and its history exactly as\n * the same edit typed by the user would (history equivalence — see\n * TextDocument.applyResolvedEdits), so it is undoable like any other edit.\n *\n * @param updateHistory Whether to record caller selection snapshots for\n * exact undo/redo restoration. Defaults to true. When false, live selections\n * are remapped during replay and the text edit still joins the undo timeline.\n */\n applyEdits(edits: TextEdit[], updateHistory = true): void {\n const textDocument = this.#textDocument;\n if (textDocument == null) {\n throw new Error('Editor is not attached');\n }\n // Only reposition focus and scroll when the editor already holds focus. A\n // programmatic edit must not pull focus from another input the user is\n // typing in; the selection state below is re-anchored either way.\n const wasFocused = this.#contentHasFocus;\n // Capture the current selection edges and the edit ranges as pre-edit\n // offsets so the caret can be re-anchored once the buffer changes. Reading\n // them after applyEdits would resolve against the new buffer and desync.\n const selectionsBefore = this.#selections;\n const selectionOffsetsBefore = selectionsBefore?.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as [number, number]\n );\n // Resolve edits to pre-edit offsets, mirroring TextDocument's own\n // resolution (swap reversed ranges, sort ascending), so the remap matches\n // the edits TextDocument actually applies below.\n const resolvedEditOffsets =\n selectionsBefore === undefined\n ? undefined\n : textDocument.resolveEdits(edits).sort((a, b) => a.start - b.start);\n\n const change = textDocument.applyEdits(\n edits,\n updateHistory,\n selectionsBefore\n );\n if (change === undefined) {\n return;\n }\n\n // Re-anchor selections against the applied edits so the editor #selections,\n // the native window selection, and the on-screen caret stay in sync with\n // the new buffer. Skipping this leaves a programmatic edit (e.g. an AI or\n // codemod insertion) with a stale caret and corrupts the next keystroke.\n let nextSelections: EditorSelection[] | undefined;\n if (\n selectionsBefore !== undefined &&\n selectionOffsetsBefore !== undefined &&\n resolvedEditOffsets !== undefined\n ) {\n nextSelections = remapSelectionsAfterEdits(\n textDocument,\n selectionsBefore,\n selectionOffsetsBefore,\n resolvedEditOffsets\n );\n if (updateHistory) {\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n }\n }\n\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change),\n { skipFocus: !wasFocused }\n );\n }\n\n /** Whether there is an edit to undo. */\n get canUndo(): boolean {\n return this.#textDocument?.canUndo ?? false;\n }\n\n /** Whether there is an undone edit to redo. */\n get canRedo(): boolean {\n return this.#textDocument?.canRedo ?? false;\n }\n\n /** Undo the last edit. Does nothing when there is nothing to undo. */\n undo(): void {\n this.#runCommand('undo');\n }\n\n /** Redo the last undone edit. Does nothing when there is nothing to redo. */\n redo(): void {\n this.#runCommand('redo');\n }\n\n getFile(): FileContents | undefined {\n const fileInfo = this.#fileInfo;\n const textDocument = this.#textDocument;\n if (fileInfo === undefined || textDocument === undefined) {\n return undefined;\n }\n const file = { ...fileInfo }; // copy\n Object.defineProperty(file, 'contents', {\n enumerable: true,\n get: () => textDocument.getText(),\n });\n return file as FileContents;\n }\n\n getText(): string {\n return this.#textDocument?.getText() ?? '';\n }\n\n getState(): EditorState {\n const fileInstance = this.#fileInstance;\n return {\n selections: this.#selections,\n view:\n fileInstance != null\n ? {\n scrollLeft: fileInstance.getCodeScrollLeft(),\n scrollTop: this.#getViewportScrollTop(),\n }\n : undefined,\n };\n }\n\n setState({ selections, view }: EditorState): void {\n if (this.#fileInstance === undefined || this.#textDocument === undefined) {\n throw new Error('Editor is not attached');\n }\n this.#canMountSelectionAction = false;\n this.#updateSelections(selections ?? []);\n // When a saved view is present, honor its scroll offsets exactly. Scrolling\n // the caret into view afterward would overwrite them whenever the caret\n // sits outside that viewport (e.g. TreeApp remount restore).\n if (view != null) {\n this.#fileInstance.setCodeScrollLeft(view.scrollLeft);\n // Records persisted before scrollTop existed lack it: leave the\n // viewport where it is rather than guessing.\n if (view.scrollTop !== undefined) {\n this.#setViewportScrollTop(view.scrollTop);\n }\n return;\n }\n this.#scrollToPrimaryCaret();\n }\n\n setSelections(\n selections: (Range & { direction: 'none' | 'backward' | 'forward' })[]\n ): void {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n throw new Error('Text document is not initialized');\n }\n const resolvedSelections = selections.map<EditorSelection>((selection) => {\n let start = textDocument.normalizePosition(selection.start);\n let end = textDocument.normalizePosition(selection.end);\n let direction: EditorSelection['direction'] =\n selection.direction === 'none'\n ? DirectionNone\n : selection.direction === 'backward'\n ? DirectionBackward\n : DirectionForward;\n\n if (comparePosition(start, end) > 0) {\n [start, end] = [end, start];\n if (direction !== DirectionNone) {\n direction =\n direction === DirectionForward\n ? DirectionBackward\n : DirectionForward;\n }\n }\n return { direction, start, end };\n });\n this.#canMountSelectionAction = false;\n this.#updateSelections(resolvedSelections);\n const primarySelection = resolvedSelections.at(-1);\n if (primarySelection !== undefined) {\n this.#revealLineIfCollapsed(getCaretPosition(primarySelection).line);\n }\n this.#scrollToPrimaryCaret();\n }\n\n setMarkers(markers: Marker[]): void {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n throw new Error('Text document is not initialized');\n }\n\n if (markers.length === 0) {\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#markerRenderer ??= new MarkerRenderer({\n popoverManager: this.#getPopoverManager(),\n getLineHeight: () => this.#metrics.lineHeight,\n getOverlayElement: () => this.#overlayElement,\n getGutterWidth: () => this.#getGutterWidth(),\n getCharX: (line, character) => this.#getCharX(line, character),\n getLineY: (line) => this.#getLineY(line),\n isMouseDown: () => this.#isContentMouseDown || this.#isGutterMouseDown,\n });\n this.#markerRenderer.setMarkers(markers, textDocument);\n if (this.#contentElement !== undefined) {\n this.#markerRenderer.listenHover(this.#contentElement);\n }\n this.#updateSelections(this.#selections ?? []);\n }\n\n focus(options?: EditorFocusOptions): void {\n const preventScroll = options?.preventScroll ?? false;\n const lineNumber = options?.lineNumber;\n if (lineNumber === 'first-visible' || typeof lineNumber === 'number') {\n const textDocument = this.#textDocument;\n if (textDocument == null || this.#fileInstance == null) {\n return;\n }\n const targetLineNumber =\n lineNumber === 'first-visible'\n ? this.#getFirstVisibleLineNumber(options?.offset)\n : lineNumber;\n if (targetLineNumber == null) {\n return;\n }\n const position = textDocument.normalizePosition({\n line: targetLineNumber - 1,\n character:\n lineNumber === 'first-visible' ? 0 : (options?.character ?? 0),\n });\n this.#focusAtPosition(position, preventScroll);\n return;\n }\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n this.#focus(pos, preventScroll);\n } else {\n this.#focus(undefined, preventScroll);\n }\n }\n\n blur(): void {\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#shouldIgnoreSelectionChange = false;\n this.#contentElement?.blur();\n }\n\n cleanUp(recycle = false): void {\n this.#invalidateOnAttach();\n if (!recycle) {\n this.#attachState.delivered = false;\n }\n const hadFileInstance = this.#fileInstance != null;\n const shouldRestoreState = this.#options.persistState === true;\n this.#stateRestoreGeneration++;\n this.#persistCurrentState();\n if (hadFileInstance) {\n this.#restoreStateOnNextSync = shouldRestoreState;\n }\n dequeueRender(this.#handleCustomPasteEvent);\n // The tokenizer is destroyed in both modes: it holds highlighter/worker\n // resources and writes into the (removed below) theme style element.\n // __syncRenderView recreates one for a retained document on re-attach.\n this.#tokenizer?.cleanUp();\n this.#tokenizer = undefined;\n\n // A full cleanUp (Edit-mode off, surface switch, unmount) drops the parsed\n // document and its file identity so the next edit() rebuilds from the\n // host's current contents. A recycle cleanUp — a virtualized host\n // temporarily unmounting — keeps them, along with the undo history living\n // inside the document, so a later edit() against the same\n // name/lang/cacheKey resumes the session via __syncRenderView's\n // reused-document path.\n if (!recycle) {\n this.#textDocument = undefined;\n this.#fileInfo = undefined;\n }\n\n // dispse event listeners\n this.#globalEventDisposes?.forEach((dispose) => dispose());\n this.#globalEventDisposes = undefined;\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = undefined;\n this.#detach?.(recycle);\n this.#detach = undefined;\n\n // cache\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n this.#lineElementsCache.clear();\n this.#lastAccessedCharX = undefined;\n\n // clean up dom elements\n this.#globalStyleElement?.remove();\n this.#globalStyleElement = undefined;\n this.#editorStyleElement?.remove();\n this.#editorStyleElement = undefined;\n this.#themeStyleElement?.remove();\n this.#themeStyleElement = undefined;\n this.#spriteElement?.remove();\n this.#spriteElement = undefined;\n this.#fileContainer = undefined;\n this.#popoverManager?.cleanUp();\n this.#popoverManager = undefined;\n this.#gutterElement = undefined;\n this.#contentElement?.removeAttribute('contentEditable');\n this.#contentElement = undefined;\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#overlayElement?.remove();\n this.#overlayElement = undefined;\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n // Let a reused instance schedule the font re-measure again on its next\n // mount, where a different font-family string may not be loaded yet.\n this.#fontRemeasureScheduled = false;\n if (this.#themeSelectionRefreshFrame !== undefined) {\n cancelAnimationFrame(this.#themeSelectionRefreshFrame);\n this.#themeSelectionRefreshFrame = undefined;\n }\n\n this.#resetState();\n this.#fileInstance = undefined;\n }\n\n /** @internal Capture outgoing state and substitute cached text before render. */\n __prepareFile(file: FileContents): FileContents {\n if (this.#options.persistState !== true) {\n return file;\n }\n\n const cacheKey = requirePersistedCacheKey(file);\n const fileInfo = this.#fileInfo;\n const languageId = file.lang ?? getFiletypeFromFileName(file.name);\n if (\n fileInfo !== undefined &&\n (requirePersistedCacheKey(fileInfo) !== cacheKey ||\n fileInfo.name !== file.name ||\n this.#textDocument?.languageId !== languageId)\n ) {\n this.#stateRestoreGeneration++;\n this.#persistCurrentState();\n }\n const textDocument = this.#getCachedTextDocument(file, cacheKey);\n if (\n textDocument === undefined ||\n textDocument.getText() === file.contents\n ) {\n return file;\n }\n return { ...file, contents: textDocument.getText() };\n }\n\n /** @internal */\n __postponeBgTokenizeToNextFrame(): void {\n const tokenizer = this.#tokenizer;\n if (tokenizer !== undefined) {\n tokenizer.pauseBackgroundTokenize();\n requestAnimationFrame(() => {\n tokenizer.resumeBackgroundTokenize();\n });\n }\n }\n\n /** @internal */\n __captureFocusForDOMReplacement(): void {\n const contentElement = this.#contentElement;\n const shadowActiveElement = this.#fileContainer?.shadowRoot?.activeElement;\n if (\n contentElement != null &&\n (this.#contentHasFocus ||\n shadowActiveElement === contentElement ||\n (shadowActiveElement != null &&\n contentElement.contains(shadowActiveElement)))\n ) {\n this.#replacementFocusRequest = {};\n }\n }\n\n /** @internal */\n __syncRenderView: DiffsEditor<LAnnotation>['__syncRenderView'] = (\n highlighter: DiffsHighlighter,\n fileContainer: HTMLElement,\n fileOrDiff: FileContents | FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined,\n renderRange: RenderRange | undefined\n ) => {\n const fileInstance = this.#fileInstance;\n if (fileInstance == null) {\n return;\n }\n const shadowRoot = fileContainer.shadowRoot;\n if (shadowRoot == null) {\n console.error('[editor] Could not find the shadow root.');\n return;\n }\n\n let codeElement: HTMLElement | undefined;\n let gutterEl: HTMLElement | undefined;\n let contentEl: HTMLElement | undefined;\n for (const el of shadowRoot.querySelectorAll<HTMLElement>('[data-code]')) {\n if (el.dataset.deletions === undefined) {\n codeElement = el;\n for (const child of el.children) {\n const el = child as HTMLElement;\n const { gutter, content } = el.dataset;\n if (gutter !== undefined) {\n gutterEl = el;\n } else if (content !== undefined) {\n contentEl = el;\n }\n }\n break;\n }\n }\n if (codeElement === undefined || contentEl === undefined) {\n this.#replacementFocusRequest = undefined;\n return;\n }\n\n this.#getPopoverManager().setViewportElements(fileContainer, codeElement);\n\n // inject editor&theme style to the file container\n if (this.#fileContainer !== fileContainer) {\n this.#fileContainer = fileContainer;\n if (this.#globalStyleElement !== undefined) {\n fileContainer.appendChild(this.#globalStyleElement);\n }\n if (this.#editorStyleElement !== undefined) {\n shadowRoot.appendChild(this.#editorStyleElement);\n }\n if (this.#themeStyleElement !== undefined) {\n shadowRoot.appendChild(this.#themeStyleElement);\n }\n if (this.#spriteElement !== undefined) {\n shadowRoot.prepend(this.#spriteElement);\n }\n }\n\n // Whether this sync replaces the document with a freshly parsed one (a new\n // file, language, or cache key) versus reusing the existing one. A reused\n // document matches the DOM the host just rebuilt: renderers persist edit\n // sessions into the host's own data (DiffHunksRenderer keeps\n // `diff.additionLines` in sync per edit; FileRenderer writes the session\n // contents back into the file on recycle), so an unchanged\n // name/lang/cacheKey re-attach renders the same text the document holds.\n const shouldRebuildDocument =\n this.#textDocument === undefined ||\n this.#fileInfo === undefined ||\n this.#fileInfo.name !== fileOrDiff.name ||\n this.#fileInfo.lang !== fileOrDiff.lang ||\n this.#fileInfo.cacheKey !== fileOrDiff.cacheKey;\n const persistedCacheKey =\n this.#options.persistState === true\n ? requirePersistedCacheKey(fileOrDiff)\n : undefined;\n\n let persistedStateTarget:\n | { cacheKey: string; textDocument: TextDocument<LAnnotation> }\n | undefined;\n\n if (shouldRebuildDocument) {\n this.#invalidateOnAttach();\n let contents = '';\n if ('contents' in fileOrDiff) {\n contents = fileOrDiff.contents;\n } else {\n contents = fileOrDiff.additionLines.join('');\n }\n const editStack = new EditStack<LAnnotation>({\n maxEntries: this.#options.historyMaxEntries,\n });\n const { name, lang, cacheKey } = fileOrDiff;\n const languageId = lang ?? getFiletypeFromFileName(fileOrDiff.name);\n const cachedTextDocument =\n persistedCacheKey !== undefined\n ? this.#getCachedTextDocument(fileOrDiff, persistedCacheKey)\n : undefined;\n // A File render substitutes cached text before painting (see\n // __prepareFile), so its DOM always matches a reused document.\n const reusableTextDocument =\n fileInstance.type === 'file' ||\n cachedTextDocument?.getText() === contents\n ? cachedTextDocument\n : undefined;\n const textDocument =\n reusableTextDocument ??\n new TextDocument(fileOrDiff.name, contents, languageId, 0, editStack);\n this.#fileInfo = { name, lang, cacheKey };\n this.#textDocument = textDocument;\n if (persistedCacheKey !== undefined) {\n this.#textDocumentCache.set(persistedCacheKey, textDocument);\n persistedStateTarget = {\n cacheKey: persistedCacheKey,\n textDocument,\n };\n }\n this.#tokenizer?.cleanUp();\n this.#tokenizer = undefined;\n this.#resetState();\n // Wrap offsets survive #resetCache, so a document swap on a reused\n // content element must drop the previous document's measurements here.\n this.#wrapLineOffsetsCache.clear();\n this.#selections = this.#initSelections;\n if (this.#options.__debug === true) {\n // A reused document keeps its undo history; only the fallback path\n // actually rebuilds one from the host's contents.\n console.log(\n reusableTextDocument !== undefined\n ? '[diffs/editor] cached text document reused for'\n : '[diffs/editor] text document rebuilt from',\n fileOrDiff.name\n );\n }\n }\n\n if (\n persistedStateTarget === undefined &&\n this.#restoreStateOnNextSync &&\n persistedCacheKey !== undefined &&\n this.#textDocument !== undefined\n ) {\n persistedStateTarget = {\n cacheKey: persistedCacheKey,\n textDocument: this.#textDocument,\n };\n }\n\n // The tokenizer is (re)created whenever the current document lacks one:\n // right after a fresh document build above, or on the first sync after a\n // recycle cleanUp re-attached a retained document. Tying it to the\n // document (rather than the rebuild) is what keeps a re-attach with an\n // unchanged cacheKey — which skips the rebuild — able to paint edits.\n const textDocument = this.#textDocument;\n if (this.#tokenizer == null && textDocument != null) {\n this.#tokenizer = new EditorTokenizer({\n highlighter,\n textDocument,\n codeOptions: this.#fileInstance?.__getEffectiveCodeOptions() ?? {},\n matchBrackets: this.#options.matchBrackets,\n onDeferTokenize: this.#onDeferTokenize,\n onThemeChange: () => this.#scheduleThemeSelectionRefresh(),\n setStyle: (css) => {\n this.#themeStyleElement!.textContent = css;\n },\n __debug: this.#options.__debug,\n });\n }\n\n if (this.#contentElement !== contentEl) {\n this.#gutterElement = gutterEl;\n this.#contentElement = extend(contentEl, {\n contentEditable: 'true',\n role: 'textbox',\n ariaMultiLine: 'true',\n autocapitalize: 'off',\n writingSuggestions: 'off',\n autocorrect: false,\n spellcheck: false,\n translate: false,\n });\n if (this.#overlayElement !== undefined) {\n contentEl.after(this.#overlayElement);\n }\n this.#metrics.init(contentEl);\n this.#remeasureMetricsOnFontLoad();\n this.#listenContentElement(contentEl, gutterEl);\n if (\n this.#contentElement !== undefined &&\n this.#options.__debug === true\n ) {\n console.log('[diffs/editor] full re-render triggered !!!');\n }\n }\n if (this.#replacementFocusRequest != null) {\n this.#replacementFocusRequest.target = contentEl;\n }\n\n // The contenteditable host advertises role=\"textbox\", so without an\n // accessible name screen readers announce an unlabeled text field. Label it\n // with the file name. The same content element is reused across file\n // switches (see File#applyFullRender), so refresh the label on every sync\n // rather than only when the element is first initialized above.\n if (contentEl.ariaLabel !== fileOrDiff.name) {\n contentEl.ariaLabel = fileOrDiff.name;\n }\n\n // Annotation rows, unified deleted rows, and hunk separators are\n // non-document rows living inside the contenteditable column; mark them\n // read-only so the caret can never enter them. Separators render in both\n // diff styles whenever a collapsed region exists.\n if (\n (lineAnnotations !== undefined && lineAnnotations.length > 0) ||\n this.#isDiff\n ) {\n for (const child of this.#contentElement.children) {\n const el = child as HTMLElement;\n const { lineAnnotation, lineType, separator } = el.dataset;\n if (\n lineAnnotation !== undefined ||\n separator !== undefined ||\n lineType === 'change-deletion'\n ) {\n el.setAttribute('contenteditable', 'false');\n }\n }\n }\n\n this.#resetCache();\n\n // The tokenizer is created once per attached document and reused across\n // re-renders, so a host-driven theme swap (theme picker, light/dark toggle)\n // wouldn't otherwise reach it. Re-apply the surface's current theme on every\n // sync so the editor's line-highlight/token colors track the active theme.\n this.#tokenizer?.syncTheme(\n this.#fileInstance?.__getEffectiveCodeOptions() ?? {}\n );\n\n this.#lineAnnotations = lineAnnotations;\n this.#renderRange = renderRange;\n // Remember the bounded window the virtualizer just synced so #applyChange\n // can clamp any edit-time widening against it. Refreshed on every scroll;\n // undefined/Infinity windows leave the clamp disabled.\n this.#viewportWindowLines = renderRange?.totalLines;\n this.#tokenizer?.prebuildStateStack(renderRange);\n\n this.#markerRenderer?.removePopover();\n\n // re-render the existing selections, matches, and markers\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n\n if (\n this.#initSelections !== undefined &&\n this.#primaryCaretElement !== undefined\n ) {\n this.#initSelections = undefined;\n this.#scrollToPrimaryCaret(false, 'center');\n } else if (this.#scrollingToLine !== undefined) {\n this.#scrollToLine(\n this.#scrollingToLine,\n this.#scrollingToLineChar,\n this.#scrollingToLineNoFocus\n );\n } else if (this.#replacementFocusRequest !== undefined) {\n this.#restoreReplacementFocus();\n } else if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n this.#contentHasFocus &&\n !this.#retainSearchPanelFocus\n ) {\n this.focus({ preventScroll: true });\n }\n\n if (this.#retainSearchPanelFocus) {\n this.#searchPanel?.focus();\n }\n\n if (this.#options.__debug === true && renderRange !== undefined) {\n const { startingLine, totalLines } = renderRange;\n console.log(\n '[diffs/editor] render file:',\n fileOrDiff.name,\n 'RenderRange:',\n startingLine + '-' + (startingLine + totalLines),\n 'of',\n this.#textDocument?.lineCount,\n 'lines'\n );\n }\n\n if (persistedStateTarget !== undefined) {\n this.#restoreStateOnNextSync = false;\n this.#restorePersistedState(\n persistedStateTarget.cacheKey,\n persistedStateTarget.textDocument\n );\n }\n\n this.#scheduleOnAttach(fileInstance);\n };\n\n #getCachedTextDocument(\n file: FileContents | FileDiffMetadata,\n cacheKey: string\n ): TextDocument<LAnnotation> | undefined {\n const textDocument = this.#textDocumentCache.get(cacheKey);\n const languageId = file.lang ?? getFiletypeFromFileName(file.name);\n return textDocument?.languageId === languageId ? textDocument : undefined;\n }\n\n #getStateStorage(): IStateStorage {\n const option = this.#options.persistStateStorage ?? 'inMemory';\n if (\n this.#stateStorage === undefined ||\n this.#stateStorageOption !== option\n ) {\n this.#stateStorage = createStateStorage(option);\n this.#stateStorageOption = option;\n }\n return this.#stateStorage;\n }\n\n #persistCurrentState(): void {\n const fileInfo = this.#fileInfo;\n const textDocument = this.#textDocument;\n if (\n this.#options.persistState !== true ||\n // Requires an attached instance: a repeated cleanUp still holds the\n // retained fileInfo but must not write (empty) state over the record\n // the first cleanUp persisted.\n this.#fileInstance === undefined ||\n fileInfo === undefined ||\n textDocument === undefined\n ) {\n return;\n }\n\n const cacheKey = requirePersistedCacheKey(fileInfo);\n this.#textDocumentCache.set(cacheKey, textDocument);\n\n let storage: IStateStorage;\n try {\n storage = this.#getStateStorage();\n } catch {\n return;\n }\n const state = cloneEditorState(this.getState());\n const pendingRestore = this.#pendingStateRestore;\n if (\n pendingRestore?.cacheKey === cacheKey &&\n pendingRestore.textDocument === textDocument\n ) {\n this.#pendingStateRestore = undefined;\n if (\n textDocument.version === pendingRestore.documentVersion &&\n this.#selections === pendingRestore.selections &&\n state.view?.scrollLeft === pendingRestore.view?.scrollLeft &&\n state.view?.scrollTop === pendingRestore.view?.scrollTop\n ) {\n return;\n }\n this.#writeState(storage, cacheKey, state, pendingRestore.completion);\n return;\n }\n\n this.#writeState(storage, cacheKey, state);\n }\n\n // Writes for the same key stay ordered even when custom storage is async.\n #writeState(\n storage: IStateStorage,\n cacheKey: string,\n state: EditorState,\n waitFor?: Promise<void>\n ): void {\n const previousWrite = this.#pendingStateWrites.get(cacheKey);\n if (waitFor !== undefined || previousWrite !== undefined) {\n let pending = waitFor ?? Promise.resolve();\n if (previousWrite !== undefined) {\n pending = pending.then(() => previousWrite);\n }\n this.#trackStateWrite(\n cacheKey,\n pending.then(() => storage.set(cacheKey, state))\n );\n return;\n }\n\n let result: void | Promise<void>;\n try {\n result = storage.set(cacheKey, state);\n } catch {\n return;\n }\n if (!isPromise(result)) {\n return;\n }\n\n this.#trackStateWrite(cacheKey, result);\n }\n\n #trackStateWrite(cacheKey: string, result: Promise<void>): void {\n const pending = result.catch(() => {});\n this.#pendingStateWrites.set(cacheKey, pending);\n void pending.finally(() => {\n if (this.#pendingStateWrites.get(cacheKey) === pending) {\n this.#pendingStateWrites.delete(cacheKey);\n }\n });\n }\n\n #restorePersistedState(\n cacheKey: string,\n textDocument: TextDocument<LAnnotation>\n ): void {\n const generation = ++this.#stateRestoreGeneration;\n const documentVersion = textDocument.version;\n const selections = this.#selections;\n const view = this.getState().view;\n let inputWatch: ViewportInputWatch | undefined;\n const applyState = (state: EditorState | undefined): void => {\n const currentView = this.getState().view;\n // scrollTop is deliberately not part of this staleness check: the\n // surface can legitimately adjust vertical scroll while an async read\n // is in flight (height reconciliation, clamping), and that must not\n // block the restore. User scrolls are detected by `inputWatch` instead.\n if (\n generation !== this.#stateRestoreGeneration ||\n this.#textDocument !== textDocument ||\n textDocument.version !== documentVersion ||\n this.#selections !== selections ||\n currentView?.scrollLeft !== view?.scrollLeft ||\n this.#fileInfo === undefined ||\n requirePersistedCacheKey(this.#fileInfo) !== cacheKey\n ) {\n return;\n }\n // Once the user engages the viewport, the vertical position is theirs:\n // neither the first-open reset nor a stored scrollTop may move it.\n const userScrolled = inputWatch?.userScrolled() === true;\n if (state === undefined) {\n // No stored record for this cacheKey — the file is opened for the\n // first time. Start the code scroller and the viewport at the top\n // instead of inheriting whatever offset the previous file left in a\n // viewport that stays mounted across switches.\n this.#fileInstance?.setCodeScrollLeft(0);\n if (!userScrolled) {\n this.#setViewportScrollTop(0);\n }\n return;\n }\n const restored = cloneEditorState(state);\n if (userScrolled && restored.view !== undefined) {\n restored.view = { scrollLeft: restored.view.scrollLeft };\n }\n this.setState(restored);\n };\n const readState = (): void | Promise<void> => {\n let result: EditorState | undefined | Promise<EditorState | undefined>;\n try {\n result = this.#getStateStorage().get(cacheKey);\n } catch {\n return;\n }\n if (isPromise(result)) {\n return result.then(applyState).catch(() => {});\n } else {\n try {\n applyState(result);\n } catch {}\n }\n };\n\n const pendingWrite = this.#pendingStateWrites.get(cacheKey);\n const result =\n pendingWrite === undefined ? readState() : pendingWrite.then(readState);\n if (isPromise(result)) {\n inputWatch = this.#watchViewportUserInput();\n const pendingRestore = {\n cacheKey,\n textDocument,\n documentVersion,\n selections,\n view,\n completion: result.catch(() => {}),\n };\n this.#pendingStateRestore = pendingRestore;\n void pendingRestore.completion.finally(() => {\n inputWatch?.dispose();\n if (this.#pendingStateRestore === pendingRestore) {\n this.#pendingStateRestore = undefined;\n }\n });\n }\n }\n\n #watchViewportUserInput(): ViewportInputWatch | undefined {\n const viewport = this.#getScrollViewport();\n if (!(viewport instanceof HTMLElement)) {\n return undefined;\n }\n let scrolled = false;\n const eventTypes = ['wheel', 'touchstart', 'mousedown'] as const;\n const dispose = (): void => {\n for (const type of eventTypes) {\n viewport.removeEventListener(type, onInput, { capture: true });\n }\n };\n const onInput = (): void => {\n scrolled = true;\n dispose();\n };\n for (const type of eventTypes) {\n viewport.addEventListener(type, onInput, {\n capture: true,\n passive: true,\n });\n }\n return { userScrolled: () => scrolled, dispose };\n }\n\n // Whether a zero-based document line has (or will have on scroll) a\n // rendered row. False only for lines hidden inside a collapsed unchanged\n // region of a diff host; hosts without collapsible regions treat every\n // line as renderable.\n #isLineRenderable(line: number): boolean {\n return this.#fileInstance?.isLineRenderable?.(line + 1) ?? true;\n }\n\n // Fold-skip resolver for vertical caret motion (zero-based lines), or\n // undefined for hosts without collapsible regions so motion stays plain\n // line arithmetic.\n get #resolveRenderableLine(): ResolveRenderableLine | undefined {\n const fileInstance = this.#fileInstance;\n if (fileInstance?.getNearestRenderableLine == null) {\n return undefined;\n }\n return (line, direction) => {\n const nearest = fileInstance.getNearestRenderableLine!(\n line + 1,\n direction\n );\n return nearest == null ? undefined : nearest - 1;\n };\n }\n\n // Jump targets (search matches, undo restores, setSelections, doc-end\n // moves) may land inside a collapsed region; expand it minimally so the\n // caret's row can render before the scroll below retries toward it.\n #revealLineIfCollapsed(line: number): void {\n if (!this.#isLineRenderable(line)) {\n this.#fileInstance?.revealLine?.(line + 1);\n }\n }\n\n get #diffSyle(): 'unified' | 'split' {\n return this.#fileInstance?.options.diffStyle ?? 'split';\n }\n\n get #isDiff(): boolean {\n return this.#fileInstance?.type === 'file-diff';\n }\n\n get #isWrap(): boolean {\n return this.#fileInstance?.options.overflow === 'wrap';\n }\n\n #getPopoverManager(): PopoverManager {\n return (this.#popoverManager ??= new PopoverManager({\n hasActivePopover: () =>\n this.#selectionAction !== undefined ||\n this.#markerRenderer?.isPopoverVisible() === true,\n updateActivePopover: () => {\n this.#updateSelectionActionPopover();\n this.#markerRenderer?.updatePopoverPosition();\n },\n }));\n }\n\n // Drop the DOM-geometry caches (memoized row elements, measured line Ys,\n // last caret x).\n #resetCache(): void {\n this.#lineYCache.clear();\n this.#lineElementsCache.clear();\n this.#lastAccessedCharX = undefined;\n }\n\n #resetState(): void {\n this.#setEditorActiveLineSafe(null);\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#resetSelectionGesture();\n this.#suppressNativeSelectionSync = false;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements = undefined;\n this.#selections = undefined;\n this.#scrollingToLine = undefined;\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#searchPanel?.cleanup();\n this.#searchPanel = undefined;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n this.#canMountSelectionAction = true;\n }\n\n #invalidateOnAttach(): void {\n const attachState = this.#attachState;\n attachState.generation++;\n if (attachState.callback != null) {\n dequeueRender(attachState.callback);\n attachState.callback = undefined;\n }\n }\n\n // A recycled attachment remains the same edit session. If its first\n // notification was canceled, the next live synchronization reschedules it;\n // once delivered, later recycled mounts stay silent.\n #scheduleOnAttach(fileInstance: DiffsEditableComponent<LAnnotation>): void {\n const attachState = this.#attachState;\n const textDocument = this.#textDocument;\n if (\n attachState.delivered ||\n attachState.callback != null ||\n textDocument == null\n ) {\n return;\n }\n const { generation } = attachState;\n const callback = () => {\n if (attachState.callback !== callback) {\n return;\n }\n attachState.callback = undefined;\n if (\n generation !== attachState.generation ||\n this.#fileInstance !== fileInstance ||\n this.#textDocument !== textDocument\n ) {\n return;\n }\n const contentElement = this.#contentElement;\n const shadowRoot = this.#fileContainer?.shadowRoot;\n // A host rerender queued ahead of this callback may have replaced the\n // editable DOM while its asynchronous editor sync is still pending.\n if (\n contentElement == null ||\n shadowRoot == null ||\n !shadowRoot.contains(contentElement)\n ) {\n return;\n }\n attachState.delivered = true;\n this.#options.onAttach?.(this, fileInstance);\n };\n attachState.callback = callback;\n queueRender(callback);\n }\n\n // Get the editor's scrolling viewport, return undefined if the Virtualizer\n // is not present.`\n #getScrollViewport(): HTMLElement | Document | undefined {\n const viewport = this.#fileInstance?.getEditorViewport?.();\n if (viewport !== undefined) {\n return viewport;\n }\n const fileContainer = this.#fileContainer;\n if (this.#fileInstance == null || fileContainer == null) {\n return undefined;\n }\n return lookupScrollContainer(fileContainer);\n }\n\n #getViewportScrollTop(): number {\n const viewport = this.#getScrollViewport();\n if (viewport instanceof HTMLElement) {\n return viewport.scrollTop;\n }\n return viewport?.defaultView?.scrollY ?? 0;\n }\n\n #setViewportScrollTop(scrollTop: number): void {\n const viewport = this.#getScrollViewport();\n if (viewport instanceof HTMLElement) {\n viewport.scrollTop = scrollTop;\n } else if (viewport instanceof Document) {\n viewport.defaultView?.scrollTo({ top: scrollTop });\n }\n }\n\n #initialize(): void {\n // Safari doesn't support `::selection` for slot elements in ShadowDOM,\n // Add a global style to disable selection for slot elements\n this.#globalStyleElement = h('style', {\n dataset: 'editorGlobalCss',\n textContent: `\n [data-annotation-slot] {\n user-select: none;\n -webkit-user-select: none;\n }\n `,\n });\n\n this.#editorStyleElement = h('style', {\n dataset: 'editorCss',\n textContent: editorCSS,\n });\n\n this.#themeStyleElement = h('style', {\n dataset: 'editorThemeCss',\n });\n\n this.#spriteElement = createSpriteElement();\n\n this.#overlayElement = h('div', {\n dataset: 'editorOverlay',\n });\n\n const replacementFocusTargetIsContent = (event: Event) => {\n const target = event.composedPath()[0];\n return (\n target instanceof Node &&\n this.#contentElement?.contains(target) === true\n );\n };\n const cancelReplacementFocus = () => {\n if (this.#replacementFocusRequest == null) {\n return;\n }\n\n // A focus or pointer target outside the editor owns the newer intent.\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#shouldIgnoreSelectionChange = false;\n };\n const finishMouseSelection = (event: PointerEvent) => {\n if (event.pointerType !== 'mouse') {\n return;\n }\n\n const refocusEditor = this.#isGutterMouseDown;\n this.#resetSelectionGesture();\n if (refocusEditor) {\n this.#focus();\n }\n\n // The popover is suppressed while the mouse is down so it doesn't\n // flicker under the cursor mid-drag. Once settled, re-run the overlay\n // pass so a ranged selection reveals it.\n if (\n this.#options.enabledSelectionAction === true &&\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n !isCollapsedSelection(this.#selections.at(-1)!)\n ) {\n this.#updateSelections(this.#selections);\n }\n };\n this.#globalEventDisposes = [\n addEventListener(\n document,\n 'focusin',\n (event) => {\n if (!replacementFocusTargetIsContent(event)) {\n cancelReplacementFocus();\n }\n },\n { passive: true }\n ),\n addEventListener(\n document,\n 'pointerdown',\n (event) => {\n if (!replacementFocusTargetIsContent(event)) {\n // Target handlers can synchronously render and arm the request.\n queueMicrotask(cancelReplacementFocus);\n }\n },\n { capture: true, passive: true }\n ),\n\n addEventListener(\n document,\n 'selectionchange',\n () => {\n const shadowRoot = this.#fileContainer?.shadowRoot;\n // Ignore selection changes while the contenteditable is unfocused. A\n // programmatic applyEdits (skipFocus) re-anchors #selections without\n // syncing the native Selection, so a DOM-driven or refocus\n // selectionchange whose range still belongs to the editor must not\n // overwrite the remapped #selections before the user returns to type.\n if (\n this.#shouldIgnoreSelectionChange ||\n this.#suppressNativeSelectionSync ||\n shadowRoot == null ||\n !this.#contentHasFocus\n ) {\n return;\n }\n\n // Native selection only tracks one range. focus() and DOM updates while\n // typing mirror the primary caret there, so selectionchange must not\n // overwrite multi-cursor editor state outside an active pointer gesture.\n if (\n this.#selections !== undefined &&\n this.#selections.length > 1 &&\n !this.#isContentMouseDown\n ) {\n return;\n }\n\n const selectionRaw = document.getSelection();\n if (selectionRaw == null) {\n return;\n }\n // Read the caret/selection through the editor's shadow root.\n // getComposedRanges is the standard, spec'd way to do this but is only\n // available in newer browsers. When it is missing (older browsers,\n // embedded WebViews, and the pinned CI Chromium), fall back to the\n // older Blink/WebKit-specific ShadowRoot.getSelection(), which still\n // reports the range inside the shadow tree. Only bail when neither API\n // yields a range, so a click can still seed the caret rather than\n // leaving the surface unusable.\n const composedRange =\n typeof selectionRaw.getComposedRanges === 'function'\n ? selectionRaw.getComposedRanges({\n shadowRoots: [shadowRoot],\n })?.[0]\n : getShadowRootRange(shadowRoot);\n if (\n composedRange === undefined ||\n !this.#rangeBelongsToEditor(composedRange)\n ) {\n return;\n }\n\n let selection = convertSelection(composedRange, DirectionNone);\n if (selection === undefined) {\n return;\n }\n\n // extend selection by shift + click\n if (\n this.#isContentMouseDown &&\n this.#shiftKeyPressed &&\n this.#selections !== undefined &&\n this.#selections.length > 0\n ) {\n const primarySelection = this.#selections.at(-1)!;\n this.#updateSelections([\n extendSelection(primarySelection, selection),\n ]);\n return;\n }\n\n if (this.#isContentMouseDown) {\n if (this.#selectionStart !== undefined) {\n selection = createSelectionFrom(this.#selectionStart, selection);\n } else {\n this.#selectionStart = selection;\n }\n } else if (this.#selectionStart !== undefined) {\n selection.direction = createSelectionFrom(\n this.#selectionStart,\n selection\n ).direction;\n } else if (\n this.#selections !== undefined &&\n this.#selections.length === 1\n ) {\n // getComposedRanges only reports an ordered start/end range, so a\n // selectionchange fired by a refocus (or by our own focus-handler\n // setBaseAndExtent) carries no direction and would otherwise flip a\n // backward selection to DirectionNone, jumping the caret/popover to\n // the bottom. When the bounds are unchanged, keep the prior\n // direction; a genuine change (different bounds) still resets it.\n const previous = this.#selections[0];\n if (\n comparePosition(previous.start, selection.start) === 0 &&\n comparePosition(previous.end, selection.end) === 0\n ) {\n selection.direction = previous.direction;\n }\n }\n\n if (this.#altColumnDrag !== undefined) {\n this.#altColumnDrag.focusLine = getCaretPosition(selection).line;\n if (this.#updateAltColumnSelections()) {\n return;\n }\n }\n\n if (this.#reservedSelections !== undefined) {\n this.#updateSelections([\n ...this.#reservedSelections.filter(\n (reservedSelection) =>\n !selectionIntersects(reservedSelection, selection)\n ),\n selection,\n ]);\n } else {\n this.#updateSelections([selection]);\n }\n },\n { passive: true }\n ),\n\n addEventListener(document, 'pointerup', finishMouseSelection, {\n passive: true,\n }),\n addEventListener(document, 'pointercancel', finishMouseSelection, {\n passive: true,\n }),\n\n addEventListener(\n document,\n 'keydown',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = this.#selections?.at(-1);\n }\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'keyup',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = undefined;\n }\n },\n { passive: true }\n ),\n ];\n }\n\n // End any in-flight text or gutter selection and release its document-level\n // listeners. Pointer completion, cancellation, and editor resets share this\n // path so none can strand gesture state.\n #resetSelectionGesture(): void {\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = undefined;\n this.#shouldIgnoreSelectionChange = false;\n this.#isGutterMouseDown = false;\n this.#isContentMouseDown = false;\n this.#altColumnDrag = undefined;\n this.#shiftKeyPressed = false;\n this.#selectionStart = undefined;\n this.#reservedSelections = undefined;\n }\n\n // Swaps in a new batch of transient \"select\" listeners — gutter drag\n // tracking or the Safari annotation-hover workaround — disposing the\n // previous batch first. Routing every reassignment through here keeps the\n // dispose-before-replace invariant in one place: a stale set (e.g. from a\n // pointerup that never fired after a canceled gesture, or a fresh\n // pointerdown before the previous interaction tore down) can never be\n // overwritten while its listeners are still attached to the document.\n #replaceSelectEventListeners(disposes: (() => void)[]): void {\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = disposes;\n }\n\n // Normal line selection owns gutter gestures when enabled, so the editor\n // must not also turn the same drag into a text selection.\n #isLineSelectionEnabled(): boolean {\n return this.#fileInstance?.options.enableLineSelection === true;\n }\n\n // Gutter gestures owned by diff interactions must not replace the editor's\n // text selections through a browser-generated selectionchange.\n #preserveEditorSelectionsForGutterGesture(): void {\n this.#suppressNativeSelectionSync = this.#selections !== undefined;\n }\n\n #listenContentElement(contentEl: HTMLElement, gutterEl?: HTMLElement): void {\n const { onFocus, onBlur } = this.#options;\n const targetIsContentElement = (e: Event) => {\n const target = e.composedPath()[0] as HTMLElement | undefined;\n return (\n target !== undefined &&\n (target === contentEl || contentEl.contains(target))\n );\n };\n\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = [\n addEventListener(\n contentEl,\n 'focus',\n () => {\n this.#contentHasFocus = true;\n onFocus?.();\n // A keyboard or direct programmatic refocus restores a stale native\n // Selection that the selectionchange handler would apply over the\n // remapped #selections (after an applyEdits inserted a line above the\n // unfocused caret). Re-assert the editor's selection so the caret\n // stays anchored. A pointer focus is left to the click, and #focus()\n // already syncs the selection during an editor-driven focus.\n if (\n !this.#isContentMouseDown &&\n !this.#shouldIgnoreSelectionChange &&\n this.#selections !== undefined &&\n this.#selections.length > 0\n ) {\n this.#setWindowSelection(this.#selections.at(-1)!);\n }\n },\n { passive: true }\n ),\n addEventListener(\n contentEl,\n 'blur',\n () => {\n if (this.#replacementFocusRequest?.target === contentEl) {\n this.#replacementFocusRequest = undefined;\n this.#shouldIgnoreSelectionChange = false;\n }\n this.#contentHasFocus = false;\n onBlur?.();\n },\n { passive: true }\n ),\n addEventListener(\n contentEl,\n 'pointerdown',\n (e) => {\n this.#canMountSelectionAction = true;\n // Any pointer press — mouse, touch, or pen — moves off the select-all\n // selection, so let selectionchange sync #selections from the new\n // native selection again. This must run before the mouse-only guard\n // below: a touch or pen tap also moves the caret, and if the flag\n // stayed set its selectionchange would be ignored and the next typed\n // character would replace the whole still-selected document.\n this.#suppressNativeSelectionSync = false;\n\n if (e.pointerType !== 'mouse') {\n return;\n }\n this.#altColumnDrag = undefined;\n\n // A click on a read-only deleted line (unified view) selects it\n // natively. Hand the selection to the deleted text and drop the\n // editor's own selection, so only one region is highlighted at a\n // time and the deleted line is not swept into an editable selection.\n if (this.#isDeletedLineTarget(e)) {\n this.#setDeletedTextSelectionActive(true);\n if (this.#selections !== undefined) {\n this.#updateSelections([]);\n }\n return;\n }\n this.#setDeletedTextSelectionActive(false);\n\n this.#markerRenderer?.removePopover();\n\n // this is a workaround for the selection rendering glitch\n // happens when selecting content in shadow DOM on Safari\n const selectEventDisposes: (() => void)[] = [];\n if (\n isSafari() &&\n this.#lineAnnotations !== undefined &&\n this.#lineAnnotations.length > 0\n ) {\n const annotationDisposes = [\n ...contentEl.querySelectorAll<HTMLElement>(\n '[data-line-annotation]'\n ),\n ]\n .map((el) => [\n addEventListener(el, 'mouseenter', () => {\n this.#shouldIgnoreSelectionChange = true;\n }),\n addEventListener(el, 'mouseleave', () => {\n this.#shouldIgnoreSelectionChange = false;\n }),\n ])\n .flat();\n selectEventDisposes.push(...annotationDisposes);\n }\n\n this.#isContentMouseDown = true;\n const isAltColumnDrag =\n e.button === 0 &&\n e.altKey &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.shiftKey;\n this.#selectionStart = undefined;\n if (isAltColumnDrag) {\n this.#altColumnDrag = {\n pointerId: e.pointerId,\n startClientX: e.clientX,\n clientX: e.clientX,\n startScrollLeft: contentEl.parentElement?.scrollLeft ?? 0,\n };\n this.#reservedSelections = undefined;\n this.#selections = undefined;\n this.#updateSelections([]);\n selectEventDisposes.push(\n addEventListener(\n document,\n 'pointermove',\n (moveEvent) => {\n const drag = this.#altColumnDrag;\n if (\n drag === undefined ||\n moveEvent.pointerType !== 'mouse' ||\n moveEvent.pointerId !== drag.pointerId\n ) {\n return;\n }\n drag.clientX = moveEvent.clientX;\n this.#updateAltColumnSelections();\n },\n { capture: true, passive: true }\n )\n );\n } else if (e.button === 0 && isPrimaryModifier(e)) {\n this.#reservedSelections = this.#selections?.map((selection) => ({\n ...selection,\n }));\n }\n this.#replaceSelectEventListeners(selectEventDisposes);\n if (e.shiftKey) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n // fix the window selection for shift mode\n this.#setWindowSelection({\n start: pos,\n end: pos,\n direction: DirectionNone,\n });\n }\n this.#shiftKeyPressed = true;\n }\n },\n { passive: true }\n ),\n\n addEventListener(contentEl, 'keydown', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#canMountSelectionAction = true;\n // A keystroke is the user acting on the select-all selection (deleting,\n // typing, moving); let selectionchange sync #selections again.\n this.#suppressNativeSelectionSync = false;\n\n // keyCode 229 opens the composition, before compositionstart fires.\n if (e.isComposing || e.keyCode === 229) {\n return;\n }\n\n const command = resolveEditorCommandFromKeyboardEvent(\n e,\n this.#options.keymap\n );\n if (command !== undefined) {\n e.preventDefault();\n if (command === 'simplifySelection') {\n this.#searchPanel?.close();\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n }\n this.#runCommand(command);\n return;\n }\n\n // handle the cursor move events manually for multiple selections and virtual viewport\n const mvShortcut = isMoveCursorShortcut(e);\n const textDocument = this.#textDocument;\n if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n mvShortcut !== undefined &&\n textDocument !== undefined\n ) {\n const cursorMoveOptions: CursorMoveOptions = {\n getSoftLineOffsets: this.#isWrap\n ? (line) => this.#wrapLineTextOrWholeLine(line)\n : undefined,\n resolveRenderableLine: this.#resolveRenderableLine,\n };\n if (e.shiftKey) {\n this.#updateSelections(\n mapSelectionShift(\n textDocument,\n this.#selections,\n mvShortcut,\n cursorMoveOptions\n )\n );\n } else {\n this.#updateSelections(\n mapCursorMove(\n textDocument,\n this.#selections,\n mvShortcut,\n cursorMoveOptions\n )\n );\n }\n this.#scrollToPrimaryCaret();\n e.preventDefault();\n return;\n }\n\n const normalizedKey = e.key.length === 1 ? e.key.toLowerCase() : e.key;\n if (normalizedKey === 'v' && isPrimaryModifier(e)) {\n // Holding paste can enqueue a costly full diff recompute for every\n // keyboard repeat. Accept the first paste and suppress repeats.\n if (e.repeat && this.#isDiff) {\n e.preventDefault();\n return;\n }\n\n // Handle the 'paste' event manually with the custom clipboard API.\n if (this.#options.clipboard !== undefined) {\n e.preventDefault();\n queueRender(this.#handleCustomPasteEvent);\n return;\n }\n }\n\n // Only hijack the native find-again shortcut while the panel is open\n // so cmd+g/cmd+shift+g step through matches; otherwise leave it alone.\n if (this.#searchPanel !== undefined) {\n const findAgain = resolveFindAgainShortcut(e);\n if (findAgain !== undefined) {\n e.preventDefault();\n this.#searchPanel.navigate(findAgain === 'previous');\n return;\n }\n }\n }),\n\n addEventListener(contentEl, 'copy', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // A read-only deleted-text selection lives outside the editor's\n // document, so #getSelectionText() would be empty. Copy the selected\n // deleted text instead.\n if (this.#isDeletedTextSelectionActive()) {\n e.clipboardData?.setData('text', this.#deletedTextForClipboard());\n } else {\n this.#writeSelectionClipboardData(\n e.clipboardData,\n this.#getSelectionText(),\n this.#getSelectionClipboardTexts()\n );\n }\n }),\n\n addEventListener(contentEl, 'cut', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // Deleted text is read-only and can't be removed, so a cut there copies\n // the selected deleted text (like the copy handler) without editing.\n if (this.#isDeletedTextSelectionActive()) {\n e.clipboardData?.setData('text', this.#deletedTextForClipboard());\n } else {\n const selectionTexts = this.#getSelectionClipboardTexts();\n this.#writeSelectionClipboardData(\n e.clipboardData,\n this.#cutSelectionText(),\n selectionTexts\n );\n }\n }),\n\n addEventListener(contentEl, 'paste', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n const clipboardData = e.clipboardData;\n const textDocument = this.#textDocument;\n if (clipboardData === null || textDocument === undefined) {\n return;\n }\n\n let text: string | string[] = clipboardData.getData('text');\n\n const selectionCount = this.#selections?.length ?? 0;\n if (selectionCount > 1) {\n const multiSelectionText = clipboardData.getData(\n MULTI_SELECTION_CLIPBOARD_TYPE\n );\n if (multiSelectionText !== undefined) {\n try {\n const selectionTexts = JSON.parse(multiSelectionText);\n if (\n Array.isArray(selectionTexts) &&\n selectionTexts.length === selectionCount\n ) {\n text = selectionTexts;\n }\n } catch {\n // ignore the invalid custom clipboard data\n }\n }\n }\n\n // Rewrite clipboard line breaks to the document's EOL so a Windows\n // clipboard (\\r\\n or \\r) doesn't leave mixed line endings behind.\n this.#replaceSelectionText(\n Array.isArray(text)\n ? text.map((t) => textDocument.normalizeEol(t))\n : textDocument.normalizeEol(text),\n undefined,\n true,\n 'document'\n );\n }),\n\n addEventListener(contentEl, 'beforeinput', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n if (e.inputType === 'insertCompositionText') {\n return;\n }\n e.preventDefault();\n this.#handleInput(e.inputType, e.data);\n }),\n\n addEventListener(contentEl, 'drop', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // TODO(@ije): Add support of drag move selection\n }),\n\n addEventListener(\n contentEl,\n 'compositionstart',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#isComposing = true;\n this.#shouldIgnoreSelectionChange = true;\n },\n { passive: true }\n ),\n\n addEventListener(\n contentEl,\n 'compositionend',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#shouldIgnoreSelectionChange = false;\n const wasComposing = this.#isComposing;\n this.#isComposing = false;\n // An empty compositionend during a tracked composition means the\n // candidate was canceled (e.g. Esc), so there is nothing to commit.\n if (e.data !== '' || !wasComposing) {\n this.#handleInput('insertText', e.data);\n }\n },\n { passive: true }\n ),\n ];\n\n // A selection in the read-only deletions column is painted natively (see\n // the gated ::selection rule). Starting one there reveals that selection\n // and clears the editor's own selection on the additions side, so only one\n // column shows a selection at a time. Non-diff files have no deletions\n // column.\n const deletionsCode =\n this.#fileContainer?.shadowRoot?.querySelector<HTMLElement>(\n '[data-deletions]'\n );\n if (deletionsCode != null) {\n this.#editorEventDisposes.push(\n addEventListener(\n deletionsCode,\n 'pointerdown',\n (e) => {\n const path = e.composedPath();\n if (isGutterUtilityPath(path)) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n // Clicking a deletion line's number selects the whole line's text\n // and dragging extends the selection across deletion lines (like a\n // click/drag on an addition line number); clicking its text lets\n // the browser place/extend the selection directly. Either way the\n // deleted-text marker reveals it and the editor drops its own\n // selection.\n const target = path[0];\n const gutterRow =\n target instanceof HTMLElement\n ? target.closest('[data-column-number]')\n : null;\n if (gutterRow instanceof HTMLElement) {\n if (this.#isLineSelectionEnabled()) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n if (\n this.#beginDeletionGutterSelection(\n gutterRow,\n deletionsCode,\n e.pointerType === 'mouse'\n )\n ) {\n return;\n }\n }\n this.#setDeletedTextSelectionActive(true);\n if (this.#selections !== undefined) {\n this.#updateSelections([]);\n }\n },\n { passive: true }\n )\n );\n }\n\n if (gutterEl !== undefined) {\n const resolveGutterTarget = (\n eventTarget: HTMLElement | undefined,\n includeContentLine = false\n ) => {\n let target = eventTarget;\n if (target?.dataset.lineNumberContent !== undefined) {\n target = target.parentElement ?? undefined;\n } else if (includeContentLine && target?.tagName === 'SPAN') {\n target = target.closest('[data-line]') as HTMLElement | undefined;\n }\n return target;\n };\n\n const resolveEditableLine = (target: HTMLElement | undefined) => {\n if (target === undefined) {\n return;\n }\n const lineType = target.dataset.lineType;\n const lineNumber =\n getLineNumberAttr(target) ??\n getLineNumberAttr(target, 'columnNumber');\n if (\n lineNumber === undefined ||\n lineType === undefined ||\n !isLineEditable(lineType)\n ) {\n return;\n }\n return lineNumber - 1;\n };\n\n this.#editorEventDisposes.push(\n addEventListener(\n gutterEl,\n 'pointerdown',\n (e) => {\n const path = e.composedPath();\n if (isGutterUtilityPath(path)) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n const gutterRow = resolveGutterTarget(\n path[0] as HTMLElement | undefined\n );\n if (gutterRow !== undefined && this.#isLineSelectionEnabled()) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n // Clicking a read-only deleted line's number (unified view) selects\n // that line's text natively, since the line is not in the editor's\n // document. This runs before the mouse-only gate below: a deletion\n // tap registers no drag state to strand, so it works on touch too,\n // matching the split deletions column.\n if (gutterRow?.dataset.lineType === 'change-deletion') {\n const code = gutterRow.closest('[data-code]');\n if (code != null) {\n this.#beginDeletionGutterSelection(\n gutterRow,\n code,\n e.pointerType === 'mouse'\n );\n }\n return;\n }\n\n // Editable gutter drag-selection is mouse-only: the global pointerup\n // that clears #isGutterMouseDown and disposes the mousemove listener\n // bails for non-mouse pointers, so reacting to a touch/pen tap here\n // would strand that state and leak the listener. Mirror the content\n // pointerdown guard.\n if (e.pointerType !== 'mouse') {\n return;\n }\n\n const textDocument = this.#textDocument;\n const lineIndex = resolveEditableLine(gutterRow);\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n this.#canMountSelectionAction = true;\n this.#markerRenderer?.removePopover();\n const selection = this.#spanLineSelection(\n lineIndex,\n lineIndex,\n textDocument\n );\n this.#isGutterMouseDown = true;\n this.#selectionStart = selection;\n this.#updateSelections([selection]);\n // Span the native selection across the clicked line and focus\n // without collapsing it. #focus(position) would drop a collapsed\n // caret at the line end, which a later selectionchange then turns\n // into a bare caret — so a single click on a line number would\n // place a cursor instead of selecting the whole line's text.\n this.#setWindowSelection(selection);\n this.#focus();\n this.#replaceSelectEventListeners([\n addEventListener(\n document,\n 'mousemove',\n (e) => {\n if (!this.#isGutterMouseDown) {\n return;\n }\n const textDocument = this.#textDocument;\n const lineIndex = resolveEditableLine(\n resolveGutterTarget(\n e.composedPath()[0] as HTMLElement | undefined,\n true\n )\n );\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n // A gutter drag keeps both the clicked line (the anchor) and\n // the line under the pointer fully selected. Until a drag\n // outruns its pointerdown the anchor is set; if it somehow is\n // not, the line under the pointer becomes the anchor.\n const anchorLine =\n this.#selectionStart?.start.line ?? lineIndex;\n const selection = this.#spanLineSelection(\n anchorLine,\n lineIndex,\n textDocument\n );\n this.#selectionStart ??= selection;\n this.#updateSelections([selection]);\n this.#focus(\n selection.direction === DirectionBackward\n ? selection.start\n : selection.end\n );\n },\n { passive: true }\n ),\n ]);\n },\n { passive: true }\n )\n );\n }\n\n this.#markerRenderer?.listenHover(contentEl);\n\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = new ResizeObserver(this.#handleLayoutResize);\n this.#resizeObserver.observe(contentEl);\n this.#resizeObserver.observe(contentEl.parentElement!);\n this.#computeContentOffset(contentEl);\n }\n\n #handleCustomPasteEvent = async () => {\n const clipboard = this.#options.clipboard;\n if (clipboard !== undefined) {\n let text: string | string[] = await clipboard.readText();\n const selectionCount = this.#selections?.length ?? 0;\n if (selectionCount > 1) {\n const multiSelectionText = await clipboard.readText(\n MULTI_SELECTION_CLIPBOARD_TYPE\n );\n try {\n const selectionTexts = JSON.parse(multiSelectionText);\n if (\n Array.isArray(selectionTexts) &&\n selectionTexts.length === selectionCount\n ) {\n text = selectionTexts;\n }\n } catch {\n // Invalid selection metadata falls back to the plain-text value.\n }\n }\n const textDocument = this.#textDocument;\n if (textDocument !== undefined) {\n this.#replaceSelectionText(\n Array.isArray(text)\n ? text.map((t) => textDocument.normalizeEol(t))\n : textDocument.normalizeEol(text),\n undefined,\n true,\n 'document'\n );\n }\n }\n };\n\n // diff(split) treat the content element as grid item,\n // that breaks the overlay element positioning.\n // this function computes the content offset to fix\n // the overlay element position.\n #computeContentOffset(contentEl: HTMLElement) {\n if (this.#isDiff && this.#diffSyle === 'split' && this.#isWrap) {\n this.#contentOffset = {\n top: contentEl.offsetTop,\n left: contentEl.offsetLeft - this.#getGutterWidth(),\n };\n if (this.#options.__debug === true) {\n console.log('[diffs/editor] content offset:', this.#contentOffset);\n }\n }\n }\n\n // #computeContentOffset only assigns #contentOffset in a split + wrap diff and\n // never clears it, so after toggling wrap off (or switching to unified) the\n // same editor keeps a stale offset. Read it through this getter, which returns\n // the offset only while the live layout is the one that produced it, so a\n // stale value is never applied to caret, selection, or line-Y positions.\n get #activeContentOffset(): { left: number; top: number } | undefined {\n if (this.#isDiff && this.#diffSyle === 'split' && this.#isWrap) {\n return this.#contentOffset;\n }\n return undefined;\n }\n\n #runCommand(command: EditorCommand) {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n return;\n }\n\n switch (command) {\n case 'openSearchPanel':\n this.#openSearchPanel('find');\n break;\n\n case 'openSearchReplacePanel':\n this.#openSearchPanel('replace');\n break;\n\n case 'findNextMatch': {\n const selections = this.#selections;\n if (selections === undefined) {\n break;\n }\n const hasCollapsed = selections.some(isCollapsedSelection);\n if (hasCollapsed) {\n const expanded: EditorSelection[] = selections.map((sel) => {\n if (isCollapsedSelection(sel)) {\n return expandCollapsedSelectionToWord(textDocument, sel);\n }\n return sel;\n });\n this.#updateSelections(expanded);\n this.focus();\n } else {\n const nextMatch = findNextMatch(textDocument, selections);\n if (nextMatch !== undefined) {\n this.#updateSelections(nextMatch);\n const primaryMatch = nextMatch.at(-1);\n if (primaryMatch !== undefined) {\n this.#revealLineIfCollapsed(getCaretPosition(primaryMatch).line);\n }\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n }\n\n case 'moveLineUp':\n case 'moveLineDown':\n this.#moveSelectedLines(command === 'moveLineUp' ? -1 : 1);\n break;\n\n case 'copyLineUp':\n case 'copyLineDown':\n this.#copySelectedLines(command === 'copyLineUp' ? -1 : 1);\n break;\n\n case 'simplifySelection': {\n const selections = this.#selections;\n const primarySelection = selections?.at(-1);\n if (selections === undefined || primarySelection === undefined) {\n break;\n }\n if (selections.length > 1) {\n this.#updateSelections([primarySelection]);\n this.#focus(getCaretPosition(primarySelection));\n } else if (!isCollapsedSelection(primarySelection)) {\n const caret = getCaretPosition(primarySelection);\n this.#updateSelections([\n { start: caret, end: caret, direction: DirectionNone },\n ]);\n this.#focus(caret);\n }\n break;\n }\n\n case 'insertBlankLine':\n this.#insertBlankLine();\n break;\n\n case 'deleteHardLineForward':\n this.#deleteHardLineForward();\n break;\n\n case 'toggleComment':\n case 'toggleBlockComment': {\n const selections = this.#selections;\n if (selections === undefined) {\n break;\n }\n const { lineComment, blockComment } = resolveCommentConfig(\n textDocument.languageId,\n this.#options.languageCommentConfig\n );\n if (command === 'toggleComment' && lineComment !== null) {\n this.#applyCommandEdits(\n resolveLineCommentEdits(textDocument, selections, lineComment)\n );\n break;\n }\n const linewise = command === 'toggleComment';\n const result = resolveBlockCommentEdits(\n textDocument,\n selections,\n blockComment,\n linewise\n );\n if (result !== undefined) {\n this.#applyCommandEdits(\n result.edits,\n linewise\n ? undefined\n : (document) =>\n result.nextSelectionOffsets.map(\n ([start, end, direction]) => ({\n start: document.positionAt(start),\n end: document.positionAt(end),\n direction,\n })\n )\n );\n }\n break;\n }\n\n case 'indent':\n case 'outdent':\n case 'indentLess':\n case 'indentMore':\n if (this.#selections !== undefined) {\n const edits: TextEdit[] = [];\n const nextSelections: EditorSelection[] = [];\n // Line-based indentation is resolved per selection, so overlapping\n // line coverage must share the same leading-whitespace edit.\n const editedLines = new Set<number>();\n // Single-line indent inserts text at each caret. When several carets\n // share a line, indentation inserted by carets to their left shifts\n // them right, so record each one here and offset its resulting\n // position once every edit on the line is known. Without this, later\n // same-line carets land before their own inserted indent.\n const sameLineIndents: Array<{\n line: number;\n startCharacter: number;\n addedLength: number;\n selectionIndex: number;\n }> = [];\n for (const selection of this.#selections) {\n const startLine = selection.start.line;\n const outdent = command === 'outdent' || command === 'indentLess';\n const lineBased =\n command === 'indentLess' || command === 'indentMore';\n if (startLine !== selection.end.line || outdent || lineBased) {\n const ret = resolveIndentEdits(\n textDocument,\n selection,\n this.#metrics.tabSize,\n outdent\n );\n for (const edit of ret[0]) {\n const line = edit.range.start.line;\n if (!editedLines.has(line)) {\n editedLines.add(line);\n edits.push(edit);\n }\n }\n nextSelections.push(ret[1]);\n } else {\n const lineChar0 = textDocument.charAt({\n line: startLine,\n character: 0,\n });\n const text =\n lineChar0 === '\\t' ? '\\t' : ' '.repeat(this.#metrics.tabSize);\n edits.push({\n range: selection,\n newText: text,\n });\n sameLineIndents.push({\n line: startLine,\n startCharacter: selection.start.character,\n addedLength:\n text.length -\n (selection.end.character - selection.start.character),\n selectionIndex: nextSelections.length,\n });\n const nextPosition = {\n line: selection.start.line,\n character: selection.start.character + text.length,\n };\n nextSelections.push({\n start: nextPosition,\n end: nextPosition,\n direction: DirectionNone,\n });\n }\n }\n for (const indent of sameLineIndents) {\n let shift = 0;\n for (const other of sameLineIndents) {\n if (\n other.line === indent.line &&\n other.startCharacter < indent.startCharacter\n ) {\n shift += other.addedLength;\n }\n }\n if (shift !== 0) {\n const current = nextSelections[indent.selectionIndex];\n const position = {\n line: indent.line,\n character: current.start.character + shift,\n };\n nextSelections[indent.selectionIndex] = {\n start: position,\n end: position,\n direction: DirectionNone,\n };\n }\n }\n const change = textDocument.applyEdits(\n edits,\n true,\n this.#selections,\n nextSelections\n );\n if (change !== undefined) {\n this.#applyChange(change, nextSelections);\n }\n }\n break;\n\n case 'selectAll': {\n const fullSelection = getDocumentFullSelection(textDocument);\n this.#updateSelections([fullSelection]);\n this.focus();\n // The editor paints selections with an overlay and otherwise leaves the\n // native selection a collapsed caret. focus() above collapses it to the\n // document start, and Safari/WebKit then fires no delete beforeinput for\n // a following Backspace — nothing sits before a caret at offset 0 — so\n // select-all then delete is silently dropped. Give WebKit a non-collapsed\n // native selection so it emits the delete; Chrome already deletes via\n // #selections regardless. #setWindowSelection can only resolve lines that\n // are currently rendered, and in a virtualized diff most of the document\n // is offscreen, so anchor the native range to the editable lines on\n // screen rather than the document bounds. The native range only needs to\n // be non-collapsed — the edit uses #selections, which still spans the\n // whole document. #suppressNativeSelectionSync then stops the resulting\n // selectionchange from reading that shorter range back over #selections\n // before the delete runs.\n const renderedLineRanges = this.#getRenderedEditableLineRanges();\n const firstRenderedLine = renderedLineRanges[0]?.[0];\n const lastRenderedLine = renderedLineRanges.at(-1)?.[1];\n if (firstRenderedLine !== undefined && lastRenderedLine !== undefined) {\n this.#suppressNativeSelectionSync = true;\n this.#setWindowSelection({\n start: { line: firstRenderedLine, character: 0 },\n end: {\n line: lastRenderedLine,\n character: textDocument.getLineLength(lastRenderedLine),\n },\n direction: DirectionForward,\n });\n }\n break;\n }\n\n case 'moveCursorToDocStart':\n case 'moveCursorToDocEnd':\n {\n const atEnd = command === 'moveCursorToDocEnd';\n const boundarySelection = getDocumentBoundarySelection(\n textDocument,\n atEnd,\n this.#isDiff\n );\n this.#updateSelections([boundarySelection]);\n this.#revealLineIfCollapsed(getCaretPosition(boundarySelection).line);\n this.#scrollToPrimaryCaret();\n }\n break;\n\n case 'expandSelectionDocStart':\n case 'expandSelectionDocEnd':\n {\n const atEnd = command === 'expandSelectionDocEnd';\n const selections = this.#selections;\n if (selections !== undefined) {\n const boundarySelection = getDocumentBoundarySelection(\n textDocument,\n atEnd,\n this.#isDiff\n );\n this.#updateSelections(\n extendSelections(selections, boundarySelection)\n );\n this.#revealLineIfCollapsed(\n getCaretPosition(boundarySelection).line\n );\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n\n case 'undo':\n case 'redo':\n this.#applyHistoryChange(command);\n break;\n }\n }\n\n // Replays history and remaps live selections when the entry intentionally\n // has no stored selection metadata.\n #applyHistoryChange(command: 'undo' | 'redo'): void {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n return;\n }\n if (\n (command === 'undo' && !textDocument.canUndo) ||\n (command === 'redo' && !textDocument.canRedo)\n ) {\n return;\n }\n const selections = this.#selections;\n const selectionOffsets = selections?.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as const\n );\n const result =\n command === 'undo' ? textDocument.undo() : textDocument.redo();\n if (result === undefined) {\n return;\n }\n const [change, recordedSelections, lineAnnotations, selectionEdits] =\n result;\n const nextSelections =\n recordedSelections ??\n (selections !== undefined &&\n selectionOffsets !== undefined &&\n selectionEdits !== undefined\n ? remapSelectionsAfterEdits(\n textDocument,\n selections,\n selectionOffsets,\n selectionEdits\n )\n : undefined);\n this.#applyChange(change, nextSelections, lineAnnotations);\n }\n\n /** Applies one undoable command batch and records its resulting selections. */\n #applyCommandEdits(\n edits: TextEdit[],\n resolveNextSelections?: (\n textDocument: TextDocument<LAnnotation>\n ) => EditorSelection[]\n ): void {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n const remapSelections = resolveNextSelections === undefined;\n const selectionOffsets = remapSelections\n ? selections.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as const\n )\n : undefined;\n const resolvedEdits = remapSelections\n ? edits\n .map((edit) => {\n const start = textDocument.offsetAt(edit.range.start);\n const end = textDocument.offsetAt(edit.range.end);\n return {\n start: Math.min(start, end),\n end: Math.max(start, end),\n text: edit.newText,\n };\n })\n .sort((a, b) => {\n const startOrder = a.start - b.start;\n return startOrder !== 0 ? startOrder : a.end - b.end;\n })\n : undefined;\n const change = textDocument.applyEdits(\n edits,\n true,\n selections,\n undefined,\n true\n );\n if (change === undefined) {\n return;\n }\n const nextSelections = remapSelections\n ? remapSelectionsAfterEdits(\n textDocument,\n selections,\n selectionOffsets!,\n resolvedEdits!\n )\n : resolveNextSelections(textDocument);\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n\n /** Copies selected line blocks and keeps the selection in the requested copy. */\n #copySelectedLines(direction: -1 | 1): void {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n\n const blocks = getSelectedLineBlocks(selections);\n if (blocks.length === 0) {\n return;\n }\n const copiedLinesBefore: number[] = [];\n let copiedLineCount = 0;\n const edits: TextEdit[] = [];\n for (const block of blocks) {\n copiedLinesBefore.push(copiedLineCount);\n const blockLineCount = block.endLine - block.startLine + 1;\n copiedLineCount += blockLineCount;\n const text = textDocument.getText({\n start: { line: block.startLine, character: 0 },\n end: {\n line: block.endLine,\n character: textDocument.getLineLength(block.endLine),\n },\n });\n\n if (direction > 0) {\n const position = { line: block.startLine, character: 0 };\n edits.push({\n range: { start: position, end: position },\n newText: text + textDocument.eol,\n });\n } else if (block.endLine < textDocument.lineCount - 1) {\n const position = { line: block.endLine + 1, character: 0 };\n edits.push({\n range: { start: position, end: position },\n newText: text + textDocument.eol,\n });\n } else {\n const position = {\n line: block.endLine,\n character: textDocument.getLineLength(block.endLine),\n };\n edits.push({\n range: { start: position, end: position },\n newText: textDocument.eol + text,\n });\n }\n }\n\n const nextSelections = selections.map((selection) => {\n const line = selection.start.line;\n let low = 0;\n let high = blocks.length - 1;\n while (low <= high) {\n const middle = (low + high) >>> 1;\n const block = blocks[middle];\n if (line < block.startLine) {\n high = middle - 1;\n } else if (line > block.endLine) {\n low = middle + 1;\n } else {\n low = middle;\n break;\n }\n }\n const blockIndex = Math.max(0, low <= high ? low : high);\n const block = blocks[blockIndex];\n const shift =\n copiedLinesBefore[blockIndex] +\n (direction > 0 ? block.endLine - block.startLine + 1 : 0);\n return {\n start: { ...selection.start, line: selection.start.line + shift },\n end: { ...selection.end, line: selection.end.line + shift },\n direction: selection.direction,\n };\n });\n this.#applyCommandEdits(edits, () => nextSelections);\n }\n\n /** Inserts an indented blank line after each selection's final line. */\n #insertBlankLine(): void {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n\n const selectionLines = selections.map(\n (selection) => getCaretPosition(selection).line\n );\n const targetLines = Array.from(new Set(selectionLines)).sort(\n (a, b) => a - b\n );\n const targetIndex = new Map<number, number>();\n const indents = new Map<number, string>();\n const edits: TextEdit[] = [];\n for (let index = 0; index < targetLines.length; index++) {\n const line = targetLines[index];\n const lineText = textDocument.getLineText(line);\n const indent = /^\\s*/.exec(lineText)?.[0] ?? '';\n targetIndex.set(line, index);\n indents.set(line, indent);\n const position = {\n line,\n character: textDocument.getLineLength(line),\n };\n edits.push({\n range: { start: position, end: position },\n newText: textDocument.eol + indent,\n });\n }\n\n const nextSelections = selections.map<EditorSelection>((_, index) => {\n const line = selectionLines[index];\n const position = {\n line: line + 1 + targetIndex.get(line)!,\n character: indents.get(line)!.length,\n };\n return { start: position, end: position, direction: DirectionNone };\n });\n this.#applyCommandEdits(edits, () => nextSelections);\n }\n\n #moveSelectedLines(direction: -1 | 1): void {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n\n const blocks = getSelectedLineBlocks(selections);\n if (\n blocks.length === 0 ||\n (direction < 0 && blocks[0].startLine === 0) ||\n (direction > 0 && blocks.at(-1)!.endLine >= textDocument.lineCount - 1)\n ) {\n return;\n }\n\n const lineCount = textDocument.lineCount;\n const lineRangeEnd = (line: number): Position =>\n line < lineCount - 1\n ? { line: line + 1, character: 0 }\n : { line, character: textDocument.getLineLength(line) };\n const getLinesText = (\n lines: number[],\n appendFinalLineBreak: boolean\n ): string => {\n const text = lines\n .map((line) => textDocument.getLineText(line))\n .join(textDocument.eol);\n return appendFinalLineBreak ? text + textDocument.eol : text;\n };\n\n const edits: TextEdit[] = [];\n if (direction < 0) {\n for (const block of blocks) {\n const previousLine = block.startLine - 1;\n const blockLines: number[] = [];\n for (let line = block.startLine; line <= block.endLine; line++) {\n blockLines.push(line);\n }\n edits.push({\n range: {\n start: { line: previousLine, character: 0 },\n end: lineRangeEnd(block.endLine),\n },\n newText: getLinesText(\n [...blockLines, previousLine],\n block.endLine < lineCount - 1\n ),\n });\n }\n } else {\n for (let index = blocks.length - 1; index >= 0; index--) {\n const block = blocks[index];\n const nextLine = block.endLine + 1;\n const blockLines: number[] = [];\n for (let line = block.startLine; line <= block.endLine; line++) {\n blockLines.push(line);\n }\n edits.push({\n range: {\n start: { line: block.startLine, character: 0 },\n end: lineRangeEnd(nextLine),\n },\n newText: getLinesText(\n [nextLine, ...blockLines],\n nextLine < lineCount - 1\n ),\n });\n }\n }\n\n const lastBlock = blocks.at(-1)!;\n const lastLineLengthAfterMove =\n direction > 0 && lastBlock.endLine === lineCount - 2\n ? textDocument.getLineLength(lastBlock.endLine)\n : textDocument.getLineLength(lineCount - 1);\n const nextSelections = selections.map((selection) =>\n shiftSelectionLines(selection, direction, lineCount, (line) =>\n line === lineCount - 1\n ? lastLineLengthAfterMove\n : textDocument.getLineLength(line)\n )\n );\n const change = textDocument.applyEdits(\n edits,\n true,\n selections,\n nextSelections,\n true\n );\n if (change !== undefined) {\n this.#applyChange(change, nextSelections);\n }\n }\n\n #handleLayoutResize = () => {\n const lineAnnotations = this.#lineAnnotations?.length ?? 0;\n const prevGutterWidth = this.#gutterWidthCache;\n const prevContentWidth = this.#contentWidthCache;\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n const gutterWidthChanged = this.#getGutterWidth() !== prevGutterWidth;\n const contentWidthChanged = this.#getContentWidth() !== prevContentWidth;\n if (!gutterWidthChanged && !contentWidthChanged) {\n return;\n }\n\n this.#lineElementsCache.clear();\n this.#lastAccessedCharX = undefined;\n // A width change means the inherited font/metrics may have changed (e.g. a\n // web font finished loading) while this same content element survived, so\n // discard memoized non-ASCII text widths and let them re-measure.\n this.#metrics.clearTextWidthCache();\n if (contentWidthChanged) {\n // Wrap points depend on the content width, so cached offsets go stale\n // even while wrap is off — the mode can be toggled back on before the\n // next width change.\n this.#wrapLineOffsetsCache.clear();\n if (this.#isWrap || lineAnnotations > 0) {\n this.#lineYCache.clear();\n }\n }\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n // Virtualized row swaps can resize a blurred editor. Repaint its overlays\n // without letting that layout work reclaim DOM focus.\n if (this.#selections !== undefined && this.#contentHasFocus) {\n this.focus();\n }\n }\n this.#markerRenderer?.removePopover();\n this.#computeContentOffset(this.#contentElement!);\n };\n\n // A custom monospace web font can finish loading after the editor first\n // renders. Until then Metrics measured the '0' width against the fallback\n // font, so the gutter width and every caret/selection x-position (each\n // offset by a whole number of `ch` units) are wrong. Re-measure once fonts\n // settle and, when the width actually changed, drop the cached widths and\n // offsets and repaint the overlays so they line up with the loaded glyphs.\n // FontFaceSet is unavailable in non-browser hosts (e.g. jsdom in tests).\n #remeasureMetricsOnFontLoad(): void {\n if (this.#fontRemeasureScheduled) {\n return;\n }\n const fonts = document.fonts as FontFaceSet | undefined;\n if (fonts === undefined) {\n return;\n }\n this.#fontRemeasureScheduled = true;\n void fonts.ready.then(() => {\n if (\n this.#contentElement === undefined ||\n !this.#metrics.remeasureCharacterWidth()\n ) {\n return;\n }\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#resetCache();\n // The loaded font changes glyph widths, which moves every wrap point.\n this.#wrapLineOffsetsCache.clear();\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n this.#markerRenderer?.removePopover();\n });\n }\n\n #rerender(\n change: TextDocumentChange,\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n renderRange = this.#renderRange,\n shouldUpdateBuffer?: boolean\n ) {\n const tokenizer = this.#tokenizer;\n const fileInstance = this.#fileInstance;\n const textDocument = this.#textDocument;\n const gutterEl = this.#gutterElement;\n const contentEl = this.#contentElement;\n if (\n tokenizer === undefined ||\n fileInstance === undefined ||\n textDocument === undefined ||\n contentEl === undefined\n ) {\n return;\n }\n\n // cancel existing background tokenizing task\n tokenizer.stopBackgroundTokenize();\n\n const t = performance.now();\n const dirtyLines = tokenizer.tokenize(\n change,\n renderRange,\n !this.#isDiff && fileInstance.getLinePosition !== undefined\n );\n const t2 = performance.now();\n\n if (dirtyLines.size > 0) {\n const children = contentEl.children;\n // Lines hidden inside a collapsed region have no row to patch, and\n // letting them reach the create branch below would append rows for\n // them; the tokenizer still received them (dirtyLines is forwarded to\n // the host untouched).\n const dirtyLineIndexes = new Set<number>();\n for (const lineIndex of dirtyLines.keys()) {\n if (this.#isLineRenderable(lineIndex)) {\n dirtyLineIndexes.add(lineIndex);\n }\n }\n\n // Update line elements that have been changed in the document. The\n // scan starts at 0 because rendered rows can be sparse (collapsed\n // regions): a dirty line's row may sit at a smaller child index than\n // its dense line-arithmetic position, and overshooting it would fall\n // through to the create branch below as a duplicate row.\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child !== undefined) {\n const lineNumber = getLineNumberAttr(child);\n const lineType = child.dataset.lineType;\n if (lineNumber === undefined || lineType === 'change-deletion') {\n continue;\n }\n const lineIndex = lineNumber - 1;\n if (dirtyLineIndexes.has(lineIndex)) {\n const tokens = dirtyLines.get(lineIndex)!;\n child.replaceChildren(...renderLineTokens(tokens));\n dirtyLineIndexes.delete(lineIndex);\n if (dirtyLineIndexes.size === 0) {\n break;\n }\n }\n }\n }\n\n // Create new line elements for the new lines — only beyond the last\n // existing rendered row: rows are appended to the column end, so any\n // earlier missing row belongs at a collapsed-region boundary and is\n // owned by the full re-render that follows a hunk-structure change.\n if (dirtyLineIndexes.size > 0) {\n let lastRenderedLineNumber = 0;\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i] as HTMLElement;\n const lineNumber = getLineNumberAttr(child);\n if (\n lineNumber !== undefined &&\n child.dataset.lineType !== 'change-deletion'\n ) {\n lastRenderedLineNumber = lineNumber;\n break;\n }\n }\n for (const lineIndex of dirtyLineIndexes) {\n if (lineIndex < lastRenderedLineNumber) {\n continue;\n }\n const tokens = dirtyLines.get(lineIndex)!;\n const lineNumber = String(lineIndex + 1);\n h(\n 'div',\n {\n dataset: {\n line: lineNumber,\n lineType: 'context',\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: renderLineTokens(tokens),\n },\n contentEl\n );\n if (gutterEl !== undefined) {\n h(\n 'div',\n {\n dataset: {\n lineType: 'context',\n columnNumber: lineNumber,\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: [\n h('span', {\n dataset: {\n lineNumberContent: '',\n },\n textContent: lineNumber,\n }),\n ],\n },\n gutterEl\n );\n }\n }\n }\n }\n\n // remove line elements that have been deleted in the document\n if (change.lineDelta < 0) {\n for (const children of [contentEl.children, gutterEl?.children ?? []]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i] as HTMLElement;\n const lineNumber =\n getLineNumberAttr(child) ??\n getLineNumberAttr(child, 'columnNumber');\n const lineType = child.dataset.lineType;\n if (lineNumber === undefined || lineType === 'change-deletion') {\n continue;\n }\n if (lineNumber - 1 < change.lineCount) {\n break;\n }\n child.remove();\n }\n }\n }\n\n const didLineCountChange = change.lineDelta !== 0;\n\n // fix grid layout\n if (didLineCountChange) {\n let gridRow = contentEl.children.length;\n for (const child of contentEl.children) {\n const { bufferSize } = (child as HTMLElement).dataset;\n if (bufferSize !== undefined) {\n gridRow += parseInt(bufferSize) - 1;\n }\n }\n contentEl.style.gridRow = 'span ' + gridRow;\n if (gutterEl !== undefined) {\n gutterEl.style.gridRow = 'span ' + gridRow;\n }\n }\n\n fileInstance.updateRenderCache(dirtyLines, tokenizer.themeType, {\n shouldRefreshDiffsView: this.#isDiff && !didLineCountChange,\n lineCountChangeInFlight: didLineCountChange,\n });\n if (didLineCountChange) {\n // Line-count change: recompute hunks from the full document and re-render.\n fileInstance.applyDocumentChange(\n textDocument,\n newLineAnnotations,\n shouldUpdateBuffer\n );\n }\n\n // A line-count change can remove cached rows, while a unified diff rebuilds\n // its content column on every edit. Either can detach the line elements\n // memoized for caret/selection geometry, making offsetTop read as 0 and\n // scrolling the caret to the top. Re-measure against the current rows.\n if (didLineCountChange || (this.#isDiff && this.#diffSyle === 'unified')) {\n this.#resetCache();\n }\n\n if (newLineAnnotations !== undefined) {\n this.#lineAnnotations = newLineAnnotations;\n renderLineAnnotations(newLineAnnotations, contentEl, gutterEl);\n }\n\n if (this.#options.__debug === true) {\n console.log(\n `[diffs/editor] re-render in: ${round(performance.now() - t2)}ms,`,\n `tokenize in: ${round(t2 - t)}ms (${dirtyLines.size} dirty lines)`\n );\n }\n }\n\n // input type doc: https://developer.mozilla.org/en-US/docs/Web/API/InputEvent/inputType\n #handleInput(inputType: string, data: string | null) {\n switch (inputType) {\n case 'insertText': {\n const text = data ?? '';\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n const autoSurroundTexts =\n textDocument !== undefined && selections !== undefined\n ? getAutoSurroundReplacementTexts(\n textDocument,\n selections,\n text,\n this.#options.autoSurround\n )\n : undefined;\n this.#replaceSelectionText(autoSurroundTexts ?? text);\n break;\n }\n case 'insertCompositionText':\n break;\n case 'insertLineBreak':\n case 'insertParagraph': {\n this.#replaceSelectionText(this.#textDocument?.eol ?? '\\n');\n break;\n }\n case 'deleteContentBackward':\n this.#deleteSelectionText();\n break;\n case 'deleteContentForward':\n this.#deleteSelectionText(true);\n break;\n case 'deleteSoftLineBackward':\n // Safari emits deleteHardLineBackward for cmd+backspace where Chrome emits\n // deleteSoftLineBackward; treat them the same so cmd+backspace deletes to\n // the line start in both. They differ only on a wrapped line (hard goes to\n // the logical line start, soft to the visual one), and Chrome's soft\n // behavior is what we match.\n case 'deleteHardLineBackward':\n this.#deleteSoftLineBackward();\n break;\n case 'deleteWordBackward':\n this.#deleteWordBackward();\n break;\n case 'insertTranspose':\n this.#insertTranspose();\n break;\n default:\n console.warn(`[diffs] Unknown input type: ${inputType}`, data);\n break;\n }\n }\n\n #focus(\n position?: Position,\n preventScroll = true,\n shouldFocus?: () => boolean\n ) {\n // Mark focus eagerly: the positional branch defers the real focus() to a\n // rAF, so a same-tick applyEdits would otherwise see the editor as\n // unfocused and skip repositioning while this focus still lands afterward.\n this.#contentHasFocus = true;\n if (position !== undefined) {\n this.#shouldIgnoreSelectionChange = true;\n this.#setWindowSelection({\n start: position,\n end: position,\n direction: DirectionNone,\n });\n // call focus in a request animation frame to prevent conflict with\n // the `setBaseAndExtent` method\n queueRender(() => {\n // #contentHasFocus was marked eagerly above; a blur (or cleanup) in\n // the deferred gap cedes focus, and this stale frame must not pull\n // it back into the current — possibly replaced — content.\n if (shouldFocus?.() === false || !this.#contentHasFocus) {\n this.#shouldIgnoreSelectionChange = false;\n return;\n }\n this.#contentElement?.focus({ preventScroll });\n // another request animation frame since the `focus` call\n // may trigger a selectionchange event, which should be ignored\n queueRender(() => {\n this.#shouldIgnoreSelectionChange = false;\n });\n });\n } else if (shouldFocus?.() !== false) {\n this.#contentElement?.focus({ preventScroll });\n } else {\n this.#contentHasFocus = false;\n }\n }\n\n // A full host render can remove the focused contenteditable before the\n // replacement view synchronizes. Restore only after the new content is live\n // and only while focus has not moved to another real control in the gap.\n #restoreReplacementFocus(position?: Position): void {\n const request = this.#replacementFocusRequest;\n if (request == null) {\n return;\n }\n if (this.#retainSearchPanelFocus) {\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#shouldIgnoreSelectionChange = false;\n return;\n }\n const contentElement = this.#contentElement;\n if (\n contentElement == null ||\n !this.#replacementFocusIsAvailable(contentElement)\n ) {\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n return;\n }\n\n const shouldFocus = () => {\n if (this.#replacementFocusRequest !== request) {\n return false;\n }\n const shouldRestore = this.#replacementFocusIsAvailable(contentElement);\n this.#replacementFocusRequest = undefined;\n return shouldRestore;\n };\n if (position != null) {\n this.#focus(position, true, shouldFocus);\n return;\n }\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection == null) {\n this.#focus(undefined, true, shouldFocus);\n return;\n }\n const primaryPosition =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n this.#focus(primaryPosition, true, shouldFocus);\n }\n\n #replacementFocusIsAvailable(contentElement: HTMLElement): boolean {\n const fileContainer = this.#fileContainer;\n const shadowRoot = fileContainer?.shadowRoot;\n if (\n fileContainer == null ||\n shadowRoot == null ||\n this.#contentElement !== contentElement ||\n !shadowRoot.contains(contentElement)\n ) {\n return false;\n }\n const { activeElement: shadowActiveElement } = shadowRoot;\n if (\n shadowActiveElement === contentElement ||\n (shadowActiveElement != null &&\n contentElement.contains(shadowActiveElement))\n ) {\n return true;\n }\n if (shadowActiveElement != null) {\n return false;\n }\n const { ownerDocument } = fileContainer;\n const { activeElement } = ownerDocument;\n return (\n activeElement == null ||\n activeElement === ownerDocument.body ||\n activeElement === ownerDocument.documentElement ||\n activeElement === fileContainer\n );\n }\n\n #getFirstVisibleLineNumber(offset = 0): number | undefined {\n const contentElement = this.#contentElement;\n const fileContainer = this.#fileContainer;\n if (\n this.#textDocument == null ||\n contentElement == null ||\n fileContainer == null\n ) {\n return undefined;\n }\n\n const viewport = this.#getScrollViewport();\n if (viewport === undefined) {\n return undefined;\n }\n\n let viewportTop: number;\n let viewportBottom: number;\n if (viewport instanceof HTMLElement) {\n const viewportRect = viewport.getBoundingClientRect();\n viewportTop = viewportRect.top;\n viewportBottom = viewportRect.bottom;\n } else {\n viewportTop = 0;\n viewportBottom = viewport.defaultView?.innerHeight ?? 0;\n }\n\n const stickyHeader = fileContainer.shadowRoot?.querySelector<HTMLElement>(\n '[data-diffs-header][data-sticky]'\n );\n if (stickyHeader != null) {\n viewportTop = Math.max(\n viewportTop,\n stickyHeader.getBoundingClientRect().bottom\n );\n }\n if (Number.isFinite(offset)) {\n viewportTop += Math.max(0, offset);\n }\n if (viewportBottom <= viewportTop) {\n return undefined;\n }\n\n for (const child of contentElement.children) {\n const row = child as HTMLElement;\n const lineNumber = getLineNumberAttr(row);\n const lineType = row.dataset.lineType;\n if (lineNumber == null || lineType == null || !isLineEditable(lineType)) {\n continue;\n }\n const rowRect = row.getBoundingClientRect();\n if (rowRect.bottom <= rowRect.top) {\n continue;\n }\n if (rowRect.top >= viewportTop && rowRect.top < viewportBottom) {\n return lineNumber;\n }\n }\n return undefined;\n }\n\n #focusAtPosition(position: Position, preventScroll: boolean): void {\n const selection: EditorSelection = {\n start: position,\n end: position,\n direction: DirectionNone,\n };\n this.#canMountSelectionAction = false;\n this.#updateSelections([selection]);\n this.#revealLineIfCollapsed(position.line);\n if (preventScroll) {\n this.#focus(position, true);\n } else {\n this.#scrollToPrimaryCaret();\n }\n }\n\n // set window native selection to match the selection\n #setWindowSelection(selection: EditorSelection) {\n const winSelection = window.getSelection();\n if (winSelection === null) {\n return;\n }\n let { start, end, direction } = selection;\n if (comparePosition(start, end) > 0) {\n [start, end] = [end, start];\n }\n const startLineElement = this.#getLineElement(start.line);\n const endLineElement = this.#getLineElement(end.line);\n if (startLineElement === undefined || endLineElement === undefined) {\n return;\n }\n let [anchorNode, anchorOffset] = getSelectionAnchor(\n startLineElement,\n start.character\n );\n let [focusNode, focusOffset] = getSelectionAnchor(\n endLineElement,\n end.character\n );\n if (direction === DirectionBackward) {\n [anchorNode, anchorOffset, focusNode, focusOffset] = [\n focusNode,\n focusOffset,\n anchorNode,\n anchorOffset,\n ];\n }\n try {\n winSelection.setBaseAndExtent(\n anchorNode,\n clampDomOffset(anchorNode, anchorOffset),\n focusNode,\n clampDomOffset(focusNode, focusOffset)\n );\n } catch (err) {\n console.error('[diffs/editor] failed to update window selection:', err);\n }\n }\n\n #scrollToPrimaryCaret(\n noFocus = false,\n scrollPosition: ScrollLogicalPosition = 'nearest'\n ) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection === undefined) {\n return;\n }\n const primaryCaretElement = this.#primaryCaretElement;\n if (primaryCaretElement !== undefined) {\n primaryCaretElement.scrollIntoView({\n block: scrollPosition,\n inline: 'nearest',\n });\n if (!noFocus) {\n const position =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n if (this.#replacementFocusRequest !== undefined) {\n this.#restoreReplacementFocus(position);\n } else {\n this.#focus(position);\n }\n }\n } else {\n const pos = getCaretPosition(primarySelection);\n this.#scrollToLine(pos.line, pos.character, noFocus);\n }\n }\n\n // add scroll margin to the primary caret element to prevent\n // the caret from being hidden by the gutter (and the search panel when\n // open). The margin must only reserve viewport space above the caret —\n // never include the host's virtualized `top` offset: that is a scroll-space\n // coordinate, and folding it in makes every caret scrollIntoView treat the\n // caret as thousands of pixels tall once the host is scrolled down, which\n // mis-scrolls the caret line (e.g. pinning it to the viewport bottom).\n #getScrollMargin() {\n const top = this.#searchPanel !== undefined ? 48 : 0;\n const start = this.#getGutterWidth() + this.#metrics.ch;\n const end = this.#metrics.ch;\n return `${top}px ${end}px 0 ${start}px`;\n }\n\n #scrollToLine(line: number, char = 0, noFocus = false) {\n this.__postponeBgTokenizeToNextFrame();\n\n const virtualCaret = h('div', {\n style: {\n position: 'absolute',\n left: '0',\n width: '2px',\n height: this.#metrics.lineHeight + 'px',\n scrollMargin: this.#getScrollMargin(),\n },\n });\n if (this.#getLineElement(line) !== undefined) {\n const [left, wrapLine] = this.#getCharX(line, char);\n const lineY = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n virtualCaret.style.top = lineY + 'px';\n virtualCaret.style.left = left + 'px';\n this.#overlayElement?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n if (!noFocus) {\n const position = { line, character: char };\n if (this.#replacementFocusRequest !== undefined) {\n this.#restoreReplacementFocus(position);\n } else {\n this.#focus(position);\n }\n }\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineFixed = false;\n this.#scrollingToLineNoFocus = false;\n }\n // if the line is not rendered yet(virtualized), scroll to the modeled or approximate\n // line position to trigger the line to be rendered, then recall this function\n // to ensure the line is scrolled into view\n else {\n const modelLinePosition = this.#fileInstance?.getLinePosition?.(line + 1);\n if (modelLinePosition !== undefined) {\n virtualCaret.style.top = modelLinePosition.top + 'px';\n this.#fileContainer?.shadowRoot?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n // A collapsed line reports its separator's (nonzero) geometry, so\n // parking the retry for it would re-scroll on every sync forever;\n // only renderable lines may keep the retry alive.\n if (modelLinePosition.height > 0 && this.#isLineRenderable(line)) {\n this.#scrollingToLine = line;\n this.#scrollingToLineChar = char;\n this.#scrollingToLineNoFocus = noFocus;\n } else {\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineNoFocus = false;\n }\n } else {\n let yFix = 0;\n if (\n this.#scrollingToLine === line &&\n this.#contentElement !== undefined\n ) {\n for (\n let i = this.#contentElement.childElementCount - 1;\n i >= 0;\n i--\n ) {\n const child = this.#contentElement.children[i] as HTMLElement;\n const lineType = child.dataset.lineType;\n const lineNumber = getLineNumberAttr(child);\n if (\n lineType !== undefined &&\n isLineEditable(lineType) &&\n lineNumber !== undefined\n ) {\n yFix = (line - (lineNumber - 1)) * this.#metrics.lineHeight;\n break;\n }\n }\n }\n const lineAnnotations = (this.#lineAnnotations ?? []).filter(\n (annotation) => annotation.lineNumber < line\n ).length;\n const approximateLineY =\n (lineAnnotations + line) * this.#metrics.lineHeight + yFix;\n virtualCaret.style.top = approximateLineY + 'px';\n this.#fileContainer?.shadowRoot?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n\n if (\n (this.#scrollingToLine === line &&\n (yFix === 0 || this.#scrollingToLineFixed)) ||\n !this.#isLineRenderable(line)\n ) {\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineFixed = false;\n this.#scrollingToLineNoFocus = false;\n } else {\n this.#scrollingToLine = line;\n this.#scrollingToLineChar = char;\n this.#scrollingToLineFixed = yFix !== 0;\n this.#scrollingToLineNoFocus = noFocus;\n }\n }\n }\n virtualCaret.remove();\n }\n\n // Build a selection that fully covers every line from the anchor line to the\n // focus line — from the topmost line's start to the bottommost line's end.\n // Dragging above the anchor yields a backward selection so the anchor line\n // stays selected and #focus lands on the line the gesture ended on. A single\n // line (anchor === focus) is a forward whole-line selection.\n #spanLineSelection(\n anchorLine: number,\n focusLine: number,\n textDocument: TextDocument<LAnnotation>\n ): EditorSelection {\n const lineStart = (line: number): Position => ({ line, character: 0 });\n const lineEnd = (line: number): Position => ({\n line,\n character: textDocument.getLineText(line).length,\n });\n if (focusLine < anchorLine) {\n return {\n start: lineStart(focusLine),\n end: lineEnd(anchorLine),\n direction: DirectionBackward,\n };\n }\n return {\n start: lineStart(anchorLine),\n end: lineEnd(focusLine),\n direction: DirectionForward,\n };\n }\n\n // A pointer gesture targets read-only deleted text when its closest row is a\n // change-deletion. Used to route a click in unified view's deleted text to a\n // native selection instead of the editor's own.\n #isDeletedLineTarget(event: Event): boolean {\n const target = event.composedPath()[0];\n return (\n target instanceof HTMLElement &&\n target.closest('[data-line]')?.getAttribute('data-line-type') ===\n 'change-deletion'\n );\n }\n\n // Select read-only deleted text with the native selection, spanning from the\n // anchor row to the focus row (the same row for a click). Deleted lines are\n // not part of the editor's document, so they cannot be selected as editor\n // text; instead select their DOM text, reveal it via the deleted-text marker,\n // drop the editor's own selection, and highlight the deleted gutter numbers so\n // the result matches a click/drag on an addition line.\n #selectDeletedLines(\n anchorContent: HTMLElement,\n focusContent: HTMLElement,\n deletionsCode: Element\n ): void {\n const rows = [\n ...deletionsCode.querySelectorAll('[data-content] > [data-line]'),\n ];\n const anchorIndex = rows.indexOf(anchorContent);\n const focusIndex = rows.indexOf(focusContent);\n const [topContent, bottomContent] =\n focusIndex < anchorIndex\n ? [focusContent, anchorContent]\n : [anchorContent, focusContent];\n\n const winSelection = window.getSelection();\n if (winSelection !== null) {\n const range = document.createRange();\n range.setStart(topContent, 0);\n range.setEnd(bottomContent, bottomContent.childNodes.length);\n winSelection.removeAllRanges();\n winSelection.addRange(range);\n }\n\n this.#setDeletedTextSelectionActive(true);\n this.#updateSelections([]);\n\n // Highlight only the focus line's gutter number — the line where the click\n // landed or the drag ended. Route it through the editor active-line state\n // so selected lines and deleted-line focus remain independent.\n this.#setEditorActiveLineSafe(\n getLineNumberAttr(focusContent) ?? null,\n true,\n 'deletions'\n );\n\n // Record the selected deleted lines' text for the clipboard. Each deleted\n // line is its own read-only host, so window.getSelection().toString() only\n // captures the first line; the copy/cut handlers prefer this value.\n const lo = Math.min(anchorIndex, focusIndex);\n const hi = Math.max(anchorIndex, focusIndex);\n this.#deletedSelectionText =\n lo < 0\n ? ''\n : rows\n .slice(lo, hi + 1)\n .filter(\n (row) => row.getAttribute('data-line-type') === 'change-deletion'\n )\n .map((row) => row.textContent ?? '')\n .join('\\n');\n }\n\n // The content row that lines up with a gutter row: the two columns are\n // parallel, so the gutter row's index is the content row's index.\n #contentRowForGutterRow(\n gutterRow: HTMLElement,\n contentColumn: Element | null | undefined\n ): HTMLElement | undefined {\n const gutterColumn = gutterRow.parentElement;\n if (gutterColumn == null || contentColumn == null) {\n return undefined;\n }\n const index = [...gutterColumn.children].indexOf(gutterRow);\n const row = contentColumn.children[index];\n return row instanceof HTMLElement ? row : undefined;\n }\n\n // Begin a native selection of read-only deleted lines from a pointerdown on a\n // deletion line number. Selects the clicked line and, for a mouse pointer,\n // tracks a drag across the deletion gutter that extends the selection — the\n // same gesture as a click/drag on an addition line number. `code` is the\n // [data-code] holding the deletion column: the separate deletions column in\n // split view, or the shared column in unified view. Returns false when the\n // gutter row has no matching content row, letting the caller fall back to a\n // plain deleted-text selection.\n #beginDeletionGutterSelection(\n gutterRow: HTMLElement,\n code: Element,\n isMouse: boolean\n ): boolean {\n const contentColumn = code.querySelector('[data-content]');\n const anchorContent = this.#contentRowForGutterRow(\n gutterRow,\n contentColumn\n );\n if (anchorContent === undefined) {\n return false;\n }\n this.#selectDeletedLines(anchorContent, anchorContent, code);\n // The document pointerup disposes this listener; it must not set\n // #isGutterMouseDown, whose pointerup focuses the editor and would collapse\n // the native deletion selection.\n if (isMouse) {\n this.#replaceSelectEventListeners([\n addEventListener(\n document,\n 'mousemove',\n (moveEvent) => {\n const moveTarget = moveEvent.composedPath()[0];\n const moveGutter =\n moveTarget instanceof HTMLElement\n ? moveTarget.closest('[data-column-number]')\n : null;\n if (\n moveGutter instanceof HTMLElement &&\n code.contains(moveGutter)\n ) {\n const focusContent = this.#contentRowForGutterRow(\n moveGutter,\n contentColumn\n );\n if (focusContent !== undefined) {\n this.#selectDeletedLines(anchorContent, focusContent, code);\n }\n }\n },\n { passive: true }\n ),\n ]);\n }\n return true;\n }\n\n // Whether a read-only deleted-text selection is currently active (the marker\n // #setDeletedTextSelectionActive sets). The copy/cut handlers read this to\n // copy the native selection instead of the editor's empty document selection.\n #isDeletedTextSelectionActive(): boolean {\n return (\n this.#fileContainer?.shadowRoot\n ?.querySelector('pre')\n ?.hasAttribute('data-deleted-text-selection') ?? false\n );\n }\n\n // The clipboard text for a read-only deleted-text selection. A gutter\n // selection records the full multi-line text in #deletedSelectionText; a\n // direct content drag leaves it empty, so fall back to the browser's native\n // selection (which spans only the first deleted line — its separate host).\n #deletedTextForClipboard(): string {\n return this.#deletedSelectionText !== ''\n ? this.#deletedSelectionText\n : (window.getSelection()?.toString() ?? '');\n }\n\n // Toggle the marker that reveals the native selection inside read-only\n // deleted text (see the gated ::selection rule). It stays on only while the\n // user is actively selecting within deleted lines, so a normal selection of\n // editable code that sweeps across an interleaved deleted line does not\n // highlight it.\n #setDeletedTextSelectionActive(active: boolean): void {\n const pre = this.#fileContainer?.shadowRoot?.querySelector('pre');\n if (pre == null) {\n return;\n }\n if (active) {\n pre.setAttribute('data-deleted-text-selection', '');\n this.#setEditorActiveLineSafe(null);\n // Reset the captured selection text. #selectDeletedLines refills it for a\n // gutter selection; a content drag leaves it empty so the copy/cut\n // handlers fall back to the native selection.\n this.#deletedSelectionText = '';\n } else {\n pre.removeAttribute('data-deleted-text-selection');\n this.#deletedSelectionText = '';\n }\n }\n\n #setEditorActiveLineSafe(\n lineNumber: number | null,\n lineNumberOnly = false,\n side: SelectionSide = 'additions'\n ): void {\n try {\n // Keep the caret decoration separate from selected lines. The component\n // confines it to the relevant diff pane, and a text selection keeps only\n // the focus line's gutter number highlighted.\n this.#fileInstance?.setEditorActiveLine(lineNumber, {\n lineNumberOnly,\n side,\n });\n } catch {\n // InteractionManager.renderSelection can throw while editor DOM is updating.\n }\n }\n\n // Re-render the selection overlay after a theme swap so rounded corner masks\n // recompute their `--diffs-selection-corner-bg`. Those masks capture the\n // resolved line-background color when the selection is drawn; a light/dark or\n // theme-name change updates the line CSS but leaves the captured color stale,\n // showing wrong-colored corners on diff-colored lines until the selection\n // moves. Deferred to the next frame because a host-driven theme change fires\n // this mid-`#sync` (before the render range is refreshed), and `#sync`\n // re-renders the overlay itself; the frame delay avoids re-entrancy and is\n // imperceptible.\n #scheduleThemeSelectionRefresh(): void {\n if (this.#themeSelectionRefreshFrame !== undefined) {\n return;\n }\n this.#themeSelectionRefreshFrame = requestAnimationFrame(() => {\n this.#themeSelectionRefreshFrame = undefined;\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n });\n }\n\n // Keep the drag's horizontal goal in pointer space so a native caret that\n // briefly clamps to a short line cannot move every generated selection.\n #updateAltColumnSelections(): boolean {\n const drag = this.#altColumnDrag;\n const selectionStart = this.#selectionStart;\n const textDocument = this.#textDocument;\n if (\n drag === undefined ||\n drag.focusLine === undefined ||\n selectionStart === undefined ||\n textDocument === undefined\n ) {\n return false;\n }\n\n const anchor =\n selectionStart.direction === DirectionBackward\n ? selectionStart.end\n : selectionStart.start;\n const scrollLeft = this.#contentElement?.parentElement?.scrollLeft ?? 0;\n const characterDeltaRaw =\n (drag.clientX - drag.startClientX + scrollLeft - drag.startScrollLeft) /\n this.#metrics.ch;\n const characterDelta =\n characterDeltaRaw < 0\n ? -Math.round(-characterDeltaRaw)\n : Math.round(characterDeltaRaw);\n const focusCharacter = Math.max(0, anchor.character + characterDelta);\n const goal = { line: drag.focusLine, character: focusCharacter };\n if (\n drag.renderedGoal !== undefined &&\n comparePosition(drag.renderedGoal, goal) === 0\n ) {\n return true;\n }\n drag.renderedGoal = goal;\n\n const selections: EditorSelection[] = [];\n const step = goal.line < anchor.line ? -1 : 1;\n for (let line = anchor.line; ; line += step) {\n if (this.#isLineRenderable(line)) {\n // Projected UTF-16 offsets must not split a grapheme on this line.\n const lineText = textDocument.getLineText(line);\n const anchorOffset = Math.min(anchor.character, lineText.length);\n const focusOffset = Math.min(focusCharacter, lineText.length);\n const anchorCharacter = snapCharacterToGraphemeBoundary(\n lineText,\n anchorOffset\n );\n const lineFocusCharacter =\n focusOffset === anchorOffset\n ? anchorCharacter\n : snapCharacterToGraphemeBoundary(lineText, focusOffset);\n selections.push({\n start: {\n line,\n character: Math.min(anchorCharacter, lineFocusCharacter),\n },\n end: {\n line,\n character: Math.max(anchorCharacter, lineFocusCharacter),\n },\n direction:\n anchorCharacter === lineFocusCharacter\n ? DirectionNone\n : anchorCharacter < lineFocusCharacter\n ? DirectionForward\n : DirectionBackward,\n });\n }\n if (line === goal.line) {\n break;\n }\n }\n this.#updateSelections(selections);\n return true;\n }\n\n #updateSelections(selections: EditorSelection[]) {\n this.__postponeBgTokenizeToNextFrame();\n\n this.#primaryCaretElement = undefined;\n this.#setEditorActiveLineSafe(null);\n\n if (\n selections.length === 0 &&\n this.#matches === undefined &&\n this.#markerRenderer === undefined\n ) {\n this.#selections = undefined;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n return;\n }\n\n const fragment = document.createDocumentFragment();\n const renderCtx = {\n fragment,\n elements: new Map<string, HTMLElement>(),\n };\n\n if (selections.length > 0) {\n const normalizedSelections = mergeOverlappingSelections(selections);\n const primarySelection = normalizedSelections.at(-1)!;\n this.#selections = normalizedSelections;\n // The caret line always keeps its highlighted gutter number. With a bare\n // caret it also gets the full-line background; once any selection spans\n // text, the background is dropped (lineNumberOnly) so the text selection\n // is the only line-level highlight.\n const hasNonEmptySelection = normalizedSelections.some(\n (selection) => !isCollapsedSelection(selection)\n );\n const caretLine = getCaretPosition(primarySelection).line + 1;\n\n this.#setEditorActiveLineSafe(caretLine, hasNonEmptySelection);\n\n for (const selection of normalizedSelections) {\n if (!isCollapsedSelection(selection)) {\n this.#renderSelection(renderCtx, 'selection', selection);\n }\n this.#renderCaret(renderCtx, selection, selection === primarySelection);\n }\n\n const bracketMatchRanges =\n this.#options.matchBrackets !== false &&\n this.#textDocument !== undefined &&\n this.#tokenizer !== undefined &&\n isCollapsedSelection(primarySelection)\n ? findBracketMatchRanges(\n this.#textDocument,\n this.#tokenizer,\n primarySelection.start\n )\n : undefined;\n if (bracketMatchRanges !== undefined) {\n for (const range of bracketMatchRanges) {\n this.#renderSelection(renderCtx, 'bracketMatch', range);\n }\n }\n }\n\n const textDocument = this.#textDocument;\n if (this.#matches !== undefined && textDocument !== undefined) {\n const matches = this.#matches;\n const renderRange = this.#renderRange;\n const shouldCullMatches =\n (renderRange !== undefined &&\n Number.isFinite(renderRange.totalLines)) ||\n (this.#isDiff && this.#fileInstance?.options.expandUnchanged !== true);\n const renderedLineRanges = shouldCullMatches\n ? this.#getRenderedEditableLineRanges()\n : undefined;\n const primarySelection = this.#selections?.at(-1);\n const primaryStartOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.start)\n : -1;\n const primaryEndOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.end)\n : -1;\n let firstMatchIndex = 0;\n const rangeCount = renderedLineRanges?.length ?? 1;\n for (let rangeIndex = 0; rangeIndex < rangeCount; rangeIndex++) {\n let visibleEndOffset = Infinity;\n const lineRange = renderedLineRanges?.[rangeIndex];\n if (lineRange !== undefined) {\n const [firstLine, lastLine] = lineRange;\n const visibleStartOffset = textDocument.offsetAt({\n line: firstLine,\n character: 0,\n });\n const endLine = lastLine + 1;\n visibleEndOffset =\n endLine < textDocument.lineCount\n ? textDocument.offsetAt({ line: endLine, character: 0 })\n : textDocument.offsetAt({\n line: endLine - 1,\n character: textDocument.getLineLength(endLine - 1),\n });\n\n // Matches are sorted and non-overlapping, so narrow the rendered\n // offset window before resolving any match positions through the treap.\n let low = firstMatchIndex;\n let high = matches.length;\n while (low < high) {\n const middle = low + Math.floor((high - low) / 2);\n if (matches[middle][1] <= visibleStartOffset) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n firstMatchIndex = low;\n }\n for (; firstMatchIndex < matches.length; firstMatchIndex++) {\n const [startOffset, endOffset] = matches[firstMatchIndex];\n if (startOffset >= visibleEndOffset) {\n break;\n }\n const range: Range = {\n start: textDocument.positionAt(startOffset),\n end: textDocument.positionAt(endOffset),\n };\n const isFocused =\n primaryStartOffset === startOffset &&\n primaryEndOffset === endOffset;\n this.#renderSelection(\n renderCtx,\n 'match',\n range,\n isFocused ? 'focus' : undefined\n );\n }\n }\n }\n\n if (this.#markerRenderer !== undefined && textDocument !== undefined) {\n for (const marker of this.#markerRenderer.markers) {\n this.#renderSelection(\n renderCtx,\n 'marker',\n marker,\n markerSeverityDatasetKey(marker.severity)\n );\n }\n }\n\n this.#overlayElement?.appendChild(fragment);\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n this.#overlayElements = renderCtx.elements;\n\n this.#updateSelectionActionPopover();\n }\n\n #renderSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n type: 'selection' | 'match' | 'marker' | 'bracketMatch',\n range: Range,\n extraDataset?: string\n ) {\n if (this.#textDocument === undefined) {\n return;\n }\n\n const { start, end } = range;\n let firstLine = start.line;\n let endLine = end.line + 1;\n if (this.#renderRange !== undefined) {\n const { startingLine, totalLines } = this.#renderRange;\n firstLine = Math.max(firstLine, startingLine);\n endLine = Math.min(endLine, startingLine + totalLines);\n }\n for (let line = firstLine; line < endLine; line++) {\n if (!this.#isLineVisible(line)) {\n continue;\n }\n\n const isLastLine = line === end.line;\n const startChar = line === start.line ? start.character : 0;\n const endChar = isLastLine\n ? end.character\n : this.#textDocument.getLineLength(line);\n\n if (this.#isWrap) {\n const contentWidth = this.#getContentWidth();\n const lineText = this.#textDocument.getLineText(line);\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n this.#renderWrappedSelection(\n renderCtx,\n line,\n lineText,\n startChar,\n endChar,\n isLastLine,\n type,\n extraDataset\n );\n continue;\n }\n }\n\n let left = 0;\n let width = 0;\n let paddingEnd = 0;\n if (startChar === 0) {\n // gutter width + inline padding (1ch), plus the split-diff content\n // offset so a column-0 selection lines up with the content panel the\n // same way #getCharX (used for startChar > 0 and the caret) does.\n left =\n this.#getGutterWidth() +\n this.#metrics.ch +\n (this.#activeContentOffset?.left ?? 0);\n } else {\n left = this.#getCharX(line, startChar)[0];\n }\n if (!isLastLine && type === 'selection') {\n paddingEnd = this.#metrics.ch;\n }\n if (startChar === endChar) {\n width = paddingEnd;\n } else {\n width = this.#getCharX(line, endChar)[0] - left + paddingEnd;\n }\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n 0,\n left,\n width,\n extraDataset\n );\n }\n }\n\n // Render the selection on a wrapped logical line by splitting it into one\n // selection-range div per visual sub-line. For each wrap segment, we compute\n // the intersection with the line's selection range and render the slice in\n // segment-local coordinates so left/width line up with the visually wrapped\n // text. Zero-width slices that fall on intermediate segment boundaries are\n // skipped to avoid duplicate markers across consecutive visual lines.\n #renderWrappedSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n line: number,\n lineText: string,\n startChar: number,\n endChar: number,\n isLastLine: boolean,\n type: 'selection' | 'match' | 'marker' | 'bracketMatch',\n extraDataset?: string\n ) {\n const wrapOffsets = this.#wrapLineTextOrWholeLine(line);\n const segmentCount = wrapOffsets.length - 1;\n // offsetLeft is the x of the content's left edge in overlay coordinates.\n // In a split diff with wrapping the content element is a grid item shifted\n // right of the deletion panel, so the same content offset that #getCharX\n // adds for the caret must be included here too; otherwise every wrapped\n // selection block is pulled left by the panel offset.\n const offsetLeft =\n this.#getGutterWidth() +\n this.#metrics.ch +\n (this.#activeContentOffset?.left ?? 0);\n\n for (let wrapLine = 0; wrapLine < segmentCount; wrapLine++) {\n const segmentStart = wrapOffsets[wrapLine];\n const segmentEnd = wrapOffsets[wrapLine + 1];\n const wrapStartChar = Math.max(startChar, segmentStart);\n const wrapEndChar = Math.min(endChar, segmentEnd);\n\n // Selection range doesn't reach this visual segment.\n if (wrapStartChar > wrapEndChar) {\n continue;\n }\n\n const segmentStartWidth = this.#segmentTextWidth(\n lineText,\n segmentStart,\n wrapStartChar\n );\n const segmentLeft = offsetLeft + segmentStartWidth;\n let paddingEnd = 0;\n if (\n !isLastLine &&\n wrapLine === segmentCount - 1 &&\n type === 'selection'\n ) {\n paddingEnd = this.#metrics.ch;\n }\n // Measure the selection width as the gap between two segment-relative\n // offsets so a tab inside the selection advances from its real column,\n // not from the start of the sliced selection text.\n const segmentWidth =\n wrapStartChar === wrapEndChar\n ? paddingEnd\n : this.#segmentTextWidth(lineText, segmentStart, wrapEndChar) -\n segmentStartWidth +\n paddingEnd;\n\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n wrapLine,\n segmentLeft,\n segmentWidth,\n extraDataset\n );\n }\n }\n\n // Pixel width of the text from a wrapped segment's start up to a character,\n // relative to the segment's left edge. Tabs advance from the segment start,\n // which sits on a tab stop, so tab stops line up with the rendered text.\n #segmentTextWidth(\n lineText: string,\n segmentStart: number,\n character: number\n ): number {\n if (character <= segmentStart) {\n return 0;\n }\n const segmentText = lineText.slice(segmentStart, character);\n const asciiColumns = getExpandedAsciiTextColumns(\n segmentText,\n this.#metrics.tabSize\n );\n return asciiColumns !== -1\n ? asciiColumns * this.#metrics.ch\n : this.#metrics.measureTextWidth(segmentText);\n }\n\n // Render one selection block for a single visual line.\n #renderSelectionBlock(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n previousSelectionRange?: {\n element: HTMLElement;\n line: number;\n wrapLine: number;\n left: number;\n width: number;\n };\n },\n type: 'selection' | 'match' | 'marker' | 'bracketMatch',\n line: number,\n wrapLine: number,\n left: number,\n width: number,\n extraDataset?: string\n ) {\n if (width === 0) {\n return;\n }\n\n const { ch, lineHeight } = this.#metrics;\n const y = this.#getLineY(line) + wrapLine * lineHeight;\n const cacheKey = `${type}-${line}/${wrapLine}-${left}-${width} ${extraDataset ?? ''}`;\n const overlayEls = this.#overlayElements;\n const rounded =\n (this.#options.roundedSelection ?? true) && type === 'selection';\n\n const addRoundedCorner = (\n line: number,\n wrapLine: number,\n left: number,\n radius: 'rtl' | 'rbl' | 'rbr'\n ) => {\n const top = this.#getLineY(line) + wrapLine * lineHeight;\n // Match the corner mask to the line color behind the selection; when\n // absent (context lines) the CSS falls back to the editor base bg.\n const lineElement = this.#getLineElement(line);\n let cornerBg = 'initial';\n if (\n lineElement !== undefined &&\n (lineElement.dataset.lineType === 'change-addition' ||\n lineElement.dataset.selectedLine !== undefined)\n ) {\n cornerBg =\n getComputedStyle(lineElement).getPropertyValue('--diffs-line-bg');\n }\n const css = `width:${ch}px;transform:translateX(${left}px) translateY(${top}px);--diffs-selection-corner-bg:${cornerBg}`;\n const dataset = {\n selectionCorner: '',\n [radius]: '',\n };\n const cacheKeyPrefix = `${type}-block-${line}/${wrapLine}-${left}-1ch`;\n let cacheKey = cacheKeyPrefix + '-' + radius;\n if (radius === 'rbl') {\n const prevCornerKey = cacheKeyPrefix + '-rtl';\n const prevCorner = renderCtx.elements.get(prevCornerKey);\n if (prevCorner !== undefined) {\n prevCorner.remove();\n renderCtx.elements.delete(prevCornerKey);\n cacheKey += '-rtl';\n dataset.rtl = '';\n }\n }\n let cornerEl = renderCtx.elements.get(cacheKey);\n if (cornerEl !== undefined) {\n return;\n }\n if (overlayEls?.has(cacheKey) === true) {\n cornerEl = overlayEls.get(cacheKey)!;\n cornerEl.style.cssText = css;\n overlayEls.delete(cacheKey);\n } else {\n cornerEl = h(\n 'div',\n {\n dataset: 'selectionRange',\n style: { cssText: css },\n children: [\n h('div', {\n dataset: dataset,\n }),\n ],\n },\n renderCtx.fragment\n );\n }\n renderCtx.elements.set(cacheKey, cornerEl);\n };\n const addRadiusStyle = (element: HTMLElement) => {\n const end = left + width;\n const dataset = element.dataset;\n const previousSelectionRange = renderCtx.previousSelectionRange;\n if (\n previousSelectionRange === undefined ||\n previousSelectionRange.line !== line ||\n previousSelectionRange.wrapLine !== wrapLine\n ) {\n renderCtx.previousSelectionRange = {\n element,\n line,\n wrapLine,\n left,\n width,\n };\n }\n if (\n previousSelectionRange === undefined ||\n end <= previousSelectionRange.left\n ) {\n ['rtl', 'rtr', 'rbl', 'rbr'].forEach((key) => {\n dataset[key] = '';\n });\n } else {\n const prevLine = previousSelectionRange.line;\n const prevWrapLine = previousSelectionRange.wrapLine;\n const prevLeft = previousSelectionRange.left;\n const prevDataset = previousSelectionRange.element.dataset;\n const prevEnd = prevLeft + previousSelectionRange.width;\n if (prevLeft > left) {\n addRoundedCorner(prevLine, prevWrapLine, prevLeft - ch, 'rbr');\n }\n delete prevDataset.rbl;\n delete dataset.rtl;\n delete dataset.rtr;\n if (end >= prevEnd) {\n delete prevDataset.rbr;\n }\n if (end > prevEnd) {\n addRoundedCorner(prevLine, prevWrapLine, prevEnd, 'rbl');\n dataset.rtr = '';\n }\n if (end < prevEnd) {\n addRoundedCorner(line, wrapLine, end, 'rtl');\n }\n if (left < prevLeft) {\n dataset.rtl = '';\n }\n dataset.rbl = '';\n dataset.rbr = '';\n }\n };\n\n let rangeEl = renderCtx.elements.get(cacheKey);\n if (rangeEl !== undefined) {\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n return;\n }\n\n if (overlayEls?.has(cacheKey) === true) {\n rangeEl = overlayEls.get(cacheKey)!;\n overlayEls.delete(cacheKey);\n } else {\n rangeEl = h(\n 'div',\n {\n dataset: extraDataset\n ? [type + 'Range', extraDataset]\n : type + 'Range',\n },\n renderCtx.fragment\n );\n }\n\n rangeEl.style.width = `${width}px`;\n rangeEl.style.transform = `translateX(${left}px) translateY(${y}px)`;\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n renderCtx.elements.set(cacheKey, rangeEl);\n }\n\n #renderCaret(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n selection: EditorSelection,\n isPrimary: boolean\n ) {\n const { line, character } = getCaretPosition(selection);\n if (!this.#isLineVisible(line)) {\n return;\n }\n const [left, wrapLine] = this.#getCharX(line, character);\n const cacheKey = 'caret-' + line + '/' + wrapLine + ':' + character;\n if (renderCtx.elements.has(cacheKey)) {\n return;\n }\n\n const x = left - 1;\n const y = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n\n const caretEl = h(\n 'div',\n {\n dataset: 'caret',\n style: { transform: `translateX(${x}px) translateY(${y}px)` },\n },\n renderCtx.fragment\n );\n renderCtx.elements.set(cacheKey, caretEl);\n if (isPrimary) {\n caretEl.style.scrollMargin = this.#getScrollMargin();\n this.#primaryCaretElement = caretEl;\n }\n }\n\n #updateSelectionActionPopover(): void {\n const primarySelection = this.#selections?.at(-1);\n const overlayElement = this.#overlayElement;\n const textDocument = this.#textDocument;\n const renderSelectionAction = this.#options.renderSelectionAction;\n const cleanup = () => {\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n };\n\n if (\n this.#options.enabledSelectionAction !== true ||\n renderSelectionAction === undefined ||\n primarySelection === undefined ||\n isCollapsedSelection(primarySelection) ||\n this.#isContentMouseDown ||\n overlayElement === undefined ||\n textDocument === undefined\n ) {\n cleanup();\n return;\n }\n\n const head = getCaretPosition(primarySelection);\n if (!this.#isLineVisible(head.line)) {\n cleanup();\n return;\n }\n\n if (this.#selectionAction === undefined) {\n if (!this.#canMountSelectionAction) {\n return;\n }\n const getActiveSelection = (): EditorSelection =>\n this.#selections?.at(-1) ?? primarySelection;\n const selectionActionElement = renderSelectionAction({\n textDocument,\n get selection(): EditorSelection {\n return getActiveSelection();\n },\n applyEdits: (edits: TextEdit[]) => this.applyEdits(edits),\n getSelectionText: () =>\n this.#textDocument?.getText(getActiveSelection()) ?? '',\n replaceSelectionText: (text: string) => {\n this.#replaceSelectionText(text, [getActiveSelection()]);\n },\n close: () => {\n cleanup();\n this.#scrollToPrimaryCaret();\n },\n });\n this.#selectionAction = new SelectionActionWidget(\n selectionActionElement,\n overlayElement,\n () => this.#updateSelectionActionPopover()\n );\n // Avoid biasing the first decision with a stale side from a prior popover.\n this.#getPopoverManager().resetPlacement(\n SELECTION_ACTION_POPOVER_PLACEMENT_KEY\n );\n }\n\n const lineHeight = this.#metrics.lineHeight;\n const isBackward = primarySelection.direction === DirectionBackward;\n const preferred = {\n placeAbove: isBackward,\n anchor: head,\n };\n const fallback: typeof preferred = isBackward\n ? { placeAbove: false, anchor: primarySelection.end }\n : { placeAbove: true, anchor: primarySelection.start };\n\n // Resolve each candidate's [left, top, bottom] in overlay coordinate space\n // up front so both the viewport fit-check and the final reposition() call\n // below can reuse them without re-deriving the same line/char geometry\n // twice. For an above placement the CSS `--popover-y-shift: -100%` lifts\n // the popover by its own height, so its top is the anchor row's top minus\n // that height.\n const popoverHeight = this.#selectionAction.height;\n const candidateGeometry = (\n candidate: typeof preferred\n ): PopoverPlacementBounds & {\n left: number;\n anchorTop: number;\n rowTop: number;\n } => {\n const [left, candidateWrapLine] = this.#getCharX(\n candidate.anchor.line,\n candidate.anchor.character\n );\n const rowTop =\n this.#getLineY(candidate.anchor.line) + candidateWrapLine * lineHeight;\n const anchorTop = candidate.placeAbove ? rowTop : rowTop + lineHeight;\n const top = candidate.placeAbove ? anchorTop - popoverHeight : anchorTop;\n return { top, bottom: top + popoverHeight, left, anchorTop, rowTop };\n };\n const preferredGeometry = candidateGeometry(preferred);\n\n const lineCount = textDocument.lineCount;\n const atDocumentEdge = isBackward\n ? head.line < POPOVER_BOUNDARY_LINES\n : head.line >= lineCount - POPOVER_BOUNDARY_LINES;\n const fallbackGeometry = this.#isLineVisible(fallback.anchor.line)\n ? candidateGeometry(fallback)\n : undefined;\n const popoverManager = this.#getPopoverManager();\n const viewport = popoverManager.getPlacementBounds();\n const useFallback =\n fallbackGeometry !== undefined &&\n popoverManager.choosePlacement({\n preferred: preferredGeometry,\n fallback: fallbackGeometry,\n viewport,\n popoverHeight,\n atDocumentEdge,\n placementKey: SELECTION_ACTION_POPOVER_PLACEMENT_KEY,\n }) === 'fallback';\n if (fallbackGeometry === undefined) {\n popoverManager.setPlacement(\n 'preferred',\n SELECTION_ACTION_POPOVER_PLACEMENT_KEY\n );\n }\n const { placeAbove } = useFallback ? fallback : preferred;\n const { left, anchorTop } =\n useFallback && fallbackGeometry !== undefined\n ? fallbackGeometry\n : preferredGeometry;\n // An endpoint outside the virtualized window extends past the viewport\n // rather than making a selection that crosses it look offscreen.\n const selectionTop = isBackward\n ? preferredGeometry.rowTop\n : (fallbackGeometry?.rowTop ?? -Infinity);\n const selectionBottom =\n (isBackward\n ? (fallbackGeometry?.rowTop ?? Infinity)\n : preferredGeometry.rowTop) +\n (primarySelection.end.line > primarySelection.start.line &&\n primarySelection.end.character === 0\n ? 0\n : lineHeight);\n const isSelectionVisible =\n viewport === undefined ||\n (selectionBottom > viewport.top && selectionTop < viewport.bottom);\n\n this.#selectionAction.reposition(\n left,\n anchorTop,\n this.#getGutterWidth(),\n placeAbove,\n isSelectionVisible,\n viewport\n );\n }\n\n // Opens the search panel in the requested mode. If a panel is already open,\n // it switches that panel's mode in place (preserving the current query)\n // rather than recreating it.\n #openSearchPanel(mode: SearchPanelMode) {\n if (this.#searchPanel !== undefined) {\n this.#searchPanel.setMode(mode);\n return;\n }\n this.#renderSearchPanel(mode);\n }\n\n #renderSearchPanel(mode: SearchPanelMode) {\n // cleanup the existing search panel\n this.#searchPanel?.cleanup();\n\n const textDocument = this.#textDocument;\n const preElement =\n this.#fileContainer?.shadowRoot?.querySelector<HTMLElement>('pre');\n const selections = this.#selections;\n if (textDocument === undefined || preElement == null) {\n return;\n }\n\n let defaultQuery = '';\n let initialMatch: [number, number] | undefined = undefined;\n\n if (selections !== undefined && selections.length > 0) {\n let primarySelection = selections.at(-1)!;\n if (isCollapsedSelection(primarySelection)) {\n primarySelection = expandCollapsedSelectionToWord(\n textDocument,\n primarySelection\n );\n this.#updateSelections([...selections.slice(0, -1), primarySelection]);\n const selectionText = textDocument.getText(primarySelection);\n if (selectionText !== '' && !selectionText.includes('\\n')) {\n defaultQuery = selectionText;\n initialMatch = [\n textDocument.offsetAt(primarySelection.start),\n textDocument.offsetAt(primarySelection.end),\n ];\n }\n }\n }\n\n const scrollToMatch = (\n [startOffset, endOffset]: MatchRange,\n retainFocus: boolean\n ) => {\n const nextSelection = createSelectionFromAnchorAndFocusOffsets(\n textDocument,\n startOffset,\n endOffset\n );\n this.#updateSelections([nextSelection]);\n // Search counts include matches hidden in collapsed regions; navigating\n // to one reveals it.\n this.#revealLineIfCollapsed(getCaretPosition(nextSelection).line);\n this.#scrollToPrimaryCaret(true); // scroll to the primary caret and don't focus\n this.#retainSearchPanelFocus = retainFocus;\n };\n\n const searchPanel = new SearchPanelWidget({\n textDocument,\n containerElement: preElement,\n defaultQuery,\n mode,\n initialMatch,\n scrollToMatch,\n applyReplace: (edits: ResolvedTextEdit[]) => {\n if (edits.length === 0) {\n return;\n }\n const change = textDocument.applyEdits(\n edits.map((edit) => ({\n range: {\n start: textDocument.positionAt(edit.start),\n end: textDocument.positionAt(edit.end),\n },\n newText: edit.text,\n })),\n true,\n this.#selections\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n undefined,\n this.#applyChangeToLineAnnotations(change),\n { skipSearchRefresh: true }\n );\n }\n },\n onUpdate: (\n allMatches: MatchRange[],\n options?: { syncSelection?: boolean }\n ): MatchRange | undefined => {\n if (allMatches.length === 0) {\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#matches = allMatches;\n if (options?.syncSelection === false) {\n this.#updateSelections(this.#selections ?? []);\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const startOffset = textDocument.offsetAt(primarySelection.start);\n const endOffset = textDocument.offsetAt(primarySelection.end);\n for (const match of allMatches) {\n if (match[0] === startOffset && match[1] === endOffset) {\n return match;\n }\n }\n }\n return undefined;\n }\n\n const primarySelection = this.#selections?.at(-1);\n let searchOffset = 0;\n let nextMatch: MatchRange | undefined;\n if (primarySelection !== undefined) {\n searchOffset = textDocument.offsetAt(primarySelection.start);\n }\n for (const m of allMatches) {\n if (m[0] >= searchOffset) {\n nextMatch = m;\n break;\n }\n }\n if (nextMatch !== undefined) {\n scrollToMatch(nextMatch, true);\n } else {\n this.#updateSelections(this.#selections ?? []);\n }\n return nextMatch;\n },\n onClose: () => {\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n },\n });\n\n this.#searchPanel = searchPanel;\n this.#retainSearchPanelFocus = false;\n }\n\n #getSelectionText() {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return '';\n }\n return getSelectionText(textDocument, selections);\n }\n\n #getSelectionClipboardTexts(): string[] {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return [];\n }\n return getSelectionClipboardTexts(textDocument, selections);\n }\n\n /** Writes both the portable text and the selection pairing metadata. */\n #writeSelectionClipboardData(\n clipboardData: DataTransfer | null,\n text: string,\n selectionTexts: string[]\n ): void {\n if (clipboardData === null) {\n return;\n }\n clipboardData.setData('text', text);\n if (selectionTexts.length > 1) {\n clipboardData.setData(\n MULTI_SELECTION_CLIPBOARD_TYPE,\n JSON.stringify(selectionTexts)\n );\n }\n }\n\n #cutSelectionText(): string {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (\n textDocument === undefined ||\n selections === undefined ||\n selections.length === 0\n ) {\n return '';\n }\n\n if (selections.some((selection) => isCollapsedSelection(selection))) {\n const cut = resolveSelectionCut(textDocument, selections);\n this.#applySelectionCutEdits(cut.edits, cut.nextSelectionOffsets);\n return cut.text;\n }\n\n const text = getSelectionText(textDocument, selections);\n this.#replaceSelectionText('', undefined, true);\n return text;\n }\n\n #applySelectionCutEdits(\n edits: ResolvedTextEdit[],\n nextSelectionOffsets: number[]\n ): void {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (\n textDocument === undefined ||\n selections === undefined ||\n edits.length === 0\n ) {\n return;\n }\n\n const change = textDocument.applyResolvedEdits(\n edits,\n true,\n selections,\n undefined,\n true\n );\n if (change === undefined) {\n return;\n }\n\n const nextSelections = nextSelectionOffsets.map<EditorSelection>(\n (offset) => {\n const caret = textDocument.positionAt(offset);\n return {\n start: caret,\n end: caret,\n direction: DirectionNone,\n };\n }\n );\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n\n // replace the selection text\n #replaceSelectionText(\n text: string | string[],\n selections = this.#selections,\n undoBoundary = false,\n textOrder: 'selection' | 'document' = 'selection'\n ) {\n if (selections === undefined) {\n return;\n }\n const textDocument = this.#textDocument;\n const primarySelection = selections.at(-1);\n if (textDocument === undefined || primarySelection === undefined) {\n return;\n }\n const { nextSelections, change } =\n Array.isArray(text) && text.length === selections.length\n ? applyTextReplaceToSelections<LAnnotation>(\n textDocument,\n selections,\n text,\n this.#lineAnnotations,\n undoBoundary,\n textOrder\n )\n : applyTextChangeToSelections<LAnnotation>(\n textDocument,\n selections,\n {\n start: textDocument.offsetAt(primarySelection.start),\n end: textDocument.offsetAt(primarySelection.end),\n text: Array.isArray(text) ? text.join(textDocument.eol) : text,\n },\n this.#lineAnnotations,\n undefined,\n undoBoundary\n );\n\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteSelectionText(forward: boolean = false) {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n\n const { nextSelections, change } =\n applyDeleteCharacterToSelections<LAnnotation>(\n textDocument,\n selections,\n forward,\n this.#lineAnnotations,\n this.#metrics.tabSize\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteSoftLineBackward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const getSoftLineStart = this.#isWrap\n ? (line: number, character: number) => {\n const wrapOffsets = this.#wrapLineTextOrWholeLine(line);\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (character >= segmentStart && character <= segmentEnd) {\n return segmentStart;\n }\n }\n return 0;\n }\n : undefined;\n const { nextSelections, change } =\n applyDeleteSoftLineBackwardToSelections<LAnnotation>(\n textDocument,\n selections,\n getSoftLineStart,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteWordBackward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } =\n applyDeleteWordBackwardToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteHardLineForward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } =\n applyDeleteHardLineForwardToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #insertTranspose() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } = applyTransposeToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #applyChange(\n change: TextDocumentChange,\n newSelections?: EditorSelection[],\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n options?: { skipSearchRefresh?: boolean; skipFocus?: boolean }\n ) {\n const fileRef = this.getFile();\n const onChange = this.#options.onChange;\n if (fileRef !== undefined && onChange !== undefined) {\n const lineAnnotations = newLineAnnotations ?? this.#lineAnnotations;\n onChange(fileRef, lineAnnotations, {\n changes: change.changes,\n file: fileRef,\n lineAnnotations,\n });\n }\n\n // Invalidate layout caches touched by the edit. Clear cached line Y\n // positions from startLine onward when either:\n // - the line count changed (inserts/deletes renumber every later line), or\n // - wrap is on, where editing a line can add or remove a wrapped row and\n // shift the Y of every line after it even though the line count is the\n // same.\n if (change.lineDelta !== 0 || this.#isWrap) {\n for (const line of this.#lineYCache.keys()) {\n if (line >= change.startLine) {\n this.#lineYCache.delete(line);\n }\n }\n }\n // Wrap offsets persist while overflow is 'scroll' (the mode can toggle\n // back before any width/font/document invalidation runs), so edits must\n // invalidate them in every mode, not just while wrap is on. The size\n // guard keeps edits free when nothing was ever measured.\n if (this.#wrapLineOffsetsCache.size > 0) {\n // Lines outside the edited ranges keep both their text and their\n // numbering when no renumbering happened anywhere, so only the rewritten\n // lines need new wrap measurements. A net-zero lineDelta alone is not\n // enough: a multi-edit batch can cancel out (one edit removes a line,\n // another adds one) while still renumbering the lines between the edits.\n // It is sufficient when the batch coalesced into a single range (any\n // renumbered lines sit inside that range), or when every individual edit\n // kept the line count.\n const keepsLineNumbers =\n change.lineDelta === 0 &&\n (change.changedLineRanges.length === 1 ||\n change.changedLineChanges?.every(\n ([, , editLineDelta]) => editLineDelta === 0\n ) === true);\n if (keepsLineNumbers) {\n for (const [rangeStart, rangeEnd] of change.changedLineRanges) {\n for (let line = rangeStart; line <= rangeEnd; line++) {\n this.#wrapLineOffsetsCache.delete(line);\n }\n }\n } else {\n // Renumbering invalidates every cached entry from startLine onward:\n // its keyed line no longer holds the text that was measured.\n for (const line of this.#wrapLineOffsetsCache.keys()) {\n if (line >= change.startLine) {\n this.#wrapLineOffsetsCache.delete(line);\n }\n }\n }\n }\n this.#lastAccessedCharX = undefined;\n\n let renderRange = this.#renderRange;\n let shouldUpdateBuffer: boolean | undefined;\n if (\n renderRange !== undefined &&\n newSelections !== undefined &&\n newSelections.length > 0\n ) {\n const primarySelection = newSelections.at(-1)!;\n const renderRangeEndLine =\n renderRange.startingLine + renderRange.totalLines;\n // When an edit moves the caret to or past the last rendered line — typing\n // Enter at the window's bottom edge, or pasting a few lines there — widen\n // the render range so every new line up to the caret gets a row when\n // #rerender runs below. The widened range is also written back to\n // #renderRange: the next edit reads renderRangeEndLine from it, and\n // #renderCaret/#isLineVisible read it to decide whether to draw the caret.\n // Without persisting, the end line stays stale, a following edit is\n // misclassified as \"past the window\", and its just-typed line is left\n // unrendered until the next scroll re-syncs the range. Only edits that\n // carry a caret reach here (the block is guarded on `selections` above), so\n // a bare programmatic applyEdits with no active selection does not widen.\n //\n // Cap the widening at a multiple of the bounded window the virtualizer\n // last synced. A large insert at the caret — most often a big multi-line\n // paste, or a scripted set-selection-then-edit at scale — can drop the\n // caret far below the window; widening to reach it would make #rerender\n // build a row per inserted line synchronously, defeating virtualization.\n // Past the cap, keep the bounded window and only recompute the buffer\n // spacer — the scroll that follows a focused edit (or the next user scroll\n // when unfocused) renders the far region with a bounded window.\n if (primarySelection.end.line >= renderRangeEndLine) {\n const widenedTotalLines =\n primarySelection.end.line - renderRange.startingLine + 1;\n const maxWidenLines =\n this.#viewportWindowLines === undefined ||\n this.#viewportWindowLines === Infinity\n ? Infinity\n : this.#viewportWindowLines * MAX_EDIT_WIDEN_WINDOW_MULTIPLE;\n // Only widen when the edit actually reaches the rendered window — its\n // dirty lines start at or before the window end. #rerender materializes\n // rows from change.startLine onward, so widening for an edit that starts\n // entirely below the window (e.g. setSelections to an offscreen line\n // then applyEdits before the virtualizer re-syncs) would leave the\n // rows between the window and the edit unbuilt while #isLineVisible\n // reports them visible, mispositioning the new rows and caret until the\n // next scroll.\n if (\n change.startLine <= renderRangeEndLine &&\n widenedTotalLines <= maxWidenLines &&\n // Widening exists to give the caret's line a row; a caret target\n // hidden in a collapsed region can never gain one, so take the\n // buffer-only path instead of building rows toward it.\n this.#isLineRenderable(primarySelection.end.line)\n ) {\n if (primarySelection.end.line > renderRangeEndLine) {\n // The line count grew below the window, so the buffer spacer must be\n // recomputed (preserves the prior behavior for this case).\n shouldUpdateBuffer = true;\n }\n renderRange = { ...renderRange, totalLines: widenedTotalLines };\n this.#renderRange = renderRange;\n } else {\n // The edit is past the cap, or starts below the rendered window: keep\n // the bounded window and only recompute the buffer; the scroll that\n // follows a focused edit (or the next user scroll) renders the far\n // region.\n shouldUpdateBuffer = true;\n }\n }\n }\n this.#rerender(change, newLineAnnotations, renderRange, shouldUpdateBuffer);\n\n if (\n options?.skipSearchRefresh !== true &&\n this.#searchPanel !== undefined &&\n this.#matches !== undefined\n ) {\n this.#searchPanel.updateMatches({ syncSelection: false });\n }\n\n if (newSelections !== undefined) {\n // Always re-render the selection range and caret overlay so editor state\n // stays in sync. When skipFocus is set (a programmatic edit on an editor\n // that is not focused) we stop here: focusing or scrolling would pull the\n // caret and viewport toward an editor the user is not interacting with.\n this.#updateSelections(newSelections);\n\n // focus to update the native window selection, and scroll to the caret\n // to mock the 'contenteditable' behavior\n if (options?.skipFocus !== true) {\n // An undo/redo caret restore can land inside a collapsed region.\n const revealTarget = newSelections.at(-1);\n if (revealTarget !== undefined) {\n this.#revealLineIfCollapsed(getCaretPosition(revealTarget).line);\n }\n if (this.#primaryCaretElement !== undefined) {\n requestAnimationFrame(() => {\n this.#primaryCaretElement?.scrollIntoView({\n block: 'nearest',\n inline: 'nearest',\n });\n });\n } else if (newSelections.length > 0) {\n const pos = getCaretPosition(newSelections.at(-1)!);\n this.#scrollToLine(pos.line, pos.character);\n }\n this.focus({ preventScroll: true });\n }\n }\n }\n\n #applyChangeToLineAnnotations(\n change: TextDocumentChange\n ): DiffLineAnnotation<LAnnotation>[] | undefined {\n if (this.#lineAnnotations !== undefined) {\n const nextLineAnnotations =\n applyDocumentChangeToLineAnnotations<LAnnotation>(\n change,\n this.#lineAnnotations\n );\n if (nextLineAnnotations !== undefined) {\n this.#textDocument?.setLastUndoLineAnnotations(\n this.#lineAnnotations,\n nextLineAnnotations\n );\n return nextLineAnnotations;\n }\n }\n return undefined;\n }\n\n // Returns contiguous document-line ranges that have editable rows in the\n // current render window. Collapsed diff sections create gaps between ranges.\n #getRenderedEditableLineRanges(): [first: number, last: number][] {\n const contentElement = this.#contentElement;\n if (contentElement === undefined) {\n return [];\n }\n const ranges: [first: number, last: number][] = [];\n for (const child of contentElement.children) {\n const el = child as HTMLElement;\n const lineType = el.dataset.lineType;\n const lineNumber = getLineNumberAttr(el);\n if (\n lineNumber === undefined ||\n lineType === undefined ||\n !isLineEditable(lineType)\n ) {\n continue;\n }\n const line = lineNumber - 1;\n const current = ranges.at(-1);\n if (current !== undefined && line <= current[1] + 1) {\n current[1] = Math.max(current[1], line);\n } else {\n ranges.push([line, line]);\n }\n }\n return ranges;\n }\n\n #getLineElement(line: number): HTMLElement | undefined {\n let lineElement = this.#lineElementsCache.get(line);\n if (lineElement !== undefined) {\n return lineElement ?? undefined;\n }\n\n const renderRange = this.#renderRange;\n if (\n renderRange !== undefined &&\n (line < renderRange.startingLine ||\n line >= renderRange.startingLine + renderRange.totalLines)\n ) {\n return undefined;\n }\n\n const contentElement = this.#contentElement;\n if (contentElement === undefined) {\n return undefined;\n }\n\n // check if the line is within the render range (fast)\n if (renderRange !== undefined) {\n const { startingLine } = renderRange;\n const { children } = contentElement;\n for (let i = line - startingLine; i <= children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child === undefined) {\n break;\n }\n const lineNumber = getLineNumberAttr(child);\n const lineType = child.dataset.lineType;\n if (\n lineNumber !== undefined &&\n lineNumber === line + 1 &&\n lineType !== undefined &&\n isLineEditable(lineType)\n ) {\n lineElement = child;\n break;\n }\n }\n }\n\n // fallback to query selector\n lineElement ??= contentElement.querySelector<HTMLElement>(\n `[data-line=\"${line + 1}\"]` +\n (this.#diffSyle === 'unified'\n ? ':not([data-line-type=\"change-deletion\"])'\n : '')\n );\n\n if (lineElement !== undefined) {\n this.#lineElementsCache.set(line, lineElement);\n }\n return lineElement ?? undefined;\n }\n\n #getGutterWidth(): number {\n if (this.#gutterElement === undefined) {\n return 0;\n }\n\n if (this.#gutterWidthCache === undefined) {\n const diffsColumnNumberWidth =\n this.#contentElement?.parentElement?.style.getPropertyValue(\n '--diffs-column-number-width'\n );\n if (\n diffsColumnNumberWidth !== undefined &&\n diffsColumnNumberWidth.length > 2 &&\n diffsColumnNumberWidth.endsWith('px')\n ) {\n this.#gutterWidthCache = parseInt(\n diffsColumnNumberWidth.slice(0, -2),\n 10\n );\n } else {\n this.#gutterWidthCache = this.#gutterElement.offsetWidth;\n }\n }\n\n return this.#gutterWidthCache;\n }\n\n #getContentWidth(): number {\n if (this.#contentElement === undefined) {\n return 0;\n }\n\n if (this.#contentWidthCache === undefined) {\n const diffsColumnContentWidth =\n this.#contentElement.parentElement?.style.getPropertyValue(\n '--diffs-column-content-width'\n );\n if (\n diffsColumnContentWidth !== undefined &&\n diffsColumnContentWidth.length > 2 &&\n diffsColumnContentWidth.endsWith('px')\n ) {\n this.#contentWidthCache = parseFloat(\n diffsColumnContentWidth.slice(0, -2)\n );\n } else {\n this.#contentWidthCache = this.#contentElement.offsetWidth;\n }\n }\n return this.#contentWidthCache;\n }\n\n // get line top(y-coordinate) position\n #getLineY(line: number) {\n const cachedY = this.#lineYCache.get(line);\n if (cachedY !== undefined) {\n return cachedY;\n }\n\n const lineElement = this.#getLineElement(line);\n if (lineElement === undefined) {\n return -1;\n }\n\n // cold(slow) path: measure line top position from DOM (will cause reflow)\n let y = lineElement.offsetTop + this.#metrics.paddingTop;\n y += this.#activeContentOffset?.top ?? 0;\n this.#lineYCache.set(line, y);\n return y;\n }\n\n // Return the visual position for a character. Wrapped lines include the\n // visual line index so carets can be placed on the correct row.\n #getCharX(line: number, char: number): [x: number, wrapLine: number] {\n if (\n this.#lastAccessedCharX !== undefined &&\n this.#lastAccessedCharX[0] === line &&\n this.#lastAccessedCharX[1] === char\n ) {\n return [this.#lastAccessedCharX[2], this.#lastAccessedCharX[3]];\n }\n\n const lineText = this.#textDocument?.getLineText(line);\n const offsetLeft = this.#getGutterWidth() + this.#metrics.ch; // gutter width + inline padding (1ch)\n if (lineText === undefined || lineText.length === 0 || char <= 0) {\n return [offsetLeft + (this.#activeContentOffset?.left ?? 0), 0];\n }\n\n const boundedCharacter = snapTextOffsetToUnicodeBoundary(\n lineText,\n Math.min(char, lineText.length)\n );\n const textBeforeCharacter = lineText.slice(0, boundedCharacter);\n const asciiColumns = getExpandedAsciiTextColumns(\n textBeforeCharacter,\n this.#metrics.tabSize\n );\n\n let left = 0;\n let wrapLine = 0;\n if (asciiColumns !== -1) {\n left = offsetLeft + asciiColumns * this.#metrics.ch;\n } else {\n left = offsetLeft + this.#metrics.measureTextWidth(textBeforeCharacter);\n }\n\n if (this.#isWrap) {\n const contentWidth = this.#getContentWidth();\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n const wrapOffsets = this.#wrapLineText(line);\n // undefined means the wrap offsets could not be measured — the\n // content element is detached or has no layout (see #wrapLineText).\n // Fall back to an unwrapped position, and return before the\n // #lastAccessedCharX write below so nothing derived from the\n // unmeasurable DOM gets memoized; the next call re-measures against\n // live layout.\n if (wrapOffsets == null) {\n return [left + (this.#activeContentOffset?.left ?? 0), 0];\n }\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (boundedCharacter <= segmentEnd) {\n wrapLine = w;\n const prefixInSegment = lineText.slice(\n segmentStart,\n boundedCharacter\n );\n const segmentAsciiColumns = getExpandedAsciiTextColumns(\n prefixInSegment,\n this.#metrics.tabSize\n );\n if (segmentAsciiColumns !== -1) {\n left = offsetLeft + segmentAsciiColumns * this.#metrics.ch;\n } else {\n left =\n offsetLeft + this.#metrics.measureTextWidth(prefixInSegment);\n }\n break;\n }\n }\n }\n left += this.#activeContentOffset?.left ?? 0;\n }\n\n if (this.#lastAccessedCharX !== undefined) {\n this.#lastAccessedCharX[0] = line;\n this.#lastAccessedCharX[1] = char;\n this.#lastAccessedCharX[2] = left;\n this.#lastAccessedCharX[3] = wrapLine;\n } else {\n this.#lastAccessedCharX = [line, char, left, wrapLine];\n }\n\n return [left, wrapLine];\n }\n\n // Compute how a logical line of text is broken into visual lines when line\n // wrapping is enabled.\n //\n // Returns undefined when the offsets cannot be measured: measurement works\n // by appending a hidden probe to #contentElement, so a detached or\n // zero-width content element (both occur while a session re-render replaces\n // the code columns) would report \"never wraps\" for any line. That result is\n // never returned or cached — a cached wrong answer would keep placing\n // carets at unwrapped positions until an unrelated edit evicted it. Callers\n // that need best-effort segmentation use #wrapLineTextOrWholeLine;\n // #getCharX propagates the undefined so its own memoization is skipped\n // too.\n #wrapLineText(line: number): Uint32Array | undefined {\n const cachedOffsets = this.#wrapLineOffsetsCache.get(line);\n if (cachedOffsets !== undefined) {\n return cachedOffsets;\n }\n if (this.#wrapLineOffsetsCache.size >= MAX_WRAP_OFFSETS_CACHE_LINES) {\n this.#wrapLineOffsetsCache.clear();\n }\n\n const lineText = this.#textDocument?.getLineText(line);\n if (lineText === undefined || lineText.length === 0) {\n const offsets = new Uint32Array([0]);\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n }\n\n const contentElement = this.#contentElement;\n if (contentElement == null || !contentElement.isConnected) {\n return undefined;\n }\n\n const div = h(\n 'div',\n {\n style: {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n boxSizing: 'border-box',\n visibility: 'hidden',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n font: 'inherit',\n paddingInline: '1ch',\n tabSize: this.#metrics.tabSize.toString(),\n },\n textContent: lineText,\n },\n contentElement\n );\n const textNode = div.firstChild as Text;\n const range = document.createRange();\n const starts: number[] = [];\n\n try {\n const divRect = div.getBoundingClientRect();\n if (divRect.width === 0) {\n return undefined;\n }\n const unicodeOffsets = getUnicodeMeasurementOffsets(lineText);\n const wrapLineStartLeft = divRect.left + this.#metrics.ch;\n\n // Measurement steps through grapheme clusters when the text needs\n // Unicode-aware boundaries, single UTF-16 units otherwise. Grapheme\n // `index` spans [graphemeStart(index), graphemeStart(index + 1)).\n const graphemeCount =\n unicodeOffsets === undefined\n ? lineText.length\n : unicodeOffsets.length - 1;\n const graphemeStart = (index: number): number =>\n unicodeOffsets === undefined ? index : unicodeOffsets[index];\n const measureGrapheme = (index: number): DOMRect => {\n range.setStart(textNode, graphemeStart(index));\n range.setEnd(textNode, graphemeStart(index + 1));\n return range.getBoundingClientRect();\n };\n\n // A new visual line starts whenever a grapheme's top edge moves below\n // the previous grapheme's top edge. Line breaking assigns graphemes to\n // visual lines in logical order, so tops are non-decreasing with the\n // text offset and each wrap point can be located by binary-searching for\n // the first grapheme below the current visual line — O(wraps * log n)\n // rect measurements instead of one per character.\n starts.push(0);\n let lastTop = measureGrapheme(0).top;\n let searchStart = 1;\n while (searchStart < graphemeCount) {\n let low = searchStart;\n let high = graphemeCount;\n while (low < high) {\n const mid = (low + high) >> 1;\n if (measureGrapheme(mid).top > lastTop) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n if (low >= graphemeCount) {\n break;\n }\n const { left, top } = measureGrapheme(low);\n // Safari can report the first range on a wrapped visual line as\n // starting one character past the visual line start. Use the previous\n // grapheme so segment-local caret math begins at the actual wrap point.\n const startsPastLineStart =\n isSafari() && left - wrapLineStartLeft > this.#metrics.ch / 2;\n starts.push(graphemeStart(startsPastLineStart ? low - 1 : low));\n lastTop = top;\n searchStart = low + 1;\n }\n\n const offsets = new Uint32Array(starts.length + 1);\n for (let i = 0; i < starts.length; i++) {\n offsets[i] = starts[i]!;\n }\n offsets[starts.length] = lineText.length;\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n } finally {\n div.remove();\n }\n }\n\n // #wrapLineText for callers that need usable offsets even when measurement\n // is impossible (undefined): treats the line as one unwrapped segment.\n // Safe because the fallback is never cached — once the content element is\n // measurable again, the same call returns real offsets.\n #wrapLineTextOrWholeLine(line: number): Uint32Array {\n const offsets = this.#wrapLineText(line);\n if (offsets !== undefined) {\n return offsets;\n }\n const length = this.#textDocument?.getLineText(line)?.length ?? 0;\n return Uint32Array.of(0, length);\n }\n\n // check if the web selection belongs to editor\n #rangeBelongsToEditor({ startContainer, endContainer }: StaticRange) {\n const contentEl = this.#contentElement;\n if (contentEl === undefined) {\n return false;\n }\n return (\n contentEl.contains(startContainer) && contentEl.contains(endContainer)\n );\n }\n\n // Check whether a line is visible in the currently rendered line window.\n #isLineVisible(line: number): boolean {\n const lineCount = this.#textDocument?.lineCount ?? 0;\n if (line < 0 || line >= lineCount) {\n return false;\n }\n return this.#getLineElement(line) !== undefined;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editor.js","names":["#editStateKey","#ownsVerticalViewport","#isRendering","#fileInstance","#renderRange","#editPrediction","#editSession","#initialState","#getLineElement","#selections","#updateSelections","#options","#getTypedEditor","#caretElements","#renderCarets","#cancelEditPrediction","#editPredictionHistory","#scheduleEditPrediction","#ghostTextRows","#caretHighlightElements","#carets","#restoreEditorStateOnSync","#initialize","#applyDocumentChange","#publishChange","#detach","#contentHasFocus","#applyChange","#applyChangeToLineAnnotations","#runCommand","#getOwnedVerticalViewport","#canMountSelectionAction","#scrollToPrimaryCaret","#checkpointEditSessionState","#revealLineIfCollapsed","#markerRenderer","#getPopoverManager","#metrics","#overlayElement","#getGutterWidth","#getCharX","#getLineY","#isContentMouseDown","#isGutterMouseDown","#contentElement","#getFirstVisibleLineNumber","#focusAtPosition","#focus","#replacementFocusRequest","#shouldIgnoreSelectionChange","#releaseEditSession","#invalidateOnAttach","#attachState","#handleCustomPasteEvent","#tokenizer","#globalEventDisposes","#editorEventDisposes","#gutterWidthCache","#contentWidthCache","#lineYCache","#wrapLineOffsetsCache","#lineElementsCache","#lastAccessedCharX","#globalStyleElement","#editorStyleElement","#themeStyleElement","#spriteElement","#fileContainer","#popoverManager","#gutterElement","#deletionsColumn","#resizeObserver","#fontRemeasureScheduled","#themeSelectionRefreshFrame","#resetState","#initSelections","#applyExternalDocumentReplacement","#onDeferTokenize","#scheduleThemeSelectionRefresh","#remeasureMetricsOnFontLoad","#listenContentElement","#isDiff","#resetCache","#lineAnnotations","#viewportWindowLines","#matches","#retryEditPredictionOnRender","#primaryCaretElement","#scrollingToLine","#scrollToLine","#scrollingToLineChar","#scrollingToLineNoFocus","#restoreReplacementFocus","#retainSearchPanelFocus","#searchPanel","#emitChange","#scheduleOnAttach","#fileDiffInstance","#virtualizedInstance","#resolveRenderableLine","#isLineRenderable","#diffSyle","#isWrap","#selectionAction","#updateSelectionActionPopover","#setEditorActiveLineSafe","#resetSelectionGesture","#suppressNativeSelectionSync","#overlayElements","editorCSS","#rangeBelongsToEditor","#shiftKeyPressed","#selectionStart","#altColumnDrag","#updateAltColumnSelections","#reservedSelections","#editPredictionRevealed","#selectEventDisposes","#setWindowSelection","#isDeletedLineTarget","#setDeletedTextSelectionActive","#replaceSelectEventListeners","#isComposing","#acceptEditPrediction","#wrapLineTextOrWholeLine","#isDeletedTextSelectionActive","#deletedTextForClipboard","#writeSelectionClipboardData","#getSelectionText","#getSelectionClipboardTexts","#cutSelectionText","#replaceSelectionText","#handleInput","#preserveEditorSelectionsForGutterGesture","#isLineSelectionEnabled","#beginDeletionGutterSelection","#spanLineSelection","#handleLayoutResize","#computeContentOffset","#contentOffset","#activeContentOffset","#openSearchPanel","#moveSelectedLines","#copySelectedLines","#insertBlankLine","#deleteHardLineForward","#applyCommandEdits","#getRenderedEditableLineRanges","#applyHistoryChange","#getContentWidth","#deleteSelectionText","#deleteSoftLineBackward","#deleteWordBackward","#insertTranspose","#replacementFocusIsAvailable","#getScrollViewport","#getScrollMargin","#scrollingToLineFixed","#deletedSelectionText","#contentRowForGutterRow","#selectDeletedLines","#composeEditPredictionGroup","#isLineVisible","#fillGhostTextElement","#cloneInsertionSuffix","#getEditPredictionGroups","#measureGhostTextRows","#deletionsColumnPartner","#editPredictionSpacers","#editPredictionTimer","#editPredictionAbortController","#editPredictionGeneration","#syncEditPredictionSpacers","#removeRenderedEditPrediction","#includesEditPredictionPath","#isLineInRenderRange","#renderSelection","#renderCaret","#renderEditPrediction","#renderSelectionBlock","#renderWrappedSelection","#segmentTextWidth","#renderSearchPanel","#applySelectionCutEdits","#rerender","#recordEditPredictionHistory","#wrapLineText"],"sources":["../../src/editor/editor.ts"],"sourcesContent":["import type { File } from '../components/File';\nimport type { FileDiff } from '../components/FileDiff';\nimport type { VirtualizedFile } from '../components/VirtualizedFile';\nimport type { VirtualizedFileDiff } from '../components/VirtualizedFileDiff';\nimport {\n dequeueRender,\n queueRender,\n} from '../managers/UniversalRenderingManager';\nimport type {\n DiffLineAnnotation,\n DiffsHighlighter,\n FileContents,\n FileDiffMetadata,\n HighlightedToken,\n LineAnnotation,\n RenderRange,\n SelectionSide,\n} from '../types';\nimport { computeLineOffsets } from '../utils/computeFileOffsets';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { isGutterUtilityPath } from '../utils/isGutterUtilityPath';\nimport { cloneRetainedDiffSessionSnapshot } from './cloneRetainedDiffSessionSnapshot';\nimport {\n type EditorCommand,\n type EditorKeymap,\n resolveEditorCommandFromKeyboardEvent,\n resolveFindAgainShortcut,\n} from './command';\nimport editorCSS from './editor.css?inline';\nimport {\n buildEditPredictionRequest,\n type EditPredictionHistoryRecord,\n type EditPredictProvider,\n type EditPredictResponse,\n matchesEditPredictionPattern,\n recordEditPrediction,\n} from './editPrediction';\nimport { EditStack } from './editStack';\nimport {\n cloneEditorViewState,\n EditStateManager,\n type ManagedEditSession,\n toManagedEditState,\n} from './EditStateManager';\nimport {\n type LanguageConfigMap,\n resolveBlockCommentEdits,\n resolveCommentConfig,\n resolveLineCommentEdits,\n} from './languages';\nimport {\n applyDocumentChangeToLineAnnotations,\n renderLineAnnotations,\n} from './lineAnnotations';\nimport {\n type Marker,\n MarkerRenderer,\n markerSeverityDatasetKey,\n} from './marker';\nimport { findBracketMatchRanges } from './matchBrackets';\nimport { isMoveCursorShortcut, isPrimaryModifier, isSafari } from './platform';\nimport {\n POPOVER_BOUNDARY_LINES,\n PopoverManager,\n type PopoverPlacementBounds,\n} from './popover';\nimport {\n type MatchRange,\n type SearchPanelMode,\n SearchPanelWidget,\n} from './searchPanel';\nimport type {\n AutoSurround,\n CursorMoveOptions,\n ResolveRenderableLine,\n} from './selection';\nimport {\n applyDeleteCharacterToSelections,\n applyDeleteHardLineForwardToSelections,\n applyDeleteSoftLineBackwardToSelections,\n applyDeleteWordBackwardToSelections,\n applyTextChangeToSelections,\n applyTextReplaceToSelections,\n applyTransposeToSelections,\n comparePosition,\n convertSelection,\n createSelectionFrom,\n createSelectionFromAnchorAndFocusOffsets,\n DirectionBackward,\n DirectionForward,\n DirectionNone,\n expandCollapsedSelectionToWord,\n extendSelection,\n extendSelections,\n findNextMatch,\n getAutoSurroundReplacementTexts,\n getCaretPosition,\n getDocumentBoundarySelection,\n getDocumentFullSelection,\n getSelectedLineBlocks,\n getSelectionAnchor,\n getSelectionClipboardTexts,\n getSelectionText,\n isCollapsedSelection,\n isLineEditable,\n mapCursorMove,\n mapSelectionShift,\n mergeOverlappingSelections,\n remapOffsetThroughEdits,\n remapSelectionsAfterEdits,\n resolveIndentEdits,\n resolveSelectionCut,\n selectionIntersects,\n shiftSelectionLines,\n snapCharacterToGraphemeBoundary,\n} from './selection';\nimport {\n type SelectionActionContext,\n SelectionActionWidget,\n} from './selectionAction';\nimport { createSpriteElement } from './sprite';\nimport { TextDocument, type TextDocumentChange } from './textDocument';\nimport { getTextDocumentChangeTransaction } from './textDocumentChangeTransaction';\nimport {\n getExpandedAsciiTextColumns,\n getUnicodeMeasurementOffsets,\n Metrics,\n snapTextOffsetToUnicodeBoundary,\n} from './textMeasure';\nimport { EditorTokenizer, renderLineTokens } from './tokenizer';\nimport type {\n EditorCaret,\n EditorChange,\n EditorChangeEvent,\n EditorEditCompleteEvent,\n EditorInitialState,\n EditorLineAnnotation,\n EditorSelection,\n EditorType,\n EditorViewState,\n EditState,\n Position,\n Range,\n ResolvedTextEdit,\n RetainedDiffSessionSnapshot,\n TextEdit,\n} from './types';\nimport {\n addEventListener,\n clampDomOffset,\n extend,\n getLineNumberAttr,\n h,\n lookupScrollContainer,\n round,\n} from './utils';\n\nexport type {\n EditPredictContext,\n EditPredictProvider,\n EditPredictRequest,\n EditPredictResponse,\n} from './editPrediction';\n\n// ShadowRoot.getSelection is a non-standard Blink/WebKit method (predates the\n// spec'd Selection.getComposedRanges) and is missing from the DOM lib types.\ntype ShadowRootWithSelection = ShadowRoot & {\n getSelection?: () => Selection | null;\n};\n\n// Fallback for browsers without Selection.getComposedRanges: read the first\n// range from the shadow root's own selection so the editor can still map a\n// caret placed by a click inside its shadow tree. Normalized to a StaticRange\n// so it matches the getComposedRanges return shape the callers expect. Returns\n// undefined when the API or a live range is unavailable.\nfunction getShadowRootRange(shadowRoot: ShadowRoot): StaticRange | undefined {\n const selection = (shadowRoot as ShadowRootWithSelection).getSelection?.();\n if (selection == null || selection.rangeCount === 0) {\n return undefined;\n }\n const range = selection.getRangeAt(0);\n return {\n collapsed: range.collapsed,\n startContainer: range.startContainer,\n startOffset: range.startOffset,\n endContainer: range.endContainer,\n endOffset: range.endOffset,\n };\n}\n\n/** Describe replacing the complete document from its previous text. */\nfunction createFullDocumentChange(\n previousContents: string,\n contents: string\n): EditorChange {\n const lineOffsets = computeLineOffsets(previousContents);\n const lastLineOffset = lineOffsets[lineOffsets.length - 1] ?? 0;\n return {\n start: 0,\n end: previousContents.length,\n text: contents,\n range: {\n start: { line: 0, character: 0 },\n end: {\n line: lineOffsets.length - 1,\n character: previousContents.length - lastLineOffset,\n },\n },\n };\n}\n\ninterface EditorAttachState {\n generation: number;\n callback: (() => void) | undefined;\n delivered: boolean;\n}\n\ninterface AltColumnDrag {\n pointerId: number;\n startClientX: number;\n clientX: number;\n startScrollLeft: number;\n focusLine?: number;\n renderedGoal?: Position;\n}\n\ninterface TrackedCaret<T> {\n caret: EditorCaret<T>;\n anchorOffset: number;\n focusOffset: number;\n}\n\ninterface SyncRenderViewBaseProps {\n highlighter: DiffsHighlighter;\n fileContainer: HTMLElement;\n renderRange: RenderRange | undefined;\n /** Start fresh history instead of retaining or extending the current history. */\n resetHistory?: boolean;\n}\n\ninterface SyncFileRenderViewProps<LAnnotation> extends SyncRenderViewBaseProps {\n file: FileContents;\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined;\n /** Treat the supplied contents as an externally provided document update. */\n externalDocument?: boolean;\n}\n\ninterface SyncDiffRenderViewProps<LAnnotation> extends SyncRenderViewBaseProps {\n fileDiff: FileDiffMetadata;\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined;\n /** Treat the supplied contents as an externally provided document update. */\n externalDocument?: boolean;\n}\n\ntype SyncRenderViewProps<\n EType extends EditorType,\n LAnnotation,\n> = EType extends 'file'\n ? SyncFileRenderViewProps<LAnnotation>\n : SyncDiffRenderViewProps<LAnnotation>;\n\ntype EditorComponent<\n EType extends EditorType,\n LAnnotation,\n Caret,\n> = EType extends 'file'\n ? File<LAnnotation, Caret>\n : FileDiff<LAnnotation, Caret>;\n\ntype EditorVirtualizedComponent<LAnnotation, Caret> =\n | VirtualizedFile<LAnnotation, Caret>\n | VirtualizedFileDiff<LAnnotation, Caret>;\n\n// Narrow an editor host through the virtualized components' runtime marker\n// without importing either component class as a runtime dependency.\nfunction isVirtualizedEditorComponent<LAnnotation, Caret>(\n instance: EditorComponent<EditorType, LAnnotation, Caret> | undefined\n): instance is EditorVirtualizedComponent<LAnnotation, Caret> {\n return (\n instance != null &&\n 'renderType' in instance &&\n instance.renderType === 'virtualized'\n );\n}\n\nexport interface EditorOptions<EType extends EditorType, LAnnotation, Caret> {\n /** The maximum number of entries to keep in the undo stack. */\n historyMaxEntries?: number;\n /**\n * Retain and restore the attached component's vertical viewport position.\n * Defaults to false because scroll views generally contain multiple items.\n * This option is captured when the editor is constructed.\n */\n ownsVerticalViewport?: boolean;\n /**\n * Document and editor state transferred to the first attachment. Missing\n * fields are initialized from the attached component. The editor takes\n * ownership and does not clone supplied objects.\n */\n initialState?: EditorInitialState<EType, LAnnotation>;\n /** Custom keymap groups checked before defaults; later groups take precedence. */\n keymap?: EditorKeymap;\n /** Render rounded corners for selection ranges, default is true. */\n roundedSelection?: boolean;\n /** Highlight matching brackets near the caret, default is true. */\n matchBrackets?: boolean;\n /**\n * Controls auto-surround when typing quotes or brackets over a selection.\n * Default is `\"default\"` (both quotes and brackets).\n */\n autoSurround?: AutoSurround;\n /** Per-language comment tokens used by the comment commands. */\n languageCommentConfig?: LanguageConfigMap;\n /**\n * Show a floating selection action popover after a user-created selection.\n * Defaults to disabled. Programmatic selection updates do not open it.\n */\n enabledSelectionAction?: boolean;\n /**\n * Configuration for inline edit prediction.\n */\n editPrediction?: {\n /**\n * The edit prediction mode.\n * - 'eager': predictions appear inline when the user types.\n * - 'subtle': pressing the `Alt` key toggles predictions inline.\n * @default 'eager'\n */\n mode?: 'eager' | 'subtle';\n /**\n * The edit prediction provider.\n */\n provider: EditPredictProvider;\n /**\n * Glob or regular-expression patterns for files to include in prediction.\n * String patterns support `?`, segment-local `*`, and cross-segment `**`.\n * An empty array matches no files.\n */\n include?: readonly (string | RegExp)[];\n /**\n * Glob or regular-expression patterns for files to exclude from prediction.\n * String patterns support `?`, segment-local `*`, and cross-segment `**`.\n * Exclusions take precedence over inclusions.\n */\n exclude?: readonly (string | RegExp)[];\n };\n /**\n * Custom clipboard provider.\n * Highly recommended to use native clipboard API if you are building an electron app.\n * see https://www.electronjs.org/docs/latest/api/clipboard\n */\n clipboard?: {\n readText: (type?: string) => Promise<string> | string;\n };\n /** Render the selection action widget element. */\n renderSelectionAction?: (\n context: SelectionActionContext<EType, LAnnotation>\n ) => HTMLElement;\n /**\n * Render an externally owned caret at its normalized document position.\n */\n renderCaret?: (caret: EditorCaret<Caret>) => HTMLElement;\n /** Callback when the editor is attached to a file. */\n onAttach?: (\n editor: Editor<EType, LAnnotation, Caret>,\n fileInstance: EditorComponent<EType, LAnnotation, Caret>\n ) => void;\n /**\n * Called with an `EditorChangeEvent` whenever the editor document changes.\n * Treat this as a document notification; do not feed the changes back into\n * the editor or you will create loops.\n */\n onChange?: (event: EditorChangeEvent<EType, LAnnotation, Caret>) => void;\n /**\n * Observes completion with the same frozen event sent to the component. Runs\n * before the component callback, including when the component callback is\n * missing. There is no way to accept or reject from this API.\n */\n onComplete?: (\n event: EditorEditCompleteEvent<EType, LAnnotation, Caret>\n ) => void;\n /** Callback when the editor gains focus. */\n onFocus?: () => void;\n /** Callback when the editor loses focus. */\n onBlur?: () => void;\n // debug flag\n __debug?: boolean;\n}\n\nexport interface EditorFocusOptions extends FocusOptions {\n /** One-based document line number or first editable line with a visible top. */\n lineNumber?: number | 'first-visible';\n /** Zero-based character offset for a numeric line. Defaults to 0. */\n character?: number;\n /** Non-negative CSS pixels below the viewport or sticky header. */\n offset?: number;\n}\n\n// Cap on how far an edit may widen the virtualized render window, as a multiple\n// of the bounded window the virtualizer last synced (~viewport + 2*hunkLineCount).\n// Edits within this many lines of the window bottom widen so their caret renders;\n// larger inserts fall back to the bounded buffer-only path instead of building a\n// row per inserted line. A safety bound, not a correctness-critical value.\nconst MAX_EDIT_WIDEN_WINDOW_MULTIPLE = 2;\n\n// Wrap offsets persist across render-range syncs (see #resetCache), so\n// scrolling through a very large file could otherwise accumulate an entry per\n// line. Past this many lines the cache resets and refills lazily for whatever\n// is measured next. A memory bound, not a correctness-critical value.\nconst MAX_WRAP_OFFSETS_CACHE_LINES = 10_000;\nconst EDIT_PREDICTION_DEBOUNCE_MS = 300;\nconst MAX_EDIT_PREDICTION_RESPONSE_EDITS = 256;\nconst MAX_EDIT_PREDICTION_RESPONSE_BYTES = 128 * 1024;\nconst editPredictionTextEncoder = new TextEncoder();\nconst SELECTION_ACTION_POPOVER_PLACEMENT_KEY = 'selection-action';\nconst MULTI_SELECTION_CLIPBOARD_TYPE =\n 'application/vnd.pierre.diffs-selections+json';\ntype OverlayRangeType =\n | 'selection'\n | 'match'\n | 'marker'\n | 'bracketMatch'\n | 'caretHighlight'\n | 'editPredictionDeletion'\n | 'editPredictionInsertion'\n | 'editPredictionReplacement';\n\n// Response edits that touch the same source lines are previewed by one ghost\n// overlay. `edit` is their combined text range; `startIndex` and `endIndex`\n// are the response edits it covers.\ninterface EditPredictionGroup {\n edit: TextEdit;\n startIndex: number;\n endIndex: number;\n}\n\n// A rendered column's content element and its gutter counterpart, or one\n// content child and the gutter child at the same index. Every rendered column\n// has a gutter, and gutter and content children are kept parallel.\ninterface ColumnElements {\n content: HTMLElement;\n gutter: HTMLElement;\n}\n\nexport class Editor<\n EType extends EditorType = EditorType,\n LAnnotation = undefined,\n Caret = undefined,\n> {\n #options: EditorOptions<EType, LAnnotation, Caret>;\n #initialState: EditorInitialState<EType, LAnnotation> | undefined;\n #editSession?: ManagedEditSession<EType, LAnnotation>;\n #metrics = new Metrics();\n #tokenizer?: EditorTokenizer;\n #popoverManager?: PopoverManager;\n // event disposes\n #editorEventDisposes?: (() => void)[];\n #globalEventDisposes?: (() => void)[];\n #selectEventDisposes?: (() => void)[];\n #detach?: () => void;\n // onAttach is deferred until the synchronized document and DOM are usable.\n // Track the state so cleanup cannot notify an editor from an ended session.\n #attachState: EditorAttachState = {\n generation: 0,\n callback: undefined,\n delivered: false,\n };\n\n // cache\n #contentOffset?: { left: number; top: number };\n #gutterWidthCache?: number;\n #contentWidthCache?: number;\n #lineYCache = new Map<number, number>();\n #wrapLineOffsetsCache = new Map<number, Uint32Array>();\n #lineElementsCache = new Map<number, HTMLElement | null>();\n #lastAccessedCharX?: [\n line: number,\n character: number,\n x: number,\n wrapLine: number,\n ];\n\n // dom\n #globalStyleElement?: HTMLStyleElement;\n #editorStyleElement?: HTMLStyleElement;\n #themeStyleElement?: HTMLStyleElement;\n #spriteElement?: SVGSVGElement;\n #fileContainer?: HTMLElement;\n #gutterElement?: HTMLElement;\n #contentElement?: HTMLElement;\n #deletionsColumn?: ColumnElements;\n #overlayElement?: HTMLElement;\n #overlayElements?: Map<string, HTMLElement>;\n #caretElements?: Map<TrackedCaret<Caret>, HTMLElement>;\n #caretHighlightElements?: HTMLElement[];\n #primaryCaretElement?: HTMLElement;\n #resizeObserver?: ResizeObserver;\n\n // state\n #fileInstance?: EditorComponent<EType, LAnnotation, Caret>;\n // Preserves the current file/diff instance's applyDocumentChange\n // type/semantics to avoid annoying `as X` narrowing\n #applyDocumentChange?: (\n textDocument: TextDocument<EType, LAnnotation>,\n newLineAnnotations: EditorLineAnnotation<EType, LAnnotation>[] | undefined,\n shouldUpdateBuffer?: boolean\n ) => void;\n #publishChange?: (\n changes: EditorChange[],\n file: FileContents,\n lineAnnotations: EditorLineAnnotation<EType, LAnnotation>[] | undefined\n ) => void;\n #isRendering = false;\n #restoreEditorStateOnSync = false;\n #lineAnnotations?: EditorLineAnnotation<EType, LAnnotation>[];\n readonly #editStateKey?: string;\n readonly #ownsVerticalViewport: boolean;\n #renderRange?: RenderRange;\n // Bounded render-window size (~viewport + 2*hunkLineCount) from the last view\n // sync. Used to cap how far #applyChange widens the window for an edit, so a\n // large insert can't materialize an unbounded number of rows. Captured at sync\n // time so consecutive edits that grow #renderRange can't ratchet the cap up.\n // undefined until the first sync; Infinity for non-virtualized (whole-file)\n // windows, where no cap is needed.\n #viewportWindowLines?: number;\n #markerRenderer?: MarkerRenderer;\n #carets?: TrackedCaret<Caret>[];\n #searchPanel?: SearchPanelWidget;\n #selectionAction?: SelectionActionWidget;\n // Programmatic ranges stay passive until the user interacts with the editor.\n #canMountSelectionAction = true;\n #shouldIgnoreSelectionChange = false;\n // Set when the browser's native Selection is temporarily not the source of\n // truth for editor text selections. Select-all can only mirror rendered\n // lines, while diff line-selection and gutter-utility gestures can move the\n // native range without selecting editor text. Gutter gestures only enable\n // this when an editor selection exists to preserve; otherwise refocus must\n // remain free to seed a caret. The next direct content pointerdown or keydown\n // clears this, and keeping it through gutter pointerup also protects against\n // a queued selectionchange.\n #suppressNativeSelectionSync = false;\n // Whether the contenteditable holds (or is claiming) focus. Synced by\n // focus/blur listeners and set eagerly by #focus(), whose real focus() call is\n // deferred to a rAF. Lets applyEdits skip focus/scroll only on unfocused\n // editors, without regressing a same-tick setSelections-then-applyEdits flow.\n #contentHasFocus = false;\n // A render-owned request object prevents an older deferred frame from\n // consuming a newer replacement's focus intent. Once synchronized, target\n // identifies the new content so a subsequent user blur can cancel it.\n #replacementFocusRequest?: { target?: HTMLElement };\n #isComposing = false;\n #isGutterMouseDown = false;\n #isContentMouseDown = false;\n #altColumnDrag?: AltColumnDrag;\n #shiftKeyPressed = false;\n #selectionStart: EditorSelection | undefined;\n // The full text of a read-only deleted-line selection built from the gutter,\n // captured when the selection is made. Deleted lines are separate read-only\n // hosts, so window.getSelection() only spans the first line; the copy/cut\n // handlers prefer this. Empty for a direct content drag (no gutter range).\n #deletedSelectionText = '';\n #reservedSelections?: EditorSelection[];\n #initSelections?: EditorSelection[];\n #selections?: EditorSelection[];\n #matches?: MatchRange[];\n #scrollingToLine?: number;\n #scrollingToLineChar?: number;\n #scrollingToLineFixed = false;\n #scrollingToLineNoFocus = false;\n #retainSearchPanelFocus = false;\n #fontRemeasureScheduled = false;\n #themeSelectionRefreshFrame?: number;\n #editPredictionTimer?: ReturnType<typeof setTimeout>;\n #editPredictionAbortController?: AbortController;\n #editPredictionGeneration = 0;\n #editPredictionRevealed = false;\n // True when we skipped asking for a prediction because the caret sits on a\n // line that has no rendered row right now (for example a large paste pushed\n // it below the virtualized window). The next time the attached component\n // renders and that row exists, we ask again.\n #retryEditPredictionOnRender = false;\n #editPrediction?: {\n document: TextDocument<EType, LAnnotation>;\n version: number;\n cursorOffset: number;\n rendered: boolean;\n response: EditPredictResponse;\n };\n #editPredictionHistory: EditPredictionHistoryRecord[] = [];\n #editPredictionSpacers = new Map<HTMLElement, number>();\n // Ghost text rows shown below lines (zero-based line -> row count). Replaced\n // only when the contents change and never mutated, so the attached component\n // can treat the same instance as \"nothing changed\".\n #ghostTextRows: ReadonlyMap<number, number> = new Map();\n #onDeferTokenize = (\n lines: Map<number, Array<HighlightedToken>>,\n themeType: 'light' | 'dark'\n ) => {\n if (!this.#isRendering) {\n return;\n }\n this.#fileInstance?.updateRenderCache(lines, themeType);\n // update the view if the render range is updated by scrolling\n // and the deferred tokenized lines inside the render range\n if (\n this.#renderRange !== undefined &&\n this.#renderRange.totalLines !== Infinity\n ) {\n const predictionLines =\n this.#editPrediction === undefined\n ? undefined\n : new Set(\n this.#editPrediction.response.edits.map(\n (edit) => edit.range.start.line\n )\n );\n let refreshPrediction = false;\n const { startingLine, totalLines } = this.#renderRange;\n const endLine = Math.min(\n startingLine + totalLines,\n (this.#editSession ?? this.#initialState)?.document?.lineCount ?? 0\n );\n for (const [line, tokens] of lines) {\n if (line >= startingLine && line < endLine) {\n const lineElement = this.#getLineElement(line);\n if (lineElement !== undefined) {\n lineElement.replaceChildren(...renderLineTokens(tokens));\n refreshPrediction ||= predictionLines?.has(line) === true;\n }\n }\n }\n if (refreshPrediction && this.#selections !== undefined) {\n this.#updateSelections(this.#selections);\n }\n }\n };\n\n /**\n * @param type The component surface this editor can attach to.\n * @param options Configure editor behavior and lifecycle callbacks.\n * @param editStateKey Retain this editable draft and its undo/redo history\n * in memory so a later editor using the same type and key can resume them.\n */\n constructor(\n public readonly type: EType,\n options: EditorOptions<EType, LAnnotation, Caret> = {},\n editStateKey?: string\n ) {\n this.#options = options;\n this.#ownsVerticalViewport = options.ownsVerticalViewport === true;\n this.#initialState = options.initialState;\n this.#editStateKey = editStateKey;\n }\n\n // Preserve the component/editor type match while keeping caret metadata\n // opaque to components, which never read it.\n get #getTypedEditor():\n | Editor<'file', LAnnotation, Caret>\n | Editor<'file-diff', LAnnotation, Caret> {\n return this.type === 'file'\n ? (this as Editor<'file', LAnnotation, Caret>)\n : (this as Editor<'file-diff', LAnnotation, Caret>);\n }\n\n setOptions(options: EditorOptions<EType, LAnnotation, Caret>): void {\n const previousRenderCaret = this.#options.renderCaret;\n const previousEditPrediction = this.#options.editPrediction;\n this.#options = {\n ...this.#options,\n ...options,\n };\n if (previousRenderCaret !== this.#options.renderCaret) {\n this.#caretElements?.forEach((element) => element.remove());\n this.#caretElements = undefined;\n this.#renderCarets();\n }\n if (previousEditPrediction !== this.#options.editPrediction) {\n this.#cancelEditPrediction(true);\n this.#editPredictionHistory = [];\n this.#scheduleEditPrediction();\n }\n }\n\n __emitEditComplete(\n event: EditorEditCompleteEvent<EType, LAnnotation, Caret>\n ): void {\n this.#options.onComplete?.(event);\n }\n\n /** @internal */\n __getGhostTextRows(): ReadonlyMap<number, number> {\n return this.#ghostTextRows;\n }\n\n setCarets(carets: EditorCaret<Caret>[]): void {\n const textDocument = this.#editSession?.document;\n if (textDocument === undefined) return;\n this.#caretElements?.forEach((element) => element.remove());\n this.#caretElements = undefined;\n this.#caretHighlightElements?.forEach((element) => element.remove());\n this.#caretHighlightElements = undefined;\n this.#carets =\n carets.length === 0\n ? undefined\n : carets.map((caret) => {\n const anchor = textDocument.normalizePosition(caret.anchor);\n const focus = textDocument.normalizePosition(caret.focus);\n return {\n caret: {\n ...caret,\n anchor,\n focus,\n },\n anchorOffset: textDocument.offsetAt(anchor),\n focusOffset: textDocument.offsetAt(focus),\n };\n });\n this.#renderCarets();\n }\n\n // UnresolvedFile extends FileDiff for rendering, but its conflict-specific\n // document model is not supported by Editor.\n edit<T extends EditorComponent<EType, LAnnotation, Caret>>(\n fileInstance: T extends { readonly type: 'unresolved-file' } ? never : T\n ): () => void;\n edit(fileInstance: EditorComponent<EType, LAnnotation, Caret>): () => void {\n const editor = this.#getTypedEditor;\n const previousSession = this.#editSession;\n if (this.#isRendering) {\n throw new Error(\n 'Editor.edit: the editor is already rendering its component'\n );\n }\n if (this.#fileInstance != null && this.#fileInstance !== fileInstance) {\n throw new Error(\n 'Editor.edit: a recycled edit session cannot attach to a different component'\n );\n }\n const initialState = this.#initialState;\n const initialEditorState = initialState?.editor;\n const editStateKey = this.#editStateKey;\n const editSession = getEditSession({\n type: this.type,\n editStateKey,\n owner: this,\n initialState,\n previousSession,\n });\n const previousDiffSession = editSession.diffSession;\n this.#initialState = undefined;\n this.#editSession = editSession;\n this.#fileInstance = fileInstance;\n this.#isRendering = true;\n this.#restoreEditorStateOnSync = editSession.editor != null;\n try {\n this.#initialize();\n if (fileInstance.type === 'file' && editor.type === 'file') {\n editor.#applyDocumentChange =\n fileInstance.applyDocumentChange.bind(fileInstance);\n editor.#publishChange = (changes, file, lineAnnotations) => {\n const event: EditorChangeEvent<'file', LAnnotation, Caret> = {\n changes,\n file,\n editor,\n lineAnnotations,\n };\n fileInstance.__acceptEditorChange(event);\n editor.#options.onChange?.(event);\n fileInstance.emitEditChange(event);\n };\n // First edit: attach the editor to the component.\n if (this.#detach == null) {\n this.#detach = fileInstance.__attachEditor(editor);\n }\n // Otherwise we resume our edit session\n else {\n fileInstance.__resumeEditor(editor);\n }\n } else if (\n fileInstance.type === 'file-diff' &&\n editor.type === 'file-diff'\n ) {\n editor.#applyDocumentChange =\n fileInstance.applyDocumentChange.bind(fileInstance);\n editor.#publishChange = (changes, file, lineAnnotations) => {\n const event: EditorChangeEvent<'file-diff', LAnnotation, Caret> = {\n changes,\n file,\n editor,\n lineAnnotations,\n };\n fileInstance.__acceptEditorChange(event);\n editor.#options.onChange?.(event);\n fileInstance.emitEditChange(event);\n };\n // First edit: attach the editor to the component.\n if (this.#detach == null) {\n this.#detach = fileInstance.__attachEditor(editor);\n }\n // Otherwise we resume our edit session\n else {\n fileInstance.__resumeEditor(editor);\n }\n } else {\n throw new Error('Editor.edit: Impossible edit state');\n }\n } catch (error: unknown) {\n this.cleanUp('recycle');\n // A failed attachment never replaced the claimed session. Restore diff\n // state that cleanup could not recapture before returning its key.\n if (editSession.type === 'file-diff' && editSession.diffSession == null) {\n editSession.diffSession = previousDiffSession;\n }\n // If we haven't ever attached, and failed to edit, release any edit\n // state lock\n if (this.#detach == null && editStateKey != null) {\n if (editor.type === 'file') {\n EditStateManager.releaseFile(editStateKey, editor);\n } else {\n EditStateManager.releaseFileDiff(editStateKey, editor);\n }\n }\n this.#editSession = previousSession;\n if (this.#detach == null) {\n this.#fileInstance = undefined;\n this.#applyDocumentChange = undefined;\n this.#publishChange = undefined;\n }\n if (initialState != null && initialEditorState != null) {\n initialState.editor = initialEditorState;\n }\n this.#initialState = initialState;\n throw error;\n }\n return () => {\n this.cleanUp('complete');\n };\n }\n\n /**\n * Apply edits to current attached file. Every edit joins the undo timeline:\n * a programmatic edit must leave the document and its history exactly as\n * the same edit typed by the user would (history equivalence — see\n * TextDocument.applyResolvedEdits), so it is undoable like any other edit.\n *\n * @param updateHistory Whether to record caller selection snapshots for\n * exact undo/redo restoration. Defaults to true. When false, live selections\n * are remapped during replay and the text edit still joins the undo timeline.\n */\n applyEdits(edits: TextEdit[], updateHistory = true): void {\n const textDocument = this.#editSession?.document;\n if (textDocument == null) {\n throw new Error('Editor.applyEdits: Editor is not attached');\n }\n // Only reposition focus and scroll when the editor already holds focus. A\n // programmatic edit must not pull focus from another input the user is\n // typing in; the selection state below is re-anchored either way.\n const wasFocused = this.#contentHasFocus;\n // Capture the current selection edges and the edit ranges as pre-edit\n // offsets so the caret can be re-anchored once the buffer changes. Reading\n // them after applyEdits would resolve against the new buffer and desync.\n const selectionsBefore = this.#selections;\n const selectionOffsetsBefore = selectionsBefore?.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as [number, number]\n );\n // Resolve edits to pre-edit offsets, mirroring TextDocument's own\n // resolution (swap reversed ranges, sort ascending), so the remap matches\n // the edits TextDocument actually applies below.\n const resolvedEditOffsets =\n selectionsBefore === undefined\n ? undefined\n : textDocument.resolveEdits(edits).sort((a, b) => a.start - b.start);\n\n const change = textDocument.applyEdits(\n edits,\n updateHistory,\n selectionsBefore\n );\n if (change === undefined) {\n return;\n }\n\n // Re-anchor selections against the applied edits so the editor #selections,\n // the native window selection, and the on-screen caret stay in sync with\n // the new buffer. Skipping this leaves a programmatic edit (e.g. an AI or\n // codemod insertion) with a stale caret and corrupts the next keystroke.\n let nextSelections: EditorSelection[] | undefined;\n if (\n selectionsBefore !== undefined &&\n selectionOffsetsBefore !== undefined &&\n resolvedEditOffsets !== undefined\n ) {\n nextSelections = remapSelectionsAfterEdits(\n textDocument,\n selectionsBefore,\n selectionOffsetsBefore,\n resolvedEditOffsets\n );\n if (updateHistory) {\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n }\n }\n\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change),\n { skipFocus: !wasFocused }\n );\n }\n\n /** Whether there is an edit to undo. */\n get canUndo(): boolean {\n return (\n (this.#editSession ?? this.#initialState)?.document?.canUndo ?? false\n );\n }\n\n /** Whether there is an undone edit to redo. */\n get canRedo(): boolean {\n return (\n (this.#editSession ?? this.#initialState)?.document?.canRedo ?? false\n );\n }\n\n /** Undo the last edit. Does nothing when there is nothing to undo. */\n undo(): void {\n this.#runCommand('undo');\n }\n\n /** Redo the last undone edit. Does nothing when there is nothing to redo. */\n redo(): void {\n this.#runCommand('redo');\n }\n\n getFile(): FileContents | undefined {\n const editSession = this.#editSession ?? this.#initialState;\n const fileInfo = editSession?.fileInfo;\n const textDocument = editSession?.document;\n if (fileInfo === undefined || textDocument === undefined) {\n return undefined;\n }\n const file = { ...fileInfo }; // copy\n Object.defineProperty(file, 'contents', {\n enumerable: true,\n get: () => textDocument.getText(),\n });\n return file as FileContents;\n }\n\n getText(): string {\n return (this.#editSession ?? this.#initialState)?.document?.getText() ?? '';\n }\n\n /** Return an isolated copy of selections and restorable view state. */\n getViewState(): EditorViewState {\n const fileInstance = this.#isRendering ? this.#fileInstance : undefined;\n if (!this.#isRendering && this.#editSession?.editor != null) {\n return cloneEditorViewState(this.#editSession.editor);\n }\n const selections = this.#selections?.map((selection) => ({\n ...selection,\n start: { ...selection.start },\n end: { ...selection.end },\n }));\n if (fileInstance == null) {\n return { selections };\n }\n\n const viewport = this.#getOwnedVerticalViewport();\n const scrollLeft = fileInstance.getCodeScrollLeft();\n if (viewport == null) {\n return { selections, view: { scrollLeft } };\n }\n return {\n selections,\n view: { scrollLeft, scrollTop: viewport.scrollTop },\n };\n }\n\n /**\n * Return the objects that make up the active edit session, or undefined when\n * no complete session exists.\n */\n getEditState(): EditState<EType, LAnnotation> | undefined {\n const editSession = this.#editSession;\n if (editSession == null) {\n return undefined;\n }\n const fileInstance = this.#fileInstance;\n if (fileInstance == null) {\n throw new Error(\n `Editor.getEditState: active ${this.type} session has no component`\n );\n }\n return toManagedEditState<EType, LAnnotation>(editSession);\n }\n\n setViewState({ selections, view }: EditorViewState): void {\n if (\n !this.#isRendering ||\n this.#fileInstance === undefined ||\n this.#editSession?.document === undefined\n ) {\n throw new Error('Editor.setViewState: Editor is not attached');\n }\n this.#canMountSelectionAction = false;\n this.#updateSelections(selections ?? []);\n // When a saved view is present, honor its scroll offsets exactly. Scrolling\n // the caret into view afterward would overwrite them whenever the caret\n // sits outside that viewport (e.g. TreeApp remount restore).\n if (view != null) {\n this.#fileInstance.setCodeScrollLeft(view.scrollLeft);\n // States without scrollTop leave the viewport where it is rather than\n // guessing.\n const viewport = this.#getOwnedVerticalViewport();\n if (view.scrollTop !== undefined && viewport != null) {\n viewport.scrollTop = view.scrollTop;\n }\n } else if (this.#ownsVerticalViewport) {\n this.#scrollToPrimaryCaret();\n }\n this.#checkpointEditSessionState();\n }\n\n setSelections(\n selections: (Range & { direction: 'none' | 'backward' | 'forward' })[]\n ): void {\n const textDocument = this.#editSession?.document;\n if (textDocument === undefined) {\n throw new Error('Editor.setSelections: Text document is not initialized');\n }\n const resolvedSelections = selections.map<EditorSelection>((selection) => {\n let start = textDocument.normalizePosition(selection.start);\n let end = textDocument.normalizePosition(selection.end);\n let direction: EditorSelection['direction'] =\n selection.direction === 'none'\n ? DirectionNone\n : selection.direction === 'backward'\n ? DirectionBackward\n : DirectionForward;\n\n if (comparePosition(start, end) > 0) {\n [start, end] = [end, start];\n if (direction !== DirectionNone) {\n direction =\n direction === DirectionForward\n ? DirectionBackward\n : DirectionForward;\n }\n }\n return { direction, start, end };\n });\n this.#canMountSelectionAction = false;\n this.#updateSelections(resolvedSelections);\n const primarySelection = resolvedSelections.at(-1);\n if (primarySelection !== undefined) {\n this.#revealLineIfCollapsed(getCaretPosition(primarySelection).line);\n }\n this.#scrollToPrimaryCaret();\n }\n\n setMarkers(markers: Marker[]): void {\n const textDocument = this.#editSession?.document;\n if (textDocument === undefined) {\n throw new Error('Editor.setMarkers: Text document is not initialized');\n }\n\n if (markers.length === 0) {\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#markerRenderer ??= new MarkerRenderer({\n popoverManager: this.#getPopoverManager(),\n getLineHeight: () => this.#metrics.lineHeight,\n getOverlayElement: () => this.#overlayElement,\n getGutterWidth: () => this.#getGutterWidth(),\n getCharX: (line, character) => this.#getCharX(line, character),\n getLineY: (line) => this.#getLineY(line),\n isMouseDown: () => this.#isContentMouseDown || this.#isGutterMouseDown,\n });\n this.#markerRenderer.setMarkers(markers, textDocument);\n if (this.#contentElement !== undefined) {\n this.#markerRenderer.listenHover(this.#contentElement);\n }\n this.#updateSelections(this.#selections ?? []);\n this.#renderCarets();\n }\n\n focus(options?: EditorFocusOptions): void {\n const preventScroll = options?.preventScroll ?? false;\n const lineNumber = options?.lineNumber;\n if (lineNumber === 'first-visible' || typeof lineNumber === 'number') {\n const textDocument = this.#editSession?.document;\n if (\n textDocument == null ||\n !this.#isRendering ||\n this.#fileInstance == null\n ) {\n return;\n }\n const targetLineNumber =\n lineNumber === 'first-visible'\n ? this.#getFirstVisibleLineNumber(options?.offset)\n : lineNumber;\n if (targetLineNumber == null) {\n return;\n }\n const position = textDocument.normalizePosition({\n line: targetLineNumber - 1,\n character:\n lineNumber === 'first-visible' ? 0 : (options?.character ?? 0),\n });\n this.#focusAtPosition(position, preventScroll);\n return;\n }\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n this.#focus(pos, preventScroll);\n } else {\n this.#focus(undefined, preventScroll);\n }\n }\n\n blur(): void {\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#shouldIgnoreSelectionChange = false;\n this.#contentElement?.blur();\n }\n\n // 'discard' ends the session and lets the component publish its completion\n // event without installing the result.\n //\n // 'recycle' suspends rendering for collapse or virtualization. The component\n // association, document, history, and editor state remain fixed so the same\n // surface resumes on the next edit().\n //\n // 'complete' ends the session and lets the component install an accepted\n // completion result. Keyed documents outlive all three teardown modes until\n // explicitly disposed or evicted from the manager.\n cleanUp(reason: 'discard' | 'recycle' | 'complete' = 'discard'): void {\n const fileInstance = this.#fileInstance;\n const recycle = reason === 'recycle';\n this.#cancelEditPrediction(true, false);\n if (!recycle) {\n this.#editPredictionHistory = [];\n }\n const editSession = this.#editSession;\n if (fileInstance != null && editSession != null) {\n const discardDiffState = !this.#checkpointEditSessionState();\n if (!recycle) {\n this.#releaseEditSession(discardDiffState);\n }\n }\n this.#invalidateOnAttach();\n if (!recycle) {\n this.#attachState.delivered = false;\n }\n this.#isRendering = false;\n dequeueRender(this.#handleCustomPasteEvent);\n // The tokenizer is destroyed in both modes: it holds highlighter/worker\n // resources and writes into the (removed below) theme style element.\n // __syncRenderView recreates one for a retained document on render resume.\n this.#tokenizer?.cleanUp();\n this.#tokenizer = undefined;\n\n // dispse event listeners\n this.#globalEventDisposes?.forEach((dispose) => dispose());\n this.#globalEventDisposes = undefined;\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = undefined;\n if (!recycle) {\n this.#detach?.();\n this.#detach = undefined;\n }\n\n // cache\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n this.#lineElementsCache.clear();\n this.#lastAccessedCharX = undefined;\n\n // clean up dom elements\n this.#globalStyleElement?.remove();\n this.#globalStyleElement = undefined;\n this.#editorStyleElement?.remove();\n this.#editorStyleElement = undefined;\n this.#themeStyleElement?.remove();\n this.#themeStyleElement = undefined;\n this.#spriteElement?.remove();\n this.#spriteElement = undefined;\n this.#fileContainer = undefined;\n this.#popoverManager?.cleanUp();\n this.#popoverManager = undefined;\n this.#gutterElement = undefined;\n this.#deletionsColumn = undefined;\n this.#contentElement?.removeAttribute('contentEditable');\n this.#contentElement = undefined;\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#overlayElement?.remove();\n this.#overlayElement = undefined;\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n // Let a reused instance schedule the font re-measure again on its next\n // mount, where a different font-family string may not be loaded yet.\n this.#fontRemeasureScheduled = false;\n if (this.#themeSelectionRefreshFrame !== undefined) {\n cancelAnimationFrame(this.#themeSelectionRefreshFrame);\n this.#themeSelectionRefreshFrame = undefined;\n }\n\n this.#resetState(recycle);\n if (!recycle) {\n try {\n if (fileInstance != null && editSession != null) {\n const editor = this.#getTypedEditor;\n const mode = reason === 'complete' ? 'install' : 'discard';\n if (fileInstance.type === 'file' && editor.type === 'file') {\n fileInstance.__completeEditSession(editor, mode);\n } else if (\n fileInstance.type === 'file-diff' &&\n editor.type === 'file-diff'\n ) {\n fileInstance.__completeEditSession(editor, mode);\n } else {\n throw new Error('Editor.cleanUp: Impossible edit state');\n }\n }\n } finally {\n this.#editSession = undefined;\n this.#fileInstance = undefined;\n this.#applyDocumentChange = undefined;\n this.#publishChange = undefined;\n }\n }\n }\n\n // Checkpoint editor and diff-component state after synchronization, edits,\n // and teardown. Returns whether a keyed diff is worth retaining after the\n // session ends.\n #checkpointEditSessionState(): boolean {\n const fileInstance = this.#fileInstance;\n const editSession = this.#editSession;\n if (fileInstance == null || editSession == null) {\n return false;\n }\n\n const editorState = this.#isRendering\n ? this.getViewState()\n : (editSession.editor ?? {});\n const { view } = editorState;\n const hasNonDefaultView =\n view != null && (view.scrollLeft !== 0 || (view.scrollTop ?? 0) !== 0);\n const hasEditorState = editorState.selections != null || hasNonDefaultView;\n editSession.editor = cloneEditorViewState(editorState);\n\n if (editSession.type === 'file') {\n return false;\n }\n\n const capturedDiffSession = fileInstance.__captureDocumentSessionState();\n editSession.diffSession = capturedDiffSession?.diffSession;\n if (capturedDiffSession == null) {\n return false;\n }\n\n const document = editSession.document;\n return (\n capturedDiffSession.hasChanges ||\n hasEditorState ||\n document?.canUndo === true ||\n document?.canRedo === true\n );\n }\n\n #releaseEditSession(discardDiffState = false): void {\n const editStateKey = this.#editStateKey;\n if (editStateKey == null) {\n return;\n }\n const editor = this.#getTypedEditor;\n if (editor.type === 'file') {\n EditStateManager.releaseFile(editStateKey, editor);\n } else {\n EditStateManager.releaseFileDiff(editStateKey, editor, discardDiffState);\n }\n }\n\n /** @internal */\n __postponeBgTokenizeToNextFrame(): void {\n const tokenizer = this.#tokenizer;\n if (tokenizer !== undefined) {\n tokenizer.pauseBackgroundTokenize();\n requestAnimationFrame(() => {\n tokenizer.resumeBackgroundTokenize();\n });\n }\n }\n\n /** @internal */\n __captureFocusForDOMReplacement(): void {\n const contentElement = this.#contentElement;\n const shadowActiveElement = this.#fileContainer?.shadowRoot?.activeElement;\n if (\n contentElement != null &&\n (this.#contentHasFocus ||\n shadowActiveElement === contentElement ||\n (shadowActiveElement != null &&\n contentElement.contains(shadowActiveElement)))\n ) {\n this.#replacementFocusRequest = {};\n }\n }\n\n /** @internal */\n __getDocumentContents(fallbackFile?: FileContents): FileContents | undefined {\n const fileInfo = this.#editSession?.fileInfo;\n const textDocument = this.#editSession?.document;\n if (textDocument == null) {\n return fileInfo == null || fallbackFile == null\n ? undefined\n : { ...fileInfo, contents: fallbackFile.contents };\n }\n const resolvedFileInfo = fileInfo ?? fallbackFile;\n if (resolvedFileInfo == null) {\n return undefined;\n }\n return {\n name: resolvedFileInfo.name,\n lang: resolvedFileInfo.lang,\n contents: textDocument.getText(),\n };\n }\n\n /** @internal */\n __getDocumentSessionState(): RetainedDiffSessionSnapshot | undefined {\n const snapshot = this.#editSession?.diffSession;\n return snapshot != null\n ? cloneRetainedDiffSessionSnapshot(snapshot)\n : undefined;\n }\n\n /** @internal */\n __syncRenderView(props: SyncRenderViewProps<EType, LAnnotation>): void {\n const {\n highlighter,\n fileContainer,\n renderRange,\n externalDocument = false,\n } = props;\n const renderView:\n | SyncFileRenderViewProps<LAnnotation>\n | SyncDiffRenderViewProps<LAnnotation> = props;\n let fileOrDiff: FileContents | FileDiffMetadata;\n if ('file' in renderView && this.type === 'file') {\n fileOrDiff = renderView.file;\n } else if ('fileDiff' in renderView && this.type === 'file-diff') {\n fileOrDiff = renderView.fileDiff;\n } else {\n throw new Error('Editor.__syncRenderView: Impossible render state');\n }\n const lineAnnotations = renderView.lineAnnotations as\n | EditorLineAnnotation<EType, LAnnotation>[]\n | undefined;\n const editStateKey = this.#editStateKey;\n const fileInstance = this.#fileInstance;\n const editSession = this.#editSession;\n if (!this.#isRendering || fileInstance == null || editSession == null) {\n return;\n }\n const shadowRoot = fileContainer.shadowRoot;\n if (shadowRoot == null) {\n console.error('[editor] Could not find the shadow root.');\n return;\n }\n\n let codeElement: HTMLElement | undefined;\n let gutterEl: HTMLElement | undefined;\n let contentEl: HTMLElement | undefined;\n let deletionsGutterEl: HTMLElement | undefined;\n let deletionsContentEl: HTMLElement | undefined;\n for (const el of shadowRoot.querySelectorAll<HTMLElement>('[data-code]')) {\n const isDeletions = el.dataset.deletions != null;\n if (!isDeletions) {\n codeElement = el;\n }\n for (const child of el.children) {\n if (!(child instanceof HTMLElement)) {\n continue;\n }\n const { gutter, content } = child.dataset;\n if (gutter != null) {\n if (isDeletions) {\n deletionsGutterEl = child;\n } else {\n gutterEl = child;\n }\n } else if (content != null) {\n if (isDeletions) {\n deletionsContentEl = child;\n } else {\n contentEl = child;\n }\n }\n }\n }\n if (deletionsContentEl == null) {\n this.#deletionsColumn = undefined;\n } else if (deletionsGutterEl == null) {\n throw new Error(\n 'Editor.__syncRenderView: the deletions column has no gutter'\n );\n } else {\n this.#deletionsColumn = {\n content: deletionsContentEl,\n gutter: deletionsGutterEl,\n };\n }\n if (codeElement === undefined || contentEl === undefined) {\n this.#replacementFocusRequest = undefined;\n return;\n }\n\n this.#getPopoverManager().setViewportElements(fileContainer, codeElement);\n\n // inject editor&theme style to the file container\n if (this.#fileContainer !== fileContainer) {\n this.#fileContainer = fileContainer;\n if (this.#globalStyleElement !== undefined) {\n fileContainer.appendChild(this.#globalStyleElement);\n }\n if (this.#editorStyleElement !== undefined) {\n shadowRoot.appendChild(this.#editorStyleElement);\n }\n if (this.#themeStyleElement !== undefined) {\n shadowRoot.appendChild(this.#themeStyleElement);\n }\n if (this.#spriteElement !== undefined) {\n shadowRoot.prepend(this.#spriteElement);\n }\n }\n\n const languageId =\n fileOrDiff.lang ?? getFiletypeFromFileName(fileOrDiff.name);\n const contents =\n 'contents' in fileOrDiff\n ? fileOrDiff.contents\n : fileOrDiff.additionLines.join('');\n const previousTextDocument = editSession.document;\n // The caller flags whether the host replaced the file (`externalDocument`)\n // document that should win. Undo-reset, however, is derived here from the\n // editor's own fileInfo: it resets only when name/language change or when\n // the caller passes in resetHistory\n const resetHistory =\n props.resetHistory ??\n (previousTextDocument != null &&\n editSession.fileInfo != null &&\n (editSession.fileInfo.name !== fileOrDiff.name ||\n previousTextDocument.languageId !== languageId));\n const documentChanges =\n externalDocument &&\n previousTextDocument !== undefined &&\n previousTextDocument.getText() !== contents\n ? [createFullDocumentChange(previousTextDocument.getText(), contents)]\n : undefined;\n\n const resetForExternalDocument = externalDocument && resetHistory;\n const shouldRebuildDocument =\n editSession.document == null ||\n editSession.fileInfo == null ||\n (editStateKey == null &&\n (editSession.fileInfo.name !== fileOrDiff.name ||\n editSession.document.languageId !== languageId)) ||\n resetForExternalDocument;\n if (shouldRebuildDocument) {\n this.#cancelEditPrediction(true);\n this.#editPredictionHistory = [];\n this.#invalidateOnAttach();\n const { name, lang } = fileOrDiff;\n let textDocument =\n resetForExternalDocument ||\n (editStateKey == null && editSession.fileInfo != null)\n ? undefined\n : editSession.document;\n if (previousTextDocument != null && textDocument == null) {\n editSession.editor = undefined;\n }\n if (textDocument == null) {\n const editStack = new EditStack<EType, LAnnotation>({\n maxEntries: this.#options.historyMaxEntries,\n });\n textDocument = new TextDocument<EType, LAnnotation>(\n fileOrDiff.name,\n contents,\n languageId,\n 0,\n editStack\n );\n }\n editSession.fileInfo = { name, lang };\n editSession.document = textDocument;\n if (resetForExternalDocument) {\n editSession.diffSession = undefined;\n }\n this.#tokenizer?.cleanUp();\n this.#tokenizer = undefined;\n this.#resetState();\n // Wrap offsets survive #resetCache, so a document swap on a reused\n // content element must drop the previous document's measurements here.\n this.#wrapLineOffsetsCache.clear();\n this.#selections = this.#initSelections;\n if (this.#options.__debug === true) {\n console.log(\n '[diffs/editor] text document initialized from',\n fileOrDiff.name\n );\n }\n }\n if (externalDocument && !resetForExternalDocument) {\n this.#applyExternalDocumentReplacement(\n editSession,\n contents,\n lineAnnotations\n );\n const { name, lang } = fileOrDiff;\n editSession.fileInfo = { name, lang };\n }\n\n // The tokenizer is (re)created whenever the current document lacks one:\n // right after a fresh document build above, or on the first sync after a\n // recycled surface resumes its retained document. Tying it to the document\n // (rather than the rebuild) keeps an unchanged resumed document, which\n // skips the rebuild, able to paint edits.\n const textDocument = editSession.document;\n if (this.#tokenizer == null && textDocument != null) {\n this.#tokenizer = new EditorTokenizer({\n highlighter,\n textDocument,\n codeOptions: this.#fileInstance?.__getEffectiveCodeOptions() ?? {},\n matchBrackets: this.#options.matchBrackets,\n onDeferTokenize: this.#onDeferTokenize,\n onThemeChange: () => this.#scheduleThemeSelectionRefresh(),\n setStyle: (css) => {\n this.#themeStyleElement!.textContent = css;\n },\n __debug: this.#options.__debug,\n });\n }\n\n if (this.#contentElement !== contentEl) {\n this.#gutterElement = gutterEl;\n this.#contentElement = extend(contentEl, {\n contentEditable: 'true',\n role: 'textbox',\n ariaMultiLine: 'true',\n autocapitalize: 'off',\n writingSuggestions: 'off',\n autocorrect: false,\n spellcheck: false,\n translate: false,\n });\n if (this.#overlayElement !== undefined) {\n contentEl.after(this.#overlayElement);\n }\n this.#metrics.init(contentEl);\n this.#remeasureMetricsOnFontLoad();\n this.#listenContentElement(contentEl, gutterEl);\n if (\n this.#contentElement !== undefined &&\n this.#options.__debug === true\n ) {\n console.log('[diffs/editor] full re-render triggered !!!');\n }\n }\n if (this.#replacementFocusRequest != null) {\n this.#replacementFocusRequest.target = contentEl;\n }\n\n // The contenteditable host advertises role=\"textbox\", so without an\n // accessible name screen readers announce an unlabeled text field. Label it\n // with the file name. The same content element is reused across file\n // switches (see File#applyFullRender), so refresh the label on every sync\n // rather than only when the element is first initialized above.\n if (contentEl.ariaLabel !== fileOrDiff.name) {\n contentEl.ariaLabel = fileOrDiff.name;\n }\n\n // Annotation rows, unified deleted rows, and hunk separators are\n // non-document rows living inside the contenteditable column; mark them\n // read-only so the caret can never enter them. Separators render in both\n // diff styles whenever a collapsed region exists.\n if (\n (lineAnnotations !== undefined && lineAnnotations.length > 0) ||\n this.#isDiff\n ) {\n for (const child of this.#contentElement.children) {\n const el = child as HTMLElement;\n const { lineAnnotation, lineType, separator } = el.dataset;\n if (\n lineAnnotation !== undefined ||\n separator !== undefined ||\n lineType === 'change-deletion'\n ) {\n el.setAttribute('contenteditable', 'false');\n }\n }\n }\n\n this.#resetCache();\n\n // The tokenizer is created once per attached document and reused across\n // re-renders, so a host-driven theme swap (theme picker, light/dark toggle)\n // wouldn't otherwise reach it. Re-apply the surface's current theme on every\n // sync so the editor's line-highlight/token colors track the active theme.\n this.#tokenizer?.syncTheme(\n this.#fileInstance?.__getEffectiveCodeOptions() ?? {}\n );\n\n this.#lineAnnotations = lineAnnotations;\n this.#renderRange = renderRange;\n // Remember the bounded window the virtualizer just synced so #applyChange\n // can clamp any edit-time widening against it. Refreshed on every scroll;\n // undefined/Infinity windows leave the clamp disabled.\n this.#viewportWindowLines = renderRange?.totalLines;\n this.#tokenizer?.prebuildStateStack(renderRange);\n\n const retainedEditorState = editSession.editor;\n const restoreEditorStateOnSync = this.#restoreEditorStateOnSync;\n\n try {\n this.#markerRenderer?.removePopover();\n\n // re-render the existing selections, matches, and markers\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n this.#renderCarets();\n if (this.#retryEditPredictionOnRender) {\n this.#scheduleEditPrediction();\n }\n\n if (\n this.#initSelections !== undefined &&\n this.#primaryCaretElement !== undefined\n ) {\n this.#initSelections = undefined;\n this.#scrollToPrimaryCaret(false, 'center');\n } else if (this.#scrollingToLine !== undefined) {\n this.#scrollToLine(\n this.#scrollingToLine,\n this.#scrollingToLineChar,\n this.#scrollingToLineNoFocus\n );\n } else if (this.#replacementFocusRequest !== undefined) {\n this.#restoreReplacementFocus();\n } else if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n this.#contentHasFocus &&\n !this.#retainSearchPanelFocus\n ) {\n this.focus({ preventScroll: true });\n }\n\n if (this.#retainSearchPanelFocus) {\n this.#searchPanel?.focus();\n }\n\n if (restoreEditorStateOnSync) {\n this.#restoreEditorStateOnSync = false;\n if (retainedEditorState !== undefined) {\n this.setViewState(retainedEditorState);\n }\n }\n\n if (this.#options.__debug === true && renderRange !== undefined) {\n const { startingLine, totalLines } = renderRange;\n console.log(\n '[diffs/editor] render file:',\n fileOrDiff.name,\n 'RenderRange:',\n startingLine + '-' + (startingLine + totalLines),\n 'of',\n editSession.document?.lineCount,\n 'lines'\n );\n }\n\n // A reconciled replacement is current even when its text did not change.\n // Retire it before checkpointing the new diff state or notifying observers.\n if (externalDocument) {\n fileInstance.__acknowledgeDocumentUpdate();\n }\n this.#checkpointEditSessionState();\n } catch (error) {\n this.#restoreEditorStateOnSync = restoreEditorStateOnSync;\n editSession.editor = retainedEditorState;\n throw error;\n }\n\n if (documentChanges != null) {\n this.#emitChange(documentChanges, lineAnnotations);\n }\n\n this.#scheduleOnAttach(fileInstance);\n }\n\n // The host component has already rendered these external contents. Update\n // only the editor document and history so the same replacement is not\n // applied twice. __syncRenderView emits the resulting onChange notification\n // afterward.\n #applyExternalDocumentReplacement(\n editSession: ManagedEditSession<EType, LAnnotation>,\n contents: string,\n lineAnnotations: EditorLineAnnotation<EType, LAnnotation>[] | undefined\n ): void {\n const textDocument = editSession.document;\n if (textDocument == null || textDocument.getText() === contents) {\n return;\n }\n\n const selections = this.#selections;\n const selectionOffsets = selections?.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as const\n );\n const replacement = {\n start: 0,\n end: textDocument.getText().length,\n text: contents,\n };\n const change = textDocument.applyResolvedEdits(\n [replacement],\n true,\n selections,\n undefined,\n true\n );\n if (change == null) {\n return;\n }\n\n if (selections != null && selectionOffsets != null) {\n const nextSelections = remapSelectionsAfterEdits(\n textDocument,\n selections,\n selectionOffsets,\n [replacement]\n );\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n this.#selections = nextSelections;\n }\n if (this.#lineAnnotations != null || lineAnnotations != null) {\n textDocument.setLastUndoLineAnnotations(\n this.#lineAnnotations ?? [],\n lineAnnotations ?? []\n );\n }\n\n this.#tokenizer?.cleanUp();\n this.#tokenizer = undefined;\n this.#resetCache();\n this.#wrapLineOffsetsCache.clear();\n this.#markerRenderer?.removePopover();\n if (this.#searchPanel !== undefined && this.#matches !== undefined) {\n this.#searchPanel.updateMatches({ syncSelection: false });\n }\n }\n\n get #fileDiffInstance(): FileDiff<LAnnotation, Caret> | undefined {\n return this.#fileInstance?.type === 'file-diff'\n ? this.#fileInstance\n : undefined;\n }\n\n get #virtualizedInstance():\n | EditorVirtualizedComponent<LAnnotation, Caret>\n | undefined {\n return isVirtualizedEditorComponent(this.#fileInstance)\n ? this.#fileInstance\n : undefined;\n }\n\n // Whether a zero-based document line has (or will have on scroll) a\n // rendered row. False only for lines hidden inside a collapsed unchanged\n // region of a diff host; hosts without collapsible regions treat every\n // line as renderable.\n #isLineRenderable(line: number): boolean {\n return this.#fileDiffInstance?.isLineRenderable?.(line + 1) ?? true;\n }\n\n // Fold-skip resolver for vertical caret motion (zero-based lines), or\n // undefined for hosts without collapsible regions so motion stays plain\n // line arithmetic.\n get #resolveRenderableLine(): ResolveRenderableLine | undefined {\n const fileInstance = this.#fileDiffInstance;\n if (fileInstance == null) {\n return undefined;\n }\n return (line, direction) => {\n const nearest = fileInstance.getNearestRenderableLine(\n line + 1,\n direction\n );\n return nearest == null ? undefined : nearest - 1;\n };\n }\n\n // Jump targets (search matches, undo restores, setSelections, doc-end\n // moves) may land inside a collapsed region; expand it minimally so the\n // caret's row can render before the scroll below retries toward it.\n #revealLineIfCollapsed(line: number): void {\n if (!this.#isLineRenderable(line)) {\n this.#fileDiffInstance?.revealLine?.(line + 1);\n }\n }\n\n get #diffSyle(): 'unified' | 'split' {\n return this.#fileDiffInstance?.options.diffStyle ?? 'split';\n }\n\n get #isDiff(): boolean {\n return this.type === 'file-diff';\n }\n\n get #isWrap(): boolean {\n return this.#fileInstance?.options.overflow === 'wrap';\n }\n\n #getPopoverManager(): PopoverManager {\n return (this.#popoverManager ??= new PopoverManager({\n hasActivePopover: () =>\n this.#selectionAction !== undefined ||\n this.#markerRenderer?.isPopoverVisible() === true,\n updateActivePopover: () => {\n this.#updateSelectionActionPopover();\n this.#markerRenderer?.updatePopoverPosition();\n },\n }));\n }\n\n // Drop the DOM-geometry caches (memoized row elements, measured line Ys,\n // last caret x).\n #resetCache(): void {\n this.#lineYCache.clear();\n this.#lineElementsCache.clear();\n this.#lastAccessedCharX = undefined;\n }\n\n #resetState(preserveCarets = false): void {\n this.#setEditorActiveLineSafe(null);\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#resetSelectionGesture();\n this.#suppressNativeSelectionSync = false;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements = undefined;\n this.#caretElements?.forEach((element) => element.remove());\n this.#caretElements = undefined;\n this.#caretHighlightElements?.forEach((element) => element.remove());\n this.#caretHighlightElements = undefined;\n if (!preserveCarets) {\n this.#carets = undefined;\n }\n this.#selections = undefined;\n this.#scrollingToLine = undefined;\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#searchPanel?.cleanup();\n this.#searchPanel = undefined;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n this.#canMountSelectionAction = true;\n }\n\n #invalidateOnAttach(): void {\n const attachState = this.#attachState;\n attachState.generation++;\n if (attachState.callback != null) {\n dequeueRender(attachState.callback);\n attachState.callback = undefined;\n }\n }\n\n // A recycled attachment remains the same edit session. If its first\n // notification was canceled, the next live synchronization reschedules it;\n // once delivered, later recycled mounts stay silent.\n #scheduleOnAttach(\n fileInstance: EditorComponent<EType, LAnnotation, Caret>\n ): void {\n const attachState = this.#attachState;\n const textDocument = this.#editSession?.document;\n if (\n attachState.delivered ||\n attachState.callback != null ||\n textDocument == null\n ) {\n return;\n }\n const { generation } = attachState;\n const callback = () => {\n if (attachState.callback !== callback) {\n return;\n }\n attachState.callback = undefined;\n if (\n generation !== attachState.generation ||\n this.#fileInstance !== fileInstance ||\n this.#editSession?.document !== textDocument\n ) {\n return;\n }\n const contentElement = this.#contentElement;\n const shadowRoot = this.#fileContainer?.shadowRoot;\n // A host rerender queued ahead of this callback may have replaced the\n // editable DOM while its asynchronous editor sync is still pending.\n if (\n contentElement == null ||\n shadowRoot == null ||\n !shadowRoot.contains(contentElement)\n ) {\n return;\n }\n attachState.delivered = true;\n this.#options.onAttach?.(this, fileInstance);\n };\n attachState.callback = callback;\n queueRender(callback);\n }\n\n // Get the editor's scrolling viewport, return undefined if the Virtualizer\n // is not present.`\n #getScrollViewport(): HTMLElement | Document | undefined {\n const viewport = this.#virtualizedInstance?.getEditorViewport?.();\n if (viewport != null) {\n return viewport;\n }\n const fileContainer = this.#fileContainer;\n if (this.#fileInstance == null || fileContainer == null) {\n return undefined;\n }\n return lookupScrollContainer(fileContainer);\n }\n\n #getOwnedVerticalViewport(): HTMLElement | undefined {\n if (!this.#ownsVerticalViewport) {\n return undefined;\n }\n const viewport = this.#virtualizedInstance?.getEditorViewport?.();\n if (viewport instanceof HTMLElement) {\n return viewport;\n }\n return undefined;\n }\n\n #initialize(): void {\n // Safari doesn't support `::selection` for slot elements in ShadowDOM,\n // Add a global style to disable selection for slot elements\n this.#globalStyleElement = h('style', {\n dataset: 'editorGlobalCss',\n textContent: `\n [data-annotation-slot] {\n user-select: none;\n -webkit-user-select: none;\n }\n `,\n });\n\n this.#editorStyleElement = h('style', {\n dataset: 'editorCss',\n textContent: editorCSS,\n });\n\n this.#themeStyleElement = h('style', {\n dataset: 'editorThemeCss',\n });\n\n this.#spriteElement = createSpriteElement();\n\n this.#overlayElement = h('div', {\n dataset: 'editorOverlay',\n });\n\n const replacementFocusTargetIsContent = (event: Event) => {\n const target = event.composedPath()[0];\n return (\n target instanceof Node &&\n this.#contentElement?.contains(target) === true\n );\n };\n const cancelReplacementFocus = () => {\n if (this.#replacementFocusRequest == null) {\n return;\n }\n\n // A focus or pointer target outside the editor owns the newer intent.\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#shouldIgnoreSelectionChange = false;\n };\n const finishMouseSelection = (event: PointerEvent) => {\n if (event.pointerType !== 'mouse') {\n return;\n }\n\n const refocusEditor = this.#isGutterMouseDown;\n this.#resetSelectionGesture();\n if (refocusEditor) {\n this.#focus();\n }\n\n // The popover is suppressed while the mouse is down so it doesn't\n // flicker under the cursor mid-drag. Once settled, re-run the overlay\n // pass so a ranged selection reveals it.\n if (\n this.#options.enabledSelectionAction === true &&\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n !isCollapsedSelection(this.#selections.at(-1)!)\n ) {\n this.#updateSelections(this.#selections);\n }\n };\n this.#globalEventDisposes = [\n addEventListener(\n document,\n 'focusin',\n (event) => {\n if (!replacementFocusTargetIsContent(event)) {\n cancelReplacementFocus();\n }\n },\n { passive: true }\n ),\n addEventListener(\n document,\n 'pointerdown',\n (event) => {\n if (!replacementFocusTargetIsContent(event)) {\n // Target handlers can synchronously render and arm the request.\n queueMicrotask(cancelReplacementFocus);\n }\n },\n { capture: true, passive: true }\n ),\n\n addEventListener(\n document,\n 'selectionchange',\n () => {\n const shadowRoot = this.#fileContainer?.shadowRoot;\n // Ignore selection changes while the contenteditable is unfocused. A\n // programmatic applyEdits (skipFocus) re-anchors #selections without\n // syncing the native Selection, so a DOM-driven or refocus\n // selectionchange whose range still belongs to the editor must not\n // overwrite the remapped #selections before the user returns to type.\n if (\n this.#shouldIgnoreSelectionChange ||\n this.#suppressNativeSelectionSync ||\n shadowRoot == null ||\n !this.#contentHasFocus\n ) {\n return;\n }\n\n // Native selection only tracks one range. focus() and DOM updates while\n // typing mirror the primary caret there, so selectionchange must not\n // overwrite multi-cursor editor state outside an active pointer gesture.\n if (\n this.#selections !== undefined &&\n this.#selections.length > 1 &&\n !this.#isContentMouseDown\n ) {\n return;\n }\n\n const selectionRaw = document.getSelection();\n if (selectionRaw == null) {\n return;\n }\n // Read the caret/selection through the editor's shadow root.\n // getComposedRanges is the standard, spec'd way to do this but is only\n // available in newer browsers. When it is missing (older browsers,\n // embedded WebViews, and the pinned CI Chromium), fall back to the\n // older Blink/WebKit-specific ShadowRoot.getSelection(), which still\n // reports the range inside the shadow tree. Normalize that live Range\n // to a StaticRange so it matches the getComposedRanges return shape.\n // Only bail when neither API yields a range, so a click can still seed\n // the caret rather than leaving the surface unusable.\n let composedRange: StaticRange | undefined;\n if (typeof selectionRaw.getComposedRanges === 'function') {\n composedRange = selectionRaw.getComposedRanges({\n shadowRoots: [shadowRoot],\n })?.[0];\n } else {\n composedRange = getShadowRootRange(shadowRoot);\n }\n if (\n composedRange === undefined ||\n !this.#rangeBelongsToEditor(composedRange)\n ) {\n return;\n }\n\n let selection = convertSelection(composedRange, DirectionNone);\n if (selection === undefined) {\n return;\n }\n\n // extend selection by shift + click\n if (\n this.#isContentMouseDown &&\n this.#shiftKeyPressed &&\n this.#selections !== undefined &&\n this.#selections.length > 0\n ) {\n const primarySelection = this.#selections.at(-1)!;\n this.#updateSelections([\n extendSelection(primarySelection, selection),\n ]);\n return;\n }\n\n if (this.#isContentMouseDown) {\n if (this.#selectionStart !== undefined) {\n selection = createSelectionFrom(this.#selectionStart, selection);\n } else {\n this.#selectionStart = selection;\n }\n } else if (this.#selectionStart !== undefined) {\n selection.direction = createSelectionFrom(\n this.#selectionStart,\n selection\n ).direction;\n } else if (\n this.#selections !== undefined &&\n this.#selections.length === 1\n ) {\n // getComposedRanges only reports an ordered start/end range, so a\n // selectionchange fired by a refocus (or by our own focus-handler\n // setBaseAndExtent) carries no direction and would otherwise flip a\n // backward selection to DirectionNone, jumping the caret/popover to\n // the bottom. When the bounds are unchanged, keep the prior\n // direction; a genuine change (different bounds) still resets it.\n const previous = this.#selections[0];\n if (\n comparePosition(previous.start, selection.start) === 0 &&\n comparePosition(previous.end, selection.end) === 0\n ) {\n selection.direction = previous.direction;\n }\n }\n\n if (this.#altColumnDrag !== undefined) {\n this.#altColumnDrag.focusLine = getCaretPosition(selection).line;\n if (this.#updateAltColumnSelections()) {\n return;\n }\n }\n\n if (this.#reservedSelections !== undefined) {\n this.#updateSelections([\n ...this.#reservedSelections.filter(\n (reservedSelection) =>\n !selectionIntersects(reservedSelection, selection)\n ),\n selection,\n ]);\n } else {\n this.#updateSelections([selection]);\n }\n },\n { passive: true }\n ),\n\n addEventListener(document, 'pointerup', finishMouseSelection, {\n passive: true,\n }),\n addEventListener(document, 'pointercancel', finishMouseSelection, {\n passive: true,\n }),\n\n addEventListener(\n document,\n 'keydown',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = this.#selections?.at(-1);\n } else if (\n e.key === 'Alt' &&\n !e.repeat &&\n this.#contentHasFocus &&\n this.#options.editPrediction?.mode === 'subtle'\n ) {\n this.#editPredictionRevealed = !this.#editPredictionRevealed;\n this.#updateSelections(this.#selections ?? []);\n }\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'keyup',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = undefined;\n }\n },\n { passive: true }\n ),\n ];\n }\n\n // End any in-flight text or gutter selection and release its document-level\n // listeners. Pointer completion, cancellation, and editor resets share this\n // path so none can strand gesture state.\n #resetSelectionGesture(): void {\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = undefined;\n this.#shouldIgnoreSelectionChange = false;\n this.#isGutterMouseDown = false;\n this.#isContentMouseDown = false;\n this.#altColumnDrag = undefined;\n this.#shiftKeyPressed = false;\n this.#selectionStart = undefined;\n this.#reservedSelections = undefined;\n }\n\n // Swaps in a new batch of transient \"select\" listeners — gutter drag\n // tracking or the Safari annotation-hover workaround — disposing the\n // previous batch first. Routing every reassignment through here keeps the\n // dispose-before-replace invariant in one place: a stale set (e.g. from a\n // pointerup that never fired after a canceled gesture, or a fresh\n // pointerdown before the previous interaction tore down) can never be\n // overwritten while its listeners are still attached to the document.\n #replaceSelectEventListeners(disposes: (() => void)[]): void {\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = disposes;\n }\n\n // Normal line selection owns gutter gestures when enabled, so the editor\n // must not also turn the same drag into a text selection.\n #isLineSelectionEnabled(): boolean {\n return this.#fileInstance?.options.enableLineSelection === true;\n }\n\n // Gutter gestures owned by diff interactions must not replace the editor's\n // text selections through a browser-generated selectionchange.\n #preserveEditorSelectionsForGutterGesture(): void {\n this.#suppressNativeSelectionSync = this.#selections !== undefined;\n }\n\n #listenContentElement(contentEl: HTMLElement, gutterEl?: HTMLElement): void {\n const { onFocus, onBlur } = this.#options;\n const targetIsContentElement = (e: Event) => {\n const target = e.composedPath()[0] as HTMLElement | undefined;\n return (\n target !== undefined &&\n (target === contentEl || contentEl.contains(target))\n );\n };\n\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = [\n addEventListener(\n contentEl,\n 'focus',\n () => {\n this.#contentHasFocus = true;\n onFocus?.();\n // A keyboard or direct programmatic refocus restores a stale native\n // Selection that the selectionchange handler would apply over the\n // remapped #selections (after an applyEdits inserted a line above the\n // unfocused caret). Re-assert the editor's selection so the caret\n // stays anchored. A pointer focus is left to the click, and #focus()\n // already syncs the selection during an editor-driven focus.\n if (\n !this.#isContentMouseDown &&\n !this.#shouldIgnoreSelectionChange &&\n this.#selections !== undefined &&\n this.#selections.length > 0\n ) {\n this.#setWindowSelection(this.#selections.at(-1)!);\n }\n },\n { passive: true }\n ),\n addEventListener(\n contentEl,\n 'blur',\n () => {\n if (this.#replacementFocusRequest?.target === contentEl) {\n this.#replacementFocusRequest = undefined;\n this.#shouldIgnoreSelectionChange = false;\n }\n this.#contentHasFocus = false;\n onBlur?.();\n },\n { passive: true }\n ),\n addEventListener(\n contentEl,\n 'pointerdown',\n (e) => {\n this.#canMountSelectionAction = true;\n // Any pointer press — mouse, touch, or pen — moves off the select-all\n // selection, so let selectionchange sync #selections from the new\n // native selection again. This must run before the mouse-only guard\n // below: a touch or pen tap also moves the caret, and if the flag\n // stayed set its selectionchange would be ignored and the next typed\n // character would replace the whole still-selected document.\n this.#suppressNativeSelectionSync = false;\n\n if (e.pointerType !== 'mouse') {\n return;\n }\n this.#altColumnDrag = undefined;\n\n // A click on a read-only deleted line (unified view) selects it\n // natively. Hand the selection to the deleted text and drop the\n // editor's own selection, so only one region is highlighted at a\n // time and the deleted line is not swept into an editable selection.\n if (this.#isDeletedLineTarget(e)) {\n this.#setDeletedTextSelectionActive(true);\n if (this.#selections !== undefined) {\n this.#updateSelections([]);\n }\n return;\n }\n this.#setDeletedTextSelectionActive(false);\n\n this.#markerRenderer?.removePopover();\n\n // this is a workaround for the selection rendering glitch\n // happens when selecting content in shadow DOM on Safari\n const selectEventDisposes: (() => void)[] = [];\n if (\n isSafari() &&\n this.#lineAnnotations !== undefined &&\n this.#lineAnnotations.length > 0\n ) {\n const annotationDisposes = [\n ...contentEl.querySelectorAll<HTMLElement>(\n '[data-line-annotation]'\n ),\n ]\n .map((el) => [\n addEventListener(el, 'mouseenter', () => {\n this.#shouldIgnoreSelectionChange = true;\n }),\n addEventListener(el, 'mouseleave', () => {\n this.#shouldIgnoreSelectionChange = false;\n }),\n ])\n .flat();\n selectEventDisposes.push(...annotationDisposes);\n }\n\n this.#isContentMouseDown = true;\n const isAltColumnDrag =\n e.button === 0 &&\n e.altKey &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.shiftKey;\n this.#selectionStart = undefined;\n if (isAltColumnDrag) {\n this.#altColumnDrag = {\n pointerId: e.pointerId,\n startClientX: e.clientX,\n clientX: e.clientX,\n startScrollLeft: contentEl.parentElement?.scrollLeft ?? 0,\n };\n this.#reservedSelections = undefined;\n this.#selections = undefined;\n this.#updateSelections([]);\n selectEventDisposes.push(\n addEventListener(\n document,\n 'pointermove',\n (moveEvent) => {\n const drag = this.#altColumnDrag;\n if (\n drag === undefined ||\n moveEvent.pointerType !== 'mouse' ||\n moveEvent.pointerId !== drag.pointerId\n ) {\n return;\n }\n drag.clientX = moveEvent.clientX;\n this.#updateAltColumnSelections();\n },\n { capture: true, passive: true }\n )\n );\n } else if (e.button === 0 && isPrimaryModifier(e)) {\n this.#reservedSelections = this.#selections?.map((selection) => ({\n ...selection,\n }));\n }\n this.#replaceSelectEventListeners(selectEventDisposes);\n if (e.shiftKey) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n // fix the window selection for shift mode\n this.#setWindowSelection({\n start: pos,\n end: pos,\n direction: DirectionNone,\n });\n }\n this.#shiftKeyPressed = true;\n }\n },\n { passive: true }\n ),\n\n addEventListener(contentEl, 'keydown', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#canMountSelectionAction = true;\n // A keystroke is the user acting on the select-all selection (deleting,\n // typing, moving); let selectionchange sync #selections again.\n this.#suppressNativeSelectionSync = false;\n\n // keyCode 229 opens the composition, before compositionstart fires.\n if (e.isComposing || e.keyCode === 229) {\n return;\n }\n\n if (\n e.key === 'Tab' &&\n !e.shiftKey &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.isComposing &&\n !this.#isComposing &&\n (!e.altKey || this.#options.editPrediction?.mode === 'subtle') &&\n this.#editPrediction?.rendered === true\n ) {\n // Ghost text is on screen, so Tab belongs to the prediction even when\n // acceptance fails; it must never fall through to indentation.\n this.#acceptEditPrediction();\n e.preventDefault();\n return;\n }\n\n if (e.key === 'Escape' && this.#editPrediction !== undefined) {\n this.#cancelEditPrediction(true);\n e.preventDefault();\n return;\n }\n\n const command = resolveEditorCommandFromKeyboardEvent(\n e,\n this.#options.keymap\n );\n if (command !== undefined) {\n e.preventDefault();\n if (command === 'simplifySelection') {\n this.#searchPanel?.close();\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n }\n this.#runCommand(command);\n return;\n }\n\n // handle the cursor move events manually for multiple selections and virtual viewport\n const mvShortcut = isMoveCursorShortcut(e);\n const textDocument = this.#editSession?.document;\n if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n mvShortcut !== undefined &&\n textDocument !== undefined\n ) {\n const cursorMoveOptions: CursorMoveOptions = {\n getSoftLineOffsets: this.#isWrap\n ? (line) => this.#wrapLineTextOrWholeLine(line)\n : undefined,\n resolveRenderableLine: this.#resolveRenderableLine,\n };\n if (e.shiftKey) {\n this.#updateSelections(\n mapSelectionShift(\n textDocument,\n this.#selections,\n mvShortcut,\n cursorMoveOptions\n )\n );\n } else {\n this.#updateSelections(\n mapCursorMove(\n textDocument,\n this.#selections,\n mvShortcut,\n cursorMoveOptions\n )\n );\n }\n this.#scrollToPrimaryCaret();\n e.preventDefault();\n return;\n }\n\n const normalizedKey = e.key.length === 1 ? e.key.toLowerCase() : e.key;\n if (normalizedKey === 'v' && isPrimaryModifier(e)) {\n // Holding paste can enqueue a costly full diff recompute for every\n // keyboard repeat. Accept the first paste and suppress repeats.\n if (e.repeat && this.#isDiff) {\n e.preventDefault();\n return;\n }\n\n // Handle the 'paste' event manually with the custom clipboard API.\n if (this.#options.clipboard !== undefined) {\n e.preventDefault();\n queueRender(this.#handleCustomPasteEvent);\n return;\n }\n }\n\n // Only hijack the native find-again shortcut while the panel is open\n // so cmd+g/cmd+shift+g step through matches; otherwise leave it alone.\n if (this.#searchPanel !== undefined) {\n const findAgain = resolveFindAgainShortcut(e);\n if (findAgain !== undefined) {\n e.preventDefault();\n this.#searchPanel.navigate(findAgain === 'previous');\n return;\n }\n }\n }),\n\n addEventListener(contentEl, 'copy', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // A read-only deleted-text selection lives outside the editor's\n // document, so #getSelectionText() would be empty. Copy the selected\n // deleted text instead.\n if (this.#isDeletedTextSelectionActive()) {\n e.clipboardData?.setData('text', this.#deletedTextForClipboard());\n } else {\n this.#writeSelectionClipboardData(\n e.clipboardData,\n this.#getSelectionText(),\n this.#getSelectionClipboardTexts()\n );\n }\n }),\n\n addEventListener(contentEl, 'cut', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // Deleted text is read-only and can't be removed, so a cut there copies\n // the selected deleted text (like the copy handler) without editing.\n if (this.#isDeletedTextSelectionActive()) {\n e.clipboardData?.setData('text', this.#deletedTextForClipboard());\n } else {\n const selectionTexts = this.#getSelectionClipboardTexts();\n this.#writeSelectionClipboardData(\n e.clipboardData,\n this.#cutSelectionText(),\n selectionTexts\n );\n }\n }),\n\n addEventListener(contentEl, 'paste', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n const clipboardData = e.clipboardData;\n const textDocument = this.#editSession?.document;\n if (clipboardData === null || textDocument === undefined) {\n return;\n }\n\n let text: string | string[] = clipboardData.getData('text');\n\n const selectionCount = this.#selections?.length ?? 0;\n if (selectionCount > 1) {\n const multiSelectionText = clipboardData.getData(\n MULTI_SELECTION_CLIPBOARD_TYPE\n );\n if (multiSelectionText !== undefined) {\n try {\n const selectionTexts = JSON.parse(multiSelectionText);\n if (\n Array.isArray(selectionTexts) &&\n selectionTexts.length === selectionCount\n ) {\n text = selectionTexts;\n }\n } catch {\n // ignore the invalid custom clipboard data\n }\n }\n }\n\n // Rewrite clipboard line breaks to the document's EOL so a Windows\n // clipboard (\\r\\n or \\r) doesn't leave mixed line endings behind.\n this.#replaceSelectionText(\n Array.isArray(text)\n ? text.map((t) => textDocument.normalizeEol(t))\n : textDocument.normalizeEol(text),\n undefined,\n true,\n 'document'\n );\n }),\n\n addEventListener(contentEl, 'beforeinput', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n if (e.inputType === 'insertCompositionText') {\n this.#cancelEditPrediction(true);\n return;\n }\n e.preventDefault();\n this.#handleInput(e.inputType, e.data);\n }),\n\n addEventListener(contentEl, 'drop', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // TODO(@ije): Add support of drag move selection\n }),\n\n addEventListener(\n contentEl,\n 'compositionstart',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#cancelEditPrediction(true);\n this.#isComposing = true;\n this.#shouldIgnoreSelectionChange = true;\n },\n { passive: true }\n ),\n\n addEventListener(\n contentEl,\n 'compositionend',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#shouldIgnoreSelectionChange = false;\n const wasComposing = this.#isComposing;\n this.#isComposing = false;\n // An empty compositionend during a tracked composition means the\n // candidate was canceled (e.g. Esc), so there is nothing to commit.\n if (e.data !== '' || !wasComposing) {\n this.#handleInput('insertText', e.data);\n }\n },\n { passive: true }\n ),\n ];\n\n // A selection in the read-only deletions column is painted natively (see\n // the gated ::selection rule). Starting one there reveals that selection\n // and clears the editor's own selection on the additions side, so only one\n // column shows a selection at a time. Non-diff files have no deletions\n // column.\n const deletionsCode =\n this.#fileContainer?.shadowRoot?.querySelector<HTMLElement>(\n '[data-deletions]'\n );\n if (deletionsCode != null) {\n this.#editorEventDisposes.push(\n addEventListener(\n deletionsCode,\n 'pointerdown',\n (e) => {\n const path = e.composedPath();\n if (isGutterUtilityPath(path)) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n // Clicking a deletion line's number selects the whole line's text\n // and dragging extends the selection across deletion lines (like a\n // click/drag on an addition line number); clicking its text lets\n // the browser place/extend the selection directly. Either way the\n // deleted-text marker reveals it and the editor drops its own\n // selection.\n const target = path[0];\n const gutterRow =\n target instanceof HTMLElement\n ? target.closest('[data-column-number]')\n : null;\n if (gutterRow instanceof HTMLElement) {\n if (this.#isLineSelectionEnabled()) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n if (\n this.#beginDeletionGutterSelection(\n gutterRow,\n deletionsCode,\n e.pointerType === 'mouse'\n )\n ) {\n return;\n }\n }\n this.#setDeletedTextSelectionActive(true);\n if (this.#selections !== undefined) {\n this.#updateSelections([]);\n }\n },\n { passive: true }\n )\n );\n }\n\n if (gutterEl !== undefined) {\n const resolveGutterTarget = (\n eventTarget: HTMLElement | undefined,\n includeContentLine = false\n ) => {\n let target = eventTarget;\n if (target?.dataset.lineNumberContent !== undefined) {\n target = target.parentElement ?? undefined;\n } else if (includeContentLine && target?.tagName === 'SPAN') {\n target = target.closest('[data-line]') as HTMLElement | undefined;\n }\n return target;\n };\n\n const resolveEditableLine = (target: HTMLElement | undefined) => {\n if (target === undefined) {\n return;\n }\n const lineType = target.dataset.lineType;\n const lineNumber =\n getLineNumberAttr(target) ??\n getLineNumberAttr(target, 'columnNumber');\n if (\n lineNumber === undefined ||\n lineType === undefined ||\n !isLineEditable(lineType)\n ) {\n return;\n }\n return lineNumber - 1;\n };\n\n this.#editorEventDisposes.push(\n addEventListener(\n gutterEl,\n 'pointerdown',\n (e) => {\n const path = e.composedPath();\n if (isGutterUtilityPath(path)) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n const gutterRow = resolveGutterTarget(\n path[0] as HTMLElement | undefined\n );\n if (gutterRow !== undefined && this.#isLineSelectionEnabled()) {\n this.#preserveEditorSelectionsForGutterGesture();\n return;\n }\n // Clicking a read-only deleted line's number (unified view) selects\n // that line's text natively, since the line is not in the editor's\n // document. This runs before the mouse-only gate below: a deletion\n // tap registers no drag state to strand, so it works on touch too,\n // matching the split deletions column.\n if (gutterRow?.dataset.lineType === 'change-deletion') {\n const code = gutterRow.closest('[data-code]');\n if (code != null) {\n this.#beginDeletionGutterSelection(\n gutterRow,\n code,\n e.pointerType === 'mouse'\n );\n }\n return;\n }\n\n // Editable gutter drag-selection is mouse-only: the global pointerup\n // that clears #isGutterMouseDown and disposes the mousemove listener\n // bails for non-mouse pointers, so reacting to a touch/pen tap here\n // would strand that state and leak the listener. Mirror the content\n // pointerdown guard.\n if (e.pointerType !== 'mouse') {\n return;\n }\n\n const textDocument = this.#editSession?.document;\n const lineIndex = resolveEditableLine(gutterRow);\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n this.#canMountSelectionAction = true;\n this.#markerRenderer?.removePopover();\n const selection = this.#spanLineSelection(\n lineIndex,\n lineIndex,\n textDocument\n );\n this.#isGutterMouseDown = true;\n this.#selectionStart = selection;\n this.#updateSelections([selection]);\n // Span the native selection across the clicked line and focus\n // without collapsing it. #focus(position) would drop a collapsed\n // caret at the line end, which a later selectionchange then turns\n // into a bare caret — so a single click on a line number would\n // place a cursor instead of selecting the whole line's text.\n this.#setWindowSelection(selection);\n this.#focus();\n this.#replaceSelectEventListeners([\n addEventListener(\n document,\n 'mousemove',\n (e) => {\n if (!this.#isGutterMouseDown) {\n return;\n }\n const textDocument = this.#editSession?.document;\n const lineIndex = resolveEditableLine(\n resolveGutterTarget(\n e.composedPath()[0] as HTMLElement | undefined,\n true\n )\n );\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n // A gutter drag keeps both the clicked line (the anchor) and\n // the line under the pointer fully selected. Until a drag\n // outruns its pointerdown the anchor is set; if it somehow is\n // not, the line under the pointer becomes the anchor.\n const anchorLine =\n this.#selectionStart?.start.line ?? lineIndex;\n const selection = this.#spanLineSelection(\n anchorLine,\n lineIndex,\n textDocument\n );\n this.#selectionStart ??= selection;\n this.#updateSelections([selection]);\n this.#focus(\n selection.direction === DirectionBackward\n ? selection.start\n : selection.end\n );\n },\n { passive: true }\n ),\n ]);\n },\n { passive: true }\n )\n );\n }\n\n this.#markerRenderer?.listenHover(contentEl);\n\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = new ResizeObserver(this.#handleLayoutResize);\n this.#resizeObserver.observe(contentEl);\n this.#resizeObserver.observe(contentEl.parentElement!);\n this.#computeContentOffset(contentEl);\n }\n\n #handleCustomPasteEvent = async () => {\n const clipboard = this.#options.clipboard;\n if (clipboard !== undefined) {\n let text: string | string[] = await clipboard.readText();\n const selectionCount = this.#selections?.length ?? 0;\n if (selectionCount > 1) {\n const multiSelectionText = await clipboard.readText(\n MULTI_SELECTION_CLIPBOARD_TYPE\n );\n try {\n const selectionTexts = JSON.parse(multiSelectionText);\n if (\n Array.isArray(selectionTexts) &&\n selectionTexts.length === selectionCount\n ) {\n text = selectionTexts;\n }\n } catch {\n // Invalid selection metadata falls back to the plain-text value.\n }\n }\n const textDocument = this.#editSession?.document;\n if (textDocument != null) {\n this.#replaceSelectionText(\n Array.isArray(text)\n ? text.map((t) => textDocument.normalizeEol(t))\n : textDocument.normalizeEol(text),\n undefined,\n true,\n 'document'\n );\n }\n }\n };\n\n // diff(split) treat the content element as grid item,\n // that breaks the overlay element positioning.\n // this function computes the content offset to fix\n // the overlay element position.\n #computeContentOffset(contentEl: HTMLElement) {\n if (this.#isDiff && this.#diffSyle === 'split' && this.#isWrap) {\n this.#contentOffset = {\n // #getLineY already includes the code column's block padding. Store\n // only the grid displacement beyond it so split + wrap does not add\n // the same top gap twice.\n top: contentEl.offsetTop - this.#metrics.paddingTop,\n left: contentEl.offsetLeft - this.#getGutterWidth(),\n };\n if (this.#options.__debug === true) {\n console.log('[diffs/editor] content offset:', this.#contentOffset);\n }\n }\n }\n\n // #computeContentOffset only assigns #contentOffset in a split + wrap diff and\n // never clears it, so after toggling wrap off (or switching to unified) the\n // same editor keeps a stale offset. Read it through this getter, which returns\n // the offset only while the live layout is the one that produced it, so a\n // stale value is never applied to caret, selection, or line-Y positions.\n get #activeContentOffset(): { left: number; top: number } | undefined {\n if (this.#isDiff && this.#diffSyle === 'split' && this.#isWrap) {\n return this.#contentOffset;\n }\n return undefined;\n }\n\n #runCommand(command: EditorCommand) {\n const textDocument = this.#editSession?.document;\n if (textDocument == null) {\n return;\n }\n\n switch (command) {\n case 'openSearchPanel':\n this.#openSearchPanel('find');\n break;\n\n case 'openSearchReplacePanel':\n this.#openSearchPanel('replace');\n break;\n\n case 'findNextMatch': {\n const selections = this.#selections;\n if (selections === undefined) {\n break;\n }\n const hasCollapsed = selections.some(isCollapsedSelection);\n if (hasCollapsed) {\n const expanded: EditorSelection[] = selections.map((sel) => {\n if (isCollapsedSelection(sel)) {\n return expandCollapsedSelectionToWord(textDocument, sel);\n }\n return sel;\n });\n this.#updateSelections(expanded);\n this.focus();\n } else {\n const nextMatch = findNextMatch(textDocument, selections);\n if (nextMatch !== undefined) {\n this.#updateSelections(nextMatch);\n const primaryMatch = nextMatch.at(-1);\n if (primaryMatch !== undefined) {\n this.#revealLineIfCollapsed(getCaretPosition(primaryMatch).line);\n }\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n }\n\n case 'moveLineUp':\n case 'moveLineDown':\n this.#moveSelectedLines(command === 'moveLineUp' ? -1 : 1);\n break;\n\n case 'copyLineUp':\n case 'copyLineDown':\n this.#copySelectedLines(command === 'copyLineUp' ? -1 : 1);\n break;\n\n case 'simplifySelection': {\n const selections = this.#selections;\n const primarySelection = selections?.at(-1);\n if (selections === undefined || primarySelection === undefined) {\n break;\n }\n if (selections.length > 1) {\n this.#updateSelections([primarySelection]);\n this.#focus(getCaretPosition(primarySelection));\n } else if (!isCollapsedSelection(primarySelection)) {\n const caret = getCaretPosition(primarySelection);\n this.#updateSelections([\n { start: caret, end: caret, direction: DirectionNone },\n ]);\n this.#focus(caret);\n }\n break;\n }\n\n case 'insertBlankLine':\n this.#insertBlankLine();\n break;\n\n case 'deleteHardLineForward':\n this.#deleteHardLineForward();\n break;\n\n case 'toggleComment':\n case 'toggleBlockComment': {\n const selections = this.#selections;\n if (selections === undefined) {\n break;\n }\n const { lineComment, blockComment } = resolveCommentConfig(\n textDocument.languageId,\n this.#options.languageCommentConfig\n );\n if (command === 'toggleComment' && lineComment !== null) {\n this.#applyCommandEdits(\n resolveLineCommentEdits(textDocument, selections, lineComment)\n );\n break;\n }\n const linewise = command === 'toggleComment';\n const result = resolveBlockCommentEdits(\n textDocument,\n selections,\n blockComment,\n linewise\n );\n if (result !== undefined) {\n this.#applyCommandEdits(\n result.edits,\n linewise\n ? undefined\n : (document) =>\n result.nextSelectionOffsets.map(\n ([start, end, direction]) => ({\n start: document.positionAt(start),\n end: document.positionAt(end),\n direction,\n })\n )\n );\n }\n break;\n }\n\n case 'indent':\n case 'outdent':\n case 'indentLess':\n case 'indentMore':\n if (this.#selections !== undefined) {\n const edits: TextEdit[] = [];\n const nextSelections: EditorSelection[] = [];\n // Line-based indentation is resolved per selection, so overlapping\n // line coverage must share the same leading-whitespace edit.\n const editedLines = new Set<number>();\n // Single-line indent inserts text at each caret. When several carets\n // share a line, indentation inserted by carets to their left shifts\n // them right, so record each one here and offset its resulting\n // position once every edit on the line is known. Without this, later\n // same-line carets land before their own inserted indent.\n const sameLineIndents: Array<{\n line: number;\n startCharacter: number;\n addedLength: number;\n selectionIndex: number;\n }> = [];\n for (const selection of this.#selections) {\n const startLine = selection.start.line;\n const outdent = command === 'outdent' || command === 'indentLess';\n const lineBased =\n command === 'indentLess' || command === 'indentMore';\n if (startLine !== selection.end.line || outdent || lineBased) {\n const ret = resolveIndentEdits(\n textDocument,\n selection,\n this.#metrics.tabSize,\n outdent\n );\n for (const edit of ret[0]) {\n const line = edit.range.start.line;\n if (!editedLines.has(line)) {\n editedLines.add(line);\n edits.push(edit);\n }\n }\n nextSelections.push(ret[1]);\n } else {\n const lineChar0 = textDocument.charAt({\n line: startLine,\n character: 0,\n });\n const text =\n lineChar0 === '\\t' ? '\\t' : ' '.repeat(this.#metrics.tabSize);\n edits.push({\n range: selection,\n newText: text,\n });\n sameLineIndents.push({\n line: startLine,\n startCharacter: selection.start.character,\n addedLength:\n text.length -\n (selection.end.character - selection.start.character),\n selectionIndex: nextSelections.length,\n });\n const nextPosition = {\n line: selection.start.line,\n character: selection.start.character + text.length,\n };\n nextSelections.push({\n start: nextPosition,\n end: nextPosition,\n direction: DirectionNone,\n });\n }\n }\n for (const indent of sameLineIndents) {\n let shift = 0;\n for (const other of sameLineIndents) {\n if (\n other.line === indent.line &&\n other.startCharacter < indent.startCharacter\n ) {\n shift += other.addedLength;\n }\n }\n if (shift !== 0) {\n const current = nextSelections[indent.selectionIndex];\n const position = {\n line: indent.line,\n character: current.start.character + shift,\n };\n nextSelections[indent.selectionIndex] = {\n start: position,\n end: position,\n direction: DirectionNone,\n };\n }\n }\n const change = textDocument.applyEdits(\n edits,\n true,\n this.#selections,\n nextSelections\n );\n if (change !== undefined) {\n this.#applyChange(change, nextSelections);\n }\n }\n break;\n\n case 'selectAll': {\n const fullSelection = getDocumentFullSelection(textDocument);\n this.#updateSelections([fullSelection]);\n this.focus();\n // The editor paints selections with an overlay and otherwise leaves the\n // native selection a collapsed caret. focus() above collapses it to the\n // document start, and Safari/WebKit then fires no delete beforeinput for\n // a following Backspace — nothing sits before a caret at offset 0 — so\n // select-all then delete is silently dropped. Give WebKit a non-collapsed\n // native selection so it emits the delete; Chrome already deletes via\n // #selections regardless. #setWindowSelection can only resolve lines that\n // are currently rendered, and in a virtualized diff most of the document\n // is offscreen, so anchor the native range to the editable lines on\n // screen rather than the document bounds. The native range only needs to\n // be non-collapsed — the edit uses #selections, which still spans the\n // whole document. #suppressNativeSelectionSync then stops the resulting\n // selectionchange from reading that shorter range back over #selections\n // before the delete runs.\n const renderedLineRanges = this.#getRenderedEditableLineRanges();\n const firstRenderedLine = renderedLineRanges[0]?.[0];\n const lastRenderedLine = renderedLineRanges.at(-1)?.[1];\n if (firstRenderedLine !== undefined && lastRenderedLine !== undefined) {\n this.#suppressNativeSelectionSync = true;\n this.#setWindowSelection({\n start: { line: firstRenderedLine, character: 0 },\n end: {\n line: lastRenderedLine,\n character: textDocument.getLineLength(lastRenderedLine),\n },\n direction: DirectionForward,\n });\n }\n break;\n }\n\n case 'moveCursorToDocStart':\n case 'moveCursorToDocEnd':\n {\n const atEnd = command === 'moveCursorToDocEnd';\n const boundarySelection = getDocumentBoundarySelection(\n textDocument,\n atEnd,\n this.#isDiff\n );\n this.#updateSelections([boundarySelection]);\n this.#revealLineIfCollapsed(getCaretPosition(boundarySelection).line);\n this.#scrollToPrimaryCaret();\n }\n break;\n\n case 'expandSelectionDocStart':\n case 'expandSelectionDocEnd':\n {\n const atEnd = command === 'expandSelectionDocEnd';\n const selections = this.#selections;\n if (selections !== undefined) {\n const boundarySelection = getDocumentBoundarySelection(\n textDocument,\n atEnd,\n this.#isDiff\n );\n this.#updateSelections(\n extendSelections(selections, boundarySelection)\n );\n this.#revealLineIfCollapsed(\n getCaretPosition(boundarySelection).line\n );\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n\n case 'undo':\n case 'redo':\n this.#applyHistoryChange(command);\n break;\n }\n }\n\n // Replays history and remaps live selections when the entry intentionally\n // has no stored selection metadata.\n #applyHistoryChange(command: 'undo' | 'redo'): void {\n const textDocument = this.#editSession?.document;\n if (textDocument == null) {\n return;\n }\n if (\n (command === 'undo' && !textDocument.canUndo) ||\n (command === 'redo' && !textDocument.canRedo)\n ) {\n return;\n }\n const selections = this.#selections;\n const selectionOffsets = selections?.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as const\n );\n const result =\n command === 'undo' ? textDocument.undo() : textDocument.redo();\n if (result === undefined) {\n return;\n }\n const [change, recordedSelections, lineAnnotations, selectionEdits] =\n result;\n const nextSelections =\n recordedSelections ??\n (selections !== undefined &&\n selectionOffsets !== undefined &&\n selectionEdits !== undefined\n ? remapSelectionsAfterEdits(\n textDocument,\n selections,\n selectionOffsets,\n selectionEdits\n )\n : undefined);\n const replayedLineAnnotations =\n lineAnnotations ??\n (this.#lineAnnotations != null\n ? applyDocumentChangeToLineAnnotations(change, this.#lineAnnotations)\n : undefined);\n this.#applyChange(change, nextSelections, replayedLineAnnotations);\n }\n\n /** Applies one undoable command batch and records its resulting selections. */\n #applyCommandEdits(\n edits: TextEdit[],\n resolveNextSelections?: (\n textDocument: TextDocument<EType, LAnnotation>\n ) => EditorSelection[]\n ): void {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n const remapSelections = resolveNextSelections === undefined;\n const selectionOffsets = remapSelections\n ? selections.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as const\n )\n : undefined;\n const resolvedEdits = remapSelections\n ? edits\n .map((edit) => {\n const start = textDocument.offsetAt(edit.range.start);\n const end = textDocument.offsetAt(edit.range.end);\n return {\n start: Math.min(start, end),\n end: Math.max(start, end),\n text: edit.newText,\n };\n })\n .sort((a, b) => {\n const startOrder = a.start - b.start;\n return startOrder !== 0 ? startOrder : a.end - b.end;\n })\n : undefined;\n const change = textDocument.applyEdits(\n edits,\n true,\n selections,\n undefined,\n true\n );\n if (change === undefined) {\n return;\n }\n const nextSelections = remapSelections\n ? remapSelectionsAfterEdits(\n textDocument,\n selections,\n selectionOffsets!,\n resolvedEdits!\n )\n : resolveNextSelections(textDocument);\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n\n /** Copies selected line blocks and keeps the selection in the requested copy. */\n #copySelectedLines(direction: -1 | 1): void {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n\n const blocks = getSelectedLineBlocks(selections);\n if (blocks.length === 0) {\n return;\n }\n const copiedLinesBefore: number[] = [];\n let copiedLineCount = 0;\n const edits: TextEdit[] = [];\n for (const block of blocks) {\n copiedLinesBefore.push(copiedLineCount);\n const blockLineCount = block.endLine - block.startLine + 1;\n copiedLineCount += blockLineCount;\n const text = textDocument.getText({\n start: { line: block.startLine, character: 0 },\n end: {\n line: block.endLine,\n character: textDocument.getLineLength(block.endLine),\n },\n });\n\n if (direction > 0) {\n const position = { line: block.startLine, character: 0 };\n edits.push({\n range: { start: position, end: position },\n newText: text + textDocument.eol,\n });\n } else if (block.endLine < textDocument.lineCount - 1) {\n const position = { line: block.endLine + 1, character: 0 };\n edits.push({\n range: { start: position, end: position },\n newText: text + textDocument.eol,\n });\n } else {\n const position = {\n line: block.endLine,\n character: textDocument.getLineLength(block.endLine),\n };\n edits.push({\n range: { start: position, end: position },\n newText: textDocument.eol + text,\n });\n }\n }\n\n const nextSelections = selections.map((selection) => {\n const line = selection.start.line;\n let low = 0;\n let high = blocks.length - 1;\n while (low <= high) {\n const middle = (low + high) >>> 1;\n const block = blocks[middle];\n if (line < block.startLine) {\n high = middle - 1;\n } else if (line > block.endLine) {\n low = middle + 1;\n } else {\n low = middle;\n break;\n }\n }\n const blockIndex = Math.max(0, low <= high ? low : high);\n const block = blocks[blockIndex];\n const shift =\n copiedLinesBefore[blockIndex] +\n (direction > 0 ? block.endLine - block.startLine + 1 : 0);\n return {\n start: { ...selection.start, line: selection.start.line + shift },\n end: { ...selection.end, line: selection.end.line + shift },\n direction: selection.direction,\n };\n });\n this.#applyCommandEdits(edits, () => nextSelections);\n }\n\n /** Inserts an indented blank line after each selection's final line. */\n #insertBlankLine(): void {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n\n const selectionLines = selections.map(\n (selection) => getCaretPosition(selection).line\n );\n const targetLines = Array.from(new Set(selectionLines)).sort(\n (a, b) => a - b\n );\n const targetIndex = new Map<number, number>();\n const indents = new Map<number, string>();\n const edits: TextEdit[] = [];\n for (let index = 0; index < targetLines.length; index++) {\n const line = targetLines[index];\n const lineText = textDocument.getLineText(line);\n const indent = /^\\s*/.exec(lineText)?.[0] ?? '';\n targetIndex.set(line, index);\n indents.set(line, indent);\n const position = {\n line,\n character: textDocument.getLineLength(line),\n };\n edits.push({\n range: { start: position, end: position },\n newText: textDocument.eol + indent,\n });\n }\n\n const nextSelections = selections.map<EditorSelection>((_, index) => {\n const line = selectionLines[index];\n const position = {\n line: line + 1 + targetIndex.get(line)!,\n character: indents.get(line)!.length,\n };\n return { start: position, end: position, direction: DirectionNone };\n });\n this.#applyCommandEdits(edits, () => nextSelections);\n }\n\n #moveSelectedLines(direction: -1 | 1): void {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return;\n }\n\n const blocks = getSelectedLineBlocks(selections);\n if (\n blocks.length === 0 ||\n (direction < 0 && blocks[0].startLine === 0) ||\n (direction > 0 && blocks.at(-1)!.endLine >= textDocument.lineCount - 1)\n ) {\n return;\n }\n\n const lineCount = textDocument.lineCount;\n const lineRangeEnd = (line: number): Position =>\n line < lineCount - 1\n ? { line: line + 1, character: 0 }\n : { line, character: textDocument.getLineLength(line) };\n const getLinesText = (\n lines: number[],\n appendFinalLineBreak: boolean\n ): string => {\n const text = lines\n .map((line) => textDocument.getLineText(line))\n .join(textDocument.eol);\n return appendFinalLineBreak ? text + textDocument.eol : text;\n };\n\n const edits: TextEdit[] = [];\n if (direction < 0) {\n for (const block of blocks) {\n const previousLine = block.startLine - 1;\n const blockLines: number[] = [];\n for (let line = block.startLine; line <= block.endLine; line++) {\n blockLines.push(line);\n }\n edits.push({\n range: {\n start: { line: previousLine, character: 0 },\n end: lineRangeEnd(block.endLine),\n },\n newText: getLinesText(\n [...blockLines, previousLine],\n block.endLine < lineCount - 1\n ),\n });\n }\n } else {\n for (let index = blocks.length - 1; index >= 0; index--) {\n const block = blocks[index];\n const nextLine = block.endLine + 1;\n const blockLines: number[] = [];\n for (let line = block.startLine; line <= block.endLine; line++) {\n blockLines.push(line);\n }\n edits.push({\n range: {\n start: { line: block.startLine, character: 0 },\n end: lineRangeEnd(nextLine),\n },\n newText: getLinesText(\n [nextLine, ...blockLines],\n nextLine < lineCount - 1\n ),\n });\n }\n }\n\n const lastBlock = blocks.at(-1)!;\n const lastLineLengthAfterMove =\n direction > 0 && lastBlock.endLine === lineCount - 2\n ? textDocument.getLineLength(lastBlock.endLine)\n : textDocument.getLineLength(lineCount - 1);\n const nextSelections = selections.map((selection) =>\n shiftSelectionLines(selection, direction, lineCount, (line) =>\n line === lineCount - 1\n ? lastLineLengthAfterMove\n : textDocument.getLineLength(line)\n )\n );\n const change = textDocument.applyEdits(\n edits,\n true,\n selections,\n nextSelections,\n true\n );\n if (change !== undefined) {\n this.#applyChange(change, nextSelections);\n }\n }\n\n #handleLayoutResize = () => {\n const lineAnnotations = this.#lineAnnotations?.length ?? 0;\n const prevGutterWidth = this.#gutterWidthCache;\n const prevContentWidth = this.#contentWidthCache;\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n const gutterWidthChanged = this.#getGutterWidth() !== prevGutterWidth;\n const contentWidthChanged = this.#getContentWidth() !== prevContentWidth;\n if (!gutterWidthChanged && !contentWidthChanged) {\n return;\n }\n\n this.#lineElementsCache.clear();\n this.#lastAccessedCharX = undefined;\n // A width change means the inherited font/metrics may have changed (e.g. a\n // web font finished loading) while this same content element survived, so\n // discard memoized non-ASCII text widths and let them re-measure.\n this.#metrics.clearTextWidthCache();\n if (contentWidthChanged) {\n // Wrap points depend on the content width, so cached offsets go stale\n // even while wrap is off — the mode can be toggled back on before the\n // next width change.\n this.#wrapLineOffsetsCache.clear();\n if (this.#isWrap || lineAnnotations > 0) {\n this.#lineYCache.clear();\n }\n }\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n // Virtualized row swaps can resize a blurred editor. Repaint its overlays\n // without letting that layout work reclaim DOM focus.\n if (this.#selections !== undefined && this.#contentHasFocus) {\n this.focus();\n }\n }\n this.#markerRenderer?.removePopover();\n this.#computeContentOffset(this.#contentElement!);\n // Reposition remote carets after a gutter or content-width change. Their\n // transforms and wrapped rows use the same geometry caches as selections.\n this.#renderCarets();\n };\n\n // A custom monospace web font can finish loading after the editor first\n // renders. Until then Metrics measured the '0' width against the fallback\n // font, so the gutter width and every caret/selection x-position (each\n // offset by a whole number of `ch` units) are wrong. Re-measure once fonts\n // settle and, when the width actually changed, drop the cached widths and\n // offsets and repaint the overlays so they line up with the loaded glyphs.\n // FontFaceSet is unavailable in non-browser hosts (e.g. jsdom in tests).\n #remeasureMetricsOnFontLoad(): void {\n if (this.#fontRemeasureScheduled) {\n return;\n }\n const fonts = document.fonts as FontFaceSet | undefined;\n if (fonts === undefined) {\n return;\n }\n this.#fontRemeasureScheduled = true;\n void fonts.ready.then(() => {\n if (\n this.#contentElement === undefined ||\n !this.#metrics.remeasureCharacterWidth()\n ) {\n return;\n }\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#resetCache();\n // The loaded font changes glyph widths, which moves every wrap point.\n this.#wrapLineOffsetsCache.clear();\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n this.#renderCarets();\n this.#markerRenderer?.removePopover();\n });\n }\n\n #rerender(\n change: TextDocumentChange,\n newLineAnnotations?: EditorLineAnnotation<EType, LAnnotation>[],\n renderRange = this.#renderRange,\n shouldUpdateBuffer?: boolean\n ) {\n const tokenizer = this.#tokenizer;\n const fileInstance = this.#fileInstance;\n const applyDocumentChange = this.#applyDocumentChange;\n const textDocument = this.#editSession?.document;\n const gutterEl = this.#gutterElement;\n const contentEl = this.#contentElement;\n if (\n tokenizer == null ||\n fileInstance == null ||\n applyDocumentChange == null ||\n textDocument == null ||\n contentEl == null\n ) {\n return;\n }\n\n // cancel existing background tokenizing task\n tokenizer.stopBackgroundTokenize();\n\n const t = performance.now();\n const dirtyLines = tokenizer.tokenize(\n change,\n renderRange,\n !this.#isDiff && this.#virtualizedInstance != null\n );\n const t2 = performance.now();\n\n if (dirtyLines.size > 0) {\n const children = contentEl.children;\n // Lines hidden inside a collapsed region have no row to patch, and\n // letting them reach the create branch below would append rows for\n // them; the tokenizer still received them (dirtyLines is forwarded to\n // the host untouched).\n const dirtyLineIndexes = new Set<number>();\n for (const lineIndex of dirtyLines.keys()) {\n if (this.#isLineRenderable(lineIndex)) {\n dirtyLineIndexes.add(lineIndex);\n }\n }\n\n // Update line elements that have been changed in the document. The\n // scan starts at 0 because rendered rows can be sparse (collapsed\n // regions): a dirty line's row may sit at a smaller child index than\n // its dense line-arithmetic position, and overshooting it would fall\n // through to the create branch below as a duplicate row.\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child !== undefined) {\n const lineNumber = getLineNumberAttr(child);\n const lineType = child.dataset.lineType;\n if (lineNumber === undefined || lineType === 'change-deletion') {\n continue;\n }\n const lineIndex = lineNumber - 1;\n if (dirtyLineIndexes.has(lineIndex)) {\n const tokens = dirtyLines.get(lineIndex)!;\n child.replaceChildren(...renderLineTokens(tokens));\n dirtyLineIndexes.delete(lineIndex);\n if (dirtyLineIndexes.size === 0) {\n break;\n }\n }\n }\n }\n\n // Create new line elements for the new lines — only beyond the last\n // existing rendered row: rows are appended to the column end, so any\n // earlier missing row belongs at a collapsed-region boundary and is\n // owned by the full re-render that follows a hunk-structure change.\n if (dirtyLineIndexes.size > 0) {\n let lastRenderedLineNumber = 0;\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i] as HTMLElement;\n const lineNumber = getLineNumberAttr(child);\n if (\n lineNumber !== undefined &&\n child.dataset.lineType !== 'change-deletion'\n ) {\n lastRenderedLineNumber = lineNumber;\n break;\n }\n }\n for (const lineIndex of dirtyLineIndexes) {\n if (lineIndex < lastRenderedLineNumber) {\n continue;\n }\n const tokens = dirtyLines.get(lineIndex)!;\n const lineNumber = String(lineIndex + 1);\n h(\n 'div',\n {\n dataset: {\n line: lineNumber,\n lineType: 'context',\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: renderLineTokens(tokens),\n },\n contentEl\n );\n if (gutterEl !== undefined) {\n h(\n 'div',\n {\n dataset: {\n lineType: 'context',\n columnNumber: lineNumber,\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: [\n h('span', {\n dataset: {\n lineNumberContent: '',\n },\n textContent: lineNumber,\n }),\n ],\n },\n gutterEl\n );\n }\n }\n }\n }\n\n // remove line elements that have been deleted in the document\n if (change.lineDelta < 0) {\n for (const children of [contentEl.children, gutterEl?.children ?? []]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i] as HTMLElement;\n const lineNumber =\n getLineNumberAttr(child) ??\n getLineNumberAttr(child, 'columnNumber');\n const lineType = child.dataset.lineType;\n if (lineNumber === undefined || lineType === 'change-deletion') {\n continue;\n }\n if (lineNumber - 1 < change.lineCount) {\n break;\n }\n child.remove();\n }\n }\n }\n\n const didLineCountChange = change.lineDelta !== 0;\n\n // fix grid layout\n if (didLineCountChange) {\n let gridRow = contentEl.children.length;\n for (const child of contentEl.children) {\n const { bufferSize } = (child as HTMLElement).dataset;\n if (bufferSize !== undefined) {\n gridRow += parseInt(bufferSize) - 1;\n }\n }\n contentEl.style.gridRow = 'span ' + gridRow;\n if (gutterEl !== undefined) {\n gutterEl.style.gridRow = 'span ' + gridRow;\n }\n }\n\n fileInstance.updateRenderCache(dirtyLines, tokenizer.themeType, {\n shouldRefreshDiffsView: this.#isDiff && !didLineCountChange,\n lineCountChangeInFlight: didLineCountChange,\n });\n if (didLineCountChange) {\n // Line-count change: recompute hunks from the full document and re-render.\n applyDocumentChange(textDocument, newLineAnnotations, shouldUpdateBuffer);\n }\n\n // A line-count change can remove cached rows, while a unified diff rebuilds\n // its content column on every edit. Either can detach the line elements\n // memoized for caret/selection geometry, making offsetTop read as 0 and\n // scrolling the caret to the top. Re-measure against the current rows.\n if (didLineCountChange || (this.#isDiff && this.#diffSyle === 'unified')) {\n this.#resetCache();\n }\n\n if (newLineAnnotations != null) {\n this.#lineAnnotations = newLineAnnotations;\n // A structural FileDiff edit rebuilds both columns and their paired\n // annotation rows together. Re-inserting those rows independently by\n // line number would break their visual alignment in split view.\n if (!this.#isDiff || !didLineCountChange) {\n renderLineAnnotations(\n newLineAnnotations,\n contentEl,\n gutterEl,\n fileInstance.getAnnotationSlotName\n );\n }\n }\n this.#renderCarets();\n\n if (this.#options.__debug === true) {\n console.log(\n `[diffs/editor] re-render in: ${round(performance.now() - t2)}ms,`,\n `tokenize in: ${round(t2 - t)}ms (${dirtyLines.size} dirty lines)`\n );\n }\n }\n\n // input type doc: https://developer.mozilla.org/en-US/docs/Web/API/InputEvent/inputType\n #handleInput(inputType: string, data: string | null) {\n switch (inputType) {\n case 'insertText': {\n const text = data ?? '';\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n const autoSurroundTexts =\n textDocument !== undefined && selections !== undefined\n ? getAutoSurroundReplacementTexts(\n textDocument,\n selections,\n text,\n this.#options.autoSurround\n )\n : undefined;\n this.#replaceSelectionText(autoSurroundTexts ?? text);\n break;\n }\n case 'insertCompositionText':\n break;\n case 'insertLineBreak':\n case 'insertParagraph': {\n this.#replaceSelectionText(this.#editSession?.document?.eol ?? '\\n');\n break;\n }\n case 'deleteContentBackward':\n this.#deleteSelectionText();\n break;\n case 'deleteContentForward':\n this.#deleteSelectionText(true);\n break;\n case 'deleteSoftLineBackward':\n // Safari emits deleteHardLineBackward for cmd+backspace where Chrome emits\n // deleteSoftLineBackward; treat them the same so cmd+backspace deletes to\n // the line start in both. They differ only on a wrapped line (hard goes to\n // the logical line start, soft to the visual one), and Chrome's soft\n // behavior is what we match.\n case 'deleteHardLineBackward':\n this.#deleteSoftLineBackward();\n break;\n case 'deleteWordBackward':\n this.#deleteWordBackward();\n break;\n case 'insertTranspose':\n this.#insertTranspose();\n break;\n default:\n console.warn(`[diffs] Unknown input type: ${inputType}`, data);\n break;\n }\n }\n\n #focus(\n position?: Position,\n preventScroll = true,\n shouldFocus?: () => boolean\n ) {\n // Mark focus eagerly: the positional branch defers the real focus() to a\n // rAF, so a same-tick applyEdits would otherwise see the editor as\n // unfocused and skip repositioning while this focus still lands afterward.\n this.#contentHasFocus = true;\n if (position !== undefined) {\n this.#shouldIgnoreSelectionChange = true;\n this.#setWindowSelection({\n start: position,\n end: position,\n direction: DirectionNone,\n });\n // call focus in a request animation frame to prevent conflict with\n // the `setBaseAndExtent` method\n queueRender(() => {\n // #contentHasFocus was marked eagerly above; a blur (or cleanup) in\n // the deferred gap cedes focus, and this stale frame must not pull\n // it back into the current — possibly replaced — content.\n if (shouldFocus?.() === false || !this.#contentHasFocus) {\n this.#shouldIgnoreSelectionChange = false;\n return;\n }\n this.#contentElement?.focus({ preventScroll });\n // another request animation frame since the `focus` call\n // may trigger a selectionchange event, which should be ignored\n queueRender(() => {\n this.#shouldIgnoreSelectionChange = false;\n });\n });\n } else if (shouldFocus?.() !== false) {\n this.#contentElement?.focus({ preventScroll });\n } else {\n this.#contentHasFocus = false;\n }\n }\n\n // A full host render can remove the focused contenteditable before the\n // replacement view synchronizes. Restore only after the new content is live\n // and only while focus has not moved to another real control in the gap.\n #restoreReplacementFocus(position?: Position): void {\n const request = this.#replacementFocusRequest;\n if (request == null) {\n return;\n }\n if (this.#retainSearchPanelFocus) {\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n this.#shouldIgnoreSelectionChange = false;\n return;\n }\n const contentElement = this.#contentElement;\n if (\n contentElement == null ||\n !this.#replacementFocusIsAvailable(contentElement)\n ) {\n this.#replacementFocusRequest = undefined;\n this.#contentHasFocus = false;\n return;\n }\n\n const shouldFocus = () => {\n if (this.#replacementFocusRequest !== request) {\n return false;\n }\n const shouldRestore = this.#replacementFocusIsAvailable(contentElement);\n this.#replacementFocusRequest = undefined;\n return shouldRestore;\n };\n if (position != null) {\n this.#focus(position, true, shouldFocus);\n return;\n }\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection == null) {\n this.#focus(undefined, true, shouldFocus);\n return;\n }\n const primaryPosition =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n this.#focus(primaryPosition, true, shouldFocus);\n }\n\n #replacementFocusIsAvailable(contentElement: HTMLElement): boolean {\n const fileContainer = this.#fileContainer;\n const shadowRoot = fileContainer?.shadowRoot;\n if (\n fileContainer == null ||\n shadowRoot == null ||\n this.#contentElement !== contentElement ||\n !shadowRoot.contains(contentElement)\n ) {\n return false;\n }\n const { activeElement: shadowActiveElement } = shadowRoot;\n if (\n shadowActiveElement === contentElement ||\n (shadowActiveElement != null &&\n contentElement.contains(shadowActiveElement))\n ) {\n return true;\n }\n if (shadowActiveElement != null) {\n return false;\n }\n const { ownerDocument } = fileContainer;\n const { activeElement } = ownerDocument;\n return (\n activeElement == null ||\n activeElement === ownerDocument.body ||\n activeElement === ownerDocument.documentElement ||\n activeElement === fileContainer\n );\n }\n\n #getFirstVisibleLineNumber(offset = 0): number | undefined {\n const contentElement = this.#contentElement;\n const fileContainer = this.#fileContainer;\n if (\n this.#editSession?.document == null ||\n contentElement == null ||\n fileContainer == null\n ) {\n return undefined;\n }\n\n const viewport = this.#getScrollViewport();\n if (viewport === undefined) {\n return undefined;\n }\n\n let viewportTop: number;\n let viewportBottom: number;\n if (viewport instanceof HTMLElement) {\n const viewportRect = viewport.getBoundingClientRect();\n viewportTop = viewportRect.top;\n viewportBottom = viewportRect.bottom;\n } else {\n viewportTop = 0;\n viewportBottom = viewport.defaultView?.innerHeight ?? 0;\n }\n\n const stickyHeader = fileContainer.shadowRoot?.querySelector<HTMLElement>(\n '[data-diffs-header][data-sticky]'\n );\n if (stickyHeader != null) {\n viewportTop = Math.max(\n viewportTop,\n stickyHeader.getBoundingClientRect().bottom\n );\n }\n if (Number.isFinite(offset)) {\n viewportTop += Math.max(0, offset);\n }\n if (viewportBottom <= viewportTop) {\n return undefined;\n }\n\n for (const child of contentElement.children) {\n const row = child as HTMLElement;\n const lineNumber = getLineNumberAttr(row);\n const lineType = row.dataset.lineType;\n if (lineNumber == null || lineType == null || !isLineEditable(lineType)) {\n continue;\n }\n const rowRect = row.getBoundingClientRect();\n if (rowRect.bottom <= rowRect.top) {\n continue;\n }\n if (rowRect.top >= viewportTop && rowRect.top < viewportBottom) {\n return lineNumber;\n }\n }\n return undefined;\n }\n\n #focusAtPosition(position: Position, preventScroll: boolean): void {\n const selection: EditorSelection = {\n start: position,\n end: position,\n direction: DirectionNone,\n };\n this.#canMountSelectionAction = false;\n this.#updateSelections([selection]);\n this.#revealLineIfCollapsed(position.line);\n if (preventScroll) {\n this.#focus(position, true);\n } else {\n this.#scrollToPrimaryCaret();\n }\n }\n\n // set window native selection to match the selection\n #setWindowSelection(selection: EditorSelection) {\n const winSelection = window.getSelection();\n if (winSelection === null) {\n return;\n }\n let { start, end, direction } = selection;\n if (comparePosition(start, end) > 0) {\n [start, end] = [end, start];\n }\n const startLineElement = this.#getLineElement(start.line);\n const endLineElement = this.#getLineElement(end.line);\n if (startLineElement === undefined || endLineElement === undefined) {\n return;\n }\n let [anchorNode, anchorOffset] = getSelectionAnchor(\n startLineElement,\n start.character\n );\n let [focusNode, focusOffset] = getSelectionAnchor(\n endLineElement,\n end.character\n );\n if (direction === DirectionBackward) {\n [anchorNode, anchorOffset, focusNode, focusOffset] = [\n focusNode,\n focusOffset,\n anchorNode,\n anchorOffset,\n ];\n }\n try {\n winSelection.setBaseAndExtent(\n anchorNode,\n clampDomOffset(anchorNode, anchorOffset),\n focusNode,\n clampDomOffset(focusNode, focusOffset)\n );\n } catch (err) {\n console.error('[diffs/editor] failed to update window selection:', err);\n }\n }\n\n #scrollToPrimaryCaret(\n noFocus = false,\n scrollPosition: ScrollLogicalPosition = 'nearest'\n ) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection === undefined) {\n return;\n }\n const primaryCaretElement = this.#primaryCaretElement;\n if (primaryCaretElement !== undefined) {\n primaryCaretElement.scrollIntoView({\n block: scrollPosition,\n inline: 'nearest',\n });\n if (!noFocus) {\n const position =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n if (this.#replacementFocusRequest !== undefined) {\n this.#restoreReplacementFocus(position);\n } else {\n this.#focus(position);\n }\n }\n } else {\n const pos = getCaretPosition(primarySelection);\n this.#scrollToLine(pos.line, pos.character, noFocus);\n }\n }\n\n // add scroll margin to the primary caret element to prevent\n // the caret from being hidden by the gutter (and the search panel when\n // open). The margin must only reserve viewport space above the caret —\n // never include the host's virtualized `top` offset: that is a scroll-space\n // coordinate, and folding it in makes every caret scrollIntoView treat the\n // caret as thousands of pixels tall once the host is scrolled down, which\n // mis-scrolls the caret line (e.g. pinning it to the viewport bottom).\n #getScrollMargin() {\n const top = this.#searchPanel !== undefined ? 48 : 0;\n const start = this.#getGutterWidth() + this.#metrics.ch;\n const end = this.#metrics.ch;\n return `${top}px ${end}px 0 ${start}px`;\n }\n\n #scrollToLine(line: number, char = 0, noFocus = false) {\n this.__postponeBgTokenizeToNextFrame();\n\n const virtualCaret = h('div', {\n style: {\n position: 'absolute',\n left: '0',\n width: '2px',\n height: this.#metrics.lineHeight + 'px',\n scrollMargin: this.#getScrollMargin(),\n },\n });\n if (this.#getLineElement(line) !== undefined) {\n const [left, wrapLine] = this.#getCharX(line, char);\n const lineY = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n virtualCaret.style.top = lineY + 'px';\n virtualCaret.style.left = left + 'px';\n this.#overlayElement?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n if (!noFocus) {\n const position = { line, character: char };\n if (this.#replacementFocusRequest !== undefined) {\n this.#restoreReplacementFocus(position);\n } else {\n this.#focus(position);\n }\n }\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineFixed = false;\n this.#scrollingToLineNoFocus = false;\n }\n // if the line is not rendered yet(virtualized), scroll to the modeled or approximate\n // line position to trigger the line to be rendered, then recall this function\n // to ensure the line is scrolled into view\n else {\n const modelLinePosition = this.#virtualizedInstance?.getLinePosition?.(\n line + 1\n );\n if (modelLinePosition !== undefined) {\n virtualCaret.style.top = modelLinePosition.top + 'px';\n this.#fileContainer?.shadowRoot?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n // A collapsed line reports its separator's (nonzero) geometry, so\n // parking the retry for it would re-scroll on every sync forever;\n // only renderable lines may keep the retry alive.\n if (modelLinePosition.height > 0 && this.#isLineRenderable(line)) {\n this.#scrollingToLine = line;\n this.#scrollingToLineChar = char;\n this.#scrollingToLineNoFocus = noFocus;\n } else {\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineNoFocus = false;\n }\n } else {\n let yFix = 0;\n if (\n this.#scrollingToLine === line &&\n this.#contentElement !== undefined\n ) {\n for (\n let i = this.#contentElement.childElementCount - 1;\n i >= 0;\n i--\n ) {\n const child = this.#contentElement.children[i] as HTMLElement;\n const lineType = child.dataset.lineType;\n const lineNumber = getLineNumberAttr(child);\n if (\n lineType !== undefined &&\n isLineEditable(lineType) &&\n lineNumber !== undefined\n ) {\n yFix = (line - (lineNumber - 1)) * this.#metrics.lineHeight;\n break;\n }\n }\n }\n const lineAnnotations = (this.#lineAnnotations ?? []).filter(\n (annotation) => annotation.lineNumber < line\n ).length;\n const approximateLineY =\n (lineAnnotations + line) * this.#metrics.lineHeight + yFix;\n virtualCaret.style.top = approximateLineY + 'px';\n this.#fileContainer?.shadowRoot?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n\n if (\n (this.#scrollingToLine === line &&\n (yFix === 0 || this.#scrollingToLineFixed)) ||\n !this.#isLineRenderable(line)\n ) {\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineFixed = false;\n this.#scrollingToLineNoFocus = false;\n } else {\n this.#scrollingToLine = line;\n this.#scrollingToLineChar = char;\n this.#scrollingToLineFixed = yFix !== 0;\n this.#scrollingToLineNoFocus = noFocus;\n }\n }\n }\n virtualCaret.remove();\n }\n\n // Build a selection that fully covers every line from the anchor line to the\n // focus line — from the topmost line's start to the bottommost line's end.\n // Dragging above the anchor yields a backward selection so the anchor line\n // stays selected and #focus lands on the line the gesture ended on. A single\n // line (anchor === focus) is a forward whole-line selection.\n #spanLineSelection(\n anchorLine: number,\n focusLine: number,\n textDocument: TextDocument<EType, LAnnotation>\n ): EditorSelection {\n const lineStart = (line: number): Position => ({ line, character: 0 });\n const lineEnd = (line: number): Position => ({\n line,\n character: textDocument.getLineText(line).length,\n });\n if (focusLine < anchorLine) {\n return {\n start: lineStart(focusLine),\n end: lineEnd(anchorLine),\n direction: DirectionBackward,\n };\n }\n return {\n start: lineStart(anchorLine),\n end: lineEnd(focusLine),\n direction: DirectionForward,\n };\n }\n\n // A pointer gesture targets read-only deleted text when its closest row is a\n // change-deletion. Used to route a click in unified view's deleted text to a\n // native selection instead of the editor's own.\n #isDeletedLineTarget(event: Event): boolean {\n const target = event.composedPath()[0];\n return (\n target instanceof HTMLElement &&\n target.closest('[data-line]')?.getAttribute('data-line-type') ===\n 'change-deletion'\n );\n }\n\n // Select read-only deleted text with the native selection, spanning from the\n // anchor row to the focus row (the same row for a click). Deleted lines are\n // not part of the editor's document, so they cannot be selected as editor\n // text; instead select their DOM text, reveal it via the deleted-text marker,\n // drop the editor's own selection, and highlight the deleted gutter numbers so\n // the result matches a click/drag on an addition line.\n #selectDeletedLines(\n anchorContent: HTMLElement,\n focusContent: HTMLElement,\n deletionsCode: Element\n ): void {\n const rows = [\n ...deletionsCode.querySelectorAll('[data-content] > [data-line]'),\n ];\n const anchorIndex = rows.indexOf(anchorContent);\n const focusIndex = rows.indexOf(focusContent);\n const [topContent, bottomContent] =\n focusIndex < anchorIndex\n ? [focusContent, anchorContent]\n : [anchorContent, focusContent];\n\n const winSelection = window.getSelection();\n if (winSelection !== null) {\n const range = document.createRange();\n range.setStart(topContent, 0);\n range.setEnd(bottomContent, bottomContent.childNodes.length);\n winSelection.removeAllRanges();\n winSelection.addRange(range);\n }\n\n this.#setDeletedTextSelectionActive(true);\n this.#updateSelections([]);\n\n // Highlight only the focus line's gutter number — the line where the click\n // landed or the drag ended. Route it through the editor active-line state\n // so selected lines and deleted-line focus remain independent.\n this.#setEditorActiveLineSafe(\n getLineNumberAttr(focusContent) ?? null,\n true,\n 'deletions'\n );\n\n // Record the selected deleted lines' text for the clipboard. Each deleted\n // line is its own read-only host, so window.getSelection().toString() only\n // captures the first line; the copy/cut handlers prefer this value.\n const lo = Math.min(anchorIndex, focusIndex);\n const hi = Math.max(anchorIndex, focusIndex);\n this.#deletedSelectionText =\n lo < 0\n ? ''\n : rows\n .slice(lo, hi + 1)\n .filter(\n (row) => row.getAttribute('data-line-type') === 'change-deletion'\n )\n .map((row) => row.textContent ?? '')\n .join('\\n');\n }\n\n // The content row that lines up with a gutter row: the two columns are\n // parallel, so the gutter row's index is the content row's index.\n #contentRowForGutterRow(\n gutterRow: HTMLElement,\n contentColumn: Element | null | undefined\n ): HTMLElement | undefined {\n const gutterColumn = gutterRow.parentElement;\n if (gutterColumn == null || contentColumn == null) {\n return undefined;\n }\n const index = [...gutterColumn.children].indexOf(gutterRow);\n const row = contentColumn.children[index];\n return row instanceof HTMLElement ? row : undefined;\n }\n\n // Begin a native selection of read-only deleted lines from a pointerdown on a\n // deletion line number. Selects the clicked line and, for a mouse pointer,\n // tracks a drag across the deletion gutter that extends the selection — the\n // same gesture as a click/drag on an addition line number. `code` is the\n // [data-code] holding the deletion column: the separate deletions column in\n // split view, or the shared column in unified view. Returns false when the\n // gutter row has no matching content row, letting the caller fall back to a\n // plain deleted-text selection.\n #beginDeletionGutterSelection(\n gutterRow: HTMLElement,\n code: Element,\n isMouse: boolean\n ): boolean {\n const contentColumn = code.querySelector('[data-content]');\n const anchorContent = this.#contentRowForGutterRow(\n gutterRow,\n contentColumn\n );\n if (anchorContent === undefined) {\n return false;\n }\n this.#selectDeletedLines(anchorContent, anchorContent, code);\n // The document pointerup disposes this listener; it must not set\n // #isGutterMouseDown, whose pointerup focuses the editor and would collapse\n // the native deletion selection.\n if (isMouse) {\n this.#replaceSelectEventListeners([\n addEventListener(\n document,\n 'mousemove',\n (moveEvent) => {\n const moveTarget = moveEvent.composedPath()[0];\n const moveGutter =\n moveTarget instanceof HTMLElement\n ? moveTarget.closest('[data-column-number]')\n : null;\n if (\n moveGutter instanceof HTMLElement &&\n code.contains(moveGutter)\n ) {\n const focusContent = this.#contentRowForGutterRow(\n moveGutter,\n contentColumn\n );\n if (focusContent !== undefined) {\n this.#selectDeletedLines(anchorContent, focusContent, code);\n }\n }\n },\n { passive: true }\n ),\n ]);\n }\n return true;\n }\n\n // Whether a read-only deleted-text selection is currently active (the marker\n // #setDeletedTextSelectionActive sets). The copy/cut handlers read this to\n // copy the native selection instead of the editor's empty document selection.\n #isDeletedTextSelectionActive(): boolean {\n return (\n this.#fileContainer?.shadowRoot\n ?.querySelector('pre')\n ?.hasAttribute('data-deleted-text-selection') ?? false\n );\n }\n\n // The clipboard text for a read-only deleted-text selection. A gutter\n // selection records the full multi-line text in #deletedSelectionText; a\n // direct content drag leaves it empty, so fall back to the browser's native\n // selection (which spans only the first deleted line — its separate host).\n #deletedTextForClipboard(): string {\n return this.#deletedSelectionText !== ''\n ? this.#deletedSelectionText\n : (window.getSelection()?.toString() ?? '');\n }\n\n // Toggle the marker that reveals the native selection inside read-only\n // deleted text (see the gated ::selection rule). It stays on only while the\n // user is actively selecting within deleted lines, so a normal selection of\n // editable code that sweeps across an interleaved deleted line does not\n // highlight it.\n #setDeletedTextSelectionActive(active: boolean): void {\n const pre = this.#fileContainer?.shadowRoot?.querySelector('pre');\n if (pre == null) {\n return;\n }\n if (active) {\n pre.setAttribute('data-deleted-text-selection', '');\n this.#setEditorActiveLineSafe(null);\n // Reset the captured selection text. #selectDeletedLines refills it for a\n // gutter selection; a content drag leaves it empty so the copy/cut\n // handlers fall back to the native selection.\n this.#deletedSelectionText = '';\n } else {\n pre.removeAttribute('data-deleted-text-selection');\n this.#deletedSelectionText = '';\n }\n }\n\n #setEditorActiveLineSafe(\n lineNumber: number | null,\n lineNumberOnly = false,\n side: SelectionSide = 'additions'\n ): void {\n try {\n // Keep the caret decoration separate from selected lines. The component\n // confines it to the relevant diff pane, and a text selection keeps only\n // the focus line's gutter number highlighted.\n this.#fileInstance?.setEditorActiveLine(lineNumber, {\n lineNumberOnly,\n side,\n });\n } catch {\n // InteractionManager.renderSelection can throw while editor DOM is updating.\n }\n }\n\n // Re-render the selection overlay after a theme swap so rounded corner masks\n // recompute their `--diffs-selection-corner-bg`. Those masks capture the\n // resolved line-background color when the selection is drawn; a light/dark or\n // theme-name change updates the line CSS but leaves the captured color stale,\n // showing wrong-colored corners on diff-colored lines until the selection\n // moves. Deferred to the next frame because a host-driven theme change fires\n // this mid-`#sync` (before the render range is refreshed), and `#sync`\n // re-renders the overlay itself; the frame delay avoids re-entrancy and is\n // imperceptible.\n #scheduleThemeSelectionRefresh(): void {\n if (this.#themeSelectionRefreshFrame !== undefined) {\n return;\n }\n this.#themeSelectionRefreshFrame = requestAnimationFrame(() => {\n this.#themeSelectionRefreshFrame = undefined;\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n });\n }\n\n // Keep the drag's horizontal goal in pointer space so a native caret that\n // briefly clamps to a short line cannot move every generated selection.\n #updateAltColumnSelections(): boolean {\n const drag = this.#altColumnDrag;\n const selectionStart = this.#selectionStart;\n const textDocument = this.#editSession?.document;\n if (\n drag === undefined ||\n drag.focusLine === undefined ||\n selectionStart === undefined ||\n textDocument === undefined\n ) {\n return false;\n }\n\n const anchor =\n selectionStart.direction === DirectionBackward\n ? selectionStart.end\n : selectionStart.start;\n const scrollLeft = this.#contentElement?.parentElement?.scrollLeft ?? 0;\n const characterDeltaRaw =\n (drag.clientX - drag.startClientX + scrollLeft - drag.startScrollLeft) /\n this.#metrics.ch;\n const characterDelta =\n characterDeltaRaw < 0\n ? -Math.round(-characterDeltaRaw)\n : Math.round(characterDeltaRaw);\n const focusCharacter = Math.max(0, anchor.character + characterDelta);\n const goal = { line: drag.focusLine, character: focusCharacter };\n if (\n drag.renderedGoal !== undefined &&\n comparePosition(drag.renderedGoal, goal) === 0\n ) {\n return true;\n }\n drag.renderedGoal = goal;\n\n const selections: EditorSelection[] = [];\n const step = goal.line < anchor.line ? -1 : 1;\n for (let line = anchor.line; ; line += step) {\n if (this.#isLineRenderable(line)) {\n // Projected UTF-16 offsets must not split a grapheme on this line.\n const lineText = textDocument.getLineText(line);\n const anchorOffset = Math.min(anchor.character, lineText.length);\n const focusOffset = Math.min(focusCharacter, lineText.length);\n const anchorCharacter = snapCharacterToGraphemeBoundary(\n lineText,\n anchorOffset\n );\n const lineFocusCharacter =\n focusOffset === anchorOffset\n ? anchorCharacter\n : snapCharacterToGraphemeBoundary(lineText, focusOffset);\n selections.push({\n start: {\n line,\n character: Math.min(anchorCharacter, lineFocusCharacter),\n },\n end: {\n line,\n character: Math.max(anchorCharacter, lineFocusCharacter),\n },\n direction:\n anchorCharacter === lineFocusCharacter\n ? DirectionNone\n : anchorCharacter < lineFocusCharacter\n ? DirectionForward\n : DirectionBackward,\n });\n }\n if (line === goal.line) {\n break;\n }\n }\n this.#updateSelections(selections);\n return true;\n }\n\n #removeRenderedEditPrediction(): void {\n for (const [key, element] of this.#overlayElements ?? []) {\n if (key.startsWith('editPrediction')) {\n element.remove();\n this.#overlayElements?.delete(key);\n }\n }\n }\n\n // Combines edits that share source lines into the exact text range rendered\n // by one ghost preview. A non-deletion replacement also includes the\n // preserved line suffix so it reflows after the ghost text. Spacing and\n // rendering both use this geometry so they cannot disagree about how many\n // continuation lines the preview contains.\n #composeEditPredictionGroup(\n textDocument: TextDocument<EType, LAnnotation>,\n edits: readonly TextEdit[],\n startIndex: number\n ): { edit: TextEdit; endIndex: number } {\n const firstEdit = edits[startIndex];\n let endIndex = startIndex;\n let endLine = firstEdit.range.end.line;\n while (\n endIndex + 1 < edits.length &&\n edits[endIndex + 1].range.start.line <= endLine\n ) {\n endIndex++;\n endLine = Math.max(endLine, edits[endIndex].range.end.line);\n }\n if (\n endIndex === startIndex &&\n (firstEdit.newText.length === 0 ||\n comparePosition(firstEdit.range.start, firstEdit.range.end) === 0)\n ) {\n return { edit: firstEdit, endIndex };\n }\n\n const start = firstEdit.range.start;\n const end = {\n line: endLine,\n character: textDocument.getLineLength(endLine),\n };\n const parts: string[] = [];\n let consumed = textDocument.offsetAt(start);\n for (let index = startIndex; index <= endIndex; index++) {\n const edit = edits[index];\n const editStart = textDocument.offsetAt(edit.range.start);\n const editEnd = textDocument.offsetAt(edit.range.end);\n parts.push(textDocument.getTextSlice(consumed, editStart), edit.newText);\n consumed = editEnd;\n }\n parts.push(textDocument.getTextSlice(consumed, textDocument.offsetAt(end)));\n return {\n edit: { range: { start, end }, newText: parts.join('') },\n endIndex,\n };\n }\n\n // Composes the active prediction into ghost groups and decides, once, whether\n // every group has rendered rows. Spacers and ghost rendering read this result\n // directly; Tab acceptance reads the `rendered` flag that rendering sets only\n // after drawing every group. A prediction is therefore shown all-or-nothing\n // and Tab acts on exactly the ghost text the user sees. A virtualized or\n // collapsed row cannot show its edit, and accepting would change unseen\n // document content. Undefined when no prediction applies to the current\n // document version or subtle mode has not revealed it.\n #getEditPredictionGroups():\n | { groups: EditPredictionGroup[]; allVisible: boolean }\n | undefined {\n const prediction = this.#editPrediction;\n const textDocument = this.#editSession?.document;\n if (\n prediction == null ||\n textDocument == null ||\n prediction.document !== textDocument ||\n prediction.version !== textDocument.version ||\n (this.#options.editPrediction?.mode === 'subtle' &&\n !this.#editPredictionRevealed)\n ) {\n return undefined;\n }\n const { edits } = prediction.response;\n const groups: EditPredictionGroup[] = [];\n let allVisible = edits.length > 0;\n for (let startIndex = 0; startIndex < edits.length; ) {\n const { edit, endIndex } = this.#composeEditPredictionGroup(\n textDocument,\n edits,\n startIndex\n );\n for (\n let line = edit.range.start.line;\n allVisible && line <= edit.range.end.line;\n line++\n ) {\n allVisible = this.#isLineVisible(line);\n }\n groups.push({ edit, startIndex, endIndex });\n startIndex = endIndex + 1;\n }\n return { groups, allVisible };\n }\n\n // Give a ghost text element one block per predicted line. The first line\n // continues from the caret, so it is indented to the caret's x. When lines\n // wrap, the element spans the rest of the column so its lines break where\n // document text would; otherwise it grows to fit its content.\n #fillGhostTextElement(\n element: HTMLElement,\n newText: string,\n anchorLeft: number,\n lineLeft: number,\n insertionSuffix: Node | undefined\n ): void {\n if (this.#isWrap) {\n element.dataset.wrap = '';\n element.style.width = `calc(100cqw - ${lineLeft}px)`;\n } else {\n delete element.dataset.wrap;\n element.style.width = 'max-content';\n }\n const lines = newText.split(/\\r\\n|\\r|\\n/);\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const lineText = lines[lineIndex];\n const suffix =\n lineIndex === lines.length - 1 ? insertionSuffix : undefined;\n const isEmpty = lineText.length === 0 && suffix === undefined;\n const line = h(\n 'span',\n {\n dataset: isEmpty\n ? ['editPredictionLine', 'empty']\n : 'editPredictionLine',\n textContent: isEmpty ? '\\u200b' : lineText,\n },\n element\n );\n if (suffix !== undefined) {\n const suffixElement = h(\n 'span',\n {\n dataset: 'editPredictionSuffix',\n },\n line\n );\n suffixElement.append(suffix);\n }\n // Indent only the first visual line to the caret; when the line wraps,\n // its continuation rows start at the column's left edge like document\n // text does. Padding would indent every row of the block.\n if (lineIndex === 0 && anchorLeft !== lineLeft) {\n line.style.textIndent = `${anchorLeft - lineLeft}px`;\n }\n }\n }\n\n // A mid-line insertion masks the rest of its line and redraws that text after\n // the ghost text. Returns the copy to redraw (cloned from the rendered row so\n // it keeps its colors), or undefined when there is nothing to redraw or a\n // neighbouring edit on the same line would move it.\n #cloneInsertionSuffix(group: EditPredictionGroup): Node | undefined {\n const prediction = this.#editPrediction;\n const textDocument = this.#editSession?.document;\n if (prediction == null || textDocument == null) {\n return undefined;\n }\n const { edit, startIndex, endIndex } = group;\n const { start, end } = edit.range;\n const isMidLineInsertion =\n comparePosition(start, end) === 0 &&\n start.character < textDocument.getLineLength(start.line);\n if (\n !isMidLineInsertion ||\n prediction.response.edits[startIndex - 1]?.range.end.line ===\n start.line ||\n prediction.response.edits[endIndex + 1]?.range.start.line === start.line\n ) {\n return undefined;\n }\n const sourceLine = this.#getLineElement(start.line);\n if (sourceLine === undefined) {\n return document.createTextNode(\n textDocument.getLineText(start.line).slice(start.character)\n );\n }\n const [suffixNode, suffixOffset] = getSelectionAnchor(\n sourceLine,\n start.character\n );\n const suffixRange = document.createRange();\n suffixRange.selectNodeContents(sourceLine);\n suffixRange.setStart(suffixNode, clampDomOffset(suffixNode, suffixOffset));\n const suffix = suffixRange.cloneContents();\n if (suffix.firstChild?.textContent === '') {\n suffix.firstChild.remove();\n }\n return suffix;\n }\n\n // How many rows of ghost text extend below the anchor row. The ghost's first\n // visual line sits on the caret's visual line and the rest run down over the\n // anchor row's remaining visual lines before spilling below it. Without\n // wrapping every predicted line is one row. With wrapping only the browser\n // knows where the lines break, so the ghost element is laid out hidden in the\n // overlay and measured; an element that cannot be measured counts as\n // unwrapped, the same fallback #wrapLineText uses.\n #measureGhostTextRows(group: EditPredictionGroup): number {\n const { edit } = group;\n const { start } = edit.range;\n const [anchorLeft, anchorWrapLine] = this.#getCharX(\n start.line,\n start.character\n );\n let anchorVisualLines = 1;\n let ghostVisualLines = edit.newText.split(/\\r\\n|\\r|\\n/).length;\n const overlayElement = this.#overlayElement;\n if (this.#isWrap && overlayElement != null) {\n anchorVisualLines = Math.max(\n 1,\n this.#wrapLineTextOrWholeLine(start.line).length - 1\n );\n const probe = h(\n 'span',\n { dataset: 'editPrediction', style: { visibility: 'hidden' } },\n overlayElement\n );\n this.#fillGhostTextElement(\n probe,\n edit.newText,\n anchorLeft,\n this.#getCharX(start.line, 0)[0],\n this.#cloneInsertionSuffix(group)\n );\n const { width, height } = probe.getBoundingClientRect();\n probe.remove();\n const { lineHeight } = this.#metrics;\n // A zero-width column (mid re-render) would wrap every character; treat\n // that, like a zero height, as unmeasurable.\n if (width > 0 && height > 0 && lineHeight > 0) {\n ghostVisualLines = Math.round(height / lineHeight);\n }\n }\n return Math.max(0, ghostVisualLines - (anchorVisualLines - anchorWrapLine));\n }\n\n // Reserve numberless grid space for ghost continuation lines without adding\n // rows that could be mistaken for document content by the editor.\n #syncEditPredictionSpacers(notifyComponent = true): void {\n const nextSpacers = new Map<HTMLElement, number>();\n // Ghost text rows per line for this sync. It replaces #ghostTextRows only\n // when the contents differ, so an unchanged map keeps its identity.\n const ghostTextRows = new Map<number, number>();\n const previousRows = this.#ghostTextRows;\n let rowsChanged = false;\n const contentElement = this.#contentElement;\n const composed = this.#getEditPredictionGroups();\n if (contentElement != null && composed != null && composed.allVisible) {\n for (const group of composed.groups) {\n const { edit } = group;\n if (edit.newText.length === 0) {\n continue;\n }\n const count = this.#measureGhostTextRows(group);\n if (count > (ghostTextRows.get(edit.range.start.line) ?? 0)) {\n ghostTextRows.set(edit.range.start.line, count);\n }\n }\n\n if (ghostTextRows.size > 0) {\n let rowIndexes: Map<Element, number> | undefined;\n const startingLine = this.#renderRange?.startingLine ?? 0;\n for (const [line, count] of ghostTextRows) {\n rowsChanged ||= previousRows.get(line) !== count;\n const lineElement = this.#getLineElement(line);\n if (lineElement === undefined) {\n continue;\n }\n let rowIndex = line - startingLine;\n if (contentElement.children[rowIndex] !== lineElement) {\n if (rowIndexes === undefined) {\n rowIndexes = new Map();\n for (\n let index = 0;\n index < contentElement.children.length;\n index++\n ) {\n rowIndexes.set(contentElement.children[index], index);\n }\n }\n rowIndex = rowIndexes.get(lineElement) ?? -1;\n }\n if (rowIndex < 0) {\n continue;\n }\n nextSpacers.set(lineElement, count);\n const gutterRow = this.#gutterElement?.children[rowIndex];\n if (gutterRow instanceof HTMLElement) {\n nextSpacers.set(gutterRow, count);\n }\n const partner = this.#deletionsColumnPartner(rowIndex);\n if (partner != null) {\n // Several anchors can share one buffer, so their rows add up.\n nextSpacers.set(\n partner.content,\n (nextSpacers.get(partner.content) ?? 0) + count\n );\n nextSpacers.set(\n partner.gutter,\n (nextSpacers.get(partner.gutter) ?? 0) + count\n );\n }\n }\n }\n }\n\n let changed = false;\n for (const [element, count] of this.#editPredictionSpacers) {\n if (nextSpacers.get(element) === count) {\n continue;\n }\n delete element.dataset.editPredictionSpacer;\n element.style.removeProperty('--diffs-edit-prediction-spacer-height');\n changed = true;\n }\n for (const [element, count] of nextSpacers) {\n if (this.#editPredictionSpacers.get(element) === count) {\n continue;\n }\n element.dataset.editPredictionSpacer = '';\n element.style.setProperty(\n '--diffs-edit-prediction-spacer-height',\n `${count}lh`\n );\n changed = true;\n }\n this.#editPredictionSpacers = nextSpacers;\n if (rowsChanged || ghostTextRows.size !== previousRows.size) {\n this.#ghostTextRows = ghostTextRows;\n if (notifyComponent) {\n this.#virtualizedInstance?.syncGhostTextRows();\n }\n }\n if (changed) {\n this.#resetCache();\n }\n }\n\n // In a split diff whose columns scroll separately, each column is its own\n // grid, so a ghost text margin on an additions row grows that column alone\n // and the deletions rows below drift out of line. Find the deletions element\n // in the same grid track as the additions row at `rowIndex`: its paired line\n // row, or the empty buffer that spans the tracks of a one-sided run. A row is\n // one track; a buffer spans `data-buffer-size` tracks. Undefined when the\n // columns share a grid (wrap mode) or this is not a split diff.\n #deletionsColumnPartner(rowIndex: number): ColumnElements | undefined {\n const deletionsColumn = this.#deletionsColumn;\n const contentElement = this.#contentElement;\n if (\n deletionsColumn == null ||\n contentElement == null ||\n !this.#isDiff ||\n this.#diffSyle !== 'split' ||\n this.#isWrap\n ) {\n return undefined;\n }\n let track = 0;\n for (let index = 0; index < rowIndex; index++) {\n track += gridTrackSpan(contentElement.children[index]);\n }\n const { content, gutter } = deletionsColumn;\n let covered = 0;\n for (let index = 0; index < content.children.length; index++) {\n const child = content.children[index];\n covered += gridTrackSpan(child);\n if (covered > track) {\n const gutterChild = gutter.children[index];\n if (\n !(child instanceof HTMLElement) ||\n !(gutterChild instanceof HTMLElement)\n ) {\n throw new Error(\n 'Editor: deletions column rows and gutter cells are out of step'\n );\n }\n return { content: child, gutter: gutterChild };\n }\n }\n return undefined;\n }\n\n #cancelEditPrediction(removeRendered: boolean, notifyComponent = true): void {\n if (this.#editPredictionTimer !== undefined) {\n clearTimeout(this.#editPredictionTimer);\n this.#editPredictionTimer = undefined;\n }\n this.#editPredictionAbortController?.abort();\n this.#editPredictionAbortController = undefined;\n this.#editPredictionGeneration++;\n this.#editPredictionRevealed = false;\n this.#retryEditPredictionOnRender = false;\n this.#editPrediction = undefined;\n this.#syncEditPredictionSpacers(notifyComponent);\n if (removeRendered) {\n this.#removeRenderedEditPrediction();\n }\n }\n\n #includesEditPredictionPath(path: string): boolean {\n const options = this.#options.editPrediction;\n if (options === undefined) {\n return false;\n }\n const normalizedPath = path.replaceAll('\\\\', '/');\n return (\n (options.include === undefined ||\n options.include.some((pattern) =>\n matchesEditPredictionPattern(normalizedPath, pattern)\n )) &&\n options.exclude?.some((pattern) =>\n matchesEditPredictionPattern(normalizedPath, pattern)\n ) !== true\n );\n }\n\n #scheduleEditPrediction(): void {\n this.#cancelEditPrediction(true);\n const selection = this.#selections?.[0];\n if (\n this.#options.editPrediction === undefined ||\n this.#editSession?.document === undefined ||\n this.#editSession?.fileInfo === undefined ||\n this.#selections?.length !== 1 ||\n selection === undefined ||\n !isCollapsedSelection(selection)\n ) {\n return;\n }\n\n const document = this.#editSession?.document;\n const cursorOffset = document.offsetAt(getCaretPosition(selection));\n this.#editPredictionTimer = setTimeout(() => {\n this.#editPredictionTimer = undefined;\n const options = this.#options.editPrediction;\n const currentSelection = this.#selections?.[0];\n const path = this.#editSession?.fileInfo?.name;\n if (\n options === undefined ||\n path === undefined ||\n this.#editSession?.document !== document ||\n this.#selections?.length !== 1 ||\n currentSelection === undefined ||\n !isCollapsedSelection(currentSelection) ||\n document.offsetAt(getCaretPosition(currentSelection)) !== cursorOffset\n ) {\n return;\n }\n\n if (!this.#includesEditPredictionPath(path)) {\n return;\n }\n\n const isLineEditable = (line: number): boolean =>\n this.#isLineInRenderRange(line) && this.#isLineRenderable(line);\n if (!isLineEditable(getCaretPosition(currentSelection).line)) {\n this.#retryEditPredictionOnRender = true;\n return;\n }\n const request = buildEditPredictionRequest(\n path,\n document,\n cursorOffset,\n this.#editPredictionHistory,\n isLineEditable\n );\n if (request === undefined) {\n return;\n }\n const excerptStartOffset = document.offsetAt({\n line: request.excerptStartLine,\n character: 0,\n });\n const editableStart = excerptStartOffset + request.editableRange.start;\n const editableEnd = excerptStartOffset + request.editableRange.end;\n const controller = new AbortController();\n const generation = ++this.#editPredictionGeneration;\n this.#editPredictionAbortController = controller;\n\n let prediction: Promise<EditPredictResponse>;\n try {\n prediction = options.provider.predict(request, {\n signal: controller.signal,\n });\n } catch {\n this.#editPredictionAbortController = undefined;\n return;\n }\n\n void Promise.resolve(prediction)\n .then((response) => {\n const selection = this.#selections?.[0];\n if (\n controller.signal.aborted ||\n generation !== this.#editPredictionGeneration ||\n this.#editPredictionAbortController !== controller ||\n this.#editSession?.document !== document ||\n document.version !== request.version ||\n this.#selections?.length !== 1 ||\n selection === undefined ||\n !isCollapsedSelection(selection) ||\n document.offsetAt(getCaretPosition(selection)) !== cursorOffset\n ) {\n return;\n }\n\n if (\n response == null ||\n !Array.isArray(response.edits) ||\n response.edits.length === 0 ||\n response.edits.length > MAX_EDIT_PREDICTION_RESPONSE_EDITS ||\n response.newCursor == null\n ) {\n return;\n }\n const resolvedEdits: ResolvedTextEdit[] = [];\n let responseBytes = 0;\n for (const edit of response.edits) {\n if (\n edit == null ||\n typeof edit.newText !== 'string' ||\n !isValidEditPredictionPosition(document, edit.range?.start) ||\n !isValidEditPredictionPosition(document, edit.range?.end) ||\n comparePosition(edit.range.start, edit.range.end) > 0\n ) {\n return;\n }\n responseBytes += editPredictionTextEncoder.encode(\n edit.newText\n ).byteLength;\n if (responseBytes > MAX_EDIT_PREDICTION_RESPONSE_BYTES) {\n return;\n }\n const start = document.offsetAt(edit.range.start);\n const end = document.offsetAt(edit.range.end);\n const resolvedEdit = document.resolveEdits([edit])[0];\n if (resolvedEdit.start !== start || resolvedEdit.end !== end) {\n return;\n }\n resolvedEdits.push(resolvedEdit);\n }\n resolvedEdits.sort((left, right) => {\n const startDelta = left.start - right.start;\n return startDelta === 0 ? left.end - right.end : startDelta;\n });\n for (let index = 0; index < resolvedEdits.length; index++) {\n const edit = resolvedEdits[index];\n if (\n edit.start < editableStart ||\n edit.end > editableEnd ||\n (index > 0 && resolvedEdits[index - 1].end > edit.start)\n ) {\n return;\n }\n }\n const edits = resolvedEdits.filter(\n (edit) => edit.text !== document.getTextSlice(edit.start, edit.end)\n );\n if (edits.length === 0) {\n return;\n }\n\n const firstEditPosition = document.positionAt(edits[0].start);\n const lastEditPosition = document.positionAt(edits.at(-1)!.end);\n const affectedStart = document.offsetAt({\n line: firstEditPosition.line,\n character: 0,\n });\n const affectedEnd = document.offsetAt({\n line: lastEditPosition.line,\n character: document.getLineLength(lastEditPosition.line),\n });\n const predictedParts: string[] = [];\n let consumed = affectedStart;\n for (const edit of edits) {\n predictedParts.push(\n document.getTextSlice(consumed, edit.start),\n edit.text\n );\n consumed = edit.end;\n }\n predictedParts.push(document.getTextSlice(consumed, affectedEnd));\n const predictedLines = predictedParts.join('').split(/\\r\\n|\\r|\\n/);\n const affectedEndLine =\n firstEditPosition.line + predictedLines.length - 1;\n const lineDelta =\n predictedLines.length -\n (lastEditPosition.line - firstEditPosition.line + 1);\n const newCursor = response.newCursor;\n if (\n !Number.isInteger(newCursor.line) ||\n !Number.isInteger(newCursor.character) ||\n newCursor.line < 0 ||\n newCursor.character < 0\n ) {\n return;\n }\n if (\n newCursor.line >= firstEditPosition.line &&\n newCursor.line <= affectedEndLine\n ) {\n const line =\n predictedLines[newCursor.line - firstEditPosition.line];\n if (\n newCursor.character > line.length ||\n splitsSurrogatePair(line, newCursor.character)\n ) {\n return;\n }\n } else {\n const originalLine =\n newCursor.line < firstEditPosition.line\n ? newCursor.line\n : newCursor.line - lineDelta;\n if (\n originalLine < 0 ||\n originalLine >= document.lineCount ||\n newCursor.character > document.getLineLength(originalLine)\n ) {\n return;\n }\n const originalOffset = document.offsetAt({\n line: originalLine,\n character: newCursor.character,\n });\n if (\n splitsSurrogatePair(\n document.charAt(originalOffset - 1) +\n document.charAt(originalOffset),\n 1\n )\n ) {\n return;\n }\n }\n\n this.#editPrediction = {\n document,\n version: request.version,\n cursorOffset,\n rendered: false,\n response: {\n edits: edits.map((edit) => ({\n range: {\n start: document.positionAt(edit.start),\n end: document.positionAt(edit.end),\n },\n newText: edit.text,\n })),\n newCursor: { ...newCursor },\n },\n };\n this.#updateSelections(this.#selections);\n })\n .catch(() => {})\n .finally(() => {\n if (this.#editPredictionAbortController === controller) {\n this.#editPredictionAbortController = undefined;\n }\n });\n }, EDIT_PREDICTION_DEBOUNCE_MS);\n }\n\n #recordEditPredictionHistory(\n change: TextDocumentChange,\n source: 'user' | 'prediction'\n ): void {\n const textDocument = this.#editSession?.document;\n const path = this.#editSession?.fileInfo?.name;\n const transaction = getTextDocumentChangeTransaction(change);\n if (\n textDocument === undefined ||\n path === undefined ||\n transaction === undefined ||\n !this.#includesEditPredictionPath(path)\n ) {\n return;\n }\n this.#editPredictionHistory = recordEditPrediction(\n this.#editPredictionHistory,\n path,\n textDocument,\n transaction,\n source\n );\n }\n\n #acceptEditPrediction(): void {\n const prediction = this.#editPrediction;\n const textDocument = this.#editSession?.document;\n const selection = this.#selections?.[0];\n if (\n prediction === undefined ||\n !prediction.rendered ||\n textDocument === undefined ||\n prediction.document !== textDocument ||\n prediction.version !== textDocument.version ||\n this.#selections?.length !== 1 ||\n selection === undefined ||\n !isCollapsedSelection(selection) ||\n textDocument.offsetAt(getCaretPosition(selection)) !==\n prediction.cursorOffset\n ) {\n return;\n }\n\n const { edits, newCursor } = prediction.response;\n this.#cancelEditPrediction(true);\n const change = textDocument.applyEdits(\n edits.map((edit) => ({\n range: {\n start: { ...edit.range.start },\n end: { ...edit.range.end },\n },\n newText: edit.newText,\n })),\n true,\n this.#selections,\n undefined,\n true\n );\n if (change === undefined) {\n this.#scheduleEditPrediction();\n return;\n }\n\n const cursor = textDocument.normalizePosition(newCursor);\n const nextSelections: EditorSelection[] = [\n { start: cursor, end: cursor, direction: DirectionNone },\n ];\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change),\n { editSource: 'prediction' }\n );\n }\n\n #renderEditPrediction(renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n }): void {\n const prediction = this.#editPrediction;\n const textDocument = this.#editSession?.document;\n if (prediction !== undefined) {\n prediction.rendered = false;\n }\n const composed = this.#getEditPredictionGroups();\n if (\n prediction == null ||\n textDocument == null ||\n composed == null ||\n !composed.allVisible\n ) {\n return;\n }\n\n for (const group of composed.groups) {\n const { edit, endIndex } = group;\n const { start, end } = edit.range;\n const isDeletion = edit.newText.length === 0;\n const isReplacement = comparePosition(start, end) !== 0;\n const lineLength = textDocument.getLineLength(start.line);\n const isMidLineInsertion = !isReplacement && start.character < lineLength;\n if (isReplacement) {\n this.#renderSelection(\n renderCtx,\n isDeletion ? 'editPredictionDeletion' : 'editPredictionReplacement',\n { start, end }\n );\n } else if (isMidLineInsertion) {\n // Hide the in-flow suffix so ghost text never collides with it.\n this.#renderSelection(renderCtx, 'editPredictionInsertion', {\n start,\n end: { line: start.line, character: lineLength },\n });\n }\n\n if (isDeletion) {\n continue;\n }\n\n const [anchorLeft, anchorWrapLine] = this.#getCharX(\n start.line,\n start.character\n );\n const lineLeft = this.#getCharX(start.line, 0)[0];\n const anchorTop =\n this.#getLineY(start.line) + anchorWrapLine * this.#metrics.lineHeight;\n const key = `editPrediction-${endIndex}`;\n let element = this.#overlayElements?.get(key);\n if (element !== undefined) {\n this.#overlayElements?.delete(key);\n element.replaceChildren();\n } else {\n element = h(\n 'span',\n {\n ariaHidden: 'true',\n contentEditable: 'false',\n dataset: 'editPrediction',\n },\n renderCtx.fragment\n );\n }\n if (isReplacement) {\n element.dataset.replacement = '';\n const lineElement = this.#getLineElement(start.line);\n if (lineElement !== undefined) {\n element.style.setProperty(\n '--diffs-edit-prediction-bg',\n getComputedStyle(lineElement).getPropertyValue('--diffs-line-bg')\n );\n }\n } else {\n delete element.dataset.replacement;\n element.style.removeProperty('--diffs-edit-prediction-bg');\n }\n this.#fillGhostTextElement(\n element,\n edit.newText,\n anchorLeft,\n lineLeft,\n this.#cloneInsertionSuffix(group)\n );\n element.style.transform = `translateX(${lineLeft}px) translateY(${anchorTop}px)`;\n renderCtx.elements.set(key, element);\n }\n prediction.rendered = true;\n }\n\n #updateSelections(selections: EditorSelection[]) {\n this.__postponeBgTokenizeToNextFrame();\n\n const previousSelections = this.#selections;\n let selectionsChanged = previousSelections?.length !== selections.length;\n if (!selectionsChanged && previousSelections !== undefined) {\n for (let i = 0; i < selections.length; i++) {\n const previous = previousSelections[i];\n const next = selections[i];\n if (\n previous.direction !== next.direction ||\n comparePosition(previous.start, next.start) !== 0 ||\n comparePosition(previous.end, next.end) !== 0\n ) {\n selectionsChanged = true;\n break;\n }\n }\n }\n if (selectionsChanged) {\n this.#cancelEditPrediction(true);\n }\n this.#syncEditPredictionSpacers();\n\n this.#primaryCaretElement = undefined;\n this.#setEditorActiveLineSafe(null);\n\n if (\n selections.length === 0 &&\n this.#matches === undefined &&\n this.#markerRenderer === undefined\n ) {\n this.#selections = undefined;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n if (selectionsChanged) {\n this.#scheduleEditPrediction();\n }\n return;\n }\n\n const fragment = document.createDocumentFragment();\n const renderCtx = {\n fragment,\n elements: new Map<string, HTMLElement>(),\n };\n\n if (selections.length > 0) {\n const normalizedSelections = mergeOverlappingSelections(selections);\n const primarySelection = normalizedSelections.at(-1)!;\n this.#selections = normalizedSelections;\n // The caret line always keeps its highlighted gutter number. With a bare\n // caret it also gets the full-line background; once any selection spans\n // text, the background is dropped (lineNumberOnly) so the text selection\n // is the only line-level highlight.\n const hasNonEmptySelection = normalizedSelections.some(\n (selection) => !isCollapsedSelection(selection)\n );\n const caretLine = getCaretPosition(primarySelection).line + 1;\n\n this.#setEditorActiveLineSafe(caretLine, hasNonEmptySelection);\n\n for (const selection of normalizedSelections) {\n if (!isCollapsedSelection(selection)) {\n this.#renderSelection(renderCtx, 'selection', selection);\n }\n this.#renderCaret(renderCtx, selection, selection === primarySelection);\n }\n\n const bracketMatchRanges =\n this.#options.matchBrackets !== false &&\n this.#editSession?.document != null &&\n this.#tokenizer !== undefined &&\n isCollapsedSelection(primarySelection)\n ? findBracketMatchRanges(\n this.#editSession?.document,\n this.#tokenizer,\n primarySelection.start\n )\n : undefined;\n if (bracketMatchRanges !== undefined) {\n for (const range of bracketMatchRanges) {\n this.#renderSelection(renderCtx, 'bracketMatch', range);\n }\n }\n }\n\n const textDocument = this.#editSession?.document;\n if (this.#matches !== undefined && textDocument !== undefined) {\n const matches = this.#matches;\n const renderRange = this.#renderRange;\n const shouldCullMatches =\n (renderRange != null && Number.isFinite(renderRange.totalLines)) ||\n (this.#isDiff &&\n this.#fileDiffInstance?.options.expandUnchanged !== true);\n const renderedLineRanges = shouldCullMatches\n ? this.#getRenderedEditableLineRanges()\n : undefined;\n const primarySelection = this.#selections?.at(-1);\n const primaryStartOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.start)\n : -1;\n const primaryEndOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.end)\n : -1;\n let firstMatchIndex = 0;\n const rangeCount = renderedLineRanges?.length ?? 1;\n for (let rangeIndex = 0; rangeIndex < rangeCount; rangeIndex++) {\n let visibleEndOffset = Infinity;\n const lineRange = renderedLineRanges?.[rangeIndex];\n if (lineRange !== undefined) {\n const [firstLine, lastLine] = lineRange;\n const visibleStartOffset = textDocument.offsetAt({\n line: firstLine,\n character: 0,\n });\n const endLine = lastLine + 1;\n visibleEndOffset =\n endLine < textDocument.lineCount\n ? textDocument.offsetAt({ line: endLine, character: 0 })\n : textDocument.offsetAt({\n line: endLine - 1,\n character: textDocument.getLineLength(endLine - 1),\n });\n\n // Matches are sorted and non-overlapping, so narrow the rendered\n // offset window before resolving any match positions through the treap.\n let low = firstMatchIndex;\n let high = matches.length;\n while (low < high) {\n const middle = low + Math.floor((high - low) / 2);\n if (matches[middle][1] <= visibleStartOffset) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n firstMatchIndex = low;\n }\n for (; firstMatchIndex < matches.length; firstMatchIndex++) {\n const [startOffset, endOffset] = matches[firstMatchIndex];\n if (startOffset >= visibleEndOffset) {\n break;\n }\n const range: Range = {\n start: textDocument.positionAt(startOffset),\n end: textDocument.positionAt(endOffset),\n };\n const isFocused =\n primaryStartOffset === startOffset &&\n primaryEndOffset === endOffset;\n this.#renderSelection(\n renderCtx,\n 'match',\n range,\n isFocused ? 'focus' : undefined\n );\n }\n }\n }\n\n if (this.#markerRenderer !== undefined && textDocument !== undefined) {\n for (const marker of this.#markerRenderer.markers) {\n this.#renderSelection(\n renderCtx,\n 'marker',\n marker,\n markerSeverityDatasetKey(marker.severity)\n );\n }\n }\n\n this.#renderEditPrediction(renderCtx);\n\n this.#overlayElement?.appendChild(fragment);\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n this.#overlayElements = renderCtx.elements;\n this.#updateSelectionActionPopover();\n if (selectionsChanged) {\n this.#scheduleEditPrediction();\n }\n }\n\n // Render externally owned cursors independently from local selections so\n // collaboration state never changes focus, editing, or native selection.\n #renderCarets(): void {\n const carets = this.#carets;\n const renderCaret = this.#options.renderCaret;\n const overlayElement = this.#overlayElement;\n this.#caretHighlightElements?.forEach((element) => element.remove());\n this.#caretHighlightElements = undefined;\n if (\n carets === undefined ||\n renderCaret === undefined ||\n overlayElement === undefined\n ) {\n this.#caretElements?.forEach((element) => element.remove());\n this.#caretElements = undefined;\n return;\n }\n\n const elements = (this.#caretElements ??= new Map());\n for (const [trackedCaret, element] of elements) {\n if (!this.#isLineVisible(trackedCaret.caret.focus.line)) {\n element.remove();\n elements.delete(trackedCaret);\n }\n }\n\n const fragment = document.createDocumentFragment();\n const highlightElements: HTMLElement[] = [];\n for (const trackedCaret of carets) {\n const { caret } = trackedCaret;\n const { line, character } = caret.focus;\n if (trackedCaret.anchorOffset !== trackedCaret.focusOffset) {\n // Keep each collaborator's rounded-corner state and highlight elements\n // separate so overlapping ranges retain their own geometry and color.\n const highlightContext = {\n fragment,\n elements: new Map<string, HTMLElement>(),\n };\n this.#renderSelection(\n highlightContext,\n 'caretHighlight',\n trackedCaret.anchorOffset < trackedCaret.focusOffset\n ? { start: caret.anchor, end: caret.focus }\n : { start: caret.focus, end: caret.anchor },\n undefined,\n caret.focus\n );\n for (const highlightElement of highlightContext.elements.values()) {\n highlightElement.style.setProperty(\n '--diffs-caret-highlight-bg',\n `color-mix(in srgb, ${caret.metadata.color} 32%, transparent)`\n );\n highlightElements.push(highlightElement);\n }\n }\n // Virtualized views omit off-screen rows. Do not leave an unpositioned\n // anchor at the overlay origin for a caret whose row is not rendered.\n if (!this.#isLineVisible(line)) continue;\n let element = elements.get(trackedCaret);\n if (element === undefined) {\n element = h(\n 'div',\n { dataset: 'remoteCaret', children: [renderCaret(caret)] },\n fragment\n );\n elements.set(trackedCaret, element);\n }\n const [left, wrapLine] = this.#getCharX(line, character);\n const top = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n element.style.transform = `translateX(${left}px) translateY(${top}px)`;\n }\n this.#caretHighlightElements = highlightElements;\n overlayElement.appendChild(fragment);\n }\n\n #renderSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n type: OverlayRangeType,\n range: Range,\n extraDataset?: string,\n connectedCaret?: Position\n ) {\n if (this.#editSession?.document == null) {\n return;\n }\n\n const { start, end } = range;\n let firstLine = start.line;\n let endLine = end.line + 1;\n if (this.#renderRange !== undefined) {\n const { startingLine, totalLines } = this.#renderRange;\n firstLine = Math.max(firstLine, startingLine);\n endLine = Math.min(endLine, startingLine + totalLines);\n }\n for (let line = firstLine; line < endLine; line++) {\n if (!this.#isLineVisible(line)) {\n continue;\n }\n\n const isLastLine = line === end.line;\n const startChar = line === start.line ? start.character : 0;\n const endChar = isLastLine\n ? end.character\n : this.#editSession?.document.getLineLength(line);\n\n // A predicted deletion of an empty line or of a lone line break has no\n // text to strike through; draw a one-character mark at the boundary so\n // the removal is visible, on flat and soft-wrapped lines alike. A range\n // that ends at column 0 of a later line also produces an empty segment\n // on that line, but that line survives the edit, so it gets no mark.\n if (\n startChar === endChar &&\n (type === 'editPredictionDeletion' ||\n type === 'editPredictionReplacement')\n ) {\n if (isLastLine && line !== start.line) {\n continue;\n }\n const [left, wrapLine] = this.#getCharX(line, startChar);\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n wrapLine,\n left,\n this.#metrics.ch,\n extraDataset\n );\n continue;\n }\n\n if (this.#isWrap) {\n const contentWidth = this.#getContentWidth();\n const lineText = this.#editSession?.document.getLineText(line);\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n this.#renderWrappedSelection(\n renderCtx,\n line,\n lineText,\n startChar,\n endChar,\n isLastLine,\n type,\n extraDataset,\n connectedCaret\n );\n continue;\n }\n }\n\n let left = 0;\n let width = 0;\n let paddingEnd = 0;\n if (startChar === 0) {\n // gutter width + inline padding (1ch), plus the split-diff content\n // offset so a column-0 selection lines up with the content panel the\n // same way #getCharX (used for startChar > 0 and the caret) does.\n left =\n this.#getGutterWidth() +\n this.#metrics.ch +\n (this.#activeContentOffset?.left ?? 0);\n } else {\n left = this.#getCharX(line, startChar)[0];\n }\n if (!isLastLine && type === 'selection') {\n paddingEnd = this.#metrics.ch;\n }\n if (startChar === endChar) {\n width = paddingEnd;\n } else {\n width = this.#getCharX(line, endChar)[0] - left + paddingEnd;\n }\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n 0,\n left,\n width,\n extraDataset,\n {\n start:\n connectedCaret?.line === start.line &&\n connectedCaret.character === start.character &&\n line === start.line,\n end:\n connectedCaret?.line === end.line &&\n connectedCaret.character === end.character &&\n line === end.line,\n }\n );\n }\n }\n\n // Render the selection on a wrapped logical line by splitting it into one\n // selection-range div per visual sub-line. For each wrap segment, we compute\n // the intersection with the line's selection range and render the slice in\n // segment-local coordinates so left/width line up with the visually wrapped\n // text. Zero-width slices that fall on intermediate segment boundaries are\n // skipped to avoid duplicate markers across consecutive visual lines.\n #renderWrappedSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n line: number,\n lineText: string,\n startChar: number,\n endChar: number,\n isLastLine: boolean,\n type: OverlayRangeType,\n extraDataset?: string,\n connectedCaret?: Position\n ) {\n const wrapOffsets = this.#wrapLineTextOrWholeLine(line);\n const segmentCount = wrapOffsets.length - 1;\n // offsetLeft is the x of the content's left edge in overlay coordinates.\n // In a split diff with wrapping the content element is a grid item shifted\n // right of the deletion panel, so the same content offset that #getCharX\n // adds for the caret must be included here too; otherwise every wrapped\n // selection block is pulled left by the panel offset.\n const offsetLeft =\n this.#getGutterWidth() +\n this.#metrics.ch +\n (this.#activeContentOffset?.left ?? 0);\n\n for (let wrapLine = 0; wrapLine < segmentCount; wrapLine++) {\n const segmentStart = wrapOffsets[wrapLine];\n const segmentEnd = wrapOffsets[wrapLine + 1];\n const wrapStartChar = Math.max(startChar, segmentStart);\n const wrapEndChar = Math.min(endChar, segmentEnd);\n\n // Selection range doesn't reach this visual segment.\n if (wrapStartChar > wrapEndChar) {\n continue;\n }\n\n const segmentStartWidth = this.#segmentTextWidth(\n lineText,\n segmentStart,\n wrapStartChar\n );\n const segmentLeft = offsetLeft + segmentStartWidth;\n let paddingEnd = 0;\n if (\n !isLastLine &&\n wrapLine === segmentCount - 1 &&\n type === 'selection'\n ) {\n paddingEnd = this.#metrics.ch;\n }\n // Measure the selection width as the gap between two segment-relative\n // offsets so a tab inside the selection advances from its real column,\n // not from the start of the sliced selection text.\n const segmentWidth =\n wrapStartChar === wrapEndChar\n ? paddingEnd\n : this.#segmentTextWidth(lineText, segmentStart, wrapEndChar) -\n segmentStartWidth +\n paddingEnd;\n\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n wrapLine,\n segmentLeft,\n segmentWidth,\n extraDataset,\n {\n start:\n connectedCaret?.line === line &&\n connectedCaret.character === startChar &&\n wrapStartChar === startChar,\n end:\n connectedCaret?.line === line &&\n connectedCaret.character === endChar &&\n wrapEndChar === endChar,\n }\n );\n }\n }\n\n // Pixel width of the text from a wrapped segment's start up to a character,\n // relative to the segment's left edge. Tabs advance from the segment start,\n // which sits on a tab stop, so tab stops line up with the rendered text.\n #segmentTextWidth(\n lineText: string,\n segmentStart: number,\n character: number\n ): number {\n if (character <= segmentStart) {\n return 0;\n }\n const segmentText = lineText.slice(segmentStart, character);\n const asciiColumns = getExpandedAsciiTextColumns(\n segmentText,\n this.#metrics.tabSize\n );\n return asciiColumns !== -1\n ? asciiColumns * this.#metrics.ch\n : this.#metrics.measureTextWidth(segmentText);\n }\n\n // Render one selection block for a single visual line.\n #renderSelectionBlock(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n previousSelectionRange?: {\n element: HTMLElement;\n line: number;\n wrapLine: number;\n left: number;\n width: number;\n };\n },\n type: OverlayRangeType,\n line: number,\n wrapLine: number,\n left: number,\n width: number,\n extraDataset?: string,\n connectedCaretEdge?: { start: boolean; end: boolean }\n ) {\n if (width === 0) {\n return;\n }\n\n const { ch, lineHeight } = this.#metrics;\n const y = this.#getLineY(line) + wrapLine * lineHeight;\n const cacheKey = `${type}-${line}/${wrapLine}-${left}-${width} ${extraDataset ?? ''}`;\n const overlayEls = this.#overlayElements;\n const rounded =\n (this.#options.roundedSelection ?? true) &&\n (type === 'selection' || type === 'caretHighlight');\n\n const addRoundedCorner = (\n line: number,\n wrapLine: number,\n left: number,\n radius: 'rtl' | 'rbl' | 'rbr'\n ) => {\n const top = this.#getLineY(line) + wrapLine * lineHeight;\n // Match the corner mask to the line color behind the selection; when\n // absent (context lines) the CSS falls back to the editor base bg.\n const lineElement = this.#getLineElement(line);\n let cornerBg = 'initial';\n if (\n lineElement !== undefined &&\n (lineElement.dataset.lineType === 'change-addition' ||\n lineElement.dataset.selectedLine !== undefined)\n ) {\n cornerBg =\n getComputedStyle(lineElement).getPropertyValue('--diffs-line-bg');\n }\n const css = `width:${ch}px;transform:translateX(${left}px) translateY(${top}px);--diffs-selection-corner-bg:${cornerBg}`;\n const dataset = {\n selectionCorner: '',\n [radius]: '',\n };\n const cacheKeyPrefix = `${type}-block-${line}/${wrapLine}-${left}-1ch`;\n let cacheKey = cacheKeyPrefix + '-' + radius;\n if (radius === 'rbl') {\n const prevCornerKey = cacheKeyPrefix + '-rtl';\n const prevCorner = renderCtx.elements.get(prevCornerKey);\n if (prevCorner !== undefined) {\n prevCorner.remove();\n renderCtx.elements.delete(prevCornerKey);\n cacheKey += '-rtl';\n dataset.rtl = '';\n }\n }\n let cornerEl = renderCtx.elements.get(cacheKey);\n if (cornerEl !== undefined) {\n return;\n }\n if (overlayEls?.has(cacheKey) === true) {\n cornerEl = overlayEls.get(cacheKey)!;\n cornerEl.style.cssText = css;\n overlayEls.delete(cacheKey);\n } else {\n cornerEl = h(\n 'div',\n {\n dataset:\n type === 'caretHighlight'\n ? 'caretHighlightRange'\n : 'selectionRange',\n style: { cssText: css },\n children: [\n h('div', {\n dataset: dataset,\n }),\n ],\n },\n renderCtx.fragment\n );\n }\n renderCtx.elements.set(cacheKey, cornerEl);\n };\n const addRadiusStyle = (element: HTMLElement) => {\n const end = left + width;\n const dataset = element.dataset;\n const previousSelectionRange = renderCtx.previousSelectionRange;\n if (\n previousSelectionRange === undefined ||\n previousSelectionRange.line !== line ||\n previousSelectionRange.wrapLine !== wrapLine\n ) {\n renderCtx.previousSelectionRange = {\n element,\n line,\n wrapLine,\n left,\n width,\n };\n }\n if (\n previousSelectionRange === undefined ||\n end <= previousSelectionRange.left\n ) {\n ['rtl', 'rtr', 'rbl', 'rbr'].forEach((key) => {\n dataset[key] = '';\n });\n } else {\n const prevLine = previousSelectionRange.line;\n const prevWrapLine = previousSelectionRange.wrapLine;\n const prevLeft = previousSelectionRange.left;\n const prevDataset = previousSelectionRange.element.dataset;\n const prevEnd = prevLeft + previousSelectionRange.width;\n if (prevLeft > left) {\n addRoundedCorner(prevLine, prevWrapLine, prevLeft - ch, 'rbr');\n }\n delete prevDataset.rbl;\n delete dataset.rtl;\n delete dataset.rtr;\n if (end >= prevEnd) {\n delete prevDataset.rbr;\n }\n if (end > prevEnd) {\n addRoundedCorner(prevLine, prevWrapLine, prevEnd, 'rbl');\n dataset.rtr = '';\n }\n if (end < prevEnd) {\n addRoundedCorner(line, wrapLine, end, 'rtl');\n }\n if (left < prevLeft) {\n dataset.rtl = '';\n }\n dataset.rbl = '';\n dataset.rbr = '';\n }\n // A collaborator's selection meets its caret at this endpoint. Keep\n // that seam square, while preserving rounded corners at the free edge.\n if (connectedCaretEdge?.start === true) {\n delete dataset.rtl;\n delete dataset.rbl;\n }\n if (connectedCaretEdge?.end === true) {\n delete dataset.rtr;\n delete dataset.rbr;\n }\n };\n\n let rangeEl = renderCtx.elements.get(cacheKey);\n if (rangeEl !== undefined) {\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n return;\n }\n\n if (overlayEls?.has(cacheKey) === true) {\n rangeEl = overlayEls.get(cacheKey)!;\n overlayEls.delete(cacheKey);\n } else {\n rangeEl = h(\n 'div',\n {\n dataset: extraDataset\n ? [type + 'Range', extraDataset]\n : type + 'Range',\n },\n renderCtx.fragment\n );\n }\n\n rangeEl.style.width = `${width}px`;\n rangeEl.style.transform = `translateX(${left}px) translateY(${y}px)`;\n if (\n type === 'editPredictionInsertion' ||\n type === 'editPredictionReplacement'\n ) {\n const lineElement = this.#getLineElement(line);\n if (lineElement !== undefined) {\n rangeEl.style.setProperty(\n '--diffs-edit-prediction-bg',\n getComputedStyle(lineElement).getPropertyValue('--diffs-line-bg')\n );\n }\n } else {\n rangeEl.style.removeProperty('--diffs-edit-prediction-bg');\n }\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n renderCtx.elements.set(cacheKey, rangeEl);\n }\n\n #renderCaret(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n selection: EditorSelection,\n isPrimary: boolean\n ) {\n const { line, character } = getCaretPosition(selection);\n if (!this.#isLineVisible(line)) {\n return;\n }\n const [left, wrapLine] = this.#getCharX(line, character);\n const cacheKey = 'caret-' + line + '/' + wrapLine + ':' + character;\n if (renderCtx.elements.has(cacheKey)) {\n return;\n }\n\n const x = left - 1;\n const y = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n\n const caretEl = h(\n 'div',\n {\n dataset: 'caret',\n style: { transform: `translateX(${x}px) translateY(${y}px)` },\n },\n renderCtx.fragment\n );\n renderCtx.elements.set(cacheKey, caretEl);\n if (isPrimary) {\n caretEl.style.scrollMargin = this.#getScrollMargin();\n this.#primaryCaretElement = caretEl;\n }\n }\n\n #updateSelectionActionPopover(): void {\n const primarySelection = this.#selections?.at(-1);\n const overlayElement = this.#overlayElement;\n const textDocument = this.#editSession?.document;\n const renderSelectionAction = this.#options.renderSelectionAction;\n const cleanup = () => {\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n };\n\n if (\n this.#options.enabledSelectionAction !== true ||\n renderSelectionAction === undefined ||\n primarySelection === undefined ||\n isCollapsedSelection(primarySelection) ||\n this.#isContentMouseDown ||\n overlayElement === undefined ||\n textDocument === undefined\n ) {\n cleanup();\n return;\n }\n\n const head = getCaretPosition(primarySelection);\n if (!this.#isLineVisible(head.line)) {\n cleanup();\n return;\n }\n\n if (this.#selectionAction === undefined) {\n if (!this.#canMountSelectionAction) {\n return;\n }\n const getActiveSelection = (): EditorSelection =>\n this.#selections?.at(-1) ?? primarySelection;\n const selectionActionElement = renderSelectionAction({\n textDocument,\n get selection(): EditorSelection {\n return getActiveSelection();\n },\n applyEdits: (edits: TextEdit[]) => this.applyEdits(edits),\n getSelectionText: () =>\n this.#editSession?.document?.getText(getActiveSelection()) ?? '',\n replaceSelectionText: (text: string) => {\n this.#replaceSelectionText(text, [getActiveSelection()]);\n },\n close: () => {\n cleanup();\n this.#scrollToPrimaryCaret();\n },\n });\n this.#selectionAction = new SelectionActionWidget(\n selectionActionElement,\n overlayElement,\n () => this.#updateSelectionActionPopover()\n );\n // Avoid biasing the first decision with a stale side from a prior popover.\n this.#getPopoverManager().resetPlacement(\n SELECTION_ACTION_POPOVER_PLACEMENT_KEY\n );\n }\n\n const lineHeight = this.#metrics.lineHeight;\n const isBackward = primarySelection.direction === DirectionBackward;\n const preferred = {\n placeAbove: isBackward,\n anchor: head,\n };\n const fallback: typeof preferred = isBackward\n ? { placeAbove: false, anchor: primarySelection.end }\n : { placeAbove: true, anchor: primarySelection.start };\n\n // Resolve each candidate's [left, top, bottom] in overlay coordinate space\n // up front so both the viewport fit-check and the final reposition() call\n // below can reuse them without re-deriving the same line/char geometry\n // twice. For an above placement the CSS `--popover-y-shift: -100%` lifts\n // the popover by its own height, so its top is the anchor row's top minus\n // that height.\n const popoverHeight = this.#selectionAction.height;\n const candidateGeometry = (\n candidate: typeof preferred\n ): PopoverPlacementBounds & {\n left: number;\n anchorTop: number;\n rowTop: number;\n } => {\n const [left, candidateWrapLine] = this.#getCharX(\n candidate.anchor.line,\n candidate.anchor.character\n );\n const rowTop =\n this.#getLineY(candidate.anchor.line) + candidateWrapLine * lineHeight;\n const anchorTop = candidate.placeAbove ? rowTop : rowTop + lineHeight;\n const top = candidate.placeAbove ? anchorTop - popoverHeight : anchorTop;\n return { top, bottom: top + popoverHeight, left, anchorTop, rowTop };\n };\n const preferredGeometry = candidateGeometry(preferred);\n\n const lineCount = textDocument.lineCount;\n const atDocumentEdge = isBackward\n ? head.line < POPOVER_BOUNDARY_LINES\n : head.line >= lineCount - POPOVER_BOUNDARY_LINES;\n const fallbackGeometry = this.#isLineVisible(fallback.anchor.line)\n ? candidateGeometry(fallback)\n : undefined;\n const popoverManager = this.#getPopoverManager();\n const viewport = popoverManager.getPlacementBounds();\n const useFallback =\n fallbackGeometry !== undefined &&\n popoverManager.choosePlacement({\n preferred: preferredGeometry,\n fallback: fallbackGeometry,\n viewport,\n popoverHeight,\n atDocumentEdge,\n placementKey: SELECTION_ACTION_POPOVER_PLACEMENT_KEY,\n }) === 'fallback';\n if (fallbackGeometry === undefined) {\n popoverManager.setPlacement(\n 'preferred',\n SELECTION_ACTION_POPOVER_PLACEMENT_KEY\n );\n }\n const { placeAbove } = useFallback ? fallback : preferred;\n const { left, anchorTop } =\n useFallback && fallbackGeometry !== undefined\n ? fallbackGeometry\n : preferredGeometry;\n // An endpoint outside the virtualized window extends past the viewport\n // rather than making a selection that crosses it look offscreen.\n const selectionTop = isBackward\n ? preferredGeometry.rowTop\n : (fallbackGeometry?.rowTop ?? -Infinity);\n const selectionBottom =\n (isBackward\n ? (fallbackGeometry?.rowTop ?? Infinity)\n : preferredGeometry.rowTop) +\n (primarySelection.end.line > primarySelection.start.line &&\n primarySelection.end.character === 0\n ? 0\n : lineHeight);\n const isSelectionVisible =\n viewport === undefined ||\n (selectionBottom > viewport.top && selectionTop < viewport.bottom);\n\n this.#selectionAction.reposition(\n left,\n anchorTop,\n this.#getGutterWidth(),\n placeAbove,\n isSelectionVisible,\n viewport\n );\n }\n\n // Opens the search panel in the requested mode. If a panel is already open,\n // it switches that panel's mode in place (preserving the current query)\n // rather than recreating it.\n #openSearchPanel(mode: SearchPanelMode) {\n if (this.#searchPanel !== undefined) {\n this.#searchPanel.setMode(mode);\n return;\n }\n this.#renderSearchPanel(mode);\n }\n\n #renderSearchPanel(mode: SearchPanelMode) {\n // cleanup the existing search panel\n this.#searchPanel?.cleanup();\n\n const textDocument = this.#editSession?.document;\n const preElement =\n this.#fileContainer?.shadowRoot?.querySelector<HTMLElement>('pre');\n const selections = this.#selections;\n if (textDocument === undefined || preElement == null) {\n return;\n }\n\n let defaultQuery = '';\n let initialMatch: [number, number] | undefined = undefined;\n\n if (selections !== undefined && selections.length > 0) {\n let primarySelection = selections.at(-1)!;\n if (isCollapsedSelection(primarySelection)) {\n primarySelection = expandCollapsedSelectionToWord(\n textDocument,\n primarySelection\n );\n this.#updateSelections([...selections.slice(0, -1), primarySelection]);\n const selectionText = textDocument.getText(primarySelection);\n if (selectionText !== '' && !selectionText.includes('\\n')) {\n defaultQuery = selectionText;\n initialMatch = [\n textDocument.offsetAt(primarySelection.start),\n textDocument.offsetAt(primarySelection.end),\n ];\n }\n }\n }\n\n const scrollToMatch = (\n [startOffset, endOffset]: MatchRange,\n retainFocus: boolean\n ) => {\n const nextSelection = createSelectionFromAnchorAndFocusOffsets(\n textDocument,\n startOffset,\n endOffset\n );\n this.#updateSelections([nextSelection]);\n // Search counts include matches hidden in collapsed regions; navigating\n // to one reveals it.\n this.#revealLineIfCollapsed(getCaretPosition(nextSelection).line);\n this.#scrollToPrimaryCaret(true); // scroll to the primary caret and don't focus\n this.#retainSearchPanelFocus = retainFocus;\n };\n\n const searchPanel = new SearchPanelWidget({\n textDocument,\n containerElement: preElement,\n defaultQuery,\n mode,\n initialMatch,\n scrollToMatch,\n applyReplace: (edits: ResolvedTextEdit[]) => {\n if (edits.length === 0) {\n return;\n }\n const change = textDocument.applyEdits(\n edits.map((edit) => ({\n range: {\n start: textDocument.positionAt(edit.start),\n end: textDocument.positionAt(edit.end),\n },\n newText: edit.text,\n })),\n true,\n this.#selections\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n undefined,\n this.#applyChangeToLineAnnotations(change),\n { skipSearchRefresh: true }\n );\n }\n },\n onUpdate: (\n allMatches: MatchRange[],\n options?: { syncSelection?: boolean }\n ): MatchRange | undefined => {\n if (allMatches.length === 0) {\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#matches = allMatches;\n if (options?.syncSelection === false) {\n this.#updateSelections(this.#selections ?? []);\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const startOffset = textDocument.offsetAt(primarySelection.start);\n const endOffset = textDocument.offsetAt(primarySelection.end);\n for (const match of allMatches) {\n if (match[0] === startOffset && match[1] === endOffset) {\n return match;\n }\n }\n }\n return undefined;\n }\n\n const primarySelection = this.#selections?.at(-1);\n let searchOffset = 0;\n let nextMatch: MatchRange | undefined;\n if (primarySelection !== undefined) {\n searchOffset = textDocument.offsetAt(primarySelection.start);\n }\n for (const m of allMatches) {\n if (m[0] >= searchOffset) {\n nextMatch = m;\n break;\n }\n }\n if (nextMatch !== undefined) {\n scrollToMatch(nextMatch, true);\n } else {\n this.#updateSelections(this.#selections ?? []);\n }\n return nextMatch;\n },\n onClose: () => {\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n },\n });\n\n this.#searchPanel = searchPanel;\n this.#retainSearchPanelFocus = false;\n }\n\n #getSelectionText() {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return '';\n }\n return getSelectionText(textDocument, selections);\n }\n\n #getSelectionClipboardTexts(): string[] {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return [];\n }\n return getSelectionClipboardTexts(textDocument, selections);\n }\n\n /** Writes both the portable text and the selection pairing metadata. */\n #writeSelectionClipboardData(\n clipboardData: DataTransfer | null,\n text: string,\n selectionTexts: string[]\n ): void {\n if (clipboardData === null) {\n return;\n }\n clipboardData.setData('text', text);\n if (selectionTexts.length > 1) {\n clipboardData.setData(\n MULTI_SELECTION_CLIPBOARD_TYPE,\n JSON.stringify(selectionTexts)\n );\n }\n }\n\n #cutSelectionText(): string {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (\n textDocument === undefined ||\n selections === undefined ||\n selections.length === 0\n ) {\n return '';\n }\n\n if (selections.some((selection) => isCollapsedSelection(selection))) {\n const cut = resolveSelectionCut(textDocument, selections);\n this.#applySelectionCutEdits(cut.edits, cut.nextSelectionOffsets);\n return cut.text;\n }\n\n const text = getSelectionText(textDocument, selections);\n this.#replaceSelectionText('', undefined, true);\n return text;\n }\n\n #applySelectionCutEdits(\n edits: ResolvedTextEdit[],\n nextSelectionOffsets: number[]\n ): void {\n const textDocument = this.#editSession?.document;\n const selections = this.#selections;\n if (\n textDocument === undefined ||\n selections === undefined ||\n edits.length === 0\n ) {\n return;\n }\n\n const change = textDocument.applyResolvedEdits(\n edits,\n true,\n selections,\n undefined,\n true\n );\n if (change === undefined) {\n return;\n }\n\n const nextSelections = nextSelectionOffsets.map<EditorSelection>(\n (offset) => {\n const caret = textDocument.positionAt(offset);\n return {\n start: caret,\n end: caret,\n direction: DirectionNone,\n };\n }\n );\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n\n // replace the selection text\n #replaceSelectionText(\n text: string | string[],\n selections = this.#selections,\n undoBoundary = false,\n textOrder: 'selection' | 'document' = 'selection'\n ) {\n if (selections === undefined) {\n return;\n }\n const textDocument = this.#editSession?.document;\n const primarySelection = selections.at(-1);\n if (textDocument === undefined || primarySelection === undefined) {\n return;\n }\n const { nextSelections, change } =\n Array.isArray(text) && text.length === selections.length\n ? applyTextReplaceToSelections<EType, LAnnotation>(\n textDocument,\n selections,\n text,\n this.#lineAnnotations,\n undoBoundary,\n textOrder\n )\n : applyTextChangeToSelections<EType, LAnnotation>(\n textDocument,\n selections,\n {\n start: textDocument.offsetAt(primarySelection.start),\n end: textDocument.offsetAt(primarySelection.end),\n text: Array.isArray(text) ? text.join(textDocument.eol) : text,\n },\n this.#lineAnnotations,\n undefined,\n undoBoundary\n );\n\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteSelectionText(forward: boolean = false) {\n const selections = this.#selections;\n const textDocument = this.#editSession?.document;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n\n const { nextSelections, change } = applyDeleteCharacterToSelections<\n EType,\n LAnnotation\n >(\n textDocument,\n selections,\n forward,\n this.#lineAnnotations,\n this.#metrics.tabSize\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteSoftLineBackward() {\n const selections = this.#selections;\n const textDocument = this.#editSession?.document;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const getSoftLineStart = this.#isWrap\n ? (line: number, character: number) => {\n const wrapOffsets = this.#wrapLineTextOrWholeLine(line);\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (character >= segmentStart && character <= segmentEnd) {\n return segmentStart;\n }\n }\n return 0;\n }\n : undefined;\n const { nextSelections, change } = applyDeleteSoftLineBackwardToSelections<\n EType,\n LAnnotation\n >(textDocument, selections, getSoftLineStart, this.#lineAnnotations);\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteWordBackward() {\n const selections = this.#selections;\n const textDocument = this.#editSession?.document;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } = applyDeleteWordBackwardToSelections<\n EType,\n LAnnotation\n >(textDocument, selections, this.#lineAnnotations);\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteHardLineForward() {\n const selections = this.#selections;\n const textDocument = this.#editSession?.document;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } = applyDeleteHardLineForwardToSelections<\n EType,\n LAnnotation\n >(textDocument, selections, this.#lineAnnotations);\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #insertTranspose() {\n const selections = this.#selections;\n const textDocument = this.#editSession?.document;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } = applyTransposeToSelections<\n EType,\n LAnnotation\n >(textDocument, selections, this.#lineAnnotations);\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #applyChange(\n change: TextDocumentChange,\n newSelections?: EditorSelection[],\n newLineAnnotations?: EditorLineAnnotation<EType, LAnnotation>[],\n options?: {\n skipSearchRefresh?: boolean;\n skipFocus?: boolean;\n editSource?: 'user' | 'prediction';\n }\n ) {\n // Cancel first so a line-count change, which rebuilds the component's\n // layout, folds the now-empty ghost rows rather than rows keyed by pre-edit\n // lines. Every change ends the prediction anyway.\n if (this.#editPrediction != null) {\n this.#cancelEditPrediction(true);\n }\n const textDocument = this.#editSession?.document;\n if (textDocument !== undefined && this.#carets !== undefined) {\n for (const trackedCaret of this.#carets) {\n trackedCaret.anchorOffset = remapOffsetThroughEdits(\n trackedCaret.anchorOffset,\n change.changes\n );\n trackedCaret.focusOffset = remapOffsetThroughEdits(\n trackedCaret.focusOffset,\n change.changes\n );\n trackedCaret.caret.anchor = textDocument.positionAt(\n trackedCaret.anchorOffset\n );\n trackedCaret.caret.focus = textDocument.positionAt(\n trackedCaret.focusOffset\n );\n }\n }\n // Invalidate layout caches touched by the edit. Clear cached line Y\n // positions from startLine onward when either:\n // - the line count changed (inserts/deletes renumber every later line), or\n // - wrap is on, where editing a line can add or remove a wrapped row and\n // shift the Y of every line after it even though the line count is the\n // same.\n if (change.lineDelta !== 0 || this.#isWrap) {\n for (const line of this.#lineYCache.keys()) {\n if (line >= change.startLine) {\n this.#lineYCache.delete(line);\n }\n }\n }\n // Wrap offsets persist while overflow is 'scroll' (the mode can toggle\n // back before any width/font/document invalidation runs), so edits must\n // invalidate them in every mode, not just while wrap is on. The size\n // guard keeps edits free when nothing was ever measured.\n if (this.#wrapLineOffsetsCache.size > 0) {\n // Lines outside the edited ranges keep both their text and their\n // numbering when no renumbering happened anywhere, so only the rewritten\n // lines need new wrap measurements. A net-zero lineDelta alone is not\n // enough: a multi-edit batch can cancel out (one edit removes a line,\n // another adds one) while still renumbering the lines between the edits.\n // It is sufficient when the batch coalesced into a single range (any\n // renumbered lines sit inside that range), or when every individual edit\n // kept the line count.\n const keepsLineNumbers =\n change.lineDelta === 0 &&\n (change.changedLineRanges.length === 1 ||\n change.changedLineChanges?.every(\n ([, , editLineDelta]) => editLineDelta === 0\n ) === true);\n if (keepsLineNumbers) {\n for (const [rangeStart, rangeEnd] of change.changedLineRanges) {\n for (let line = rangeStart; line <= rangeEnd; line++) {\n this.#wrapLineOffsetsCache.delete(line);\n }\n }\n } else {\n // Renumbering invalidates every cached entry from startLine onward:\n // its keyed line no longer holds the text that was measured.\n for (const line of this.#wrapLineOffsetsCache.keys()) {\n if (line >= change.startLine) {\n this.#wrapLineOffsetsCache.delete(line);\n }\n }\n }\n }\n this.#lastAccessedCharX = undefined;\n\n let renderRange = this.#renderRange;\n let shouldUpdateBuffer: boolean | undefined;\n if (\n renderRange !== undefined &&\n newSelections !== undefined &&\n newSelections.length > 0\n ) {\n const primarySelection = newSelections.at(-1)!;\n const renderRangeEndLine =\n renderRange.startingLine + renderRange.totalLines;\n // When an edit moves the caret to or past the last rendered line — typing\n // Enter at the window's bottom edge, or pasting a few lines there — widen\n // the render range so every new line up to the caret gets a row when\n // #rerender runs below. The widened range is also written back to\n // #renderRange: the next edit reads renderRangeEndLine from it, and\n // #renderCaret/#isLineVisible read it to decide whether to draw the caret.\n // Without persisting, the end line stays stale, a following edit is\n // misclassified as \"past the window\", and its just-typed line is left\n // unrendered until the next scroll re-syncs the range. Only edits that\n // carry a caret reach here (the block is guarded on `selections` above), so\n // a bare programmatic applyEdits with no active selection does not widen.\n //\n // Cap the widening at a multiple of the bounded window the virtualizer\n // last synced. A large insert at the caret — most often a big multi-line\n // paste, or a scripted set-selection-then-edit at scale — can drop the\n // caret far below the window; widening to reach it would make #rerender\n // build a row per inserted line synchronously, defeating virtualization.\n // Past the cap, keep the bounded window and only recompute the buffer\n // spacer — the scroll that follows a focused edit (or the next user scroll\n // when unfocused) renders the far region with a bounded window.\n if (primarySelection.end.line >= renderRangeEndLine) {\n const widenedTotalLines =\n primarySelection.end.line - renderRange.startingLine + 1;\n const maxWidenLines =\n this.#viewportWindowLines === undefined ||\n this.#viewportWindowLines === Infinity\n ? Infinity\n : this.#viewportWindowLines * MAX_EDIT_WIDEN_WINDOW_MULTIPLE;\n // Only widen when the edit actually reaches the rendered window — its\n // dirty lines start at or before the window end. #rerender materializes\n // rows from change.startLine onward, so widening for an edit that starts\n // entirely below the window (e.g. setSelections to an offscreen line\n // then applyEdits before the virtualizer re-syncs) would leave the\n // rows between the window and the edit unbuilt while #isLineVisible\n // reports them visible, mispositioning the new rows and caret until the\n // next scroll.\n if (\n change.startLine <= renderRangeEndLine &&\n widenedTotalLines <= maxWidenLines &&\n // Widening exists to give the caret's line a row; a caret target\n // hidden in a collapsed region can never gain one, so take the\n // buffer-only path instead of building rows toward it.\n this.#isLineRenderable(primarySelection.end.line)\n ) {\n if (primarySelection.end.line > renderRangeEndLine) {\n // The line count grew below the window, so the buffer spacer must be\n // recomputed (preserves the prior behavior for this case).\n shouldUpdateBuffer = true;\n }\n renderRange = { ...renderRange, totalLines: widenedTotalLines };\n this.#renderRange = renderRange;\n } else {\n // The edit is past the cap, or starts below the rendered window: keep\n // the bounded window and only recompute the buffer; the scroll that\n // follows a focused edit (or the next user scroll) renders the far\n // region.\n shouldUpdateBuffer = true;\n }\n }\n }\n this.#rerender(change, newLineAnnotations, renderRange, shouldUpdateBuffer);\n\n if (newSelections != null) {\n // Install the resulting selections before publishing so event state and\n // synchronous getViewState() calls describe the edited document.\n this.#updateSelections(newSelections);\n }\n\n // A completed local edit also supersedes any pending external replacement.\n this.#fileInstance?.__acknowledgeDocumentUpdate();\n this.#checkpointEditSessionState();\n\n this.#recordEditPredictionHistory(change, options?.editSource ?? 'user');\n this.#scheduleEditPrediction();\n\n // Publish the change only after the host renderer agrees with the new\n // document. Consumers may synchronously render the returned annotations,\n // which must not observe the previous line structure.\n this.#emitChange(\n change.changes,\n newLineAnnotations ?? this.#lineAnnotations\n );\n\n if (\n options?.skipSearchRefresh !== true &&\n this.#searchPanel !== undefined &&\n this.#matches !== undefined\n ) {\n this.#searchPanel.updateMatches({ syncSelection: false });\n }\n\n if (newSelections != null) {\n // When skipFocus is set (a programmatic edit on an editor that is not\n // focused) we stop here: focusing or scrolling would pull the caret and\n // viewport toward an editor the user is not interacting with.\n // focus to update the native window selection, and scroll to the caret\n // to mock the 'contenteditable' behavior\n if (options?.skipFocus !== true) {\n // An undo/redo caret restore can land inside a collapsed region.\n const revealTarget = newSelections.at(-1);\n if (revealTarget !== undefined) {\n this.#revealLineIfCollapsed(getCaretPosition(revealTarget).line);\n }\n if (this.#primaryCaretElement !== undefined) {\n requestAnimationFrame(() => {\n this.#primaryCaretElement?.scrollIntoView({\n block: 'nearest',\n inline: 'nearest',\n });\n });\n } else if (newSelections.length > 0) {\n const pos = getCaretPosition(newSelections.at(-1)!);\n this.#scrollToLine(pos.line, pos.character);\n }\n this.focus({ preventScroll: true });\n }\n }\n }\n\n #emitChange(\n changes: EditorChange[],\n lineAnnotations: EditorLineAnnotation<EType, LAnnotation>[] | undefined\n ): void {\n const file = this.getFile();\n const publishChange = this.#publishChange;\n if (file == null || publishChange == null) {\n return;\n }\n publishChange(changes, file, lineAnnotations);\n }\n\n #applyChangeToLineAnnotations(\n change: TextDocumentChange\n ): EditorLineAnnotation<EType, LAnnotation>[] | undefined {\n if (this.#lineAnnotations != null) {\n const nextLineAnnotations = applyDocumentChangeToLineAnnotations(\n change,\n this.#lineAnnotations\n );\n if (nextLineAnnotations != null) {\n this.#editSession?.document?.setLastUndoLineAnnotations(\n this.#lineAnnotations,\n nextLineAnnotations\n );\n return nextLineAnnotations;\n }\n }\n return undefined;\n }\n\n // Returns contiguous document-line ranges that have editable rows in the\n // current render window. Collapsed diff sections create gaps between ranges.\n #getRenderedEditableLineRanges(): [first: number, last: number][] {\n const contentElement = this.#contentElement;\n if (contentElement === undefined) {\n return [];\n }\n const ranges: [first: number, last: number][] = [];\n for (const child of contentElement.children) {\n const el = child as HTMLElement;\n const lineType = el.dataset.lineType;\n const lineNumber = getLineNumberAttr(el);\n if (\n lineNumber === undefined ||\n lineType === undefined ||\n !isLineEditable(lineType)\n ) {\n continue;\n }\n const line = lineNumber - 1;\n const current = ranges.at(-1);\n if (current !== undefined && line <= current[1] + 1) {\n current[1] = Math.max(current[1], line);\n } else {\n ranges.push([line, line]);\n }\n }\n return ranges;\n }\n\n // Whether the File or FileDiff component this editor is attached to\n // currently renders a row for this document line. Virtualized components\n // only render a window of lines, so a line outside that window has no DOM\n // row. Without a render range, every line has a row.\n #isLineInRenderRange(line: number): boolean {\n const renderRange = this.#renderRange;\n return (\n renderRange == null ||\n (line >= renderRange.startingLine &&\n line < renderRange.startingLine + renderRange.totalLines)\n );\n }\n\n #getLineElement(line: number): HTMLElement | undefined {\n let lineElement = this.#lineElementsCache.get(line);\n if (lineElement !== undefined) {\n return lineElement ?? undefined;\n }\n\n const renderRange = this.#renderRange;\n if (!this.#isLineInRenderRange(line)) {\n return undefined;\n }\n\n const contentElement = this.#contentElement;\n if (contentElement === undefined) {\n return undefined;\n }\n\n // check if the line is within the render range (fast)\n if (renderRange !== undefined) {\n const { startingLine } = renderRange;\n const { children } = contentElement;\n for (let i = line - startingLine; i <= children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child === undefined) {\n break;\n }\n const lineNumber = getLineNumberAttr(child);\n const lineType = child.dataset.lineType;\n if (\n lineNumber !== undefined &&\n lineNumber === line + 1 &&\n lineType !== undefined &&\n isLineEditable(lineType)\n ) {\n lineElement = child;\n break;\n }\n }\n }\n\n // fallback to query selector\n lineElement ??= contentElement.querySelector<HTMLElement>(\n `[data-line=\"${line + 1}\"]` +\n (this.#diffSyle === 'unified'\n ? ':not([data-line-type=\"change-deletion\"])'\n : '')\n );\n\n if (lineElement !== undefined) {\n this.#lineElementsCache.set(line, lineElement);\n }\n return lineElement ?? undefined;\n }\n\n #getGutterWidth(): number {\n if (this.#gutterElement === undefined) {\n return 0;\n }\n\n if (this.#gutterWidthCache === undefined) {\n const diffsColumnNumberWidth =\n this.#contentElement?.parentElement?.style.getPropertyValue(\n '--diffs-column-number-width'\n );\n if (\n diffsColumnNumberWidth !== undefined &&\n diffsColumnNumberWidth.length > 2 &&\n diffsColumnNumberWidth.endsWith('px')\n ) {\n this.#gutterWidthCache = parseInt(\n diffsColumnNumberWidth.slice(0, -2),\n 10\n );\n } else {\n this.#gutterWidthCache = this.#gutterElement.offsetWidth;\n }\n }\n\n return this.#gutterWidthCache;\n }\n\n #getContentWidth(): number {\n if (this.#contentElement === undefined) {\n return 0;\n }\n\n if (this.#contentWidthCache === undefined) {\n const diffsColumnContentWidth =\n this.#contentElement.parentElement?.style.getPropertyValue(\n '--diffs-column-content-width'\n );\n if (\n diffsColumnContentWidth !== undefined &&\n diffsColumnContentWidth.length > 2 &&\n diffsColumnContentWidth.endsWith('px')\n ) {\n this.#contentWidthCache = parseFloat(\n diffsColumnContentWidth.slice(0, -2)\n );\n } else {\n this.#contentWidthCache = this.#contentElement.offsetWidth;\n }\n }\n return this.#contentWidthCache;\n }\n\n // get line top(y-coordinate) position\n #getLineY(line: number) {\n const cachedY = this.#lineYCache.get(line);\n if (cachedY !== undefined) {\n return cachedY;\n }\n\n const lineElement = this.#getLineElement(line);\n if (lineElement === undefined) {\n return -1;\n }\n\n // cold(slow) path: measure line top position from DOM (will cause reflow)\n let y = lineElement.offsetTop + this.#metrics.paddingTop;\n y += this.#activeContentOffset?.top ?? 0;\n this.#lineYCache.set(line, y);\n return y;\n }\n\n // Return the visual position for a character. Wrapped lines include the\n // visual line index so carets can be placed on the correct row.\n #getCharX(line: number, char: number): [x: number, wrapLine: number] {\n if (\n this.#lastAccessedCharX !== undefined &&\n this.#lastAccessedCharX[0] === line &&\n this.#lastAccessedCharX[1] === char\n ) {\n return [this.#lastAccessedCharX[2], this.#lastAccessedCharX[3]];\n }\n\n const lineText = this.#editSession?.document?.getLineText(line);\n const offsetLeft = this.#getGutterWidth() + this.#metrics.ch; // gutter width + inline padding (1ch)\n if (lineText === undefined || lineText.length === 0 || char <= 0) {\n return [offsetLeft + (this.#activeContentOffset?.left ?? 0), 0];\n }\n\n const boundedCharacter = snapTextOffsetToUnicodeBoundary(\n lineText,\n Math.min(char, lineText.length)\n );\n const textBeforeCharacter = lineText.slice(0, boundedCharacter);\n const asciiColumns = getExpandedAsciiTextColumns(\n textBeforeCharacter,\n this.#metrics.tabSize\n );\n\n let left = 0;\n let wrapLine = 0;\n if (asciiColumns !== -1) {\n left = offsetLeft + asciiColumns * this.#metrics.ch;\n } else {\n left = offsetLeft + this.#metrics.measureTextWidth(textBeforeCharacter);\n }\n\n if (this.#isWrap) {\n const contentWidth = this.#getContentWidth();\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n const wrapOffsets = this.#wrapLineText(line);\n // undefined means the wrap offsets could not be measured — the\n // content element is detached or has no layout (see #wrapLineText).\n // Fall back to an unwrapped position, and return before the\n // #lastAccessedCharX write below so nothing derived from the\n // unmeasurable DOM gets memoized; the next call re-measures against\n // live layout.\n if (wrapOffsets == null) {\n return [left + (this.#activeContentOffset?.left ?? 0), 0];\n }\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (boundedCharacter <= segmentEnd) {\n wrapLine = w;\n const prefixInSegment = lineText.slice(\n segmentStart,\n boundedCharacter\n );\n const segmentAsciiColumns = getExpandedAsciiTextColumns(\n prefixInSegment,\n this.#metrics.tabSize\n );\n if (segmentAsciiColumns !== -1) {\n left = offsetLeft + segmentAsciiColumns * this.#metrics.ch;\n } else {\n left =\n offsetLeft + this.#metrics.measureTextWidth(prefixInSegment);\n }\n break;\n }\n }\n }\n left += this.#activeContentOffset?.left ?? 0;\n }\n\n if (this.#lastAccessedCharX !== undefined) {\n this.#lastAccessedCharX[0] = line;\n this.#lastAccessedCharX[1] = char;\n this.#lastAccessedCharX[2] = left;\n this.#lastAccessedCharX[3] = wrapLine;\n } else {\n this.#lastAccessedCharX = [line, char, left, wrapLine];\n }\n\n return [left, wrapLine];\n }\n\n // Compute how a logical line of text is broken into visual lines when line\n // wrapping is enabled.\n //\n // Returns undefined when the offsets cannot be measured: measurement works\n // by appending a hidden probe to #contentElement, so a detached or\n // zero-width content element (both occur while a session re-render replaces\n // the code columns) would report \"never wraps\" for any line. That result is\n // never returned or cached — a cached wrong answer would keep placing\n // carets at unwrapped positions until an unrelated edit evicted it. Callers\n // that need best-effort segmentation use #wrapLineTextOrWholeLine;\n // #getCharX propagates the undefined so its own memoization is skipped\n // too.\n #wrapLineText(line: number): Uint32Array | undefined {\n const cachedOffsets = this.#wrapLineOffsetsCache.get(line);\n if (cachedOffsets !== undefined) {\n return cachedOffsets;\n }\n if (this.#wrapLineOffsetsCache.size >= MAX_WRAP_OFFSETS_CACHE_LINES) {\n this.#wrapLineOffsetsCache.clear();\n }\n\n const lineText = this.#editSession?.document?.getLineText(line);\n if (lineText === undefined || lineText.length === 0) {\n const offsets = new Uint32Array([0]);\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n }\n\n const contentElement = this.#contentElement;\n if (contentElement == null || !contentElement.isConnected) {\n return undefined;\n }\n\n const div = h(\n 'div',\n {\n style: {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n boxSizing: 'border-box',\n visibility: 'hidden',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n font: 'inherit',\n paddingInline: '1ch',\n tabSize: this.#metrics.tabSize.toString(),\n },\n textContent: lineText,\n },\n contentElement\n );\n const textNode = div.firstChild as Text;\n const range = document.createRange();\n const starts: number[] = [];\n\n try {\n const divRect = div.getBoundingClientRect();\n if (divRect.width === 0) {\n return undefined;\n }\n const unicodeOffsets = getUnicodeMeasurementOffsets(lineText);\n const wrapLineStartLeft = divRect.left + this.#metrics.ch;\n\n // Measurement steps through grapheme clusters when the text needs\n // Unicode-aware boundaries, single UTF-16 units otherwise. Grapheme\n // `index` spans [graphemeStart(index), graphemeStart(index + 1)).\n const graphemeCount =\n unicodeOffsets === undefined\n ? lineText.length\n : unicodeOffsets.length - 1;\n const graphemeStart = (index: number): number =>\n unicodeOffsets === undefined ? index : unicodeOffsets[index];\n const measureGrapheme = (index: number): DOMRect => {\n range.setStart(textNode, graphemeStart(index));\n range.setEnd(textNode, graphemeStart(index + 1));\n // WebKit adds a zero-width fragment on the previous row at soft wraps;\n // the final fragment belongs to the grapheme's rendered row.\n const clientRects = range.getClientRects();\n return (\n clientRects.item(clientRects.length - 1) ??\n range.getBoundingClientRect()\n );\n };\n\n // A new visual line starts whenever a grapheme's top edge moves below\n // the previous grapheme's top edge. Line breaking assigns graphemes to\n // visual lines in logical order, so tops are non-decreasing with the\n // text offset and each wrap point can be located by binary-searching for\n // the first grapheme below the current visual line — O(wraps * log n)\n // rect measurements instead of one per character.\n starts.push(0);\n let lastTop = measureGrapheme(0).top;\n let searchStart = 1;\n while (searchStart < graphemeCount) {\n let low = searchStart;\n let high = graphemeCount;\n while (low < high) {\n const mid = (low + high) >> 1;\n if (measureGrapheme(mid).top > lastTop) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n if (low >= graphemeCount) {\n break;\n }\n const { left, top } = measureGrapheme(low);\n // Safari can report the first range on a wrapped visual line as\n // starting one character past the visual line start. Use the previous\n // grapheme so segment-local caret math begins at the actual wrap point.\n const startsPastLineStart =\n isSafari() && left - wrapLineStartLeft > this.#metrics.ch / 2;\n starts.push(graphemeStart(startsPastLineStart ? low - 1 : low));\n lastTop = top;\n searchStart = low + 1;\n }\n\n const offsets = new Uint32Array(starts.length + 1);\n for (let i = 0; i < starts.length; i++) {\n offsets[i] = starts[i]!;\n }\n offsets[starts.length] = lineText.length;\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n } finally {\n div.remove();\n }\n }\n\n // #wrapLineText for callers that need usable offsets even when measurement\n // is impossible (undefined): treats the line as one unwrapped segment.\n // Safe because the fallback is never cached — once the content element is\n // measurable again, the same call returns real offsets.\n #wrapLineTextOrWholeLine(line: number): Uint32Array {\n const offsets = this.#wrapLineText(line);\n if (offsets !== undefined) {\n return offsets;\n }\n const length = this.#editSession?.document?.getLineText(line)?.length ?? 0;\n return Uint32Array.of(0, length);\n }\n\n // check if the web selection belongs to editor\n #rangeBelongsToEditor({ startContainer, endContainer }: StaticRange) {\n const contentEl = this.#contentElement;\n if (contentEl === undefined) {\n return false;\n }\n return (\n contentEl.contains(startContainer) && contentEl.contains(endContainer)\n );\n }\n\n // Check whether a line is visible in the currently rendered line window.\n #isLineVisible(line: number): boolean {\n const lineCount = this.#editSession?.document?.lineCount ?? 0;\n if (line < 0 || line >= lineCount) {\n return false;\n }\n return this.#getLineElement(line) !== undefined;\n }\n}\n\ninterface GetEditSessionProps<EType extends EditorType, LAnnotation, Caret> {\n type: EType;\n editStateKey: string | undefined;\n owner: Editor<EType, LAnnotation, Caret>;\n initialState: EditorInitialState<EType, LAnnotation> | undefined;\n previousSession: ManagedEditSession<EType, LAnnotation> | undefined;\n}\n\nfunction getEditSession<EType extends EditorType, LAnnotation, Caret>({\n type,\n editStateKey,\n owner,\n initialState,\n previousSession,\n}: GetEditSessionProps<EType, LAnnotation, Caret>): ManagedEditSession<\n EType,\n LAnnotation\n> {\n if (initialState != null && initialState.type !== type) {\n throw new TypeError(\n `Editor: initialState: a ${initialState.type} state cannot initialize a ${type} editor`\n );\n }\n const initialSession = initialState as\n | ManagedEditSession<EType, LAnnotation>\n | undefined;\n if (editStateKey != null) {\n return EditStateManager.activate(type, editStateKey, owner, initialSession);\n }\n if (initialSession != null) {\n return initialSession;\n }\n if (previousSession != null) {\n return previousSession;\n }\n return (\n type === 'file' ? { type: 'file' } : { type: 'file-diff' }\n ) as ManagedEditSession<EType, LAnnotation>;\n}\n\n// Grid tracks a rendered column child occupies: rows take one, empty buffers\n// take the `data-buffer-size` they were emitted with.\nfunction gridTrackSpan(child: Element | undefined): number {\n if (!(child instanceof HTMLElement)) {\n return 1;\n }\n return Number(child.dataset.bufferSize ?? 1);\n}\n\nfunction isValidEditPredictionPosition<EType extends EditorType, LAnnotation>(\n document: TextDocument<EType, LAnnotation>,\n position: Position | undefined\n): position is Position {\n return (\n position !== undefined &&\n Number.isInteger(position.line) &&\n Number.isInteger(position.character) &&\n position.line >= 0 &&\n position.line < document.lineCount &&\n position.character >= 0 &&\n position.character <= document.getLineLength(position.line)\n );\n}\n\nfunction splitsSurrogatePair(text: string, offset: number): boolean {\n const previous = text.charCodeAt(offset - 1);\n const next = text.charCodeAt(offset);\n return (\n offset > 0 &&\n offset < text.length &&\n previous >= 0xd800 &&\n previous <= 0xdbff &&\n next >= 0xdc00 &&\n next <= 0xdfff\n );\n}\n"],"mappings":"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"}