@simon_he/vue-tui 0.0.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/README.md +142 -30
  2. package/dist/TSelect-BwJJbuTt.js +6089 -0
  3. package/dist/TTree-DK_DQBYm.js +6480 -0
  4. package/dist/agent.cjs +39416 -0
  5. package/dist/agent.d.cts +44 -0
  6. package/dist/agent.d.ts +44 -0
  7. package/dist/agent.js +828 -0
  8. package/dist/ansi-palette-CNXqFciC.js +57 -0
  9. package/dist/ansi-styles.d.ts +200 -0
  10. package/dist/block-source-CKUOnkgT.js +1663 -0
  11. package/dist/cli/headless-renderer.d.ts +29 -0
  12. package/dist/cli/input.d.ts +49 -0
  13. package/dist/cli/node-file-writers.d.ts +13 -0
  14. package/dist/cli/node-module.d.ts +2 -0
  15. package/dist/cli/parse-kitty.d.ts +2 -0
  16. package/dist/cli/parse-mouse.d.ts +2 -0
  17. package/dist/cli/parse-utils.d.ts +14 -0
  18. package/dist/cli/parse-xterm.d.ts +2 -0
  19. package/dist/cli/path-provider-types.d.ts +1 -0
  20. package/dist/cli/path-provider.d.ts +4 -0
  21. package/dist/cli/path-suggest-core.d.ts +1 -0
  22. package/dist/cli/path-suggest.d.ts +15 -0
  23. package/dist/cli/recording.d.ts +4 -0
  24. package/dist/cli/stdin-buffer.d.ts +33 -0
  25. package/dist/cli.cjs +11061 -0
  26. package/dist/cli.d.cts +23 -0
  27. package/dist/cli.d.ts +23 -0
  28. package/dist/cli.js +9875 -0
  29. package/dist/core/ansi/capability.d.ts +20 -0
  30. package/dist/core/ansi/colors.d.ts +41 -0
  31. package/dist/core/ansi/sgr.d.ts +7 -0
  32. package/dist/core/ansi/theme.d.ts +6 -0
  33. package/dist/core/ansi-palette.d.ts +14 -0
  34. package/dist/core/buffer/buffer.d.ts +54 -0
  35. package/dist/core/buffer/width.d.ts +4 -0
  36. package/dist/core/debug-logger.d.ts +18 -0
  37. package/dist/core/hyperlink.d.ts +9 -0
  38. package/dist/core/index.d.ts +4 -0
  39. package/dist/core/path-provider-types.d.ts +24 -0
  40. package/dist/core/path-suggest.d.ts +35 -0
  41. package/dist/core/render-plane.d.ts +3 -0
  42. package/dist/core/terminal/create-terminal.d.ts +8 -0
  43. package/dist/core/terminal/emitter.d.ts +7 -0
  44. package/dist/core/types.d.ts +107 -0
  45. package/dist/core.cjs +3153 -0
  46. package/dist/core.d.cts +14 -0
  47. package/dist/core.d.ts +14 -0
  48. package/dist/core.js +424 -0
  49. package/dist/create-terminal-C2oiWFJU.js +1434 -0
  50. package/dist/create-terminal-app.d.ts +36 -0
  51. package/dist/dom-renderer-BqGijQID.js +1173 -0
  52. package/dist/env-Cl8qmNFN.js +19 -0
  53. package/dist/events/index.d.ts +6 -0
  54. package/dist/events/manager/cli-event-manager.d.ts +22 -0
  55. package/dist/events/manager/event-manager.d.ts +30 -0
  56. package/dist/events/manager/selection-suppression.d.ts +3 -0
  57. package/dist/events/manager/types.d.ts +108 -0
  58. package/dist/events/recording.d.ts +44 -0
  59. package/dist/experimental.cjs +4412 -1641
  60. package/dist/experimental.d.cts +42 -0
  61. package/dist/experimental.d.ts +42 -825
  62. package/dist/experimental.js +31 -7392
  63. package/dist/frame-perf-C6Xfg85O.js +24 -0
  64. package/dist/hyperlink-Bn02UXJb.js +419 -0
  65. package/dist/index.cjs +14765 -17582
  66. package/dist/index.d.cts +35 -0
  67. package/dist/index.d.ts +35 -1528
  68. package/dist/index.js +17 -20026
  69. package/dist/linkify-D_gzn9Xq.js +562 -0
  70. package/dist/markdown.cjs +9321 -7623
  71. package/dist/markdown.d.cts +11 -0
  72. package/dist/markdown.d.ts +11 -112
  73. package/dist/markdown.js +36 -1427
  74. package/dist/observability/cli-latency-node.d.ts +3 -0
  75. package/dist/observability/cli-latency-types.d.ts +41 -0
  76. package/dist/observability/cli-latency.d.ts +3 -0
  77. package/dist/observability/frame-perf-store.d.ts +18 -0
  78. package/dist/observability/frame-perf.d.ts +40 -0
  79. package/dist/observability/perf-sink.d.ts +56 -0
  80. package/dist/observability/trace.d.ts +40 -0
  81. package/dist/observability/tui-profiler.d.ts +33 -0
  82. package/dist/observability.cjs +221 -0
  83. package/dist/observability.d.cts +8 -0
  84. package/dist/observability.d.ts +8 -0
  85. package/dist/observability.js +4 -0
  86. package/dist/path-mnSgEpCm.js +81 -0
  87. package/dist/path-suggest-BNqcuE3-.js +274 -0
  88. package/dist/path-suggest-Dk9TRLh5.js +3 -0
  89. package/dist/{path-suggest-DmrmeueH.js → path-suggest-bvR9SY6Q.js} +86 -18
  90. package/dist/renderer/capabilities.d.ts +13 -0
  91. package/dist/renderer/cli/index.d.ts +2 -0
  92. package/dist/renderer/cli/stdout-metrics.d.ts +18 -0
  93. package/dist/renderer/cli/stdout-renderer.d.ts +48 -0
  94. package/dist/renderer/dom/dom-renderer.d.ts +157 -0
  95. package/dist/renderer/dom/index.d.ts +2 -0
  96. package/dist/renderer/index.d.ts +2 -0
  97. package/dist/renderer-dom.cjs +1505 -0
  98. package/dist/renderer-dom.d.cts +4 -0
  99. package/dist/renderer-dom.d.ts +4 -0
  100. package/dist/renderer-dom.js +7 -0
  101. package/dist/runtime/index.d.ts +36 -0
  102. package/dist/runtime/osc52.d.ts +9 -0
  103. package/dist/runtime-rfcZCyJq.js +1197 -0
  104. package/dist/runtime.cjs +1698 -0
  105. package/dist/runtime.d.cts +9 -0
  106. package/dist/runtime.d.ts +9 -0
  107. package/dist/runtime.js +4 -0
  108. package/dist/selection/terminal-selection.d.ts +123 -0
  109. package/dist/sgr-BmzxEjAO.js +304 -0
  110. package/dist/terminal-selection-DBinO6p5.js +330 -0
  111. package/dist/tlog-theme-qPBt5rge.js +9254 -0
  112. package/dist/trace-CjzYeIxN.js +182 -0
  113. package/dist/utils/env.d.ts +3 -0
  114. package/dist/utils/grapheme.d.ts +5 -0
  115. package/dist/utils/newlines.d.ts +1 -0
  116. package/dist/utils/path.d.ts +7 -0
  117. package/dist/utils/url-safety.d.ts +2 -0
  118. package/dist/vue/agent/view-models.d.ts +98 -0
  119. package/dist/vue/components/TAnchor.d.ts +108 -0
  120. package/dist/vue/components/TBox.d.ts +144 -0
  121. package/dist/vue/components/TCommandPalette.d.ts +587 -0
  122. package/dist/vue/components/TDataTable.d.ts +367 -0
  123. package/dist/vue/components/TDebugOverlay.d.ts +43 -0
  124. package/dist/vue/components/TDialog.d.ts +255 -0
  125. package/dist/vue/components/TFeedback.d.ts +635 -0
  126. package/dist/vue/components/TFlow.d.ts +85 -0
  127. package/dist/vue/components/TForm.d.ts +1230 -0
  128. package/dist/vue/components/TInput.d.ts +545 -0
  129. package/dist/vue/components/TInputBox.d.ts +158 -0
  130. package/dist/vue/components/TJsonEditor.d.ts +165 -0
  131. package/dist/vue/components/TLink.d.ts +239 -0
  132. package/dist/vue/components/TLinkifyText.d.ts +141 -0
  133. package/dist/vue/components/TList.d.ts +119 -0
  134. package/dist/vue/components/TLogLinksPanel.d.ts +238 -0
  135. package/dist/vue/components/TLogMinimap.d.ts +263 -0
  136. package/dist/vue/components/TLogScrollbar.d.ts +236 -0
  137. package/dist/vue/components/TLogSearchBar.d.ts +267 -0
  138. package/dist/vue/components/TLogSearchPager.d.ts +162 -0
  139. package/dist/vue/components/TLogSearchResults.d.ts +200 -0
  140. package/dist/vue/components/TLogView.d.ts +536 -0
  141. package/dist/vue/components/TLogVirtualLinksPanel.d.ts +141 -0
  142. package/dist/vue/components/TLogVirtualSearchResults.d.ts +146 -0
  143. package/dist/vue/components/TMarkdownText.d.ts +134 -0
  144. package/dist/vue/components/TMultilineModal.d.ts +62 -0
  145. package/dist/vue/components/TNavigation.d.ts +324 -0
  146. package/dist/vue/components/TOverlay.d.ts +366 -0
  147. package/dist/vue/components/TPanels.d.ts +244 -0
  148. package/dist/vue/components/TPathPicker.d.ts +213 -0
  149. package/dist/vue/components/TRenderLayer.d.ts +16 -0
  150. package/dist/vue/components/TRenderPlane.d.ts +17 -0
  151. package/dist/vue/components/TSelect.d.ts +335 -0
  152. package/dist/vue/components/TTable.d.ts +317 -0
  153. package/dist/vue/components/TText.d.ts +116 -0
  154. package/dist/vue/components/TThinkingView.d.ts +233 -0
  155. package/dist/vue/components/TToolCallView.d.ts +384 -0
  156. package/dist/vue/components/TTranscriptView.d.ts +221 -0
  157. package/dist/vue/components/TTransition.d.ts +83 -0
  158. package/dist/vue/components/TTree.d.ts +200 -0
  159. package/dist/vue/components/TUserMessageView.d.ts +344 -0
  160. package/dist/vue/components/TView.d.ts +127 -0
  161. package/dist/vue/components/TVirtualList.d.ts +182 -0
  162. package/dist/vue/components/TVirtualMarkdown.d.ts +168 -0
  163. package/dist/vue/components/TVirtualRows.d.ts +247 -0
  164. package/dist/vue/components/TerminalProvider.d.ts +218 -0
  165. package/dist/vue/components/input/host.d.ts +17 -0
  166. package/dist/vue/components/input/plugins/hostPlugin.d.ts +7 -0
  167. package/dist/vue/components/input/plugins/hostPlugin.node.d.ts +15 -0
  168. package/dist/vue/components/input/plugins/mentionUtils.d.ts +17 -0
  169. package/dist/vue/components/input/plugins/nodeMentionPathProvider.d.ts +2 -0
  170. package/dist/vue/components/input/plugins/promptMentionPlugin.d.ts +8 -0
  171. package/dist/vue/components/input/plugins/promptMentionState.d.ts +98 -0
  172. package/dist/vue/components/input/plugins/restrictText.d.ts +27 -0
  173. package/dist/vue/components/input/plugins/types.d.ts +90 -0
  174. package/dist/vue/components/input/utils/inlineText.d.ts +57 -0
  175. package/dist/vue/components/input/utils/inlineTextTokens.d.ts +34 -0
  176. package/dist/vue/components/input/utils/primitives.d.ts +3 -0
  177. package/dist/vue/components/input/utils/wordNavigation.d.ts +6 -0
  178. package/dist/vue/components/link/host.d.ts +15 -0
  179. package/dist/vue/components/list/list-geometry.d.ts +16 -0
  180. package/dist/vue/components/list/list-paint.d.ts +1 -0
  181. package/dist/vue/components/list/scroll-state.d.ts +25 -0
  182. package/dist/vue/components/list/selection-state.d.ts +6 -0
  183. package/dist/vue/components/simple-utils.d.ts +5 -0
  184. package/dist/vue/components/terminal-provider/copy-toast.d.ts +6 -0
  185. package/dist/vue/components/terminal-provider/portals.d.ts +17 -0
  186. package/dist/vue/components/terminal-provider/scheduler.d.ts +29 -0
  187. package/dist/vue/components/terminal-provider/selection-config.d.ts +15 -0
  188. package/dist/vue/components/terminal-provider/utils.d.ts +5 -0
  189. package/dist/vue/composables/use-layout.d.ts +2 -0
  190. package/dist/vue/composables/use-render-node.d.ts +19 -0
  191. package/dist/vue/composables/use-render-stack.d.ts +3 -0
  192. package/dist/vue/composables/use-runtime.d.ts +5 -0
  193. package/dist/vue/composables/use-terminal-node.d.ts +14 -0
  194. package/dist/vue/composables/use-terminal.d.ts +2 -0
  195. package/dist/vue/composables/use-visibility.d.ts +12 -0
  196. package/dist/vue/context.d.ts +153 -0
  197. package/dist/vue/index.d.ts +69 -0
  198. package/dist/vue/injection-key.d.ts +2 -0
  199. package/dist/vue/linkify.d.ts +11 -0
  200. package/dist/vue/log/append-only-log-store.d.ts +2 -0
  201. package/dist/vue/log/tlog-keymap.d.ts +28 -0
  202. package/dist/vue/log/tlog-plugins.d.ts +144 -0
  203. package/dist/vue/log/tlog-session.d.ts +81 -0
  204. package/dist/vue/log/tlog-theme.d.ts +68 -0
  205. package/dist/vue/log/types.d.ts +43 -0
  206. package/dist/vue/log/use-tlog-link-controller.d.ts +31 -0
  207. package/dist/vue/log/use-tlog-retained-index.d.ts +26 -0
  208. package/dist/vue/log/use-tlog-search-controller.d.ts +51 -0
  209. package/dist/vue/log/use-tlog-search-results-page.d.ts +31 -0
  210. package/dist/vue/log/use-tlog-virtual-search-results.d.ts +22 -0
  211. package/dist/vue/markdown/ast.d.ts +3 -0
  212. package/dist/vue/markdown/block-source.d.ts +22 -0
  213. package/dist/vue/markdown/document.d.ts +20 -0
  214. package/dist/vue/markdown/layout.d.ts +21 -0
  215. package/dist/vue/markdown/parser.d.ts +11 -0
  216. package/dist/vue/markdown/render.d.ts +10 -0
  217. package/dist/vue/markdown/theme.d.ts +186 -0
  218. package/dist/vue/markdown/types.d.ts +59 -0
  219. package/dist/vue/overlay.d.ts +27 -0
  220. package/dist/vue/render/context.d.ts +3 -0
  221. package/dist/vue/render/render-manager.d.ts +94 -0
  222. package/dist/vue/router/RouterView.d.ts +25 -0
  223. package/dist/vue/router/composables.d.ts +4 -0
  224. package/dist/vue/router/context.d.ts +4 -0
  225. package/dist/vue/router/router.d.ts +7 -0
  226. package/dist/vue/router/types.d.ts +29 -0
  227. package/dist/vue/scheduler/frame-mailbox.d.ts +55 -0
  228. package/dist/vue/scheduler/frame-scheduler.d.ts +51 -0
  229. package/dist/vue/theme.d.ts +48 -0
  230. package/dist/vue/transcript/hit-regions.d.ts +2 -0
  231. package/dist/vue/transcript/layout.d.ts +20 -0
  232. package/dist/vue/transcript/plain-text.d.ts +2 -0
  233. package/dist/vue/transcript/types.d.ts +122 -0
  234. package/dist/vue/utils/frame-task.d.ts +6 -0
  235. package/dist/vue/utils/rect.d.ts +4 -0
  236. package/dist/vue/utils/row-scroll.d.ts +25 -0
  237. package/dist/vue/utils/style-cache.d.ts +3 -0
  238. package/dist/vue/utils/text.d.ts +27 -0
  239. package/dist/vue/utils/wheel-scroll.d.ts +18 -0
  240. package/dist/vue.cjs +23668 -0
  241. package/dist/vue.d.cts +1 -0
  242. package/dist/vue.d.ts +1 -0
  243. package/dist/vue.js +3957 -0
  244. package/dist/{wheel-scroll-CiNsasLf.js → wheel-scroll-vBRaQ7p-.js} +404 -405
  245. package/package.json +185 -35
  246. package/dist/path-suggest-BeV6n7m-.js +0 -3
  247. package/dist/sgr-Tko2EQ0U.js +0 -484
  248. package/dist/theme-Bsm65g8k.d.ts +0 -32
  249. package/dist/types-ClIV2h1o.d.ts +0 -103
@@ -0,0 +1,1434 @@
1
+ import { charCellWidth, segmentedGraphemes } from "./hyperlink-Bn02UXJb.js";
2
+ import { parseAnsiSgr } from "./sgr-BmzxEjAO.js";
3
+
4
+ //#region src/core/render-plane.ts
5
+ const TERMINAL_RENDER_PLANES = [
6
+ "default",
7
+ "transcript",
8
+ "chrome",
9
+ "overlay"
10
+ ];
11
+
12
+ //#endregion
13
+ //#region src/core/buffer/buffer.ts
14
+ const DEFAULT_STYLE = Object.freeze({});
15
+ const styleCache = new WeakMap();
16
+ const blankCellCache = new WeakMap();
17
+ const continuationCellCache = new WeakMap();
18
+ const cellCacheWidth1 = new WeakMap();
19
+ const cellCacheWidth2 = new WeakMap();
20
+ const MAX_CACHED_CELLS_PER_STYLE = 128;
21
+ function normalizeStyle(style) {
22
+ if (!style) return DEFAULT_STYLE;
23
+ if (Object.isFrozen(style)) return style;
24
+ const cached = styleCache.get(style);
25
+ if (cached) return cached;
26
+ const frozen = Object.freeze({ ...style });
27
+ styleCache.set(style, frozen);
28
+ return frozen;
29
+ }
30
+ function getOrCreateCellCache(map, style) {
31
+ const cached = map.get(style);
32
+ if (cached) return cached;
33
+ const next = new Map();
34
+ map.set(style, next);
35
+ return next;
36
+ }
37
+ function createCell(ch, style, widthProvider) {
38
+ if (ch === " ") return createBlankCell(style);
39
+ const normalizedStyle = normalizeStyle(style);
40
+ const width = charCellWidth(ch, widthProvider);
41
+ const map = width === 2 ? getOrCreateCellCache(cellCacheWidth2, normalizedStyle) : getOrCreateCellCache(cellCacheWidth1, normalizedStyle);
42
+ const cached = map.get(ch);
43
+ if (cached) return cached;
44
+ const cell = {
45
+ ch,
46
+ width,
47
+ style: normalizedStyle
48
+ };
49
+ map.set(ch, cell);
50
+ if (map.size > MAX_CACHED_CELLS_PER_STYLE) map.clear();
51
+ return cell;
52
+ }
53
+ function createBlankCell(style) {
54
+ const normalizedStyle = normalizeStyle(style);
55
+ const cached = blankCellCache.get(normalizedStyle);
56
+ if (cached) return cached;
57
+ const cell = Object.freeze({
58
+ ch: " ",
59
+ width: 1,
60
+ style: normalizedStyle
61
+ });
62
+ blankCellCache.set(normalizedStyle, cell);
63
+ return cell;
64
+ }
65
+ function createContinuationCell(style) {
66
+ const normalizedStyle = normalizeStyle(style);
67
+ const cached = continuationCellCache.get(normalizedStyle);
68
+ if (cached) return cached;
69
+ const cell = Object.freeze({
70
+ ch: "",
71
+ width: 1,
72
+ continuation: true,
73
+ style: normalizedStyle
74
+ });
75
+ continuationCellCache.set(normalizedStyle, cell);
76
+ return cell;
77
+ }
78
+ function createGridBuffer(cols, rows, options = {}) {
79
+ const safeCols = Math.max(0, Math.floor(cols));
80
+ const safeRows = Math.max(0, Math.floor(rows));
81
+ const blank = createBlankCell();
82
+ const grid = Array.from({ length: safeRows }, () => Array.from({ length: safeCols }, () => blank));
83
+ return {
84
+ cols: safeCols,
85
+ rows: safeRows,
86
+ grid,
87
+ gridStart: 0,
88
+ dirtyBits: new Uint8Array(safeRows),
89
+ dirtyCount: safeRows || 0,
90
+ dirtyMin: safeRows ? 0 : Number.POSITIVE_INFINITY,
91
+ dirtyMax: safeRows ? safeRows - 1 : -1,
92
+ dirtyAll: safeRows > 0,
93
+ cursorX: 0,
94
+ cursorY: 0,
95
+ cursorVisible: true,
96
+ cursorStyle: DEFAULT_STYLE,
97
+ scrollback: [],
98
+ scrollbackLimit: 1e3,
99
+ rowPool: [],
100
+ soaFingerprints: null,
101
+ fingerprintFn: null,
102
+ widthProvider: options.widthProvider ?? "default"
103
+ };
104
+ }
105
+ function clamp(n, min, max) {
106
+ return Math.max(min, Math.min(max, n));
107
+ }
108
+ /**
109
+ * Register a fingerprint function on the buffer. This enables SoA fingerprint
110
+ * pre-computation: cell writes will update fingerprints inline, and the renderer
111
+ * can read them via getRowFingerprints() instead of per-cell hash computation.
112
+ */
113
+ function setFingerprintFn(buffer, fn) {
114
+ buffer.fingerprintFn = fn;
115
+ const len = buffer.rows * buffer.cols;
116
+ if (!len) {
117
+ buffer.soaFingerprints = null;
118
+ return;
119
+ }
120
+ buffer.soaFingerprints = new Uint32Array(len);
121
+ for (let y = 0; y < buffer.rows; y++) {
122
+ const row = getBufferRow(buffer, y);
123
+ const physY = physicalRowIndex(buffer, y);
124
+ const base = physY * buffer.cols;
125
+ for (let x = 0; x < buffer.cols; x++) {
126
+ const cell = row[x];
127
+ buffer.soaFingerprints[base + x] = fn(cell.ch, cell.style);
128
+ }
129
+ }
130
+ }
131
+ /**
132
+ * Get pre-computed fingerprints for a logical row as a TypedArray slice.
133
+ * Returns null if fingerprinting is not enabled on this buffer.
134
+ */
135
+ function getRowFingerprints(buffer, y) {
136
+ if (!buffer.soaFingerprints) return null;
137
+ const physY = physicalRowIndex(buffer, y);
138
+ const base = physY * buffer.cols;
139
+ return buffer.soaFingerprints.subarray(base, base + buffer.cols);
140
+ }
141
+ /** Update the SoA fingerprint for a single cell (called inline from putCell/fillRect). */
142
+ function updateCellFingerprint(buffer, physY, x, ch, style) {
143
+ if (!buffer.soaFingerprints || !buffer.fingerprintFn) return;
144
+ buffer.soaFingerprints[physY * buffer.cols + x] = buffer.fingerprintFn(ch, style);
145
+ }
146
+ /** Update SoA fingerprints for a range of cells in a physical row. */
147
+ function updateRangeFingerprint(buffer, physY, x0, x1, ch, style) {
148
+ if (!buffer.soaFingerprints || !buffer.fingerprintFn) return;
149
+ const fp = buffer.fingerprintFn(ch, style);
150
+ const base = physY * buffer.cols;
151
+ for (let x = x0; x < x1; x++) buffer.soaFingerprints[base + x] = fp;
152
+ }
153
+ function physicalRowIndex(buffer, y) {
154
+ return (buffer.gridStart + y) % buffer.rows;
155
+ }
156
+ function getBufferRow(buffer, y) {
157
+ return buffer.grid[physicalRowIndex(buffer, y)];
158
+ }
159
+ function getBufferCell(buffer, x, y) {
160
+ return getBufferRow(buffer, y)[x];
161
+ }
162
+ function markAllDirty(buffer) {
163
+ if (buffer.rows <= 0) return;
164
+ buffer.dirtyAll = true;
165
+ buffer.dirtyCount = buffer.rows;
166
+ buffer.dirtyMin = 0;
167
+ buffer.dirtyMax = buffer.rows - 1;
168
+ }
169
+ function markDirty(buffer, y) {
170
+ if (buffer.dirtyAll) return;
171
+ if (y < 0 || y >= buffer.rows) return;
172
+ if (buffer.dirtyBits[y]) return;
173
+ buffer.dirtyBits[y] = 1;
174
+ buffer.dirtyCount++;
175
+ if (y < buffer.dirtyMin) buffer.dirtyMin = y;
176
+ if (y > buffer.dirtyMax) buffer.dirtyMax = y;
177
+ }
178
+ function clearCellRange(row, startX, endXExclusive) {
179
+ const blank = createBlankCell();
180
+ for (let x = startX; x < endXExclusive; x++) row[x] = blank;
181
+ }
182
+ function clearWideIfOverwriting(row, x) {
183
+ const cell = row[x];
184
+ if (!cell) return;
185
+ if (cell.continuation) {
186
+ if (x - 1 >= 0) row[x - 1] = createBlankCell();
187
+ row[x] = createBlankCell();
188
+ return;
189
+ }
190
+ if (cell.width === 2) {
191
+ row[x] = createBlankCell();
192
+ if (x + 1 < row.length) row[x + 1] = createBlankCell();
193
+ }
194
+ }
195
+ function putCell(buffer, x, y, ch, style) {
196
+ if (y < 0 || y >= buffer.rows) return;
197
+ if (x < 0 || x >= buffer.cols) return;
198
+ const row = getBufferRow(buffer, y);
199
+ const width = charCellWidth(ch, buffer.widthProvider);
200
+ const previous = row[x];
201
+ const next = width === 2 && x + 1 < buffer.cols ? row[x + 1] : void 0;
202
+ const previousWideOverlap = Boolean(previous?.continuation || previous?.width === 2 || next?.continuation || next?.width === 2);
203
+ clearWideIfOverwriting(row, x);
204
+ if (width === 2 && x + 1 < buffer.cols) clearWideIfOverwriting(row, x + 1);
205
+ if (width === 2 && x + 1 >= buffer.cols) {
206
+ const blank = createBlankCell();
207
+ row[x] = blank;
208
+ if (buffer.soaFingerprints) if (previousWideOverlap) recomputeFingerprintsForRows(buffer, y, y + 1);
209
+ else {
210
+ const physY = physicalRowIndex(buffer, y);
211
+ updateCellFingerprint(buffer, physY, x, blank.ch, blank.style);
212
+ }
213
+ markDirty(buffer, y);
214
+ return;
215
+ }
216
+ const cell = createCell(ch, style, buffer.widthProvider);
217
+ row[x] = cell;
218
+ if (width === 2 && x + 1 < buffer.cols) row[x + 1] = createContinuationCell(style);
219
+ if (buffer.soaFingerprints) if (previousWideOverlap) recomputeFingerprintsForRows(buffer, y, y + 1);
220
+ else {
221
+ const physY = physicalRowIndex(buffer, y);
222
+ updateCellFingerprint(buffer, physY, x, cell.ch, cell.style);
223
+ if (width === 2 && x + 1 < buffer.cols) updateCellFingerprint(buffer, physY, x + 1, "", cell.style);
224
+ }
225
+ markDirty(buffer, y);
226
+ }
227
+ function fillRect(buffer, x, y, w, h, ch = " ", style) {
228
+ if (w <= 0 || h <= 0 || buffer.cols === 0 || buffer.rows === 0) return;
229
+ const x0 = clamp(Math.floor(x), 0, buffer.cols);
230
+ const y0 = clamp(Math.floor(y), 0, buffer.rows);
231
+ const x1 = clamp(Math.floor(x + w), 0, buffer.cols);
232
+ const y1 = clamp(Math.floor(y + h), 0, buffer.rows);
233
+ if (x1 <= x0 || y1 <= y0) return;
234
+ const width = charCellWidth(ch, buffer.widthProvider);
235
+ if (width === 1) {
236
+ const fillCell$1 = createCell(ch, style, buffer.widthProvider);
237
+ const blank$1 = createBlankCell();
238
+ for (let yy = y0; yy < y1; yy++) {
239
+ const row = getBufferRow(buffer, yy);
240
+ const clearsLeftWideBase = Boolean(row[x0]?.continuation);
241
+ const clearsRightContinuation = Boolean(x1 < buffer.cols && row[x1]?.continuation);
242
+ if (clearsLeftWideBase) clearWideIfOverwriting(row, x0);
243
+ row.fill(fillCell$1, x0, x1);
244
+ if (clearsRightContinuation) row[x1] = blank$1;
245
+ if (buffer.soaFingerprints) if (clearsLeftWideBase || clearsRightContinuation) recomputeFingerprintsForRows(buffer, yy, yy + 1);
246
+ else {
247
+ const physY = physicalRowIndex(buffer, yy);
248
+ updateRangeFingerprint(buffer, physY, x0, x1, fillCell$1.ch, fillCell$1.style);
249
+ }
250
+ markDirty(buffer, yy);
251
+ }
252
+ return;
253
+ }
254
+ const fillCell = createCell(ch, style, buffer.widthProvider);
255
+ const continuationCell = createContinuationCell(style);
256
+ const blank = createBlankCell();
257
+ for (let yy = y0; yy < y1; yy++) {
258
+ const row = getBufferRow(buffer, yy);
259
+ for (let xx = x0; xx < x1;) {
260
+ clearWideIfOverwriting(row, xx);
261
+ if (xx + 1 >= x1 || xx + 1 >= buffer.cols) {
262
+ row[xx] = blank;
263
+ xx += 1;
264
+ continue;
265
+ }
266
+ clearWideIfOverwriting(row, xx + 1);
267
+ row[xx] = fillCell;
268
+ row[xx + 1] = continuationCell;
269
+ xx += 2;
270
+ }
271
+ recomputeFingerprintsForRows(buffer, yy, yy + 1);
272
+ markDirty(buffer, yy);
273
+ }
274
+ }
275
+ function clearRect(buffer, x, y, w, h) {
276
+ if (buffer.cols === 0 || buffer.rows === 0) return;
277
+ if (x == null || y == null || w == null || h == null) {
278
+ const blank = createBlankCell();
279
+ for (let yy = 0; yy < buffer.rows; yy++) {
280
+ const row = getBufferRow(buffer, yy);
281
+ row.length = buffer.cols;
282
+ for (let xx = 0; xx < buffer.cols; xx++) row[xx] = blank;
283
+ }
284
+ recomputeFingerprintsForRows(buffer, 0, buffer.rows);
285
+ markAllDirty(buffer);
286
+ buffer.cursorX = 0;
287
+ buffer.cursorY = 0;
288
+ return;
289
+ }
290
+ if (w <= 0 || h <= 0) return;
291
+ const x0 = clamp(Math.floor(x), 0, buffer.cols);
292
+ const y0 = clamp(Math.floor(y), 0, buffer.rows);
293
+ const x1 = clamp(Math.floor(x + w), 0, buffer.cols);
294
+ const y1 = clamp(Math.floor(y + h), 0, buffer.rows);
295
+ if (x1 <= x0 || y1 <= y0) return;
296
+ for (let yy = y0; yy < y1; yy++) {
297
+ const row = getBufferRow(buffer, yy);
298
+ if (row[x0]?.continuation) clearWideIfOverwriting(row, x0);
299
+ clearCellRange(row, x0, x1);
300
+ if (x1 < buffer.cols && row[x1]?.continuation) row[x1] = createBlankCell();
301
+ recomputeFingerprintsForRows(buffer, yy, yy + 1);
302
+ markDirty(buffer, yy);
303
+ }
304
+ }
305
+ function takePooledRow(buffer) {
306
+ const row = buffer.rowPool.pop();
307
+ return row ?? null;
308
+ }
309
+ function blankRow(buffer) {
310
+ const pooled = takePooledRow(buffer);
311
+ if (!pooled) return Array.from({ length: buffer.cols }, () => createBlankCell());
312
+ pooled.length = buffer.cols;
313
+ const blank = createBlankCell();
314
+ for (let x = 0; x < buffer.cols; x++) pooled[x] = blank;
315
+ return pooled;
316
+ }
317
+ function recomputeFingerprintsForRows(buffer, startY, endY) {
318
+ if (!buffer.soaFingerprints || !buffer.fingerprintFn) return;
319
+ for (let y = startY; y < endY; y++) {
320
+ const row = getBufferRow(buffer, y);
321
+ const physY = physicalRowIndex(buffer, y);
322
+ const base = physY * buffer.cols;
323
+ for (let x = 0; x < buffer.cols; x++) {
324
+ const cell = row[x];
325
+ buffer.soaFingerprints[base + x] = buffer.fingerprintFn(cell.ch, cell.style);
326
+ }
327
+ }
328
+ }
329
+ function recomputeAllVisibleFingerprints(buffer) {
330
+ recomputeFingerprintsForRows(buffer, 0, buffer.rows);
331
+ }
332
+ function scrollBuffer(buffer, lines) {
333
+ const raw = Math.trunc(lines);
334
+ if (raw === 0 || buffer.rows === 0) return;
335
+ const abs = Math.min(Math.abs(raw), buffer.rows);
336
+ const n = raw > 0 ? abs : -abs;
337
+ if (n > 0) for (let i = 0; i < n; i++) {
338
+ const removedIdx = buffer.gridStart;
339
+ const removed = buffer.grid[removedIdx];
340
+ if (buffer.scrollbackLimit > 0) {
341
+ buffer.scrollback.push(removed);
342
+ if (buffer.scrollback.length > buffer.scrollbackLimit) {
343
+ const excess = buffer.scrollback.length - buffer.scrollbackLimit;
344
+ const dropped = buffer.scrollback.splice(0, excess);
345
+ buffer.rowPool.push(...dropped);
346
+ }
347
+ } else buffer.rowPool.push(removed);
348
+ buffer.gridStart = (buffer.gridStart + 1) % buffer.rows;
349
+ const bottomIdx = (buffer.gridStart + buffer.rows - 1) % buffer.rows;
350
+ buffer.grid[bottomIdx] = blankRow(buffer);
351
+ }
352
+ else for (let i = 0; i < -n; i++) {
353
+ const bottomIdx = (buffer.gridStart + buffer.rows - 1) % buffer.rows;
354
+ const removed = buffer.grid[bottomIdx];
355
+ buffer.rowPool.push(removed);
356
+ buffer.gridStart = (buffer.gridStart - 1 + buffer.rows) % buffer.rows;
357
+ buffer.grid[buffer.gridStart] = blankRow(buffer);
358
+ }
359
+ const inserted = Math.abs(n);
360
+ if (inserted >= buffer.rows) recomputeAllVisibleFingerprints(buffer);
361
+ else if (n > 0) recomputeFingerprintsForRows(buffer, buffer.rows - inserted, buffer.rows);
362
+ else recomputeFingerprintsForRows(buffer, 0, inserted);
363
+ markAllDirty(buffer);
364
+ buffer.cursorY = clamp(buffer.cursorY - n, 0, Math.max(0, buffer.rows - 1));
365
+ }
366
+ function scrollBufferRegion(buffer, startY, endY, lines) {
367
+ const n = Math.trunc(lines);
368
+ if (n === 0 || buffer.rows === 0) return [];
369
+ const start = clamp(Math.floor(startY), 0, buffer.rows);
370
+ const end = clamp(Math.floor(endY), 0, buffer.rows);
371
+ const height = end - start;
372
+ if (height <= 0) return [];
373
+ const absDelta = Math.abs(n);
374
+ const insertedRows = [];
375
+ const replaceRegionWithBlankRows = () => {
376
+ for (let y = start; y < end; y++) {
377
+ const physY = physicalRowIndex(buffer, y);
378
+ buffer.rowPool.push(buffer.grid[physY]);
379
+ buffer.grid[physY] = blankRow(buffer);
380
+ markDirty(buffer, y);
381
+ insertedRows.push(y);
382
+ }
383
+ };
384
+ if (absDelta >= height) {
385
+ replaceRegionWithBlankRows();
386
+ recomputeFingerprintsForRows(buffer, start, end);
387
+ if (buffer.cursorY >= start && buffer.cursorY < end) buffer.cursorY = clamp(buffer.cursorY - n, start, Math.max(start, end - 1));
388
+ return insertedRows;
389
+ }
390
+ const regionRows = [];
391
+ for (let y = start; y < end; y++) regionRows.push(getBufferRow(buffer, y));
392
+ const nextRows = Array.from({ length: height }, () => []);
393
+ if (n > 0) {
394
+ const movedCount = height - n;
395
+ for (let i = 0; i < movedCount; i++) nextRows[i] = regionRows[i + n];
396
+ for (let i = 0; i < n; i++) {
397
+ buffer.rowPool.push(regionRows[i]);
398
+ const y = end - n + i;
399
+ nextRows[movedCount + i] = blankRow(buffer);
400
+ markDirty(buffer, y);
401
+ insertedRows.push(y);
402
+ }
403
+ } else {
404
+ const insertedCount = -n;
405
+ const movedCount = height - insertedCount;
406
+ for (let i = 0; i < insertedCount; i++) {
407
+ buffer.rowPool.push(regionRows[height - insertedCount + i]);
408
+ const y = start + i;
409
+ nextRows[i] = blankRow(buffer);
410
+ markDirty(buffer, y);
411
+ insertedRows.push(y);
412
+ }
413
+ for (let i = 0; i < movedCount; i++) nextRows[insertedCount + i] = regionRows[i];
414
+ }
415
+ for (let i = 0; i < height; i++) {
416
+ const physY = physicalRowIndex(buffer, start + i);
417
+ buffer.grid[physY] = nextRows[i];
418
+ }
419
+ recomputeFingerprintsForRows(buffer, start, end);
420
+ if (buffer.cursorY >= start && buffer.cursorY < end) buffer.cursorY = clamp(buffer.cursorY - n, start, Math.max(start, end - 1));
421
+ return insertedRows;
422
+ }
423
+ function resizeBuffer(buffer, cols, rows) {
424
+ const nextCols = Math.max(0, Math.floor(cols));
425
+ const nextRows = Math.max(0, Math.floor(rows));
426
+ if (nextCols === buffer.cols && nextRows === buffer.rows) return;
427
+ const blank = createBlankCell();
428
+ const nextGrid = Array.from({ length: nextRows }, () => Array.from({ length: nextCols }, () => blank));
429
+ const copyRows = Math.min(buffer.rows, nextRows);
430
+ const copyCols = Math.min(buffer.cols, nextCols);
431
+ for (let y = 0; y < copyRows; y++) {
432
+ const src = getBufferRow(buffer, y);
433
+ const dst = nextGrid[y];
434
+ for (let x = 0; x < copyCols; x++) dst[x] = src[x];
435
+ }
436
+ if (nextCols > 0) for (let y = 0; y < nextGrid.length; y++) {
437
+ const row = nextGrid[y];
438
+ for (let x = 0; x < nextCols; x++) {
439
+ const cell = row[x];
440
+ if (cell.continuation) {
441
+ if (x === 0 || row[x - 1]?.width !== 2 || row[x - 1]?.continuation) row[x] = blank;
442
+ continue;
443
+ }
444
+ if (cell.width === 2 && (x + 1 >= nextCols || !row[x + 1]?.continuation)) row[x] = blank;
445
+ }
446
+ }
447
+ for (let y = 0; y < buffer.rows; y++) buffer.rowPool.push(getBufferRow(buffer, y));
448
+ buffer.grid = nextGrid;
449
+ buffer.gridStart = 0;
450
+ buffer.cols = nextCols;
451
+ buffer.rows = nextRows;
452
+ buffer.dirtyBits = new Uint8Array(nextRows);
453
+ buffer.dirtyCount = nextRows || 0;
454
+ buffer.dirtyMin = nextRows ? 0 : Number.POSITIVE_INFINITY;
455
+ buffer.dirtyMax = nextRows ? nextRows - 1 : -1;
456
+ buffer.dirtyAll = nextRows > 0;
457
+ buffer.cursorX = clamp(buffer.cursorX, 0, Math.max(0, nextCols));
458
+ buffer.cursorY = clamp(buffer.cursorY, 0, Math.max(0, nextRows - 1));
459
+ if (buffer.fingerprintFn) {
460
+ const len = nextRows * nextCols;
461
+ if (len > 0) {
462
+ buffer.soaFingerprints = new Uint32Array(len);
463
+ for (let y = 0; y < nextRows; y++) {
464
+ const row = nextGrid[y];
465
+ const base = y * nextCols;
466
+ for (let x = 0; x < nextCols; x++) {
467
+ const cell = row[x];
468
+ buffer.soaFingerprints[base + x] = buffer.fingerprintFn(cell.ch, cell.style);
469
+ }
470
+ }
471
+ } else buffer.soaFingerprints = null;
472
+ }
473
+ }
474
+ function snapshotText(buffer) {
475
+ const out = [];
476
+ for (let y = 0; y < buffer.rows; y++) {
477
+ const row = getBufferRow(buffer, y);
478
+ out.push(row.map((cell) => cell.continuation ? " " : cell.ch || " ").join(""));
479
+ }
480
+ return out;
481
+ }
482
+
483
+ //#endregion
484
+ //#region src/core/terminal/emitter.ts
485
+ const emitterListeners = new WeakMap();
486
+ var Emitter = class {
487
+ constructor() {
488
+ emitterListeners.set(this, new Map());
489
+ }
490
+ getListeners() {
491
+ return emitterListeners.get(this);
492
+ }
493
+ on(event, cb) {
494
+ const listeners = this.getListeners();
495
+ let set = listeners.get(event);
496
+ if (!set) {
497
+ set = new Set();
498
+ listeners.set(event, set);
499
+ }
500
+ set.add(cb);
501
+ return () => {
502
+ set.delete(cb);
503
+ if (set.size === 0) listeners.delete(event);
504
+ };
505
+ }
506
+ emit(event, payload) {
507
+ const set = this.getListeners().get(event);
508
+ if (!set) return;
509
+ for (const cb of set) cb(payload);
510
+ }
511
+ clear() {
512
+ this.getListeners().clear();
513
+ }
514
+ };
515
+
516
+ //#endregion
517
+ //#region src/core/terminal/create-terminal.ts
518
+ function isControlChar(ch) {
519
+ return ch === "\n" || ch === "\r" || ch === " ";
520
+ }
521
+ function mergePlanes(prev, next) {
522
+ if (!prev?.length) return next?.length ? [...next] : null;
523
+ if (!next?.length) return prev;
524
+ const merged = new Set(prev);
525
+ for (const plane of next) merged.add(plane);
526
+ return Array.from(merged);
527
+ }
528
+ const TERMINAL_PLANE_INTERNALS = Symbol.for("@simon_he/vue-tui:v1:terminal-plane-internals");
529
+ function createCoverage(cols, rows) {
530
+ return Array.from({ length: rows }, () => new Uint8Array(cols));
531
+ }
532
+ function resizeCoverage(prev, cols, rows) {
533
+ const next = createCoverage(cols, rows);
534
+ const copyRows = Math.min(prev.length, rows);
535
+ for (let y = 0; y < copyRows; y++) {
536
+ const src = prev[y];
537
+ const dst = next[y];
538
+ dst.set(src.subarray(0, Math.min(src.length, cols)));
539
+ }
540
+ return next;
541
+ }
542
+ function setBufferClean(buffer) {
543
+ buffer.dirtyBits.fill(0);
544
+ buffer.dirtyCount = 0;
545
+ buffer.dirtyMin = Number.POSITIVE_INFINITY;
546
+ buffer.dirtyMax = -1;
547
+ buffer.dirtyAll = false;
548
+ }
549
+ function createPlaneState(cols, rows, widthProvider) {
550
+ const buffer = createGridBuffer(cols, rows, { widthProvider });
551
+ setBufferClean(buffer);
552
+ buffer.cursorVisible = false;
553
+ return {
554
+ buffer,
555
+ coverage: createCoverage(cols, rows)
556
+ };
557
+ }
558
+ function collectAndClearDirtyRows(buffer) {
559
+ if (buffer.rows === 0) return [];
560
+ if (buffer.dirtyAll) {
561
+ buffer.dirtyAll = false;
562
+ buffer.dirtyBits.fill(0);
563
+ buffer.dirtyCount = 0;
564
+ buffer.dirtyMin = Number.POSITIVE_INFINITY;
565
+ buffer.dirtyMax = -1;
566
+ return null;
567
+ }
568
+ if (buffer.dirtyCount === 0) return [];
569
+ const out = [];
570
+ const start = Math.max(0, buffer.dirtyMin);
571
+ const end = Math.min(buffer.rows - 1, buffer.dirtyMax);
572
+ for (let y = start; y <= end; y++) if (buffer.dirtyBits[y]) {
573
+ buffer.dirtyBits[y] = 0;
574
+ out.push(y);
575
+ if (out.length === buffer.dirtyCount) break;
576
+ }
577
+ buffer.dirtyCount = 0;
578
+ buffer.dirtyMin = Number.POSITIVE_INFINITY;
579
+ buffer.dirtyMax = -1;
580
+ return out;
581
+ }
582
+ function peekDirtyRows(buffer) {
583
+ if (buffer.rows === 0) return [];
584
+ if (buffer.dirtyAll) return null;
585
+ if (buffer.dirtyCount === 0) return [];
586
+ const out = [];
587
+ const start = Math.max(0, buffer.dirtyMin);
588
+ const end = Math.min(buffer.rows - 1, buffer.dirtyMax);
589
+ for (let y = start; y <= end; y++) if (buffer.dirtyBits[y]) {
590
+ out.push(y);
591
+ if (out.length === buffer.dirtyCount) break;
592
+ }
593
+ return out;
594
+ }
595
+ function clearPlaneCoverageRow(state, y) {
596
+ if (y < 0 || y >= state.buffer.rows) return;
597
+ const row = getBufferRow(state.buffer, y);
598
+ const blank = createBlankCell();
599
+ row.length = state.buffer.cols;
600
+ for (let x = 0; x < state.buffer.cols; x++) row[x] = blank;
601
+ state.coverage[y]?.fill(0);
602
+ markDirty(state.buffer, y);
603
+ }
604
+ function markPlaneCoverageRange(state, x0, y0, x1, y1, value) {
605
+ for (let y = y0; y < y1; y++) {
606
+ const row = state.coverage[y];
607
+ if (!row) continue;
608
+ row.fill(value, x0, x1);
609
+ }
610
+ }
611
+ function markPlaneCoverageForPut(state, x, y, ch, prevCell) {
612
+ const row = state.coverage[y];
613
+ if (!row) return;
614
+ if (prevCell?.continuation && x > 0) row[x - 1] = 1;
615
+ if (prevCell?.width === 2 && x + 1 < row.length) row[x + 1] = 1;
616
+ row[x] = 1;
617
+ if (ch !== " " && x + 1 < row.length) {
618
+ const next = getBufferCell(state.buffer, x, y);
619
+ if (next.width === 2) row[x + 1] = 1;
620
+ }
621
+ }
622
+ function scrollPlaneCoverage(state, lines) {
623
+ const n = Math.trunc(lines);
624
+ if (n === 0 || state.coverage.length === 0) return;
625
+ const rows = state.coverage.length;
626
+ const cols = state.buffer.cols;
627
+ if (Math.abs(n) >= rows) {
628
+ for (const row of state.coverage) row.fill(0);
629
+ return;
630
+ }
631
+ if (n > 0) {
632
+ state.coverage.splice(0, n);
633
+ for (let i = 0; i < n; i++) state.coverage.push(new Uint8Array(cols));
634
+ return;
635
+ }
636
+ state.coverage.splice(rows + n, -n);
637
+ for (let i = 0; i < -n; i++) state.coverage.unshift(new Uint8Array(cols));
638
+ }
639
+ function scrollPlaneCoverageRegion(state, startY, endY, lines) {
640
+ const n = Math.trunc(lines);
641
+ if (n === 0 || state.coverage.length === 0) return;
642
+ const start = Math.max(0, Math.min(state.coverage.length, Math.floor(startY)));
643
+ const end = Math.max(0, Math.min(state.coverage.length, Math.floor(endY)));
644
+ const height = end - start;
645
+ if (height <= 0) return;
646
+ const cols = state.buffer.cols;
647
+ if (Math.abs(n) >= height) {
648
+ for (let y = start; y < end; y++) state.coverage[y] = new Uint8Array(cols);
649
+ return;
650
+ }
651
+ const region = state.coverage.slice(start, end);
652
+ const next = Array.from({ length: height }, () => new Uint8Array(0));
653
+ if (n > 0) {
654
+ const movedCount = height - n;
655
+ for (let i = 0; i < movedCount; i++) next[i] = region[i + n];
656
+ for (let i = 0; i < n; i++) next[movedCount + i] = new Uint8Array(cols);
657
+ } else {
658
+ const insertedCount = -n;
659
+ const movedCount = height - insertedCount;
660
+ for (let i = 0; i < insertedCount; i++) next[i] = new Uint8Array(cols);
661
+ for (let i = 0; i < movedCount; i++) next[insertedCount + i] = region[i];
662
+ }
663
+ for (let i = 0; i < height; i++) state.coverage[start + i] = next[i];
664
+ }
665
+ function resizePlaneState(state, cols, rows) {
666
+ resizeBuffer(state.buffer, cols, rows);
667
+ state.coverage = resizeCoverage(state.coverage, state.buffer.cols, state.buffer.rows);
668
+ }
669
+ function normalizeDirtyRows(rows, totalRows) {
670
+ if (rows === null) return null;
671
+ if (rows.length === 0) return rows;
672
+ const out = [];
673
+ for (const y of rows) {
674
+ const yy = Math.floor(y);
675
+ if (yy < 0 || yy >= totalRows) continue;
676
+ if (out[out.length - 1] === yy) continue;
677
+ out.push(yy);
678
+ }
679
+ return out;
680
+ }
681
+ function getPlaneTerminal(terminal, plane) {
682
+ const internals = terminal[TERMINAL_PLANE_INTERNALS];
683
+ return internals?.getPlaneTerminal(plane) ?? terminal;
684
+ }
685
+ function resetPlaneRowsForRender(terminal, plane, dirtyRows) {
686
+ const internals = terminal[TERMINAL_PLANE_INTERNALS];
687
+ internals?.resetRowsForRender(plane, dirtyRows);
688
+ }
689
+ function scrollPlaneRows(terminal, plane, startY, endY, lines) {
690
+ const internals = terminal[TERMINAL_PLANE_INTERNALS];
691
+ internals?.scrollRows(plane, startY, endY, lines);
692
+ }
693
+ function createTerminal(opts) {
694
+ const widthProvider = opts.widthProvider ?? "default";
695
+ const emitter = new Emitter();
696
+ const compositeBuffer = createGridBuffer(opts.cols, opts.rows, { widthProvider });
697
+ const planeStates = new Map();
698
+ let disposed = false;
699
+ let batchingDepth = 0;
700
+ let pendingCommit = false;
701
+ let pendingCommitAllPlanes = false;
702
+ let pendingCommitPlanes = null;
703
+ const pendingPlaneScrollOps = new Map();
704
+ const planeTerminals = new Map();
705
+ let base;
706
+ compositeBuffer.cursorVisible = false;
707
+ function assertNotDisposed() {
708
+ if (disposed) throw new Error("Terminal is disposed");
709
+ }
710
+ function getPlaneState(plane) {
711
+ let state = planeStates.get(plane);
712
+ if (!state) {
713
+ state = createPlaneState(compositeBuffer.cols, compositeBuffer.rows, widthProvider);
714
+ planeStates.set(plane, state);
715
+ }
716
+ return state;
717
+ }
718
+ function setCursorForPlane(plane, x, y, visible = true) {
719
+ const state = getPlaneState(plane);
720
+ state.buffer.cursorX = Math.max(0, Math.min(state.buffer.cols, Math.floor(x)));
721
+ state.buffer.cursorY = Math.max(0, Math.min(state.buffer.rows ? state.buffer.rows - 1 : 0, Math.floor(y)));
722
+ state.buffer.cursorVisible = visible;
723
+ markDirty(state.buffer, state.buffer.cursorY);
724
+ }
725
+ function putForPlane(plane, x, y, ch, style) {
726
+ const state = getPlaneState(plane);
727
+ if (y < 0 || y >= state.buffer.rows || x < 0 || x >= state.buffer.cols) return;
728
+ const prevCell = getBufferCell(state.buffer, x, y);
729
+ putCell(state.buffer, x, y, ch, style);
730
+ markPlaneCoverageForPut(state, x, y, ch, prevCell);
731
+ }
732
+ function writeAtForPlane(plane, text, x, y, style) {
733
+ const state = getPlaneState(plane);
734
+ let cx = x;
735
+ let cy = y;
736
+ if (state.buffer.cols === 0 || state.buffer.rows === 0) return {
737
+ x: cx,
738
+ y: cy
739
+ };
740
+ const writeChar = (ch) => {
741
+ if (isControlChar(ch)) {
742
+ if (ch === "\n") {
743
+ cx = 0;
744
+ cy += 1;
745
+ if (cy >= state.buffer.rows) {
746
+ scrollBuffer(state.buffer, 1);
747
+ scrollPlaneCoverage(state, 1);
748
+ cy = state.buffer.rows - 1;
749
+ }
750
+ } else if (ch === "\r") cx = 0;
751
+ else if (ch === " ") {
752
+ const tabSize = 4;
753
+ const next = Math.min(state.buffer.cols, cx + (tabSize - cx % tabSize));
754
+ for (; cx < next; cx++) putForPlane(plane, cx, cy, " ", style);
755
+ }
756
+ return true;
757
+ }
758
+ if (cy < 0 || cy >= state.buffer.rows) return false;
759
+ if (cx >= state.buffer.cols) {
760
+ cx = 0;
761
+ cy += 1;
762
+ }
763
+ if (cy >= state.buffer.rows) {
764
+ scrollBuffer(state.buffer, 1);
765
+ scrollPlaneCoverage(state, 1);
766
+ cy = state.buffer.rows - 1;
767
+ }
768
+ putForPlane(plane, cx, cy, ch, style);
769
+ const width = ch === " " ? 1 : getBufferCell(state.buffer, cx, cy).width || 1;
770
+ cx += width;
771
+ return true;
772
+ };
773
+ const segments = segmentedGraphemes(text);
774
+ if (segments) {
775
+ for (const seg of segments) if (!writeChar(seg.segment)) break;
776
+ return {
777
+ x: cx,
778
+ y: cy
779
+ };
780
+ }
781
+ let i = 0;
782
+ for (; i < text.length; i++) {
783
+ const code = text.charCodeAt(i);
784
+ if (code > 127) break;
785
+ if (!writeChar(text[i])) return {
786
+ x: cx,
787
+ y: cy
788
+ };
789
+ }
790
+ if (i < text.length) {
791
+ const rest = text.slice(i);
792
+ const restSegments = segmentedGraphemes(rest);
793
+ if (restSegments) {
794
+ for (const seg of restSegments) if (!writeChar(seg.segment)) break;
795
+ } else for (const ch of rest) if (!writeChar(ch)) break;
796
+ }
797
+ return {
798
+ x: cx,
799
+ y: cy
800
+ };
801
+ }
802
+ function clearForPlane(plane, x, y, w, h) {
803
+ const state = getPlaneState(plane);
804
+ clearRect(state.buffer, x, y, w, h);
805
+ if (x == null || y == null || w == null || h == null) {
806
+ for (const row of state.coverage) row.fill(1);
807
+ return;
808
+ }
809
+ if (w <= 0 || h <= 0) return;
810
+ const x0 = Math.max(0, Math.min(state.buffer.cols, Math.floor(x)));
811
+ const y0 = Math.max(0, Math.min(state.buffer.rows, Math.floor(y)));
812
+ const x1 = Math.max(0, Math.min(state.buffer.cols, Math.floor(x + w)));
813
+ const y1 = Math.max(0, Math.min(state.buffer.rows, Math.floor(y + h)));
814
+ if (x1 <= x0 || y1 <= y0) return;
815
+ markPlaneCoverageRange(state, x0, y0, x1, y1, 1);
816
+ }
817
+ function fillForPlane(plane, x, y, w, h, ch, style) {
818
+ const state = getPlaneState(plane);
819
+ fillRect(state.buffer, x, y, w, h, ch ?? " ", style);
820
+ if (w <= 0 || h <= 0 || state.buffer.cols === 0 || state.buffer.rows === 0) return;
821
+ const x0 = Math.max(0, Math.min(state.buffer.cols, Math.floor(x)));
822
+ const y0 = Math.max(0, Math.min(state.buffer.rows, Math.floor(y)));
823
+ const x1 = Math.max(0, Math.min(state.buffer.cols, Math.floor(x + w)));
824
+ const y1 = Math.max(0, Math.min(state.buffer.rows, Math.floor(y + h)));
825
+ if (x1 <= x0 || y1 <= y0) return;
826
+ markPlaneCoverageRange(state, x0, y0, x1, y1, 1);
827
+ }
828
+ function scrollForPlane(plane, lines) {
829
+ const state = getPlaneState(plane);
830
+ scrollBuffer(state.buffer, lines);
831
+ scrollPlaneCoverage(state, lines);
832
+ }
833
+ function normalizeScrollOperation(startY, endY, delta, totalRows) {
834
+ const start = Math.max(0, Math.min(totalRows, Math.floor(startY)));
835
+ const end = Math.max(0, Math.min(totalRows, Math.floor(endY)));
836
+ const height = end - start;
837
+ const lines = Math.trunc(delta);
838
+ if (height <= 0 || lines === 0 || Math.abs(lines) >= height) return null;
839
+ return {
840
+ startY: start,
841
+ endY: end,
842
+ delta: lines
843
+ };
844
+ }
845
+ function recordPendingScrollOp(plane, op) {
846
+ const list = pendingPlaneScrollOps.get(plane) ?? [];
847
+ const last = list[list.length - 1];
848
+ if (last && last.startY === op.startY && last.endY === op.endY && Math.sign(last.delta) === Math.sign(op.delta)) {
849
+ const next = normalizeScrollOperation(op.startY, op.endY, last.delta + op.delta, compositeBuffer.rows);
850
+ if (next) list[list.length - 1] = next;
851
+ else list.push(op);
852
+ } else list.push(op);
853
+ pendingPlaneScrollOps.set(plane, list);
854
+ }
855
+ function takePendingScrollOps(planes) {
856
+ const planesToTake = planes?.length ? planes : TERMINAL_RENDER_PLANES;
857
+ const out = [];
858
+ for (const plane of planesToTake) {
859
+ const ops = pendingPlaneScrollOps.get(plane);
860
+ if (!ops?.length) continue;
861
+ pendingPlaneScrollOps.delete(plane);
862
+ for (const op of ops) out.push({
863
+ plane,
864
+ ...op
865
+ });
866
+ }
867
+ return out.length ? out : null;
868
+ }
869
+ function higherPlanesFor(plane) {
870
+ const planeIndex = TERMINAL_RENDER_PLANES.indexOf(plane);
871
+ if (planeIndex < 0) return [];
872
+ return TERMINAL_RENDER_PLANES.slice(planeIndex + 1);
873
+ }
874
+ function higherPlaneCoverageKind(plane, y) {
875
+ const higherPlanes = higherPlanesFor(plane);
876
+ if (!higherPlanes.length || y < 0 || y >= compositeBuffer.rows) return 0;
877
+ let covered = 0;
878
+ for (let x = 0; x < compositeBuffer.cols; x++) {
879
+ let cellCovered = false;
880
+ for (const higherPlane of higherPlanes) {
881
+ const state = planeStates.get(higherPlane);
882
+ if (state?.coverage[y]?.[x]) {
883
+ cellCovered = true;
884
+ break;
885
+ }
886
+ }
887
+ if (cellCovered) covered++;
888
+ }
889
+ if (covered === 0) return 0;
890
+ if (covered >= compositeBuffer.cols) return 2;
891
+ return 1;
892
+ }
893
+ function addAffectedRows(out, op) {
894
+ for (let y = op.startY; y < op.endY; y++) out.add(y);
895
+ }
896
+ function areDisjointSorted(ops) {
897
+ for (let i = 1; i < ops.length; i++) if (ops[i - 1].endY > ops[i].startY) return false;
898
+ return true;
899
+ }
900
+ function groupedPendingScrollOps(pendingOps) {
901
+ const grouped = new Map();
902
+ for (const pending of pendingOps) {
903
+ const list = grouped.get(pending.plane) ?? [];
904
+ list.push({
905
+ startY: pending.startY,
906
+ endY: pending.endY,
907
+ delta: pending.delta
908
+ });
909
+ grouped.set(pending.plane, list);
910
+ }
911
+ return grouped;
912
+ }
913
+ function prepareCompositeScrollOps(pendingOps) {
914
+ if (!pendingOps?.length) return {
915
+ scrollOperations: null,
916
+ extraDirtyRows: []
917
+ };
918
+ const scrollOperations = [];
919
+ const extraDirtyRows = new Set();
920
+ const grouped = groupedPendingScrollOps(pendingOps);
921
+ for (const [plane, ops] of grouped) {
922
+ const sorted = [...ops].sort((a, b) => a.startY - b.startY || a.endY - b.endY);
923
+ if (!areDisjointSorted(sorted)) {
924
+ for (const op of ops) addAffectedRows(extraDirtyRows, op);
925
+ continue;
926
+ }
927
+ for (const op of sorted) {
928
+ const blockedRows = new Set();
929
+ const partiallyBlockedRows = new Set();
930
+ for (let y = op.startY; y < op.endY; y++) {
931
+ const coverageKind = higherPlaneCoverageKind(plane, y);
932
+ if (coverageKind === 0) continue;
933
+ blockedRows.add(y);
934
+ if (coverageKind === 1) partiallyBlockedRows.add(y);
935
+ }
936
+ if (!blockedRows.size) {
937
+ scrollOperations.push({
938
+ startY: op.startY,
939
+ endY: op.endY,
940
+ delta: op.delta
941
+ });
942
+ continue;
943
+ }
944
+ const absDelta = Math.abs(op.delta);
945
+ for (let y = op.startY; y < op.endY; y++) if (partiallyBlockedRows.has(y)) extraDirtyRows.add(y);
946
+ let bandStart = -1;
947
+ const flushBand = (bandEnd) => {
948
+ if (bandStart < 0 || bandEnd <= bandStart) return;
949
+ const bandHeight = bandEnd - bandStart;
950
+ if (absDelta >= bandHeight) {
951
+ for (let y = bandStart; y < bandEnd; y++) extraDirtyRows.add(y);
952
+ bandStart = -1;
953
+ return;
954
+ }
955
+ scrollOperations.push({
956
+ startY: bandStart,
957
+ endY: bandEnd,
958
+ delta: op.delta
959
+ });
960
+ if (op.delta > 0) for (let y = bandEnd - absDelta; y < bandEnd; y++) extraDirtyRows.add(y);
961
+ else for (let y = bandStart; y < bandStart + absDelta; y++) extraDirtyRows.add(y);
962
+ bandStart = -1;
963
+ };
964
+ for (let y = op.startY; y < op.endY; y++) {
965
+ if (blockedRows.has(y)) {
966
+ flushBand(y);
967
+ continue;
968
+ }
969
+ if (bandStart < 0) bandStart = y;
970
+ }
971
+ flushBand(op.endY);
972
+ }
973
+ }
974
+ return {
975
+ scrollOperations: scrollOperations.length ? scrollOperations : null,
976
+ extraDirtyRows: Array.from(extraDirtyRows).sort((a, b) => a - b)
977
+ };
978
+ }
979
+ function dirtyRowsCoverRange(rows, startY, endY) {
980
+ if (rows === null) return true;
981
+ if (!rows.length) return false;
982
+ let idx = 0;
983
+ while (idx < rows.length && (rows[idx] ?? -1) < startY) idx++;
984
+ for (let y = startY; y < endY; y++) {
985
+ if (rows[idx] !== y) return false;
986
+ idx++;
987
+ }
988
+ return true;
989
+ }
990
+ function dropScrollOpsCoveredByDirtyRows(ops, dirtyRows) {
991
+ if (!ops?.length) return null;
992
+ const next = ops.filter((op) => !dirtyRowsCoverRange(dirtyRows, op.startY, op.endY));
993
+ return next.length ? next : null;
994
+ }
995
+ function scrollRowsForPlane(plane, startY, endY, lines) {
996
+ const state = getPlaneState(plane);
997
+ const op = normalizeScrollOperation(startY, endY, lines, state.buffer.rows);
998
+ if (!op) return;
999
+ scrollBufferRegion(state.buffer, op.startY, op.endY, op.delta);
1000
+ scrollPlaneCoverageRegion(state, op.startY, op.endY, op.delta);
1001
+ recordPendingScrollOp(plane, op);
1002
+ }
1003
+ function composeRows(rows, planes = TERMINAL_RENDER_PLANES) {
1004
+ const blank = createBlankCell();
1005
+ const fpFn = compositeBuffer.fingerprintFn;
1006
+ const fpArr = compositeBuffer.soaFingerprints;
1007
+ const rowList = rows ?? Array.from({ length: compositeBuffer.rows }, (_, index) => index);
1008
+ for (const y of rowList) {
1009
+ if (y < 0 || y >= compositeBuffer.rows) continue;
1010
+ const dst = getBufferRow(compositeBuffer, y);
1011
+ dst.length = compositeBuffer.cols;
1012
+ for (let x = 0; x < compositeBuffer.cols; x++) dst[x] = blank;
1013
+ for (const plane of planes) {
1014
+ const state = planeStates.get(plane);
1015
+ if (!state) continue;
1016
+ const src = getBufferRow(state.buffer, y);
1017
+ const coverage = state.coverage[y];
1018
+ if (!coverage) continue;
1019
+ for (let x = 0; x < compositeBuffer.cols; x++) if (coverage[x]) dst[x] = src[x];
1020
+ }
1021
+ const cols = compositeBuffer.cols;
1022
+ for (let x = 0; x < cols; x++) {
1023
+ const cell = dst[x];
1024
+ if (cell.width === 2 && !cell.continuation) {
1025
+ if (x + 1 >= cols || !dst[x + 1].continuation) dst[x] = blank;
1026
+ } else if (cell.continuation) {
1027
+ if (x === 0 || dst[x - 1].width !== 2 || dst[x - 1].continuation) dst[x] = blank;
1028
+ }
1029
+ }
1030
+ if (fpFn && fpArr) {
1031
+ const physY = (compositeBuffer.gridStart + y) % compositeBuffer.rows;
1032
+ const base$1 = physY * cols;
1033
+ for (let x = 0; x < cols; x++) {
1034
+ const cell = dst[x];
1035
+ fpArr[base$1 + x] = fpFn(cell.ch, cell.style);
1036
+ }
1037
+ }
1038
+ markDirty(compositeBuffer, y);
1039
+ }
1040
+ }
1041
+ function syncCompositeCursor() {
1042
+ const prevVisible = compositeBuffer.cursorVisible;
1043
+ const prevY = compositeBuffer.cursorY;
1044
+ let nextPlane = null;
1045
+ for (const plane of [
1046
+ "overlay",
1047
+ "chrome",
1048
+ "transcript",
1049
+ "default"
1050
+ ]) {
1051
+ const state = planeStates.get(plane);
1052
+ if (state?.buffer.cursorVisible) {
1053
+ nextPlane = state;
1054
+ break;
1055
+ }
1056
+ }
1057
+ compositeBuffer.cursorVisible = Boolean(nextPlane);
1058
+ compositeBuffer.cursorX = nextPlane?.buffer.cursorX ?? 0;
1059
+ compositeBuffer.cursorY = nextPlane?.buffer.cursorY ?? 0;
1060
+ if (prevVisible) markDirty(compositeBuffer, prevY);
1061
+ if (compositeBuffer.cursorVisible) markDirty(compositeBuffer, compositeBuffer.cursorY);
1062
+ }
1063
+ function syncCompositeForRead(planes) {
1064
+ const planesToCompose = planes?.length ? planes : TERMINAL_RENDER_PLANES;
1065
+ let composeAllRows = false;
1066
+ const dirtyRows = new Set();
1067
+ for (const plane of planesToCompose) {
1068
+ const state = planeStates.get(plane);
1069
+ if (!state) continue;
1070
+ const rows = peekDirtyRows(state.buffer);
1071
+ if (rows === null) {
1072
+ composeAllRows = true;
1073
+ break;
1074
+ }
1075
+ for (const y of rows) dirtyRows.add(y);
1076
+ }
1077
+ if (composeAllRows || dirtyRows.size > 0) composeRows(composeAllRows ? null : Array.from(dirtyRows).sort((a, b) => a - b), planesToCompose);
1078
+ syncCompositeCursor();
1079
+ }
1080
+ function readRowForPlanes(y, planes) {
1081
+ assertNotDisposed();
1082
+ if (y < 0 || y >= compositeBuffer.rows) throw new RangeError("Row out of bounds");
1083
+ composeRows([y], planes?.length ? planes : TERMINAL_RENDER_PLANES);
1084
+ return getBufferRow(compositeBuffer, y);
1085
+ }
1086
+ function pendingDirtyRowsForPlanes(planes) {
1087
+ const planesToCheck = planes?.length ? planes : TERMINAL_RENDER_PLANES;
1088
+ let full = false;
1089
+ const rows = new Set();
1090
+ for (const plane of planesToCheck) {
1091
+ const state = planeStates.get(plane);
1092
+ if (!state) continue;
1093
+ const dirty = peekDirtyRows(state.buffer);
1094
+ if (dirty === null) {
1095
+ full = true;
1096
+ break;
1097
+ }
1098
+ for (const y of dirty) rows.add(y);
1099
+ }
1100
+ if (full) return null;
1101
+ return Array.from(rows).sort((a, b) => a - b);
1102
+ }
1103
+ function createPlaneTerminalApi(plane) {
1104
+ const existing = planeTerminals.get(plane);
1105
+ if (existing) return existing;
1106
+ const api = {
1107
+ resize(cols, rows) {
1108
+ assertNotDisposed();
1109
+ base.resize(cols, rows);
1110
+ },
1111
+ clear(x, y, w, h) {
1112
+ assertNotDisposed();
1113
+ clearForPlane(plane, x, y, w, h);
1114
+ },
1115
+ write(text, opts$1) {
1116
+ assertNotDisposed();
1117
+ const state = getPlaneState(plane);
1118
+ const x = opts$1?.x;
1119
+ const y = opts$1?.y;
1120
+ const style = opts$1?.style;
1121
+ if (x == null || y == null) {
1122
+ const next = writeAtForPlane(plane, text, state.buffer.cursorX, state.buffer.cursorY, style ?? state.buffer.cursorStyle);
1123
+ state.buffer.cursorX = next.x;
1124
+ state.buffer.cursorY = next.y;
1125
+ } else writeAtForPlane(plane, text, x, y, style);
1126
+ },
1127
+ writeAnsi(text, opts$1) {
1128
+ assertNotDisposed();
1129
+ const state = getPlaneState(plane);
1130
+ const x = opts$1?.x;
1131
+ const y = opts$1?.y;
1132
+ const positionedWrite = x != null && y != null;
1133
+ let cx = positionedWrite ? x : state.buffer.cursorX;
1134
+ let cy = positionedWrite ? y : state.buffer.cursorY;
1135
+ let style = positionedWrite ? {} : state.buffer.cursorStyle;
1136
+ for (const seg of parseAnsiSgr(text, style)) {
1137
+ const next = writeAtForPlane(plane, seg.text, cx, cy, seg.style);
1138
+ cx = next.x;
1139
+ cy = next.y;
1140
+ style = seg.style;
1141
+ }
1142
+ if (!positionedWrite) {
1143
+ state.buffer.cursorX = cx;
1144
+ state.buffer.cursorY = cy;
1145
+ state.buffer.cursorStyle = style;
1146
+ }
1147
+ },
1148
+ put(x, y, ch, style) {
1149
+ assertNotDisposed();
1150
+ putForPlane(plane, x, y, ch, style);
1151
+ },
1152
+ fill(x, y, w, h, ch, style) {
1153
+ assertNotDisposed();
1154
+ fillForPlane(plane, x, y, w, h, ch, style);
1155
+ },
1156
+ scroll(lines) {
1157
+ assertNotDisposed();
1158
+ scrollForPlane(plane, lines);
1159
+ },
1160
+ setCursor(x, y, visible) {
1161
+ assertNotDisposed();
1162
+ setCursorForPlane(plane, x, y, visible);
1163
+ },
1164
+ batch(fn) {
1165
+ assertNotDisposed();
1166
+ return base.batch(fn);
1167
+ },
1168
+ commit(meta) {
1169
+ assertNotDisposed();
1170
+ return base.commit({
1171
+ planes: meta?.planes ?? [plane],
1172
+ sync: meta?.sync
1173
+ });
1174
+ },
1175
+ on(event, cb) {
1176
+ assertNotDisposed();
1177
+ return base.on(event, cb);
1178
+ },
1179
+ dispose() {
1180
+ base.dispose();
1181
+ },
1182
+ size() {
1183
+ assertNotDisposed();
1184
+ return base.size();
1185
+ },
1186
+ snapshot() {
1187
+ assertNotDisposed();
1188
+ const state = getPlaneState(plane);
1189
+ return {
1190
+ cols: state.buffer.cols,
1191
+ rows: state.buffer.rows,
1192
+ lines: snapshotText(state.buffer)
1193
+ };
1194
+ },
1195
+ getCell(x, y) {
1196
+ assertNotDisposed();
1197
+ const state = getPlaneState(plane);
1198
+ if (y < 0 || y >= state.buffer.rows || x < 0 || x >= state.buffer.cols) throw new RangeError("Cell out of bounds");
1199
+ return getBufferCell(state.buffer, x, y);
1200
+ },
1201
+ getRow(y) {
1202
+ assertNotDisposed();
1203
+ const state = getPlaneState(plane);
1204
+ if (y < 0 || y >= state.buffer.rows) throw new RangeError("Row out of bounds");
1205
+ return getBufferRow(state.buffer, y);
1206
+ },
1207
+ setScrollbackLimit(limit) {
1208
+ assertNotDisposed();
1209
+ const state = getPlaneState(plane);
1210
+ state.buffer.scrollbackLimit = Math.max(0, Math.floor(limit));
1211
+ if (state.buffer.scrollback.length > state.buffer.scrollbackLimit) state.buffer.scrollback.splice(0, state.buffer.scrollback.length - state.buffer.scrollbackLimit);
1212
+ },
1213
+ getScrollbackLines(count) {
1214
+ assertNotDisposed();
1215
+ const state = getPlaneState(plane);
1216
+ const all = state.buffer.scrollback.map((row) => row.map((cell) => cell.continuation ? " " : cell.ch || " ").join(""));
1217
+ if (count == null) return all;
1218
+ return all.slice(Math.max(0, all.length - Math.max(0, Math.floor(count))));
1219
+ },
1220
+ setFingerprintFn(fn) {
1221
+ assertNotDisposed();
1222
+ base.setFingerprintFn(fn);
1223
+ },
1224
+ getRowFingerprints(y) {
1225
+ assertNotDisposed();
1226
+ return base.getRowFingerprints(y);
1227
+ }
1228
+ };
1229
+ planeTerminals.set(plane, api);
1230
+ return api;
1231
+ }
1232
+ base = {
1233
+ resize(cols, rows) {
1234
+ assertNotDisposed();
1235
+ const prevCols = compositeBuffer.cols;
1236
+ const prevRows = compositeBuffer.rows;
1237
+ resizeBuffer(compositeBuffer, cols, rows);
1238
+ for (const state of planeStates.values()) resizePlaneState(state, cols, rows);
1239
+ if (compositeBuffer.cols !== prevCols || compositeBuffer.rows !== prevRows) emitter.emit("resize", {
1240
+ cols: compositeBuffer.cols,
1241
+ rows: compositeBuffer.rows
1242
+ });
1243
+ },
1244
+ clear(x, y, w, h) {
1245
+ assertNotDisposed();
1246
+ clearForPlane("default", x, y, w, h);
1247
+ },
1248
+ write(text, opts$1) {
1249
+ assertNotDisposed();
1250
+ createPlaneTerminalApi("default").write(text, opts$1);
1251
+ },
1252
+ writeAnsi(text, opts$1) {
1253
+ assertNotDisposed();
1254
+ createPlaneTerminalApi("default").writeAnsi(text, opts$1);
1255
+ },
1256
+ put(x, y, ch, style) {
1257
+ assertNotDisposed();
1258
+ putForPlane("default", x, y, ch, style);
1259
+ },
1260
+ fill(x, y, w, h, ch, style) {
1261
+ assertNotDisposed();
1262
+ fillForPlane("default", x, y, w, h, ch, style);
1263
+ },
1264
+ scroll(lines) {
1265
+ assertNotDisposed();
1266
+ scrollForPlane("default", lines);
1267
+ },
1268
+ setCursor(x, y, visible = true) {
1269
+ assertNotDisposed();
1270
+ setCursorForPlane("default", x, y, visible);
1271
+ },
1272
+ batch(fn) {
1273
+ assertNotDisposed();
1274
+ batchingDepth++;
1275
+ try {
1276
+ return fn();
1277
+ } finally {
1278
+ batchingDepth--;
1279
+ if (batchingDepth === 0 && pendingCommit) {
1280
+ pendingCommit = false;
1281
+ const planes = pendingCommitAllPlanes ? null : pendingCommitPlanes;
1282
+ pendingCommitAllPlanes = false;
1283
+ pendingCommitPlanes = null;
1284
+ base.commit({ planes });
1285
+ }
1286
+ }
1287
+ },
1288
+ commit(meta) {
1289
+ assertNotDisposed();
1290
+ if (batchingDepth > 0) {
1291
+ pendingCommit = true;
1292
+ if (!meta?.planes?.length) {
1293
+ pendingCommitAllPlanes = true;
1294
+ pendingCommitPlanes = null;
1295
+ } else if (!pendingCommitAllPlanes) pendingCommitPlanes = mergePlanes(pendingCommitPlanes, meta.planes);
1296
+ return pendingDirtyRowsForPlanes(meta?.planes ?? null);
1297
+ }
1298
+ const planesToCompose = meta?.planes?.length ? meta.planes : TERMINAL_RENDER_PLANES;
1299
+ const pendingScrollOps = takePendingScrollOps(planesToCompose);
1300
+ const preparedScroll = prepareCompositeScrollOps(pendingScrollOps);
1301
+ let scrollOperations = preparedScroll.scrollOperations;
1302
+ let composeAllRows = false;
1303
+ const dirtyRows = new Set();
1304
+ for (const plane of planesToCompose) {
1305
+ const state = planeStates.get(plane);
1306
+ if (!state) continue;
1307
+ const rows = collectAndClearDirtyRows(state.buffer);
1308
+ if (rows === null) {
1309
+ composeAllRows = true;
1310
+ break;
1311
+ }
1312
+ for (const y of rows) dirtyRows.add(y);
1313
+ }
1314
+ for (const y of preparedScroll.extraDirtyRows) dirtyRows.add(y);
1315
+ const normalizedDirtyRows = composeAllRows ? null : Array.from(dirtyRows).sort((a, b) => a - b);
1316
+ scrollOperations = dropScrollOpsCoveredByDirtyRows(scrollOperations, normalizedDirtyRows);
1317
+ if (scrollOperations) for (const op of scrollOperations) scrollBufferRegion(compositeBuffer, op.startY, op.endY, op.delta);
1318
+ if (normalizedDirtyRows !== null && normalizedDirtyRows.length === 0) {
1319
+ const pendingCompositeRows = collectAndClearDirtyRows(compositeBuffer);
1320
+ if (pendingCompositeRows !== null && pendingCompositeRows.length === 0) return pendingCompositeRows;
1321
+ emitter.emit("commit", {
1322
+ dirtyRows: pendingCompositeRows,
1323
+ planes: meta?.planes ?? null,
1324
+ sync: meta?.sync,
1325
+ scrollOperations
1326
+ });
1327
+ return pendingCompositeRows;
1328
+ }
1329
+ composeRows(normalizedDirtyRows);
1330
+ if (normalizedDirtyRows === null) markAllDirty(compositeBuffer);
1331
+ syncCompositeCursor();
1332
+ const committedRows = collectAndClearDirtyRows(compositeBuffer);
1333
+ if (committedRows !== null && committedRows.length === 0) return committedRows;
1334
+ emitter.emit("commit", {
1335
+ dirtyRows: committedRows,
1336
+ planes: meta?.planes ?? null,
1337
+ sync: meta?.sync,
1338
+ scrollOperations
1339
+ });
1340
+ return committedRows;
1341
+ },
1342
+ on(event, cb) {
1343
+ assertNotDisposed();
1344
+ return emitter.on(event, cb);
1345
+ },
1346
+ dispose() {
1347
+ disposed = true;
1348
+ emitter.clear();
1349
+ },
1350
+ size() {
1351
+ assertNotDisposed();
1352
+ return {
1353
+ cols: compositeBuffer.cols,
1354
+ rows: compositeBuffer.rows
1355
+ };
1356
+ },
1357
+ snapshot() {
1358
+ assertNotDisposed();
1359
+ if (batchingDepth === 0) syncCompositeForRead();
1360
+ const source = batchingDepth > 0 ? getPlaneState("default").buffer : compositeBuffer;
1361
+ return {
1362
+ cols: source.cols,
1363
+ rows: source.rows,
1364
+ lines: snapshotText(source)
1365
+ };
1366
+ },
1367
+ getCell(x, y) {
1368
+ assertNotDisposed();
1369
+ if (batchingDepth === 0) syncCompositeForRead();
1370
+ const source = batchingDepth > 0 ? getPlaneState("default").buffer : compositeBuffer;
1371
+ if (y < 0 || y >= source.rows || x < 0 || x >= source.cols) throw new RangeError("Cell out of bounds");
1372
+ return getBufferCell(source, x, y);
1373
+ },
1374
+ getRow(y) {
1375
+ assertNotDisposed();
1376
+ if (batchingDepth === 0) syncCompositeForRead();
1377
+ const source = batchingDepth > 0 ? getPlaneState("default").buffer : compositeBuffer;
1378
+ if (y < 0 || y >= source.rows) throw new RangeError("Row out of bounds");
1379
+ return getBufferRow(source, y);
1380
+ },
1381
+ setScrollbackLimit(limit) {
1382
+ assertNotDisposed();
1383
+ const state = getPlaneState("default");
1384
+ state.buffer.scrollbackLimit = Math.max(0, Math.floor(limit));
1385
+ if (state.buffer.scrollback.length > state.buffer.scrollbackLimit) state.buffer.scrollback.splice(0, state.buffer.scrollback.length - state.buffer.scrollbackLimit);
1386
+ },
1387
+ getScrollbackLines(count) {
1388
+ assertNotDisposed();
1389
+ const state = getPlaneState("default");
1390
+ const all = state.buffer.scrollback.map((row) => row.map((cell) => cell.continuation ? " " : cell.ch || " ").join(""));
1391
+ if (count == null) return all;
1392
+ return all.slice(Math.max(0, all.length - Math.max(0, Math.floor(count))));
1393
+ },
1394
+ setFingerprintFn(fn) {
1395
+ assertNotDisposed();
1396
+ setFingerprintFn(compositeBuffer, fn);
1397
+ },
1398
+ getRowFingerprints(y) {
1399
+ assertNotDisposed();
1400
+ return getRowFingerprints(compositeBuffer, y);
1401
+ }
1402
+ };
1403
+ base[TERMINAL_PLANE_INTERNALS] = {
1404
+ getPlaneTerminal: createPlaneTerminalApi,
1405
+ readRowForPlanes,
1406
+ resetRowsForRender(plane, dirtyRows) {
1407
+ const state = getPlaneState(plane);
1408
+ const rows = normalizeDirtyRows(dirtyRows, state.buffer.rows);
1409
+ if (rows === null) {
1410
+ for (let y = 0; y < state.buffer.rows; y++) clearPlaneCoverageRow(state, y);
1411
+ return;
1412
+ }
1413
+ for (const y of rows) clearPlaneCoverageRow(state, y);
1414
+ },
1415
+ getRowCoverageKind(plane, y) {
1416
+ const state = getPlaneState(plane);
1417
+ if (y < 0 || y >= state.coverage.length) return 0;
1418
+ const row = state.coverage[y];
1419
+ if (!row?.length) return 0;
1420
+ let covered = 0;
1421
+ for (let x = 0; x < row.length; x++) if (row[x]) covered++;
1422
+ if (covered === 0) return 0;
1423
+ if (covered >= row.length) return 2;
1424
+ return 1;
1425
+ },
1426
+ scrollRows(plane, startY, endY, lines) {
1427
+ scrollRowsForPlane(plane, startY, endY, lines);
1428
+ }
1429
+ };
1430
+ return base;
1431
+ }
1432
+
1433
+ //#endregion
1434
+ export { TERMINAL_RENDER_PLANES, createTerminal, getPlaneTerminal, resetPlaneRowsForRender, scrollPlaneRows };