mindweave 2.3.1 → 2.4.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 (121) hide show
  1. package/README.md +26 -43
  2. package/dist/alternator/chassis/lsp.js +67 -0
  3. package/dist/alternator/chassis/lsp.js.map +1 -1
  4. package/dist/cli/App.js +1175 -99
  5. package/dist/cli/App.js.map +1 -1
  6. package/dist/cli/altScreen.js +80 -10
  7. package/dist/cli/altScreen.js.map +1 -1
  8. package/dist/cli/appIdentity.js +54 -0
  9. package/dist/cli/appIdentity.js.map +1 -0
  10. package/dist/cli/attachments.js +27 -3
  11. package/dist/cli/attachments.js.map +1 -1
  12. package/dist/cli/blockHeights.js +58 -0
  13. package/dist/cli/blockHeights.js.map +1 -0
  14. package/dist/cli/caretPark.js +94 -0
  15. package/dist/cli/caretPark.js.map +1 -0
  16. package/dist/cli/clipboard.js +68 -0
  17. package/dist/cli/clipboard.js.map +1 -0
  18. package/dist/cli/commandLabel.js +19 -2
  19. package/dist/cli/commandLabel.js.map +1 -1
  20. package/dist/cli/commands.js +1 -0
  21. package/dist/cli/commands.js.map +1 -1
  22. package/dist/cli/components/BlockView.js +1 -1
  23. package/dist/cli/components/BlockView.js.map +1 -1
  24. package/dist/cli/components/KeyManager.js +11 -5
  25. package/dist/cli/components/KeyManager.js.map +1 -1
  26. package/dist/cli/components/Picker.js +18 -3
  27. package/dist/cli/components/Picker.js.map +1 -1
  28. package/dist/cli/components/PromptInput.js +300 -74
  29. package/dist/cli/components/PromptInput.js.map +1 -1
  30. package/dist/cli/components/TipLine.js +33 -0
  31. package/dist/cli/components/TipLine.js.map +1 -0
  32. package/dist/cli/components/ToolLine.js +30 -3
  33. package/dist/cli/components/ToolLine.js.map +1 -1
  34. package/dist/cli/dropHandles.js +76 -0
  35. package/dist/cli/dropHandles.js.map +1 -0
  36. package/dist/cli/exitCursor.js +56 -0
  37. package/dist/cli/exitCursor.js.map +1 -0
  38. package/dist/cli/framebuffer/overlay.js +42 -0
  39. package/dist/cli/framebuffer/overlay.js.map +1 -0
  40. package/dist/cli/framebuffer/paint.js +8 -1
  41. package/dist/cli/framebuffer/paint.js.map +1 -1
  42. package/dist/cli/framebuffer/parse.js +54 -4
  43. package/dist/cli/framebuffer/parse.js.map +1 -1
  44. package/dist/cli/framebuffer/writer.js +357 -6
  45. package/dist/cli/framebuffer/writer.js.map +1 -1
  46. package/dist/cli/groupReveal.js +29 -3
  47. package/dist/cli/groupReveal.js.map +1 -1
  48. package/dist/cli/inputView.js +45 -0
  49. package/dist/cli/inputView.js.map +1 -1
  50. package/dist/cli/livePad.js +53 -0
  51. package/dist/cli/livePad.js.map +1 -0
  52. package/dist/cli/memoryTuning.js +31 -0
  53. package/dist/cli/memoryTuning.js.map +1 -0
  54. package/dist/cli/messageQueue.js +76 -7
  55. package/dist/cli/messageQueue.js.map +1 -1
  56. package/dist/cli/mouse.js +40 -7
  57. package/dist/cli/mouse.js.map +1 -1
  58. package/dist/cli/quietConsole.js +50 -0
  59. package/dist/cli/quietConsole.js.map +1 -0
  60. package/dist/cli/screenMode.js +118 -0
  61. package/dist/cli/screenMode.js.map +1 -0
  62. package/dist/cli/screenShell.js +67 -0
  63. package/dist/cli/screenShell.js.map +1 -0
  64. package/dist/cli/screenStore.js +46 -0
  65. package/dist/cli/screenStore.js.map +1 -0
  66. package/dist/cli/scrollPill.js +101 -0
  67. package/dist/cli/scrollPill.js.map +1 -0
  68. package/dist/cli/selection.js +130 -0
  69. package/dist/cli/selection.js.map +1 -0
  70. package/dist/cli/startupFill.js +48 -0
  71. package/dist/cli/startupFill.js.map +1 -0
  72. package/dist/cli/terminalRestore.js +1 -1
  73. package/dist/cli/terminalRestore.js.map +1 -1
  74. package/dist/cli/toolDisplay.js +11 -2
  75. package/dist/cli/toolDisplay.js.map +1 -1
  76. package/dist/cli/toolItems.js +1 -0
  77. package/dist/cli/toolItems.js.map +1 -1
  78. package/dist/cli/transcript.js +54 -3
  79. package/dist/cli/transcript.js.map +1 -1
  80. package/dist/cli/wordEdit.js +95 -0
  81. package/dist/cli/wordEdit.js.map +1 -0
  82. package/dist/drivers/openai/manifest.js +4 -1
  83. package/dist/drivers/openai/manifest.js.map +1 -1
  84. package/dist/dynamo/engine.js +126 -20
  85. package/dist/dynamo/engine.js.map +1 -1
  86. package/dist/index.js +42 -3
  87. package/dist/index.js.map +1 -1
  88. package/dist/memory/pastedText.js +37 -0
  89. package/dist/memory/pastedText.js.map +1 -0
  90. package/dist/memory/presence.js +47 -0
  91. package/dist/memory/presence.js.map +1 -1
  92. package/dist/memory/session.js +78 -4
  93. package/dist/memory/session.js.map +1 -1
  94. package/dist/memory/store.js +22 -1
  95. package/dist/memory/store.js.map +1 -1
  96. package/dist/memory/types.js.map +1 -1
  97. package/dist/tools/backgroundShells.js +105 -18
  98. package/dist/tools/backgroundShells.js.map +1 -1
  99. package/dist/tools/commandOutput.js +207 -0
  100. package/dist/tools/commandOutput.js.map +1 -0
  101. package/dist/tools/detail.js +2 -2
  102. package/dist/tools/detail.js.map +1 -1
  103. package/dist/tools/openDefault.js +150 -0
  104. package/dist/tools/openDefault.js.map +1 -0
  105. package/dist/tools/outputShape.js +31 -6
  106. package/dist/tools/outputShape.js.map +1 -1
  107. package/dist/tools/pathList.js +32 -0
  108. package/dist/tools/pathList.js.map +1 -0
  109. package/dist/tools/readFile.js +3 -15
  110. package/dist/tools/readFile.js.map +1 -1
  111. package/dist/tools/registry.js +3 -1
  112. package/dist/tools/registry.js.map +1 -1
  113. package/dist/tools/runCommand.js +154 -58
  114. package/dist/tools/runCommand.js.map +1 -1
  115. package/dist/tools/screenshot.js +35 -3
  116. package/dist/tools/screenshot.js.map +1 -1
  117. package/dist/tools/viewImage.js +88 -0
  118. package/dist/tools/viewImage.js.map +1 -0
  119. package/dist/tools/writeFile.js +9 -1
  120. package/dist/tools/writeFile.js.map +1 -1
  121. package/package.json +74 -74
@@ -33,8 +33,25 @@
33
33
  * write contains anything printable once its escape sequences are removed.
34
34
  */
35
35
  import { Screen } from "./screen.js";
36
+ import { applyFrameOverlay, hasFrameOverlay, publishScreen, setOverlayRepaint } from "./overlay.js";
36
37
  import { parseFrame } from "./parse.js";
37
38
  import { paint } from "./paint.js";
39
+ import { caretCell, onCaretMoved, parkAt, HIDE } from "../caretPark.js";
40
+ /**
41
+ * Synchronized output (DECSET 2026): hold the frame back until it is complete.
42
+ *
43
+ * The painter walks the cursor across the screen laying its runs down, and a terminal
44
+ * draws every intermediate state — including the cursor at each stop. The first attempt
45
+ * at hiding that streak HID THE CURSOR around each paint, which meant switching it off
46
+ * and on again on every keystroke: the caret visibly blinked out whenever anything was
47
+ * typed. This is the mechanism meant for the job. The terminal buffers between the two
48
+ * markers and presents once, so nothing intermediate is ever shown and the cursor never
49
+ * has to be taken away.
50
+ *
51
+ * Unsupported terminals ignore both as unknown modes and simply paint as they used to.
52
+ */
53
+ const SYNC_START = "[?2026h";
54
+ const SYNC_END = "[?2026l";
38
55
  /**
39
56
  * The prefix Ink puts before a frame to remove the previous one:
40
57
  * `\x1b[2K` (erase line) and `\x1b[1A` (cursor up) repeated, then `\x1b[G`.
@@ -44,6 +61,14 @@ import { paint } from "./paint.js";
44
61
  * exactly the work being saved.
45
62
  */
46
63
  const ERASE_PREFIX = /^(?:\x1b\[2K(?:\x1b\[1A)?)+\x1b\[G/;
64
+ /**
65
+ * A write with nothing in it but erasing — Ink clearing the screen on a narrowing resize.
66
+ *
67
+ * Every alternative matched is an erase, or the cursor move that walks between the rows
68
+ * being erased. A sequence that also DRAWS cannot match: painted output carries absolute
69
+ * cursor positioning and text, and neither is in this set.
70
+ */
71
+ const ERASE_ONLY = /^(?:\x1b\[2K|\x1b\[1A|\x1b\[G)+$/;
47
72
  /** Any escape sequence, for deciding whether a write carries visible content. */
48
73
  const ANY_ESCAPE = /\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[[\]()#;?]*[0-9;]*[A-Za-z]|\x1b./g;
49
74
  /**
@@ -69,18 +94,103 @@ function fullRepaintMs() {
69
94
  * lands mid-burst: every frame cancels and re-arms it.
70
95
  */
71
96
  const IDLE_REPAINT_MS = 400;
97
+ /**
98
+ * Whether the framebuffer is doing anything at all.
99
+ *
100
+ * Module level rather than per wrapper, because there is exactly one wrapper in a
101
+ * process (index.ts hands it to `render()`) and the switch is reached from the command
102
+ * that flips screen modes, which has no access to it.
103
+ */
104
+ let enabled = true;
105
+ /** Called when the framebuffer is switched back on, so it forgets the screen. */
106
+ let onReenable = null;
107
+ /** Called when the framebuffer stands down, so nothing it armed can still fire. */
108
+ let onDisable = null;
109
+ /**
110
+ * Turn the diffing renderer on or off.
111
+ *
112
+ * Switching ON throws away the model of the screen, and that is not optional: while it
113
+ * was off the terminal was scrolling and printing on its own, so every cell the model
114
+ * remembers is a guess about a screen that has moved. Without this the first frame after
115
+ * a switch back would diff against a fiction and paint almost nothing.
116
+ */
117
+ export function setFramebufferEnabled(on) {
118
+ if (enabled === on)
119
+ return;
120
+ enabled = on;
121
+ if (on)
122
+ onReenable?.();
123
+ else
124
+ onDisable?.();
125
+ }
126
+ /** Whether frames are currently being diffed. */
127
+ export function framebufferEnabled() {
128
+ return enabled;
129
+ }
72
130
  /**
73
131
  * Wrap `real` so Ink's frames are diffed before they reach it.
74
132
  *
75
133
  * `onFrame` is called after each frame with what it cost, so the perf log can report
76
134
  * the saving without this module knowing anything about logging.
77
135
  */
136
+ /**
137
+ * The cursor instruction to append to a frame: parked at the caret, or hidden.
138
+ *
139
+ * The position comes from the LAYOUT (see caretPark.ts), not from the painted cells, so
140
+ * it does not depend on the frame at all — only on the layout the frame was built from.
141
+ * Hidden when nothing declares a caret, which is every screen that is not an input.
142
+ */
143
+ function caretTail() {
144
+ // Nothing at all while stood down, and this is the invariant rather than a tidy-up.
145
+ //
146
+ // `parkAt` is an ABSOLUTE move — row N of the viewport. That is right when the app
147
+ // owns the screen and catastrophic when it does not: in the inline shell the caret's
148
+ // measured y is its row within the LIVE REGION, a handful of rows tall at the bottom
149
+ // of a terminal full of scrollback, so row N addresses somewhere near the top of the
150
+ // window, in the middle of the conversation. The cursor lands there, and everything
151
+ // that follows — the shell's own prompt after the process exits, most visibly — is
152
+ // printed over the transcript.
153
+ //
154
+ // Stated here, at the single point the absolute move is produced, so no future caller
155
+ // has to remember it. Empty and NOT `HIDE`: while stood down the caret belongs to Ink,
156
+ // which shows the terminal's real cursor at the input, and hiding it would take away
157
+ // the caret the inline shell types with.
158
+ if (!enabled)
159
+ return "";
160
+ const cell = caretCell();
161
+ return cell ? parkAt(cell) : HIDE;
162
+ }
78
163
  export function framebufferStdout(real, onFrame) {
79
164
  // The grid currently on the terminal, and the one being built for this frame. Two
80
165
  // long-lived buffers, swapped — never reallocated per frame, which is the whole
81
166
  // reason the cell data is in typed arrays.
82
167
  let onScreen = new Screen(real.columns ?? 80, real.rows ?? 24);
83
168
  let pending = new Screen(onScreen.width, onScreen.height);
169
+ // The last frame as it was BEFORE any overlay tinted it. Only kept up to date while an
170
+ // overlay is installed, which is what lets a highlight move without a new frame: the
171
+ // clean copy is re-tinted at the new position rather than the tinted one being undone.
172
+ const clean = new Screen(onScreen.width, onScreen.height);
173
+ /** Whether `clean` actually holds the frame that is on screen. False until a frame has
174
+ * been drawn WITH an overlay installed — which is the usual state, since an overlay is
175
+ * installed long after the first frame. Re-tinting from a `clean` that was never filled
176
+ * would repaint the screen as blanks. */
177
+ let cleanValid = false;
178
+ /**
179
+ * The last write that carried a frame, kept whether or not the framebuffer is on.
180
+ *
181
+ * Recorded while STOOD DOWN too, and that is the point: a shell switch renders the new
182
+ * shell before the effect that moves the terminal runs, so the frame for the shell
183
+ * being entered is written while this is still standing aside. It is the only copy of
184
+ * that frame anyone has — Ink will not write it again, having already written it — so
185
+ * paints from here. See there.
186
+ */
187
+ let lastFrameData = "";
188
+ /** The cursor instruction already on the terminal. Re-sending an identical one would
189
+ * put bytes on the wire for a frame where nothing changed, which is the one thing this
190
+ * renderer promises never to do. */
191
+ let lastCursor = "";
192
+ /** The cursor instruction the terminal is actually showing, for the change check. */
193
+ let lastShown = "";
84
194
  const repaintEvery = fullRepaintMs();
85
195
  /** When every cell was last written, which is what bounds how long a disagreement
86
196
  * with the real terminal can survive. */
@@ -99,8 +209,14 @@ export function framebufferStdout(real, onFrame) {
99
209
  * `Tools(session)s, ask_user, create_skill,`.
100
210
  */
101
211
  function syncSize() {
102
- const w = real.columns ?? onScreen.width;
103
- const h = real.rows ?? onScreen.height;
212
+ // A LIVE query where the platform has one (`getWindowSize`), because `real.rows` /
213
+ // `real.columns` are getters that on Windows can return a size cached at the last
214
+ // resize event — an event that frequently never fires. Sized from the cached getter,
215
+ // the grid stayed small while the frame above it grew, so the paint clipped to the
216
+ // old height and the bottom of the screen went stale.
217
+ const win = real.getWindowSize?.();
218
+ const w = win ? win[0] : real.columns ?? onScreen.width;
219
+ const h = win ? win[1] : real.rows ?? onScreen.height;
104
220
  if (w === onScreen.width && h === onScreen.height)
105
221
  return false;
106
222
  onScreen.resize(w, h);
@@ -132,6 +248,43 @@ export function framebufferStdout(real, onFrame) {
132
248
  onScreen.invalidate();
133
249
  lastFull = Date.now();
134
250
  }
251
+ // Coming back from the inline shell: the terminal has been scrolling and printing on
252
+ // its own, so nothing the model believes about the screen is still true. Forget all of
253
+ // it, and forget the cursor instruction too — the next frame has to send one whatever
254
+ // it says, since the cursor is wherever the other shell left it.
255
+ onReenable = () => {
256
+ invalidate();
257
+ lastCursor = "";
258
+ lastShown = "";
259
+ cleanValid = false;
260
+ // And PAINT the frame again, because otherwise nobody will.
261
+ //
262
+ // The order a shell switch actually happens in is the whole reason this is needed.
263
+ // React renders the new shell first and Ink writes that frame immediately — while
264
+ // the framebuffer is still stood down, so it goes to the terminal untouched and
265
+ // lands on the screen being left behind. Only then does the effect run: the
266
+ // alternate screen is entered, which is blank, and this is switched back on. Ink is
267
+ // now holding output identical to what it just wrote, so it writes nothing more, and
268
+ // nothing else is scheduled to. The result is an empty alternate screen that stays
269
+ // empty until something unrelated happens to cause a render.
270
+ //
271
+ // Re-feeding the last frame through the ordinary write path is what closes that gap.
272
+ // It is the same bytes Ink produced for the shell being entered — React had already
273
+ // rendered it — and going through `fbWrite` means it is parsed, diffed against the
274
+ // just-invalidated model, and painted exactly like any other frame, rather than
275
+ // through a second copy of that logic that could drift from it.
276
+ if (lastFrameData !== "")
277
+ fbWrite(lastFrameData);
278
+ };
279
+ // Going the other way: disarm the repaint the last frame of this shell armed. The
280
+ // guards inside it make firing harmless, but a timer whose only possible outcome is
281
+ // to do nothing is one that should not be running — and cancelling it is what makes
282
+ // "stood down means silent" true by construction rather than by three checks agreeing.
283
+ onDisable = () => {
284
+ if (idle)
285
+ clearTimeout(idle);
286
+ idle = undefined;
287
+ };
135
288
  /**
136
289
  * Re-assert the model onto the terminal outside of any frame.
137
290
  *
@@ -140,6 +293,16 @@ export function framebufferStdout(real, onFrame) {
140
293
  * nothing, and the two swap back exactly as they do on a normal frame.
141
294
  */
142
295
  function repaintNow() {
296
+ // Stood down: the terminal is not ours to repaint. Everything below addresses cells
297
+ // absolutely, so re-asserting a model of a screen we no longer own would stamp the
298
+ // last full-screen frame over whatever the inline shell has printed since.
299
+ //
300
+ // The guard is here as well as on the timer that arms this, because the timer can
301
+ // already be in flight when the switch happens — it is armed by the last frame of
302
+ // the previous shell and fires a moment later, which is exactly the window this
303
+ // used to go wrong in.
304
+ if (!enabled)
305
+ return;
143
306
  if (onScreen.width === 0 || onScreen.height === 0)
144
307
  return;
145
308
  pending.copyFrom(onScreen);
@@ -148,9 +311,110 @@ export function framebufferStdout(real, onFrame) {
148
311
  const previous = onScreen;
149
312
  onScreen = pending;
150
313
  pending = previous;
151
- if (escape !== "")
152
- real.write(escape);
314
+ // The grids were swapped, so the object anything outside is holding is now the
315
+ // scratch buffer — and `invalidate()` above filled that one with a sentinel no
316
+ // character can equal. Republishing is what stops a reader seeing it.
317
+ publishScreen(onScreen);
318
+ // Re-park the cursor, unconditionally.
319
+ //
320
+ // A repaint moves the cursor wherever its last run ended, so the position sent with
321
+ // the previous frame is no longer where the cursor is — the dedup must be bypassed
322
+ // rather than trusted. Skipping this left the cursor sitting in the bottom-right
323
+ // corner, still visible, a fraction of a second after every burst of frames settled.
324
+ // Bracketed for the same reason as a frame: a repaint writes every cell, so the
325
+ // cursor would otherwise be seen travelling the whole screen.
326
+ lastCursor = caretTail();
327
+ lastShown = lastCursor;
328
+ const painted = escape === "" ? lastCursor : SYNC_START + escape + lastCursor + SYNC_END;
329
+ if (painted !== "")
330
+ real.write(painted);
331
+ }
332
+ /**
333
+ * Re-tint the frame already on screen and write the difference.
334
+ *
335
+ * This is what makes a drag cheap. Moving a selection changes no layout, so React
336
+ * produces no new frame and there would otherwise be nothing to repaint. Re-tinting the
337
+ * CLEAN copy (rather than trying to undo the tint on the screen grid) means the new
338
+ * highlight is computed from scratch every time, so it cannot accumulate or leave a
339
+ * cell inverted after the pointer has moved off it. The diff then writes only the cells
340
+ * whose highlight actually changed, which is a couple of short runs.
341
+ */
342
+ function refreshOverlay() {
343
+ // Stood down: same reason as `repaintNow`. There is no selection layer in the inline
344
+ // shell, so this has nothing to re-tint there in any case.
345
+ if (!enabled)
346
+ return;
347
+ if (!hasFrameOverlay())
348
+ return;
349
+ if (onScreen.width === 0 || onScreen.height === 0)
350
+ return;
351
+ if (clean.width !== onScreen.width || clean.height !== onScreen.height) {
352
+ clean.resize(onScreen.width, onScreen.height);
353
+ cleanValid = false;
354
+ }
355
+ // The first re-tint after an overlay is installed has no clean copy to work from,
356
+ // because the frame on screen was drawn before there was anything to keep one for.
357
+ // That frame IS clean, though: nothing has tinted it yet. Taking it as the baseline
358
+ // is what stops this repainting the screen as blanks.
359
+ if (!cleanValid) {
360
+ clean.copyFrom(onScreen);
361
+ cleanValid = true;
362
+ }
363
+ pending.copyFrom(clean);
364
+ applyFrameOverlay(pending);
365
+ const escape = paint(onScreen, pending, 1);
366
+ const previous = onScreen;
367
+ onScreen = pending;
368
+ pending = previous;
369
+ publishScreen(onScreen);
370
+ // Re-park the cursor, unconditionally.
371
+ //
372
+ // A repaint moves the cursor wherever its last run ended, so the position sent with
373
+ // the previous frame is no longer where the cursor is — the dedup must be bypassed
374
+ // rather than trusted. Skipping this left the cursor sitting in the bottom-right
375
+ // corner, still visible, a fraction of a second after every burst of frames settled.
376
+ // Bracketed for the same reason as a frame: a repaint writes every cell, so the
377
+ // cursor would otherwise be seen travelling the whole screen.
378
+ lastCursor = caretTail();
379
+ lastShown = lastCursor;
380
+ const painted = escape === "" ? lastCursor : SYNC_START + escape + lastCursor + SYNC_END;
381
+ if (painted !== "")
382
+ real.write(painted);
153
383
  }
384
+ setOverlayRepaint(refreshOverlay);
385
+ /**
386
+ * Park the cursor when the caret moves but NO frame follows.
387
+ *
388
+ * Ink writes nothing when its output is unchanged, and typing a space at the end of a
389
+ * line produces exactly that: the trailing blank is indistinguishable from the padding
390
+ * beside it. The cursor was then the only thing that had moved, and nothing carried it
391
+ * — so it sat a character behind until the after-burst repaint corrected it, which is
392
+ * the pause that felt like the caret arriving late.
393
+ *
394
+ * Deferred by a microtask so the layout is settled and, more importantly, so a frame
395
+ * that IS about to be written gets there first: it carries the same position, and the
396
+ * change check below then makes this a no-op rather than a second write.
397
+ */
398
+ let parkQueued = false;
399
+ onCaretMoved(() => {
400
+ if (parkQueued)
401
+ return;
402
+ parkQueued = true;
403
+ queueMicrotask(() => {
404
+ parkQueued = false;
405
+ // Stood down. This path writes to the terminal directly rather than through
406
+ // `fbWrite`, so the check has to be repeated here: in the inline shell the cursor
407
+ // belongs to Ink, and an absolute move would drop it somewhere in the scrollback.
408
+ if (!enabled)
409
+ return;
410
+ const parked = caretTail();
411
+ if (parked === lastShown)
412
+ return;
413
+ lastShown = parked;
414
+ lastCursor = parked;
415
+ real.write(parked);
416
+ });
417
+ });
154
418
  /** Arm the after-the-burst repaint. Unref'd: a screen touch-up must never be the
155
419
  * reason the process is still alive. */
156
420
  function armIdleRepaint() {
@@ -177,6 +441,57 @@ export function framebufferStdout(real, onFrame) {
177
441
  * only `write` is ours. Nothing has to be enumerated, so nothing can be forgotten.
178
442
  */
179
443
  const fbWrite = (data, callback) => {
444
+ // Stood down. Everything Ink writes goes straight to the terminal, untouched.
445
+ //
446
+ // The inline shell (see `screenMode.ts`) does not own the screen: its committed
447
+ // output IS the terminal's scrollback, written once and scrolled by the terminal
448
+ // itself. Every single thing this renderer does is wrong there. It strips the
449
+ // erase-lines prefix, which is how Ink rewrites its live region; it diffs against
450
+ // a grid the height of the window, when the real content is taller and moving; and
451
+ // it parks the cursor absolutely, when in that mode the cursor belongs to Ink.
452
+ //
453
+ // A flag rather than a second stdout, because the stream is handed to `render()`
454
+ // once and Ink holds it for the life of the process. `/screen` has to be able to
455
+ // change its mind without unmounting the app.
456
+ // Stood down. Everything Ink writes goes straight to the terminal, untouched —
457
+ // INCLUDING the cursor move and show that Ink appends when a component has asked
458
+ // for a position through `useCursor` (see PromptInput). That suffix is how the
459
+ // caret exists at all in the inline shell, so nothing here may add to a frame or
460
+ // take anything from it.
461
+ if (!enabled) {
462
+ // Remembered on the way past, because this is where the frame for the shell
463
+ // being ENTERED goes: React renders it before the effect that moves the
464
+ // terminal runs, so it is written while this is still standing aside. Ink will
465
+ // not produce it a second time, so `onReenable` paints from what is kept here.
466
+ // Only writes that carry cells — a bare control sequence is not a frame.
467
+ if (data.replace(ANY_ESCAPE, "").trim() !== "")
468
+ lastFrameData = data;
469
+ return real.write(data, callback);
470
+ }
471
+ // A write that is NOTHING BUT AN ERASE. Swallowed, and this is the whole reason a
472
+ // narrowing resize used to flicker.
473
+ //
474
+ // Ink clears the screen itself whenever the terminal gets narrower, to stop its own
475
+ // re-renders overlapping. It writes that erase on its own, unsynchronized — measured
476
+ // here, twenty-one `erase line` sequences in one write with no content — and only
477
+ // then lays the new frame out. Forwarded, it does exactly what it says: the screen
478
+ // goes blank, and stays blank for as long as the relayout takes. Dragging an edge is
479
+ // one of those per event, which is the flicker.
480
+ //
481
+ // Nothing is lost by dropping it. The erase exists to stop stale rows showing
482
+ // through a partial redraw, and that cannot happen here: a resize invalidates the
483
+ // model below, so the next frame writes EVERY cell, and it goes out wrapped in
484
+ // synchronized-update markers — the terminal holds the old picture until the whole
485
+ // new one has arrived, then swaps in one step. That is strictly better than erasing,
486
+ // because the old frame stays readable the entire time instead of a blank screen.
487
+ //
488
+ // Ink's own bookkeeping is untouched: `clear()` still runs and still resets its line
489
+ // count, so it remains consistent with what it believes. Only the bytes are dropped,
490
+ // and the screen was never Ink's to erase while this is switched on.
491
+ if (ERASE_ONLY.test(data)) {
492
+ callback?.(null);
493
+ return true;
494
+ }
180
495
  const body = data.replace(ERASE_PREFIX, "");
181
496
  const bare = body.replace(ANY_ESCAPE, "");
182
497
  // Nothing at all once the escapes are gone: a pure control sequence, not a frame.
@@ -213,6 +528,21 @@ export function framebufferStdout(real, onFrame) {
213
528
  // not the tail of what used to be there.
214
529
  pending.clear();
215
530
  parseFrame(pending, body);
531
+ // A selection highlight is added HERE, to the finished frame, and never reaches
532
+ // React. `clean` keeps the untinted frame so the highlight can be moved without a
533
+ // re-render (see `refreshOverlay`); it is only maintained while something is
534
+ // actually tinting, so a session that never drags pays nothing for it.
535
+ if (hasFrameOverlay()) {
536
+ if (clean.width !== pending.width || clean.height !== pending.height) {
537
+ clean.resize(pending.width, pending.height);
538
+ }
539
+ clean.copyFrom(pending);
540
+ cleanValid = true;
541
+ applyFrameOverlay(pending);
542
+ }
543
+ else {
544
+ cleanValid = false;
545
+ }
216
546
  const escape = paint(onScreen, pending, 1);
217
547
  // Swap rather than copy. Both grids are the same shape and `pending` is fully
218
548
  // rewritten at the start of every frame, so the old on-screen grid is free to
@@ -220,17 +550,38 @@ export function framebufferStdout(real, onFrame) {
220
550
  const previous = onScreen;
221
551
  onScreen = pending;
222
552
  pending = previous;
553
+ publishScreen(onScreen);
223
554
  onFrame?.({ inBytes: data.length, outBytes: escape.length });
224
555
  // Put the screen beyond doubt once this burst of frames stops. During a burst it
225
556
  // is only ever cancelled and re-armed, so it costs nothing until things settle.
226
557
  armIdleRepaint();
227
- if (escape === "") {
558
+ // The caret is the TERMINAL's own cursor, parked AFTER the frame it belongs to.
559
+ //
560
+ // Last, and it has to be last: the painter moves the cursor all over the screen to
561
+ // lay its runs down, so a position chosen before it finishes ends up wherever the
562
+ // final run happened to leave off. Appended to the same write for the same reason —
563
+ // a separate write could interleave and leave the cursor mid-paint.
564
+ const parked = caretTail();
565
+ lastCursor = parked;
566
+ // A frame that PAINTED must always re-park, even when the caret has not moved.
567
+ //
568
+ // Painting walks the cursor to wherever the last run ended, so the instruction being
569
+ // unchanged does not mean the cursor is still where it was put. Skipping it left the
570
+ // caret stranded at the end of whatever was repainted — a rotating tip line was
571
+ // enough to take it away, with nothing to bring it back until the next keystroke.
572
+ //
573
+ // The change check only applies when NOTHING was painted, which is the case it was
574
+ // for: writing zero bytes for a frame where nothing happened.
575
+ const out = escape === "" ? (parked === lastShown ? "" : parked) : SYNC_START + escape + parked + SYNC_END;
576
+ if (out !== "")
577
+ lastShown = parked;
578
+ if (out === "") {
228
579
  // Nothing changed. Writing zero bytes is the correct output, but the caller
229
580
  // may be waiting on the callback, so it still has to be settled.
230
581
  callback?.(null);
231
582
  return true;
232
583
  }
233
- return real.write(escape, callback);
584
+ return real.write(out, callback);
234
585
  };
235
586
  return new Proxy(real, {
236
587
  get(target, prop, receiver) {
@@ -1 +1 @@
1
- {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../../src/cli/framebuffer/writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../../src/cli/framebuffer/writer.ts"],"names":[],"mappings":"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"}
@@ -35,9 +35,19 @@ export function groupSettled(queueAfterFront) {
35
35
  * queued behind it, so the row arrives already carrying its diff/output instead
36
36
  * of appearing as a bare `Update(home.html)` that grows a body a beat later.
37
37
  *
38
- * Same principle as the group hold above, and the same absence of a timer. The
39
- * caller releases the hold when the stream ends (no further event can arrive) or
40
- * when the user flushes with Esc.
38
+ * Same principle as the group hold above — but NOT the same absence of a timer,
39
+ * and that difference was a real failure. A group is a burst of local reads that
40
+ * resolve in milliseconds; a standalone call can be a release build. Held
41
+ * with no limit, its row was invisible for as long as the command ran: the last
42
+ * thing on screen stayed the tool before it, and an agent quietly building for
43
+ * ten minutes was indistinguishable from an agent that had hung. Reported as a
44
+ * hang, and it was not one.
45
+ *
46
+ * So the hold has a deadline. Past it the row is shown bare and its body arrives
47
+ * when the result does — the two-stage reveal this exists to avoid, accepted
48
+ * deliberately, because it is strictly better than showing nothing at all. The
49
+ * deadline is set well past any local tool, so a read or an edit still arrives
50
+ * whole and nothing about the calm case changes.
41
51
  */
42
52
  export function resultQueued(toolId, queue) {
43
53
  return queue.some((a) => a.type === "toolEnd" && a.toolId === toolId);
@@ -48,4 +58,20 @@ export function resultQueued(toolId, queue) {
48
58
  export function planGroupReveal(settled, flushing) {
49
59
  return settled || flushing ? "flush" : "hold";
50
60
  }
61
+ /**
62
+ * How long a standalone tool row may be held waiting for its own result.
63
+ *
64
+ * Comfortably past any tool that touches only this machine — a read, an edit, a
65
+ * search all resolve in single-digit milliseconds — so the calm case is unchanged
66
+ * and those rows still arrive carrying their body. Comfortably short of the point
67
+ * where a person starts wondering whether anything is happening.
68
+ */
69
+ export const STANDALONE_HOLD_MS = 600;
70
+ /** Whether a held standalone row may be shown now (pure). */
71
+ export function planStandaloneReveal(input) {
72
+ const { resultQueued, flushing, streamDone, heldForMs } = input;
73
+ if (resultQueued || flushing || streamDone)
74
+ return "reveal";
75
+ return heldForMs >= STANDALONE_HOLD_MS ? "reveal" : "hold";
76
+ }
51
77
  //# sourceMappingURL=groupReveal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"groupReveal.js","sourceRoot":"","sources":["../../src/cli/groupReveal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;yDACyD;AACzD,MAAM,UAAU,aAAa,CAAC,CAAoC;IAChE,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;AAC9E,CAAC;AAED;qEACqE;AACrE,MAAM,UAAU,YAAY,CAAC,eAA6D;IACxF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,KAAmD;IAC9F,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACxE,CAAC;AAID;;iEAEiE;AACjE,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,QAAiB;IACjE,OAAO,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"groupReveal.js","sourceRoot":"","sources":["../../src/cli/groupReveal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;yDACyD;AACzD,MAAM,UAAU,aAAa,CAAC,CAAoC;IAChE,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;AAC9E,CAAC;AAED;qEACqE;AACrE,MAAM,UAAU,YAAY,CAAC,eAA6D;IACxF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,KAAmD;IAC9F,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACxE,CAAC;AAID;;iEAEiE;AACjE,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,QAAiB;IACjE,OAAO,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAChD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAEtC,6DAA6D;AAC7D,MAAM,UAAU,oBAAoB,CAAC,KAUpC;IACC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAChE,IAAI,YAAY,IAAI,QAAQ,IAAI,UAAU;QAAE,OAAO,QAAQ,CAAC;IAC5D,OAAO,SAAS,IAAI,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7D,CAAC"}
@@ -13,6 +13,7 @@
13
13
  * off-by-one lives: a word break silently drops the space it broke on, so the rendered
14
14
  * text is shorter than the source it came from.
15
15
  */
16
+ import { findTextColumn } from "./wordEdit.js";
16
17
  /**
17
18
  * Greedy word-wrap that remembers offsets (pure).
18
19
  *
@@ -102,4 +103,48 @@ export function inputView(value, cursor, width, maxRows) {
102
103
  hiddenBelow: all.length - (first + cap),
103
104
  };
104
105
  }
106
+ /**
107
+ * The buffer offset a click at (clickX, clickY) landed on, or null when the click cannot
108
+ * be placed with confidence.
109
+ *
110
+ * A mouse report gives a terminal row and column; this has to turn that into a position
111
+ * in the text. The obvious route — work out where the box was laid out and subtract — is
112
+ * the one thing that must not be done here: the layout is decided by flex at render time,
113
+ * the box has a marker on its first row and continuations on the rest, and any arithmetic
114
+ * that duplicates that becomes wrong the day one of them changes. A wrong answer is not a
115
+ * missing feature, it is a cursor that jumps somewhere the user did not click.
116
+ *
117
+ * So it reads the screen instead. `gridRowAt(y)` returns what was actually PAINTED on
118
+ * row y, and a view row is located by finding its own text there; the difference between
119
+ * where the text starts and where the click landed is the column, with no assumption
120
+ * about borders, padding or the prompt marker.
121
+ *
122
+ * A neighbouring row is checked as well, because two rows of a message can read the same
123
+ * and matching the wrong one would place the caret a line away. Anything that does not
124
+ * resolve returns null and the caller does nothing.
125
+ */
126
+ export function clickToOffset(rows, cursorRow, cursorCol, gridRowAt, width, clickX, clickY) {
127
+ // A painted row IS the row: the caret takes no column of its own. It is the TERMINAL
128
+ // cursor now, parked after the frame (see caretPark.ts), so nothing is inserted into
129
+ // the text and what was rendered matches the buffer exactly.
130
+ for (let i = 0; i < rows.length; i++) {
131
+ const row = rows[i];
132
+ const col = findTextColumn(gridRowAt(clickY), width, row.text);
133
+ if (col < 0)
134
+ continue;
135
+ // Confirm with a neighbour: view rows are contiguous on screen, so the row above (or
136
+ // below, for the first) must be where this match implies it is.
137
+ if (i > 0) {
138
+ if (findTextColumn(gridRowAt(clickY - 1), width, rows[i - 1].text) < 0)
139
+ continue;
140
+ }
141
+ else if (rows.length > 1) {
142
+ if (findTextColumn(gridRowAt(clickY + 1), width, rows[1].text) < 0)
143
+ continue;
144
+ }
145
+ const within = Math.max(0, Math.min(row.text.length, clickX - col));
146
+ return row.start + within;
147
+ }
148
+ return null;
149
+ }
105
150
  //# sourceMappingURL=inputView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"inputView.js","sourceRoot":"","sources":["../../src/cli/inputView.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputView.js","sourceRoot":"","sources":["../../src/cli/inputView.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAoB/C;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,KAAa;IACzD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/D,MAAM;YACR,CAAC;YACD,+EAA+E;YAC/E,sCAAsC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;YACzE,wEAAwE;YACxE,CAAC,IAAI,IAAI,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,CAAC;IACD,KAAK,SAAS,CAAC;IACf,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,4EAA4E;AAC5E,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,SAAS,CAAC;QACR,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7C,OAAO,GAAG,CAAC;QACb,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACjD,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,MAAc,EAAE,KAAa,EAAE,OAAe;IACrF,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAElE,mFAAmF;IACnF,mFAAmF;IACnF,kFAAkF;IAClF,oDAAoD;IACpD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,CAAC,CAAE,CAAC,KAAK,IAAI,aAAa;YAAE,GAAG,GAAG,CAAC,CAAC;;YACvC,MAAM;IACb,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC,GAAG,CAAE,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhG,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IAClF,CAAC;IACD,mFAAmF;IACnF,uFAAuF;IACvF,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IACrE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC3B,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC;QACnC,SAAS,EAAE,GAAG,GAAG,KAAK;QACtB,SAAS;QACT,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC;KACxC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAgB,EAChB,SAAiB,EACjB,SAAiB,EACjB,SAA+C,EAC/C,KAAa,EACb,MAAc,EACd,MAAc;IAEd,qFAAqF;IACrF,qFAAqF;IACrF,6DAA6D;IAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,MAAM,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,GAAG,GAAG,CAAC;YAAE,SAAS;QAEtB,qFAAqF;QACrF,gEAAgE;QAChE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,SAAS;QACpF,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,SAAS;QAChF,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;QACpE,OAAO,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}