@floegence/floeterm-terminal-web 0.14.1 → 0.15.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 (156) hide show
  1. package/README.md +78 -445
  2. package/dist/core/TerminalInputBridge.d.ts +7 -3
  3. package/dist/core/TerminalInputBridge.d.ts.map +1 -1
  4. package/dist/core/TerminalInputBridge.js +63 -4
  5. package/dist/core/TerminalInputBridge.js.map +1 -1
  6. package/dist/entries/live.d.ts +4 -4
  7. package/dist/entries/live.d.ts.map +1 -1
  8. package/dist/entries/live.js +2 -2
  9. package/dist/entries/live.js.map +1 -1
  10. package/dist/entries/semantic.d.ts +9 -0
  11. package/dist/entries/semantic.d.ts.map +1 -0
  12. package/dist/entries/semantic.js +5 -0
  13. package/dist/entries/semantic.js.map +1 -0
  14. package/dist/entries/sessions.d.ts +1 -1
  15. package/dist/entries/sessions.d.ts.map +1 -1
  16. package/dist/index.d.ts +4 -26
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -16
  19. package/dist/index.js.map +1 -1
  20. package/dist/live/client.d.ts +4 -6
  21. package/dist/live/client.d.ts.map +1 -1
  22. package/dist/live/client.js +19 -72
  23. package/dist/live/client.js.map +1 -1
  24. package/dist/live/codec.d.ts +8 -21
  25. package/dist/live/codec.d.ts.map +1 -1
  26. package/dist/live/codec.js +79 -111
  27. package/dist/live/codec.js.map +1 -1
  28. package/dist/live/transport.d.ts +38 -18
  29. package/dist/live/transport.d.ts.map +1 -1
  30. package/dist/live/transport.js +59 -133
  31. package/dist/live/transport.js.map +1 -1
  32. package/dist/semantic/RendererSurface.d.ts +65 -0
  33. package/dist/semantic/RendererSurface.d.ts.map +1 -0
  34. package/dist/semantic/RendererSurface.js +566 -0
  35. package/dist/semantic/RendererSurface.js.map +1 -0
  36. package/dist/semantic/presentation.d.ts +97 -0
  37. package/dist/semantic/presentation.d.ts.map +1 -0
  38. package/dist/semantic/presentation.js +102 -0
  39. package/dist/semantic/presentation.js.map +1 -0
  40. package/dist/types.d.ts +13 -494
  41. package/dist/types.d.ts.map +1 -1
  42. package/dist/types.js +1 -37
  43. package/dist/types.js.map +1 -1
  44. package/package.json +11 -19
  45. package/dist/checkpoint/GhosttyCheckpoint.worker.d.ts +0 -2
  46. package/dist/checkpoint/GhosttyCheckpoint.worker.d.ts.map +0 -1
  47. package/dist/checkpoint/GhosttyCheckpoint.worker.js +0 -9
  48. package/dist/checkpoint/GhosttyCheckpoint.worker.js.map +0 -1
  49. package/dist/checkpoint/GhosttyCheckpointActor.d.ts +0 -44
  50. package/dist/checkpoint/GhosttyCheckpointActor.d.ts.map +0 -1
  51. package/dist/checkpoint/GhosttyCheckpointActor.js +0 -284
  52. package/dist/checkpoint/GhosttyCheckpointActor.js.map +0 -1
  53. package/dist/checkpoint/GhosttyCheckpointEngine.d.ts +0 -62
  54. package/dist/checkpoint/GhosttyCheckpointEngine.d.ts.map +0 -1
  55. package/dist/checkpoint/GhosttyCheckpointEngine.js +0 -175
  56. package/dist/checkpoint/GhosttyCheckpointEngine.js.map +0 -1
  57. package/dist/checkpoint/GhosttyCheckpointWorkerRuntime.d.ts +0 -31
  58. package/dist/checkpoint/GhosttyCheckpointWorkerRuntime.d.ts.map +0 -1
  59. package/dist/checkpoint/GhosttyCheckpointWorkerRuntime.js +0 -112
  60. package/dist/checkpoint/GhosttyCheckpointWorkerRuntime.js.map +0 -1
  61. package/dist/core/PagedTerminalOutputCoordinator.d.ts +0 -130
  62. package/dist/core/PagedTerminalOutputCoordinator.d.ts.map +0 -1
  63. package/dist/core/PagedTerminalOutputCoordinator.js +0 -1213
  64. package/dist/core/PagedTerminalOutputCoordinator.js.map +0 -1
  65. package/dist/core/TerminalCore.d.ts +0 -286
  66. package/dist/core/TerminalCore.d.ts.map +0 -1
  67. package/dist/core/TerminalCore.js +0 -3566
  68. package/dist/core/TerminalCore.js.map +0 -1
  69. package/dist/core/TerminalOutputPipeline.d.ts +0 -86
  70. package/dist/core/TerminalOutputPipeline.d.ts.map +0 -1
  71. package/dist/core/TerminalOutputPipeline.js +0 -511
  72. package/dist/core/TerminalOutputPipeline.js.map +0 -1
  73. package/dist/core/TerminalRenderScheduler.d.ts +0 -45
  74. package/dist/core/TerminalRenderScheduler.d.ts.map +0 -1
  75. package/dist/core/TerminalRenderScheduler.js +0 -145
  76. package/dist/core/TerminalRenderScheduler.js.map +0 -1
  77. package/dist/core/TerminalScrollbarOverlay.d.ts +0 -63
  78. package/dist/core/TerminalScrollbarOverlay.d.ts.map +0 -1
  79. package/dist/core/TerminalScrollbarOverlay.js +0 -493
  80. package/dist/core/TerminalScrollbarOverlay.js.map +0 -1
  81. package/dist/entries/history.d.ts +0 -4
  82. package/dist/entries/history.d.ts.map +0 -1
  83. package/dist/entries/history.js +0 -2
  84. package/dist/entries/history.js.map +0 -1
  85. package/dist/entries/preload.d.ts +0 -3
  86. package/dist/entries/preload.d.ts.map +0 -1
  87. package/dist/entries/preload.js +0 -2
  88. package/dist/entries/preload.js.map +0 -1
  89. package/dist/fabric/BeamtermFabricRenderer.d.ts +0 -67
  90. package/dist/fabric/BeamtermFabricRenderer.d.ts.map +0 -1
  91. package/dist/fabric/BeamtermFabricRenderer.js +0 -659
  92. package/dist/fabric/BeamtermFabricRenderer.js.map +0 -1
  93. package/dist/fabric/TerminalFabricCoordinator.d.ts +0 -40
  94. package/dist/fabric/TerminalFabricCoordinator.d.ts.map +0 -1
  95. package/dist/fabric/TerminalFabricCoordinator.js +0 -141
  96. package/dist/fabric/TerminalFabricCoordinator.js.map +0 -1
  97. package/dist/fabric/TerminalLiveFabric.d.ts +0 -44
  98. package/dist/fabric/TerminalLiveFabric.d.ts.map +0 -1
  99. package/dist/fabric/TerminalLiveFabric.js +0 -117
  100. package/dist/fabric/TerminalLiveFabric.js.map +0 -1
  101. package/dist/fabric/types.d.ts +0 -152
  102. package/dist/fabric/types.d.ts.map +0 -1
  103. package/dist/fabric/types.js +0 -2
  104. package/dist/fabric/types.js.map +0 -1
  105. package/dist/internal/BeamtermResourceLoader.d.ts +0 -3
  106. package/dist/internal/BeamtermResourceLoader.d.ts.map +0 -1
  107. package/dist/internal/BeamtermResourceLoader.js +0 -14
  108. package/dist/internal/BeamtermResourceLoader.js.map +0 -1
  109. package/dist/internal/GhosttyCompatibilityVersion.d.ts +0 -2
  110. package/dist/internal/GhosttyCompatibilityVersion.d.ts.map +0 -1
  111. package/dist/internal/GhosttyCompatibilityVersion.js +0 -2
  112. package/dist/internal/GhosttyCompatibilityVersion.js.map +0 -1
  113. package/dist/internal/GhosttyScrollbackCompat.d.ts +0 -16
  114. package/dist/internal/GhosttyScrollbackCompat.d.ts.map +0 -1
  115. package/dist/internal/GhosttyScrollbackCompat.js +0 -43
  116. package/dist/internal/GhosttyScrollbackCompat.js.map +0 -1
  117. package/dist/internal/GhosttyScrollbarCompat.d.ts +0 -12
  118. package/dist/internal/GhosttyScrollbarCompat.d.ts.map +0 -1
  119. package/dist/internal/GhosttyScrollbarCompat.js +0 -160
  120. package/dist/internal/GhosttyScrollbarCompat.js.map +0 -1
  121. package/dist/internal/SequenceBuffer.d.ts +0 -19
  122. package/dist/internal/SequenceBuffer.d.ts.map +0 -1
  123. package/dist/internal/SequenceBuffer.js +0 -83
  124. package/dist/internal/SequenceBuffer.js.map +0 -1
  125. package/dist/internal/TerminalInitializationScheduler.d.ts +0 -38
  126. package/dist/internal/TerminalInitializationScheduler.d.ts.map +0 -1
  127. package/dist/internal/TerminalInitializationScheduler.js +0 -112
  128. package/dist/internal/TerminalInitializationScheduler.js.map +0 -1
  129. package/dist/internal/TerminalResourceLoader.d.ts +0 -40
  130. package/dist/internal/TerminalResourceLoader.d.ts.map +0 -1
  131. package/dist/internal/TerminalResourceLoader.js +0 -165
  132. package/dist/internal/TerminalResourceLoader.js.map +0 -1
  133. package/dist/internal/UnicodeSafeUrlProvider.d.ts +0 -17
  134. package/dist/internal/UnicodeSafeUrlProvider.d.ts.map +0 -1
  135. package/dist/internal/UnicodeSafeUrlProvider.js +0 -32
  136. package/dist/internal/UnicodeSafeUrlProvider.js.map +0 -1
  137. package/dist/internal/scheduleUiTurn.d.ts +0 -5
  138. package/dist/internal/scheduleUiTurn.d.ts.map +0 -1
  139. package/dist/internal/scheduleUiTurn.js +0 -37
  140. package/dist/internal/scheduleUiTurn.js.map +0 -1
  141. package/dist/manager/TerminalInstanceController.d.ts +0 -88
  142. package/dist/manager/TerminalInstanceController.d.ts.map +0 -1
  143. package/dist/manager/TerminalInstanceController.js +0 -1076
  144. package/dist/manager/TerminalInstanceController.js.map +0 -1
  145. package/dist/utils/errors.d.ts +0 -3
  146. package/dist/utils/errors.d.ts.map +0 -1
  147. package/dist/utils/errors.js +0 -11
  148. package/dist/utils/errors.js.map +0 -1
  149. package/dist/utils/history.d.ts +0 -2
  150. package/dist/utils/history.d.ts.map +0 -1
  151. package/dist/utils/history.js +0 -12
  152. package/dist/utils/history.js.map +0 -1
  153. package/dist/utils/xtermAutoResponseFilter.d.ts +0 -2
  154. package/dist/utils/xtermAutoResponseFilter.d.ts.map +0 -1
  155. package/dist/utils/xtermAutoResponseFilter.js +0 -109
  156. package/dist/utils/xtermAutoResponseFilter.js.map +0 -1
package/README.md CHANGED
@@ -1,486 +1,119 @@
1
- # terminal-web
1
+ # @floegence/floeterm-terminal-web
2
2
 
3
- Framework-neutral ghostty-web (xterm.js API-compatible) integration with terminal core, session, and data flow utilities.
3
+ Framework-neutral browser components for FloeTerm's semantic terminal protocol.
4
4
 
5
- The WebGL2 backend is the exact version of `@floegence/beamterm-renderer` declared by this package. Renderer initialization failures are explicit and retry the same backend; terminal-web never silently falls back to a second renderer.
5
+ The package does not contain a VT parser, Ghostty WASM, a raw replay/checkpoint
6
+ pipeline, or a WebGL terminal renderer. `terminal-go` owns terminal state and emits
7
+ complete immutable Presentations. The browser owns only view-local rendering and
8
+ interaction.
6
9
 
7
10
  ## Install
8
11
 
9
12
  ```bash
10
- npm i @floegence/floeterm-terminal-web
13
+ npm install @floegence/floeterm-terminal-web@0.15.0
11
14
  ```
12
15
 
13
- ## Usage
16
+ ## Exports
14
17
 
15
- Use the managed controller when you want attach, reconnect-friendly replay, ordered writes, resize, and action helpers handled for you:
18
+ | Subpath | API |
19
+ | --- | --- |
20
+ | `./semantic` | `RendererSurface`, `TerminalInputBridge`, validators, semantic types, themes |
21
+ | `./live` | semantic WebSocket codec, client, transport, lifecycle and geometry events |
22
+ | `./sessions` | session coordinator and display-only metadata normalization |
23
+ | `.` | semantic aggregation plus shell-integration parsing utilities |
16
24
 
17
- ```ts
18
- import { createTerminalInstance } from '@floegence/floeterm-terminal-web';
19
-
20
- const controller = createTerminalInstance({
21
- sessionId: 'session-1',
22
- isActive: true,
23
- transport: myTransport,
24
- eventSource: myEventSource,
25
- });
26
-
27
- const unsubscribe = controller.subscribe((snapshot) => {
28
- console.log(snapshot.connection.state, snapshot.loadingMessage);
29
- });
30
-
31
- await controller.mount(container);
32
-
33
- // Later:
34
- controller.actions.copySelection('command');
35
- unsubscribe();
36
- controller.dispose();
37
- ```
38
-
39
- Use `TerminalCore` directly when the host product owns its own session lifecycle, paging, shell integration, or workbench coordination:
40
-
41
- ```ts
42
- import { TerminalCore, getDefaultTerminalConfig } from '@floegence/floeterm-terminal-web';
43
-
44
- const core = new TerminalCore(
45
- container,
46
- getDefaultTerminalConfig('dark', { clipboard: { copyOnSelect: false } }),
47
- {
48
- onData: data => transport.sendInput(sessionId, data),
49
- onResize: size => transport.resize(sessionId, size.cols, size.rows),
50
- },
51
- );
52
-
53
- await core.initialize();
54
- ```
55
-
56
- Session catalogs can carry independent `executionContext`, `workState`,
57
- `foregroundCommand`, and `outputActivity` snapshots. The coordinator fences
58
- each dimension by its own monotonic revision. `TerminalShellIntegrationParser`
59
- filters strict `FloetermContext=v1` and `FloetermWork=v1` metadata from renderer
60
- display data while returning ordered structured events; standard OSC title and
61
- OSC 7 controls remain untouched so replay preserves normal terminal semantics.
62
- Hosts must treat every context value as untrusted presentation metadata.
63
-
64
- Floeterm projects one renderer-neutral DOM scrollbar for both canvas and WebGL terminals while Ghostty remains the only scrollback and viewport owner:
65
-
66
- ```ts
67
- const core = new TerminalCore(container, {
68
- rendererType: 'webgl',
69
- fit: { scrollbarReservePx: 15 },
70
- scrollbar: {
71
- visibility: 'persistent', // "auto" by default, or "hidden"
72
- minThumbPx: 24,
73
- ariaLabel: 'Terminal history',
74
- },
75
- });
76
-
77
- // Keep a long-lived Core aligned with a runtime locale change.
78
- core.setScrollbarOptions({ ariaLabel: localizedTerminalHistoryLabel });
79
- ```
80
-
81
- The scrollbar uses a 12px visual and fine-pointer rail. Reserve at least 12px when the last terminal column must remain fully unobstructed; the default 15px reserve provides a stable gutter. An explicit `scrollbarReservePx: 0` remains supported as an overlay mode and may cover the rightmost 12px. The visual overlay itself never owns pointer hit testing: Floeterm captures fine-pointer track and thumb gestures at the viewport boundary, while wheel and touch events continue to target Ghostty's terminal surface exactly once. `persistent` automatically behaves as `auto` on coarse-pointer-only devices. Mixed-pointer devices keep mouse and pen interaction without creating a dead touch strip.
82
-
83
- Floeterm follows Ghostty's default `keystroke, no-output` viewport policy. New output follows automatically while the viewport is already at the bottom. After a user scrolls into history, incoming output preserves that reading anchor; keyboard or text input, the End key, or an explicit scrollbar action returns to the latest output. Terminal-generated responses and mouse protocol events do not count as user input.
84
-
85
- `auto` reveals on terminal wheel activity, keyboard focus, or fine-pointer movement into the right-edge rail, then fades after 1,200ms of inactivity. `persistent` remains visible on fine-pointer layouts and `hidden` removes the control from pointer, tab, and accessibility access. Alternate-screen programs and empty buffers also hide it. Theme-derived idle and hover/focus colors meet 3:1 and 4.5:1 contrast targets. Drag color targets 7:1; when that ratio is mathematically impossible against the configured background, Floeterm chooses whichever of black or white provides the highest available contrast. Forced-colors and reduced-motion preferences are honored.
86
-
87
- After a host-owned layout transition or history recovery, request an explicit
88
- presentation fence before declaring the terminal surface ready:
89
-
90
- ```ts
91
- await core.forceResizeAndWaitForPresentation();
92
- ```
93
-
94
- The fence performs a fresh resize, requires a complete Beamterm frame, finishes
95
- the submitted WebGL work, and resolves after that frame has crossed a browser
96
- paint opportunity. Concurrent callers before the frame is submitted share the
97
- same work; a caller arriving after submission requests a newer frame. This is an
98
- explicit recovery/lifecycle operation, not a replacement for ordinary demand
99
- rendering.
100
-
101
- Hosts can preload the dynamic Ghostty module, WASM, and renderer resources before a terminal surface is visible without creating a `TerminalCore`:
102
-
103
- ```ts
104
- import { preloadTerminalResources } from '@floegence/floeterm-terminal-web/preload';
105
-
106
- await preloadTerminalResources({ signal });
107
- await core.initialize({ priority: 'interactive', signal });
108
- ```
109
-
110
- Resource loading is single-flight and retryable after a real import or WASM initialization failure. Caller cancellation only stops that caller from waiting; it does not interrupt shared resource initialization. Core initialization is globally bounded, gives queued interactive work priority over background work, and shares the actual ready promise across duplicate calls.
111
-
112
- Use the lightweight subpath exports when the host needs session metadata or renderer-neutral history before loading the full terminal feature:
25
+ ## Render a Presentation
113
26
 
114
27
  ```ts
115
28
  import {
116
- TerminalSessionsCoordinator,
117
- classifyTerminalAgentCli,
118
- } from '@floegence/floeterm-terminal-web/sessions';
119
- import { preparePagedTerminalHistory } from '@floegence/floeterm-terminal-web/history';
120
- ```
121
-
122
- `TerminalSessionsCoordinator` treats `pollMs: 0` as a real periodic-poll disable. Subscribing still performs one best-effort initial reconcile, and explicit `refresh()` calls remain available to a host-owned lifecycle coordinator.
123
-
124
- Session snapshots may include independent `foregroundCommand` and
125
- `outputActivity` metadata. The coordinator normalizes missing metadata to
126
- `unknown` and merges each field only when its own revision is newer, so a stale
127
- list response cannot overwrite a newer output boundary. `outputActivity.phase`
128
- is `streaming` while a running command is producing visible display payload and
129
- becomes `settled` after the configured quiet interval. `settled` does not mean
130
- that the command, Agent turn, or task completed successfully.
131
-
132
- `classifyTerminalAgentCli` maps an already-sanitized foreground basename to an
133
- audited strict identity for Codex, Claude Code, OpenCode, Kimi Code, Gemini CLI,
134
- Qwen Code, GitHub Copilot CLI, Cline, Roo Code, Mistral Vibe, Cursor
135
- Agent, Junie CLI, Kiro CLI, OpenHands, Pi, TRAE Agent, or Kilo Code. Matching is
136
- case-insensitive and accepts one Windows executable suffix (`.exe`, `.cmd`, or
137
- `.bat`), but deliberately rejects paths, arguments, wrappers, partial matches,
138
- Unicode guesses, and overlong values. The root package exports the same helper.
139
- The lightweight sessions entry does not load TerminalCore or renderer code.
140
-
141
- Hosts that own output projection can reuse the bounded shell parser instead of
142
- maintaining a product-specific OSC implementation:
143
-
144
- ```ts
145
- import { TerminalShellIntegrationParser } from '@floegence/floeterm-terminal-web';
146
-
147
- const parser = new TerminalShellIntegrationParser();
148
- const { displayData, events, tokens } = parser.parse(chunk);
149
- core.write(displayData);
150
- ```
151
-
152
- When the host has an authoritative PTY hostname, pass it explicitly as
153
- `new TerminalShellIntegrationParser({ localHostname })` to reject same-host
154
- remote hints. The parser never infers the PTY host from the browser page origin.
155
-
156
- The parser recognizes OSC 633 prompt/command/cwd markers and Floeterm's safe
157
- program label. Recognized metadata is removed from display output, unknown OSC
158
- sequences are preserved, fragmented input is bounded, and program labels are
159
- limited to a 64-byte ASCII allowlist. The label never contains command
160
- arguments or environment values. `tokens` preserves the original order of
161
- display segments and recognized events, allowing hosts to attribute output to
162
- the foreground revision that was active at that exact byte boundary.
163
-
164
- ## Notes
165
-
166
- - You must provide a `TerminalTransport` and `TerminalEventSource` for the managed controller.
167
- - Each `TerminalCore` owns an isolated `@floegence/ghostty-web` WASM runtime; consumers must not provide or share a Ghostty runtime.
168
- - `scrollback` is measured in terminal buffer rows, including separately wrapped rows, and accepts integers from 1 through 10,000. Within the supported geometry, Floeterm preserves at least the requested number of buffer rows; it does not trim to an exact physical row count. Floeterm maps that contract to a bounded byte budget for the exact pinned `@floegence/ghostty-web@0.5.0-rc.0` release, which currently interprets the value as bytes. The 81,920,000-byte cap limits Ghostty's scrollback arena, not the total memory of a WASM runtime. The mapping is temporary and must be reviewed and removed or updated with any Ghostty upgrade.
169
- - Supported terminal geometry is limited to 500 columns. Explicit dimensions above that limit fail, while automatic fitting reports at most 500 columns.
170
- - Consumer dependency overrides for `@floegence/ghostty-web` are unsupported. Floeterm's compatibility guard requires the exact package pin so an upstream behavior change cannot silently apply the row-to-byte mapping twice or reactivate the native canvas scrollbar beneath the renderer-neutral DOM control.
171
- - `TerminalCore` bridges the hidden textarea used by `ghostty-web`, so soft-keyboard and composition input continue to work on touch devices.
172
- - The hidden terminal input is mounted in the document viewport plane and anchored from rendered cursor geometry, so native IME candidate windows stay aligned without expanding transformed terminal hosts.
173
- - Programmatic terminal focus uses no-scroll focus by default, keeping embedded terminals stable inside scaled, projected, or otherwise transformed host surfaces.
174
- - Explicit terminal copy is handled through shared selection-copy APIs, so keyboard shortcuts, native app menus, and product context menus can reuse the same selection logic.
175
- - `TerminalCore` exposes runtime appearance updates, shell bell/title events, custom terminal link providers, buffer line reads, and touch-scroll helpers without requiring consumers to reach into private runtime objects.
176
- - Multiple live `TerminalCore` instances share one render scheduler, so large terminal grids coalesce demand-driven canvas work into browser frames.
177
-
178
- ## Paged History And Live Recovery
179
-
180
- Hosts with cursor-paged history APIs can use the framework-neutral coordinator instead of maintaining a second live-output queue:
181
-
182
- ```ts
183
- const output = createPagedTerminalOutputCoordinator({
184
- fetchPage: ({ startSequence, endSequence, historyGeneration, cursor, signal }) =>
185
- transport.historyPage(sessionId, {
186
- startSequence,
187
- endSequence,
188
- historyGeneration,
189
- cursor,
190
- signal,
191
- }),
192
- write: data => new Promise(resolve => core.write(data, resolve)),
193
- writeHistory: data => new Promise(resolve => core.writeHistory(data, resolve)),
194
- clear: () => core.clear(),
195
- });
196
-
197
- void output.attach(1);
198
- const baseline = await output.waitForBaseline();
199
- if (!baseline.baselineReady) {
200
- throw baseline.failure;
201
- }
202
- events.onData(sessionId, chunk => output.pushLive(chunk));
203
- ```
204
-
205
- History pages must explicitly include `coveredThroughSequence`, including the valid empty-history value `0`. A missing or malformed value produces a structured contract failure instead of guessing from the last returned chunk. The first page may also provide `snapshotEndSequence`, `firstRetainedSequence`, and `historyGeneration`; pass the snapshot end and generation through each later request.
206
-
207
- History chunks must also carry the PTY geometry that produced their bytes:
208
- `geometryGeneration`, `cols`, and `rows`. The coordinator validates that tuple,
209
- keeps generations monotonic, splits writes at geometry changes, and invokes
210
- `applyHistoryGeometry` immediately before each history batch. Hosts that replay
211
- history into a fixed-grid renderer must use that hook to set the recorded
212
- dimensions; omitting or conflicting geometry fails the replay contract rather
213
- than silently interpreting historical cursor movement at the current grid.
214
-
215
- If a page reports `historyReset` or changes `historyGeneration` while catch-up is running, the coordinator atomically clears the obsolete baseline, preserves retained live output, and restarts from the new generation. Hosts must not merge pages from different generations or reinterpret the expected coverage reset as a malformed regression.
216
-
217
- `baselineReady` becomes true only after the complete fixed history snapshot has been source-sequence merged with retained live output and the final history writer completion has fired. After that fence, catch-up retries preserve baseline readiness and do not need to block input. Structured failures distinguish initial replay from background catch-up and expose stable codes without requiring error-string parsing.
218
-
219
- Use `TerminalCore.writeHistory` for history batches. Its auto-response suppression is scoped to that parser write and ends at its completion callback, so later live output and user input use normal terminal behavior.
220
-
221
- Running sessions can prepare bounded history before a visible terminal exists. Preparation does not create a Core, attach a session, resize a PTY, or subscribe to live output:
222
-
223
- ```ts
224
- const preparedHistory = await preparePagedTerminalHistory({
225
- fetchPage: request => transport.historyPage(sessionId, request),
226
- maxBytes: 4 * 1024 * 1024,
227
- signal,
228
- });
229
-
230
- const attachGeneration = output.beginAttach(0);
231
- const attach = await transport.attachWithHistoryBoundary(sessionId, cols, rows);
232
- await output.completeAttach(attachGeneration, attach.historyBoundarySequence, {
233
- preparedHistory,
234
- });
235
-
236
- const baseline = await output.waitForBaseline();
237
- if (baseline.preparedHistoryOutcome?.status === 'accepted') {
238
- console.log('prepared history used', { rebased: baseline.preparedHistoryOutcome.rebased });
239
- }
240
- ```
241
-
242
- Prepared history is renderer-neutral and pins `historyGeneration`, `firstRetainedSequence`, and `snapshotEndSequence`. The visible attach validates those boundaries, replays the seed once, and fetches only the missing delta. A generation reset, retention advance, stale fence, or malformed seed discards it and falls back to the normal full recovery path. The baseline snapshot reports `accepted`, `rejected`, or `not-provided` plus a `rebased` flag, so hosts do not need to infer seed use from fetched byte counts.
243
-
244
- `preparePagedTerminalHistory` requires those three metadata fields on every prepared page and passes the remaining retained-byte budget as `request.maxBytes` so transports can bound each page as well. The helper always enforces its retained seed budget after a page returns; adapters should honor the request hint to keep peak response memory bounded too.
245
-
246
- ## Restorable In-Memory Snapshots
247
-
248
- Adaptive host worksets can release inactive renderers without closing their PTY sessions:
249
-
250
- ```ts
251
- await output.pause();
252
- const snapshot = core.captureRestorableSnapshot({
253
- coveredThroughSequence: output.getSnapshot().coveredThroughSequence,
254
- });
255
- const estimate = core.getResourceEstimate();
256
-
257
- core.dispose(); // The host-owned PTY and output coordinator remain alive.
29
+ RendererSurface,
30
+ getThemeColors,
31
+ validatePresentation,
32
+ } from '@floegence/floeterm-terminal-web/semantic';
258
33
 
259
- const restored = await nextCore.restoreSnapshot(snapshot);
260
- output.setActive(true);
34
+ const renderer = new RendererSurface(canvas, error => showInlineError(error));
35
+ renderer.setPalette(getThemeColors('tokyoNight'));
36
+ renderer.apply(validatePresentation(payload));
261
37
  ```
262
38
 
263
- `pause()` stops new live writes, cancels retry or catch-up work, and resolves only after every writer that already entered the terminal parser has completed. Live output received while paused remains in the coordinator's bounded retained queue. Hosts must await this fence before capturing or disposing a core; if a host abandons hibernation, it should keep the core and call `setActive(true)`.
264
-
265
- Snapshots are versioned opaque values intended for memory-only storage. They are bounded to 2 MiB by default and include sequence coverage so the host can fetch only newer output. Floeterm does not write snapshots to persistent browser storage.
266
-
267
- ## Responsive Resize
39
+ `RendererSurface` owns one 2D canvas. It keeps the latest immutable Presentation,
40
+ rejects sequence or geometry regressions, follows host CSS bounds, tracks DPR changes,
41
+ fills every backing pixel before painting cells/graphics/cursor, and never stretches
42
+ the authoritative cell grid to an observer viewport.
268
43
 
269
- When the same remote terminal session can be displayed in multiple views, enable responsive options so the focused terminal re-syncs cols/rows to the remote PTY:
44
+ Themes are view-local. Changing the palette repaints the latest Presentation without
45
+ requesting output, resizing the PTY, or affecting another view. Explicit ANSI/RGB
46
+ colors stay semantic; only default foreground/background/cursor fallbacks change.
270
47
 
271
- ```ts
272
- const core = new TerminalCore(container, {
273
- responsive: {
274
- fitOnFocus: true,
275
- emitResizeOnFocus: true,
276
- notifyResizeOnlyWhenFocused: true,
277
- },
278
- });
279
- ```
280
-
281
- For an active fixed-grid view that is becoming interactive after history recovery,
282
- measure host capacity without changing the shared PTY grid, then submit that
283
- capacity through the host transport:
48
+ ## Input and IME
284
49
 
285
50
  ```ts
286
- await core.forceResizeAndWaitForPresentation();
287
- const hostDimensions = core.measureHostDimensions();
288
- ```
51
+ import { TerminalInputBridge } from '@floegence/floeterm-terminal-web/semantic';
289
52
 
290
- `measureHostDimensions()` is read-only. It returns `undefined` while the host or
291
- renderer has no usable dimensions and never bypasses focus-gated resize policy;
292
- the host remains responsible for deciding whether to request a shared PTY resize.
293
-
294
- When a host can capture an atomic attach boundary, call `beginAttach(startSequence)` before subscribing and starting the server attach, then pass its generation token together with the returned server boundary to `completeAttach(attachGeneration, snapshotEndSequence)`. Live output arriving during the attach round trip remains retained, while a stale attach acknowledgement cannot complete a newer generation. The convenience `attach(startSequence, snapshotEndSequence)` performs both steps when no such window exists. Route only sequences after the boundary to `pushLive`: initial history is fixed at the boundary, while catch-up history is bounded before the first retained live sequence. If defensive overlap still reaches the coordinator, the raw live copy wins over history for the same sequence so terminal query/response behavior is not replaced by replay semantics.
295
-
296
- Passive mirrors of a remote PTY can render with the session owner's current dimensions:
297
-
298
- ```ts
299
- const core = new TerminalCore(container, {
300
- fixedDimensions: { cols: 100, rows: 30 },
53
+ const bridge = new TerminalInputBridge({
54
+ inputHost,
55
+ inputElement: textarea,
56
+ onData: data => sendInput(data),
57
+ syncInputGeometry: () => positionTextarea(renderer.getCursorClientRect()),
301
58
  });
302
-
303
- core.setFixedDimensions(null);
304
- core.forceResize();
305
59
  ```
306
60
 
307
- Interactive views of one shared PTY can keep independent viewport measurements while rendering the server-confirmed terminal grid:
308
-
309
- ```ts
310
- const controller = createTerminalInstance({
311
- sessionId,
312
- transport,
313
- eventSource,
314
- isActive: true,
315
- config: {
316
- responsive: {
317
- reportHostDimensionsWithFixedGrid: true,
318
- },
319
- },
320
- });
321
- ```
61
+ The textarea must remain editable and positioned in the visible terminal viewport.
62
+ Composition preedit is never sent to the PTY. The final Unicode composition commit is
63
+ sent exactly once across Chrome/Safari event orderings. Physical keys, paste,
64
+ dead-key/emoji input, copy shortcuts, focus, and controller ownership remain separate
65
+ from composition state.
322
66
 
323
- The live transport applies `ATTACHED`, `GEOMETRY_CHANGED`, `RESIZE_APPLIED`, and `OUTPUT_BATCH` geometry monotonically. Container resize notifications still report each view's own capacity to the server.
67
+ The cursor rectangle uses CSS pixels. Canvas backing DPR is not multiplied into the
68
+ IME anchor.
324
69
 
325
- Hosts that need to explain shared PTY geometry can request the structured, boundary-ordered resize result instead of guessing from the latest geometry event:
70
+ ## Semantic Live Transport
326
71
 
327
72
  ```ts
328
- const applied = await transport.resizeWithEffectiveGeometry(sessionId, localCols, localRows);
329
-
330
- console.log(applied.runtimeAttachGeneration);
331
- console.log(applied.requested); // This view's requested grid.
332
- console.log(applied.effective); // The shared grid after its output boundary.
333
- ```
334
-
335
- The existing `transport.resize()` remains available and resolves at the same boundary without returning the result. `eventSource.onTerminalLiveAttachmentLifecycle()` reports the exact runtime attach generation entering `attached` or `closed`. Output, geometry, resize results, errors, and close callbacks from superseded generations are fenced before they reach host listeners.
336
-
337
- Hosts with overlay scrollbars can remove the default ghostty-web scrollbar reserve:
338
-
339
- ```ts
340
- const core = new TerminalCore(container, {
341
- fit: {
342
- scrollbarReservePx: 0,
343
- },
344
- });
345
- ```
346
-
347
- ## Clipboard
348
-
349
- By default, upstream mouse selection keeps the `ghostty-web` behavior and copies immediately on selection. Consumers that want explicit copy commands only can disable that side effect:
350
-
351
- ```ts
352
- const core = new TerminalCore(container, {
353
- clipboard: {
354
- copyOnSelect: false,
355
- },
73
+ import {
74
+ createSemanticTerminalLiveTransport,
75
+ } from '@floegence/floeterm-terminal-web/live';
76
+
77
+ const { transport, eventSource } = createSemanticTerminalLiveTransport({
78
+ connectionId,
79
+ openStream,
80
+ control,
81
+ onError: reportError,
356
82
  });
357
- ```
358
-
359
- With `copyOnSelect: false`, `TerminalCore` keeps selection explicit:
360
-
361
- - `core.hasSelection()` reports whether the terminal currently owns a copyable selection.
362
- - `core.copySelection()` writes the current terminal selection to the clipboard.
363
- - `Cmd+C` / `Ctrl+C` copies only when the terminal currently has a selection. Without a selection, `Ctrl+C` remains terminal input and produces the standard interrupt control byte; `Cmd+C` is not converted into terminal input.
364
-
365
- The managed controller exposes the same helpers through `controller.actions`.
366
-
367
- ## Link Providers And Buffer Reads
368
83
 
369
- `TerminalCore` forwards shell lifecycle events and lets consumers register custom links over rendered terminal rows:
370
-
371
- ```ts
372
- import { TerminalCore, type TerminalLinkProvider } from '@floegence/floeterm-terminal-web';
373
-
374
- const linkProvider: TerminalLinkProvider = {
375
- provideLinks(y, callback) {
376
- const line = core.readBufferLine(y);
377
- void line;
378
- callback(undefined);
379
- },
380
- };
381
-
382
- const core = new TerminalCore(container, {}, {
383
- onBell: () => console.log('bell'),
384
- onTitleChange: title => console.log('title', title),
84
+ await transport.attach(sessionId, cols, rows);
85
+ const stop = eventSource.onTerminalPresentation(sessionId, value => {
86
+ renderer.apply(validatePresentation(value));
385
87
  });
386
-
387
- await core.initialize();
388
- core.registerLinkProvider(linkProvider);
389
88
  ```
390
89
 
391
- This is the intended extension point for product features such as modifier-click file navigation, build-log deep links, or shell attention badges driven by bell events.
90
+ The transport carries attach, structured input, canonical resize settlement,
91
+ Presentation, geometry, and lifecycle frames. It does not carry raw PTY output.
92
+ Unknown input is not replayed after a disconnect. A new transport generation does not
93
+ write through an old connection.
392
94
 
393
- ## Touch Scroll Helpers
95
+ ## Session Metadata
394
96
 
395
- Hosts with custom mobile input surfaces can ask `TerminalCore` for a safe touch-scroll facade instead of reaching into the underlying runtime:
97
+ The `./sessions` entry is independent of rendering. It normalizes session list,
98
+ foreground command, output activity, execution context, and semantic work metadata.
99
+ These values are display-only and must not be used for authorization.
396
100
 
397
- ```ts
398
- const touch = core.getTouchScrollRuntime();
399
-
400
- if (touch?.isAlternateScreen()) {
401
- touch.sendAlternateScreenInput('\x1B[A');
402
- } else {
403
- touch?.scrollLines(-3);
404
- }
405
- ```
101
+ ## Lifecycle
406
102
 
407
- ## Visual Work Suspension
103
+ Dispose each view's subscriptions, input bridge, renderer, and live transport. Disposal
104
+ cancels RAF/blink/DPR/font listeners and releases graphics bitmaps without detaching or
105
+ resizing another view.
408
106
 
409
- Hosts that animate a surrounding workbench can temporarily suspend expensive terminal visual work while keeping PTY output and the terminal buffer live:
410
-
411
- ```ts
412
- const suspend = core.beginVisualSuspend({ reason: 'workbench_widget_drag' });
413
-
414
- try {
415
- // Move, zoom, or resize the host surface.
416
- } finally {
417
- suspend.dispose();
418
- }
419
- ```
420
-
421
- While suspended, `write()` continues to update terminal state. Rendering, fit, full repaint, and overlay refresh requests are coalesced and reconciled when the final nested suspend handle is disposed.
422
-
423
- ## Multi-Terminal Render Scheduling
424
-
425
- `TerminalCore` keeps ghostty-web rendering demand-driven and routes visible terminal repaints through a shared scheduler. Demo or profiling surfaces can inspect the scheduler without reaching into private instances:
426
-
427
- ```ts
428
- import { getTerminalRenderSchedulerStats } from '@floegence/floeterm-terminal-web';
429
-
430
- const stats = getTerminalRenderSchedulerStats();
431
- console.log(stats.lastFrameRendered, stats.pending);
432
- ```
107
+ ## Development
433
108
 
434
- Product code should continue to interact with `TerminalCore` or the managed controller.
435
-
436
- ## Runtime Appearance Updates
437
-
438
- Consumers that need to respond to user preferences can update appearance without rebuilding the terminal session:
439
-
440
- ```ts
441
- import { getThemeColors } from '@floegence/floeterm-terminal-web';
442
-
443
- core.setAppearance({
444
- theme: getThemeColors('light'),
445
- fontSize: 14,
446
- fontFamily: '"Iosevka Term", monospace',
447
- presentationScale: 1,
448
- });
449
-
450
- core.setFontFamily('"Iosevka Term", monospace');
451
- ```
452
-
453
- ## Built-in Theme Catalog
454
-
455
- Floeterm 0.8.0 publishes 20 immutable built-in theme definitions. Hosts can use
456
- the same stable catalog for validation, previews, and terminal rendering:
457
-
458
- ```ts
459
- import {
460
- TERMINAL_THEME_DEFINITIONS,
461
- getThemeColors,
462
- normalizeTerminalThemeName,
463
- } from '@floegence/floeterm-terminal-web';
464
-
465
- const selected = normalizeTerminalThemeName(persistedValue, 'dark');
466
- const colors = getThemeColors(selected);
467
- const lightThemes = TERMINAL_THEME_DEFINITIONS.filter(
468
- (theme) => theme.appearance === 'light',
469
- );
109
+ ```bash
110
+ npm ci
111
+ npm run lint
112
+ npm test
113
+ npm run test:browser
114
+ npm run build
115
+ npm run check:package-artifact
470
116
  ```
471
117
 
472
- The exported arrays, definitions, and nested color objects are frozen at
473
- runtime. `getThemeColors()` returns a defensive copy. Theme provenance and
474
- third-party license details ship in `THEME_PROVENANCE.json` and
475
- `THIRD_PARTY_THEME_NOTICES.md`. The package also includes
476
- `THEME_QUALITY_EVIDENCE.json` with the catalog thresholds, measured results,
477
- and Signal Safe color-vision simulation evidence.
478
-
479
- ### 0.8.0 migration
480
-
481
- - `TerminalThemeName` now includes the full catalog; exhaustive switches must
482
- handle the new IDs.
483
- - `getThemeColors()` keeps its function name but returns the exact readonly
484
- `TerminalThemeColors` type instead of a mutable `Record<string, string>`.
485
- - `light`, `solarizedDark`, and `monokai` add `cursorAccent` equal to their
486
- existing background. All other legacy fields and values are unchanged.
118
+ The package-artifact check installs the packed tarball into a fresh consumer and
119
+ rejects removed parser, checkpoint, renderer, and WASM contracts.
@@ -1,6 +1,6 @@
1
1
  import type { Logger, TerminalCopySelectionResult, TerminalCopySelectionSource, TerminalFocusOptions } from '../types.js';
2
2
  export declare const resolveTerminalInputElement: (inputHost: HTMLElement) => HTMLTextAreaElement | null;
3
- type terminal_input_bridge_options = {
3
+ export type TerminalInputBridgeOptions = {
4
4
  inputHost: HTMLElement;
5
5
  inputElement: HTMLTextAreaElement;
6
6
  onData: (data: string) => void;
@@ -18,6 +18,7 @@ export declare class TerminalInputBridge {
18
18
  private readonly copySelection;
19
19
  private readonly syncInputGeometry;
20
20
  private isComposing;
21
+ private pendingCompositionCommit;
21
22
  private ignoreNextInput;
22
23
  private suppressionToken;
23
24
  private ephemeralStateResetTimer;
@@ -30,11 +31,13 @@ export declare class TerminalInputBridge {
30
31
  private readonly compositionStartListener;
31
32
  private readonly compositionEndListener;
32
33
  private readonly focusListener;
34
+ private readonly blurListener;
33
35
  private readonly inputHostFocusInListener;
34
36
  private readonly inputHostPointerDownListener;
35
37
  private inputFocusClaimTimer;
36
- constructor(options: terminal_input_bridge_options);
38
+ constructor(options: TerminalInputBridgeOptions);
37
39
  focus(options?: TerminalFocusOptions): void;
40
+ syncGeometry(): void;
38
41
  dispose(): void;
39
42
  private attach;
40
43
  private handleInputHostFocusIn;
@@ -44,6 +47,7 @@ export declare class TerminalInputBridge {
44
47
  private handleInput;
45
48
  private handleCompositionStart;
46
49
  private handleCompositionEnd;
50
+ private consumeCompositionCommitBeforeInput;
47
51
  containsTarget(target: Node): boolean;
48
52
  tryHandleDocumentCopyShortcut(event: KeyboardEvent): boolean;
49
53
  tryHandleDocumentCopyEvent(event: ClipboardEvent): boolean;
@@ -52,10 +56,10 @@ export declare class TerminalInputBridge {
52
56
  private patchTerminalFocusHost;
53
57
  private requestSelectionCopy;
54
58
  private clearInputValue;
59
+ private resetCompositionState;
55
60
  private emitData;
56
61
  private scheduleEphemeralStateReset;
57
62
  private clearEphemeralStateResetTimer;
58
63
  private clearInputFocusClaimTimer;
59
64
  }
60
- export {};
61
65
  //# sourceMappingURL=TerminalInputBridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TerminalInputBridge.d.ts","sourceRoot":"","sources":["../../src/core/TerminalInputBridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAsLrB,eAAO,MAAM,2BAA2B,GAAI,WAAW,WAAW,KAAG,mBAAmB,GAAG,IAG1F,CAAC;AAEF,KAAK,6BAA6B,GAAG;IACnC,SAAS,EAAE,WAAW,CAAC;IACvB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,CACd,MAAM,EAAE,2BAA2B,EACnC,aAAa,CAAC,EAAE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC;IACxE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAChC,CAAC;AAEF,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAG0C;IACxE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAa;IAC/C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAwC;IAChE,OAAO,CAAC,wBAAwB,CAA8C;IAC9E,OAAO,CAAC,wBAAwB,CAA4B;IAC5D,OAAO,CAAC,wBAAwB,CAA6B;IAC7D,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAa;IAE9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAE9B;IAEF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAElC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAEvC;IAEF,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAErC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAEvC;IAEF,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAE3C;IAEF,OAAO,CAAC,oBAAoB,CAA8C;gBAE9D,OAAO,EAAE,6BAA6B;IAmBlD,KAAK,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI;IAK3C,OAAO,IAAI,IAAI;IAiBf,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,WAAW;IA6BnB,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,oBAAoB;IAc5B,cAAc,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO;IAMrC,6BAA6B,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAuB5D,0BAA0B,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO;IAmB1D,OAAO,CAAC,iCAAiC;IAQzC,OAAO,CAAC,6BAA6B;IAerC,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,2BAA2B;IASnC,OAAO,CAAC,6BAA6B;IASrC,OAAO,CAAC,yBAAyB;CAQlC"}
1
+ {"version":3,"file":"TerminalInputBridge.d.ts","sourceRoot":"","sources":["../../src/core/TerminalInputBridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAsLrB,eAAO,MAAM,2BAA2B,GAAI,WAAW,WAAW,KAAG,mBAAmB,GAAG,IAG1F,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,WAAW,CAAC;IACvB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,CACd,MAAM,EAAE,2BAA2B,EACnC,aAAa,CAAC,EAAE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC;IACxE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAChC,CAAC;AAEF,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAG0C;IACxE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAa;IAC/C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,wBAAwB,CAAuB;IACvD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAwC;IAChE,OAAO,CAAC,wBAAwB,CAA8C;IAC9E,OAAO,CAAC,wBAAwB,CAA4B;IAC5D,OAAO,CAAC,wBAAwB,CAA6B;IAC7D,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAa;IAE9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAE9B;IAEF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAElC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAEvC;IAEF,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAErC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAG5B;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAG3B;IAEF,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAEvC;IAEF,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAE3C;IAEF,OAAO,CAAC,oBAAoB,CAA8C;gBAE9D,OAAO,EAAE,0BAA0B;IAmB/C,KAAK,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI;IAK3C,YAAY,IAAI,IAAI;IAIpB,OAAO,IAAI,IAAI;IAkBf,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,aAAa;IA6BrB,OAAO,CAAC,iBAAiB;IAsCzB,OAAO,CAAC,WAAW;IAsCnB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mCAAmC;IAqB3C,cAAc,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO;IAMrC,6BAA6B,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAuB5D,0BAA0B,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO;IAmB1D,OAAO,CAAC,iCAAiC;IAQzC,OAAO,CAAC,6BAA6B;IAerC,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,2BAA2B;IASnC,OAAO,CAAC,6BAA6B;IASrC,OAAO,CAAC,yBAAyB;CAQlC"}