diff --git a/.patches/@opentui/core/LICENSE b/.patches/@opentui/core/LICENSE new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 opentui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/.patches/@opentui/core/NativeSpanFeed.d.ts b/.patches/@opentui/core/NativeSpanFeed.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/NativeSpanFeed.d.ts @@ -0,0 +1,52 @@ +import { type Pointer } from "./platform/ffi.js"; +import type { NativeSpanFeedOptions } from "./zig-structs.js"; +export type { GrowthPolicy, NativeSpanFeedOptions, NativeSpanFeedStats } from "./zig-structs.js"; +export type DataHandler = (data: Uint8Array) => void | Promise; +/** + * Zero-copy wrapper over Zig memory; not a full stream interface. + * Chunk and state typed-array views are borrowed and invalid after destroy. + */ +export declare class NativeSpanFeed { + static create(options?: NativeSpanFeedOptions): NativeSpanFeed; + static attach(streamPtr: Pointer, _options?: NativeSpanFeedOptions): NativeSpanFeed; + readonly streamPtr: Pointer; + private readonly lib; + private readonly eventHandler; + private chunkMap; + private chunkSizes; + private dataHandlers; + private errorHandlers; + private drainBuffer; + private stateBuffer; + private closed; + private destroyed; + private draining; + private pendingDataAvailable; + private pendingClose; + private closing; + private pendingAsyncHandlers; + private inCallback; + private closeQueued; + private idleResolvers; + private pendingHandlerError; + private pendingHandlerErrorQueued; + private constructor(); + private ensureDrainBuffer; + onData(handler: DataHandler): () => void; + onError(handler: (code: number) => void): () => void; + private hasPinnedChunks; + isBackpressured(): boolean; + close(): void; + private processPendingClose; + private performClose; + private finalizeDestroy; + private isIdle; + private resolveIdleIfNeeded; + idle(): Promise; + private handleEvent; + private decrementRefcount; + private queuePendingHandlerError; + private throwPendingHandlerError; + private drainOnce; + drainAll(): void; +} diff --git a/.patches/@opentui/core/README.md b/.patches/@opentui/core/README.md new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/README.md @@ -0,0 +1,63 @@ +# OpenTUI Core + +OpenTUI is a native terminal UI core written in Zig with TypeScript bindings. The native core exposes a C ABI and can be used from any language. OpenTUI powers OpenCode in production today and will also power terminal.shop. It is an extensible core with a focus on correctness, stability, and high performance. It provides a component-based architecture with flexible layout capabilities, allowing you to create complex terminal applications. + +## Documentation + +- [Getting Started](docs/getting-started.md) - API and usage guide +- [Development Guide](docs/development.md) - Building, testing, and contributing +- [Tree-Sitter](docs/tree-sitter.md) - Syntax highlighting integration +- [Renderables vs Constructs](docs/renderables-vs-constructs.md) - Understanding the component model +- [Environment Variables](docs/env-vars.md) - Configuration options + +## Install + +```bash +bun install @opentui/core +``` + +## Build + +```bash +bun run build +``` + +This creates platform-specific libraries that are automatically loaded by the TypeScript layer. + +## Examples + +```bash +bun install +cd ../examples +bun run dev +``` + +## Benchmarks + +Run native performance benchmarks: + +```bash +bun run bench:native +``` + +See [src/zig/bench.zig](src/zig/bench.zig) for available options like `--filter` and `--mem`. + +NativeSpanFeed TypeScript benchmarks: + +- [src/benchmark/native-span-feed-benchmark.md](src/benchmark/native-span-feed-benchmark.md) + +## CLI Renderer + +### Renderables + +Renderables are hierarchical objects that can be positioned, nested, styled and rendered to the terminal: + +```typescript +import { createCliRenderer, TextRenderable } from "@opentui/core" + +const renderer = await createCliRenderer() + +const obj = new TextRenderable(renderer, { id: "my-obj", content: "Hello, world!" }) + +renderer.root.add(obj) +``` diff --git a/.patches/@opentui/core/Renderable.d.ts b/.patches/@opentui/core/Renderable.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/Renderable.d.ts @@ -0,0 +1,351 @@ +import { EventEmitter } from "events"; +import { type Node as YogaNode } from "./yoga.js"; +import { OptimizedBuffer } from "./buffer.js"; +import type { KeyEvent, PasteEvent } from "./lib/KeyHandler.js"; +import type { Selection } from "./lib/selection.js"; +import { type AlignString, type FlexDirectionString, type JustifyString, type OverflowString, type PositionTypeString, type WrapString } from "./lib/yoga.options.js"; +import { type VNode } from "./renderables/composition/vnode.js"; +import type { MouseEvent } from "./renderer.js"; +import type { RenderContext } from "./types.js"; +declare const BrandedRenderable: unique symbol; +export declare enum LayoutEvents { + LAYOUT_CHANGED = "layout-changed", + ADDED = "added", + REMOVED = "removed", + RESIZED = "resized" +} +export declare enum RenderableEvents { + FOCUSED = "focused", + BLURRED = "blurred", + DESTROYED = "destroyed" +} +export interface Position { + top?: number | "auto" | `${number}%`; + right?: number | "auto" | `${number}%`; + bottom?: number | "auto" | `${number}%`; + left?: number | "auto" | `${number}%`; +} +export interface BaseRenderableOptions { + id?: string; +} +export interface LayoutOptions extends BaseRenderableOptions { + flexGrow?: number; + flexShrink?: number; + flexDirection?: FlexDirectionString; + flexWrap?: WrapString; + alignItems?: AlignString; + justifyContent?: JustifyString; + alignSelf?: AlignString; + flexBasis?: number | "auto" | undefined; + position?: PositionTypeString; + overflow?: OverflowString; + top?: number | "auto" | `${number}%`; + right?: number | "auto" | `${number}%`; + bottom?: number | "auto" | `${number}%`; + left?: number | "auto" | `${number}%`; + minWidth?: number | "auto" | `${number}%`; + minHeight?: number | "auto" | `${number}%`; + maxWidth?: number | "auto" | `${number}%`; + maxHeight?: number | "auto" | `${number}%`; + margin?: number | "auto" | `${number}%`; + marginX?: number | "auto" | `${number}%`; + marginY?: number | "auto" | `${number}%`; + marginTop?: number | "auto" | `${number}%`; + marginRight?: number | "auto" | `${number}%`; + marginBottom?: number | "auto" | `${number}%`; + marginLeft?: number | "auto" | `${number}%`; + padding?: number | `${number}%`; + paddingX?: number | `${number}%`; + paddingY?: number | `${number}%`; + paddingTop?: number | `${number}%`; + paddingRight?: number | `${number}%`; + paddingBottom?: number | `${number}%`; + paddingLeft?: number | `${number}%`; + enableLayout?: boolean; +} +export interface RenderableOptions extends Partial { + width?: number | "auto" | `${number}%`; + height?: number | "auto" | `${number}%`; + zIndex?: number; + visible?: boolean; + buffered?: boolean; + live?: boolean; + opacity?: number; + renderBefore?: (this: T, buffer: OptimizedBuffer, deltaTime: number) => void; + renderAfter?: (this: T, buffer: OptimizedBuffer, deltaTime: number) => void; + onMouse?: (this: T, event: MouseEvent) => void; + onMouseDown?: (this: T, event: MouseEvent) => void; + onMouseUp?: (this: T, event: MouseEvent) => void; + onMouseMove?: (this: T, event: MouseEvent) => void; + onMouseDrag?: (this: T, event: MouseEvent) => void; + onMouseDragEnd?: (this: T, event: MouseEvent) => void; + onMouseDrop?: (this: T, event: MouseEvent) => void; + onMouseOver?: (this: T, event: MouseEvent) => void; + onMouseOut?: (this: T, event: MouseEvent) => void; + onMouseScroll?: (this: T, event: MouseEvent) => void; + onPaste?: (this: T, event: PasteEvent) => void; + onKeyDown?: (key: KeyEvent) => void; + onSizeChange?: (this: T) => void; +} +export declare function isRenderable(obj: any): obj is Renderable; +export declare abstract class BaseRenderable extends EventEmitter { + [BrandedRenderable]: boolean; + private static renderableNumber; + protected _id: string; + readonly num: number; + protected _dirty: boolean; + parent: BaseRenderable | null; + protected _visible: boolean; + constructor(options: BaseRenderableOptions); + abstract add(obj: BaseRenderable | unknown, index?: number): number; + abstract remove(id: string): void; + abstract insertBefore(obj: BaseRenderable | unknown, anchor: BaseRenderable | unknown): void; + abstract getChildren(): BaseRenderable[]; + abstract getChildrenCount(): number; + abstract getRenderable(id: string): BaseRenderable | undefined; + abstract requestRender(): void; + abstract findDescendantById(id: string): BaseRenderable | undefined; + get id(): string; + set id(value: string); + get isDirty(): boolean; + protected markClean(): void; + protected markDirty(): void; + destroy(): void; + destroyRecursively(): void; + get visible(): boolean; + set visible(value: boolean); +} +export declare abstract class Renderable extends BaseRenderable { + static renderablesByNumber: Map; + protected _isDestroyed: boolean; + protected _ctx: RenderContext; + protected _translateX: number; + protected _translateY: number; + protected _x: number; + protected _y: number; + protected _screenX: number; + protected _screenY: number; + protected _width: number | "auto" | `${number}%`; + protected _height: number | "auto" | `${number}%`; + protected _widthValue: number; + protected _heightValue: number; + private _zIndex; + selectable: boolean; + protected buffered: boolean; + protected frameBuffer: OptimizedBuffer | null; + protected _focusable: boolean; + protected _focused: boolean; + protected _hasFocusedDescendant: boolean; + protected keypressHandler: ((key: KeyEvent) => void) | null; + protected pasteHandler: ((event: PasteEvent) => void) | null; + private _live; + protected _liveCount: number; + private _sizeChangeListener; + private _mouseListener; + private _mouseListeners; + private _pasteListener; + private _keyListeners; + protected yogaNode: YogaNode; + protected _positionType: PositionTypeString; + protected _overflow: OverflowString; + protected _position: Position; + protected _opacity: number; + private _flexShrink; + private renderableMapById; + protected _childrenInLayoutOrder: Renderable[]; + protected _childrenInZIndexOrder: Renderable[]; + private needsZIndexSort; + parent: Renderable | null; + private childrenPrimarySortDirty; + private childrenSortedByPrimaryAxis; + private _shouldUpdateBefore; + private _lastLayoutFrame; + onLifecyclePass: (() => void) | null; + renderBefore?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void; + renderAfter?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void; + constructor(ctx: RenderContext, options: RenderableOptions); + get id(): string; + set id(value: string); + get focusable(): boolean; + set focusable(value: boolean); + get ctx(): RenderContext; + get visible(): boolean; + get primaryAxis(): "row" | "column"; + set visible(value: boolean); + get opacity(): number; + set opacity(value: number); + hasSelection(): boolean; + onSelectionChanged(selection: Selection | null): boolean; + getSelectedText(): string; + shouldStartSelection(x: number, y: number): boolean; + focus(): void; + protected propagateFocusChange(hasFocus: boolean): void; + blur(): void; + get focused(): boolean; + get hasFocusedDescendant(): boolean; + get live(): boolean; + get liveCount(): number; + set live(value: boolean); + protected propagateLiveCount(delta: number): void; + handleKeyPress?(key: KeyEvent): boolean; + handlePaste?(event: PasteEvent): void; + findDescendantById(id: string): Renderable | undefined; + requestRender(): void; + get translateX(): number; + set translateX(value: number); + get translateY(): number; + set translateY(value: number); + get screenX(): number; + get screenY(): number; + get x(): number; + set x(value: number); + get top(): number | "auto" | `${number}%` | undefined; + set top(value: number | "auto" | `${number}%` | undefined); + get right(): number | "auto" | `${number}%` | undefined; + set right(value: number | "auto" | `${number}%` | undefined); + get bottom(): number | "auto" | `${number}%` | undefined; + set bottom(value: number | "auto" | `${number}%` | undefined); + get left(): number | "auto" | `${number}%` | undefined; + set left(value: number | "auto" | `${number}%` | undefined); + get y(): number; + set y(value: number); + get width(): number; + set width(value: number | "auto" | `${number}%`); + get height(): number; + set height(value: number | "auto" | `${number}%`); + get zIndex(): number; + set zIndex(value: number); + private requestZIndexSort; + private ensureZIndexSorted; + getChildrenSortedByPrimaryAxis(): Renderable[]; + private setupYogaProperties; + private setupMarginAndPadding; + set position(positionType: PositionTypeString | null | undefined); + get overflow(): OverflowString; + set overflow(overflow: OverflowString | null | undefined); + setPosition(position: Position): void; + private updateYogaPosition; + set flexGrow(grow: number | null | undefined); + set flexShrink(shrink: number | null | undefined); + set flexDirection(direction: FlexDirectionString | null | undefined); + set flexWrap(wrap: WrapString | null | undefined); + set alignItems(alignItems: AlignString | null | undefined); + set justifyContent(justifyContent: JustifyString | null | undefined); + set alignSelf(alignSelf: AlignString | null | undefined); + set flexBasis(basis: number | "auto" | null | undefined); + set minWidth(minWidth: number | `${number}%` | null | undefined); + set maxWidth(maxWidth: number | `${number}%` | null | undefined); + set minHeight(minHeight: number | `${number}%` | null | undefined); + set maxHeight(maxHeight: number | `${number}%` | null | undefined); + set margin(margin: number | "auto" | `${number}%` | null | undefined); + set marginX(marginX: number | "auto" | `${number}%` | null | undefined); + set marginY(marginY: number | "auto" | `${number}%` | null | undefined); + set marginTop(margin: number | "auto" | `${number}%` | null | undefined); + get marginTop(): number | "auto" | `${number}%`; + set marginRight(margin: number | "auto" | `${number}%` | null | undefined); + set marginBottom(margin: number | "auto" | `${number}%` | null | undefined); + set marginLeft(margin: number | "auto" | `${number}%` | null | undefined); + set padding(padding: number | `${number}%` | null | undefined); + set paddingX(paddingX: number | `${number}%` | null | undefined); + set paddingY(paddingY: number | `${number}%` | null | undefined); + set paddingTop(padding: number | `${number}%` | null | undefined); + set paddingRight(padding: number | `${number}%` | null | undefined); + set paddingBottom(padding: number | `${number}%` | null | undefined); + set paddingLeft(padding: number | `${number}%` | null | undefined); + getLayoutNode(): YogaNode; + updateFromLayout(): void; + protected onLayoutResize(width: number, height: number): void; + protected handleFrameBufferResize(width: number, height: number): void; + protected createFrameBuffer(): void; + /** + * This will be called during a render pass. + * Requesting a render during a render pass will drop the requested render. + * If you need to request a render during a render pass, use process.nextTick. + */ + protected onResize(width: number, height: number): void; + private replaceParent; + add(obj: Renderable | VNode | unknown, index?: number): number; + insertBefore(obj: Renderable | VNode | unknown, anchor?: Renderable | unknown): number; + getRenderable(id: string): Renderable | undefined; + remove(id: string): void; + protected onRemove(): void; + getChildren(): Renderable[]; + getChildrenCount(): number; + updateLayout(deltaTime: number, renderList?: RenderCommand[]): void; + render(buffer: OptimizedBuffer, deltaTime: number): void; + protected _hasVisibleChildFilter(): boolean; + protected _getVisibleChildren(): number[]; + canReuseRenderCommandList(): boolean; + protected onUpdate(deltaTime: number): void; + protected getScissorRect(): { + x: number; + y: number; + width: number; + height: number; + }; + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void; + get isDestroyed(): boolean; + destroy(): void; + destroyRecursively(): void; + protected destroySelf(): void; + processMouseEvent(event: MouseEvent): void; + protected onMouseEvent(event: MouseEvent): void; + set onMouse(handler: ((event: MouseEvent) => void) | undefined); + set onMouseDown(handler: ((event: MouseEvent) => void) | undefined); + set onMouseUp(handler: ((event: MouseEvent) => void) | undefined); + set onMouseMove(handler: ((event: MouseEvent) => void) | undefined); + set onMouseDrag(handler: ((event: MouseEvent) => void) | undefined); + set onMouseDragEnd(handler: ((event: MouseEvent) => void) | undefined); + set onMouseDrop(handler: ((event: MouseEvent) => void) | undefined); + set onMouseOver(handler: ((event: MouseEvent) => void) | undefined); + set onMouseOut(handler: ((event: MouseEvent) => void) | undefined); + set onMouseScroll(handler: ((event: MouseEvent) => void) | undefined); + set onPaste(handler: ((event: PasteEvent) => void) | undefined); + get onPaste(): ((event: PasteEvent) => void) | undefined; + set onKeyDown(handler: ((key: KeyEvent) => void) | undefined); + get onKeyDown(): ((key: KeyEvent) => void) | undefined; + set onSizeChange(handler: (() => void) | undefined); + get onSizeChange(): (() => void) | undefined; + private applyEventOptions; +} +interface RenderCommandBase { + action: "render" | "pushScissorRect" | "popScissorRect" | "pushOpacity" | "popOpacity"; +} +interface RenderCommandPushScissorRect extends RenderCommandBase { + action: "pushScissorRect"; + x: number; + y: number; + width: number; + height: number; + screenX: number; + screenY: number; +} +interface RenderCommandPopScissorRect extends RenderCommandBase { + action: "popScissorRect"; +} +interface RenderCommandRender extends RenderCommandBase { + action: "render"; + renderable: Renderable; +} +interface RenderCommandPushOpacity extends RenderCommandBase { + action: "pushOpacity"; + opacity: number; +} +interface RenderCommandPopOpacity extends RenderCommandBase { + action: "popOpacity"; +} +export type RenderCommand = RenderCommandPushScissorRect | RenderCommandPopScissorRect | RenderCommandRender | RenderCommandPushOpacity | RenderCommandPopOpacity; +export declare class RootRenderable extends Renderable { + private renderList; + private appliedLayoutGeneration; + private appliedRenderListRevision; + private renderListReusable; + constructor(ctx: RenderContext); + render(buffer: OptimizedBuffer, deltaTime: number): void; + protected propagateLiveCount(delta: number): void; + calculateLayout(): void; + private syncExternalLayoutGeneration; + private canReuseCurrentRenderList; + resize(width: number, height: number): void; +} +export {}; diff --git a/.patches/@opentui/core/animation/Timeline.d.ts b/.patches/@opentui/core/animation/Timeline.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/animation/Timeline.d.ts @@ -0,0 +1,126 @@ +import type { CliRenderer } from "../renderer.js"; +export interface TimelineOptions { + duration?: number; + loop?: boolean; + autoplay?: boolean; + onComplete?: () => void; + onPause?: () => void; +} +export interface AnimationOptions { + duration: number; + ease?: EasingFunctions; + onUpdate?: (animation: JSAnimation) => void; + onComplete?: () => void; + onStart?: () => void; + onLoop?: () => void; + loop?: boolean | number; + loopDelay?: number; + alternate?: boolean; + once?: boolean; + [key: string]: any; +} +export interface JSAnimation { + targets: any[]; + deltaTime: number; + progress: number; + currentTime: number; +} +interface TimelineItem { + type: "animation" | "callback" | "timeline"; + startTime: number; +} +interface TimelineTimelineItem extends TimelineItem { + type: "timeline"; + timeline: Timeline; + timelineStarted?: boolean; +} +interface TimelineCallbackItem extends TimelineItem { + type: "callback"; + callback: () => void; + executed: boolean; +} +interface TimelineAnimationItem extends TimelineItem { + type: "animation"; + target: any[]; + properties?: Record; + initialValues?: Record[]; + duration?: number; + ease?: keyof typeof easingFunctions; + loop?: boolean | number; + loopDelay?: number; + alternate?: boolean; + onUpdate?: (animation: JSAnimation) => void; + onComplete?: () => void; + onStart?: () => void; + onLoop?: () => void; + completed?: boolean; + started?: boolean; + currentLoop?: number; + once?: boolean; +} +export type EasingFunctions = keyof typeof easingFunctions; +declare const easingFunctions: { + linear: (t: number) => number; + inQuad: (t: number) => number; + outQuad: (t: number) => number; + inOutQuad: (t: number) => number; + inExpo: (t: number) => number; + outExpo: (t: number) => number; + inOutSine: (t: number) => number; + outBounce: (t: number) => number; + outElastic: (t: number) => number; + inBounce: (t: number) => number; + inCirc: (t: number) => number; + outCirc: (t: number) => number; + inOutCirc: (t: number) => number; + inBack: (t: number, s?: number) => number; + outBack: (t: number, s?: number) => number; + inOutBack: (t: number, s?: number) => number; +}; +export declare class Timeline { + items: (TimelineAnimationItem | TimelineCallbackItem)[]; + subTimelines: TimelineTimelineItem[]; + currentTime: number; + isPlaying: boolean; + isComplete: boolean; + duration: number; + loop: boolean; + synced: boolean; + private autoplay; + private onComplete?; + private onPause?; + private stateChangeListeners; + constructor(options?: TimelineOptions); + addStateChangeListener(listener: (timeline: Timeline) => void): void; + removeStateChangeListener(listener: (timeline: Timeline) => void): void; + private notifyStateChange; + add(target: any, properties: AnimationOptions, startTime?: number | string): this; + once(target: any, properties: AnimationOptions): this; + call(callback: () => void, startTime?: number | string): this; + sync(timeline: Timeline, startTime?: number): this; + play(): this; + pause(): this; + resetItems(): void; + restart(): this; + update(deltaTime: number): void; +} +declare class TimelineEngine { + private timelines; + private renderer; + private frameCallback; + private isLive; + defaults: { + frameRate: number; + }; + attach(renderer: CliRenderer): void; + detach(): void; + private updateLiveState; + private onTimelineStateChange; + register(timeline: Timeline): void; + unregister(timeline: Timeline): void; + clear(): void; + update(deltaTime: number): void; +} +export declare const engine: TimelineEngine; +export declare function createTimeline(options?: TimelineOptions): Timeline; +export {}; diff --git a/.patches/@opentui/core/ansi.d.ts b/.patches/@opentui/core/ansi.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/ansi.d.ts @@ -0,0 +1,17 @@ +export declare const ANSI: { + switchToAlternateScreen: string; + switchToMainScreen: string; + reset: string; + resetScrollRegion: string; + home: string; + clearScreen: string; + clearSavedLines: string; + scrollDown: (lines: number) => string; + scrollUp: (lines: number) => string; + moveCursor: (row: number, col: number) => string; + moveCursorAndClear: (row: number, col: number) => string; + setRgbBackground: (r: number, g: number, b: number) => string; + resetBackground: string; + bracketedPasteStart: string; + bracketedPasteEnd: string; +}; diff --git a/.patches/@opentui/core/assets/javascript/highlights.scm b/.patches/@opentui/core/assets/javascript/highlights.scm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/javascript/highlights.scm @@ -0,0 +1,205 @@ +; Query from: https://raw.githubusercontent.com/tree-sitter/tree-sitter-javascript/refs/heads/master/queries/highlights.scm +; Variables +;---------- + +(identifier) @variable + +; Properties +;----------- + +(property_identifier) @property + +; Function and method definitions +;-------------------------------- + +(function_expression + name: (identifier) @function) +(function_declaration + name: (identifier) @function) +(method_definition + name: (property_identifier) @function.method) + +(pair + key: (property_identifier) @function.method + value: [(function_expression) (arrow_function)]) + +(assignment_expression + left: (member_expression + property: (property_identifier) @function.method) + right: [(function_expression) (arrow_function)]) + +(variable_declarator + name: (identifier) @function + value: [(function_expression) (arrow_function)]) + +(assignment_expression + left: (identifier) @function + right: [(function_expression) (arrow_function)]) + +; Function and method calls +;-------------------------- + +(call_expression + function: (identifier) @function) + +(call_expression + function: (member_expression + property: (property_identifier) @function.method)) + +; Special identifiers +;-------------------- + +((identifier) @constructor + (#match? @constructor "^[A-Z]")) + +([ + (identifier) + (shorthand_property_identifier) + (shorthand_property_identifier_pattern) + ] @constant + (#match? @constant "^[A-Z_][A-Z\\d_]+$")) + +((identifier) @variable.builtin + (#match? @variable.builtin "^(arguments|module|console|window|document)$") + (#is-not? local)) + +((identifier) @function.builtin + (#eq? @function.builtin "require") + (#is-not? local)) + +; Literals +;--------- + +(this) @variable.builtin +(super) @variable.builtin + +[ + (true) + (false) + (null) + (undefined) +] @constant.builtin + +(comment) @comment + +[ + (string) + (template_string) +] @string + +(regex) @string.special +(number) @number + +; Tokens +;------- + +[ + ";" + (optional_chain) + "." + "," +] @punctuation.delimiter + +[ + "-" + "--" + "-=" + "+" + "++" + "+=" + "*" + "*=" + "**" + "**=" + "/" + "/=" + "%" + "%=" + "<" + "<=" + "<<" + "<<=" + "=" + "==" + "===" + "!" + "!=" + "!==" + "=>" + ">" + ">=" + ">>" + ">>=" + ">>>" + ">>>=" + "~" + "^" + "&" + "|" + "^=" + "&=" + "|=" + "&&" + "||" + "??" + "&&=" + "||=" + "??=" +] @operator + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +(template_substitution + "${" @punctuation.special + "}" @punctuation.special) @embedded + +[ + "as" + "async" + "await" + "break" + "case" + "catch" + "class" + "const" + "continue" + "debugger" + "default" + "delete" + "do" + "else" + "export" + "extends" + "finally" + "for" + "from" + "function" + "get" + "if" + "import" + "in" + "instanceof" + "let" + "new" + "of" + "return" + "set" + "static" + "switch" + "target" + "throw" + "try" + "typeof" + "var" + "void" + "while" + "with" + "yield" +] @keyword diff --git a/.patches/@opentui/core/assets/javascript/tree-sitter-javascript.wasm b/.patches/@opentui/core/assets/javascript/tree-sitter-javascript.wasm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/javascript/tree-sitter-javascript.wasm diff --git a/.patches/@opentui/core/assets/markdown/highlights.scm b/.patches/@opentui/core/assets/markdown/highlights.scm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/markdown/highlights.scm @@ -0,0 +1,150 @@ +; Query from: https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/markdown/highlights.scm +;From MDeiml/tree-sitter-markdown & Helix +(setext_heading + (paragraph) @markup.heading.1 + (setext_h1_underline) @markup.heading.1) + +(setext_heading + (paragraph) @markup.heading.2 + (setext_h2_underline) @markup.heading.2) + +; Capture the entire heading node first based on the marker it contains +((atx_heading (atx_h1_marker)) @markup.heading.1 + (#set! priority 90)) + +((atx_heading (atx_h2_marker)) @markup.heading.2 + (#set! priority 90)) + +((atx_heading (atx_h3_marker)) @markup.heading.3 + (#set! priority 90)) + +((atx_heading (atx_h4_marker)) @markup.heading.4 + (#set! priority 90)) + +((atx_heading (atx_h5_marker)) @markup.heading.5 + (#set! priority 90)) + +((atx_heading (atx_h6_marker)) @markup.heading.6 + (#set! priority 90)) + +; Then capture and conceal just the markers (they don't need special styling) +(atx_heading + (atx_h1_marker) @conceal + (#set! conceal "")) + +(atx_heading + (atx_h2_marker) @conceal + (#set! conceal "")) + +(atx_heading + (atx_h3_marker) @conceal + (#set! conceal "")) + +(atx_heading + (atx_h4_marker) @conceal + (#set! conceal "")) + +(atx_heading + (atx_h5_marker) @conceal + (#set! conceal "")) + +(atx_heading + (atx_h6_marker) @conceal + (#set! conceal "")) + +(info_string) @label + +(pipe_table_header + (pipe_table_cell) @markup.heading) + +(pipe_table_header + "|" @punctuation.special) + +(pipe_table_row + "|" @punctuation.special) + +(pipe_table_delimiter_row + "|" @punctuation.special) + +(pipe_table_delimiter_cell) @punctuation.special + +; Code blocks (conceal backticks and language annotation) +(indented_code_block) @markup.raw.block + +((fenced_code_block) @markup.raw.block + (#set! priority 90)) + +(fenced_code_block + (fenced_code_block_delimiter) @markup.raw.block + (#set! conceal "") + (#set! conceal_lines "")) + +(fenced_code_block + (info_string + (language) @label + (#set! conceal "") + (#set! conceal_lines ""))) + +(link_destination) @markup.link.url + +[ + (link_title) + (link_label) +] @markup.link.label + +((link_label) + . + ":" @punctuation.delimiter) + +[ + (list_marker_plus) + (list_marker_minus) + (list_marker_star) + (list_marker_dot) + (list_marker_parenthesis) +] @markup.list + +; NOTE: The following has been commented out due to issues with spaces in the +; list marker nodes generated by the parser. If those spaces ever get captured +; by a different node (e.g. block_continuation) we can safely re-add these +; conceals. +; ;; Conceal bullet points +; ([(list_marker_plus) (list_marker_star)] +; @punctuation.special +; (#offset! @punctuation.special 0 0 0 -1) +; (#set! conceal "•")) +; ([(list_marker_plus) (list_marker_star)] +; @punctuation.special +; (#any-of? @punctuation.special "+" "*") +; (#set! conceal "•")) +; ((list_marker_minus) +; @punctuation.special +; (#offset! @punctuation.special 0 0 0 -1) +; (#set! conceal "—")) +; ((list_marker_minus) +; @punctuation.special +; (#eq? @punctuation.special "-") +; (#set! conceal "—")) +(thematic_break) @punctuation.special + +(task_list_marker_unchecked) @markup.list.unchecked + +(task_list_marker_checked) @markup.list.checked + +((block_quote) @markup.quote + (#set! priority 90)) + +([ + (plus_metadata) + (minus_metadata) +] @keyword.directive + (#set! priority 90)) + +[ + (block_continuation) + (block_quote_marker) +] @punctuation.special + +(backslash_escape) @string.escape + +(inline) @spell diff --git a/.patches/@opentui/core/assets/markdown/injections.scm b/.patches/@opentui/core/assets/markdown/injections.scm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/markdown/injections.scm @@ -0,0 +1,27 @@ +; Query from: https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/markdown/injections.scm +(fenced_code_block + (info_string + (language) @_lang) + (code_fence_content) @injection.content + (#set-lang-from-info-string! @_lang)) + +((html_block) @injection.content + (#set! injection.language "html") + (#set! injection.combined) + (#set! injection.include-children)) + +((minus_metadata) @injection.content + (#set! injection.language "yaml") + (#offset! @injection.content 1 0 -1 0) + (#set! injection.include-children)) + +((plus_metadata) @injection.content + (#set! injection.language "toml") + (#offset! @injection.content 1 0 -1 0) + (#set! injection.include-children)) + +([ + (inline) + (pipe_table_cell) +] @injection.content + (#set! injection.language "markdown_inline")) diff --git a/.patches/@opentui/core/assets/markdown/tree-sitter-markdown.wasm b/.patches/@opentui/core/assets/markdown/tree-sitter-markdown.wasm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/markdown/tree-sitter-markdown.wasm diff --git a/.patches/@opentui/core/assets/markdown_inline/highlights.scm b/.patches/@opentui/core/assets/markdown_inline/highlights.scm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/markdown_inline/highlights.scm @@ -0,0 +1,115 @@ +; Query from: https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/99ddf573531c4dbe53f743ecbc1595af5eb1d32f/queries/markdown_inline/highlights.scm +; From MDeiml/tree-sitter-markdown +(code_span) @markup.raw @nospell + +(emphasis) @markup.italic + +(strong_emphasis) @markup.strong + +(strikethrough) @markup.strikethrough + +(shortcut_link + (link_text) @nospell) + +[ + (backslash_escape) + (hard_line_break) +] @string.escape + +; Conceal codeblock and text style markers +([ + (code_span_delimiter) + (emphasis_delimiter) +] @conceal + (#set! conceal "")) + +; Inline links - style all parts +(inline_link + ["[" "(" ")"] @markup.link) + +(inline_link + "]" @markup.link.bracket.close) + +; Conceal opening bracket +((inline_link + "[" @conceal) + (#set! conceal "")) + +; Conceal closing bracket with space replacement +((inline_link + "]" @conceal) + (#set! conceal " ")) + +; Conceal image links +(image + [ + "!" + "[" + "]" + "(" + (link_destination) + ")" + ] @markup.link + (#set! conceal "")) + +; Conceal full reference links +(full_reference_link + [ + "[" + "]" + (link_label) + ] @markup.link + (#set! conceal "")) + +; Conceal collapsed reference links +(collapsed_reference_link + [ + "[" + "]" + ] @markup.link + (#set! conceal "")) + +; Conceal shortcut links +(shortcut_link + [ + "[" + "]" + ] @markup.link + (#set! conceal "")) + +[ + (link_destination) + (uri_autolink) +] @markup.link.url @nospell + +[ + (link_label) + (link_text) + (link_title) + (image_description) +] @markup.link.label + +; Replace common HTML entities. +((entity_reference) @character.special + (#eq? @character.special " ") + (#set! conceal "")) + +((entity_reference) @character.special + (#eq? @character.special "<") + (#set! conceal "<")) + +((entity_reference) @character.special + (#eq? @character.special ">") + (#set! conceal ">")) + +((entity_reference) @character.special + (#eq? @character.special "&") + (#set! conceal "&")) + +((entity_reference) @character.special + (#eq? @character.special """) + (#set! conceal "\"")) + +((entity_reference) @character.special + (#any-of? @character.special " " " ") + (#set! conceal " ")) diff --git a/.patches/@opentui/core/assets/markdown_inline/tree-sitter-markdown_inline.wasm b/.patches/@opentui/core/assets/markdown_inline/tree-sitter-markdown_inline.wasm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/markdown_inline/tree-sitter-markdown_inline.wasm diff --git a/.patches/@opentui/core/assets/typescript/highlights.scm b/.patches/@opentui/core/assets/typescript/highlights.scm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/typescript/highlights.scm @@ -0,0 +1,604 @@ +; Query from: https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/ecma/highlights.scm +; Types +; Javascript +; Variables +;----------- +(identifier) @variable + +; Properties +;----------- +(property_identifier) @variable.member + +(shorthand_property_identifier) @variable.member + +(private_property_identifier) @variable.member + +(object_pattern + (shorthand_property_identifier_pattern) @variable) + +(object_pattern + (object_assignment_pattern + (shorthand_property_identifier_pattern) @variable)) + +; Special identifiers +;-------------------- +((identifier) @type + (#lua-match? @type "^[A-Z]")) + +((identifier) @constant + (#lua-match? @constant "^_*[A-Z][A-Z%d_]*$")) + +((shorthand_property_identifier) @constant + (#lua-match? @constant "^_*[A-Z][A-Z%d_]*$")) + +((identifier) @variable.builtin + (#any-of? @variable.builtin "arguments" "module" "console" "window" "document")) + +((identifier) @type.builtin + (#any-of? @type.builtin + "Object" "Function" "Boolean" "Symbol" "Number" "Math" "Date" "String" "RegExp" "Map" "Set" + "WeakMap" "WeakSet" "Promise" "Array" "Int8Array" "Uint8Array" "Uint8ClampedArray" "Int16Array" + "Uint16Array" "Int32Array" "Uint32Array" "Float32Array" "Float64Array" "ArrayBuffer" "DataView" + "Error" "EvalError" "InternalError" "RangeError" "ReferenceError" "SyntaxError" "TypeError" + "URIError")) + +(statement_identifier) @label + +; Function and method definitions +;-------------------------------- +(function_expression + name: (identifier) @function) + +(function_declaration + name: (identifier) @function) + +(generator_function + name: (identifier) @function) + +(generator_function_declaration + name: (identifier) @function) + +(method_definition + name: [ + (property_identifier) + (private_property_identifier) + ] @function.method) + +(method_definition + name: (property_identifier) @constructor + (#eq? @constructor "constructor")) + +(pair + key: (property_identifier) @function.method + value: (function_expression)) + +(pair + key: (property_identifier) @function.method + value: (arrow_function)) + +(assignment_expression + left: (member_expression + property: (property_identifier) @function.method) + right: (arrow_function)) + +(assignment_expression + left: (member_expression + property: (property_identifier) @function.method) + right: (function_expression)) + +(variable_declarator + name: (identifier) @function + value: (arrow_function)) + +(variable_declarator + name: (identifier) @function + value: (function_expression)) + +(assignment_expression + left: (identifier) @function + right: (arrow_function)) + +(assignment_expression + left: (identifier) @function + right: (function_expression)) + +; Function and method calls +;-------------------------- +(call_expression + function: (identifier) @function.call) + +(call_expression + function: (member_expression + property: [ + (property_identifier) + (private_property_identifier) + ] @function.method.call)) + +(call_expression + function: (await_expression + (identifier) @function.call)) + +(call_expression + function: (await_expression + (member_expression + property: [ + (property_identifier) + (private_property_identifier) + ] @function.method.call))) + +; Builtins +;--------- +((identifier) @module.builtin + (#eq? @module.builtin "Intl")) + +((identifier) @function.builtin + (#any-of? @function.builtin + "eval" "isFinite" "isNaN" "parseFloat" "parseInt" "decodeURI" "decodeURIComponent" "encodeURI" + "encodeURIComponent" "require")) + +; Constructor +;------------ +(new_expression + constructor: (identifier) @constructor) + +; Decorators +;---------- +(decorator + "@" @attribute + (identifier) @attribute) + +(decorator + "@" @attribute + (call_expression + (identifier) @attribute)) + +(decorator + "@" @attribute + (member_expression + (property_identifier) @attribute)) + +(decorator + "@" @attribute + (call_expression + (member_expression + (property_identifier) @attribute))) + +; Literals +;--------- +[ + (this) + (super) +] @variable.builtin + +((identifier) @variable.builtin + (#eq? @variable.builtin "self")) + +[ + (true) + (false) +] @boolean + +[ + (null) + (undefined) +] @constant.builtin + +[ + (comment) + (html_comment) +] @comment @spell + +((comment) @comment.documentation + (#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$")) + +(hash_bang_line) @keyword.directive + +((string_fragment) @keyword.directive + (#eq? @keyword.directive "use strict")) + +(string) @string + +(template_string) @string + +(escape_sequence) @string.escape + +(regex_pattern) @string.regexp + +(regex_flags) @character.special + +(regex + "/" @punctuation.bracket) ; Regex delimiters + +(number) @number + +((identifier) @number + (#any-of? @number "NaN" "Infinity")) + +; Punctuation +;------------ +[ + ";" + "." + "," + ":" +] @punctuation.delimiter + +[ + "--" + "-" + "-=" + "&&" + "+" + "++" + "+=" + "&=" + "/=" + "**=" + "<<=" + "<" + "<=" + "<<" + "=" + "==" + "===" + "!=" + "!==" + "=>" + ">" + ">=" + ">>" + "||" + "%" + "%=" + "*" + "**" + ">>>" + "&" + "|" + "^" + "??" + "*=" + ">>=" + ">>>=" + "^=" + "|=" + "&&=" + "||=" + "??=" + "..." +] @operator + +(binary_expression + "/" @operator) + +(ternary_expression + [ + "?" + ":" + ] @keyword.conditional.ternary) + +(unary_expression + [ + "!" + "~" + "-" + "+" + ] @operator) + +(unary_expression + [ + "delete" + "void" + ] @keyword.operator) + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +(template_substitution + [ + "${" + "}" + ] @punctuation.special) @none + +; Imports +;---------- +(namespace_import + "*" @character.special + (identifier) @module) + +(namespace_export + "*" @character.special + (identifier) @module) + +(export_statement + "*" @character.special) + +; Keywords +;---------- +[ + "if" + "else" + "switch" + "case" +] @keyword.conditional + +[ + "import" + "from" + "as" + "export" +] @keyword.import + +[ + "for" + "of" + "do" + "while" + "continue" +] @keyword.repeat + +[ + "break" + "const" + "debugger" + "extends" + "get" + "let" + "set" + "static" + "target" + "var" + "with" +] @keyword + +"class" @keyword.type + +[ + "async" + "await" +] @keyword.coroutine + +[ + "return" + "yield" +] @keyword.return + +"function" @keyword.function + +[ + "new" + "delete" + "in" + "instanceof" + "typeof" +] @keyword.operator + +[ + "throw" + "try" + "catch" + "finally" +] @keyword.exception + +(export_statement + "default" @keyword) + +(switch_default + "default" @keyword.conditional) + + +; Query from: https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/typescript/highlights.scm +; inherits: ecma + +"require" @keyword.import + +(import_require_clause + source: (string) @string.special.url) + +[ + "declare" + "implements" + "type" + "override" + "module" + "asserts" + "infer" + "is" + "using" +] @keyword + +[ + "namespace" + "interface" + "enum" +] @keyword.type + +[ + "keyof" + "satisfies" +] @keyword.operator + +(as_expression + "as" @keyword.operator) + +(mapped_type_clause + "as" @keyword.operator) + +[ + "abstract" + "private" + "protected" + "public" + "readonly" +] @keyword.modifier + +; types +(type_identifier) @type + +(predefined_type) @type.builtin + +(import_statement + "type" + (import_clause + (named_imports + (import_specifier + name: (identifier) @type)))) + +(template_literal_type) @string + +(non_null_expression + "!" @operator) + +; punctuation +(type_arguments + [ + "<" + ">" + ] @punctuation.bracket) + +(type_parameters + [ + "<" + ">" + ] @punctuation.bracket) + +(object_type + [ + "{|" + "|}" + ] @punctuation.bracket) + +(union_type + "|" @punctuation.delimiter) + +(intersection_type + "&" @punctuation.delimiter) + +(type_annotation + ":" @punctuation.delimiter) + +(type_predicate_annotation + ":" @punctuation.delimiter) + +(index_signature + ":" @punctuation.delimiter) + +(omitting_type_annotation + "-?:" @punctuation.delimiter) + +(adding_type_annotation + "+?:" @punctuation.delimiter) + +(opting_type_annotation + "?:" @punctuation.delimiter) + +"?." @punctuation.delimiter + +(abstract_method_signature + "?" @punctuation.special) + +(method_signature + "?" @punctuation.special) + +(method_definition + "?" @punctuation.special) + +(property_signature + "?" @punctuation.special) + +(optional_parameter + "?" @punctuation.special) + +(optional_type + "?" @punctuation.special) + +(public_field_definition + [ + "?" + "!" + ] @punctuation.special) + +(flow_maybe_type + "?" @punctuation.special) + +(template_type + [ + "${" + "}" + ] @punctuation.special) + +(conditional_type + [ + "?" + ":" + ] @keyword.conditional.ternary) + +; Parameters +(required_parameter + pattern: (identifier) @variable.parameter) + +(optional_parameter + pattern: (identifier) @variable.parameter) + +(required_parameter + (rest_pattern + (identifier) @variable.parameter)) + +; ({ a }) => null +(required_parameter + (object_pattern + (shorthand_property_identifier_pattern) @variable.parameter)) + +; ({ a = b }) => null +(required_parameter + (object_pattern + (object_assignment_pattern + (shorthand_property_identifier_pattern) @variable.parameter))) + +; ({ a: b }) => null +(required_parameter + (object_pattern + (pair_pattern + value: (identifier) @variable.parameter))) + +; ([ a ]) => null +(required_parameter + (array_pattern + (identifier) @variable.parameter)) + +; a => null +(arrow_function + parameter: (identifier) @variable.parameter) + +; global declaration +(ambient_declaration + "global" @module) + +; function signatures +(ambient_declaration + (function_signature + name: (identifier) @function)) + +; method signatures +(method_signature + name: (_) @function.method) + +(abstract_method_signature + name: (property_identifier) @function.method) + +; property signatures +(property_signature + name: (property_identifier) @function.method + type: (type_annotation + [ + (union_type + (parenthesized_type + (function_type))) + (function_type) + ])) diff --git a/.patches/@opentui/core/assets/typescript/tree-sitter-typescript.wasm b/.patches/@opentui/core/assets/typescript/tree-sitter-typescript.wasm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/typescript/tree-sitter-typescript.wasm diff --git a/.patches/@opentui/core/assets/zig/highlights.scm b/.patches/@opentui/core/assets/zig/highlights.scm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/zig/highlights.scm @@ -0,0 +1,284 @@ +; Query from: https://github.com/nvim-treesitter/nvim-treesitter/raw/refs/heads/master/queries/zig/highlights.scm +; Variables +(identifier) @variable + +; Parameters +(parameter + name: (identifier) @variable.parameter) + +(payload + (identifier) @variable.parameter) + +; Types +(parameter + type: (identifier) @type) + +((identifier) @type + (#lua-match? @type "^[A-Z_][a-zA-Z0-9_]*")) + +(variable_declaration + (identifier) @type + "=" + [ + (struct_declaration) + (enum_declaration) + (union_declaration) + (opaque_declaration) + ]) + +[ + (builtin_type) + "anyframe" +] @type.builtin + +; Constants +((identifier) @constant + (#lua-match? @constant "^[A-Z][A-Z_0-9]+$")) + +[ + "null" + "unreachable" + "undefined" +] @constant.builtin + +(field_expression + . + member: (identifier) @constant) + +(enum_declaration + (container_field + type: (identifier) @constant)) + +; Labels +(block_label + (identifier) @label) + +(break_label + (identifier) @label) + +; Fields +(field_initializer + . + (identifier) @variable.member) + +(field_expression + (_) + member: (identifier) @variable.member) + +(container_field + name: (identifier) @variable.member) + +(initializer_list + (assignment_expression + left: (field_expression + . + member: (identifier) @variable.member))) + +; Functions +(builtin_identifier) @function.builtin + +(call_expression + function: (identifier) @function.call) + +(call_expression + function: (field_expression + member: (identifier) @function.call)) + +(function_declaration + name: (identifier) @function) + +; Modules +(variable_declaration + (identifier) @module + (builtin_function + (builtin_identifier) @keyword.import + (#any-of? @keyword.import "@import" "@cImport"))) + +; Builtins +[ + "c" + "..." +] @variable.builtin + +((identifier) @variable.builtin + (#eq? @variable.builtin "_")) + +(calling_convention + (identifier) @variable.builtin) + +; Keywords +[ + "asm" + "defer" + "errdefer" + "test" + "error" + "const" + "var" +] @keyword + +[ + "struct" + "union" + "enum" + "opaque" +] @keyword.type + +[ + "async" + "await" + "suspend" + "nosuspend" + "resume" +] @keyword.coroutine + +"fn" @keyword.function + +[ + "and" + "or" + "orelse" +] @keyword.operator + +"return" @keyword.return + +[ + "if" + "else" + "switch" +] @keyword.conditional + +[ + "for" + "while" + "break" + "continue" +] @keyword.repeat + +[ + "usingnamespace" + "export" +] @keyword.import + +[ + "try" + "catch" +] @keyword.exception + +[ + "volatile" + "allowzero" + "noalias" + "addrspace" + "align" + "callconv" + "linksection" + "pub" + "inline" + "noinline" + "extern" + "comptime" + "packed" + "threadlocal" +] @keyword.modifier + +; Operator +[ + "=" + "*=" + "*%=" + "*|=" + "/=" + "%=" + "+=" + "+%=" + "+|=" + "-=" + "-%=" + "-|=" + "<<=" + "<<|=" + ">>=" + "&=" + "^=" + "|=" + "!" + "~" + "-" + "-%" + "&" + "==" + "!=" + ">" + ">=" + "<=" + "<" + "&" + "^" + "|" + "<<" + ">>" + "<<|" + "+" + "++" + "+%" + "-%" + "+|" + "-|" + "*" + "/" + "%" + "**" + "*%" + "*|" + "||" + ".*" + ".?" + "?" + ".." +] @operator + +; Literals +(character) @character + +([ + (string) + (multiline_string) +] @string + (#set! "priority" 95)) + +(integer) @number + +(float) @number.float + +(boolean) @boolean + +(escape_sequence) @string.escape + +; Punctuation +[ + "[" + "]" + "(" + ")" + "{" + "}" +] @punctuation.bracket + +[ + ";" + "." + "," + ":" + "=>" + "->" +] @punctuation.delimiter + +(payload + "|" @punctuation.bracket) + +; Comments +(comment) @comment @spell + +((comment) @comment.documentation + (#lua-match? @comment.documentation "^//!")) diff --git a/.patches/@opentui/core/assets/zig/tree-sitter-zig.wasm b/.patches/@opentui/core/assets/zig/tree-sitter-zig.wasm new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/assets/zig/tree-sitter-zig.wasm diff --git a/.patches/@opentui/core/audio.d.ts b/.patches/@opentui/core/audio.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/audio.d.ts @@ -0,0 +1,89 @@ +import { EventEmitter } from "events"; +import type { AudioStats } from "./zig-structs.js"; +export interface AudioSetupOptions { + autoStart?: boolean; + sampleRate?: number; + playbackChannels?: number; + startOptions?: AudioStartOptions; +} +export interface AudioStartOptions { + periodSizeInFrames?: number; + periodSizeInMilliseconds?: number; + periods?: number; + performanceProfile?: number; + shareMode?: number; + noPreSilencedOutputBuffer?: boolean; + noClip?: boolean; + noDisableDenormals?: boolean; + noFixedSizedCallback?: boolean; + wasapiNoAutoConvertSrc?: boolean; + wasapiNoDefaultQualitySrc?: boolean; + alsaNoMMap?: boolean; + alsaNoAutoFormat?: boolean; + alsaNoAutoChannels?: boolean; + alsaNoAutoResample?: boolean; +} +export interface AudioPlayOptions { + volume?: number; + pan?: number; + loop?: boolean; + groupId?: number; +} +export type AudioGroup = number; +export type AudioVoice = number; +export type AudioSound = number; +export interface AudioPlaybackDevice { + index: number; + name: string; + isDefault: boolean; +} +export type AudioAction = "createAudioEngine" | "start" | "startMixer" | "stop" | "loadSound" | "loadSoundFile" | "unloadSound" | "group" | "play" | "stopVoice" | "setVoiceGroup" | "setGroupVolume" | "setMasterVolume" | "mixFrames" | "enableTap" | "readTapFrames" | "listPlaybackDevices" | "selectPlaybackDevice" | "clearPlaybackDeviceSelection" | "getStats"; +export interface AudioErrorContext { + action: AudioAction; + status?: number; +} +export interface AudioEvents { + error: [error: Error, context: AudioErrorContext]; + started: []; + mixerStarted: []; + stopped: []; + disposed: []; +} +export declare class Audio extends EventEmitter { + static create(options?: AudioSetupOptions): Audio; + private readonly lib; + private readonly defaultStartOptions; + private engine; + private readonly groups; + private playbackStarted; + private mixerStarted; + private constructor(); + private emitError; + start(options?: AudioStartOptions): boolean; + startMixer(): boolean; + stop(): boolean; + isStarted(): boolean; + isMixerStarted(): boolean; + loadSound(data: Uint8Array | ArrayBuffer): AudioSound | null; + loadSoundFile(filePath: string): Promise; + unloadSound(sound: AudioSound): boolean; + group(name: string): AudioGroup | null; + play(sound: AudioSound, options?: AudioPlayOptions): AudioVoice | null; + stopVoice(voice: AudioVoice): boolean; + setVoiceGroup(voice: AudioVoice, group: AudioGroup): boolean; + setGroupVolume(group: AudioGroup, volume: number): boolean; + setMasterVolume(volume: number): boolean; + mixFrames(frameCount: number, channels?: number): Float32Array | null; + enableTap(capacityFrames?: number): boolean; + disableTap(): boolean; + readTapFrames(frameCount: number, channels?: number): { + frames: Float32Array; + framesRead: number; + } | null; + listPlaybackDevices(): AudioPlaybackDevice[] | null; + selectPlaybackDevice(index: number): boolean; + clearPlaybackDeviceSelection(): void; + getStats(): AudioStats | null; + dispose(): void; +} +export declare function setupAudio(options?: AudioSetupOptions): Audio; diff --git a/.patches/@opentui/core/buffer.d.ts b/.patches/@opentui/core/buffer.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/buffer.d.ts @@ -0,0 +1,113 @@ +import { RGBA } from "./lib/index.js"; +import { type OptimizedBufferHandle, type RenderLib } from "./zig.js"; +import { type Pointer, type PointerInput } from "./platform/ffi.js"; +import { type BorderStyle, type BorderSides } from "./lib/index.js"; +import { TargetChannel, type WidthMethod, type CapturedLine } from "./types.js"; +import type { TextBufferView } from "./text-buffer-view.js"; +import type { EditorView } from "./editor-view.js"; +export declare class OptimizedBuffer { + private static fbIdCounter; + id: string; + lib: RenderLib; + private bufferPtr; + private _width; + private _height; + private _widthMethod; + respectAlpha: boolean; + private _rawBuffers; + private _destroyed; + get ptr(): OptimizedBufferHandle; + private guard; + private ensureRawBufferViews; + get buffers(): { + char: Uint32Array; + fg: Uint16Array; + bg: Uint16Array; + attributes: Uint32Array; + }; + constructor(lib: RenderLib, ptr: OptimizedBufferHandle, width: number, height: number, options: { + respectAlpha?: boolean; + id?: string; + widthMethod?: WidthMethod; + }); + static create(width: number, height: number, widthMethod: WidthMethod, options?: { + respectAlpha?: boolean; + id?: string; + }): OptimizedBuffer; + get widthMethod(): WidthMethod; + get width(): number; + get height(): number; + setRespectAlpha(respectAlpha: boolean): void; + getNativeId(): string; + getRealCharBytes(addLineBreaks?: boolean): Uint8Array; + getSpanLines(): CapturedLine[]; + clear(bg?: RGBA): void; + setCell(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes?: number): void; + setCellWithAlphaBlending(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes?: number): void; + drawText(text: string, x: number, y: number, fg: RGBA, bg?: RGBA, attributes?: number, selection?: { + start: number; + end: number; + bgColor?: RGBA; + fgColor?: RGBA; + } | null): void; + fillRect(x: number, y: number, width: number, height: number, bg: RGBA): void; + colorMatrix(matrix: Float32Array, cellMask: Float32Array, strength?: number, target?: TargetChannel): void; + colorMatrixUniform(matrix: Float32Array, strength?: number, target?: TargetChannel): void; + drawFrameBuffer(destX: number, destY: number, frameBuffer: OptimizedBuffer, sourceX?: number, sourceY?: number, sourceWidth?: number, sourceHeight?: number): void; + destroy(): void; + drawTextBuffer(textBufferView: TextBufferView, x: number, y: number): void; + drawEditorView(editorView: EditorView, x: number, y: number): void; + drawSuperSampleBuffer(x: number, y: number, pixelDataPtr: PointerInput, pixelDataLength: number, format: "bgra8unorm" | "rgba8unorm", alignedBytesPerRow: number): void; + drawPackedBuffer(dataPtr: PointerInput, dataLen: number, posX: number, posY: number, terminalWidthCells: number, terminalHeightCells: number): void; + drawGrayscaleBuffer(posX: number, posY: number, intensities: Float32Array, srcWidth: number, srcHeight: number, fg?: RGBA | null, bg?: RGBA | null): void; + drawGrayscaleBufferSupersampled(posX: number, posY: number, intensities: Float32Array, srcWidth: number, srcHeight: number, fg?: RGBA | null, bg?: RGBA | null): void; + resize(width: number, height: number): void; + drawBox(options: { + x: number; + y: number; + width: number; + height: number; + borderStyle?: BorderStyle; + customBorderChars?: Uint32Array; + border: boolean | BorderSides[]; + borderColor: RGBA; + backgroundColor: RGBA; + shouldFill?: boolean; + title?: string; + titleColor?: RGBA; + titleAlignment?: "left" | "center" | "right"; + bottomTitle?: string; + bottomTitleAlignment?: "left" | "center" | "right"; + }): void; + pushScissorRect(x: number, y: number, width: number, height: number): void; + popScissorRect(): void; + clearScissorRects(): void; + pushOpacity(opacity: number): void; + popOpacity(): void; + getCurrentOpacity(): number; + clearOpacity(): void; + encodeUnicode(text: string): { + ptr: Pointer; + data: Array<{ + width: number; + char: number; + }>; + } | null; + freeUnicode(encoded: { + ptr: Pointer; + data: Array<{ + width: number; + char: number; + }>; + }): void; + drawGrid(options: { + borderChars: Uint32Array; + borderFg: RGBA; + borderBg: RGBA; + columnOffsets: Int32Array; + rowOffsets: Int32Array; + drawInner: boolean; + drawOuter: boolean; + }): void; + drawChar(char: number, x: number, y: number, fg: RGBA, bg: RGBA, attributes?: number): void; +} diff --git a/.patches/@opentui/core/console.d.ts b/.patches/@opentui/core/console.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/console.d.ts @@ -0,0 +1,146 @@ +import { EventEmitter } from "events"; +import type { CliRenderer, MouseEvent } from "./renderer.js"; +import type { ColorInput } from "./lib/RGBA.js"; +import { OptimizedBuffer } from "./buffer.js"; +import { type Clock } from "./lib/clock.js"; +import { Capture } from "./lib/output.capture.js"; +import { type KeyBinding as BaseKeyBinding } from "./lib/keybinding.internal.js"; +type KeyAliasMap = Record; +export declare const capture: Capture; +export declare enum ConsolePosition { + TOP = "top", + BOTTOM = "bottom", + LEFT = "left", + RIGHT = "right" +} +export type ConsoleAction = "scroll-up" | "scroll-down" | "scroll-to-top" | "scroll-to-bottom" | "position-previous" | "position-next" | "size-increase" | "size-decrease" | "save-logs" | "copy-selection"; +export type ConsoleKeyBinding = BaseKeyBinding; +export interface ConsoleOptions { + position?: ConsolePosition; + sizePercent?: number; + zIndex?: number; + colorInfo?: ColorInput; + colorWarn?: ColorInput; + colorError?: ColorInput; + colorDebug?: ColorInput; + colorDefault?: ColorInput; + backgroundColor?: ColorInput; + startInDebugMode?: boolean; + title?: string; + titleBarColor?: ColorInput; + titleBarTextColor?: ColorInput; + cursorColor?: ColorInput; + maxStoredLogs?: number; + maxDisplayLines?: number; + onCopySelection?: (text: string) => void; + keyBindings?: ConsoleKeyBinding[]; + keyAliasMap?: KeyAliasMap; + selectionColor?: ColorInput; + copyButtonColor?: ColorInput; + clock?: Clock; +} +export declare class TerminalConsole extends EventEmitter { + private isVisible; + private isFocused; + private renderer; + private keyHandler; + private options; + private _debugModeEnabled; + private frameBuffer; + private consoleX; + private consoleY; + private consoleWidth; + private consoleHeight; + private scrollTopIndex; + private isScrolledToBottom; + private currentLineIndex; + private _displayLines; + private _allLogEntries; + private _needsFrameBufferUpdate; + private _entryListener; + private _selectionStart; + private _selectionEnd; + private _isDragging; + private _copyButtonBounds; + private _autoScrollInterval; + private readonly clock; + private _keyBindingsMap; + private _keyAliasMap; + private _keyBindings; + private _mergedKeyBindings; + private _actionHandlers; + private markNeedsRerender; + private getCopyButtonLabel; + private _rgbaInfo; + private _rgbaWarn; + private _rgbaError; + private _rgbaDebug; + private _rgbaDefault; + private backgroundColor; + private _rgbaTitleBar; + private _rgbaTitleBarText; + private _title; + private _rgbaCursor; + private _rgbaSelection; + private _rgbaCopyButton; + private _positions; + constructor(renderer: CliRenderer, options?: ConsoleOptions); + private buildActionHandlers; + activate(): void; + deactivate(): void; + private _handleNewLog; + private _updateConsoleDimensions; + private handleKeyPress; + private scrollUp; + private scrollDown; + private scrollToTop; + private scrollToBottomAction; + private positionPrevious; + private positionNext; + private sizeIncrease; + private sizeDecrease; + private saveLogsAction; + private triggerCopyAction; + private attachStdin; + private detachStdin; + private formatTimestamp; + private formatArguments; + resize(width: number, height: number): void; + clear(): void; + toggle(): void; + focus(): void; + blur(): void; + show(): void; + hide(): void; + destroy(): void; + getCachedLogs(): string; + private updateFrameBuffer; + renderToBuffer(buffer: OptimizedBuffer): void; + setDebugMode(enabled: boolean): void; + toggleDebugMode(): void; + set keyBindings(bindings: ConsoleKeyBinding[]); + set keyAliasMap(aliases: KeyAliasMap); + set onCopySelection(callback: ((text: string) => void) | undefined); + get onCopySelection(): ((text: string) => void) | undefined; + private _scrollToBottom; + private _processLogEntry; + private _processCachedLogs; + private hasSelection; + private normalizeSelection; + private getSelectedText; + private clearSelection; + private stopAutoScroll; + private startAutoScroll; + private triggerCopy; + private getLineSelectionRange; + handleMouse(event: MouseEvent): boolean; + get visible(): boolean; + get bounds(): { + x: number; + y: number; + width: number; + height: number; + }; + private saveLogsToFile; +} +export {}; diff --git a/.patches/@opentui/core/edit-buffer.d.ts b/.patches/@opentui/core/edit-buffer.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/edit-buffer.d.ts @@ -0,0 +1,97 @@ +import { type EditBufferHandle, type LogicalCursor, type RenderLib } from "./zig.js"; +import { type WidthMethod, type Highlight } from "./types.js"; +import { RGBA } from "./lib/RGBA.js"; +import { EventEmitter } from "events"; +import type { SyntaxStyle } from "./syntax-style.js"; +export type { LogicalCursor }; +/** + * EditBuffer provides a text editing buffer with cursor management, + * incremental editing, and grapheme-aware operations. + */ +export declare class EditBuffer extends EventEmitter { + private static registry; + private static nativeEventsSubscribed; + private lib; + private bufferPtr; + private textBufferPtr; + readonly id: number; + private _destroyed; + private _textBytes; + private _singleTextBytes; + private _singleTextMemId; + private _syntaxStyle?; + constructor(lib: RenderLib, ptr: EditBufferHandle); + static create(widthMethod: WidthMethod): EditBuffer; + private static subscribeToNativeEvents; + private guard; + get ptr(): EditBufferHandle; + /** + * Set text and completely reset the buffer state (clears history, resets add_buffer). + * Use this for initial text setting or when you want a clean slate. + */ + setText(text: string): void; + /** + * Set text using owned memory and completely reset the buffer state (clears history, resets add_buffer). + * The native code takes ownership of the memory. + */ + setTextOwned(text: string): void; + /** + * Replace text while preserving undo history (creates an undo point). + * Use this when you want the setText operation to be undoable. + */ + replaceText(text: string): void; + /** + * Replace text using owned memory while preserving undo history (creates an undo point). + * The native code takes ownership of the memory. + */ + replaceTextOwned(text: string): void; + getLineCount(): number; + getText(): string; + insertChar(char: string): void; + insertText(text: string): void; + deleteChar(): void; + deleteCharBackward(): void; + deleteRange(startLine: number, startCol: number, endLine: number, endCol: number): void; + newLine(): void; + deleteLine(): void; + moveCursorLeft(): void; + moveCursorRight(): void; + moveCursorUp(): void; + moveCursorDown(): void; + gotoLine(line: number): void; + setCursor(line: number, col: number): void; + setCursorToLineCol(line: number, col: number): void; + setCursorByOffset(offset: number): void; + getCursorPosition(): LogicalCursor; + getNextWordBoundary(): LogicalCursor; + getPrevWordBoundary(): LogicalCursor; + getEOL(): LogicalCursor; + offsetToPosition(offset: number): { + row: number; + col: number; + } | null; + positionToOffset(row: number, col: number): number; + getLineStartOffset(row: number): number; + getTextRange(startOffset: number, endOffset: number): string; + getTextRangeByCoords(startRow: number, startCol: number, endRow: number, endCol: number): string; + debugLogRope(): void; + undo(): string | null; + redo(): string | null; + canUndo(): boolean; + canRedo(): boolean; + clearHistory(): void; + setDefaultFg(fg: RGBA | null): void; + setDefaultBg(bg: RGBA | null): void; + setDefaultAttributes(attributes: number | null): void; + resetDefaults(): void; + setSyntaxStyle(style: SyntaxStyle | null): void; + getSyntaxStyle(): SyntaxStyle | null; + addHighlight(lineIdx: number, highlight: Highlight): void; + addHighlightByCharRange(highlight: Highlight): void; + removeHighlightsByRef(hlRef: number): void; + clearLineHighlights(lineIdx: number): void; + clearAllHighlights(): void; + getLineHighlights(lineIdx: number): Array; + clear(): void; + destroy(): void; +} diff --git a/.patches/@opentui/core/editor-view.d.ts b/.patches/@opentui/core/editor-view.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/editor-view.d.ts @@ -0,0 +1,72 @@ +import { RGBA } from "./lib/RGBA.js"; +import { type EditorViewHandle, type RenderLib, type VisualCursor, type LineInfo } from "./zig.js"; +import type { EditBuffer } from "./edit-buffer.js"; +export interface Viewport { + offsetY: number; + offsetX: number; + height: number; + width: number; +} +export type { VisualCursor }; +export declare class EditorView { + private lib; + private viewPtr; + private editBuffer; + private _destroyed; + private _extmarksController?; + private _textBufferViewPtr?; + constructor(lib: RenderLib, ptr: EditorViewHandle, editBuffer: EditBuffer); + static create(editBuffer: EditBuffer, viewportWidth: number, viewportHeight: number): EditorView; + private guard; + get ptr(): EditorViewHandle; + setViewportSize(width: number, height: number): void; + setViewport(x: number, y: number, width: number, height: number, moveCursor?: boolean): void; + getViewport(): Viewport; + setScrollMargin(margin: number): void; + setWrapMode(mode: "none" | "char" | "word"): void; + getVirtualLineCount(): number; + getTotalVirtualLineCount(): number; + setSelection(start: number, end: number, bgColor?: RGBA, fgColor?: RGBA): void; + updateSelection(end: number, bgColor?: RGBA, fgColor?: RGBA): void; + resetSelection(): void; + getSelection(): { + start: number; + end: number; + } | null; + hasSelection(): boolean; + setLocalSelection(anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor?: RGBA, fgColor?: RGBA, updateCursor?: boolean, followCursor?: boolean): boolean; + updateLocalSelection(anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor?: RGBA, fgColor?: RGBA, updateCursor?: boolean, followCursor?: boolean): boolean; + resetLocalSelection(): void; + getSelectedText(): string; + getCursor(): { + row: number; + col: number; + }; + getText(): string; + getVisualCursor(): VisualCursor; + moveUpVisual(): void; + moveDownVisual(): void; + deleteSelectedText(): void; + setCursorByOffset(offset: number): void; + getNextWordBoundary(): VisualCursor; + getPrevWordBoundary(): VisualCursor; + getEOL(): VisualCursor; + getVisualSOL(): VisualCursor; + getVisualEOL(): VisualCursor; + getLineInfo(): LineInfo; + getLogicalLineInfo(): LineInfo; + get extmarks(): any; + setPlaceholderStyledText(chunks: { + text: string; + fg?: RGBA; + bg?: RGBA; + attributes?: number; + }[]): void; + setTabIndicator(indicator: string | number): void; + setTabIndicatorColor(color: RGBA): void; + measureForDimensions(width: number, height: number): { + lineCount: number; + widthColsMax: number; + } | null; + destroy(): void; +} diff --git a/.patches/@opentui/core/index-07zpr2dg.js b/.patches/@opentui/core/index-07zpr2dg.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/index-07zpr2dg.js @@ -0,0 +1,10058 @@ +import { + InternalKeyHandler, + KeyHandler, + OptimizedBuffer, + RGBA, + Selection, + SpanInfoStruct, + StdinParser, + StyledText, + SystemClock, + TextBuffer, + borderCharsToArray, + buildTerminalPaletteSignature, + convertGlobalToLocalSelection, + createExtmarksController, + createTerminalPalette, + createTextAttributes, + destroyTreeSitterClient, + env, + getBorderSides, + getTreeSitterClient, + isStyledText, + normalizeTerminalPalette, + parseAlign, + parseAlignItems, + parseBorderStyle, + parseColor, + parseFlexDirection, + parseJustify, + parseOverflow, + parsePositionType, + parseWrap, + registerEnvVar, + resolveRenderLib, + singleton, + sleep, + stringToStyledText, + toArrayBuffer, + treeSitterToTextChunks, + yoga_default +} from "./index-pcvh9d34.js"; + +// src/Renderable.ts +import { EventEmitter } from "events"; + +// src/lib/renderable.validations.ts +function validateOptions(id, options) { + if (typeof options.width === "number") { + if (options.width < 0) { + throw new TypeError(`Invalid width for Renderable ${id}: ${options.width}`); + } + } + if (typeof options.height === "number") { + if (options.height < 0) { + throw new TypeError(`Invalid height for Renderable ${id}: ${options.height}`); + } + } +} +function isValidPercentage(value) { + if (typeof value === "string" && value.endsWith("%")) { + const numPart = value.slice(0, -1); + const num = parseFloat(numPart); + return !Number.isNaN(num); + } + return false; +} +function isMarginType(value) { + if (typeof value === "number" && !Number.isNaN(value)) { + return true; + } + if (value === "auto") { + return true; + } + return isValidPercentage(value); +} +function isPaddingType(value) { + if (typeof value === "number" && !Number.isNaN(value)) { + return true; + } + return isValidPercentage(value); +} +function isPositionType(value) { + if (typeof value === "number" && !Number.isNaN(value)) { + return true; + } + if (value === "auto") { + return true; + } + return isValidPercentage(value); +} +function isPositionTypeType(value) { + return value === "relative" || value === "absolute"; +} +function isOverflowType(value) { + return value === "visible" || value === "hidden" || value === "scroll"; +} +function isDimensionType(value) { + return isPositionType(value); +} +function isFlexBasisType(value) { + if (value === undefined || value === "auto") { + return true; + } + if (typeof value === "number" && !Number.isNaN(value)) { + return true; + } + return false; +} +function isSizeType(value) { + if (value === undefined) { + return true; + } + if (typeof value === "number" && !Number.isNaN(value)) { + return true; + } + return isValidPercentage(value); +} + +// src/Renderable.ts +var BrandedRenderable = Symbol.for("@opentui/core/Renderable"); +var LayoutEvents; +((LayoutEvents2) => { + LayoutEvents2["LAYOUT_CHANGED"] = "layout-changed"; + LayoutEvents2["ADDED"] = "added"; + LayoutEvents2["REMOVED"] = "removed"; + LayoutEvents2["RESIZED"] = "resized"; +})(LayoutEvents ||= {}); +var RenderableEvents; +((RenderableEvents2) => { + RenderableEvents2["FOCUSED"] = "focused"; + RenderableEvents2["BLURRED"] = "blurred"; + RenderableEvents2["DESTROYED"] = "destroyed"; +})(RenderableEvents ||= {}); +function isRenderable(obj) { + return !!obj?.[BrandedRenderable]; +} + +class BaseRenderable extends EventEmitter { + [BrandedRenderable] = true; + static renderableNumber = 1; + _id; + num; + _dirty = false; + parent = null; + _visible = true; + constructor(options) { + super(); + this.num = BaseRenderable.renderableNumber++; + this._id = options.id ?? `renderable-${this.num}`; + } + get id() { + return this._id; + } + set id(value) { + this._id = value; + } + get isDirty() { + return this._dirty; + } + markClean() { + this._dirty = false; + } + markDirty() { + this._dirty = true; + } + destroy() {} + destroyRecursively() {} + get visible() { + return this._visible; + } + set visible(value) { + this._visible = value; + } +} +function getLayoutGeneration(ctx) { + return ctx.__otuiLayoutGeneration ?? 0; +} +function bumpLayoutGeneration(ctx) { + const next = getLayoutGeneration(ctx) + 1; + const generationContext = ctx; + generationContext.__otuiLayoutGeneration = next; + return next; +} +function getRenderListRevision(ctx) { + return ctx.__otuiRenderListRevision ?? 0; +} +function bumpRenderListRevision(ctx) { + const generationContext = ctx; + generationContext.__otuiRenderListRevision = getRenderListRevision(ctx) + 1; +} + +class Renderable extends BaseRenderable { + static renderablesByNumber = new Map; + _isDestroyed = false; + _ctx; + _translateX = 0; + _translateY = 0; + _x = 0; + _y = 0; + _screenX = 0; + _screenY = 0; + _width; + _height; + _widthValue = 0; + _heightValue = 0; + _zIndex; + selectable = false; + buffered; + frameBuffer = null; + _focusable = false; + _focused = false; + _hasFocusedDescendant = false; + keypressHandler = null; + pasteHandler = null; + _live = false; + _liveCount = 0; + _sizeChangeListener = undefined; + _mouseListener = null; + _mouseListeners = {}; + _pasteListener = undefined; + _keyListeners = {}; + yogaNode; + _positionType = "relative"; + _overflow = "visible"; + _position = {}; + _opacity = 1; + _flexShrink = 1; + renderableMapById = new Map; + _childrenInLayoutOrder = []; + _childrenInZIndexOrder = []; + needsZIndexSort = false; + parent = null; + childrenPrimarySortDirty = true; + childrenSortedByPrimaryAxis = []; + _shouldUpdateBefore = new Set; + _lastLayoutFrame = -1; + onLifecyclePass = null; + renderBefore; + renderAfter; + constructor(ctx, options) { + super(options); + this._ctx = ctx; + Renderable.renderablesByNumber.set(this.num, this); + validateOptions(this.id, options); + this.renderBefore = options.renderBefore; + this.renderAfter = options.renderAfter; + this._width = options.width ?? "auto"; + this._height = options.height ?? "auto"; + if (typeof this._width === "number") { + this._widthValue = this._width; + } + if (typeof this._height === "number") { + this._heightValue = this._height; + } + this._zIndex = options.zIndex ?? 0; + this._visible = options.visible !== false; + this.buffered = options.buffered ?? false; + this._live = options.live ?? false; + this._liveCount = this._live && this._visible ? 1 : 0; + this._opacity = options.opacity !== undefined ? Math.max(0, Math.min(1, options.opacity)) : 1; + this.yogaNode = yoga_default.Node.createForOpenTUI(); + this.yogaNode.setDisplay(this._visible ? 0 /* Flex */ : 1 /* None */); + this.setupYogaProperties(options); + this.applyEventOptions(options); + if (this.buffered) { + this.createFrameBuffer(); + } + } + get id() { + return this._id; + } + set id(value) { + if (this.parent) { + this.parent.renderableMapById.delete(this.id); + this.parent.renderableMapById.set(value, this); + } + super.id = value; + } + get focusable() { + return this._focusable; + } + set focusable(value) { + this._focusable = value; + } + get ctx() { + return this._ctx; + } + get visible() { + return this._visible; + } + get primaryAxis() { + const dir = this.yogaNode.getFlexDirection(); + return dir === 2 || dir === 3 ? "row" : "column"; + } + set visible(value) { + if (this._visible === value) + return; + const wasVisible = this._visible; + this._visible = value; + this.yogaNode.setDisplay(value ? 0 /* Flex */ : 1 /* None */); + bumpRenderListRevision(this._ctx); + if (this._live) { + if (!wasVisible && value) { + this.propagateLiveCount(1); + } else if (wasVisible && !value) { + this.propagateLiveCount(-1); + } + } + if (this._focused) { + this.blur(); + } + this.requestRender(); + } + get opacity() { + return this._opacity; + } + set opacity(value) { + const clamped = Math.max(0, Math.min(1, value)); + if (this._opacity !== clamped) { + this._opacity = clamped; + bumpRenderListRevision(this._ctx); + this.requestRender(); + } + } + hasSelection() { + return false; + } + onSelectionChanged(selection) { + return false; + } + getSelectedText() { + return ""; + } + shouldStartSelection(x, y) { + return false; + } + focus() { + if (this._isDestroyed || this._focused || !this._focusable) + return; + this._focused = true; + this._ctx.focusRenderable(this); + this.requestRender(); + this.keypressHandler = (key) => { + if (this._isDestroyed) + return; + this._keyListeners["down"]?.(key); + if (this._isDestroyed) + return; + if (!key.defaultPrevented && this.handleKeyPress) { + this.handleKeyPress(key); + } + }; + this.pasteHandler = (event) => { + if (this._isDestroyed) + return; + this._pasteListener?.call(this, event); + if (this._isDestroyed) + return; + if (!event.defaultPrevented && this.handlePaste) { + this.handlePaste(event); + } + }; + this.ctx._internalKeyInput.onInternal("keypress", this.keypressHandler); + this.ctx._internalKeyInput.onInternal("paste", this.pasteHandler); + this.propagateFocusChange(true); + this.emit("focused" /* FOCUSED */); + } + propagateFocusChange(hasFocus) { + let parent = this.parent; + while (parent) { + if (parent._hasFocusedDescendant !== hasFocus) { + parent._hasFocusedDescendant = hasFocus; + parent.markDirty(); + } + parent = parent.parent; + } + this.requestRender(); + } + blur() { + if (!this._focused || !this._focusable) + return; + this._ctx.blurRenderable(this); + this._focused = false; + this.requestRender(); + if (this.keypressHandler) { + this.ctx._internalKeyInput.offInternal("keypress", this.keypressHandler); + this.keypressHandler = null; + } + if (this.pasteHandler) { + this.ctx._internalKeyInput.offInternal("paste", this.pasteHandler); + this.pasteHandler = null; + } + this.propagateFocusChange(false); + this.emit("blurred" /* BLURRED */); + } + get focused() { + return this._focused; + } + get hasFocusedDescendant() { + return this._hasFocusedDescendant; + } + get live() { + return this._live; + } + get liveCount() { + return this._liveCount; + } + set live(value) { + if (this._live === value) + return; + this._live = value; + if (this._visible) { + const delta = value ? 1 : -1; + this.propagateLiveCount(delta); + } + } + propagateLiveCount(delta) { + this._liveCount += delta; + this.parent?.propagateLiveCount(delta); + } + findDescendantById(id) { + for (const child of this._childrenInLayoutOrder) { + if (child.id === id) + return child; + if (isRenderable(child)) { + const found = child.findDescendantById(id); + if (found) + return found; + } + } + return; + } + requestRender() { + this.markDirty(); + this._ctx.requestRender(); + } + get translateX() { + return this._translateX; + } + set translateX(value) { + if (this._translateX === value) + return; + this._translateX = value; + const parentScreenX = this.parent ? this.parent._screenX : 0; + this._screenX = parentScreenX + this._x + this._translateX; + if (this.parent) + this.parent.childrenPrimarySortDirty = true; + bumpRenderListRevision(this._ctx); + this.requestRender(); + } + get translateY() { + return this._translateY; + } + set translateY(value) { + if (this._translateY === value) + return; + this._translateY = value; + const parentScreenY = this.parent ? this.parent._screenY : 0; + this._screenY = parentScreenY + this._y + this._translateY; + if (this.parent) + this.parent.childrenPrimarySortDirty = true; + bumpRenderListRevision(this._ctx); + this.requestRender(); + } + get screenX() { + const parentScreenX = this.parent ? this.parent._screenX : 0; + return parentScreenX + this._x + this._translateX; + } + get screenY() { + const parentScreenY = this.parent ? this.parent._screenY : 0; + return parentScreenY + this._y + this._translateY; + } + get x() { + if (this.parent) { + return this.parent.x + this._x + this._translateX; + } + return this._x + this._translateX; + } + set x(value) { + this.left = value; + } + get top() { + return this._position.top; + } + set top(value) { + if (isPositionType(value) || value === undefined) { + this.setPosition({ top: value }); + } + } + get right() { + return this._position.right; + } + set right(value) { + if (isPositionType(value) || value === undefined) { + this.setPosition({ right: value }); + } + } + get bottom() { + return this._position.bottom; + } + set bottom(value) { + if (isPositionType(value) || value === undefined) { + this.setPosition({ bottom: value }); + } + } + get left() { + return this._position.left; + } + set left(value) { + if (isPositionType(value) || value === undefined) { + this.setPosition({ left: value }); + } + } + get y() { + if (this.parent) { + return this.parent.y + this._y + this._translateY; + } + return this._y + this._translateY; + } + set y(value) { + this.top = value; + } + get width() { + return this._widthValue; + } + set width(value) { + if (!isDimensionType(value) || this._width === value) { + return; + } + this._width = value; + this.yogaNode.setWidth(value); + if (typeof value === "number" && this._flexShrink === 1) { + this._flexShrink = 0; + this.yogaNode.setFlexShrink(0); + } + this.requestRender(); + } + get height() { + return this._heightValue; + } + set height(value) { + if (!isDimensionType(value) || this._height === value) { + return; + } + this._height = value; + this.yogaNode.setHeight(value); + if (typeof value === "number" && this._flexShrink === 1) { + this._flexShrink = 0; + this.yogaNode.setFlexShrink(0); + } + this.requestRender(); + } + get zIndex() { + return this._zIndex; + } + set zIndex(value) { + if (this._zIndex !== value) { + this._zIndex = value; + this.parent?.requestZIndexSort(); + bumpRenderListRevision(this._ctx); + this.requestRender(); + } + } + requestZIndexSort() { + this.needsZIndexSort = true; + } + ensureZIndexSorted() { + if (this.needsZIndexSort) { + this._childrenInZIndexOrder.sort((a, b) => a.zIndex > b.zIndex ? 1 : a.zIndex < b.zIndex ? -1 : 0); + this.needsZIndexSort = false; + } + } + getChildrenSortedByPrimaryAxis() { + if (!this.childrenPrimarySortDirty && this.childrenSortedByPrimaryAxis.length === this._childrenInLayoutOrder.length) { + return this.childrenSortedByPrimaryAxis; + } + const dir = this.yogaNode.getFlexDirection(); + const axis = dir === 2 || dir === 3 ? "x" : "y"; + const sorted = [...this._childrenInLayoutOrder]; + sorted.sort((a, b) => { + const va = axis === "y" ? a.screenY : a.screenX; + const vb = axis === "y" ? b.screenY : b.screenX; + return va - vb; + }); + this.childrenSortedByPrimaryAxis = sorted; + this.childrenPrimarySortDirty = false; + return this.childrenSortedByPrimaryAxis; + } + setupYogaProperties(options) { + const node = this.yogaNode; + if (isFlexBasisType(options.flexBasis)) { + node.setFlexBasis(options.flexBasis); + } + if (isSizeType(options.minWidth)) { + node.setMinWidth(options.minWidth); + } + if (isSizeType(options.minHeight)) { + node.setMinHeight(options.minHeight); + } + if (options.flexGrow !== undefined) { + node.setFlexGrow(options.flexGrow); + } else { + node.setFlexGrow(0); + } + if (options.flexShrink !== undefined) { + this._flexShrink = options.flexShrink; + node.setFlexShrink(options.flexShrink); + } else { + const hasExplicitWidth = typeof options.width === "number"; + const hasExplicitHeight = typeof options.height === "number"; + this._flexShrink = hasExplicitWidth || hasExplicitHeight ? 0 : 1; + node.setFlexShrink(this._flexShrink); + } + node.setFlexDirection(parseFlexDirection(options.flexDirection)); + node.setFlexWrap(parseWrap(options.flexWrap)); + node.setAlignItems(parseAlignItems(options.alignItems)); + node.setJustifyContent(parseJustify(options.justifyContent)); + node.setAlignSelf(parseAlign(options.alignSelf)); + if (isDimensionType(options.width)) { + this._width = options.width; + this.yogaNode.setWidth(options.width); + } + if (isDimensionType(options.height)) { + this._height = options.height; + this.yogaNode.setHeight(options.height); + } + this._positionType = options.position === "absolute" ? "absolute" : "relative"; + if (this._positionType !== "relative") { + node.setPositionType(parsePositionType(this._positionType)); + } + this._overflow = options.overflow === "hidden" ? "hidden" : options.overflow === "scroll" ? "scroll" : "visible"; + if (this._overflow !== "visible") { + node.setOverflow(parseOverflow(this._overflow)); + } + const hasPositionProps = options.top !== undefined || options.right !== undefined || options.bottom !== undefined || options.left !== undefined; + if (hasPositionProps) { + this._position = { + top: options.top, + right: options.right, + bottom: options.bottom, + left: options.left + }; + this.updateYogaPosition(this._position); + } + if (isSizeType(options.maxWidth)) { + node.setMaxWidth(options.maxWidth); + } + if (isSizeType(options.maxHeight)) { + node.setMaxHeight(options.maxHeight); + } + this.setupMarginAndPadding(options); + } + setupMarginAndPadding(options) { + const node = this.yogaNode; + if (isMarginType(options.margin)) { + node.setMargin(8 /* All */, options.margin); + } + if (isMarginType(options.marginX)) { + node.setMargin(6 /* Horizontal */, options.marginX); + } + if (isMarginType(options.marginY)) { + node.setMargin(7 /* Vertical */, options.marginY); + } + if (isMarginType(options.marginTop)) { + node.setMargin(1 /* Top */, options.marginTop); + } + if (isMarginType(options.marginRight)) { + node.setMargin(2 /* Right */, options.marginRight); + } + if (isMarginType(options.marginBottom)) { + node.setMargin(3 /* Bottom */, options.marginBottom); + } + if (isMarginType(options.marginLeft)) { + node.setMargin(0 /* Left */, options.marginLeft); + } + if (isPaddingType(options.padding)) { + node.setPadding(8 /* All */, options.padding); + } + if (isPaddingType(options.paddingX)) { + node.setPadding(6 /* Horizontal */, options.paddingX); + } + if (isPaddingType(options.paddingY)) { + node.setPadding(7 /* Vertical */, options.paddingY); + } + if (isPaddingType(options.paddingTop)) { + node.setPadding(1 /* Top */, options.paddingTop); + } + if (isPaddingType(options.paddingRight)) { + node.setPadding(2 /* Right */, options.paddingRight); + } + if (isPaddingType(options.paddingBottom)) { + node.setPadding(3 /* Bottom */, options.paddingBottom); + } + if (isPaddingType(options.paddingLeft)) { + node.setPadding(0 /* Left */, options.paddingLeft); + } + } + set position(positionType) { + if (!isPositionTypeType(positionType) || this._positionType === positionType) + return; + this._positionType = positionType; + this.yogaNode.setPositionType(parsePositionType(positionType)); + this.requestRender(); + } + get overflow() { + return this._overflow; + } + set overflow(overflow) { + if (!isOverflowType(overflow) || this._overflow === overflow) + return; + this._overflow = overflow; + this.yogaNode.setOverflow(parseOverflow(overflow)); + bumpRenderListRevision(this._ctx); + this.requestRender(); + } + setPosition(position) { + this._position = { ...this._position, ...position }; + this.updateYogaPosition(position); + } + updateYogaPosition(position) { + const node = this.yogaNode; + const { top, right, bottom, left } = position; + if (isPositionType(top)) { + if (top === "auto") { + node.setPositionAuto(1 /* Top */); + } else { + node.setPosition(1 /* Top */, top); + } + } + if (isPositionType(right)) { + if (right === "auto") { + node.setPositionAuto(2 /* Right */); + } else { + node.setPosition(2 /* Right */, right); + } + } + if (isPositionType(bottom)) { + if (bottom === "auto") { + node.setPositionAuto(3 /* Bottom */); + } else { + node.setPosition(3 /* Bottom */, bottom); + } + } + if (isPositionType(left)) { + if (left === "auto") { + node.setPositionAuto(0 /* Left */); + } else { + node.setPosition(0 /* Left */, left); + } + } + this.requestRender(); + } + set flexGrow(grow) { + if (grow == null) { + this.yogaNode.setFlexGrow(0); + } else { + this.yogaNode.setFlexGrow(grow); + } + this.requestRender(); + } + set flexShrink(shrink) { + const value = shrink == null ? 1 : shrink; + this._flexShrink = value; + this.yogaNode.setFlexShrink(value); + this.requestRender(); + } + set flexDirection(direction) { + this.yogaNode.setFlexDirection(parseFlexDirection(direction)); + this.requestRender(); + } + set flexWrap(wrap) { + this.yogaNode.setFlexWrap(parseWrap(wrap)); + this.requestRender(); + } + set alignItems(alignItems) { + this.yogaNode.setAlignItems(parseAlignItems(alignItems)); + this.requestRender(); + } + set justifyContent(justifyContent) { + this.yogaNode.setJustifyContent(parseJustify(justifyContent)); + this.requestRender(); + } + set alignSelf(alignSelf) { + this.yogaNode.setAlignSelf(parseAlign(alignSelf)); + this.requestRender(); + } + set flexBasis(basis) { + if (isFlexBasisType(basis)) { + this.yogaNode.setFlexBasis(basis); + this.requestRender(); + } + } + set minWidth(minWidth) { + if (isSizeType(minWidth)) { + this.yogaNode.setMinWidth(minWidth); + this.requestRender(); + } + } + set maxWidth(maxWidth) { + if (isSizeType(maxWidth)) { + this.yogaNode.setMaxWidth(maxWidth); + this.requestRender(); + } + } + set minHeight(minHeight) { + if (isSizeType(minHeight)) { + this.yogaNode.setMinHeight(minHeight); + this.requestRender(); + } + } + set maxHeight(maxHeight) { + if (isSizeType(maxHeight)) { + this.yogaNode.setMaxHeight(maxHeight); + this.requestRender(); + } + } + set margin(margin) { + if (isMarginType(margin)) { + this.yogaNode.setMargin(8 /* All */, margin); + this.requestRender(); + } + } + set marginX(marginX) { + if (isMarginType(marginX)) { + this.yogaNode.setMargin(6 /* Horizontal */, marginX); + this.requestRender(); + } + } + set marginY(marginY) { + if (isMarginType(marginY)) { + this.yogaNode.setMargin(7 /* Vertical */, marginY); + this.requestRender(); + } + } + set marginTop(margin) { + if (isMarginType(margin)) { + this.yogaNode.setMargin(1 /* Top */, margin); + this.requestRender(); + } + } + get marginTop() { + const margin = this.yogaNode.getMargin(1 /* Top */); + if (typeof margin === "number") + return margin; + if (typeof margin === "object" && margin && "value" in margin && typeof margin.value === "number") + return margin.value; + return 0; + } + set marginRight(margin) { + if (isMarginType(margin)) { + this.yogaNode.setMargin(2 /* Right */, margin); + this.requestRender(); + } + } + set marginBottom(margin) { + if (isMarginType(margin)) { + this.yogaNode.setMargin(3 /* Bottom */, margin); + this.requestRender(); + } + } + set marginLeft(margin) { + if (isMarginType(margin)) { + this.yogaNode.setMargin(0 /* Left */, margin); + this.requestRender(); + } + } + set padding(padding) { + if (isPaddingType(padding)) { + this.yogaNode.setPadding(8 /* All */, padding); + this.requestRender(); + } + } + set paddingX(paddingX) { + if (isPaddingType(paddingX)) { + this.yogaNode.setPadding(6 /* Horizontal */, paddingX); + this.requestRender(); + } + } + set paddingY(paddingY) { + if (isPaddingType(paddingY)) { + this.yogaNode.setPadding(7 /* Vertical */, paddingY); + this.requestRender(); + } + } + set paddingTop(padding) { + if (isPaddingType(padding)) { + this.yogaNode.setPadding(1 /* Top */, padding); + this.requestRender(); + } + } + set paddingRight(padding) { + if (isPaddingType(padding)) { + this.yogaNode.setPadding(2 /* Right */, padding); + this.requestRender(); + } + } + set paddingBottom(padding) { + if (isPaddingType(padding)) { + this.yogaNode.setPadding(3 /* Bottom */, padding); + this.requestRender(); + } + } + set paddingLeft(padding) { + if (isPaddingType(padding)) { + this.yogaNode.setPadding(0 /* Left */, padding); + this.requestRender(); + } + } + getLayoutNode() { + return this.yogaNode; + } + updateFromLayout() { + const frameId = this._ctx.frameId; + if (this._lastLayoutFrame === frameId) + return; + this._lastLayoutFrame = frameId; + const layout = this.yogaNode.getComputedLayout(); + const oldX = this._x; + const oldY = this._y; + const oldWidth = this._widthValue; + const oldHeight = this._heightValue; + this._x = layout.left; + this._y = layout.top; + const parentScreenX = this.parent ? this.parent._screenX : 0; + const parentScreenY = this.parent ? this.parent._screenY : 0; + this._screenX = parentScreenX + this._x + this._translateX; + this._screenY = parentScreenY + this._y + this._translateY; + const newWidth = Math.max(layout.width, 1); + const newHeight = Math.max(layout.height, 1); + const sizeChanged = oldWidth !== newWidth || oldHeight !== newHeight; + this._widthValue = newWidth; + this._heightValue = newHeight; + if (sizeChanged) { + this.onLayoutResize(newWidth, newHeight); + } + const positionChanged = oldX !== this._x || oldY !== this._y; + if (positionChanged) { + if (this.parent) + this.parent.childrenPrimarySortDirty = true; + } + } + onLayoutResize(width, height) { + if (this._visible) { + this.handleFrameBufferResize(width, height); + this.onResize(width, height); + this.requestRender(); + } + } + handleFrameBufferResize(width, height) { + if (!this.buffered) + return; + if (width <= 0 || height <= 0) { + return; + } + if (this.frameBuffer) { + this.frameBuffer.resize(width, height); + } else { + this.createFrameBuffer(); + } + } + createFrameBuffer() { + const w = this.width; + const h = this.height; + if (w <= 0 || h <= 0) { + return; + } + try { + const widthMethod = this._ctx.widthMethod; + this.frameBuffer = OptimizedBuffer.create(w, h, widthMethod, { + respectAlpha: true, + id: `framebuffer-${this.id}` + }); + } catch (error) { + console.error(`Failed to create frame buffer for ${this.id}:`, error); + this.frameBuffer = null; + } + } + onResize(width, height) { + this.onSizeChange?.(); + this.emit("resize"); + } + replaceParent(obj) { + if (obj.parent) { + obj.parent.remove(obj.id); + } + obj.parent = this; + } + add(obj, index) { + if (!obj) { + return -1; + } + const renderable = maybeMakeRenderable(this._ctx, obj); + if (!renderable) { + return -1; + } + if (renderable.isDestroyed) { + if (true) { + console.warn(`Renderable with id ${renderable.id} was already destroyed, skipping add`); + } + return -1; + } + const anchorRenderable = index !== undefined ? this._childrenInLayoutOrder[index] : undefined; + if (anchorRenderable) { + return this.insertBefore(renderable, anchorRenderable); + } + if (renderable.parent === this) { + this.yogaNode.removeChild(renderable.getLayoutNode()); + this._childrenInLayoutOrder.splice(this._childrenInLayoutOrder.indexOf(renderable), 1); + } else { + this.replaceParent(renderable); + this.needsZIndexSort = true; + this.renderableMapById.set(renderable.id, renderable); + this._childrenInZIndexOrder.push(renderable); + if (typeof renderable.onLifecyclePass === "function") { + this._ctx.registerLifecyclePass(renderable); + } + if (renderable._liveCount > 0) { + this.propagateLiveCount(renderable._liveCount); + } + } + const childLayoutNode = renderable.getLayoutNode(); + const insertedIndex = this._childrenInLayoutOrder.length; + this._childrenInLayoutOrder.push(renderable); + this.yogaNode.insertChild(childLayoutNode, insertedIndex); + this.childrenPrimarySortDirty = true; + this._shouldUpdateBefore.add(renderable); + bumpRenderListRevision(this._ctx); + this.requestRender(); + return insertedIndex; + } + insertBefore(obj, anchor) { + if (!anchor) { + return this.add(obj); + } + if (!obj) { + return -1; + } + const renderable = maybeMakeRenderable(this._ctx, obj); + if (!renderable) { + return -1; + } + if (renderable.isDestroyed) { + if (true) { + console.warn(`Renderable with id ${renderable.id} was already destroyed, skipping insertBefore`); + } + return -1; + } + if (!isRenderable(anchor)) { + throw new Error("Anchor must be a Renderable"); + } + if (anchor.isDestroyed) { + if (true) { + console.warn(`Anchor with id ${anchor.id} was already destroyed, skipping insertBefore`); + } + return -1; + } + if (!this.renderableMapById.has(anchor.id)) { + if (true) { + console.warn(`Anchor with id ${anchor.id} does not exist within the parent ${this.id}, skipping insertBefore`); + } + return -1; + } + if (renderable === anchor || renderable.id === anchor.id) { + if (true) { + console.warn(`Anchor is the same as the node ${renderable.id} being inserted, skipping insertBefore`); + } + return -1; + } + if (renderable.parent === this) { + this.yogaNode.removeChild(renderable.getLayoutNode()); + this._childrenInLayoutOrder.splice(this._childrenInLayoutOrder.indexOf(renderable), 1); + } else { + this.replaceParent(renderable); + this.needsZIndexSort = true; + this.renderableMapById.set(renderable.id, renderable); + this._childrenInZIndexOrder.push(renderable); + if (typeof renderable.onLifecyclePass === "function") { + this._ctx.registerLifecyclePass(renderable); + } + if (renderable._liveCount > 0) { + this.propagateLiveCount(renderable._liveCount); + } + } + this.childrenPrimarySortDirty = true; + const anchorIndex = this._childrenInLayoutOrder.indexOf(anchor); + const insertedIndex = Math.max(0, Math.min(anchorIndex, this._childrenInLayoutOrder.length)); + this._childrenInLayoutOrder.splice(insertedIndex, 0, renderable); + this.yogaNode.insertChild(renderable.getLayoutNode(), insertedIndex); + this._shouldUpdateBefore.add(renderable); + bumpRenderListRevision(this._ctx); + this.requestRender(); + return insertedIndex; + } + getRenderable(id) { + return this.renderableMapById.get(id); + } + remove(id) { + if (!id) { + return; + } + if (this.renderableMapById.has(id)) { + const obj = this.renderableMapById.get(id); + if (obj) { + if (obj._liveCount > 0) { + this.propagateLiveCount(-obj._liveCount); + } + const childLayoutNode = obj.getLayoutNode(); + this.yogaNode.removeChild(childLayoutNode); + this.requestRender(); + obj.onRemove(); + obj.parent = null; + this._ctx.unregisterLifecyclePass(obj); + this.renderableMapById.delete(id); + const index = this._childrenInLayoutOrder.findIndex((obj2) => obj2.id === id); + if (index !== -1) { + this._childrenInLayoutOrder.splice(index, 1); + } + const zIndexIndex = this._childrenInZIndexOrder.findIndex((obj2) => obj2.id === id); + if (zIndexIndex !== -1) { + this._childrenInZIndexOrder.splice(zIndexIndex, 1); + } + this.childrenPrimarySortDirty = true; + bumpRenderListRevision(this._ctx); + } + } + } + onRemove() {} + getChildren() { + return [...this._childrenInLayoutOrder]; + } + getChildrenCount() { + return this._childrenInLayoutOrder.length; + } + updateLayout(deltaTime, renderList = []) { + if (!this.visible) + return; + this.onUpdate(deltaTime); + if (this._isDestroyed) + return; + this.updateFromLayout(); + if (this._shouldUpdateBefore.size > 0) { + for (const child of this._shouldUpdateBefore) { + if (!child.isDestroyed) { + child.updateFromLayout(); + } + } + this._shouldUpdateBefore.clear(); + } + if (this._isDestroyed) + return; + const shouldPushOpacity = this._opacity < 1; + if (shouldPushOpacity) { + renderList.push({ action: "pushOpacity", opacity: this._opacity }); + } + renderList.push({ action: "render", renderable: this }); + this.ensureZIndexSorted(); + const shouldPushScissor = this._overflow !== "visible" && this.width > 0 && this.height > 0; + if (shouldPushScissor) { + const scissorRect = this.getScissorRect(); + renderList.push({ + action: "pushScissorRect", + x: scissorRect.x, + y: scissorRect.y, + width: scissorRect.width, + height: scissorRect.height, + screenX: this._screenX, + screenY: this._screenY + }); + } + if (!this._hasVisibleChildFilter()) { + for (const child of this._childrenInZIndexOrder) { + child.updateLayout(deltaTime, renderList); + } + } else { + for (const child of this._childrenInZIndexOrder) { + if (child.isDestroyed) + continue; + child.updateFromLayout(); + } + const visibleChildren = this._getVisibleChildren(); + const visibleChildSet = new Set(visibleChildren); + for (const child of this._childrenInZIndexOrder) { + if (!visibleChildSet.has(child.num)) + continue; + child.updateLayout(deltaTime, renderList); + } + } + if (shouldPushScissor) { + renderList.push({ action: "popScissorRect" }); + } + if (shouldPushOpacity) { + renderList.push({ action: "popOpacity" }); + } + } + render(buffer, deltaTime) { + let renderBuffer = buffer; + if (this.buffered && this.frameBuffer) { + renderBuffer = this.frameBuffer; + } + if (this.renderBefore) { + this.renderBefore.call(this, renderBuffer, deltaTime); + } + this.renderSelf(renderBuffer, deltaTime); + if (this.renderAfter) { + this.renderAfter.call(this, renderBuffer, deltaTime); + } + const screenX = this._screenX; + const screenY = this._screenY; + this.markClean(); + this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num); + if (this.buffered && this.frameBuffer) { + buffer.drawFrameBuffer(screenX, screenY, this.frameBuffer); + } + } + _hasVisibleChildFilter() { + return this._getVisibleChildren !== Renderable.prototype._getVisibleChildren; + } + _getVisibleChildren() { + return this._childrenInZIndexOrder.map((child) => child.num); + } + canReuseRenderCommandList() { + return this.onUpdate === Renderable.prototype.onUpdate && (this._overflow === "visible" || this.getScissorRect === Renderable.prototype.getScissorRect) && !this._hasVisibleChildFilter(); + } + onUpdate(deltaTime) {} + getScissorRect() { + return { + x: this.buffered ? 0 : this._screenX, + y: this.buffered ? 0 : this._screenY, + width: this.width, + height: this.height + }; + } + renderSelf(buffer, deltaTime) {} + get isDestroyed() { + return this._isDestroyed; + } + destroy() { + if (this._isDestroyed) { + return; + } + this._isDestroyed = true; + this.emit("destroyed" /* DESTROYED */); + if (this.parent) { + this.parent.remove(this.id); + } + if (this.frameBuffer) { + this.frameBuffer.destroy(); + this.frameBuffer = null; + } + for (const child of this._childrenInLayoutOrder) { + this.remove(child.id); + } + this._childrenInLayoutOrder = []; + this.renderableMapById.clear(); + Renderable.renderablesByNumber.delete(this.num); + this.blur(); + this.removeAllListeners(); + this.destroySelf(); + try { + this.yogaNode.free(); + } catch (e) {} + } + destroyRecursively() { + const children = [...this._childrenInLayoutOrder]; + for (const child of children) { + child.destroyRecursively(); + } + this.destroy(); + } + destroySelf() {} + processMouseEvent(event) { + this._mouseListener?.call(this, event); + this._mouseListeners[event.type]?.call(this, event); + this.onMouseEvent(event); + if (this.parent && !event.propagationStopped) { + this.parent.processMouseEvent(event); + } + } + onMouseEvent(event) {} + set onMouse(handler) { + if (handler) + this._mouseListener = handler; + else + this._mouseListener = null; + } + set onMouseDown(handler) { + if (handler) + this._mouseListeners["down"] = handler; + else + delete this._mouseListeners["down"]; + } + set onMouseUp(handler) { + if (handler) + this._mouseListeners["up"] = handler; + else + delete this._mouseListeners["up"]; + } + set onMouseMove(handler) { + if (handler) + this._mouseListeners["move"] = handler; + else + delete this._mouseListeners["move"]; + } + set onMouseDrag(handler) { + if (handler) + this._mouseListeners["drag"] = handler; + else + delete this._mouseListeners["drag"]; + } + set onMouseDragEnd(handler) { + if (handler) + this._mouseListeners["drag-end"] = handler; + else + delete this._mouseListeners["drag-end"]; + } + set onMouseDrop(handler) { + if (handler) + this._mouseListeners["drop"] = handler; + else + delete this._mouseListeners["drop"]; + } + set onMouseOver(handler) { + if (handler) + this._mouseListeners["over"] = handler; + else + delete this._mouseListeners["over"]; + } + set onMouseOut(handler) { + if (handler) + this._mouseListeners["out"] = handler; + else + delete this._mouseListeners["out"]; + } + set onMouseScroll(handler) { + if (handler) + this._mouseListeners["scroll"] = handler; + else + delete this._mouseListeners["scroll"]; + } + set onPaste(handler) { + this._pasteListener = handler; + } + get onPaste() { + return this._pasteListener; + } + set onKeyDown(handler) { + if (handler) + this._keyListeners["down"] = handler; + else + delete this._keyListeners["down"]; + } + get onKeyDown() { + return this._keyListeners["down"]; + } + set onSizeChange(handler) { + this._sizeChangeListener = handler; + } + get onSizeChange() { + return this._sizeChangeListener; + } + applyEventOptions(options) { + this.onMouse = options.onMouse; + this.onMouseDown = options.onMouseDown; + this.onMouseUp = options.onMouseUp; + this.onMouseMove = options.onMouseMove; + this.onMouseDrag = options.onMouseDrag; + this.onMouseDragEnd = options.onMouseDragEnd; + this.onMouseDrop = options.onMouseDrop; + this.onMouseOver = options.onMouseOver; + this.onMouseOut = options.onMouseOut; + this.onMouseScroll = options.onMouseScroll; + this.onPaste = options.onPaste; + this.onKeyDown = options.onKeyDown; + this.onSizeChange = options.onSizeChange; + } +} + +class RootRenderable extends Renderable { + renderList = []; + appliedLayoutGeneration = -1; + appliedRenderListRevision = -1; + renderListReusable = false; + constructor(ctx) { + super(ctx, { + id: "__root__", + zIndex: 0, + visible: true, + width: ctx.width, + height: ctx.height, + enableLayout: true + }); + if (this.yogaNode) { + this.yogaNode.free(); + } + this.yogaNode = yoga_default.Node.createForOpenTUI(); + this.yogaNode.setWidth(ctx.width); + this.yogaNode.setHeight(ctx.height); + this.yogaNode.setFlexDirection(0 /* Column */); + this.calculateLayout(); + } + render(buffer, deltaTime) { + if (!this.visible) + return; + for (const renderable of this._ctx.getLifecyclePasses()) { + renderable.onLifecyclePass?.call(renderable); + } + if (this.yogaNode.isDirty()) { + this.calculateLayout(); + } else { + this.syncExternalLayoutGeneration(); + } + const layoutGeneration = getLayoutGeneration(this._ctx); + const renderListRevision = getRenderListRevision(this._ctx); + const canReuseRenderList = this.renderListReusable && this.appliedLayoutGeneration === layoutGeneration && this.appliedRenderListRevision === renderListRevision; + if (!canReuseRenderList) { + this.renderList.length = 0; + super.updateLayout(deltaTime, this.renderList); + this.appliedLayoutGeneration = layoutGeneration; + this.appliedRenderListRevision = getRenderListRevision(this._ctx); + this.renderListReusable = this.canReuseCurrentRenderList(); + } + this._ctx.clearHitGridScissorRects(); + for (let i = 1;i < this.renderList.length; i++) { + const command = this.renderList[i]; + switch (command.action) { + case "render": + if (!command.renderable.isDestroyed) { + command.renderable.render(buffer, deltaTime); + } + break; + case "pushScissorRect": + buffer.pushScissorRect(command.x, command.y, command.width, command.height); + this._ctx.pushHitGridScissorRect(command.screenX, command.screenY, command.width, command.height); + break; + case "popScissorRect": + buffer.popScissorRect(); + this._ctx.popHitGridScissorRect(); + break; + case "pushOpacity": + buffer.pushOpacity(command.opacity); + break; + case "popOpacity": + buffer.popOpacity(); + break; + } + } + } + propagateLiveCount(delta) { + const oldCount = this._liveCount; + this._liveCount += delta; + if (oldCount === 0 && this._liveCount > 0) { + this._ctx.requestLive(); + } else if (oldCount > 0 && this._liveCount === 0) { + this._ctx.dropLive(); + } + } + calculateLayout() { + this.yogaNode.calculateLayout(this.width, this.height, 1 /* LTR */); + bumpLayoutGeneration(this._ctx); + this.yogaNode.markLayoutSeen(); + this.emit("layout-changed" /* LAYOUT_CHANGED */); + } + syncExternalLayoutGeneration() { + if (!this.yogaNode.hasNewLayout()) + return; + bumpLayoutGeneration(this._ctx); + this.yogaNode.markLayoutSeen(); + } + canReuseCurrentRenderList() { + if (this._liveCount > 0) + return false; + for (const command of this.renderList) { + if (command.action !== "render") + continue; + if (!command.renderable.canReuseRenderCommandList()) + return false; + } + return true; + } + resize(width, height) { + this.width = width; + this.height = height; + this.emit("resized" /* RESIZED */, { width, height }); + } +} + +// src/renderables/composition/vnode.ts +import util from "node:util"; +var BrandedVNode = Symbol.for("@opentui/core/VNode"); +function isRenderableConstructor(value) { + return typeof value === "function" && value.prototype && Renderable.prototype.isPrototypeOf(value.prototype); +} +function flattenChildren(children) { + const result = []; + for (const child of children) { + if (Array.isArray(child)) { + result.push(...flattenChildren(child)); + } else if (child !== null && child !== undefined && child !== false) { + result.push(child); + } + } + return result; +} +function h(type, props, ...children) { + if (typeof type !== "function") { + throw new TypeError("h() received an invalid vnode type"); + } + const vnode = { + [BrandedVNode]: true, + type, + props, + children: flattenChildren(children), + __pendingCalls: [] + }; + if (isRenderableConstructor(type)) { + return new Proxy(vnode, { + get(target, prop, receiver) { + if (prop in target) { + return Reflect.get(target, prop, receiver); + } + if (typeof prop === "string") { + const prototype = type.prototype; + const hasMethod = prototype && (typeof prototype[prop] === "function" || Object.getOwnPropertyDescriptor(prototype, prop) || Object.getOwnPropertyDescriptor(Object.getPrototypeOf(prototype), prop)); + if (hasMethod) { + return (...args) => { + target.__pendingCalls = target.__pendingCalls || []; + target.__pendingCalls.push({ method: prop, args }); + return target; + }; + } + } + return Reflect.get(target, prop, receiver); + }, + set(target, prop, value, receiver) { + if (typeof prop === "string" && isRenderableConstructor(type)) { + const prototype = type.prototype; + const descriptor = Object.getOwnPropertyDescriptor(prototype, prop) || Object.getOwnPropertyDescriptor(Object.getPrototypeOf(prototype), prop); + if (descriptor && descriptor.set) { + target.__pendingCalls = target.__pendingCalls || []; + target.__pendingCalls.push({ method: prop, args: [value], isProperty: true }); + return true; + } + } + return Reflect.set(target, prop, value, receiver); + } + }); + } + return vnode; +} +function isVNode(node) { + return node && node[BrandedVNode]; +} +function maybeMakeRenderable(ctx, node) { + if (isRenderable(node)) + return node; + if (isVNode(node)) + return instantiate(ctx, node); + if (true) { + console.warn("maybeMakeRenderable received an invalid node", util.inspect(node, { depth: 2 })); + } + return null; +} +function wrapWithDelegates(instance, delegateMap) { + if (!delegateMap || Object.keys(delegateMap).length === 0) + return instance; + const descendantCache = new Map; + const getDescendant = (id) => { + if (descendantCache.has(id)) { + const cached = descendantCache.get(id); + if (cached !== undefined) { + return cached; + } + } + const descendant = instance.findDescendantById(id); + if (descendant) { + descendantCache.set(id, descendant); + } + return descendant; + }; + const proxy = new Proxy(instance, { + get(target, prop, receiver) { + if (typeof prop === "string" && delegateMap[prop]) { + const host = getDescendant(delegateMap[prop]); + if (host) { + const value = host[prop]; + if (typeof value === "function") { + return value.bind(host); + } + return value; + } + } + return Reflect.get(target, prop, receiver); + }, + set(target, prop, value, receiver) { + if (typeof prop === "string" && delegateMap[prop]) { + const host = getDescendant(delegateMap[prop]); + if (host) { + return Reflect.set(host, prop, value); + } + } + return Reflect.set(target, prop, value, receiver); + } + }); + return proxy; +} +function instantiate(ctx, node) { + if (isRenderable(node)) + return node; + if (!node || typeof node !== "object") { + throw new TypeError("mount() received an invalid vnode"); + } + const vnode = node; + const { type, props } = vnode; + const children = flattenChildren(vnode.children || []); + const delegateMap = vnode.__delegateMap; + if (isRenderableConstructor(type)) { + const instance = new type(ctx, props || {}); + for (const child of children) { + if (isRenderable(child)) { + instance.add(child); + } else { + const mounted = instantiate(ctx, child); + instance.add(mounted); + } + } + const delegatedInstance = wrapWithDelegates(instance, delegateMap); + const pendingCalls = vnode.__pendingCalls; + if (pendingCalls) { + for (const call of pendingCalls) { + if (call.isProperty) { + delegatedInstance[call.method] = call.args[0]; + } else { + delegatedInstance[call.method].apply(delegatedInstance, call.args); + } + } + } + return delegatedInstance; + } + const resolved = type(props || {}, children); + const inst = instantiate(ctx, resolved); + return wrapWithDelegates(inst, delegateMap); +} +function delegate(mapping, vnode) { + if (isRenderable(vnode)) { + return wrapWithDelegates(vnode, mapping); + } + if (!vnode || typeof vnode !== "object") + return vnode; + vnode.__delegateMap = { ...vnode.__delegateMap || {}, ...mapping }; + return vnode; +} + +// src/text-buffer-view.ts +class TextBufferView { + lib; + viewPtr; + textBuffer; + _destroyed = false; + constructor(lib, ptr, textBuffer) { + this.lib = lib; + this.viewPtr = ptr; + this.textBuffer = textBuffer; + } + static create(textBuffer) { + const lib = resolveRenderLib(); + const viewPtr = lib.createTextBufferView(textBuffer.ptr); + return new TextBufferView(lib, viewPtr, textBuffer); + } + guard() { + if (this._destroyed) + throw new Error("TextBufferView is destroyed"); + } + get ptr() { + this.guard(); + return this.viewPtr; + } + setSelection(start, end, bgColor, fgColor) { + this.guard(); + this.lib.textBufferViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null); + } + updateSelection(end, bgColor, fgColor) { + this.guard(); + this.lib.textBufferViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null); + } + resetSelection() { + this.guard(); + this.lib.textBufferViewResetSelection(this.viewPtr); + } + getSelection() { + this.guard(); + return this.lib.textBufferViewGetSelection(this.viewPtr); + } + hasSelection() { + this.guard(); + return this.getSelection() !== null; + } + setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) { + this.guard(); + return this.lib.textBufferViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null); + } + updateLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) { + this.guard(); + return this.lib.textBufferViewUpdateLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null); + } + resetLocalSelection() { + this.guard(); + this.lib.textBufferViewResetLocalSelection(this.viewPtr); + } + setWrapWidth(width) { + this.guard(); + this.lib.textBufferViewSetWrapWidth(this.viewPtr, width ?? 0); + } + setWrapMode(mode) { + this.guard(); + this.lib.textBufferViewSetWrapMode(this.viewPtr, mode); + } + setFirstLineOffset(offset) { + this.guard(); + this.lib.textBufferViewSetFirstLineOffset(this.viewPtr, offset); + } + setViewportSize(width, height) { + this.guard(); + this.lib.textBufferViewSetViewportSize(this.viewPtr, width, height); + } + setViewport(x, y, width, height) { + this.guard(); + this.lib.textBufferViewSetViewport(this.viewPtr, x, y, width, height); + } + get lineInfo() { + this.guard(); + return this.lib.textBufferViewGetLineInfo(this.viewPtr); + } + get logicalLineInfo() { + this.guard(); + return this.lib.textBufferViewGetLogicalLineInfo(this.viewPtr); + } + getSelectedText() { + this.guard(); + const byteSize = this.textBuffer.byteSize; + if (byteSize === 0) + return ""; + const selectedBytes = this.lib.textBufferViewGetSelectedTextBytes(this.viewPtr, byteSize); + if (!selectedBytes) + return ""; + return this.lib.decoder.decode(selectedBytes); + } + getPlainText() { + this.guard(); + const byteSize = this.textBuffer.byteSize; + if (byteSize === 0) + return ""; + const plainBytes = this.lib.textBufferViewGetPlainTextBytes(this.viewPtr, byteSize); + if (!plainBytes) + return ""; + return this.lib.decoder.decode(plainBytes); + } + setTabIndicator(indicator) { + this.guard(); + const codePoint = typeof indicator === "string" ? indicator.codePointAt(0) ?? 0 : indicator; + this.lib.textBufferViewSetTabIndicator(this.viewPtr, codePoint); + } + setTabIndicatorColor(color) { + this.guard(); + this.lib.textBufferViewSetTabIndicatorColor(this.viewPtr, color); + } + setTruncate(truncate) { + this.guard(); + this.lib.textBufferViewSetTruncate(this.viewPtr, truncate); + } + measureForDimensions(width, height) { + this.guard(); + return this.lib.textBufferViewMeasureForDimensions(this.viewPtr, width, height); + } + getVirtualLineCount() { + this.guard(); + return this.lib.textBufferViewGetVirtualLineCount(this.viewPtr); + } + destroy() { + if (this._destroyed) + return; + this._destroyed = true; + this.lib.destroyTextBufferView(this.viewPtr); + } +} + +// src/edit-buffer.ts +import { EventEmitter as EventEmitter2 } from "events"; + +class EditBuffer extends EventEmitter2 { + static registry = new Map; + static nativeEventsSubscribed = false; + lib; + bufferPtr; + textBufferPtr; + id; + _destroyed = false; + _textBytes = []; + _singleTextBytes = null; + _singleTextMemId = null; + _syntaxStyle; + constructor(lib, ptr) { + super(); + this.lib = lib; + this.bufferPtr = ptr; + this.textBufferPtr = lib.editBufferGetTextBuffer(ptr); + this.id = lib.editBufferGetId(ptr); + EditBuffer.registry.set(this.id, this); + EditBuffer.subscribeToNativeEvents(lib); + } + static create(widthMethod) { + const lib = resolveRenderLib(); + const ptr = lib.createEditBuffer(widthMethod); + return new EditBuffer(lib, ptr); + } + static subscribeToNativeEvents(lib) { + if (EditBuffer.nativeEventsSubscribed) + return; + EditBuffer.nativeEventsSubscribed = true; + lib.onAnyNativeEvent((name, data) => { + const buffer = new Uint16Array(data); + if (name.startsWith("eb_") && buffer.length >= 1) { + const id = buffer[0]; + const instance = EditBuffer.registry.get(id); + if (instance) { + const eventName = name.slice(3); + const eventData = data.slice(2); + instance.emit(eventName, eventData); + } + } + }); + } + guard() { + if (this._destroyed) + throw new Error("EditBuffer is destroyed"); + } + get ptr() { + this.guard(); + return this.bufferPtr; + } + setText(text) { + this.guard(); + const textBytes = this.lib.encoder.encode(text); + if (this._singleTextMemId !== null) { + this.lib.textBufferReplaceMemBuffer(this.textBufferPtr, this._singleTextMemId, textBytes, false); + } else { + this._singleTextMemId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false); + } + this._singleTextBytes = textBytes; + this.lib.editBufferSetTextFromMem(this.bufferPtr, this._singleTextMemId); + } + setTextOwned(text) { + this.guard(); + const textBytes = this.lib.encoder.encode(text); + this.lib.editBufferSetText(this.bufferPtr, textBytes); + } + replaceText(text) { + this.guard(); + const textBytes = this.lib.encoder.encode(text); + this._textBytes.push(textBytes); + const memId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false); + this.lib.editBufferReplaceTextFromMem(this.bufferPtr, memId); + } + replaceTextOwned(text) { + this.guard(); + const textBytes = this.lib.encoder.encode(text); + this.lib.editBufferReplaceText(this.bufferPtr, textBytes); + } + getLineCount() { + this.guard(); + return this.lib.textBufferGetLineCount(this.textBufferPtr); + } + getText() { + this.guard(); + const maxSize = 1024 * 1024; + const textBytes = this.lib.editBufferGetText(this.bufferPtr, maxSize); + if (!textBytes) + return ""; + return this.lib.decoder.decode(textBytes); + } + insertChar(char) { + this.guard(); + this.lib.editBufferInsertChar(this.bufferPtr, char); + } + insertText(text) { + this.guard(); + this.lib.editBufferInsertText(this.bufferPtr, text); + } + deleteChar() { + this.guard(); + this.lib.editBufferDeleteChar(this.bufferPtr); + } + deleteCharBackward() { + this.guard(); + this.lib.editBufferDeleteCharBackward(this.bufferPtr); + } + deleteRange(startLine, startCol, endLine, endCol) { + this.guard(); + this.lib.editBufferDeleteRange(this.bufferPtr, startLine, startCol, endLine, endCol); + } + newLine() { + this.guard(); + this.lib.editBufferNewLine(this.bufferPtr); + } + deleteLine() { + this.guard(); + this.lib.editBufferDeleteLine(this.bufferPtr); + } + moveCursorLeft() { + this.guard(); + this.lib.editBufferMoveCursorLeft(this.bufferPtr); + } + moveCursorRight() { + this.guard(); + this.lib.editBufferMoveCursorRight(this.bufferPtr); + } + moveCursorUp() { + this.guard(); + this.lib.editBufferMoveCursorUp(this.bufferPtr); + } + moveCursorDown() { + this.guard(); + this.lib.editBufferMoveCursorDown(this.bufferPtr); + } + gotoLine(line) { + this.guard(); + this.lib.editBufferGotoLine(this.bufferPtr, line); + } + setCursor(line, col) { + this.guard(); + this.lib.editBufferSetCursor(this.bufferPtr, line, col); + } + setCursorToLineCol(line, col) { + this.guard(); + this.lib.editBufferSetCursorToLineCol(this.bufferPtr, line, col); + } + setCursorByOffset(offset) { + this.guard(); + this.lib.editBufferSetCursorByOffset(this.bufferPtr, offset); + } + getCursorPosition() { + this.guard(); + return this.lib.editBufferGetCursorPosition(this.bufferPtr); + } + getNextWordBoundary() { + this.guard(); + const boundary = this.lib.editBufferGetNextWordBoundary(this.bufferPtr); + return { + row: boundary.row, + col: boundary.col, + offset: boundary.offset + }; + } + getPrevWordBoundary() { + this.guard(); + const boundary = this.lib.editBufferGetPrevWordBoundary(this.bufferPtr); + return { + row: boundary.row, + col: boundary.col, + offset: boundary.offset + }; + } + getEOL() { + this.guard(); + const boundary = this.lib.editBufferGetEOL(this.bufferPtr); + return { + row: boundary.row, + col: boundary.col, + offset: boundary.offset + }; + } + offsetToPosition(offset) { + this.guard(); + const result = this.lib.editBufferOffsetToPosition(this.bufferPtr, offset); + if (!result) + return null; + return { row: result.row, col: result.col }; + } + positionToOffset(row, col) { + this.guard(); + return this.lib.editBufferPositionToOffset(this.bufferPtr, row, col); + } + getLineStartOffset(row) { + this.guard(); + return this.lib.editBufferGetLineStartOffset(this.bufferPtr, row); + } + getTextRange(startOffset, endOffset) { + this.guard(); + if (startOffset >= endOffset) + return ""; + const maxSize = 1024 * 1024; + const textBytes = this.lib.editBufferGetTextRange(this.bufferPtr, startOffset, endOffset, maxSize); + if (!textBytes) + return ""; + return this.lib.decoder.decode(textBytes); + } + getTextRangeByCoords(startRow, startCol, endRow, endCol) { + this.guard(); + const maxSize = 1024 * 1024; + const textBytes = this.lib.editBufferGetTextRangeByCoords(this.bufferPtr, startRow, startCol, endRow, endCol, maxSize); + if (!textBytes) + return ""; + return this.lib.decoder.decode(textBytes); + } + debugLogRope() { + this.guard(); + this.lib.editBufferDebugLogRope(this.bufferPtr); + } + undo() { + this.guard(); + const maxSize = 256; + const metaBytes = this.lib.editBufferUndo(this.bufferPtr, maxSize); + if (!metaBytes) + return null; + return this.lib.decoder.decode(metaBytes); + } + redo() { + this.guard(); + const maxSize = 256; + const metaBytes = this.lib.editBufferRedo(this.bufferPtr, maxSize); + if (!metaBytes) + return null; + return this.lib.decoder.decode(metaBytes); + } + canUndo() { + this.guard(); + return this.lib.editBufferCanUndo(this.bufferPtr); + } + canRedo() { + this.guard(); + return this.lib.editBufferCanRedo(this.bufferPtr); + } + clearHistory() { + this.guard(); + this.lib.editBufferClearHistory(this.bufferPtr); + } + setDefaultFg(fg) { + this.guard(); + this.lib.textBufferSetDefaultFg(this.textBufferPtr, fg); + } + setDefaultBg(bg) { + this.guard(); + this.lib.textBufferSetDefaultBg(this.textBufferPtr, bg); + } + setDefaultAttributes(attributes) { + this.guard(); + this.lib.textBufferSetDefaultAttributes(this.textBufferPtr, attributes); + } + resetDefaults() { + this.guard(); + this.lib.textBufferResetDefaults(this.textBufferPtr); + } + setSyntaxStyle(style) { + this.guard(); + if (this.lib.textBufferSetSyntaxStyle(this.textBufferPtr, style?.ptr ?? null)) { + this._syntaxStyle = style ?? undefined; + } + } + getSyntaxStyle() { + this.guard(); + return this._syntaxStyle ?? null; + } + addHighlight(lineIdx, highlight) { + this.guard(); + this.lib.textBufferAddHighlight(this.textBufferPtr, lineIdx, highlight); + } + addHighlightByCharRange(highlight) { + this.guard(); + this.lib.textBufferAddHighlightByCharRange(this.textBufferPtr, highlight); + } + removeHighlightsByRef(hlRef) { + this.guard(); + this.lib.textBufferRemoveHighlightsByRef(this.textBufferPtr, hlRef); + } + clearLineHighlights(lineIdx) { + this.guard(); + this.lib.textBufferClearLineHighlights(this.textBufferPtr, lineIdx); + } + clearAllHighlights() { + this.guard(); + this.lib.textBufferClearAllHighlights(this.textBufferPtr); + } + getLineHighlights(lineIdx) { + this.guard(); + return this.lib.textBufferGetLineHighlights(this.textBufferPtr, lineIdx); + } + clear() { + this.guard(); + this.lib.editBufferClear(this.bufferPtr); + } + destroy() { + if (this._destroyed) + return; + this._destroyed = true; + EditBuffer.registry.delete(this.id); + this.lib.destroyEditBuffer(this.bufferPtr); + } +} + +// src/editor-view.ts +class EditorView { + lib; + viewPtr; + editBuffer; + _destroyed = false; + _extmarksController; + _textBufferViewPtr; + constructor(lib, ptr, editBuffer) { + this.lib = lib; + this.viewPtr = ptr; + this.editBuffer = editBuffer; + } + static create(editBuffer, viewportWidth, viewportHeight) { + const lib = resolveRenderLib(); + const viewPtr = lib.createEditorView(editBuffer.ptr, viewportWidth, viewportHeight); + return new EditorView(lib, viewPtr, editBuffer); + } + guard() { + if (this._destroyed) + throw new Error("EditorView is destroyed"); + } + get ptr() { + this.guard(); + return this.viewPtr; + } + setViewportSize(width, height) { + this.guard(); + this.lib.editorViewSetViewportSize(this.viewPtr, width, height); + } + setViewport(x, y, width, height, moveCursor = true) { + this.guard(); + this.lib.editorViewSetViewport(this.viewPtr, x, y, width, height, moveCursor); + } + getViewport() { + this.guard(); + return this.lib.editorViewGetViewport(this.viewPtr); + } + setScrollMargin(margin) { + this.guard(); + this.lib.editorViewSetScrollMargin(this.viewPtr, margin); + } + setWrapMode(mode) { + this.guard(); + this.lib.editorViewSetWrapMode(this.viewPtr, mode); + } + getVirtualLineCount() { + this.guard(); + return this.lib.editorViewGetVirtualLineCount(this.viewPtr); + } + getTotalVirtualLineCount() { + this.guard(); + return this.lib.editorViewGetTotalVirtualLineCount(this.viewPtr); + } + setSelection(start, end, bgColor, fgColor) { + this.guard(); + this.lib.editorViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null); + } + updateSelection(end, bgColor, fgColor) { + this.guard(); + this.lib.editorViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null); + } + resetSelection() { + this.guard(); + this.lib.editorViewResetSelection(this.viewPtr); + } + getSelection() { + this.guard(); + return this.lib.editorViewGetSelection(this.viewPtr); + } + hasSelection() { + this.guard(); + return this.getSelection() !== null; + } + setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) { + this.guard(); + return this.lib.editorViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null, updateCursor ?? false, followCursor ?? false); + } + updateLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) { + this.guard(); + return this.lib.editorViewUpdateLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null, updateCursor ?? false, followCursor ?? false); + } + resetLocalSelection() { + this.guard(); + this.lib.editorViewResetLocalSelection(this.viewPtr); + } + getSelectedText() { + this.guard(); + const maxLength = 1024 * 1024; + const selectedBytes = this.lib.editorViewGetSelectedTextBytes(this.viewPtr, maxLength); + if (!selectedBytes) + return ""; + return this.lib.decoder.decode(selectedBytes); + } + getCursor() { + this.guard(); + return this.lib.editorViewGetCursor(this.viewPtr); + } + getText() { + this.guard(); + const maxLength = 1024 * 1024; + const textBytes = this.lib.editorViewGetText(this.viewPtr, maxLength); + if (!textBytes) + return ""; + return this.lib.decoder.decode(textBytes); + } + getVisualCursor() { + this.guard(); + return this.lib.editorViewGetVisualCursor(this.viewPtr); + } + moveUpVisual() { + this.guard(); + this.lib.editorViewMoveUpVisual(this.viewPtr); + } + moveDownVisual() { + this.guard(); + this.lib.editorViewMoveDownVisual(this.viewPtr); + } + deleteSelectedText() { + this.guard(); + this.lib.editorViewDeleteSelectedText(this.viewPtr); + } + setCursorByOffset(offset) { + this.guard(); + this.lib.editorViewSetCursorByOffset(this.viewPtr, offset); + } + getNextWordBoundary() { + this.guard(); + return this.lib.editorViewGetNextWordBoundary(this.viewPtr); + } + getPrevWordBoundary() { + this.guard(); + return this.lib.editorViewGetPrevWordBoundary(this.viewPtr); + } + getEOL() { + this.guard(); + return this.lib.editorViewGetEOL(this.viewPtr); + } + getVisualSOL() { + this.guard(); + return this.lib.editorViewGetVisualSOL(this.viewPtr); + } + getVisualEOL() { + this.guard(); + return this.lib.editorViewGetVisualEOL(this.viewPtr); + } + getLineInfo() { + this.guard(); + return this.lib.editorViewGetLineInfo(this.viewPtr); + } + getLogicalLineInfo() { + this.guard(); + return this.lib.editorViewGetLogicalLineInfo(this.viewPtr); + } + get extmarks() { + if (!this._extmarksController) { + this._extmarksController = createExtmarksController(this.editBuffer, this); + } + return this._extmarksController; + } + setPlaceholderStyledText(chunks) { + this.guard(); + this.lib.editorViewSetPlaceholderStyledText(this.viewPtr, chunks); + } + setTabIndicator(indicator) { + this.guard(); + const codePoint = typeof indicator === "string" ? indicator.codePointAt(0) ?? 0 : indicator; + this.lib.editorViewSetTabIndicator(this.viewPtr, codePoint); + } + setTabIndicatorColor(color) { + this.guard(); + this.lib.editorViewSetTabIndicatorColor(this.viewPtr, color); + } + measureForDimensions(width, height) { + this.guard(); + if (!this._textBufferViewPtr) { + this._textBufferViewPtr = this.lib.editorViewGetTextBufferView(this.viewPtr); + } + return this.lib.textBufferViewMeasureForDimensions(this._textBufferViewPtr, width, height); + } + destroy() { + if (this._destroyed) + return; + if (this._extmarksController) { + this._extmarksController.destroy(); + this._extmarksController = undefined; + } + this._destroyed = true; + this.lib.destroyEditorView(this.viewPtr); + } +} + +// src/syntax-style.ts +function convertThemeToStyles(theme) { + const flatStyles = {}; + for (const tokenStyle of theme) { + const styleDefinition = {}; + if (tokenStyle.style.foreground) { + styleDefinition.fg = parseColor(tokenStyle.style.foreground); + } + if (tokenStyle.style.background) { + styleDefinition.bg = parseColor(tokenStyle.style.background); + } + if (tokenStyle.style.bold !== undefined) { + styleDefinition.bold = tokenStyle.style.bold; + } + if (tokenStyle.style.italic !== undefined) { + styleDefinition.italic = tokenStyle.style.italic; + } + if (tokenStyle.style.underline !== undefined) { + styleDefinition.underline = tokenStyle.style.underline; + } + if (tokenStyle.style.dim !== undefined) { + styleDefinition.dim = tokenStyle.style.dim; + } + for (const scope of tokenStyle.scope) { + flatStyles[scope] = styleDefinition; + } + } + return flatStyles; +} + +class SyntaxStyle { + lib; + stylePtr; + _destroyed = false; + nameCache = new Map; + styleDefs = new Map; + mergedCache = new Map; + constructor(lib, ptr) { + this.lib = lib; + this.stylePtr = ptr; + } + static create() { + const lib = resolveRenderLib(); + const ptr = lib.createSyntaxStyle(); + return new SyntaxStyle(lib, ptr); + } + static fromTheme(theme) { + const style = SyntaxStyle.create(); + const flatStyles = convertThemeToStyles(theme); + for (const [name, styleDef] of Object.entries(flatStyles)) { + style.registerStyle(name, styleDef); + } + return style; + } + static fromStyles(styles) { + const style = SyntaxStyle.create(); + for (const [name, styleDef] of Object.entries(styles)) { + style.registerStyle(name, styleDef); + } + return style; + } + guard() { + if (this._destroyed) + throw new Error("NativeSyntaxStyle is destroyed"); + } + registerStyle(name, style) { + this.guard(); + const attributes = createTextAttributes({ + bold: style.bold, + italic: style.italic, + underline: style.underline, + dim: style.dim + }); + const fg = style.fg ? parseColor(style.fg) : null; + const bg = style.bg ? parseColor(style.bg) : null; + const id = this.lib.syntaxStyleRegister(this.stylePtr, name, fg, bg, attributes); + this.nameCache.set(name, id); + this.styleDefs.set(name, { ...style, fg: fg ?? undefined, bg: bg ?? undefined }); + return id; + } + resolveStyleId(name) { + this.guard(); + const cached = this.nameCache.get(name); + if (cached !== undefined) + return cached; + const id = this.lib.syntaxStyleResolveByName(this.stylePtr, name); + if (id !== null) { + this.nameCache.set(name, id); + } + return id; + } + getStyleId(name) { + this.guard(); + const id = this.resolveStyleId(name); + if (id !== null) + return id; + if (name.includes(".")) { + const baseName = name.split(".")[0]; + return this.resolveStyleId(baseName); + } + return null; + } + get ptr() { + this.guard(); + return this.stylePtr; + } + getStyleCount() { + this.guard(); + return this.lib.syntaxStyleGetStyleCount(this.stylePtr); + } + clearNameCache() { + this.nameCache.clear(); + } + getStyle(name) { + this.guard(); + if (Object.prototype.hasOwnProperty.call(this.styleDefs, name)) { + return; + } + const style = this.styleDefs.get(name); + if (style) + return style; + if (name.includes(".")) { + const baseName = name.split(".")[0]; + if (Object.prototype.hasOwnProperty.call(this.styleDefs, baseName)) { + return; + } + return this.styleDefs.get(baseName); + } + return; + } + mergeStyles(...styleNames) { + this.guard(); + const cacheKey = styleNames.join(":"); + const cached = this.mergedCache.get(cacheKey); + if (cached) + return cached; + const styleDefinition = {}; + for (const name of styleNames) { + const style = this.getStyle(name); + if (!style) + continue; + if (style.fg) + styleDefinition.fg = style.fg; + if (style.bg) + styleDefinition.bg = style.bg; + if (style.bold !== undefined) + styleDefinition.bold = style.bold; + if (style.italic !== undefined) + styleDefinition.italic = style.italic; + if (style.underline !== undefined) + styleDefinition.underline = style.underline; + if (style.dim !== undefined) + styleDefinition.dim = style.dim; + } + const attributes = createTextAttributes({ + bold: styleDefinition.bold, + italic: styleDefinition.italic, + underline: styleDefinition.underline, + dim: styleDefinition.dim + }); + const merged = { + fg: styleDefinition.fg, + bg: styleDefinition.bg, + attributes + }; + this.mergedCache.set(cacheKey, merged); + return merged; + } + clearCache() { + this.guard(); + this.mergedCache.clear(); + } + getCacheSize() { + this.guard(); + return this.mergedCache.size; + } + getAllStyles() { + this.guard(); + return new Map(this.styleDefs); + } + getRegisteredNames() { + this.guard(); + return Array.from(this.styleDefs.keys()); + } + destroy() { + if (this._destroyed) + return; + this._destroyed = true; + this.nameCache.clear(); + this.styleDefs.clear(); + this.mergedCache.clear(); + this.lib.destroySyntaxStyle(this.stylePtr); + } +} + +// src/renderables/Box.ts +function isGapType(value) { + if (value === undefined) { + return true; + } + if (typeof value === "number" && !Number.isNaN(value)) { + return true; + } + return isValidPercentage(value); +} + +class BoxRenderable extends Renderable { + _backgroundColor; + _border; + _borderStyle; + _borderColor; + _focusedBorderColor; + _customBorderCharsObj; + _customBorderChars; + borderSides; + shouldFill; + _title; + _titleColor; + _titleAlignment; + _bottomTitle; + _bottomTitleAlignment; + _defaultOptions = { + backgroundColor: "transparent", + borderStyle: "single", + border: false, + borderColor: "#FFFFFF", + shouldFill: true, + titleAlignment: "left", + bottomTitleAlignment: "left", + focusedBorderColor: "#00AAFF" + }; + constructor(ctx, options) { + super(ctx, options); + if (options.focusable === true) { + this._focusable = true; + } + this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor); + this._border = options.border ?? this._defaultOptions.border; + if (!options.border && (options.borderStyle || options.borderColor || options.focusedBorderColor || options.customBorderChars)) { + this._border = true; + } + this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle); + this._borderColor = parseColor(options.borderColor || this._defaultOptions.borderColor); + this._focusedBorderColor = parseColor(options.focusedBorderColor || this._defaultOptions.focusedBorderColor); + this._customBorderCharsObj = options.customBorderChars; + this._customBorderChars = this._customBorderCharsObj ? borderCharsToArray(this._customBorderCharsObj) : undefined; + this.borderSides = getBorderSides(this._border); + this.shouldFill = options.shouldFill ?? this._defaultOptions.shouldFill; + this._title = options.title; + this._titleColor = options.titleColor ? parseColor(options.titleColor) : undefined; + this._titleAlignment = options.titleAlignment || this._defaultOptions.titleAlignment; + this._bottomTitle = options.bottomTitle; + this._bottomTitleAlignment = options.bottomTitleAlignment || this._defaultOptions.bottomTitleAlignment; + this.applyYogaBorders(); + const hasInitialGapProps = options.gap !== undefined || options.rowGap !== undefined || options.columnGap !== undefined; + if (hasInitialGapProps) { + this.applyYogaGap(options); + } + } + initializeBorder() { + if (this._border === false) { + this._border = true; + this.borderSides = getBorderSides(this._border); + this.applyYogaBorders(); + } + } + get customBorderChars() { + return this._customBorderCharsObj; + } + set customBorderChars(value) { + this._customBorderCharsObj = value; + this._customBorderChars = value ? borderCharsToArray(value) : undefined; + this.requestRender(); + } + get backgroundColor() { + return this._backgroundColor; + } + set backgroundColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.backgroundColor); + if (this._backgroundColor !== newColor) { + this._backgroundColor = newColor; + this.requestRender(); + } + } + get border() { + return this._border; + } + set border(value) { + if (this._border !== value) { + this._border = value; + this.borderSides = getBorderSides(value); + this.applyYogaBorders(); + this.requestRender(); + } + } + get borderStyle() { + return this._borderStyle; + } + set borderStyle(value) { + const _value = parseBorderStyle(value, this._defaultOptions.borderStyle); + if (this._borderStyle !== _value || !this._border) { + this._borderStyle = _value; + this._customBorderChars = undefined; + this.initializeBorder(); + this.requestRender(); + } + } + get borderColor() { + return this._borderColor; + } + set borderColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.borderColor); + if (this._borderColor !== newColor) { + this._borderColor = newColor; + this.initializeBorder(); + this.requestRender(); + } + } + get focusedBorderColor() { + return this._focusedBorderColor; + } + set focusedBorderColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.focusedBorderColor); + if (this._focusedBorderColor !== newColor) { + this._focusedBorderColor = newColor; + this.initializeBorder(); + if (this._focused) { + this.requestRender(); + } + } + } + get title() { + return this._title; + } + set title(value) { + if (this._title !== value) { + this._title = value; + this.requestRender(); + } + } + get titleColor() { + return this._titleColor; + } + set titleColor(value) { + const newColor = value ? parseColor(value) : undefined; + if (this._titleColor !== newColor) { + this._titleColor = newColor; + this.requestRender(); + } + } + get titleAlignment() { + return this._titleAlignment; + } + set titleAlignment(value) { + if (this._titleAlignment !== value) { + this._titleAlignment = value; + this.requestRender(); + } + } + get bottomTitle() { + return this._bottomTitle; + } + set bottomTitle(value) { + if (this._bottomTitle !== value) { + this._bottomTitle = value; + this.requestRender(); + } + } + get bottomTitleAlignment() { + return this._bottomTitleAlignment; + } + set bottomTitleAlignment(value) { + if (this._bottomTitleAlignment !== value) { + this._bottomTitleAlignment = value; + this.requestRender(); + } + } + renderSelf(buffer) { + const hasBorder = this.borderSides.top || this.borderSides.right || this.borderSides.bottom || this.borderSides.left; + const hasVisibleFill = this.shouldFill && this._backgroundColor.a > 0; + if (!hasBorder && !hasVisibleFill) { + return; + } + const hasFocusWithin = this._focusable && (this._focused || this._hasFocusedDescendant); + const currentBorderColor = hasFocusWithin ? this._focusedBorderColor : this._borderColor; + const screenX = this._screenX; + const screenY = this._screenY; + buffer.drawBox({ + x: screenX, + y: screenY, + width: this.width, + height: this.height, + borderStyle: this._borderStyle, + customBorderChars: this._customBorderChars, + border: this._border, + borderColor: currentBorderColor, + backgroundColor: this._backgroundColor, + shouldFill: this.shouldFill, + title: this._title, + titleColor: this._titleColor ?? currentBorderColor, + titleAlignment: this._titleAlignment, + bottomTitle: this._bottomTitle, + bottomTitleAlignment: this._bottomTitleAlignment + }); + } + getScissorRect() { + const baseRect = super.getScissorRect(); + if (!this.borderSides.top && !this.borderSides.right && !this.borderSides.bottom && !this.borderSides.left) { + return baseRect; + } + const leftInset = this.borderSides.left ? 1 : 0; + const rightInset = this.borderSides.right ? 1 : 0; + const topInset = this.borderSides.top ? 1 : 0; + const bottomInset = this.borderSides.bottom ? 1 : 0; + return { + x: baseRect.x + leftInset, + y: baseRect.y + topInset, + width: Math.max(0, baseRect.width - leftInset - rightInset), + height: Math.max(0, baseRect.height - topInset - bottomInset) + }; + } + applyYogaBorders() { + const node = this.yogaNode; + node.setBorder(0 /* Left */, this.borderSides.left ? 1 : 0); + node.setBorder(2 /* Right */, this.borderSides.right ? 1 : 0); + node.setBorder(1 /* Top */, this.borderSides.top ? 1 : 0); + node.setBorder(3 /* Bottom */, this.borderSides.bottom ? 1 : 0); + this.requestRender(); + } + applyYogaGap(options) { + const node = this.yogaNode; + if (isGapType(options.gap)) { + node.setGap(2 /* All */, options.gap); + } + if (isGapType(options.rowGap)) { + node.setGap(1 /* Row */, options.rowGap); + } + if (isGapType(options.columnGap)) { + node.setGap(0 /* Column */, options.columnGap); + } + } + set gap(gap) { + if (isGapType(gap)) { + this.yogaNode.setGap(2 /* All */, gap); + this.requestRender(); + } + } + set rowGap(rowGap) { + if (isGapType(rowGap)) { + this.yogaNode.setGap(1 /* Row */, rowGap); + this.requestRender(); + } + } + set columnGap(columnGap) { + if (isGapType(columnGap)) { + this.yogaNode.setGap(0 /* Column */, columnGap); + this.requestRender(); + } + } +} + +// src/renderables/TextBufferRenderable.ts +class TextBufferRenderable extends Renderable { + selectable = true; + _defaultFg; + _defaultBg; + _defaultAttributes; + _selectionBg; + _selectionFg; + _wrapMode = "word"; + lastLocalSelection = null; + _tabIndicator; + _tabIndicatorColor; + _scrollX = 0; + _scrollY = 0; + _truncate = false; + _firstLineOffset = 0; + textBuffer; + textBufferView; + _textBufferSyntaxStyle; + _defaultOptions = { + fg: RGBA.fromValues(1, 1, 1, 1), + bg: RGBA.fromValues(0, 0, 0, 0), + selectionBg: undefined, + selectionFg: undefined, + selectable: true, + attributes: 0, + wrapMode: "word", + tabIndicator: undefined, + tabIndicatorColor: undefined, + truncate: false + }; + constructor(ctx, options) { + super(ctx, options); + this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg); + this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg); + this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes; + this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg; + this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg; + this.selectable = options.selectable ?? this._defaultOptions.selectable; + this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode; + this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator; + this._tabIndicatorColor = options.tabIndicatorColor ? parseColor(options.tabIndicatorColor) : this._defaultOptions.tabIndicatorColor; + this._truncate = options.truncate ?? this._defaultOptions.truncate; + this.textBuffer = TextBuffer.create(this._ctx.widthMethod); + this.textBufferView = TextBufferView.create(this.textBuffer); + this._firstLineOffset = ctx.claimFirstLineOffset?.(this) ?? 0; + this._textBufferSyntaxStyle = SyntaxStyle.create(); + this.textBuffer.setSyntaxStyle(this._textBufferSyntaxStyle); + this.textBufferView.setWrapMode(this._wrapMode); + this.textBufferView.setFirstLineOffset(this._firstLineOffset); + this.setupMeasureFunc(); + this.textBuffer.setDefaultFg(this._defaultFg); + this.textBuffer.setDefaultBg(this._defaultBg); + this.textBuffer.setDefaultAttributes(this._defaultAttributes); + if (this._tabIndicator !== undefined) { + this.textBufferView.setTabIndicator(this._tabIndicator); + } + if (this._tabIndicatorColor !== undefined) { + this.textBufferView.setTabIndicatorColor(this._tabIndicatorColor); + } + if (this._wrapMode !== "none" && this.width > 0) { + this.textBufferView.setWrapWidth(this.width); + } + if (this.width > 0 && this.height > 0) { + this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height); + } + this.textBufferView.setTruncate(this._truncate); + this.updateTextInfo(); + } + onMouseEvent(event) { + if (event.type === "scroll") { + this.handleScroll(event); + } + } + handleScroll(event) { + if (!event.scroll) + return; + const { direction, delta } = event.scroll; + if (direction === "up") { + this.scrollY -= delta; + } else if (direction === "down") { + this.scrollY += delta; + } + if (this._wrapMode === "none") { + if (direction === "left") { + this.scrollX -= delta; + } else if (direction === "right") { + this.scrollX += delta; + } + } + } + get lineInfo() { + return this.textBufferView.logicalLineInfo; + } + get lineCount() { + return this.textBuffer.getLineCount(); + } + get virtualLineCount() { + return this.textBufferView.getVirtualLineCount(); + } + get scrollY() { + return this._scrollY; + } + set scrollY(value) { + const maxScrollY = Math.max(0, this.scrollHeight - this.height); + const clamped = Math.max(0, Math.min(value, maxScrollY)); + if (this._scrollY !== clamped) { + this._scrollY = clamped; + this.updateViewportOffset(); + this.requestRender(); + } + } + get scrollX() { + return this._scrollX; + } + set scrollX(value) { + const maxScrollX = Math.max(0, this.scrollWidth - this.width); + const clamped = Math.max(0, Math.min(value, maxScrollX)); + if (this._scrollX !== clamped) { + this._scrollX = clamped; + this.updateViewportOffset(); + this.requestRender(); + } + } + get scrollWidth() { + return this.lineInfo.lineWidthColsMax; + } + get scrollHeight() { + return this.lineInfo.lineStartCols.length; + } + get maxScrollY() { + return Math.max(0, this.scrollHeight - this.height); + } + get maxScrollX() { + return Math.max(0, this.scrollWidth - this.width); + } + updateViewportOffset() { + if (this.width > 0 && this.height > 0) { + this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height); + } + } + get plainText() { + return this.textBuffer.getPlainText(); + } + get textLength() { + return this.textBuffer.length; + } + get fg() { + return this._defaultFg; + } + set fg(value) { + const newColor = parseColor(value ?? this._defaultOptions.fg); + if (this._defaultFg !== newColor) { + this._defaultFg = newColor; + this.textBuffer.setDefaultFg(this._defaultFg); + this.onFgChanged(newColor); + this.requestRender(); + } + } + get selectionBg() { + return this._selectionBg; + } + set selectionBg(value) { + const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg; + if (this._selectionBg !== newColor) { + this._selectionBg = newColor; + if (this.lastLocalSelection) { + this.updateLocalSelection(this.lastLocalSelection); + } + this.requestRender(); + } + } + get selectionFg() { + return this._selectionFg; + } + set selectionFg(value) { + const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg; + if (this._selectionFg !== newColor) { + this._selectionFg = newColor; + if (this.lastLocalSelection) { + this.updateLocalSelection(this.lastLocalSelection); + } + this.requestRender(); + } + } + get bg() { + return this._defaultBg; + } + set bg(value) { + const newColor = parseColor(value ?? this._defaultOptions.bg); + if (this._defaultBg !== newColor) { + this._defaultBg = newColor; + this.textBuffer.setDefaultBg(this._defaultBg); + this.onBgChanged(newColor); + this.requestRender(); + } + } + get attributes() { + return this._defaultAttributes; + } + set attributes(value) { + if (this._defaultAttributes !== value) { + this._defaultAttributes = value; + this.textBuffer.setDefaultAttributes(this._defaultAttributes); + this.onAttributesChanged(value); + this.requestRender(); + } + } + get wrapMode() { + return this._wrapMode; + } + set wrapMode(value) { + if (this._wrapMode !== value) { + this._wrapMode = value; + this.textBufferView.setWrapMode(this._wrapMode); + if (value !== "none" && this.width > 0) { + this.textBufferView.setWrapWidth(this.width); + } + this.yogaNode.markDirty(); + this.requestRender(); + } + } + get tabIndicator() { + return this._tabIndicator; + } + set tabIndicator(value) { + if (this._tabIndicator !== value) { + this._tabIndicator = value; + if (value !== undefined) { + this.textBufferView.setTabIndicator(value); + } + this.requestRender(); + } + } + get tabIndicatorColor() { + return this._tabIndicatorColor; + } + set tabIndicatorColor(value) { + const newColor = value ? parseColor(value) : undefined; + if (this._tabIndicatorColor !== newColor) { + this._tabIndicatorColor = newColor; + if (newColor !== undefined) { + this.textBufferView.setTabIndicatorColor(newColor); + } + this.requestRender(); + } + } + get truncate() { + return this._truncate; + } + set truncate(value) { + if (this._truncate !== value) { + this._truncate = value; + this.textBufferView.setTruncate(value); + this.requestRender(); + } + } + onResize(width, height) { + this.textBufferView.setViewport(this._scrollX, this._scrollY, width, height); + this.yogaNode.markDirty(); + this.requestRender(); + this.emit("line-info-change"); + } + refreshLocalSelection() { + if (this.lastLocalSelection) { + return this.updateLocalSelection(this.lastLocalSelection); + } + return false; + } + updateLocalSelection(localSelection) { + if (!localSelection?.isActive) { + this.textBufferView.resetLocalSelection(); + return true; + } + return this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg); + } + updateTextInfo() { + if (this.lastLocalSelection) { + this.updateLocalSelection(this.lastLocalSelection); + } + this.yogaNode.markDirty(); + this.requestRender(); + this.emit("line-info-change"); + } + setupMeasureFunc() { + const measureFunc = (width, widthMode, height, heightMode) => { + let effectiveWidth; + if (widthMode === 0 /* Undefined */ || isNaN(width)) { + effectiveWidth = 0; + } else { + effectiveWidth = width; + } + const effectiveHeight = isNaN(height) ? 1 : height; + const measureResult = this.textBufferView.measureForDimensions(Math.floor(effectiveWidth), Math.floor(effectiveHeight)); + const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1; + const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1; + if (widthMode === 2 /* AtMost */ && this._positionType !== "absolute") { + return { + width: Math.min(effectiveWidth, measuredWidth), + height: Math.min(effectiveHeight, measuredHeight) + }; + } + return { + width: measuredWidth, + height: measuredHeight + }; + }; + this.yogaNode.setMeasureFunc(measureFunc); + } + shouldStartSelection(x, y) { + if (!this.selectable) + return false; + const localX = x - this.x; + const localY = y - this.y; + return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height; + } + onSelectionChanged(selection) { + const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y); + this.lastLocalSelection = localSelection; + let changed; + if (!localSelection?.isActive) { + this.textBufferView.resetLocalSelection(); + changed = true; + } else if (selection?.isStart) { + changed = this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg); + } else { + changed = this.textBufferView.updateLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg); + } + if (changed) { + this.requestRender(); + } + return this.hasSelection(); + } + getSelectedText() { + return this.textBufferView.getSelectedText(); + } + hasSelection() { + return this.textBufferView.hasSelection(); + } + getSelection() { + return this.textBufferView.getSelection(); + } + render(buffer, deltaTime) { + if (!this.visible) + return; + const screenX = this._screenX; + const screenY = this._screenY; + this.markClean(); + this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num); + this.renderSelf(buffer); + if (this.buffered && this.frameBuffer) { + buffer.drawFrameBuffer(screenX, screenY, this.frameBuffer); + } + } + renderSelf(buffer) { + if (this.textBuffer.ptr) { + buffer.drawTextBuffer(this.textBufferView, this._screenX, this._screenY); + } + } + destroy() { + if (this.isDestroyed) + return; + this.textBuffer.setSyntaxStyle(null); + this._textBufferSyntaxStyle.destroy(); + this.textBufferView.destroy(); + this.textBuffer.destroy(); + super.destroy(); + } + onFgChanged(newColor) {} + onBgChanged(newColor) {} + onAttributesChanged(newAttributes) {} +} + +// src/renderables/Code.ts +class CodeRenderable extends TextBufferRenderable { + _content; + _filetype; + _syntaxStyle; + _isHighlighting = false; + _treeSitterClient; + _highlightsDirty = false; + _highlightSnapshotId = 0; + _conceal; + _drawUnstyledText; + _shouldRenderTextBuffer = true; + _streaming; + _initialStyledText; + _hadInitialContent = false; + _lastHighlights = []; + _baseHighlight; + _onHighlight; + _onChunks; + _highlightingPromise = Promise.resolve(); + _renderedLineSources; + _mappedLineInfo; + _contentDefaultOptions = { + content: "", + conceal: true, + drawUnstyledText: true, + streaming: false + }; + constructor(ctx, options) { + super(ctx, options); + this._content = options.content ?? this._contentDefaultOptions.content; + this._filetype = options.filetype; + this._syntaxStyle = options.syntaxStyle; + this._treeSitterClient = options.treeSitterClient ?? getTreeSitterClient(); + this._conceal = options.conceal ?? this._contentDefaultOptions.conceal; + this._drawUnstyledText = options.drawUnstyledText ?? this._contentDefaultOptions.drawUnstyledText; + this._streaming = options.streaming ?? this._contentDefaultOptions.streaming; + this._initialStyledText = options.initialStyledText; + this._baseHighlight = options.baseHighlight; + this._onHighlight = options.onHighlight; + this._onChunks = options.onChunks; + if (this._content.length > 0) { + if (this._initialStyledText && this._drawUnstyledText) { + this.textBuffer.setStyledText(this._initialStyledText); + } else { + this.textBuffer.setText(this._content); + } + this.updateTextInfo(); + this._shouldRenderTextBuffer = this._drawUnstyledText || !this._filetype; + } + this._highlightsDirty = this._content.length > 0; + } + get content() { + return this._content; + } + set content(value) { + if (this._content !== value) { + this._content = value; + this._highlightsDirty = true; + this._highlightSnapshotId++; + if (this._streaming && this._filetype && !this._drawUnstyledText) { + this.requestRender(); + return; + } + if (this._initialStyledText && this._drawUnstyledText) { + this.textBuffer.setStyledText(this._initialStyledText); + } else { + this.textBuffer.setText(value); + } + this.setRenderedLineSources(undefined); + this.updateTextInfo(); + } + } + get lineInfo() { + if (!this._renderedLineSources) + return super.lineInfo; + if (this._mappedLineInfo) + return this._mappedLineInfo; + const lineInfo = super.lineInfo; + const renderedLineSources = this._renderedLineSources; + this._mappedLineInfo = { + ...lineInfo, + lineSources: lineInfo.lineSources.map((line) => renderedLineSources[line] ?? line) + }; + return this._mappedLineInfo; + } + get wrapMode() { + return super.wrapMode; + } + set wrapMode(value) { + if (super.wrapMode !== value) { + this._mappedLineInfo = undefined; + super.wrapMode = value; + } + } + onResize(width, height) { + this._mappedLineInfo = undefined; + super.onResize(width, height); + } + updateTextInfo() { + this._mappedLineInfo = undefined; + super.updateTextInfo(); + } + get filetype() { + return this._filetype; + } + set filetype(value) { + if (this._filetype !== value) { + this._filetype = value; + this._highlightsDirty = true; + } + } + get syntaxStyle() { + return this._syntaxStyle; + } + set syntaxStyle(value) { + if (this._syntaxStyle !== value) { + this._syntaxStyle = value; + this._highlightsDirty = true; + } + } + get conceal() { + return this._conceal; + } + set conceal(value) { + if (this._conceal !== value) { + this._conceal = value; + this._highlightsDirty = true; + } + } + get drawUnstyledText() { + return this._drawUnstyledText; + } + set drawUnstyledText(value) { + if (this._drawUnstyledText !== value) { + this._drawUnstyledText = value; + this._highlightsDirty = true; + } + } + get streaming() { + return this._streaming; + } + set initialStyledText(value) { + if (this._initialStyledText !== value) { + this._initialStyledText = value; + this._highlightsDirty = true; + } + } + set streaming(value) { + if (this._streaming !== value) { + this._streaming = value; + this._hadInitialContent = false; + this._lastHighlights = []; + this._highlightsDirty = true; + } + } + get treeSitterClient() { + return this._treeSitterClient; + } + set treeSitterClient(value) { + if (this._treeSitterClient !== value) { + this._treeSitterClient = value; + this._highlightsDirty = true; + } + } + get onHighlight() { + return this._onHighlight; + } + get baseHighlight() { + return this._baseHighlight; + } + set baseHighlight(value) { + if (this._baseHighlight !== value) { + this._baseHighlight = value; + this._highlightsDirty = true; + } + } + set onHighlight(value) { + if (this._onHighlight !== value) { + this._onHighlight = value; + this._highlightsDirty = true; + } + } + get onChunks() { + return this._onChunks; + } + set onChunks(value) { + if (this._onChunks !== value) { + this._onChunks = value; + this._highlightsDirty = true; + } + } + get isHighlighting() { + return this._isHighlighting; + } + get highlightingDone() { + return this._highlightingPromise; + } + async transformChunks(chunks, context) { + if (!this._onChunks) + return chunks; + const modified = await this._onChunks(chunks, context); + return modified ?? chunks; + } + ensureVisibleTextBeforeHighlight() { + if (this.isDestroyed) + return; + const content = this._content; + if (!this._filetype) { + this._shouldRenderTextBuffer = true; + return; + } + const isInitialContent = this._streaming && !this._hadInitialContent; + const shouldDrawUnstyledNow = this._streaming ? isInitialContent && this._drawUnstyledText : this._drawUnstyledText; + if (this._streaming && !isInitialContent) { + this._shouldRenderTextBuffer = true; + } else if (shouldDrawUnstyledNow) { + if (this._initialStyledText) { + this.textBuffer.setStyledText(this._initialStyledText); + } else { + this.textBuffer.setText(content); + } + this.setRenderedLineSources(undefined); + this._shouldRenderTextBuffer = true; + } else { + this._shouldRenderTextBuffer = false; + } + } + async startHighlight() { + const content = this._content; + const filetype = this._filetype; + const snapshotId = ++this._highlightSnapshotId; + if (!filetype) + return; + const isInitialContent = this._streaming && !this._hadInitialContent; + if (isInitialContent) { + this._hadInitialContent = true; + } + this._isHighlighting = true; + try { + const result = await this._treeSitterClient.highlightOnce(content, filetype); + if (snapshotId !== this._highlightSnapshotId) { + this.requestRender(); + return; + } + if (this.isDestroyed) + return; + let highlights = result.highlights ?? []; + if (this._onHighlight && highlights.length >= 0) { + const context = { + content, + filetype, + syntaxStyle: this._syntaxStyle + }; + const modified = await this._onHighlight(highlights, context); + if (modified !== undefined) { + highlights = modified; + } + } + if (snapshotId !== this._highlightSnapshotId) { + this.requestRender(); + return; + } + if (this.isDestroyed) + return; + if (highlights.length > 0) { + if (this._streaming) { + this._lastHighlights = highlights; + } + } + if (highlights.length > 0 || this._onChunks || this._baseHighlight) { + const context = { + content, + filetype, + syntaxStyle: this._syntaxStyle, + highlights + }; + let chunks = treeSitterToTextChunks(content, highlights, this._syntaxStyle, { + enabled: this._conceal, + baseHighlight: this._baseHighlight + }); + const renderedLineSources = this._onChunks ? undefined : this.getConcealLinesSourceMap(content, highlights); + chunks = await this.transformChunks(chunks, context); + if (snapshotId !== this._highlightSnapshotId) { + this.requestRender(); + return; + } + if (this.isDestroyed) + return; + const styledText = new StyledText(chunks); + this.textBuffer.setStyledText(styledText); + this.setRenderedLineSources(renderedLineSources); + } else { + this.textBuffer.setText(content); + this.setRenderedLineSources(undefined); + } + this._shouldRenderTextBuffer = true; + this._isHighlighting = false; + this._highlightsDirty = false; + this.updateTextInfo(); + this.requestRender(); + } catch (error) { + if (snapshotId !== this._highlightSnapshotId) { + this.requestRender(); + return; + } + console.warn("Code highlighting failed, falling back to plain text:", error); + if (this.isDestroyed) + return; + this.textBuffer.setText(content); + this.setRenderedLineSources(undefined); + this._shouldRenderTextBuffer = true; + this._isHighlighting = false; + this._highlightsDirty = false; + this.updateTextInfo(); + this.requestRender(); + } + } + setRenderedLineSources(lineSources) { + this._renderedLineSources = lineSources; + this._mappedLineInfo = undefined; + } + static isIdentityLineSources(lineSources) { + for (let i = 0;i < lineSources.length; i++) { + if (lineSources[i] !== i) + return false; + } + return true; + } + static getMergedConcealLineRanges(highlights) { + const ranges = []; + for (const highlight of highlights) { + const meta = highlight[3]; + if (meta?.concealLines === undefined) + continue; + const group = highlight[2]; + const isEmptyConceal = meta.conceal === "" || meta.conceal === undefined && (group === "conceal" || group.startsWith("conceal.")); + if (isEmptyConceal) { + ranges.push([highlight[0], highlight[1]]); + } + } + if (ranges.length <= 1) + return ranges; + ranges.sort((a, b) => a[0] - b[0]); + let writeIndex = 0; + for (let i = 1;i < ranges.length; i++) { + const current = ranges[writeIndex]; + const next = ranges[i]; + if (next[0] <= current[1]) { + current[1] = Math.max(current[1], next[1]); + } else { + writeIndex++; + ranges[writeIndex] = next; + } + } + ranges.length = writeIndex + 1; + return ranges; + } + getConcealLinesSourceMap(content, highlights) { + if (!this._conceal || content.length === 0) + return; + const concealLineRanges = CodeRenderable.getMergedConcealLineRanges(highlights); + if (concealLineRanges.length === 0) + return; + const lineSources = []; + let sourceLine = 0; + let lineStart = 0; + let rangeIndex = 0; + let currentRenderedLineHasText = false; + const setCurrentRenderedLineSource = (line, hasText) => { + if (lineSources.length === 0) { + lineSources.push(line); + } else if (!currentRenderedLineHasText) { + lineSources[lineSources.length - 1] = line; + } + if (hasText) + currentRenderedLineHasText = true; + }; + while (lineStart <= content.length) { + const newlineOffset = content.indexOf(` +`, lineStart); + const lineEnd = newlineOffset === -1 ? content.length : newlineOffset; + while (rangeIndex < concealLineRanges.length && concealLineRanges[rangeIndex][1] <= lineStart) { + rangeIndex++; + } + const range = concealLineRanges[rangeIndex]; + const fullyConcealed = !!range && lineEnd > lineStart && range[0] <= lineStart && range[1] >= lineEnd; + const lineBreakConcealed = newlineOffset !== -1 && !!range && range[0] <= newlineOffset && range[1] >= newlineOffset; + if (!fullyConcealed || !lineBreakConcealed) { + const hasText = lineEnd > lineStart && !fullyConcealed; + if (hasText || newlineOffset !== -1 || !fullyConcealed) { + setCurrentRenderedLineSource(sourceLine, hasText); + } + if (newlineOffset !== -1 && !lineBreakConcealed) { + lineSources.push(sourceLine + 1); + currentRenderedLineHasText = false; + } + } + sourceLine++; + if (newlineOffset === -1) + break; + lineStart = newlineOffset + 1; + } + if (lineSources.length === 0 || CodeRenderable.isIdentityLineSources(lineSources)) + return; + return lineSources; + } + getLineHighlights(lineIdx) { + return this.textBuffer.getLineHighlights(lineIdx); + } + renderSelf(buffer) { + if (this._highlightsDirty) { + if (this.isDestroyed) + return; + if (this._content.length === 0) { + this._shouldRenderTextBuffer = false; + this._highlightsDirty = false; + } else if (!this._filetype) { + this._shouldRenderTextBuffer = true; + this._highlightsDirty = false; + } else { + this.ensureVisibleTextBeforeHighlight(); + this._highlightsDirty = false; + this._highlightingPromise = this.startHighlight(); + } + } + if (!this._shouldRenderTextBuffer) + return; + super.renderSelf(buffer); + } +} + +// src/renderables/TextNode.ts +var BrandedTextNodeRenderable = Symbol.for("@opentui/core/TextNodeRenderable"); +function isTextNodeRenderable(obj) { + return !!obj?.[BrandedTextNodeRenderable]; +} +function styledTextToTextNodes(styledText) { + return styledText.chunks.map((chunk) => { + const node = new TextNodeRenderable({ + fg: chunk.fg, + bg: chunk.bg, + attributes: chunk.attributes, + link: chunk.link + }); + node.add(chunk.text); + return node; + }); +} + +class TextNodeRenderable extends BaseRenderable { + [BrandedTextNodeRenderable] = true; + _fg; + _bg; + _attributes; + _link; + _children = []; + parent = null; + constructor(options) { + super(options); + this._fg = options.fg ? parseColor(options.fg) : undefined; + this._bg = options.bg ? parseColor(options.bg) : undefined; + this._attributes = options.attributes ?? 0; + this._link = options.link; + } + get children() { + return this._children; + } + set children(children) { + this._children = children; + this.requestRender(); + } + requestRender() { + this.markDirty(); + this.parent?.requestRender(); + } + add(obj, index) { + if (typeof obj === "string") { + if (index !== undefined) { + this._children.splice(index, 0, obj); + this.requestRender(); + return index; + } + const insertIndex = this._children.length; + this._children.push(obj); + this.requestRender(); + return insertIndex; + } + if (isTextNodeRenderable(obj)) { + if (index !== undefined) { + this._children.splice(index, 0, obj); + obj.parent = this; + this.requestRender(); + return index; + } + const insertIndex = this._children.length; + this._children.push(obj); + obj.parent = this; + this.requestRender(); + return insertIndex; + } + if (isStyledText(obj)) { + const textNodes = styledTextToTextNodes(obj); + if (index !== undefined) { + this._children.splice(index, 0, ...textNodes); + textNodes.forEach((node) => node.parent = this); + this.requestRender(); + return index; + } + const insertIndex = this._children.length; + this._children.push(...textNodes); + textNodes.forEach((node) => node.parent = this); + this.requestRender(); + return insertIndex; + } + throw new Error("TextNodeRenderable only accepts strings, TextNodeRenderable instances, or StyledText instances"); + } + replace(obj, index) { + this._children[index] = obj; + if (typeof obj !== "string") { + obj.parent = this; + } + this.requestRender(); + } + insertBefore(child, anchorNode) { + if (!anchorNode || !isTextNodeRenderable(anchorNode)) { + throw new Error("Anchor must be a TextNodeRenderable"); + } + const anchorIndex = this._children.indexOf(anchorNode); + if (anchorIndex === -1) { + throw new Error("Anchor node not found in children"); + } + if (typeof child === "string") { + this._children.splice(anchorIndex, 0, child); + } else if (isTextNodeRenderable(child)) { + this._children.splice(anchorIndex, 0, child); + child.parent = this; + } else if (child instanceof StyledText) { + const textNodes = styledTextToTextNodes(child); + this._children.splice(anchorIndex, 0, ...textNodes); + textNodes.forEach((node) => node.parent = this); + } else { + throw new Error("Child must be a string, TextNodeRenderable, or StyledText instance"); + } + this.requestRender(); + return this; + } + remove(id) { + const childIndex = this.getRenderableIndex(id); + if (childIndex === -1) { + throw new Error("Child not found in children"); + } + const child = this._children[childIndex]; + this._children.splice(childIndex, 1); + child.parent = null; + this.requestRender(); + return this; + } + clear() { + this._children = []; + this.requestRender(); + } + mergeStyles(parentStyle) { + return { + fg: this._fg ?? parentStyle.fg, + bg: this._bg ?? parentStyle.bg, + attributes: this._attributes | parentStyle.attributes, + link: this._link ?? parentStyle.link + }; + } + gatherWithInheritedStyle(parentStyle = { + fg: undefined, + bg: undefined, + attributes: 0 + }) { + const currentStyle = this.mergeStyles(parentStyle); + const chunks = []; + for (const child of this._children) { + if (typeof child === "string") { + chunks.push({ + __isChunk: true, + text: child, + fg: currentStyle.fg, + bg: currentStyle.bg, + attributes: currentStyle.attributes, + link: currentStyle.link + }); + } else { + const childChunks = child.gatherWithInheritedStyle(currentStyle); + chunks.push(...childChunks); + } + } + this.markClean(); + return chunks; + } + static fromString(text, options = {}) { + const node = new TextNodeRenderable(options); + node.add(text); + return node; + } + static fromNodes(nodes, options = {}) { + const node = new TextNodeRenderable(options); + for (const childNode of nodes) { + node.add(childNode); + } + return node; + } + toChunks(parentStyle = { + fg: undefined, + bg: undefined, + attributes: 0 + }) { + return this.gatherWithInheritedStyle(parentStyle); + } + getChildren() { + return this._children.filter((child) => typeof child !== "string"); + } + getChildrenCount() { + return this._children.length; + } + getRenderable(id) { + return this._children.find((child) => typeof child !== "string" && child.id === id); + } + getRenderableIndex(id) { + return this._children.findIndex((child) => isTextNodeRenderable(child) && child.id === id); + } + get fg() { + return this._fg; + } + set fg(fg) { + if (!fg) { + this._fg = undefined; + this.requestRender(); + return; + } + this._fg = parseColor(fg); + this.requestRender(); + } + set bg(bg) { + if (!bg) { + this._bg = undefined; + this.requestRender(); + return; + } + this._bg = parseColor(bg); + this.requestRender(); + } + get bg() { + return this._bg; + } + set attributes(attributes) { + this._attributes = attributes; + this.requestRender(); + } + get attributes() { + return this._attributes; + } + set link(link) { + this._link = link; + this.requestRender(); + } + get link() { + return this._link; + } + findDescendantById(id) { + return; + } +} + +class RootTextNodeRenderable extends TextNodeRenderable { + ctx; + textParent; + constructor(ctx, options, textParent) { + super(options); + this.ctx = ctx; + this.textParent = textParent; + } + requestRender() { + this.markDirty(); + this.ctx.requestRender(); + } +} + +// src/renderables/Text.ts +class TextRenderable extends TextBufferRenderable { + _text; + _hasManualStyledText = false; + rootTextNode; + _contentDefaultOptions = { + content: "" + }; + constructor(ctx, options) { + super(ctx, options); + const content = options.content ?? this._contentDefaultOptions.content; + const styledText = typeof content === "string" ? stringToStyledText(content) : content; + this._text = styledText; + this._hasManualStyledText = options.content !== undefined && content !== ""; + this.rootTextNode = new RootTextNodeRenderable(ctx, { + id: `${this.id}-root`, + fg: this._defaultFg, + bg: this._defaultBg, + attributes: this._defaultAttributes + }, this); + this.updateTextBuffer(styledText); + } + updateTextBuffer(styledText) { + this.textBuffer.setStyledText(styledText); + this.clearChunks(styledText); + } + clearChunks(styledText) {} + get content() { + return this._text; + } + get chunks() { + return this._text.chunks; + } + get textNode() { + return this.rootTextNode; + } + set content(value) { + this._hasManualStyledText = true; + const styledText = typeof value === "string" ? stringToStyledText(value) : value; + if (this._text !== styledText) { + this._text = styledText; + this.updateTextBuffer(styledText); + this.updateTextInfo(); + } + } + updateTextFromNodes() { + if (this.rootTextNode.isDirty && !this._hasManualStyledText) { + const chunks = this.rootTextNode.gatherWithInheritedStyle({ + fg: this._defaultFg, + bg: this._defaultBg, + attributes: this._defaultAttributes, + link: undefined + }); + this.textBuffer.setStyledText(new StyledText(chunks)); + this.refreshLocalSelection(); + this.yogaNode.markDirty(); + } + } + add(obj, index) { + return this.rootTextNode.add(obj, index); + } + remove(id) { + this.rootTextNode.remove(id); + } + insertBefore(obj, anchor) { + this.rootTextNode.insertBefore(obj, anchor); + return this.rootTextNode.children.indexOf(obj); + } + getTextChildren() { + return this.rootTextNode.getChildren(); + } + clear() { + this.rootTextNode.clear(); + const emptyStyledText = stringToStyledText(""); + this._text = emptyStyledText; + this.updateTextBuffer(emptyStyledText); + this.updateTextInfo(); + this.requestRender(); + } + onLifecyclePass = () => { + this.updateTextFromNodes(); + }; + onFgChanged(newColor) { + this.rootTextNode.fg = newColor; + } + onBgChanged(newColor) { + this.rootTextNode.bg = newColor; + } + onAttributesChanged(newAttributes) { + this.rootTextNode.attributes = newAttributes; + } + destroy() { + this.rootTextNode.children.length = 0; + super.destroy(); + } +} + +// src/NativeSpanFeed.ts +function toNumber(value) { + return typeof value === "bigint" ? Number(value) : value; +} +var canThrowAcrossNativeCallback = typeof process !== "undefined" && typeof process.versions === "object" && process.versions !== null && typeof process.versions.bun === "string"; + +class NativeSpanFeed { + static create(options) { + const lib = resolveRenderLib(); + const streamPtr = lib.createNativeSpanFeed(options); + const stream = new NativeSpanFeed(streamPtr); + lib.registerNativeSpanFeedStream(streamPtr, stream.eventHandler); + const status = lib.attachNativeSpanFeed(streamPtr); + if (status !== 0) { + lib.unregisterNativeSpanFeedStream(streamPtr); + lib.destroyNativeSpanFeed(streamPtr); + throw new Error(`Failed to attach stream: ${status}`); + } + return stream; + } + static attach(streamPtr, _options) { + const lib = resolveRenderLib(); + const stream = new NativeSpanFeed(streamPtr); + lib.registerNativeSpanFeedStream(streamPtr, stream.eventHandler); + const status = lib.attachNativeSpanFeed(streamPtr); + if (status !== 0) { + lib.unregisterNativeSpanFeedStream(streamPtr); + throw new Error(`Failed to attach stream: ${status}`); + } + return stream; + } + streamPtr; + lib = resolveRenderLib(); + eventHandler; + chunkMap = new Map; + chunkSizes = new Map; + dataHandlers = new Set; + errorHandlers = new Set; + drainBuffer = null; + stateBuffer = null; + closed = false; + destroyed = false; + draining = false; + pendingDataAvailable = false; + pendingClose = false; + closing = false; + pendingAsyncHandlers = 0; + inCallback = false; + closeQueued = false; + idleResolvers = []; + pendingHandlerError = null; + pendingHandlerErrorQueued = false; + constructor(streamPtr) { + this.streamPtr = streamPtr; + this.eventHandler = (eventId, arg0, arg1) => { + this.handleEvent(eventId, arg0, arg1); + }; + this.ensureDrainBuffer(); + } + ensureDrainBuffer() { + if (this.drainBuffer) + return; + const capacity = 256; + this.drainBuffer = new Uint8Array(capacity * SpanInfoStruct.size); + } + onData(handler) { + this.dataHandlers.add(handler); + if (this.pendingDataAvailable) { + this.pendingDataAvailable = false; + this.drainAll(); + } + return () => this.dataHandlers.delete(handler); + } + onError(handler) { + this.errorHandlers.add(handler); + return () => this.errorHandlers.delete(handler); + } + hasPinnedChunks() { + if (!this.stateBuffer) + return false; + for (const refcount of this.stateBuffer) { + if (refcount > 0) + return true; + } + return false; + } + isBackpressured() { + return this.pendingAsyncHandlers > 0 || this.pendingDataAvailable || this.hasPinnedChunks(); + } + close() { + if (this.destroyed) + return; + if (this.inCallback || this.draining || this.pendingAsyncHandlers > 0) { + this.pendingClose = true; + if (!this.closeQueued) { + this.closeQueued = true; + queueMicrotask(() => { + this.closeQueued = false; + this.processPendingClose(); + }); + } + return; + } + this.performClose(); + } + processPendingClose() { + if (!this.pendingClose || this.destroyed) + return; + if (this.inCallback || this.draining || this.pendingAsyncHandlers > 0) + return; + this.pendingClose = false; + this.performClose(); + this.resolveIdleIfNeeded(); + } + performClose() { + if (this.closing) + return; + this.closing = true; + if (!this.closed) { + const status = this.lib.streamClose(this.streamPtr); + if (status !== 0) { + this.closing = false; + return; + } + this.closed = true; + } + this.finalizeDestroy(); + } + finalizeDestroy() { + if (this.destroyed) + return; + this.lib.unregisterNativeSpanFeedStream(this.streamPtr); + this.lib.destroyNativeSpanFeed(this.streamPtr); + this.destroyed = true; + this.chunkMap.clear(); + this.chunkSizes.clear(); + this.stateBuffer = null; + this.drainBuffer = null; + this.dataHandlers.clear(); + this.errorHandlers.clear(); + this.pendingDataAvailable = false; + this.resolveIdleIfNeeded(); + } + isIdle() { + return !this.inCallback && !this.draining && this.pendingAsyncHandlers === 0 && !this.pendingDataAvailable && !this.hasPinnedChunks(); + } + resolveIdleIfNeeded() { + if (!this.isIdle()) + return; + const resolvers = this.idleResolvers.splice(0); + for (const resolve of resolvers) { + resolve(); + } + } + idle() { + if (this.isIdle()) + return Promise.resolve(); + return new Promise((resolve) => { + this.idleResolvers.push(resolve); + }); + } + handleEvent(eventId, arg0, arg1) { + this.inCallback = true; + try { + switch (eventId) { + case 8 /* StateBuffer */: { + const len = toNumber(arg1); + if (len > 0 && arg0) { + const buffer = toArrayBuffer(arg0, 0, len); + this.stateBuffer = new Uint8Array(buffer); + } + break; + } + case 7 /* DataAvailable */: { + if (this.closing) + break; + if (this.dataHandlers.size === 0) { + this.pendingDataAvailable = true; + break; + } + this.drainAll(); + break; + } + case 2 /* ChunkAdded */: { + const chunkLen = toNumber(arg1); + if (chunkLen > 0 && arg0) { + if (!this.chunkMap.has(arg0)) { + const buffer = toArrayBuffer(arg0, 0, chunkLen); + this.chunkMap.set(arg0, buffer); + } + this.chunkSizes.set(arg0, chunkLen); + } + break; + } + case 6 /* Error */: { + const code = toNumber(arg0); + for (const handler of this.errorHandlers) + handler(code); + break; + } + case 5 /* Closed */: { + this.closed = true; + break; + } + default: + break; + } + } finally { + this.inCallback = false; + this.resolveIdleIfNeeded(); + } + } + decrementRefcount(chunkIndex) { + if (this.stateBuffer && chunkIndex < this.stateBuffer.length) { + const prev = this.stateBuffer[chunkIndex]; + this.stateBuffer[chunkIndex] = prev > 0 ? prev - 1 : 0; + } + } + queuePendingHandlerError(error) { + this.pendingHandlerError ??= error; + if (this.pendingHandlerErrorQueued) + return; + this.pendingHandlerErrorQueued = true; + queueMicrotask(() => { + this.pendingHandlerErrorQueued = false; + if (this.pendingHandlerError === null) + return; + const pendingError = this.pendingHandlerError; + this.pendingHandlerError = null; + throw pendingError; + }); + } + throwPendingHandlerError() { + if (this.pendingHandlerError === null) + return; + const pendingError = this.pendingHandlerError; + this.pendingHandlerError = null; + throw pendingError; + } + drainOnce() { + if (!this.drainBuffer || this.draining || this.pendingClose) + return 0; + const capacity = Math.floor(this.drainBuffer.byteLength / SpanInfoStruct.size); + if (capacity === 0) + return 0; + const count = this.lib.streamDrainSpans(this.streamPtr, this.drainBuffer, capacity); + if (count === 0) + return 0; + this.draining = true; + const spans = SpanInfoStruct.unpackList(this.drainBuffer.buffer, count); + let firstError = null; + try { + for (const span of spans) { + if (span.len === 0) + continue; + let buffer = this.chunkMap.get(span.chunkPtr); + if (!buffer) { + const size = this.chunkSizes.get(span.chunkPtr); + if (!size) + continue; + buffer = toArrayBuffer(span.chunkPtr, 0, size); + this.chunkMap.set(span.chunkPtr, buffer); + } + if (span.offset + span.len > buffer.byteLength) + continue; + const slice = new Uint8Array(buffer, span.offset, span.len); + let asyncResults = null; + for (const handler of this.dataHandlers) { + try { + const result = handler(slice); + if (result && typeof result.then === "function") { + asyncResults ??= []; + asyncResults.push(result); + } + } catch (e) { + firstError ??= e; + } + } + const shouldStopAfterThisSpan = this.pendingClose; + if (asyncResults) { + const chunkIndex = span.chunkIndex; + this.pendingAsyncHandlers += 1; + Promise.allSettled(asyncResults).then(() => { + this.decrementRefcount(chunkIndex); + this.pendingAsyncHandlers -= 1; + this.processPendingClose(); + this.resolveIdleIfNeeded(); + }); + } else { + this.decrementRefcount(span.chunkIndex); + } + if (shouldStopAfterThisSpan) + break; + } + } finally { + this.draining = false; + this.resolveIdleIfNeeded(); + } + if (firstError) { + if (!this.inCallback || canThrowAcrossNativeCallback) { + throw firstError; + } + this.queuePendingHandlerError(firstError); + } + return count; + } + drainAll() { + let count = this.drainOnce(); + while (count > 0) { + count = this.drainOnce(); + } + if (!this.inCallback) { + this.throwPendingHandlerError(); + } + } +} + +// src/console.ts +import { EventEmitter as EventEmitter4 } from "events"; +import { Console } from "node:console"; +import fs from "node:fs"; +import path from "node:path"; +import util2 from "node:util"; + +// src/lib/output.capture.ts +import { Writable } from "stream"; +import { EventEmitter as EventEmitter3 } from "events"; + +class Capture extends EventEmitter3 { + output = []; + constructor() { + super(); + } + get size() { + return this.output.length; + } + write(stream, data) { + this.output.push({ stream, output: data }); + this.emit("write", stream, data); + } + claimOutput() { + const output = this.output.map((o) => o.output).join(""); + this.clear(); + return output; + } + clear() { + this.output = []; + } +} + +class CapturedWritableStream extends Writable { + stream; + capture; + isTTY = true; + columns = process.stdout.columns || 80; + rows = process.stdout.rows || 24; + constructor(stream, capture) { + super(); + this.stream = stream; + this.capture = capture; + } + _write(chunk, encoding, callback) { + const data = chunk.toString(); + this.capture.write(this.stream, data); + callback(); + } + getColorDepth() { + return process.stdout.getColorDepth?.() || 8; + } +} + +// src/lib/keybinding.internal.ts +var defaultKeyAliases = { + enter: "return", + esc: "escape", + kp0: "0", + kp1: "1", + kp2: "2", + kp3: "3", + kp4: "4", + kp5: "5", + kp6: "6", + kp7: "7", + kp8: "8", + kp9: "9", + kpdecimal: ".", + kpdivide: "/", + kpmultiply: "*", + kpminus: "-", + kpplus: "+", + kpenter: "enter", + kpequal: "=", + kpseparator: ",", + kpleft: "left", + kpright: "right", + kpup: "up", + kpdown: "down", + kppageup: "pageup", + kppagedown: "pagedown", + kphome: "home", + kpend: "end", + kpinsert: "insert", + kpdelete: "delete" +}; +function mergeKeyAliases(defaults, custom) { + return { ...defaults, ...custom }; +} +function mergeKeyBindings(defaults, custom) { + const map = new Map; + for (const binding of defaults) { + const key = getKeyBindingKey(binding); + map.set(key, binding); + } + for (const binding of custom) { + const key = getKeyBindingKey(binding); + map.set(key, binding); + } + return Array.from(map.values()); +} +function getKeyBindingKey(binding) { + return `${binding.name}:${binding.ctrl ? 1 : 0}:${binding.shift ? 1 : 0}:${binding.meta ? 1 : 0}:${binding.super ? 1 : 0}`; +} +function getBaseCodeKeyName(baseCode) { + if (baseCode === undefined || baseCode < 32 || baseCode === 127) { + return; + } + try { + const name = String.fromCodePoint(baseCode); + if (name.length === 1 && name >= "A" && name <= "Z") { + return name.toLowerCase(); + } + return name; + } catch { + return; + } +} +function getKeyBindingKeys(binding) { + const names = new Set([binding.name]); + const baseCodeName = getBaseCodeKeyName(binding.baseCode); + if (baseCodeName) { + names.add(baseCodeName); + } + return [...names].map((name) => getKeyBindingKey({ ...binding, name })); +} +function getKeyBindingAction(map, binding) { + for (const key of getKeyBindingKeys(binding)) { + const action = map.get(key); + if (action !== undefined) { + return action; + } + } + return; +} +function matchesKeyBinding(binding, match) { + const matchKey = getKeyBindingKey(match); + return getKeyBindingKeys(binding).includes(matchKey); +} +function buildKeyBindingsMap(bindings, aliasMap) { + const map = new Map; + const aliases = aliasMap || {}; + for (const binding of bindings) { + const key = getKeyBindingKey(binding); + map.set(key, binding.action); + } + for (const binding of bindings) { + const normalizedName = aliases[binding.name] || binding.name; + if (normalizedName !== binding.name) { + const aliasedKey = getKeyBindingKey({ ...binding, name: normalizedName }); + map.set(aliasedKey, binding.action); + } + } + return map; +} +function keyBindingToString(binding) { + const parts = []; + if (binding.ctrl) + parts.push("ctrl"); + if (binding.shift) + parts.push("shift"); + if (binding.meta) + parts.push("meta"); + if (binding.super) + parts.push("super"); + parts.push(binding.name); + return parts.join("+"); +} + +// src/console.ts +function getCallerInfo() { + const err = new Error; + const stackLines = err.stack?.split(` +`).slice(5) || []; + if (!stackLines.length) + return null; + const callerLine = stackLines[0].trim(); + const regex = /at\s+(?:([\w$.<>]+)\s+\()?((?:\/|[A-Za-z]:\\)[^:]+):(\d+):(\d+)\)?/; + const match = callerLine.match(regex); + if (!match) + return null; + const functionName = match[1] || ""; + const fullPath = match[2]; + const fileName = fullPath.split(/[\\/]/).pop() || ""; + const lineNumber = parseInt(match[3], 10) || 0; + const columnNumber = parseInt(match[4], 10) || 0; + return { functionName, fullPath, fileName, lineNumber, columnNumber }; +} +var capture = singleton("ConsoleCapture", () => new Capture); +registerEnvVar({ + name: "OTUI_USE_CONSOLE", + description: "Whether to use the console. Will not capture console output if set to false.", + type: "boolean", + default: true +}); +registerEnvVar({ + name: "SHOW_CONSOLE", + description: "Show the console at startup if set to true.", + type: "boolean", + default: false +}); + +class TerminalConsoleCache extends EventEmitter4 { + _cachedLogs = []; + MAX_CACHE_SIZE = 1000; + _collectCallerInfo = false; + _cachingEnabled = true; + _originalConsole = null; + get cachedLogs() { + return this._cachedLogs; + } + constructor() { + super(); + } + activate() { + if (!this._originalConsole) { + this._originalConsole = global.console; + } + this.setupConsoleCapture(); + this.overrideConsoleMethods(); + } + setupConsoleCapture() { + if (!env.OTUI_USE_CONSOLE) + return; + const mockStdout = new CapturedWritableStream("stdout", capture); + const mockStderr = new CapturedWritableStream("stderr", capture); + global.console = new Console({ + stdout: mockStdout, + stderr: mockStderr, + colorMode: true, + inspectOptions: { + compact: false, + breakLength: 80, + depth: 2 + } + }); + } + overrideConsoleMethods() { + console.log = (...args) => { + this.appendToConsole("LOG" /* LOG */, ...args); + }; + console.info = (...args) => { + this.appendToConsole("INFO" /* INFO */, ...args); + }; + console.warn = (...args) => { + this.appendToConsole("WARN" /* WARN */, ...args); + }; + console.error = (...args) => { + this.appendToConsole("ERROR" /* ERROR */, ...args); + }; + console.debug = (...args) => { + this.appendToConsole("DEBUG" /* DEBUG */, ...args); + }; + if (typeof console.timeStamp !== "function") { + console.timeStamp = () => {}; + } + } + setCollectCallerInfo(enabled) { + this._collectCallerInfo = enabled; + } + clearConsole() { + this._cachedLogs = []; + } + setCachingEnabled(enabled) { + this._cachingEnabled = enabled; + } + deactivate() { + this.restoreOriginalConsole(); + } + restoreOriginalConsole() { + if (this._originalConsole) { + global.console = this._originalConsole; + } + } + addLogEntry(level, ...args) { + const callerInfo = this._collectCallerInfo ? getCallerInfo() : null; + const logEntry = [new Date, level, args, callerInfo]; + if (this._cachingEnabled) { + if (this._cachedLogs.length >= this.MAX_CACHE_SIZE) { + this._cachedLogs.shift(); + } + this._cachedLogs.push(logEntry); + } + return logEntry; + } + appendToConsole(level, ...args) { + if (this._cachedLogs.length >= this.MAX_CACHE_SIZE) { + this._cachedLogs.shift(); + } + const entry = this.addLogEntry(level, ...args); + this.emit("entry", entry); + } + destroy() { + this.deactivate(); + } +} +var terminalConsoleCache = singleton("TerminalConsoleCache", () => { + const terminalConsoleCache2 = new TerminalConsoleCache; + process.on("exit", () => { + terminalConsoleCache2.destroy(); + }); + return terminalConsoleCache2; +}); +var ConsolePosition; +((ConsolePosition2) => { + ConsolePosition2["TOP"] = "top"; + ConsolePosition2["BOTTOM"] = "bottom"; + ConsolePosition2["LEFT"] = "left"; + ConsolePosition2["RIGHT"] = "right"; +})(ConsolePosition ||= {}); +var defaultConsoleKeybindings = [ + { name: "up", action: "scroll-up" }, + { name: "down", action: "scroll-down" }, + { name: "up", shift: true, action: "scroll-to-top" }, + { name: "down", shift: true, action: "scroll-to-bottom" }, + { name: "p", ctrl: true, action: "position-previous" }, + { name: "o", ctrl: true, action: "position-next" }, + { name: "+", action: "size-increase" }, + { name: "=", shift: true, action: "size-increase" }, + { name: "-", action: "size-decrease" }, + { name: "s", ctrl: true, action: "save-logs" }, + { name: "c", ctrl: true, shift: true, action: "copy-selection" } +]; +var DEFAULT_CONSOLE_OPTIONS = { + position: "bottom" /* BOTTOM */, + sizePercent: 30, + zIndex: Infinity, + colorInfo: "#00FFFF", + colorWarn: "#FFFF00", + colorError: "#FF0000", + colorDebug: "#808080", + colorDefault: "#FFFFFF", + backgroundColor: RGBA.fromValues(0.1, 0.1, 0.1, 0.7), + startInDebugMode: false, + title: "Console", + titleBarColor: RGBA.fromValues(0.05, 0.05, 0.05, 0.7), + titleBarTextColor: "#FFFFFF", + cursorColor: "#00A0FF", + maxStoredLogs: 2000, + maxDisplayLines: 3000, + onCopySelection: undefined, + keyBindings: undefined, + keyAliasMap: undefined, + selectionColor: RGBA.fromValues(0.3, 0.5, 0.8, 0.5), + copyButtonColor: "#00A0FF" +}; +var INDENT_WIDTH = 2; + +class TerminalConsole extends EventEmitter4 { + isVisible = false; + isFocused = false; + renderer; + keyHandler; + options; + _debugModeEnabled = false; + frameBuffer = null; + consoleX = 0; + consoleY = 0; + consoleWidth = 0; + consoleHeight = 0; + scrollTopIndex = 0; + isScrolledToBottom = true; + currentLineIndex = 0; + _displayLines = []; + _allLogEntries = []; + _needsFrameBufferUpdate = false; + _entryListener; + _selectionStart = null; + _selectionEnd = null; + _isDragging = false; + _copyButtonBounds = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + _autoScrollInterval = null; + clock; + _keyBindingsMap; + _keyAliasMap; + _keyBindings; + _mergedKeyBindings; + _actionHandlers; + markNeedsRerender() { + this._needsFrameBufferUpdate = true; + this.renderer.requestRender(); + } + getCopyButtonLabel() { + const copyBindings = this._mergedKeyBindings.filter((b) => b.action === "copy-selection"); + const copyBinding = copyBindings[copyBindings.length - 1]; + if (copyBinding) { + const shortcut = keyBindingToString(copyBinding); + return `[Copy (${shortcut})]`; + } + return "[Copy]"; + } + _rgbaInfo; + _rgbaWarn; + _rgbaError; + _rgbaDebug; + _rgbaDefault; + backgroundColor; + _rgbaTitleBar; + _rgbaTitleBarText; + _title; + _rgbaCursor; + _rgbaSelection; + _rgbaCopyButton; + _positions = [ + "top" /* TOP */, + "right" /* RIGHT */, + "bottom" /* BOTTOM */, + "left" /* LEFT */ + ]; + constructor(renderer, options = {}) { + super(); + this.renderer = renderer; + this.clock = options.clock ?? new SystemClock; + this.options = { ...DEFAULT_CONSOLE_OPTIONS, ...options }; + this.keyHandler = this.handleKeyPress.bind(this); + this._debugModeEnabled = this.options.startInDebugMode; + terminalConsoleCache.setCollectCallerInfo(this._debugModeEnabled); + this._rgbaInfo = parseColor(this.options.colorInfo); + this._rgbaWarn = parseColor(this.options.colorWarn); + this._rgbaError = parseColor(this.options.colorError); + this._rgbaDebug = parseColor(this.options.colorDebug); + this._rgbaDefault = parseColor(this.options.colorDefault); + this.backgroundColor = parseColor(this.options.backgroundColor); + this._rgbaTitleBar = parseColor(this.options.titleBarColor); + this._rgbaTitleBarText = parseColor(this.options.titleBarTextColor || this.options.colorDefault); + this._title = this.options.title; + this._rgbaCursor = parseColor(this.options.cursorColor); + this._rgbaSelection = parseColor(this.options.selectionColor); + this._rgbaCopyButton = parseColor(this.options.copyButtonColor); + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {}); + this._keyBindings = options.keyBindings || []; + this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap); + this._actionHandlers = this.buildActionHandlers(); + this._updateConsoleDimensions(); + this._scrollToBottom(true); + this._entryListener = (logEntry) => { + this._handleNewLog(logEntry); + }; + terminalConsoleCache.on("entry", this._entryListener); + if (env.SHOW_CONSOLE) { + this.show(); + } + } + buildActionHandlers() { + return new Map([ + ["scroll-up", () => this.scrollUp()], + ["scroll-down", () => this.scrollDown()], + ["scroll-to-top", () => this.scrollToTop()], + ["scroll-to-bottom", () => this.scrollToBottomAction()], + ["position-previous", () => this.positionPrevious()], + ["position-next", () => this.positionNext()], + ["size-increase", () => this.sizeIncrease()], + ["size-decrease", () => this.sizeDecrease()], + ["save-logs", () => this.saveLogsAction()], + ["copy-selection", () => this.triggerCopyAction()] + ]); + } + activate() { + terminalConsoleCache.activate(); + } + deactivate() { + terminalConsoleCache.deactivate(); + } + _handleNewLog(logEntry) { + if (!this.isVisible) + return; + this._allLogEntries.push(logEntry); + if (this._allLogEntries.length > this.options.maxStoredLogs) { + this._allLogEntries.splice(0, this._allLogEntries.length - this.options.maxStoredLogs); + } + const newDisplayLines = this._processLogEntry(logEntry); + this._displayLines.push(...newDisplayLines); + if (this._displayLines.length > this.options.maxDisplayLines) { + this._displayLines.splice(0, this._displayLines.length - this.options.maxDisplayLines); + const linesRemoved = this._displayLines.length - this.options.maxDisplayLines; + this.scrollTopIndex = Math.max(0, this.scrollTopIndex - linesRemoved); + } + if (this.isScrolledToBottom) { + this._scrollToBottom(); + } + this.markNeedsRerender(); + } + _updateConsoleDimensions(termWidth, termHeight) { + const width = termWidth ?? this.renderer.width; + const height = termHeight ?? this.renderer.height; + const sizePercent = this.options.sizePercent / 100; + switch (this.options.position) { + case "top" /* TOP */: + this.consoleX = 0; + this.consoleY = 0; + this.consoleWidth = width; + this.consoleHeight = Math.max(1, Math.floor(height * sizePercent)); + break; + case "bottom" /* BOTTOM */: + this.consoleHeight = Math.max(1, Math.floor(height * sizePercent)); + this.consoleWidth = width; + this.consoleX = 0; + this.consoleY = height - this.consoleHeight; + break; + case "left" /* LEFT */: + this.consoleWidth = Math.max(1, Math.floor(width * sizePercent)); + this.consoleHeight = height; + this.consoleX = 0; + this.consoleY = 0; + break; + case "right" /* RIGHT */: + this.consoleWidth = Math.max(1, Math.floor(width * sizePercent)); + this.consoleHeight = height; + this.consoleY = 0; + this.consoleX = width - this.consoleWidth; + break; + } + this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, this.consoleHeight - 1)); + } + handleKeyPress(event) { + if (event.name === "escape") { + this.blur(); + return; + } + const action = getKeyBindingAction(this._keyBindingsMap, event); + if (action) { + const handler = this._actionHandlers.get(action); + if (handler) { + handler(); + return; + } + } + } + scrollUp() { + const logAreaHeight = Math.max(1, this.consoleHeight - 1); + if (this.currentLineIndex > 0) { + this.currentLineIndex--; + this.markNeedsRerender(); + } else if (this.scrollTopIndex > 0) { + this.scrollTopIndex--; + this.isScrolledToBottom = false; + this.markNeedsRerender(); + } + return true; + } + scrollDown() { + const displayLineCount = this._displayLines.length; + const logAreaHeight = Math.max(1, this.consoleHeight - 1); + const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight); + const canCursorMoveDown = this.currentLineIndex < logAreaHeight - 1 && this.scrollTopIndex + this.currentLineIndex < displayLineCount - 1; + if (canCursorMoveDown) { + this.currentLineIndex++; + this.markNeedsRerender(); + } else if (this.scrollTopIndex < maxScrollTop) { + this.scrollTopIndex++; + this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop; + this.markNeedsRerender(); + } + return true; + } + scrollToTop() { + if (this.scrollTopIndex > 0 || this.currentLineIndex > 0) { + this.scrollTopIndex = 0; + this.currentLineIndex = 0; + this.isScrolledToBottom = this._displayLines.length <= Math.max(1, this.consoleHeight - 1); + this.markNeedsRerender(); + } + return true; + } + scrollToBottomAction() { + const logAreaHeightForScroll = Math.max(1, this.consoleHeight - 1); + const maxScrollPossible = Math.max(0, this._displayLines.length - logAreaHeightForScroll); + if (this.scrollTopIndex < maxScrollPossible || !this.isScrolledToBottom) { + this._scrollToBottom(true); + this.markNeedsRerender(); + } + return true; + } + positionPrevious() { + const currentPositionIndex = this._positions.indexOf(this.options.position); + const prevIndex = (currentPositionIndex - 1 + this._positions.length) % this._positions.length; + this.options.position = this._positions[prevIndex]; + this.resize(this.renderer.width, this.renderer.height); + return true; + } + positionNext() { + const currentPositionIndex = this._positions.indexOf(this.options.position); + const nextIndex = (currentPositionIndex + 1) % this._positions.length; + this.options.position = this._positions[nextIndex]; + this.resize(this.renderer.width, this.renderer.height); + return true; + } + sizeIncrease() { + this.options.sizePercent = Math.min(100, this.options.sizePercent + 5); + this.resize(this.renderer.width, this.renderer.height); + return true; + } + sizeDecrease() { + this.options.sizePercent = Math.max(10, this.options.sizePercent - 5); + this.resize(this.renderer.width, this.renderer.height); + return true; + } + saveLogsAction() { + this.saveLogsToFile(); + return true; + } + triggerCopyAction() { + this.triggerCopy(); + return true; + } + attachStdin() { + if (this.isFocused) + return; + this.renderer.keyInput.on("keypress", this.keyHandler); + this.isFocused = true; + } + detachStdin() { + if (!this.isFocused) + return; + this.renderer.keyInput.off("keypress", this.keyHandler); + this.isFocused = false; + } + formatTimestamp(date) { + return new Intl.DateTimeFormat("en-US", { + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + hour12: false + }).format(date); + } + formatArguments(args) { + return args.map((arg) => { + if (arg instanceof Error) { + const errorProps = arg; + return `Error: ${errorProps.message} +` + (errorProps.stack ? `${errorProps.stack} +` : ""); + } + if (typeof arg === "object" && arg !== null) { + try { + return util2.inspect(arg, { depth: 2 }); + } catch (e) { + return String(arg); + } + } + try { + return util2.inspect(arg, { depth: 2 }); + } catch (e) { + return String(arg); + } + }).join(" "); + } + resize(width, height) { + this._updateConsoleDimensions(width, height); + if (this.frameBuffer) { + this.frameBuffer.resize(this.consoleWidth, this.consoleHeight); + const displayLineCount = this._displayLines.length; + const logAreaHeight = Math.max(1, this.consoleHeight - 1); + const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight); + this.scrollTopIndex = Math.min(this.scrollTopIndex, maxScrollTop); + this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop; + const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex); + this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, visibleLineCount - 1)); + if (this.isVisible) { + this.markNeedsRerender(); + } + } + } + clear() { + terminalConsoleCache.clearConsole(); + this._allLogEntries = []; + this._displayLines = []; + this.markNeedsRerender(); + } + toggle() { + if (this.isVisible) { + if (this.isFocused) { + this.hide(); + } else { + this.focus(); + } + } else { + this.show(); + } + if (!this.renderer.isRunning) { + this.renderer.requestRender(); + } + } + focus() { + this.attachStdin(); + this._scrollToBottom(true); + this.markNeedsRerender(); + } + blur() { + this.detachStdin(); + this.markNeedsRerender(); + } + show() { + if (!this.isVisible) { + this.isVisible = true; + this._processCachedLogs(); + terminalConsoleCache.setCachingEnabled(false); + if (!this.frameBuffer) { + this.frameBuffer = OptimizedBuffer.create(this.consoleWidth, this.consoleHeight, this.renderer.widthMethod, { + respectAlpha: this.backgroundColor.a < 1, + id: "console framebuffer" + }); + } + const logCount = terminalConsoleCache.cachedLogs.length; + const visibleLogLines = Math.min(this.consoleHeight, logCount); + this.currentLineIndex = Math.max(0, visibleLogLines - 1); + this.scrollTopIndex = 0; + this._scrollToBottom(true); + this.focus(); + this.markNeedsRerender(); + } + } + hide() { + if (this.isVisible) { + this.isVisible = false; + this.blur(); + terminalConsoleCache.setCachingEnabled(true); + } + } + destroy() { + this.stopAutoScroll(); + this.hide(); + this.deactivate(); + terminalConsoleCache.off("entry", this._entryListener); + } + getCachedLogs() { + return terminalConsoleCache.cachedLogs.map((logEntry) => logEntry[0].toISOString() + " " + logEntry.slice(1).join(" ")).join(` +`); + } + updateFrameBuffer() { + if (!this.frameBuffer) + return; + this.frameBuffer.clear(this.backgroundColor); + const displayLines = this._displayLines; + const displayLineCount = displayLines.length; + const logAreaHeight = Math.max(1, this.consoleHeight - 1); + this.frameBuffer.fillRect(0, 0, this.consoleWidth, 1, this._rgbaTitleBar); + const dynamicTitle = `${this._title}${this.isFocused ? " (Focused)" : ""}`; + const titleX = Math.max(0, Math.floor((this.consoleWidth - dynamicTitle.length) / 2)); + this.frameBuffer.drawText(dynamicTitle, titleX, 0, this._rgbaTitleBarText, this._rgbaTitleBar); + const copyLabel = this.getCopyButtonLabel(); + const copyButtonX = this.consoleWidth - copyLabel.length - 1; + if (copyButtonX >= 0) { + const copyButtonEnabled = this.hasSelection(); + const disabledColor = RGBA.fromInts(100, 100, 100, 255); + const copyColor = copyButtonEnabled ? this._rgbaCopyButton : disabledColor; + this.frameBuffer.drawText(copyLabel, copyButtonX, 0, copyColor, this._rgbaTitleBar); + this._copyButtonBounds = { x: copyButtonX, y: 0, width: copyLabel.length, height: 1 }; + } else { + this._copyButtonBounds = { x: -1, y: -1, width: 0, height: 0 }; + } + const startIndex = this.scrollTopIndex; + const endIndex = Math.min(startIndex + logAreaHeight, displayLineCount); + const visibleDisplayLines = displayLines.slice(startIndex, endIndex); + let lineY = 1; + for (let i = 0;i < visibleDisplayLines.length; i++) { + if (lineY >= this.consoleHeight) + break; + const displayLine = visibleDisplayLines[i]; + const absoluteLineIndex = startIndex + i; + let levelColor = this._rgbaDefault; + switch (displayLine.level) { + case "INFO" /* INFO */: + levelColor = this._rgbaInfo; + break; + case "WARN" /* WARN */: + levelColor = this._rgbaWarn; + break; + case "ERROR" /* ERROR */: + levelColor = this._rgbaError; + break; + case "DEBUG" /* DEBUG */: + levelColor = this._rgbaDebug; + break; + } + const linePrefix = displayLine.indent ? " ".repeat(INDENT_WIDTH) : ""; + const textToDraw = displayLine.text; + const textAvailableWidth = this.consoleWidth - 1 - (displayLine.indent ? INDENT_WIDTH : 0); + const showCursor = this.isFocused && lineY - 1 === this.currentLineIndex; + if (showCursor) { + this.frameBuffer.drawText(">", 0, lineY, this._rgbaCursor, this.backgroundColor); + } else { + this.frameBuffer.drawText(" ", 0, lineY, this._rgbaDefault, this.backgroundColor); + } + const fullText = `${linePrefix}${textToDraw.substring(0, textAvailableWidth)}`; + const selectionRange = this.getLineSelectionRange(absoluteLineIndex); + if (selectionRange) { + const adjustedStart = Math.max(0, selectionRange.start); + const adjustedEnd = Math.min(fullText.length, selectionRange.end); + if (adjustedStart > 0) { + this.frameBuffer.drawText(fullText.substring(0, adjustedStart), 1, lineY, levelColor); + } + if (adjustedStart < adjustedEnd) { + this.frameBuffer.fillRect(1 + adjustedStart, lineY, adjustedEnd - adjustedStart, 1, this._rgbaSelection); + this.frameBuffer.drawText(fullText.substring(adjustedStart, adjustedEnd), 1 + adjustedStart, lineY, levelColor, this._rgbaSelection); + } + if (adjustedEnd < fullText.length) { + this.frameBuffer.drawText(fullText.substring(adjustedEnd), 1 + adjustedEnd, lineY, levelColor); + } + } else { + this.frameBuffer.drawText(fullText, 1, lineY, levelColor); + } + lineY++; + } + } + renderToBuffer(buffer) { + if (!this.isVisible || !this.frameBuffer) + return; + if (this._needsFrameBufferUpdate) { + this.updateFrameBuffer(); + this._needsFrameBufferUpdate = false; + } + buffer.drawFrameBuffer(this.consoleX, this.consoleY, this.frameBuffer); + } + setDebugMode(enabled) { + this._debugModeEnabled = enabled; + terminalConsoleCache.setCollectCallerInfo(enabled); + if (this.isVisible) { + this.markNeedsRerender(); + } + } + toggleDebugMode() { + this.setDebugMode(!this._debugModeEnabled); + } + set keyBindings(bindings) { + this._keyBindings = bindings; + this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, bindings); + this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap); + this.markNeedsRerender(); + } + set keyAliasMap(aliases) { + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases); + this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap); + this.markNeedsRerender(); + } + set onCopySelection(callback) { + this.options.onCopySelection = callback; + } + get onCopySelection() { + return this.options.onCopySelection; + } + _scrollToBottom(forceCursorToLastLine = false) { + const displayLineCount = this._displayLines.length; + const logAreaHeight = Math.max(1, this.consoleHeight - 1); + const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight); + this.scrollTopIndex = maxScrollTop; + this.isScrolledToBottom = true; + const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex); + if (forceCursorToLastLine || this.currentLineIndex >= visibleLineCount) { + this.currentLineIndex = Math.max(0, visibleLineCount - 1); + } + } + _processLogEntry(logEntry) { + const [date, level, args, callerInfo] = logEntry; + const displayLines = []; + const timestamp = this.formatTimestamp(date); + const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : "unknown"; + const prefix = `[${timestamp}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : "") + " "; + const formattedArgs = this.formatArguments(args); + const initialLines = formattedArgs.split(` +`); + for (let i = 0;i < initialLines.length; i++) { + const lineText = initialLines[i]; + const isFirstLineOfEntry = i === 0; + const availableWidth = this.consoleWidth - 1 - (isFirstLineOfEntry ? 0 : INDENT_WIDTH); + const linePrefix = isFirstLineOfEntry ? prefix : " ".repeat(INDENT_WIDTH); + const textToWrap = isFirstLineOfEntry ? linePrefix + lineText : lineText; + let currentPos = 0; + while (currentPos < textToWrap.length || isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0) { + const segment = textToWrap.substring(currentPos, currentPos + availableWidth); + const isFirstSegmentOfLine = currentPos === 0; + displayLines.push({ + text: isFirstSegmentOfLine && !isFirstLineOfEntry ? linePrefix + segment : segment, + level, + indent: !isFirstLineOfEntry || !isFirstSegmentOfLine + }); + currentPos += availableWidth; + if (isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0) + break; + } + } + return displayLines; + } + _processCachedLogs() { + const logsToProcess = [...terminalConsoleCache.cachedLogs]; + terminalConsoleCache.clearConsole(); + this._allLogEntries.push(...logsToProcess); + if (this._allLogEntries.length > this.options.maxStoredLogs) { + this._allLogEntries.splice(0, this._allLogEntries.length - this.options.maxStoredLogs); + } + for (const logEntry of logsToProcess) { + const processed = this._processLogEntry(logEntry); + this._displayLines.push(...processed); + } + if (this._displayLines.length > this.options.maxDisplayLines) { + this._displayLines.splice(0, this._displayLines.length - this.options.maxDisplayLines); + } + } + hasSelection() { + if (this._selectionStart === null || this._selectionEnd === null) + return false; + return this._selectionStart.line !== this._selectionEnd.line || this._selectionStart.col !== this._selectionEnd.col; + } + normalizeSelection() { + if (!this._selectionStart || !this._selectionEnd) + return null; + const start = this._selectionStart; + const end = this._selectionEnd; + const startBeforeEnd = start.line < end.line || start.line === end.line && start.col <= end.col; + if (startBeforeEnd) { + return { + startLine: start.line, + startCol: start.col, + endLine: end.line, + endCol: end.col + }; + } else { + return { + startLine: end.line, + startCol: end.col, + endLine: start.line, + endCol: start.col + }; + } + } + getSelectedText() { + const selection = this.normalizeSelection(); + if (!selection) + return ""; + const lines = []; + for (let i = selection.startLine;i <= selection.endLine; i++) { + if (i < 0 || i >= this._displayLines.length) + continue; + const line = this._displayLines[i]; + const linePrefix = line.indent ? " ".repeat(INDENT_WIDTH) : ""; + const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0); + const fullText = linePrefix + line.text.substring(0, textAvailableWidth); + let text = fullText; + if (i === selection.startLine && i === selection.endLine) { + text = fullText.substring(selection.startCol, selection.endCol); + } else if (i === selection.startLine) { + text = fullText.substring(selection.startCol); + } else if (i === selection.endLine) { + text = fullText.substring(0, selection.endCol); + } + lines.push(text); + } + return lines.join(` +`); + } + clearSelection() { + this._selectionStart = null; + this._selectionEnd = null; + this._isDragging = false; + this.stopAutoScroll(); + } + stopAutoScroll() { + if (this._autoScrollInterval !== null) { + this.clock.clearInterval(this._autoScrollInterval); + this._autoScrollInterval = null; + } + } + startAutoScroll(direction) { + this.stopAutoScroll(); + this._autoScrollInterval = this.clock.setInterval(() => { + if (direction === "up") { + if (this.scrollTopIndex > 0) { + this.scrollTopIndex--; + this.isScrolledToBottom = false; + if (this._selectionEnd) { + this._selectionEnd = { + line: this.scrollTopIndex, + col: this._selectionEnd.col + }; + } + this.markNeedsRerender(); + } else { + this.stopAutoScroll(); + } + } else { + const displayLineCount = this._displayLines.length; + const logAreaHeight = Math.max(1, this.consoleHeight - 1); + const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight); + if (this.scrollTopIndex < maxScrollTop) { + this.scrollTopIndex++; + this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop; + if (this._selectionEnd) { + const maxLine = this.scrollTopIndex + logAreaHeight - 1; + this._selectionEnd = { + line: Math.min(maxLine, displayLineCount - 1), + col: this._selectionEnd.col + }; + } + this.markNeedsRerender(); + } else { + this.stopAutoScroll(); + } + } + }, 50); + } + triggerCopy() { + if (!this.hasSelection()) + return; + const text = this.getSelectedText(); + if (text && this.options.onCopySelection) { + try { + this.options.onCopySelection(text); + } catch {} + this.clearSelection(); + this.markNeedsRerender(); + } + } + getLineSelectionRange(lineIndex) { + const selection = this.normalizeSelection(); + if (!selection) + return null; + if (lineIndex < selection.startLine || lineIndex > selection.endLine) { + return null; + } + const line = this._displayLines[lineIndex]; + if (!line) + return null; + const linePrefix = line.indent ? " ".repeat(INDENT_WIDTH) : ""; + const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0); + const fullTextLength = linePrefix.length + Math.min(line.text.length, textAvailableWidth); + let start = 0; + let end = fullTextLength; + if (lineIndex === selection.startLine) { + start = Math.max(0, selection.startCol); + } + if (lineIndex === selection.endLine) { + end = Math.min(fullTextLength, selection.endCol); + } + if (start >= end) + return null; + return { start, end }; + } + handleMouse(event) { + if (!this.isVisible) + return false; + const localX = event.x - this.consoleX; + const localY = event.y - this.consoleY; + if (localX < 0 || localX >= this.consoleWidth || localY < 0 || localY >= this.consoleHeight) { + return false; + } + if (event.type === "scroll" && event.scroll) { + if (event.scroll.direction === "up") { + this.scrollUp(); + } else if (event.scroll.direction === "down") { + this.scrollDown(); + } + return true; + } + if (localY === 0) { + if (event.type === "down" && event.button === 0 && localX >= this._copyButtonBounds.x && localX < this._copyButtonBounds.x + this._copyButtonBounds.width) { + this.triggerCopy(); + return true; + } + return true; + } + const lineIndex = this.scrollTopIndex + (localY - 1); + const colIndex = Math.max(0, localX - 1); + if (event.type === "down" && event.button === 0) { + this.clearSelection(); + this._selectionStart = { line: lineIndex, col: colIndex }; + this._selectionEnd = { line: lineIndex, col: colIndex }; + this._isDragging = true; + this.markNeedsRerender(); + return true; + } + if (event.type === "drag" && this._isDragging) { + this._selectionEnd = { line: lineIndex, col: colIndex }; + const logAreaHeight = Math.max(1, this.consoleHeight - 1); + const relativeY = localY - 1; + if (relativeY <= 0) { + this.startAutoScroll("up"); + } else if (relativeY >= logAreaHeight - 1) { + this.startAutoScroll("down"); + } else { + this.stopAutoScroll(); + } + this.markNeedsRerender(); + return true; + } + if (event.type === "up") { + if (this._isDragging) { + this._selectionEnd = { line: lineIndex, col: colIndex }; + this._isDragging = false; + this.stopAutoScroll(); + this.markNeedsRerender(); + } + return true; + } + return true; + } + get visible() { + return this.isVisible; + } + get bounds() { + return { + x: this.consoleX, + y: this.consoleY, + width: this.consoleWidth, + height: this.consoleHeight + }; + } + saveLogsToFile() { + try { + const timestamp = Date.now(); + const filename = `_console_${timestamp}.log`; + const filepath = path.join(process.cwd(), filename); + const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs]; + const logLines = []; + for (const [date, level, args, callerInfo] of allLogEntries) { + const timestampStr = this.formatTimestamp(date); + const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : "unknown"; + const prefix = `[${timestampStr}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : "") + " "; + const formattedArgs = this.formatArguments(args); + logLines.push(prefix + formattedArgs); + } + const content = logLines.join(` +`); + fs.writeFileSync(filepath, content, "utf8"); + console.info(`Console logs saved to: ${filename}`); + } catch (error) { + console.error(`Failed to save console logs:`, error); + } + } +} + +// src/renderables/EditBufferRenderable.ts +var BrandedEditBufferRenderable = Symbol.for("@opentui/core/EditBufferRenderable"); +var EditBufferRenderableEvents; +((EditBufferRenderableEvents2) => { + EditBufferRenderableEvents2["TRAITS_CHANGED"] = "traits-changed"; +})(EditBufferRenderableEvents ||= {}); +function sameCapture(a, b) { + if (a === b) + return true; + if (!a || !b) + return !a && !b; + if (a.length !== b.length) + return false; + return a.every((item, i) => item === b[i]); +} +function sameTraits(a, b) { + return a.suspend === b.suspend && a.status === b.status && sameCapture(a.capture, b.capture); +} +function isEditBufferRenderable(obj) { + return !!(obj && typeof obj === "object" && (BrandedEditBufferRenderable in obj)); +} + +class EditBufferRenderable extends Renderable { + [BrandedEditBufferRenderable] = true; + _focusable = true; + selectable = true; + _traits = {}; + _textColor; + _backgroundColor; + _defaultAttributes; + _selectionBg; + _selectionFg; + _wrapMode = "word"; + _scrollMargin = 0.2; + _showCursor = true; + _cursorColor; + _cursorStyle; + lastLocalSelection = null; + _tabIndicator; + _tabIndicatorColor; + _cursorChangeListener = undefined; + _contentChangeListener = undefined; + _autoScrollVelocity = 0; + _autoScrollAccumulator = 0; + _scrollSpeed = 16; + _keyboardSelectionActive = false; + editBuffer; + editorView; + _defaultOptions = { + textColor: RGBA.fromValues(1, 1, 1, 1), + backgroundColor: "transparent", + selectionBg: undefined, + selectionFg: undefined, + selectable: true, + attributes: 0, + wrapMode: "word", + scrollMargin: 0.2, + scrollSpeed: 16, + showCursor: true, + cursorColor: RGBA.fromValues(1, 1, 1, 1), + cursorStyle: { + style: "block", + blinking: true + }, + tabIndicator: undefined, + tabIndicatorColor: undefined + }; + constructor(ctx, options) { + super(ctx, options); + this._textColor = parseColor(options.textColor ?? this._defaultOptions.textColor); + this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor); + this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes; + this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg; + this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg; + this.selectable = options.selectable ?? this._defaultOptions.selectable; + this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode; + this._scrollMargin = options.scrollMargin ?? this._defaultOptions.scrollMargin; + this._scrollSpeed = options.scrollSpeed ?? this._defaultOptions.scrollSpeed; + this._showCursor = options.showCursor ?? this._defaultOptions.showCursor; + this._cursorColor = parseColor(options.cursorColor ?? this._defaultOptions.cursorColor); + this._cursorStyle = options.cursorStyle ?? this._defaultOptions.cursorStyle; + this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator; + this._tabIndicatorColor = options.tabIndicatorColor ? parseColor(options.tabIndicatorColor) : this._defaultOptions.tabIndicatorColor; + this.editBuffer = EditBuffer.create(this._ctx.widthMethod); + this.editorView = EditorView.create(this.editBuffer, this.width || 80, this.height || 24); + this.editorView.setWrapMode(this._wrapMode); + this.editorView.setScrollMargin(this._scrollMargin); + this.editBuffer.setDefaultFg(this._textColor); + this.editBuffer.setDefaultBg(this._backgroundColor); + this.editBuffer.setDefaultAttributes(this._defaultAttributes); + if (options.syntaxStyle) { + this.editBuffer.setSyntaxStyle(options.syntaxStyle); + } + if (this._tabIndicator !== undefined) { + this.editorView.setTabIndicator(this._tabIndicator); + } + if (this._tabIndicatorColor !== undefined) { + this.editorView.setTabIndicatorColor(this._tabIndicatorColor); + } + this.setupMeasureFunc(); + this.setupEventListeners(options); + } + get lineInfo() { + return this.editorView.getLogicalLineInfo(); + } + setupEventListeners(options) { + this._cursorChangeListener = options.onCursorChange; + this._contentChangeListener = options.onContentChange; + this.editBuffer.on("cursor-changed", () => { + if (this._cursorChangeListener) { + const cursor = this.editBuffer.getCursorPosition(); + this._cursorChangeListener({ + line: cursor.row, + visualColumn: cursor.col + }); + } + }); + this.editBuffer.on("content-changed", () => { + this.yogaNode.markDirty(); + this.requestRender(); + this.emit("line-info-change"); + if (this._contentChangeListener) { + this._contentChangeListener({}); + } + }); + } + get lineCount() { + return this.editBuffer.getLineCount(); + } + get virtualLineCount() { + return this.editorView.getVirtualLineCount(); + } + get scrollY() { + return this.editorView.getViewport().offsetY; + } + get plainText() { + return this.editBuffer.getText(); + } + get logicalCursor() { + return this.editBuffer.getCursorPosition(); + } + get visualCursor() { + return this.editorView.getVisualCursor(); + } + get cursorOffset() { + return this.editorView.getVisualCursor().offset; + } + set cursorOffset(offset) { + this.editorView.setCursorByOffset(offset); + this.requestRender(); + } + get cursorCharacterOffset() { + const len = this.plainText.length; + if (len <= 0) + return; + const cursor = this.logicalCursor; + const offset = this.cursorOffset; + if (offset >= len) { + if (cursor.col > 0) + return len - 1; + return 0; + } + if (this.plainText[offset] === ` +` && cursor.col > 0) { + return offset - 1; + } + return offset; + } + get textColor() { + return this._textColor; + } + set textColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.textColor); + if (this._textColor !== newColor) { + this._textColor = newColor; + this.editBuffer.setDefaultFg(newColor); + this.requestRender(); + } + } + get selectionBg() { + return this._selectionBg; + } + get traits() { + return this._traits; + } + set traits(value) { + if (sameTraits(this._traits, value)) + return; + const prev = this._traits; + this._traits = value; + this.emit("traits-changed" /* TRAITS_CHANGED */, value, prev); + } + set selectionBg(value) { + const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg; + if (this._selectionBg !== newColor) { + this._selectionBg = newColor; + this.refreshSelectionStyle(); + this.requestRender(); + } + } + get selectionFg() { + return this._selectionFg; + } + set selectionFg(value) { + const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg; + if (this._selectionFg !== newColor) { + this._selectionFg = newColor; + this.refreshSelectionStyle(); + this.requestRender(); + } + } + get backgroundColor() { + return this._backgroundColor; + } + set backgroundColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.backgroundColor); + if (this._backgroundColor !== newColor) { + this._backgroundColor = newColor; + this.editBuffer.setDefaultBg(newColor); + this.requestRender(); + } + } + get attributes() { + return this._defaultAttributes; + } + set attributes(value) { + if (this._defaultAttributes !== value) { + this._defaultAttributes = value; + this.editBuffer.setDefaultAttributes(value); + this.requestRender(); + } + } + get wrapMode() { + return this._wrapMode; + } + set wrapMode(value) { + if (this._wrapMode !== value) { + this._wrapMode = value; + this.editorView.setWrapMode(value); + this.yogaNode.markDirty(); + this.requestRender(); + } + } + get showCursor() { + return this._showCursor; + } + set showCursor(value) { + if (this._showCursor !== value) { + this._showCursor = value; + if (!value && this._focused) { + this._ctx.setCursorPosition(0, 0, false); + } + this.requestRender(); + } + } + get cursorColor() { + return this._cursorColor; + } + set cursorColor(value) { + const newColor = parseColor(value); + if (this._cursorColor !== newColor) { + this._cursorColor = newColor; + if (this._focused) { + this.requestRender(); + } + } + } + get cursorStyle() { + return this._cursorStyle; + } + set cursorStyle(style) { + const newStyle = style; + if (this.cursorStyle.style !== newStyle.style || this.cursorStyle.blinking !== newStyle.blinking) { + this._cursorStyle = newStyle; + if (this._focused) { + this.requestRender(); + } + } + } + get tabIndicator() { + return this._tabIndicator; + } + set tabIndicator(value) { + if (this._tabIndicator !== value) { + this._tabIndicator = value; + if (value !== undefined) { + this.editorView.setTabIndicator(value); + } + this.requestRender(); + } + } + get tabIndicatorColor() { + return this._tabIndicatorColor; + } + set tabIndicatorColor(value) { + const newColor = value ? parseColor(value) : undefined; + if (this._tabIndicatorColor !== newColor) { + this._tabIndicatorColor = newColor; + if (newColor !== undefined) { + this.editorView.setTabIndicatorColor(newColor); + } + this.requestRender(); + } + } + get scrollSpeed() { + return this._scrollSpeed; + } + set scrollSpeed(value) { + this._scrollSpeed = Math.max(0, value); + } + onMouseEvent(event) { + if (event.type === "scroll") { + this.handleScroll(event); + } + } + handleScroll(event) { + if (!event.scroll) + return; + const { direction, delta } = event.scroll; + const viewport = this.editorView.getViewport(); + if (direction === "up") { + const newOffsetY = Math.max(0, viewport.offsetY - delta); + this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true); + this.requestRender(); + } else if (direction === "down") { + const totalVirtualLines = this.editorView.getTotalVirtualLineCount(); + const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height); + const newOffsetY = Math.min(viewport.offsetY + delta, maxOffsetY); + this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true); + this.requestRender(); + } + if (this._wrapMode === "none") { + if (direction === "left") { + const newOffsetX = Math.max(0, viewport.offsetX - delta); + this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true); + this.requestRender(); + } else if (direction === "right") { + const newOffsetX = viewport.offsetX + delta; + this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true); + this.requestRender(); + } + } + } + onResize(width, height) { + this.editorView.setViewportSize(width, height); + } + refreshLocalSelection() { + if (this.lastLocalSelection) { + return this.updateLocalSelection(this.lastLocalSelection); + } + return false; + } + updateLocalSelection(localSelection) { + if (!localSelection?.isActive) { + this.editorView.resetLocalSelection(); + return true; + } + return this.editorView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg, false); + } + shouldStartSelection(x, y) { + if (!this.selectable) + return false; + const localX = x - this.x; + const localY = y - this.y; + return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height; + } + onSelectionChanged(selection) { + const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y); + this.lastLocalSelection = localSelection; + const updateCursor = true; + const followCursor = this._keyboardSelectionActive; + let changed; + if (!localSelection?.isActive) { + this._keyboardSelectionActive = false; + this.editorView.resetLocalSelection(); + changed = true; + } else if (selection?.isStart) { + changed = this.editorView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg, updateCursor, followCursor); + } else { + changed = this.editorView.updateLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg, updateCursor, followCursor); + } + if (changed && localSelection?.isActive && selection?.isDragging) { + const viewport = this.editorView.getViewport(); + const focusY = localSelection.focusY; + const scrollMargin = Math.max(1, Math.floor(viewport.height * this._scrollMargin)); + if (focusY < scrollMargin) { + this._autoScrollVelocity = -this._scrollSpeed; + } else if (focusY >= viewport.height - scrollMargin) { + this._autoScrollVelocity = this._scrollSpeed; + } else { + this._autoScrollVelocity = 0; + } + } else { + this._keyboardSelectionActive = false; + this._autoScrollVelocity = 0; + this._autoScrollAccumulator = 0; + } + if (changed) { + this.requestRender(); + } + return this.hasSelection(); + } + onUpdate(deltaTime) { + super.onUpdate(deltaTime); + if (this._autoScrollVelocity !== 0 && this.hasSelection()) { + const deltaSeconds = deltaTime / 1000; + this._autoScrollAccumulator += this._autoScrollVelocity * deltaSeconds; + const linesToScroll = Math.floor(Math.abs(this._autoScrollAccumulator)); + if (linesToScroll > 0) { + const direction = this._autoScrollVelocity > 0 ? 1 : -1; + const viewport = this.editorView.getViewport(); + const totalVirtualLines = this.editorView.getTotalVirtualLineCount(); + const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height); + const newOffsetY = Math.max(0, Math.min(viewport.offsetY + direction * linesToScroll, maxOffsetY)); + if (newOffsetY !== viewport.offsetY) { + this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, false); + this._ctx.requestSelectionUpdate(); + } + this._autoScrollAccumulator -= direction * linesToScroll; + } + } + } + getSelectedText() { + return this.editorView.getSelectedText(); + } + hasSelection() { + return this.editorView.hasSelection(); + } + getSelection() { + return this.editorView.getSelection(); + } + refreshSelectionStyle() { + if (this.lastLocalSelection) { + this.updateLocalSelection(this.lastLocalSelection); + return; + } + const selection = this.getSelection(); + if (!selection) + return; + this.editorView.setSelection(selection.start, selection.end, this._selectionBg, this._selectionFg); + } + deleteSelectedText() { + this.editorView.deleteSelectedText(); + this._ctx.clearSelection(); + this.requestRender(); + } + setSelection(start, end) { + this.lastLocalSelection = null; + this.editorView.resetLocalSelection(); + this._ctx.clearSelection(); + this.editorView.setSelection(start, end, this._selectionBg, this._selectionFg); + this.requestRender(); + } + setSelectionInclusive(start, end) { + this.setSelection(Math.min(start, end), Math.max(start, end) + 1); + } + clearSelection() { + const had = this.hasSelection(); + this.lastLocalSelection = null; + this.editorView.resetSelection(); + this.editorView.resetLocalSelection(); + this._ctx.clearSelection(); + if (had) { + this.requestRender(); + } + return had; + } + deleteSelection() { + if (!this.hasSelection()) + return false; + this.lastLocalSelection = null; + this.deleteSelectedText(); + return true; + } + setCursor(row, col) { + this.editBuffer.setCursor(row, col); + this.requestRender(); + } + insertChar(char) { + if (this.hasSelection()) { + this.deleteSelectedText(); + } + this.editBuffer.insertChar(char); + this.requestRender(); + } + insertText(text) { + if (this.hasSelection()) { + this.deleteSelectedText(); + } + this.editBuffer.insertText(text); + this.requestRender(); + } + deleteChar() { + if (this.hasSelection()) { + this.deleteSelectedText(); + return true; + } + this._ctx.clearSelection(); + this.editBuffer.deleteChar(); + this.requestRender(); + return true; + } + deleteCharBackward() { + if (this.hasSelection()) { + this.deleteSelectedText(); + return true; + } + this._ctx.clearSelection(); + this.editBuffer.deleteCharBackward(); + this.requestRender(); + return true; + } + newLine() { + this._ctx.clearSelection(); + this.editBuffer.newLine(); + this.requestRender(); + return true; + } + deleteLine() { + this._ctx.clearSelection(); + this.editBuffer.deleteLine(); + this.requestRender(); + return true; + } + moveCursorLeft(options) { + const select = options?.select ?? false; + if (!select && this.hasSelection()) { + const selection = this.getSelection(); + this.editBuffer.setCursorByOffset(selection.start); + this._ctx.clearSelection(); + this.requestRender(); + return true; + } + this.updateSelectionForMovement(select, true); + this.editBuffer.moveCursorLeft(); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + moveCursorRight(options) { + const select = options?.select ?? false; + if (!select && this.hasSelection()) { + const selection = this.getSelection(); + const targetOffset = this.cursorOffset === selection.start ? selection.end - 1 : selection.end; + this.editBuffer.setCursorByOffset(targetOffset); + this._ctx.clearSelection(); + this.requestRender(); + return true; + } + this.updateSelectionForMovement(select, true); + this.editBuffer.moveCursorRight(); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + moveCursorUp(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + this.editorView.moveUpVisual(); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + moveCursorDown(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + this.editorView.moveDownVisual(); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + gotoLine(line) { + this.editBuffer.gotoLine(line); + this.requestRender(); + } + gotoLineStart() { + this.setCursor(this.logicalCursor.row, 0); + } + gotoLineTextEnd() { + const eol = this.editBuffer.getEOL(); + this.setCursor(eol.row, eol.col); + } + gotoLineHome(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + const cursor = this.editorView.getCursor(); + if (cursor.col === 0 && cursor.row > 0) { + this.editBuffer.setCursor(cursor.row - 1, 0); + const prevLineEol = this.editBuffer.getEOL(); + this.editBuffer.setCursor(prevLineEol.row, prevLineEol.col); + } else { + this.editBuffer.setCursor(cursor.row, 0); + } + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + gotoLineEnd(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + const cursor = this.editorView.getCursor(); + const eol = this.editBuffer.getEOL(); + const lineCount = this.editBuffer.getLineCount(); + if (cursor.col === eol.col && cursor.row < lineCount - 1) { + this.editBuffer.setCursor(cursor.row + 1, 0); + } else { + this.editBuffer.setCursor(eol.row, eol.col); + } + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + gotoVisualLineHome(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + const sol = this.editorView.getVisualSOL(); + this.editBuffer.setCursor(sol.logicalRow, sol.logicalCol); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + gotoVisualLineEnd(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + const eol = this.editorView.getVisualEOL(); + this.editBuffer.setCursor(eol.logicalRow, eol.logicalCol); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + gotoBufferHome(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + this.editBuffer.setCursor(0, 0); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + gotoBufferEnd(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + this.editBuffer.gotoLine(999999); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + selectAll() { + this.updateSelectionForMovement(false, true); + this.editBuffer.setCursor(0, 0); + return this.gotoBufferEnd({ select: true }); + } + deleteToLineEnd() { + const cursor = this.editorView.getCursor(); + const eol = this.editBuffer.getEOL(); + if (eol.col > cursor.col) { + this.editBuffer.deleteRange(cursor.row, cursor.col, eol.row, eol.col); + } + this.requestRender(); + return true; + } + deleteToLineStart() { + const cursor = this.editorView.getCursor(); + if (cursor.col > 0) { + this.editBuffer.deleteRange(cursor.row, 0, cursor.row, cursor.col); + } else if (cursor.row > 0) { + this.editBuffer.deleteCharBackward(); + } + this.requestRender(); + return true; + } + undo() { + this._ctx.clearSelection(); + this.editBuffer.undo(); + this.requestRender(); + return true; + } + redo() { + this._ctx.clearSelection(); + this.editBuffer.redo(); + this.requestRender(); + return true; + } + moveWordForward(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + const nextWord = this.editBuffer.getNextWordBoundary(); + this.editBuffer.setCursorByOffset(nextWord.offset); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + moveWordBackward(options) { + const select = options?.select ?? false; + this.updateSelectionForMovement(select, true); + const prevWord = this.editBuffer.getPrevWordBoundary(); + this.editBuffer.setCursorByOffset(prevWord.offset); + this.updateSelectionForMovement(select, false); + this.requestRender(); + return true; + } + deleteWordForward() { + if (this.hasSelection()) { + this.deleteSelectedText(); + return true; + } + const currentCursor = this.editBuffer.getCursorPosition(); + const nextWord = this.editBuffer.getNextWordBoundary(); + if (nextWord.offset > currentCursor.offset) { + this.editBuffer.deleteRange(currentCursor.row, currentCursor.col, nextWord.row, nextWord.col); + } + this._ctx.clearSelection(); + this.requestRender(); + return true; + } + deleteWordBackward() { + if (this.hasSelection()) { + this.deleteSelectedText(); + return true; + } + const currentCursor = this.editBuffer.getCursorPosition(); + const prevWord = this.editBuffer.getPrevWordBoundary(); + if (prevWord.offset < currentCursor.offset) { + this.editBuffer.deleteRange(prevWord.row, prevWord.col, currentCursor.row, currentCursor.col); + } + this._ctx.clearSelection(); + this.requestRender(); + return true; + } + setupMeasureFunc() { + const measureFunc = (width, widthMode, height, heightMode) => { + let effectiveWidth; + if (widthMode === 0 /* Undefined */ || isNaN(width)) { + effectiveWidth = 0; + } else { + effectiveWidth = width; + } + const effectiveHeight = isNaN(height) ? 1 : height; + const measureResult = this.editorView.measureForDimensions(Math.floor(effectiveWidth), Math.floor(effectiveHeight)); + const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1; + const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1; + if (widthMode === 2 /* AtMost */ && this._positionType !== "absolute") { + return { + width: Math.min(effectiveWidth, measuredWidth), + height: Math.min(effectiveHeight, measuredHeight) + }; + } + return { + width: measuredWidth, + height: measuredHeight + }; + }; + this.yogaNode.setMeasureFunc(measureFunc); + } + render(buffer, deltaTime) { + if (!this.visible) + return; + if (this.isDestroyed) + return; + const screenX = this._screenX; + const screenY = this._screenY; + this.markClean(); + this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num); + this.renderSelf(buffer); + this.renderCursor(buffer); + } + renderSelf(buffer) { + buffer.drawEditorView(this.editorView, this._screenX, this._screenY); + } + renderCursor(buffer) { + if (!this._showCursor || !this._focused) + return; + const visualCursor = this.editorView.getVisualCursor(); + const screenX = this._screenX; + const screenY = this._screenY; + const cursorX = screenX + visualCursor.visualCol + 1; + const cursorY = screenY + visualCursor.visualRow + 1; + this._ctx.setCursorPosition(cursorX, cursorY, true); + this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor }); + } + focus() { + super.focus(); + this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor }); + this.requestRender(); + } + blur() { + super.blur(); + this._ctx.setCursorPosition(0, 0, false); + this.requestRender(); + } + onRemove() { + if (this._focused) { + this._ctx.setCursorPosition(0, 0, false); + } + } + destroy() { + if (this.isDestroyed) + return; + this.traits = {}; + if (this._focused) { + this._ctx.setCursorPosition(0, 0, false); + this.blur(); + } + this.editorView.destroy(); + this.editBuffer.destroy(); + super.destroy(); + } + set onCursorChange(handler) { + this._cursorChangeListener = handler; + } + get onCursorChange() { + return this._cursorChangeListener; + } + set onContentChange(handler) { + this._contentChangeListener = handler; + } + get onContentChange() { + return this._contentChangeListener; + } + get syntaxStyle() { + return this.editBuffer.getSyntaxStyle(); + } + set syntaxStyle(style) { + this.editBuffer.setSyntaxStyle(style); + this.requestRender(); + } + addHighlight(lineIdx, highlight) { + this.editBuffer.addHighlight(lineIdx, highlight); + this.requestRender(); + } + addHighlightByCharRange(highlight) { + this.editBuffer.addHighlightByCharRange(highlight); + this.requestRender(); + } + removeHighlightsByRef(hlRef) { + this.editBuffer.removeHighlightsByRef(hlRef); + this.requestRender(); + } + clearLineHighlights(lineIdx) { + this.editBuffer.clearLineHighlights(lineIdx); + this.requestRender(); + } + clearAllHighlights() { + this.editBuffer.clearAllHighlights(); + this.requestRender(); + } + getLineHighlights(lineIdx) { + return this.editBuffer.getLineHighlights(lineIdx); + } + setText(text) { + this.editBuffer.setText(text); + this.yogaNode.markDirty(); + this.requestRender(); + } + replaceText(text) { + this.editBuffer.replaceText(text); + this.yogaNode.markDirty(); + this.requestRender(); + } + clear() { + this.editBuffer.clear(); + this.editBuffer.clearAllHighlights(); + this.yogaNode.markDirty(); + this.requestRender(); + } + deleteRange(startLine, startCol, endLine, endCol) { + this.editBuffer.deleteRange(startLine, startCol, endLine, endCol); + this.yogaNode.markDirty(); + this.requestRender(); + } + getTextRange(startOffset, endOffset) { + return this.editBuffer.getTextRange(startOffset, endOffset); + } + getTextRangeByCoords(startRow, startCol, endRow, endCol) { + return this.editBuffer.getTextRangeByCoords(startRow, startCol, endRow, endCol); + } + updateSelectionForMovement(shiftPressed, isBeforeMovement) { + if (!this.selectable) + return; + if (!shiftPressed) { + this._keyboardSelectionActive = false; + this._ctx.clearSelection(); + return; + } + this._keyboardSelectionActive = true; + const visualCursor = this.editorView.getVisualCursor(); + const cursorX = this.x + visualCursor.visualCol; + const cursorY = this.y + visualCursor.visualRow; + if (isBeforeMovement) { + if (!this._ctx.hasSelection) { + this._ctx.startSelection(this, cursorX, cursorY); + } + return; + } + this._ctx.updateSelection(this, cursorX, cursorY, { finishDragging: true }); + } +} + +// src/ansi.ts +var ANSI = { + switchToAlternateScreen: "\x1B[?1049h", + switchToMainScreen: "\x1B[?1049l", + reset: "\x1B[0m", + resetScrollRegion: "\x1B[r", + home: "\x1B[H", + clearScreen: "\x1B[2J", + clearSavedLines: "\x1B[3J", + scrollDown: (lines) => `\x1B[${lines}T`, + scrollUp: (lines) => `\x1B[${lines}S`, + moveCursor: (row, col) => `\x1B[${row};${col}H`, + moveCursorAndClear: (row, col) => `\x1B[${row};${col}H\x1B[J`, + setRgbBackground: (r, g, b) => `\x1B[48;2;${r};${g};${b}m`, + resetBackground: "\x1B[49m", + bracketedPasteStart: "\x1B[200~", + bracketedPasteEnd: "\x1B[201~" +}; + +// src/lib/clipboard.ts +function encodeOsc52Payload(text, encoder = new TextEncoder) { + const base64 = Buffer.from(text).toString("base64"); + return encoder.encode(base64); +} + +class Clipboard { + lib; + rendererPtr; + constructor(lib, rendererPtr) { + this.lib = lib; + this.rendererPtr = rendererPtr; + } + copyToClipboardOSC52(text, target = 0 /* Clipboard */) { + if (!this.isOsc52Supported()) { + return false; + } + const payload = encodeOsc52Payload(text, this.lib.encoder); + return this.lib.copyToClipboardOSC52(this.rendererPtr, target, payload); + } + clearClipboardOSC52(target = 0 /* Clipboard */) { + if (!this.isOsc52Supported()) { + return false; + } + return this.lib.clearClipboardOSC52(this.rendererPtr, target); + } + isOsc52Supported() { + const caps = this.lib.getTerminalCapabilities(this.rendererPtr); + return Boolean(caps?.osc52); + } +} + +// src/renderer.ts +import { EventEmitter as EventEmitter5 } from "events"; + +// src/lib/objects-in-viewport.ts +function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) { + if (viewport.width <= 0 || viewport.height <= 0) { + return []; + } + if (objects.length === 0) { + return []; + } + if (objects.length < minTriggerSize) { + return objects; + } + const viewportTop = viewport.y - padding; + const viewportBottom = viewport.y + viewport.height + padding; + const viewportLeft = viewport.x - padding; + const viewportRight = viewport.x + viewport.width + padding; + const isRow = direction === "row"; + const children = objects; + const totalChildren = children.length; + if (totalChildren === 0) + return []; + const vpStart = isRow ? viewportLeft : viewportTop; + const vpEnd = isRow ? viewportRight : viewportBottom; + let lo = 0; + let hi = totalChildren - 1; + let candidate = -1; + while (lo <= hi) { + const mid = lo + hi >> 1; + const c = children[mid]; + const start = isRow ? c.screenX : c.screenY; + const end = isRow ? c.screenX + c.width : c.screenY + c.height; + if (end < vpStart) { + lo = mid + 1; + } else if (start > vpEnd) { + hi = mid - 1; + } else { + candidate = mid; + break; + } + } + const visibleChildren = []; + if (candidate === -1) { + candidate = lo > 0 ? lo - 1 : 0; + } + const maxLookBehind = 50; + let left = candidate; + let gapCount = 0; + while (left - 1 >= 0) { + const prev = children[left - 1]; + const prevEnd = isRow ? prev.screenX + prev.width : prev.screenY + prev.height; + if (prevEnd <= vpStart) { + gapCount++; + if (gapCount >= maxLookBehind) { + break; + } + } else { + gapCount = 0; + } + left--; + } + let right = candidate + 1; + while (right < totalChildren) { + const next = children[right]; + if ((isRow ? next.screenX : next.screenY) >= vpEnd) + break; + right++; + } + for (let i = left;i < right; i++) { + const child = children[i]; + const start = isRow ? child.screenX : child.screenY; + const end = isRow ? child.screenX + child.width : child.screenY + child.height; + if (end <= vpStart) + continue; + if (start >= vpEnd) + break; + if (isRow) { + const childBottom = child.screenY + child.height; + if (childBottom < viewportTop) + continue; + const childTop = child.screenY; + if (childTop > viewportBottom) + continue; + } else { + const childRight = child.screenX + child.width; + if (childRight < viewportLeft) + continue; + const childLeft = child.screenX; + if (childLeft > viewportRight) + continue; + } + visibleChildren.push(child); + } + if (visibleChildren.length > 1) { + visibleChildren.sort((a, b) => a.zIndex > b.zIndex ? 1 : a.zIndex < b.zIndex ? -1 : 0); + } + return visibleChildren; +} + +// src/lib/render-geometry.ts +function calculateRenderGeometry(screenMode, terminalWidth, terminalHeight, footerHeight) { + const safeTerminalWidth = Math.max(terminalWidth, 0); + const safeTerminalHeight = Math.max(terminalHeight, 0); + if (screenMode !== "split-footer") { + return { + effectiveFooterHeight: 0, + renderOffset: 0, + renderWidth: safeTerminalWidth, + renderHeight: safeTerminalHeight + }; + } + const effectiveFooterHeight = Math.min(footerHeight, safeTerminalHeight); + return { + effectiveFooterHeight, + renderOffset: safeTerminalHeight - effectiveFooterHeight, + renderWidth: safeTerminalWidth, + renderHeight: effectiveFooterHeight + }; +} + +// src/lib/terminal-capability-detection.ts +function isCapabilityResponse(sequence) { + if (/\x1b\[\?\d+(?:;\d+)*\$y/.test(sequence)) { + return true; + } + if (/\x1b\[1;(?!1R)\d+R/.test(sequence)) { + return true; + } + if (/\x1bP>\|[\s\S]*?\x1b\\/.test(sequence)) { + return true; + } + if (/\x1b_G[\s\S]*?\x1b\\/.test(sequence)) { + return true; + } + if (/\x1b\[\?\d+(?:;\d+)?u/.test(sequence)) { + return true; + } + if (/\x1b\[\?[0-9;]*c/.test(sequence)) { + return true; + } + if (/\x1b\]99;[^\x07\x1b]*i=opentui-notifications[^\x07\x1b]*p=\?[\s\S]*?(?:\x07|\x1b\\)/.test(sequence)) { + return true; + } + if (/\x1b\]1337;Capabilities=[\s\S]*?(?:\x07|\x1b\\)/.test(sequence)) { + return true; + } + return false; +} +function isPixelResolutionResponse(sequence) { + return /\x1b\[4;\d+;\d+t/.test(sequence); +} +function parsePixelResolution(sequence) { + const match = sequence.match(/\x1b\[4;(\d+);(\d+)t/); + if (match) { + return { + width: parseInt(match[2]), + height: parseInt(match[1]) + }; + } + return null; +} + +// src/renderer-theme-mode.ts +var OSC_THEME_RESPONSE = /\x1b](10|11);(?:(?:rgb:)([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\x07|\x1b\\)/g; +function scaleOscThemeComponent(component) { + const value = parseInt(component, 16); + const maxValue = (1 << 4 * component.length) - 1; + return Math.round(value / maxValue * 255).toString(16).padStart(2, "0"); +} +function oscThemeColorToHex(r, g, b, hex6) { + if (hex6) { + return `#${hex6.toLowerCase()}`; + } + if (r && g && b) { + return `#${scaleOscThemeComponent(r)}${scaleOscThemeComponent(g)}${scaleOscThemeComponent(b)}`; + } + return "#000000"; +} +function inferThemeModeFromBackgroundColor(color) { + const [r, g, b] = parseColor(color).toInts(); + const brightness = (r * 299 + g * 587 + b * 114) / 1000; + return brightness > 128 ? "light" : "dark"; +} + +class RendererThemeMode { + host; + clock; + static QUERY_TIMEOUT_MS = 250; + _themeMode = null; + themeQueryPending = true; + themeOscForeground = null; + themeOscBackground = null; + themeRefreshTimeoutId = null; + waiters = new Set; + constructor(host, clock) { + this.host = host; + this.clock = clock; + } + get themeMode() { + return this._themeMode; + } + waitForThemeMode(timeoutMs, isDestroyed) { + if (this._themeMode !== null || isDestroyed || timeoutMs === 0) { + return Promise.resolve(this._themeMode); + } + return new Promise((resolve) => { + const waiter = { + resolve, + timeoutHandle: null + }; + if (timeoutMs > 0) { + waiter.timeoutHandle = this.clock.setTimeout(() => { + this.waiters.delete(waiter); + waiter.timeoutHandle = null; + resolve(this._themeMode); + }, timeoutMs); + } + this.waiters.add(waiter); + }); + } + cancelRefresh() { + if (this.themeRefreshTimeoutId === null) { + return; + } + this.clock.clearTimeout(this.themeRefreshTimeoutId); + this.themeRefreshTimeoutId = null; + this.themeQueryPending = false; + } + dispose() { + this.cancelRefresh(); + for (const waiter of this.waiters) { + if (waiter.timeoutHandle !== null) { + this.clock.clearTimeout(waiter.timeoutHandle); + } + waiter.resolve(this._themeMode); + } + this.waiters.clear(); + } + handleSequence(sequence) { + if (sequence === "\x1B[?997;1n" || sequence === "\x1B[?997;2n") { + this.requestThemeOscColors(); + return { handled: true, changedMode: null }; + } + let handledOscThemeResponse = false; + let match; + OSC_THEME_RESPONSE.lastIndex = 0; + while (match = OSC_THEME_RESPONSE.exec(sequence)) { + handledOscThemeResponse = true; + const color = oscThemeColorToHex(match[2], match[3], match[4], match[5]); + if (match[1] === "10") { + this.themeOscForeground = color; + } else { + this.themeOscBackground = color; + } + } + if (!handledOscThemeResponse) { + return { handled: false, changedMode: null }; + } + if (!this.themeQueryPending) { + return { handled: true, changedMode: null }; + } + if (!this.themeOscForeground || !this.themeOscBackground) { + return { handled: true, changedMode: null }; + } + const nextMode = inferThemeModeFromBackgroundColor(this.themeOscBackground); + const changedMode = this.applyThemeMode(nextMode); + this.completeThemeQuery(); + return { handled: true, changedMode }; + } + clearThemeRefreshTimeout() { + if (this.themeRefreshTimeoutId === null) { + return; + } + this.clock.clearTimeout(this.themeRefreshTimeoutId); + this.themeRefreshTimeoutId = null; + } + completeThemeQuery() { + this.clearThemeRefreshTimeout(); + this.themeQueryPending = false; + } + requestThemeOscColors() { + if (this.themeRefreshTimeoutId !== null) { + return; + } + this.themeQueryPending = true; + this.themeOscForeground = null; + this.themeOscBackground = null; + this.host.queryThemeColors(); + this.clearThemeRefreshTimeout(); + this.themeRefreshTimeoutId = this.clock.setTimeout(() => { + this.completeThemeQuery(); + }, RendererThemeMode.QUERY_TIMEOUT_MS); + } + applyThemeMode(mode) { + const changed = this._themeMode !== mode; + this._themeMode = mode; + if (!changed) { + return null; + } + for (const waiter of this.waiters) { + if (waiter.timeoutHandle !== null) { + this.clock.clearTimeout(waiter.timeoutHandle); + } + waiter.resolve(mode); + } + this.waiters.clear(); + return mode; + } +} + +// src/renderer.ts +registerEnvVar({ + name: "OTUI_DUMP_CAPTURES", + description: "Dump captured stdout and console caches when the renderer exit handler runs.", + type: "boolean", + default: false +}); +registerEnvVar({ + name: "OTUI_NO_NATIVE_RENDER", + description: "Skip the Zig/native frame renderer. Useful for debugging the render loop; split-footer stdout flushing may still write ANSI.", + type: "boolean", + default: false +}); +registerEnvVar({ + name: "OTUI_USE_ALTERNATE_SCREEN", + description: "When explicitly set, force screen mode selection: true=alternate-screen, false=main-screen.", + type: "boolean", + default: true +}); +registerEnvVar({ + name: "OTUI_OVERRIDE_STDOUT", + description: "When explicitly set, force stdout routing: false=passthrough, true=capture in split-footer mode.", + type: "boolean", + default: true +}); +registerEnvVar({ + name: "OTUI_DEBUG", + description: "Enable debug mode to capture all raw input for debugging purposes.", + type: "boolean", + default: false +}); +registerEnvVar({ + name: "OTUI_SHOW_STATS", + description: "Show the debug overlay at startup.", + type: "boolean", + default: false +}); +var DEFAULT_FOOTER_HEIGHT = 12; +var MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES = 4; +var TRANSPARENT_RGBA = RGBA.fromValues(0, 0, 0, 0); +var scrollbackSurfaceCounter = 0; +function normalizeFooterHeight(footerHeight) { + if (footerHeight === undefined) { + return DEFAULT_FOOTER_HEIGHT; + } + if (!Number.isFinite(footerHeight)) { + throw new Error("footerHeight must be a finite number"); + } + const normalizedFooterHeight = Math.trunc(footerHeight); + if (normalizedFooterHeight <= 0) { + throw new Error("footerHeight must be greater than 0"); + } + return normalizedFooterHeight; +} +function resolveModes(config) { + let screenMode = config.screenMode ?? "alternate-screen"; + if (process.env.OTUI_USE_ALTERNATE_SCREEN !== undefined) { + screenMode = env.OTUI_USE_ALTERNATE_SCREEN ? "alternate-screen" : "main-screen"; + } + const footerHeight = screenMode === "split-footer" ? normalizeFooterHeight(config.footerHeight) : DEFAULT_FOOTER_HEIGHT; + let externalOutputMode = config.externalOutputMode ?? (screenMode === "split-footer" ? "capture-stdout" : "passthrough"); + if (process.env.OTUI_OVERRIDE_STDOUT !== undefined) { + externalOutputMode = env.OTUI_OVERRIDE_STDOUT && screenMode === "split-footer" ? "capture-stdout" : "passthrough"; + } + if (externalOutputMode === "capture-stdout" && screenMode !== "split-footer") { + throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"'); + } + return { + screenMode, + footerHeight, + externalOutputMode + }; +} + +class ExternalOutputQueue { + commits = []; + get size() { + return this.commits.length; + } + writeSnapshot(commit) { + this.commits.push(commit); + } + peek(limit = Number.POSITIVE_INFINITY) { + const clampedLimit = Number.isFinite(limit) ? Math.max(1, Math.trunc(limit)) : this.commits.length; + return this.commits.slice(0, clampedLimit); + } + claim(limit = Number.POSITIVE_INFINITY) { + if (this.commits.length === 0) { + return []; + } + const clampedLimit = Number.isFinite(limit) ? Math.max(1, Math.trunc(limit)) : this.commits.length; + if (clampedLimit >= this.commits.length) { + const output2 = this.commits; + this.commits = []; + return output2; + } + const output = this.commits.slice(0, clampedLimit); + this.commits = this.commits.slice(clampedLimit); + return output; + } + drop(count) { + for (const commit of this.commits.splice(0, count)) { + commit.snapshot.destroy(); + } + } + clear() { + this.drop(this.commits.length); + } +} +var CHAR_FLAG_CONTINUATION = 3221225472 >>> 0; +var CHAR_FLAG_MASK = 3221225472 >>> 0; + +class ScrollbackSnapshotRenderContext extends EventEmitter5 { + width; + height; + frameId = 0; + widthMethod; + capabilities = null; + hasSelection = false; + currentFocusedRenderable = null; + keyInput; + _internalKeyInput; + lifecyclePasses = new Set; + constructor(width, height, widthMethod) { + super(); + this.width = width; + this.height = height; + this.widthMethod = widthMethod; + this.keyInput = new KeyHandler; + this._internalKeyInput = new InternalKeyHandler; + } + addToHitGrid(_x, _y, _width, _height, _id) {} + pushHitGridScissorRect(_x, _y, _width, _height) {} + popHitGridScissorRect() {} + clearHitGridScissorRects() {} + requestRender() {} + setCursorPosition(_x, _y, _visible) {} + setCursorStyle(_options) {} + setCursorColor(_color) {} + setMousePointer(_shape) {} + requestLive() {} + dropLive() {} + getSelection() { + return null; + } + get currentFocusedEditor() { + if (!this.currentFocusedRenderable) + return null; + if (!isEditBufferRenderable(this.currentFocusedRenderable)) + return null; + return this.currentFocusedRenderable; + } + requestSelectionUpdate() {} + focusRenderable(renderable) { + this.currentFocusedRenderable = renderable; + } + blurRenderable(renderable) { + if (this.currentFocusedRenderable === renderable) { + this.currentFocusedRenderable = null; + } + } + registerLifecyclePass(renderable) { + this.lifecyclePasses.add(renderable); + } + unregisterLifecyclePass(renderable) { + this.lifecyclePasses.delete(renderable); + } + getLifecyclePasses() { + return this.lifecyclePasses; + } + clearSelection() {} + startSelection(_renderable, _x, _y) {} + updateSelection(_currentRenderable, _x, _y, _options) {} +} +var DEFAULT_FORWARDED_ENV_KEYS = [ + "TMUX", + "ZELLIJ", + "ZELLIJ_SESSION_NAME", + "ZELLIJ_PANE_ID", + "TERM", + "OPENTUI_GRAPHICS", + "TERM_PROGRAM", + "TERM_PROGRAM_VERSION", + "TERM_FEATURES", + "ALACRITTY_SOCKET", + "ALACRITTY_LOG", + "COLORTERM", + "TERMUX_VERSION", + "VHS_RECORD", + "OPENTUI_FORCE_WCWIDTH", + "OPENTUI_FORCE_UNICODE", + "OPENTUI_FORCE_NOZWJ", + "OPENTUI_FORCE_EXPLICIT_WIDTH", + "OPENTUI_NOTIFICATION_PROTOCOL", + "OPENTUI_NOTIFICATIONS", + "WT_SESSION", + "STY", + "WSL_DISTRO_NAME", + "WSL_INTEROP" +]; +var NATIVE_RENDER_STATUS_SKIPPED = 1; +var NATIVE_RENDER_STATUS_FAILED = 2; +var KITTY_FLAG_DISAMBIGUATE = 1; +var KITTY_FLAG_EVENT_TYPES = 2; +var KITTY_FLAG_ALTERNATE_KEYS = 4; +var KITTY_FLAG_ALL_KEYS_AS_ESCAPES = 8; +var KITTY_FLAG_REPORT_TEXT = 16; +var DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES = 64 * 1024 * 1024; +var NATIVE_PALETTE_QUERY_SIZE = 16; +function buildKittyKeyboardFlags(config) { + if (!config) { + return 0; + } + let flags = 0; + if (config.disambiguate !== false) { + flags |= KITTY_FLAG_DISAMBIGUATE; + } + if (config.alternateKeys !== false) { + flags |= KITTY_FLAG_ALTERNATE_KEYS; + } + if (config.events === true) { + flags |= KITTY_FLAG_EVENT_TYPES; + } + if (config.allKeysAsEscapes === true) { + flags |= KITTY_FLAG_ALL_KEYS_AS_ESCAPES; + } + if (config.reportText === true) { + flags |= KITTY_FLAG_REPORT_TEXT; + } + return flags; +} + +class MouseEvent { + type; + button; + x; + y; + source; + modifiers; + scroll; + target; + isDragging; + _propagationStopped = false; + _defaultPrevented = false; + get propagationStopped() { + return this._propagationStopped; + } + get defaultPrevented() { + return this._defaultPrevented; + } + constructor(target, attributes) { + this.target = target; + this.type = attributes.type; + this.button = attributes.button; + this.x = attributes.x; + this.y = attributes.y; + this.modifiers = attributes.modifiers; + this.scroll = attributes.scroll; + this.source = attributes.source; + this.isDragging = attributes.isDragging; + } + stopPropagation() { + this._propagationStopped = true; + } + preventDefault() { + this._defaultPrevented = true; + } +} +var MouseButton; +((MouseButton2) => { + MouseButton2[MouseButton2["LEFT"] = 0] = "LEFT"; + MouseButton2[MouseButton2["MIDDLE"] = 1] = "MIDDLE"; + MouseButton2[MouseButton2["RIGHT"] = 2] = "RIGHT"; + MouseButton2[MouseButton2["WHEEL_UP"] = 4] = "WHEEL_UP"; + MouseButton2[MouseButton2["WHEEL_DOWN"] = 5] = "WHEEL_DOWN"; +})(MouseButton ||= {}); +var rendererTracker = singleton("RendererTracker", () => ({ + renderers: new Set, + streamOwners: new WeakMap +})); +async function createCliRenderer(config = {}) { + if (process.argv.includes("--delay-start")) { + await new Promise((resolve) => setTimeout(resolve, 5000)); + } + const stdin = config.stdin ?? process.stdin; + const stdout = config.stdout ?? process.stdout; + const width = stdout.columns || config.width || 80; + const height = stdout.rows || config.height || 24; + const renderer = new CliRenderer(stdin, stdout, width, height, config); + try { + await renderer.setupTerminal(); + return renderer; + } catch (error) { + try { + renderer.destroy(); + } catch (destroyError) { + console.error("Error destroying partially-set-up renderer:", destroyError); + } + throw error; + } +} +var CliRenderEvents; +((CliRenderEvents2) => { + CliRenderEvents2["RESIZE"] = "resize"; + CliRenderEvents2["FRAME"] = "frame"; + CliRenderEvents2["EXTERNAL_OUTPUT"] = "external_output"; + CliRenderEvents2["FOCUS"] = "focus"; + CliRenderEvents2["BLUR"] = "blur"; + CliRenderEvents2["FOCUSED_RENDERABLE"] = "focused_renderable"; + CliRenderEvents2["FOCUSED_EDITOR"] = "focused_editor"; + CliRenderEvents2["THEME_MODE"] = "theme_mode"; + CliRenderEvents2["PALETTE"] = "palette"; + CliRenderEvents2["CAPABILITIES"] = "capabilities"; + CliRenderEvents2["SELECTION"] = "selection"; + CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle"; + CliRenderEvents2["DESTROY"] = "destroy"; + CliRenderEvents2["MEMORY_SNAPSHOT"] = "memory:snapshot"; +})(CliRenderEvents ||= {}); +var RendererControlState; +((RendererControlState2) => { + RendererControlState2["IDLE"] = "idle"; + RendererControlState2["AUTO_STARTED"] = "auto_started"; + RendererControlState2["EXPLICIT_STARTED"] = "explicit_started"; + RendererControlState2["EXPLICIT_PAUSED"] = "explicit_paused"; + RendererControlState2["EXPLICIT_SUSPENDED"] = "explicit_suspended"; + RendererControlState2["EXPLICIT_STOPPED"] = "explicit_stopped"; +})(RendererControlState ||= {}); + +class CliRenderer extends EventEmitter5 { + static animationFrameId = 0; + lib; + rendererPtr; + stdin; + stdout; + exitOnCtrlC; + exitSignals; + _exitListenersAdded = false; + _isDestroyed = false; + _destroyPending = false; + _destroyFinalized = false; + _destroyCleanupPrepared = false; + _streamLeaseAcquired = false; + nextRenderBuffer; + currentRenderBuffer; + _isRunning = false; + _targetFps = 30; + _maxFps = 60; + automaticMemorySnapshot = false; + memorySnapshotInterval; + memorySnapshotTimer = null; + lastMemorySnapshot = { + heapUsed: 0, + heapTotal: 0, + arrayBuffers: 0 + }; + root; + width; + height; + _useThread = false; + gatherStats = false; + frameTimes = []; + maxStatSamples = 300; + postProcessFns = []; + backgroundColor = RGBA.fromInts(0, 0, 0, 0); + waitingForPixelResolution = false; + clock; + rendering = false; + renderingNative = false; + renderTimeout = null; + lastTime = 0; + frameCount = 0; + _frameId = 0; + lastFpsTime = 0; + currentFps = 0; + targetFrameTime = 1000 / this._targetFps; + minTargetFrameTime = 1000 / this._maxFps; + immediateRerenderRequested = false; + updateScheduled = false; + liveRequestCounter = 0; + _controlState = "idle" /* IDLE */; + frameCallbacks = []; + renderStats = { + frameCount: 0, + fps: 0, + renderTime: 0, + frameCallbackTime: 0 + }; + debugOverlay = { + enabled: env.OTUI_SHOW_STATS, + corner: 3 /* bottomRight */ + }; + _console; + _resolution = null; + _keyHandler; + stdinParser = null; + oscSubscribers = new Set; + hasLoggedStdinParserError = false; + animationRequest = new Map; + resizeTimeoutId = null; + capabilityTimeoutId = null; + xtVersionWaiters = new Set; + splitStartupSeedTimeoutId = null; + pendingSplitStartupCursorSeed = false; + resizeDebounceDelay = 100; + enableMouseMovement = false; + _useMouse = true; + autoFocus = true; + _screenMode = "alternate-screen"; + _footerHeight = DEFAULT_FOOTER_HEIGHT; + _externalOutputMode = "passthrough"; + clearOnShutdown = true; + _suspendedMouseEnabled = false; + _previousControlState = "idle" /* IDLE */; + pendingSuspendedTerminalSetup = false; + suspendedNonAltSurfacePreserved = false; + capturedRenderable; + lastOverRenderableNum = 0; + lastOverRenderable; + currentSelection = null; + selectionContainers = []; + clipboard; + _splitHeight = 0; + renderOffset = 0; + splitTailColumn = 0; + pendingSplitFooterTransition = null; + forceFullRepaintRequested = false; + maxSplitCommitsPerFrame = 8; + _terminalWidth = 0; + _terminalHeight = 0; + _terminalIsSetup = false; + externalOutputQueue = new ExternalOutputQueue; + pendingExternalOutputMode = null; + realStdoutWrite; + _useConsole = true; + sigwinchHandler = (() => { + const width = this.stdout.columns || 80; + const height = this.stdout.rows || 24; + this.handleResize(width, height); + }).bind(this); + _capabilities = null; + _latestPointer = { x: 0, y: 0 }; + _hasPointer = false; + _lastPointerModifiers = { + shift: false, + alt: false, + ctrl: false + }; + _currentMousePointerStyle = undefined; + _currentFocusedRenderable = null; + lifecyclePasses = new Set; + _openConsoleOnError = true; + _paletteDetector = null; + _paletteCache = new Map; + _paletteDetectionPromise = null; + _paletteDetectionSize = 0; + _paletteEpoch = 0; + _nativePaletteSignature = null; + _emittedPaletteSignature = null; + _palettePublishGeneration = 0; + _onDestroy; + themeModeState; + _terminalFocusState = null; + sequenceHandlers = []; + prependedInputHandlers = []; + shouldRestoreModesOnNextFocus = false; + themeModeHandler; + idleResolvers = []; + _debugInputs = []; + _debugModeEnabled = env.OTUI_DEBUG; + handleError = ((error) => { + console.error(error); + if (this._openConsoleOnError) { + this.console.show(); + } + }).bind(this); + dumpOutputCache(optionalMessage = "") { + const cachedLogs = this.console.getCachedLogs(); + const capturedConsoleOutput = capture.claimOutput(); + const capturedExternalOutputCommits = this.externalOutputQueue.claim(); + let capturedExternalOutput = ""; + for (const commit of capturedExternalOutputCommits) { + capturedExternalOutput += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}] +`; + commit.snapshot.destroy(); + } + if (capturedConsoleOutput.length > 0 || capturedExternalOutput.length > 0 || cachedLogs.length > 0) { + this.realStdoutWrite.call(this.stdout, optionalMessage); + } + if (cachedLogs.length > 0) { + this.realStdoutWrite.call(this.stdout, `Console cache: +`); + this.realStdoutWrite.call(this.stdout, cachedLogs); + } + if (capturedConsoleOutput.length > 0) { + this.realStdoutWrite.call(this.stdout, ` +Captured console output: +`); + this.realStdoutWrite.call(this.stdout, capturedConsoleOutput + ` +`); + } + if (capturedExternalOutput.length > 0) { + this.realStdoutWrite.call(this.stdout, ` +Captured external output: +`); + this.realStdoutWrite.call(this.stdout, capturedExternalOutput + ` +`); + } + this.realStdoutWrite.call(this.stdout, ANSI.reset); + } + exitHandler = (() => { + this.destroy(); + if (env.OTUI_DUMP_CAPTURES) { + sleep(100).then(() => { + this.dumpOutputCache(`=== CAPTURED OUTPUT === +`); + }); + } + }).bind(this); + warningHandler = ((warning) => { + console.warn(JSON.stringify(warning.message, null, 2)); + }).bind(this); + _usesProcessStdout; + _feed = null; + _detachFeed = null; + _detachFeedError = null; + feedIdleRenderScheduled = false; + ordinaryFrameWaitingForFeed = false; + ordinaryFrameWaitControlState = null; + get controlState() { + return this._controlState; + } + constructor(stdin, stdout, width, height, config = {}) { + super(); + this.stdin = stdin; + this.stdout = stdout; + this._usesProcessStdout = stdout === process.stdout; + this.realStdoutWrite = stdout.write; + const lib = resolveRenderLib(); + const useMemoryBufferedOutput = config.bufferedOutput === "memory"; + const useFeedOutput = !this._usesProcessStdout && !useMemoryBufferedOutput; + const { screenMode, footerHeight, externalOutputMode } = resolveModes(config); + const initialGeometry = calculateRenderGeometry(screenMode, width, height, footerHeight); + const remoteMode = config.remote ?? (useFeedOutput ? true : undefined); + if (rendererTracker.streamOwners.get(stdin)) { + throw new Error("Cannot create CliRenderer: stdin is already used by another CliRenderer"); + } + if (rendererTracker.streamOwners.get(stdout)) { + throw new Error("Cannot create CliRenderer: stdout is already used by another CliRenderer"); + } + let feed = null; + if (useFeedOutput) { + try { + feed = NativeSpanFeed.create(); + } catch (error) { + throw new Error(`Failed to allocate NativeSpanFeed for custom stdout: ${error instanceof Error ? error.message : String(error)}`); + } + } + let rendererPtr; + try { + rendererPtr = lib.createRenderer(initialGeometry.renderWidth, initialGeometry.renderHeight, { + remote: remoteMode, + feedPtr: feed?.streamPtr ?? null, + bufferedOutput: config.bufferedOutput + }); + } catch (error) { + feed?.close(); + throw error; + } + if (!rendererPtr) { + feed?.close(); + throw new Error("Failed to create renderer"); + } + if (config.useThread === undefined) + config.useThread = true; + if (process.platform === "linux") + config.useThread = false; + lib.setUseThread(rendererPtr, config.useThread); + const kittyConfig = config.useKittyKeyboard ?? {}; + const kittyFlags = buildKittyKeyboardFlags(kittyConfig); + lib.setKittyKeyboardFlags(rendererPtr, kittyFlags); + this._feed = feed; + if (feed) { + this._detachFeed = feed.onData((bytes) => { + return new Promise((resolve) => { + this.realStdoutWrite.call(this.stdout, bytes, () => resolve()); + }); + }); + this._detachFeedError = feed.onError((code) => { + console.error(`[CliRenderer] NativeSpanFeed error: code=${code}`); + }); + } + this.lib = lib; + this._terminalWidth = width; + this._terminalHeight = height; + this._useThread = config.useThread; + this._externalOutputMode = externalOutputMode; + this.width = initialGeometry.renderWidth; + this.height = initialGeometry.renderHeight; + this._splitHeight = initialGeometry.effectiveFooterHeight; + this.renderOffset = screenMode === "split-footer" ? 0 : initialGeometry.renderOffset; + this._footerHeight = footerHeight; + this.rendererPtr = rendererPtr; + this.clearOnShutdown = config.clearOnShutdown ?? true; + this.lib.setClearOnShutdown(this.rendererPtr, this.clearOnShutdown); + const forwardEnvKeys = config.forwardEnvKeys ?? (config.remote === false ? [...DEFAULT_FORWARDED_ENV_KEYS] : []); + for (const key of forwardEnvKeys) { + const value = process.env[key]; + if (value === undefined) + continue; + this.lib.setTerminalEnvVar(this.rendererPtr, key, value); + } + this.exitOnCtrlC = config.exitOnCtrlC === undefined ? true : config.exitOnCtrlC; + this.exitSignals = config.exitSignals || [ + "SIGINT", + "SIGTERM", + "SIGQUIT", + "SIGABRT", + "SIGHUP", + "SIGBREAK", + "SIGPIPE", + "SIGBUS" + ]; + this.clipboard = new Clipboard(this.lib, this.rendererPtr); + this.resizeDebounceDelay = config.debounceDelay || 100; + this.targetFps = config.targetFps || 30; + this.maxFps = config.maxFps || 60; + this.clock = config.clock ?? new SystemClock; + this.themeModeState = new RendererThemeMode({ + queryThemeColors: () => { + this.lib.queryThemeColors(this.rendererPtr); + } + }, this.clock); + this.themeModeHandler = (sequence) => { + const result = this.themeModeState.handleSequence(sequence); + if (result.changedMode) { + this.clearPaletteCache(); + if (this.shouldSyncNativePaletteState() || this.listenerCount("palette" /* PALETTE */) > 0) { + this.refreshPalette(); + } + this.emit("theme_mode" /* THEME_MODE */, result.changedMode); + } + return result.handled; + }; + this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0; + this.gatherStats = config.gatherStats || false; + this.maxStatSamples = config.maxStatSamples || 300; + this.enableMouseMovement = config.enableMouseMovement ?? true; + this._useMouse = config.useMouse ?? true; + this.autoFocus = config.autoFocus ?? true; + this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr); + this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr); + this.postProcessFns = config.postProcessFns || []; + this.prependedInputHandlers = config.prependInputHandlers || []; + this.root = new RootRenderable(this); + if (this.memorySnapshotInterval > 0) { + this.startMemorySnapshotTimer(); + } + if (this._usesProcessStdout) { + process.on("SIGWINCH", this.sigwinchHandler); + } + process.on("warning", this.warningHandler); + process.on("uncaughtException", this.handleError); + process.on("unhandledRejection", this.handleError); + process.on("beforeExit", this.exitHandler); + const useKittyForParsing = kittyConfig !== null; + this._keyHandler = new InternalKeyHandler; + this._keyHandler.on("keypress", (event) => { + if (this.exitOnCtrlC && matchesKeyBinding(event, { name: "c", ctrl: true })) { + process.nextTick(() => { + this.destroy(); + }); + return; + } + }); + this.addExitListeners(); + const stdinParserMaxBufferBytes = config.stdinParserMaxBufferBytes ?? DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES; + this.stdinParser = new StdinParser({ + timeoutMs: 20, + maxPendingBytes: stdinParserMaxBufferBytes, + armTimeouts: true, + onTimeoutFlush: () => { + this.drainStdinParser(); + }, + useKittyKeyboard: useKittyForParsing, + protocolContext: { + kittyKeyboardEnabled: useKittyForParsing, + privateCapabilityRepliesActive: false, + pixelResolutionQueryActive: false, + explicitWidthCprActive: false, + startupCursorCprActive: false + }, + clock: this.clock + }); + this._console = new TerminalConsole(this, { + ...config.consoleOptions ?? {}, + clock: this.clock + }); + this.consoleMode = config.consoleMode ?? "console-overlay"; + this.applyScreenMode(screenMode, false, false); + rendererTracker.streamOwners.set(stdin, this); + rendererTracker.streamOwners.set(stdout, this); + this._streamLeaseAcquired = true; + rendererTracker.renderers.add(this); + this.stdout.write = externalOutputMode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite; + this._openConsoleOnError = config.openConsoleOnError ?? true; + this._onDestroy = config.onDestroy; + global.requestAnimationFrame = (callback) => { + const id = CliRenderer.animationFrameId++; + this.animationRequest.set(id, callback); + this.requestLive(); + return id; + }; + global.cancelAnimationFrame = (handle) => { + this.animationRequest.delete(handle); + }; + const window = global.window; + if (!window) { + global.window = {}; + } + global.window.requestAnimationFrame = requestAnimationFrame; + if (env.OTUI_NO_NATIVE_RENDER) { + this.renderNative = () => { + if (this._splitHeight > 0) { + this.flushStdoutCache(this._splitHeight); + } + return "rendered"; + }; + } + try { + this.setupInput(); + } catch (error) { + try { + this.destroy(); + } catch (destroyError) { + console.error("Error destroying renderer after input setup failure:", destroyError); + } + throw error; + } + } + addExitListeners() { + if (this._exitListenersAdded || this.exitSignals.length === 0) + return; + this.exitSignals.forEach((signal) => { + process.addListener(signal, this.exitHandler); + }); + this._exitListenersAdded = true; + } + removeExitListeners() { + if (!this._exitListenersAdded || this.exitSignals.length === 0) + return; + this.exitSignals.forEach((signal) => { + process.removeListener(signal, this.exitHandler); + }); + this._exitListenersAdded = false; + } + get isDestroyed() { + return this._isDestroyed; + } + registerLifecyclePass(renderable) { + this.lifecyclePasses.add(renderable); + } + unregisterLifecyclePass(renderable) { + this.lifecyclePasses.delete(renderable); + } + getLifecyclePasses() { + return this.lifecyclePasses; + } + get currentFocusedRenderable() { + return this._currentFocusedRenderable; + } + get currentFocusedEditor() { + if (!this._currentFocusedRenderable) + return null; + if (!isEditBufferRenderable(this._currentFocusedRenderable)) + return null; + return this._currentFocusedRenderable; + } + normalizeClockTime(now, fallback) { + if (Number.isFinite(now)) { + return now; + } + return Number.isFinite(fallback) ? fallback : 0; + } + getElapsedMs(now, then) { + if (!Number.isFinite(now) || !Number.isFinite(then)) { + return 0; + } + return Math.max(now - then, 0); + } + focusRenderable(renderable) { + if (this._currentFocusedRenderable === renderable) { + return; + } + const previousRenderable = this._currentFocusedRenderable; + const previousEditor = this.currentFocusedEditor; + this._currentFocusedRenderable = renderable; + previousRenderable?.blur(); + const currentEditor = this.currentFocusedEditor; + if (previousEditor !== currentEditor) { + this.emit("focused_editor" /* FOCUSED_EDITOR */, currentEditor, previousEditor); + } + this.emit("focused_renderable" /* FOCUSED_RENDERABLE */, renderable, previousRenderable); + } + blurRenderable(renderable) { + if (this._currentFocusedRenderable !== renderable) { + return; + } + const previousEditor = this.currentFocusedEditor; + this._currentFocusedRenderable = null; + if (previousEditor !== null) { + this.emit("focused_editor" /* FOCUSED_EDITOR */, null, previousEditor); + } + this.emit("focused_renderable" /* FOCUSED_RENDERABLE */, null, renderable); + } + setCapturedRenderable(renderable) { + if (this.capturedRenderable === renderable) { + return; + } + this.capturedRenderable = renderable; + } + addToHitGrid(x, y, width, height, id) { + if (!this._useMouse) + return; + if (id !== this.capturedRenderable?.num) { + this.lib.addToHitGrid(this.rendererPtr, x, y, width, height, id); + } + } + pushHitGridScissorRect(x, y, width, height) { + this.lib.hitGridPushScissorRect(this.rendererPtr, x, y, width, height); + } + popHitGridScissorRect() { + this.lib.hitGridPopScissorRect(this.rendererPtr); + } + clearHitGridScissorRects() { + this.lib.hitGridClearScissorRects(this.rendererPtr); + } + get widthMethod() { + const caps = this.capabilities; + return caps?.unicode === "wcwidth" ? "wcwidth" : "unicode"; + } + get frameId() { + return this._frameId; + } + writeOut(chunk, encoding, callback) { + if (this.rendererPtr && (this._useThread || this._feed !== null)) { + const data = typeof chunk === "string" ? chunk : chunk?.toString() ?? ""; + this.lib.writeOut(this.rendererPtr, data); + if (typeof callback === "function") { + process.nextTick(callback); + } + return true; + } + return this.realStdoutWrite.call(this.stdout, chunk, encoding, callback); + } + scheduleRenderAfterFeedIdle() { + const feed = this._feed; + if (!feed || this.feedIdleRenderScheduled || this._isDestroyed) + return; + this.feedIdleRenderScheduled = true; + feed.idle().then(() => { + this.feedIdleRenderScheduled = false; + const ordinaryFrameWasWaiting = this.ordinaryFrameWaitingForFeed; + const ordinaryFrameWaitControlState = this.ordinaryFrameWaitControlState; + this.ordinaryFrameWaitingForFeed = false; + this.ordinaryFrameWaitControlState = null; + if (this._isDestroyed || ordinaryFrameWasWaiting && this._controlState !== ordinaryFrameWaitControlState && (this._controlState === "explicit_paused" /* EXPLICIT_PAUSED */ || this._controlState === "explicit_stopped" /* EXPLICIT_STOPPED */ || this._controlState === "explicit_suspended" /* EXPLICIT_SUSPENDED */)) { + this.resolveIdleIfNeeded(); + return; + } + this.scheduleRenderTimer(); + this.resolveIdleIfNeeded(); + }); + } + handleNativeRenderRejection(status) { + if (status === NATIVE_RENDER_STATUS_SKIPPED && this._feed) { + this.ordinaryFrameWaitingForFeed = true; + this.ordinaryFrameWaitControlState = this._controlState; + this.scheduleRenderAfterFeedIdle(); + return "retryable-skip"; + } + if (status === NATIVE_RENDER_STATUS_SKIPPED) { + console.error("[CliRenderer] Native frame render unexpectedly skipped without a feed"); + return "failed"; + } + return this.reportNativeRenderFailure(); + } + reportNativeRenderFailure() { + console.error("[CliRenderer] Native frame render failed; waiting for the next render request to force repaint"); + return "failed"; + } + scheduleRenderTimer() { + if (this.renderTimeout || this._isDestroyed || this._controlState === "explicit_suspended" /* EXPLICIT_SUSPENDED */) + return; + const now = this.normalizeClockTime(this.clock.now(), this.lastTime); + const elapsed = this.getElapsedMs(now, this.lastTime); + const delay = Math.max(this.minTargetFrameTime - elapsed, 0); + this.renderTimeout = this.clock.setTimeout(() => { + this.renderTimeout = null; + this.loop(); + }, delay); + } + scheduleRenderAfterBackpressure() { + if (this._feed) { + this.scheduleRenderAfterFeedIdle(); + return; + } + this.scheduleRenderTimer(); + } + requestRender() { + if (this._controlState === "explicit_suspended" /* EXPLICIT_SUSPENDED */) { + return; + } + if (this.feedIdleRenderScheduled) { + return; + } + if (this._isRunning) { + if (!this.rendering && !this.renderTimeout && !this.ordinaryFrameWaitingForFeed) { + this.scheduleRenderTimer(); + } + return; + } + if (this.ordinaryFrameWaitingForFeed) { + return; + } + if (this.rendering) { + this.immediateRerenderRequested = true; + return; + } + if (!this.updateScheduled && !this.renderTimeout) { + this.updateScheduled = true; + const now = this.normalizeClockTime(this.clock.now(), this.lastTime); + const elapsed = this.getElapsedMs(now, this.lastTime); + const delay = Math.max(this.minTargetFrameTime - elapsed, 0); + if (delay === 0) { + process.nextTick(() => this.activateFrame()); + return; + } + this.clock.setTimeout(() => this.activateFrame(), delay); + } + } + async activateFrame() { + if (!this.updateScheduled) { + this.resolveIdleIfNeeded(); + return; + } + try { + await this.loop(); + } finally { + this.updateScheduled = false; + this.resolveIdleIfNeeded(); + } + } + get consoleMode() { + return this._useConsole ? "console-overlay" : "disabled"; + } + set consoleMode(mode) { + this._useConsole = mode === "console-overlay"; + if (this._useConsole) { + this.console.activate(); + } else { + this.console.deactivate(); + } + } + get isRunning() { + return this._isRunning; + } + isIdleNow() { + if (this._isDestroyed) + return true; + return !this._isRunning && !this.rendering && !this.renderTimeout && !this.updateScheduled && !this.feedIdleRenderScheduled && !this.immediateRerenderRequested; + } + resolveIdleIfNeeded() { + if (!this.isIdleNow()) + return; + const resolvers = this.idleResolvers.splice(0); + for (const resolve of resolvers) { + resolve(); + } + } + idle() { + if (this._isDestroyed) + return Promise.resolve(); + if (this.isIdleNow()) + return Promise.resolve(); + return new Promise((resolve) => { + this.idleResolvers.push(resolve); + }); + } + getSchedulerState() { + return { + isRunning: this._isRunning, + isRendering: this.rendering, + hasScheduledRender: Boolean(this.renderTimeout || this.updateScheduled || this.immediateRerenderRequested) + }; + } + get resolution() { + return this._resolution; + } + get console() { + return this._console; + } + get keyInput() { + return this._keyHandler; + } + get _internalKeyInput() { + return this._keyHandler; + } + get terminalWidth() { + return this._terminalWidth; + } + get terminalHeight() { + return this._terminalHeight; + } + get useThread() { + return this._useThread; + } + get targetFps() { + return this._targetFps; + } + set targetFps(targetFps) { + this._targetFps = targetFps; + this.targetFrameTime = 1000 / this._targetFps; + } + get maxFps() { + return this._maxFps; + } + set maxFps(maxFps) { + this._maxFps = maxFps; + this.minTargetFrameTime = 1000 / this._maxFps; + } + get useMouse() { + return this._useMouse; + } + set useMouse(useMouse) { + if (this._useMouse === useMouse) + return; + this._useMouse = useMouse; + if (useMouse) { + this.enableMouse(); + this.requestRender(); + } else { + this.disableMouse(); + } + } + get screenMode() { + return this._screenMode; + } + set screenMode(mode) { + if (this.externalOutputMode === "capture-stdout" && mode !== "split-footer") { + if (this.pendingExternalOutputMode === "passthrough") { + this.flushPendingSplitOutputBeforeLeavingSplitFooter(); + } + if (this.externalOutputMode !== "capture-stdout") { + this.applyScreenMode(mode); + return; + } + throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"'); + } + this.applyScreenMode(mode); + } + get footerHeight() { + return this._footerHeight; + } + set footerHeight(footerHeight) { + const normalizedFooterHeight = normalizeFooterHeight(footerHeight); + if (normalizedFooterHeight === this._footerHeight) { + return; + } + this._footerHeight = normalizedFooterHeight; + if (this.screenMode === "split-footer") { + this.applyScreenMode("split-footer"); + } + } + get externalOutputMode() { + return this._externalOutputMode; + } + set externalOutputMode(mode) { + if (mode === "capture-stdout" && this.screenMode !== "split-footer") { + throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"'); + } + const previousMode = this._externalOutputMode; + if (previousMode === mode) { + if (this.pendingExternalOutputMode !== null && this.pendingExternalOutputMode !== mode) { + this.pendingExternalOutputMode = null; + } + return; + } + const canFlushSplitOutputBeforeTransition = this.canFlushSplitOutputBeforeTransition(); + const isSplitCaptureToPassthrough = previousMode === "capture-stdout" && mode === "passthrough" && this._screenMode === "split-footer" && this._splitHeight > 0; + if (isSplitCaptureToPassthrough && this.externalOutputQueue.size > 0 && !canFlushSplitOutputBeforeTransition) { + this.pendingExternalOutputMode = "passthrough"; + return; + } + if (isSplitCaptureToPassthrough && canFlushSplitOutputBeforeTransition) { + this.flushPendingSplitOutputBeforeTransition(); + } + this.pendingExternalOutputMode = null; + this.applyExternalOutputMode(mode); + this.afterExternalOutputModeChanged(previousMode, mode); + } + applyExternalOutputMode(mode) { + this._externalOutputMode = mode; + this.stdout.write = mode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite; + } + afterExternalOutputModeChanged(previousMode, mode) { + if (this._screenMode === "split-footer" && this._splitHeight > 0 && mode === "capture-stdout") { + const previousSurfaceTopLine = this.renderOffset + 1; + const previousSurfaceHeight = this._splitHeight; + this.clearPendingSplitFooterTransition(); + this.resetSplitScrollback(this.getSplitCursorSeedRows()); + if (previousMode === "passthrough" && this._terminalIsSetup) { + const nextSurfaceTopLine = this.renderOffset + 1; + if (previousSurfaceTopLine !== nextSurfaceTopLine) { + this.setPendingSplitFooterTransition({ + mode: "clear-stale-rows", + sourceTopLine: previousSurfaceTopLine, + sourceHeight: previousSurfaceHeight, + targetTopLine: nextSurfaceTopLine, + targetHeight: this._splitHeight, + scrollLines: 0 + }); + this.forceFullRepaintRequested = true; + } + } + this.requestRender(); + return; + } + if (this._screenMode === "split-footer" && this._splitHeight > 0 && previousMode === "capture-stdout" && mode === "passthrough") { + this.clearPendingSplitFooterTransition(); + return; + } + this.syncSplitFooterState(); + } + applyPendingExternalOutputModeIfReady() { + const pendingMode = this.pendingExternalOutputMode; + if (pendingMode === null || this.externalOutputQueue.size > 0) { + return; + } + const previousMode = this._externalOutputMode; + this.pendingExternalOutputMode = null; + if (previousMode === pendingMode) { + return; + } + this.applyExternalOutputMode(pendingMode); + this.afterExternalOutputModeChanged(previousMode, pendingMode); + } + flushPendingSplitOutputBeforeLeavingSplitFooter() { + if (this.pendingExternalOutputMode !== "passthrough") { + return; + } + if (this.isSplitCursorSeedFrameBlocked() && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) { + this.abortSplitStartupCursorSeed(); + } + this.flushPendingSplitOutputBeforeTransition(); + if (this.pendingExternalOutputMode !== null) { + throw new Error("Cannot leave split-footer while captured output is pending"); + } + } + get liveRequestCount() { + return this.liveRequestCounter; + } + get currentControlState() { + return this._controlState; + } + get capabilities() { + return this._capabilities; + } + triggerNotification(message, title) { + if (this._isDestroyed) + return false; + return this.lib.triggerNotification(this.rendererPtr, message, title); + } + get themeMode() { + return this.themeModeState.themeMode; + } + waitForThemeMode(timeoutMs = 1000) { + if (!Number.isFinite(timeoutMs) || timeoutMs < 0) { + throw new Error("timeoutMs must be a non-negative finite number"); + } + return this.themeModeState.waitForThemeMode(timeoutMs, this._isDestroyed); + } + getDebugInputs() { + return [...this._debugInputs]; + } + get useKittyKeyboard() { + return this.lib.getKittyKeyboardFlags(this.rendererPtr) > 0; + } + set useKittyKeyboard(use) { + const flags = use ? KITTY_FLAG_DISAMBIGUATE | KITTY_FLAG_ALTERNATE_KEYS : 0; + this.lib.setKittyKeyboardFlags(this.rendererPtr, flags); + } + createScrollbackSurface(options = {}) { + if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") { + throw new Error('createScrollbackSurface requires screenMode "split-footer" and externalOutputMode "capture-stdout"'); + } + const renderer = this; + const surfaceId = scrollbackSurfaceCounter++; + const startOnNewLine = options.startOnNewLine ?? true; + const tailColumn = renderer.getPendingSplitTailColumn(); + const firstLineOffset = !startOnNewLine && tailColumn > 0 && tailColumn < renderer.width ? tailColumn : 0; + const snapshotContext = new ScrollbackSnapshotRenderContext(renderer.width, 1, renderer.widthMethod); + let firstLineOffsetOwner = null; + const renderContext = Object.create(snapshotContext); + Object.defineProperty(renderContext, "claimFirstLineOffset", { + value: (renderable) => { + if (firstLineOffsetOwner?.isDestroyed) { + firstLineOffsetOwner = null; + } + if (firstLineOffsetOwner) { + return 0; + } + firstLineOffsetOwner = renderable ?? null; + return firstLineOffset; + }, + enumerable: true, + configurable: true + }); + const internalRoot = new RootRenderable(renderContext); + const publicRoot = new BoxRenderable(renderContext, { + id: `scrollback-surface-root-${surfaceId}`, + position: "absolute", + left: 0, + top: 0, + width: renderer.width, + height: "auto", + border: false, + backgroundColor: "transparent", + shouldFill: false, + flexDirection: "column" + }); + internalRoot.add(publicRoot); + let surfaceWidth = renderer.width; + let surfaceHeight = 1; + let surfaceWidthMethod = renderer.widthMethod; + let surfaceDestroyed = false; + let hasRendered = false; + let nextCommitStartOnNewLine = startOnNewLine; + let backingBuffer = OptimizedBuffer.create(surfaceWidth, surfaceHeight, surfaceWidthMethod, { + id: `scrollback-surface-buffer-${surfaceId}` + }); + const destroyListener = () => { + destroySurface(); + }; + const assertNotDestroyed = () => { + if (surfaceDestroyed) { + throw new Error("ScrollbackSurface is destroyed"); + } + }; + const assertRendered = () => { + if (!hasRendered) { + throw new Error("ScrollbackSurface.commitRows requires render() before commitRows()"); + } + }; + const assertGeometryStillCurrent = () => { + if (renderer.width !== surfaceWidth || renderer.widthMethod !== surfaceWidthMethod) { + throw new Error("ScrollbackSurface.commitRows requires render() after renderer geometry changes"); + } + }; + const assertRowRange = (startRow, endRowExclusive) => { + if (!Number.isInteger(startRow) || !Number.isInteger(endRowExclusive)) { + throw new Error("ScrollbackSurface.commitRows requires finite integer row bounds"); + } + if (startRow < 0) { + throw new Error("ScrollbackSurface.commitRows requires startRow >= 0"); + } + if (endRowExclusive < startRow) { + throw new Error("ScrollbackSurface.commitRows requires endRowExclusive >= startRow"); + } + if (endRowExclusive > surfaceHeight) { + throw new Error("ScrollbackSurface.commitRows row range exceeds rendered surface height"); + } + }; + const collectPendingCodeRenderables = (node) => { + const pending = []; + if (node instanceof CodeRenderable && node.isHighlighting) { + pending.push(node); + } + for (const child of node.getChildren()) { + pending.push(...collectPendingCodeRenderables(child)); + } + return pending; + }; + const waitForPendingHighlights = async (pending, timeoutMs) => { + await new Promise((resolve, reject) => { + let settled = false; + const timeoutHandle = renderer.clock.setTimeout(() => { + if (settled) { + return; + } + settled = true; + reject(new Error("ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting")); + }, timeoutMs); + Promise.all(pending.map((renderable) => renderable.highlightingDone)).then(() => { + if (settled) { + return; + } + settled = true; + renderer.clock.clearTimeout(timeoutHandle); + resolve(); + }, (error) => { + if (settled) { + return; + } + settled = true; + renderer.clock.clearTimeout(timeoutHandle); + reject(error); + }); + }); + }; + const renderSurface = () => { + assertNotDestroyed(); + const width = renderer.width; + const widthMethod = renderer.widthMethod; + snapshotContext.width = width; + snapshotContext.widthMethod = widthMethod; + publicRoot.width = width; + const renderPass = (height) => { + snapshotContext.height = height; + internalRoot.resize(width, height); + backingBuffer.resize(width, height); + backingBuffer.clear(TRANSPARENT_RGBA); + snapshotContext.frameId += 1; + internalRoot.render(backingBuffer, 0); + }; + let targetHeight = Math.max(1, surfaceHeight); + if (surfaceWidthMethod !== widthMethod) { + backingBuffer.destroy(); + backingBuffer = OptimizedBuffer.create(width, targetHeight, widthMethod, { + id: `scrollback-surface-buffer-${surfaceId}` + }); + } else { + backingBuffer.resize(width, targetHeight); + } + for (let pass = 0;pass < MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES; pass += 1) { + renderPass(targetHeight); + const measuredHeight = Math.max(1, publicRoot.height); + if (measuredHeight === targetHeight) { + surfaceWidth = width; + surfaceHeight = measuredHeight; + surfaceWidthMethod = widthMethod; + hasRendered = true; + return; + } + targetHeight = measuredHeight; + } + renderPass(targetHeight); + surfaceWidth = width; + surfaceHeight = targetHeight; + surfaceWidthMethod = widthMethod; + hasRendered = true; + }; + const settleSurface = async (timeoutMs = 2000) => { + assertNotDestroyed(); + const startedAt = renderer.clock.now(); + renderSurface(); + while (true) { + assertNotDestroyed(); + const pending = collectPendingCodeRenderables(publicRoot); + if (pending.length === 0) { + return; + } + const remainingMs = timeoutMs - (renderer.clock.now() - startedAt); + if (remainingMs <= 0) { + throw new Error("ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting"); + } + await waitForPendingHighlights(pending, remainingMs); + assertNotDestroyed(); + renderSurface(); + } + }; + const commitRows = (startRow, endRowExclusive, commitOptions = {}) => { + assertNotDestroyed(); + assertRendered(); + assertGeometryStillCurrent(); + assertRowRange(startRow, endRowExclusive); + if (startRow === endRowExclusive) { + return; + } + const rowCount = endRowExclusive - startRow; + const commitBuffer = OptimizedBuffer.create(surfaceWidth, rowCount, surfaceWidthMethod, { + id: `scrollback-surface-commit-${surfaceId}` + }); + try { + commitBuffer.drawFrameBuffer(0, 0, backingBuffer, 0, startRow, surfaceWidth, rowCount); + renderer.enqueueRenderedScrollbackCommit({ + snapshot: commitBuffer, + rowColumns: commitOptions.rowColumns, + startOnNewLine: nextCommitStartOnNewLine, + trailingNewline: commitOptions.trailingNewline ?? true + }); + nextCommitStartOnNewLine = false; + } catch (error) { + commitBuffer.destroy(); + throw error; + } + }; + const destroySurface = () => { + if (surfaceDestroyed) { + return; + } + surfaceDestroyed = true; + renderer.off("destroy" /* DESTROY */, destroyListener); + let destroyError = null; + try { + internalRoot.destroyRecursively(); + } catch (error) { + destroyError = error; + } + try { + backingBuffer.destroy(); + } catch (error) { + if (destroyError === null) { + destroyError = error; + } + } + renderContext.removeAllListeners(); + snapshotContext.removeAllListeners(); + if (destroyError !== null) { + throw destroyError; + } + }; + renderer.on("destroy" /* DESTROY */, destroyListener); + return { + get renderContext() { + return renderContext; + }, + get root() { + return publicRoot; + }, + get width() { + return surfaceWidth; + }, + get height() { + return surfaceHeight; + }, + get isDestroyed() { + return surfaceDestroyed; + }, + render: renderSurface, + settle: settleSurface, + commitRows, + destroy: destroySurface + }; + } + writeToScrollback(write) { + if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") { + throw new Error('writeToScrollback requires screenMode "split-footer" and externalOutputMode "capture-stdout"'); + } + const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, this.height, this.widthMethod); + const snapshot = write({ + width: this.width, + widthMethod: this.widthMethod, + tailColumn: this.getPendingSplitTailColumn(), + renderContext: snapshotContext + }); + if (!snapshot || !snapshot.root) { + throw new Error("writeToScrollback must return a snapshot root renderable"); + } + let renderFailed = false; + let snapshotRoot = null; + let snapshotBuffer = null; + try { + const rootRenderable = snapshot.root; + const snapshotWidth = this.getSnapshotWidth(snapshot.width, rootRenderable.width); + const snapshotHeight = this.getSnapshotHeight(snapshot.height, rootRenderable.height); + snapshotContext.width = snapshotWidth; + snapshotContext.height = snapshotHeight; + snapshotContext.widthMethod = this.widthMethod; + snapshotRoot = new RootRenderable(snapshotContext); + snapshotBuffer = OptimizedBuffer.create(snapshotWidth, snapshotHeight, this.widthMethod, { + id: "scrollback-snapshot-commit" + }); + snapshotRoot.add(rootRenderable); + snapshotRoot.render(snapshotBuffer, 0); + this.enqueueRenderedScrollbackCommit({ + snapshot: snapshotBuffer, + rowColumns: snapshot.rowColumns, + startOnNewLine: snapshot.startOnNewLine, + trailingNewline: snapshot.trailingNewline + }); + } catch (error) { + renderFailed = true; + snapshotBuffer?.destroy(); + throw error; + } finally { + let cleanupError = null; + try { + if (snapshotRoot) { + snapshotRoot.destroyRecursively(); + } else { + snapshot.root.destroyRecursively(); + } + } catch (error) { + cleanupError = error; + } + try { + snapshot.teardown?.(); + } catch (error) { + if (cleanupError === null) { + cleanupError = error; + } + } + if (!renderFailed && cleanupError) { + throw cleanupError; + } + } + } + resetSplitFooterForReplay(options = {}) { + if (this._isDestroyed) + return; + if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") { + throw new Error('resetSplitFooterForReplay requires screenMode "split-footer" and externalOutputMode "capture-stdout"'); + } + if (!this._terminalIsSetup || this._controlState === "explicit_suspended" /* EXPLICIT_SUSPENDED */) { + throw new Error("resetSplitFooterForReplay requires an active terminal"); + } + this.flushPendingSplitOutputBeforeTransition(true); + this.externalOutputQueue.clear(); + this.abortSplitStartupCursorSeed(); + this.clearPendingSplitFooterTransition(); + this.resetSplitScrollback(); + this.currentRenderBuffer.clear(this.backgroundColor); + this.nextRenderBuffer.clear(this.backgroundColor); + this.forceFullRepaintRequested = true; + this.writeOut(ANSI.resetScrollRegion + ANSI.reset + ANSI.home + ANSI.clearScreen + (options.clearSavedLines ? ANSI.clearSavedLines : "") + ANSI.home); + this.requestRender(); + } + getSnapshotWidth(value, fallback) { + const rawValue = value ?? fallback; + if (!Number.isFinite(rawValue)) { + throw new Error("writeToScrollback produced a non-finite width"); + } + return Math.min(Math.max(Math.trunc(rawValue), 1), Math.max(this.width, 1)); + } + getSnapshotHeight(value, fallback) { + const rawValue = value ?? fallback; + if (!Number.isFinite(rawValue)) { + throw new Error("writeToScrollback produced a non-finite height"); + } + return Math.max(Math.trunc(rawValue), 1); + } + getSnapshotRowWidths(snapshot, rowColumns) { + const widths = []; + const limit = Math.min(Math.max(Math.trunc(rowColumns), 0), snapshot.width); + const chars = snapshot.buffers.char; + for (let y = 0;y < snapshot.height; y += 1) { + let x = limit; + while (x > 0) { + const cp = chars[y * snapshot.width + x - 1]; + if (cp === 0 || (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION) { + x -= 1; + continue; + } + break; + } + widths.push(x); + } + return widths; + } + advanceSplitTailColumn(tailColumn, columns, width) { + if (columns <= 0) { + return tailColumn; + } + let tail = tailColumn; + let remaining = columns; + while (remaining > 0) { + if (tail >= width) { + tail = 0; + } + const step = Math.min(remaining, width - tail); + tail += step; + remaining -= step; + if (remaining > 0 && tail >= width) { + tail = 0; + } + } + return tail; + } + getSplitTailColumnAfterCommit(commit, initialTailColumn, width) { + let tailColumn = initialTailColumn; + if (commit.startOnNewLine && tailColumn > 0) { + tailColumn = 0; + } + const rowWidths = this.getSnapshotRowWidths(commit.snapshot, commit.rowColumns); + for (const [index, rowWidth] of rowWidths.entries()) { + tailColumn = this.advanceSplitTailColumn(tailColumn, rowWidth, width); + if (index < rowWidths.length - 1 || commit.trailingNewline) { + tailColumn = 0; + } + } + return tailColumn; + } + recordSplitCommit(commit) { + this.splitTailColumn = this.getSplitTailColumnAfterCommit(commit, this.splitTailColumn, Math.max(this.width, 1)); + } + getPendingSplitTailColumn() { + const width = Math.max(this.width, 1); + let tailColumn = this.splitTailColumn; + for (const commit of this.externalOutputQueue.peek()) { + tailColumn = this.getSplitTailColumnAfterCommit(commit, tailColumn, width); + } + return tailColumn; + } + enqueueRenderedScrollbackCommit(options) { + if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") { + throw new Error('scrollback commit requires screenMode "split-footer" and externalOutputMode "capture-stdout"'); + } + const rowColumns = Math.min(Math.max(Math.trunc(options.rowColumns ?? options.snapshot.width), 0), options.snapshot.width); + this.enqueueSplitCommit({ + snapshot: options.snapshot, + rowColumns, + startOnNewLine: options.startOnNewLine ?? true, + trailingNewline: options.trailingNewline ?? true + }); + this.requestRender(); + } + enqueueSplitCommit(commit) { + this.externalOutputQueue.writeSnapshot(commit); + if (this.listenerCount("external_output" /* EXTERNAL_OUTPUT */) > 0) { + this.emit("external_output" /* EXTERNAL_OUTPUT */, commit); + } + } + createStdoutSnapshotCommit(line, trailingNewline) { + const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, 1, this.widthMethod); + const maxWidth = Math.max(1, this.width); + const lineCells = [...line]; + const rowColumns = Math.min(lineCells.length, maxWidth); + const renderedLine = lineCells.slice(0, maxWidth).join(""); + const snapshotRoot = new RootRenderable(snapshotContext); + const snapshotRenderable = new TextRenderable(snapshotContext, { + id: "captured-stdout-snapshot", + position: "absolute", + left: 0, + top: 0, + width: Math.max(1, rowColumns), + height: 1, + content: renderedLine + }); + const snapshotBuffer = OptimizedBuffer.create(Math.max(1, rowColumns), 1, this.widthMethod, { + id: "captured-stdout-snapshot" + }); + try { + snapshotRoot.add(snapshotRenderable); + snapshotRoot.render(snapshotBuffer, 0); + return { + snapshot: snapshotBuffer, + rowColumns, + startOnNewLine: false, + trailingNewline + }; + } catch (error) { + snapshotBuffer.destroy(); + throw error; + } finally { + snapshotRoot.destroyRecursively(); + } + } + splitStdoutRows(text) { + const rows = []; + let current = ""; + for (const char of text) { + if (char === "\r") { + current = ""; + continue; + } + if (char === ` +`) { + rows.push({ line: current, trailingNewline: true }); + current = ""; + continue; + } + current += char; + } + if (current.length > 0) { + rows.push({ line: current, trailingNewline: false }); + } + return rows; + } + createStdoutSnapshotCommits(text) { + if (text.length === 0) { + return []; + } + const commits = []; + const chunkWidth = Math.max(1, this.width); + for (const row of this.splitStdoutRows(text)) { + const rowCells = [...row.line]; + if (rowCells.length === 0) { + commits.push(this.createStdoutSnapshotCommit("", row.trailingNewline)); + continue; + } + let offset = 0; + while (offset < rowCells.length) { + const chunk = rowCells.slice(offset, offset + chunkWidth).join(""); + offset += chunkWidth; + const isLastChunk = offset >= rowCells.length; + commits.push(this.createStdoutSnapshotCommit(chunk, isLastChunk ? row.trailingNewline : false)); + } + } + return commits; + } + flushPendingSplitCommits(forceFooterRepaint = false, drainAll = false) { + const commits = this.externalOutputQueue.peek(drainAll ? Number.POSITIVE_INFINITY : this.maxSplitCommitsPerFrame); + let hasCommittedOutput = false; + const lastCommitIndex = commits.length - 1; + let acceptedCommits = 0; + let nativeBackpressured = false; + let nativeFailed = false; + for (const [index, commit] of commits.entries()) { + const forceCommit = forceFooterRepaint && index === lastCommitIndex; + const beginFrame = index === 0; + const finalizeFrame = index === lastCommitIndex; + const nativeResult = this.lib.commitSplitFooterSnapshot(this.rendererPtr, commit.snapshot, commit.rowColumns, commit.startOnNewLine, commit.trailingNewline, this.getSplitPinnedRenderOffset(), forceCommit, beginFrame, finalizeFrame); + if (nativeResult.status === NATIVE_RENDER_STATUS_SKIPPED) { + nativeBackpressured = true; + break; + } + if (nativeResult.status === NATIVE_RENDER_STATUS_FAILED) { + nativeFailed = true; + break; + } + this.renderOffset = nativeResult.renderOffset; + this.recordSplitCommit(commit); + hasCommittedOutput = true; + acceptedCommits++; + } + if (acceptedCommits > 0) { + this.externalOutputQueue.drop(acceptedCommits); + } + if (nativeFailed) { + return this.reportNativeRenderFailure(); + } + if (nativeBackpressured) { + this.scheduleRenderAfterFeedIdle(); + return "backpressured"; + } + if (!hasCommittedOutput) { + const nativeResult = this.lib.repaintSplitFooter(this.rendererPtr, this.getSplitPinnedRenderOffset(), forceFooterRepaint); + if (nativeResult.status === NATIVE_RENDER_STATUS_SKIPPED) { + this.scheduleRenderAfterFeedIdle(); + return "backpressured"; + } + if (nativeResult.status === NATIVE_RENDER_STATUS_FAILED) { + return this.reportNativeRenderFailure(); + } + this.renderOffset = nativeResult.renderOffset; + } + this.pendingSplitFooterTransition = null; + if (this.externalOutputQueue.size > 0) { + this.requestRender(); + } else { + this.applyPendingExternalOutputModeIfReady(); + } + return "rendered"; + } + interceptStdoutWrite = (chunk, encoding, callback) => { + const resolvedCallback = typeof encoding === "function" ? encoding : callback; + const resolvedEncoding = typeof encoding === "string" ? encoding : undefined; + const text = typeof chunk === "string" ? chunk : chunk?.toString(resolvedEncoding) ?? ""; + if (this._externalOutputMode === "capture-stdout" && this._screenMode === "split-footer" && this._splitHeight > 0) { + const commits = this.createStdoutSnapshotCommits(text); + for (const commit of commits) { + this.enqueueSplitCommit(commit); + } + if (commits.length > 0) { + this.requestRender(); + } + } + if (typeof resolvedCallback === "function") { + process.nextTick(resolvedCallback); + } + return true; + }; + getSplitPinnedRenderOffset() { + return this._screenMode === "split-footer" ? Math.max(this._terminalHeight - this._splitHeight, 0) : 0; + } + getSplitCursorSeedRows() { + const cursorState = this.lib.getCursorState(this.rendererPtr); + const cursorRow = Number.isFinite(cursorState.y) ? Math.max(Math.trunc(cursorState.y), 1) : 1; + return Math.min(cursorRow, Math.max(this._terminalHeight, 1)); + } + isSplitCursorSeedFrameBlocked() { + return this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout" && this._splitHeight > 0 && this.pendingSplitStartupCursorSeed && this.splitStartupSeedTimeoutId !== null; + } + canFlushSplitOutputBeforeTransition(allowSuspended = false, allowUnsetup = false) { + return (this._terminalIsSetup || allowUnsetup) && (allowSuspended || this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) && !this.isSplitCursorSeedFrameBlocked(); + } + clearSplitStartupCursorSeed() { + this.pendingSplitStartupCursorSeed = false; + if (this.splitStartupSeedTimeoutId !== null) { + this.clock.clearTimeout(this.splitStartupSeedTimeoutId); + this.splitStartupSeedTimeoutId = null; + } + } + abortSplitStartupCursorSeed() { + this.clearSplitStartupCursorSeed(); + this.stdinParser?.abortPendingStartupCursorCpr(); + this.updateStdinParserProtocolContext({ startupCursorCprActive: false }); + } + flushPendingSplitOutputBeforeTransition(forceFooterRepaint = false, options = {}) { + const hasDeferredCapturedOutput = this.externalOutputQueue.size > 0 || this.pendingExternalOutputMode !== null; + if (this._screenMode !== "split-footer" || this._splitHeight <= 0 || this._externalOutputMode !== "capture-stdout" && !(options.allowPassthrough && hasDeferredCapturedOutput)) { + return; + } + if (!this.canFlushSplitOutputBeforeTransition(options.allowSuspended ?? false, options.allowUnsetup ?? false)) { + return; + } + if (this.externalOutputQueue.size === 0 && !forceFooterRepaint) { + this.applyPendingExternalOutputModeIfReady(); + return; + } + this.flushPendingSplitCommits(this._externalOutputMode === "capture-stdout" ? forceFooterRepaint : false, true); + } + resetSplitScrollback(seedRows = 0) { + this.splitTailColumn = 0; + this.renderOffset = this.lib.resetSplitScrollback(this.rendererPtr, seedRows, this.getSplitPinnedRenderOffset()); + } + syncSplitScrollback() { + this.renderOffset = this.lib.syncSplitScrollback(this.rendererPtr, this.getSplitPinnedRenderOffset()); + } + getSplitOutputOffset(surfaceOffset = this.renderOffset) { + return this.lib.getSplitOutputOffset(this.rendererPtr, surfaceOffset); + } + clearPendingSplitFooterTransition() { + if (this.pendingSplitFooterTransition === null) { + return; + } + this.pendingSplitFooterTransition = null; + this.lib.clearPendingSplitFooterTransition(this.rendererPtr); + } + setPendingSplitFooterTransition(transition) { + this.pendingSplitFooterTransition = transition; + this.lib.setPendingSplitFooterTransition(this.rendererPtr, transition.mode === "viewport-scroll" ? 1 : 2, transition.sourceTopLine, transition.sourceHeight, transition.targetTopLine, transition.targetHeight, transition.scrollLines ?? 0); + } + syncSplitFooterState() { + const splitActive = this._screenMode === "split-footer" && this._splitHeight > 0; + if (!splitActive) { + this.clearPendingSplitFooterTransition(); + this.splitTailColumn = 0; + this.lib.resetSplitScrollback(this.rendererPtr, 0, 0); + this.renderOffset = 0; + this.lib.setRenderOffset(this.rendererPtr, this.renderOffset); + return; + } + if (this._externalOutputMode === "capture-stdout") { + this.syncSplitScrollback(); + } else { + this.clearPendingSplitFooterTransition(); + this.splitTailColumn = 0; + this.lib.resetSplitScrollback(this.rendererPtr, 0, 0); + this.renderOffset = this.getSplitPinnedRenderOffset(); + this.lib.setRenderOffset(this.rendererPtr, this.renderOffset); + } + } + clearStaleSplitSurfaceRows(previousTopLine, previousHeight, nextTopLine, nextHeight) { + if (!this._terminalIsSetup || previousHeight <= 0 || this._terminalHeight <= 0) { + return; + } + const terminalBottom = this._terminalHeight; + const previousStart = Math.max(1, previousTopLine); + const previousEnd = Math.min(terminalBottom, previousTopLine + previousHeight - 1); + if (previousEnd < previousStart) { + return; + } + const nextStart = Math.max(1, nextTopLine); + const nextEnd = Math.min(terminalBottom, nextTopLine + Math.max(nextHeight, 0) - 1); + let clear = ""; + for (let line = previousStart;line <= previousEnd; line += 1) { + if (line >= nextStart && line <= nextEnd) { + continue; + } + clear += `${ANSI.moveCursor(line, 1)}\x1B[2K`; + } + if (clear.length > 0) { + this.writeOut(clear); + } + } + applyScreenMode(screenMode, emitResize = true, requestRender = true) { + const prevScreenMode = this._screenMode; + const prevSplitHeight = this._splitHeight; + const nextGeometry = calculateRenderGeometry(screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight); + const nextSplitHeight = nextGeometry.effectiveFooterHeight; + if (prevScreenMode === screenMode && prevSplitHeight === nextSplitHeight) { + return; + } + const terminalWritable = this._terminalIsSetup && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */; + const prevUseAlternateScreen = prevScreenMode === "alternate-screen"; + const nextUseAlternateScreen = screenMode === "alternate-screen"; + const terminalScreenModeChanged = this._terminalIsSetup && prevUseAlternateScreen !== nextUseAlternateScreen; + const leavingSplitFooter = prevSplitHeight > 0 && nextSplitHeight === 0; + if (terminalWritable && prevSplitHeight > 0) { + this.flushPendingSplitOutputBeforeTransition(); + } + const previousSurfaceTopLine = this.renderOffset + 1; + const shouldDeferSplitFooterResizeTransition = this._terminalIsSetup && prevScreenMode === "split-footer" && screenMode === "split-footer" && this._externalOutputMode === "capture-stdout" && prevSplitHeight > 0 && nextSplitHeight > 0 && !terminalScreenModeChanged; + const splitStartupSeedBlocksFirstNativeFrame = this.pendingSplitStartupCursorSeed && this.splitStartupSeedTimeoutId !== null; + const splitTransitionSourceTopLine = this.pendingSplitFooterTransition?.sourceTopLine ?? previousSurfaceTopLine; + const splitTransitionSourceHeight = this.pendingSplitFooterTransition?.sourceHeight ?? prevSplitHeight; + const splitTransitionSourceSurfaceOffset = Math.max(splitTransitionSourceTopLine - 1, 0); + const splitTransitionSourceOutputOffset = prevScreenMode === "split-footer" && prevSplitHeight > 0 && this._externalOutputMode === "capture-stdout" ? this.getSplitOutputOffset(splitTransitionSourceSurfaceOffset) : splitTransitionSourceSurfaceOffset; + const nextPinnedRenderOffset = nextGeometry.renderOffset; + const nextSplitOutputOffset = screenMode === "split-footer" && nextSplitHeight > 0 && this._externalOutputMode === "capture-stdout" ? this.getSplitOutputOffset(nextPinnedRenderOffset) : nextPinnedRenderOffset; + const pendingSplitFooterTransition = this.pendingSplitFooterTransition; + const pendingSplitFooterReturn = pendingSplitFooterTransition !== null && nextSplitHeight === splitTransitionSourceHeight; + const pendingSplitFooterViewportReturn = pendingSplitFooterReturn && pendingSplitFooterTransition.mode === "viewport-scroll" && (pendingSplitFooterTransition.scrollLines ?? 0) > 0; + const shrinkingSplitFooter = nextSplitHeight > 0 && nextSplitHeight < splitTransitionSourceHeight; + const growingSplitFooter = nextSplitHeight > splitTransitionSourceHeight && splitTransitionSourceHeight > 0; + const nextSplitSurfaceOffset = screenMode !== "split-footer" || nextSplitHeight === 0 ? 0 : pendingSplitFooterViewportReturn ? pendingSplitFooterTransition.targetTopLine - 1 : pendingSplitFooterReturn ? splitTransitionSourceSurfaceOffset : shrinkingSplitFooter && splitTransitionSourceSurfaceOffset > 0 ? splitTransitionSourceSurfaceOffset : shrinkingSplitFooter ? nextSplitOutputOffset : growingSplitFooter ? Math.max(nextSplitOutputOffset, Math.min(splitTransitionSourceSurfaceOffset, nextPinnedRenderOffset)) : nextPinnedRenderOffset; + const splitTransitionTargetTopLine = nextSplitSurfaceOffset + 1; + const splitViewportScrollLines = pendingSplitFooterViewportReturn ? pendingSplitFooterTransition.scrollLines ?? 0 : nextSplitHeight > 0 && !pendingSplitFooterReturn ? Math.max(splitTransitionSourceOutputOffset - nextSplitOutputOffset, 0) : 0; + const splitTransitionMode = (!shrinkingSplitFooter || pendingSplitFooterViewportReturn) && splitViewportScrollLines > 0 ? "viewport-scroll" : "clear-stale-rows"; + const splitFooterSurfaceMovesDown = nextSplitSurfaceOffset > splitTransitionSourceSurfaceOffset; + const splitFooterSurfaceLeavesStaleRows = splitFooterSurfaceMovesDown || shrinkingSplitFooter; + const shouldClearSplitSurfaceRowsImmediately = terminalWritable && !terminalScreenModeChanged && !shouldDeferSplitFooterResizeTransition && splitFooterSurfaceLeavesStaleRows && nextSplitHeight > 0; + if (terminalWritable && leavingSplitFooter) { + this.clearPendingSplitFooterTransition(); + this.renderOffset = 0; + this.lib.setRenderOffset(this.rendererPtr, 0); + } + if (terminalWritable && !terminalScreenModeChanged && !shouldDeferSplitFooterResizeTransition) { + if (prevSplitHeight === 0 && nextSplitHeight > 0) { + const freedLines = this._terminalHeight - nextSplitHeight; + const scrollDown = ANSI.scrollDown(freedLines); + this.writeOut(scrollDown); + } else if (splitViewportScrollLines > 0) { + const additionalLines = splitViewportScrollLines; + const scrollUp = ANSI.scrollUp(additionalLines); + this.writeOut(scrollUp); + } + } + this._screenMode = screenMode; + this._splitHeight = nextSplitHeight; + this.width = nextGeometry.renderWidth; + this.height = nextGeometry.renderHeight; + this.lib.resizeRenderer(this.rendererPtr, this.width, this.height); + if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") { + if (prevScreenMode !== "split-footer") { + this.resetSplitScrollback(this.getSplitCursorSeedRows()); + } else { + this.renderOffset = nextSplitSurfaceOffset; + this.lib.setRenderOffset(this.rendererPtr, this.renderOffset); + } + if (shouldDeferSplitFooterResizeTransition) { + if (splitStartupSeedBlocksFirstNativeFrame) { + this.clearPendingSplitFooterTransition(); + } else { + this.setPendingSplitFooterTransition({ + mode: splitTransitionMode, + sourceTopLine: splitTransitionSourceTopLine, + sourceHeight: splitTransitionSourceHeight, + targetTopLine: splitTransitionTargetTopLine, + targetHeight: nextSplitHeight, + scrollLines: splitViewportScrollLines + }); + } + this.forceFullRepaintRequested = true; + } else if (shouldClearSplitSurfaceRowsImmediately) { + this.clearPendingSplitFooterTransition(); + this.clearStaleSplitSurfaceRows(splitTransitionSourceTopLine, splitTransitionSourceHeight, splitTransitionTargetTopLine, nextSplitHeight); + } else { + this.clearPendingSplitFooterTransition(); + } + } else { + this.syncSplitFooterState(); + if (shouldClearSplitSurfaceRowsImmediately) { + this.clearStaleSplitSurfaceRows(splitTransitionSourceTopLine, splitTransitionSourceHeight, this.renderOffset + 1, nextSplitHeight); + } + } + this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr); + this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr); + this._console.resize(this.width, this.height); + this.root.resize(this.width, this.height); + if (terminalScreenModeChanged) { + if (terminalWritable) { + this.lib.suspendRenderer(this.rendererPtr); + this.lib.setupTerminal(this.rendererPtr, nextUseAlternateScreen); + this.pendingSuspendedTerminalSetup = false; + } else { + this.pendingSuspendedTerminalSetup = true; + } + if (terminalWritable && this._useMouse) { + this.enableMouse(); + } + } + if (emitResize) { + this.emit("resize" /* RESIZE */, this.width, this.height); + } + if (requestRender) { + this.requestRender(); + } + } + flushStdoutCache(space, force = false) { + if (this.externalOutputQueue.size === 0 && !force) + return false; + const outputCommits = this.externalOutputQueue.claim(); + let output = ""; + for (const commit of outputCommits) { + output += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}] +`; + commit.snapshot.destroy(); + } + const rendererStartLine = this.renderOffset + 1; + const flush = ANSI.moveCursorAndClear(rendererStartLine, 1); + const outputLine = this.renderOffset + 1; + const move = ANSI.moveCursor(outputLine, 1); + let clear = ""; + if (space > 0) { + const backgroundColor = this.backgroundColor.toInts(); + const newlines = " ".repeat(this.width) + ` +`.repeat(space); + if (backgroundColor[3] === 0) { + clear = newlines; + } else { + clear = ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) + newlines + ANSI.resetBackground; + } + } + this.writeOut(flush + move + output + clear); + return true; + } + enableMouse() { + this._useMouse = true; + this.lib.enableMouse(this.rendererPtr, this.enableMouseMovement); + } + disableMouse() { + this._useMouse = false; + this.setCapturedRenderable(undefined); + this.stdinParser?.resetMouseState(); + this.lib.disableMouse(this.rendererPtr); + } + enableKittyKeyboard(flags = 3) { + this.lib.enableKittyKeyboard(this.rendererPtr, flags); + this.updateStdinParserProtocolContext({ kittyKeyboardEnabled: true }); + } + disableKittyKeyboard() { + this.lib.disableKittyKeyboard(this.rendererPtr); + this.updateStdinParserProtocolContext({ kittyKeyboardEnabled: false }, true); + } + set useThread(useThread) { + this._useThread = useThread; + this.lib.setUseThread(this.rendererPtr, useThread); + } + async setupTerminal() { + if (this._terminalIsSetup) + return; + this._terminalIsSetup = true; + const startupCursorCprActive = this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout"; + this.updateStdinParserProtocolContext({ + privateCapabilityRepliesActive: true, + explicitWidthCprActive: true, + startupCursorCprActive + }); + this.lib.setupTerminal(this.rendererPtr, this._screenMode === "alternate-screen"); + this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr); + if (this.debugOverlay.enabled) { + this.lib.setDebugOverlay(this.rendererPtr, true, this.debugOverlay.corner); + if (!this.memorySnapshotInterval) { + this.memorySnapshotInterval = 3000; + this.startMemorySnapshotTimer(); + this.automaticMemorySnapshot = true; + } + } + this.capabilityTimeoutId = this.clock.setTimeout(() => { + this.capabilityTimeoutId = null; + this.clearSplitStartupCursorSeed(); + if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") { + this.requestRender(); + } + this.removeInputHandler(this.capabilityHandler); + this.updateStdinParserProtocolContext({ + privateCapabilityRepliesActive: false, + explicitWidthCprActive: false, + startupCursorCprActive: false + }, true); + this.resolveXtVersionWaiters(); + }, 5000); + if (this._useMouse) { + this.enableMouse(); + } + if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") { + this.pendingSplitStartupCursorSeed = true; + if (this.splitStartupSeedTimeoutId !== null) { + this.clock.clearTimeout(this.splitStartupSeedTimeoutId); + } + this.splitStartupSeedTimeoutId = this.clock.setTimeout(() => { + this.splitStartupSeedTimeoutId = null; + if (!this.pendingSplitStartupCursorSeed) { + return; + } + this.updateStdinParserProtocolContext({ startupCursorCprActive: false }); + if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") { + this.requestRender(); + } + this.flushPendingSplitOutputBeforeTransition(false, { allowPassthrough: true }); + }, 120); + } + this.queryPixelResolution(); + if (this.shouldSyncNativePaletteState()) { + this.refreshPalette(); + } + if (this._feed?.isBackpressured()) { + await this._feed.idle(); + } + } + stdinListener = ((chunk) => { + const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); + if (!this.stdinParser) + return; + try { + this.stdinParser.push(data); + this.drainStdinParser(); + } catch (error) { + this.handleStdinParserFailure(error); + } + }).bind(this); + addInputHandler(handler) { + this.sequenceHandlers.push(handler); + } + prependInputHandler(handler) { + this.sequenceHandlers.unshift(handler); + } + removeInputHandler(handler) { + this.sequenceHandlers = this.sequenceHandlers.filter((candidate) => candidate !== handler); + } + updateStdinParserProtocolContext(patch, drain = false) { + if (!this.stdinParser) + return; + this.stdinParser.updateProtocolContext(patch); + if (drain) + this.drainStdinParser(); + } + subscribeOsc(handler) { + this.oscSubscribers.add(handler); + return () => { + this.oscSubscribers.delete(handler); + }; + } + processCapabilitySequence(sequence, hasCursorReport) { + const hasStandardCapabilitySignature = isCapabilityResponse(sequence); + const shouldProcessAsCapability = hasStandardCapabilitySignature || hasCursorReport && this.capabilityTimeoutId !== null; + if (!shouldProcessAsCapability) { + return false; + } + this.lib.processCapabilityResponse(this.rendererPtr, sequence); + this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr); + if (this._capabilities?.terminal?.from_xtversion) { + this.resolveXtVersionWaiters(); + } + if (hasStandardCapabilitySignature) { + this.forceFullRepaintRequested = true; + this.requestRender(); + } + this.emit("capabilities" /* CAPABILITIES */, this._capabilities); + const hadPendingSplitStartupCursorSeed = this.pendingSplitStartupCursorSeed; + if (hadPendingSplitStartupCursorSeed && hasCursorReport && this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") { + this.resetSplitScrollback(this.getSplitCursorSeedRows()); + this.clearPendingSplitFooterTransition(); + this.clearSplitStartupCursorSeed(); + this.updateStdinParserProtocolContext({ startupCursorCprActive: false }); + this.requestRender(); + if (this.pendingExternalOutputMode === "passthrough") { + this.flushPendingSplitOutputBeforeTransition(); + } + } + const consumeStartupCursorReport = hadPendingSplitStartupCursorSeed && hasCursorReport && this.splitStartupSeedTimeoutId !== null; + return hasStandardCapabilitySignature || consumeStartupCursorReport; + } + capabilityHandler = ((sequence) => { + return this.processCapabilitySequence(sequence, false); + }).bind(this); + focusHandler = ((sequence) => { + if (sequence === "\x1B[I") { + if (this.shouldRestoreModesOnNextFocus) { + this.lib.restoreTerminalModes(this.rendererPtr); + this.shouldRestoreModesOnNextFocus = false; + } + if (this._terminalFocusState !== true) { + this._terminalFocusState = true; + this.emit("focus" /* FOCUS */); + } + return true; + } + if (sequence === "\x1B[O") { + this.shouldRestoreModesOnNextFocus = true; + if (this._terminalFocusState !== false) { + this._terminalFocusState = false; + this.emit("blur" /* BLUR */); + } + return true; + } + return false; + }).bind(this); + dispatchSequenceHandlers(sequence) { + if (this._debugModeEnabled) { + this._debugInputs.push({ + timestamp: new Date().toISOString(), + sequence + }); + } + for (const handler of this.sequenceHandlers) { + if (handler(sequence)) { + return true; + } + } + return false; + } + drainStdinParser() { + if (!this.stdinParser) + return; + this.stdinParser.drain((event) => { + this.handleStdinEvent(event); + }); + } + handleStdinEvent(event) { + switch (event.type) { + case "key": + if (this.dispatchSequenceHandlers(event.raw)) { + return; + } + this._keyHandler.processParsedKey(event.key); + return; + case "mouse": + if (this._useMouse && this.processSingleMouseEvent(event.event)) { + return; + } + this.dispatchSequenceHandlers(event.raw); + return; + case "paste": + this._keyHandler.processPaste(event.bytes, event.metadata); + return; + case "response": + if (event.protocol === "osc") { + for (const subscriber of this.oscSubscribers) { + subscriber(event.sequence); + } + } + if (event.protocol === "cpr" && this.processCapabilitySequence(event.sequence, true)) { + return; + } + this.dispatchSequenceHandlers(event.sequence); + return; + } + } + handleStdinParserFailure(error) { + if (!this.hasLoggedStdinParserError) { + this.hasLoggedStdinParserError = true; + if (true) { + console.error("[stdin-parser-error] parser failure, resetting parser", error); + } + } + try { + this.stdinParser?.reset(); + } catch (resetError) { + console.error("stdin parser reset failed after parser error", resetError); + } + } + setupInput() { + for (const handler of this.prependedInputHandlers) { + this.addInputHandler(handler); + } + this.addInputHandler((sequence) => { + if (isPixelResolutionResponse(sequence) && this.waitingForPixelResolution) { + const resolution = parsePixelResolution(sequence); + if (resolution) { + this._resolution = resolution; + } + this.waitingForPixelResolution = false; + this.updateStdinParserProtocolContext({ pixelResolutionQueryActive: false }, true); + return true; + } + return false; + }); + this.addInputHandler(this.capabilityHandler); + this.addInputHandler(this.focusHandler); + this.addInputHandler(this.themeModeHandler); + if (this.stdin.setRawMode) { + this.stdin.setRawMode(true); + } + this.stdin.on("data", this.stdinListener); + this.stdin.resume(); + } + dispatchMouseEvent(target, attributes) { + const event = new MouseEvent(target, attributes); + target.processMouseEvent(event); + if (this.autoFocus && event.type === "down" && event.button === 0 /* LEFT */ && !event.defaultPrevented) { + let current = target; + while (current) { + if (current.focusable) { + current.focus(); + break; + } + current = current.parent; + } + } + return event; + } + processSingleMouseEvent(mouseEvent) { + if (this._splitHeight > 0) { + if (mouseEvent.y < this.renderOffset) { + return false; + } + mouseEvent.y -= this.renderOffset; + } + this._latestPointer.x = mouseEvent.x; + this._latestPointer.y = mouseEvent.y; + this._hasPointer = true; + this._lastPointerModifiers = mouseEvent.modifiers; + if (this._console.visible) { + const consoleBounds = this._console.bounds; + if (mouseEvent.x >= consoleBounds.x && mouseEvent.x < consoleBounds.x + consoleBounds.width && mouseEvent.y >= consoleBounds.y && mouseEvent.y < consoleBounds.y + consoleBounds.height) { + const event2 = new MouseEvent(null, mouseEvent); + const handled = this._console.handleMouse(event2); + if (handled) + return true; + } + } + if (mouseEvent.type === "scroll") { + const maybeRenderableId2 = this.hitTest(mouseEvent.x, mouseEvent.y); + const maybeRenderable2 = Renderable.renderablesByNumber.get(maybeRenderableId2); + const fallbackTarget = this._currentFocusedRenderable && !this._currentFocusedRenderable.isDestroyed && this._currentFocusedRenderable.focused ? this._currentFocusedRenderable : null; + const scrollTarget = maybeRenderable2 ?? fallbackTarget; + if (scrollTarget) { + const event2 = new MouseEvent(scrollTarget, mouseEvent); + scrollTarget.processMouseEvent(event2); + } + return true; + } + const maybeRenderableId = this.hitTest(mouseEvent.x, mouseEvent.y); + const sameElement = maybeRenderableId === this.lastOverRenderableNum; + this.lastOverRenderableNum = maybeRenderableId; + const maybeRenderable = Renderable.renderablesByNumber.get(maybeRenderableId); + if (mouseEvent.type === "down" && mouseEvent.button === 0 /* LEFT */ && !this.currentSelection?.isDragging && !mouseEvent.modifiers.ctrl) { + const canStartSelection = Boolean(maybeRenderable && maybeRenderable.selectable && !maybeRenderable.isDestroyed && maybeRenderable.shouldStartSelection(mouseEvent.x, mouseEvent.y)); + if (canStartSelection && maybeRenderable) { + this.startSelection(maybeRenderable, mouseEvent.x, mouseEvent.y); + this.dispatchMouseEvent(maybeRenderable, mouseEvent); + return true; + } + } + if (mouseEvent.type === "drag" && this.currentSelection?.isDragging) { + this.updateSelection(maybeRenderable, mouseEvent.x, mouseEvent.y); + if (maybeRenderable) { + const event2 = new MouseEvent(maybeRenderable, { + ...mouseEvent, + isDragging: true + }); + maybeRenderable.processMouseEvent(event2); + } + return true; + } + if (mouseEvent.type === "up" && this.currentSelection?.isDragging) { + if (maybeRenderable) { + const event2 = new MouseEvent(maybeRenderable, { + ...mouseEvent, + isDragging: true + }); + maybeRenderable.processMouseEvent(event2); + } + this.finishSelection(); + return true; + } + if (mouseEvent.type === "down" && mouseEvent.button === 0 /* LEFT */ && this.currentSelection) { + if (mouseEvent.modifiers.ctrl) { + this.currentSelection.isDragging = true; + this.updateSelection(maybeRenderable, mouseEvent.x, mouseEvent.y); + return true; + } + } + if (!sameElement && (mouseEvent.type === "drag" || mouseEvent.type === "move")) { + if (this.lastOverRenderable && this.lastOverRenderable !== this.capturedRenderable && !this.lastOverRenderable.isDestroyed) { + const event2 = new MouseEvent(this.lastOverRenderable, { + ...mouseEvent, + type: "out" + }); + this.lastOverRenderable.processMouseEvent(event2); + } + this.lastOverRenderable = maybeRenderable; + if (maybeRenderable) { + const event2 = new MouseEvent(maybeRenderable, { + ...mouseEvent, + type: "over", + source: this.capturedRenderable + }); + maybeRenderable.processMouseEvent(event2); + } + } + if (this.capturedRenderable && mouseEvent.type !== "up") { + const event2 = new MouseEvent(this.capturedRenderable, mouseEvent); + this.capturedRenderable.processMouseEvent(event2); + return true; + } + if (this.capturedRenderable && mouseEvent.type === "up") { + const event2 = new MouseEvent(this.capturedRenderable, { + ...mouseEvent, + type: "drag-end" + }); + this.capturedRenderable.processMouseEvent(event2); + this.capturedRenderable.processMouseEvent(new MouseEvent(this.capturedRenderable, mouseEvent)); + if (maybeRenderable) { + const event3 = new MouseEvent(maybeRenderable, { + ...mouseEvent, + type: "drop", + source: this.capturedRenderable + }); + maybeRenderable.processMouseEvent(event3); + } + this.lastOverRenderable = this.capturedRenderable; + this.lastOverRenderableNum = this.capturedRenderable.num; + this.setCapturedRenderable(undefined); + this.requestRender(); + } + let event; + if (maybeRenderable) { + if (mouseEvent.type === "drag" && mouseEvent.button === 0 /* LEFT */) { + this.setCapturedRenderable(maybeRenderable); + } else { + this.setCapturedRenderable(undefined); + } + event = this.dispatchMouseEvent(maybeRenderable, mouseEvent); + } else { + this.setCapturedRenderable(undefined); + this.lastOverRenderable = undefined; + } + if (!event?.defaultPrevented && mouseEvent.type === "down" && this.currentSelection) { + this.clearSelection(); + } + return true; + } + recheckHoverState() { + if (this._isDestroyed || !this._hasPointer) + return; + if (this.capturedRenderable) + return; + const hitId = this.hitTest(this._latestPointer.x, this._latestPointer.y); + const hitRenderable = Renderable.renderablesByNumber.get(hitId); + const lastOver = this.lastOverRenderable; + if (lastOver?.num === hitId) { + this.lastOverRenderableNum = hitId; + return; + } + const baseEvent = { + type: "move", + button: 0, + x: this._latestPointer.x, + y: this._latestPointer.y, + modifiers: this._lastPointerModifiers + }; + if (lastOver && !lastOver.isDestroyed) { + const event = new MouseEvent(lastOver, { ...baseEvent, type: "out" }); + lastOver.processMouseEvent(event); + } + this.lastOverRenderable = hitRenderable; + this.lastOverRenderableNum = hitId; + if (hitRenderable) { + const event = new MouseEvent(hitRenderable, { + ...baseEvent, + type: "over" + }); + hitRenderable.processMouseEvent(event); + } + } + setMousePointer(style) { + this._currentMousePointerStyle = style; + this.lib.setCursorStyleOptions(this.rendererPtr, { cursor: style }); + } + hitTest(x, y) { + return this.lib.checkHit(this.rendererPtr, x, y); + } + takeMemorySnapshot() { + if (this._isDestroyed) + return; + const memoryUsage = process.memoryUsage(); + this.lastMemorySnapshot = { + heapUsed: memoryUsage.heapUsed, + heapTotal: memoryUsage.heapTotal, + arrayBuffers: memoryUsage.arrayBuffers + }; + this.lib.updateMemoryStats(this.rendererPtr, this.lastMemorySnapshot.heapUsed, this.lastMemorySnapshot.heapTotal, this.lastMemorySnapshot.arrayBuffers); + this.emit("memory:snapshot" /* MEMORY_SNAPSHOT */, this.lastMemorySnapshot); + } + startMemorySnapshotTimer() { + this.stopMemorySnapshotTimer(); + this.memorySnapshotTimer = this.clock.setInterval(() => { + this.takeMemorySnapshot(); + }, this.memorySnapshotInterval); + } + stopMemorySnapshotTimer() { + if (this.memorySnapshotTimer) { + this.clock.clearInterval(this.memorySnapshotTimer); + this.memorySnapshotTimer = null; + } + } + setMemorySnapshotInterval(interval) { + this.memorySnapshotInterval = interval; + if (this._isRunning && interval > 0) { + this.startMemorySnapshotTimer(); + } else if (interval <= 0 && this.memorySnapshotTimer) { + this.clock.clearInterval(this.memorySnapshotTimer); + this.memorySnapshotTimer = null; + } + } + handleResize(width, height) { + if (this._isDestroyed) + return; + if (this._splitHeight > 0) { + this.processResize(width, height); + return; + } + if (this.resizeTimeoutId !== null) { + this.clock.clearTimeout(this.resizeTimeoutId); + this.resizeTimeoutId = null; + } + this.resizeTimeoutId = this.clock.setTimeout(() => { + this.resizeTimeoutId = null; + this.processResize(width, height); + }, this.resizeDebounceDelay); + } + queryPixelResolution() { + this.waitingForPixelResolution = true; + this.updateStdinParserProtocolContext({ pixelResolutionQueryActive: true }); + this.lib.queryPixelResolution(this.rendererPtr); + } + processResize(width, height) { + if (width === this._terminalWidth && height === this._terminalHeight) + return; + if (this._terminalIsSetup && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */ && !this.isSplitCursorSeedFrameBlocked()) { + this.flushPendingSplitOutputBeforeTransition(); + } + const pendingSplitFooterTransition = this.pendingSplitFooterTransition; + const previousGeometry = calculateRenderGeometry(this._screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight); + const prevWidth = this._terminalWidth; + const previousTerminalHeight = this._terminalHeight; + const visiblePreviousSplitHeight = pendingSplitFooterTransition?.sourceHeight ?? previousGeometry.effectiveFooterHeight; + this._terminalWidth = width; + this._terminalHeight = height; + this.queryPixelResolution(); + this.setCapturedRenderable(undefined); + this.stdinParser?.resetMouseState(); + const nextGeometry = calculateRenderGeometry(this._screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight); + const splitFooterActive = this._screenMode === "split-footer"; + if (splitFooterActive) { + let clearStart = null; + if (width < prevWidth && visiblePreviousSplitHeight > 0) { + clearStart = Math.max(previousTerminalHeight - visiblePreviousSplitHeight * 2, 1); + } + if (pendingSplitFooterTransition !== null) { + clearStart = clearStart === null ? pendingSplitFooterTransition.sourceTopLine : Math.min(clearStart, pendingSplitFooterTransition.sourceTopLine); + } + if (clearStart !== null) { + const flush = ANSI.moveCursorAndClear(clearStart, 1); + this.writeOut(flush); + } + this.currentRenderBuffer.clear(this.backgroundColor); + } + this.clearPendingSplitFooterTransition(); + this._splitHeight = nextGeometry.effectiveFooterHeight; + this.width = nextGeometry.renderWidth; + this.height = nextGeometry.renderHeight; + this.lib.resizeRenderer(this.rendererPtr, this.width, this.height); + if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") { + this.syncSplitScrollback(); + } else { + this.syncSplitFooterState(); + } + this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr); + this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr); + this._console.resize(this.width, this.height); + this.root.resize(this.width, this.height); + this.emit("resize" /* RESIZE */, this.width, this.height); + this.requestRender(); + } + resize(width, height) { + if (this._isDestroyed) + return; + this.processResize(width, height); + } + setBackgroundColor(color) { + const parsedColor = parseColor(color); + this.lib.setBackgroundColor(this.rendererPtr, parsedColor); + this.backgroundColor = parsedColor; + this.nextRenderBuffer.clear(parsedColor); + this.requestRender(); + } + toggleDebugOverlay() { + const willBeEnabled = !this.debugOverlay.enabled; + if (willBeEnabled && !this.memorySnapshotInterval) { + this.memorySnapshotInterval = 3000; + this.startMemorySnapshotTimer(); + this.automaticMemorySnapshot = true; + } else if (!willBeEnabled && this.automaticMemorySnapshot) { + this.stopMemorySnapshotTimer(); + this.memorySnapshotInterval = 0; + this.automaticMemorySnapshot = false; + } + this.debugOverlay.enabled = !this.debugOverlay.enabled; + this.lib.setDebugOverlay(this.rendererPtr, this.debugOverlay.enabled, this.debugOverlay.corner); + this.emit("debugOverlay:toggle" /* DEBUG_OVERLAY_TOGGLE */, this.debugOverlay.enabled); + this.requestRender(); + } + configureDebugOverlay(options) { + this.debugOverlay.enabled = options.enabled ?? this.debugOverlay.enabled; + this.debugOverlay.corner = options.corner ?? this.debugOverlay.corner; + this.lib.setDebugOverlay(this.rendererPtr, this.debugOverlay.enabled, this.debugOverlay.corner); + this.requestRender(); + } + setTerminalTitle(title) { + this.lib.setTerminalTitle(this.rendererPtr, title); + } + resetTerminalBgColor() { + this.writeOut("\x1B]111\x07"); + } + copyToClipboardOSC52(text, target) { + return this.clipboard.copyToClipboardOSC52(text, target); + } + clearClipboardOSC52(target) { + return this.clipboard.clearClipboardOSC52(target); + } + isOsc52Supported() { + return this._capabilities?.osc52 ?? this.clipboard.isOsc52Supported(); + } + dumpHitGrid() { + this.lib.dumpHitGrid(this.rendererPtr); + } + dumpBuffers(timestamp) { + this.lib.dumpBuffers(this.rendererPtr, timestamp); + } + dumpOutputBuffer(timestamp) { + this.lib.dumpOutputBuffer(this.rendererPtr, timestamp); + } + static setCursorPosition(renderer, x, y, visible = true) { + const lib = resolveRenderLib(); + lib.setCursorPosition(renderer.rendererPtr, x, y, visible); + } + static setCursorStyle(renderer, options) { + const lib = resolveRenderLib(); + lib.setCursorStyleOptions(renderer.rendererPtr, options); + if (options.cursor !== undefined) { + renderer._currentMousePointerStyle = options.cursor; + } + } + static setCursorColor(renderer, color) { + const lib = resolveRenderLib(); + lib.setCursorColor(renderer.rendererPtr, color); + } + setCursorPosition(x, y, visible = true) { + this.lib.setCursorPosition(this.rendererPtr, x, y, visible); + } + setCursorStyle(options) { + this.lib.setCursorStyleOptions(this.rendererPtr, options); + if (options.cursor !== undefined) { + this._currentMousePointerStyle = options.cursor; + } + } + setCursorColor(color) { + this.lib.setCursorColor(this.rendererPtr, color); + } + getCursorState() { + return this.lib.getCursorState(this.rendererPtr); + } + addPostProcessFn(processFn) { + this.postProcessFns.push(processFn); + } + removePostProcessFn(processFn) { + this.postProcessFns = this.postProcessFns.filter((fn) => fn !== processFn); + } + clearPostProcessFns() { + this.postProcessFns = []; + } + setFrameCallback(callback) { + this.frameCallbacks.push(callback); + } + removeFrameCallback(callback) { + this.frameCallbacks = this.frameCallbacks.filter((cb) => cb !== callback); + } + clearFrameCallbacks() { + this.frameCallbacks = []; + } + requestLive() { + this.liveRequestCounter++; + if (this._controlState === "idle" /* IDLE */ && this.liveRequestCounter > 0) { + this._controlState = "auto_started" /* AUTO_STARTED */; + this.internalStart(); + } + } + dropLive() { + this.liveRequestCounter = Math.max(0, this.liveRequestCounter - 1); + if (this._controlState === "auto_started" /* AUTO_STARTED */ && this.liveRequestCounter === 0) { + this._controlState = "idle" /* IDLE */; + this.internalPause(); + } + } + start() { + this._controlState = "explicit_started" /* EXPLICIT_STARTED */; + this.internalStart(); + } + auto() { + this._controlState = this._isRunning ? "auto_started" /* AUTO_STARTED */ : "idle" /* IDLE */; + } + internalStart() { + if (!this._isRunning && !this._isDestroyed) { + this._isRunning = true; + this.updateScheduled = false; + if (this.memorySnapshotInterval > 0) { + this.startMemorySnapshotTimer(); + } + this.startRenderLoop(); + } + } + pause() { + this._controlState = "explicit_paused" /* EXPLICIT_PAUSED */; + this.internalPause(); + } + suspend() { + this._previousControlState = this._controlState; + this._controlState = "explicit_suspended" /* EXPLICIT_SUSPENDED */; + this.updateScheduled = false; + this.internalPause(); + if (this._terminalIsSetup) { + this.clearSplitStartupCursorSeed(); + this.flushPendingSplitOutputBeforeTransition(true, { allowSuspended: true }); + this.suspendedNonAltSurfacePreserved = this._screenMode !== "alternate-screen" && this.renderOffset > 0; + } else { + this.suspendedNonAltSurfacePreserved = false; + } + this._suspendedMouseEnabled = this._useMouse; + this.disableMouse(); + this.removeExitListeners(); + this.waitingForPixelResolution = false; + this.updateStdinParserProtocolContext({ + privateCapabilityRepliesActive: false, + pixelResolutionQueryActive: false, + explicitWidthCprActive: false, + startupCursorCprActive: false + }); + this.stdinParser?.reset(); + this.stdin.removeListener("data", this.stdinListener); + this.themeModeState.cancelRefresh(); + this.lib.suspendRenderer(this.rendererPtr); + if (this.stdin.setRawMode) { + this.stdin.setRawMode(false); + } + this.stdin.pause(); + } + resume() { + if (this.stdin.setRawMode) { + this.stdin.setRawMode(true); + } + while (this.stdin.read() !== null) {} + this.stdin.on("data", this.stdinListener); + this.stdin.resume(); + this.addExitListeners(); + const resumePreservedNonAltSurface = this.pendingSuspendedTerminalSetup && this._screenMode !== "alternate-screen" && this.suspendedNonAltSurfacePreserved && this.renderOffset > 0; + if (this.pendingSuspendedTerminalSetup) { + this.pendingSuspendedTerminalSetup = false; + if (resumePreservedNonAltSurface) { + this.lib.resumeRenderer(this.rendererPtr); + } else { + this.lib.setupTerminal(this.rendererPtr, this._screenMode === "alternate-screen"); + } + } else { + this.lib.resumeRenderer(this.rendererPtr); + } + this.suspendedNonAltSurfacePreserved = false; + this.flushPendingSplitOutputBeforeTransition(false, { allowSuspended: true, allowPassthrough: true }); + if (this._screenMode === "split-footer" && this._splitHeight > 0) { + this.syncSplitFooterState(); + } + if (this._suspendedMouseEnabled) { + this.enableMouse(); + } + this.forceFullRepaintRequested = true; + this._controlState = this._previousControlState; + if (this._previousControlState === "auto_started" /* AUTO_STARTED */ || this._previousControlState === "explicit_started" /* EXPLICIT_STARTED */) { + this.internalStart(); + } else { + this.requestRender(); + } + } + internalPause() { + this._isRunning = false; + if (this.renderTimeout) { + this.clock.clearTimeout(this.renderTimeout); + this.renderTimeout = null; + } + if (!this.rendering) { + this.resolveIdleIfNeeded(); + } + } + stop() { + this._controlState = "explicit_stopped" /* EXPLICIT_STOPPED */; + this.internalStop(); + } + internalStop() { + if (this.isRunning && !this._isDestroyed) { + this._isRunning = false; + if (this.memorySnapshotTimer) { + this.clock.clearInterval(this.memorySnapshotTimer); + this.memorySnapshotTimer = null; + } + if (this.renderTimeout) { + this.clock.clearTimeout(this.renderTimeout); + this.renderTimeout = null; + } + if (!this.rendering) { + this.resolveIdleIfNeeded(); + } + } + } + destroy() { + if (this._isDestroyed) + return; + this._isDestroyed = true; + this._destroyPending = true; + this._palettePublishGeneration++; + if (this.rendering) { + this.prepareDestroyDuringRender(); + return; + } + this.finalizeDestroy(); + } + cleanupBeforeDestroy() { + if (this._destroyCleanupPrepared) + return; + this._destroyCleanupPrepared = true; + if (this._usesProcessStdout) { + process.removeListener("SIGWINCH", this.sigwinchHandler); + } + process.removeListener("uncaughtException", this.handleError); + process.removeListener("unhandledRejection", this.handleError); + process.removeListener("warning", this.warningHandler); + process.removeListener("beforeExit", this.exitHandler); + this.removeExitListeners(); + if (this.resizeTimeoutId !== null) { + this.clock.clearTimeout(this.resizeTimeoutId); + this.resizeTimeoutId = null; + } + if (this.capabilityTimeoutId !== null) { + this.clock.clearTimeout(this.capabilityTimeoutId); + this.capabilityTimeoutId = null; + } + this.clearSplitStartupCursorSeed(); + if (this.memorySnapshotTimer) { + this.clock.clearInterval(this.memorySnapshotTimer); + this.memorySnapshotTimer = null; + } + if (this.renderTimeout) { + this.clock.clearTimeout(this.renderTimeout); + this.renderTimeout = null; + } + this.themeModeState.cancelRefresh(); + this._isRunning = false; + this.waitingForPixelResolution = false; + this.updateStdinParserProtocolContext({ + privateCapabilityRepliesActive: false, + pixelResolutionQueryActive: false, + explicitWidthCprActive: false, + startupCursorCprActive: false + }, true); + this._useMouse = false; + this.setCapturedRenderable(undefined); + this.stdin.removeListener("data", this.stdinListener); + if (this.stdin.setRawMode) { + try { + this.stdin.setRawMode(false); + } catch (e) { + console.error("Error disabling raw mode during destroy:", e); + } + } + try { + this.stdin.pause(); + } catch (e) { + console.error("Error pausing stdin during destroy:", e); + } + if (this._feed !== null && this._splitHeight > 0 && !this._terminalIsSetup) { + this.flushPendingSplitOutputBeforeTransition(false, { allowSuspended: true, allowUnsetup: true }); + } + this.externalOutputMode = "passthrough"; + if (this._splitHeight > 0) { + this.flushStdoutCache(this._splitHeight, true); + } + } + prepareDestroyDuringRender() { + this.cleanupBeforeDestroy(); + this.lib.suspendRenderer(this.rendererPtr); + } + finalizeDestroy() { + if (this._destroyFinalized) + return; + this._destroyFinalized = true; + this._destroyPending = false; + this.cleanupBeforeDestroy(); + if (this._paletteDetector) { + this._paletteDetector.cleanup(); + this._paletteDetector = null; + } + this._paletteCache.clear(); + this._paletteDetectionPromise = null; + this._paletteDetectionSize = 0; + this._nativePaletteSignature = null; + this._emittedPaletteSignature = null; + this._paletteEpoch = 0; + this.resolveXtVersionWaiters(); + this.themeModeState.dispose(); + this.emit("destroy" /* DESTROY */); + try { + this.root.destroyRecursively(); + } catch (e) { + console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e)); + } + this.stdinParser?.destroy(); + this.stdinParser = null; + this.oscSubscribers.clear(); + this._console.destroy(); + if (this._splitHeight > 0 && this._terminalIsSetup && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) { + this.flushPendingSplitOutputBeforeTransition(true); + this.renderOffset = 0; + if (this.clearOnShutdown) { + this.lib.setRenderOffset(this.rendererPtr, 0); + } + } + this._externalOutputMode = "passthrough"; + this.pendingExternalOutputMode = null; + this.stdout.write = this.realStdoutWrite; + this.externalOutputQueue.clear(); + if (this._feed) { + try { + this._feed.drainAll(); + } catch (e) { + console.error("Error draining NativeSpanFeed during destroy:", e); + } + } + try { + this.lib.destroyRenderer(this.rendererPtr); + } catch (e) { + console.error("Error in lib.destroyRenderer during destroy:", e); + } + rendererTracker.renderers.delete(this); + if (rendererTracker.renderers.size === 0) { + destroyTreeSitterClient().catch((error) => { + console.error("Failed to destroy tree-sitter client:", error); + }); + } + if (this._feed) { + try { + this._feed.drainAll(); + } catch (e) { + console.error("Error draining NativeSpanFeed shutdown frames:", e); + } + this._detachFeed?.(); + this._detachFeed = null; + this._detachFeedError?.(); + this._detachFeedError = null; + this._feed.close(); + this._feed = null; + } + if (this._streamLeaseAcquired) { + if (rendererTracker.streamOwners.get(this.stdin) === this) + rendererTracker.streamOwners.delete(this.stdin); + if (rendererTracker.streamOwners.get(this.stdout) === this) + rendererTracker.streamOwners.delete(this.stdout); + this._streamLeaseAcquired = false; + } + if (this._onDestroy) { + try { + this._onDestroy(); + } catch (e) { + console.error("Error in onDestroy callback:", e instanceof Error ? e.stack : String(e)); + } + } + this.resolveIdleIfNeeded(); + } + startRenderLoop() { + if (!this._isRunning) + return; + this.lastTime = this.normalizeClockTime(this.clock.now(), 0); + this.frameCount = 0; + this.lastFpsTime = this.lastTime; + this.currentFps = 0; + if (this.feedIdleRenderScheduled) + return; + this.loop(); + } + async loop() { + if (this.rendering || this._isDestroyed) + return; + this.renderTimeout = null; + this.rendering = true; + if (this.renderTimeout) { + this.clock.clearTimeout(this.renderTimeout); + this.renderTimeout = null; + } + try { + this._frameId++; + const now = this.normalizeClockTime(this.clock.now(), this.lastTime); + const elapsed = this.getElapsedMs(now, this.lastTime); + const deltaTime = elapsed; + this.lastTime = now; + this.frameCount++; + if (this.getElapsedMs(now, this.lastFpsTime) >= 1000) { + this.currentFps = this.frameCount; + this.frameCount = 0; + this.lastFpsTime = now; + } + this.renderStats.frameCount++; + this.renderStats.fps = this.currentFps; + const overallStart = performance.now(); + const frameRequests = Array.from(this.animationRequest.values()); + this.animationRequest.clear(); + const animationRequestStart = performance.now(); + for (const callback of frameRequests) { + callback(deltaTime); + this.dropLive(); + } + const animationRequestEnd = performance.now(); + const animationRequestTime = animationRequestEnd - animationRequestStart; + const start = performance.now(); + for (const frameCallback of this.frameCallbacks) { + try { + await frameCallback(deltaTime); + } catch (error) { + console.error("Error in frame callback:", error); + } + } + const end = performance.now(); + this.renderStats.frameCallbackTime = end - start; + this.root.render(this.nextRenderBuffer, deltaTime); + for (const postProcessFn of this.postProcessFns) { + postProcessFn(this.nextRenderBuffer, deltaTime); + } + this._console.renderToBuffer(this.nextRenderBuffer); + if (!this._isDestroyed) { + const nativeStatus = this.renderNative() ?? "rendered"; + if (nativeStatus === "rendered") { + if (this._useMouse && this.lib.getHitGridDirty(this.rendererPtr)) { + this.recheckHoverState(); + } + const overallFrameTime = performance.now() - overallStart; + this.lib.updateStats(this.rendererPtr, overallFrameTime, this.renderStats.fps, this.renderStats.frameCallbackTime); + if (this.listenerCount("frame" /* FRAME */) > 0) { + this.emit("frame" /* FRAME */, { + frameId: this.frameId + }); + } + if (this.gatherStats) { + this.collectStatSample(overallFrameTime); + } + if (this._isRunning || this.immediateRerenderRequested) { + const targetFrameTime = this.immediateRerenderRequested ? this.minTargetFrameTime : this.targetFrameTime; + const delay = Math.max(1, targetFrameTime - Math.floor(overallFrameTime)); + this.immediateRerenderRequested = false; + this.renderTimeout = this.clock.setTimeout(() => { + this.renderTimeout = null; + this.loop(); + }, delay); + } else { + this.clock.clearTimeout(this.renderTimeout); + this.renderTimeout = null; + } + } else if (nativeStatus === "blocked") { + const overallFrameTime = performance.now() - overallStart; + if (this._isRunning || this.immediateRerenderRequested) { + const targetFrameTime = this.immediateRerenderRequested ? this.minTargetFrameTime : this.targetFrameTime; + const delay = Math.max(1, targetFrameTime - Math.floor(overallFrameTime)); + this.immediateRerenderRequested = false; + this.renderTimeout = this.clock.setTimeout(() => { + this.renderTimeout = null; + this.loop(); + }, delay); + } else { + this.clock.clearTimeout(this.renderTimeout); + this.renderTimeout = null; + } + } else if (nativeStatus === "backpressured") { + this.scheduleRenderAfterBackpressure(); + } else if (nativeStatus === "retryable-skip") { + this.immediateRerenderRequested = false; + this.renderTimeout = null; + } else if (nativeStatus === "failed") { + this.immediateRerenderRequested = false; + this.renderTimeout = null; + } + } + } finally { + this.rendering = false; + if (this._destroyPending) { + this.finalizeDestroy(); + } + this.resolveIdleIfNeeded(); + } + } + intermediateRender() { + this.immediateRerenderRequested = true; + this.loop(); + } + renderNative() { + if (this.renderingNative) { + console.error("Rendering called concurrently"); + throw new Error("Rendering called concurrently"); + } + this.renderingNative = true; + try { + if (this.isSplitCursorSeedFrameBlocked()) { + return "blocked"; + } + if (this._splitHeight > 0 && this._externalOutputMode === "capture-stdout") { + const forceSplitRepaint = this.forceFullRepaintRequested; + const status = this.flushPendingSplitCommits(forceSplitRepaint, this.pendingExternalOutputMode === "passthrough"); + if (status === "backpressured") { + return "backpressured"; + } + if (status === "failed") { + return "failed"; + } + this.forceFullRepaintRequested = false; + this.pendingSplitFooterTransition = null; + return "rendered"; + } + const force = this.forceFullRepaintRequested; + const nativeStatus = this.lib.render(this.rendererPtr, force); + if (nativeStatus === NATIVE_RENDER_STATUS_SKIPPED || nativeStatus === NATIVE_RENDER_STATUS_FAILED) { + return this.handleNativeRenderRejection(nativeStatus); + } + this.forceFullRepaintRequested = false; + this.pendingSplitFooterTransition = null; + return "rendered"; + } finally { + this.renderingNative = false; + } + } + collectStatSample(frameTime) { + this.frameTimes.push(frameTime); + if (this.frameTimes.length > this.maxStatSamples) { + this.frameTimes.shift(); + } + } + getNativeStats() { + return this.lib.getRenderStats(this.rendererPtr); + } + getStats() { + const nativeStats = this.getNativeStats(); + const frameTimes = [...this.frameTimes]; + const sum = frameTimes.reduce((acc, time) => acc + time, 0); + const avg = frameTimes.length ? sum / frameTimes.length : 0; + const min = frameTimes.length ? Math.min(...frameTimes) : 0; + const max = frameTimes.length ? Math.max(...frameTimes) : 0; + return { + ...nativeStats, + fps: this.renderStats.fps, + frameCount: this.renderStats.frameCount, + frameTimes, + averageFrameTime: avg, + minFrameTime: min, + maxFrameTime: max, + frameCallbackTime: this.renderStats.frameCallbackTime + }; + } + resetStats() { + this.frameTimes = []; + this.renderStats.frameCount = 0; + } + setGatherStats(enabled) { + this.gatherStats = enabled; + if (!enabled) { + this.frameTimes = []; + } + } + getSelection() { + return this.currentSelection; + } + get hasSelection() { + return !!this.currentSelection; + } + getSelectionContainer() { + return this.selectionContainers.length > 0 ? this.selectionContainers[this.selectionContainers.length - 1] : null; + } + clearSelection() { + if (this.currentSelection) { + for (const renderable of this.currentSelection.touchedRenderables) { + if (renderable.selectable && !renderable.isDestroyed) { + renderable.onSelectionChanged(null); + } + } + this.currentSelection = null; + } + this.selectionContainers = []; + } + startSelection(renderable, x, y) { + if (!renderable.selectable) + return; + this.clearSelection(); + this.selectionContainers.push(renderable.parent || this.root); + this.currentSelection = new Selection(renderable, { x, y }, { x, y }); + this.currentSelection.isStart = true; + this.notifySelectablesOfSelectionChange(); + } + updateSelection(currentRenderable, x, y, options) { + if (this.currentSelection) { + this.currentSelection.isStart = false; + this.currentSelection.focus = { x, y }; + if (options?.finishDragging) { + this.currentSelection.isDragging = false; + } + if (this.selectionContainers.length > 0) { + const currentContainer = this.selectionContainers[this.selectionContainers.length - 1]; + if (!currentRenderable || !this.isWithinContainer(currentRenderable, currentContainer)) { + const parentContainer = currentContainer.parent || this.root; + this.selectionContainers.push(parentContainer); + } else if (currentRenderable && this.selectionContainers.length > 1) { + let containerIndex = this.selectionContainers.indexOf(currentRenderable); + if (containerIndex === -1) { + const immediateParent = currentRenderable.parent || this.root; + containerIndex = this.selectionContainers.indexOf(immediateParent); + } + if (containerIndex !== -1 && containerIndex < this.selectionContainers.length - 1) { + this.selectionContainers = this.selectionContainers.slice(0, containerIndex + 1); + } + } + } + this.notifySelectablesOfSelectionChange(); + } + } + requestSelectionUpdate() { + if (this.currentSelection?.isDragging) { + const pointer = this._latestPointer; + const maybeRenderableId = this.hitTest(pointer.x, pointer.y); + const maybeRenderable = Renderable.renderablesByNumber.get(maybeRenderableId); + this.updateSelection(maybeRenderable, pointer.x, pointer.y); + } + } + isWithinContainer(renderable, container) { + let current = renderable; + while (current) { + if (current === container) + return true; + current = current.parent; + } + return false; + } + finishSelection() { + if (this.currentSelection) { + this.currentSelection.isDragging = false; + this.emit("selection" /* SELECTION */, this.currentSelection); + this.notifySelectablesOfSelectionChange(); + } + } + notifySelectablesOfSelectionChange() { + const selectedRenderables = []; + const touchedRenderables = []; + const currentContainer = this.selectionContainers.length > 0 ? this.selectionContainers[this.selectionContainers.length - 1] : this.root; + if (this.currentSelection) { + this.walkSelectableRenderables(currentContainer, this.currentSelection.bounds, selectedRenderables, touchedRenderables); + for (const renderable of this.currentSelection.touchedRenderables) { + if (!touchedRenderables.includes(renderable) && !renderable.isDestroyed) { + renderable.onSelectionChanged(null); + } + } + this.currentSelection.updateSelectedRenderables(selectedRenderables); + this.currentSelection.updateTouchedRenderables(touchedRenderables); + } + } + walkSelectableRenderables(container, selectionBounds, selectedRenderables, touchedRenderables) { + const children = getObjectsInViewport(selectionBounds, container.getChildrenSortedByPrimaryAxis(), container.primaryAxis, 0, 0); + for (const child of children) { + if (child.selectable) { + const hasSelection = child.onSelectionChanged(this.currentSelection); + if (hasSelection) { + selectedRenderables.push(child); + } + touchedRenderables.push(child); + } + if (child.getChildrenCount() > 0) { + this.walkSelectableRenderables(child, selectionBounds, selectedRenderables, touchedRenderables); + } + } + } + get paletteDetectionStatus() { + if (this._paletteDetectionPromise) + return "detecting"; + if (this._paletteCache.size > 0) + return "cached"; + return "idle"; + } + getCachedPaletteBySize(size) { + const exactMatch = this._paletteCache.get(size); + if (exactMatch) { + return exactMatch; + } + const largerSize = [...this._paletteCache.keys()].sort((a, b) => a - b).find((candidate) => candidate >= size); + if (largerSize === undefined) { + return null; + } + const source = this._paletteCache.get(largerSize); + if (!source) { + return null; + } + const projected = { + ...source, + palette: source.palette.slice(0, size) + }; + this._paletteCache.set(size, projected); + return projected; + } + ensurePaletteDetector() { + if (!this._paletteDetector) { + const isTmux = Boolean(this.capabilities?.multiplexer === "tmux" || this.capabilities?.terminal?.name?.toLowerCase()?.includes("tmux")); + const isLegacyTmux = this.capabilities?.terminal?.name?.toLowerCase()?.includes("tmux") && this.capabilities?.terminal?.version?.localeCompare("3.6") < 0; + this._paletteDetector = createTerminalPalette({ + stdin: this.stdin, + stdout: this.stdout, + writeFn: (data) => this._isDestroyed ? false : this.writeOut(data), + isLegacyTmux, + isTmux, + oscSource: { + subscribeOsc: this.subscribeOsc.bind(this) + }, + clock: this.clock + }); + } + return this._paletteDetector; + } + syncNativePaletteState(colors) { + const signature = buildTerminalPaletteSignature(colors); + if (this._nativePaletteSignature !== signature) { + this._paletteEpoch = this._paletteEpoch + 1 >>> 0; + } + this._nativePaletteSignature = signature; + const normalized = normalizeTerminalPalette(colors); + this.lib.rendererSetPaletteState(this.rendererPtr, normalized.palette, normalized.defaultForeground, normalized.defaultBackground, this._paletteEpoch); + } + emitPaletteChange(colors) { + if (this.listenerCount("palette" /* PALETTE */) === 0) + return; + const signature = buildTerminalPaletteSignature(colors); + if (this._emittedPaletteSignature === signature) + return; + this._emittedPaletteSignature = signature; + this.emit("palette" /* PALETTE */, colors); + } + resolveXtVersionWaiters() { + if (this.xtVersionWaiters.size === 0) + return; + const resolvers = [...this.xtVersionWaiters]; + this.xtVersionWaiters.clear(); + for (const resolve of resolvers) { + resolve(); + } + } + waitForXtVersion() { + if (this.capabilityTimeoutId === null || this._capabilities?.terminal?.from_xtversion) { + return Promise.resolve(); + } + return new Promise((resolve) => { + this.xtVersionWaiters.add(resolve); + }); + } + shouldSyncNativePaletteState() { + return Boolean(this._terminalIsSetup && !this._isDestroyed && this._capabilities?.ansi256 && !this._capabilities?.rgb); + } + refreshPalette() { + const publishGeneration = this._palettePublishGeneration; + this.getPalette({ size: NATIVE_PALETTE_QUERY_SIZE }).then(() => { + if (this._isDestroyed) + return; + if (this._palettePublishGeneration === publishGeneration) + this.requestRender(); + }).catch(() => {}); + } + clearPaletteCache() { + this._palettePublishGeneration++; + this._paletteCache.clear(); + } + async getPalette(options) { + if (this._controlState === "explicit_suspended" /* EXPLICIT_SUSPENDED */) { + throw new Error("Cannot detect palette while renderer is suspended"); + } + const requestedSize = options?.size ?? 16; + const detectionTimeout = options?.timeout; + const cachedPalette = this.getCachedPaletteBySize(requestedSize); + if (cachedPalette) { + return cachedPalette; + } + const terminal = this._capabilities?.terminal; + const hasTmuxVersion = terminal?.name?.toLowerCase() === "tmux" && Boolean(terminal.version); + if (this._capabilities?.multiplexer === "tmux" && !hasTmuxVersion) { + await this.waitForXtVersion(); + const afterCapabilityWait = this.getCachedPaletteBySize(requestedSize); + if (afterCapabilityWait) { + return afterCapabilityWait; + } + } + if (this._paletteDetectionPromise) { + if (this._paletteDetectionSize >= requestedSize) { + return this._paletteDetectionPromise.then((palette) => { + const cached = this.getCachedPaletteBySize(requestedSize); + if (cached) { + return cached; + } + const projected = { + ...palette, + palette: palette.palette.slice(0, requestedSize) + }; + this._paletteCache.set(requestedSize, projected); + return projected; + }); + } + await this._paletteDetectionPromise; + const afterWait = this.getCachedPaletteBySize(requestedSize); + if (afterWait) { + return afterWait; + } + } + const detector = this.ensurePaletteDetector(); + const publishGeneration = this._palettePublishGeneration; + this._paletteDetectionSize = requestedSize; + this._paletteDetectionPromise = detector.detect({ ...options, timeout: detectionTimeout }).then((result) => { + this._paletteCache.set(result.palette.length, result); + this._paletteDetectionPromise = null; + this._paletteDetectionSize = 0; + if (!this._isDestroyed && this._palettePublishGeneration === publishGeneration) { + this.emitPaletteChange(result); + if (this.shouldSyncNativePaletteState() && result.palette.length >= NATIVE_PALETTE_QUERY_SIZE) { + this.syncNativePaletteState(result); + } else if (this.shouldSyncNativePaletteState() && !this._paletteCache.has(NATIVE_PALETTE_QUERY_SIZE)) { + this.refreshPalette(); + } + } + return result; + }).catch((error) => { + this._paletteDetectionPromise = null; + this._paletteDetectionSize = 0; + throw error; + }); + const detected = await this._paletteDetectionPromise; + const finalPalette = this.getCachedPaletteBySize(requestedSize) ?? detected; + return finalPalette; + } +} + +export { h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, TextBufferView, EditBuffer, EditorView, convertThemeToStyles, SyntaxStyle, ANSI, BoxRenderable, TextBufferRenderable, CodeRenderable, isTextNodeRenderable, TextNodeRenderable, RootTextNodeRenderable, TextRenderable, NativeSpanFeed, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingAction, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, EditBufferRenderableEvents, isEditBufferRenderable, EditBufferRenderable, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer }; + +//# debugId=D566D64CFF69CBEF64756E2164756E21 +//# sourceMappingURL=index-07zpr2dg.js.map diff --git a/.patches/@opentui/core/index-07zpr2dg.js.map b/.patches/@opentui/core/index-07zpr2dg.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/index-07zpr2dg.js.map @@ -0,0 +1,33 @@ +{ + "version": 3, + "sources": ["../src/Renderable.ts", "../src/lib/renderable.validations.ts", "../src/renderables/composition/vnode.ts", "../src/text-buffer-view.ts", "../src/edit-buffer.ts", "../src/editor-view.ts", "../src/syntax-style.ts", "../src/renderables/Box.ts", "../src/renderables/TextBufferRenderable.ts", "../src/renderables/Code.ts", "../src/renderables/TextNode.ts", "../src/renderables/Text.ts", "../src/NativeSpanFeed.ts", "../src/console.ts", "../src/lib/output.capture.ts", "../src/lib/keybinding.internal.ts", "../src/renderables/EditBufferRenderable.ts", "../src/ansi.ts", "../src/lib/clipboard.ts", "../src/renderer.ts", "../src/lib/objects-in-viewport.ts", "../src/lib/render-geometry.ts", "../src/lib/terminal-capability-detection.ts", "../src/renderer-theme-mode.ts"], + "sourcesContent": [ + "import { EventEmitter } from \"events\"\nimport Yoga, { Direction, Display, Edge, FlexDirection, type Node as YogaNode } from \"./yoga.js\"\nimport { OptimizedBuffer } from \"./buffer.js\"\nimport type { KeyEvent, PasteEvent } from \"./lib/KeyHandler.js\"\nimport type { MouseEventType } from \"./lib/parse.mouse.js\"\nimport type { Selection } from \"./lib/selection.js\"\nimport {\n parseAlign,\n parseAlignItems,\n parseFlexDirection,\n parseJustify,\n parseOverflow,\n parsePositionType,\n parseWrap,\n type AlignString,\n type FlexDirectionString,\n type JustifyString,\n type OverflowString,\n type PositionTypeString,\n type WrapString,\n} from \"./lib/yoga.options.js\"\nimport { maybeMakeRenderable, type VNode } from \"./renderables/composition/vnode.js\"\nimport type { MouseEvent } from \"./renderer.js\"\nimport type { RenderContext } from \"./types.js\"\nimport {\n validateOptions,\n isPositionType,\n isDimensionType,\n isFlexBasisType,\n isSizeType,\n isMarginType,\n isPaddingType,\n isPositionTypeType,\n isOverflowType,\n} from \"./lib/renderable.validations.js\"\n\nconst BrandedRenderable: unique symbol = Symbol.for(\"@opentui/core/Renderable\")\n\nexport enum LayoutEvents {\n LAYOUT_CHANGED = \"layout-changed\",\n ADDED = \"added\",\n REMOVED = \"removed\",\n RESIZED = \"resized\",\n}\n\nexport enum RenderableEvents {\n FOCUSED = \"focused\",\n BLURRED = \"blurred\",\n DESTROYED = \"destroyed\",\n}\n\nexport interface Position {\n top?: number | \"auto\" | `${number}%`\n right?: number | \"auto\" | `${number}%`\n bottom?: number | \"auto\" | `${number}%`\n left?: number | \"auto\" | `${number}%`\n}\n\nexport interface BaseRenderableOptions {\n id?: string\n}\n\nexport interface LayoutOptions extends BaseRenderableOptions {\n flexGrow?: number\n flexShrink?: number\n flexDirection?: FlexDirectionString\n flexWrap?: WrapString\n alignItems?: AlignString\n justifyContent?: JustifyString\n alignSelf?: AlignString\n flexBasis?: number | \"auto\" | undefined\n position?: PositionTypeString\n overflow?: OverflowString\n top?: number | \"auto\" | `${number}%`\n right?: number | \"auto\" | `${number}%`\n bottom?: number | \"auto\" | `${number}%`\n left?: number | \"auto\" | `${number}%`\n minWidth?: number | \"auto\" | `${number}%`\n minHeight?: number | \"auto\" | `${number}%`\n maxWidth?: number | \"auto\" | `${number}%`\n maxHeight?: number | \"auto\" | `${number}%`\n margin?: number | \"auto\" | `${number}%`\n marginX?: number | \"auto\" | `${number}%`\n marginY?: number | \"auto\" | `${number}%`\n marginTop?: number | \"auto\" | `${number}%`\n marginRight?: number | \"auto\" | `${number}%`\n marginBottom?: number | \"auto\" | `${number}%`\n marginLeft?: number | \"auto\" | `${number}%`\n padding?: number | `${number}%`\n paddingX?: number | `${number}%`\n paddingY?: number | `${number}%`\n paddingTop?: number | `${number}%`\n paddingRight?: number | `${number}%`\n paddingBottom?: number | `${number}%`\n paddingLeft?: number | `${number}%`\n enableLayout?: boolean\n}\n\nexport interface RenderableOptions extends Partial {\n width?: number | \"auto\" | `${number}%`\n height?: number | \"auto\" | `${number}%`\n zIndex?: number\n visible?: boolean\n buffered?: boolean\n live?: boolean\n opacity?: number\n\n // Draw-only hooks for custom rendering/decorations. They run after layout\n // and viewport culling, so do not mutate layout, children, or reactive state here.\n // Culled children do not run these hooks.\n renderBefore?: (this: T, buffer: OptimizedBuffer, deltaTime: number) => void\n renderAfter?: (this: T, buffer: OptimizedBuffer, deltaTime: number) => void\n\n // catch all\n onMouse?: (this: T, event: MouseEvent) => void\n\n onMouseDown?: (this: T, event: MouseEvent) => void\n onMouseUp?: (this: T, event: MouseEvent) => void\n onMouseMove?: (this: T, event: MouseEvent) => void\n onMouseDrag?: (this: T, event: MouseEvent) => void\n onMouseDragEnd?: (this: T, event: MouseEvent) => void\n onMouseDrop?: (this: T, event: MouseEvent) => void\n onMouseOver?: (this: T, event: MouseEvent) => void\n onMouseOut?: (this: T, event: MouseEvent) => void\n onMouseScroll?: (this: T, event: MouseEvent) => void\n\n onPaste?: (this: T, event: PasteEvent) => void\n\n onKeyDown?: (key: KeyEvent) => void\n\n onSizeChange?: (this: T) => void\n}\n\nexport function isRenderable(obj: any): obj is Renderable {\n return !!obj?.[BrandedRenderable]\n}\n\nexport abstract class BaseRenderable extends EventEmitter {\n [BrandedRenderable] = true\n\n private static renderableNumber = 1\n protected _id: string\n public readonly num: number\n protected _dirty: boolean = false\n public parent: BaseRenderable | null = null\n protected _visible: boolean = true\n\n constructor(options: BaseRenderableOptions) {\n super()\n this.num = BaseRenderable.renderableNumber++\n this._id = options.id ?? `renderable-${this.num}`\n }\n\n public abstract add(obj: BaseRenderable | unknown, index?: number): number\n public abstract remove(id: string): void\n public abstract insertBefore(obj: BaseRenderable | unknown, anchor: BaseRenderable | unknown): void\n public abstract getChildren(): BaseRenderable[]\n public abstract getChildrenCount(): number\n public abstract getRenderable(id: string): BaseRenderable | undefined\n public abstract requestRender(): void\n public abstract findDescendantById(id: string): BaseRenderable | undefined\n\n public get id(): string {\n return this._id\n }\n\n public set id(value: string) {\n this._id = value\n }\n\n public get isDirty(): boolean {\n return this._dirty\n }\n\n protected markClean(): void {\n this._dirty = false\n }\n\n protected markDirty(): void {\n this._dirty = true\n }\n\n public destroy(): void {\n // Default implementation: do nothing\n // Override this method to provide custom removal logic\n }\n\n public destroyRecursively(): void {\n // Default implementation: do nothing\n // Override this method to provide custom destruction logic\n }\n\n public get visible(): boolean {\n return this._visible\n }\n\n public set visible(value: boolean) {\n this._visible = value\n }\n}\n\ninterface LayoutGenerationContext extends RenderContext {\n __otuiLayoutGeneration?: number\n __otuiRenderListRevision?: number\n}\n\nfunction getLayoutGeneration(ctx: RenderContext): number {\n return (ctx as LayoutGenerationContext).__otuiLayoutGeneration ?? 0\n}\n\nfunction bumpLayoutGeneration(ctx: RenderContext): number {\n const next = getLayoutGeneration(ctx) + 1\n const generationContext = ctx as LayoutGenerationContext\n generationContext.__otuiLayoutGeneration = next\n return next\n}\n\nfunction getRenderListRevision(ctx: RenderContext): number {\n return (ctx as LayoutGenerationContext).__otuiRenderListRevision ?? 0\n}\n\nfunction bumpRenderListRevision(ctx: RenderContext): void {\n const generationContext = ctx as LayoutGenerationContext\n generationContext.__otuiRenderListRevision = getRenderListRevision(ctx) + 1\n}\n\nexport abstract class Renderable extends BaseRenderable {\n static renderablesByNumber: Map = new Map()\n\n protected _isDestroyed: boolean = false\n protected _ctx: RenderContext\n protected _translateX: number = 0\n protected _translateY: number = 0\n protected _x: number = 0\n protected _y: number = 0\n // Render hot paths only need absolute terminal coordinates. Cache them during\n // layout so render-time code does not keep walking parent chains via x/y.\n protected _screenX: number = 0\n protected _screenY: number = 0\n protected _width: number | \"auto\" | `${number}%`\n protected _height: number | \"auto\" | `${number}%`\n protected _widthValue: number = 0\n protected _heightValue: number = 0\n private _zIndex: number\n public selectable: boolean = false\n protected buffered: boolean\n protected frameBuffer: OptimizedBuffer | null = null\n\n protected _focusable: boolean = false\n protected _focused: boolean = false\n protected _hasFocusedDescendant: boolean = false\n protected keypressHandler: ((key: KeyEvent) => void) | null = null\n protected pasteHandler: ((event: PasteEvent) => void) | null = null\n\n private _live: boolean = false\n protected _liveCount: number = 0\n\n private _sizeChangeListener: (() => void) | undefined = undefined\n private _mouseListener: ((event: MouseEvent) => void) | null = null\n private _mouseListeners: Partial void>> = {}\n private _pasteListener: ((event: PasteEvent) => void) | undefined = undefined\n private _keyListeners: Partial void>> = {}\n\n protected yogaNode: YogaNode\n protected _positionType: PositionTypeString = \"relative\"\n protected _overflow: OverflowString = \"visible\"\n protected _position: Position = {}\n protected _opacity: number = 1.0\n private _flexShrink: number = 1\n\n private renderableMapById: Map = new Map()\n protected _childrenInLayoutOrder: Renderable[] = []\n protected _childrenInZIndexOrder: Renderable[] = []\n private needsZIndexSort: boolean = false\n public parent: Renderable | null = null\n\n private childrenPrimarySortDirty: boolean = true\n private childrenSortedByPrimaryAxis: Renderable[] = []\n private _shouldUpdateBefore: Set = new Set()\n\n // Frame id of the last updateFromLayout(); -1 ensures the first call runs.\n private _lastLayoutFrame: number = -1\n\n public onLifecyclePass: (() => void) | null = null\n\n public renderBefore?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void\n public renderAfter?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void\n\n constructor(ctx: RenderContext, options: RenderableOptions) {\n super(options)\n\n this._ctx = ctx\n Renderable.renderablesByNumber.set(this.num, this)\n\n validateOptions(this.id, options)\n\n this.renderBefore = options.renderBefore\n this.renderAfter = options.renderAfter\n\n this._width = options.width ?? \"auto\"\n this._height = options.height ?? \"auto\"\n\n if (typeof this._width === \"number\") {\n this._widthValue = this._width\n }\n if (typeof this._height === \"number\") {\n this._heightValue = this._height\n }\n\n this._zIndex = options.zIndex ?? 0\n this._visible = options.visible !== false\n this.buffered = options.buffered ?? false\n this._live = options.live ?? false\n this._liveCount = this._live && this._visible ? 1 : 0\n this._opacity = options.opacity !== undefined ? Math.max(0, Math.min(1, options.opacity)) : 1.0\n\n this.yogaNode = Yoga.Node.createForOpenTUI()\n this.yogaNode.setDisplay(this._visible ? Display.Flex : Display.None)\n this.setupYogaProperties(options)\n\n this.applyEventOptions(options)\n\n if (this.buffered) {\n this.createFrameBuffer()\n }\n }\n\n public override get id() {\n return this._id\n }\n\n public override set id(value: string) {\n if (this.parent) {\n this.parent.renderableMapById.delete(this.id)\n this.parent.renderableMapById.set(value, this)\n }\n super.id = value\n }\n\n public get focusable(): boolean {\n return this._focusable\n }\n\n public set focusable(value: boolean) {\n this._focusable = value\n }\n\n public get ctx(): RenderContext {\n return this._ctx\n }\n\n public get visible(): boolean {\n return this._visible\n }\n\n public get primaryAxis(): \"row\" | \"column\" {\n const dir = this.yogaNode.getFlexDirection()\n return dir === 2 || dir === 3 ? \"row\" : \"column\"\n }\n\n public set visible(value: boolean) {\n if (this._visible === value) return\n\n const wasVisible = this._visible\n this._visible = value\n this.yogaNode.setDisplay(value ? Display.Flex : Display.None)\n bumpRenderListRevision(this._ctx)\n\n if (this._live) {\n if (!wasVisible && value) {\n this.propagateLiveCount(1)\n } else if (wasVisible && !value) {\n this.propagateLiveCount(-1)\n }\n }\n\n if (this._focused) {\n this.blur()\n }\n this.requestRender()\n }\n\n public get opacity(): number {\n return this._opacity\n }\n\n public set opacity(value: number) {\n const clamped = Math.max(0, Math.min(1, value))\n if (this._opacity !== clamped) {\n this._opacity = clamped\n bumpRenderListRevision(this._ctx)\n this.requestRender()\n }\n }\n\n public hasSelection(): boolean {\n return false\n }\n\n public onSelectionChanged(selection: Selection | null): boolean {\n // Default implementation: do nothing\n // Override this method to provide custom selection handling\n return false\n }\n\n public getSelectedText(): string {\n return \"\"\n }\n\n public shouldStartSelection(x: number, y: number): boolean {\n return false\n }\n\n public focus(): void {\n if (this._isDestroyed || this._focused || !this._focusable) return\n\n this._focused = true\n this._ctx.focusRenderable(this)\n this.requestRender()\n\n this.keypressHandler = (key: KeyEvent) => {\n if (this._isDestroyed) return\n this._keyListeners[\"down\"]?.(key)\n // Check again after user listener - it might have destroyed the renderable\n if (this._isDestroyed) return\n if (!key.defaultPrevented && this.handleKeyPress) {\n this.handleKeyPress(key)\n }\n }\n\n this.pasteHandler = (event: PasteEvent) => {\n if (this._isDestroyed) return\n this._pasteListener?.call(this, event)\n // Check again after user listener - it might have destroyed the renderable\n if (this._isDestroyed) return\n if (!event.defaultPrevented && this.handlePaste) {\n this.handlePaste(event)\n }\n }\n\n this.ctx._internalKeyInput.onInternal(\"keypress\", this.keypressHandler)\n this.ctx._internalKeyInput.onInternal(\"paste\", this.pasteHandler)\n this.propagateFocusChange(true)\n this.emit(RenderableEvents.FOCUSED)\n }\n\n protected propagateFocusChange(hasFocus: boolean): void {\n let parent = this.parent\n while (parent) {\n if (parent._hasFocusedDescendant !== hasFocus) {\n parent._hasFocusedDescendant = hasFocus\n parent.markDirty()\n }\n parent = parent.parent\n }\n\n this.requestRender()\n }\n\n public blur(): void {\n if (!this._focused || !this._focusable) return\n\n this._ctx.blurRenderable(this)\n this._focused = false\n this.requestRender()\n\n if (this.keypressHandler) {\n this.ctx._internalKeyInput.offInternal(\"keypress\", this.keypressHandler)\n this.keypressHandler = null\n }\n\n if (this.pasteHandler) {\n this.ctx._internalKeyInput.offInternal(\"paste\", this.pasteHandler)\n this.pasteHandler = null\n }\n\n this.propagateFocusChange(false)\n this.emit(RenderableEvents.BLURRED)\n }\n\n public get focused(): boolean {\n return this._focused\n }\n\n public get hasFocusedDescendant(): boolean {\n return this._hasFocusedDescendant\n }\n\n public get live(): boolean {\n return this._live\n }\n\n public get liveCount(): number {\n return this._liveCount\n }\n\n public set live(value: boolean) {\n if (this._live === value) return\n\n this._live = value\n\n if (this._visible) {\n const delta = value ? 1 : -1\n this.propagateLiveCount(delta)\n }\n }\n\n protected propagateLiveCount(delta: number): void {\n this._liveCount += delta\n this.parent?.propagateLiveCount(delta)\n }\n\n public handleKeyPress?(key: KeyEvent): boolean\n public handlePaste?(event: PasteEvent): void\n\n public findDescendantById(id: string): Renderable | undefined {\n for (const child of this._childrenInLayoutOrder) {\n if (child.id === id) return child\n if (isRenderable(child)) {\n const found = child.findDescendantById(id)\n if (found) return found\n }\n }\n return undefined\n }\n\n public requestRender() {\n this.markDirty()\n this._ctx.requestRender()\n }\n\n public get translateX(): number {\n return this._translateX\n }\n\n // Translate updates bypass layout, so keep the absolute screen cache current\n // here to make same-frame sort/cull/render reads observe the new position.\n public set translateX(value: number) {\n if (this._translateX === value) return\n this._translateX = value\n const parentScreenX = this.parent ? this.parent._screenX : 0\n this._screenX = parentScreenX + this._x + this._translateX\n if (this.parent) this.parent.childrenPrimarySortDirty = true\n bumpRenderListRevision(this._ctx)\n this.requestRender()\n }\n\n public get translateY(): number {\n return this._translateY\n }\n\n public set translateY(value: number) {\n if (this._translateY === value) return\n this._translateY = value\n const parentScreenY = this.parent ? this.parent._screenY : 0\n this._screenY = parentScreenY + this._y + this._translateY\n if (this.parent) this.parent.childrenPrimarySortDirty = true\n bumpRenderListRevision(this._ctx)\n this.requestRender()\n }\n\n // Use the cached parent screen position plus this node's current local offset.\n // That keeps culling/sorting in sync even before this node refreshes _screenX/Y.\n public get screenX(): number {\n const parentScreenX = this.parent ? this.parent._screenX : 0\n return parentScreenX + this._x + this._translateX\n }\n\n public get screenY(): number {\n const parentScreenY = this.parent ? this.parent._screenY : 0\n return parentScreenY + this._y + this._translateY\n }\n\n public get x(): number {\n if (this.parent) {\n return this.parent.x + this._x + this._translateX\n }\n return this._x + this._translateX\n }\n\n public set x(value: number) {\n this.left = value\n }\n\n public get top(): number | \"auto\" | `${number}%` | undefined {\n return this._position.top\n }\n\n public set top(value: number | \"auto\" | `${number}%` | undefined) {\n if (isPositionType(value) || value === undefined) {\n this.setPosition({ top: value })\n }\n }\n\n public get right(): number | \"auto\" | `${number}%` | undefined {\n return this._position.right\n }\n\n public set right(value: number | \"auto\" | `${number}%` | undefined) {\n if (isPositionType(value) || value === undefined) {\n this.setPosition({ right: value })\n }\n }\n\n public get bottom(): number | \"auto\" | `${number}%` | undefined {\n return this._position.bottom\n }\n\n public set bottom(value: number | \"auto\" | `${number}%` | undefined) {\n if (isPositionType(value) || value === undefined) {\n this.setPosition({ bottom: value })\n }\n }\n\n public get left(): number | \"auto\" | `${number}%` | undefined {\n return this._position.left\n }\n\n public set left(value: number | \"auto\" | `${number}%` | undefined) {\n if (isPositionType(value) || value === undefined) {\n this.setPosition({ left: value })\n }\n }\n\n public get y(): number {\n if (this.parent) {\n return this.parent.y + this._y + this._translateY\n }\n return this._y + this._translateY\n }\n\n public set y(value: number) {\n this.top = value\n }\n\n public get width(): number {\n return this._widthValue\n }\n\n public set width(value: number | \"auto\" | `${number}%`) {\n if (!isDimensionType(value) || this._width === value) {\n return\n }\n\n this._width = value\n this.yogaNode.setWidth(value)\n\n if (typeof value === \"number\" && this._flexShrink === 1) {\n this._flexShrink = 0\n this.yogaNode.setFlexShrink(0)\n }\n\n this.requestRender()\n }\n\n public get height(): number {\n return this._heightValue\n }\n\n public set height(value: number | \"auto\" | `${number}%`) {\n if (!isDimensionType(value) || this._height === value) {\n return\n }\n\n this._height = value\n this.yogaNode.setHeight(value)\n\n if (typeof value === \"number\" && this._flexShrink === 1) {\n this._flexShrink = 0\n this.yogaNode.setFlexShrink(0)\n }\n\n this.requestRender()\n }\n\n public get zIndex(): number {\n return this._zIndex\n }\n\n public set zIndex(value: number) {\n if (this._zIndex !== value) {\n this._zIndex = value\n this.parent?.requestZIndexSort()\n bumpRenderListRevision(this._ctx)\n this.requestRender()\n }\n }\n\n private requestZIndexSort(): void {\n this.needsZIndexSort = true\n }\n\n private ensureZIndexSorted(): void {\n if (this.needsZIndexSort) {\n this._childrenInZIndexOrder.sort((a, b) => (a.zIndex > b.zIndex ? 1 : a.zIndex < b.zIndex ? -1 : 0))\n this.needsZIndexSort = false\n }\n }\n\n public getChildrenSortedByPrimaryAxis(): Renderable[] {\n if (\n !this.childrenPrimarySortDirty &&\n this.childrenSortedByPrimaryAxis.length === this._childrenInLayoutOrder.length\n ) {\n return this.childrenSortedByPrimaryAxis\n }\n\n const dir = this.yogaNode.getFlexDirection()\n const axis: \"x\" | \"y\" = dir === 2 || dir === 3 ? \"x\" : \"y\"\n\n const sorted = [...this._childrenInLayoutOrder]\n sorted.sort((a, b) => {\n // Viewport culling compares against screen-space bounds, so primary-axis\n // ordering has to use absolute positions instead of parent-relative x/y.\n const va = axis === \"y\" ? a.screenY : a.screenX\n const vb = axis === \"y\" ? b.screenY : b.screenX\n return va - vb\n })\n\n this.childrenSortedByPrimaryAxis = sorted\n this.childrenPrimarySortDirty = false\n return this.childrenSortedByPrimaryAxis\n }\n\n private setupYogaProperties(options: RenderableOptions): void {\n const node = this.yogaNode\n\n if (isFlexBasisType(options.flexBasis)) {\n node.setFlexBasis(options.flexBasis)\n }\n\n if (isSizeType(options.minWidth)) {\n node.setMinWidth(options.minWidth)\n }\n if (isSizeType(options.minHeight)) {\n node.setMinHeight(options.minHeight)\n }\n\n if (options.flexGrow !== undefined) {\n node.setFlexGrow(options.flexGrow)\n } else {\n node.setFlexGrow(0)\n }\n\n if (options.flexShrink !== undefined) {\n this._flexShrink = options.flexShrink\n node.setFlexShrink(options.flexShrink)\n } else {\n // If explicit numeric width is set, don't shrink by default\n // Otherwise follow web default of 1\n const hasExplicitWidth = typeof options.width === \"number\"\n const hasExplicitHeight = typeof options.height === \"number\"\n this._flexShrink = hasExplicitWidth || hasExplicitHeight ? 0 : 1\n node.setFlexShrink(this._flexShrink)\n }\n\n node.setFlexDirection(parseFlexDirection(options.flexDirection))\n node.setFlexWrap(parseWrap(options.flexWrap))\n node.setAlignItems(parseAlignItems(options.alignItems))\n node.setJustifyContent(parseJustify(options.justifyContent))\n node.setAlignSelf(parseAlign(options.alignSelf))\n\n if (isDimensionType(options.width)) {\n this._width = options.width\n this.yogaNode.setWidth(options.width)\n }\n if (isDimensionType(options.height)) {\n this._height = options.height\n this.yogaNode.setHeight(options.height)\n }\n\n this._positionType = options.position === \"absolute\" ? \"absolute\" : \"relative\"\n if (this._positionType !== \"relative\") {\n node.setPositionType(parsePositionType(this._positionType))\n }\n\n this._overflow = options.overflow === \"hidden\" ? \"hidden\" : options.overflow === \"scroll\" ? \"scroll\" : \"visible\"\n if (this._overflow !== \"visible\") {\n node.setOverflow(parseOverflow(this._overflow))\n }\n\n // TODO: flatten position properties internally as well\n const hasPositionProps =\n options.top !== undefined ||\n options.right !== undefined ||\n options.bottom !== undefined ||\n options.left !== undefined\n if (hasPositionProps) {\n this._position = {\n top: options.top,\n right: options.right,\n bottom: options.bottom,\n left: options.left,\n }\n this.updateYogaPosition(this._position)\n }\n\n if (isSizeType(options.maxWidth)) {\n node.setMaxWidth(options.maxWidth)\n }\n if (isSizeType(options.maxHeight)) {\n node.setMaxHeight(options.maxHeight)\n }\n\n this.setupMarginAndPadding(options)\n }\n\n private setupMarginAndPadding(options: RenderableOptions): void {\n const node = this.yogaNode\n\n if (isMarginType(options.margin)) {\n node.setMargin(Edge.All, options.margin)\n }\n\n if (isMarginType(options.marginX)) {\n node.setMargin(Edge.Horizontal, options.marginX)\n }\n if (isMarginType(options.marginY)) {\n node.setMargin(Edge.Vertical, options.marginY)\n }\n if (isMarginType(options.marginTop)) {\n node.setMargin(Edge.Top, options.marginTop)\n }\n if (isMarginType(options.marginRight)) {\n node.setMargin(Edge.Right, options.marginRight)\n }\n if (isMarginType(options.marginBottom)) {\n node.setMargin(Edge.Bottom, options.marginBottom)\n }\n if (isMarginType(options.marginLeft)) {\n node.setMargin(Edge.Left, options.marginLeft)\n }\n\n if (isPaddingType(options.padding)) {\n node.setPadding(Edge.All, options.padding)\n }\n\n if (isPaddingType(options.paddingX)) {\n node.setPadding(Edge.Horizontal, options.paddingX)\n }\n if (isPaddingType(options.paddingY)) {\n node.setPadding(Edge.Vertical, options.paddingY)\n }\n if (isPaddingType(options.paddingTop)) {\n node.setPadding(Edge.Top, options.paddingTop)\n }\n if (isPaddingType(options.paddingRight)) {\n node.setPadding(Edge.Right, options.paddingRight)\n }\n if (isPaddingType(options.paddingBottom)) {\n node.setPadding(Edge.Bottom, options.paddingBottom)\n }\n if (isPaddingType(options.paddingLeft)) {\n node.setPadding(Edge.Left, options.paddingLeft)\n }\n }\n\n set position(positionType: PositionTypeString | null | undefined) {\n if (!isPositionTypeType(positionType) || this._positionType === positionType) return\n\n this._positionType = positionType\n this.yogaNode.setPositionType(parsePositionType(positionType))\n this.requestRender()\n }\n\n get overflow(): OverflowString {\n return this._overflow\n }\n\n set overflow(overflow: OverflowString | null | undefined) {\n if (!isOverflowType(overflow) || this._overflow === overflow) return\n\n this._overflow = overflow\n this.yogaNode.setOverflow(parseOverflow(overflow))\n bumpRenderListRevision(this._ctx)\n this.requestRender()\n }\n\n public setPosition(position: Position): void {\n this._position = { ...this._position, ...position }\n this.updateYogaPosition(position)\n }\n\n private updateYogaPosition(position: Position): void {\n const node = this.yogaNode\n const { top, right, bottom, left } = position\n\n if (isPositionType(top)) {\n if (top === \"auto\") {\n node.setPositionAuto(Edge.Top)\n } else {\n node.setPosition(Edge.Top, top)\n }\n }\n if (isPositionType(right)) {\n if (right === \"auto\") {\n node.setPositionAuto(Edge.Right)\n } else {\n node.setPosition(Edge.Right, right)\n }\n }\n if (isPositionType(bottom)) {\n if (bottom === \"auto\") {\n node.setPositionAuto(Edge.Bottom)\n } else {\n node.setPosition(Edge.Bottom, bottom)\n }\n }\n if (isPositionType(left)) {\n if (left === \"auto\") {\n node.setPositionAuto(Edge.Left)\n } else {\n node.setPosition(Edge.Left, left)\n }\n }\n this.requestRender()\n }\n\n public set flexGrow(grow: number | null | undefined) {\n if (grow == null) {\n this.yogaNode.setFlexGrow(0)\n } else {\n this.yogaNode.setFlexGrow(grow)\n }\n this.requestRender()\n }\n\n public set flexShrink(shrink: number | null | undefined) {\n const value = shrink == null ? 1 : shrink\n this._flexShrink = value\n this.yogaNode.setFlexShrink(value)\n this.requestRender()\n }\n\n public set flexDirection(direction: FlexDirectionString | null | undefined) {\n this.yogaNode.setFlexDirection(parseFlexDirection(direction))\n this.requestRender()\n }\n\n public set flexWrap(wrap: WrapString | null | undefined) {\n this.yogaNode.setFlexWrap(parseWrap(wrap))\n this.requestRender()\n }\n\n public set alignItems(alignItems: AlignString | null | undefined) {\n this.yogaNode.setAlignItems(parseAlignItems(alignItems))\n this.requestRender()\n }\n\n public set justifyContent(justifyContent: JustifyString | null | undefined) {\n this.yogaNode.setJustifyContent(parseJustify(justifyContent))\n this.requestRender()\n }\n\n public set alignSelf(alignSelf: AlignString | null | undefined) {\n this.yogaNode.setAlignSelf(parseAlign(alignSelf))\n this.requestRender()\n }\n\n public set flexBasis(basis: number | \"auto\" | null | undefined) {\n if (isFlexBasisType(basis)) {\n this.yogaNode.setFlexBasis(basis)\n this.requestRender()\n }\n }\n\n public set minWidth(minWidth: number | `${number}%` | null | undefined) {\n if (isSizeType(minWidth)) {\n this.yogaNode.setMinWidth(minWidth)\n this.requestRender()\n }\n }\n\n public set maxWidth(maxWidth: number | `${number}%` | null | undefined) {\n if (isSizeType(maxWidth)) {\n this.yogaNode.setMaxWidth(maxWidth)\n this.requestRender()\n }\n }\n\n public set minHeight(minHeight: number | `${number}%` | null | undefined) {\n if (isSizeType(minHeight)) {\n this.yogaNode.setMinHeight(minHeight)\n this.requestRender()\n }\n }\n\n public set maxHeight(maxHeight: number | `${number}%` | null | undefined) {\n if (isSizeType(maxHeight)) {\n this.yogaNode.setMaxHeight(maxHeight)\n this.requestRender()\n }\n }\n\n public set margin(margin: number | \"auto\" | `${number}%` | null | undefined) {\n if (isMarginType(margin)) {\n this.yogaNode.setMargin(Edge.All, margin)\n this.requestRender()\n }\n }\n\n public set marginX(marginX: number | \"auto\" | `${number}%` | null | undefined) {\n if (isMarginType(marginX)) {\n this.yogaNode.setMargin(Edge.Horizontal, marginX)\n this.requestRender()\n }\n }\n\n public set marginY(marginY: number | \"auto\" | `${number}%` | null | undefined) {\n if (isMarginType(marginY)) {\n this.yogaNode.setMargin(Edge.Vertical, marginY)\n this.requestRender()\n }\n }\n\n public set marginTop(margin: number | \"auto\" | `${number}%` | null | undefined) {\n if (isMarginType(margin)) {\n this.yogaNode.setMargin(Edge.Top, margin)\n this.requestRender()\n }\n }\n\n public get marginTop(): number | \"auto\" | `${number}%` {\n const margin = this.yogaNode.getMargin(Edge.Top) as unknown\n if (typeof margin === \"number\") return margin\n if (typeof margin === \"object\" && margin && \"value\" in margin && typeof margin.value === \"number\")\n return margin.value\n return 0\n }\n\n public set marginRight(margin: number | \"auto\" | `${number}%` | null | undefined) {\n if (isMarginType(margin)) {\n this.yogaNode.setMargin(Edge.Right, margin)\n this.requestRender()\n }\n }\n\n public set marginBottom(margin: number | \"auto\" | `${number}%` | null | undefined) {\n if (isMarginType(margin)) {\n this.yogaNode.setMargin(Edge.Bottom, margin)\n this.requestRender()\n }\n }\n\n public set marginLeft(margin: number | \"auto\" | `${number}%` | null | undefined) {\n if (isMarginType(margin)) {\n this.yogaNode.setMargin(Edge.Left, margin)\n this.requestRender()\n }\n }\n\n public set padding(padding: number | `${number}%` | null | undefined) {\n if (isPaddingType(padding)) {\n this.yogaNode.setPadding(Edge.All, padding)\n this.requestRender()\n }\n }\n\n public set paddingX(paddingX: number | `${number}%` | null | undefined) {\n if (isPaddingType(paddingX)) {\n this.yogaNode.setPadding(Edge.Horizontal, paddingX)\n this.requestRender()\n }\n }\n\n public set paddingY(paddingY: number | `${number}%` | null | undefined) {\n if (isPaddingType(paddingY)) {\n this.yogaNode.setPadding(Edge.Vertical, paddingY)\n this.requestRender()\n }\n }\n\n public set paddingTop(padding: number | `${number}%` | null | undefined) {\n if (isPaddingType(padding)) {\n this.yogaNode.setPadding(Edge.Top, padding)\n this.requestRender()\n }\n }\n\n public set paddingRight(padding: number | `${number}%` | null | undefined) {\n if (isPaddingType(padding)) {\n this.yogaNode.setPadding(Edge.Right, padding)\n this.requestRender()\n }\n }\n\n public set paddingBottom(padding: number | `${number}%` | null | undefined) {\n if (isPaddingType(padding)) {\n this.yogaNode.setPadding(Edge.Bottom, padding)\n this.requestRender()\n }\n }\n\n public set paddingLeft(padding: number | `${number}%` | null | undefined) {\n if (isPaddingType(padding)) {\n this.yogaNode.setPadding(Edge.Left, padding)\n this.requestRender()\n }\n }\n\n public getLayoutNode(): YogaNode {\n return this.yogaNode\n }\n\n public updateFromLayout(): void {\n // Yoga layout is stable within a frame; skip the FFI round-trip on repeat calls.\n const frameId = this._ctx.frameId\n if (this._lastLayoutFrame === frameId) return\n this._lastLayoutFrame = frameId\n\n const layout = this.yogaNode.getComputedLayout()\n\n const oldX = this._x\n const oldY = this._y\n const oldWidth = this._widthValue\n const oldHeight = this._heightValue\n\n this._x = layout.left\n this._y = layout.top\n // Layout is updated top-down, so the parent cache is already current here.\n // Recomputing once per layout pass keeps render-time coordinate reads cheap.\n const parentScreenX = this.parent ? this.parent._screenX : 0\n const parentScreenY = this.parent ? this.parent._screenY : 0\n this._screenX = parentScreenX + this._x + this._translateX\n this._screenY = parentScreenY + this._y + this._translateY\n\n const newWidth = Math.max(layout.width, 1)\n const newHeight = Math.max(layout.height, 1)\n const sizeChanged = oldWidth !== newWidth || oldHeight !== newHeight\n\n this._widthValue = newWidth\n this._heightValue = newHeight\n\n if (sizeChanged) {\n this.onLayoutResize(newWidth, newHeight)\n }\n\n const positionChanged = oldX !== this._x || oldY !== this._y\n if (positionChanged) {\n if (this.parent) this.parent.childrenPrimarySortDirty = true\n }\n }\n\n protected onLayoutResize(width: number, height: number): void {\n if (this._visible) {\n // TODO: Should probably .markDirty()\n this.handleFrameBufferResize(width, height)\n this.onResize(width, height)\n this.requestRender()\n }\n }\n\n protected handleFrameBufferResize(width: number, height: number): void {\n if (!this.buffered) return\n\n if (width <= 0 || height <= 0) {\n return\n }\n\n if (this.frameBuffer) {\n this.frameBuffer.resize(width, height)\n } else {\n this.createFrameBuffer()\n }\n }\n\n protected createFrameBuffer(): void {\n const w = this.width\n const h = this.height\n\n if (w <= 0 || h <= 0) {\n return\n }\n\n try {\n const widthMethod = this._ctx.widthMethod\n this.frameBuffer = OptimizedBuffer.create(w, h, widthMethod, {\n respectAlpha: true,\n id: `framebuffer-${this.id}`,\n })\n } catch (error) {\n console.error(`Failed to create frame buffer for ${this.id}:`, error)\n this.frameBuffer = null\n }\n }\n\n /**\n * This will be called during a render pass.\n * Requesting a render during a render pass will drop the requested render.\n * If you need to request a render during a render pass, use process.nextTick.\n */\n protected onResize(width: number, height: number): void {\n this.onSizeChange?.()\n this.emit(\"resize\")\n // Override in subclasses for additional resize logic\n }\n\n private replaceParent(obj: Renderable) {\n if (obj.parent) {\n obj.parent.remove(obj.id)\n }\n obj.parent = this\n }\n\n public add(obj: Renderable | VNode | unknown, index?: number): number {\n if (!obj) {\n return -1\n }\n\n const renderable = maybeMakeRenderable(this._ctx, obj)\n if (!renderable) {\n return -1\n }\n\n if (renderable.isDestroyed) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`Renderable with id ${renderable.id} was already destroyed, skipping add`)\n }\n return -1\n }\n\n const anchorRenderable = index !== undefined ? this._childrenInLayoutOrder[index] : undefined\n\n if (anchorRenderable) {\n return this.insertBefore(renderable, anchorRenderable)\n }\n\n if (renderable.parent === this) {\n this.yogaNode.removeChild(renderable.getLayoutNode())\n this._childrenInLayoutOrder.splice(this._childrenInLayoutOrder.indexOf(renderable), 1)\n } else {\n this.replaceParent(renderable)\n this.needsZIndexSort = true\n this.renderableMapById.set(renderable.id, renderable)\n this._childrenInZIndexOrder.push(renderable)\n\n if (typeof renderable.onLifecyclePass === \"function\") {\n this._ctx.registerLifecyclePass(renderable)\n }\n\n if (renderable._liveCount > 0) {\n this.propagateLiveCount(renderable._liveCount)\n }\n }\n\n const childLayoutNode = renderable.getLayoutNode()\n const insertedIndex = this._childrenInLayoutOrder.length\n this._childrenInLayoutOrder.push(renderable)\n this.yogaNode.insertChild(childLayoutNode, insertedIndex)\n\n this.childrenPrimarySortDirty = true\n this._shouldUpdateBefore.add(renderable)\n bumpRenderListRevision(this._ctx)\n\n this.requestRender()\n\n return insertedIndex\n }\n\n insertBefore(obj: Renderable | VNode | unknown, anchor?: Renderable | unknown): number {\n if (!anchor) {\n return this.add(obj)\n }\n\n if (!obj) {\n return -1\n }\n\n const renderable = maybeMakeRenderable(this._ctx, obj)\n if (!renderable) {\n return -1\n }\n\n if (renderable.isDestroyed) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`Renderable with id ${renderable.id} was already destroyed, skipping insertBefore`)\n }\n return -1\n }\n\n if (!isRenderable(anchor)) {\n throw new Error(\"Anchor must be a Renderable\")\n }\n\n if (anchor.isDestroyed) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`Anchor with id ${anchor.id} was already destroyed, skipping insertBefore`)\n }\n return -1\n }\n\n if (!this.renderableMapById.has(anchor.id)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`Anchor with id ${anchor.id} does not exist within the parent ${this.id}, skipping insertBefore`)\n }\n return -1\n }\n\n if (renderable === anchor || renderable.id === anchor.id) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`Anchor is the same as the node ${renderable.id} being inserted, skipping insertBefore`)\n }\n return -1\n }\n\n if (renderable.parent === this) {\n this.yogaNode.removeChild(renderable.getLayoutNode())\n this._childrenInLayoutOrder.splice(this._childrenInLayoutOrder.indexOf(renderable), 1)\n } else {\n this.replaceParent(renderable)\n this.needsZIndexSort = true\n this.renderableMapById.set(renderable.id, renderable)\n this._childrenInZIndexOrder.push(renderable)\n\n if (typeof renderable.onLifecyclePass === \"function\") {\n this._ctx.registerLifecyclePass(renderable)\n }\n\n if (renderable._liveCount > 0) {\n this.propagateLiveCount(renderable._liveCount)\n }\n }\n\n this.childrenPrimarySortDirty = true\n\n const anchorIndex = this._childrenInLayoutOrder.indexOf(anchor)\n const insertedIndex = Math.max(0, Math.min(anchorIndex, this._childrenInLayoutOrder.length))\n\n this._childrenInLayoutOrder.splice(insertedIndex, 0, renderable)\n this.yogaNode.insertChild(renderable.getLayoutNode(), insertedIndex)\n\n this._shouldUpdateBefore.add(renderable)\n bumpRenderListRevision(this._ctx)\n\n this.requestRender()\n\n return insertedIndex\n }\n\n // TODO: that naming is meh\n public getRenderable(id: string): Renderable | undefined {\n return this.renderableMapById.get(id)\n }\n\n public remove(id: string): void {\n if (!id) {\n return\n }\n\n if (this.renderableMapById.has(id)) {\n const obj = this.renderableMapById.get(id)\n if (obj) {\n if (obj._liveCount > 0) {\n this.propagateLiveCount(-obj._liveCount)\n }\n\n const childLayoutNode = obj.getLayoutNode()\n this.yogaNode.removeChild(childLayoutNode)\n this.requestRender()\n\n obj.onRemove()\n obj.parent = null\n this._ctx.unregisterLifecyclePass(obj)\n this.renderableMapById.delete(id)\n\n const index = this._childrenInLayoutOrder.findIndex((obj) => obj.id === id)\n if (index !== -1) {\n this._childrenInLayoutOrder.splice(index, 1)\n }\n\n const zIndexIndex = this._childrenInZIndexOrder.findIndex((obj) => obj.id === id)\n if (zIndexIndex !== -1) {\n this._childrenInZIndexOrder.splice(zIndexIndex, 1)\n }\n\n this.childrenPrimarySortDirty = true\n bumpRenderListRevision(this._ctx)\n }\n }\n }\n\n protected onRemove(): void {\n // Default implementation: do nothing\n // Override this method to provide custom removal logic\n }\n\n public getChildren(): Renderable[] {\n return [...this._childrenInLayoutOrder]\n }\n\n public getChildrenCount(): number {\n return this._childrenInLayoutOrder.length\n }\n\n public updateLayout(deltaTime: number, renderList: RenderCommand[] = []): void {\n if (!this.visible) return\n\n this.onUpdate(deltaTime)\n\n // If destroyed during onUpdate, don't add to render list\n if (this._isDestroyed) return\n\n // NOTE: worst case updateFromLayout is called throughout the whole tree,\n // which currently still has yoga performance issues.\n // This can be mitigated at some point when the layout tree moved to native,\n // as in the native yoga tree we can use events during the calculateLayout phase,\n // and anctually know if a child has changed or not.\n // That would allow us to to generate optimised render commands,\n // including the layout updates, in one pass.\n this.updateFromLayout()\n\n // Update newly added children before getting visible children\n // This ensures their positions are current when culling happens\n if (this._shouldUpdateBefore.size > 0) {\n for (const child of this._shouldUpdateBefore) {\n if (!child.isDestroyed) {\n child.updateFromLayout()\n }\n }\n this._shouldUpdateBefore.clear()\n }\n\n // Check again after updateFromLayout, which calls onResize/onSizeChange\n if (this._isDestroyed) return\n\n // Push opacity BEFORE rendering this element so it affects this element and all children\n const shouldPushOpacity = this._opacity < 1.0\n if (shouldPushOpacity) {\n renderList.push({ action: \"pushOpacity\", opacity: this._opacity })\n }\n\n renderList.push({ action: \"render\", renderable: this })\n\n this.ensureZIndexSorted()\n\n const shouldPushScissor = this._overflow !== \"visible\" && this.width > 0 && this.height > 0\n if (shouldPushScissor) {\n const scissorRect = this.getScissorRect()\n renderList.push({\n action: \"pushScissorRect\",\n x: scissorRect.x,\n y: scissorRect.y,\n width: scissorRect.width,\n height: scissorRect.height,\n screenX: this._screenX,\n screenY: this._screenY,\n })\n }\n // Most renderables expose all children. Skip building a visible-child list\n // unless a subclass actually performs viewport/style-based child filtering.\n if (!this._hasVisibleChildFilter()) {\n for (const child of this._childrenInZIndexOrder) {\n child.updateLayout(deltaTime, renderList)\n }\n } else {\n // Refresh every child's layout before culling reads their screen\n // coordinates; otherwise culling runs against last frame's positions\n // and drops content that shifted this frame. The per-frame guard in\n // updateFromLayout keeps this at one FFI call per child per frame.\n for (const child of this._childrenInZIndexOrder) {\n if (child.isDestroyed) continue\n child.updateFromLayout()\n }\n const visibleChildren = this._getVisibleChildren()\n const visibleChildSet = new Set(visibleChildren)\n for (const child of this._childrenInZIndexOrder) {\n if (!visibleChildSet.has(child.num)) continue\n child.updateLayout(deltaTime, renderList)\n }\n }\n\n if (shouldPushScissor) {\n renderList.push({ action: \"popScissorRect\" })\n }\n if (shouldPushOpacity) {\n renderList.push({ action: \"popOpacity\" })\n }\n }\n\n public render(buffer: OptimizedBuffer, deltaTime: number): void {\n let renderBuffer = buffer\n if (this.buffered && this.frameBuffer) {\n renderBuffer = this.frameBuffer\n }\n\n // Layout and culling are already finalized for this frame. These hooks are\n // only safe for drawing into the buffer; avoid renderable/reactive mutations.\n if (this.renderBefore) {\n this.renderBefore.call(this, renderBuffer, deltaTime)\n }\n\n this.renderSelf(renderBuffer, deltaTime)\n\n if (this.renderAfter) {\n this.renderAfter.call(this, renderBuffer, deltaTime)\n }\n\n // Hooks may move the renderable mid-frame, so sample the cached absolute\n // position after they run before hit-grid writes or framebuffer compositing.\n const screenX = this._screenX\n const screenY = this._screenY\n\n this.markClean()\n this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num)\n\n if (this.buffered && this.frameBuffer) {\n buffer.drawFrameBuffer(screenX, screenY, this.frameBuffer)\n }\n }\n\n protected _hasVisibleChildFilter(): boolean {\n // Presume an override of _getVisibleChildren means this subclass is using\n // the legacy filtering hook, so existing custom renderables keep working.\n return this._getVisibleChildren !== Renderable.prototype._getVisibleChildren\n }\n\n protected _getVisibleChildren(): number[] {\n return this._childrenInZIndexOrder.map((child) => child.num)\n }\n\n public canReuseRenderCommandList(): boolean {\n return (\n this.onUpdate === Renderable.prototype.onUpdate &&\n (this._overflow === \"visible\" || this.getScissorRect === Renderable.prototype.getScissorRect) &&\n !this._hasVisibleChildFilter()\n )\n }\n\n protected onUpdate(deltaTime: number): void {\n // Default implementation: do nothing\n // Override this method to provide custom rendering\n }\n\n protected getScissorRect(): {\n x: number\n y: number\n width: number\n height: number\n } {\n return {\n x: this.buffered ? 0 : this._screenX,\n y: this.buffered ? 0 : this._screenY,\n width: this.width,\n height: this.height,\n }\n }\n\n protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void {\n // Default implementation: do nothing\n // Override this method to provide custom rendering\n }\n\n public get isDestroyed(): boolean {\n return this._isDestroyed\n }\n\n public destroy(): void {\n if (this._isDestroyed) {\n return\n }\n\n this._isDestroyed = true\n this.emit(RenderableEvents.DESTROYED)\n\n if (this.parent) {\n this.parent.remove(this.id)\n }\n\n if (this.frameBuffer) {\n this.frameBuffer.destroy()\n this.frameBuffer = null\n }\n\n for (const child of this._childrenInLayoutOrder) {\n this.remove(child.id)\n }\n\n this._childrenInLayoutOrder = []\n this.renderableMapById.clear()\n Renderable.renderablesByNumber.delete(this.num)\n\n this.blur()\n this.removeAllListeners()\n\n this.destroySelf()\n\n try {\n this.yogaNode.free()\n } catch (e) {\n // Might be already freed and will throw an error if we try to free it again\n }\n }\n\n public destroyRecursively(): void {\n // Destroy children first to ensure removal as destroy clears child array\n // Make a copy of the children array to avoid iteration issues when children are destroyed\n const children = [...this._childrenInLayoutOrder]\n for (const child of children) {\n child.destroyRecursively()\n }\n this.destroy()\n }\n\n protected destroySelf(): void {\n // Default implementation: do nothing else\n // Override this method to provide custom cleanup\n }\n\n public processMouseEvent(event: MouseEvent): void {\n this._mouseListener?.call(this, event)\n this._mouseListeners[event.type]?.call(this, event)\n this.onMouseEvent(event)\n\n if (this.parent && !event.propagationStopped) {\n this.parent.processMouseEvent(event)\n }\n }\n\n protected onMouseEvent(event: MouseEvent): void {\n // Default implementation: do nothing\n // Override this method to provide custom event handling\n }\n\n public set onMouse(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListener = handler\n else this._mouseListener = null\n }\n\n public set onMouseDown(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"down\"] = handler\n else delete this._mouseListeners[\"down\"]\n }\n\n public set onMouseUp(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"up\"] = handler\n else delete this._mouseListeners[\"up\"]\n }\n\n public set onMouseMove(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"move\"] = handler\n else delete this._mouseListeners[\"move\"]\n }\n\n public set onMouseDrag(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"drag\"] = handler\n else delete this._mouseListeners[\"drag\"]\n }\n\n public set onMouseDragEnd(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"drag-end\"] = handler\n else delete this._mouseListeners[\"drag-end\"]\n }\n\n public set onMouseDrop(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"drop\"] = handler\n else delete this._mouseListeners[\"drop\"]\n }\n\n public set onMouseOver(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"over\"] = handler\n else delete this._mouseListeners[\"over\"]\n }\n\n public set onMouseOut(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"out\"] = handler\n else delete this._mouseListeners[\"out\"]\n }\n\n public set onMouseScroll(handler: ((event: MouseEvent) => void) | undefined) {\n if (handler) this._mouseListeners[\"scroll\"] = handler\n else delete this._mouseListeners[\"scroll\"]\n }\n\n public set onPaste(handler: ((event: PasteEvent) => void) | undefined) {\n this._pasteListener = handler\n }\n public get onPaste(): ((event: PasteEvent) => void) | undefined {\n return this._pasteListener\n }\n\n public set onKeyDown(handler: ((key: KeyEvent) => void) | undefined) {\n if (handler) this._keyListeners[\"down\"] = handler\n else delete this._keyListeners[\"down\"]\n }\n public get onKeyDown(): ((key: KeyEvent) => void) | undefined {\n return this._keyListeners[\"down\"]\n }\n\n public set onSizeChange(handler: (() => void) | undefined) {\n this._sizeChangeListener = handler\n }\n public get onSizeChange(): (() => void) | undefined {\n return this._sizeChangeListener\n }\n\n private applyEventOptions(options: RenderableOptions): void {\n this.onMouse = options.onMouse\n this.onMouseDown = options.onMouseDown\n this.onMouseUp = options.onMouseUp\n this.onMouseMove = options.onMouseMove\n this.onMouseDrag = options.onMouseDrag\n this.onMouseDragEnd = options.onMouseDragEnd\n this.onMouseDrop = options.onMouseDrop\n this.onMouseOver = options.onMouseOver\n this.onMouseOut = options.onMouseOut\n this.onMouseScroll = options.onMouseScroll\n this.onPaste = options.onPaste\n this.onKeyDown = options.onKeyDown\n this.onSizeChange = options.onSizeChange\n }\n}\n\ninterface RenderCommandBase {\n action: \"render\" | \"pushScissorRect\" | \"popScissorRect\" | \"pushOpacity\" | \"popOpacity\"\n}\n\ninterface RenderCommandPushScissorRect extends RenderCommandBase {\n action: \"pushScissorRect\"\n x: number\n y: number\n width: number\n height: number\n screenX: number\n screenY: number\n}\n\ninterface RenderCommandPopScissorRect extends RenderCommandBase {\n action: \"popScissorRect\"\n}\n\ninterface RenderCommandRender extends RenderCommandBase {\n action: \"render\"\n renderable: Renderable\n}\n\ninterface RenderCommandPushOpacity extends RenderCommandBase {\n action: \"pushOpacity\"\n opacity: number\n}\n\ninterface RenderCommandPopOpacity extends RenderCommandBase {\n action: \"popOpacity\"\n}\n\nexport type RenderCommand =\n | RenderCommandPushScissorRect\n | RenderCommandPopScissorRect\n | RenderCommandRender\n | RenderCommandPushOpacity\n | RenderCommandPopOpacity\n\nexport class RootRenderable extends Renderable {\n private renderList: RenderCommand[] = []\n private appliedLayoutGeneration: number = -1\n private appliedRenderListRevision: number = -1\n private renderListReusable: boolean = false\n\n constructor(ctx: RenderContext) {\n super(ctx, {\n id: \"__root__\",\n zIndex: 0,\n visible: true,\n width: ctx.width,\n height: ctx.height,\n enableLayout: true,\n })\n\n if (this.yogaNode) {\n this.yogaNode.free()\n }\n\n this.yogaNode = Yoga.Node.createForOpenTUI()\n this.yogaNode.setWidth(ctx.width)\n this.yogaNode.setHeight(ctx.height)\n this.yogaNode.setFlexDirection(FlexDirection.Column)\n\n this.calculateLayout()\n }\n\n public render(buffer: OptimizedBuffer, deltaTime: number): void {\n if (!this.visible) return\n\n // 0. Run lifecycle pass\n for (const renderable of this._ctx.getLifecyclePasses()) {\n renderable.onLifecyclePass?.call(renderable)\n }\n\n // NOTE: Strictly speaking, this is a 3-pass rendering process:\n // 1. Calculate layout from root\n // 2. Update layout throughout the tree and collect render list\n // 3. Render all collected renderables\n // Should be 2-pass by hooking into the calculateLayout phase,\n // but that's only possible if we move the layout tree to native.\n\n // 1. Calculate layout from root\n if (this.yogaNode.isDirty()) {\n this.calculateLayout()\n } else {\n this.syncExternalLayoutGeneration()\n }\n\n // 2. Update layout throughout the tree and collect render list\n const layoutGeneration = getLayoutGeneration(this._ctx)\n const renderListRevision = getRenderListRevision(this._ctx)\n const canReuseRenderList =\n this.renderListReusable &&\n this.appliedLayoutGeneration === layoutGeneration &&\n this.appliedRenderListRevision === renderListRevision\n\n if (!canReuseRenderList) {\n this.renderList.length = 0\n super.updateLayout(deltaTime, this.renderList)\n this.appliedLayoutGeneration = layoutGeneration\n this.appliedRenderListRevision = getRenderListRevision(this._ctx)\n this.renderListReusable = this.canReuseCurrentRenderList()\n }\n\n // 3. Render all collected renderables\n this._ctx.clearHitGridScissorRects()\n for (let i = 1; i < this.renderList.length; i++) {\n const command = this.renderList[i]\n switch (command.action) {\n case \"render\":\n // Skip if renderable was destroyed during a previous render callback\n if (!command.renderable.isDestroyed) {\n command.renderable.render(buffer, deltaTime)\n }\n break\n case \"pushScissorRect\":\n buffer.pushScissorRect(command.x, command.y, command.width, command.height)\n this._ctx.pushHitGridScissorRect(command.screenX, command.screenY, command.width, command.height)\n break\n case \"popScissorRect\":\n buffer.popScissorRect()\n this._ctx.popHitGridScissorRect()\n break\n case \"pushOpacity\":\n buffer.pushOpacity(command.opacity)\n break\n case \"popOpacity\":\n buffer.popOpacity()\n break\n }\n }\n }\n\n protected propagateLiveCount(delta: number): void {\n const oldCount = this._liveCount\n this._liveCount += delta\n\n if (oldCount === 0 && this._liveCount > 0) {\n this._ctx.requestLive()\n } else if (oldCount > 0 && this._liveCount === 0) {\n this._ctx.dropLive()\n }\n }\n\n public calculateLayout(): void {\n this.yogaNode.calculateLayout(this.width, this.height, Direction.LTR)\n bumpLayoutGeneration(this._ctx)\n this.yogaNode.markLayoutSeen()\n this.emit(LayoutEvents.LAYOUT_CHANGED)\n }\n\n private syncExternalLayoutGeneration(): void {\n if (!this.yogaNode.hasNewLayout()) return\n bumpLayoutGeneration(this._ctx)\n this.yogaNode.markLayoutSeen()\n }\n\n private canReuseCurrentRenderList(): boolean {\n if (this._liveCount > 0) return false\n\n for (const command of this.renderList) {\n if (command.action !== \"render\") continue\n if (!command.renderable.canReuseRenderCommandList()) return false\n }\n\n return true\n }\n\n public resize(width: number, height: number): void {\n this.width = width\n this.height = height\n\n this.emit(LayoutEvents.RESIZED, { width, height })\n }\n}\n", + "import type { RenderableOptions, Renderable } from \"../Renderable.js\"\nimport type { PositionTypeString, OverflowString } from \"./yoga.options.js\"\n\nexport function validateOptions(id: string, options: RenderableOptions): void {\n if (typeof options.width === \"number\") {\n if (options.width < 0) {\n throw new TypeError(`Invalid width for Renderable ${id}: ${options.width}`)\n }\n }\n if (typeof options.height === \"number\") {\n if (options.height < 0) {\n throw new TypeError(`Invalid height for Renderable ${id}: ${options.height}`)\n }\n }\n}\n\nexport function isValidPercentage(value: any): value is `${number}%` {\n if (typeof value === \"string\" && value.endsWith(\"%\")) {\n const numPart = value.slice(0, -1)\n const num = parseFloat(numPart)\n return !Number.isNaN(num)\n }\n return false\n}\n\nexport function isMarginType(value: any): value is number | \"auto\" | `${number}%` {\n if (typeof value === \"number\" && !Number.isNaN(value)) {\n return true\n }\n if (value === \"auto\") {\n return true\n }\n return isValidPercentage(value)\n}\n\nexport function isPaddingType(value: any): value is number | `${number}%` {\n if (typeof value === \"number\" && !Number.isNaN(value)) {\n return true\n }\n return isValidPercentage(value)\n}\n\nexport function isPositionType(value: any): value is number | \"auto\" | `${number}%` {\n if (typeof value === \"number\" && !Number.isNaN(value)) {\n return true\n }\n if (value === \"auto\") {\n return true\n }\n return isValidPercentage(value)\n}\n\nexport function isPositionTypeType(value: any): value is PositionTypeString {\n return value === \"relative\" || value === \"absolute\"\n}\n\nexport function isOverflowType(value: any): value is OverflowString {\n return value === \"visible\" || value === \"hidden\" || value === \"scroll\"\n}\n\nexport function isDimensionType(value: any): value is number | \"auto\" | `${number}%` {\n return isPositionType(value)\n}\n\nexport function isFlexBasisType(value: any): value is number | \"auto\" | undefined {\n if (value === undefined || value === \"auto\") {\n return true\n }\n if (typeof value === \"number\" && !Number.isNaN(value)) {\n return true\n }\n return false\n}\n\nexport function isSizeType(value: any): value is number | `${number}%` | undefined {\n if (value === undefined) {\n return true\n }\n if (typeof value === \"number\" && !Number.isNaN(value)) {\n return true\n }\n return isValidPercentage(value)\n}\n", + "import { isRenderable, Renderable, type RenderableOptions } from \"../../Renderable.js\"\nimport type { RenderContext } from \"../../types.js\"\nimport util from \"node:util\"\n\nexport type VChild = VNode | Renderable | VChild[] | null | undefined | false\n\nexport interface PendingCall {\n method: string\n args: any[]\n isProperty?: boolean\n}\n\nconst BrandedVNode: unique symbol = Symbol.for(\"@opentui/core/VNode\")\n\nexport interface VNode

{\n [BrandedVNode]: true\n type: Construct

\n props?: P\n children?: C\n __delegateMap?: Record\n __pendingCalls?: PendingCall[]\n}\n\n// Type that represents a VNode with Renderable methods available for chaining\nexport type ProxiedVNode> = VNode<\n TCtor extends RenderableConstructor ? P : any\n> & {\n [K in keyof InstanceType]: InstanceType[K] extends (...args: infer Args) => any\n ? (...args: Args) => ProxiedVNode\n : InstanceType[K]\n}\n\nexport interface RenderableConstructor

= RenderableOptions> {\n new (ctx: RenderContext, options: P): Renderable\n}\n\nexport type FunctionalConstruct

= (props: P, children?: VChild[]) => VNode\n\nexport type Construct

=\n | RenderableConstructor

? P : never>\n | FunctionalConstruct

\n\nfunction isRenderableConstructor

= RenderableOptions>(\n value: any,\n): value is RenderableConstructor

{\n return typeof value === \"function\" && value.prototype && Renderable.prototype.isPrototypeOf(value.prototype)\n}\n\nfunction flattenChildren(children: VChild[]): VChild[] {\n const result: VChild[] = []\n for (const child of children) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child))\n } else if (child !== null && child !== undefined && child !== false) {\n result.push(child)\n }\n }\n return result\n}\n\n// Overloads for proper typing\nexport function h>(\n type: TCtor,\n props?: TCtor extends RenderableConstructor ? P : never,\n ...children: VChild[]\n): ProxiedVNode\nexport function h

(type: FunctionalConstruct

, props?: P, ...children: VChild[]): VNode

\nexport function h

(type: Construct

, props?: P, ...children: VChild[]): VNode

| ProxiedVNode\nexport function h

(type: Construct

, props?: P, ...children: VChild[]): any {\n if (typeof type !== \"function\") {\n throw new TypeError(\"h() received an invalid vnode type\")\n }\n\n const vnode: VNode

= {\n [BrandedVNode]: true,\n type,\n props,\n children: flattenChildren(children),\n __pendingCalls: [],\n }\n\n if (isRenderableConstructor(type)) {\n return new Proxy(vnode, {\n get(target, prop, receiver) {\n // Return VNode properties directly\n if (prop in target) {\n return Reflect.get(target, prop, receiver)\n }\n\n if (typeof prop === \"string\") {\n const prototype = type.prototype\n const hasMethod =\n prototype &&\n (typeof prototype[prop] === \"function\" ||\n Object.getOwnPropertyDescriptor(prototype, prop) ||\n Object.getOwnPropertyDescriptor(Object.getPrototypeOf(prototype), prop))\n\n if (hasMethod) {\n return (...args: any[]) => {\n target.__pendingCalls = target.__pendingCalls || []\n target.__pendingCalls.push({ method: prop, args })\n return target\n }\n }\n }\n\n return Reflect.get(target, prop, receiver)\n },\n\n set(target, prop, value, receiver) {\n if (typeof prop === \"string\" && isRenderableConstructor(type)) {\n const prototype = type.prototype\n const descriptor =\n Object.getOwnPropertyDescriptor(prototype, prop) ||\n Object.getOwnPropertyDescriptor(Object.getPrototypeOf(prototype), prop)\n\n if (descriptor && descriptor.set) {\n target.__pendingCalls = target.__pendingCalls || []\n target.__pendingCalls.push({ method: prop, args: [value], isProperty: true })\n return true\n }\n }\n\n return Reflect.set(target, prop, value, receiver)\n },\n })\n }\n\n return vnode\n}\n\nexport function isVNode(node: any): node is VNode {\n return node && node[BrandedVNode]\n}\n\nexport function maybeMakeRenderable(\n ctx: RenderContext,\n node: Renderable | VNode | unknown,\n): Renderable | null {\n if (isRenderable(node)) return node\n if (isVNode(node)) return instantiate(ctx, node)\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\"maybeMakeRenderable received an invalid node\", util.inspect(node, { depth: 2 }))\n }\n return null\n}\n\nexport function wrapWithDelegates>(\n instance: T,\n delegateMap: Record | undefined,\n): T {\n if (!delegateMap || Object.keys(delegateMap).length === 0) return instance\n\n const descendantCache = new Map()\n\n const getDescendant = (id: string): Renderable | undefined => {\n if (descendantCache.has(id)) {\n const cached = descendantCache.get(id)\n if (cached !== undefined) {\n return cached\n }\n }\n const descendant = (instance as Renderable).findDescendantById(id)\n if (descendant) {\n descendantCache.set(id, descendant)\n }\n return descendant\n }\n\n const proxy = new Proxy(instance as any, {\n get(target, prop, receiver) {\n if (typeof prop === \"string\" && delegateMap[prop]) {\n const host = getDescendant(delegateMap[prop])\n if (host) {\n const value = (host as any)[prop]\n if (typeof value === \"function\") {\n return value.bind(host)\n }\n return value\n }\n }\n return Reflect.get(target, prop, receiver)\n },\n set(target, prop, value, receiver) {\n if (typeof prop === \"string\" && delegateMap[prop]) {\n const host = getDescendant(delegateMap[prop])\n if (host) {\n return Reflect.set(host as any, prop, value)\n }\n }\n return Reflect.set(target, prop, value, receiver)\n },\n })\n return proxy\n}\n\nexport type InstantiateFn = Renderable & { __node?: NodeType }\n\nexport function instantiate(\n ctx: RenderContext,\n node: NodeType,\n): InstantiateFn {\n if (isRenderable(node)) return node\n\n if (!node || typeof node !== \"object\") {\n throw new TypeError(\"mount() received an invalid vnode\")\n }\n\n const vnode = node as VNode\n const { type, props } = vnode\n const children = flattenChildren(vnode.children || [])\n const delegateMap = (vnode as any).__delegateMap as Record | undefined\n\n if (isRenderableConstructor(type)) {\n const instance = new type(ctx, (props || {}) as any)\n\n for (const child of children) {\n if (isRenderable(child)) {\n instance.add(child)\n } else {\n const mounted = instantiate(ctx, child as NodeType)\n instance.add(mounted)\n }\n }\n\n const delegatedInstance = wrapWithDelegates(instance, delegateMap)\n\n const pendingCalls = (vnode as any).__pendingCalls as PendingCall[] | undefined\n if (pendingCalls) {\n for (const call of pendingCalls) {\n if (call.isProperty) {\n ;(delegatedInstance as any)[call.method] = call.args[0]\n } else {\n ;(delegatedInstance as any)[call.method].apply(delegatedInstance, call.args)\n }\n }\n }\n\n return delegatedInstance\n }\n\n // Functional construct: resolve to a concrete vnode and mount it\n const resolved = (type as FunctionalConstruct)(props || ({} as any), children)\n const inst = instantiate(ctx, resolved)\n\n return wrapWithDelegates(inst, delegateMap) as InstantiateFn\n}\n\nexport type DelegateMap = Partial>\n\nexport type ValidateShape = {\n [K in keyof Given]: K extends keyof AllowedKeys ? NonNullable : never\n}\n\ntype InferNode = T extends InstantiateFn ? U : never\n\nexport function delegate<\n Factory extends InstantiateFn,\n InnerNode extends InferNode,\n TargetMap extends Record,\n const Mapping extends Partial,\n>(mapping: ValidateShape, vnode: Factory): Renderable\n\nexport function delegate<\n ConstructorType extends RenderableConstructor,\n TargetMap extends Record, string>,\n const Mapping extends Partial,\n>(mapping: ValidateShape, vnode: ProxiedVNode): ProxiedVNode\n\nexport function delegate<\n ConstructorType extends RenderableConstructor,\n const Mapping extends DelegateMap>,\n>(mapping: ValidateShape, vnode: VNode & { type: ConstructorType }): VNode\n\n/**\n * Controlled delegation that routes selected properties/methods\n * to a descendant renderable identified by ID.\n */\nexport function delegate>(\n mapping: Record,\n vnode: NodeType,\n): VNode | Renderable {\n if (isRenderable(vnode)) {\n return wrapWithDelegates(vnode, mapping)\n }\n if (!vnode || typeof vnode !== \"object\") return vnode\n vnode.__delegateMap = { ...(vnode.__delegateMap || {}), ...mapping }\n return vnode\n}\n", + "import { RGBA } from \"./lib/RGBA.js\"\nimport { resolveRenderLib, type LineInfo, type RenderLib, type TextBufferViewHandle } from \"./zig.js\"\nimport type { TextBuffer } from \"./text-buffer.js\"\n\nexport class TextBufferView {\n private lib: RenderLib\n private viewPtr: TextBufferViewHandle\n private textBuffer: TextBuffer\n private _destroyed: boolean = false\n\n constructor(lib: RenderLib, ptr: TextBufferViewHandle, textBuffer: TextBuffer) {\n this.lib = lib\n this.viewPtr = ptr\n this.textBuffer = textBuffer\n }\n\n static create(textBuffer: TextBuffer): TextBufferView {\n const lib = resolveRenderLib()\n const viewPtr = lib.createTextBufferView(textBuffer.ptr)\n return new TextBufferView(lib, viewPtr, textBuffer)\n }\n\n // Fail loud and clear\n private guard(): void {\n if (this._destroyed) throw new Error(\"TextBufferView is destroyed\")\n }\n\n public get ptr(): TextBufferViewHandle {\n this.guard()\n return this.viewPtr\n }\n\n public setSelection(start: number, end: number, bgColor?: RGBA, fgColor?: RGBA): void {\n this.guard()\n this.lib.textBufferViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null)\n }\n\n public updateSelection(end: number, bgColor?: RGBA, fgColor?: RGBA): void {\n this.guard()\n this.lib.textBufferViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null)\n }\n\n public resetSelection(): void {\n this.guard()\n this.lib.textBufferViewResetSelection(this.viewPtr)\n }\n\n public getSelection(): { start: number; end: number } | null {\n this.guard()\n return this.lib.textBufferViewGetSelection(this.viewPtr)\n }\n\n public hasSelection(): boolean {\n this.guard()\n return this.getSelection() !== null\n }\n\n public setLocalSelection(\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor?: RGBA,\n fgColor?: RGBA,\n ): boolean {\n this.guard()\n return this.lib.textBufferViewSetLocalSelection(\n this.viewPtr,\n anchorX,\n anchorY,\n focusX,\n focusY,\n bgColor || null,\n fgColor || null,\n )\n }\n\n public updateLocalSelection(\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor?: RGBA,\n fgColor?: RGBA,\n ): boolean {\n this.guard()\n return this.lib.textBufferViewUpdateLocalSelection(\n this.viewPtr,\n anchorX,\n anchorY,\n focusX,\n focusY,\n bgColor || null,\n fgColor || null,\n )\n }\n\n public resetLocalSelection(): void {\n this.guard()\n this.lib.textBufferViewResetLocalSelection(this.viewPtr)\n }\n\n public setWrapWidth(width: number | null): void {\n this.guard()\n this.lib.textBufferViewSetWrapWidth(this.viewPtr, width ?? 0)\n }\n\n public setWrapMode(mode: \"none\" | \"char\" | \"word\"): void {\n this.guard()\n this.lib.textBufferViewSetWrapMode(this.viewPtr, mode)\n }\n\n public setFirstLineOffset(offset: number): void {\n this.guard()\n this.lib.textBufferViewSetFirstLineOffset(this.viewPtr, offset)\n }\n\n public setViewportSize(width: number, height: number): void {\n this.guard()\n this.lib.textBufferViewSetViewportSize(this.viewPtr, width, height)\n }\n\n public setViewport(x: number, y: number, width: number, height: number): void {\n this.guard()\n this.lib.textBufferViewSetViewport(this.viewPtr, x, y, width, height)\n }\n\n public get lineInfo(): LineInfo {\n this.guard()\n return this.lib.textBufferViewGetLineInfo(this.viewPtr)\n }\n\n public get logicalLineInfo(): LineInfo {\n this.guard()\n return this.lib.textBufferViewGetLogicalLineInfo(this.viewPtr)\n }\n\n public getSelectedText(): string {\n this.guard()\n const byteSize = this.textBuffer.byteSize\n if (byteSize === 0) return \"\"\n\n const selectedBytes = this.lib.textBufferViewGetSelectedTextBytes(this.viewPtr, byteSize)\n\n if (!selectedBytes) return \"\"\n\n return this.lib.decoder.decode(selectedBytes)\n }\n\n public getPlainText(): string {\n this.guard()\n const byteSize = this.textBuffer.byteSize\n if (byteSize === 0) return \"\"\n\n const plainBytes = this.lib.textBufferViewGetPlainTextBytes(this.viewPtr, byteSize)\n\n if (!plainBytes) return \"\"\n\n return this.lib.decoder.decode(plainBytes)\n }\n\n public setTabIndicator(indicator: string | number): void {\n this.guard()\n const codePoint = typeof indicator === \"string\" ? (indicator.codePointAt(0) ?? 0) : indicator\n this.lib.textBufferViewSetTabIndicator(this.viewPtr, codePoint)\n }\n\n public setTabIndicatorColor(color: RGBA): void {\n this.guard()\n this.lib.textBufferViewSetTabIndicatorColor(this.viewPtr, color)\n }\n\n public setTruncate(truncate: boolean): void {\n this.guard()\n this.lib.textBufferViewSetTruncate(this.viewPtr, truncate)\n }\n\n public measureForDimensions(width: number, height: number): { lineCount: number; widthColsMax: number } | null {\n this.guard()\n return this.lib.textBufferViewMeasureForDimensions(this.viewPtr, width, height)\n }\n\n public getVirtualLineCount(): number {\n this.guard()\n return this.lib.textBufferViewGetVirtualLineCount(this.viewPtr)\n }\n\n public destroy(): void {\n if (this._destroyed) return\n this._destroyed = true\n this.lib.destroyTextBufferView(this.viewPtr)\n }\n}\n", + "import {\n resolveRenderLib,\n type EditBufferHandle,\n type LogicalCursor,\n type RenderLib,\n type TextBufferHandle,\n} from \"./zig.js\"\nimport { type WidthMethod, type Highlight } from \"./types.js\"\nimport { RGBA } from \"./lib/RGBA.js\"\nimport { EventEmitter } from \"events\"\nimport type { SyntaxStyle } from \"./syntax-style.js\"\n\nexport type { LogicalCursor }\n\n/**\n * EditBuffer provides a text editing buffer with cursor management,\n * incremental editing, and grapheme-aware operations.\n */\nexport class EditBuffer extends EventEmitter {\n private static registry = new Map()\n private static nativeEventsSubscribed = false\n\n private lib: RenderLib\n private bufferPtr: EditBufferHandle\n private textBufferPtr: TextBufferHandle\n public readonly id: number\n private _destroyed: boolean = false\n private _textBytes: Uint8Array[] = []\n private _singleTextBytes: Uint8Array | null = null\n private _singleTextMemId: number | null = null\n private _syntaxStyle?: SyntaxStyle\n\n constructor(lib: RenderLib, ptr: EditBufferHandle) {\n super()\n this.lib = lib\n this.bufferPtr = ptr\n this.textBufferPtr = lib.editBufferGetTextBuffer(ptr)\n this.id = lib.editBufferGetId(ptr)\n\n EditBuffer.registry.set(this.id, this)\n EditBuffer.subscribeToNativeEvents(lib)\n }\n\n static create(widthMethod: WidthMethod): EditBuffer {\n const lib = resolveRenderLib()\n const ptr = lib.createEditBuffer(widthMethod)\n return new EditBuffer(lib, ptr)\n }\n\n private static subscribeToNativeEvents(lib: RenderLib): void {\n if (EditBuffer.nativeEventsSubscribed) return\n EditBuffer.nativeEventsSubscribed = true\n\n lib.onAnyNativeEvent((name: string, data: ArrayBuffer) => {\n const buffer = new Uint16Array(data)\n\n if (name.startsWith(\"eb_\") && buffer.length >= 1) {\n const id = buffer[0]\n const instance = EditBuffer.registry.get(id)\n\n if (instance) {\n // Strip the \"eb_\" prefix and forward the event\n const eventName = name.slice(3)\n const eventData = data.slice(2)\n instance.emit(eventName, eventData)\n }\n }\n })\n }\n\n private guard(): void {\n if (this._destroyed) throw new Error(\"EditBuffer is destroyed\")\n }\n\n public get ptr(): EditBufferHandle {\n this.guard()\n return this.bufferPtr\n }\n\n /**\n * Set text and completely reset the buffer state (clears history, resets add_buffer).\n * Use this for initial text setting or when you want a clean slate.\n */\n public setText(text: string): void {\n this.guard()\n const textBytes = this.lib.encoder.encode(text)\n\n if (this._singleTextMemId !== null) {\n this.lib.textBufferReplaceMemBuffer(this.textBufferPtr, this._singleTextMemId, textBytes, false)\n } else {\n this._singleTextMemId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false)\n }\n this._singleTextBytes = textBytes\n this.lib.editBufferSetTextFromMem(this.bufferPtr, this._singleTextMemId)\n }\n\n /**\n * Set text using owned memory and completely reset the buffer state (clears history, resets add_buffer).\n * The native code takes ownership of the memory.\n */\n public setTextOwned(text: string): void {\n this.guard()\n const textBytes = this.lib.encoder.encode(text)\n this.lib.editBufferSetText(this.bufferPtr, textBytes)\n }\n\n /**\n * Replace text while preserving undo history (creates an undo point).\n * Use this when you want the setText operation to be undoable.\n */\n public replaceText(text: string): void {\n this.guard()\n const textBytes = this.lib.encoder.encode(text)\n this._textBytes.push(textBytes)\n const memId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false)\n this.lib.editBufferReplaceTextFromMem(this.bufferPtr, memId)\n }\n\n /**\n * Replace text using owned memory while preserving undo history (creates an undo point).\n * The native code takes ownership of the memory.\n */\n public replaceTextOwned(text: string): void {\n this.guard()\n const textBytes = this.lib.encoder.encode(text)\n this.lib.editBufferReplaceText(this.bufferPtr, textBytes)\n }\n\n public getLineCount(): number {\n this.guard()\n return this.lib.textBufferGetLineCount(this.textBufferPtr)\n }\n\n public getText(): string {\n this.guard()\n // TODO: Use byte size of text buffer to get the actual size of the text\n // actually native can stack alloc all the text and decode will alloc as js string then\n const maxSize = 1024 * 1024 // 1MB max\n const textBytes = this.lib.editBufferGetText(this.bufferPtr, maxSize)\n\n if (!textBytes) return \"\"\n\n return this.lib.decoder.decode(textBytes)\n }\n\n public insertChar(char: string): void {\n this.guard()\n this.lib.editBufferInsertChar(this.bufferPtr, char)\n }\n\n public insertText(text: string): void {\n this.guard()\n this.lib.editBufferInsertText(this.bufferPtr, text)\n }\n\n public deleteChar(): void {\n this.guard()\n this.lib.editBufferDeleteChar(this.bufferPtr)\n }\n\n public deleteCharBackward(): void {\n this.guard()\n this.lib.editBufferDeleteCharBackward(this.bufferPtr)\n }\n\n public deleteRange(startLine: number, startCol: number, endLine: number, endCol: number): void {\n this.guard()\n this.lib.editBufferDeleteRange(this.bufferPtr, startLine, startCol, endLine, endCol)\n }\n\n public newLine(): void {\n this.guard()\n this.lib.editBufferNewLine(this.bufferPtr)\n }\n\n public deleteLine(): void {\n this.guard()\n this.lib.editBufferDeleteLine(this.bufferPtr)\n }\n\n public moveCursorLeft(): void {\n this.guard()\n this.lib.editBufferMoveCursorLeft(this.bufferPtr)\n }\n\n public moveCursorRight(): void {\n this.guard()\n this.lib.editBufferMoveCursorRight(this.bufferPtr)\n }\n\n public moveCursorUp(): void {\n this.guard()\n this.lib.editBufferMoveCursorUp(this.bufferPtr)\n }\n\n public moveCursorDown(): void {\n this.guard()\n this.lib.editBufferMoveCursorDown(this.bufferPtr)\n }\n\n public gotoLine(line: number): void {\n this.guard()\n this.lib.editBufferGotoLine(this.bufferPtr, line)\n }\n\n public setCursor(line: number, col: number): void {\n this.guard()\n this.lib.editBufferSetCursor(this.bufferPtr, line, col)\n }\n\n public setCursorToLineCol(line: number, col: number): void {\n this.guard()\n this.lib.editBufferSetCursorToLineCol(this.bufferPtr, line, col)\n }\n\n public setCursorByOffset(offset: number): void {\n this.guard()\n this.lib.editBufferSetCursorByOffset(this.bufferPtr, offset)\n }\n\n public getCursorPosition(): LogicalCursor {\n this.guard()\n return this.lib.editBufferGetCursorPosition(this.bufferPtr)\n }\n\n public getNextWordBoundary(): LogicalCursor {\n this.guard()\n const boundary = this.lib.editBufferGetNextWordBoundary(this.bufferPtr)\n return {\n row: boundary.row,\n col: boundary.col,\n offset: boundary.offset,\n }\n }\n\n public getPrevWordBoundary(): LogicalCursor {\n this.guard()\n const boundary = this.lib.editBufferGetPrevWordBoundary(this.bufferPtr)\n return {\n row: boundary.row,\n col: boundary.col,\n offset: boundary.offset,\n }\n }\n\n public getEOL(): LogicalCursor {\n this.guard()\n const boundary = this.lib.editBufferGetEOL(this.bufferPtr)\n return {\n row: boundary.row,\n col: boundary.col,\n offset: boundary.offset,\n }\n }\n\n public offsetToPosition(offset: number): { row: number; col: number } | null {\n this.guard()\n const result = this.lib.editBufferOffsetToPosition(this.bufferPtr, offset)\n if (!result) return null\n return { row: result.row, col: result.col }\n }\n\n public positionToOffset(row: number, col: number): number {\n this.guard()\n return this.lib.editBufferPositionToOffset(this.bufferPtr, row, col)\n }\n\n public getLineStartOffset(row: number): number {\n this.guard()\n return this.lib.editBufferGetLineStartOffset(this.bufferPtr, row)\n }\n\n public getTextRange(startOffset: number, endOffset: number): string {\n this.guard()\n if (startOffset >= endOffset) return \"\"\n\n // TODO: Use actual expected size of the text\n // like other methods native can just return a pointer and size\n // and we immediately decode the text into a js string then the native stack\n // can go out of scope\n const maxSize = 1024 * 1024 // 1MB max\n const textBytes = this.lib.editBufferGetTextRange(this.bufferPtr, startOffset, endOffset, maxSize)\n\n if (!textBytes) return \"\"\n\n return this.lib.decoder.decode(textBytes)\n }\n\n public getTextRangeByCoords(startRow: number, startCol: number, endRow: number, endCol: number): string {\n this.guard()\n\n const maxSize = 1024 * 1024 // 1MB max\n const textBytes = this.lib.editBufferGetTextRangeByCoords(\n this.bufferPtr,\n startRow,\n startCol,\n endRow,\n endCol,\n maxSize,\n )\n\n if (!textBytes) return \"\"\n\n return this.lib.decoder.decode(textBytes)\n }\n\n public debugLogRope(): void {\n this.guard()\n this.lib.editBufferDebugLogRope(this.bufferPtr)\n }\n\n public undo(): string | null {\n this.guard()\n const maxSize = 256\n const metaBytes = this.lib.editBufferUndo(this.bufferPtr, maxSize)\n if (!metaBytes) return null\n return this.lib.decoder.decode(metaBytes)\n }\n\n public redo(): string | null {\n this.guard()\n const maxSize = 256\n const metaBytes = this.lib.editBufferRedo(this.bufferPtr, maxSize)\n if (!metaBytes) return null\n return this.lib.decoder.decode(metaBytes)\n }\n\n public canUndo(): boolean {\n this.guard()\n return this.lib.editBufferCanUndo(this.bufferPtr)\n }\n\n public canRedo(): boolean {\n this.guard()\n return this.lib.editBufferCanRedo(this.bufferPtr)\n }\n\n public clearHistory(): void {\n this.guard()\n this.lib.editBufferClearHistory(this.bufferPtr)\n }\n\n public setDefaultFg(fg: RGBA | null): void {\n this.guard()\n this.lib.textBufferSetDefaultFg(this.textBufferPtr, fg)\n }\n\n public setDefaultBg(bg: RGBA | null): void {\n this.guard()\n this.lib.textBufferSetDefaultBg(this.textBufferPtr, bg)\n }\n\n public setDefaultAttributes(attributes: number | null): void {\n this.guard()\n this.lib.textBufferSetDefaultAttributes(this.textBufferPtr, attributes)\n }\n\n public resetDefaults(): void {\n this.guard()\n this.lib.textBufferResetDefaults(this.textBufferPtr)\n }\n\n public setSyntaxStyle(style: SyntaxStyle | null): void {\n this.guard()\n if (this.lib.textBufferSetSyntaxStyle(this.textBufferPtr, style?.ptr ?? null)) {\n this._syntaxStyle = style ?? undefined\n }\n }\n\n public getSyntaxStyle(): SyntaxStyle | null {\n this.guard()\n return this._syntaxStyle ?? null\n }\n\n public addHighlight(lineIdx: number, highlight: Highlight): void {\n this.guard()\n this.lib.textBufferAddHighlight(this.textBufferPtr, lineIdx, highlight)\n }\n\n public addHighlightByCharRange(highlight: Highlight): void {\n this.guard()\n this.lib.textBufferAddHighlightByCharRange(this.textBufferPtr, highlight)\n }\n\n public removeHighlightsByRef(hlRef: number): void {\n this.guard()\n this.lib.textBufferRemoveHighlightsByRef(this.textBufferPtr, hlRef)\n }\n\n public clearLineHighlights(lineIdx: number): void {\n this.guard()\n this.lib.textBufferClearLineHighlights(this.textBufferPtr, lineIdx)\n }\n\n public clearAllHighlights(): void {\n this.guard()\n this.lib.textBufferClearAllHighlights(this.textBufferPtr)\n }\n\n public getLineHighlights(lineIdx: number): Array {\n this.guard()\n return this.lib.textBufferGetLineHighlights(this.textBufferPtr, lineIdx)\n }\n\n public clear(): void {\n this.guard()\n this.lib.editBufferClear(this.bufferPtr)\n }\n\n public destroy(): void {\n if (this._destroyed) return\n\n this._destroyed = true\n EditBuffer.registry.delete(this.id)\n this.lib.destroyEditBuffer(this.bufferPtr)\n }\n}\n", + "import { RGBA } from \"./lib/RGBA.js\"\nimport {\n resolveRenderLib,\n type EditorViewHandle,\n type RenderLib,\n type TextBufferViewHandle,\n type VisualCursor,\n type LineInfo,\n} from \"./zig.js\"\nimport type { EditBuffer } from \"./edit-buffer.js\"\nimport { createExtmarksController } from \"./lib/index.js\"\n\nexport interface Viewport {\n offsetY: number\n offsetX: number\n height: number\n width: number\n}\n\nexport type { VisualCursor }\n\nexport class EditorView {\n private lib: RenderLib\n private viewPtr: EditorViewHandle\n private editBuffer: EditBuffer\n private _destroyed: boolean = false\n private _extmarksController?: any\n private _textBufferViewPtr?: TextBufferViewHandle\n\n constructor(lib: RenderLib, ptr: EditorViewHandle, editBuffer: EditBuffer) {\n this.lib = lib\n this.viewPtr = ptr\n this.editBuffer = editBuffer\n }\n\n static create(editBuffer: EditBuffer, viewportWidth: number, viewportHeight: number): EditorView {\n const lib = resolveRenderLib()\n const viewPtr = lib.createEditorView(editBuffer.ptr, viewportWidth, viewportHeight)\n return new EditorView(lib, viewPtr, editBuffer)\n }\n\n private guard(): void {\n if (this._destroyed) throw new Error(\"EditorView is destroyed\")\n }\n\n public get ptr(): EditorViewHandle {\n this.guard()\n return this.viewPtr\n }\n\n public setViewportSize(width: number, height: number): void {\n this.guard()\n this.lib.editorViewSetViewportSize(this.viewPtr, width, height)\n }\n\n public setViewport(x: number, y: number, width: number, height: number, moveCursor: boolean = true): void {\n this.guard()\n this.lib.editorViewSetViewport(this.viewPtr, x, y, width, height, moveCursor)\n }\n\n public getViewport(): Viewport {\n this.guard()\n return this.lib.editorViewGetViewport(this.viewPtr)\n }\n\n public setScrollMargin(margin: number): void {\n this.guard()\n this.lib.editorViewSetScrollMargin(this.viewPtr, margin)\n }\n\n public setWrapMode(mode: \"none\" | \"char\" | \"word\"): void {\n this.guard()\n this.lib.editorViewSetWrapMode(this.viewPtr, mode)\n }\n\n public getVirtualLineCount(): number {\n this.guard()\n return this.lib.editorViewGetVirtualLineCount(this.viewPtr)\n }\n\n public getTotalVirtualLineCount(): number {\n this.guard()\n return this.lib.editorViewGetTotalVirtualLineCount(this.viewPtr)\n }\n\n public setSelection(start: number, end: number, bgColor?: RGBA, fgColor?: RGBA): void {\n this.guard()\n this.lib.editorViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null)\n }\n\n public updateSelection(end: number, bgColor?: RGBA, fgColor?: RGBA): void {\n this.guard()\n this.lib.editorViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null)\n }\n\n public resetSelection(): void {\n this.guard()\n this.lib.editorViewResetSelection(this.viewPtr)\n }\n\n public getSelection(): { start: number; end: number } | null {\n this.guard()\n return this.lib.editorViewGetSelection(this.viewPtr)\n }\n\n public hasSelection(): boolean {\n this.guard()\n return this.getSelection() !== null\n }\n\n public setLocalSelection(\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor?: RGBA,\n fgColor?: RGBA,\n updateCursor?: boolean,\n followCursor?: boolean,\n ): boolean {\n this.guard()\n return this.lib.editorViewSetLocalSelection(\n this.viewPtr,\n anchorX,\n anchorY,\n focusX,\n focusY,\n bgColor || null,\n fgColor || null,\n updateCursor ?? false,\n followCursor ?? false,\n )\n }\n\n public updateLocalSelection(\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor?: RGBA,\n fgColor?: RGBA,\n updateCursor?: boolean,\n followCursor?: boolean,\n ): boolean {\n this.guard()\n return this.lib.editorViewUpdateLocalSelection(\n this.viewPtr,\n anchorX,\n anchorY,\n focusX,\n focusY,\n bgColor || null,\n fgColor || null,\n updateCursor ?? false,\n followCursor ?? false,\n )\n }\n\n public resetLocalSelection(): void {\n this.guard()\n this.lib.editorViewResetLocalSelection(this.viewPtr)\n }\n\n public getSelectedText(): string {\n this.guard()\n // TODO: native can stack alloc all the text and decode will alloc as js string then\n const maxLength = 1024 * 1024 // 1MB should be enough for most selections\n const selectedBytes = this.lib.editorViewGetSelectedTextBytes(this.viewPtr, maxLength)\n\n if (!selectedBytes) return \"\"\n\n return this.lib.decoder.decode(selectedBytes)\n }\n\n public getCursor(): { row: number; col: number } {\n this.guard()\n return this.lib.editorViewGetCursor(this.viewPtr)\n }\n\n public getText(): string {\n this.guard()\n const maxLength = 1024 * 1024 // 1MB buffer\n const textBytes = this.lib.editorViewGetText(this.viewPtr, maxLength)\n if (!textBytes) return \"\"\n return this.lib.decoder.decode(textBytes)\n }\n\n public getVisualCursor(): VisualCursor {\n this.guard()\n return this.lib.editorViewGetVisualCursor(this.viewPtr)\n }\n\n public moveUpVisual(): void {\n this.guard()\n this.lib.editorViewMoveUpVisual(this.viewPtr)\n }\n\n public moveDownVisual(): void {\n this.guard()\n this.lib.editorViewMoveDownVisual(this.viewPtr)\n }\n\n public deleteSelectedText(): void {\n this.guard()\n this.lib.editorViewDeleteSelectedText(this.viewPtr)\n }\n\n public setCursorByOffset(offset: number): void {\n this.guard()\n this.lib.editorViewSetCursorByOffset(this.viewPtr, offset)\n }\n\n public getNextWordBoundary(): VisualCursor {\n this.guard()\n return this.lib.editorViewGetNextWordBoundary(this.viewPtr)\n }\n\n public getPrevWordBoundary(): VisualCursor {\n this.guard()\n return this.lib.editorViewGetPrevWordBoundary(this.viewPtr)\n }\n\n public getEOL(): VisualCursor {\n this.guard()\n return this.lib.editorViewGetEOL(this.viewPtr)\n }\n\n public getVisualSOL(): VisualCursor {\n this.guard()\n return this.lib.editorViewGetVisualSOL(this.viewPtr)\n }\n\n public getVisualEOL(): VisualCursor {\n this.guard()\n return this.lib.editorViewGetVisualEOL(this.viewPtr)\n }\n\n public getLineInfo(): LineInfo {\n this.guard()\n return this.lib.editorViewGetLineInfo(this.viewPtr)\n }\n\n public getLogicalLineInfo(): LineInfo {\n this.guard()\n return this.lib.editorViewGetLogicalLineInfo(this.viewPtr)\n }\n\n public get extmarks(): any {\n if (!this._extmarksController) {\n this._extmarksController = createExtmarksController(this.editBuffer, this)\n }\n return this._extmarksController\n }\n\n public setPlaceholderStyledText(chunks: { text: string; fg?: RGBA; bg?: RGBA; attributes?: number }[]): void {\n this.guard()\n this.lib.editorViewSetPlaceholderStyledText(this.viewPtr, chunks)\n }\n\n public setTabIndicator(indicator: string | number): void {\n this.guard()\n const codePoint = typeof indicator === \"string\" ? (indicator.codePointAt(0) ?? 0) : indicator\n this.lib.editorViewSetTabIndicator(this.viewPtr, codePoint)\n }\n\n public setTabIndicatorColor(color: RGBA): void {\n this.guard()\n this.lib.editorViewSetTabIndicatorColor(this.viewPtr, color)\n }\n\n public measureForDimensions(width: number, height: number): { lineCount: number; widthColsMax: number } | null {\n this.guard()\n if (!this._textBufferViewPtr) {\n this._textBufferViewPtr = this.lib.editorViewGetTextBufferView(this.viewPtr)\n }\n return this.lib.textBufferViewMeasureForDimensions(this._textBufferViewPtr, width, height)\n }\n\n public destroy(): void {\n if (this._destroyed) return\n\n if (this._extmarksController) {\n this._extmarksController.destroy()\n this._extmarksController = undefined\n }\n\n this._destroyed = true\n this.lib.destroyEditorView(this.viewPtr)\n }\n}\n", + "import { RGBA, parseColor, type ColorInput } from \"./lib/RGBA.js\"\nimport { resolveRenderLib, type RenderLib, type SyntaxStyleHandle } from \"./zig.js\"\nimport { createTextAttributes } from \"./utils.js\"\n\nexport interface StyleDefinition {\n fg?: RGBA\n bg?: RGBA\n bold?: boolean\n italic?: boolean\n underline?: boolean\n dim?: boolean\n}\n\nexport interface StyleDefinitionInput {\n fg?: ColorInput\n bg?: ColorInput\n bold?: boolean\n italic?: boolean\n underline?: boolean\n dim?: boolean\n}\n\nexport interface MergedStyle {\n fg?: RGBA\n bg?: RGBA\n attributes: number\n}\n\nexport interface ThemeTokenStyle {\n scope: string[]\n style: {\n foreground?: ColorInput\n background?: ColorInput\n bold?: boolean\n italic?: boolean\n underline?: boolean\n dim?: boolean\n }\n}\n\nexport function convertThemeToStyles(theme: ThemeTokenStyle[]): Record {\n const flatStyles: Record = {}\n\n for (const tokenStyle of theme) {\n const styleDefinition: StyleDefinition = {}\n\n if (tokenStyle.style.foreground) {\n styleDefinition.fg = parseColor(tokenStyle.style.foreground)\n }\n if (tokenStyle.style.background) {\n styleDefinition.bg = parseColor(tokenStyle.style.background)\n }\n\n if (tokenStyle.style.bold !== undefined) {\n styleDefinition.bold = tokenStyle.style.bold\n }\n if (tokenStyle.style.italic !== undefined) {\n styleDefinition.italic = tokenStyle.style.italic\n }\n if (tokenStyle.style.underline !== undefined) {\n styleDefinition.underline = tokenStyle.style.underline\n }\n if (tokenStyle.style.dim !== undefined) {\n styleDefinition.dim = tokenStyle.style.dim\n }\n\n // Apply the same style to all scopes\n for (const scope of tokenStyle.scope) {\n flatStyles[scope] = styleDefinition\n }\n }\n\n return flatStyles\n}\n\nexport class SyntaxStyle {\n private lib: RenderLib\n private stylePtr: SyntaxStyleHandle\n private _destroyed: boolean = false\n private nameCache: Map = new Map()\n private styleDefs: Map = new Map()\n private mergedCache: Map = new Map()\n\n constructor(lib: RenderLib, ptr: SyntaxStyleHandle) {\n this.lib = lib\n this.stylePtr = ptr\n }\n\n static create(): SyntaxStyle {\n const lib = resolveRenderLib()\n const ptr = lib.createSyntaxStyle()\n return new SyntaxStyle(lib, ptr)\n }\n\n static fromTheme(theme: ThemeTokenStyle[]): SyntaxStyle {\n const style = SyntaxStyle.create()\n const flatStyles = convertThemeToStyles(theme)\n\n for (const [name, styleDef] of Object.entries(flatStyles)) {\n style.registerStyle(name, styleDef)\n }\n\n return style\n }\n\n static fromStyles(styles: Record): SyntaxStyle {\n const style = SyntaxStyle.create()\n\n for (const [name, styleDef] of Object.entries(styles)) {\n style.registerStyle(name, styleDef)\n }\n\n return style\n }\n\n private guard(): void {\n if (this._destroyed) throw new Error(\"NativeSyntaxStyle is destroyed\")\n }\n\n public registerStyle(name: string, style: StyleDefinitionInput): number {\n this.guard()\n\n const attributes = createTextAttributes({\n bold: style.bold,\n italic: style.italic,\n underline: style.underline,\n dim: style.dim,\n })\n\n const fg = style.fg ? parseColor(style.fg) : null\n const bg = style.bg ? parseColor(style.bg) : null\n const id = this.lib.syntaxStyleRegister(this.stylePtr, name, fg, bg, attributes)\n\n this.nameCache.set(name, id)\n this.styleDefs.set(name, { ...style, fg: fg ?? undefined, bg: bg ?? undefined })\n\n return id\n }\n\n public resolveStyleId(name: string): number | null {\n this.guard()\n\n // Check cache first\n const cached = this.nameCache.get(name)\n if (cached !== undefined) return cached\n\n const id = this.lib.syntaxStyleResolveByName(this.stylePtr, name)\n\n if (id !== null) {\n this.nameCache.set(name, id)\n }\n\n return id\n }\n\n public getStyleId(name: string): number | null {\n this.guard()\n\n const id = this.resolveStyleId(name)\n if (id !== null) return id\n\n // Try base name if it's a scoped style\n if (name.includes(\".\")) {\n const baseName = name.split(\".\")[0]\n return this.resolveStyleId(baseName)\n }\n\n return null\n }\n\n public get ptr(): SyntaxStyleHandle {\n this.guard()\n return this.stylePtr\n }\n\n public getStyleCount(): number {\n this.guard()\n return this.lib.syntaxStyleGetStyleCount(this.stylePtr)\n }\n\n public clearNameCache(): void {\n this.nameCache.clear()\n }\n\n public getStyle(name: string): StyleDefinition | undefined {\n this.guard()\n\n if (Object.prototype.hasOwnProperty.call(this.styleDefs, name)) {\n return undefined\n }\n\n const style = this.styleDefs.get(name)\n if (style) return style\n\n if (name.includes(\".\")) {\n const baseName = name.split(\".\")[0]\n if (Object.prototype.hasOwnProperty.call(this.styleDefs, baseName)) {\n return undefined\n }\n return this.styleDefs.get(baseName)\n }\n\n return undefined\n }\n\n public mergeStyles(...styleNames: string[]): MergedStyle {\n this.guard()\n\n const cacheKey = styleNames.join(\":\")\n const cached = this.mergedCache.get(cacheKey)\n if (cached) return cached\n\n const styleDefinition: StyleDefinition = {}\n\n for (const name of styleNames) {\n const style = this.getStyle(name)\n\n if (!style) continue\n\n if (style.fg) styleDefinition.fg = style.fg\n if (style.bg) styleDefinition.bg = style.bg\n if (style.bold !== undefined) styleDefinition.bold = style.bold\n if (style.italic !== undefined) styleDefinition.italic = style.italic\n if (style.underline !== undefined) styleDefinition.underline = style.underline\n if (style.dim !== undefined) styleDefinition.dim = style.dim\n }\n\n const attributes = createTextAttributes({\n bold: styleDefinition.bold,\n italic: styleDefinition.italic,\n underline: styleDefinition.underline,\n dim: styleDefinition.dim,\n })\n\n const merged: MergedStyle = {\n fg: styleDefinition.fg,\n bg: styleDefinition.bg,\n attributes,\n }\n\n this.mergedCache.set(cacheKey, merged)\n\n return merged\n }\n\n public clearCache(): void {\n this.guard()\n this.mergedCache.clear()\n }\n\n public getCacheSize(): number {\n this.guard()\n return this.mergedCache.size\n }\n\n public getAllStyles(): Map {\n this.guard()\n return new Map(this.styleDefs)\n }\n\n public getRegisteredNames(): string[] {\n this.guard()\n return Array.from(this.styleDefs.keys())\n }\n\n public destroy(): void {\n if (this._destroyed) return\n this._destroyed = true\n this.nameCache.clear()\n this.styleDefs.clear()\n this.mergedCache.clear()\n this.lib.destroySyntaxStyle(this.stylePtr)\n }\n}\n", + "import { Edge, Gutter } from \"../yoga.js\"\nimport { type RenderableOptions, Renderable } from \"../Renderable.js\"\nimport type { OptimizedBuffer } from \"../buffer.js\"\nimport {\n type BorderCharacters,\n type BorderSides,\n type BorderSidesConfig,\n type BorderStyle,\n borderCharsToArray,\n getBorderSides,\n parseBorderStyle,\n} from \"../lib/index.js\"\nimport { type ColorInput, RGBA, parseColor } from \"../lib/RGBA.js\"\nimport { isValidPercentage } from \"../lib/renderable.validations.js\"\nimport type { RenderContext } from \"../types.js\"\n\nexport interface BoxOptions extends RenderableOptions {\n backgroundColor?: string | RGBA\n borderStyle?: BorderStyle\n border?: boolean | BorderSides[]\n borderColor?: string | RGBA\n customBorderChars?: BorderCharacters\n shouldFill?: boolean\n title?: string\n titleColor?: string | RGBA\n titleAlignment?: \"left\" | \"center\" | \"right\"\n bottomTitle?: string\n bottomTitleAlignment?: \"left\" | \"center\" | \"right\"\n focusedBorderColor?: ColorInput\n focusable?: boolean\n gap?: number | `${number}%`\n rowGap?: number | `${number}%`\n columnGap?: number | `${number}%`\n}\n\nfunction isGapType(value: any): value is number | undefined {\n if (value === undefined) {\n return true\n }\n if (typeof value === \"number\" && !Number.isNaN(value)) {\n return true\n }\n return isValidPercentage(value)\n}\n\nexport class BoxRenderable extends Renderable {\n protected _backgroundColor: RGBA\n protected _border: boolean | BorderSides[]\n protected _borderStyle: BorderStyle\n protected _borderColor: RGBA\n protected _focusedBorderColor: RGBA\n private _customBorderCharsObj: BorderCharacters | undefined\n protected _customBorderChars?: Uint32Array\n protected borderSides: BorderSidesConfig\n public shouldFill: boolean\n protected _title?: string\n protected _titleColor?: RGBA\n protected _titleAlignment: \"left\" | \"center\" | \"right\"\n protected _bottomTitle?: string\n protected _bottomTitleAlignment: \"left\" | \"center\" | \"right\"\n\n protected _defaultOptions = {\n backgroundColor: \"transparent\",\n borderStyle: \"single\",\n border: false,\n borderColor: \"#FFFFFF\",\n shouldFill: true,\n titleAlignment: \"left\",\n bottomTitleAlignment: \"left\",\n focusedBorderColor: \"#00AAFF\",\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: BoxOptions) {\n super(ctx, options)\n\n if (options.focusable === true) {\n this._focusable = true\n }\n\n this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor)\n this._border = options.border ?? this._defaultOptions.border\n if (\n !options.border &&\n (options.borderStyle || options.borderColor || options.focusedBorderColor || options.customBorderChars)\n ) {\n this._border = true\n }\n this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle)\n this._borderColor = parseColor(options.borderColor || this._defaultOptions.borderColor)\n this._focusedBorderColor = parseColor(options.focusedBorderColor || this._defaultOptions.focusedBorderColor)\n this._customBorderCharsObj = options.customBorderChars\n this._customBorderChars = this._customBorderCharsObj ? borderCharsToArray(this._customBorderCharsObj) : undefined\n this.borderSides = getBorderSides(this._border)\n this.shouldFill = options.shouldFill ?? this._defaultOptions.shouldFill\n this._title = options.title\n this._titleColor = options.titleColor ? parseColor(options.titleColor) : undefined\n this._titleAlignment = options.titleAlignment || this._defaultOptions.titleAlignment\n this._bottomTitle = options.bottomTitle\n this._bottomTitleAlignment = options.bottomTitleAlignment || this._defaultOptions.bottomTitleAlignment\n\n this.applyYogaBorders()\n\n const hasInitialGapProps =\n options.gap !== undefined || options.rowGap !== undefined || options.columnGap !== undefined\n if (hasInitialGapProps) {\n this.applyYogaGap(options)\n }\n }\n\n private initializeBorder(): void {\n // https://github.com/anomalyco/opentui/issues/186\n // Solid-js reconciler does not pass props to constructor on init,\n // so we need to initialize the border when supporting properties are set.\n // borderStyle, borderColor, focusedBorderColor\n if (this._border === false) {\n this._border = true\n this.borderSides = getBorderSides(this._border)\n this.applyYogaBorders()\n }\n }\n\n public get customBorderChars(): BorderCharacters | undefined {\n return this._customBorderCharsObj\n }\n\n public set customBorderChars(value: BorderCharacters | undefined) {\n this._customBorderCharsObj = value\n this._customBorderChars = value ? borderCharsToArray(value) : undefined\n this.requestRender()\n }\n\n public get backgroundColor(): RGBA {\n return this._backgroundColor\n }\n\n public set backgroundColor(value: RGBA | string | undefined) {\n const newColor = parseColor(value ?? this._defaultOptions.backgroundColor)\n if (this._backgroundColor !== newColor) {\n this._backgroundColor = newColor\n this.requestRender()\n }\n }\n\n public get border(): boolean | BorderSides[] {\n return this._border\n }\n\n public set border(value: boolean | BorderSides[]) {\n if (this._border !== value) {\n this._border = value\n this.borderSides = getBorderSides(value)\n this.applyYogaBorders()\n this.requestRender()\n }\n }\n\n public get borderStyle(): BorderStyle {\n return this._borderStyle\n }\n\n public set borderStyle(value: BorderStyle) {\n const _value = parseBorderStyle(value, this._defaultOptions.borderStyle)\n if (this._borderStyle !== _value || !this._border) {\n this._borderStyle = _value\n this._customBorderChars = undefined\n this.initializeBorder()\n this.requestRender()\n }\n }\n\n public get borderColor(): RGBA {\n return this._borderColor\n }\n\n public set borderColor(value: RGBA | string) {\n const newColor = parseColor(value ?? this._defaultOptions.borderColor)\n if (this._borderColor !== newColor) {\n this._borderColor = newColor\n this.initializeBorder()\n this.requestRender()\n }\n }\n\n public get focusedBorderColor(): RGBA {\n return this._focusedBorderColor\n }\n\n public set focusedBorderColor(value: RGBA | string) {\n const newColor = parseColor(value ?? this._defaultOptions.focusedBorderColor)\n if (this._focusedBorderColor !== newColor) {\n this._focusedBorderColor = newColor\n this.initializeBorder()\n if (this._focused) {\n this.requestRender()\n }\n }\n }\n\n public get title(): string | undefined {\n return this._title\n }\n\n public set title(value: string | undefined) {\n if (this._title !== value) {\n this._title = value\n this.requestRender()\n }\n }\n\n public get titleColor(): RGBA | undefined {\n return this._titleColor\n }\n\n public set titleColor(value: string | RGBA | undefined) {\n const newColor = value ? parseColor(value) : undefined\n if (this._titleColor !== newColor) {\n this._titleColor = newColor\n this.requestRender()\n }\n }\n\n public get titleAlignment(): \"left\" | \"center\" | \"right\" {\n return this._titleAlignment\n }\n\n public set titleAlignment(value: \"left\" | \"center\" | \"right\") {\n if (this._titleAlignment !== value) {\n this._titleAlignment = value\n this.requestRender()\n }\n }\n\n public get bottomTitle(): string | undefined {\n return this._bottomTitle\n }\n\n public set bottomTitle(value: string | undefined) {\n if (this._bottomTitle !== value) {\n this._bottomTitle = value\n this.requestRender()\n }\n }\n\n public get bottomTitleAlignment(): \"left\" | \"center\" | \"right\" {\n return this._bottomTitleAlignment\n }\n\n public set bottomTitleAlignment(value: \"left\" | \"center\" | \"right\") {\n if (this._bottomTitleAlignment !== value) {\n this._bottomTitleAlignment = value\n this.requestRender()\n }\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n const hasBorder = this.borderSides.top || this.borderSides.right || this.borderSides.bottom || this.borderSides.left\n const hasVisibleFill = this.shouldFill && this._backgroundColor.a > 0\n // Many boxes are used only for layout. Skip drawBox entirely when a box\n // would not draw pixels so wrapper nodes do not pay the FFI/native cost.\n if (!hasBorder && !hasVisibleFill) {\n return\n }\n\n const hasFocusWithin = this._focusable && (this._focused || this._hasFocusedDescendant)\n const currentBorderColor = hasFocusWithin ? this._focusedBorderColor : this._borderColor\n const screenX = this._screenX\n const screenY = this._screenY\n\n buffer.drawBox({\n x: screenX,\n y: screenY,\n width: this.width,\n height: this.height,\n borderStyle: this._borderStyle,\n customBorderChars: this._customBorderChars,\n border: this._border,\n borderColor: currentBorderColor,\n backgroundColor: this._backgroundColor,\n shouldFill: this.shouldFill,\n title: this._title,\n titleColor: this._titleColor ?? currentBorderColor,\n titleAlignment: this._titleAlignment,\n bottomTitle: this._bottomTitle,\n bottomTitleAlignment: this._bottomTitleAlignment,\n })\n }\n\n protected getScissorRect(): { x: number; y: number; width: number; height: number } {\n const baseRect = super.getScissorRect()\n\n if (!this.borderSides.top && !this.borderSides.right && !this.borderSides.bottom && !this.borderSides.left) {\n return baseRect\n }\n\n const leftInset = this.borderSides.left ? 1 : 0\n const rightInset = this.borderSides.right ? 1 : 0\n const topInset = this.borderSides.top ? 1 : 0\n const bottomInset = this.borderSides.bottom ? 1 : 0\n\n return {\n x: baseRect.x + leftInset,\n y: baseRect.y + topInset,\n width: Math.max(0, baseRect.width - leftInset - rightInset),\n height: Math.max(0, baseRect.height - topInset - bottomInset),\n }\n }\n\n private applyYogaBorders(): void {\n const node = this.yogaNode\n node.setBorder(Edge.Left, this.borderSides.left ? 1 : 0)\n node.setBorder(Edge.Right, this.borderSides.right ? 1 : 0)\n node.setBorder(Edge.Top, this.borderSides.top ? 1 : 0)\n node.setBorder(Edge.Bottom, this.borderSides.bottom ? 1 : 0)\n this.requestRender()\n }\n\n private applyYogaGap(options: BoxOptions): void {\n const node = this.yogaNode\n\n if (isGapType(options.gap)) {\n node.setGap(Gutter.All, options.gap)\n }\n\n if (isGapType(options.rowGap)) {\n node.setGap(Gutter.Row, options.rowGap)\n }\n\n if (isGapType(options.columnGap)) {\n node.setGap(Gutter.Column, options.columnGap)\n }\n }\n\n public set gap(gap: number | `${number}%` | undefined) {\n if (isGapType(gap)) {\n this.yogaNode.setGap(Gutter.All, gap)\n this.requestRender()\n }\n }\n\n public set rowGap(rowGap: number | `${number}%` | undefined) {\n if (isGapType(rowGap)) {\n this.yogaNode.setGap(Gutter.Row, rowGap)\n this.requestRender()\n }\n }\n\n public set columnGap(columnGap: number | `${number}%` | undefined) {\n if (isGapType(columnGap)) {\n this.yogaNode.setGap(Gutter.Column, columnGap)\n this.requestRender()\n }\n }\n}\n", + "import { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport { convertGlobalToLocalSelection, Selection, type LocalSelectionBounds } from \"../lib/selection.js\"\nimport { TextBuffer, type TextChunk } from \"../text-buffer.js\"\nimport { TextBufferView } from \"../text-buffer-view.js\"\nimport { RGBA, parseColor } from \"../lib/RGBA.js\"\nimport { type RenderContext, type LineInfoProvider } from \"../types.js\"\nimport type { OptimizedBuffer } from \"../buffer.js\"\nimport { MeasureMode } from \"../yoga.js\"\nimport type { LineInfo } from \"../zig.js\"\nimport { SyntaxStyle } from \"../syntax-style.js\"\n\nexport interface TextBufferOptions extends RenderableOptions {\n fg?: string | RGBA\n bg?: string | RGBA\n selectionBg?: string | RGBA\n selectionFg?: string | RGBA\n selectable?: boolean\n attributes?: number\n wrapMode?: \"none\" | \"char\" | \"word\"\n tabIndicator?: string | number\n tabIndicatorColor?: string | RGBA\n truncate?: boolean\n}\n\nexport abstract class TextBufferRenderable extends Renderable implements LineInfoProvider {\n public selectable: boolean = true\n\n protected _defaultFg: RGBA\n protected _defaultBg: RGBA\n protected _defaultAttributes: number\n protected _selectionBg: RGBA | undefined\n protected _selectionFg: RGBA | undefined\n protected _wrapMode: \"none\" | \"char\" | \"word\" = \"word\"\n protected lastLocalSelection: LocalSelectionBounds | null = null\n protected _tabIndicator?: string | number\n protected _tabIndicatorColor?: RGBA\n protected _scrollX: number = 0\n protected _scrollY: number = 0\n protected _truncate: boolean = false\n protected _firstLineOffset: number = 0\n\n protected textBuffer: TextBuffer\n protected textBufferView: TextBufferView\n protected _textBufferSyntaxStyle: SyntaxStyle\n\n protected _defaultOptions = {\n fg: RGBA.fromValues(1, 1, 1, 1),\n bg: RGBA.fromValues(0, 0, 0, 0),\n selectionBg: undefined,\n selectionFg: undefined,\n selectable: true,\n attributes: 0,\n wrapMode: \"word\" as \"none\" | \"char\" | \"word\",\n tabIndicator: undefined,\n tabIndicatorColor: undefined,\n truncate: false,\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: TextBufferOptions) {\n super(ctx, options)\n\n this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg)\n this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg)\n this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes\n this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg\n this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg\n this.selectable = options.selectable ?? this._defaultOptions.selectable\n this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode\n this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator\n this._tabIndicatorColor = options.tabIndicatorColor\n ? parseColor(options.tabIndicatorColor)\n : this._defaultOptions.tabIndicatorColor\n this._truncate = options.truncate ?? this._defaultOptions.truncate\n\n this.textBuffer = TextBuffer.create(this._ctx.widthMethod)\n this.textBufferView = TextBufferView.create(this.textBuffer)\n this._firstLineOffset = ctx.claimFirstLineOffset?.(this) ?? 0\n\n this._textBufferSyntaxStyle = SyntaxStyle.create()\n this.textBuffer.setSyntaxStyle(this._textBufferSyntaxStyle)\n\n this.textBufferView.setWrapMode(this._wrapMode)\n this.textBufferView.setFirstLineOffset(this._firstLineOffset)\n this.setupMeasureFunc()\n\n this.textBuffer.setDefaultFg(this._defaultFg)\n this.textBuffer.setDefaultBg(this._defaultBg)\n this.textBuffer.setDefaultAttributes(this._defaultAttributes)\n\n if (this._tabIndicator !== undefined) {\n this.textBufferView.setTabIndicator(this._tabIndicator)\n }\n if (this._tabIndicatorColor !== undefined) {\n this.textBufferView.setTabIndicatorColor(this._tabIndicatorColor)\n }\n\n if (this._wrapMode !== \"none\" && this.width > 0) {\n this.textBufferView.setWrapWidth(this.width)\n }\n\n if (this.width > 0 && this.height > 0) {\n this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height)\n }\n\n this.textBufferView.setTruncate(this._truncate)\n\n this.updateTextInfo()\n }\n\n protected onMouseEvent(event: any): void {\n if (event.type === \"scroll\") {\n this.handleScroll(event)\n }\n }\n\n protected handleScroll(event: any): void {\n if (!event.scroll) return\n\n const { direction, delta } = event.scroll\n\n if (direction === \"up\") {\n this.scrollY -= delta\n } else if (direction === \"down\") {\n this.scrollY += delta\n }\n\n if (this._wrapMode === \"none\") {\n if (direction === \"left\") {\n this.scrollX -= delta\n } else if (direction === \"right\") {\n this.scrollX += delta\n }\n }\n }\n\n public get lineInfo(): LineInfo {\n return this.textBufferView.logicalLineInfo\n }\n\n public get lineCount(): number {\n return this.textBuffer.getLineCount()\n }\n\n public get virtualLineCount(): number {\n return this.textBufferView.getVirtualLineCount()\n }\n\n public get scrollY(): number {\n return this._scrollY\n }\n\n public set scrollY(value: number) {\n const maxScrollY = Math.max(0, this.scrollHeight - this.height)\n const clamped = Math.max(0, Math.min(value, maxScrollY))\n if (this._scrollY !== clamped) {\n this._scrollY = clamped\n this.updateViewportOffset()\n this.requestRender()\n }\n }\n\n public get scrollX(): number {\n return this._scrollX\n }\n\n public set scrollX(value: number) {\n const maxScrollX = Math.max(0, this.scrollWidth - this.width)\n const clamped = Math.max(0, Math.min(value, maxScrollX))\n if (this._scrollX !== clamped) {\n this._scrollX = clamped\n this.updateViewportOffset()\n this.requestRender()\n }\n }\n\n public get scrollWidth(): number {\n return this.lineInfo.lineWidthColsMax\n }\n\n public get scrollHeight(): number {\n return this.lineInfo.lineStartCols.length\n }\n\n public get maxScrollY(): number {\n return Math.max(0, this.scrollHeight - this.height)\n }\n\n public get maxScrollX(): number {\n return Math.max(0, this.scrollWidth - this.width)\n }\n\n protected updateViewportOffset(): void {\n // Update the viewport with the new scroll position\n if (this.width > 0 && this.height > 0) {\n this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height)\n }\n }\n\n get plainText(): string {\n return this.textBuffer.getPlainText()\n }\n\n get textLength(): number {\n return this.textBuffer.length\n }\n\n get fg(): RGBA {\n return this._defaultFg\n }\n\n set fg(value: RGBA | string | undefined) {\n const newColor = parseColor(value ?? this._defaultOptions.fg)\n if (this._defaultFg !== newColor) {\n this._defaultFg = newColor\n this.textBuffer.setDefaultFg(this._defaultFg)\n this.onFgChanged(newColor)\n this.requestRender()\n }\n }\n\n get selectionBg(): RGBA | undefined {\n return this._selectionBg\n }\n\n set selectionBg(value: RGBA | string | undefined) {\n const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg\n if (this._selectionBg !== newColor) {\n this._selectionBg = newColor\n if (this.lastLocalSelection) {\n this.updateLocalSelection(this.lastLocalSelection)\n }\n this.requestRender()\n }\n }\n\n get selectionFg(): RGBA | undefined {\n return this._selectionFg\n }\n\n set selectionFg(value: RGBA | string | undefined) {\n const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg\n if (this._selectionFg !== newColor) {\n this._selectionFg = newColor\n if (this.lastLocalSelection) {\n this.updateLocalSelection(this.lastLocalSelection)\n }\n this.requestRender()\n }\n }\n\n get bg(): RGBA {\n return this._defaultBg\n }\n\n set bg(value: RGBA | string | undefined) {\n const newColor = parseColor(value ?? this._defaultOptions.bg)\n if (this._defaultBg !== newColor) {\n this._defaultBg = newColor\n this.textBuffer.setDefaultBg(this._defaultBg)\n this.onBgChanged(newColor)\n this.requestRender()\n }\n }\n\n get attributes(): number {\n return this._defaultAttributes\n }\n\n set attributes(value: number) {\n if (this._defaultAttributes !== value) {\n this._defaultAttributes = value\n this.textBuffer.setDefaultAttributes(this._defaultAttributes)\n this.onAttributesChanged(value)\n this.requestRender()\n }\n }\n\n get wrapMode(): \"none\" | \"char\" | \"word\" {\n return this._wrapMode\n }\n\n set wrapMode(value: \"none\" | \"char\" | \"word\") {\n if (this._wrapMode !== value) {\n this._wrapMode = value\n this.textBufferView.setWrapMode(this._wrapMode)\n if (value !== \"none\" && this.width > 0) {\n this.textBufferView.setWrapWidth(this.width)\n }\n // Changing wrap mode can change dimensions, so mark yoga node dirty to trigger re-measurement\n this.yogaNode.markDirty()\n this.requestRender()\n }\n }\n\n get tabIndicator(): string | number | undefined {\n return this._tabIndicator\n }\n\n set tabIndicator(value: string | number | undefined) {\n if (this._tabIndicator !== value) {\n this._tabIndicator = value\n if (value !== undefined) {\n this.textBufferView.setTabIndicator(value)\n }\n this.requestRender()\n }\n }\n\n get tabIndicatorColor(): RGBA | undefined {\n return this._tabIndicatorColor\n }\n\n set tabIndicatorColor(value: RGBA | string | undefined) {\n const newColor = value ? parseColor(value) : undefined\n if (this._tabIndicatorColor !== newColor) {\n this._tabIndicatorColor = newColor\n if (newColor !== undefined) {\n this.textBufferView.setTabIndicatorColor(newColor)\n }\n this.requestRender()\n }\n }\n\n get truncate(): boolean {\n return this._truncate\n }\n\n set truncate(value: boolean) {\n if (this._truncate !== value) {\n this._truncate = value\n this.textBufferView.setTruncate(value)\n this.requestRender()\n }\n }\n\n protected onResize(width: number, height: number): void {\n this.textBufferView.setViewport(this._scrollX, this._scrollY, width, height)\n this.yogaNode.markDirty()\n this.requestRender()\n this.emit(\"line-info-change\")\n }\n\n protected refreshLocalSelection(): boolean {\n if (this.lastLocalSelection) {\n return this.updateLocalSelection(this.lastLocalSelection)\n }\n return false\n }\n\n private updateLocalSelection(localSelection: LocalSelectionBounds | null): boolean {\n if (!localSelection?.isActive) {\n this.textBufferView.resetLocalSelection()\n return true\n }\n\n return this.textBufferView.setLocalSelection(\n localSelection.anchorX,\n localSelection.anchorY,\n localSelection.focusX,\n localSelection.focusY,\n this._selectionBg,\n this._selectionFg,\n )\n }\n\n protected updateTextInfo(): void {\n if (this.lastLocalSelection) {\n this.updateLocalSelection(this.lastLocalSelection)\n }\n\n this.yogaNode.markDirty()\n this.requestRender()\n this.emit(\"line-info-change\")\n }\n\n // Undefined = 0,\n // Exactly = 1,\n // AtMost = 2\n private setupMeasureFunc(): void {\n const measureFunc = (\n width: number,\n widthMode: MeasureMode,\n height: number,\n heightMode: MeasureMode,\n ): { width: number; height: number } => {\n // When widthMode is Undefined, Yoga is asking for the intrinsic/natural width\n // Pass width=0 to measureForDimensions to signal we want max-content (no wrapping)\n // The Zig code treats width=0 with wrap_mode != none as null wrap_width,\n // which triggers no-wrap mode and returns iter_mod.getMaxLineWidth()\n let effectiveWidth: number\n if (widthMode === MeasureMode.Undefined || isNaN(width)) {\n effectiveWidth = 0\n } else {\n effectiveWidth = width\n }\n\n const effectiveHeight = isNaN(height) ? 1 : height\n\n const measureResult = this.textBufferView.measureForDimensions(\n Math.floor(effectiveWidth),\n Math.floor(effectiveHeight),\n )\n\n const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1\n const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1\n\n if (widthMode === MeasureMode.AtMost && this._positionType !== \"absolute\") {\n return {\n width: Math.min(effectiveWidth, measuredWidth),\n height: Math.min(effectiveHeight, measuredHeight),\n }\n }\n\n // NOTE: Yoga may use these measurements or not.\n // If the yoga node settings and the parent allow this node to grow, it will.\n return {\n width: measuredWidth,\n height: measuredHeight,\n }\n }\n\n this.yogaNode.setMeasureFunc(measureFunc)\n }\n\n shouldStartSelection(x: number, y: number): boolean {\n if (!this.selectable) return false\n\n const localX = x - this.x\n const localY = y - this.y\n\n return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height\n }\n\n onSelectionChanged(selection: Selection | null): boolean {\n const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y)\n this.lastLocalSelection = localSelection\n\n let changed: boolean\n if (!localSelection?.isActive) {\n this.textBufferView.resetLocalSelection()\n changed = true\n } else if (selection?.isStart) {\n changed = this.textBufferView.setLocalSelection(\n localSelection.anchorX,\n localSelection.anchorY,\n localSelection.focusX,\n localSelection.focusY,\n this._selectionBg,\n this._selectionFg,\n )\n } else {\n changed = this.textBufferView.updateLocalSelection(\n localSelection.anchorX,\n localSelection.anchorY,\n localSelection.focusX,\n localSelection.focusY,\n this._selectionBg,\n this._selectionFg,\n )\n }\n\n if (changed) {\n this.requestRender()\n }\n\n return this.hasSelection()\n }\n\n getSelectedText(): string {\n return this.textBufferView.getSelectedText()\n }\n\n hasSelection(): boolean {\n return this.textBufferView.hasSelection()\n }\n\n getSelection(): { start: number; end: number } | null {\n return this.textBufferView.getSelection()\n }\n\n render(buffer: OptimizedBuffer, deltaTime: number): void {\n if (!this.visible) return\n // Text views do enough per-frame work that avoiding recursive x/y lookups is\n // measurable; use the layout cache for hit-grid and draw entry points.\n const screenX = this._screenX\n const screenY = this._screenY\n\n this.markClean()\n this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num)\n\n this.renderSelf(buffer)\n\n if (this.buffered && this.frameBuffer) {\n buffer.drawFrameBuffer(screenX, screenY, this.frameBuffer)\n }\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n if (this.textBuffer.ptr) {\n buffer.drawTextBuffer(this.textBufferView, this._screenX, this._screenY)\n }\n }\n\n destroy(): void {\n if (this.isDestroyed) return\n\n this.textBuffer.setSyntaxStyle(null)\n this._textBufferSyntaxStyle.destroy()\n this.textBufferView.destroy()\n this.textBuffer.destroy()\n super.destroy()\n }\n\n protected onFgChanged(newColor: RGBA): void {\n // Override in subclasses if needed\n }\n\n protected onBgChanged(newColor: RGBA): void {\n // Override in subclasses if needed\n }\n\n protected onAttributesChanged(newAttributes: number): void {\n // Override in subclasses if needed\n }\n}\n", + "import { type LineInfo, type RenderContext } from \"../types.js\"\nimport { StyledText } from \"../lib/styled-text.js\"\nimport { SyntaxStyle } from \"../syntax-style.js\"\nimport { getTreeSitterClient, TreeSitterClient } from \"../lib/tree-sitter/index.js\"\nimport { TextBufferRenderable, type TextBufferOptions } from \"./TextBufferRenderable.js\"\nimport type { OptimizedBuffer } from \"../buffer.js\"\nimport type { SimpleHighlight } from \"../lib/tree-sitter/types.js\"\nimport type { TextChunk } from \"../text-buffer.js\"\nimport { treeSitterToTextChunks } from \"../lib/tree-sitter-styled-text.js\"\n\nexport interface HighlightContext {\n content: string\n filetype: string\n syntaxStyle: SyntaxStyle\n}\n\nexport type OnHighlightCallback = (\n highlights: SimpleHighlight[],\n context: HighlightContext,\n) => SimpleHighlight[] | undefined | Promise\n\nexport interface ChunkRenderContext extends HighlightContext {\n highlights: SimpleHighlight[]\n}\n\nexport type OnChunksCallback = (\n chunks: TextChunk[],\n context: ChunkRenderContext,\n) => TextChunk[] | undefined | Promise\n\nexport interface CodeOptions extends TextBufferOptions {\n content?: string\n filetype?: string\n syntaxStyle: SyntaxStyle\n treeSitterClient?: TreeSitterClient\n conceal?: boolean\n drawUnstyledText?: boolean\n streaming?: boolean\n initialStyledText?: StyledText\n baseHighlight?: string\n onHighlight?: OnHighlightCallback\n onChunks?: OnChunksCallback\n}\n\ntype ConcealLineRange = [start: number, end: number]\n\nexport class CodeRenderable extends TextBufferRenderable {\n private _content: string\n private _filetype?: string\n private _syntaxStyle: SyntaxStyle\n private _isHighlighting: boolean = false\n private _treeSitterClient: TreeSitterClient\n private _highlightsDirty: boolean = false\n private _highlightSnapshotId: number = 0\n private _conceal: boolean\n private _drawUnstyledText: boolean\n private _shouldRenderTextBuffer: boolean = true\n private _streaming: boolean\n private _initialStyledText?: StyledText\n private _hadInitialContent: boolean = false\n private _lastHighlights: SimpleHighlight[] = []\n private _baseHighlight?: string\n private _onHighlight?: OnHighlightCallback\n private _onChunks?: OnChunksCallback\n private _highlightingPromise: Promise = Promise.resolve()\n // Temporary rendered-line -> source-line map for concealment; native extmarks should replace this.\n private _renderedLineSources?: number[]\n private _mappedLineInfo?: LineInfo\n\n protected _contentDefaultOptions = {\n content: \"\",\n conceal: true,\n drawUnstyledText: true,\n streaming: false,\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: CodeOptions) {\n super(ctx, options)\n\n this._content = options.content ?? this._contentDefaultOptions.content\n this._filetype = options.filetype\n this._syntaxStyle = options.syntaxStyle\n this._treeSitterClient = options.treeSitterClient ?? getTreeSitterClient()\n this._conceal = options.conceal ?? this._contentDefaultOptions.conceal\n this._drawUnstyledText = options.drawUnstyledText ?? this._contentDefaultOptions.drawUnstyledText\n this._streaming = options.streaming ?? this._contentDefaultOptions.streaming\n this._initialStyledText = options.initialStyledText\n this._baseHighlight = options.baseHighlight\n this._onHighlight = options.onHighlight\n this._onChunks = options.onChunks\n\n if (this._content.length > 0) {\n if (this._initialStyledText && this._drawUnstyledText) {\n this.textBuffer.setStyledText(this._initialStyledText)\n } else {\n this.textBuffer.setText(this._content)\n }\n this.updateTextInfo()\n this._shouldRenderTextBuffer = this._drawUnstyledText || !this._filetype\n }\n\n this._highlightsDirty = this._content.length > 0\n }\n\n get content(): string {\n return this._content\n }\n\n set content(value: string) {\n if (this._content !== value) {\n this._content = value\n this._highlightsDirty = true\n this._highlightSnapshotId++\n\n if (this._streaming && this._filetype && !this._drawUnstyledText) {\n this.requestRender()\n return\n }\n\n if (this._initialStyledText && this._drawUnstyledText) {\n this.textBuffer.setStyledText(this._initialStyledText)\n } else {\n this.textBuffer.setText(value)\n }\n this.setRenderedLineSources(undefined)\n this.updateTextInfo()\n }\n }\n\n public override get lineInfo(): LineInfo {\n if (!this._renderedLineSources) return super.lineInfo\n if (this._mappedLineInfo) return this._mappedLineInfo\n\n const lineInfo = super.lineInfo\n const renderedLineSources = this._renderedLineSources\n\n // Native reports visual rows for the rendered buffer; remap those rows back to source lines.\n this._mappedLineInfo = {\n ...lineInfo,\n lineSources: lineInfo.lineSources.map((line) => renderedLineSources[line] ?? line),\n }\n return this._mappedLineInfo\n }\n\n public override get wrapMode(): \"none\" | \"char\" | \"word\" {\n return super.wrapMode\n }\n\n public override set wrapMode(value: \"none\" | \"char\" | \"word\") {\n if (super.wrapMode !== value) {\n this._mappedLineInfo = undefined\n super.wrapMode = value\n }\n }\n\n protected override onResize(width: number, height: number): void {\n this._mappedLineInfo = undefined\n super.onResize(width, height)\n }\n\n protected override updateTextInfo(): void {\n this._mappedLineInfo = undefined\n super.updateTextInfo()\n }\n\n get filetype(): string | undefined {\n return this._filetype\n }\n\n set filetype(value: string | undefined) {\n if (this._filetype !== value) {\n this._filetype = value\n this._highlightsDirty = true\n }\n }\n\n get syntaxStyle(): SyntaxStyle {\n return this._syntaxStyle\n }\n\n set syntaxStyle(value: SyntaxStyle) {\n if (this._syntaxStyle !== value) {\n this._syntaxStyle = value\n this._highlightsDirty = true\n }\n }\n\n get conceal(): boolean {\n return this._conceal\n }\n\n set conceal(value: boolean) {\n if (this._conceal !== value) {\n this._conceal = value\n this._highlightsDirty = true\n }\n }\n\n get drawUnstyledText(): boolean {\n return this._drawUnstyledText\n }\n\n set drawUnstyledText(value: boolean) {\n if (this._drawUnstyledText !== value) {\n this._drawUnstyledText = value\n this._highlightsDirty = true\n }\n }\n\n get streaming(): boolean {\n return this._streaming\n }\n\n set initialStyledText(value: StyledText | undefined) {\n if (this._initialStyledText !== value) {\n this._initialStyledText = value\n this._highlightsDirty = true\n }\n }\n\n set streaming(value: boolean) {\n if (this._streaming !== value) {\n this._streaming = value\n this._hadInitialContent = false\n this._lastHighlights = []\n this._highlightsDirty = true\n }\n }\n\n get treeSitterClient(): TreeSitterClient {\n return this._treeSitterClient\n }\n\n set treeSitterClient(value: TreeSitterClient) {\n if (this._treeSitterClient !== value) {\n this._treeSitterClient = value\n this._highlightsDirty = true\n }\n }\n\n get onHighlight(): OnHighlightCallback | undefined {\n return this._onHighlight\n }\n\n get baseHighlight(): string | undefined {\n return this._baseHighlight\n }\n\n set baseHighlight(value: string | undefined) {\n if (this._baseHighlight !== value) {\n this._baseHighlight = value\n this._highlightsDirty = true\n }\n }\n\n set onHighlight(value: OnHighlightCallback | undefined) {\n if (this._onHighlight !== value) {\n this._onHighlight = value\n this._highlightsDirty = true\n }\n }\n\n get onChunks(): OnChunksCallback | undefined {\n return this._onChunks\n }\n\n set onChunks(value: OnChunksCallback | undefined) {\n if (this._onChunks !== value) {\n this._onChunks = value\n this._highlightsDirty = true\n }\n }\n\n get isHighlighting(): boolean {\n return this._isHighlighting\n }\n\n get highlightingDone(): Promise {\n return this._highlightingPromise\n }\n\n protected async transformChunks(chunks: TextChunk[], context: ChunkRenderContext): Promise {\n if (!this._onChunks) return chunks\n\n const modified = await this._onChunks(chunks, context)\n return modified ?? chunks\n }\n\n private ensureVisibleTextBeforeHighlight(): void {\n if (this.isDestroyed) return\n\n const content = this._content\n\n if (!this._filetype) {\n this._shouldRenderTextBuffer = true\n return\n }\n\n const isInitialContent = this._streaming && !this._hadInitialContent\n const shouldDrawUnstyledNow = this._streaming ? isInitialContent && this._drawUnstyledText : this._drawUnstyledText\n\n if (this._streaming && !isInitialContent) {\n this._shouldRenderTextBuffer = true\n } else if (shouldDrawUnstyledNow) {\n if (this._initialStyledText) {\n this.textBuffer.setStyledText(this._initialStyledText)\n } else {\n this.textBuffer.setText(content)\n }\n this.setRenderedLineSources(undefined)\n this._shouldRenderTextBuffer = true\n } else {\n this._shouldRenderTextBuffer = false\n }\n }\n\n private async startHighlight(): Promise {\n const content = this._content\n const filetype = this._filetype\n const snapshotId = ++this._highlightSnapshotId\n\n if (!filetype) return\n\n const isInitialContent = this._streaming && !this._hadInitialContent\n if (isInitialContent) {\n this._hadInitialContent = true\n }\n\n this._isHighlighting = true\n\n try {\n const result = await this._treeSitterClient.highlightOnce(content, filetype)\n\n if (snapshotId !== this._highlightSnapshotId) {\n this.requestRender()\n return\n }\n\n if (this.isDestroyed) return\n\n let highlights = result.highlights ?? []\n\n if (this._onHighlight && highlights.length >= 0) {\n const context: HighlightContext = {\n content,\n filetype,\n syntaxStyle: this._syntaxStyle,\n }\n const modified = await this._onHighlight(highlights, context)\n if (modified !== undefined) {\n highlights = modified\n }\n }\n\n if (snapshotId !== this._highlightSnapshotId) {\n this.requestRender()\n return\n }\n\n if (this.isDestroyed) return\n\n if (highlights.length > 0) {\n if (this._streaming) {\n this._lastHighlights = highlights\n }\n }\n\n if (highlights.length > 0 || this._onChunks || this._baseHighlight) {\n const context: ChunkRenderContext = {\n content,\n filetype,\n syntaxStyle: this._syntaxStyle,\n highlights,\n }\n\n let chunks = treeSitterToTextChunks(content, highlights, this._syntaxStyle, {\n enabled: this._conceal,\n baseHighlight: this._baseHighlight,\n })\n // onChunks may rewrite text arbitrarily, so the conceal-only source map would be invalid.\n const renderedLineSources = this._onChunks ? undefined : this.getConcealLinesSourceMap(content, highlights)\n\n chunks = await this.transformChunks(chunks, context)\n\n if (snapshotId !== this._highlightSnapshotId) {\n this.requestRender()\n return\n }\n\n if (this.isDestroyed) return\n\n const styledText = new StyledText(chunks)\n this.textBuffer.setStyledText(styledText)\n this.setRenderedLineSources(renderedLineSources)\n } else {\n this.textBuffer.setText(content)\n this.setRenderedLineSources(undefined)\n }\n\n this._shouldRenderTextBuffer = true\n this._isHighlighting = false\n this._highlightsDirty = false\n this.updateTextInfo()\n this.requestRender()\n } catch (error) {\n if (snapshotId !== this._highlightSnapshotId) {\n this.requestRender()\n return\n }\n\n console.warn(\"Code highlighting failed, falling back to plain text:\", error)\n if (this.isDestroyed) return\n this.textBuffer.setText(content)\n this.setRenderedLineSources(undefined)\n this._shouldRenderTextBuffer = true\n this._isHighlighting = false\n this._highlightsDirty = false\n this.updateTextInfo()\n this.requestRender()\n }\n }\n\n private setRenderedLineSources(lineSources: number[] | undefined): void {\n this._renderedLineSources = lineSources\n this._mappedLineInfo = undefined\n }\n\n private static isIdentityLineSources(lineSources: number[]): boolean {\n for (let i = 0; i < lineSources.length; i++) {\n if (lineSources[i] !== i) return false\n }\n return true\n }\n\n private static getMergedConcealLineRanges(highlights: SimpleHighlight[]): ConcealLineRange[] {\n const ranges: ConcealLineRange[] = []\n\n for (const highlight of highlights) {\n const meta = highlight[3]\n if (meta?.concealLines === undefined) continue\n\n const group = highlight[2]\n const isEmptyConceal =\n meta.conceal === \"\" || (meta.conceal === undefined && (group === \"conceal\" || group.startsWith(\"conceal.\")))\n if (isEmptyConceal) {\n ranges.push([highlight[0], highlight[1]])\n }\n }\n\n if (ranges.length <= 1) return ranges\n\n // Overlapping conceal ranges must collapse before line-by-line source mapping.\n ranges.sort((a, b) => a[0] - b[0])\n let writeIndex = 0\n\n for (let i = 1; i < ranges.length; i++) {\n const current = ranges[writeIndex]\n const next = ranges[i]\n\n if (next[0] <= current[1]) {\n current[1] = Math.max(current[1], next[1])\n } else {\n writeIndex++\n ranges[writeIndex] = next\n }\n }\n\n ranges.length = writeIndex + 1\n return ranges\n }\n\n private getConcealLinesSourceMap(content: string, highlights: SimpleHighlight[]): number[] | undefined {\n if (!this._conceal || content.length === 0) return undefined\n\n // setStyledText gives native only rendered text; rebuild enough source identity for concealed lines.\n // Native view-resolved extmarks should make this a layout query instead of a parallel map.\n const concealLineRanges = CodeRenderable.getMergedConcealLineRanges(highlights)\n if (concealLineRanges.length === 0) return undefined\n\n const lineSources: number[] = []\n let sourceLine = 0\n let lineStart = 0\n let rangeIndex = 0\n let currentRenderedLineHasText = false\n\n const setCurrentRenderedLineSource = (line: number, hasText: boolean): void => {\n // Until visible text is emitted, a rendered line can still map to a later collapsed source line.\n if (lineSources.length === 0) {\n lineSources.push(line)\n } else if (!currentRenderedLineHasText) {\n lineSources[lineSources.length - 1] = line\n }\n\n if (hasText) currentRenderedLineHasText = true\n }\n\n while (lineStart <= content.length) {\n const newlineOffset = content.indexOf(\"\\n\", lineStart)\n const lineEnd = newlineOffset === -1 ? content.length : newlineOffset\n\n while (rangeIndex < concealLineRanges.length && concealLineRanges[rangeIndex][1] <= lineStart) {\n rangeIndex++\n }\n\n const range = concealLineRanges[rangeIndex]\n const fullyConcealed = !!range && lineEnd > lineStart && range[0] <= lineStart && range[1] >= lineEnd\n const lineBreakConcealed =\n newlineOffset !== -1 && !!range && range[0] <= newlineOffset && range[1] >= newlineOffset\n\n if (!fullyConcealed || !lineBreakConcealed) {\n const hasText = lineEnd > lineStart && !fullyConcealed\n if (hasText || newlineOffset !== -1 || !fullyConcealed) {\n setCurrentRenderedLineSource(sourceLine, hasText)\n }\n\n if (newlineOffset !== -1 && !lineBreakConcealed) {\n lineSources.push(sourceLine + 1)\n currentRenderedLineHasText = false\n }\n }\n\n sourceLine++\n if (newlineOffset === -1) break\n lineStart = newlineOffset + 1\n }\n\n if (lineSources.length === 0 || CodeRenderable.isIdentityLineSources(lineSources)) return undefined\n return lineSources\n }\n\n public getLineHighlights(lineIdx: number) {\n return this.textBuffer.getLineHighlights(lineIdx)\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n if (this._highlightsDirty) {\n if (this.isDestroyed) return\n\n if (this._content.length === 0) {\n this._shouldRenderTextBuffer = false\n this._highlightsDirty = false\n } else if (!this._filetype) {\n this._shouldRenderTextBuffer = true\n this._highlightsDirty = false\n } else {\n this.ensureVisibleTextBeforeHighlight()\n this._highlightsDirty = false\n this._highlightingPromise = this.startHighlight()\n }\n }\n\n if (!this._shouldRenderTextBuffer) return\n super.renderSelf(buffer)\n }\n}\n", + "import type { TextRenderable } from \"./Text.js\"\nimport { BaseRenderable, type BaseRenderableOptions } from \"../Renderable.js\"\nimport { RGBA, parseColor } from \"../lib/RGBA.js\"\nimport { isStyledText, StyledText } from \"../lib/styled-text.js\"\nimport { type TextChunk } from \"../text-buffer.js\"\nimport type { RenderContext } from \"../types.js\"\n\nexport interface TextNodeOptions extends BaseRenderableOptions {\n fg?: string | RGBA\n bg?: string | RGBA\n attributes?: number\n link?: { url: string }\n}\n\nconst BrandedTextNodeRenderable: unique symbol = Symbol.for(\"@opentui/core/TextNodeRenderable\")\n\nexport function isTextNodeRenderable(obj: any): obj is TextNodeRenderable {\n return !!obj?.[BrandedTextNodeRenderable]\n}\n\nfunction styledTextToTextNodes(styledText: StyledText): TextNodeRenderable[] {\n return styledText.chunks.map((chunk) => {\n const node = new TextNodeRenderable({\n fg: chunk.fg,\n bg: chunk.bg,\n attributes: chunk.attributes,\n link: chunk.link,\n })\n node.add(chunk.text)\n return node\n })\n}\n\nexport class TextNodeRenderable extends BaseRenderable {\n [BrandedTextNodeRenderable] = true\n\n private _fg?: RGBA\n private _bg?: RGBA\n private _attributes: number\n private _link?: { url: string }\n private _children: (string | TextNodeRenderable)[] = []\n public parent: TextNodeRenderable | null = null\n\n constructor(options: TextNodeOptions) {\n super(options)\n\n this._fg = options.fg ? parseColor(options.fg) : undefined\n this._bg = options.bg ? parseColor(options.bg) : undefined\n this._attributes = options.attributes ?? 0\n this._link = options.link\n }\n\n public get children(): (string | TextNodeRenderable)[] {\n return this._children\n }\n\n public set children(children: (string | TextNodeRenderable)[]) {\n this._children = children\n this.requestRender()\n }\n\n public requestRender(): void {\n this.markDirty()\n this.parent?.requestRender()\n }\n\n public add(obj: TextNodeRenderable | StyledText | string, index?: number): number {\n if (typeof obj === \"string\") {\n if (index !== undefined) {\n this._children.splice(index, 0, obj)\n this.requestRender()\n return index\n }\n\n const insertIndex = this._children.length\n this._children.push(obj)\n this.requestRender()\n return insertIndex\n }\n\n if (isTextNodeRenderable(obj)) {\n if (index !== undefined) {\n this._children.splice(index, 0, obj)\n obj.parent = this\n this.requestRender()\n return index\n }\n\n const insertIndex = this._children.length\n this._children.push(obj)\n obj.parent = this\n this.requestRender()\n return insertIndex\n }\n\n if (isStyledText(obj)) {\n const textNodes = styledTextToTextNodes(obj)\n if (index !== undefined) {\n this._children.splice(index, 0, ...textNodes)\n textNodes.forEach((node) => (node.parent = this))\n this.requestRender()\n return index\n }\n\n const insertIndex = this._children.length\n this._children.push(...textNodes)\n textNodes.forEach((node) => (node.parent = this))\n this.requestRender()\n return insertIndex\n }\n\n throw new Error(\"TextNodeRenderable only accepts strings, TextNodeRenderable instances, or StyledText instances\")\n }\n\n public replace(obj: TextNodeRenderable | string, index: number) {\n this._children[index] = obj\n if (typeof obj !== \"string\") {\n obj.parent = this\n }\n this.requestRender()\n }\n\n public insertBefore(\n child: string | TextNodeRenderable | StyledText,\n anchorNode: TextNodeRenderable | string | unknown,\n ): this {\n if (!anchorNode || !isTextNodeRenderable(anchorNode)) {\n throw new Error(\"Anchor must be a TextNodeRenderable\")\n }\n\n const anchorIndex = this._children.indexOf(anchorNode)\n if (anchorIndex === -1) {\n throw new Error(\"Anchor node not found in children\")\n }\n\n if (typeof child === \"string\") {\n this._children.splice(anchorIndex, 0, child)\n } else if (isTextNodeRenderable(child)) {\n this._children.splice(anchorIndex, 0, child)\n child.parent = this\n } else if (child instanceof StyledText) {\n const textNodes = styledTextToTextNodes(child)\n this._children.splice(anchorIndex, 0, ...textNodes)\n textNodes.forEach((node) => (node.parent = this))\n } else {\n throw new Error(\"Child must be a string, TextNodeRenderable, or StyledText instance\")\n }\n\n this.requestRender()\n return this\n }\n\n public remove(id: string): this {\n const childIndex = this.getRenderableIndex(id)\n if (childIndex === -1) {\n throw new Error(\"Child not found in children\")\n }\n\n const child = this._children[childIndex] as TextNodeRenderable\n\n this._children.splice(childIndex, 1)\n child.parent = null\n this.requestRender()\n return this\n }\n\n public clear(): void {\n this._children = []\n this.requestRender()\n }\n\n public mergeStyles(parentStyle: { fg?: RGBA; bg?: RGBA; attributes: number; link?: { url: string } }): {\n fg?: RGBA\n bg?: RGBA\n attributes: number\n link?: { url: string }\n } {\n return {\n fg: this._fg ?? parentStyle.fg,\n bg: this._bg ?? parentStyle.bg,\n attributes: this._attributes | parentStyle.attributes,\n link: this._link ?? parentStyle.link,\n }\n }\n\n public gatherWithInheritedStyle(\n parentStyle: { fg?: RGBA; bg?: RGBA; attributes: number; link?: { url: string } } = {\n fg: undefined,\n bg: undefined,\n attributes: 0,\n },\n ): TextChunk[] {\n const currentStyle = this.mergeStyles(parentStyle)\n\n const chunks: TextChunk[] = []\n\n for (const child of this._children) {\n if (typeof child === \"string\") {\n chunks.push({\n __isChunk: true,\n text: child,\n fg: currentStyle.fg,\n bg: currentStyle.bg,\n attributes: currentStyle.attributes,\n link: currentStyle.link,\n })\n } else {\n const childChunks = child.gatherWithInheritedStyle(currentStyle)\n chunks.push(...childChunks)\n }\n }\n\n this.markClean()\n\n return chunks\n }\n\n public static fromString(text: string, options: Partial = {}): TextNodeRenderable {\n const node = new TextNodeRenderable(options)\n node.add(text)\n return node\n }\n\n public static fromNodes(nodes: TextNodeRenderable[], options: Partial = {}): TextNodeRenderable {\n const node = new TextNodeRenderable(options)\n for (const childNode of nodes) {\n node.add(childNode)\n }\n return node\n }\n\n public toChunks(\n parentStyle: { fg?: RGBA; bg?: RGBA; attributes: number; link?: { url: string } } = {\n fg: undefined,\n bg: undefined,\n attributes: 0,\n },\n ): TextChunk[] {\n return this.gatherWithInheritedStyle(parentStyle)\n }\n\n public getChildren(): BaseRenderable[] {\n return this._children.filter((child): child is TextNodeRenderable => typeof child !== \"string\")\n }\n\n public getChildrenCount(): number {\n return this._children.length\n }\n\n public getRenderable(id: string): BaseRenderable | undefined {\n return this._children.find((child): child is TextNodeRenderable => typeof child !== \"string\" && child.id === id)\n }\n\n public getRenderableIndex(id: string): number {\n return this._children.findIndex((child) => isTextNodeRenderable(child) && child.id === id)\n }\n\n public get fg(): RGBA | undefined {\n return this._fg\n }\n\n public set fg(fg: RGBA | string | undefined) {\n if (!fg) {\n this._fg = undefined\n this.requestRender()\n return\n }\n this._fg = parseColor(fg)\n this.requestRender()\n }\n\n public set bg(bg: RGBA | string | undefined) {\n if (!bg) {\n this._bg = undefined\n this.requestRender()\n return\n }\n this._bg = parseColor(bg)\n this.requestRender()\n }\n\n public get bg(): RGBA | undefined {\n return this._bg\n }\n\n public set attributes(attributes: number) {\n this._attributes = attributes\n this.requestRender()\n }\n\n public get attributes(): number {\n return this._attributes\n }\n\n public set link(link: { url: string } | undefined) {\n this._link = link\n this.requestRender()\n }\n\n public get link(): { url: string } | undefined {\n return this._link\n }\n\n public findDescendantById(id: string): BaseRenderable | undefined {\n return undefined\n }\n}\n\nexport class RootTextNodeRenderable extends TextNodeRenderable {\n textParent: TextRenderable\n\n constructor(\n private readonly ctx: RenderContext,\n options: TextNodeOptions,\n textParent: TextRenderable,\n ) {\n super(options)\n this.textParent = textParent\n }\n\n public requestRender(): void {\n this.markDirty()\n this.ctx.requestRender()\n }\n}\n", + "import { BaseRenderable } from \"../Renderable.js\"\nimport { stringToStyledText, StyledText } from \"../lib/styled-text.js\"\nimport { type TextChunk } from \"../text-buffer.js\"\nimport { RGBA } from \"../lib/RGBA.js\"\nimport { type RenderContext } from \"../types.js\"\nimport { RootTextNodeRenderable, TextNodeRenderable } from \"./TextNode.js\"\nimport { TextBufferRenderable, type TextBufferOptions } from \"./TextBufferRenderable.js\"\n\nexport interface TextOptions extends TextBufferOptions {\n content?: StyledText | string\n}\n\nexport class TextRenderable extends TextBufferRenderable {\n private _text: StyledText\n\n // TODO: The TextRenderable is currently juggling both a StyledText and a RootTextNodeRenderable.\n // We should refactor this to only use the RootTextNodeRenderable here and have a separate StyledTextRenderable with `content`.\n private _hasManualStyledText: boolean = false\n\n protected rootTextNode: RootTextNodeRenderable\n\n protected _contentDefaultOptions = {\n content: \"\",\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: TextOptions) {\n super(ctx, options)\n\n const content = options.content ?? this._contentDefaultOptions.content\n const styledText = typeof content === \"string\" ? stringToStyledText(content) : content\n this._text = styledText\n this._hasManualStyledText = options.content !== undefined && content !== \"\"\n\n this.rootTextNode = new RootTextNodeRenderable(\n ctx,\n {\n id: `${this.id}-root`,\n fg: this._defaultFg,\n bg: this._defaultBg,\n attributes: this._defaultAttributes,\n },\n this,\n )\n\n this.updateTextBuffer(styledText)\n }\n\n private updateTextBuffer(styledText: StyledText): void {\n this.textBuffer.setStyledText(styledText)\n this.clearChunks(styledText)\n }\n\n private clearChunks(styledText: StyledText): void {\n // Clearing chunks that were already writtend to the text buffer,\n // to not retain references to the text data in js\n // TODO: This is causing issues in the solid renderer\n // styledText.chunks.forEach((chunk) => {\n // // @ts-ignore\n // chunk.text = undefined\n // })\n }\n\n get content(): StyledText {\n return this._text\n }\n\n get chunks(): TextChunk[] {\n return this._text.chunks\n }\n\n get textNode(): RootTextNodeRenderable {\n return this.rootTextNode\n }\n\n set content(value: StyledText | string) {\n this._hasManualStyledText = true\n const styledText = typeof value === \"string\" ? stringToStyledText(value) : value\n if (this._text !== styledText) {\n this._text = styledText\n this.updateTextBuffer(styledText)\n this.updateTextInfo()\n }\n }\n\n private updateTextFromNodes(): void {\n if (this.rootTextNode.isDirty && !this._hasManualStyledText) {\n const chunks = this.rootTextNode.gatherWithInheritedStyle({\n fg: this._defaultFg,\n bg: this._defaultBg,\n attributes: this._defaultAttributes,\n link: undefined,\n })\n this.textBuffer.setStyledText(new StyledText(chunks))\n this.refreshLocalSelection()\n this.yogaNode.markDirty()\n }\n }\n\n public add(obj: TextNodeRenderable | StyledText | string, index?: number): number {\n return this.rootTextNode.add(obj, index)\n }\n\n public remove(id: string): void {\n this.rootTextNode.remove(id)\n }\n\n public insertBefore(obj: BaseRenderable | any, anchor?: TextNodeRenderable): number {\n this.rootTextNode.insertBefore(obj, anchor)\n return this.rootTextNode.children.indexOf(obj)\n }\n\n public getTextChildren(): BaseRenderable[] {\n return this.rootTextNode.getChildren()\n }\n\n public clear(): void {\n this.rootTextNode.clear()\n\n const emptyStyledText = stringToStyledText(\"\")\n this._text = emptyStyledText\n this.updateTextBuffer(emptyStyledText)\n this.updateTextInfo()\n\n this.requestRender()\n }\n\n public onLifecyclePass = () => {\n this.updateTextFromNodes()\n }\n\n protected onFgChanged(newColor: RGBA): void {\n this.rootTextNode.fg = newColor\n }\n\n protected onBgChanged(newColor: RGBA): void {\n this.rootTextNode.bg = newColor\n }\n\n protected onAttributesChanged(newAttributes: number): void {\n this.rootTextNode.attributes = newAttributes\n }\n\n destroy(): void {\n this.rootTextNode.children.length = 0\n super.destroy()\n }\n}\n", + "import { toArrayBuffer, type Pointer } from \"./platform/ffi.js\"\nimport { resolveRenderLib } from \"./zig.js\"\nimport { SpanInfoStruct } from \"./zig-structs.js\"\nimport type { NativeSpanFeedOptions } from \"./zig-structs.js\"\n\nexport type { GrowthPolicy, NativeSpanFeedOptions, NativeSpanFeedStats } from \"./zig-structs.js\"\n\nconst enum EventId {\n ChunkAdded = 2,\n Closed = 5,\n Error = 6,\n DataAvailable = 7,\n StateBuffer = 8,\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === \"bigint\" ? Number(value) : value\n}\n\ntype StreamEventHandler = (eventId: number, arg0: Pointer, arg1: number | bigint) => void\n\nexport type DataHandler = (data: Uint8Array) => void | Promise\n\nconst canThrowAcrossNativeCallback =\n typeof process !== \"undefined\" &&\n typeof process.versions === \"object\" &&\n process.versions !== null &&\n typeof process.versions.bun === \"string\"\n\n/**\n * Zero-copy wrapper over Zig memory; not a full stream interface.\n * Chunk and state typed-array views are borrowed and invalid after destroy.\n */\nexport class NativeSpanFeed {\n static create(options?: NativeSpanFeedOptions): NativeSpanFeed {\n const lib = resolveRenderLib()\n const streamPtr = lib.createNativeSpanFeed(options)\n const stream = new NativeSpanFeed(streamPtr)\n\n lib.registerNativeSpanFeedStream(streamPtr, stream.eventHandler)\n\n const status = lib.attachNativeSpanFeed(streamPtr)\n if (status !== 0) {\n lib.unregisterNativeSpanFeedStream(streamPtr)\n lib.destroyNativeSpanFeed(streamPtr)\n throw new Error(`Failed to attach stream: ${status}`)\n }\n\n return stream\n }\n\n static attach(streamPtr: Pointer, _options?: NativeSpanFeedOptions): NativeSpanFeed {\n const lib = resolveRenderLib()\n const stream = new NativeSpanFeed(streamPtr)\n\n lib.registerNativeSpanFeedStream(streamPtr, stream.eventHandler)\n\n const status = lib.attachNativeSpanFeed(streamPtr)\n if (status !== 0) {\n lib.unregisterNativeSpanFeedStream(streamPtr)\n throw new Error(`Failed to attach stream: ${status}`)\n }\n\n return stream\n }\n\n readonly streamPtr: Pointer\n private readonly lib = resolveRenderLib()\n private readonly eventHandler: StreamEventHandler\n private chunkMap = new Map()\n private chunkSizes = new Map()\n private dataHandlers = new Set()\n private errorHandlers = new Set<(code: number) => void>()\n private drainBuffer: Uint8Array | null = null\n private stateBuffer: Uint8Array | null = null\n private closed = false\n private destroyed = false\n private draining = false\n private pendingDataAvailable = false\n private pendingClose = false\n private closing = false\n private pendingAsyncHandlers = 0\n private inCallback = false\n private closeQueued = false\n private idleResolvers: Array<() => void> = []\n private pendingHandlerError: unknown = null\n private pendingHandlerErrorQueued = false\n\n private constructor(streamPtr: Pointer) {\n this.streamPtr = streamPtr\n this.eventHandler = (eventId, arg0, arg1) => {\n this.handleEvent(eventId, arg0, arg1)\n }\n this.ensureDrainBuffer()\n }\n\n private ensureDrainBuffer(): void {\n if (this.drainBuffer) return\n const capacity = 256\n this.drainBuffer = new Uint8Array(capacity * SpanInfoStruct.size)\n }\n\n onData(handler: DataHandler): () => void {\n this.dataHandlers.add(handler)\n if (this.pendingDataAvailable) {\n this.pendingDataAvailable = false\n this.drainAll()\n }\n return () => this.dataHandlers.delete(handler)\n }\n\n onError(handler: (code: number) => void): () => void {\n this.errorHandlers.add(handler)\n return () => this.errorHandlers.delete(handler)\n }\n\n private hasPinnedChunks(): boolean {\n if (!this.stateBuffer) return false\n for (const refcount of this.stateBuffer) {\n if (refcount > 0) return true\n }\n return false\n }\n\n isBackpressured(): boolean {\n return this.pendingAsyncHandlers > 0 || this.pendingDataAvailable || this.hasPinnedChunks()\n }\n\n close(): void {\n if (this.destroyed) return\n if (this.inCallback || this.draining || this.pendingAsyncHandlers > 0) {\n this.pendingClose = true\n if (!this.closeQueued) {\n this.closeQueued = true\n queueMicrotask(() => {\n this.closeQueued = false\n this.processPendingClose()\n })\n }\n return\n }\n this.performClose()\n }\n\n private processPendingClose(): void {\n if (!this.pendingClose || this.destroyed) return\n if (this.inCallback || this.draining || this.pendingAsyncHandlers > 0) return\n this.pendingClose = false\n this.performClose()\n this.resolveIdleIfNeeded()\n }\n\n private performClose(): void {\n if (this.closing) return\n this.closing = true\n if (!this.closed) {\n const status = this.lib.streamClose(this.streamPtr)\n if (status !== 0) {\n this.closing = false\n return\n }\n this.closed = true\n }\n this.finalizeDestroy()\n }\n\n private finalizeDestroy(): void {\n if (this.destroyed) return\n this.lib.unregisterNativeSpanFeedStream(this.streamPtr)\n this.lib.destroyNativeSpanFeed(this.streamPtr)\n this.destroyed = true\n this.chunkMap.clear()\n this.chunkSizes.clear()\n this.stateBuffer = null\n this.drainBuffer = null\n this.dataHandlers.clear()\n this.errorHandlers.clear()\n this.pendingDataAvailable = false\n this.resolveIdleIfNeeded()\n }\n\n private isIdle(): boolean {\n return (\n !this.inCallback &&\n !this.draining &&\n this.pendingAsyncHandlers === 0 &&\n !this.pendingDataAvailable &&\n !this.hasPinnedChunks()\n )\n }\n\n private resolveIdleIfNeeded(): void {\n if (!this.isIdle()) return\n const resolvers = this.idleResolvers.splice(0)\n for (const resolve of resolvers) {\n resolve()\n }\n }\n\n idle(): Promise {\n if (this.isIdle()) return Promise.resolve()\n return new Promise((resolve) => {\n this.idleResolvers.push(resolve)\n })\n }\n\n private handleEvent(eventId: number, arg0: Pointer, arg1: number | bigint): void {\n this.inCallback = true\n try {\n switch (eventId) {\n case EventId.StateBuffer: {\n const len = toNumber(arg1)\n if (len > 0 && arg0) {\n // toArrayBuffer must alias Zig memory so refcount writes are visible.\n const buffer = toArrayBuffer(arg0, 0, len)\n this.stateBuffer = new Uint8Array(buffer)\n }\n break\n }\n case EventId.DataAvailable: {\n if (this.closing) break\n if (this.dataHandlers.size === 0) {\n this.pendingDataAvailable = true\n break\n }\n this.drainAll()\n break\n }\n case EventId.ChunkAdded: {\n const chunkLen = toNumber(arg1)\n if (chunkLen > 0 && arg0) {\n if (!this.chunkMap.has(arg0)) {\n const buffer = toArrayBuffer(arg0, 0, chunkLen)\n this.chunkMap.set(arg0, buffer)\n }\n this.chunkSizes.set(arg0, chunkLen)\n }\n break\n }\n case EventId.Error: {\n const code = toNumber(arg0)\n for (const handler of this.errorHandlers) handler(code)\n break\n }\n case EventId.Closed: {\n this.closed = true\n break\n }\n default:\n break\n }\n } finally {\n this.inCallback = false\n this.resolveIdleIfNeeded()\n }\n }\n\n private decrementRefcount(chunkIndex: number): void {\n if (this.stateBuffer && chunkIndex < this.stateBuffer.length) {\n const prev = this.stateBuffer[chunkIndex]\n this.stateBuffer[chunkIndex] = prev > 0 ? prev - 1 : 0\n }\n }\n\n private queuePendingHandlerError(error: unknown): void {\n this.pendingHandlerError ??= error\n if (this.pendingHandlerErrorQueued) return\n\n this.pendingHandlerErrorQueued = true\n queueMicrotask(() => {\n this.pendingHandlerErrorQueued = false\n if (this.pendingHandlerError === null) return\n\n const pendingError = this.pendingHandlerError\n this.pendingHandlerError = null\n throw pendingError\n })\n }\n\n private throwPendingHandlerError(): void {\n if (this.pendingHandlerError === null) return\n\n const pendingError = this.pendingHandlerError\n this.pendingHandlerError = null\n throw pendingError\n }\n\n private drainOnce(): number {\n if (!this.drainBuffer || this.draining || this.pendingClose) return 0\n const capacity = Math.floor(this.drainBuffer.byteLength / SpanInfoStruct.size)\n if (capacity === 0) return 0\n\n const count = this.lib.streamDrainSpans(this.streamPtr, this.drainBuffer, capacity)\n if (count === 0) return 0\n\n this.draining = true\n const spans = SpanInfoStruct.unpackList(this.drainBuffer.buffer, count)\n let firstError: unknown = null\n\n try {\n for (const span of spans) {\n if (span.len === 0) continue\n\n let buffer = this.chunkMap.get(span.chunkPtr)\n if (!buffer) {\n const size = this.chunkSizes.get(span.chunkPtr)\n if (!size) continue\n buffer = toArrayBuffer(span.chunkPtr, 0, size)\n this.chunkMap.set(span.chunkPtr, buffer)\n }\n\n if (span.offset + span.len > buffer.byteLength) continue\n\n const slice = new Uint8Array(buffer, span.offset, span.len)\n let asyncResults: Promise[] | null = null\n\n for (const handler of this.dataHandlers) {\n try {\n const result = handler(slice)\n // Async handlers keep the chunk pinned until they settle.\n if (result && typeof result.then === \"function\") {\n asyncResults ??= []\n asyncResults.push(result)\n }\n } catch (e) {\n firstError ??= e\n }\n }\n\n const shouldStopAfterThisSpan = this.pendingClose\n\n if (asyncResults) {\n // Use allSettled so rejections still release refcounts.\n const chunkIndex = span.chunkIndex\n this.pendingAsyncHandlers += 1\n Promise.allSettled(asyncResults).then(() => {\n this.decrementRefcount(chunkIndex)\n this.pendingAsyncHandlers -= 1\n this.processPendingClose()\n this.resolveIdleIfNeeded()\n })\n } else {\n this.decrementRefcount(span.chunkIndex)\n }\n\n if (shouldStopAfterThisSpan) break\n }\n } finally {\n this.draining = false\n this.resolveIdleIfNeeded()\n }\n\n if (firstError) {\n if (!this.inCallback || canThrowAcrossNativeCallback) {\n throw firstError\n }\n\n // Node FFI terminates when JS exceptions cross a native callback boundary.\n // Surface the error after the callback returns instead of swallowing it.\n this.queuePendingHandlerError(firstError)\n }\n\n return count\n }\n\n drainAll(): void {\n let count = this.drainOnce()\n while (count > 0) {\n count = this.drainOnce()\n }\n if (!this.inCallback) {\n this.throwPendingHandlerError()\n }\n }\n}\n", + "import { EventEmitter } from \"events\"\nimport { Console } from \"node:console\"\nimport fs from \"node:fs\"\nimport path from \"node:path\"\nimport util from \"node:util\"\nimport type { CliRenderer, MouseEvent } from \"./renderer.js\"\nimport type { ColorInput } from \"./lib/RGBA.js\"\nimport { OptimizedBuffer } from \"./buffer.js\"\nimport { type Clock, SystemClock } from \"./lib/clock.js\"\nimport { Capture, CapturedWritableStream } from \"./lib/output.capture.js\"\nimport { parseColor, RGBA } from \"./lib/RGBA.js\"\nimport { singleton } from \"./lib/singleton.js\"\nimport { env, registerEnvVar } from \"./lib/env.js\"\nimport type { KeyEvent } from \"./lib/KeyHandler.js\"\nimport {\n type KeyBinding as BaseKeyBinding,\n mergeKeyBindings,\n buildKeyBindingsMap,\n getKeyBindingAction,\n defaultKeyAliases,\n mergeKeyAliases,\n keyBindingToString,\n} from \"./lib/keybinding.internal.js\"\n\ntype KeyAliasMap = Record\n\ninterface CallerInfo {\n functionName: string\n fullPath: string\n fileName: string\n lineNumber: number\n columnNumber: number\n}\n\nfunction getCallerInfo(): CallerInfo | null {\n const err = new Error()\n const stackLines = err.stack?.split(\"\\n\").slice(5) || []\n if (!stackLines.length) return null\n\n const callerLine = stackLines[0].trim()\n\n const regex = /at\\s+(?:([\\w$.<>]+)\\s+\\()?((?:\\/|[A-Za-z]:\\\\)[^:]+):(\\d+):(\\d+)\\)?/\n const match = callerLine.match(regex)\n\n if (!match) return null\n\n // Extract details from the match.\n const functionName = match[1] || \"\"\n const fullPath = match[2]\n const fileName = fullPath.split(/[\\\\/]/).pop() || \"\"\n const lineNumber = parseInt(match[3], 10) || 0\n const columnNumber = parseInt(match[4], 10) || 0\n\n return { functionName, fullPath, fileName, lineNumber, columnNumber }\n}\n\nenum LogLevel {\n LOG = \"LOG\",\n INFO = \"INFO\",\n WARN = \"WARN\",\n ERROR = \"ERROR\",\n DEBUG = \"DEBUG\",\n}\n\nexport const capture = singleton(\"ConsoleCapture\", () => new Capture())\n\nregisterEnvVar({\n name: \"OTUI_USE_CONSOLE\",\n description: \"Whether to use the console. Will not capture console output if set to false.\",\n type: \"boolean\",\n default: true,\n})\n\nregisterEnvVar({\n name: \"SHOW_CONSOLE\",\n description: \"Show the console at startup if set to true.\",\n type: \"boolean\",\n default: false,\n})\n\nclass TerminalConsoleCache extends EventEmitter {\n private _cachedLogs: [Date, LogLevel, any[], CallerInfo | null][] = []\n private readonly MAX_CACHE_SIZE = 1000\n private _collectCallerInfo: boolean = false\n private _cachingEnabled: boolean = true\n private _originalConsole: typeof console | null = null\n\n get cachedLogs(): [Date, LogLevel, any[], CallerInfo | null][] {\n return this._cachedLogs\n }\n\n constructor() {\n super()\n\n // Note: Console activation will be handled by the renderer when needed\n // Don't activate on import to avoid hiding console.log globally\n }\n\n public activate(): void {\n if (!this._originalConsole) {\n this._originalConsole = global.console\n }\n this.setupConsoleCapture()\n this.overrideConsoleMethods()\n }\n\n private setupConsoleCapture(): void {\n if (!env.OTUI_USE_CONSOLE) return\n\n const mockStdout = new CapturedWritableStream(\"stdout\", capture)\n const mockStderr = new CapturedWritableStream(\"stderr\", capture)\n\n // TODO: The Console constructor doesn't return a full Console interface implementation,\n // it only provides a subset of methods (log, info, warn, error, debug, etc.).\n // TypeScript's Console interface requires all methods (assert, clear, count, etc.).\n // Using 'as any' as a workaround since we override the methods we use immediately after.\n global.console = new Console({\n stdout: mockStdout,\n stderr: mockStderr,\n colorMode: true,\n inspectOptions: {\n compact: false,\n breakLength: 80,\n depth: 2,\n },\n }) as any\n }\n\n private overrideConsoleMethods(): void {\n console.log = (...args: any[]) => {\n this.appendToConsole(LogLevel.LOG, ...args)\n }\n\n console.info = (...args: any[]) => {\n this.appendToConsole(LogLevel.INFO, ...args)\n }\n\n console.warn = (...args: any[]) => {\n this.appendToConsole(LogLevel.WARN, ...args)\n }\n\n console.error = (...args: any[]) => {\n this.appendToConsole(LogLevel.ERROR, ...args)\n }\n\n console.debug = (...args: any[]) => {\n this.appendToConsole(LogLevel.DEBUG, ...args)\n }\n\n // React 19.2's reconciler calls console.timeStamp with a 6-arg Performance Tracks signature.\n // The new Console instance from setupConsoleCapture lacks timeStamp, so provide a no-op\n // unless the runtime already supplies one.\n if (typeof console.timeStamp !== \"function\") {\n console.timeStamp = () => {}\n }\n }\n\n public setCollectCallerInfo(enabled: boolean): void {\n this._collectCallerInfo = enabled\n }\n\n public clearConsole(): void {\n this._cachedLogs = []\n }\n\n public setCachingEnabled(enabled: boolean): void {\n this._cachingEnabled = enabled\n }\n\n public deactivate(): void {\n this.restoreOriginalConsole()\n }\n\n private restoreOriginalConsole(): void {\n if (this._originalConsole) {\n global.console = this._originalConsole\n }\n }\n\n public addLogEntry(level: LogLevel, ...args: any[]) {\n const callerInfo = this._collectCallerInfo ? getCallerInfo() : null\n const logEntry: [Date, LogLevel, any[], CallerInfo | null] = [new Date(), level, args, callerInfo]\n\n if (this._cachingEnabled) {\n if (this._cachedLogs.length >= this.MAX_CACHE_SIZE) {\n this._cachedLogs.shift()\n }\n this._cachedLogs.push(logEntry)\n }\n\n return logEntry\n }\n\n private appendToConsole(level: LogLevel, ...args: any[]): void {\n if (this._cachedLogs.length >= this.MAX_CACHE_SIZE) {\n this._cachedLogs.shift()\n }\n const entry = this.addLogEntry(level, ...args)\n this.emit(\"entry\", entry)\n }\n\n public destroy(): void {\n this.deactivate()\n }\n}\n\nconst terminalConsoleCache = singleton(\"TerminalConsoleCache\", () => {\n const terminalConsoleCache = new TerminalConsoleCache()\n process.on(\"exit\", () => {\n terminalConsoleCache.destroy()\n })\n return terminalConsoleCache\n})\n\nexport enum ConsolePosition {\n TOP = \"top\",\n BOTTOM = \"bottom\",\n LEFT = \"left\",\n RIGHT = \"right\",\n}\n\ninterface ConsoleSelection {\n startLine: number\n startCol: number\n endLine: number\n endCol: number\n}\n\nexport type ConsoleAction =\n | \"scroll-up\"\n | \"scroll-down\"\n | \"scroll-to-top\"\n | \"scroll-to-bottom\"\n | \"position-previous\"\n | \"position-next\"\n | \"size-increase\"\n | \"size-decrease\"\n | \"save-logs\"\n | \"copy-selection\"\n\nexport type ConsoleKeyBinding = BaseKeyBinding\n\nconst defaultConsoleKeybindings: ConsoleKeyBinding[] = [\n { name: \"up\", action: \"scroll-up\" },\n { name: \"down\", action: \"scroll-down\" },\n { name: \"up\", shift: true, action: \"scroll-to-top\" },\n { name: \"down\", shift: true, action: \"scroll-to-bottom\" },\n { name: \"p\", ctrl: true, action: \"position-previous\" },\n { name: \"o\", ctrl: true, action: \"position-next\" },\n { name: \"+\", action: \"size-increase\" },\n { name: \"=\", shift: true, action: \"size-increase\" },\n { name: \"-\", action: \"size-decrease\" },\n { name: \"s\", ctrl: true, action: \"save-logs\" },\n { name: \"c\", ctrl: true, shift: true, action: \"copy-selection\" },\n]\n\nexport interface ConsoleOptions {\n position?: ConsolePosition\n sizePercent?: number\n zIndex?: number\n colorInfo?: ColorInput\n colorWarn?: ColorInput\n colorError?: ColorInput\n colorDebug?: ColorInput\n colorDefault?: ColorInput\n backgroundColor?: ColorInput\n startInDebugMode?: boolean\n title?: string\n titleBarColor?: ColorInput\n titleBarTextColor?: ColorInput\n cursorColor?: ColorInput\n maxStoredLogs?: number\n maxDisplayLines?: number\n onCopySelection?: (text: string) => void\n keyBindings?: ConsoleKeyBinding[]\n keyAliasMap?: KeyAliasMap\n selectionColor?: ColorInput\n copyButtonColor?: ColorInput\n clock?: Clock\n}\n\nconst DEFAULT_CONSOLE_OPTIONS: Required<\n Omit\n> & {\n onCopySelection?: (text: string) => void\n keyBindings?: ConsoleKeyBinding[]\n keyAliasMap?: KeyAliasMap\n} = {\n position: ConsolePosition.BOTTOM,\n sizePercent: 30,\n zIndex: Infinity,\n colorInfo: \"#00FFFF\", // Cyan\n colorWarn: \"#FFFF00\", // Yellow\n colorError: \"#FF0000\", // Red\n colorDebug: \"#808080\", // Gray\n colorDefault: \"#FFFFFF\", // White\n backgroundColor: RGBA.fromValues(0.1, 0.1, 0.1, 0.7),\n startInDebugMode: false,\n title: \"Console\",\n titleBarColor: RGBA.fromValues(0.05, 0.05, 0.05, 0.7),\n titleBarTextColor: \"#FFFFFF\",\n cursorColor: \"#00A0FF\",\n maxStoredLogs: 2000,\n maxDisplayLines: 3000,\n onCopySelection: undefined,\n keyBindings: undefined,\n keyAliasMap: undefined,\n selectionColor: RGBA.fromValues(0.3, 0.5, 0.8, 0.5),\n copyButtonColor: \"#00A0FF\",\n}\n\nconst INDENT_WIDTH = 2\n\ninterface DisplayLine {\n text: string\n level: LogLevel\n indent: boolean\n}\n\nexport class TerminalConsole extends EventEmitter {\n private isVisible: boolean = false\n private isFocused: boolean = false\n private renderer: CliRenderer\n private keyHandler: (event: KeyEvent) => void\n private options: Required> & {\n onCopySelection?: (text: string) => void\n keyBindings?: ConsoleKeyBinding[]\n keyAliasMap?: KeyAliasMap\n }\n private _debugModeEnabled: boolean = false\n\n private frameBuffer: OptimizedBuffer | null = null\n private consoleX: number = 0\n private consoleY: number = 0\n private consoleWidth: number = 0\n private consoleHeight: number = 0\n private scrollTopIndex: number = 0\n private isScrolledToBottom: boolean = true\n private currentLineIndex: number = 0\n private _displayLines: DisplayLine[] = []\n private _allLogEntries: [Date, LogLevel, any[], CallerInfo | null][] = []\n private _needsFrameBufferUpdate: boolean = false\n private _entryListener: (logEntry: [Date, LogLevel, any[], CallerInfo | null]) => void\n\n private _selectionStart: { line: number; col: number } | null = null\n private _selectionEnd: { line: number; col: number } | null = null\n private _isDragging: boolean = false\n private _copyButtonBounds: { x: number; y: number; width: number; height: number } = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n }\n private _autoScrollInterval: ReturnType | null = null\n private readonly clock: Clock\n\n private _keyBindingsMap: Map\n private _keyAliasMap: KeyAliasMap\n private _keyBindings: ConsoleKeyBinding[]\n private _mergedKeyBindings: ConsoleKeyBinding[]\n private _actionHandlers: Map boolean>\n\n private markNeedsRerender(): void {\n this._needsFrameBufferUpdate = true\n this.renderer.requestRender()\n }\n\n private getCopyButtonLabel(): string {\n const copyBindings = this._mergedKeyBindings.filter((b) => b.action === \"copy-selection\")\n const copyBinding = copyBindings[copyBindings.length - 1]\n if (copyBinding) {\n const shortcut = keyBindingToString(copyBinding)\n return `[Copy (${shortcut})]`\n }\n return \"[Copy]\"\n }\n\n private _rgbaInfo: RGBA\n private _rgbaWarn: RGBA\n private _rgbaError: RGBA\n private _rgbaDebug: RGBA\n private _rgbaDefault: RGBA\n private backgroundColor: RGBA\n private _rgbaTitleBar: RGBA\n private _rgbaTitleBarText: RGBA\n private _title: string\n private _rgbaCursor: RGBA\n private _rgbaSelection: RGBA\n private _rgbaCopyButton: RGBA\n\n private _positions: ConsolePosition[] = [\n ConsolePosition.TOP,\n ConsolePosition.RIGHT,\n ConsolePosition.BOTTOM,\n ConsolePosition.LEFT,\n ]\n\n constructor(renderer: CliRenderer, options: ConsoleOptions = {}) {\n super()\n this.renderer = renderer\n this.clock = options.clock ?? new SystemClock()\n this.options = { ...DEFAULT_CONSOLE_OPTIONS, ...options }\n this.keyHandler = this.handleKeyPress.bind(this)\n this._debugModeEnabled = this.options.startInDebugMode\n terminalConsoleCache.setCollectCallerInfo(this._debugModeEnabled)\n\n this._rgbaInfo = parseColor(this.options.colorInfo)\n this._rgbaWarn = parseColor(this.options.colorWarn)\n this._rgbaError = parseColor(this.options.colorError)\n this._rgbaDebug = parseColor(this.options.colorDebug)\n this._rgbaDefault = parseColor(this.options.colorDefault)\n this.backgroundColor = parseColor(this.options.backgroundColor)\n this._rgbaTitleBar = parseColor(this.options.titleBarColor)\n this._rgbaTitleBarText = parseColor(this.options.titleBarTextColor || this.options.colorDefault)\n this._title = this.options.title\n this._rgbaCursor = parseColor(this.options.cursorColor)\n this._rgbaSelection = parseColor(this.options.selectionColor)\n this._rgbaCopyButton = parseColor(this.options.copyButtonColor)\n\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {})\n this._keyBindings = options.keyBindings || []\n this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap)\n this._actionHandlers = this.buildActionHandlers()\n\n this._updateConsoleDimensions()\n this._scrollToBottom(true)\n\n this._entryListener = (logEntry: [Date, LogLevel, any[], CallerInfo | null]) => {\n this._handleNewLog(logEntry)\n }\n terminalConsoleCache.on(\"entry\", this._entryListener)\n\n if (env.SHOW_CONSOLE) {\n this.show()\n }\n }\n\n private buildActionHandlers(): Map boolean> {\n return new Map([\n [\"scroll-up\", () => this.scrollUp()],\n [\"scroll-down\", () => this.scrollDown()],\n [\"scroll-to-top\", () => this.scrollToTop()],\n [\"scroll-to-bottom\", () => this.scrollToBottomAction()],\n [\"position-previous\", () => this.positionPrevious()],\n [\"position-next\", () => this.positionNext()],\n [\"size-increase\", () => this.sizeIncrease()],\n [\"size-decrease\", () => this.sizeDecrease()],\n [\"save-logs\", () => this.saveLogsAction()],\n [\"copy-selection\", () => this.triggerCopyAction()],\n ])\n }\n\n public activate(): void {\n terminalConsoleCache.activate()\n }\n\n public deactivate(): void {\n terminalConsoleCache.deactivate()\n }\n\n // Handles a single new log entry *while the console is visible*\n private _handleNewLog(logEntry: [Date, LogLevel, any[], CallerInfo | null]): void {\n if (!this.isVisible) return\n\n this._allLogEntries.push(logEntry)\n\n if (this._allLogEntries.length > this.options.maxStoredLogs) {\n this._allLogEntries.splice(0, this._allLogEntries.length - this.options.maxStoredLogs)\n }\n\n const newDisplayLines = this._processLogEntry(logEntry)\n this._displayLines.push(...newDisplayLines)\n\n if (this._displayLines.length > this.options.maxDisplayLines) {\n this._displayLines.splice(0, this._displayLines.length - this.options.maxDisplayLines)\n const linesRemoved = this._displayLines.length - this.options.maxDisplayLines\n this.scrollTopIndex = Math.max(0, this.scrollTopIndex - linesRemoved)\n }\n\n if (this.isScrolledToBottom) {\n this._scrollToBottom()\n }\n this.markNeedsRerender()\n }\n\n private _updateConsoleDimensions(termWidth?: number, termHeight?: number): void {\n const width = termWidth ?? this.renderer.width\n const height = termHeight ?? this.renderer.height\n const sizePercent = this.options.sizePercent / 100\n\n switch (this.options.position) {\n case ConsolePosition.TOP:\n this.consoleX = 0\n this.consoleY = 0\n this.consoleWidth = width\n this.consoleHeight = Math.max(1, Math.floor(height * sizePercent))\n break\n case ConsolePosition.BOTTOM:\n this.consoleHeight = Math.max(1, Math.floor(height * sizePercent))\n this.consoleWidth = width\n this.consoleX = 0\n this.consoleY = height - this.consoleHeight\n break\n case ConsolePosition.LEFT:\n this.consoleWidth = Math.max(1, Math.floor(width * sizePercent))\n this.consoleHeight = height\n this.consoleX = 0\n this.consoleY = 0\n break\n case ConsolePosition.RIGHT:\n this.consoleWidth = Math.max(1, Math.floor(width * sizePercent))\n this.consoleHeight = height\n this.consoleY = 0\n this.consoleX = width - this.consoleWidth\n break\n }\n this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, this.consoleHeight - 1))\n }\n\n private handleKeyPress(event: KeyEvent): void {\n if (event.name === \"escape\") {\n this.blur()\n return\n }\n\n const action = getKeyBindingAction(this._keyBindingsMap, event)\n\n if (action) {\n const handler = this._actionHandlers.get(action)\n if (handler) {\n handler()\n return\n }\n }\n }\n\n private scrollUp(): boolean {\n const logAreaHeight = Math.max(1, this.consoleHeight - 1)\n\n if (this.currentLineIndex > 0) {\n this.currentLineIndex--\n this.markNeedsRerender()\n } else if (this.scrollTopIndex > 0) {\n this.scrollTopIndex--\n this.isScrolledToBottom = false\n this.markNeedsRerender()\n }\n return true\n }\n\n private scrollDown(): boolean {\n const displayLineCount = this._displayLines.length\n const logAreaHeight = Math.max(1, this.consoleHeight - 1)\n const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight)\n const canCursorMoveDown =\n this.currentLineIndex < logAreaHeight - 1 && this.scrollTopIndex + this.currentLineIndex < displayLineCount - 1\n\n if (canCursorMoveDown) {\n this.currentLineIndex++\n this.markNeedsRerender()\n } else if (this.scrollTopIndex < maxScrollTop) {\n this.scrollTopIndex++\n this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop\n this.markNeedsRerender()\n }\n return true\n }\n\n private scrollToTop(): boolean {\n if (this.scrollTopIndex > 0 || this.currentLineIndex > 0) {\n this.scrollTopIndex = 0\n this.currentLineIndex = 0\n this.isScrolledToBottom = this._displayLines.length <= Math.max(1, this.consoleHeight - 1)\n this.markNeedsRerender()\n }\n return true\n }\n\n private scrollToBottomAction(): boolean {\n const logAreaHeightForScroll = Math.max(1, this.consoleHeight - 1)\n const maxScrollPossible = Math.max(0, this._displayLines.length - logAreaHeightForScroll)\n if (this.scrollTopIndex < maxScrollPossible || !this.isScrolledToBottom) {\n this._scrollToBottom(true)\n this.markNeedsRerender()\n }\n return true\n }\n\n private positionPrevious(): boolean {\n const currentPositionIndex = this._positions.indexOf(this.options.position)\n const prevIndex = (currentPositionIndex - 1 + this._positions.length) % this._positions.length\n this.options.position = this._positions[prevIndex]\n this.resize(this.renderer.width, this.renderer.height)\n return true\n }\n\n private positionNext(): boolean {\n const currentPositionIndex = this._positions.indexOf(this.options.position)\n const nextIndex = (currentPositionIndex + 1) % this._positions.length\n this.options.position = this._positions[nextIndex]\n this.resize(this.renderer.width, this.renderer.height)\n return true\n }\n\n private sizeIncrease(): boolean {\n this.options.sizePercent = Math.min(100, this.options.sizePercent + 5)\n this.resize(this.renderer.width, this.renderer.height)\n return true\n }\n\n private sizeDecrease(): boolean {\n this.options.sizePercent = Math.max(10, this.options.sizePercent - 5)\n this.resize(this.renderer.width, this.renderer.height)\n return true\n }\n\n private saveLogsAction(): boolean {\n this.saveLogsToFile()\n return true\n }\n\n private triggerCopyAction(): boolean {\n this.triggerCopy()\n return true\n }\n\n private attachStdin(): void {\n if (this.isFocused) return\n this.renderer.keyInput.on(\"keypress\", this.keyHandler)\n this.isFocused = true\n }\n\n private detachStdin(): void {\n if (!this.isFocused) return\n this.renderer.keyInput.off(\"keypress\", this.keyHandler)\n this.isFocused = false\n }\n\n private formatTimestamp(date: Date): string {\n return new Intl.DateTimeFormat(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n }).format(date)\n }\n\n private formatArguments(args: any[]): string {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n const errorProps = arg\n return `Error: ${errorProps.message}\\n` + (errorProps.stack ? `${errorProps.stack}\\n` : \"\")\n }\n if (typeof arg === \"object\" && arg !== null) {\n try {\n return util.inspect(arg, { depth: 2 })\n } catch (e) {\n return String(arg)\n }\n }\n try {\n return util.inspect(arg, { depth: 2 })\n } catch (e) {\n return String(arg)\n }\n })\n .join(\" \")\n }\n\n public resize(width: number, height: number): void {\n this._updateConsoleDimensions(width, height)\n\n if (this.frameBuffer) {\n this.frameBuffer.resize(this.consoleWidth, this.consoleHeight)\n\n const displayLineCount = this._displayLines.length\n const logAreaHeight = Math.max(1, this.consoleHeight - 1)\n const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight)\n this.scrollTopIndex = Math.min(this.scrollTopIndex, maxScrollTop)\n this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop\n const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex)\n this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, visibleLineCount - 1))\n\n if (this.isVisible) {\n this.markNeedsRerender()\n }\n }\n }\n\n public clear(): void {\n terminalConsoleCache.clearConsole()\n this._allLogEntries = []\n this._displayLines = []\n this.markNeedsRerender()\n }\n\n public toggle(): void {\n if (this.isVisible) {\n if (this.isFocused) {\n this.hide()\n } else {\n this.focus()\n }\n } else {\n this.show()\n }\n if (!this.renderer.isRunning) {\n this.renderer.requestRender()\n }\n }\n\n public focus(): void {\n this.attachStdin()\n this._scrollToBottom(true)\n this.markNeedsRerender()\n }\n\n public blur(): void {\n this.detachStdin()\n this.markNeedsRerender()\n }\n\n public show(): void {\n if (!this.isVisible) {\n this.isVisible = true\n this._processCachedLogs()\n terminalConsoleCache.setCachingEnabled(false)\n\n if (!this.frameBuffer) {\n this.frameBuffer = OptimizedBuffer.create(this.consoleWidth, this.consoleHeight, this.renderer.widthMethod, {\n respectAlpha: this.backgroundColor.a < 1,\n id: \"console framebuffer\",\n })\n }\n const logCount = terminalConsoleCache.cachedLogs.length\n const visibleLogLines = Math.min(this.consoleHeight, logCount)\n this.currentLineIndex = Math.max(0, visibleLogLines - 1)\n this.scrollTopIndex = 0\n this._scrollToBottom(true)\n\n this.focus()\n this.markNeedsRerender()\n }\n }\n\n public hide(): void {\n if (this.isVisible) {\n this.isVisible = false\n this.blur()\n terminalConsoleCache.setCachingEnabled(true)\n }\n }\n\n public destroy(): void {\n this.stopAutoScroll()\n this.hide()\n this.deactivate()\n terminalConsoleCache.off(\"entry\", this._entryListener)\n }\n\n public getCachedLogs(): string {\n return terminalConsoleCache.cachedLogs\n .map((logEntry) => logEntry[0].toISOString() + \" \" + logEntry.slice(1).join(\" \"))\n .join(\"\\n\")\n }\n\n private updateFrameBuffer(): void {\n if (!this.frameBuffer) return\n\n this.frameBuffer.clear(this.backgroundColor)\n\n const displayLines = this._displayLines\n const displayLineCount = displayLines.length\n const logAreaHeight = Math.max(1, this.consoleHeight - 1)\n\n // --- Draw Title Bar ---\n this.frameBuffer.fillRect(0, 0, this.consoleWidth, 1, this._rgbaTitleBar)\n const dynamicTitle = `${this._title}${this.isFocused ? \" (Focused)\" : \"\"}`\n const titleX = Math.max(0, Math.floor((this.consoleWidth - dynamicTitle.length) / 2))\n this.frameBuffer.drawText(dynamicTitle, titleX, 0, this._rgbaTitleBarText, this._rgbaTitleBar)\n\n // --- Draw [Copy] Button ---\n const copyLabel = this.getCopyButtonLabel()\n const copyButtonX = this.consoleWidth - copyLabel.length - 1\n if (copyButtonX >= 0) {\n const copyButtonEnabled = this.hasSelection()\n const disabledColor = RGBA.fromInts(100, 100, 100, 255)\n const copyColor = copyButtonEnabled ? this._rgbaCopyButton : disabledColor\n this.frameBuffer.drawText(copyLabel, copyButtonX, 0, copyColor, this._rgbaTitleBar)\n this._copyButtonBounds = { x: copyButtonX, y: 0, width: copyLabel.length, height: 1 }\n } else {\n this._copyButtonBounds = { x: -1, y: -1, width: 0, height: 0 }\n }\n\n const startIndex = this.scrollTopIndex\n const endIndex = Math.min(startIndex + logAreaHeight, displayLineCount)\n const visibleDisplayLines = displayLines.slice(startIndex, endIndex)\n\n let lineY = 1\n for (let i = 0; i < visibleDisplayLines.length; i++) {\n if (lineY >= this.consoleHeight) break\n\n const displayLine = visibleDisplayLines[i]\n const absoluteLineIndex = startIndex + i\n\n let levelColor = this._rgbaDefault\n switch (displayLine.level) {\n case LogLevel.INFO:\n levelColor = this._rgbaInfo\n break\n case LogLevel.WARN:\n levelColor = this._rgbaWarn\n break\n case LogLevel.ERROR:\n levelColor = this._rgbaError\n break\n case LogLevel.DEBUG:\n levelColor = this._rgbaDebug\n break\n }\n\n const linePrefix = displayLine.indent ? \" \".repeat(INDENT_WIDTH) : \"\"\n const textToDraw = displayLine.text\n const textAvailableWidth = this.consoleWidth - 1 - (displayLine.indent ? INDENT_WIDTH : 0)\n const showCursor = this.isFocused && lineY - 1 === this.currentLineIndex\n\n if (showCursor) {\n this.frameBuffer.drawText(\">\", 0, lineY, this._rgbaCursor, this.backgroundColor)\n } else {\n this.frameBuffer.drawText(\" \", 0, lineY, this._rgbaDefault, this.backgroundColor)\n }\n\n const fullText = `${linePrefix}${textToDraw.substring(0, textAvailableWidth)}`\n const selectionRange = this.getLineSelectionRange(absoluteLineIndex)\n\n if (selectionRange) {\n const adjustedStart = Math.max(0, selectionRange.start)\n const adjustedEnd = Math.min(fullText.length, selectionRange.end)\n\n if (adjustedStart > 0) {\n this.frameBuffer.drawText(fullText.substring(0, adjustedStart), 1, lineY, levelColor)\n }\n\n if (adjustedStart < adjustedEnd) {\n this.frameBuffer.fillRect(1 + adjustedStart, lineY, adjustedEnd - adjustedStart, 1, this._rgbaSelection)\n this.frameBuffer.drawText(\n fullText.substring(adjustedStart, adjustedEnd),\n 1 + adjustedStart,\n lineY,\n levelColor,\n this._rgbaSelection,\n )\n }\n\n if (adjustedEnd < fullText.length) {\n this.frameBuffer.drawText(fullText.substring(adjustedEnd), 1 + adjustedEnd, lineY, levelColor)\n }\n } else {\n this.frameBuffer.drawText(fullText, 1, lineY, levelColor)\n }\n\n lineY++\n }\n }\n\n public renderToBuffer(buffer: OptimizedBuffer): void {\n if (!this.isVisible || !this.frameBuffer) return\n\n if (this._needsFrameBufferUpdate) {\n this.updateFrameBuffer()\n this._needsFrameBufferUpdate = false\n }\n\n buffer.drawFrameBuffer(this.consoleX, this.consoleY, this.frameBuffer)\n }\n\n public setDebugMode(enabled: boolean): void {\n this._debugModeEnabled = enabled\n terminalConsoleCache.setCollectCallerInfo(enabled)\n if (this.isVisible) {\n this.markNeedsRerender()\n }\n }\n\n public toggleDebugMode(): void {\n this.setDebugMode(!this._debugModeEnabled)\n }\n\n public set keyBindings(bindings: ConsoleKeyBinding[]) {\n this._keyBindings = bindings\n this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, bindings)\n this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap)\n this.markNeedsRerender()\n }\n\n public set keyAliasMap(aliases: KeyAliasMap) {\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases)\n this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap)\n this.markNeedsRerender()\n }\n\n public set onCopySelection(callback: ((text: string) => void) | undefined) {\n this.options.onCopySelection = callback\n }\n\n public get onCopySelection(): ((text: string) => void) | undefined {\n return this.options.onCopySelection\n }\n\n private _scrollToBottom(forceCursorToLastLine: boolean = false): void {\n const displayLineCount = this._displayLines.length\n const logAreaHeight = Math.max(1, this.consoleHeight - 1)\n const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight)\n this.scrollTopIndex = maxScrollTop\n this.isScrolledToBottom = true\n\n const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex)\n if (forceCursorToLastLine || this.currentLineIndex >= visibleLineCount) {\n this.currentLineIndex = Math.max(0, visibleLineCount - 1)\n }\n }\n\n private _processLogEntry(logEntry: [Date, LogLevel, any[], CallerInfo | null]): DisplayLine[] {\n const [date, level, args, callerInfo] = logEntry\n const displayLines: DisplayLine[] = []\n\n const timestamp = this.formatTimestamp(date)\n const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : \"unknown\"\n const prefix = `[${timestamp}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : \"\") + \" \"\n\n const formattedArgs = this.formatArguments(args)\n const initialLines = formattedArgs.split(\"\\n\")\n\n for (let i = 0; i < initialLines.length; i++) {\n const lineText = initialLines[i]\n const isFirstLineOfEntry = i === 0\n const availableWidth = this.consoleWidth - 1 - (isFirstLineOfEntry ? 0 : INDENT_WIDTH)\n const linePrefix = isFirstLineOfEntry ? prefix : \" \".repeat(INDENT_WIDTH)\n const textToWrap = isFirstLineOfEntry ? linePrefix + lineText : lineText\n\n let currentPos = 0\n while (currentPos < textToWrap.length || (isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0)) {\n const segment = textToWrap.substring(currentPos, currentPos + availableWidth)\n const isFirstSegmentOfLine = currentPos === 0\n\n displayLines.push({\n text: isFirstSegmentOfLine && !isFirstLineOfEntry ? linePrefix + segment : segment,\n level: level,\n indent: !isFirstLineOfEntry || !isFirstSegmentOfLine,\n })\n\n currentPos += availableWidth\n if (isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0) break\n }\n }\n\n return displayLines\n }\n\n private _processCachedLogs(): void {\n const logsToProcess = [...terminalConsoleCache.cachedLogs]\n terminalConsoleCache.clearConsole()\n\n this._allLogEntries.push(...logsToProcess)\n\n if (this._allLogEntries.length > this.options.maxStoredLogs) {\n this._allLogEntries.splice(0, this._allLogEntries.length - this.options.maxStoredLogs)\n }\n\n for (const logEntry of logsToProcess) {\n const processed = this._processLogEntry(logEntry)\n this._displayLines.push(...processed)\n }\n\n if (this._displayLines.length > this.options.maxDisplayLines) {\n this._displayLines.splice(0, this._displayLines.length - this.options.maxDisplayLines)\n }\n }\n\n private hasSelection(): boolean {\n if (this._selectionStart === null || this._selectionEnd === null) return false\n\n return this._selectionStart.line !== this._selectionEnd.line || this._selectionStart.col !== this._selectionEnd.col\n }\n\n private normalizeSelection(): ConsoleSelection | null {\n if (!this._selectionStart || !this._selectionEnd) return null\n\n const start = this._selectionStart\n const end = this._selectionEnd\n\n const startBeforeEnd = start.line < end.line || (start.line === end.line && start.col <= end.col)\n\n if (startBeforeEnd) {\n return {\n startLine: start.line,\n startCol: start.col,\n endLine: end.line,\n endCol: end.col,\n }\n } else {\n return {\n startLine: end.line,\n startCol: end.col,\n endLine: start.line,\n endCol: start.col,\n }\n }\n }\n\n private getSelectedText(): string {\n const selection = this.normalizeSelection()\n if (!selection) return \"\"\n\n const lines: string[] = []\n for (let i = selection.startLine; i <= selection.endLine; i++) {\n if (i < 0 || i >= this._displayLines.length) continue\n const line = this._displayLines[i]\n const linePrefix = line.indent ? \" \".repeat(INDENT_WIDTH) : \"\"\n const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0)\n const fullText = linePrefix + line.text.substring(0, textAvailableWidth)\n let text = fullText\n\n if (i === selection.startLine && i === selection.endLine) {\n text = fullText.substring(selection.startCol, selection.endCol)\n } else if (i === selection.startLine) {\n text = fullText.substring(selection.startCol)\n } else if (i === selection.endLine) {\n text = fullText.substring(0, selection.endCol)\n }\n\n lines.push(text)\n }\n\n return lines.join(\"\\n\")\n }\n\n private clearSelection(): void {\n this._selectionStart = null\n this._selectionEnd = null\n this._isDragging = false\n this.stopAutoScroll()\n }\n\n private stopAutoScroll(): void {\n if (this._autoScrollInterval !== null) {\n this.clock.clearInterval(this._autoScrollInterval)\n this._autoScrollInterval = null\n }\n }\n\n private startAutoScroll(direction: \"up\" | \"down\"): void {\n this.stopAutoScroll()\n this._autoScrollInterval = this.clock.setInterval(() => {\n if (direction === \"up\") {\n if (this.scrollTopIndex > 0) {\n this.scrollTopIndex--\n this.isScrolledToBottom = false\n if (this._selectionEnd) {\n this._selectionEnd = {\n line: this.scrollTopIndex,\n col: this._selectionEnd.col,\n }\n }\n this.markNeedsRerender()\n } else {\n this.stopAutoScroll()\n }\n } else {\n const displayLineCount = this._displayLines.length\n const logAreaHeight = Math.max(1, this.consoleHeight - 1)\n const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight)\n if (this.scrollTopIndex < maxScrollTop) {\n this.scrollTopIndex++\n this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop\n if (this._selectionEnd) {\n const maxLine = this.scrollTopIndex + logAreaHeight - 1\n this._selectionEnd = {\n line: Math.min(maxLine, displayLineCount - 1),\n col: this._selectionEnd.col,\n }\n }\n this.markNeedsRerender()\n } else {\n this.stopAutoScroll()\n }\n }\n }, 50)\n }\n\n private triggerCopy(): void {\n if (!this.hasSelection()) return\n const text = this.getSelectedText()\n if (text && this.options.onCopySelection) {\n try {\n this.options.onCopySelection(text)\n } catch {}\n this.clearSelection()\n this.markNeedsRerender()\n }\n }\n\n private getLineSelectionRange(lineIndex: number): { start: number; end: number } | null {\n const selection = this.normalizeSelection()\n if (!selection) return null\n\n if (lineIndex < selection.startLine || lineIndex > selection.endLine) {\n return null\n }\n\n const line = this._displayLines[lineIndex]\n if (!line) return null\n\n const linePrefix = line.indent ? \" \".repeat(INDENT_WIDTH) : \"\"\n const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0)\n const fullTextLength = linePrefix.length + Math.min(line.text.length, textAvailableWidth)\n\n let start = 0\n let end = fullTextLength\n\n if (lineIndex === selection.startLine) {\n start = Math.max(0, selection.startCol)\n }\n if (lineIndex === selection.endLine) {\n end = Math.min(fullTextLength, selection.endCol)\n }\n\n if (start >= end) return null\n return { start, end }\n }\n\n public handleMouse(event: MouseEvent): boolean {\n if (!this.isVisible) return false\n\n const localX = event.x - this.consoleX\n const localY = event.y - this.consoleY\n\n if (localX < 0 || localX >= this.consoleWidth || localY < 0 || localY >= this.consoleHeight) {\n return false\n }\n\n if (event.type === \"scroll\" && event.scroll) {\n if (event.scroll.direction === \"up\") {\n this.scrollUp()\n } else if (event.scroll.direction === \"down\") {\n this.scrollDown()\n }\n return true\n }\n\n if (localY === 0) {\n if (\n event.type === \"down\" &&\n event.button === 0 &&\n localX >= this._copyButtonBounds.x &&\n localX < this._copyButtonBounds.x + this._copyButtonBounds.width\n ) {\n this.triggerCopy()\n return true\n }\n return true\n }\n\n const lineIndex = this.scrollTopIndex + (localY - 1)\n const colIndex = Math.max(0, localX - 1)\n\n if (event.type === \"down\" && event.button === 0) {\n this.clearSelection()\n this._selectionStart = { line: lineIndex, col: colIndex }\n this._selectionEnd = { line: lineIndex, col: colIndex }\n this._isDragging = true\n this.markNeedsRerender()\n return true\n }\n\n if (event.type === \"drag\" && this._isDragging) {\n this._selectionEnd = { line: lineIndex, col: colIndex }\n\n // Check if drag is at the edge and trigger auto-scroll\n const logAreaHeight = Math.max(1, this.consoleHeight - 1)\n const relativeY = localY - 1 // Subtract 1 for title bar\n\n if (relativeY <= 0) {\n // Dragging at top edge\n this.startAutoScroll(\"up\")\n } else if (relativeY >= logAreaHeight - 1) {\n // Dragging at bottom edge\n this.startAutoScroll(\"down\")\n } else {\n // Not at edge, stop auto-scrolling\n this.stopAutoScroll()\n }\n\n this.markNeedsRerender()\n return true\n }\n\n if (event.type === \"up\") {\n if (this._isDragging) {\n this._selectionEnd = { line: lineIndex, col: colIndex }\n this._isDragging = false\n this.stopAutoScroll()\n this.markNeedsRerender()\n }\n return true\n }\n\n return true\n }\n\n public get visible(): boolean {\n return this.isVisible\n }\n\n public get bounds(): { x: number; y: number; width: number; height: number } {\n return {\n x: this.consoleX,\n y: this.consoleY,\n width: this.consoleWidth,\n height: this.consoleHeight,\n }\n }\n\n private saveLogsToFile(): void {\n try {\n const timestamp = Date.now()\n const filename = `_console_${timestamp}.log`\n const filepath = path.join(process.cwd(), filename)\n\n const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs]\n\n const logLines: string[] = []\n\n for (const [date, level, args, callerInfo] of allLogEntries) {\n const timestampStr = this.formatTimestamp(date)\n const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : \"unknown\"\n const prefix = `[${timestampStr}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : \"\") + \" \"\n const formattedArgs = this.formatArguments(args)\n logLines.push(prefix + formattedArgs)\n }\n\n const content = logLines.join(\"\\n\")\n fs.writeFileSync(filepath, content, \"utf8\")\n\n console.info(`Console logs saved to: ${filename}`)\n } catch (error) {\n console.error(`Failed to save console logs:`, error)\n }\n }\n}\n", + "import { Writable } from \"stream\"\nimport { EventEmitter } from \"events\"\n\nexport type CapturedOutput = {\n stream: \"stdout\" | \"stderr\"\n output: string\n}\n\nexport class Capture extends EventEmitter {\n // TODO: Cache could rather be a buffer to avoid join()?\n private output: CapturedOutput[] = []\n\n constructor() {\n super()\n }\n\n get size(): number {\n return this.output.length\n }\n\n write(stream: \"stdout\" | \"stderr\", data: string): void {\n this.output.push({ stream, output: data })\n this.emit(\"write\", stream, data)\n }\n\n claimOutput() {\n const output = this.output.map((o) => o.output).join(\"\")\n this.clear()\n return output\n }\n\n private clear(): void {\n this.output = []\n }\n}\n\nexport class CapturedWritableStream extends Writable {\n public isTTY: boolean = true\n public columns: number = process.stdout.columns || 80\n public rows: number = process.stdout.rows || 24\n\n constructor(\n private stream: \"stdout\" | \"stderr\",\n private capture: Capture,\n ) {\n super()\n }\n\n _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void {\n const data = chunk.toString()\n this.capture.write(this.stream, data)\n callback()\n }\n\n getColorDepth(): number {\n return process.stdout.getColorDepth?.() || 8\n }\n}\n", + "export interface KeyBindingLike {\n name: string\n ctrl?: boolean\n shift?: boolean\n meta?: boolean\n super?: boolean\n}\n\nexport interface KeyBinding extends KeyBindingLike {\n action: Action\n}\n\nexport interface KeyBindingLookup extends KeyBindingLike {\n // Kitty's base-layout codepoint as a Unicode number. Example: 99 means \"c\".\n baseCode?: number\n}\n\nexport type KeyAliasMap = Record\n\nexport const defaultKeyAliases: KeyAliasMap = {\n enter: \"return\",\n esc: \"escape\",\n kp0: \"0\",\n kp1: \"1\",\n kp2: \"2\",\n kp3: \"3\",\n kp4: \"4\",\n kp5: \"5\",\n kp6: \"6\",\n kp7: \"7\",\n kp8: \"8\",\n kp9: \"9\",\n kpdecimal: \".\",\n kpdivide: \"/\",\n kpmultiply: \"*\",\n kpminus: \"-\",\n kpplus: \"+\",\n kpenter: \"enter\",\n kpequal: \"=\",\n kpseparator: \",\",\n kpleft: \"left\",\n kpright: \"right\",\n kpup: \"up\",\n kpdown: \"down\",\n kppageup: \"pageup\",\n kppagedown: \"pagedown\",\n kphome: \"home\",\n kpend: \"end\",\n kpinsert: \"insert\",\n kpdelete: \"delete\",\n}\n\nexport function mergeKeyAliases(defaults: KeyAliasMap, custom: KeyAliasMap): KeyAliasMap {\n return { ...defaults, ...custom }\n}\n\nexport function mergeKeyBindings(\n defaults: KeyBinding[],\n custom: KeyBinding[],\n): KeyBinding[] {\n const map = new Map>()\n for (const binding of defaults) {\n const key = getKeyBindingKey(binding)\n map.set(key, binding)\n }\n for (const binding of custom) {\n const key = getKeyBindingKey(binding)\n map.set(key, binding)\n }\n return Array.from(map.values())\n}\n\nexport function getKeyBindingKey(binding: KeyBindingLike): string {\n return `${binding.name}:${binding.ctrl ? 1 : 0}:${binding.shift ? 1 : 0}:${binding.meta ? 1 : 0}:${binding.super ? 1 : 0}`\n}\n\n// `baseCode` is Kitty's \"base layout codepoint\": the character for the same\n// physical key on the keyboard's base layout. Example: an event may arrive as\n// `name: \"ㅊ\", baseCode: 99`, where `99` is Unicode `c`. We normalize that\n// numeric codepoint to the key names we store in key maps so Ctrl+ㅊ can still\n// match a Ctrl+C binding.\nfunction getBaseCodeKeyName(baseCode: number | undefined): string | undefined {\n if (baseCode === undefined || baseCode < 32 || baseCode === 127) {\n return undefined\n }\n\n try {\n const name = String.fromCodePoint(baseCode)\n\n if (name.length === 1 && name >= \"A\" && name <= \"Z\") {\n return name.toLowerCase()\n }\n\n return name\n } catch {\n return undefined\n }\n}\n\n// Return every lookup key that can represent this event. We try the parsed\n// name first, then the base-layout key when Kitty provides one. That keeps\n// direct character bindings precise, and still lets physical-layout\n// shortcuts resolve.\nexport function getKeyBindingKeys(binding: KeyBindingLookup): string[] {\n const names = new Set([binding.name])\n const baseCodeName = getBaseCodeKeyName(binding.baseCode)\n\n if (baseCodeName) {\n names.add(baseCodeName)\n }\n\n return [...names].map((name) => getKeyBindingKey({ ...binding, name }))\n}\n\nexport function getKeyBindingAction(\n map: Map,\n binding: KeyBindingLookup,\n): Action | undefined {\n for (const key of getKeyBindingKeys(binding)) {\n const action = map.get(key)\n\n if (action !== undefined) {\n return action\n }\n }\n\n return undefined\n}\n\nexport function matchesKeyBinding(binding: KeyBindingLookup, match: KeyBindingLike): boolean {\n const matchKey = getKeyBindingKey(match)\n\n return getKeyBindingKeys(binding).includes(matchKey)\n}\n\nexport function buildKeyBindingsMap(\n bindings: KeyBinding[],\n aliasMap?: KeyAliasMap,\n): Map {\n const map = new Map()\n const aliases = aliasMap || {}\n\n for (const binding of bindings) {\n const key = getKeyBindingKey(binding)\n map.set(key, binding.action)\n }\n\n // Add aliased versions of all bindings\n for (const binding of bindings) {\n const normalizedName = aliases[binding.name] || binding.name\n if (normalizedName !== binding.name) {\n // Create aliased key with normalized name\n const aliasedKey = getKeyBindingKey({ ...binding, name: normalizedName })\n map.set(aliasedKey, binding.action)\n }\n }\n\n return map\n}\n\n/**\n * Converts a key binding to a human-readable string representation\n * @param binding The key binding to stringify\n * @returns A string like \"ctrl+shift+y\" or just \"escape\"\n * @example\n * keyBindingToString({ name: \"y\", ctrl: true, shift: true }) // \"ctrl+shift+y\"\n * keyBindingToString({ name: \"escape\" }) // \"escape\"\n * keyBindingToString({ name: \"c\", ctrl: true }) // \"ctrl+c\"\n * keyBindingToString({ name: \"s\", super: true }) // \"super+s\"\n */\nexport function keyBindingToString(binding: KeyBinding): string {\n const parts: string[] = []\n\n if (binding.ctrl) parts.push(\"ctrl\")\n if (binding.shift) parts.push(\"shift\")\n if (binding.meta) parts.push(\"meta\")\n if (binding.super) parts.push(\"super\")\n\n parts.push(binding.name)\n\n return parts.join(\"+\")\n}\n", + "import { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport { convertGlobalToLocalSelection, Selection, type LocalSelectionBounds } from \"../lib/selection.js\"\nimport { EditBuffer, type LogicalCursor } from \"../edit-buffer.js\"\nimport { EditorView, type VisualCursor } from \"../editor-view.js\"\nimport { RGBA, parseColor } from \"../lib/RGBA.js\"\nimport type { RenderContext, Highlight, CursorStyleOptions, LineInfoProvider, LineInfo } from \"../types.js\"\nimport type { OptimizedBuffer } from \"../buffer.js\"\nimport { MeasureMode } from \"../yoga.js\"\nimport type { SyntaxStyle } from \"../syntax-style.js\"\n\nconst BrandedEditBufferRenderable: unique symbol = Symbol.for(\"@opentui/core/EditBufferRenderable\")\n\nexport type EditorCapture = \"escape\" | \"navigate\" | \"submit\" | \"tab\"\n\nexport interface EditorTraits {\n capture?: readonly EditorCapture[]\n suspend?: boolean\n status?: string\n}\n\nexport enum EditBufferRenderableEvents {\n TRAITS_CHANGED = \"traits-changed\",\n}\n\nfunction sameCapture(a?: readonly EditorCapture[], b?: readonly EditorCapture[]) {\n if (a === b) return true\n if (!a || !b) return !a && !b\n if (a.length !== b.length) return false\n return a.every((item, i) => item === b[i])\n}\n\nfunction sameTraits(a: EditorTraits, b: EditorTraits) {\n return a.suspend === b.suspend && a.status === b.status && sameCapture(a.capture, b.capture)\n}\n\nexport function isEditBufferRenderable(obj: unknown): obj is EditBufferRenderable {\n return !!(obj && typeof obj === \"object\" && BrandedEditBufferRenderable in obj)\n}\n\nexport interface CursorChangeEvent {\n line: number\n visualColumn: number\n}\n\nexport interface ContentChangeEvent {\n // No payload - use getText() to retrieve content if needed\n}\n\nexport interface EditBufferOptions extends RenderableOptions {\n textColor?: string | RGBA\n backgroundColor?: string | RGBA\n selectionBg?: string | RGBA\n selectionFg?: string | RGBA\n selectable?: boolean\n attributes?: number\n wrapMode?: \"none\" | \"char\" | \"word\"\n scrollMargin?: number\n scrollSpeed?: number\n showCursor?: boolean\n cursorColor?: string | RGBA\n cursorStyle?: CursorStyleOptions\n syntaxStyle?: SyntaxStyle\n tabIndicator?: string | number\n tabIndicatorColor?: string | RGBA\n onCursorChange?: (event: CursorChangeEvent) => void\n onContentChange?: (event: ContentChangeEvent) => void\n}\n\nexport abstract class EditBufferRenderable extends Renderable implements LineInfoProvider {\n [BrandedEditBufferRenderable] = true\n protected _focusable: boolean = true\n public selectable: boolean = true\n private _traits: EditorTraits = {}\n\n protected _textColor: RGBA\n protected _backgroundColor: RGBA\n protected _defaultAttributes: number\n protected _selectionBg: RGBA | undefined\n protected _selectionFg: RGBA | undefined\n protected _wrapMode: \"none\" | \"char\" | \"word\" = \"word\"\n protected _scrollMargin: number = 0.2\n protected _showCursor: boolean = true\n protected _cursorColor: RGBA\n protected _cursorStyle: CursorStyleOptions\n protected lastLocalSelection: LocalSelectionBounds | null = null\n protected _tabIndicator?: string | number\n protected _tabIndicatorColor?: RGBA\n\n private _cursorChangeListener: ((event: CursorChangeEvent) => void) | undefined = undefined\n private _contentChangeListener: ((event: ContentChangeEvent) => void) | undefined = undefined\n\n private _autoScrollVelocity: number = 0\n private _autoScrollAccumulator: number = 0\n private _scrollSpeed: number = 16\n private _keyboardSelectionActive: boolean = false\n\n public readonly editBuffer: EditBuffer\n public readonly editorView: EditorView\n\n protected _defaultOptions = {\n textColor: RGBA.fromValues(1, 1, 1, 1),\n backgroundColor: \"transparent\",\n selectionBg: undefined,\n selectionFg: undefined,\n selectable: true,\n attributes: 0,\n wrapMode: \"word\" as \"none\" | \"char\" | \"word\",\n scrollMargin: 0.2,\n scrollSpeed: 16,\n showCursor: true,\n cursorColor: RGBA.fromValues(1, 1, 1, 1),\n cursorStyle: {\n style: \"block\",\n blinking: true,\n },\n tabIndicator: undefined,\n tabIndicatorColor: undefined,\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: EditBufferOptions) {\n super(ctx, options)\n\n this._textColor = parseColor(options.textColor ?? this._defaultOptions.textColor)\n this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor)\n this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes\n this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg\n this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg\n this.selectable = options.selectable ?? this._defaultOptions.selectable\n this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode\n this._scrollMargin = options.scrollMargin ?? this._defaultOptions.scrollMargin\n this._scrollSpeed = options.scrollSpeed ?? this._defaultOptions.scrollSpeed\n this._showCursor = options.showCursor ?? this._defaultOptions.showCursor\n this._cursorColor = parseColor(options.cursorColor ?? this._defaultOptions.cursorColor)\n this._cursorStyle = options.cursorStyle ?? this._defaultOptions.cursorStyle\n this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator\n this._tabIndicatorColor = options.tabIndicatorColor\n ? parseColor(options.tabIndicatorColor)\n : this._defaultOptions.tabIndicatorColor\n\n this.editBuffer = EditBuffer.create(this._ctx.widthMethod)\n this.editorView = EditorView.create(this.editBuffer, this.width || 80, this.height || 24)\n\n this.editorView.setWrapMode(this._wrapMode)\n this.editorView.setScrollMargin(this._scrollMargin)\n\n this.editBuffer.setDefaultFg(this._textColor)\n this.editBuffer.setDefaultBg(this._backgroundColor)\n this.editBuffer.setDefaultAttributes(this._defaultAttributes)\n\n if (options.syntaxStyle) {\n this.editBuffer.setSyntaxStyle(options.syntaxStyle)\n }\n\n if (this._tabIndicator !== undefined) {\n this.editorView.setTabIndicator(this._tabIndicator)\n }\n if (this._tabIndicatorColor !== undefined) {\n this.editorView.setTabIndicatorColor(this._tabIndicatorColor)\n }\n\n this.setupMeasureFunc()\n this.setupEventListeners(options)\n }\n\n public get lineInfo(): LineInfo {\n return this.editorView.getLogicalLineInfo()\n }\n\n private setupEventListeners(options: EditBufferOptions): void {\n this._cursorChangeListener = options.onCursorChange\n this._contentChangeListener = options.onContentChange\n\n this.editBuffer.on(\"cursor-changed\", () => {\n if (this._cursorChangeListener) {\n const cursor = this.editBuffer.getCursorPosition()\n this._cursorChangeListener({\n line: cursor.row,\n visualColumn: cursor.col,\n })\n }\n })\n\n this.editBuffer.on(\"content-changed\", () => {\n this.yogaNode.markDirty()\n this.requestRender()\n this.emit(\"line-info-change\")\n if (this._contentChangeListener) {\n this._contentChangeListener({})\n }\n })\n }\n\n public get lineCount(): number {\n return this.editBuffer.getLineCount()\n }\n\n public get virtualLineCount(): number {\n return this.editorView.getVirtualLineCount()\n }\n\n public get scrollY(): number {\n return this.editorView.getViewport().offsetY\n }\n\n get plainText(): string {\n return this.editBuffer.getText()\n }\n\n get logicalCursor(): LogicalCursor {\n return this.editBuffer.getCursorPosition()\n }\n\n get visualCursor(): VisualCursor {\n return this.editorView.getVisualCursor()\n }\n\n get cursorOffset(): number {\n return this.editorView.getVisualCursor().offset\n }\n\n set cursorOffset(offset: number) {\n this.editorView.setCursorByOffset(offset)\n this.requestRender()\n }\n\n get cursorCharacterOffset(): number | undefined {\n const len = this.plainText.length\n if (len <= 0) return\n\n const cursor = this.logicalCursor\n const offset = this.cursorOffset\n if (offset >= len) {\n if (cursor.col > 0) return len - 1\n return 0\n }\n\n if (this.plainText[offset] === \"\\n\" && cursor.col > 0) {\n return offset - 1\n }\n\n return offset\n }\n\n get textColor(): RGBA {\n return this._textColor\n }\n\n set textColor(value: RGBA | string | undefined) {\n const newColor = parseColor(value ?? this._defaultOptions.textColor)\n if (this._textColor !== newColor) {\n this._textColor = newColor\n this.editBuffer.setDefaultFg(newColor)\n this.requestRender()\n }\n }\n\n get selectionBg(): RGBA | undefined {\n return this._selectionBg\n }\n\n get traits(): EditorTraits {\n return this._traits\n }\n\n set traits(value: EditorTraits) {\n if (sameTraits(this._traits, value)) return\n const prev = this._traits\n this._traits = value\n this.emit(EditBufferRenderableEvents.TRAITS_CHANGED, value, prev)\n }\n\n set selectionBg(value: RGBA | string | undefined) {\n const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg\n if (this._selectionBg !== newColor) {\n this._selectionBg = newColor\n this.refreshSelectionStyle()\n this.requestRender()\n }\n }\n\n get selectionFg(): RGBA | undefined {\n return this._selectionFg\n }\n\n set selectionFg(value: RGBA | string | undefined) {\n const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg\n if (this._selectionFg !== newColor) {\n this._selectionFg = newColor\n this.refreshSelectionStyle()\n this.requestRender()\n }\n }\n\n get backgroundColor(): RGBA {\n return this._backgroundColor\n }\n\n set backgroundColor(value: RGBA | string | undefined) {\n const newColor = parseColor(value ?? this._defaultOptions.backgroundColor)\n if (this._backgroundColor !== newColor) {\n this._backgroundColor = newColor\n this.editBuffer.setDefaultBg(newColor)\n this.requestRender()\n }\n }\n\n get attributes(): number {\n return this._defaultAttributes\n }\n\n set attributes(value: number) {\n if (this._defaultAttributes !== value) {\n this._defaultAttributes = value\n this.editBuffer.setDefaultAttributes(value)\n this.requestRender()\n }\n }\n\n get wrapMode(): \"none\" | \"char\" | \"word\" {\n return this._wrapMode\n }\n\n set wrapMode(value: \"none\" | \"char\" | \"word\") {\n if (this._wrapMode !== value) {\n this._wrapMode = value\n this.editorView.setWrapMode(value)\n this.yogaNode.markDirty()\n this.requestRender()\n }\n }\n\n get showCursor(): boolean {\n return this._showCursor\n }\n\n set showCursor(value: boolean) {\n if (this._showCursor !== value) {\n this._showCursor = value\n if (!value && this._focused) {\n this._ctx.setCursorPosition(0, 0, false)\n }\n this.requestRender()\n }\n }\n\n get cursorColor(): RGBA {\n return this._cursorColor\n }\n\n set cursorColor(value: RGBA | string) {\n const newColor = parseColor(value)\n if (this._cursorColor !== newColor) {\n this._cursorColor = newColor\n if (this._focused) {\n this.requestRender()\n }\n }\n }\n\n get cursorStyle(): CursorStyleOptions {\n return this._cursorStyle\n }\n\n set cursorStyle(style: CursorStyleOptions) {\n const newStyle = style\n if (this.cursorStyle.style !== newStyle.style || this.cursorStyle.blinking !== newStyle.blinking) {\n this._cursorStyle = newStyle\n if (this._focused) {\n this.requestRender()\n }\n }\n }\n\n get tabIndicator(): string | number | undefined {\n return this._tabIndicator\n }\n\n set tabIndicator(value: string | number | undefined) {\n if (this._tabIndicator !== value) {\n this._tabIndicator = value\n if (value !== undefined) {\n this.editorView.setTabIndicator(value)\n }\n this.requestRender()\n }\n }\n\n get tabIndicatorColor(): RGBA | undefined {\n return this._tabIndicatorColor\n }\n\n set tabIndicatorColor(value: RGBA | string | undefined) {\n const newColor = value ? parseColor(value) : undefined\n if (this._tabIndicatorColor !== newColor) {\n this._tabIndicatorColor = newColor\n if (newColor !== undefined) {\n this.editorView.setTabIndicatorColor(newColor)\n }\n this.requestRender()\n }\n }\n\n get scrollSpeed(): number {\n return this._scrollSpeed\n }\n\n set scrollSpeed(value: number) {\n this._scrollSpeed = Math.max(0, value)\n }\n\n protected override onMouseEvent(event: any): void {\n if (event.type === \"scroll\") {\n this.handleScroll(event)\n }\n }\n\n protected handleScroll(event: any): void {\n if (!event.scroll) return\n\n const { direction, delta } = event.scroll\n const viewport = this.editorView.getViewport()\n\n if (direction === \"up\") {\n const newOffsetY = Math.max(0, viewport.offsetY - delta)\n this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true)\n this.requestRender()\n } else if (direction === \"down\") {\n const totalVirtualLines = this.editorView.getTotalVirtualLineCount()\n const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height)\n const newOffsetY = Math.min(viewport.offsetY + delta, maxOffsetY)\n this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true)\n this.requestRender()\n }\n\n if (this._wrapMode === \"none\") {\n if (direction === \"left\") {\n const newOffsetX = Math.max(0, viewport.offsetX - delta)\n this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true)\n this.requestRender()\n } else if (direction === \"right\") {\n const newOffsetX = viewport.offsetX + delta\n this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true)\n this.requestRender()\n }\n }\n }\n\n protected onResize(width: number, height: number): void {\n this.editorView.setViewportSize(width, height)\n }\n\n protected refreshLocalSelection(): boolean {\n if (this.lastLocalSelection) {\n return this.updateLocalSelection(this.lastLocalSelection)\n }\n return false\n }\n\n private updateLocalSelection(localSelection: LocalSelectionBounds | null): boolean {\n if (!localSelection?.isActive) {\n this.editorView.resetLocalSelection()\n return true\n }\n return this.editorView.setLocalSelection(\n localSelection.anchorX,\n localSelection.anchorY,\n localSelection.focusX,\n localSelection.focusY,\n this._selectionBg,\n this._selectionFg,\n false,\n )\n }\n\n shouldStartSelection(x: number, y: number): boolean {\n if (!this.selectable) return false\n\n const localX = x - this.x\n const localY = y - this.y\n\n return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height\n }\n\n onSelectionChanged(selection: Selection | null): boolean {\n const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y)\n this.lastLocalSelection = localSelection\n\n const updateCursor = true\n const followCursor = this._keyboardSelectionActive\n\n let changed: boolean\n if (!localSelection?.isActive) {\n this._keyboardSelectionActive = false\n this.editorView.resetLocalSelection()\n changed = true\n } else if (selection?.isStart) {\n changed = this.editorView.setLocalSelection(\n localSelection.anchorX,\n localSelection.anchorY,\n localSelection.focusX,\n localSelection.focusY,\n this._selectionBg,\n this._selectionFg,\n updateCursor,\n followCursor,\n )\n } else {\n changed = this.editorView.updateLocalSelection(\n localSelection.anchorX,\n localSelection.anchorY,\n localSelection.focusX,\n localSelection.focusY,\n this._selectionBg,\n this._selectionFg,\n updateCursor,\n followCursor,\n )\n }\n\n if (changed && localSelection?.isActive && selection?.isDragging) {\n const viewport = this.editorView.getViewport()\n const focusY = localSelection.focusY\n const scrollMargin = Math.max(1, Math.floor(viewport.height * this._scrollMargin))\n\n if (focusY < scrollMargin) {\n this._autoScrollVelocity = -this._scrollSpeed\n } else if (focusY >= viewport.height - scrollMargin) {\n this._autoScrollVelocity = this._scrollSpeed\n } else {\n this._autoScrollVelocity = 0\n }\n } else {\n this._keyboardSelectionActive = false\n this._autoScrollVelocity = 0\n this._autoScrollAccumulator = 0\n }\n\n if (changed) {\n this.requestRender()\n }\n\n return this.hasSelection()\n }\n\n protected override onUpdate(deltaTime: number): void {\n super.onUpdate(deltaTime)\n\n if (this._autoScrollVelocity !== 0 && this.hasSelection()) {\n const deltaSeconds = deltaTime / 1000\n this._autoScrollAccumulator += this._autoScrollVelocity * deltaSeconds\n\n const linesToScroll = Math.floor(Math.abs(this._autoScrollAccumulator))\n if (linesToScroll > 0) {\n const direction = this._autoScrollVelocity > 0 ? 1 : -1\n const viewport = this.editorView.getViewport()\n const totalVirtualLines = this.editorView.getTotalVirtualLineCount()\n const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height)\n const newOffsetY = Math.max(0, Math.min(viewport.offsetY + direction * linesToScroll, maxOffsetY))\n\n if (newOffsetY !== viewport.offsetY) {\n this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, false)\n\n this._ctx.requestSelectionUpdate()\n }\n\n this._autoScrollAccumulator -= direction * linesToScroll\n }\n }\n }\n\n getSelectedText(): string {\n return this.editorView.getSelectedText()\n }\n\n hasSelection(): boolean {\n return this.editorView.hasSelection()\n }\n\n getSelection(): { start: number; end: number } | null {\n return this.editorView.getSelection()\n }\n\n private refreshSelectionStyle(): void {\n if (this.lastLocalSelection) {\n this.updateLocalSelection(this.lastLocalSelection)\n return\n }\n\n const selection = this.getSelection()\n if (!selection) return\n this.editorView.setSelection(selection.start, selection.end, this._selectionBg, this._selectionFg)\n }\n\n private deleteSelectedText(): void {\n this.editorView.deleteSelectedText()\n this._ctx.clearSelection()\n this.requestRender()\n }\n\n setSelection(start: number, end: number): void {\n this.lastLocalSelection = null\n this.editorView.resetLocalSelection()\n this._ctx.clearSelection()\n this.editorView.setSelection(start, end, this._selectionBg, this._selectionFg)\n this.requestRender()\n }\n\n setSelectionInclusive(start: number, end: number): void {\n this.setSelection(Math.min(start, end), Math.max(start, end) + 1)\n }\n\n clearSelection(): boolean {\n const had = this.hasSelection()\n this.lastLocalSelection = null\n this.editorView.resetSelection()\n this.editorView.resetLocalSelection()\n this._ctx.clearSelection()\n if (had) {\n this.requestRender()\n }\n return had\n }\n\n deleteSelection(): boolean {\n if (!this.hasSelection()) return false\n\n this.lastLocalSelection = null\n this.deleteSelectedText()\n return true\n }\n\n setCursor(row: number, col: number): void {\n this.editBuffer.setCursor(row, col)\n this.requestRender()\n }\n\n public insertChar(char: string): void {\n if (this.hasSelection()) {\n this.deleteSelectedText()\n }\n\n this.editBuffer.insertChar(char)\n this.requestRender()\n }\n\n public insertText(text: string): void {\n if (this.hasSelection()) {\n this.deleteSelectedText()\n }\n\n this.editBuffer.insertText(text)\n this.requestRender()\n }\n\n public deleteChar(): boolean {\n if (this.hasSelection()) {\n this.deleteSelectedText()\n return true\n }\n\n this._ctx.clearSelection()\n this.editBuffer.deleteChar()\n this.requestRender()\n return true\n }\n\n public deleteCharBackward(): boolean {\n if (this.hasSelection()) {\n this.deleteSelectedText()\n return true\n }\n\n this._ctx.clearSelection()\n this.editBuffer.deleteCharBackward()\n this.requestRender()\n return true\n }\n\n public newLine(): boolean {\n this._ctx.clearSelection()\n this.editBuffer.newLine()\n this.requestRender()\n return true\n }\n\n public deleteLine(): boolean {\n this._ctx.clearSelection()\n this.editBuffer.deleteLine()\n this.requestRender()\n return true\n }\n\n public moveCursorLeft(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n\n if (!select && this.hasSelection()) {\n const selection = this.getSelection()!\n this.editBuffer.setCursorByOffset(selection.start)\n this._ctx.clearSelection()\n this.requestRender()\n return true\n }\n\n this.updateSelectionForMovement(select, true)\n this.editBuffer.moveCursorLeft()\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public moveCursorRight(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n\n if (!select && this.hasSelection()) {\n const selection = this.getSelection()!\n const targetOffset = this.cursorOffset === selection.start ? selection.end - 1 : selection.end\n this.editBuffer.setCursorByOffset(targetOffset)\n this._ctx.clearSelection()\n this.requestRender()\n return true\n }\n\n this.updateSelectionForMovement(select, true)\n this.editBuffer.moveCursorRight()\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public moveCursorUp(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n this.editorView.moveUpVisual()\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public moveCursorDown(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n this.editorView.moveDownVisual()\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public gotoLine(line: number): void {\n this.editBuffer.gotoLine(line)\n this.requestRender()\n }\n\n public gotoLineStart(): void {\n this.setCursor(this.logicalCursor.row, 0)\n }\n\n public gotoLineTextEnd(): void {\n const eol = this.editBuffer.getEOL()\n this.setCursor(eol.row, eol.col)\n }\n\n public gotoLineHome(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n const cursor = this.editorView.getCursor()\n if (cursor.col === 0 && cursor.row > 0) {\n this.editBuffer.setCursor(cursor.row - 1, 0)\n const prevLineEol = this.editBuffer.getEOL()\n this.editBuffer.setCursor(prevLineEol.row, prevLineEol.col)\n } else {\n this.editBuffer.setCursor(cursor.row, 0)\n }\n\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public gotoLineEnd(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n const cursor = this.editorView.getCursor()\n const eol = this.editBuffer.getEOL()\n const lineCount = this.editBuffer.getLineCount()\n if (cursor.col === eol.col && cursor.row < lineCount - 1) {\n this.editBuffer.setCursor(cursor.row + 1, 0)\n } else {\n this.editBuffer.setCursor(eol.row, eol.col)\n }\n\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public gotoVisualLineHome(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n const sol = this.editorView.getVisualSOL()\n this.editBuffer.setCursor(sol.logicalRow, sol.logicalCol)\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public gotoVisualLineEnd(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n const eol = this.editorView.getVisualEOL()\n this.editBuffer.setCursor(eol.logicalRow, eol.logicalCol)\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public gotoBufferHome(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n this.editBuffer.setCursor(0, 0)\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public gotoBufferEnd(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n this.editBuffer.gotoLine(999999)\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public selectAll(): boolean {\n this.updateSelectionForMovement(false, true)\n this.editBuffer.setCursor(0, 0)\n return this.gotoBufferEnd({ select: true })\n }\n\n public deleteToLineEnd(): boolean {\n const cursor = this.editorView.getCursor()\n const eol = this.editBuffer.getEOL()\n\n if (eol.col > cursor.col) {\n this.editBuffer.deleteRange(cursor.row, cursor.col, eol.row, eol.col)\n }\n\n this.requestRender()\n return true\n }\n\n public deleteToLineStart(): boolean {\n const cursor = this.editorView.getCursor()\n\n if (cursor.col > 0) {\n this.editBuffer.deleteRange(cursor.row, 0, cursor.row, cursor.col)\n } else if (cursor.row > 0) {\n this.editBuffer.deleteCharBackward()\n }\n\n this.requestRender()\n return true\n }\n\n public undo(): boolean {\n this._ctx.clearSelection()\n this.editBuffer.undo()\n this.requestRender()\n return true\n }\n\n public redo(): boolean {\n this._ctx.clearSelection()\n this.editBuffer.redo()\n this.requestRender()\n return true\n }\n\n public moveWordForward(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n const nextWord = this.editBuffer.getNextWordBoundary()\n this.editBuffer.setCursorByOffset(nextWord.offset)\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public moveWordBackward(options?: { select?: boolean }): boolean {\n const select = options?.select ?? false\n this.updateSelectionForMovement(select, true)\n const prevWord = this.editBuffer.getPrevWordBoundary()\n this.editBuffer.setCursorByOffset(prevWord.offset)\n this.updateSelectionForMovement(select, false)\n this.requestRender()\n return true\n }\n\n public deleteWordForward(): boolean {\n if (this.hasSelection()) {\n this.deleteSelectedText()\n return true\n }\n\n const currentCursor = this.editBuffer.getCursorPosition()\n const nextWord = this.editBuffer.getNextWordBoundary()\n\n if (nextWord.offset > currentCursor.offset) {\n this.editBuffer.deleteRange(currentCursor.row, currentCursor.col, nextWord.row, nextWord.col)\n }\n\n this._ctx.clearSelection()\n this.requestRender()\n return true\n }\n\n public deleteWordBackward(): boolean {\n if (this.hasSelection()) {\n this.deleteSelectedText()\n return true\n }\n\n const currentCursor = this.editBuffer.getCursorPosition()\n const prevWord = this.editBuffer.getPrevWordBoundary()\n\n if (prevWord.offset < currentCursor.offset) {\n this.editBuffer.deleteRange(prevWord.row, prevWord.col, currentCursor.row, currentCursor.col)\n }\n\n this._ctx.clearSelection()\n this.requestRender()\n return true\n }\n\n // Undefined = 0,\n // Exactly = 1,\n // AtMost = 2\n private setupMeasureFunc(): void {\n const measureFunc = (\n width: number,\n widthMode: MeasureMode,\n height: number,\n heightMode: MeasureMode,\n ): { width: number; height: number } => {\n // When widthMode is Undefined, Yoga is asking for the intrinsic/natural width\n // Pass width=0 to measureForDimensions to signal we want max-content (no wrapping)\n // The Zig code treats width=0 with wrap_mode != none as null wrap_width,\n // which triggers no-wrap mode and returns the text's intrinsic width\n let effectiveWidth: number\n if (widthMode === MeasureMode.Undefined || isNaN(width)) {\n effectiveWidth = 0\n } else {\n effectiveWidth = width\n }\n\n const effectiveHeight = isNaN(height) ? 1 : height\n\n const measureResult = this.editorView.measureForDimensions(\n Math.floor(effectiveWidth),\n Math.floor(effectiveHeight),\n )\n\n const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1\n const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1\n\n if (widthMode === MeasureMode.AtMost && this._positionType !== \"absolute\") {\n return {\n width: Math.min(effectiveWidth, measuredWidth),\n height: Math.min(effectiveHeight, measuredHeight),\n }\n }\n\n return {\n width: measuredWidth,\n height: measuredHeight,\n }\n }\n\n this.yogaNode.setMeasureFunc(measureFunc)\n }\n\n render(buffer: OptimizedBuffer, deltaTime: number): void {\n if (!this.visible) return\n if (this.isDestroyed) return\n // Editor rendering/cursor placement reads absolute coordinates multiple\n // times per frame, so it benefits from the same cached screen position.\n const screenX = this._screenX\n const screenY = this._screenY\n\n this.markClean()\n this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num)\n\n this.renderSelf(buffer)\n this.renderCursor(buffer)\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n buffer.drawEditorView(this.editorView, this._screenX, this._screenY)\n }\n\n protected renderCursor(buffer: OptimizedBuffer): void {\n if (!this._showCursor || !this._focused) return\n\n const visualCursor = this.editorView.getVisualCursor()\n const screenX = this._screenX\n const screenY = this._screenY\n\n const cursorX = screenX + visualCursor.visualCol + 1 // +1 for 1-based terminal coords\n const cursorY = screenY + visualCursor.visualRow + 1 // +1 for 1-based terminal coords\n\n this._ctx.setCursorPosition(cursorX, cursorY, true)\n this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor })\n }\n\n public focus(): void {\n super.focus()\n this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor })\n this.requestRender()\n }\n\n public blur(): void {\n super.blur()\n this._ctx.setCursorPosition(0, 0, false)\n this.requestRender()\n }\n\n protected onRemove(): void {\n if (this._focused) {\n this._ctx.setCursorPosition(0, 0, false)\n }\n }\n\n override destroy(): void {\n if (this.isDestroyed) return\n\n this.traits = {}\n\n if (this._focused) {\n this._ctx.setCursorPosition(0, 0, false)\n // Manually blur to unhook event handlers BEFORE setting destroyed flag\n // This prevents the guard in super.destroy() from skipping blur()\n this.blur()\n }\n\n // Destroy dependent resources in correct order BEFORE calling super\n // EditorView depends on EditBuffer, so destroy it first\n this.editorView.destroy()\n this.editBuffer.destroy()\n\n // Finally clean up parent resources\n // Note: super.destroy() will try to blur() again, but blur() has guards to prevent double-blur\n super.destroy()\n }\n\n public set onCursorChange(handler: ((event: CursorChangeEvent) => void) | undefined) {\n this._cursorChangeListener = handler\n }\n\n public get onCursorChange(): ((event: CursorChangeEvent) => void) | undefined {\n return this._cursorChangeListener\n }\n\n public set onContentChange(handler: ((event: ContentChangeEvent) => void) | undefined) {\n this._contentChangeListener = handler\n }\n\n public get onContentChange(): ((event: ContentChangeEvent) => void) | undefined {\n return this._contentChangeListener\n }\n\n get syntaxStyle(): SyntaxStyle | null {\n return this.editBuffer.getSyntaxStyle()\n }\n\n set syntaxStyle(style: SyntaxStyle | null) {\n this.editBuffer.setSyntaxStyle(style)\n this.requestRender()\n }\n\n public addHighlight(lineIdx: number, highlight: Highlight): void {\n this.editBuffer.addHighlight(lineIdx, highlight)\n this.requestRender()\n }\n\n public addHighlightByCharRange(highlight: Highlight): void {\n this.editBuffer.addHighlightByCharRange(highlight)\n this.requestRender()\n }\n\n public removeHighlightsByRef(hlRef: number): void {\n this.editBuffer.removeHighlightsByRef(hlRef)\n this.requestRender()\n }\n\n public clearLineHighlights(lineIdx: number): void {\n this.editBuffer.clearLineHighlights(lineIdx)\n this.requestRender()\n }\n\n public clearAllHighlights(): void {\n this.editBuffer.clearAllHighlights()\n this.requestRender()\n }\n\n public getLineHighlights(lineIdx: number): Array {\n return this.editBuffer.getLineHighlights(lineIdx)\n }\n\n /**\n * Set text and completely reset the buffer state (clears history, resets add_buffer).\n * Use this for initial text setting or when you want a clean slate.\n */\n public setText(text: string): void {\n this.editBuffer.setText(text)\n this.yogaNode.markDirty()\n this.requestRender()\n }\n\n /**\n * Replace text while preserving undo history (creates an undo point).\n * Use this when you want the setText operation to be undoable.\n */\n public replaceText(text: string): void {\n this.editBuffer.replaceText(text)\n this.yogaNode.markDirty()\n this.requestRender()\n }\n\n public clear(): void {\n this.editBuffer.clear()\n this.editBuffer.clearAllHighlights()\n this.yogaNode.markDirty()\n this.requestRender()\n }\n\n public deleteRange(startLine: number, startCol: number, endLine: number, endCol: number): void {\n this.editBuffer.deleteRange(startLine, startCol, endLine, endCol)\n this.yogaNode.markDirty()\n this.requestRender()\n }\n\n public getTextRange(startOffset: number, endOffset: number): string {\n return this.editBuffer.getTextRange(startOffset, endOffset)\n }\n\n public getTextRangeByCoords(startRow: number, startCol: number, endRow: number, endCol: number): string {\n return this.editBuffer.getTextRangeByCoords(startRow, startCol, endRow, endCol)\n }\n\n protected updateSelectionForMovement(shiftPressed: boolean, isBeforeMovement: boolean): void {\n if (!this.selectable) return\n\n if (!shiftPressed) {\n this._keyboardSelectionActive = false\n this._ctx.clearSelection()\n return\n }\n\n this._keyboardSelectionActive = true\n\n const visualCursor = this.editorView.getVisualCursor()\n const cursorX = this.x + visualCursor.visualCol\n const cursorY = this.y + visualCursor.visualRow\n\n if (isBeforeMovement) {\n if (!this._ctx.hasSelection) {\n this._ctx.startSelection(this, cursorX, cursorY)\n }\n return\n }\n\n this._ctx.updateSelection(this, cursorX, cursorY, { finishDragging: true })\n }\n}\n", + "export const ANSI = {\n switchToAlternateScreen: \"\\x1b[?1049h\",\n switchToMainScreen: \"\\x1b[?1049l\",\n reset: \"\\x1b[0m\",\n resetScrollRegion: \"\\x1b[r\",\n home: \"\\x1b[H\",\n clearScreen: \"\\x1b[2J\",\n clearSavedLines: \"\\x1b[3J\",\n\n scrollDown: (lines: number) => `\\x1b[${lines}T`,\n scrollUp: (lines: number) => `\\x1b[${lines}S`,\n\n moveCursor: (row: number, col: number) => `\\x1b[${row};${col}H`,\n moveCursorAndClear: (row: number, col: number) => `\\x1b[${row};${col}H\\x1b[J`,\n\n setRgbBackground: (r: number, g: number, b: number) => `\\x1b[48;2;${r};${g};${b}m`,\n resetBackground: \"\\x1b[49m\",\n\n // Bracketed paste mode\n bracketedPasteStart: \"\\u001b[200~\",\n bracketedPasteEnd: \"\\u001b[201~\",\n}\n", + "// OSC 52 clipboard support for terminal applications.\n// Delegates to native Zig implementation for ANSI sequence generation.\n\nimport type { RendererHandle, RenderLib } from \"../zig.js\"\n\nexport enum ClipboardTarget {\n Clipboard = 0,\n Primary = 1,\n Secondary = 2,\n Query = 3,\n}\n\nexport function encodeOsc52Payload(text: string, encoder: TextEncoder = new TextEncoder()): Uint8Array {\n const base64 = Buffer.from(text).toString(\"base64\")\n return encoder.encode(base64)\n}\n\nexport class Clipboard {\n private lib: RenderLib\n private rendererPtr: RendererHandle\n\n constructor(lib: RenderLib, rendererPtr: RendererHandle) {\n this.lib = lib\n this.rendererPtr = rendererPtr\n }\n\n public copyToClipboardOSC52(text: string, target: ClipboardTarget = ClipboardTarget.Clipboard): boolean {\n if (!this.isOsc52Supported()) {\n return false\n }\n const payload = encodeOsc52Payload(text, this.lib.encoder)\n return this.lib.copyToClipboardOSC52(this.rendererPtr, target, payload)\n }\n\n public clearClipboardOSC52(target: ClipboardTarget = ClipboardTarget.Clipboard): boolean {\n if (!this.isOsc52Supported()) {\n return false\n }\n return this.lib.clearClipboardOSC52(this.rendererPtr, target)\n }\n\n public isOsc52Supported(): boolean {\n const caps = this.lib.getTerminalCapabilities(this.rendererPtr)\n return Boolean(caps?.osc52)\n }\n}\n", + "import { ANSI } from \"./ansi.js\"\nimport { Renderable, RootRenderable } from \"./Renderable.js\"\nimport { BoxRenderable } from \"./renderables/Box.js\"\nimport { CodeRenderable } from \"./renderables/Code.js\"\nimport { TextRenderable } from \"./renderables/Text.js\"\nimport {\n DebugOverlayCorner,\n type CursorStyleOptions,\n type MousePointerStyle,\n type RenderContext,\n type TerminalCapabilities,\n type ThemeMode,\n type ViewportBounds,\n type WidthMethod,\n} from \"./types.js\"\nimport { RGBA, parseColor, type ColorInput } from \"./lib/RGBA.js\"\nimport { sleep } from \"./platform/runtime.js\"\nimport { OptimizedBuffer } from \"./buffer.js\"\nimport {\n resolveRenderLib,\n type NativeBufferedOutput,\n type NativeRenderStats,\n type RenderLib,\n type RendererHandle,\n} from \"./zig.js\"\nimport { NativeSpanFeed } from \"./NativeSpanFeed.js\"\nimport { TerminalConsole, type ConsoleOptions, capture } from \"./console.js\"\nimport { type MouseEventType, type RawMouseEvent, type ScrollInfo } from \"./lib/parse.mouse.js\"\nimport { Selection } from \"./lib/selection.js\"\nimport { Clipboard, type ClipboardTarget } from \"./lib/clipboard.js\"\nimport { EventEmitter } from \"events\"\nimport { singleton } from \"./lib/singleton.js\"\nimport { getObjectsInViewport } from \"./lib/objects-in-viewport.js\"\nimport { KeyHandler, InternalKeyHandler } from \"./lib/KeyHandler.js\"\nimport { isEditBufferRenderable, type EditBufferRenderable } from \"./renderables/EditBufferRenderable.js\"\nimport { env, registerEnvVar } from \"./lib/env.js\"\nimport { destroyTreeSitterClient } from \"./lib/tree-sitter/index.js\"\nimport {\n buildTerminalPaletteSignature,\n createTerminalPalette,\n normalizeTerminalPalette,\n type TerminalPaletteDetector,\n type TerminalColors,\n type GetPaletteOptions,\n} from \"./lib/terminal-palette.js\"\nimport { calculateRenderGeometry } from \"./lib/render-geometry.js\"\nimport {\n isCapabilityResponse,\n isPixelResolutionResponse,\n parsePixelResolution,\n} from \"./lib/terminal-capability-detection.js\"\nimport { type Clock, type TimerHandle, SystemClock } from \"./lib/clock.js\"\nimport { StdinParser, type StdinEvent, type StdinParserProtocolContext } from \"./lib/stdin-parser.js\"\nimport { matchesKeyBinding } from \"./lib/keybinding.internal.js\"\nimport { RendererThemeMode } from \"./renderer-theme-mode.js\"\n\nregisterEnvVar({\n name: \"OTUI_DUMP_CAPTURES\",\n description: \"Dump captured stdout and console caches when the renderer exit handler runs.\",\n type: \"boolean\",\n default: false,\n})\n\nregisterEnvVar({\n name: \"OTUI_NO_NATIVE_RENDER\",\n description:\n \"Skip the Zig/native frame renderer. Useful for debugging the render loop; split-footer stdout flushing may still write ANSI.\",\n type: \"boolean\",\n default: false,\n})\n\nregisterEnvVar({\n name: \"OTUI_USE_ALTERNATE_SCREEN\",\n description: \"When explicitly set, force screen mode selection: true=alternate-screen, false=main-screen.\",\n type: \"boolean\",\n default: true,\n})\n\nregisterEnvVar({\n name: \"OTUI_OVERRIDE_STDOUT\",\n description: \"When explicitly set, force stdout routing: false=passthrough, true=capture in split-footer mode.\",\n type: \"boolean\",\n default: true,\n})\n\nregisterEnvVar({\n name: \"OTUI_DEBUG\",\n description: \"Enable debug mode to capture all raw input for debugging purposes.\",\n type: \"boolean\",\n default: false,\n})\n\nregisterEnvVar({\n name: \"OTUI_SHOW_STATS\",\n description: \"Show the debug overlay at startup.\",\n type: \"boolean\",\n default: false,\n})\n\nexport interface CliRendererConfig {\n // Read input from this stream. Defaults to process.stdin. Any `Readable`\n // works; capabilities like `setRawMode` are duck-typed and used when present.\n stdin?: NodeJS.ReadStream\n\n // Destination for rendered output. Defaults to process.stdout. When this is\n // not `process.stdout`, the renderer internally wires a `NativeSpanFeed`\n // between Zig and the provided `Writable` so frames flow there instead of\n // the host terminal. TTY capabilities like `columns`/`rows` are duck-typed.\n stdout?: NodeJS.WriteStream\n\n // Fallback terminal width when `stdout.columns` is not available. Useful\n // when running against a non-TTY `Writable` (e.g. an SSH channel) where\n // initial dimensions come from elsewhere. Default 80.\n width?: number\n\n // Fallback terminal height when `stdout.rows` is not available. Default 24.\n height?: number\n\n // Tell the native renderer it is driving a remote terminal. When omitted,\n // native startup auto-detects SSH/mosh sessions; custom stdout feed output\n // defaults to remote because it is not connected to the host TTY directly.\n remote?: boolean\n\n // Use an in-memory native buffered output destination instead of process stdout.\n // Intended for test helpers that need native rendering without terminal I/O.\n bufferedOutput?: NativeBufferedOutput\n\n // Call renderer.destroy() when Ctrl+C is pressed. Defaults to true.\n exitOnCtrlC?: boolean\n\n // Clean up on these signals. Defaults to the common termination signals.\n exitSignals?: NodeJS.Signals[]\n\n // Clear owned screen regions on suspend/destroy. Defaults to true.\n clearOnShutdown?: boolean\n\n // Forward these env var names to native terminal detection.\n forwardEnvKeys?: string[]\n\n // Wait this long before handling resize events. Defaults to 100 ms.\n debounceDelay?: number\n\n // Aim for this many frames per second in continuous mode. Defaults to 30.\n targetFps?: number\n\n // Cap immediate re-renders at this frame rate. Defaults to 60.\n maxFps?: number\n\n // Emit memory snapshots on this interval in ms. Set 0 to disable.\n memorySnapshotInterval?: number\n\n // Render from a separate thread when the platform supports it.\n useThread?: boolean\n\n // Collect frame timing stats for the debug overlay.\n gatherStats?: boolean\n\n // Keep this many timing samples. Defaults to 300.\n maxStatSamples?: number\n\n // Pass options to the built-in console overlay.\n consoleOptions?: Omit\n\n // Run these hooks after each render pass.\n postProcessFns?: ((buffer: OptimizedBuffer, deltaTime: number) => void)[]\n\n // Track mouse move events. Defaults to true.\n enableMouseMovement?: boolean\n\n // Enable mouse input. Defaults to true.\n useMouse?: boolean\n\n // Focus the nearest focusable renderable on left click. Defaults to true.\n autoFocus?: boolean\n\n // Choose where the renderer owns terminal space. Defaults to \"alternate-screen\".\n screenMode?: ScreenMode\n\n // Set the requested footer height for \"split-footer\". Defaults to 12.\n footerHeight?: number\n\n // Choose what happens to writes that go through `stdout.write`.\n externalOutputMode?: ExternalOutputMode\n\n // Choose what the built-in console overlay does.\n consoleMode?: ConsoleMode\n\n // Set Kitty keyboard protocol flags, or null to disable them.\n useKittyKeyboard?: KittyKeyboardOptions | null\n\n // Fill the render buffer with this background color. Default transparent.\n backgroundColor?: ColorInput\n\n // Open the console overlay on uncaught errors. Defaults to true in development.\n openConsoleOnError?: boolean\n\n // Run these input handlers before the built-in handlers.\n prependInputHandlers?: ((sequence: string) => boolean)[]\n\n // Cap the stdin parser buffer size in bytes. Defaults to 64 MB.\n stdinParserMaxBufferBytes?: number\n\n // Use a custom clock for timers and tests.\n clock?: Clock\n\n // Run after destroy() finishes cleanup.\n onDestroy?: () => void\n}\n\n// Controls how the renderer uses terminal space:\n//\n// - \"alternate-screen\": Use the terminal's alternate screen buffer.\n//\n// - \"main-screen\": Render on the main screen.\n//\n// - \"split-footer\": Keep the renderer in a reserved footer on the main screen.\nexport type ScreenMode = \"alternate-screen\" | \"main-screen\" | \"split-footer\"\n\n// Controls writes that go through the configured `stdout.write`.\n//\n// - \"capture-stdout\": Queue stdout and replay it above the split footer.\n// Only valid with \"split-footer\".\n//\n// - \"passthrough\": Leave stdout alone.\nexport type ExternalOutputMode = \"capture-stdout\" | \"passthrough\"\n\nexport interface CliRendererExternalOutputEvent {\n snapshot: OptimizedBuffer\n rowColumns: number\n startOnNewLine: boolean\n trailingNewline: boolean\n}\n\n// Controls the built-in console overlay:\n//\n// - \"console-overlay\": Capture `console.*` output and show the overlay.\n//\n// - \"disabled\": Hide the overlay. `OTUI_USE_CONSOLE` controls global console\n// capture.\nexport type ConsoleMode = \"console-overlay\" | \"disabled\"\n\nexport type PixelResolution = {\n width: number\n height: number\n}\n\nexport interface CliRendererStats extends NativeRenderStats {\n fps: number\n frameCount: number\n frameTimes: number[]\n averageFrameTime: number\n minFrameTime: number\n maxFrameTime: number\n frameCallbackTime: number\n}\n\nexport interface CliRendererFrameEvent {\n frameId: number\n}\n\nexport interface RendererSchedulerState {\n isRunning: boolean\n isRendering: boolean\n hasScheduledRender: boolean\n}\n\nexport interface ScrollbackRenderContext {\n width: number\n widthMethod: WidthMethod\n tailColumn: number\n renderContext: RenderContext\n}\n\nexport interface ScrollbackSnapshot {\n root: Renderable\n width?: number\n height?: number\n rowColumns?: number\n startOnNewLine?: boolean\n trailingNewline?: boolean\n teardown?: () => void\n}\n\nexport type ScrollbackWriter = (ctx: ScrollbackRenderContext) => ScrollbackSnapshot\n\nexport interface ScrollbackSurfaceOptions {\n startOnNewLine?: boolean\n}\n\nexport interface ScrollbackSurfaceCommitOptions {\n rowColumns?: number\n trailingNewline?: boolean\n}\n\nexport interface ScrollbackSurface {\n readonly renderContext: RenderContext\n readonly root: Renderable\n readonly width: number\n readonly height: number\n readonly isDestroyed: boolean\n\n render(): void\n settle(timeoutMs?: number): Promise\n commitRows(startRow: number, endRowExclusive: number, options?: ScrollbackSurfaceCommitOptions): void\n destroy(): void\n}\n\nexport interface SplitFooterReplayResetOptions {\n clearSavedLines?: boolean\n}\n\nconst DEFAULT_FOOTER_HEIGHT = 12\nconst MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES = 4\nconst TRANSPARENT_RGBA = RGBA.fromValues(0, 0, 0, 0)\n\nlet scrollbackSurfaceCounter = 0\n\nfunction normalizeFooterHeight(footerHeight: number | undefined): number {\n if (footerHeight === undefined) {\n return DEFAULT_FOOTER_HEIGHT\n }\n\n if (!Number.isFinite(footerHeight)) {\n throw new Error(\"footerHeight must be a finite number\")\n }\n\n const normalizedFooterHeight = Math.trunc(footerHeight)\n if (normalizedFooterHeight <= 0) {\n throw new Error(\"footerHeight must be greater than 0\")\n }\n\n return normalizedFooterHeight\n}\n\nfunction resolveModes(config: CliRendererConfig): {\n screenMode: ScreenMode\n footerHeight: number\n externalOutputMode: ExternalOutputMode\n} {\n let screenMode = config.screenMode ?? \"alternate-screen\"\n if (process.env.OTUI_USE_ALTERNATE_SCREEN !== undefined) {\n screenMode = env.OTUI_USE_ALTERNATE_SCREEN ? \"alternate-screen\" : \"main-screen\"\n }\n\n const footerHeight =\n screenMode === \"split-footer\" ? normalizeFooterHeight(config.footerHeight) : DEFAULT_FOOTER_HEIGHT\n\n let externalOutputMode =\n config.externalOutputMode ?? (screenMode === \"split-footer\" ? \"capture-stdout\" : \"passthrough\")\n if (process.env.OTUI_OVERRIDE_STDOUT !== undefined) {\n externalOutputMode = env.OTUI_OVERRIDE_STDOUT && screenMode === \"split-footer\" ? \"capture-stdout\" : \"passthrough\"\n }\n\n if (externalOutputMode === \"capture-stdout\" && screenMode !== \"split-footer\") {\n throw new Error('externalOutputMode \"capture-stdout\" requires screenMode \"split-footer\"')\n }\n\n return {\n screenMode,\n footerHeight,\n externalOutputMode,\n }\n}\n\ntype ExternalOutputCommit = {\n snapshot: OptimizedBuffer\n rowColumns: number\n startOnNewLine: boolean\n trailingNewline: boolean\n}\n\ntype PendingSplitFooterTransition = {\n mode: \"viewport-scroll\" | \"clear-stale-rows\"\n sourceTopLine: number\n sourceHeight: number\n targetTopLine: number\n targetHeight: number\n scrollLines?: number\n}\n\nclass ExternalOutputQueue {\n private commits: ExternalOutputCommit[] = []\n\n get size(): number {\n return this.commits.length\n }\n\n writeSnapshot(commit: ExternalOutputCommit): void {\n this.commits.push(commit)\n }\n\n peek(limit: number = Number.POSITIVE_INFINITY): readonly ExternalOutputCommit[] {\n const clampedLimit = Number.isFinite(limit) ? Math.max(1, Math.trunc(limit)) : this.commits.length\n return this.commits.slice(0, clampedLimit)\n }\n\n claim(limit: number = Number.POSITIVE_INFINITY): ExternalOutputCommit[] {\n if (this.commits.length === 0) {\n return []\n }\n\n // Split-footer capture can enqueue many tiny commits in a burst (for example,\n // simulated Ctrl+R hold). Taking everything at once creates very large native\n // frames that increase visible churn. We keep claim() bounded so one render tick\n // produces one modest frame and schedules another tick if work remains.\n const clampedLimit = Number.isFinite(limit) ? Math.max(1, Math.trunc(limit)) : this.commits.length\n if (clampedLimit >= this.commits.length) {\n const output = this.commits\n this.commits = []\n return output\n }\n\n const output = this.commits.slice(0, clampedLimit)\n this.commits = this.commits.slice(clampedLimit)\n return output\n }\n\n drop(count: number): void {\n for (const commit of this.commits.splice(0, count)) {\n commit.snapshot.destroy()\n }\n }\n\n clear(): void {\n this.drop(this.commits.length)\n }\n}\n\nconst CHAR_FLAG_CONTINUATION = 0xc0000000 >>> 0\nconst CHAR_FLAG_MASK = 0xc0000000 >>> 0\n\nclass ScrollbackSnapshotRenderContext extends EventEmitter implements RenderContext {\n public width: number\n public height: number\n public frameId = 0\n public widthMethod: WidthMethod\n public capabilities: TerminalCapabilities | null = null\n public hasSelection: boolean = false\n public currentFocusedRenderable: Renderable | null = null\n public keyInput: KeyHandler\n public _internalKeyInput: InternalKeyHandler\n\n private lifecyclePasses: Set = new Set()\n\n constructor(width: number, height: number, widthMethod: WidthMethod) {\n super()\n this.width = width\n this.height = height\n this.widthMethod = widthMethod\n this.keyInput = new KeyHandler()\n this._internalKeyInput = new InternalKeyHandler()\n }\n\n public addToHitGrid(_x: number, _y: number, _width: number, _height: number, _id: number): void {}\n public pushHitGridScissorRect(_x: number, _y: number, _width: number, _height: number): void {}\n public popHitGridScissorRect(): void {}\n public clearHitGridScissorRects(): void {}\n public requestRender(): void {}\n public setCursorPosition(_x: number, _y: number, _visible: boolean): void {}\n public setCursorStyle(_options: CursorStyleOptions): void {}\n public setCursorColor(_color: RGBA): void {}\n public setMousePointer(_shape: MousePointerStyle): void {}\n public requestLive(): void {}\n public dropLive(): void {}\n public getSelection(): Selection | null {\n return null\n }\n public get currentFocusedEditor(): EditBufferRenderable | null {\n if (!this.currentFocusedRenderable) return null\n if (!isEditBufferRenderable(this.currentFocusedRenderable)) return null\n return this.currentFocusedRenderable\n }\n public requestSelectionUpdate(): void {}\n public focusRenderable(renderable: Renderable): void {\n this.currentFocusedRenderable = renderable\n }\n public blurRenderable(renderable: Renderable): void {\n if (this.currentFocusedRenderable === renderable) {\n this.currentFocusedRenderable = null\n }\n }\n public registerLifecyclePass(renderable: Renderable): void {\n this.lifecyclePasses.add(renderable)\n }\n public unregisterLifecyclePass(renderable: Renderable): void {\n this.lifecyclePasses.delete(renderable)\n }\n public getLifecyclePasses(): Set {\n return this.lifecyclePasses\n }\n public clearSelection(): void {}\n public startSelection(_renderable: Renderable, _x: number, _y: number): void {}\n public updateSelection(\n _currentRenderable: Renderable | undefined,\n _x: number,\n _y: number,\n _options?: { finishDragging?: boolean },\n ): void {}\n}\n\nconst DEFAULT_FORWARDED_ENV_KEYS = [\n \"TMUX\",\n \"ZELLIJ\",\n \"ZELLIJ_SESSION_NAME\",\n \"ZELLIJ_PANE_ID\",\n \"TERM\",\n \"OPENTUI_GRAPHICS\",\n \"TERM_PROGRAM\",\n \"TERM_PROGRAM_VERSION\",\n \"TERM_FEATURES\",\n \"ALACRITTY_SOCKET\",\n \"ALACRITTY_LOG\",\n \"COLORTERM\",\n \"TERMUX_VERSION\",\n \"VHS_RECORD\",\n \"OPENTUI_FORCE_WCWIDTH\",\n \"OPENTUI_FORCE_UNICODE\",\n \"OPENTUI_FORCE_NOZWJ\",\n \"OPENTUI_FORCE_EXPLICIT_WIDTH\",\n \"OPENTUI_NOTIFICATION_PROTOCOL\",\n \"OPENTUI_NOTIFICATIONS\",\n \"WT_SESSION\",\n \"STY\",\n \"WSL_DISTRO_NAME\",\n \"WSL_INTEROP\",\n] as const\n\nconst NATIVE_RENDER_STATUS_SKIPPED = 1\nconst NATIVE_RENDER_STATUS_FAILED = 2\n\n// Kitty keyboard protocol flags\n// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/\nconst KITTY_FLAG_DISAMBIGUATE = 0b1 // Report disambiguated escape codes\nconst KITTY_FLAG_EVENT_TYPES = 0b10 // Report event types (press/repeat/release)\nconst KITTY_FLAG_ALTERNATE_KEYS = 0b100 // Report alternate keys (e.g., numpad vs regular)\nconst KITTY_FLAG_ALL_KEYS_AS_ESCAPES = 0b1000 // Report all keys as escape codes\nconst KITTY_FLAG_REPORT_TEXT = 0b10000 // Report text associated with key events\n\nconst DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES = 64 * 1024 * 1024\nconst NATIVE_PALETTE_QUERY_SIZE = 16\n\n/**\n * Kitty Keyboard Protocol configuration options\n * See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement\n */\nexport interface KittyKeyboardOptions {\n /** Disambiguate escape codes (fixes ESC timing, alt+key ambiguity, ctrl+c as event). Default: true */\n disambiguate?: boolean\n /** Report alternate keys (numpad, shifted, base layout) for cross-keyboard shortcuts. Default: true */\n alternateKeys?: boolean\n /** Report event types (press/repeat/release). Default: false */\n events?: boolean\n /** Report all keys as escape codes. Default: false */\n allKeysAsEscapes?: boolean\n /** Report text associated with key events. Default: false */\n reportText?: boolean\n}\n\n/**\n * Build kitty keyboard protocol flags based on configuration\n * @param config Kitty keyboard configuration object (null/undefined = disabled)\n * @returns The combined flags value (0 = disabled, >0 = enabled)\n * @internal Exported for testing\n */\nexport function buildKittyKeyboardFlags(config: KittyKeyboardOptions | null | undefined): number {\n if (!config) {\n return 0\n }\n\n let flags = 0\n\n // Default: disambiguate + alternate keys (both default to true)\n // - Disambiguate (0b1): Fixes ESC timing issues, alt+key ambiguity, makes ctrl+c a key event\n // - Alternate keys (0b100): Reports shifted/base-layout keys for cross-keyboard shortcuts\n\n // disambiguate defaults to true unless explicitly set to false\n if (config.disambiguate !== false) {\n flags |= KITTY_FLAG_DISAMBIGUATE\n }\n\n // alternateKeys defaults to true unless explicitly set to false\n if (config.alternateKeys !== false) {\n flags |= KITTY_FLAG_ALTERNATE_KEYS\n }\n\n // Optional flags (default to false, only enabled when explicitly true)\n if (config.events === true) {\n flags |= KITTY_FLAG_EVENT_TYPES\n }\n\n if (config.allKeysAsEscapes === true) {\n flags |= KITTY_FLAG_ALL_KEYS_AS_ESCAPES\n }\n\n if (config.reportText === true) {\n flags |= KITTY_FLAG_REPORT_TEXT\n }\n\n return flags\n}\n\nexport class MouseEvent {\n public readonly type: MouseEventType\n public readonly button: number\n public readonly x: number\n public readonly y: number\n public readonly source?: Renderable\n public readonly modifiers: {\n shift: boolean\n alt: boolean\n ctrl: boolean\n }\n public readonly scroll?: ScrollInfo\n public readonly target: Renderable | null\n public readonly isDragging?: boolean\n private _propagationStopped: boolean = false\n private _defaultPrevented: boolean = false\n\n public get propagationStopped(): boolean {\n return this._propagationStopped\n }\n\n public get defaultPrevented(): boolean {\n return this._defaultPrevented\n }\n\n constructor(target: Renderable | null, attributes: RawMouseEvent & { source?: Renderable; isDragging?: boolean }) {\n this.target = target\n this.type = attributes.type\n this.button = attributes.button\n this.x = attributes.x\n this.y = attributes.y\n this.modifiers = attributes.modifiers\n this.scroll = attributes.scroll\n this.source = attributes.source\n this.isDragging = attributes.isDragging\n }\n\n public stopPropagation(): void {\n this._propagationStopped = true\n }\n\n public preventDefault(): void {\n this._defaultPrevented = true\n }\n}\n\nexport enum MouseButton {\n LEFT = 0,\n MIDDLE = 1,\n RIGHT = 2,\n WHEEL_UP = 4,\n WHEEL_DOWN = 5,\n}\n\nconst rendererTracker = singleton(\"RendererTracker\", () => ({\n renderers: new Set(),\n streamOwners: new WeakMap(),\n}))\n\n/**\n * Create a CLI renderer and run its async terminal setup. The constructor\n * owns all stream and backend decisions; this factory only layers on the\n * `--delay-start` flag and the `await setupTerminal()` convenience.\n */\nexport async function createCliRenderer(config: CliRendererConfig = {}): Promise {\n if (process.argv.includes(\"--delay-start\")) {\n await new Promise((resolve) => setTimeout(resolve, 5000))\n }\n const stdin = config.stdin ?? process.stdin\n const stdout = config.stdout ?? process.stdout\n\n // Prefer real TTY dimensions, then explicit config fallbacks, then defaults.\n // `||` (not `??`) preserves the historical falsy-fallback semantics where\n // `stdout.columns === 0` falls through rather than being treated as valid.\n const width = stdout.columns || config.width || 80\n const height = stdout.rows || config.height || 24\n\n const renderer = new CliRenderer(stdin, stdout, width, height, config)\n try {\n await renderer.setupTerminal()\n return renderer\n } catch (error) {\n try {\n renderer.destroy()\n } catch (destroyError) {\n console.error(\"Error destroying partially-set-up renderer:\", destroyError)\n }\n throw error\n }\n}\n\nexport enum CliRenderEvents {\n RESIZE = \"resize\",\n FRAME = \"frame\",\n EXTERNAL_OUTPUT = \"external_output\",\n FOCUS = \"focus\",\n BLUR = \"blur\",\n FOCUSED_RENDERABLE = \"focused_renderable\",\n FOCUSED_EDITOR = \"focused_editor\",\n THEME_MODE = \"theme_mode\",\n PALETTE = \"palette\",\n CAPABILITIES = \"capabilities\",\n SELECTION = \"selection\",\n DEBUG_OVERLAY_TOGGLE = \"debugOverlay:toggle\",\n DESTROY = \"destroy\",\n MEMORY_SNAPSHOT = \"memory:snapshot\",\n}\n\nexport enum RendererControlState {\n IDLE = \"idle\",\n AUTO_STARTED = \"auto_started\",\n EXPLICIT_STARTED = \"explicit_started\",\n EXPLICIT_PAUSED = \"explicit_paused\",\n EXPLICIT_SUSPENDED = \"explicit_suspended\",\n EXPLICIT_STOPPED = \"explicit_stopped\",\n}\n\nexport class CliRenderer extends EventEmitter implements RenderContext {\n private static animationFrameId = 0\n private lib: RenderLib\n public rendererPtr: RendererHandle\n public stdin: NodeJS.ReadStream\n private stdout: NodeJS.WriteStream\n private exitOnCtrlC: boolean\n private exitSignals: NodeJS.Signals[]\n private _exitListenersAdded: boolean = false\n private _isDestroyed: boolean = false\n private _destroyPending: boolean = false\n private _destroyFinalized: boolean = false\n private _destroyCleanupPrepared: boolean = false\n private _streamLeaseAcquired: boolean = false\n public nextRenderBuffer: OptimizedBuffer\n public currentRenderBuffer: OptimizedBuffer\n private _isRunning: boolean = false\n private _targetFps: number = 30\n private _maxFps: number = 60\n private automaticMemorySnapshot: boolean = false\n private memorySnapshotInterval: number\n private memorySnapshotTimer: TimerHandle | null = null\n private lastMemorySnapshot: {\n heapUsed: number\n heapTotal: number\n arrayBuffers: number\n } = {\n heapUsed: 0,\n heapTotal: 0,\n arrayBuffers: 0,\n }\n public readonly root: RootRenderable\n public width: number\n public height: number\n private _useThread: boolean = false\n private gatherStats: boolean = false\n private frameTimes: number[] = []\n private maxStatSamples: number = 300\n private postProcessFns: ((buffer: OptimizedBuffer, deltaTime: number) => void)[] = []\n private backgroundColor: RGBA = RGBA.fromInts(0, 0, 0, 0)\n private waitingForPixelResolution: boolean = false\n private readonly clock: Clock\n\n private rendering: boolean = false\n private renderingNative: boolean = false\n private renderTimeout: TimerHandle | null = null\n private lastTime: number = 0\n private frameCount: number = 0\n // Bumped once per loop() iteration; see RenderContext.frameId.\n private _frameId: number = 0\n private lastFpsTime: number = 0\n private currentFps: number = 0\n private targetFrameTime: number = 1000 / this._targetFps\n private minTargetFrameTime: number = 1000 / this._maxFps\n private immediateRerenderRequested: boolean = false\n private updateScheduled: boolean = false\n\n private liveRequestCounter: number = 0\n private _controlState: RendererControlState = RendererControlState.IDLE\n\n private frameCallbacks: ((deltaTime: number) => Promise)[] = []\n private renderStats: {\n frameCount: number\n fps: number\n renderTime?: number\n frameCallbackTime: number\n } = {\n frameCount: 0,\n fps: 0,\n renderTime: 0,\n frameCallbackTime: 0,\n }\n public debugOverlay = {\n enabled: env.OTUI_SHOW_STATS,\n corner: DebugOverlayCorner.bottomRight,\n }\n\n private _console: TerminalConsole\n private _resolution: PixelResolution | null = null\n private _keyHandler: InternalKeyHandler\n private stdinParser: StdinParser | null = null\n private readonly oscSubscribers = new Set<(sequence: string) => void>()\n private hasLoggedStdinParserError = false\n\n private animationRequest: Map = new Map()\n\n private resizeTimeoutId: TimerHandle | null = null\n private capabilityTimeoutId: TimerHandle | null = null\n private xtVersionWaiters = new Set<() => void>()\n private splitStartupSeedTimeoutId: TimerHandle | null = null\n private pendingSplitStartupCursorSeed: boolean = false\n private resizeDebounceDelay: number = 100\n\n private enableMouseMovement: boolean = false\n private _useMouse: boolean = true\n private autoFocus: boolean = true\n private _screenMode: ScreenMode = \"alternate-screen\"\n private _footerHeight: number = DEFAULT_FOOTER_HEIGHT\n private _externalOutputMode: ExternalOutputMode = \"passthrough\"\n private clearOnShutdown: boolean = true\n private _suspendedMouseEnabled: boolean = false\n private _previousControlState: RendererControlState = RendererControlState.IDLE\n private pendingSuspendedTerminalSetup: boolean = false\n private suspendedNonAltSurfacePreserved: boolean = false\n private capturedRenderable?: Renderable\n private lastOverRenderableNum: number = 0\n private lastOverRenderable?: Renderable\n\n private currentSelection: Selection | null = null\n private selectionContainers: Renderable[] = []\n private clipboard: Clipboard\n\n private _splitHeight: number = 0\n private renderOffset: number = 0\n private splitTailColumn: number = 0\n private pendingSplitFooterTransition: PendingSplitFooterTransition | null = null\n // One-shot latch used to request a full split repaint after transitions\n // (resize/mode/output-path changes). Cleared on first renderNative tick.\n private forceFullRepaintRequested: boolean = false\n // Upper bound for captured stdout commits consumed per native frame.\n // This is a visual smoothness control: smaller batches reduce frame envelope\n // churn and keep render latency predictable under heavy scrollback append load.\n private readonly maxSplitCommitsPerFrame: number = 8\n\n private _terminalWidth: number = 0\n private _terminalHeight: number = 0\n private _terminalIsSetup: boolean = false\n\n private externalOutputQueue = new ExternalOutputQueue()\n private pendingExternalOutputMode: ExternalOutputMode | null = null\n private realStdoutWrite: (chunk: any, encoding?: any, callback?: any) => boolean\n\n private _useConsole: boolean = true\n private sigwinchHandler: () => void = (() => {\n const width = this.stdout.columns || 80\n const height = this.stdout.rows || 24\n this.handleResize(width, height)\n }).bind(this)\n private _capabilities: TerminalCapabilities | null = null\n private _latestPointer: { x: number; y: number } = { x: 0, y: 0 }\n private _hasPointer: boolean = false\n private _lastPointerModifiers: RawMouseEvent[\"modifiers\"] = {\n shift: false,\n alt: false,\n ctrl: false,\n }\n private _currentMousePointerStyle: MousePointerStyle | undefined = undefined\n\n private _currentFocusedRenderable: Renderable | null = null\n private lifecyclePasses: Set = new Set()\n private _openConsoleOnError: boolean = true\n private _paletteDetector: TerminalPaletteDetector | null = null\n private _paletteCache = new Map()\n private _paletteDetectionPromise: Promise | null = null\n private _paletteDetectionSize = 0\n private _paletteEpoch = 0\n private _nativePaletteSignature: string | null = null\n private _emittedPaletteSignature: string | null = null\n private _palettePublishGeneration = 0\n private _onDestroy?: () => void\n private themeModeState: RendererThemeMode\n private _terminalFocusState: boolean | null = null\n\n private sequenceHandlers: ((sequence: string) => boolean)[] = []\n private prependedInputHandlers: ((sequence: string) => boolean)[] = []\n private shouldRestoreModesOnNextFocus: boolean = false\n private themeModeHandler!: (sequence: string) => boolean\n\n private idleResolvers: (() => void)[] = []\n\n private _debugInputs: Array<{ timestamp: string; sequence: string }> = []\n private _debugModeEnabled: boolean = env.OTUI_DEBUG\n\n private handleError: (error: Error) => void = ((error: Error) => {\n console.error(error)\n\n if (this._openConsoleOnError) {\n this.console.show()\n }\n }).bind(this)\n\n private dumpOutputCache(optionalMessage: string = \"\"): void {\n const cachedLogs = this.console.getCachedLogs()\n const capturedConsoleOutput = capture.claimOutput()\n const capturedExternalOutputCommits = this.externalOutputQueue.claim()\n\n let capturedExternalOutput = \"\"\n for (const commit of capturedExternalOutputCommits) {\n capturedExternalOutput += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}]\\n`\n commit.snapshot.destroy()\n }\n\n if (capturedConsoleOutput.length > 0 || capturedExternalOutput.length > 0 || cachedLogs.length > 0) {\n this.realStdoutWrite.call(this.stdout, optionalMessage)\n }\n\n if (cachedLogs.length > 0) {\n this.realStdoutWrite.call(this.stdout, \"Console cache:\\n\")\n this.realStdoutWrite.call(this.stdout, cachedLogs)\n }\n\n if (capturedConsoleOutput.length > 0) {\n this.realStdoutWrite.call(this.stdout, \"\\nCaptured console output:\\n\")\n this.realStdoutWrite.call(this.stdout, capturedConsoleOutput + \"\\n\")\n }\n\n if (capturedExternalOutput.length > 0) {\n this.realStdoutWrite.call(this.stdout, \"\\nCaptured external output:\\n\")\n this.realStdoutWrite.call(this.stdout, capturedExternalOutput + \"\\n\")\n }\n\n this.realStdoutWrite.call(this.stdout, ANSI.reset)\n }\n\n private exitHandler: () => void = (() => {\n this.destroy()\n if (env.OTUI_DUMP_CAPTURES) {\n sleep(100).then(() => {\n this.dumpOutputCache(\"=== CAPTURED OUTPUT ===\\n\")\n })\n }\n }).bind(this)\n\n private warningHandler: (warning: any) => void = ((warning: any) => {\n console.warn(JSON.stringify(warning.message, null, 2))\n }).bind(this)\n\n // Stream identity flag. Used only for SIGWINCH gating (terminal-driven\n // resize only fires for process.stdout). Other per-stream behavior uses\n // identity checks inline (e.g. rendererTracker compares `stdin` directly)\n // or duck-typed capability checks (e.g. `stdin.setRawMode?.()`).\n private readonly _usesProcessStdout: boolean\n\n // Feed wiring. Non-null when the given stdout is not process.stdout and native\n // output is not explicitly redirected to a buffered memory destination.\n private _feed: NativeSpanFeed | null = null\n private _detachFeed: (() => void) | null = null\n private _detachFeedError: (() => void) | null = null\n private feedIdleRenderScheduled = false\n private ordinaryFrameWaitingForFeed = false\n private ordinaryFrameWaitControlState: RendererControlState | null = null\n\n public get controlState(): RendererControlState {\n return this._controlState\n }\n\n /**\n * Construct a renderer over the given streams.\n *\n * If `stdout` is not `process.stdout`, a `NativeSpanFeed` is allocated\n * internally and rendered bytes are piped through it to `stdout` unless\n * `bufferedOutput: \"memory\"` is set. Prefer `createCliRenderer` for the async\n * `setupTerminal` convenience.\n *\n * Construction side effects (observable before the constructor returns):\n * - Acquires exclusive ownership of the given stdin/stdout streams\n * - Allocates a `NativeSpanFeed` (for non-process stdout unless bufferedOutput is \"memory\")\n * - Calls `lib.createRenderer` → native Zig allocation\n * - Registers in the process-wide `rendererTracker`\n * - Adds `process.on(...)` listeners for SIGWINCH (process.stdout only),\n * \"warning\", \"uncaughtException\", \"unhandledRejection\", \"beforeExit\",\n * plus the configured `exitSignals`\n * - Replaces `global.requestAnimationFrame` with the renderer's impl\n * - When `setupTerminal()` is called, it will put `stdin` in raw mode and\n * call `stdin.resume()`\n *\n * Some late constructor side effects are not rolled back if construction\n * throws partway; production callers should use `createCliRenderer`, which\n * wraps `setupTerminal()` in a try/catch that calls `destroy()` on failure.\n */\n constructor(\n stdin: NodeJS.ReadStream,\n stdout: NodeJS.WriteStream,\n width: number,\n height: number,\n config: CliRendererConfig = {},\n ) {\n super()\n\n this.stdin = stdin\n this.stdout = stdout\n this._usesProcessStdout = stdout === process.stdout\n this.realStdoutWrite = stdout.write\n\n const lib = resolveRenderLib()\n const useMemoryBufferedOutput = config.bufferedOutput === \"memory\"\n const useFeedOutput = !this._usesProcessStdout && !useMemoryBufferedOutput\n const { screenMode, footerHeight, externalOutputMode } = resolveModes(config)\n const initialGeometry = calculateRenderGeometry(screenMode, width, height, footerHeight)\n const remoteMode = config.remote ?? (useFeedOutput ? true : undefined)\n\n if (rendererTracker.streamOwners.get(stdin)) {\n throw new Error(\"Cannot create CliRenderer: stdin is already used by another CliRenderer\")\n }\n if (rendererTracker.streamOwners.get(stdout)) {\n throw new Error(\"Cannot create CliRenderer: stdout is already used by another CliRenderer\")\n }\n\n // Feed allocation: only when the output target is a non-process Writable.\n // Tests use custom Writable instances too; those should exercise the same\n // output transport as production custom stdout.\n let feed: NativeSpanFeed | null = null\n if (useFeedOutput) {\n try {\n feed = NativeSpanFeed.create()\n } catch (error) {\n throw new Error(\n `Failed to allocate NativeSpanFeed for custom stdout: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n }\n\n // Native renderer creation. Custom writable feed output defaults to remote\n // so Zig skips local-TTY capability-query timing assumptions; process\n // stdout and memory output preserve native auto detection.\n //\n let rendererPtr: RendererHandle | null\n try {\n rendererPtr = lib.createRenderer(initialGeometry.renderWidth, initialGeometry.renderHeight, {\n remote: remoteMode,\n feedPtr: feed?.streamPtr ?? null,\n bufferedOutput: config.bufferedOutput,\n })\n } catch (error) {\n feed?.close()\n throw error\n }\n if (!rendererPtr) {\n feed?.close()\n throw new Error(\"Failed to create renderer\")\n }\n\n // Threading defaults (on everywhere except linux, where it currently\n // crashes — likely a missing build dep).\n if (config.useThread === undefined) config.useThread = true\n if (process.platform === \"linux\") config.useThread = false\n lib.setUseThread(rendererPtr, config.useThread)\n\n const kittyConfig = config.useKittyKeyboard ?? {}\n const kittyFlags = buildKittyKeyboardFlags(kittyConfig)\n lib.setKittyKeyboardFlags(rendererPtr, kittyFlags)\n\n // Wire feed → Writable piping. The returned Promise keeps the chunk\n // pinned (refcount held) until Node's write callback fires; this turns\n // Node's Writable flow control into async backpressure for the feed.\n // Write errors are surfaced via feed.onError / console.error; we do not\n // interfere with the Writable's own error handling (matches the\n // pre-feed-integration posture where process.stdout EPIPE was the OS's\n // problem, not the renderer's).\n this._feed = feed\n if (feed) {\n this._detachFeed = feed.onData((bytes: Uint8Array) => {\n return new Promise((resolve) => {\n // Renderer-owned frame bytes must bypass any later stdout.write\n // interception (e.g. split-footer capture) and go straight to the\n // caller's actual sink.\n this.realStdoutWrite.call(this.stdout, bytes, () => resolve())\n })\n })\n this._detachFeedError = feed.onError((code) => {\n console.error(`[CliRenderer] NativeSpanFeed error: code=${code}`)\n })\n }\n\n this.lib = lib\n this._terminalWidth = width\n this._terminalHeight = height\n this._useThread = config.useThread\n this._externalOutputMode = externalOutputMode\n\n this.width = initialGeometry.renderWidth\n this.height = initialGeometry.renderHeight\n this._splitHeight = initialGeometry.effectiveFooterHeight\n this.renderOffset = screenMode === \"split-footer\" ? 0 : initialGeometry.renderOffset\n\n this._footerHeight = footerHeight\n\n this.rendererPtr = rendererPtr\n this.clearOnShutdown = config.clearOnShutdown ?? true\n this.lib.setClearOnShutdown(this.rendererPtr, this.clearOnShutdown)\n\n const forwardEnvKeys = config.forwardEnvKeys ?? (config.remote === false ? [...DEFAULT_FORWARDED_ENV_KEYS] : [])\n for (const key of forwardEnvKeys) {\n const value = process.env[key]\n if (value === undefined) continue\n this.lib.setTerminalEnvVar(this.rendererPtr, key, value)\n }\n\n this.exitOnCtrlC = config.exitOnCtrlC === undefined ? true : config.exitOnCtrlC\n this.exitSignals = config.exitSignals || [\n \"SIGINT\", // Ctrl+C\n \"SIGTERM\", // Termination signal\n \"SIGQUIT\", // Ctrl+\\\n \"SIGABRT\", // Abort signal\n \"SIGHUP\", // Hangup (terminal closed)\n \"SIGBREAK\", // Ctrl+Break on Windows\n \"SIGPIPE\", // Broken pipe\n \"SIGBUS\", // Bus error\n ]\n\n this.clipboard = new Clipboard(this.lib, this.rendererPtr)\n this.resizeDebounceDelay = config.debounceDelay || 100\n this.targetFps = config.targetFps || 30\n this.maxFps = config.maxFps || 60\n this.clock = config.clock ?? new SystemClock()\n this.themeModeState = new RendererThemeMode(\n {\n queryThemeColors: () => {\n this.lib.queryThemeColors(this.rendererPtr)\n },\n },\n this.clock,\n )\n this.themeModeHandler = (sequence: string) => {\n const result = this.themeModeState.handleSequence(sequence)\n if (result.changedMode) {\n this.clearPaletteCache()\n if (this.shouldSyncNativePaletteState() || this.listenerCount(CliRenderEvents.PALETTE) > 0) {\n this.refreshPalette()\n }\n this.emit(CliRenderEvents.THEME_MODE, result.changedMode)\n }\n return result.handled\n }\n this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0\n this.gatherStats = config.gatherStats || false\n this.maxStatSamples = config.maxStatSamples || 300\n this.enableMouseMovement = config.enableMouseMovement ?? true\n this._useMouse = config.useMouse ?? true\n this.autoFocus = config.autoFocus ?? true\n this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr)\n this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr)\n this.postProcessFns = config.postProcessFns || []\n this.prependedInputHandlers = config.prependInputHandlers || []\n\n this.root = new RootRenderable(this)\n\n if (this.memorySnapshotInterval > 0) {\n this.startMemorySnapshotTimer()\n }\n\n // Handle terminal resize via SIGWINCH, but only when attached to the\n // process's real stdout — a custom Writable wouldn't drive SIGWINCH\n // anyway, and external consumers can call `renderer.resize(w, h)` to\n // announce dimension changes themselves.\n if (this._usesProcessStdout) {\n process.on(\"SIGWINCH\", this.sigwinchHandler)\n }\n\n process.on(\"warning\", this.warningHandler)\n\n process.on(\"uncaughtException\", this.handleError)\n process.on(\"unhandledRejection\", this.handleError)\n process.on(\"beforeExit\", this.exitHandler)\n\n const useKittyForParsing = kittyConfig !== null\n this._keyHandler = new InternalKeyHandler()\n this._keyHandler.on(\"keypress\", (event) => {\n // Use the shared matcher here too. Kitty can report a non-Latin\n // character plus a base-layout `c`, and Ctrl+C should still exit.\n if (this.exitOnCtrlC && matchesKeyBinding(event, { name: \"c\", ctrl: true })) {\n process.nextTick(() => {\n this.destroy()\n })\n return\n }\n })\n\n this.addExitListeners()\n\n const stdinParserMaxBufferBytes = config.stdinParserMaxBufferBytes ?? DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES\n this.stdinParser = new StdinParser({\n timeoutMs: 20,\n maxPendingBytes: stdinParserMaxBufferBytes,\n armTimeouts: true,\n onTimeoutFlush: () => {\n this.drainStdinParser()\n },\n useKittyKeyboard: useKittyForParsing,\n protocolContext: {\n kittyKeyboardEnabled: useKittyForParsing,\n privateCapabilityRepliesActive: false,\n pixelResolutionQueryActive: false,\n explicitWidthCprActive: false,\n startupCursorCprActive: false,\n },\n clock: this.clock,\n })\n\n this._console = new TerminalConsole(this, {\n ...(config.consoleOptions ?? {}),\n clock: this.clock,\n })\n this.consoleMode = config.consoleMode ?? \"console-overlay\"\n this.applyScreenMode(screenMode, false, false)\n rendererTracker.streamOwners.set(stdin, this)\n rendererTracker.streamOwners.set(stdout, this)\n this._streamLeaseAcquired = true\n rendererTracker.renderers.add(this)\n this.stdout.write = externalOutputMode === \"capture-stdout\" ? this.interceptStdoutWrite : this.realStdoutWrite\n this._openConsoleOnError = config.openConsoleOnError ?? process.env.NODE_ENV !== \"production\"\n this._onDestroy = config.onDestroy\n\n global.requestAnimationFrame = (callback: FrameRequestCallback) => {\n const id = CliRenderer.animationFrameId++\n this.animationRequest.set(id, callback)\n this.requestLive()\n return id\n }\n global.cancelAnimationFrame = (handle: number) => {\n this.animationRequest.delete(handle)\n }\n\n const window = global.window\n if (!window) {\n global.window = {} as Window & typeof globalThis\n }\n global.window.requestAnimationFrame = requestAnimationFrame\n\n // Prevents output from being written to the terminal, useful for debugging\n if (env.OTUI_NO_NATIVE_RENDER) {\n this.renderNative = () => {\n if (this._splitHeight > 0) {\n this.flushStdoutCache(this._splitHeight)\n }\n return \"rendered\"\n }\n }\n\n try {\n this.setupInput()\n } catch (error) {\n try {\n this.destroy()\n } catch (destroyError) {\n console.error(\"Error destroying renderer after input setup failure:\", destroyError)\n }\n throw error\n }\n }\n\n private addExitListeners(): void {\n if (this._exitListenersAdded || this.exitSignals.length === 0) return\n\n this.exitSignals.forEach((signal) => {\n process.addListener(signal, this.exitHandler)\n })\n\n this._exitListenersAdded = true\n }\n\n private removeExitListeners(): void {\n if (!this._exitListenersAdded || this.exitSignals.length === 0) return\n\n this.exitSignals.forEach((signal) => {\n process.removeListener(signal, this.exitHandler)\n })\n\n this._exitListenersAdded = false\n }\n\n public get isDestroyed(): boolean {\n return this._isDestroyed\n }\n\n public registerLifecyclePass(renderable: Renderable) {\n this.lifecyclePasses.add(renderable)\n }\n\n public unregisterLifecyclePass(renderable: Renderable) {\n this.lifecyclePasses.delete(renderable)\n }\n\n public getLifecyclePasses() {\n return this.lifecyclePasses\n }\n\n public get currentFocusedRenderable(): Renderable | null {\n return this._currentFocusedRenderable\n }\n\n public get currentFocusedEditor(): EditBufferRenderable | null {\n if (!this._currentFocusedRenderable) return null\n if (!isEditBufferRenderable(this._currentFocusedRenderable)) return null\n return this._currentFocusedRenderable\n }\n\n private normalizeClockTime(now: number, fallback: number): number {\n if (Number.isFinite(now)) {\n return now\n }\n\n return Number.isFinite(fallback) ? fallback : 0\n }\n\n private getElapsedMs(now: number, then: number): number {\n if (!Number.isFinite(now) || !Number.isFinite(then)) {\n return 0\n }\n\n return Math.max(now - then, 0)\n }\n\n public focusRenderable(renderable: Renderable) {\n if (this._currentFocusedRenderable === renderable) {\n return\n }\n\n const previousRenderable = this._currentFocusedRenderable\n const previousEditor = this.currentFocusedEditor\n\n this._currentFocusedRenderable = renderable\n previousRenderable?.blur()\n\n const currentEditor = this.currentFocusedEditor\n if (previousEditor !== currentEditor) {\n this.emit(CliRenderEvents.FOCUSED_EDITOR, currentEditor, previousEditor)\n }\n\n this.emit(CliRenderEvents.FOCUSED_RENDERABLE, renderable, previousRenderable)\n }\n\n public blurRenderable(renderable: Renderable): void {\n if (this._currentFocusedRenderable !== renderable) {\n return\n }\n\n const previousEditor = this.currentFocusedEditor\n this._currentFocusedRenderable = null\n\n if (previousEditor !== null) {\n this.emit(CliRenderEvents.FOCUSED_EDITOR, null, previousEditor)\n }\n\n this.emit(CliRenderEvents.FOCUSED_RENDERABLE, null, renderable)\n }\n\n private setCapturedRenderable(renderable: Renderable | undefined): void {\n if (this.capturedRenderable === renderable) {\n return\n }\n this.capturedRenderable = renderable\n }\n\n public addToHitGrid(x: number, y: number, width: number, height: number, id: number) {\n if (!this._useMouse) return\n if (id !== this.capturedRenderable?.num) {\n this.lib.addToHitGrid(this.rendererPtr, x, y, width, height, id)\n }\n }\n\n public pushHitGridScissorRect(x: number, y: number, width: number, height: number): void {\n this.lib.hitGridPushScissorRect(this.rendererPtr, x, y, width, height)\n }\n\n public popHitGridScissorRect(): void {\n this.lib.hitGridPopScissorRect(this.rendererPtr)\n }\n\n public clearHitGridScissorRects(): void {\n this.lib.hitGridClearScissorRects(this.rendererPtr)\n }\n\n public get widthMethod(): WidthMethod {\n const caps = this.capabilities\n return caps?.unicode === \"wcwidth\" ? \"wcwidth\" : \"unicode\"\n }\n\n public get frameId(): number {\n return this._frameId\n }\n\n private writeOut(chunk: any, encoding?: any, callback?: any): boolean {\n // Route through the native backend whenever:\n // (a) threading is on (pre-existing path — batches with the render thread), OR\n // (b) a feed is wired (custom stdout) — otherwise the else-branch would\n // write directly to the user's Writable, bypassing the feed and\n // causing TS-side ANSI to interleave with Zig-emitted frame bytes\n // on Linux where threading is forced off.\n if (this.rendererPtr && (this._useThread || this._feed !== null)) {\n const data = typeof chunk === \"string\" ? chunk : (chunk?.toString() ?? \"\")\n this.lib.writeOut(this.rendererPtr, data)\n if (typeof callback === \"function\") {\n process.nextTick(callback)\n }\n return true\n }\n\n return this.realStdoutWrite.call(this.stdout, chunk, encoding, callback)\n }\n\n private scheduleRenderAfterFeedIdle(): void {\n const feed = this._feed\n if (!feed || this.feedIdleRenderScheduled || this._isDestroyed) return\n\n this.feedIdleRenderScheduled = true\n feed.idle().then(() => {\n this.feedIdleRenderScheduled = false\n const ordinaryFrameWasWaiting = this.ordinaryFrameWaitingForFeed\n const ordinaryFrameWaitControlState = this.ordinaryFrameWaitControlState\n this.ordinaryFrameWaitingForFeed = false\n this.ordinaryFrameWaitControlState = null\n if (\n this._isDestroyed ||\n (ordinaryFrameWasWaiting &&\n this._controlState !== ordinaryFrameWaitControlState &&\n (this._controlState === RendererControlState.EXPLICIT_PAUSED ||\n this._controlState === RendererControlState.EXPLICIT_STOPPED ||\n this._controlState === RendererControlState.EXPLICIT_SUSPENDED))\n ) {\n this.resolveIdleIfNeeded()\n return\n }\n\n this.scheduleRenderTimer()\n this.resolveIdleIfNeeded()\n })\n }\n\n private handleNativeRenderRejection(status: number): \"retryable-skip\" | \"failed\" {\n if (status === NATIVE_RENDER_STATUS_SKIPPED && this._feed) {\n this.ordinaryFrameWaitingForFeed = true\n this.ordinaryFrameWaitControlState = this._controlState\n this.scheduleRenderAfterFeedIdle()\n return \"retryable-skip\"\n }\n\n if (status === NATIVE_RENDER_STATUS_SKIPPED) {\n console.error(\"[CliRenderer] Native frame render unexpectedly skipped without a feed\")\n return \"failed\"\n }\n\n return this.reportNativeRenderFailure()\n }\n\n private reportNativeRenderFailure(): \"failed\" {\n console.error(\"[CliRenderer] Native frame render failed; waiting for the next render request to force repaint\")\n return \"failed\"\n }\n\n private scheduleRenderTimer(): void {\n if (this.renderTimeout || this._isDestroyed || this._controlState === RendererControlState.EXPLICIT_SUSPENDED)\n return\n\n const now = this.normalizeClockTime(this.clock.now(), this.lastTime)\n const elapsed = this.getElapsedMs(now, this.lastTime)\n const delay = Math.max(this.minTargetFrameTime - elapsed, 0)\n this.renderTimeout = this.clock.setTimeout(() => {\n this.renderTimeout = null\n this.loop()\n }, delay)\n }\n\n private scheduleRenderAfterBackpressure(): void {\n if (this._feed) {\n this.scheduleRenderAfterFeedIdle()\n return\n }\n\n this.scheduleRenderTimer()\n }\n\n public requestRender() {\n if (this._controlState === RendererControlState.EXPLICIT_SUSPENDED) {\n return\n }\n\n // A skipped feed-backed frame already owns the next scheduling attempt through\n // feed.idle(). Coalesce normal invalidations into that retry so split-footer\n // output and UI updates cannot start competing render passes while the feed is busy.\n if (this.feedIdleRenderScheduled) {\n return\n }\n\n if (this._isRunning) {\n if (!this.rendering && !this.renderTimeout && !this.ordinaryFrameWaitingForFeed) {\n this.scheduleRenderTimer()\n }\n return\n }\n\n if (this.ordinaryFrameWaitingForFeed) {\n return\n }\n\n // NOTE: Using a frame callback that causes a re-render while already rendering\n // leads to a continuous loop of renders.\n if (this.rendering) {\n this.immediateRerenderRequested = true\n return\n }\n\n if (!this.updateScheduled && !this.renderTimeout) {\n this.updateScheduled = true\n const now = this.normalizeClockTime(this.clock.now(), this.lastTime)\n const elapsed = this.getElapsedMs(now, this.lastTime)\n const delay = Math.max(this.minTargetFrameTime - elapsed, 0)\n\n if (delay === 0) {\n process.nextTick(() => this.activateFrame())\n return\n }\n\n this.clock.setTimeout(() => this.activateFrame(), delay)\n }\n }\n\n private async activateFrame() {\n if (!this.updateScheduled) {\n this.resolveIdleIfNeeded()\n return\n }\n\n try {\n await this.loop()\n } finally {\n this.updateScheduled = false\n this.resolveIdleIfNeeded()\n }\n }\n\n public get consoleMode(): ConsoleMode {\n return this._useConsole ? \"console-overlay\" : \"disabled\"\n }\n\n public set consoleMode(mode: ConsoleMode) {\n this._useConsole = mode === \"console-overlay\"\n if (this._useConsole) {\n this.console.activate()\n } else {\n this.console.deactivate()\n }\n }\n\n public get isRunning(): boolean {\n return this._isRunning\n }\n\n private isIdleNow(): boolean {\n if (this._isDestroyed) return true\n\n return (\n !this._isRunning &&\n !this.rendering &&\n !this.renderTimeout &&\n !this.updateScheduled &&\n !this.feedIdleRenderScheduled &&\n !this.immediateRerenderRequested\n )\n }\n\n private resolveIdleIfNeeded(): void {\n if (!this.isIdleNow()) return\n const resolvers = this.idleResolvers.splice(0)\n for (const resolve of resolvers) {\n resolve()\n }\n }\n\n public idle(): Promise {\n if (this._isDestroyed) return Promise.resolve()\n if (this.isIdleNow()) return Promise.resolve()\n return new Promise((resolve) => {\n this.idleResolvers.push(resolve)\n })\n }\n\n public getSchedulerState(): RendererSchedulerState {\n return {\n isRunning: this._isRunning,\n isRendering: this.rendering,\n hasScheduledRender: Boolean(this.renderTimeout || this.updateScheduled || this.immediateRerenderRequested),\n }\n }\n\n public get resolution(): PixelResolution | null {\n return this._resolution\n }\n\n public get console(): TerminalConsole {\n return this._console\n }\n\n public get keyInput(): KeyHandler {\n return this._keyHandler\n }\n\n public get _internalKeyInput(): InternalKeyHandler {\n return this._keyHandler\n }\n\n public get terminalWidth(): number {\n return this._terminalWidth\n }\n\n public get terminalHeight(): number {\n return this._terminalHeight\n }\n\n public get useThread(): boolean {\n return this._useThread\n }\n\n public get targetFps(): number {\n return this._targetFps\n }\n\n public set targetFps(targetFps: number) {\n this._targetFps = targetFps\n this.targetFrameTime = 1000 / this._targetFps\n }\n\n public get maxFps(): number {\n return this._maxFps\n }\n\n public set maxFps(maxFps: number) {\n this._maxFps = maxFps\n this.minTargetFrameTime = 1000 / this._maxFps\n }\n\n public get useMouse(): boolean {\n return this._useMouse\n }\n\n public set useMouse(useMouse: boolean) {\n if (this._useMouse === useMouse) return // No change needed\n\n this._useMouse = useMouse\n\n if (useMouse) {\n this.enableMouse()\n this.requestRender()\n } else {\n this.disableMouse()\n }\n }\n\n public get screenMode(): ScreenMode {\n return this._screenMode\n }\n\n public set screenMode(mode: ScreenMode) {\n if (this.externalOutputMode === \"capture-stdout\" && mode !== \"split-footer\") {\n if (this.pendingExternalOutputMode === \"passthrough\") {\n this.flushPendingSplitOutputBeforeLeavingSplitFooter()\n }\n\n if (this.externalOutputMode !== \"capture-stdout\") {\n this.applyScreenMode(mode)\n return\n }\n\n throw new Error('externalOutputMode \"capture-stdout\" requires screenMode \"split-footer\"')\n }\n\n this.applyScreenMode(mode)\n }\n\n public get footerHeight(): number {\n return this._footerHeight\n }\n\n public set footerHeight(footerHeight: number) {\n const normalizedFooterHeight = normalizeFooterHeight(footerHeight)\n if (normalizedFooterHeight === this._footerHeight) {\n return\n }\n\n this._footerHeight = normalizedFooterHeight\n if (this.screenMode === \"split-footer\") {\n this.applyScreenMode(\"split-footer\")\n }\n }\n\n public get externalOutputMode(): ExternalOutputMode {\n return this._externalOutputMode\n }\n\n public set externalOutputMode(mode: ExternalOutputMode) {\n if (mode === \"capture-stdout\" && this.screenMode !== \"split-footer\") {\n throw new Error('externalOutputMode \"capture-stdout\" requires screenMode \"split-footer\"')\n }\n\n const previousMode = this._externalOutputMode\n if (previousMode === mode) {\n if (this.pendingExternalOutputMode !== null && this.pendingExternalOutputMode !== mode) {\n this.pendingExternalOutputMode = null\n }\n return\n }\n\n const canFlushSplitOutputBeforeTransition = this.canFlushSplitOutputBeforeTransition()\n const isSplitCaptureToPassthrough =\n previousMode === \"capture-stdout\" &&\n mode === \"passthrough\" &&\n this._screenMode === \"split-footer\" &&\n this._splitHeight > 0\n\n if (isSplitCaptureToPassthrough && this.externalOutputQueue.size > 0 && !canFlushSplitOutputBeforeTransition) {\n this.pendingExternalOutputMode = \"passthrough\"\n return\n }\n\n if (isSplitCaptureToPassthrough && canFlushSplitOutputBeforeTransition) {\n this.flushPendingSplitOutputBeforeTransition()\n }\n\n this.pendingExternalOutputMode = null\n this.applyExternalOutputMode(mode)\n this.afterExternalOutputModeChanged(previousMode, mode)\n }\n\n private applyExternalOutputMode(mode: ExternalOutputMode): void {\n this._externalOutputMode = mode\n this.stdout.write = mode === \"capture-stdout\" ? this.interceptStdoutWrite : this.realStdoutWrite\n }\n\n private afterExternalOutputModeChanged(previousMode: ExternalOutputMode, mode: ExternalOutputMode): void {\n if (this._screenMode === \"split-footer\" && this._splitHeight > 0 && mode === \"capture-stdout\") {\n const previousSurfaceTopLine = this.renderOffset + 1\n const previousSurfaceHeight = this._splitHeight\n\n this.clearPendingSplitFooterTransition()\n this.resetSplitScrollback(this.getSplitCursorSeedRows())\n\n if (previousMode === \"passthrough\" && this._terminalIsSetup) {\n const nextSurfaceTopLine = this.renderOffset + 1\n if (previousSurfaceTopLine !== nextSurfaceTopLine) {\n this.setPendingSplitFooterTransition({\n mode: \"clear-stale-rows\",\n sourceTopLine: previousSurfaceTopLine,\n sourceHeight: previousSurfaceHeight,\n targetTopLine: nextSurfaceTopLine,\n targetHeight: this._splitHeight,\n scrollLines: 0,\n })\n this.forceFullRepaintRequested = true\n }\n }\n\n this.requestRender()\n return\n }\n\n if (\n this._screenMode === \"split-footer\" &&\n this._splitHeight > 0 &&\n previousMode === \"capture-stdout\" &&\n mode === \"passthrough\"\n ) {\n this.clearPendingSplitFooterTransition()\n return\n }\n\n this.syncSplitFooterState()\n }\n\n private applyPendingExternalOutputModeIfReady(): void {\n const pendingMode = this.pendingExternalOutputMode\n if (pendingMode === null || this.externalOutputQueue.size > 0) {\n return\n }\n\n const previousMode = this._externalOutputMode\n this.pendingExternalOutputMode = null\n\n if (previousMode === pendingMode) {\n return\n }\n\n this.applyExternalOutputMode(pendingMode)\n this.afterExternalOutputModeChanged(previousMode, pendingMode)\n }\n\n private flushPendingSplitOutputBeforeLeavingSplitFooter(): void {\n if (this.pendingExternalOutputMode !== \"passthrough\") {\n return\n }\n\n if (this.isSplitCursorSeedFrameBlocked() && this._controlState !== RendererControlState.EXPLICIT_SUSPENDED) {\n this.abortSplitStartupCursorSeed()\n }\n\n this.flushPendingSplitOutputBeforeTransition()\n\n if (this.pendingExternalOutputMode !== null) {\n throw new Error(\"Cannot leave split-footer while captured output is pending\")\n }\n }\n\n public get liveRequestCount(): number {\n return this.liveRequestCounter\n }\n\n public get currentControlState(): string {\n return this._controlState\n }\n\n public get capabilities(): TerminalCapabilities | null {\n return this._capabilities\n }\n\n public triggerNotification(message: string, title?: string): boolean {\n if (this._isDestroyed) return false\n return this.lib.triggerNotification(this.rendererPtr, message, title)\n }\n\n public get themeMode(): ThemeMode | null {\n return this.themeModeState.themeMode\n }\n\n public waitForThemeMode(timeoutMs: number = 1000): Promise {\n if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {\n throw new Error(\"timeoutMs must be a non-negative finite number\")\n }\n\n return this.themeModeState.waitForThemeMode(timeoutMs, this._isDestroyed)\n }\n\n public getDebugInputs(): Array<{ timestamp: string; sequence: string }> {\n return [...this._debugInputs]\n }\n\n public get useKittyKeyboard(): boolean {\n return this.lib.getKittyKeyboardFlags(this.rendererPtr) > 0\n }\n\n public set useKittyKeyboard(use: boolean) {\n const flags = use ? KITTY_FLAG_DISAMBIGUATE | KITTY_FLAG_ALTERNATE_KEYS : 0\n this.lib.setKittyKeyboardFlags(this.rendererPtr, flags)\n }\n\n public createScrollbackSurface(options: ScrollbackSurfaceOptions = {}): ScrollbackSurface {\n if (this._screenMode !== \"split-footer\" || this._externalOutputMode !== \"capture-stdout\") {\n throw new Error(\n 'createScrollbackSurface requires screenMode \"split-footer\" and externalOutputMode \"capture-stdout\"',\n )\n }\n\n const renderer = this\n const surfaceId = scrollbackSurfaceCounter++\n const startOnNewLine = options.startOnNewLine ?? true\n const tailColumn = renderer.getPendingSplitTailColumn()\n const firstLineOffset = !startOnNewLine && tailColumn > 0 && tailColumn < renderer.width ? tailColumn : 0\n\n const snapshotContext = new ScrollbackSnapshotRenderContext(renderer.width, 1, renderer.widthMethod)\n let firstLineOffsetOwner: Renderable | null = null\n const renderContext = Object.create(snapshotContext) as RenderContext\n Object.defineProperty(renderContext, \"claimFirstLineOffset\", {\n value: (renderable?: Renderable): number => {\n if (firstLineOffsetOwner?.isDestroyed) {\n firstLineOffsetOwner = null\n }\n\n if (firstLineOffsetOwner) {\n return 0\n }\n\n firstLineOffsetOwner = renderable ?? null\n return firstLineOffset\n },\n enumerable: true,\n configurable: true,\n })\n\n const internalRoot = new RootRenderable(renderContext)\n const publicRoot = new BoxRenderable(renderContext, {\n id: `scrollback-surface-root-${surfaceId}`,\n position: \"absolute\",\n left: 0,\n top: 0,\n width: renderer.width,\n height: \"auto\",\n border: false,\n backgroundColor: \"transparent\",\n shouldFill: false,\n flexDirection: \"column\",\n })\n internalRoot.add(publicRoot)\n\n let surfaceWidth = renderer.width\n let surfaceHeight = 1\n let surfaceWidthMethod = renderer.widthMethod\n let surfaceDestroyed = false\n let hasRendered = false\n let nextCommitStartOnNewLine = startOnNewLine\n let backingBuffer = OptimizedBuffer.create(surfaceWidth, surfaceHeight, surfaceWidthMethod, {\n id: `scrollback-surface-buffer-${surfaceId}`,\n })\n\n const destroyListener = (): void => {\n destroySurface()\n }\n\n const assertNotDestroyed = (): void => {\n if (surfaceDestroyed) {\n throw new Error(\"ScrollbackSurface is destroyed\")\n }\n }\n\n const assertRendered = (): void => {\n if (!hasRendered) {\n throw new Error(\"ScrollbackSurface.commitRows requires render() before commitRows()\")\n }\n }\n\n const assertGeometryStillCurrent = (): void => {\n if (renderer.width !== surfaceWidth || renderer.widthMethod !== surfaceWidthMethod) {\n throw new Error(\"ScrollbackSurface.commitRows requires render() after renderer geometry changes\")\n }\n }\n\n const assertRowRange = (startRow: number, endRowExclusive: number): void => {\n if (!Number.isInteger(startRow) || !Number.isInteger(endRowExclusive)) {\n throw new Error(\"ScrollbackSurface.commitRows requires finite integer row bounds\")\n }\n\n if (startRow < 0) {\n throw new Error(\"ScrollbackSurface.commitRows requires startRow >= 0\")\n }\n\n if (endRowExclusive < startRow) {\n throw new Error(\"ScrollbackSurface.commitRows requires endRowExclusive >= startRow\")\n }\n\n if (endRowExclusive > surfaceHeight) {\n throw new Error(\"ScrollbackSurface.commitRows row range exceeds rendered surface height\")\n }\n }\n\n const collectPendingCodeRenderables = (node: Renderable): CodeRenderable[] => {\n const pending: CodeRenderable[] = []\n\n if (node instanceof CodeRenderable && node.isHighlighting) {\n pending.push(node)\n }\n\n for (const child of node.getChildren()) {\n pending.push(...collectPendingCodeRenderables(child))\n }\n\n return pending\n }\n\n const waitForPendingHighlights = async (pending: CodeRenderable[], timeoutMs: number): Promise => {\n await new Promise((resolve, reject) => {\n let settled = false\n const timeoutHandle = renderer.clock.setTimeout(() => {\n if (settled) {\n return\n }\n\n settled = true\n reject(new Error(\"ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting\"))\n }, timeoutMs)\n\n Promise.all(pending.map((renderable) => renderable.highlightingDone)).then(\n () => {\n if (settled) {\n return\n }\n\n settled = true\n renderer.clock.clearTimeout(timeoutHandle)\n resolve()\n },\n (error) => {\n if (settled) {\n return\n }\n\n settled = true\n renderer.clock.clearTimeout(timeoutHandle)\n reject(error)\n },\n )\n })\n }\n\n const renderSurface = (): void => {\n assertNotDestroyed()\n\n const width = renderer.width\n const widthMethod = renderer.widthMethod\n\n snapshotContext.width = width\n snapshotContext.widthMethod = widthMethod\n publicRoot.width = width\n\n const renderPass = (height: number): void => {\n snapshotContext.height = height\n internalRoot.resize(width, height)\n backingBuffer.resize(width, height)\n backingBuffer.clear(TRANSPARENT_RGBA)\n snapshotContext.frameId += 1\n internalRoot.render(backingBuffer, 0)\n }\n\n let targetHeight = Math.max(1, surfaceHeight)\n\n if (surfaceWidthMethod !== widthMethod) {\n backingBuffer.destroy()\n backingBuffer = OptimizedBuffer.create(width, targetHeight, widthMethod, {\n id: `scrollback-surface-buffer-${surfaceId}`,\n })\n } else {\n backingBuffer.resize(width, targetHeight)\n }\n\n for (let pass = 0; pass < MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES; pass += 1) {\n renderPass(targetHeight)\n\n const measuredHeight = Math.max(1, publicRoot.height)\n if (measuredHeight === targetHeight) {\n surfaceWidth = width\n surfaceHeight = measuredHeight\n surfaceWidthMethod = widthMethod\n hasRendered = true\n return\n }\n\n targetHeight = measuredHeight\n }\n\n renderPass(targetHeight)\n\n surfaceWidth = width\n surfaceHeight = targetHeight\n surfaceWidthMethod = widthMethod\n hasRendered = true\n }\n\n const settleSurface = async (timeoutMs: number = 2000): Promise => {\n assertNotDestroyed()\n\n const startedAt = renderer.clock.now()\n renderSurface()\n\n while (true) {\n assertNotDestroyed()\n\n const pending = collectPendingCodeRenderables(publicRoot)\n if (pending.length === 0) {\n return\n }\n\n const remainingMs = timeoutMs - (renderer.clock.now() - startedAt)\n if (remainingMs <= 0) {\n throw new Error(\"ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting\")\n }\n\n await waitForPendingHighlights(pending, remainingMs)\n assertNotDestroyed()\n renderSurface()\n }\n }\n\n const commitRows = (\n startRow: number,\n endRowExclusive: number,\n commitOptions: ScrollbackSurfaceCommitOptions = {},\n ): void => {\n assertNotDestroyed()\n assertRendered()\n assertGeometryStillCurrent()\n assertRowRange(startRow, endRowExclusive)\n\n if (startRow === endRowExclusive) {\n return\n }\n\n const rowCount = endRowExclusive - startRow\n const commitBuffer = OptimizedBuffer.create(surfaceWidth, rowCount, surfaceWidthMethod, {\n id: `scrollback-surface-commit-${surfaceId}`,\n })\n\n try {\n commitBuffer.drawFrameBuffer(0, 0, backingBuffer, 0, startRow, surfaceWidth, rowCount)\n\n renderer.enqueueRenderedScrollbackCommit({\n snapshot: commitBuffer,\n rowColumns: commitOptions.rowColumns,\n startOnNewLine: nextCommitStartOnNewLine,\n trailingNewline: commitOptions.trailingNewline ?? true,\n })\n\n nextCommitStartOnNewLine = false\n } catch (error) {\n commitBuffer.destroy()\n throw error\n }\n }\n\n const destroySurface = (): void => {\n if (surfaceDestroyed) {\n return\n }\n\n surfaceDestroyed = true\n renderer.off(CliRenderEvents.DESTROY, destroyListener)\n\n let destroyError: unknown = null\n\n try {\n internalRoot.destroyRecursively()\n } catch (error) {\n destroyError = error\n }\n\n try {\n backingBuffer.destroy()\n } catch (error) {\n if (destroyError === null) {\n destroyError = error\n }\n }\n\n renderContext.removeAllListeners()\n snapshotContext.removeAllListeners()\n\n if (destroyError !== null) {\n throw destroyError\n }\n }\n\n renderer.on(CliRenderEvents.DESTROY, destroyListener)\n\n return {\n get renderContext(): RenderContext {\n return renderContext\n },\n get root(): Renderable {\n return publicRoot\n },\n get width(): number {\n return surfaceWidth\n },\n get height(): number {\n return surfaceHeight\n },\n get isDestroyed(): boolean {\n return surfaceDestroyed\n },\n render: renderSurface,\n settle: settleSurface,\n commitRows,\n destroy: destroySurface,\n }\n }\n\n // writeToScrollback is a \"render to scrollback commit\" API, not a direct stdout\n // write. The callback returns a renderable tree, we render that tree into an\n // off-screen OptimizedBuffer, then enqueue the result as one ExternalOutputCommit.\n //\n // Why this shape exists:\n // - It keeps app-authored scrollback output in the same FIFO queue as captured\n // stdout, so ordering is deterministic even when both sources interleave.\n // - It lets the render loop batch multiple queued commits into one native frame,\n // which is the key mechanism that avoids repeated sync/cursor toggles (flicker).\n // - It reuses the normal renderable pipeline (layout, styling, grapheme shaping),\n // so scrollback payloads match what users see in the live UI.\n //\n // startOnNewLine and trailingNewline preserve newline intent when one logical\n // write spans multiple commits. startOnNewLine adds a newline before this commit\n // if the previous commit ended mid-row. trailingNewline adds a newline after this\n // commit's final row.\n //\n // Native split append uses these flags to avoid glued rows (missing newline), and\n // double-advance gaps (extra newline), while still appending payload and repainting\n // footer in the same frame.\n //\n // Side effects: throws if split-footer capture mode is not active, transfers\n // snapshot buffer ownership to the queue on success, triggers async render,\n // and invokes snapshot teardown when cleanup runs.\n public writeToScrollback(write: ScrollbackWriter): void {\n if (this._screenMode !== \"split-footer\" || this._externalOutputMode !== \"capture-stdout\") {\n throw new Error('writeToScrollback requires screenMode \"split-footer\" and externalOutputMode \"capture-stdout\"')\n }\n\n const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, this.height, this.widthMethod)\n const snapshot = write({\n width: this.width,\n widthMethod: this.widthMethod,\n tailColumn: this.getPendingSplitTailColumn(),\n renderContext: snapshotContext,\n })\n\n if (!snapshot || !snapshot.root) {\n throw new Error(\"writeToScrollback must return a snapshot root renderable\")\n }\n\n let renderFailed = false\n let snapshotRoot: RootRenderable | null = null\n let snapshotBuffer: OptimizedBuffer | null = null\n\n try {\n const rootRenderable = snapshot.root\n const snapshotWidth = this.getSnapshotWidth(snapshot.width, rootRenderable.width)\n const snapshotHeight = this.getSnapshotHeight(snapshot.height, rootRenderable.height)\n\n snapshotContext.width = snapshotWidth\n snapshotContext.height = snapshotHeight\n snapshotContext.widthMethod = this.widthMethod\n\n snapshotRoot = new RootRenderable(snapshotContext)\n snapshotBuffer = OptimizedBuffer.create(snapshotWidth, snapshotHeight, this.widthMethod, {\n id: \"scrollback-snapshot-commit\",\n })\n\n // Render through normal renderables so split scrollback output uses the same\n // text shaping/styling pipeline as the rest of the renderer.\n snapshotRoot.add(rootRenderable)\n snapshotRoot.render(snapshotBuffer, 0)\n this.enqueueRenderedScrollbackCommit({\n snapshot: snapshotBuffer,\n rowColumns: snapshot.rowColumns,\n startOnNewLine: snapshot.startOnNewLine,\n trailingNewline: snapshot.trailingNewline,\n })\n } catch (error) {\n renderFailed = true\n snapshotBuffer?.destroy()\n throw error\n } finally {\n let cleanupError: unknown | null = null\n\n try {\n if (snapshotRoot) {\n snapshotRoot.destroyRecursively()\n } else {\n snapshot.root.destroyRecursively()\n }\n } catch (error) {\n cleanupError = error\n }\n\n try {\n snapshot.teardown?.()\n } catch (error) {\n if (cleanupError === null) {\n cleanupError = error\n }\n }\n\n if (!renderFailed && cleanupError) {\n throw cleanupError\n }\n }\n }\n\n public resetSplitFooterForReplay(options: SplitFooterReplayResetOptions = {}): void {\n if (this._isDestroyed) return\n if (this._screenMode !== \"split-footer\" || this._externalOutputMode !== \"capture-stdout\") {\n throw new Error(\n 'resetSplitFooterForReplay requires screenMode \"split-footer\" and externalOutputMode \"capture-stdout\"',\n )\n }\n if (!this._terminalIsSetup || this._controlState === RendererControlState.EXPLICIT_SUSPENDED) {\n throw new Error(\"resetSplitFooterForReplay requires an active terminal\")\n }\n\n this.flushPendingSplitOutputBeforeTransition(true)\n this.externalOutputQueue.clear()\n this.abortSplitStartupCursorSeed()\n this.clearPendingSplitFooterTransition()\n this.resetSplitScrollback()\n this.currentRenderBuffer.clear(this.backgroundColor)\n this.nextRenderBuffer.clear(this.backgroundColor)\n this.forceFullRepaintRequested = true\n this.writeOut(\n ANSI.resetScrollRegion +\n ANSI.reset +\n ANSI.home +\n ANSI.clearScreen +\n (options.clearSavedLines ? ANSI.clearSavedLines : \"\") +\n ANSI.home,\n )\n this.requestRender()\n }\n\n private getSnapshotWidth(value: number | undefined, fallback: number): number {\n const rawValue = value ?? fallback\n\n if (!Number.isFinite(rawValue)) {\n throw new Error(\"writeToScrollback produced a non-finite width\")\n }\n\n return Math.min(Math.max(Math.trunc(rawValue), 1), Math.max(this.width, 1))\n }\n\n private getSnapshotHeight(value: number | undefined, fallback: number): number {\n const rawValue = value ?? fallback\n\n if (!Number.isFinite(rawValue)) {\n throw new Error(\"writeToScrollback produced a non-finite height\")\n }\n\n return Math.max(Math.trunc(rawValue), 1)\n }\n\n private getSnapshotRowWidths(snapshot: OptimizedBuffer, rowColumns: number): number[] {\n const widths: number[] = []\n const limit = Math.min(Math.max(Math.trunc(rowColumns), 0), snapshot.width)\n const chars = snapshot.buffers.char\n\n for (let y = 0; y < snapshot.height; y += 1) {\n let x = limit\n\n while (x > 0) {\n const cp = chars[y * snapshot.width + x - 1]\n if (cp === 0 || (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION) {\n x -= 1\n continue\n }\n\n break\n }\n\n widths.push(x)\n }\n\n return widths\n }\n\n private advanceSplitTailColumn(tailColumn: number, columns: number, width: number): number {\n if (columns <= 0) {\n return tailColumn\n }\n\n let tail = tailColumn\n let remaining = columns\n\n while (remaining > 0) {\n if (tail >= width) {\n tail = 0\n }\n\n const step = Math.min(remaining, width - tail)\n tail += step\n remaining -= step\n\n if (remaining > 0 && tail >= width) {\n tail = 0\n }\n }\n\n return tail\n }\n\n private getSplitTailColumnAfterCommit(\n commit: ExternalOutputCommit,\n initialTailColumn: number,\n width: number,\n ): number {\n let tailColumn = initialTailColumn\n\n if (commit.startOnNewLine && tailColumn > 0) {\n tailColumn = 0\n }\n\n const rowWidths = this.getSnapshotRowWidths(commit.snapshot, commit.rowColumns)\n for (const [index, rowWidth] of rowWidths.entries()) {\n tailColumn = this.advanceSplitTailColumn(tailColumn, rowWidth, width)\n if (index < rowWidths.length - 1 || commit.trailingNewline) {\n tailColumn = 0\n }\n }\n\n return tailColumn\n }\n\n private recordSplitCommit(commit: ExternalOutputCommit): void {\n this.splitTailColumn = this.getSplitTailColumnAfterCommit(commit, this.splitTailColumn, Math.max(this.width, 1))\n }\n\n private getPendingSplitTailColumn(): number {\n const width = Math.max(this.width, 1)\n let tailColumn = this.splitTailColumn\n\n for (const commit of this.externalOutputQueue.peek()) {\n tailColumn = this.getSplitTailColumnAfterCommit(commit, tailColumn, width)\n }\n\n return tailColumn\n }\n\n private enqueueRenderedScrollbackCommit(options: {\n snapshot: OptimizedBuffer\n rowColumns?: number\n startOnNewLine?: boolean\n trailingNewline?: boolean\n }): void {\n if (this._screenMode !== \"split-footer\" || this._externalOutputMode !== \"capture-stdout\") {\n throw new Error('scrollback commit requires screenMode \"split-footer\" and externalOutputMode \"capture-stdout\"')\n }\n\n const rowColumns = Math.min(\n Math.max(Math.trunc(options.rowColumns ?? options.snapshot.width), 0),\n options.snapshot.width,\n )\n\n this.enqueueSplitCommit({\n snapshot: options.snapshot,\n rowColumns,\n startOnNewLine: options.startOnNewLine ?? true,\n trailingNewline: options.trailingNewline ?? true,\n })\n\n this.requestRender()\n }\n\n private enqueueSplitCommit(commit: ExternalOutputCommit): void {\n this.externalOutputQueue.writeSnapshot(commit)\n if (this.listenerCount(CliRenderEvents.EXTERNAL_OUTPUT) > 0) {\n this.emit(CliRenderEvents.EXTERNAL_OUTPUT, commit)\n }\n }\n\n private createStdoutSnapshotCommit(line: string, trailingNewline: boolean): ExternalOutputCommit {\n // Convert captured stdout into the same commit shape used by writeToScrollback.\n // One commit format keeps split append behavior consistent across both sources.\n const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, 1, this.widthMethod)\n const maxWidth = Math.max(1, this.width)\n const lineCells = [...line]\n const rowColumns = Math.min(lineCells.length, maxWidth)\n const renderedLine = lineCells.slice(0, maxWidth).join(\"\")\n const snapshotRoot = new RootRenderable(snapshotContext)\n const snapshotRenderable = new TextRenderable(snapshotContext, {\n id: \"captured-stdout-snapshot\",\n position: \"absolute\",\n left: 0,\n top: 0,\n width: Math.max(1, rowColumns),\n height: 1,\n content: renderedLine,\n })\n const snapshotBuffer = OptimizedBuffer.create(Math.max(1, rowColumns), 1, this.widthMethod, {\n id: \"captured-stdout-snapshot\",\n })\n\n try {\n snapshotRoot.add(snapshotRenderable)\n snapshotRoot.render(snapshotBuffer, 0)\n return {\n snapshot: snapshotBuffer,\n rowColumns,\n startOnNewLine: false,\n trailingNewline,\n }\n } catch (error) {\n snapshotBuffer.destroy()\n throw error\n } finally {\n snapshotRoot.destroyRecursively()\n }\n }\n\n private splitStdoutRows(text: string): Array<{ line: string; trailingNewline: boolean }> {\n // Captured stdout arrives as an arbitrary byte stream, but split append commits\n // are row-based (line text + whether that row ended with '\\n'). We normalize\n // here because native split append expects already-decoded row intent, not raw\n // control characters.\n //\n // '\\r' must restart the in-progress row so in-place status updates (progress\n // bars/spinners) do not accumulate stale prefixes in scrollback. '\\n' commits\n // the row and marks newline intent for the final chunk of that logical row.\n const rows: Array<{ line: string; trailingNewline: boolean }> = []\n let current = \"\"\n\n for (const char of text) {\n if (char === \"\\r\") {\n current = \"\"\n continue\n }\n\n if (char === \"\\n\") {\n rows.push({ line: current, trailingNewline: true })\n current = \"\"\n continue\n }\n\n current += char\n }\n\n if (current.length > 0) {\n rows.push({ line: current, trailingNewline: false })\n }\n\n return rows\n }\n\n private createStdoutSnapshotCommits(text: string): ExternalOutputCommit[] {\n if (text.length === 0) {\n return []\n }\n\n // Chunk captured stdout into width-bounded row commits so each commit is a\n // small, deterministic append step. This keeps bursty output smooth while\n // preserving newline ownership on the final chunk of each logical row.\n const commits: ExternalOutputCommit[] = []\n // Split commits are row-oriented snapshots. We chunk by renderer width so each\n // commit maps to a single logical terminal row append operation.\n const chunkWidth = Math.max(1, this.width)\n for (const row of this.splitStdoutRows(text)) {\n const rowCells = [...row.line]\n if (rowCells.length === 0) {\n // Preserve empty-line writes: newline-only chunks still need a commit so\n // split scrollback state advances correctly in native code.\n commits.push(this.createStdoutSnapshotCommit(\"\", row.trailingNewline))\n continue\n }\n\n let offset = 0\n while (offset < rowCells.length) {\n const chunk = rowCells.slice(offset, offset + chunkWidth).join(\"\")\n offset += chunkWidth\n const isLastChunk = offset >= rowCells.length\n // Only the final wrapped chunk carries newline intent.\n commits.push(this.createStdoutSnapshotCommit(chunk, isLastChunk ? row.trailingNewline : false))\n }\n }\n\n return commits\n }\n\n private flushPendingSplitCommits(\n forceFooterRepaint: boolean = false,\n drainAll: boolean = false,\n ): \"rendered\" | \"backpressured\" | \"failed\" {\n // Drain only a bounded prefix so one JS render pass maps to one native frame.\n // Remaining commits are intentionally left queued and rendered on subsequent\n // ticks to avoid giant multi-thousand-cell frames that can flicker.\n const commits = this.externalOutputQueue.peek(drainAll ? Number.POSITIVE_INFINITY : this.maxSplitCommitsPerFrame)\n let hasCommittedOutput = false\n const lastCommitIndex = commits.length - 1\n let acceptedCommits = 0\n let nativeBackpressured = false\n let nativeFailed = false\n\n for (const [index, commit] of commits.entries()) {\n // Force repaint only on the last commit in a frame. Repainting after every\n // chunk negates batching and reintroduces duplicate clear/move traffic.\n const forceCommit = forceFooterRepaint && index === lastCommitIndex\n // beginFrame/finalizeFrame tell native code whether this commit opens or\n // closes the shared frame envelope. Intermediate commits append payload only.\n const beginFrame = index === 0\n const finalizeFrame = index === lastCommitIndex\n\n // Keep split append policy in native code so every producer (captured stdout\n // and writeToScrollback) shares the same cursor/scrollback invariants.\n const nativeResult = this.lib.commitSplitFooterSnapshot(\n this.rendererPtr,\n commit.snapshot,\n commit.rowColumns,\n commit.startOnNewLine,\n commit.trailingNewline,\n this.getSplitPinnedRenderOffset(),\n forceCommit,\n beginFrame,\n finalizeFrame,\n )\n if (nativeResult.status === NATIVE_RENDER_STATUS_SKIPPED) {\n nativeBackpressured = true\n break\n }\n\n if (nativeResult.status === NATIVE_RENDER_STATUS_FAILED) {\n nativeFailed = true\n break\n }\n\n this.renderOffset = nativeResult.renderOffset\n this.recordSplitCommit(commit)\n hasCommittedOutput = true\n acceptedCommits++\n }\n\n if (acceptedCommits > 0) {\n this.externalOutputQueue.drop(acceptedCommits)\n }\n\n if (nativeFailed) {\n return this.reportNativeRenderFailure()\n }\n\n if (nativeBackpressured) {\n this.scheduleRenderAfterFeedIdle()\n return \"backpressured\"\n }\n\n if (!hasCommittedOutput) {\n const nativeResult = this.lib.repaintSplitFooter(\n this.rendererPtr,\n this.getSplitPinnedRenderOffset(),\n forceFooterRepaint,\n )\n if (nativeResult.status === NATIVE_RENDER_STATUS_SKIPPED) {\n this.scheduleRenderAfterFeedIdle()\n return \"backpressured\"\n }\n if (nativeResult.status === NATIVE_RENDER_STATUS_FAILED) {\n return this.reportNativeRenderFailure()\n }\n this.renderOffset = nativeResult.renderOffset\n }\n\n this.pendingSplitFooterTransition = null\n\n if (this.externalOutputQueue.size > 0) {\n // Preserve FIFO ordering without doing unbounded work in one tick.\n // This keeps sustained stdout bursts smooth instead of blocking on one frame.\n this.requestRender()\n } else {\n this.applyPendingExternalOutputModeIfReady()\n }\n\n return \"rendered\"\n }\n\n private interceptStdoutWrite = (chunk: any, encoding?: any, callback?: any): boolean => {\n const resolvedCallback = typeof encoding === \"function\" ? encoding : callback\n const resolvedEncoding = typeof encoding === \"string\" ? encoding : undefined\n const text = typeof chunk === \"string\" ? chunk : (chunk?.toString(resolvedEncoding) ?? \"\")\n\n if (this._externalOutputMode === \"capture-stdout\" && this._screenMode === \"split-footer\" && this._splitHeight > 0) {\n // Capture mode intentionally diverts stdout into split commit snapshots\n // instead of writing directly to process stdout. Native flushing will append\n // and repaint in one controlled frame, which is what avoids footer flicker.\n const commits = this.createStdoutSnapshotCommits(text)\n for (const commit of commits) {\n this.enqueueSplitCommit(commit)\n }\n\n if (commits.length > 0) {\n // Defer actual terminal writes to the render loop so commits can be batched.\n this.requestRender()\n }\n }\n\n if (typeof resolvedCallback === \"function\") {\n process.nextTick(resolvedCallback)\n }\n\n return true\n }\n\n private getSplitPinnedRenderOffset(): number {\n return this._screenMode === \"split-footer\" ? Math.max(this._terminalHeight - this._splitHeight, 0) : 0\n }\n\n private getSplitCursorSeedRows(): number {\n const cursorState = this.lib.getCursorState(this.rendererPtr)\n const cursorRow = Number.isFinite(cursorState.y) ? Math.max(Math.trunc(cursorState.y), 1) : 1\n return Math.min(cursorRow, Math.max(this._terminalHeight, 1))\n }\n\n private isSplitCursorSeedFrameBlocked(): boolean {\n return (\n this._screenMode === \"split-footer\" &&\n this._externalOutputMode === \"capture-stdout\" &&\n this._splitHeight > 0 &&\n this.pendingSplitStartupCursorSeed &&\n this.splitStartupSeedTimeoutId !== null\n )\n }\n\n private canFlushSplitOutputBeforeTransition(allowSuspended: boolean = false, allowUnsetup: boolean = false): boolean {\n return (\n (this._terminalIsSetup || allowUnsetup) &&\n (allowSuspended || this._controlState !== RendererControlState.EXPLICIT_SUSPENDED) &&\n !this.isSplitCursorSeedFrameBlocked()\n )\n }\n\n private clearSplitStartupCursorSeed(): void {\n this.pendingSplitStartupCursorSeed = false\n if (this.splitStartupSeedTimeoutId !== null) {\n this.clock.clearTimeout(this.splitStartupSeedTimeoutId)\n this.splitStartupSeedTimeoutId = null\n }\n }\n\n private abortSplitStartupCursorSeed(): void {\n this.clearSplitStartupCursorSeed()\n this.stdinParser?.abortPendingStartupCursorCpr()\n this.updateStdinParserProtocolContext({ startupCursorCprActive: false })\n }\n\n private flushPendingSplitOutputBeforeTransition(\n forceFooterRepaint: boolean = false,\n options: { allowSuspended?: boolean; allowPassthrough?: boolean; allowUnsetup?: boolean } = {},\n ): void {\n const hasDeferredCapturedOutput = this.externalOutputQueue.size > 0 || this.pendingExternalOutputMode !== null\n if (\n this._screenMode !== \"split-footer\" ||\n this._splitHeight <= 0 ||\n (this._externalOutputMode !== \"capture-stdout\" && !(options.allowPassthrough && hasDeferredCapturedOutput))\n ) {\n return\n }\n\n if (!this.canFlushSplitOutputBeforeTransition(options.allowSuspended ?? false, options.allowUnsetup ?? false)) {\n return\n }\n\n if (this.externalOutputQueue.size === 0 && !forceFooterRepaint) {\n this.applyPendingExternalOutputModeIfReady()\n return\n }\n\n this.flushPendingSplitCommits(this._externalOutputMode === \"capture-stdout\" ? forceFooterRepaint : false, true)\n }\n\n private resetSplitScrollback(seedRows: number = 0): void {\n this.splitTailColumn = 0\n this.renderOffset = this.lib.resetSplitScrollback(this.rendererPtr, seedRows, this.getSplitPinnedRenderOffset())\n }\n\n private syncSplitScrollback(): void {\n this.renderOffset = this.lib.syncSplitScrollback(this.rendererPtr, this.getSplitPinnedRenderOffset())\n }\n\n private getSplitOutputOffset(surfaceOffset: number = this.renderOffset): number {\n return this.lib.getSplitOutputOffset(this.rendererPtr, surfaceOffset)\n }\n\n private clearPendingSplitFooterTransition(): void {\n if (this.pendingSplitFooterTransition === null) {\n return\n }\n\n this.pendingSplitFooterTransition = null\n this.lib.clearPendingSplitFooterTransition(this.rendererPtr)\n }\n\n private setPendingSplitFooterTransition(transition: PendingSplitFooterTransition): void {\n this.pendingSplitFooterTransition = transition\n this.lib.setPendingSplitFooterTransition(\n this.rendererPtr,\n transition.mode === \"viewport-scroll\" ? 1 : 2,\n transition.sourceTopLine,\n transition.sourceHeight,\n transition.targetTopLine,\n transition.targetHeight,\n transition.scrollLines ?? 0,\n )\n }\n\n private syncSplitFooterState(): void {\n const splitActive = this._screenMode === \"split-footer\" && this._splitHeight > 0\n\n if (!splitActive) {\n this.clearPendingSplitFooterTransition()\n this.splitTailColumn = 0\n this.lib.resetSplitScrollback(this.rendererPtr, 0, 0)\n this.renderOffset = 0\n this.lib.setRenderOffset(this.rendererPtr, this.renderOffset)\n return\n }\n\n if (this._externalOutputMode === \"capture-stdout\") {\n this.syncSplitScrollback()\n } else {\n this.clearPendingSplitFooterTransition()\n this.splitTailColumn = 0\n this.lib.resetSplitScrollback(this.rendererPtr, 0, 0)\n this.renderOffset = this.getSplitPinnedRenderOffset()\n this.lib.setRenderOffset(this.rendererPtr, this.renderOffset)\n }\n }\n\n private clearStaleSplitSurfaceRows(\n previousTopLine: number,\n previousHeight: number,\n nextTopLine: number,\n nextHeight: number,\n ): void {\n if (!this._terminalIsSetup || previousHeight <= 0 || this._terminalHeight <= 0) {\n return\n }\n\n const terminalBottom = this._terminalHeight\n const previousStart = Math.max(1, previousTopLine)\n const previousEnd = Math.min(terminalBottom, previousTopLine + previousHeight - 1)\n\n if (previousEnd < previousStart) {\n return\n }\n\n const nextStart = Math.max(1, nextTopLine)\n const nextEnd = Math.min(terminalBottom, nextTopLine + Math.max(nextHeight, 0) - 1)\n\n let clear = \"\"\n for (let line = previousStart; line <= previousEnd; line += 1) {\n if (line >= nextStart && line <= nextEnd) {\n continue\n }\n\n clear += `${ANSI.moveCursor(line, 1)}\\x1b[2K`\n }\n\n if (clear.length > 0) {\n this.writeOut(clear)\n }\n }\n\n private applyScreenMode(screenMode: ScreenMode, emitResize: boolean = true, requestRender: boolean = true): void {\n const prevScreenMode = this._screenMode\n const prevSplitHeight = this._splitHeight\n const nextGeometry = calculateRenderGeometry(\n screenMode,\n this._terminalWidth,\n this._terminalHeight,\n this._footerHeight,\n )\n const nextSplitHeight = nextGeometry.effectiveFooterHeight\n\n if (prevScreenMode === screenMode && prevSplitHeight === nextSplitHeight) {\n return\n }\n\n const terminalWritable = this._terminalIsSetup && this._controlState !== RendererControlState.EXPLICIT_SUSPENDED\n const prevUseAlternateScreen = prevScreenMode === \"alternate-screen\"\n const nextUseAlternateScreen = screenMode === \"alternate-screen\"\n const terminalScreenModeChanged = this._terminalIsSetup && prevUseAlternateScreen !== nextUseAlternateScreen\n const leavingSplitFooter = prevSplitHeight > 0 && nextSplitHeight === 0\n\n if (terminalWritable && prevSplitHeight > 0) {\n this.flushPendingSplitOutputBeforeTransition()\n }\n\n const previousSurfaceTopLine = this.renderOffset + 1\n const shouldDeferSplitFooterResizeTransition =\n this._terminalIsSetup &&\n prevScreenMode === \"split-footer\" &&\n screenMode === \"split-footer\" &&\n this._externalOutputMode === \"capture-stdout\" &&\n prevSplitHeight > 0 &&\n nextSplitHeight > 0 &&\n !terminalScreenModeChanged\n const splitStartupSeedBlocksFirstNativeFrame =\n this.pendingSplitStartupCursorSeed && this.splitStartupSeedTimeoutId !== null\n const splitTransitionSourceTopLine = this.pendingSplitFooterTransition?.sourceTopLine ?? previousSurfaceTopLine\n const splitTransitionSourceHeight = this.pendingSplitFooterTransition?.sourceHeight ?? prevSplitHeight\n const splitTransitionSourceSurfaceOffset = Math.max(splitTransitionSourceTopLine - 1, 0)\n const splitTransitionSourceOutputOffset =\n prevScreenMode === \"split-footer\" && prevSplitHeight > 0 && this._externalOutputMode === \"capture-stdout\"\n ? this.getSplitOutputOffset(splitTransitionSourceSurfaceOffset)\n : splitTransitionSourceSurfaceOffset\n const nextPinnedRenderOffset = nextGeometry.renderOffset\n const nextSplitOutputOffset =\n screenMode === \"split-footer\" && nextSplitHeight > 0 && this._externalOutputMode === \"capture-stdout\"\n ? this.getSplitOutputOffset(nextPinnedRenderOffset)\n : nextPinnedRenderOffset\n const pendingSplitFooterTransition = this.pendingSplitFooterTransition\n const pendingSplitFooterReturn =\n pendingSplitFooterTransition !== null && nextSplitHeight === splitTransitionSourceHeight\n const pendingSplitFooterViewportReturn =\n pendingSplitFooterReturn &&\n pendingSplitFooterTransition.mode === \"viewport-scroll\" &&\n (pendingSplitFooterTransition.scrollLines ?? 0) > 0\n const shrinkingSplitFooter = nextSplitHeight > 0 && nextSplitHeight < splitTransitionSourceHeight\n const growingSplitFooter = nextSplitHeight > splitTransitionSourceHeight && splitTransitionSourceHeight > 0\n const nextSplitSurfaceOffset =\n screenMode !== \"split-footer\" || nextSplitHeight === 0\n ? 0\n : pendingSplitFooterViewportReturn\n ? pendingSplitFooterTransition.targetTopLine - 1\n : pendingSplitFooterReturn\n ? splitTransitionSourceSurfaceOffset\n : shrinkingSplitFooter && splitTransitionSourceSurfaceOffset > 0\n ? splitTransitionSourceSurfaceOffset\n : shrinkingSplitFooter\n ? nextSplitOutputOffset\n : growingSplitFooter\n ? Math.max(\n nextSplitOutputOffset,\n Math.min(splitTransitionSourceSurfaceOffset, nextPinnedRenderOffset),\n )\n : nextPinnedRenderOffset\n const splitTransitionTargetTopLine = nextSplitSurfaceOffset + 1\n const splitViewportScrollLines = pendingSplitFooterViewportReturn\n ? (pendingSplitFooterTransition.scrollLines ?? 0)\n : nextSplitHeight > 0 && !pendingSplitFooterReturn\n ? Math.max(splitTransitionSourceOutputOffset - nextSplitOutputOffset, 0)\n : 0\n const splitTransitionMode =\n (!shrinkingSplitFooter || pendingSplitFooterViewportReturn) && splitViewportScrollLines > 0\n ? \"viewport-scroll\"\n : \"clear-stale-rows\"\n const splitFooterSurfaceMovesDown = nextSplitSurfaceOffset > splitTransitionSourceSurfaceOffset\n const splitFooterSurfaceLeavesStaleRows = splitFooterSurfaceMovesDown || shrinkingSplitFooter\n const shouldClearSplitSurfaceRowsImmediately =\n terminalWritable &&\n !terminalScreenModeChanged &&\n !shouldDeferSplitFooterResizeTransition &&\n splitFooterSurfaceLeavesStaleRows &&\n nextSplitHeight > 0\n\n if (terminalWritable && leavingSplitFooter) {\n this.clearPendingSplitFooterTransition()\n this.renderOffset = 0\n this.lib.setRenderOffset(this.rendererPtr, 0)\n }\n\n if (terminalWritable && !terminalScreenModeChanged && !shouldDeferSplitFooterResizeTransition) {\n if (prevSplitHeight === 0 && nextSplitHeight > 0) {\n const freedLines = this._terminalHeight - nextSplitHeight\n const scrollDown = ANSI.scrollDown(freedLines)\n this.writeOut(scrollDown)\n } else if (splitViewportScrollLines > 0) {\n const additionalLines = splitViewportScrollLines\n const scrollUp = ANSI.scrollUp(additionalLines)\n this.writeOut(scrollUp)\n }\n }\n\n this._screenMode = screenMode\n this._splitHeight = nextSplitHeight\n this.width = nextGeometry.renderWidth\n this.height = nextGeometry.renderHeight\n\n this.lib.resizeRenderer(this.rendererPtr, this.width, this.height)\n\n if (this._screenMode === \"split-footer\" && this._externalOutputMode === \"capture-stdout\") {\n if (prevScreenMode !== \"split-footer\") {\n this.resetSplitScrollback(this.getSplitCursorSeedRows())\n } else {\n this.renderOffset = nextSplitSurfaceOffset\n this.lib.setRenderOffset(this.rendererPtr, this.renderOffset)\n }\n\n if (shouldDeferSplitFooterResizeTransition) {\n if (splitStartupSeedBlocksFirstNativeFrame) {\n this.clearPendingSplitFooterTransition()\n } else {\n this.setPendingSplitFooterTransition({\n mode: splitTransitionMode,\n sourceTopLine: splitTransitionSourceTopLine,\n sourceHeight: splitTransitionSourceHeight,\n targetTopLine: splitTransitionTargetTopLine,\n targetHeight: nextSplitHeight,\n scrollLines: splitViewportScrollLines,\n })\n }\n this.forceFullRepaintRequested = true\n } else if (shouldClearSplitSurfaceRowsImmediately) {\n this.clearPendingSplitFooterTransition()\n this.clearStaleSplitSurfaceRows(\n splitTransitionSourceTopLine,\n splitTransitionSourceHeight,\n splitTransitionTargetTopLine,\n nextSplitHeight,\n )\n } else {\n this.clearPendingSplitFooterTransition()\n }\n } else {\n this.syncSplitFooterState()\n if (shouldClearSplitSurfaceRowsImmediately) {\n this.clearStaleSplitSurfaceRows(\n splitTransitionSourceTopLine,\n splitTransitionSourceHeight,\n this.renderOffset + 1,\n nextSplitHeight,\n )\n }\n }\n\n this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr)\n this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr)\n\n this._console.resize(this.width, this.height)\n this.root.resize(this.width, this.height)\n\n if (terminalScreenModeChanged) {\n if (terminalWritable) {\n this.lib.suspendRenderer(this.rendererPtr)\n this.lib.setupTerminal(this.rendererPtr, nextUseAlternateScreen)\n this.pendingSuspendedTerminalSetup = false\n } else {\n this.pendingSuspendedTerminalSetup = true\n }\n\n if (terminalWritable && this._useMouse) {\n this.enableMouse()\n }\n }\n\n if (emitResize) {\n this.emit(CliRenderEvents.RESIZE, this.width, this.height)\n }\n\n if (requestRender) {\n this.requestRender()\n }\n }\n\n // TODO: Move this to native\n private flushStdoutCache(space: number, force: boolean = false): boolean {\n if (this.externalOutputQueue.size === 0 && !force) return false\n\n const outputCommits = this.externalOutputQueue.claim()\n let output = \"\"\n for (const commit of outputCommits) {\n output += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}]\\n`\n commit.snapshot.destroy()\n }\n\n const rendererStartLine = this.renderOffset + 1\n const flush = ANSI.moveCursorAndClear(rendererStartLine, 1)\n\n const outputLine = this.renderOffset + 1\n const move = ANSI.moveCursor(outputLine, 1)\n\n let clear = \"\"\n if (space > 0) {\n const backgroundColor = this.backgroundColor.toInts()\n const newlines = \" \".repeat(this.width) + \"\\n\".repeat(space)\n // Check if background is transparent (alpha = 0)\n if (backgroundColor[3] === 0) {\n clear = newlines\n } else {\n clear =\n ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) +\n newlines +\n ANSI.resetBackground\n }\n }\n\n this.writeOut(flush + move + output + clear)\n\n return true\n }\n\n private enableMouse(): void {\n this._useMouse = true\n this.lib.enableMouse(this.rendererPtr, this.enableMouseMovement)\n }\n\n private disableMouse(): void {\n this._useMouse = false\n this.setCapturedRenderable(undefined)\n this.stdinParser?.resetMouseState()\n this.lib.disableMouse(this.rendererPtr)\n }\n\n public enableKittyKeyboard(flags: number = 0b00011): void {\n this.lib.enableKittyKeyboard(this.rendererPtr, flags)\n this.updateStdinParserProtocolContext({ kittyKeyboardEnabled: true })\n }\n\n public disableKittyKeyboard(): void {\n this.lib.disableKittyKeyboard(this.rendererPtr)\n this.updateStdinParserProtocolContext({ kittyKeyboardEnabled: false }, true)\n }\n\n public set useThread(useThread: boolean) {\n this._useThread = useThread\n this.lib.setUseThread(this.rendererPtr, useThread)\n }\n\n // TODO: All input management may move to native when zig finally has async io support again,\n // without rolling a full event loop\n public async setupTerminal(): Promise {\n if (this._terminalIsSetup) return\n this._terminalIsSetup = true\n\n const startupCursorCprActive = this._screenMode === \"split-footer\" && this._externalOutputMode === \"capture-stdout\"\n this.updateStdinParserProtocolContext({\n privateCapabilityRepliesActive: true,\n explicitWidthCprActive: true,\n startupCursorCprActive,\n })\n this.lib.setupTerminal(this.rendererPtr, this._screenMode === \"alternate-screen\")\n this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr)\n\n if (this.debugOverlay.enabled) {\n this.lib.setDebugOverlay(this.rendererPtr, true, this.debugOverlay.corner)\n if (!this.memorySnapshotInterval) {\n this.memorySnapshotInterval = 3000\n this.startMemorySnapshotTimer()\n this.automaticMemorySnapshot = true\n }\n }\n\n this.capabilityTimeoutId = this.clock.setTimeout(() => {\n this.capabilityTimeoutId = null\n this.clearSplitStartupCursorSeed()\n\n if (this._screenMode === \"split-footer\" && this._externalOutputMode === \"capture-stdout\") {\n this.requestRender()\n }\n\n this.removeInputHandler(this.capabilityHandler)\n this.updateStdinParserProtocolContext(\n {\n privateCapabilityRepliesActive: false,\n explicitWidthCprActive: false,\n startupCursorCprActive: false,\n },\n true,\n )\n this.resolveXtVersionWaiters()\n }, 5000)\n\n if (this._useMouse) {\n this.enableMouse()\n }\n\n if (this._screenMode === \"split-footer\" && this._externalOutputMode === \"capture-stdout\") {\n this.pendingSplitStartupCursorSeed = true\n\n if (this.splitStartupSeedTimeoutId !== null) {\n this.clock.clearTimeout(this.splitStartupSeedTimeoutId)\n }\n\n this.splitStartupSeedTimeoutId = this.clock.setTimeout(() => {\n this.splitStartupSeedTimeoutId = null\n\n if (!this.pendingSplitStartupCursorSeed) {\n return\n }\n\n this.updateStdinParserProtocolContext({ startupCursorCprActive: false })\n\n if (this._screenMode === \"split-footer\" && this._externalOutputMode === \"capture-stdout\") {\n this.requestRender()\n }\n\n this.flushPendingSplitOutputBeforeTransition(false, { allowPassthrough: true })\n }, 120)\n }\n\n this.queryPixelResolution()\n if (this.shouldSyncNativePaletteState()) {\n this.refreshPalette()\n }\n\n // Feed-backed startup writes are async relative to the JS Writable. Wait\n // until they drain so callers can safely destroy immediately after\n // createCliRenderer() resolves.\n if (this._feed?.isBackpressured()) {\n await this._feed.idle()\n }\n }\n\n private stdinListener: (chunk: Buffer | string) => void = ((chunk: Buffer | string) => {\n const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n if (!this.stdinParser) return\n\n try {\n this.stdinParser.push(data)\n this.drainStdinParser()\n } catch (error) {\n this.handleStdinParserFailure(error)\n }\n }).bind(this)\n\n public addInputHandler(handler: (sequence: string) => boolean): void {\n this.sequenceHandlers.push(handler)\n }\n\n public prependInputHandler(handler: (sequence: string) => boolean): void {\n this.sequenceHandlers.unshift(handler)\n }\n\n public removeInputHandler(handler: (sequence: string) => boolean): void {\n this.sequenceHandlers = this.sequenceHandlers.filter((candidate) => candidate !== handler)\n }\n\n private updateStdinParserProtocolContext(patch: Partial, drain = false): void {\n if (!this.stdinParser) return\n this.stdinParser.updateProtocolContext(patch)\n if (drain) this.drainStdinParser()\n }\n\n public subscribeOsc(handler: (sequence: string) => void): () => void {\n this.oscSubscribers.add(handler)\n return () => {\n this.oscSubscribers.delete(handler)\n }\n }\n\n private processCapabilitySequence(sequence: string, hasCursorReport: boolean): boolean {\n const hasStandardCapabilitySignature = isCapabilityResponse(sequence)\n const shouldProcessAsCapability =\n hasStandardCapabilitySignature || (hasCursorReport && this.capabilityTimeoutId !== null)\n\n if (!shouldProcessAsCapability) {\n return false\n }\n\n this.lib.processCapabilityResponse(this.rendererPtr, sequence)\n this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr)\n if (this._capabilities?.terminal?.from_xtversion) {\n this.resolveXtVersionWaiters()\n }\n if (hasStandardCapabilitySignature) {\n this.forceFullRepaintRequested = true\n this.requestRender()\n }\n this.emit(CliRenderEvents.CAPABILITIES, this._capabilities)\n\n const hadPendingSplitStartupCursorSeed = this.pendingSplitStartupCursorSeed\n\n if (\n hadPendingSplitStartupCursorSeed &&\n hasCursorReport &&\n this._screenMode === \"split-footer\" &&\n this._externalOutputMode === \"capture-stdout\"\n ) {\n this.resetSplitScrollback(this.getSplitCursorSeedRows())\n this.clearPendingSplitFooterTransition()\n this.clearSplitStartupCursorSeed()\n this.updateStdinParserProtocolContext({ startupCursorCprActive: false })\n\n this.requestRender()\n if (this.pendingExternalOutputMode === \"passthrough\") {\n this.flushPendingSplitOutputBeforeTransition()\n }\n }\n\n const consumeStartupCursorReport =\n hadPendingSplitStartupCursorSeed && hasCursorReport && this.splitStartupSeedTimeoutId !== null\n\n return hasStandardCapabilitySignature || consumeStartupCursorReport\n }\n\n private capabilityHandler: (sequence: string) => boolean = ((sequence: string) => {\n return this.processCapabilitySequence(sequence, false)\n }).bind(this)\n\n private focusHandler: (sequence: string) => boolean = ((sequence: string) => {\n if (sequence === \"\\x1b[I\") {\n // When the terminal regains focus, some terminal emulators (notably\n // Windows Terminal / ConPTY) may have stripped DEC private modes like\n // mouse tracking, bracketed paste, and focus tracking itself while the\n // window was unfocused.\n if (this.shouldRestoreModesOnNextFocus) {\n this.lib.restoreTerminalModes(this.rendererPtr)\n this.shouldRestoreModesOnNextFocus = false\n }\n if (this._terminalFocusState !== true) {\n this._terminalFocusState = true\n this.emit(CliRenderEvents.FOCUS)\n }\n return true\n }\n if (sequence === \"\\x1b[O\") {\n this.shouldRestoreModesOnNextFocus = true\n if (this._terminalFocusState !== false) {\n this._terminalFocusState = false\n this.emit(CliRenderEvents.BLUR)\n }\n return true\n }\n return false\n }).bind(this)\n\n private dispatchSequenceHandlers(sequence: string): boolean {\n if (this._debugModeEnabled) {\n this._debugInputs.push({\n timestamp: new Date().toISOString(),\n sequence,\n })\n }\n\n for (const handler of this.sequenceHandlers) {\n if (handler(sequence)) {\n return true\n }\n }\n\n return false\n }\n\n private drainStdinParser(): void {\n if (!this.stdinParser) return\n\n this.stdinParser.drain((event) => {\n this.handleStdinEvent(event)\n })\n }\n\n private handleStdinEvent(event: StdinEvent): void {\n switch (event.type) {\n case \"key\":\n if (this.dispatchSequenceHandlers(event.raw)) {\n return\n }\n\n this._keyHandler.processParsedKey(event.key)\n return\n case \"mouse\":\n if (this._useMouse && this.processSingleMouseEvent(event.event)) {\n return\n }\n\n this.dispatchSequenceHandlers(event.raw)\n return\n case \"paste\":\n this._keyHandler.processPaste(event.bytes, event.metadata)\n return\n case \"response\":\n if (event.protocol === \"osc\") {\n for (const subscriber of this.oscSubscribers) {\n subscriber(event.sequence)\n }\n }\n\n if (event.protocol === \"cpr\" && this.processCapabilitySequence(event.sequence, true)) {\n return\n }\n\n this.dispatchSequenceHandlers(event.sequence)\n return\n }\n }\n\n private handleStdinParserFailure(error: unknown): void {\n if (!this.hasLoggedStdinParserError) {\n this.hasLoggedStdinParserError = true\n if (process.env.NODE_ENV !== \"test\") {\n console.error(\"[stdin-parser-error] parser failure, resetting parser\", error)\n }\n }\n\n try {\n this.stdinParser?.reset()\n } catch (resetError) {\n console.error(\"stdin parser reset failed after parser error\", resetError)\n }\n }\n\n private setupInput(): void {\n for (const handler of this.prependedInputHandlers) {\n this.addInputHandler(handler)\n }\n\n this.addInputHandler((sequence: string) => {\n if (isPixelResolutionResponse(sequence) && this.waitingForPixelResolution) {\n const resolution = parsePixelResolution(sequence)\n if (resolution) {\n this._resolution = resolution\n }\n this.waitingForPixelResolution = false\n this.updateStdinParserProtocolContext({ pixelResolutionQueryActive: false }, true)\n return true\n }\n return false\n })\n this.addInputHandler(this.capabilityHandler)\n this.addInputHandler(this.focusHandler)\n this.addInputHandler(this.themeModeHandler)\n\n if (this.stdin.setRawMode) {\n this.stdin.setRawMode(true)\n }\n\n this.stdin.on(\"data\", this.stdinListener)\n this.stdin.resume()\n }\n\n private dispatchMouseEvent(\n target: Renderable,\n attributes: RawMouseEvent & { source?: Renderable; isDragging?: boolean },\n ): MouseEvent {\n const event = new MouseEvent(target, attributes)\n target.processMouseEvent(event)\n\n if (this.autoFocus && event.type === \"down\" && event.button === MouseButton.LEFT && !event.defaultPrevented) {\n let current: Renderable | null = target\n while (current) {\n if (current.focusable) {\n current.focus()\n break\n }\n current = current.parent\n }\n }\n\n return event\n }\n\n private processSingleMouseEvent(mouseEvent: RawMouseEvent): boolean {\n if (this._splitHeight > 0) {\n if (mouseEvent.y < this.renderOffset) {\n return false\n }\n mouseEvent.y -= this.renderOffset\n }\n\n this._latestPointer.x = mouseEvent.x\n this._latestPointer.y = mouseEvent.y\n this._hasPointer = true\n this._lastPointerModifiers = mouseEvent.modifiers\n\n if (this._console.visible) {\n const consoleBounds = this._console.bounds\n if (\n mouseEvent.x >= consoleBounds.x &&\n mouseEvent.x < consoleBounds.x + consoleBounds.width &&\n mouseEvent.y >= consoleBounds.y &&\n mouseEvent.y < consoleBounds.y + consoleBounds.height\n ) {\n const event = new MouseEvent(null, mouseEvent)\n const handled = this._console.handleMouse(event)\n if (handled) return true\n }\n }\n\n if (mouseEvent.type === \"scroll\") {\n const maybeRenderableId = this.hitTest(mouseEvent.x, mouseEvent.y)\n const maybeRenderable = Renderable.renderablesByNumber.get(maybeRenderableId)\n const fallbackTarget =\n this._currentFocusedRenderable &&\n !this._currentFocusedRenderable.isDestroyed &&\n this._currentFocusedRenderable.focused\n ? this._currentFocusedRenderable\n : null\n const scrollTarget = maybeRenderable ?? fallbackTarget\n\n if (scrollTarget) {\n const event = new MouseEvent(scrollTarget, mouseEvent)\n scrollTarget.processMouseEvent(event)\n }\n return true\n }\n\n const maybeRenderableId = this.hitTest(mouseEvent.x, mouseEvent.y)\n const sameElement = maybeRenderableId === this.lastOverRenderableNum\n this.lastOverRenderableNum = maybeRenderableId\n const maybeRenderable = Renderable.renderablesByNumber.get(maybeRenderableId)\n\n if (\n mouseEvent.type === \"down\" &&\n mouseEvent.button === MouseButton.LEFT &&\n !this.currentSelection?.isDragging &&\n !mouseEvent.modifiers.ctrl\n ) {\n const canStartSelection = Boolean(\n maybeRenderable &&\n maybeRenderable.selectable &&\n !maybeRenderable.isDestroyed &&\n maybeRenderable.shouldStartSelection(mouseEvent.x, mouseEvent.y),\n )\n\n if (canStartSelection && maybeRenderable) {\n this.startSelection(maybeRenderable, mouseEvent.x, mouseEvent.y)\n this.dispatchMouseEvent(maybeRenderable, mouseEvent)\n return true\n }\n }\n\n if (mouseEvent.type === \"drag\" && this.currentSelection?.isDragging) {\n this.updateSelection(maybeRenderable, mouseEvent.x, mouseEvent.y)\n\n if (maybeRenderable) {\n const event = new MouseEvent(maybeRenderable, {\n ...mouseEvent,\n isDragging: true,\n })\n maybeRenderable.processMouseEvent(event)\n }\n\n return true\n }\n\n if (mouseEvent.type === \"up\" && this.currentSelection?.isDragging) {\n if (maybeRenderable) {\n const event = new MouseEvent(maybeRenderable, {\n ...mouseEvent,\n isDragging: true,\n })\n maybeRenderable.processMouseEvent(event)\n }\n\n this.finishSelection()\n return true\n }\n\n if (mouseEvent.type === \"down\" && mouseEvent.button === MouseButton.LEFT && this.currentSelection) {\n if (mouseEvent.modifiers.ctrl) {\n this.currentSelection.isDragging = true\n this.updateSelection(maybeRenderable, mouseEvent.x, mouseEvent.y)\n return true\n }\n }\n\n if (!sameElement && (mouseEvent.type === \"drag\" || mouseEvent.type === \"move\")) {\n if (\n this.lastOverRenderable &&\n this.lastOverRenderable !== this.capturedRenderable &&\n !this.lastOverRenderable.isDestroyed\n ) {\n const event = new MouseEvent(this.lastOverRenderable, {\n ...mouseEvent,\n type: \"out\",\n })\n this.lastOverRenderable.processMouseEvent(event)\n }\n this.lastOverRenderable = maybeRenderable\n if (maybeRenderable) {\n const event = new MouseEvent(maybeRenderable, {\n ...mouseEvent,\n type: \"over\",\n source: this.capturedRenderable,\n })\n maybeRenderable.processMouseEvent(event)\n }\n }\n\n if (this.capturedRenderable && mouseEvent.type !== \"up\") {\n const event = new MouseEvent(this.capturedRenderable, mouseEvent)\n this.capturedRenderable.processMouseEvent(event)\n return true\n }\n\n if (this.capturedRenderable && mouseEvent.type === \"up\") {\n const event = new MouseEvent(this.capturedRenderable, {\n ...mouseEvent,\n type: \"drag-end\",\n })\n this.capturedRenderable.processMouseEvent(event)\n this.capturedRenderable.processMouseEvent(new MouseEvent(this.capturedRenderable, mouseEvent))\n if (maybeRenderable) {\n const event = new MouseEvent(maybeRenderable, {\n ...mouseEvent,\n type: \"drop\",\n source: this.capturedRenderable,\n })\n maybeRenderable.processMouseEvent(event)\n }\n this.lastOverRenderable = this.capturedRenderable\n this.lastOverRenderableNum = this.capturedRenderable.num\n this.setCapturedRenderable(undefined)\n // Dropping the renderable needs to push another frame when the renderer is not live\n // to update the hit grid, otherwise capturedRenderable won't be in the hit grid and will not receive mouse events\n this.requestRender()\n }\n\n let event: MouseEvent | undefined\n if (maybeRenderable) {\n if (mouseEvent.type === \"drag\" && mouseEvent.button === MouseButton.LEFT) {\n this.setCapturedRenderable(maybeRenderable)\n } else {\n this.setCapturedRenderable(undefined)\n }\n event = this.dispatchMouseEvent(maybeRenderable, mouseEvent)\n } else {\n this.setCapturedRenderable(undefined)\n this.lastOverRenderable = undefined\n }\n\n if (!event?.defaultPrevented && mouseEvent.type === \"down\" && this.currentSelection) {\n this.clearSelection()\n }\n\n return true\n }\n\n /**\n * Recheck hover state after hit grid changes.\n * Called after render when native code detects the hit grid changed.\n * Fires out/over events if the element under the cursor changed.\n */\n private recheckHoverState(): void {\n if (this._isDestroyed || !this._hasPointer) return\n if (this.capturedRenderable) return\n\n const hitId = this.hitTest(this._latestPointer.x, this._latestPointer.y)\n const hitRenderable = Renderable.renderablesByNumber.get(hitId)\n const lastOver = this.lastOverRenderable\n\n // No change\n if (lastOver?.num === hitId) {\n this.lastOverRenderableNum = hitId\n return\n }\n\n const baseEvent: RawMouseEvent = {\n type: \"move\",\n button: 0,\n x: this._latestPointer.x,\n y: this._latestPointer.y,\n modifiers: this._lastPointerModifiers,\n }\n\n // Fire out on old element\n if (lastOver && !lastOver.isDestroyed) {\n const event = new MouseEvent(lastOver, { ...baseEvent, type: \"out\" })\n lastOver.processMouseEvent(event)\n }\n\n this.lastOverRenderable = hitRenderable\n this.lastOverRenderableNum = hitId\n\n // Fire over on new element\n if (hitRenderable) {\n const event = new MouseEvent(hitRenderable, {\n ...baseEvent,\n type: \"over\",\n })\n hitRenderable.processMouseEvent(event)\n }\n }\n public setMousePointer(style: MousePointerStyle): void {\n this._currentMousePointerStyle = style\n this.lib.setCursorStyleOptions(this.rendererPtr, { cursor: style })\n }\n\n public hitTest(x: number, y: number): number {\n return this.lib.checkHit(this.rendererPtr, x, y)\n }\n\n private takeMemorySnapshot(): void {\n if (this._isDestroyed) return\n\n const memoryUsage = process.memoryUsage()\n this.lastMemorySnapshot = {\n heapUsed: memoryUsage.heapUsed,\n heapTotal: memoryUsage.heapTotal,\n arrayBuffers: memoryUsage.arrayBuffers,\n }\n\n this.lib.updateMemoryStats(\n this.rendererPtr,\n this.lastMemorySnapshot.heapUsed,\n this.lastMemorySnapshot.heapTotal,\n this.lastMemorySnapshot.arrayBuffers,\n )\n\n this.emit(CliRenderEvents.MEMORY_SNAPSHOT, this.lastMemorySnapshot)\n }\n\n private startMemorySnapshotTimer(): void {\n this.stopMemorySnapshotTimer()\n\n this.memorySnapshotTimer = this.clock.setInterval(() => {\n this.takeMemorySnapshot()\n }, this.memorySnapshotInterval)\n }\n\n private stopMemorySnapshotTimer(): void {\n if (this.memorySnapshotTimer) {\n this.clock.clearInterval(this.memorySnapshotTimer)\n this.memorySnapshotTimer = null\n }\n }\n\n public setMemorySnapshotInterval(interval: number): void {\n this.memorySnapshotInterval = interval\n\n if (this._isRunning && interval > 0) {\n this.startMemorySnapshotTimer()\n } else if (interval <= 0 && this.memorySnapshotTimer) {\n this.clock.clearInterval(this.memorySnapshotTimer)\n this.memorySnapshotTimer = null\n }\n }\n\n private handleResize(width: number, height: number): void {\n if (this._isDestroyed) return\n if (this._splitHeight > 0) {\n this.processResize(width, height)\n return\n }\n\n if (this.resizeTimeoutId !== null) {\n this.clock.clearTimeout(this.resizeTimeoutId)\n this.resizeTimeoutId = null\n }\n\n this.resizeTimeoutId = this.clock.setTimeout(() => {\n this.resizeTimeoutId = null\n this.processResize(width, height)\n }, this.resizeDebounceDelay)\n }\n\n private queryPixelResolution() {\n this.waitingForPixelResolution = true\n this.updateStdinParserProtocolContext({ pixelResolutionQueryActive: true })\n this.lib.queryPixelResolution(this.rendererPtr)\n }\n\n private processResize(width: number, height: number): void {\n if (width === this._terminalWidth && height === this._terminalHeight) return\n\n if (\n this._terminalIsSetup &&\n this._controlState !== RendererControlState.EXPLICIT_SUSPENDED &&\n !this.isSplitCursorSeedFrameBlocked()\n ) {\n this.flushPendingSplitOutputBeforeTransition()\n }\n\n const pendingSplitFooterTransition = this.pendingSplitFooterTransition\n const previousGeometry = calculateRenderGeometry(\n this._screenMode,\n this._terminalWidth,\n this._terminalHeight,\n this._footerHeight,\n )\n const prevWidth = this._terminalWidth\n const previousTerminalHeight = this._terminalHeight\n const visiblePreviousSplitHeight =\n pendingSplitFooterTransition?.sourceHeight ?? previousGeometry.effectiveFooterHeight\n\n this._terminalWidth = width\n this._terminalHeight = height\n this.queryPixelResolution()\n\n this.setCapturedRenderable(undefined)\n this.stdinParser?.resetMouseState()\n\n const nextGeometry = calculateRenderGeometry(\n this._screenMode,\n this._terminalWidth,\n this._terminalHeight,\n this._footerHeight,\n )\n const splitFooterActive = this._screenMode === \"split-footer\"\n\n if (splitFooterActive) {\n // Width shrink historically needs a broader scrub band, but if resize interrupts\n // a deferred footer transition we also need to clear from that visible source surface.\n let clearStart: number | null = null\n\n if (width < prevWidth && visiblePreviousSplitHeight > 0) {\n clearStart = Math.max(previousTerminalHeight - visiblePreviousSplitHeight * 2, 1)\n }\n\n if (pendingSplitFooterTransition !== null) {\n clearStart =\n clearStart === null\n ? pendingSplitFooterTransition.sourceTopLine\n : Math.min(clearStart, pendingSplitFooterTransition.sourceTopLine)\n }\n\n if (clearStart !== null) {\n const flush = ANSI.moveCursorAndClear(clearStart, 1)\n this.writeOut(flush)\n }\n\n this.currentRenderBuffer.clear(this.backgroundColor)\n }\n\n this.clearPendingSplitFooterTransition()\n\n this._splitHeight = nextGeometry.effectiveFooterHeight\n this.width = nextGeometry.renderWidth\n this.height = nextGeometry.renderHeight\n\n this.lib.resizeRenderer(this.rendererPtr, this.width, this.height)\n\n if (this._screenMode === \"split-footer\" && this._externalOutputMode === \"capture-stdout\") {\n this.syncSplitScrollback()\n } else {\n this.syncSplitFooterState()\n }\n\n this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr)\n this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr)\n this._console.resize(this.width, this.height)\n this.root.resize(this.width, this.height)\n this.emit(CliRenderEvents.RESIZE, this.width, this.height)\n this.requestRender()\n }\n\n /**\n * Programmatically resize the renderer to new dimensions.\n *\n * Use this for externally-driven resize events — for example, an SSH\n * `window-change` signal or a test harness simulating a terminal resize.\n * When the renderer is attached to `process.stdout`, `SIGWINCH` is handled\n * automatically and callers do not need this method.\n */\n public resize(width: number, height: number): void {\n if (this._isDestroyed) return\n this.processResize(width, height)\n }\n\n public setBackgroundColor(color: ColorInput): void {\n const parsedColor = parseColor(color)\n this.lib.setBackgroundColor(this.rendererPtr, parsedColor as RGBA)\n this.backgroundColor = parsedColor as RGBA\n this.nextRenderBuffer.clear(parsedColor as RGBA)\n this.requestRender()\n }\n\n public toggleDebugOverlay(): void {\n const willBeEnabled = !this.debugOverlay.enabled\n\n if (willBeEnabled && !this.memorySnapshotInterval) {\n this.memorySnapshotInterval = 3000\n this.startMemorySnapshotTimer()\n this.automaticMemorySnapshot = true\n } else if (!willBeEnabled && this.automaticMemorySnapshot) {\n this.stopMemorySnapshotTimer()\n this.memorySnapshotInterval = 0\n this.automaticMemorySnapshot = false\n }\n\n this.debugOverlay.enabled = !this.debugOverlay.enabled\n this.lib.setDebugOverlay(this.rendererPtr, this.debugOverlay.enabled, this.debugOverlay.corner)\n this.emit(CliRenderEvents.DEBUG_OVERLAY_TOGGLE, this.debugOverlay.enabled)\n this.requestRender()\n }\n\n public configureDebugOverlay(options: { enabled?: boolean; corner?: DebugOverlayCorner }): void {\n this.debugOverlay.enabled = options.enabled ?? this.debugOverlay.enabled\n this.debugOverlay.corner = options.corner ?? this.debugOverlay.corner\n this.lib.setDebugOverlay(this.rendererPtr, this.debugOverlay.enabled, this.debugOverlay.corner)\n this.requestRender()\n }\n\n public setTerminalTitle(title: string): void {\n this.lib.setTerminalTitle(this.rendererPtr, title)\n }\n\n /**\n * Reset the terminal background color to its default via OSC 111.\n * Called automatically by destroy() and suspend(), but exposed for\n * consumers that need explicit control (e.g. before SIGTSTP).\n */\n public resetTerminalBgColor(): void {\n this.writeOut(\"\\x1b]111\\x07\")\n }\n\n public copyToClipboardOSC52(text: string, target?: ClipboardTarget): boolean {\n return this.clipboard.copyToClipboardOSC52(text, target)\n }\n\n public clearClipboardOSC52(target?: ClipboardTarget): boolean {\n return this.clipboard.clearClipboardOSC52(target)\n }\n\n public isOsc52Supported(): boolean {\n return this._capabilities?.osc52 ?? this.clipboard.isOsc52Supported()\n }\n\n public dumpHitGrid(): void {\n this.lib.dumpHitGrid(this.rendererPtr)\n }\n\n public dumpBuffers(timestamp?: number): void {\n this.lib.dumpBuffers(this.rendererPtr, timestamp)\n }\n\n public dumpOutputBuffer(timestamp?: number): void {\n this.lib.dumpOutputBuffer(this.rendererPtr, timestamp)\n }\n\n public static setCursorPosition(renderer: CliRenderer, x: number, y: number, visible: boolean = true): void {\n const lib = resolveRenderLib()\n lib.setCursorPosition(renderer.rendererPtr, x, y, visible)\n }\n\n public static setCursorStyle(renderer: CliRenderer, options: CursorStyleOptions): void {\n const lib = resolveRenderLib()\n lib.setCursorStyleOptions(renderer.rendererPtr, options)\n if (options.cursor !== undefined) {\n renderer._currentMousePointerStyle = options.cursor\n }\n }\n\n public static setCursorColor(renderer: CliRenderer, color: RGBA): void {\n const lib = resolveRenderLib()\n lib.setCursorColor(renderer.rendererPtr, color)\n }\n\n public setCursorPosition(x: number, y: number, visible: boolean = true): void {\n this.lib.setCursorPosition(this.rendererPtr, x, y, visible)\n }\n\n public setCursorStyle(options: CursorStyleOptions): void {\n this.lib.setCursorStyleOptions(this.rendererPtr, options)\n if (options.cursor !== undefined) {\n this._currentMousePointerStyle = options.cursor\n }\n }\n\n public setCursorColor(color: RGBA): void {\n this.lib.setCursorColor(this.rendererPtr, color)\n }\n\n public getCursorState() {\n return this.lib.getCursorState(this.rendererPtr)\n }\n\n public addPostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void {\n this.postProcessFns.push(processFn)\n }\n\n public removePostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void {\n this.postProcessFns = this.postProcessFns.filter((fn) => fn !== processFn)\n }\n\n public clearPostProcessFns(): void {\n this.postProcessFns = []\n }\n\n public setFrameCallback(callback: (deltaTime: number) => Promise): void {\n this.frameCallbacks.push(callback)\n }\n\n public removeFrameCallback(callback: (deltaTime: number) => Promise): void {\n this.frameCallbacks = this.frameCallbacks.filter((cb) => cb !== callback)\n }\n\n public clearFrameCallbacks(): void {\n this.frameCallbacks = []\n }\n\n public requestLive(): void {\n this.liveRequestCounter++\n\n if (this._controlState === RendererControlState.IDLE && this.liveRequestCounter > 0) {\n this._controlState = RendererControlState.AUTO_STARTED\n this.internalStart()\n }\n }\n\n public dropLive(): void {\n this.liveRequestCounter = Math.max(0, this.liveRequestCounter - 1)\n\n if (this._controlState === RendererControlState.AUTO_STARTED && this.liveRequestCounter === 0) {\n this._controlState = RendererControlState.IDLE\n this.internalPause()\n }\n }\n\n public start(): void {\n this._controlState = RendererControlState.EXPLICIT_STARTED\n this.internalStart()\n }\n\n public auto(): void {\n this._controlState = this._isRunning ? RendererControlState.AUTO_STARTED : RendererControlState.IDLE\n }\n\n private internalStart(): void {\n if (!this._isRunning && !this._isDestroyed) {\n this._isRunning = true\n\n // Invalidate any queued idle one-shot frame.\n // start()/live/resume transition to the continuous loop, so queued\n // activateFrame callbacks must no-op via !updateScheduled.\n this.updateScheduled = false\n\n if (this.memorySnapshotInterval > 0) {\n this.startMemorySnapshotTimer()\n }\n\n this.startRenderLoop()\n }\n }\n\n public pause(): void {\n this._controlState = RendererControlState.EXPLICIT_PAUSED\n this.internalPause()\n }\n\n public suspend(): void {\n this._previousControlState = this._controlState\n\n this._controlState = RendererControlState.EXPLICIT_SUSPENDED\n this.updateScheduled = false\n this.internalPause()\n\n if (this._terminalIsSetup) {\n this.clearSplitStartupCursorSeed()\n this.flushPendingSplitOutputBeforeTransition(true, { allowSuspended: true })\n this.suspendedNonAltSurfacePreserved = this._screenMode !== \"alternate-screen\" && this.renderOffset > 0\n } else {\n this.suspendedNonAltSurfacePreserved = false\n }\n\n this._suspendedMouseEnabled = this._useMouse\n\n this.disableMouse()\n this.removeExitListeners()\n this.waitingForPixelResolution = false\n this.updateStdinParserProtocolContext({\n privateCapabilityRepliesActive: false,\n pixelResolutionQueryActive: false,\n explicitWidthCprActive: false,\n startupCursorCprActive: false,\n })\n this.stdinParser?.reset()\n this.stdin.removeListener(\"data\", this.stdinListener)\n\n this.themeModeState.cancelRefresh()\n\n this.lib.suspendRenderer(this.rendererPtr)\n\n if (this.stdin.setRawMode) {\n this.stdin.setRawMode(false)\n }\n\n this.stdin.pause()\n }\n\n public resume(): void {\n if (this.stdin.setRawMode) {\n this.stdin.setRawMode(true)\n }\n\n // Drain any input buffered during suspension before registering the\n // listener. Adding a \"data\" listener can auto-resume a Readable, so the\n // drain must come first while the stream is still paused and read()\n // pulls from the internal buffer rather than being a flowing-mode no-op.\n while (this.stdin.read() !== null) {}\n this.stdin.on(\"data\", this.stdinListener)\n this.stdin.resume()\n this.addExitListeners()\n\n const resumePreservedNonAltSurface =\n this.pendingSuspendedTerminalSetup &&\n this._screenMode !== \"alternate-screen\" &&\n this.suspendedNonAltSurfacePreserved &&\n this.renderOffset > 0\n\n if (this.pendingSuspendedTerminalSetup) {\n this.pendingSuspendedTerminalSetup = false\n if (resumePreservedNonAltSurface) {\n this.lib.resumeRenderer(this.rendererPtr)\n } else {\n this.lib.setupTerminal(this.rendererPtr, this._screenMode === \"alternate-screen\")\n }\n } else {\n this.lib.resumeRenderer(this.rendererPtr)\n }\n\n this.suspendedNonAltSurfacePreserved = false\n\n this.flushPendingSplitOutputBeforeTransition(false, { allowSuspended: true, allowPassthrough: true })\n\n if (this._screenMode === \"split-footer\" && this._splitHeight > 0) {\n this.syncSplitFooterState()\n }\n\n if (this._suspendedMouseEnabled) {\n this.enableMouse()\n }\n\n this.forceFullRepaintRequested = true\n this._controlState = this._previousControlState\n\n if (\n this._previousControlState === RendererControlState.AUTO_STARTED ||\n this._previousControlState === RendererControlState.EXPLICIT_STARTED\n ) {\n this.internalStart()\n } else {\n this.requestRender()\n }\n }\n\n private internalPause(): void {\n this._isRunning = false\n\n if (this.renderTimeout) {\n this.clock.clearTimeout(this.renderTimeout)\n this.renderTimeout = null\n }\n\n if (!this.rendering) {\n this.resolveIdleIfNeeded()\n }\n }\n\n public stop(): void {\n this._controlState = RendererControlState.EXPLICIT_STOPPED\n this.internalStop()\n }\n\n private internalStop(): void {\n if (this.isRunning && !this._isDestroyed) {\n this._isRunning = false\n\n if (this.memorySnapshotTimer) {\n this.clock.clearInterval(this.memorySnapshotTimer)\n this.memorySnapshotTimer = null\n }\n\n if (this.renderTimeout) {\n this.clock.clearTimeout(this.renderTimeout)\n this.renderTimeout = null\n }\n\n // If we're currently rendering, the frame will resolve idle when it completes\n // Otherwise, resolve immediately\n if (!this.rendering) {\n this.resolveIdleIfNeeded()\n }\n }\n }\n\n public destroy(): void {\n if (this._isDestroyed) return\n this._isDestroyed = true\n this._destroyPending = true\n this._palettePublishGeneration++\n\n if (this.rendering) {\n // Restore terminal/input state immediately, but defer full native teardown until the frame unwinds.\n this.prepareDestroyDuringRender()\n return\n }\n\n this.finalizeDestroy()\n }\n\n private cleanupBeforeDestroy(): void {\n if (this._destroyCleanupPrepared) return\n this._destroyCleanupPrepared = true\n\n if (this._usesProcessStdout) {\n process.removeListener(\"SIGWINCH\", this.sigwinchHandler)\n }\n process.removeListener(\"uncaughtException\", this.handleError)\n process.removeListener(\"unhandledRejection\", this.handleError)\n process.removeListener(\"warning\", this.warningHandler)\n process.removeListener(\"beforeExit\", this.exitHandler)\n this.removeExitListeners()\n\n if (this.resizeTimeoutId !== null) {\n this.clock.clearTimeout(this.resizeTimeoutId)\n this.resizeTimeoutId = null\n }\n\n if (this.capabilityTimeoutId !== null) {\n this.clock.clearTimeout(this.capabilityTimeoutId)\n this.capabilityTimeoutId = null\n }\n\n this.clearSplitStartupCursorSeed()\n\n if (this.memorySnapshotTimer) {\n this.clock.clearInterval(this.memorySnapshotTimer)\n this.memorySnapshotTimer = null\n }\n\n if (this.renderTimeout) {\n this.clock.clearTimeout(this.renderTimeout)\n this.renderTimeout = null\n }\n\n this.themeModeState.cancelRefresh()\n\n this._isRunning = false\n this.waitingForPixelResolution = false\n this.updateStdinParserProtocolContext(\n {\n privateCapabilityRepliesActive: false,\n pixelResolutionQueryActive: false,\n explicitWidthCprActive: false,\n startupCursorCprActive: false,\n },\n true,\n )\n this._useMouse = false\n this.setCapturedRenderable(undefined)\n\n this.stdin.removeListener(\"data\", this.stdinListener)\n if (this.stdin.setRawMode) {\n try {\n this.stdin.setRawMode(false)\n } catch (e) {\n console.error(\"Error disabling raw mode during destroy:\", e)\n }\n }\n try {\n this.stdin.pause()\n } catch (e) {\n console.error(\"Error pausing stdin during destroy:\", e)\n }\n\n if (this._feed !== null && this._splitHeight > 0 && !this._terminalIsSetup) {\n this.flushPendingSplitOutputBeforeTransition(false, { allowSuspended: true, allowUnsetup: true })\n }\n\n this.externalOutputMode = \"passthrough\"\n\n if (this._splitHeight > 0) {\n this.flushStdoutCache(this._splitHeight, true)\n }\n }\n\n private prepareDestroyDuringRender(): void {\n this.cleanupBeforeDestroy()\n this.lib.suspendRenderer(this.rendererPtr)\n }\n\n private finalizeDestroy(): void {\n if (this._destroyFinalized) return\n\n this._destroyFinalized = true\n this._destroyPending = false\n\n this.cleanupBeforeDestroy()\n\n // Clean up palette detector\n if (this._paletteDetector) {\n this._paletteDetector.cleanup()\n this._paletteDetector = null\n }\n this._paletteCache.clear()\n this._paletteDetectionPromise = null\n this._paletteDetectionSize = 0\n this._nativePaletteSignature = null\n this._emittedPaletteSignature = null\n this._paletteEpoch = 0\n this.resolveXtVersionWaiters()\n\n this.themeModeState.dispose()\n\n this.emit(CliRenderEvents.DESTROY)\n\n try {\n this.root.destroyRecursively()\n } catch (e) {\n console.error(\"Error destroying root renderable:\", e instanceof Error ? e.stack : String(e))\n }\n\n this.stdinParser?.destroy()\n this.stdinParser = null\n this.oscSubscribers.clear()\n this._console.destroy()\n\n // Split-footer cleanup: flush pending output and reset offset before\n // tearing down the native renderer.\n if (\n this._splitHeight > 0 &&\n this._terminalIsSetup &&\n this._controlState !== RendererControlState.EXPLICIT_SUSPENDED\n ) {\n this.flushPendingSplitOutputBeforeTransition(true)\n this.renderOffset = 0\n if (this.clearOnShutdown) {\n this.lib.setRenderOffset(this.rendererPtr, 0)\n }\n }\n\n this._externalOutputMode = \"passthrough\"\n this.pendingExternalOutputMode = null\n this.stdout.write = this.realStdoutWrite\n this.externalOutputQueue.clear()\n\n // Teardown ordering for the feed backend is subtle and must satisfy two\n // invariants simultaneously:\n //\n // 1. The shutdown ANSI sequence emitted by `lib.destroyRenderer` via\n // FeedBackend.writeOut MUST reach the user's Writable. Otherwise the\n // remote terminal is left in alt-screen / mouse-tracking / kitty-\n // keyboard state at session close.\n //\n // 2. The data handler (which does `stdout.write`) must be detached\n // before `feed.close()`, otherwise `close()` will wait for any\n // in-flight writes that reference chunks about to be freed.\n //\n // The correct order is:\n // a) drain any frames already committed but not yet delivered\n // b) call lib.destroyRenderer — this commits shutdown bytes into the feed\n // c) drain again — this flushes those shutdown bytes through the handler\n // d) detach the handler now that no more data will flow\n // e) close the feed (releases chunk memory once async handlers settle)\n //\n // Memory-lifetime invariant: `lib.destroyRenderer` calls into Zig's\n // `FeedBackend.deinit`, which is a DOCUMENTED NO-OP — feed memory is\n // owned by the TS side and only released by `feed.close()` at step (e).\n // Consequently, step (c)'s drain operates on still-valid chunk memory;\n // there is no use-after-free window between (b) and (e).\n //\n // Caller note: `feed.close()` is queued as a microtask when async handlers\n // from the final drain are still pending. If the caller tears down the\n // underlying Writable synchronously right after `destroy()` returns (e.g.\n // `channel.close()` on the very next line, or `process.exit()`), the\n // shutdown bytes may not have flushed yet. For async teardown, allow one\n // microtask tick (e.g. `await new Promise(queueMicrotask)`) before closing\n // the transport.\n if (this._feed) {\n try {\n this._feed.drainAll()\n } catch (e) {\n console.error(\"Error draining NativeSpanFeed during destroy:\", e)\n }\n }\n\n try {\n this.lib.destroyRenderer(this.rendererPtr)\n } catch (e) {\n console.error(\"Error in lib.destroyRenderer during destroy:\", e)\n }\n rendererTracker.renderers.delete(this)\n if (rendererTracker.renderers.size === 0) {\n void destroyTreeSitterClient().catch((error) => {\n console.error(\"Failed to destroy tree-sitter client:\", error)\n })\n }\n\n if (this._feed) {\n try {\n this._feed.drainAll()\n } catch (e) {\n console.error(\"Error draining NativeSpanFeed shutdown frames:\", e)\n }\n this._detachFeed?.()\n this._detachFeed = null\n this._detachFeedError?.()\n this._detachFeedError = null\n this._feed.close()\n this._feed = null\n }\n\n if (this._streamLeaseAcquired) {\n if (rendererTracker.streamOwners.get(this.stdin) === this) rendererTracker.streamOwners.delete(this.stdin)\n if (rendererTracker.streamOwners.get(this.stdout) === this) rendererTracker.streamOwners.delete(this.stdout)\n this._streamLeaseAcquired = false\n }\n\n if (this._onDestroy) {\n try {\n this._onDestroy()\n } catch (e) {\n console.error(\"Error in onDestroy callback:\", e instanceof Error ? e.stack : String(e))\n }\n }\n\n // Resolve any pending idle() calls\n this.resolveIdleIfNeeded()\n }\n\n private startRenderLoop(): void {\n if (!this._isRunning) return\n\n this.lastTime = this.normalizeClockTime(this.clock.now(), 0)\n this.frameCount = 0\n this.lastFpsTime = this.lastTime\n this.currentFps = 0\n\n // Starting continuous mode must not bypass an existing feed-idle retry. Keep\n // _isRunning true, but let the idle callback schedule the first loop once the\n // feed is ready; a successful frame will then resume the normal cadence.\n if (this.feedIdleRenderScheduled) return\n\n this.loop()\n }\n\n private async loop(): Promise {\n if (this.rendering || this._isDestroyed) return\n this.renderTimeout = null\n\n this.rendering = true\n if (this.renderTimeout) {\n this.clock.clearTimeout(this.renderTimeout)\n this.renderTimeout = null\n }\n try {\n // Bump before any work so all callers this iteration see the new id.\n this._frameId++\n\n const now = this.normalizeClockTime(this.clock.now(), this.lastTime)\n const elapsed = this.getElapsedMs(now, this.lastTime)\n\n const deltaTime = elapsed\n this.lastTime = now\n\n this.frameCount++\n if (this.getElapsedMs(now, this.lastFpsTime) >= 1000) {\n this.currentFps = this.frameCount\n this.frameCount = 0\n this.lastFpsTime = now\n }\n\n this.renderStats.frameCount++\n this.renderStats.fps = this.currentFps\n const overallStart = performance.now()\n\n const frameRequests = Array.from(this.animationRequest.values())\n this.animationRequest.clear()\n const animationRequestStart = performance.now()\n for (const callback of frameRequests) {\n callback(deltaTime)\n this.dropLive()\n }\n const animationRequestEnd = performance.now()\n const animationRequestTime = animationRequestEnd - animationRequestStart\n\n const start = performance.now()\n for (const frameCallback of this.frameCallbacks) {\n try {\n await frameCallback(deltaTime)\n } catch (error) {\n console.error(\"Error in frame callback:\", error)\n }\n }\n const end = performance.now()\n this.renderStats.frameCallbackTime = end - start\n\n this.root.render(this.nextRenderBuffer, deltaTime)\n\n for (const postProcessFn of this.postProcessFns) {\n postProcessFn(this.nextRenderBuffer, deltaTime)\n }\n\n this._console.renderToBuffer(this.nextRenderBuffer)\n\n // If destroy() was requested during this frame, skip native work and scheduling.\n if (!this._isDestroyed) {\n const nativeStatus = this.renderNative() ?? \"rendered\"\n\n if (nativeStatus === \"rendered\") {\n // Check if hit grid changed and recheck hover state if needed\n if (this._useMouse && this.lib.getHitGridDirty(this.rendererPtr)) {\n this.recheckHoverState()\n }\n\n const overallFrameTime = performance.now() - overallStart\n\n // TODO: Add animationRequestTime to stats\n this.lib.updateStats(\n this.rendererPtr,\n overallFrameTime,\n this.renderStats.fps,\n this.renderStats.frameCallbackTime,\n )\n\n if (this.listenerCount(CliRenderEvents.FRAME) > 0) {\n this.emit(CliRenderEvents.FRAME, {\n frameId: this.frameId,\n })\n }\n\n if (this.gatherStats) {\n this.collectStatSample(overallFrameTime)\n }\n\n if (this._isRunning || this.immediateRerenderRequested) {\n const targetFrameTime = this.immediateRerenderRequested ? this.minTargetFrameTime : this.targetFrameTime\n const delay = Math.max(1, targetFrameTime - Math.floor(overallFrameTime))\n this.immediateRerenderRequested = false\n this.renderTimeout = this.clock.setTimeout(() => {\n this.renderTimeout = null\n this.loop()\n }, delay)\n } else {\n this.clock.clearTimeout(this.renderTimeout!)\n this.renderTimeout = null\n }\n } else if (nativeStatus === \"blocked\") {\n const overallFrameTime = performance.now() - overallStart\n\n if (this._isRunning || this.immediateRerenderRequested) {\n const targetFrameTime = this.immediateRerenderRequested ? this.minTargetFrameTime : this.targetFrameTime\n const delay = Math.max(1, targetFrameTime - Math.floor(overallFrameTime))\n this.immediateRerenderRequested = false\n this.renderTimeout = this.clock.setTimeout(() => {\n this.renderTimeout = null\n this.loop()\n }, delay)\n } else {\n this.clock.clearTimeout(this.renderTimeout!)\n this.renderTimeout = null\n }\n } else if (nativeStatus === \"backpressured\") {\n this.scheduleRenderAfterBackpressure()\n } else if (nativeStatus === \"retryable-skip\") {\n this.immediateRerenderRequested = false\n this.renderTimeout = null\n } else if (nativeStatus === \"failed\") {\n this.immediateRerenderRequested = false\n this.renderTimeout = null\n }\n }\n } finally {\n this.rendering = false\n if (this._destroyPending) {\n this.finalizeDestroy()\n }\n this.resolveIdleIfNeeded()\n }\n }\n\n public intermediateRender(): void {\n this.immediateRerenderRequested = true\n this.loop()\n }\n\n private renderNative(): \"rendered\" | \"retryable-skip\" | \"failed\" | \"blocked\" | \"backpressured\" {\n if (this.renderingNative) {\n console.error(\"Rendering called concurrently\")\n throw new Error(\"Rendering called concurrently\")\n }\n\n this.renderingNative = true\n\n try {\n if (this.isSplitCursorSeedFrameBlocked()) {\n return \"blocked\"\n }\n\n if (this._splitHeight > 0 && this._externalOutputMode === \"capture-stdout\") {\n // forceFullRepaintRequested is a one-shot latch used when mode/geometry\n // transitions need a complete footer refresh. Consume it once so steady-state\n // capture path keeps using diff-based repainting.\n const forceSplitRepaint = this.forceFullRepaintRequested\n const status = this.flushPendingSplitCommits(\n forceSplitRepaint,\n this.pendingExternalOutputMode === \"passthrough\",\n )\n if (status === \"backpressured\") {\n return \"backpressured\"\n }\n if (status === \"failed\") {\n return \"failed\"\n }\n this.forceFullRepaintRequested = false\n this.pendingSplitFooterTransition = null\n return \"rendered\"\n }\n\n const force = this.forceFullRepaintRequested\n const nativeStatus = this.lib.render(this.rendererPtr, force)\n if (nativeStatus === NATIVE_RENDER_STATUS_SKIPPED || nativeStatus === NATIVE_RENDER_STATUS_FAILED) {\n return this.handleNativeRenderRejection(nativeStatus)\n }\n\n this.forceFullRepaintRequested = false\n this.pendingSplitFooterTransition = null\n // this.dumpOutputBuffer(Date.now())\n return \"rendered\"\n } finally {\n this.renderingNative = false\n }\n }\n\n private collectStatSample(frameTime: number): void {\n this.frameTimes.push(frameTime)\n if (this.frameTimes.length > this.maxStatSamples) {\n this.frameTimes.shift()\n }\n }\n\n public getNativeStats(): NativeRenderStats {\n return this.lib.getRenderStats(this.rendererPtr)\n }\n\n public getStats(): CliRendererStats {\n const nativeStats = this.getNativeStats()\n const frameTimes = [...this.frameTimes]\n const sum = frameTimes.reduce((acc, time) => acc + time, 0)\n const avg = frameTimes.length ? sum / frameTimes.length : 0\n const min = frameTimes.length ? Math.min(...frameTimes) : 0\n const max = frameTimes.length ? Math.max(...frameTimes) : 0\n\n return {\n ...nativeStats,\n fps: this.renderStats.fps,\n frameCount: this.renderStats.frameCount,\n frameTimes,\n averageFrameTime: avg,\n minFrameTime: min,\n maxFrameTime: max,\n frameCallbackTime: this.renderStats.frameCallbackTime,\n }\n }\n\n public resetStats(): void {\n this.frameTimes = []\n this.renderStats.frameCount = 0\n }\n\n public setGatherStats(enabled: boolean): void {\n this.gatherStats = enabled\n if (!enabled) {\n this.frameTimes = []\n }\n }\n\n public getSelection(): Selection | null {\n return this.currentSelection\n }\n\n public get hasSelection(): boolean {\n return !!this.currentSelection\n }\n\n public getSelectionContainer(): Renderable | null {\n return this.selectionContainers.length > 0 ? this.selectionContainers[this.selectionContainers.length - 1] : null\n }\n\n public clearSelection(): void {\n if (this.currentSelection) {\n for (const renderable of this.currentSelection.touchedRenderables) {\n if (renderable.selectable && !renderable.isDestroyed) {\n renderable.onSelectionChanged(null)\n }\n }\n this.currentSelection = null\n }\n this.selectionContainers = []\n }\n\n /**\n * Start a new selection at the given coordinates.\n * Used by both mouse and keyboard selection.\n */\n public startSelection(renderable: Renderable, x: number, y: number): void {\n if (!renderable.selectable) return\n\n this.clearSelection()\n this.selectionContainers.push(renderable.parent || this.root)\n this.currentSelection = new Selection(renderable, { x, y }, { x, y })\n this.currentSelection.isStart = true\n\n this.notifySelectablesOfSelectionChange()\n }\n\n public updateSelection(\n currentRenderable: Renderable | undefined,\n x: number,\n y: number,\n options?: { finishDragging?: boolean },\n ): void {\n if (this.currentSelection) {\n this.currentSelection.isStart = false\n this.currentSelection.focus = { x, y }\n\n if (options?.finishDragging) {\n this.currentSelection.isDragging = false\n }\n\n if (this.selectionContainers.length > 0) {\n const currentContainer = this.selectionContainers[this.selectionContainers.length - 1]\n\n if (!currentRenderable || !this.isWithinContainer(currentRenderable, currentContainer)) {\n const parentContainer = currentContainer.parent || this.root\n this.selectionContainers.push(parentContainer)\n } else if (currentRenderable && this.selectionContainers.length > 1) {\n let containerIndex = this.selectionContainers.indexOf(currentRenderable)\n\n if (containerIndex === -1) {\n const immediateParent = currentRenderable.parent || this.root\n containerIndex = this.selectionContainers.indexOf(immediateParent)\n }\n\n if (containerIndex !== -1 && containerIndex < this.selectionContainers.length - 1) {\n this.selectionContainers = this.selectionContainers.slice(0, containerIndex + 1)\n }\n }\n }\n\n this.notifySelectablesOfSelectionChange()\n }\n }\n\n public requestSelectionUpdate(): void {\n if (this.currentSelection?.isDragging) {\n const pointer = this._latestPointer\n\n const maybeRenderableId = this.hitTest(pointer.x, pointer.y)\n const maybeRenderable = Renderable.renderablesByNumber.get(maybeRenderableId)\n\n this.updateSelection(maybeRenderable, pointer.x, pointer.y)\n }\n }\n\n private isWithinContainer(renderable: Renderable, container: Renderable): boolean {\n let current: Renderable | null = renderable\n while (current) {\n if (current === container) return true\n current = current.parent\n }\n return false\n }\n\n private finishSelection(): void {\n if (this.currentSelection) {\n this.currentSelection.isDragging = false\n this.emit(CliRenderEvents.SELECTION, this.currentSelection)\n this.notifySelectablesOfSelectionChange()\n }\n }\n\n private notifySelectablesOfSelectionChange(): void {\n const selectedRenderables: Renderable[] = []\n const touchedRenderables: Renderable[] = []\n const currentContainer =\n this.selectionContainers.length > 0 ? this.selectionContainers[this.selectionContainers.length - 1] : this.root\n\n if (this.currentSelection) {\n this.walkSelectableRenderables(\n currentContainer,\n this.currentSelection.bounds,\n selectedRenderables,\n touchedRenderables,\n )\n\n for (const renderable of this.currentSelection.touchedRenderables) {\n if (!touchedRenderables.includes(renderable) && !renderable.isDestroyed) {\n renderable.onSelectionChanged(null)\n }\n }\n\n this.currentSelection.updateSelectedRenderables(selectedRenderables)\n this.currentSelection.updateTouchedRenderables(touchedRenderables)\n }\n }\n\n private walkSelectableRenderables(\n container: Renderable,\n selectionBounds: ViewportBounds,\n selectedRenderables: Renderable[],\n touchedRenderables: Renderable[],\n ): void {\n const children = getObjectsInViewport(\n selectionBounds,\n container.getChildrenSortedByPrimaryAxis(),\n container.primaryAxis,\n 0, // padding\n 0, // minTriggerSize - always perform overlap checks for selection\n )\n\n for (const child of children) {\n if (child.selectable) {\n const hasSelection = child.onSelectionChanged(this.currentSelection)\n if (hasSelection) {\n selectedRenderables.push(child)\n }\n touchedRenderables.push(child)\n }\n if (child.getChildrenCount() > 0) {\n this.walkSelectableRenderables(child, selectionBounds, selectedRenderables, touchedRenderables)\n }\n }\n }\n\n public get paletteDetectionStatus(): \"idle\" | \"detecting\" | \"cached\" {\n if (this._paletteDetectionPromise) return \"detecting\"\n if (this._paletteCache.size > 0) return \"cached\"\n return \"idle\"\n }\n\n private getCachedPaletteBySize(size: number): TerminalColors | null {\n const exactMatch = this._paletteCache.get(size)\n if (exactMatch) {\n return exactMatch\n }\n\n const largerSize = [...this._paletteCache.keys()].sort((a, b) => a - b).find((candidate) => candidate >= size)\n if (largerSize === undefined) {\n return null\n }\n\n const source = this._paletteCache.get(largerSize)\n if (!source) {\n return null\n }\n\n const projected = {\n ...source,\n palette: source.palette.slice(0, size),\n }\n\n this._paletteCache.set(size, projected)\n return projected\n }\n\n private ensurePaletteDetector(): TerminalPaletteDetector {\n if (!this._paletteDetector) {\n const isTmux = Boolean(\n this.capabilities?.multiplexer === \"tmux\" || this.capabilities?.terminal?.name?.toLowerCase()?.includes(\"tmux\"),\n )\n const isLegacyTmux =\n this.capabilities?.terminal?.name?.toLowerCase()?.includes(\"tmux\") &&\n this.capabilities?.terminal?.version?.localeCompare(\"3.6\") < 0\n this._paletteDetector = createTerminalPalette({\n stdin: this.stdin,\n stdout: this.stdout,\n writeFn: (data) => (this._isDestroyed ? false : this.writeOut(data)),\n isLegacyTmux,\n isTmux,\n oscSource: {\n subscribeOsc: this.subscribeOsc.bind(this),\n },\n clock: this.clock,\n })\n }\n\n return this._paletteDetector\n }\n\n private syncNativePaletteState(colors: TerminalColors | null): void {\n const signature = buildTerminalPaletteSignature(colors)\n if (this._nativePaletteSignature !== signature) {\n this._paletteEpoch = (this._paletteEpoch + 1) >>> 0\n }\n\n this._nativePaletteSignature = signature\n\n const normalized = normalizeTerminalPalette(colors)\n this.lib.rendererSetPaletteState(\n this.rendererPtr,\n normalized.palette,\n normalized.defaultForeground,\n normalized.defaultBackground,\n this._paletteEpoch,\n )\n }\n\n private emitPaletteChange(colors: TerminalColors): void {\n if (this.listenerCount(CliRenderEvents.PALETTE) === 0) return\n\n const signature = buildTerminalPaletteSignature(colors)\n if (this._emittedPaletteSignature === signature) return\n\n this._emittedPaletteSignature = signature\n this.emit(CliRenderEvents.PALETTE, colors)\n }\n\n private resolveXtVersionWaiters(): void {\n if (this.xtVersionWaiters.size === 0) return\n\n const resolvers = [...this.xtVersionWaiters]\n this.xtVersionWaiters.clear()\n for (const resolve of resolvers) {\n resolve()\n }\n }\n\n private waitForXtVersion(): Promise {\n if (this.capabilityTimeoutId === null || this._capabilities?.terminal?.from_xtversion) {\n return Promise.resolve()\n }\n\n return new Promise((resolve) => {\n this.xtVersionWaiters.add(resolve)\n })\n }\n\n private shouldSyncNativePaletteState(): boolean {\n return Boolean(\n this._terminalIsSetup && !this._isDestroyed && this._capabilities?.ansi256 && !this._capabilities?.rgb,\n )\n }\n\n private refreshPalette(): void {\n const publishGeneration = this._palettePublishGeneration\n\n void this.getPalette({ size: NATIVE_PALETTE_QUERY_SIZE })\n .then(() => {\n if (this._isDestroyed) return\n if (this._palettePublishGeneration === publishGeneration) this.requestRender()\n })\n .catch(() => {})\n }\n\n public clearPaletteCache(): void {\n this._palettePublishGeneration++\n this._paletteCache.clear()\n }\n\n /**\n * Detects the terminal's color palette\n *\n * @returns Promise resolving to TerminalColors object containing palette and special colors\n * @throws Error if renderer is suspended\n */\n public async getPalette(options?: GetPaletteOptions): Promise {\n if (this._controlState === RendererControlState.EXPLICIT_SUSPENDED) {\n throw new Error(\"Cannot detect palette while renderer is suspended\")\n }\n\n const requestedSize = options?.size ?? 16\n const detectionTimeout = options?.timeout\n\n const cachedPalette = this.getCachedPaletteBySize(requestedSize)\n if (cachedPalette) {\n return cachedPalette\n }\n\n // tmux OSC 4 strategy depends on version. Env may provide it via\n // TERM_PROGRAM=tmux/TERM_PROGRAM_VERSION; otherwise wait for XTVERSION.\n const terminal = this._capabilities?.terminal\n const hasTmuxVersion = terminal?.name?.toLowerCase() === \"tmux\" && Boolean(terminal.version)\n if (this._capabilities?.multiplexer === \"tmux\" && !hasTmuxVersion) {\n await this.waitForXtVersion()\n\n // Another caller may have populated the cache while this call waited.\n const afterCapabilityWait = this.getCachedPaletteBySize(requestedSize)\n if (afterCapabilityWait) {\n return afterCapabilityWait\n }\n }\n\n if (this._paletteDetectionPromise) {\n if (this._paletteDetectionSize >= requestedSize) {\n return this._paletteDetectionPromise.then((palette) => {\n const cached = this.getCachedPaletteBySize(requestedSize)\n if (cached) {\n return cached\n }\n\n const projected = {\n ...palette,\n palette: palette.palette.slice(0, requestedSize),\n }\n this._paletteCache.set(requestedSize, projected)\n return projected\n })\n }\n\n await this._paletteDetectionPromise\n\n const afterWait = this.getCachedPaletteBySize(requestedSize)\n if (afterWait) {\n return afterWait\n }\n }\n\n const detector = this.ensurePaletteDetector()\n const publishGeneration = this._palettePublishGeneration\n this._paletteDetectionSize = requestedSize\n this._paletteDetectionPromise = detector\n .detect({ ...options, timeout: detectionTimeout })\n .then((result) => {\n this._paletteCache.set(result.palette.length, result)\n this._paletteDetectionPromise = null\n this._paletteDetectionSize = 0\n\n if (!this._isDestroyed && this._palettePublishGeneration === publishGeneration) {\n this.emitPaletteChange(result)\n if (this.shouldSyncNativePaletteState() && result.palette.length >= NATIVE_PALETTE_QUERY_SIZE) {\n this.syncNativePaletteState(result)\n } else if (this.shouldSyncNativePaletteState() && !this._paletteCache.has(NATIVE_PALETTE_QUERY_SIZE)) {\n this.refreshPalette()\n }\n }\n\n return result\n })\n .catch((error) => {\n this._paletteDetectionPromise = null\n this._paletteDetectionSize = 0\n throw error\n })\n\n const detected = await this._paletteDetectionPromise\n const finalPalette = this.getCachedPaletteBySize(requestedSize) ?? detected\n return finalPalette\n }\n}\n", + "import type { ViewportBounds } from \"../types.js\"\n\ninterface ViewportObject {\n screenX: number\n screenY: number\n width: number\n height: number\n zIndex: number\n}\n\n/**\n * Returns objects that overlap with the viewport bounds.\n *\n * @param viewport - The viewport bounds to check against\n * @param objects - Array of objects MUST be sorted by screen position (screenY for column, screenX for row direction)\n * @param direction - Primary scroll direction: \"column\" (vertical) or \"row\" (horizontal)\n * @param padding - Extra padding around viewport to include nearby objects\n * @param minTriggerSize - Minimum array size to use binary search optimization\n * @returns Array of visible objects sorted by zIndex\n *\n * @remarks\n * Objects must be pre-sorted by their start screen position (screenY for column direction, screenX for row direction).\n * Unsorted input will produce incorrect results.\n */\nexport function getObjectsInViewport(\n viewport: ViewportBounds,\n objects: T[],\n direction: \"row\" | \"column\" = \"column\",\n padding: number = 10,\n minTriggerSize: number = 16,\n): T[] {\n if (viewport.width <= 0 || viewport.height <= 0) {\n return []\n }\n\n if (objects.length === 0) {\n return []\n }\n\n if (objects.length < minTriggerSize) {\n return objects\n }\n\n const viewportTop = viewport.y - padding\n const viewportBottom = viewport.y + viewport.height + padding\n const viewportLeft = viewport.x - padding\n const viewportRight = viewport.x + viewport.width + padding\n\n const isRow = direction === \"row\"\n\n const children = objects\n const totalChildren = children.length\n if (totalChildren === 0) return []\n\n const vpStart = isRow ? viewportLeft : viewportTop\n const vpEnd = isRow ? viewportRight : viewportBottom\n\n // Binary search to find any child that overlaps along the primary axis\n let lo = 0\n let hi = totalChildren - 1\n let candidate = -1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const c = children[mid]\n const start = isRow ? c.screenX : c.screenY\n const end = isRow ? c.screenX + c.width : c.screenY + c.height\n\n if (end < vpStart) {\n lo = mid + 1\n } else if (start > vpEnd) {\n hi = mid - 1\n } else {\n candidate = mid\n break\n }\n }\n\n const visibleChildren: T[] = []\n\n // If binary search found no candidate, the viewport might be in a gap between objects\n // Start from the position where the search ended\n if (candidate === -1) {\n // Binary search failed to find overlap - viewport is in a gap\n // We need to check objects before lo for any that extend into the viewport\n candidate = lo > 0 ? lo - 1 : 0\n }\n\n // Expand left to find all objects that overlap the viewport\n // To handle large objects that start early but extend far, we continue\n // checking even after finding objects that don't overlap, up to a limit\n // This handles cases where many small objects sit between a large object and the viewport\n // Real-world examples: background panels, large images, or spanning containers\n const maxLookBehind = 50\n let left = candidate\n let gapCount = 0\n\n while (left - 1 >= 0) {\n const prev = children[left - 1]\n const prevEnd = isRow ? prev.screenX + prev.width : prev.screenY + prev.height\n\n if (prevEnd <= vpStart) {\n gapCount++\n if (gapCount >= maxLookBehind) {\n break\n }\n } else {\n gapCount = 0\n }\n\n left--\n }\n\n // Expand right to find the rightmost overlapping object\n let right = candidate + 1\n while (right < totalChildren) {\n const next = children[right]\n if ((isRow ? next.screenX : next.screenY) >= vpEnd) break\n right++\n }\n\n // Collect candidates that also overlap on the cross axis\n for (let i = left; i < right; i++) {\n const child = children[i]\n const start = isRow ? child.screenX : child.screenY\n const end = isRow ? child.screenX + child.width : child.screenY + child.height\n\n // Check primary axis overlap (optimization: skip objects that don't overlap)\n if (end <= vpStart) continue\n if (start >= vpEnd) break\n\n // Check cross-axis overlap\n if (isRow) {\n const childBottom = child.screenY + child.height\n if (childBottom < viewportTop) continue\n const childTop = child.screenY\n if (childTop > viewportBottom) continue\n } else {\n const childRight = child.screenX + child.width\n if (childRight < viewportLeft) continue\n const childLeft = child.screenX\n if (childLeft > viewportRight) continue\n }\n\n visibleChildren.push(child)\n }\n\n // Sort by zIndex\n if (visibleChildren.length > 1) {\n visibleChildren.sort((a, b) => (a.zIndex > b.zIndex ? 1 : a.zIndex < b.zIndex ? -1 : 0))\n }\n\n return visibleChildren\n}\n", + "export type RenderGeometryScreenMode = \"alternate-screen\" | \"main-screen\" | \"split-footer\"\n\nexport interface RenderGeometry {\n effectiveFooterHeight: number\n renderOffset: number\n renderWidth: number\n renderHeight: number\n}\n\nexport function calculateRenderGeometry(\n screenMode: RenderGeometryScreenMode,\n terminalWidth: number,\n terminalHeight: number,\n footerHeight: number,\n): RenderGeometry {\n const safeTerminalWidth = Math.max(terminalWidth, 0)\n const safeTerminalHeight = Math.max(terminalHeight, 0)\n\n if (screenMode !== \"split-footer\") {\n return {\n effectiveFooterHeight: 0,\n renderOffset: 0,\n renderWidth: safeTerminalWidth,\n renderHeight: safeTerminalHeight,\n }\n }\n\n const effectiveFooterHeight = Math.min(footerHeight, safeTerminalHeight)\n\n return {\n effectiveFooterHeight,\n renderOffset: safeTerminalHeight - effectiveFooterHeight,\n renderWidth: safeTerminalWidth,\n renderHeight: effectiveFooterHeight,\n }\n}\n", + "/**\n * Terminal capability response detection utilities.\n *\n * Detects various terminal capability response sequences:\n * - DECRPM (DEC Request Mode): ESC[?...;N$y where N is 0,1,2,3,4\n * - CPR (Cursor Position Report): ESC[row;colR (used for width detection)\n * - XTVersion: ESC P >| ... ESC \\\n * - Kitty Graphics: ESC _ G ... ESC \\\n * - Kitty Keyboard Query: ESC[?Nu where N is 0,1,2,etc\n * - DA1 (Device Attributes): ESC[?...c\n * - Pixel Resolution: ESC[4;height;widtht\n * - OSC 99 notification capability query response\n * - iTerm2 OSC 1337 feature-reporting response\n */\n\n/**\n * Check if a sequence is a terminal capability response.\n * Returns true if the sequence matches any known capability response pattern.\n */\nexport function isCapabilityResponse(sequence: string): boolean {\n // DECRPM: ESC[?digits;digits$y\n if (/\\x1b\\[\\?\\d+(?:;\\d+)*\\$y/.test(sequence)) {\n return true\n }\n\n // CPR for explicit width/scaled text detection: ESC[1;NR where N >= 2\n // The column number tells us how many characters were rendered with width annotations\n // ESC[1;1R means no width support (cursor didn't move)\n // ESC[1;2R or higher means width support (cursor moved after rendering)\n // We accept any column >= 2 to handle cases where cursor wasn't at exact home position\n if (/\\x1b\\[1;(?!1R)\\d+R/.test(sequence)) {\n return true\n }\n\n // XTVersion: ESC P >| ... ESC \\\n if (/\\x1bP>\\|[\\s\\S]*?\\x1b\\\\/.test(sequence)) {\n return true\n }\n\n // Kitty graphics response: ESC _ G ... ESC \\\n // Matches any graphics response including OK, errors, etc.\n // This is for filtering capability responses from user input\n if (/\\x1b_G[\\s\\S]*?\\x1b\\\\/.test(sequence)) {\n return true\n }\n\n // Kitty keyboard query response: ESC[?Nu or ESC[?N;Mu (progressive enhancement)\n if (/\\x1b\\[\\?\\d+(?:;\\d+)?u/.test(sequence)) {\n return true\n }\n\n // DA1 (Device Attributes): ESC[?...c\n if (/\\x1b\\[\\?[0-9;]*c/.test(sequence)) {\n return true\n }\n\n // Kitty desktop notification capability query response.\n if (/\\x1b\\]99;[^\\x07\\x1b]*i=opentui-notifications[^\\x07\\x1b]*p=\\?[\\s\\S]*?(?:\\x07|\\x1b\\\\)/.test(sequence)) {\n return true\n }\n\n // iTerm2 feature reporting response. The native parser decides whether the\n // feature string contains the Notifications feature code.\n if (/\\x1b\\]1337;Capabilities=[\\s\\S]*?(?:\\x07|\\x1b\\\\)/.test(sequence)) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a sequence is a pixel resolution response.\n * Format: ESC[4;height;widtht\n */\nexport function isPixelResolutionResponse(sequence: string): boolean {\n return /\\x1b\\[4;\\d+;\\d+t/.test(sequence)\n}\n\n/**\n * Parse pixel resolution from response sequence.\n * Returns { width, height } or null if not a valid resolution response.\n */\nexport function parsePixelResolution(sequence: string): { width: number; height: number } | null {\n const match = sequence.match(/\\x1b\\[4;(\\d+);(\\d+)t/)\n if (match) {\n return {\n width: parseInt(match[2]),\n height: parseInt(match[1]),\n }\n }\n return null\n}\n", + "import { parseColor } from \"./lib/RGBA.js\"\nimport { type Clock, type TimerHandle } from \"./lib/clock.js\"\nimport type { ThemeMode } from \"./types.js\"\n\nconst OSC_THEME_RESPONSE =\n /\\x1b](10|11);(?:(?:rgb:)([0-9a-fA-F]+)\\/([0-9a-fA-F]+)\\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\\x07|\\x1b\\\\)/g\n\nfunction scaleOscThemeComponent(component: string): string {\n const value = parseInt(component, 16)\n const maxValue = (1 << (4 * component.length)) - 1\n return Math.round((value / maxValue) * 255)\n .toString(16)\n .padStart(2, \"0\")\n}\n\nfunction oscThemeColorToHex(r?: string, g?: string, b?: string, hex6?: string): string {\n if (hex6) {\n return `#${hex6.toLowerCase()}`\n }\n\n if (r && g && b) {\n return `#${scaleOscThemeComponent(r)}${scaleOscThemeComponent(g)}${scaleOscThemeComponent(b)}`\n }\n\n return \"#000000\"\n}\n\nfunction inferThemeModeFromBackgroundColor(color: string): ThemeMode {\n const [r, g, b] = parseColor(color).toInts()\n const brightness = (r * 299 + g * 587 + b * 114) / 1000\n return brightness > 128 ? \"light\" : \"dark\"\n}\n\nexport interface RendererThemeModeHost {\n queryThemeColors(): void\n}\n\ntype ThemeWaiter = {\n resolve: (mode: ThemeMode | null) => void\n timeoutHandle: TimerHandle | null\n}\n\nexport class RendererThemeMode {\n private static readonly QUERY_TIMEOUT_MS = 250\n\n private _themeMode: ThemeMode | null = null\n private themeQueryPending = true\n private themeOscForeground: string | null = null\n private themeOscBackground: string | null = null\n private themeRefreshTimeoutId: TimerHandle | null = null\n private waiters = new Set()\n\n constructor(\n private readonly host: RendererThemeModeHost,\n private readonly clock: Clock,\n ) {}\n\n public get themeMode(): ThemeMode | null {\n return this._themeMode\n }\n\n public waitForThemeMode(timeoutMs: number, isDestroyed: boolean): Promise {\n if (this._themeMode !== null || isDestroyed || timeoutMs === 0) {\n return Promise.resolve(this._themeMode)\n }\n\n return new Promise((resolve) => {\n const waiter: ThemeWaiter = {\n resolve,\n timeoutHandle: null,\n }\n\n if (timeoutMs > 0) {\n waiter.timeoutHandle = this.clock.setTimeout(() => {\n this.waiters.delete(waiter)\n waiter.timeoutHandle = null\n resolve(this._themeMode)\n }, timeoutMs)\n }\n\n this.waiters.add(waiter)\n })\n }\n\n public cancelRefresh(): void {\n if (this.themeRefreshTimeoutId === null) {\n return\n }\n\n this.clock.clearTimeout(this.themeRefreshTimeoutId)\n this.themeRefreshTimeoutId = null\n this.themeQueryPending = false\n }\n\n public dispose(): void {\n this.cancelRefresh()\n\n for (const waiter of this.waiters) {\n if (waiter.timeoutHandle !== null) {\n this.clock.clearTimeout(waiter.timeoutHandle)\n }\n waiter.resolve(this._themeMode)\n }\n\n this.waiters.clear()\n }\n\n public handleSequence(sequence: string): { handled: boolean; changedMode: ThemeMode | null } {\n if (sequence === \"\\x1b[?997;1n\" || sequence === \"\\x1b[?997;2n\") {\n this.requestThemeOscColors()\n return { handled: true, changedMode: null }\n }\n\n let handledOscThemeResponse = false\n let match: RegExpExecArray | null\n\n OSC_THEME_RESPONSE.lastIndex = 0\n while ((match = OSC_THEME_RESPONSE.exec(sequence))) {\n handledOscThemeResponse = true\n const color = oscThemeColorToHex(match[2], match[3], match[4], match[5])\n\n if (match[1] === \"10\") {\n this.themeOscForeground = color\n } else {\n this.themeOscBackground = color\n }\n }\n\n if (!handledOscThemeResponse) {\n return { handled: false, changedMode: null }\n }\n\n if (!this.themeQueryPending) {\n return { handled: true, changedMode: null }\n }\n\n if (!this.themeOscForeground || !this.themeOscBackground) {\n return { handled: true, changedMode: null }\n }\n\n const nextMode = inferThemeModeFromBackgroundColor(this.themeOscBackground)\n const changedMode = this.applyThemeMode(nextMode)\n this.completeThemeQuery()\n\n return { handled: true, changedMode }\n }\n\n private clearThemeRefreshTimeout(): void {\n if (this.themeRefreshTimeoutId === null) {\n return\n }\n\n this.clock.clearTimeout(this.themeRefreshTimeoutId)\n this.themeRefreshTimeoutId = null\n }\n\n private completeThemeQuery(): void {\n this.clearThemeRefreshTimeout()\n this.themeQueryPending = false\n }\n\n private requestThemeOscColors(): void {\n // Ignore repeated ?997 notifications while the current OSC refresh is\n // still in flight.\n if (this.themeRefreshTimeoutId !== null) {\n return\n }\n\n this.themeQueryPending = true\n this.themeOscForeground = null\n this.themeOscBackground = null\n\n this.host.queryThemeColors()\n\n this.clearThemeRefreshTimeout()\n this.themeRefreshTimeoutId = this.clock.setTimeout(() => {\n this.completeThemeQuery()\n }, RendererThemeMode.QUERY_TIMEOUT_MS)\n }\n\n private applyThemeMode(mode: ThemeMode): ThemeMode | null {\n const changed = this._themeMode !== mode\n this._themeMode = mode\n\n if (!changed) {\n return null\n }\n\n for (const waiter of this.waiters) {\n if (waiter.timeoutHandle !== null) {\n this.clock.clearTimeout(waiter.timeoutHandle)\n }\n waiter.resolve(mode)\n }\n\n this.waiters.clear()\n return mode\n }\n}\n" + ], + "mappings": "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", + "debugId": "D566D64CFF69CBEF64756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/.patches/@opentui/core/index-pcvh9d34.js b/.patches/@opentui/core/index-pcvh9d34.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/index-pcvh9d34.js @@ -0,0 +1,16213 @@ +import { createRequire } from "node:module"; +var __create = Object.create; +var __getProtoOf = Object.getPrototypeOf; +var __defProp = Object.defineProperty; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +function __accessProp(key) { + return this[key]; +} +var __toESMCache_node; +var __toESMCache_esm; +var __toESM = (mod, isNodeMode, target) => { + var canCache = mod != null && typeof mod === "object"; + if (canCache) { + var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap; + var cached = cache.get(mod); + if (cached) + return cached; + } + target = mod != null ? __create(__getProtoOf(mod)) : {}; + const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target; + for (let key of __getOwnPropNames(mod)) + if (!__hasOwnProp.call(to, key)) + __defProp(to, key, { + get: __accessProp.bind(mod, key), + enumerable: true + }); + if (canCache) + cache.set(mod, to); + return to; +}; +var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); +var __returnValue = (v) => v; +function __exportSetter(name, newValue) { + this[name] = __returnValue.bind(null, newValue); +} +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { + get: all[name], + enumerable: true, + configurable: true, + set: __exportSetter.bind(all, name) + }); +}; +var __require = /* @__PURE__ */ createRequire(import.meta.url); + +// ../../node_modules/.bun/emoji-regex@10.6.0/node_modules/emoji-regex/index.js +var require_emoji_regex = __commonJS((exports, module) => { + module.exports = () => { + return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g; + }; +}); + +// src/yoga.ts +var exports_yoga = {}; +__export(exports_yoga, { + default: () => yoga_default, + Wrap: () => Wrap, + WRAP_WRAP_REVERSE: () => WRAP_WRAP_REVERSE, + WRAP_WRAP: () => WRAP_WRAP, + WRAP_NO_WRAP: () => WRAP_NO_WRAP, + Unit: () => Unit, + UNIT_UNDEFINED: () => UNIT_UNDEFINED, + UNIT_POINT: () => UNIT_POINT, + UNIT_PERCENT: () => UNIT_PERCENT, + UNIT_AUTO: () => UNIT_AUTO, + PositionType: () => PositionType, + POSITION_TYPE_STATIC: () => POSITION_TYPE_STATIC, + POSITION_TYPE_RELATIVE: () => POSITION_TYPE_RELATIVE, + POSITION_TYPE_ABSOLUTE: () => POSITION_TYPE_ABSOLUTE, + Overflow: () => Overflow, + OVERFLOW_VISIBLE: () => OVERFLOW_VISIBLE, + OVERFLOW_SCROLL: () => OVERFLOW_SCROLL, + OVERFLOW_HIDDEN: () => OVERFLOW_HIDDEN, + NodeType: () => NodeType, + Node: () => Node, + NODE_TYPE_TEXT: () => NODE_TYPE_TEXT, + NODE_TYPE_DEFAULT: () => NODE_TYPE_DEFAULT, + MeasureMode: () => MeasureMode, + MEASURE_MODE_UNDEFINED: () => MEASURE_MODE_UNDEFINED, + MEASURE_MODE_EXACTLY: () => MEASURE_MODE_EXACTLY, + MEASURE_MODE_AT_MOST: () => MEASURE_MODE_AT_MOST, + LogLevel: () => LogLevel, + LOG_LEVEL_WARN: () => LOG_LEVEL_WARN, + LOG_LEVEL_VERBOSE: () => LOG_LEVEL_VERBOSE, + LOG_LEVEL_INFO: () => LOG_LEVEL_INFO, + LOG_LEVEL_FATAL: () => LOG_LEVEL_FATAL, + LOG_LEVEL_ERROR: () => LOG_LEVEL_ERROR, + LOG_LEVEL_DEBUG: () => LOG_LEVEL_DEBUG, + Justify: () => Justify, + JUSTIFY_SPACE_EVENLY: () => JUSTIFY_SPACE_EVENLY, + JUSTIFY_SPACE_BETWEEN: () => JUSTIFY_SPACE_BETWEEN, + JUSTIFY_SPACE_AROUND: () => JUSTIFY_SPACE_AROUND, + JUSTIFY_FLEX_START: () => JUSTIFY_FLEX_START, + JUSTIFY_FLEX_END: () => JUSTIFY_FLEX_END, + JUSTIFY_CENTER: () => JUSTIFY_CENTER, + Gutter: () => Gutter, + GUTTER_ROW: () => GUTTER_ROW, + GUTTER_COLUMN: () => GUTTER_COLUMN, + GUTTER_ALL: () => GUTTER_ALL, + FlexDirection: () => FlexDirection, + FLEX_DIRECTION_ROW_REVERSE: () => FLEX_DIRECTION_ROW_REVERSE, + FLEX_DIRECTION_ROW: () => FLEX_DIRECTION_ROW, + FLEX_DIRECTION_COLUMN_REVERSE: () => FLEX_DIRECTION_COLUMN_REVERSE, + FLEX_DIRECTION_COLUMN: () => FLEX_DIRECTION_COLUMN, + ExperimentalFeature: () => ExperimentalFeature, + Errata: () => Errata, + Edge: () => Edge, + EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS: () => EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, + ERRATA_STRETCH_FLEX_BASIS: () => ERRATA_STRETCH_FLEX_BASIS, + ERRATA_NONE: () => ERRATA_NONE, + ERRATA_CLASSIC: () => ERRATA_CLASSIC, + ERRATA_ALL: () => ERRATA_ALL, + ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING: () => ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, + ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE: () => ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, + EDGE_VERTICAL: () => EDGE_VERTICAL, + EDGE_TOP: () => EDGE_TOP, + EDGE_START: () => EDGE_START, + EDGE_RIGHT: () => EDGE_RIGHT, + EDGE_LEFT: () => EDGE_LEFT, + EDGE_HORIZONTAL: () => EDGE_HORIZONTAL, + EDGE_END: () => EDGE_END, + EDGE_BOTTOM: () => EDGE_BOTTOM, + EDGE_ALL: () => EDGE_ALL, + Display: () => Display, + Direction: () => Direction, + Dimension: () => Dimension, + DISPLAY_NONE: () => DISPLAY_NONE, + DISPLAY_FLEX: () => DISPLAY_FLEX, + DISPLAY_CONTENTS: () => DISPLAY_CONTENTS, + DIRECTION_RTL: () => DIRECTION_RTL, + DIRECTION_LTR: () => DIRECTION_LTR, + DIRECTION_INHERIT: () => DIRECTION_INHERIT, + DIMENSION_WIDTH: () => DIMENSION_WIDTH, + DIMENSION_HEIGHT: () => DIMENSION_HEIGHT, + Config: () => Config, + BoxSizing: () => BoxSizing, + BOX_SIZING_CONTENT_BOX: () => BOX_SIZING_CONTENT_BOX, + BOX_SIZING_BORDER_BOX: () => BOX_SIZING_BORDER_BOX, + Align: () => Align, + ALIGN_STRETCH: () => ALIGN_STRETCH, + ALIGN_SPACE_EVENLY: () => ALIGN_SPACE_EVENLY, + ALIGN_SPACE_BETWEEN: () => ALIGN_SPACE_BETWEEN, + ALIGN_SPACE_AROUND: () => ALIGN_SPACE_AROUND, + ALIGN_FLEX_START: () => ALIGN_FLEX_START, + ALIGN_FLEX_END: () => ALIGN_FLEX_END, + ALIGN_CENTER: () => ALIGN_CENTER, + ALIGN_BASELINE: () => ALIGN_BASELINE, + ALIGN_AUTO: () => ALIGN_AUTO +}); + +// src/platform/ffi.ts +import { createRequire as createRequire2 } from "node:module"; +import { fileURLToPath } from "node:url"; +var FFIType = { + char: "char", + int8_t: "int8_t", + i8: "i8", + uint8_t: "uint8_t", + u8: "u8", + int16_t: "int16_t", + i16: "i16", + uint16_t: "uint16_t", + u16: "u16", + int32_t: "int32_t", + i32: "i32", + int: "int", + uint32_t: "uint32_t", + u32: "u32", + int64_t: "int64_t", + i64: "i64", + uint64_t: "uint64_t", + u64: "u64", + double: "double", + f64: "f64", + float: "float", + f32: "f32", + bool: "bool", + ptr: "ptr", + pointer: "pointer", + void: "void", + cstring: "cstring", + function: "function", + usize: "usize", + callback: "callback", + napi_env: "napi_env", + napi_value: "napi_value", + buffer: "buffer" +}; +var FFI_UNAVAILABLE = "OpenTUI native FFI is not available for this runtime yet"; +var BUN_DLOPEN_NULL = "Bun FFI backend does not support dlopen(null)"; +var LIBRARY_CLOSED = "Cannot create FFI callback after library.close() has been called"; +var NODE_CALLBACK_THREADSAFE = "Node FFI callbacks are same-thread only and do not support threadsafe callbacks"; +var NODE_NAPI_UNSUPPORTED = "Node FFI backend does not support Bun N-API FFI types"; +var NODE_POINTER_OVERRIDE = "Node FFI backend does not support FFIFunction.ptr overrides"; +var NODE_POINTER_ARGUMENT = "Node FFI pointer arguments must be a Pointer, ArrayBuffer, or ArrayBufferView"; +var NODE_PTR_VALUE = "node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values backed by ArrayBuffer"; +var NODE_STRING_RETURN = "Node FFI backend does not normalize string return values (yet)"; +var NODE_USIZE_UNSUPPORTED = "Node FFI backend does not support usize yet"; +var POINTER_NEGATIVE = "Pointer must be non-negative"; +var POINTER_OFFSET_NEGATIVE = "Pointer offset must be non-negative"; +var POINTER_OFFSET_UNSAFE = "Pointer offset must be a safe integer"; +var POINTER_UNSAFE = "Pointer exceeds safe integer range"; +function unavailable(cause) { + throw new Error(FFI_UNAVAILABLE, { cause }); +} +function createUnsupportedBackend(cause) { + return { + dlopen() { + return unavailable(cause); + }, + ptr() { + return unavailable(cause); + }, + suffix: "", + toArrayBuffer() { + return unavailable(cause); + } + }; +} +var isBun = typeof process !== "undefined" && typeof process.versions === "object" && process.versions !== null && typeof process.versions.bun === "string"; +const isDeno = typeof globalThis !== "undefined" && "Deno" in globalThis; +var requireModule = createRequire2(import.meta.url); +var backend = loadBackend(); +function loadBackend() { + if (isBun) { + return createBunBackend(requireModule("bun:ffi")); + } + if (isDeno) { + return createDenoBackend(); + } + try { + const nodeFfi = requireModule("node:ffi"); + return createNodeBackend(nodeFfi.default ?? nodeFfi); + } catch (error) { + return createUnsupportedBackend(error); + } +} +function toPointer(value) { + if (isBun && typeof value === "bigint") { + return toSafeNumberPointer(value); + } + if (!isBun && typeof value === "number") { + return toSafeBigIntPointer(value); + } + return value; +} +function ffiBool(value) { + return value ? 1 : 0; +} +function toSafeNumberPointer(pointer) { + if (pointer < 0n) { + throw new Error(POINTER_NEGATIVE); + } + if (pointer > BigInt(Number.MAX_SAFE_INTEGER)) { + throw new Error(POINTER_UNSAFE); + } + return Number(pointer); +} +function toSafeBigIntPointer(pointer) { + if (pointer < 0) { + throw new Error(POINTER_NEGATIVE); + } + if (!Number.isSafeInteger(pointer)) { + throw new Error(POINTER_UNSAFE); + } + return BigInt(pointer); +} +function createManagedCallback(raw, callbacks) { + let ptr = raw.ptr; + let closed = false; + const instance = { + get ptr() { + return ptr; + }, + get threadsafe() { + return raw.threadsafe; + }, + close() { + if (closed) { + return; + } + closed = true; + callbacks.delete(instance); + try { + raw.close(); + } finally { + ptr = null; + } + } + }; + callbacks.add(instance); + return instance; +} +function normalizeBunDefinitions(definitions) { + return Object.fromEntries(Object.entries(definitions).map(([name, definition]) => [name, normalizeBunDefinition(definition)])); +} +function normalizeBunDefinition(definition) { + return { + args: definition.args, + returns: definition.returns, + ptr: definition.ptr == null ? undefined : toBunPointer(definition.ptr), + threadsafe: definition.threadsafe + }; +} +function toBunPointer(pointer) { + return typeof pointer === "bigint" ? toSafeNumberPointer(pointer) : pointer; +} +function createBunBackend(bun) { + return { + dlopen(path, symbols) { + if (path === null) { + throw new Error(BUN_DLOPEN_NULL); + } + const library = bun.dlopen(path, normalizeBunDefinitions(symbols)); + const callbacks = new Set; + let closed = false; + return { + symbols: library.symbols, + createCallback(callback, definition) { + if (closed) { + throw new Error(LIBRARY_CLOSED); + } + const raw = new bun.JSCallback(callback, normalizeBunDefinition(definition)); + return createManagedCallback(raw, callbacks); + }, + close() { + if (closed) { + return; + } + closed = true; + try { + library.close(); + } finally { + for (const callback of [...callbacks]) { + callback.close(); + } + } + } + }; + }, + ptr: bun.ptr, + suffix: bun.suffix, + toArrayBuffer(pointer, offset, length) { + return bun.toArrayBuffer(toBunPointer(pointer), offset, length); + } + }; +} +export function createDenoBackend() { + const DenoGlobal = (globalThis).Deno; + + function unwrapToBigInt(arg) { + if (arg == null) return 0n; + if (typeof arg === "bigint") return arg; + if (typeof arg === "number") return toSafeBigIntPointer(arg); + + if (typeof arg === "object" && "pointer" in arg) { + return BigInt(DenoGlobal.UnsafePointer.value(arg)); + } + + try { + return BigInt( + DenoGlobal.UnsafePointer.value(DenoGlobal.UnsafePointer.of(arg)), + ); + } catch { + return 0n; + } + } + + return { + dlopen(path, symbols) { + const denoPath = path instanceof URL ? fileURLToPath(path) : path; + + const denoSymbols = Object.fromEntries( + Object.entries(symbols).map(([name, def]) => [ + name, + { + parameters: (def.args ?? []).map(toDenoFFIType), + result: toDenoFFIType(def.returns ?? FFIType.void), + nonblocking: def.threadsafe ?? false, + }, + ]), + ); + + const library = DenoGlobal.dlopen(denoPath, denoSymbols); + const callbacks = new Set(); + let closed = false; + + const wrappedSymbols = Object.fromEntries( + Object.entries(library.symbols).map(([name, symbolFn]) => { + const definition = symbols[name]; + return [ + name, + (...args) => { + const normalizedArgs = args.map((arg, idx) => { + const type = definition.args?.[idx]; + + if (type && isPointerLikeType(type)) { + if (arg == null) return null; + return DenoGlobal.UnsafePointer.create(unwrapToBigInt(arg)); + } + + if (type === FFIType.bool) { + return Boolean(arg); + } + + return arg; + }); + + const result = (symbolFn)(...normalizedArgs); + + if (definition.returns && isPointerLikeType(definition.returns)) { + return (result === null + ? 0n + : BigInt(DenoGlobal.UnsafePointer.value(result))); + } + return result; + return result; + }, + ]; + }), + ); + + return { + symbols: wrappedSymbols, + createCallback(callback, definition) { + if (closed) { + throw new Error(LIBRARY_CLOSED); + } + + const callbackSignal = { + parameters: (definition.args ?? []).map(toDenoFFIType), + result: toDenoFFIType(definition.returns ?? FFIType.void), + }; + + const denoCallback = new DenoGlobal.UnsafeCallback( + callbackSignal, + (...args) => { + const normalizedArgs = args.map((arg, idx) => { + const type = definition.args?.[idx]; + if (type && isPointerLikeType(type)) { + return (arg === null + ? 0n + : DenoGlobal.UnsafePointer.of(arg)); + } + return arg; + }); + return callback(...normalizedArgs); + }, + ); + + const raw = { + ptr: denoCallback, + threadsafe: definition.threadsafe ?? false, + close() { + denoCallback.close(); + }, + }; + + return createManagedCallback(raw, callbacks); + }, + close() { + if (closed) { + return; + } + closed = true; + try { + library.close(); + } finally { + for (const callback of [...callbacks]) { + callback.close(); + } + } + }, + }; + }, + ptr(value) { + const buffer = ArrayBuffer.isView(value) ? value.buffer : value; + const offset = ArrayBuffer.isView(value) ? value.byteOffset : 0; + const basePointer = DenoGlobal.UnsafePointer.of(buffer); + if (basePointer === null) return 0n; + + const baseBigInt = BigInt(DenoGlobal.UnsafePointer.value(basePointer)); + return (baseBigInt + BigInt(offset)); + }, + get suffix() { + switch (DenoGlobal.build.os) { + case "windows": + return ".dll"; + case "darwin": + return ".dylib"; + default: + return ".so"; + } + }, + toArrayBuffer(pointer, offset, length) { + const ptrBigInt = unwrapToBigInt(pointer) + toNodePointerOffset(offset); + const denoPtr = DenoGlobal.UnsafePointer.create(ptrBigInt); + if (denoPtr === null) return new ArrayBuffer(0); + const view = new DenoGlobal.UnsafePointerView(denoPtr); + return view.getArrayBuffer(length); + }, + }; +} +function createNodeBackend(nodeFfi) { + return { + dlopen(path, symbols) { + const { lib, functions } = nodeFfi.dlopen(toNodeLibraryPath(path), normalizeNodeDefinitions(symbols)); + const callbacks = new Set; + let closed = false; + let libraryClosed = false; + return { + symbols: wrapNodeSymbols(functions, symbols, nodeFfi), + createCallback(callback, definition) { + if (closed) { + throw new Error(LIBRARY_CLOSED); + } + if (definition.threadsafe) { + throw new Error(NODE_CALLBACK_THREADSAFE); + } + const callbackPointer = lib.registerCallback(normalizeNodeDefinition(definition), callback); + const raw = { + ptr: callbackPointer, + threadsafe: false, + close() { + if (!libraryClosed) { + lib.unregisterCallback(callbackPointer); + } + } + }; + return createManagedCallback(raw, callbacks); + }, + close() { + if (closed) { + return; + } + closed = true; + try { + libraryClosed = true; + lib.close(); + } finally { + for (const callback of [...callbacks]) { + callback.close(); + } + } + } + }; + }, + ptr(value) { + return toNodeSourcePointer(nodeFfi, value); + }, + suffix: nodeFfi.suffix, + toArrayBuffer(pointer, offset, length) { + return nodeFfi.toArrayBuffer(toBigIntPointer(pointer) + toNodePointerOffset(offset), length, false); + } + }; +} +function toNodeLibraryPath(path) { + return path instanceof URL ? fileURLToPath(path) : path; +} +function normalizeNodeDefinitions(definitions) { + return Object.fromEntries(Object.entries(definitions).map(([name, definition]) => [name, normalizeNodeDefinition(definition)])); +} +function wrapNodeSymbols(functions, definitions, nodeFfi) { + return Object.fromEntries(Object.entries(functions).map(([name, fn]) => [name, wrapNodeSymbol(fn, definitions[name], nodeFfi)])); +} +function wrapNodeSymbol(fn, definition, nodeFfi) { + const pointerArgIndexes = (definition.args ?? []).flatMap((type, index) => isNodePointerArgumentType(type) ? [index] : []); + if (pointerArgIndexes.length === 0) { + return fn; + } + return (...args) => { + const normalizedArgs = args.slice(); + for (const index of pointerArgIndexes) { + normalizedArgs[index] = toNodePointerArgument(nodeFfi, normalizedArgs[index]); + } + return fn(...normalizedArgs); + }; +} +function isNodePointerArgumentType(type) { + return type === FFIType.ptr || type === FFIType.pointer || type === FFIType.function || type === FFIType.callback; +} +function toNodePointerArgument(nodeFfi, value) { + if (value == null) { + return 0n; + } + if (typeof value === "number" || typeof value === "bigint") { + return toBigIntPointer(value); + } + if (ArrayBuffer.isView(value)) { + if (value.byteLength === 0) { + return 0n; + } + return toNodeSourcePointer(nodeFfi, value); + } + if (value instanceof ArrayBuffer) { + if (value.byteLength === 0) { + return 0n; + } + return toNodeSourcePointer(nodeFfi, value); + } + throw new TypeError(NODE_POINTER_ARGUMENT); +} +function toNodeSourcePointer(nodeFfi, value) { + if (ArrayBuffer.isView(value)) { + if (!(value.buffer instanceof ArrayBuffer)) { + throw new TypeError(NODE_PTR_VALUE); + } + return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset); + } + if (value instanceof ArrayBuffer) { + return nodeFfi.getRawPointer(value); + } + throw new TypeError(NODE_PTR_VALUE); +} +function toNodePointerOffset(offset) { + if (offset == null) { + return 0n; + } + if (offset < 0) { + throw new Error(POINTER_OFFSET_NEGATIVE); + } + if (!Number.isSafeInteger(offset)) { + throw new Error(POINTER_OFFSET_UNSAFE); + } + return BigInt(offset); +} +function normalizeNodeDefinition(definition) { + if (definition.ptr != null) { + throw new Error(NODE_POINTER_OVERRIDE); + } + return { + arguments: (definition.args ?? []).map((type) => toNodeFFIType(type, "parameter")), + return: toNodeFFIType(definition.returns ?? FFIType.void, "result") + }; +} +function toDenoFFIType(type) { + switch (type) { + case FFIType.char: + return "i8"; + case FFIType.int8_t: + case FFIType.i8: + return "i8"; + case FFIType.uint8_t: + case FFIType.u8: + return "u8"; + case FFIType.int16_t: + case FFIType.i16: + return "i16"; + case FFIType.uint16_t: + case FFIType.u16: + return "u16"; + case FFIType.int32_t: + case FFIType.int: + case FFIType.i32: + return "i32"; + case FFIType.uint32_t: + case FFIType.u32: + return "u32"; + case FFIType.int64_t: + case FFIType.i64: + return "i64"; + case FFIType.uint64_t: + case FFIType.u64: + return "u64"; + case FFIType.double: + case FFIType.f64: + return "f64"; + case FFIType.float: + case FFIType.f32: + return "f32"; + case FFIType.bool: + return "bool"; + case FFIType.ptr: + case FFIType.pointer: + case FFIType.function: + case FFIType.callback: + case FFIType.buffer: + return "pointer"; + case FFIType.void: + return "void"; + case FFIType.cstring: + return "buffer"; + case FFIType.usize: + return "usize"; + case FFIType.napi_env: + case FFIType.napi_value: + throw new Error(DENO_NAPI_UNSUPPORTED); + default: + return type; + } +} +function isPointerLikeType(type) { + return ( + type === FFIType.ptr || + type === FFIType.pointer || + type === FFIType.function || + type === FFIType.callback || + type === FFIType.buffer || + type === FFIType.cstring + ); +} +function toNodeFFIType(type, position) { + switch (type) { + case FFIType.char: + return "char"; + case FFIType.int8_t: + case FFIType.i8: + return "i8"; + case FFIType.uint8_t: + case FFIType.u8: + return "u8"; + case FFIType.int16_t: + case FFIType.i16: + return "i16"; + case FFIType.uint16_t: + case FFIType.u16: + return "u16"; + case FFIType.int32_t: + case FFIType.int: + case FFIType.i32: + return "i32"; + case FFIType.uint32_t: + case FFIType.u32: + return "u32"; + case FFIType.int64_t: + case FFIType.i64: + return "i64"; + case FFIType.uint64_t: + case FFIType.u64: + return "u64"; + case FFIType.double: + case FFIType.f64: + return "f64"; + case FFIType.float: + case FFIType.f32: + return "f32"; + case FFIType.bool: + return "bool"; + case FFIType.ptr: + case FFIType.pointer: + return "pointer"; + case FFIType.void: + return "void"; + case FFIType.cstring: + if (position === "result") { + throw new Error(NODE_STRING_RETURN); + } + return "string"; + case FFIType.function: + case FFIType.callback: + return "pointer"; + case FFIType.usize: + throw new Error(NODE_USIZE_UNSUPPORTED); + case FFIType.napi_env: + case FFIType.napi_value: + throw new Error(NODE_NAPI_UNSUPPORTED); + case FFIType.buffer: + return "buffer"; + default: + return unsupportedNodeFFIType(type); + } +} +function unsupportedNodeFFIType(type) { + throw new Error(`Unsupported FFIType for node:ffi: ${String(type)}`); +} +function toBigIntPointer(pointer) { + if (typeof pointer === "bigint") { + if (pointer < 0n) { + throw new Error(POINTER_NEGATIVE); + } + return pointer; + } + return toSafeBigIntPointer(pointer); +} +var dlopen = backend.dlopen; +var ptr = backend.ptr; +var suffix = backend.suffix; +var toArrayBuffer = backend.toArrayBuffer; + +// src/platform/runtime.ts +import { existsSync } from "node:fs"; +import { mkdir, writeFile as writeFileNode } from "node:fs/promises"; +import { dirname, isAbsolute, resolve } from "node:path"; +import { fileURLToPath as fileURLToPath2 } from "node:url"; + +// ../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js +function ansiRegex({ onlyFirst = false } = {}) { + const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)"; + const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`; + const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]"; + const pattern = `${osc}|${csi}`; + return new RegExp(pattern, onlyFirst ? undefined : "g"); +} + +// ../../node_modules/.bun/strip-ansi@7.1.2/node_modules/strip-ansi/index.js +var regex = ansiRegex(); +function stripAnsi(string) { + if (typeof string !== "string") { + throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); + } + return string.replace(regex, ""); +} + +// ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js +function isAmbiguous(x) { + return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109; +} +function isFullWidth(x) { + return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510; +} +function isWide(x) { + return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141; +} + +// ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js +function validate(codePoint) { + if (!Number.isSafeInteger(codePoint)) { + throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`); + } +} +function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) { + validate(codePoint); + if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) { + return 2; + } + return 1; +} + +// ../../node_modules/.bun/string-width@7.2.0/node_modules/string-width/index.js +var import_emoji_regex = __toESM(require_emoji_regex(), 1); +var segmenter = new Intl.Segmenter; +var defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u; +function stringWidth(string, options = {}) { + if (typeof string !== "string" || string.length === 0) { + return 0; + } + const { + ambiguousIsNarrow = true, + countAnsiEscapeCodes = false + } = options; + if (!countAnsiEscapeCodes) { + string = stripAnsi(string); + } + if (string.length === 0) { + return 0; + } + let width = 0; + const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow }; + for (const { segment: character } of segmenter.segment(string)) { + const codePoint = character.codePointAt(0); + if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) { + continue; + } + if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) { + continue; + } + if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) { + continue; + } + if (codePoint >= 55296 && codePoint <= 57343) { + continue; + } + if (codePoint >= 65024 && codePoint <= 65039) { + continue; + } + if (defaultIgnorableCodePointRegex.test(character)) { + continue; + } + if (import_emoji_regex.default().test(character)) { + width += 2; + continue; + } + width += eastAsianWidth(codePoint, eastAsianWidthOptions); + } + return width; +} + +// src/platform/runtime.ts +var TEXT_ENCODER = new TextEncoder; +var bun = globalThis.Bun; +var sleep = bun?.sleep ?? standardSleep; +var stringWidth2 = bun?.stringWidth ?? stringWidth; +var stripANSI = bun?.stripANSI ?? stripAnsi; +var writeFile = bun?.write ?? writeFilePortable; +async function resolveBundledFilePath(loadBundledFile, fallbackPath, metaUrl) { + if (!bun) { + const path = resolveFallbackFilePath(fallbackPath, metaUrl); + if (existsSync(path)) { + return path; + } + return await loadBundledFilePath(loadBundledFile, metaUrl) ?? path; + } + return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl); +} +function resolveFallbackFilePath(fallbackPath, metaUrl) { + const path = typeof fallbackPath === "function" ? fallbackPath() : fallbackPath; + return fileURLToPath2(path instanceof URL ? path : new URL(path, metaUrl)); +} +function normalizeLoadedFilePath(loadedPath, baseUrl) { + if (loadedPath.startsWith("file:")) { + return fileURLToPath2(loadedPath); + } + if (isAbsolute(loadedPath)) { + return loadedPath; + } + return resolve(dirname(fileURLToPath2(baseUrl)), loadedPath); +} +async function loadBundledFilePath(loadBundledFile, metaUrl) { + const specifier = extractBundledImportSpecifier(loadBundledFile); + if (!specifier) { + return; + } + try { + const moduleUrl = new URL(specifier, metaUrl); + const loaded = await import(moduleUrl.href); + return normalizeLoadedFilePath(loaded.default, moduleUrl.href); + } catch { + return; + } +} +function extractBundledImportSpecifier(loadBundledFile) { + const match = String(loadBundledFile).match(/\bimport\(\s*(["'`])([^"'`]+)\1/); + return match?.[2]; +} +function standardSleep(msOrDate) { + const ms = msOrDate instanceof Date ? msOrDate.getTime() - Date.now() : msOrDate; + return new Promise((resolve2) => setTimeout(resolve2, ms)); +} +async function writeFilePortable(destination, data, options) { + const destinationPath = destination instanceof URL ? fileURLToPath2(destination) : destination; + if (options?.createPath) { + await mkdir(dirname(destinationPath), { recursive: true }); + } + const bytes = typeof data === "string" ? TEXT_ENCODER.encode(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength); + await writeFileNode(destinationPath, bytes, { mode: options?.mode }); + return bytes.byteLength; +} + +// src/zig.ts +import { existsSync as existsSync3, writeFileSync } from "fs"; +import { EventEmitter as EventEmitter4 } from "events"; + +// src/lib/RGBA.ts +var DEFAULT_FOREGROUND_RGB = [255, 255, 255]; +var DEFAULT_BACKGROUND_RGB = [0, 0, 0]; +var INTENT_RGB = 0; +var INTENT_INDEXED = 1; +var INTENT_DEFAULT = 2; +var ANSI16_RGB = [ + [0, 0, 0], + [128, 0, 0], + [0, 128, 0], + [128, 128, 0], + [0, 0, 128], + [128, 0, 128], + [0, 128, 128], + [192, 192, 192], + [128, 128, 128], + [255, 0, 0], + [0, 255, 0], + [255, 255, 0], + [0, 0, 255], + [255, 0, 255], + [0, 255, 255], + [255, 255, 255] +]; +var ANSI_256_CUBE_LEVELS = [0, 95, 135, 175, 215, 255]; +function packMeta(intent, slot = 0) { + return (slot & 255 | (intent & 255) << 8) >>> 0; +} +function toU8(value) { + return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255); +} +function toByte(value) { + return Math.round(Math.max(0, Math.min(255, Number.isFinite(value) ? value : 0))); +} +function packRGBA8(r, g, b, a, meta) { + return new Uint16Array([ + toByte(r) & 255 | (meta >>> 0 & 255) << 8, + toByte(g) & 255 | (meta >>> 8 & 255) << 8, + toByte(b) & 255 | (meta >>> 16 & 255) << 8, + toByte(a) & 255 | (meta >>> 24 & 255) << 8 + ]); +} +function rgbaForAnsi256Index(index) { + const [r, g, b] = ansi256IndexToRgb(index); + return RGBA.fromInts(r, g, b); +} +function normalizeIndexedColorIndex(index) { + if (!Number.isInteger(index) || index < 0 || index > 255) { + throw new RangeError(`Indexed color must be an integer in the range 0..255, got ${index}`); + } + return index; +} +function ansi256IndexToRgb(index) { + const normalizedIndex = normalizeIndexedColorIndex(index); + if (normalizedIndex < ANSI16_RGB.length) { + return ANSI16_RGB[normalizedIndex]; + } + if (normalizedIndex < 232) { + const cubeIndex = normalizedIndex - 16; + const r = Math.floor(cubeIndex / 36); + const g = Math.floor(cubeIndex / 6) % 6; + const b = cubeIndex % 6; + return [ANSI_256_CUBE_LEVELS[r], ANSI_256_CUBE_LEVELS[g], ANSI_256_CUBE_LEVELS[b]]; + } + const value = 8 + (normalizedIndex - 232) * 10; + return [value, value, value]; +} + +class RGBA { + buffer; + constructor(buffer) { + this.buffer = new Uint16Array(4); + this.buffer.set(buffer.subarray(0, 4)); + } + static fromArray(array) { + return new RGBA(array); + } + static fromValues(r, g, b, a = 1) { + return new RGBA(packRGBA8(toU8(r), toU8(g), toU8(b), toU8(a), packMeta(INTENT_RGB))); + } + static clone(rgba) { + return new RGBA(rgba.buffer); + } + static fromInts(r, g, b, a = 255) { + return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_RGB))); + } + static fromHex(hex) { + return hexToRgb(hex); + } + static fromIndex(index, snapshot) { + const normalized = normalizeIndexedColorIndex(index); + const rgba = snapshot ? parseColor(snapshot) : rgbaForAnsi256Index(normalized); + const [r, g, b, a] = rgba.toInts(); + return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_INDEXED, normalized))); + } + static defaultForeground(snapshot) { + const rgba = snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_FOREGROUND_RGB); + const [r, g, b, a] = rgba.toInts(); + return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_DEFAULT))); + } + static defaultBackground(snapshot) { + const rgba = snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_BACKGROUND_RGB); + const [r, g, b, a] = rgba.toInts(); + return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_DEFAULT))); + } + toInts() { + return [this.buffer[0] & 255, this.buffer[1] & 255, this.buffer[2] & 255, this.buffer[3] & 255]; + } + get r() { + return (this.buffer[0] & 255) / 255; + } + set r(value) { + this.buffer[0] = this.buffer[0] & 65280 | toU8(value); + } + get g() { + return (this.buffer[1] & 255) / 255; + } + set g(value) { + this.buffer[1] = this.buffer[1] & 65280 | toU8(value); + } + get b() { + return (this.buffer[2] & 255) / 255; + } + set b(value) { + this.buffer[2] = this.buffer[2] & 65280 | toU8(value); + } + get a() { + return (this.buffer[3] & 255) / 255; + } + set a(value) { + this.buffer[3] = this.buffer[3] & 65280 | toU8(value); + } + get meta() { + return (this.buffer[0] >>> 8 | this.buffer[1] >>> 8 << 8 | this.buffer[2] >>> 8 << 16 | this.buffer[3] >>> 8 << 24) >>> 0; + } + get intent() { + switch (this.meta >>> 8 & 255) { + case INTENT_INDEXED: + return "indexed"; + case INTENT_DEFAULT: + return "default"; + default: + return "rgb"; + } + } + get slot() { + return this.meta & 255; + } + map(fn) { + return [fn(this.r), fn(this.g), fn(this.b), fn(this.a)]; + } + toString() { + return `rgba(${this.r.toFixed(2)}, ${this.g.toFixed(2)}, ${this.b.toFixed(2)}, ${this.a.toFixed(2)})`; + } + equals(other) { + if (!other) + return false; + return this.buffer[0] === other.buffer[0] && this.buffer[1] === other.buffer[1] && this.buffer[2] === other.buffer[2] && this.buffer[3] === other.buffer[3]; + } +} +function normalizeColorValue(value) { + if (value == null) + return null; + return { rgba: parseColor(value) }; +} +function hexToRgb(hex) { + hex = hex.replace(/^#/, ""); + if (hex.length === 3) { + hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; + } else if (hex.length === 4) { + hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3]; + } + if (!/^[0-9A-Fa-f]{6}$/.test(hex) && !/^[0-9A-Fa-f]{8}$/.test(hex)) { + console.warn(`Invalid hex color: ${hex}, defaulting to magenta`); + return RGBA.fromValues(1, 0, 1, 1); + } + const r = parseInt(hex.substring(0, 2), 16); + const g = parseInt(hex.substring(2, 4), 16); + const b = parseInt(hex.substring(4, 6), 16); + const a = hex.length === 8 ? parseInt(hex.substring(6, 8), 16) : 255; + return RGBA.fromInts(r, g, b, a); +} +function rgbToHex(rgb) { + const [r, g, b, a] = rgb.toInts(); + const components = a === 255 ? [r, g, b] : [r, g, b, a]; + return "#" + components.map((x) => x.toString(16).padStart(2, "0")).join(""); +} +function hsvToRgb(h, s, v) { + let r = 0, g = 0, b = 0; + const i = Math.floor(h / 60) % 6; + const f = h / 60 - Math.floor(h / 60); + const p = v * (1 - s); + const q = v * (1 - f * s); + const t = v * (1 - (1 - f) * s); + switch (i) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; + } + return RGBA.fromValues(r, g, b, 1); +} +var CSS_COLOR_NAMES = { + black: "#000000", + white: "#FFFFFF", + red: "#FF0000", + green: "#008000", + blue: "#0000FF", + yellow: "#FFFF00", + cyan: "#00FFFF", + magenta: "#FF00FF", + silver: "#C0C0C0", + gray: "#808080", + grey: "#808080", + maroon: "#800000", + olive: "#808000", + lime: "#00FF00", + aqua: "#00FFFF", + teal: "#008080", + navy: "#000080", + fuchsia: "#FF00FF", + purple: "#800080", + orange: "#FFA500", + brightblack: "#666666", + brightred: "#FF6666", + brightgreen: "#66FF66", + brightblue: "#6666FF", + brightyellow: "#FFFF66", + brightcyan: "#66FFFF", + brightmagenta: "#FF66FF", + brightwhite: "#FFFFFF" +}; +function parseColor(color) { + if (typeof color === "string") { + const lowerColor = color.toLowerCase(); + if (lowerColor === "transparent") { + return RGBA.fromValues(0, 0, 0, 0); + } + if (CSS_COLOR_NAMES[lowerColor]) { + return hexToRgb(CSS_COLOR_NAMES[lowerColor]); + } + return hexToRgb(color); + } + return color; +} + +// src/lib/border.ts +var VALID_BORDER_STYLES = ["single", "double", "rounded", "heavy"]; +function isValidBorderStyle(value) { + return typeof value === "string" && VALID_BORDER_STYLES.includes(value); +} +function parseBorderStyle(value, fallback = "single") { + if (isValidBorderStyle(value)) { + return value; + } + if (value !== undefined && value !== null) { + console.warn(`Invalid borderStyle "${value}", falling back to "${fallback}". Valid values are: ${VALID_BORDER_STYLES.join(", ")}`); + } + return fallback; +} +var BorderChars = { + single: { + topLeft: "┌", + topRight: "┐", + bottomLeft: "└", + bottomRight: "┘", + horizontal: "─", + vertical: "│", + topT: "┬", + bottomT: "┴", + leftT: "├", + rightT: "┤", + cross: "┼" + }, + double: { + topLeft: "╔", + topRight: "╗", + bottomLeft: "╚", + bottomRight: "╝", + horizontal: "═", + vertical: "║", + topT: "╦", + bottomT: "╩", + leftT: "╠", + rightT: "╣", + cross: "╬" + }, + rounded: { + topLeft: "╭", + topRight: "╮", + bottomLeft: "╰", + bottomRight: "╯", + horizontal: "─", + vertical: "│", + topT: "┬", + bottomT: "┴", + leftT: "├", + rightT: "┤", + cross: "┼" + }, + heavy: { + topLeft: "┏", + topRight: "┓", + bottomLeft: "┗", + bottomRight: "┛", + horizontal: "━", + vertical: "┃", + topT: "┳", + bottomT: "┻", + leftT: "┣", + rightT: "┫", + cross: "╋" + } +}; +function getBorderFromSides(sides) { + const result = []; + if (sides.top) + result.push("top"); + if (sides.right) + result.push("right"); + if (sides.bottom) + result.push("bottom"); + if (sides.left) + result.push("left"); + return result.length > 0 ? result : false; +} +function getBorderSides(border) { + return border === true ? { top: true, right: true, bottom: true, left: true } : Array.isArray(border) ? { + top: border.includes("top"), + right: border.includes("right"), + bottom: border.includes("bottom"), + left: border.includes("left") + } : { top: false, right: false, bottom: false, left: false }; +} +function borderCharsToArray(chars) { + const array = new Uint32Array(11); + array[0] = chars.topLeft.codePointAt(0); + array[1] = chars.topRight.codePointAt(0); + array[2] = chars.bottomLeft.codePointAt(0); + array[3] = chars.bottomRight.codePointAt(0); + array[4] = chars.horizontal.codePointAt(0); + array[5] = chars.vertical.codePointAt(0); + array[6] = chars.topT.codePointAt(0); + array[7] = chars.bottomT.codePointAt(0); + array[8] = chars.leftT.codePointAt(0); + array[9] = chars.rightT.codePointAt(0); + array[10] = chars.cross.codePointAt(0); + return array; +} +var BorderCharArrays = { + single: borderCharsToArray(BorderChars.single), + double: borderCharsToArray(BorderChars.double), + rounded: borderCharsToArray(BorderChars.rounded), + heavy: borderCharsToArray(BorderChars.heavy) +}; +// src/lib/KeyHandler.ts +import { EventEmitter } from "events"; + +class KeyEvent { + name; + ctrl; + meta; + shift; + option; + sequence; + number; + raw; + eventType; + source; + code; + super; + hyper; + capsLock; + numLock; + baseCode; + repeated; + _defaultPrevented = false; + _propagationStopped = false; + constructor(key) { + this.name = key.name; + this.ctrl = key.ctrl; + this.meta = key.meta; + this.shift = key.shift; + this.option = key.option; + this.sequence = key.sequence; + this.number = key.number; + this.raw = key.raw; + this.eventType = key.eventType; + this.source = key.source; + this.code = key.code; + this.super = key.super; + this.hyper = key.hyper; + this.capsLock = key.capsLock; + this.numLock = key.numLock; + this.baseCode = key.baseCode; + this.repeated = key.repeated; + } + get defaultPrevented() { + return this._defaultPrevented; + } + get propagationStopped() { + return this._propagationStopped; + } + preventDefault() { + this._defaultPrevented = true; + } + stopPropagation() { + this._propagationStopped = true; + } +} + +class PasteEvent { + type = "paste"; + bytes; + metadata; + _defaultPrevented = false; + _propagationStopped = false; + constructor(bytes, metadata) { + this.bytes = bytes; + this.metadata = metadata; + } + get defaultPrevented() { + return this._defaultPrevented; + } + get propagationStopped() { + return this._propagationStopped; + } + preventDefault() { + this._defaultPrevented = true; + } + stopPropagation() { + this._propagationStopped = true; + } +} + +class KeyHandler extends EventEmitter { + processParsedKey(parsedKey) { + try { + switch (parsedKey.eventType) { + case "press": + this.emit("keypress", new KeyEvent(parsedKey)); + break; + case "release": + this.emit("keyrelease", new KeyEvent(parsedKey)); + break; + default: + this.emit("keypress", new KeyEvent(parsedKey)); + break; + } + } catch (error) { + console.error(`[KeyHandler] Error processing parsed key:`, error); + return true; + } + return true; + } + processPaste(bytes, metadata) { + try { + this.emit("paste", new PasteEvent(bytes, metadata)); + } catch (error) { + console.error(`[KeyHandler] Error processing paste:`, error); + } + } +} + +class InternalKeyHandler extends KeyHandler { + renderableHandlers = new Map; + emit(event, ...args) { + return this.emitWithPriority(event, ...args); + } + emitWithPriority(event, ...args) { + let hasGlobalListeners = false; + const globalListeners = this.listeners(event); + if (globalListeners.length > 0) { + hasGlobalListeners = true; + for (const listener of globalListeners) { + try { + listener(...args); + } catch (error) { + console.error(`[KeyHandler] Error in global ${event} handler:`, error); + } + if (event === "keypress" || event === "keyrelease" || event === "paste") { + const keyEvent = args[0]; + if (keyEvent.propagationStopped) { + return hasGlobalListeners; + } + } + } + } + const renderableSet = this.renderableHandlers.get(event); + const renderableHandlers = renderableSet && renderableSet.size > 0 ? [...renderableSet] : []; + let hasRenderableListeners = false; + if (renderableSet && renderableSet.size > 0) { + hasRenderableListeners = true; + if (event === "keypress" || event === "keyrelease" || event === "paste") { + const keyEvent = args[0]; + if (keyEvent.defaultPrevented) + return hasGlobalListeners || hasRenderableListeners; + if (keyEvent.propagationStopped) + return hasGlobalListeners || hasRenderableListeners; + } + for (const handler of renderableHandlers) { + try { + handler(...args); + } catch (error) { + console.error(`[KeyHandler] Error in renderable ${event} handler:`, error); + } + if (event === "keypress" || event === "keyrelease" || event === "paste") { + const keyEvent = args[0]; + if (keyEvent.propagationStopped) { + return hasGlobalListeners || hasRenderableListeners; + } + } + } + } + return hasGlobalListeners || hasRenderableListeners; + } + onInternal(event, handler) { + if (!this.renderableHandlers.has(event)) { + this.renderableHandlers.set(event, new Set); + } + this.renderableHandlers.get(event).add(handler); + } + offInternal(event, handler) { + const handlers = this.renderableHandlers.get(event); + if (handlers) { + handlers.delete(handler); + } + } +} +// src/lib/fonts/block.json +var block_default = { + name: "block", + version: "0.2.0", + homepage: "https://github.com/dominikwilkowski/cfonts", + colors: 2, + lines: 6, + buffer: ["", "", "", "", "", ""], + letterspace: [" ", " ", " ", " ", " ", " "], + letterspace_size: 1, + chars: { + A: [ + " █████ ", + "██╔══██", + "███████", + "██╔══██", + "██ ██", + "╚═╝ ╚═╝" + ], + B: [ + "██████", + "██╔══██", + "██████╔╝", + "██╔══██", + "██████╔╝", + "╚═════╝ " + ], + C: [ + " ██████", + "██╔════╝", + "██", + "██", + "██████", + " ╚═════╝" + ], + D: [ + "██████", + "██╔══██", + "██ ██", + "██ ██", + "██████╔╝", + "╚═════╝ " + ], + E: [ + "███████", + "██╔════╝", + "█████", + "██╔══╝ ", + "███████", + "╚══════╝" + ], + F: [ + "███████", + "██╔════╝", + "█████", + "██╔══╝ ", + "██", + "╚═╝ " + ], + G: [ + " ██████", + "██╔════╝ ", + "██ ███", + "██ ██", + "██████╔╝", + " ╚═════╝ " + ], + H: [ + "██ ██", + "██ ██", + "███████", + "██╔══██", + "██ ██", + "╚═╝ ╚═╝" + ], + I: [ + "██", + "██", + "██", + "██", + "██", + "╚═╝" + ], + J: [ + " ██", + " ██", + " ██", + "██ ██", + "█████╔╝", + " ╚════╝ " + ], + K: [ + "██ ██", + "██ ██╔╝", + "█████╔╝ ", + "██╔═██", + "██ ██", + "╚═╝ ╚═╝" + ], + L: [ + "██", + "██", + "██", + "██", + "███████", + "╚══════╝" + ], + M: [ + "███ ███", + "████ ████", + "████████", + "██║╚██╔╝██", + "██║ ╚═╝ ██", + "╚═╝ ╚═╝" + ], + N: [ + "███ ██", + "████ ██", + "████ ██", + "██║╚████", + "██║ ╚████", + "╚═╝ ╚═══╝" + ], + O: [ + " ██████", + "██╔═══██", + "██ ██", + "██ ██", + "██████╔╝", + " ╚═════╝ " + ], + P: [ + "██████", + "██╔══██", + "██████╔╝", + "██╔═══╝ ", + "██", + "╚═╝ " + ], + Q: [ + " ██████", + "██╔═══██", + "██ ██", + "██▄▄ ██", + "██████╔╝", + " ╚══▀▀═╝ " + ], + R: [ + "██████", + "██╔══██", + "██████╔╝", + "██╔══██", + "██ ██", + "╚═╝ ╚═╝" + ], + S: [ + "███████", + "██╔════╝", + "███████", + "╚════██", + "███████", + "╚══════╝" + ], + T: [ + "████████", + "╚══██╔══╝", + " ██", + " ██", + " ██", + " ╚═╝ " + ], + U: [ + "██ ██", + "██ ██", + "██ ██", + "██ ██", + "██████╔╝", + " ╚═════╝ " + ], + V: [ + "██ ██", + "██ ██", + "██ ██", + "██ ██╔╝", + "████╔╝ ", + " ╚═══╝ " + ], + W: [ + "████", + "████", + "██ ██", + "███████", + "██████╔╝", + " ╚══╝╚══╝ " + ], + X: [ + "██ ██", + "████╔╝", + "███╔╝ ", + " ████", + "██╔╝ ██", + "╚═╝ ╚═╝" + ], + Y: [ + "██ ██", + "██ ██╔╝", + "████╔╝ ", + "██╔╝ ", + " ██", + " ╚═╝ " + ], + Z: [ + "███████", + "╚══███╔╝", + " ███╔╝ ", + " ███╔╝ ", + "███████", + "╚══════╝" + ], + "0": [ + " ██████", + "██╔═████", + "██████", + "████╔╝██", + "██████╔╝", + " ╚═════╝ " + ], + "1": [ + " ██", + "███", + "██", + " ██", + " ██", + " ╚═╝" + ], + "2": [ + "██████", + "╚════██", + " █████╔╝", + "██╔═══╝ ", + "███████", + "╚══════╝" + ], + "3": [ + "██████", + "╚════██", + " █████╔╝", + " ╚═══██", + "██████╔╝", + "╚═════╝ " + ], + "4": [ + "██ ██", + "██ ██", + "███████", + "╚════██", + " ██", + " ╚═╝" + ], + "5": [ + "███████", + "██╔════╝", + "███████", + "╚════██", + "███████", + "╚══════╝" + ], + "6": [ + " ██████", + "██╔════╝ ", + "███████", + "██╔═══██", + "██████╔╝", + " ╚═════╝ " + ], + "7": [ + "███████", + "╚════██", + " ██╔╝", + " ██╔╝ ", + " ██", + " ╚═╝ " + ], + "8": [ + " █████", + "██╔══██", + "█████╔╝", + "██╔══██", + "█████╔╝", + " ╚════╝ " + ], + "9": [ + " █████", + "██╔══██", + "██████", + " ╚═══██", + " █████╔╝", + " ╚════╝ " + ], + "!": [ + "██", + "██", + "██", + "╚═╝", + "██", + "╚═╝" + ], + "?": [ + "██████", + "╚════██", + " ▄███╔╝", + " ▀▀══╝ ", + " ██", + " ╚═╝ " + ], + ".": [" ", " ", " ", " ", "██", "╚═╝"], + "+": [ + " ", + " ██", + "██████", + "██╔═╝", + " ╚═╝ ", + " " + ], + "-": [" ", " ", "█████", "╚════╝", " ", " "], + _: [" ", " ", " ", " ", "███████", "╚══════╝"], + "=": [ + " ", + "██████", + "╚═════╝", + "██████", + "╚═════╝", + " " + ], + "@": [ + " ██████", + "██╔═══██", + "██████", + "██████", + "████╔╝", + " ╚╝╚═══╝ " + ], + "#": [ + " ██ ██", + "████████", + "██╔═██╔╝", + "████████", + "██╔═██╔╝", + " ╚═╝ ╚═╝ " + ], + $: [ + "▄▄███▄▄·", + "██╔════╝", + "███████", + "╚════██", + "███████", + "╚═▀▀▀══╝" + ], + "%": [ + "██ ██", + "╚═╝██╔╝", + " ██╔╝ ", + " ██╔╝ ", + "██╔╝██", + "╚═╝ ╚═╝" + ], + "&": [ + " ██", + " ██", + "████████", + "██╔═██╔═╝", + "██████", + "╚═════╝ " + ], + "(": [ + " ██", + "██╔╝", + "██║ ", + "██║ ", + "██", + " ╚═╝" + ], + ")": [ + "██", + "██", + " ██", + " ██", + "██╔╝", + "╚═╝ " + ], + "/": [ + " ██", + " ██╔╝", + " ██╔╝ ", + " ██╔╝ ", + "██╔╝ ", + "╚═╝ " + ], + ":": [" ", "██", "╚═╝", "██", "╚═╝", " "], + ";": [" ", " ", "██", "╚═╝", "▄█", "═╝"], + ",": [" ", " ", " ", " ", "▄█", "═╝"], + "'": [" ", "╚╝ ", " ", " ", " ", " "], + '"': [" ", "╚╝╚╝ ", " ", " ", " ", " "], + " ": [" ", " ", " ", " ", " ", " "] + } +}; +// src/lib/fonts/shade.json +var shade_default = { + name: "shade", + version: "0.2.0", + homepage: "https://github.com/dominikwilkowski/cfonts", + colors: 2, + lines: 8, + buffer: ["", "", "", "", "", "", "", ""], + letterspace: [ + "", + "", + "", + "", + "", + "", + "", + "" + ], + letterspace_size: 1, + chars: { + A: [ + "░░░░", + "██", + "█ █", + "████", + "█ █", + "░░", + " ░░ ", + "░░░░" + ], + B: [ + "░░░░", + "███", + "█ █", + "███ ", + "█ █", + "███ ", + " ", + "░░░░" + ], + C: [ + "░░░░", + "████", + " ", + "░░░", + "░░░", + "████", + " ", + "░░░░" + ], + D: [ + "░░░░", + "███", + "█ █", + "░░", + "░░", + "███ ", + " ", + "░░░░" + ], + E: [ + "░░░░", + "████", + " ", + "███", + " ", + "████", + " ", + "░░░░" + ], + F: [ + "░░░░", + "████", + " ", + "███", + " ", + "░░░", + " ░░░", + "░░░░" + ], + G: [ + "░░░░", + "███", + " ", + "██", + " ", + "███ ", + " ", + "░░░░" + ], + H: [ + "░░░░", + "░░", + "░░", + "████", + "█ █", + "░░", + " ░░ ", + "░░░░" + ], + I: [ + "░░░", + "███", + " ", + "", + "", + "███", + " ", + "░░░" + ], + J: [ + "░░░░", + "███", + " ", + "░░", + "", + "███", + " ", + "░░░░" + ], + K: [ + "░░░░", + "░░", + "░░", + "███ ", + "█ █", + "░░", + " ░░ ", + "░░░░" + ], + L: [ + "░░░░", + "░░░", + "░░░", + "░░░", + "░░░", + "████", + " ", + "░░░░" + ], + M: [ + "░░░░", + "░░", + "████", + "█ █", + "░░", + "░░", + " ░░ ", + "░░░░" + ], + N: [ + "░░░░", + "░░", + "██", + "█ ██", + " ", + "░░", + " ░░ ", + "░░░░" + ], + O: [ + "░░░░", + "██", + "█ █", + "░░", + "░░", + " ██ ", + "░ ░", + "░░░░" + ], + P: [ + "░░░░", + "███", + "█ █", + "███ ", + " ", + "░░░", + " ░░░", + "░░░░" + ], + Q: [ + "░░░░", + "██", + "█ █", + "░░", + "░░", + " ███", + " ", + "░░░░" + ], + R: [ + "░░░░", + "███", + "█ █", + "███ ", + "█ █", + "░░", + " ░░ ", + "░░░░" + ], + S: [ + "░░░░", + "███", + " ", + " ██", + " ", + "███ ", + " ", + "░░░░" + ], + T: [ + "░░░", + "███", + " ", + "", + "", + "", + "░ ░", + "░░░" + ], + U: [ + "░░░░", + "░░", + "░░", + "░░", + "░░", + " ██ ", + "░ ░", + "░░░░" + ], + V: [ + "░░░░░", + "░░░", + "░░░", + "░░░", + " ", + " ", + "░░ ░░", + "░░░░░" + ], + W: [ + "░░░░", + "░░", + "░░", + "░░", + "████", + "█ █", + " ░░ ", + "░░░░" + ], + X: [ + "░░░░", + "░░", + "░░", + " ██ ", + "█ █", + "░░", + " ░░ ", + "░░░░" + ], + Y: [ + "░░░", + "", + "███", + " ", + "", + "", + "░ ░", + "░░░" + ], + Z: [ + "░░░░", + "████", + " ", + " ", + " ░░", + "████", + " ", + "░░░░" + ], + "0": [ + "░░░░", + "██", + "█ █", + "▌█", + " ", + " ██ ", + "░ ░", + "░░░░" + ], + "1": [ + "░░░░", + "██░░", + " ░░", + "░░", + "░░", + "███", + " ", + "░░░░" + ], + "2": [ + "░░░░", + "▐██", + " ", + "░░ ", + " ", + "████", + " ", + "░░░░" + ], + "3": [ + "░░░░", + "████", + " ", + "░░██", + "░░ ", + "████", + " ", + "░░░░" + ], + "4": [ + "░░░░", + "░░░", + "", + "████", + " ", + "░░░", + "░░░ ", + "░░░░" + ], + "5": [ + "░░░░", + "████", + " ", + "███", + " ", + "███ ", + " ", + "░░░░" + ], + "6": [ + "░░░░", + "███", + " ", + "███", + "█ █", + " ██ ", + "░ ░", + "░░░░" + ], + "7": [ + "░░░░", + "████", + " ", + "████", + " ", + " ░░", + " ░░░", + "░░░░" + ], + "8": [ + "░░░░", + "██", + "█ █", + " ██ ", + "█ █", + " ██ ", + "░ ░", + "░░░░" + ], + "9": [ + "░░░░", + "██", + "█ █", + " ███", + " ", + "░░ ", + "░░ ░", + "░░░░" + ], + "!": [ + "░░░░", + "██", + "██", + "██", + "░ ░", + "██", + "░ ░", + "░░░░" + ], + "?": [ + "░░░░", + "▐██", + " ", + "░░ ", + "░░ ░", + "░░", + "░░ ░", + "░░░░" + ], + ".": [ + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░", + "░░ ░", + "░░░░" + ], + "+": [ + "░░░░", + "░░░░", + "░░", + "███", + " ", + "░░ ░", + "░░░░", + "░░░░" + ], + "-": [ + "░░░░", + "░░░░", + "░░░░", + "████", + " ", + "░░░░", + "░░░░", + "░░░░" + ], + _: [ + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "████", + " " + ], + "=": [ + "░░░░", + "░░░░", + "████", + " ", + "████", + " ", + "░░░░", + "░░░░" + ], + "@": [ + "░░░░", + "██", + "█ █", + "▌█", + " ", + " ███", + " ", + "░░░░" + ], + "#": [ + "░░░░", + "▌▐", + "████", + " ▌▐ ", + "████", + " ▌▐ ", + "░ ░", + "░░░░" + ], + $: [ + "░░░░", + "░░", + "███", + "█ █ ", + " ██", + "░░▌█", + "███ ", + " " + ], + "%": [ + "░░░░", + "░░░", + " ", + " ", + " ", + "", + " ", + " ░░░" + ], + "&": [ + "░░░░░", + "░░░", + "░░░", + "█████", + "█ █ ", + "████", + " ", + "░░░░░" + ], + "(": [ + "░░░░", + "░░", + " ", + " ░░", + "░░░", + " ░░", + " ", + "░░ ░" + ], + ")": [ + "░░░░", + "░░", + " ", + "░░ ", + "░░░", + "░░ ", + " ", + "░ ░░" + ], + "/": [ + "░░░░", + "░░░", + "░░ ", + "░░", + " ", + "░░", + " ░░", + " ░░░" + ], + ":": [ + "░░░░", + "░░░░", + "░░", + "░ ░░", + "░░░░", + "░░", + "░ ░░", + "░░░░" + ], + ";": [ + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░", + "░ ░░", + "░░", + "░░" + ], + ",": [ + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░", + " " + ], + "'": [ + "░░░░", + "░░", + "░ ░░", + "░░░░", + "░░░░", + "░░░░", + "░░░░", + "░░░░" + ], + '"': [ + "░░░░░░", + "░░", + "░ ░ ░░", + "░░░░░░", + "░░░░░░", + "░░░░░░", + "░░░░░░", + "░░░░░░" + ], + " ": [ + "░░░", + "░░░", + "░░░", + "░░░", + "░░░", + "░░░", + "░░░", + "░░░" + ] + } +}; +// src/lib/fonts/slick.json +var slick_default = { + name: "slick", + version: "0.1.0", + homepage: "https://github.com/dominikwilkowski/cfonts", + colors: 2, + lines: 6, + buffer: ["", "", "", "", "", ""], + letterspace: ["", "", "", "", "", ""], + letterspace_size: 1, + chars: { + A: [ + "╭━━━╮", + "┃╭━╮┃", + "┃┃┃┃", + "┃╰━╯┃", + "┃╭━╮┃", + "╰╯╰╯" + ], + B: [ + "╭━━╮", + "┃╭╮┃", + "┃╰╯╰╮", + "┃╭━╮┃", + "┃╰━╯┃", + "╰━━━╯" + ], + C: [ + "╭━━━╮", + "┃╭━╮┃", + "┃┃╰╯", + "┃┃╭╮", + "┃╰━╯┃", + "╰━━━╯" + ], + D: [ + "╭━━━╮", + "╰╮╭╮┃", + "┃┃┃┃", + "┃┃┃┃", + "╭╯╰╯┃", + "╰━━━╯" + ], + E: ["╭━━━╮", "┃╭━━╯", "┃╰━━╮", "┃╭━━╯", "┃╰━━╮", "╰━━━╯"], + F: [ + "╭━━━╮", + "┃╭━━╯", + "┃╰━━╮", + "┃╭━━╯", + "┃┃╱╱╱", + "╰╯╱╱╱" + ], + G: [ + "╭━━━╮", + "┃╭━╮┃", + "┃┃╰╯", + "┃┃╭━╮", + "┃╰┻━┃", + "╰━━━╯" + ], + H: [ + "╭╮╭╮", + "┃┃┃┃", + "┃╰━╯┃", + "┃╭━╮┃", + "┃┃┃┃", + "╰╯╰╯" + ], + I: [ + "╭━━╮", + "╰┫┣╯", + "┃┃", + "┃┃", + "╭┫┣╮", + "╰━━╯" + ], + J: [ + "╱╱╭╮", + "╱╱┃┃", + "╱╱┃┃", + "╭╮┃┃", + "┃╰╯┃", + "╰━━╯" + ], + K: [ + "╭╮╭━╮", + "┃┃┃╭╯", + "┃╰╯╯", + "┃╭╮┃", + "┃┃┃╰╮", + "╰╯╰━╯" + ], + L: [ + "╭╮╱╱╱", + "┃┃╱╱╱", + "┃┃╱╱╱", + "┃┃╭╮", + "┃╰━╯┃", + "╰━━━╯" + ], + M: [ + "╭━╮╭━╮", + "┃┃╰╯┃┃", + "┃╭╮╭╮┃", + "┃┃┃┃┃┃", + "┃┃┃┃┃┃", + "╰╯╰╯╰╯" + ], + N: [ + "╭━╮╭╮", + "┃┃╰╮┃┃", + "┃╭╮╰╯┃", + "┃┃╰╮┃┃", + "┃┃┃┃┃", + "╰╯╰━╯" + ], + O: [ + "╭━━━╮", + "┃╭━╮┃", + "┃┃┃┃", + "┃┃┃┃", + "┃╰━╯┃", + "╰━━━╯" + ], + P: [ + "╭━━━╮", + "┃╭━╮┃", + "┃╰━╯┃", + "┃╭━━╯", + "┃┃╱╱╱", + "╰╯╱╱╱" + ], + Q: [ + "╭━━━╮", + "┃╭━╮┃", + "┃┃┃┃", + "┃┃┃┃", + "┃╰━╯┃╮", + "╰━━━━╯" + ], + R: ["╭━━━╮", "┃╭━╮┃", "┃╰━╯┃", "┃╭╮╭╯", "┃┃┃╰╮", "╰╯╰━╯"], + S: ["╭━━━╮", "┃╭━╮┃", "┃╰━━╮", "╰━━╮┃", "┃╰━╯┃", "╰━━━╯"], + T: [ + "╭━━━━╮", + "┃╭╮╭╮┃", + "╰╯┃┃╰╯", + "╱╱┃┃╱╱", + "╱╱┃┃╱╱", + "╱╱╰╯╱╱" + ], + U: [ + "╭╮╭╮", + "┃┃┃┃", + "┃┃┃┃", + "┃┃┃┃", + "┃╰━╯┃", + "╰━━━╯" + ], + V: [ + "╭╮╱╱╭╮", + "┃╰╮╭╯┃", + "╰╮┃┃╭╯", + "┃╰╯┃", + "╰╮╭╯", + "╱╱╰╯╱╱" + ], + W: [ + "╭╮╭╮╭╮", + "┃┃┃┃┃┃", + "┃┃┃┃┃┃", + "┃╰╯╰╯┃", + "╰╮╭╮╭╯", + "╰╯╰╯" + ], + X: [ + "╭━╮╭━╮", + "╰╮╰╯╭╯", + "╰╮╭╯", + "╭╯╰╮", + "╭╯╭╮╰╮", + "╰━╯╰━╯" + ], + Y: [ + "╭╮╱╱╭╮", + "┃╰╮╭╯┃", + "╰╮╰╯╭╯", + "╰╮╭╯", + "╱╱┃┃╱╱", + "╱╱╰╯╱╱" + ], + Z: [ + "╭━━━━╮", + "╰━━╮━┃", + "╱╱╭╯╭╯", + "╭╯╭╯", + "╭╯━╰━╮", + "╰━━━━╯" + ], + "0": ["╭━━━╮", "┃╭━╮┃", "┃┃┃┃┃", "┃┃┃┃┃", "┃╰━╯┃", "╰━━━╯"], + "1": [ + "╭╮", + "╭╯┃", + "╰╮┃", + "┃┃", + "╭╯╰╮", + "╰━━╯" + ], + "2": ["╭━━━╮", "┃╭━╮┃", "╰╯╭╯┃", "╭━╯╭╯", "┃╰━━╮", "╰━━━╯"], + "3": ["╭━━━╮", "┃╭━╮┃", "╰╯╭╯┃", "╭╮╰╮┃", "┃╰━╯┃", "╰━━━╯"], + "4": [ + "╭╮╭╮", + "┃┃┃┃", + "┃╰━╯┃", + "╰━━╮┃", + "╱╱╱┃┃", + "╱╱╱╰╯" + ], + "5": ["╭━━━╮", "┃╭━━╯", "┃╰━━╮", "╰━━╮┃", "╭━━╯┃", "╰━━━╯"], + "6": ["╭━━━╮", "┃╭━━╯", "┃╰━━╮", "┃╭━╮┃", "┃╰━╯┃", "╰━━━╯"], + "7": [ + "╭━━━╮", + "┃╭━╮┃", + "╰╯╭╯┃", + "╱╱┃╭╯", + "╱╱┃┃", + "╱╱╰╯" + ], + "8": ["╭━━━╮", "┃╭━╮┃", "┃╰━╯┃", "┃╭━╮┃", "┃╰━╯┃", "╰━━━╯"], + "9": ["╭━━━╮", "┃╭━╮┃", "┃╰━╯┃", "╰━━╮┃", "╭━━╯┃", "╰━━━╯"], + "!": ["╭╮", "┃┃", "┃┃", "╰╯", "╭╮", "╰╯"], + "?": [ + "╭━━━╮", + "┃╭━╮┃", + "╰╯╭╯┃", + "╱╱┃╭╯", + "╱╱╭╮", + "╱╱╰╯" + ], + ".": ["╱╱", "╱╱", "╱╱", "╱╱", "╭╮", "╰╯"], + "+": [ + "╱╱╱╱", + "╱╱╱╱", + "╭╮", + "╭╯╰╮", + "╰╮╭╯", + "╰╯" + ], + "-": ["╱╱╱╱", "╱╱╱╱", "╱╱╱╱", "╭━━╮", "╰━━╯", "╱╱╱╱"], + _: ["╱╱╱╱", "╱╱╱╱", "╱╱╱╱", "╱╱╱╱", "╭━━╮", "╰━━╯"], + "=": ["╱╱╱╱╱", "╱╱╱╱╱", "╭━━━╮", "╰━━━╯", "╭━━━╮", "╰━━━╯"], + "@": [ + "╭━━━━╮", + "┃╭━━╮┃", + "┃┃╭━┃┃", + "┃┃╰╯┃┃", + "┃╰━━╯━╮", + "╰━━━━━╯" + ], + "#": [ + "╭━━╮", + "╭╯╭╮╰╮", + "╰╮┃┃╭╯", + "╭╯┃┃╰╮", + "╰╮╰╯╭╯", + "╰━━╯" + ], + $: [ + "╱╱╭╮", + "╭━╯╰╮", + "┃╰━━╮", + "╰━━╮┃", + "╰╮╭━╯", + "╰╯╱╱" + ], + "%": [ + "╭╮╱╱╭━╮", + "╰╯╭╯╭╯", + "╱╱╭╯╭╯", + "╭╯╭╯╱╱", + "╭╯╭╯╭╮", + "╰━╯╱╱╰╯" + ], + "&": [ + "╭━━╮", + "┃╭━╯", + "╭╯╰╮", + "┃╭╮┃", + "┃╰╯┃╮", + "╰━━━╯" + ], + "(": [ + "╱╱╭━╮", + "╭╯╭╯", + "╭╯╭╯", + "╰╮╰╮", + "╰╮╰╮", + "╱╱╰━╯" + ], + ")": [ + "╭━╮╱╱", + "╰╮╰╮", + "╰╮╰╮", + "╭╯╭╯", + "╭╯╭╯", + "╰━╯╱╱" + ], + "/": [ + "╱╱╱╱╭━╮", + "╱╱╱╭╯╭╯", + "╱╱╭╯╭╯", + "╭╯╭╯╱╱", + "╭╯╭╯╱╱╱", + "╰━╯╱╱╱╱" + ], + ":": ["╱╱", "╭╮", "╰╯", "╭╮", "╰╯", "╱╱"], + ";": ["╭╮", "┃┃", "╰╯", "╭╮", "╰┫", ""], + ",": ["╱╱", "╱╱", "╱╱", "╭╮", "╰┫", ""], + "'": ["╭╮", "╰╯", "╱╱", "╱╱", "╱╱", "╱╱"], + '"': ["╭╮╭╮", "╰╯╰╯", "╱╱╱╱", "╱╱╱╱", "╱╱╱╱", "╱╱╱╱"], + " ": ["╱╱╱", "╱╱╱", "╱╱╱", "╱╱╱", "╱╱╱", "╱╱╱"] + } +}; +// src/lib/fonts/tiny.json +var tiny_default = { + name: "tiny", + version: "0.2.0", + homepage: "https://github.com/dominikwilkowski/cfonts", + colors: 1, + lines: 2, + buffer: ["", ""], + letterspace: [" ", " "], + letterspace_size: 1, + chars: { + A: ["▄▀█", "█▀█"], + B: ["█▄▄", "█▄█"], + C: ["█▀▀", "█▄▄"], + D: ["█▀▄", "█▄▀"], + E: ["█▀▀", "██▄"], + F: ["█▀▀", "█▀ "], + G: ["█▀▀", "█▄█"], + H: ["█ █", "█▀█"], + I: ["█", "█"], + J: [" █", "█▄█"], + K: ["█▄▀", "█ █"], + L: ["█ ", "█▄▄"], + M: ["█▀▄▀█", "█ ▀ █"], + N: ["█▄ █", "█ ▀█"], + O: ["█▀█", "█▄█"], + P: ["█▀█", "█▀▀"], + Q: ["█▀█", "▀▀█"], + R: ["█▀█", "█▀▄"], + S: ["█▀▀", "▄▄█"], + T: ["▀█▀", " █ "], + U: ["█ █", "█▄█"], + V: ["█ █", "▀▄▀"], + W: ["█ █ █", "▀▄▀▄▀"], + X: ["▀▄▀", "█ █"], + Y: ["█▄█", " █ "], + Z: ["▀█", "█▄"], + "0": ["▞█▚", "▚█▞"], + "1": ["▄█", " █"], + "2": ["▀█", "█▄"], + "3": ["▀▀█", "▄██"], + "4": ["█ █", "▀▀█"], + "5": ["█▀", "▄█"], + "6": ["█▄▄", "█▄█"], + "7": ["▀▀█", " █"], + "8": ["███", "█▄█"], + "9": ["█▀█", "▀▀█"], + "!": ["█", "▄"], + "?": ["▀█", " ▄"], + ".": [" ", "▄"], + "+": ["▄█▄", " ▀ "], + "-": ["▄▄", " "], + _: [" ", "▄▄"], + "=": ["▀▀", "▀▀"], + "@": ["▛█▜", "▙▟▃"], + "#": ["▟▄▙", "▜▀▛"], + $: ["▖█▗", "▘█▝"], + "%": ["▀ ▄▀", "▄▀ ▄"], + "&": ["▄▄█", "█▄█"], + "(": ["▄▀", "▀▄"], + ")": ["▀▄", "▄▀"], + "/": [" ▄▀", "▄▀ "], + ":": ["▀", "▄"], + ";": [" ", "▄▀"], + ",": [" ", "█"], + "'": ["▀", " "], + '"': ["▛ ▜", " "], + " ": [" ", " "] + } +}; +// src/lib/fonts/huge.json +var huge_default = { + name: "huge", + version: "0.2.0", + homepage: "https://github.com/dominikwilkowski/cfonts", + colors: 2, + lines: 11, + buffer: ["", "", "", "", "", "", "", "", "", "", ""], + letterspace: [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "], + letterspace_size: 1, + chars: { + A: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "▌ ▐", + "▌ ▐", + " ▀ ▀ " + ], + B: [ + " ▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░ ", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░ ", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░ ", + " ▀▀▀▀▀▀▀▀▀▀ " + ], + C: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + " ", + " ", + " ", + " ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + D: [ + " ▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░ ", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░ ", + " ▀▀▀▀▀▀▀▀▀▀ " + ], + E: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + F: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + " ", + " ", + " " + ], + G: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + "▌ ▄▄▄▄▄▄▄▄ ", + "▌▐░░░░░░░░", + "▌ ▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + H: [ + " ▄ ▄ ", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "▌ ▐", + "▌ ▐", + " ▀ ▀ " + ], + I: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀██▀▀▀▀ ", + " ", + " ", + " ", + " ", + " ", + " ▄▄▄▄██▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + J: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀██▀▀▀ ", + " ", + " ", + " ", + " ", + " ", + " ▄▄▄▄▄█ ", + "░░░░░░░ ", + " ▀▀▀▀▀▀▀ " + ], + K: [ + " ▄ ▄ ", + "▌ ▐", + "▌ ▐ ", + "▌▐ ", + " ", + "░░ ", + " ", + "▌▐ ", + "▌ ▐ ", + "▌ ▐", + " ▀ ▀ " + ], + L: [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + M: [ + " ▄▄ ▄▄ ", + "░░▌ ▐░░", + "▌ ▐", + "▌▐▌ ▐▌▐", + "▌ ▐▌ ▐", + "▌ ▐▌ ▐", + "▌ ▀ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + " ▀ ▀ " + ], + N: [ + " ▄▄ ▄ ", + "░░▌ ▐", + "▌ ▐", + "▌▐▌ ▐", + "▌ ▐▌ ▐", + "▌ ▐▌ ▐", + "▌ ▐▌ ▐", + "▌ ▐▌▐", + "▌ ▐", + "▌ ▐░░", + " ▀ ▀▀ " + ], + O: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + P: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + " ", + " ", + " " + ], + Q: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀██▀▀ ", + " ", + " " + ], + R: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + "█▀▀▀▀██▀▀ ", + "▌ ▐ ", + "▌ ▐ ", + "▌ ▐", + " ▀ ▀ " + ], + S: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ▄▄▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + T: [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀██▀▀▀▀ ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + U: [ + " ▄ ▄ ", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + V: [ + " ▄ ▄ ", + "▌ ▐", + " ▌ ▐ ", + " ▌ ▐ ", + " ▌ ▐ ", + " ▌ ▐ ", + " ▌ ▐ ", + " ▌ ▐ ", + " ", + " ", + " " + ], + W: [ + " ▄ ▄ ", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "▌ ▄ ▐", + "▌ ▐▌ ▐", + "▌ ▐▌ ▐", + "▌▐▌ ▐▌▐", + "▌ ▐", + "░░▌ ▐░░", + " ▀▀ ▀▀ " + ], + X: [ + " ▄ ▄ ", + "▌ ▐", + " ▌ ▐ ", + " ▌ ▐ ", + " ", + " ", + " ", + " ▌ ▐ ", + " ▌ ▐ ", + "▌ ▐", + " ▀ ▀ " + ], + Y: [ + " ▄ ▄ ", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀██▀▀▀▀ ", + " ", + " ", + " ", + " " + ], + Z: [ + " ▄▄▄▄▄▄▄ ", + "░░░░░░░", + " ▀▀▀▀▀█", + " ", + " ", + " ", + " ", + " ", + "█▄▄▄▄▄ ", + "░░░░░░░", + " ▀▀▀▀▀▀▀ " + ], + "0": [ + " ▄▄▄▄▄▄▄▄▄ ", + " ░░░░░░░░░ ", + "█▀▀▀▀▀█", + "▌▐▌ ▐", + "▌ ▐▌ ▐", + "▌ ▐▌ ▐", + "▌ ▐▌ ▐", + "▌ ▐▌▐", + "█▄▄▄▄▄█", + " ░░░░░░░░░ ", + " ▀▀▀▀▀▀▀▀▀ " + ], + "1": [ + " ▄▄▄▄ ", + " ▄█░░░░ ", + " ░░▌▐░░ ", + " ▀▀ ▐░░ ", + " ░░ ", + " ░░ ", + " ░░ ", + " ░░ ", + " ▄▄▄▄█░░█▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + "2": [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ", + " ▄▄▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + "3": [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ▄▄▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ▄▄▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + "4": [ + " ▄ ▄ ", + "▌ ▐", + "▌ ▐", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ", + " ", + " " + ], + "5": [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ", + " ▄▄▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + "6": [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀▀ ", + " ", + "█▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + "7": [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "8": [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + " ░░░░░░░░░ ", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + "9": [ + " ▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀▀▀▀▀▀█", + "▌ ▐", + "█▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀█", + " ", + " ▄▄▄▄▄▄▄▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀ " + ], + "!": [ + " ▄▄ ", + "░░", + "░░", + "░░", + "░░", + "░░", + "░░", + " ▀▀ ", + " ▄▄ ", + "░░", + " ▀▀ " + ], + "?": [ + " ▄▄▄▄▄▄▄ ", + " ▄█░░░░░░█▄ ", + " ░░▌▀▀▀▀█░░", + " ▀▀ ▄▄▄█░░", + " ▄█░░░░░ ", + " ░░▌▀▀▀▀ ", + " ░░ ", + " ▀▀ ", + " ▄▄ ", + " ░░ ", + " ▀▀ " + ], + ".": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ▄▄ ", + "░░", + " ▀▀ " + ], + "+": [ + " ", + " ", + " ▄▄ ", + " ░░ ", + " ▄▄█░░█▄▄ ", + "░░░░░░░░", + " ▀▀█░░█▀▀ ", + " ░░ ", + " ▀▀ ", + " ", + " " + ], + "-": [ + " ", + " ", + " ", + " ", + " ▄▄▄▄▄ ", + "░░░░░", + " ▀▀▀▀▀ ", + " ", + " ", + " ", + " " + ], + _: [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ▄▄▄▄▄ ", + "░░░░░", + " ▀▀▀▀▀ ", + " " + ], + "=": [ + " ", + " ", + " ▄▄▄▄▄ ", + "░░░░░", + " ▀▀▀▀▀ ", + " ", + " ▄▄▄▄▄ ", + "░░░░░", + " ▀▀▀▀▀ ", + " ", + " " + ], + "@": [ + " ▄▄▄▄▄▄▄▄▄▄▄▄ ", + "░░░░░░░░░░░░", + "█▀▀▀▀▀▀▀▀█", + "▌ ▐", + "▌ ▄▄▄▄ ▐", + "▌ █░░░░█ ▐", + "▌▐████▄█", + "▌ █░░░░░░░░", + "▌▄▄███████", + "░░░░░░░░░░░░", + " ▀▀▀▀▀▀▀▀▀▀▀▀ " + ], + "#": [ + " ▄ ▄ ", + " ▌ ▐ ", + " ▄██▄▄▄▄▄▄▄██▄ ", + "░░░░░░░░░░░░░░░", + " ▀██▀▀▀▀▀▀▀██▀ ", + " ▌ ▐ ", + " ▄██▄▄▄▄▄▄▄██▄ ", + "░░░░░░░░░░░░░░░", + " ▀██▀▀▀▀▀▀▀██▀ ", + " ▌ ▐ ", + " ▀ ▀ " + ], + $: [ + " ", + " ▄▄▄▄██▄▄▄▄ ", + "░░░░░░░░░░░", + "█▀▀██▀▀▀▀ ", + "█▄▄██▄▄▄▄ ", + "░░░░░░░░░░░", + " ▀▀▀▀██▀▀█", + " ▄▄▄▄██▄▄█", + "░░░░░░░░░░░", + " ▀▀▀▀██▀▀▀▀ ", + " " + ], + "%": [ + " ", + " ▄ ▐", + " ▌ ▐ ", + " ▀ ▐ ", + " ", + " ", + " ", + " ▌ ▄ ", + " ▌ ▐ ", + "▌ ▀ ", + " " + ], + "&": [ + " ▄▄▄▄▄▄▄ ", + "░░░░░░░ ", + "█▀▀▀█ ", + "▌ ▐ ", + "█▄▄▄█ ", + " ░░░░░░ ", + "█▀▀▀▀█▌ ▄ ", + "▌ ▐", + "█▄▄▄▄█ ", + "░░░░░░▌▐ ", + " ▀▀▀▀▀▀ ▀ " + ], + "(": [ + " ▄▄▄▄▄ ", + " ░░░░░", + "░░█▀▀▀ ", + "░░ ", + "░░ ", + "░░ ", + "░░ ", + "░░ ", + "░░█▄▄▄ ", + " ░░░░░", + " ▀▀▀▀▀ " + ], + ")": [ + " ▄▄▄▄▄ ", + "░░░░░ ", + " ▀▀▀█░░", + " ░░", + " ░░", + " ░░", + " ░░", + " ░░", + " ▄▄▄█░░", + "░░░░░ ", + " ▀▀▀▀▀ " + ], + "/": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + ":": [ + " ", + " ", + " ▄▄ ", + "░░", + " ▀▀ ", + " ", + " ▄▄ ", + "░░", + " ▀▀ ", + " ", + " " + ], + ";": [ + " ", + " ", + " ▄▄ ", + "░░", + " ▀▀ ", + " ", + " ▄▄ ", + "░░", + " ▀▌ ", + " ", + " " + ], + ",": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ▄▄ ", + "░░", + " ▀▌ ", + " " + ], + "'": [ + " ", + "", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + '"': [ + " ▄ ▄ ", + "▐▐", + "▐▐", + " ▀ ▀ ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + " ": [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "] + } +}; +// src/lib/fonts/grid.json +var grid_default = { + name: "grid", + version: "0.1.0", + homepage: "https://github.com/dominikwilkowski/cfonts", + colors: 2, + lines: 6, + buffer: ["", "", "", "", "", ""], + letterspace: ["", "", "", "", "", ""], + letterspace_size: 1, + chars: { + A: ["╋╋╋╋", "┏━━┓", "┃┏┓┃", "┃┏┓┃", "┗┛┗┛", "╋╋╋╋"], + B: [ + "┏┓╋╋", + "┃┗━┓", + "┃┏┓┃", + "┃┗┛┃", + "┗━━┛", + "╋╋╋╋" + ], + C: ["╋╋╋╋", "┏━━┓", "┃┏━┛", "┃┗━┓", "┗━━┛", "╋╋╋╋"], + D: [ + "╋╋┏┓", + "┏━┛┃", + "┃┏┓┃", + "┃┗┛┃", + "┗━━┛", + "╋╋╋╋" + ], + E: ["╋╋╋╋", "┏━━┓", "┃┃━┫", "┃┃━┫", "┗━━┛", "╋╋╋╋"], + F: [ + "┏━┓", + "┏┛┗┓", + "┗┓┏┛", + "┃┃", + "┗┛", + "╋╋╋╋" + ], + G: ["╋╋╋╋", "┏━━┓", "┃┏┓┃", "┃┗┛┃", "┗━┓┃", "┗━━┛"], + H: [ + "┏┓╋╋", + "┃┗━┓", + "┃┏┓┃", + "┃┃┃┃", + "┗┛┗┛", + "╋╋╋╋" + ], + I: ["┏┓", "┗┛", "┏┓", "┃┃", "┗┛", "╋╋"], + J: [ + "┏┓", + "┗┛", + "┏┓", + "┃┃", + "┏┛┃", + "┗━┛" + ], + K: [ + "┏┓╋╋", + "┃┃┏┓", + "┃┗┛┛", + "┃┏┓┓", + "┗┛┗┛", + "╋╋╋╋" + ], + L: [ + "┏┓", + "┃┃", + "┃┃", + "┃┗┓", + "┗━┛", + "╋╋╋" + ], + M: ["╋╋╋╋", "┏┓┏┓", "┃┗┛┃", "┃┃┃┃", "┗┻┻┛", "╋╋╋╋"], + N: [ + "╋╋╋╋", + "┏━┓", + "┃┏┓┓", + "┃┃┃┃", + "┗┛┗┛", + "╋╋╋╋" + ], + O: ["╋╋╋╋", "┏━━┓", "┃┏┓┃", "┃┗┛┃", "┗━━┛", "╋╋╋╋"], + P: [ + "╋╋╋╋", + "┏━━┓", + "┃┏┓┃", + "┃┗┛┃", + "┃┏━┛", + "┗┛╋╋" + ], + Q: [ + "╋╋╋╋", + "┏━━┓", + "┃┏┓┃", + "┃┗┛┃", + "┗━┓┃", + "╋╋┗┛" + ], + R: [ + "╋╋╋", + "┏━┓", + "┃┏┛", + "┃┃", + "┗┛", + "╋╋╋" + ], + S: ["╋╋╋╋", "┏━━┓", "┃━━┫", "┣━━┃", "┗━━┛", "╋╋╋╋"], + T: [ + "┏┓", + "┏┛┗┓", + "┗┓┏┛", + "┃┗┓", + "┗━┛", + "╋╋╋╋" + ], + U: ["╋╋╋╋", "┏┓┏┓", "┃┃┃┃", "┃┗┛┃", "┗━━┛", "╋╋╋╋"], + V: [ + "╋╋╋╋", + "┏┓┏┓", + "┃┗┛┃", + "┗┓┏┛", + "┗┛", + "╋╋╋╋" + ], + W: [ + "╋╋╋╋╋╋", + "┏┓┏┓┏┓", + "┃┗┛┗┛┃", + "┗┓┏┓┏┛", + "┗┛┗┛", + "╋╋╋╋╋╋" + ], + X: ["╋╋╋╋", "┏┓┏┓", "┗╋╋┛", "┏╋╋┓", "┗┛┗┛", "╋╋╋╋"], + Y: [ + "╋╋╋╋╋", + "┏┓┏┓", + "┃┗━┛┃", + "┗━┓┏┛", + "┗━━┛", + "╋╋╋╋╋" + ], + Z: ["╋╋╋╋╋", "┏━━━┓", "┣━━┃┃", "┃┃━━┫", "┗━━━┛", "╋╋╋╋╋"], + "0": ["┏━━━┓", "┃┏━┓┃", "┃┃┃┃┃", "┃┃┃┃┃", "┃┗━┛┃", "┗━━━┛"], + "1": [ + "┏┓", + "┏┛┃", + "┗┓┃", + "┃┃", + "┏┛┗┓", + "┗━━┛" + ], + "2": ["┏━━━┓", "┃┏━┓┃", "┗┛┏┛┃", "┏━┛┏┛", "┃┗━┻┓", "┗━━━┛"], + "3": ["┏━━━┓", "┃┏━┓┃", "┗┛┏┛┃", "┏┓┗┓┃", "┃┗━┛┃", "┗━━━┛"], + "4": [ + "┏┓┏┓", + "┃┃┃┃", + "┃┗━┛┃", + "┗━━┓┃", + "╋╋╋┃┃", + "╋╋╋┗┛" + ], + "5": ["┏━━━┓", "┃┏━━┛", "┃┗━━┓", "┗━━┓┃", "┏━━┛┃", "┗━━━┛"], + "6": ["┏━━━┓", "┃┏━━┛", "┃┗━━┓", "┃┏━┓┃", "┃┗━┛┃", "┗━━━┛"], + "7": [ + "┏━━━┓", + "┃┏━┓┃", + "┗┛┏┛┃", + "╋╋┃┏┛", + "╋╋┃┃", + "╋╋┗┛" + ], + "8": ["┏━━━┓", "┃┏━┓┃", "┃┗━┛┃", "┃┏━┓┃", "┃┗━┛┃", "┗━━━┛"], + "9": ["┏━━━┓", "┃┏━┓┃", "┃┗━┛┃", "┗━━┓┃", "┏━━┛┃", "┗━━━┛"], + "!": ["┏┓", "┃┃", "┃┃", "┗┛", "┏┓", "┗┛"], + "?": [ + "┏━━━┓", + "┃┏━┓┃", + "┗┛┏┛┃", + "╋╋┃┏┛", + "╋╋┏┓", + "╋╋┗┛" + ], + ".": ["╋╋", "╋╋", "╋╋", "╋╋", "┏┓", "┗┛"], + "+": [ + "╋╋╋╋", + "┏┓", + "┏┛┗┓", + "┗┓┏┛", + "┗┛", + "╋╋╋╋" + ], + "-": ["╋╋╋╋", "╋╋╋╋", "┏━━┓", "┗━━┛", "╋╋╋╋", "╋╋╋╋"], + _: ["╋╋╋╋", "╋╋╋╋", "╋╋╋╋", "╋╋╋╋", "┏━━┓", "┗━━┛"], + "=": ["╋╋╋╋╋", "┏━━━┓", "┗━━━┛", "┏━━━┓", "┗━━━┛", "╋╋╋╋╋"], + "@": [ + "┏━━━━┓", + "┃┏━━┓┃", + "┃┃┏━┃┃", + "┃┃┗┛┃┃", + "┃┗━━┛┗┓", + "┗━━━━━┛" + ], + "#": [ + "┏━━━┓", + "┏┛┏━┓┗┓", + "┗┓┃┃┃┏┛", + "┏┛┃┃┃┗┓", + "┗┓┗━┛┏┛", + "┗━━━┛" + ], + $: [ + "┏┓", + "┏┛┗┓", + "┃━━┫", + "┣━━┃", + "┗┓┏┛", + "┗┛" + ], + "%": [ + "┏┓╋╋┏━┓", + "┗┛┏┛┏┛", + "╋╋┏┛┏┛", + "┏┛┏┛╋╋", + "┏┛┏┛┏┓", + "┗━┛╋╋┗┛" + ], + "&": [ + "╋╋┏┓", + "╋╋┃┃", + "┏━┛┗┓", + "┃┏┓┏┛", + "┃┗┛┃", + "┗━━┛" + ], + "(": [ + "╋╋┏━┓", + "┏┛┏┛", + "┏┛┏┛", + "┗┓┗┓", + "┗┓┗┓", + "╋╋┗━┛" + ], + ")": [ + "┏━┓╋╋", + "┗┓┗┓", + "┗┓┗┓", + "┏┛┏┛", + "┏┛┏┛", + "┗━┛╋╋" + ], + "/": [ + "╋╋╋╋┏━┓", + "╋╋╋┏┛┏┛", + "╋╋┏┛┏┛", + "┏┛┏┛╋╋", + "┏┛┏┛╋╋╋", + "┗━┛╋╋╋╋" + ], + ":": ["╋╋", "┏┓", "┗┛", "┏┓", "┗┛", "╋╋"], + ";": ["╋╋", "┏┓", "┗┛", "╋╋", "┏┓", "┗┫"], + ",": ["╋╋", "╋╋", "╋╋", "╋╋", "┏┓", "┗┫"], + "'": ["┏┓", "┗┛", "╋╋", "╋╋", "╋╋", "╋╋"], + '"': ["┏┓┏┓", "┗┛┗┛", "╋╋╋╋", "╋╋╋╋", "╋╋╋╋", "╋╋╋╋"], + " ": ["╋╋", "╋╋", "╋╋", "╋╋", "╋╋", "╋╋"] + } +}; +// src/lib/fonts/pallet.json +var pallet_default = { + name: "pallet", + version: "0.1.0", + homepage: "https://github.com/dominikwilkowski/cfonts", + colors: 2, + lines: 6, + buffer: ["", "", "", "", "", ""], + letterspace: ["", "", "", "", "", ""], + letterspace_size: 1, + chars: { + A: [ + "╔═══╗", + "║╔═╗║", + "║║║║", + "║╚═╝║", + "║╔═╗║", + "╚╝╚╝" + ], + B: [ + "╔══╗", + "║╔╗║", + "║╚╝╚╗", + "║╔═╗║", + "║╚═╝║", + "╚═══╝" + ], + C: [ + "╔═══╗", + "║╔═╗║", + "║║╚╝", + "║║╔╗", + "║╚═╝║", + "╚═══╝" + ], + D: [ + "╔═══╗", + "╚╗╔╗║", + "║║║║", + "║║║║", + "╔╝╚╝║", + "╚═══╝" + ], + E: ["╔═══╗", "║╔══╝", "║╚══╗", "║╔══╝", "║╚══╗", "╚═══╝"], + F: [ + "╔═══╗", + "║╔══╝", + "║╚══╗", + "║╔══╝", + "║║───", + "╚╝───" + ], + G: [ + "╔═══╗", + "║╔═╗║", + "║║╚╝", + "║║╔═╗", + "║╚╩═║", + "╚═══╝" + ], + H: [ + "╔╗╔╗", + "║║║║", + "║╚═╝║", + "║╔═╗║", + "║║║║", + "╚╝╚╝" + ], + I: [ + "╔══╗", + "╚╣╠╝", + "║║", + "║║", + "╔╣╠╗", + "╚══╝" + ], + J: [ + "──╔╗", + "──║║", + "──║║", + "╔╗║║", + "║╚╝║", + "╚══╝" + ], + K: [ + "╔╗╔═╗", + "║║║╔╝", + "║╚╝╝", + "║╔╗║", + "║║║╚╗", + "╚╝╚═╝" + ], + L: [ + "╔╗───", + "║║───", + "║║───", + "║║╔╗", + "║╚═╝║", + "╚═══╝" + ], + M: [ + "╔═╗╔═╗", + "║║╚╝║║", + "║╔╗╔╗║", + "║║║║║║", + "║║║║║║", + "╚╝╚╝╚╝" + ], + N: [ + "╔═╗╔╗", + "║║╚╗║║", + "║╔╗╚╝║", + "║║╚╗║║", + "║║║║║", + "╚╝╚═╝" + ], + O: [ + "╔═══╗", + "║╔═╗║", + "║║║║", + "║║║║", + "║╚═╝║", + "╚═══╝" + ], + P: [ + "╔═══╗", + "║╔═╗║", + "║╚═╝║", + "║╔══╝", + "║║───", + "╚╝───" + ], + Q: [ + "╔═══╗", + "║╔═╗║", + "║║║║", + "║║║║", + "║╚═╝╠╗", + "╚════╝" + ], + R: ["╔═══╗", "║╔═╗║", "║╚═╝║", "║╔╗╔╝", "║║║╚╗", "╚╝╚═╝"], + S: ["╔═══╗", "║╔═╗║", "║╚══╗", "╚══╗║", "║╚═╝║", "╚═══╝"], + T: [ + "╔════╗", + "║╔╗╔╗║", + "╚╝║║╚╝", + "──║║──", + "──║║──", + "──╚╝──" + ], + U: [ + "╔╗╔╗", + "║║║║", + "║║║║", + "║║║║", + "║╚═╝║", + "╚═══╝" + ], + V: [ + "╔╗──╔╗", + "║╚╗╔╝║", + "╚╗║║╔╝", + "║╚╝║", + "╚╗╔╝", + "──╚╝──" + ], + W: [ + "╔╗╔╗╔╗", + "║║║║║║", + "║║║║║║", + "║╚╝╚╝║", + "╚╗╔╗╔╝", + "╚╝╚╝" + ], + X: [ + "╔═╗╔═╗", + "╚╗╚╝╔╝", + "╚╗╔╝", + "╔╝╚╗", + "╔╝╔╗╚╗", + "╚═╝╚═╝" + ], + Y: [ + "╔╗──╔╗", + "║╚╗╔╝║", + "╚╗╚╝╔╝", + "╚╗╔╝", + "──║║──", + "──╚╝──" + ], + Z: [ + "╔════╗", + "╚══╗═║", + "──╔╝╔╝", + "╔╝╔╝", + "╔╝═╚═╗", + "╚════╝" + ], + "0": ["╔═══╗", "║╔═╗║", "║║║║║", "║║║║║", "║╚═╝║", "╚═══╝"], + "1": [ + "╔╗", + "╔╝║", + "╚╗║", + "║║", + "╔╝╚╗", + "╚══╝" + ], + "2": ["╔═══╗", "║╔═╗║", "╚╝╔╝║", "╔═╝╔╝", "║║╚═╗", "╚═══╝"], + "3": ["╔═══╗", "║╔═╗║", "╚╝╔╝║", "╔╗╚╗║", "║╚═╝║", "╚═══╝"], + "4": [ + "╔╗╔╗", + "║║║║", + "║╚═╝║", + "╚══╗║", + "───║║", + "───╚╝" + ], + "5": ["╔═══╗", "║╔══╝", "║╚══╗", "╚══╗║", "╔══╝║", "╚═══╝"], + "6": ["╔═══╗", "║╔══╝", "║╚══╗", "║╔═╗║", "║╚═╝║", "╚═══╝"], + "7": [ + "╔═══╗", + "║╔═╗║", + "╚╝╔╝║", + "──║╔╝", + "──║║", + "──╚╝" + ], + "8": ["╔═══╗", "║╔═╗║", "║╚═╝║", "║╔═╗║", "║╚═╝║", "╚═══╝"], + "9": ["╔═══╗", "║╔═╗║", "║╚═╝║", "╚══╗║", "╔══╝║", "╚═══╝"], + "!": ["╔╗", "║║", "║║", "╚╝", "╔╗", "╚╝"], + "?": [ + "╔═══╗", + "║╔═╗║", + "╚╝╔╝║", + "──║╔╝", + "──╔╗", + "──╚╝" + ], + ".": ["──", "──", "──", "──", "╔╗", "╚╝"], + "+": [ + "────", + "────", + "╔╗", + "╔╝╚╗", + "╚╗╔╝", + "╚╝" + ], + "-": ["────", "────", "╔══╗", "╚══╝", "────", "────"], + _: ["────", "────", "────", "────", "╔══╗", "╚══╝"], + "=": ["─────", "╔═══╗", "╚═══╝", "╔═══╗", "╚═══╝", "─────"], + "@": [ + "╔════╗", + "║╔══╗║", + "║║╔═║║", + "║║╚╝║║", + "║╚══╝╠╗", + "╚═════╝" + ], + "#": [ + "╔╩╩╩╗", + "╔╝╔═╗╚╗", + "╚╗╠═╣╔╝", + "╔╝╠═╣╚╗", + "╚╗╚═╝╔╝", + "╚╦╦╦╝" + ], + $: ["╔╝╩╚╗", "║╔═╗║", "║╚══╗", "╚══╗║", "║╚═╝║", "╚╗╦╔╝"], + "%": [ + "╔╗──╔═╗", + "╚╝╔╝╔╝", + "──╔╝╔╝", + "╔╝╔╝──", + "╔╝╔╝╔╗", + "╚═╝──╚╝" + ], + "&": [ + "──╔╗", + "──║║", + "╔═╝╚╗", + "║╔╗╔╝", + "║╚╝║", + "╚══╝" + ], + "(": [ + "──╔═╗", + "╔╝╔╝", + "╔╝╔╝", + "╚╗╚╗", + "╚╗╚╗", + "──╚═╝" + ], + ")": [ + "╔═╗──", + "╚╗╚╗", + "╚╗╚╗", + "╔╝╔╝", + "╔╝╔╝", + "╚═╝──" + ], + "/": [ + "────╔═╗", + "───╔╝╔╝", + "──╔╝╔╝", + "╔╝╔╝──", + "╔╝╔╝───", + "╚═╝────" + ], + ":": ["──", "╔╗", "╚╝", "╔╗", "╚╝", "──"], + ";": ["──", "──", "──", "╔╗", "╚╣", ""], + ",": ["╔╗", "║║", "╚╝", "╔╗", "╚╣", ""], + "'": ["╔╗", "║║", "╚╝", "──", "──", "──"], + '"': ["╔╗╔╗", "║║║║", "╚╝╚╝", "────", "────", "────"], + " ": ["───", "───", "───", "───", "───", "───"] + } +}; + +// src/lib/ascii.font.ts +var fonts = { + tiny: tiny_default, + block: block_default, + shade: shade_default, + slick: slick_default, + huge: huge_default, + grid: grid_default, + pallet: pallet_default +}; +var parsedFonts = {}; +function parseColorTags(text) { + const segments = []; + let currentIndex = 0; + const colorTagRegex = /(.*?)<\/c\d+>/g; + let lastIndex = 0; + let match; + while ((match = colorTagRegex.exec(text)) !== null) { + if (match.index > lastIndex) { + const plainText = text.slice(lastIndex, match.index); + if (plainText) { + segments.push({ text: plainText, colorIndex: 0 }); + } + } + const colorIndex = parseInt(match[1]) - 1; + const taggedText = match[2]; + segments.push({ text: taggedText, colorIndex: Math.max(0, colorIndex) }); + lastIndex = match.index + match[0].length; + } + if (lastIndex < text.length) { + const remainingText = text.slice(lastIndex); + if (remainingText) { + segments.push({ text: remainingText, colorIndex: 0 }); + } + } + return segments; +} +function getParsedFont(fontKey) { + if (!parsedFonts[fontKey]) { + const fontDef = fonts[fontKey]; + const parsedChars = {}; + for (const [char, lines] of Object.entries(fontDef.chars)) { + parsedChars[char] = lines.map((line) => parseColorTags(line)); + } + parsedFonts[fontKey] = { + ...fontDef, + colors: fontDef.colors || 1, + chars: parsedChars + }; + } + return parsedFonts[fontKey]; +} +function measureText({ text, font = "tiny" }) { + const fontDef = getParsedFont(font); + if (!fontDef) { + console.warn(`Font '${font}' not found`); + return { width: 0, height: 0 }; + } + let currentX = 0; + for (let i = 0;i < text.length; i++) { + const char = text[i].toUpperCase(); + const charDef = fontDef.chars[char]; + if (!charDef) { + const spaceChar = fontDef.chars[" "]; + if (spaceChar && spaceChar[0]) { + let spaceWidth = 0; + for (const segment of spaceChar[0]) { + spaceWidth += segment.text.length; + } + currentX += spaceWidth; + } else { + currentX += 1; + } + continue; + } + let charWidth = 0; + if (charDef[0]) { + for (const segment of charDef[0]) { + charWidth += segment.text.length; + } + } + currentX += charWidth; + if (i < text.length - 1) { + currentX += fontDef.letterspace_size; + } + } + return { + width: currentX, + height: fontDef.lines + }; +} +function getCharacterPositions(text, font = "tiny") { + const fontDef = getParsedFont(font); + if (!fontDef) { + return [0]; + } + const positions = [0]; + let currentX = 0; + for (let i = 0;i < text.length; i++) { + const char = text[i].toUpperCase(); + const charDef = fontDef.chars[char]; + let charWidth = 0; + if (!charDef) { + const spaceChar = fontDef.chars[" "]; + if (spaceChar && spaceChar[0]) { + for (const segment of spaceChar[0]) { + charWidth += segment.text.length; + } + } else { + charWidth = 1; + } + } else if (charDef[0]) { + for (const segment of charDef[0]) { + charWidth += segment.text.length; + } + } + currentX += charWidth; + if (i < text.length - 1) { + currentX += fontDef.letterspace_size; + } + positions.push(currentX); + } + return positions; +} +function coordinateToCharacterIndex(x, text, font = "tiny") { + const positions = getCharacterPositions(text, font); + if (x < 0) { + return 0; + } + for (let i = 0;i < positions.length - 1; i++) { + const currentPos = positions[i]; + const nextPos = positions[i + 1]; + if (x >= currentPos && x < nextPos) { + const charMidpoint = currentPos + (nextPos - currentPos) / 2; + return x < charMidpoint ? i : i + 1; + } + } + if (positions.length > 0 && x >= positions[positions.length - 1]) { + return text.length; + } + return 0; +} +function renderFontToFrameBuffer(buffer, { + text, + x = 0, + y = 0, + color = [RGBA.fromInts(255, 255, 255, 255)], + backgroundColor = RGBA.fromInts(0, 0, 0, 255), + font = "tiny" +}) { + const width = buffer.width; + const height = buffer.height; + const fontDef = getParsedFont(font); + if (!fontDef) { + console.warn(`Font '${font}' not found`); + return { width: 0, height: 0 }; + } + const colors = Array.isArray(color) ? color : [color]; + if (y < 0 || y + fontDef.lines > height) { + return { width: 0, height: fontDef.lines }; + } + let currentX = x; + const startX = x; + for (let i = 0;i < text.length; i++) { + const char = text[i].toUpperCase(); + const charDef = fontDef.chars[char]; + if (!charDef) { + const spaceChar = fontDef.chars[" "]; + if (spaceChar && spaceChar[0]) { + let spaceWidth = 0; + for (const segment of spaceChar[0]) { + spaceWidth += segment.text.length; + } + currentX += spaceWidth; + } else { + currentX += 1; + } + continue; + } + let charWidth = 0; + if (charDef[0]) { + for (const segment of charDef[0]) { + charWidth += segment.text.length; + } + } + if (currentX >= width) + break; + if (currentX + charWidth < 0) { + currentX += charWidth + fontDef.letterspace_size; + continue; + } + for (let lineIdx = 0;lineIdx < fontDef.lines && lineIdx < charDef.length; lineIdx++) { + const segments = charDef[lineIdx]; + const renderY = y + lineIdx; + if (renderY >= 0 && renderY < height) { + let segmentX = currentX; + for (const segment of segments) { + const segmentColor = colors[segment.colorIndex] || colors[0]; + for (let charIdx = 0;charIdx < segment.text.length; charIdx++) { + const renderX = segmentX + charIdx; + if (renderX >= 0 && renderX < width) { + const fontChar = segment.text[charIdx]; + if (fontChar !== " ") { + buffer.setCellWithAlphaBlending(renderX, renderY, fontChar, parseColor(segmentColor), parseColor(backgroundColor)); + } + } + } + segmentX += segment.text.length; + } + } + } + currentX += charWidth; + if (i < text.length - 1) { + currentX += fontDef.letterspace_size; + } + } + return { + width: currentX - startX, + height: fontDef.lines + }; +} +// src/types.ts +var TextAttributes = { + NONE: 0, + BOLD: 1 << 0, + DIM: 1 << 1, + ITALIC: 1 << 2, + UNDERLINE: 1 << 3, + BLINK: 1 << 4, + INVERSE: 1 << 5, + HIDDEN: 1 << 6, + STRIKETHROUGH: 1 << 7 +}; +var ATTRIBUTE_BASE_BITS = 8; +var ATTRIBUTE_BASE_MASK = 255; +function getBaseAttributes(attr) { + return attr & ATTRIBUTE_BASE_MASK; +} +var DebugOverlayCorner; +((DebugOverlayCorner2) => { + DebugOverlayCorner2[DebugOverlayCorner2["topLeft"] = 0] = "topLeft"; + DebugOverlayCorner2[DebugOverlayCorner2["topRight"] = 1] = "topRight"; + DebugOverlayCorner2[DebugOverlayCorner2["bottomLeft"] = 2] = "bottomLeft"; + DebugOverlayCorner2[DebugOverlayCorner2["bottomRight"] = 3] = "bottomRight"; +})(DebugOverlayCorner ||= {}); +var TargetChannel; +((TargetChannel2) => { + TargetChannel2[TargetChannel2["FG"] = 1] = "FG"; + TargetChannel2[TargetChannel2["BG"] = 2] = "BG"; + TargetChannel2[TargetChannel2["Both"] = 3] = "Both"; +})(TargetChannel ||= {}); + +// src/utils.ts +function createTextAttributes({ + bold = false, + italic = false, + underline = false, + dim = false, + blink = false, + inverse = false, + hidden = false, + strikethrough = false +} = {}) { + let attributes = TextAttributes.NONE; + if (bold) + attributes |= TextAttributes.BOLD; + if (italic) + attributes |= TextAttributes.ITALIC; + if (underline) + attributes |= TextAttributes.UNDERLINE; + if (dim) + attributes |= TextAttributes.DIM; + if (blink) + attributes |= TextAttributes.BLINK; + if (inverse) + attributes |= TextAttributes.INVERSE; + if (hidden) + attributes |= TextAttributes.HIDDEN; + if (strikethrough) + attributes |= TextAttributes.STRIKETHROUGH; + return attributes; +} +var ATTRIBUTE_BASE_MASK2 = 255; +var LINK_ID_SHIFT = 8; +var LINK_ID_PAYLOAD_MASK = 16777215; +function attributesWithLink(baseAttributes, linkId) { + const base = baseAttributes & ATTRIBUTE_BASE_MASK2; + const linkBits = (linkId & LINK_ID_PAYLOAD_MASK) << LINK_ID_SHIFT; + return base | linkBits; +} +function getLinkId(attributes) { + return attributes >>> LINK_ID_SHIFT & LINK_ID_PAYLOAD_MASK; +} +function visualizeRenderableTree(renderable, maxDepth = 10) { + function buildTreeLines(node, prefix = "", parentPrefix = "", isLastChild = true, depth = 0) { + if (depth >= maxDepth) { + return [`${prefix}${node.id} ... (max depth reached)`]; + } + const lines = []; + const children = node.getChildren(); + lines.push(`${prefix}${node.id}`); + if (children.length > 0) { + const lastChildIndex = children.length - 1; + children.forEach((child, index) => { + const childIsLast = index === lastChildIndex; + const connector = childIsLast ? "└── " : "├── "; + const childPrefix = parentPrefix + (isLastChild ? " " : "│ "); + const childLines = buildTreeLines(child, childPrefix + connector, childPrefix, childIsLast, depth + 1); + lines.push(...childLines); + }); + } + return lines; + } + const treeLines = buildTreeLines(renderable); + console.log(`Renderable Tree: +` + treeLines.join(` +`)); +} + +// src/lib/styled-text.ts +var BrandedStyledText = Symbol.for("@opentui/core/StyledText"); +function isStyledText(obj) { + return obj && obj[BrandedStyledText]; +} + +class StyledText { + [BrandedStyledText] = true; + chunks; + constructor(chunks) { + this.chunks = chunks; + } +} +function stringToStyledText(content) { + const chunk = { + __isChunk: true, + text: content + }; + return new StyledText([chunk]); +} +function applyStyle(input, style) { + if (typeof input === "object" && "__isChunk" in input) { + const existingChunk = input; + const fg = style.fg ? parseColor(style.fg) : existingChunk.fg; + const bg = style.bg ? parseColor(style.bg) : existingChunk.bg; + const newAttrs = createTextAttributes(style); + const mergedAttrs = existingChunk.attributes ? existingChunk.attributes | newAttrs : newAttrs; + return { + __isChunk: true, + text: existingChunk.text, + fg, + bg, + attributes: mergedAttrs, + link: existingChunk.link + }; + } else { + const plainTextStr = String(input); + const fg = style.fg ? parseColor(style.fg) : undefined; + const bg = style.bg ? parseColor(style.bg) : undefined; + const attributes = createTextAttributes(style); + return { + __isChunk: true, + text: plainTextStr, + fg, + bg, + attributes + }; + } +} +var black = (input) => applyStyle(input, { fg: "black" }); +var red = (input) => applyStyle(input, { fg: "red" }); +var green = (input) => applyStyle(input, { fg: "green" }); +var yellow = (input) => applyStyle(input, { fg: "yellow" }); +var blue = (input) => applyStyle(input, { fg: "blue" }); +var magenta = (input) => applyStyle(input, { fg: "magenta" }); +var cyan = (input) => applyStyle(input, { fg: "cyan" }); +var white = (input) => applyStyle(input, { fg: "white" }); +var brightBlack = (input) => applyStyle(input, { fg: "brightBlack" }); +var brightRed = (input) => applyStyle(input, { fg: "brightRed" }); +var brightGreen = (input) => applyStyle(input, { fg: "brightGreen" }); +var brightYellow = (input) => applyStyle(input, { fg: "brightYellow" }); +var brightBlue = (input) => applyStyle(input, { fg: "brightBlue" }); +var brightMagenta = (input) => applyStyle(input, { fg: "brightMagenta" }); +var brightCyan = (input) => applyStyle(input, { fg: "brightCyan" }); +var brightWhite = (input) => applyStyle(input, { fg: "brightWhite" }); +var bgBlack = (input) => applyStyle(input, { bg: "black" }); +var bgRed = (input) => applyStyle(input, { bg: "red" }); +var bgGreen = (input) => applyStyle(input, { bg: "green" }); +var bgYellow = (input) => applyStyle(input, { bg: "yellow" }); +var bgBlue = (input) => applyStyle(input, { bg: "blue" }); +var bgMagenta = (input) => applyStyle(input, { bg: "magenta" }); +var bgCyan = (input) => applyStyle(input, { bg: "cyan" }); +var bgWhite = (input) => applyStyle(input, { bg: "white" }); +var bold = (input) => applyStyle(input, { bold: true }); +var italic = (input) => applyStyle(input, { italic: true }); +var underline = (input) => applyStyle(input, { underline: true }); +var strikethrough = (input) => applyStyle(input, { strikethrough: true }); +var dim = (input) => applyStyle(input, { dim: true }); +var reverse = (input) => applyStyle(input, { reverse: true }); +var blink = (input) => applyStyle(input, { blink: true }); +var fg = (color) => (input) => applyStyle(input, { fg: color }); +var bg = (color) => (input) => applyStyle(input, { bg: color }); +var link = (url) => (input) => { + const chunk = typeof input === "object" && "__isChunk" in input ? input : { + __isChunk: true, + text: String(input) + }; + return { + ...chunk, + link: { url } + }; +}; +function t(strings, ...values) { + const chunks = []; + for (let i = 0;i < strings.length; i++) { + const raw = strings[i]; + if (raw) { + chunks.push({ + __isChunk: true, + text: raw, + attributes: 0 + }); + } + const val = values[i]; + if (typeof val === "object" && "__isChunk" in val) { + chunks.push(val); + } else if (val !== undefined) { + const plainTextStr = String(val); + chunks.push({ + __isChunk: true, + text: plainTextStr, + attributes: 0 + }); + } + } + return new StyledText(chunks); +} + +// src/lib/hast-styled-text.ts +function hastToTextChunks(node, syntaxStyle, parentStyles = []) { + const chunks = []; + if (node.type === "text") { + const stylesToMerge = parentStyles.length > 0 ? parentStyles : ["default"]; + const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge); + chunks.push({ + __isChunk: true, + text: node.value, + fg: mergedStyle.fg, + bg: mergedStyle.bg, + attributes: mergedStyle.attributes + }); + } else if (node.type === "element") { + let currentStyles = [...parentStyles]; + if (node.properties?.className) { + const classes = node.properties.className.split(" "); + for (const cls of classes) { + currentStyles.push(cls); + } + } + for (const child of node.children) { + chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles)); + } + } + return chunks; +} +function hastToStyledText(hast, syntaxStyle) { + const chunks = hastToTextChunks(hast, syntaxStyle); + return new StyledText(chunks); +} +// src/lib/clock.ts +class SystemClock { + now() { + if (!globalThis.performance || typeof globalThis.performance.now !== "function") { + throw new Error("SystemClock requires globalThis.performance.now()"); + } + return globalThis.performance.now(); + } + setTimeout(fn, delayMs) { + return globalThis.setTimeout(fn, delayMs); + } + clearTimeout(handle) { + globalThis.clearTimeout(handle); + } + setInterval(fn, delayMs) { + return globalThis.setInterval(fn, delayMs); + } + clearInterval(handle) { + globalThis.clearInterval(handle); + } +} +// src/lib/parse.keypress.ts +import { Buffer as Buffer2 } from "node:buffer"; + +// src/lib/parse.keypress-kitty.ts +var kittyKeyMap = { + 27: "escape", + 9: "tab", + 13: "return", + 127: "backspace", + 57344: "escape", + 57345: "return", + 57346: "tab", + 57347: "backspace", + 57348: "insert", + 57349: "delete", + 57350: "left", + 57351: "right", + 57352: "up", + 57353: "down", + 57354: "pageup", + 57355: "pagedown", + 57356: "home", + 57357: "end", + 57358: "capslock", + 57359: "scrolllock", + 57360: "numlock", + 57361: "printscreen", + 57362: "pause", + 57363: "menu", + 57364: "f1", + 57365: "f2", + 57366: "f3", + 57367: "f4", + 57368: "f5", + 57369: "f6", + 57370: "f7", + 57371: "f8", + 57372: "f9", + 57373: "f10", + 57374: "f11", + 57375: "f12", + 57376: "f13", + 57377: "f14", + 57378: "f15", + 57379: "f16", + 57380: "f17", + 57381: "f18", + 57382: "f19", + 57383: "f20", + 57384: "f21", + 57385: "f22", + 57386: "f23", + 57387: "f24", + 57388: "f25", + 57389: "f26", + 57390: "f27", + 57391: "f28", + 57392: "f29", + 57393: "f30", + 57394: "f31", + 57395: "f32", + 57396: "f33", + 57397: "f34", + 57398: "f35", + 57399: "kp0", + 57400: "kp1", + 57401: "kp2", + 57402: "kp3", + 57403: "kp4", + 57404: "kp5", + 57405: "kp6", + 57406: "kp7", + 57407: "kp8", + 57408: "kp9", + 57409: "kpdecimal", + 57410: "kpdivide", + 57411: "kpmultiply", + 57412: "kpminus", + 57413: "kpplus", + 57414: "kpenter", + 57415: "kpequal", + 57416: "kpseparator", + 57417: "kpleft", + 57418: "kpright", + 57419: "kpup", + 57420: "kpdown", + 57421: "kppageup", + 57422: "kppagedown", + 57423: "kphome", + 57424: "kpend", + 57425: "kpinsert", + 57426: "kpdelete", + 57427: "clear", + 57428: "mediaplay", + 57429: "mediapause", + 57430: "mediaplaypause", + 57431: "mediareverse", + 57432: "mediastop", + 57433: "mediafastforward", + 57434: "mediarewind", + 57435: "medianext", + 57436: "mediaprev", + 57437: "mediarecord", + 57438: "volumedown", + 57439: "volumeup", + 57440: "mute", + 57441: "leftshift", + 57442: "leftctrl", + 57443: "leftalt", + 57444: "leftsuper", + 57445: "lefthyper", + 57446: "leftmeta", + 57447: "rightshift", + 57448: "rightctrl", + 57449: "rightalt", + 57450: "rightsuper", + 57451: "righthyper", + 57452: "rightmeta", + 57453: "iso_level3_shift", + 57454: "iso_level5_shift" +}; +var kittyNamedSingleStrokeKeys = [...new Set(Object.values(kittyKeyMap))]; +var printableKeypadText = { + kp0: "0", + kp1: "1", + kp2: "2", + kp3: "3", + kp4: "4", + kp5: "5", + kp6: "6", + kp7: "7", + kp8: "8", + kp9: "9", + kpdecimal: ".", + kpdivide: "/", + kpmultiply: "*", + kpminus: "-", + kpplus: "+", + kpequal: "=", + kpseparator: "," +}; +function getPrintableKittyKeyText(key) { + return printableKeypadText[key.name]; +} +function fromKittyMods(mod) { + return { + shift: !!(mod & 1), + alt: !!(mod & 2), + ctrl: !!(mod & 4), + super: !!(mod & 8), + hyper: !!(mod & 16), + meta: !!(mod & 32), + capsLock: !!(mod & 64), + numLock: !!(mod & 128) + }; +} +var functionalKeyMap = { + A: "up", + B: "down", + C: "right", + D: "left", + H: "home", + F: "end", + E: "clear", + P: "f1", + Q: "f2", + S: "f4" +}; +var tildeKeyMap = { + "1": "home", + "2": "insert", + "3": "delete", + "4": "end", + "5": "pageup", + "6": "pagedown", + "7": "home", + "8": "end", + "11": "f1", + "12": "f2", + "13": "f3", + "14": "f4", + "15": "f5", + "17": "f6", + "18": "f7", + "19": "f8", + "20": "f9", + "21": "f10", + "23": "f11", + "24": "f12", + "29": "menu", + "57427": "clear" +}; +function parseKittySpecialKey(sequence) { + const specialKeyRe = /^\x1b\[(\d+);(\d+):(\d+)([A-Z~])$/; + const match = specialKeyRe.exec(sequence); + if (!match) + return null; + const keyNumOrOne = match[1]; + const modifierStr = match[2]; + const eventTypeStr = match[3]; + const terminator = match[4]; + let keyName; + if (terminator === "~") { + keyName = tildeKeyMap[keyNumOrOne]; + } else { + if (keyNumOrOne !== "1") + return null; + keyName = functionalKeyMap[terminator]; + } + if (!keyName) + return null; + const key = { + name: keyName, + ctrl: false, + meta: false, + shift: false, + option: false, + number: false, + sequence, + raw: sequence, + eventType: "press", + source: "kitty", + super: false, + hyper: false, + capsLock: false, + numLock: false + }; + if (modifierStr) { + const modifierMask = parseInt(modifierStr, 10); + if (!isNaN(modifierMask) && modifierMask > 1) { + const mods = fromKittyMods(modifierMask - 1); + key.shift = mods.shift; + key.ctrl = mods.ctrl; + key.meta = mods.alt || mods.meta; + key.option = mods.alt; + key.super = mods.super; + key.hyper = mods.hyper; + key.capsLock = mods.capsLock; + key.numLock = mods.numLock; + } + } + if (eventTypeStr === "1" || !eventTypeStr) { + key.eventType = "press"; + } else if (eventTypeStr === "2") { + key.eventType = "press"; + key.repeated = true; + } else if (eventTypeStr === "3") { + key.eventType = "release"; + } + return key; +} +function parseKittyKeyboard(sequence) { + const specialResult = parseKittySpecialKey(sequence); + if (specialResult) + return specialResult; + const kittyRe = /^\x1b\[([^\x1b]+)u$/; + const match = kittyRe.exec(sequence); + if (!match) + return null; + const params = match[1]; + const fields = params.split(";"); + if (fields.length < 1) + return null; + const key = { + name: "", + ctrl: false, + meta: false, + shift: false, + option: false, + number: false, + sequence, + raw: sequence, + eventType: "press", + source: "kitty", + super: false, + hyper: false, + capsLock: false, + numLock: false + }; + let text = ""; + const field1 = fields[0]?.split(":") || []; + const codepointStr = field1[0]; + if (!codepointStr) + return null; + const codepoint = parseInt(codepointStr, 10); + if (isNaN(codepoint)) + return null; + let shiftedCodepoint; + let baseCodepoint; + if (field1[1]) { + const shifted = parseInt(field1[1], 10); + if (!isNaN(shifted) && shifted > 0 && shifted <= 1114111) { + shiftedCodepoint = shifted; + } + } + if (field1[2]) { + const base = parseInt(field1[2], 10); + if (!isNaN(base) && base > 0 && base <= 1114111) { + baseCodepoint = base; + } + } + const knownKey = kittyKeyMap[codepoint]; + if (knownKey) { + key.name = knownKey; + key.code = `[${codepoint}u`; + } else if (codepoint === 0) { + key.name = ""; + } else { + if (codepoint > 0 && codepoint <= 1114111) { + const char = String.fromCodePoint(codepoint); + key.name = char === " " ? "space" : char; + if (baseCodepoint) { + key.baseCode = baseCodepoint; + } + } else { + return null; + } + } + if (fields[1]) { + const field2 = fields[1].split(":"); + const modifierStr = field2[0]; + const eventTypeStr = field2[1]; + if (modifierStr) { + const modifierMask = parseInt(modifierStr, 10); + if (!isNaN(modifierMask) && modifierMask > 1) { + const mods = fromKittyMods(modifierMask - 1); + key.shift = mods.shift; + key.ctrl = mods.ctrl; + key.meta = mods.alt || mods.meta; + key.option = mods.alt; + key.super = mods.super; + key.hyper = mods.hyper; + key.capsLock = mods.capsLock; + key.numLock = mods.numLock; + } + } + if (eventTypeStr === "1" || !eventTypeStr) { + key.eventType = "press"; + } else if (eventTypeStr === "2") { + key.eventType = "press"; + key.repeated = true; + } else if (eventTypeStr === "3") { + key.eventType = "release"; + } else { + key.eventType = "press"; + } + } + if (fields[2]) { + const codepoints = fields[2].split(":"); + for (const cpStr of codepoints) { + const cp = parseInt(cpStr, 10); + if (!isNaN(cp) && cp > 0 && cp <= 1114111) { + text += String.fromCodePoint(cp); + } + } + } + if (text === "") { + text = getPrintableKittyKeyText(key) ?? ""; + } + if (text === "") { + const isPrintable = key.name.length > 0 && !kittyKeyMap[codepoint]; + if (isPrintable) { + if (codepoint === 32) { + text = " "; + } else if (key.shift && shiftedCodepoint) { + text = String.fromCodePoint(shiftedCodepoint); + } else if (key.shift && key.name.length === 1) { + text = key.name.toLocaleUpperCase(); + } else { + text = key.name; + } + } + } + if (text) { + if (codepoint === 0) { + key.name = text; + } + key.sequence = text; + } + if (codepoint === 0 && text === "") { + return null; + } + return key; +} + +// src/lib/parse.keypress.ts +var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/; +var fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/; +var keyName = { + OP: "f1", + OQ: "f2", + OR: "f3", + OS: "f4", + "[11~": "f1", + "[12~": "f2", + "[13~": "f3", + "[14~": "f4", + "[[A": "f1", + "[[B": "f2", + "[[C": "f3", + "[[D": "f4", + "[[E": "f5", + "[15~": "f5", + "[17~": "f6", + "[18~": "f7", + "[19~": "f8", + "[20~": "f9", + "[21~": "f10", + "[23~": "f11", + "[24~": "f12", + "[29~": "menu", + "[57427~": "clear", + "[A": "up", + "[B": "down", + "[C": "right", + "[D": "left", + "[E": "clear", + "[F": "end", + "[H": "home", + "[P": "f1", + "[Q": "f2", + "[S": "f4", + OA: "up", + OB: "down", + OC: "right", + OD: "left", + OE: "clear", + OF: "end", + OH: "home", + OM: "return", + Oj: "*", + Ok: "+", + Ol: ",", + Om: "-", + On: ".", + Oo: "/", + Op: "0", + Oq: "1", + Or: "2", + Os: "3", + Ot: "4", + Ou: "5", + Ov: "6", + Ow: "7", + Ox: "8", + Oy: "9", + OX: "=", + "[1~": "home", + "[2~": "insert", + "[3~": "delete", + "[4~": "end", + "[5~": "pageup", + "[6~": "pagedown", + "[[5~": "pageup", + "[[6~": "pagedown", + "[7~": "home", + "[8~": "end", + "[a": "up", + "[b": "down", + "[c": "right", + "[d": "left", + "[e": "clear", + f: "right", + b: "left", + p: "up", + n: "down", + "[2$": "insert", + "[3$": "delete", + "[5$": "pageup", + "[6$": "pagedown", + "[7$": "home", + "[8$": "end", + Oa: "up", + Ob: "down", + Oc: "right", + Od: "left", + Oe: "clear", + "[2^": "insert", + "[3^": "delete", + "[5^": "pageup", + "[6^": "pagedown", + "[7^": "home", + "[8^": "end", + "[Z": "tab" +}; +var nonAlphanumericKeys = [...Object.values(keyName), "backspace"]; +var terminalNamedSingleStrokeKeys = [ + ...new Set(["return", "linefeed", "tab", "escape", "space", ...nonAlphanumericKeys, ...kittyNamedSingleStrokeKeys]) +]; +var isShiftKey = (code) => { + return ["[a", "[b", "[c", "[d", "[e", "[2$", "[3$", "[5$", "[6$", "[7$", "[8$", "[Z"].includes(code); +}; +var isCtrlKey = (code) => { + return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code); +}; +var getCtrlKeyName = (charCode) => { + if (charCode === 0) { + return "space"; + } + if (charCode >= 1 && charCode <= 26) { + return String.fromCharCode(charCode + 97 - 1); + } + if (charCode >= 28 && charCode <= 31) { + return String.fromCharCode(charCode + 64); + } + return; +}; +var ss3NumpadPrintable = { + Op: "0", + Oq: "1", + Or: "2", + Os: "3", + Ot: "4", + Ou: "5", + Ov: "6", + Ow: "7", + Ox: "8", + Oy: "9", + Oj: "*", + Ok: "+", + Ol: ",", + Om: "-", + On: ".", + Oo: "/", + OX: "=" +}; +var modifyOtherKeysRe = /^\x1b\[27;(\d+);(\d+)~$/; +var parseKeypress = (s = "", options = {}) => { + let parts; + if (Buffer2.isBuffer(s)) { + if (s[0] > 127 && s[1] === undefined) { + s[0] -= 128; + s = "\x1B" + String(s); + } else { + s = String(s); + } + } else if (s !== undefined && typeof s !== "string") { + s = String(s); + } else if (!s) { + s = ""; + } + if (/^\x1b\[<\d+;\d+;\d+[Mm]$/.test(s)) { + return null; + } + if (/^\[<\d+;\d+;\d+[Mm]$/.test(s)) { + return null; + } + if (/^\x1b\[<[\d;]*$/.test(s)) { + return null; + } + if (/^\[<[\d;]*$/.test(s)) { + return null; + } + if (s.startsWith("\x1B[M") && s.length >= 6) { + return null; + } + if (/^\x1b\[\d+;\d+;\d+t$/.test(s)) { + return null; + } + if (/^\x1b\[\d+;\d+R$/.test(s)) { + return null; + } + if (/^\x1b\[\?[\d;]+c$/.test(s)) { + return null; + } + if (/^\x1b\[\?[\d;]+\$y$/.test(s)) { + return null; + } + if (s === "\x1B[I" || s === "\x1B[O") { + return null; + } + if (/^\x1b\][\d;].*(\x1b\\|\x07)$/.test(s)) { + return null; + } + if (s === "\x1B[200~" || s === "\x1B[201~") { + return null; + } + const key = { + name: "", + ctrl: false, + meta: false, + shift: false, + option: false, + number: false, + sequence: s, + raw: s, + eventType: "press", + source: "raw" + }; + key.sequence = key.sequence || s || key.name; + const ctrlKeyName = s.length === 1 ? getCtrlKeyName(s.charCodeAt(0)) : undefined; + const metaCtrlKeyName = s.length === 2 && s[0] === "\x1B" ? getCtrlKeyName(s.charCodeAt(1)) : undefined; + if (options.useKittyKeyboard) { + const kittyResult = parseKittyKeyboard(s); + if (kittyResult) { + return kittyResult; + } + } + const modifyOtherKeysMatch = modifyOtherKeysRe.exec(s); + if (modifyOtherKeysMatch) { + const modifier = parseInt(modifyOtherKeysMatch[1], 10) - 1; + const charCode = parseInt(modifyOtherKeysMatch[2], 10); + key.ctrl = !!(modifier & 4); + key.meta = !!(modifier & 2); + key.shift = !!(modifier & 1); + key.option = !!(modifier & 2); + key.super = !!(modifier & 8); + key.hyper = !!(modifier & 16); + if (charCode === 13) { + key.name = "return"; + } else if (charCode === 27) { + key.name = "escape"; + } else if (charCode === 9) { + key.name = "tab"; + } else if (charCode === 32) { + key.name = "space"; + } else if (charCode === 127 || charCode === 8) { + key.name = "backspace"; + } else { + const char = String.fromCharCode(charCode); + key.name = char; + key.sequence = char; + if (charCode >= 48 && charCode <= 57) { + key.number = true; + } + } + return key; + } + if (s === "\r" || s === "\x1B\r") { + key.name = "return"; + key.meta = s.length === 2; + } else if (s === ` +` || s === `\x1B +`) { + key.name = "linefeed"; + key.meta = s.length === 2; + } else if (s === "\t") { + key.name = "tab"; + } else if (s === "\b" || s === "\x1B\b" || s === "" || s === "\x1B") { + key.name = "backspace"; + key.meta = s.charAt(0) === "\x1B"; + } else if (s === "\x1B" || s === "\x1B\x1B") { + key.name = "escape"; + key.meta = s.length === 2; + } else if (s === " " || s === "\x1B ") { + key.name = "space"; + key.meta = s.length === 2; + } else if (ctrlKeyName) { + key.name = ctrlKeyName; + key.ctrl = true; + } else if (s.length === 1 && s >= "0" && s <= "9") { + key.name = s; + key.number = true; + } else if (s.length === 1 && s >= "a" && s <= "z") { + key.name = s; + } else if (s.length === 1 && s >= "A" && s <= "Z") { + key.name = s.toLowerCase(); + key.shift = true; + } else if (s.length === 1 || s.length === 2 && s.codePointAt(0) > 65535) { + key.name = s; + } else if (parts = metaKeyCodeRe.exec(s)) { + key.meta = true; + const char = parts[1]; + const isUpperCase = /^[A-Z]$/.test(char); + if (char === "F") { + key.name = "right"; + } else if (char === "B") { + key.name = "left"; + } else if (isUpperCase) { + key.shift = true; + key.name = char; + } else { + key.name = char; + } + } else if (metaCtrlKeyName) { + key.meta = true; + key.ctrl = true; + key.name = metaCtrlKeyName; + } else if (parts = fnKeyRe.exec(s)) { + const segs = [...s]; + if (segs[0] === "\x1B" && segs[1] === "\x1B") { + key.option = true; + key.meta = true; + } + const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join(""); + const modifier = parseInt(parts[3] || parts[5] || "1", 10) - 1; + key.ctrl = key.ctrl || !!(modifier & 4); + key.meta = key.meta || !!(modifier & 2); + key.shift = key.shift || !!(modifier & 1); + key.option = key.option || !!(modifier & 2); + key.super = !!(modifier & 8); + key.hyper = !!(modifier & 16); + key.code = code; + const keyNameResult = keyName[code]; + if (keyNameResult) { + key.name = keyNameResult; + key.shift = isShiftKey(code) || key.shift; + key.ctrl = isCtrlKey(code) || key.ctrl; + const ss3Char = ss3NumpadPrintable[code]; + if (ss3Char !== undefined) { + key.sequence = ss3Char; + if (key.name >= "0" && key.name <= "9") { + key.number = true; + } + } + } else { + key.name = ""; + key.code = undefined; + } + } else if (s === "\x1B[3~") { + key.name = "delete"; + key.meta = false; + key.code = "[3~"; + } + return key; +}; +// src/lib/scroll-acceleration.ts +class LinearScrollAccel { + tick(_now) { + return 1; + } + reset() {} +} + +class MacOSScrollAccel { + opts; + lastTickTime = 0; + velocityHistory = []; + historySize = 3; + streakTimeout = 150; + minTickInterval = 6; + constructor(opts = {}) { + this.opts = opts; + } + tick(now = Date.now()) { + const A = this.opts.A ?? 0.8; + const tau = this.opts.tau ?? 3; + const maxMultiplier = this.opts.maxMultiplier ?? 6; + const dt = this.lastTickTime ? now - this.lastTickTime : Infinity; + if (dt === Infinity || dt > this.streakTimeout) { + this.lastTickTime = now; + this.velocityHistory = []; + return 1; + } + if (dt < this.minTickInterval) { + return 1; + } + this.lastTickTime = now; + this.velocityHistory.push(dt); + if (this.velocityHistory.length > this.historySize) { + this.velocityHistory.shift(); + } + const avgInterval = this.velocityHistory.reduce((a, b) => a + b, 0) / this.velocityHistory.length; + const referenceInterval = 100; + const velocity = referenceInterval / avgInterval; + const x = velocity / tau; + const multiplier = 1 + A * (Math.exp(x) - 1); + return Math.min(multiplier, maxMultiplier); + } + reset() { + this.lastTickTime = 0; + this.velocityHistory = []; + } +} +// src/lib/yoga.options.ts +function parseAlign(value) { + if (value == null) { + return 0 /* Auto */; + } + switch (value.toLowerCase()) { + case "auto": + return 0 /* Auto */; + case "flex-start": + return 1 /* FlexStart */; + case "center": + return 2 /* Center */; + case "flex-end": + return 3 /* FlexEnd */; + case "stretch": + return 4 /* Stretch */; + case "baseline": + return 5 /* Baseline */; + case "space-between": + return 6 /* SpaceBetween */; + case "space-around": + return 7 /* SpaceAround */; + case "space-evenly": + return 8 /* SpaceEvenly */; + default: + return 0 /* Auto */; + } +} +function parseAlignItems(value) { + if (value == null) { + return 4 /* Stretch */; + } + switch (value.toLowerCase()) { + case "auto": + return 0 /* Auto */; + case "flex-start": + return 1 /* FlexStart */; + case "center": + return 2 /* Center */; + case "flex-end": + return 3 /* FlexEnd */; + case "stretch": + return 4 /* Stretch */; + case "baseline": + return 5 /* Baseline */; + case "space-between": + return 6 /* SpaceBetween */; + case "space-around": + return 7 /* SpaceAround */; + case "space-evenly": + return 8 /* SpaceEvenly */; + default: + return 4 /* Stretch */; + } +} +function parseBoxSizing(value) { + if (value == null) { + return 0 /* BorderBox */; + } + switch (value.toLowerCase()) { + case "border-box": + return 0 /* BorderBox */; + case "content-box": + return 1 /* ContentBox */; + default: + return 0 /* BorderBox */; + } +} +function parseDimension(value) { + if (value == null) { + return 0 /* Width */; + } + switch (value.toLowerCase()) { + case "width": + return 0 /* Width */; + case "height": + return 1 /* Height */; + default: + return 0 /* Width */; + } +} +function parseDirection(value) { + if (value == null) { + return 1 /* LTR */; + } + switch (value.toLowerCase()) { + case "inherit": + return 0 /* Inherit */; + case "ltr": + return 1 /* LTR */; + case "rtl": + return 2 /* RTL */; + default: + return 1 /* LTR */; + } +} +function parseDisplay(value) { + if (value == null) { + return 0 /* Flex */; + } + switch (value.toLowerCase()) { + case "flex": + return 0 /* Flex */; + case "none": + return 1 /* None */; + case "contents": + return 2 /* Contents */; + default: + return 0 /* Flex */; + } +} +function parseEdge(value) { + if (value == null) { + return 8 /* All */; + } + switch (value.toLowerCase()) { + case "left": + return 0 /* Left */; + case "top": + return 1 /* Top */; + case "right": + return 2 /* Right */; + case "bottom": + return 3 /* Bottom */; + case "start": + return 4 /* Start */; + case "end": + return 5 /* End */; + case "horizontal": + return 6 /* Horizontal */; + case "vertical": + return 7 /* Vertical */; + case "all": + return 8 /* All */; + default: + return 8 /* All */; + } +} +function parseFlexDirection(value) { + if (value == null) { + return 0 /* Column */; + } + switch (value.toLowerCase()) { + case "column": + return 0 /* Column */; + case "column-reverse": + return 1 /* ColumnReverse */; + case "row": + return 2 /* Row */; + case "row-reverse": + return 3 /* RowReverse */; + default: + return 0 /* Column */; + } +} +function parseGutter(value) { + if (value == null) { + return 2 /* All */; + } + switch (value.toLowerCase()) { + case "column": + return 0 /* Column */; + case "row": + return 1 /* Row */; + case "all": + return 2 /* All */; + default: + return 2 /* All */; + } +} +function parseJustify(value) { + if (value == null) { + return 0 /* FlexStart */; + } + switch (value.toLowerCase()) { + case "flex-start": + return 0 /* FlexStart */; + case "center": + return 1 /* Center */; + case "flex-end": + return 2 /* FlexEnd */; + case "space-between": + return 3 /* SpaceBetween */; + case "space-around": + return 4 /* SpaceAround */; + case "space-evenly": + return 5 /* SpaceEvenly */; + default: + return 0 /* FlexStart */; + } +} +function parseLogLevel(value) { + if (value == null) { + return 2 /* Info */; + } + switch (value.toLowerCase()) { + case "error": + return 0 /* Error */; + case "warn": + return 1 /* Warn */; + case "info": + return 2 /* Info */; + case "debug": + return 3 /* Debug */; + case "verbose": + return 4 /* Verbose */; + case "fatal": + return 5 /* Fatal */; + default: + return 2 /* Info */; + } +} +function parseMeasureMode(value) { + if (value == null) { + return 0 /* Undefined */; + } + switch (value.toLowerCase()) { + case "undefined": + return 0 /* Undefined */; + case "exactly": + return 1 /* Exactly */; + case "at-most": + return 2 /* AtMost */; + default: + return 0 /* Undefined */; + } +} +function parseOverflow(value) { + if (value == null) { + return 0 /* Visible */; + } + switch (value.toLowerCase()) { + case "visible": + return 0 /* Visible */; + case "hidden": + return 1 /* Hidden */; + case "scroll": + return 2 /* Scroll */; + default: + return 0 /* Visible */; + } +} +function parsePositionType(value) { + if (value == null) { + return 1 /* Relative */; + } + switch (value.toLowerCase()) { + case "static": + return 0 /* Static */; + case "relative": + return 1 /* Relative */; + case "absolute": + return 2 /* Absolute */; + default: + return 0 /* Static */; + } +} +function parseUnit(value) { + if (value == null) { + return 1 /* Point */; + } + switch (value.toLowerCase()) { + case "undefined": + return 0 /* Undefined */; + case "point": + return 1 /* Point */; + case "percent": + return 2 /* Percent */; + case "auto": + return 3 /* Auto */; + default: + return 1 /* Point */; + } +} +function parseWrap(value) { + if (value == null) { + return 0 /* NoWrap */; + } + switch (value.toLowerCase()) { + case "no-wrap": + return 0 /* NoWrap */; + case "wrap": + return 1 /* Wrap */; + case "wrap-reverse": + return 2 /* WrapReverse */; + default: + return 0 /* NoWrap */; + } +} +// src/lib/parse.mouse.ts +class MouseParser { + mouseButtonsPressed = new Set; + static SCROLL_DIRECTIONS = { + 0: "up", + 1: "down", + 2: "left", + 3: "right" + }; + reset() { + this.mouseButtonsPressed.clear(); + } + decodeInput(data) { + const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength); + return buf.toString("latin1"); + } + parseMouseEvent(data) { + const str = this.decodeInput(data); + const parsed = this.parseMouseSequenceAt(str, 0); + return parsed?.event ?? null; + } + parseAllMouseEvents(data) { + const str = this.decodeInput(data); + const events = []; + let offset = 0; + while (offset < str.length) { + const parsed = this.parseMouseSequenceAt(str, offset); + if (!parsed) { + break; + } + events.push(parsed.event); + offset += parsed.consumed; + } + return events; + } + parseMouseSequenceAt(str, offset) { + if (!str.startsWith("\x1B[", offset)) + return null; + const introducer = str[offset + 2]; + if (introducer === "<") { + return this.parseSgrSequence(str, offset); + } + if (introducer === "M") { + return this.parseBasicSequence(str, offset); + } + return null; + } + parseSgrSequence(str, offset) { + let index = offset + 3; + const values = [0, 0, 0]; + let part = 0; + let hasDigit = false; + while (index < str.length) { + const char = str[index]; + const charCode = str.charCodeAt(index); + if (charCode >= 48 && charCode <= 57) { + hasDigit = true; + values[part] = values[part] * 10 + (charCode - 48); + index++; + continue; + } + switch (char) { + case ";": { + if (!hasDigit || part >= 2) + return null; + part++; + hasDigit = false; + index++; + break; + } + case "M": + case "m": { + if (!hasDigit || part !== 2) + return null; + return { + event: this.decodeSgrEvent(values[0], values[1], values[2], char), + consumed: index - offset + 1 + }; + } + default: + return null; + } + } + return null; + } + parseBasicSequence(str, offset) { + if (offset + 6 > str.length) + return null; + const buttonByte = str.charCodeAt(offset + 3) - 32; + const x = str.charCodeAt(offset + 4) - 33; + const y = str.charCodeAt(offset + 5) - 33; + return { + event: this.decodeBasicEvent(buttonByte, x, y), + consumed: 6 + }; + } + decodeSgrEvent(rawButtonCode, wireX, wireY, pressRelease) { + const button = rawButtonCode & 3; + const isScroll = (rawButtonCode & 64) !== 0; + const scrollDirection = !isScroll ? undefined : MouseParser.SCROLL_DIRECTIONS[button]; + const isMotion = (rawButtonCode & 32) !== 0; + const modifiers = { + shift: (rawButtonCode & 4) !== 0, + alt: (rawButtonCode & 8) !== 0, + ctrl: (rawButtonCode & 16) !== 0 + }; + let type; + let scrollInfo; + if (isMotion) { + const isDragging = this.mouseButtonsPressed.size > 0; + if (button === 3) { + type = "move"; + } else if (isDragging) { + type = "drag"; + } else { + type = "move"; + } + } else if (isScroll && pressRelease === "M") { + type = "scroll"; + scrollInfo = { + direction: scrollDirection, + delta: 1 + }; + } else { + type = pressRelease === "M" ? "down" : "up"; + if (type === "down" && button !== 3) { + this.mouseButtonsPressed.add(button); + } else if (type === "up") { + this.mouseButtonsPressed.clear(); + } + } + return { + type, + button: button === 3 ? 0 : button, + x: wireX - 1, + y: wireY - 1, + modifiers, + scroll: scrollInfo + }; + } + decodeBasicEvent(buttonByte, x, y) { + const button = buttonByte & 3; + const isScroll = (buttonByte & 64) !== 0; + const isMotion = (buttonByte & 32) !== 0; + const scrollDirection = !isScroll ? undefined : MouseParser.SCROLL_DIRECTIONS[button]; + const modifiers = { + shift: (buttonByte & 4) !== 0, + alt: (buttonByte & 8) !== 0, + ctrl: (buttonByte & 16) !== 0 + }; + let type; + let actualButton; + let scrollInfo; + if (isMotion) { + type = "move"; + actualButton = button === 3 ? -1 : button; + } else if (isScroll) { + type = "scroll"; + actualButton = 0; + scrollInfo = { + direction: scrollDirection, + delta: 1 + }; + } else { + type = button === 3 ? "up" : "down"; + actualButton = button === 3 ? 0 : button; + } + return { + type, + button: actualButton, + x, + y, + modifiers, + scroll: scrollInfo + }; + } +} +// src/lib/selection.ts +class SelectionAnchor { + renderable; + relativeX; + relativeY; + constructor(renderable, absoluteX, absoluteY) { + this.renderable = renderable; + this.relativeX = absoluteX - this.renderable.x; + this.relativeY = absoluteY - this.renderable.y; + } + get x() { + return this.renderable.x + this.relativeX; + } + get y() { + return this.renderable.y + this.relativeY; + } +} + +class Selection { + _anchor; + _focus; + _selectedRenderables = []; + _touchedRenderables = []; + _isActive = true; + _isDragging = true; + _isStart = false; + constructor(anchorRenderable, anchor, focus) { + this._anchor = new SelectionAnchor(anchorRenderable, anchor.x, anchor.y); + this._focus = { ...focus }; + } + get isStart() { + return this._isStart; + } + set isStart(value) { + this._isStart = value; + } + get anchor() { + return { x: this._anchor.x, y: this._anchor.y }; + } + get focus() { + return { ...this._focus }; + } + set focus(value) { + this._focus = { ...value }; + } + get isActive() { + return this._isActive; + } + set isActive(value) { + this._isActive = value; + } + get isDragging() { + return this._isDragging; + } + set isDragging(value) { + this._isDragging = value; + } + get bounds() { + const minX = Math.min(this._anchor.x, this._focus.x); + const maxX = Math.max(this._anchor.x, this._focus.x); + const minY = Math.min(this._anchor.y, this._focus.y); + const maxY = Math.max(this._anchor.y, this._focus.y); + const width = maxX - minX + 1; + const height = maxY - minY + 1; + return { + x: minX, + y: minY, + width, + height + }; + } + updateSelectedRenderables(selectedRenderables) { + this._selectedRenderables = selectedRenderables; + } + get selectedRenderables() { + return this._selectedRenderables; + } + updateTouchedRenderables(touchedRenderables) { + this._touchedRenderables = touchedRenderables; + } + get touchedRenderables() { + return this._touchedRenderables; + } + getSelectedText() { + const selectedTextsByLine = new Map; + const selectedRenderables = this._selectedRenderables.sort((a, b) => { + const aY = a.y; + const bY = b.y; + if (aY !== bY) { + return aY - bY; + } + return a.x - b.x; + }).filter((renderable) => !renderable.isDestroyed); + for (const renderable of selectedRenderables) { + const text = renderable.getSelectedText(); + if (!text) + continue; + const lines = text.split(` +`); + for (let index = 0;index < lines.length; index += 1) { + const y = renderable.y + index; + const line = selectedTextsByLine.get(y) ?? []; + line.push({ x: renderable.x, text: lines[index] }); + selectedTextsByLine.set(y, line); + } + } + return [...selectedTextsByLine.entries()].sort(([leftY], [rightY]) => leftY - rightY).map(([, line]) => line.sort((left, right) => left.x - right.x).map((segment) => segment.text).join("")).join(` +`); + } +} +function convertGlobalToLocalSelection(globalSelection, localX, localY) { + if (!globalSelection?.isActive) { + return null; + } + return { + anchorX: globalSelection.anchor.x - localX, + anchorY: globalSelection.anchor.y - localY, + focusX: globalSelection.focus.x - localX, + focusY: globalSelection.focus.y - localY, + isActive: true + }; +} + +class ASCIIFontSelectionHelper { + getText; + getFont; + localSelection = null; + constructor(getText, getFont) { + this.getText = getText; + this.getFont = getFont; + } + hasSelection() { + return this.localSelection !== null; + } + getSelection() { + return this.localSelection; + } + shouldStartSelection(localX, localY, width, height) { + if (localX < 0 || localX >= width || localY < 0 || localY >= height) { + return false; + } + const text = this.getText(); + const font = this.getFont(); + const charIndex = coordinateToCharacterIndex(localX, text, font); + return charIndex >= 0 && charIndex <= text.length; + } + onLocalSelectionChanged(localSelection, width, height) { + const previousSelection = this.localSelection; + if (!localSelection?.isActive) { + this.localSelection = null; + return previousSelection !== null; + } + const text = this.getText(); + const font = this.getFont(); + const selStart = { x: localSelection.anchorX, y: localSelection.anchorY }; + const selEnd = { x: localSelection.focusX, y: localSelection.focusY }; + if (height - 1 < selStart.y || 0 > selEnd.y) { + this.localSelection = null; + return previousSelection !== null; + } + let startCharIndex = 0; + let endCharIndex = text.length; + if (selStart.y > height - 1) { + this.localSelection = null; + return previousSelection !== null; + } else if (selStart.y >= 0 && selStart.y <= height - 1) { + if (selStart.x > 0) { + startCharIndex = coordinateToCharacterIndex(selStart.x, text, font); + } + } + if (selEnd.y < 0) { + this.localSelection = null; + return previousSelection !== null; + } else if (selEnd.y >= 0 && selEnd.y <= height - 1) { + if (selEnd.x >= 0) { + endCharIndex = coordinateToCharacterIndex(selEnd.x, text, font); + } else { + endCharIndex = 0; + } + } + if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) { + this.localSelection = { start: startCharIndex, end: endCharIndex }; + } else { + this.localSelection = null; + } + return previousSelection?.start !== this.localSelection?.start || previousSelection?.end !== this.localSelection?.end; + } +} +// src/lib/singleton.ts +var singletonCacheSymbol = Symbol.for("@opentui/core/singleton"); +function singleton(key, factory) { + const bag = globalThis[singletonCacheSymbol] ??= {}; + if (!(key in bag)) { + bag[key] = factory(); + } + return bag[key]; +} +function getSingleton(key) { + const bag = globalThis[singletonCacheSymbol]; + return bag?.[key]; +} +function destroySingleton(key) { + const bag = globalThis[singletonCacheSymbol]; + if (bag && key in bag) { + delete bag[key]; + } +} + +// src/lib/env.ts +var envRegistry = singleton("env-registry", () => ({})); +function registerEnvVar(config) { + const existing = envRegistry[config.name]; + if (existing) { + if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default) { + throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`); + } + return; + } + envRegistry[config.name] = config; +} +function normalizeBoolean(value) { + const lowerValue = value.toLowerCase(); + return ["true", "1", "on", "yes"].includes(lowerValue); +} +function parseEnvValue(config) { + const envValue = process.env[config.name]; + if (envValue === undefined && config.default !== undefined) { + return config.default; + } + if (envValue === undefined) { + throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`); + } + switch (config.type) { + case "boolean": + return typeof envValue === "boolean" ? envValue : normalizeBoolean(envValue); + case "number": + const numValue = Number(envValue); + if (isNaN(numValue)) { + throw new Error(`Environment variable ${config.name} must be a valid number, got: ${envValue}`); + } + return numValue; + case "string": + default: + return envValue; + } +} + +class EnvStore { + parsedValues = new Map; + get(key) { + if (this.parsedValues.has(key)) { + return this.parsedValues.get(key); + } + if (!(key in envRegistry)) { + throw new Error(`Environment variable ${key} is not registered.`); + } + try { + const value = parseEnvValue(envRegistry[key]); + this.parsedValues.set(key, value); + return value; + } catch (error) { + throw new Error(`Failed to parse env var ${key}: ${error instanceof Error ? error.message : String(error)}`); + } + } + has(key) { + return key in envRegistry; + } + clearCache() { + this.parsedValues.clear(); + } +} +var envStore = singleton("env-store", () => new EnvStore); +function clearEnvCache() { + envStore.clearCache(); +} +function generateEnvMarkdown() { + const configs = Object.values(envRegistry); + if (configs.length === 0) { + return `# Environment Variables + +No environment variables registered. +`; + } + let markdown = `# Environment Variables + +`; + for (const config of configs) { + markdown += `## ${config.name} + +`; + markdown += `${config.description} + +`; + markdown += `**Type:** \`${config.type || "string"}\` +`; + if (config.default !== undefined) { + const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default); + markdown += `**Default:** \`${defaultValue}\` +`; + } else { + markdown += `**Default:** *Required* +`; + } + markdown += ` +`; + } + return markdown; +} +function generateEnvColored() { + const configs = Object.values(envRegistry); + if (configs.length === 0) { + return `\x1B[1;36mEnvironment Variables\x1B[0m + +No environment variables registered. +`; + } + let output = `\x1B[1;36mEnvironment Variables\x1B[0m + +`; + for (const config of configs) { + output += `\x1B[1;33m${config.name}\x1B[0m +`; + output += `${config.description} +`; + output += `\x1B[32mType:\x1B[0m \x1B[36m${config.type || "string"}\x1B[0m +`; + if (config.default !== undefined) { + const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default); + output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m +`; + } else { + output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m +`; + } + output += ` +`; + } + return output; +} +var env = new Proxy({}, { + get(target, prop) { + if (typeof prop !== "string") { + return; + } + return envStore.get(prop); + }, + has(target, prop) { + return envStore.has(prop); + }, + ownKeys() { + return Object.keys(envRegistry); + }, + getOwnPropertyDescriptor(target, prop) { + if (envStore.has(prop)) { + return { + enumerable: true, + configurable: true, + get: () => envStore.get(prop) + }; + } + return; + } +}); +// src/lib/stdin-parser.ts +import { Buffer as Buffer3 } from "node:buffer"; +var DEFAULT_TIMEOUT_MS = 20; +var DEFAULT_MAX_PENDING_BYTES = 64 * 1024; +var INITIAL_PENDING_CAPACITY = 256; +var ESC = 27; +var BEL = 7; +var BRACKETED_PASTE_START = Buffer3.from("\x1B[200~"); +var BRACKETED_PASTE_END = Buffer3.from("\x1B[201~"); +var EMPTY_BYTES = new Uint8Array(0); +var KEY_DECODER = new TextDecoder; +var DEFAULT_PROTOCOL_CONTEXT = { + kittyKeyboardEnabled: false, + privateCapabilityRepliesActive: false, + pixelResolutionQueryActive: false, + explicitWidthCprActive: false, + startupCursorCprActive: false +}; +var RXVT_DOLLAR_CSI_RE = /^\x1b\[\d+\$$/; +var SYSTEM_CLOCK = new SystemClock; + +class ByteQueue { + buf; + start = 0; + end = 0; + constructor(capacity = INITIAL_PENDING_CAPACITY) { + this.buf = new Uint8Array(capacity); + } + get length() { + return this.end - this.start; + } + get capacity() { + return this.buf.length; + } + view() { + return this.buf.subarray(this.start, this.end); + } + take() { + const chunk = this.view(); + this.start = 0; + this.end = 0; + return chunk; + } + append(chunk) { + if (chunk.length === 0) { + return; + } + this.ensureCapacity(this.length + chunk.length); + this.buf.set(chunk, this.end); + this.end += chunk.length; + } + consume(count) { + if (count <= 0) { + return; + } + if (count >= this.length) { + this.start = 0; + this.end = 0; + return; + } + this.start += count; + if (this.start >= this.buf.length / 2) { + this.buf.copyWithin(0, this.start, this.end); + this.end -= this.start; + this.start = 0; + } + } + clear() { + this.start = 0; + this.end = 0; + } + reset(capacity = INITIAL_PENDING_CAPACITY) { + this.buf = new Uint8Array(capacity); + this.start = 0; + this.end = 0; + } + ensureCapacity(requiredLength) { + const currentLength = this.length; + if (requiredLength <= this.buf.length) { + const availableAtEnd = this.buf.length - this.end; + if (availableAtEnd >= requiredLength - currentLength) { + return; + } + this.buf.copyWithin(0, this.start, this.end); + this.end = currentLength; + this.start = 0; + if (requiredLength <= this.buf.length) { + return; + } + } + let nextCapacity = this.buf.length; + while (nextCapacity < requiredLength) { + nextCapacity *= 2; + } + const next = new Uint8Array(nextCapacity); + next.set(this.view(), 0); + this.buf = next; + this.start = 0; + this.end = currentLength; + } +} +function normalizePositiveOption(value, fallback) { + if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) { + return fallback; + } + return Math.floor(value); +} +function utf8SequenceLength(first) { + if (first < 128) + return 1; + if (first >= 194 && first <= 223) + return 2; + if (first >= 224 && first <= 239) + return 3; + if (first >= 240 && first <= 244) + return 4; + return 0; +} +function bytesEqual(left, right) { + if (left.length !== right.length) { + return false; + } + for (let index = 0;index < left.length; index += 1) { + if (left[index] !== right[index]) { + return false; + } + } + return true; +} +function isMouseSgrSequence(sequence) { + if (sequence.length < 7) { + return false; + } + if (sequence[0] !== ESC || sequence[1] !== 91 || sequence[2] !== 60) { + return false; + } + const final = sequence[sequence.length - 1]; + if (final !== 77 && final !== 109) { + return false; + } + let part = 0; + let hasDigit = false; + for (let index = 3;index < sequence.length - 1; index += 1) { + const byte = sequence[index]; + if (byte >= 48 && byte <= 57) { + hasDigit = true; + continue; + } + if (byte === 59 && hasDigit && part < 2) { + part += 1; + hasDigit = false; + continue; + } + return false; + } + return part === 2 && hasDigit; +} +function isAsciiDigit(byte) { + return byte >= 48 && byte <= 57; +} +function parsePositiveDecimalPrefix(sequence, start, endExclusive) { + if (start >= endExclusive) + return null; + let value = 0; + let sawDigit = false; + for (let index = start;index < endExclusive; index += 1) { + const byte = sequence[index]; + if (!isAsciiDigit(byte)) + return null; + sawDigit = true; + value = value * 10 + (byte - 48); + } + return sawDigit ? value : null; +} +function parseKittyFirstFieldCodepoint(sequence, start, endExclusive) { + if (start >= endExclusive) + return null; + let firstColon = -1; + for (let index = start;index < endExclusive; index += 1) { + if (sequence[index] === 58) { + firstColon = index; + break; + } + } + if (firstColon === -1) + return null; + const codepoint = parsePositiveDecimalPrefix(sequence, start, firstColon); + if (codepoint === null) + return null; + for (let index = firstColon + 1;index < endExclusive; index += 1) { + const byte = sequence[index]; + if (byte !== 58 && !isAsciiDigit(byte)) + return null; + } + return codepoint; +} +function canStillBeKittyU(state) { + return state.semicolons >= 1; +} +function canStillBeKittySpecial(state) { + return state.semicolons === 1 && state.segments > 1; +} +function canStillBeExplicitWidthCpr(state) { + return state.firstParamValue === 1 && state.semicolons === 1; +} +function canStillBeStartupCursorCpr(state) { + return state.semicolons === 1; +} +function canStillBeStartupCursorCprPrefix(state) { + return state.segments === 1 && state.semicolons <= 1; +} +function canStillBePixelResolution(state) { + return state.firstParamValue === 4 && state.semicolons === 2; +} +function canDeferParametricCsi(state, context) { + return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.startupCursorCprActive && canStillBeStartupCursorCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state); +} +function canCompleteDeferredParametricCsi(state, byte, context) { + if (context.kittyKeyboardEnabled) { + if (state.hasDigit && byte === 117) + return true; + if (state.hasDigit && state.semicolons === 1 && state.segments > 1 && (byte === 126 || byte >= 65 && byte <= 90)) { + return true; + } + } + if (context.explicitWidthCprActive && state.hasDigit && state.firstParamValue === 1 && state.semicolons === 1 && byte === 82) { + return true; + } + if (context.startupCursorCprActive && state.hasDigit && state.semicolons === 1 && byte === 82) { + return true; + } + if (context.pixelResolutionQueryActive && state.hasDigit && state.firstParamValue === 4 && state.semicolons === 2 && byte === 116) { + return true; + } + return false; +} +function classifyParametricCsiProtocol(state, finalByte) { + if (finalByte === 82 && state.semicolons === 1 && state.segments === 1 && state.hasDigit) { + return "cpr"; + } + return "csi"; +} +function canDeferPrivateReplyCsi(context) { + return context.privateCapabilityRepliesActive; +} +function canCompleteDeferredPrivateReplyCsi(state, byte, context) { + if (!context.privateCapabilityRepliesActive) + return false; + if (state.sawDollar) + return state.hasDigit && byte === 121; + if (byte === 99) + return state.hasDigit || state.semicolons > 0; + if (byte === 110) + return state.hasDigit; + return state.hasDigit && byte === 117; +} +function concatBytes(left, right) { + if (left.length === 0) { + return right; + } + if (right.length === 0) { + return left; + } + const combined = new Uint8Array(left.length + right.length); + combined.set(left, 0); + combined.set(right, left.length); + return combined; +} +function withEscPrefix(bytes) { + const prefixed = new Uint8Array(bytes.length + 1); + prefixed[0] = ESC; + prefixed.set(bytes, 1); + return prefixed; +} +function indexOfBytes(haystack, needle) { + if (needle.length === 0) { + return 0; + } + const limit = haystack.length - needle.length; + for (let offset = 0;offset <= limit; offset += 1) { + let matched = true; + for (let index = 0;index < needle.length; index += 1) { + if (haystack[offset + index] !== needle[index]) { + matched = false; + break; + } + } + if (matched) { + return offset; + } + } + return -1; +} +function decodeLatin1(bytes) { + return Buffer3.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("latin1"); +} +function decodeUtf8(bytes) { + return KEY_DECODER.decode(bytes); +} +function createPasteCollector() { + return { + tail: EMPTY_BYTES, + parts: [], + totalLength: 0 + }; +} +function joinPasteBytes(parts, totalLength) { + if (totalLength === 0) { + return EMPTY_BYTES; + } + if (parts.length === 1) { + return parts[0]; + } + const bytes = new Uint8Array(totalLength); + let offset = 0; + for (const part of parts) { + bytes.set(part, offset); + offset += part.length; + } + return bytes; +} + +class StdinParser { + pending = new ByteQueue(INITIAL_PENDING_CAPACITY); + events = []; + timeoutMs; + maxPendingBytes; + armTimeouts; + onTimeoutFlush; + useKittyKeyboard; + mouseParser = new MouseParser; + clock; + protocolContext; + timeoutId = null; + destroyed = false; + pendingSinceMs = null; + forceFlush = false; + justFlushedEsc = false; + state = { tag: "ground" }; + cursor = 0; + unitStart = 0; + paste = null; + constructor(options = {}) { + this.timeoutMs = normalizePositiveOption(options.timeoutMs, DEFAULT_TIMEOUT_MS); + this.maxPendingBytes = normalizePositiveOption(options.maxPendingBytes, DEFAULT_MAX_PENDING_BYTES); + this.armTimeouts = options.armTimeouts ?? true; + this.onTimeoutFlush = options.onTimeoutFlush ?? null; + this.useKittyKeyboard = options.useKittyKeyboard ?? true; + this.clock = options.clock ?? SYSTEM_CLOCK; + this.protocolContext = { + ...DEFAULT_PROTOCOL_CONTEXT, + kittyKeyboardEnabled: options.protocolContext?.kittyKeyboardEnabled ?? false, + privateCapabilityRepliesActive: options.protocolContext?.privateCapabilityRepliesActive ?? false, + pixelResolutionQueryActive: options.protocolContext?.pixelResolutionQueryActive ?? false, + explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false, + startupCursorCprActive: options.protocolContext?.startupCursorCprActive ?? false + }; + } + get bufferCapacity() { + return this.pending.capacity; + } + updateProtocolContext(patch) { + this.ensureAlive(); + this.protocolContext = { ...this.protocolContext, ...patch }; + this.reconcileDeferredStateWithProtocolContext(); + this.reconcileTimeoutState(); + } + getAbortableStartupCursorCprState() { + if (this.pending.length === 0) { + return null; + } + switch (this.state.tag) { + case "csi": { + const bytes = this.pending.view(); + const firstParamStart = this.unitStart + 2; + if (this.cursor < firstParamStart) { + return null; + } + let firstParamValue = null; + for (let index = firstParamStart;index < this.cursor; index += 1) { + const byte = bytes[index]; + if (!isAsciiDigit(byte)) { + return null; + } + firstParamValue = (firstParamValue ?? 0) * 10 + (byte - 48); + } + return { + tag: "csi_parametric_ignored", + semicolons: 0, + segments: 1, + hasDigit: this.cursor > firstParamStart, + firstParamValue + }; + } + case "csi_parametric": + case "csi_parametric_deferred": + if (!canStillBeStartupCursorCprPrefix(this.state) || this.protocolContext.explicitWidthCprActive && canStillBeExplicitWidthCpr(this.state)) { + return null; + } + return { + tag: "csi_parametric_ignored", + semicolons: this.state.semicolons, + segments: this.state.segments, + hasDigit: this.state.hasDigit, + firstParamValue: this.state.firstParamValue + }; + } + return null; + } + abortPendingStartupCursorCpr() { + this.ensureAlive(); + const nextState = this.getAbortableStartupCursorCprState(); + if (!nextState) { + return; + } + this.state = nextState; + if (this.pendingSinceMs === null) { + this.markPending(); + } + this.forceFlush = false; + this.reconcileTimeoutState(); + } + push(data) { + this.ensureAlive(); + if (data.length === 0) { + this.emitKeyOrResponse("unknown", ""); + return; + } + let remainder = data; + while (remainder.length > 0) { + if (this.paste) { + remainder = this.consumePasteBytes(remainder); + continue; + } + const immediatePasteStartIndex = this.state.tag === "ground" && this.pending.length === 0 ? indexOfBytes(remainder, BRACKETED_PASTE_START) : -1; + const appendEnd = immediatePasteStartIndex === -1 ? remainder.length : immediatePasteStartIndex + BRACKETED_PASTE_START.length; + this.pending.append(remainder.subarray(0, appendEnd)); + remainder = remainder.subarray(appendEnd); + this.scanPending(); + if (this.paste && this.pending.length > 0) { + remainder = this.consumePasteBytes(this.takePendingBytes()); + continue; + } + if (!this.paste && this.pending.length > this.maxPendingBytes) { + this.flushPendingOverflow(); + this.scanPending(); + if (this.paste && this.pending.length > 0) { + remainder = this.consumePasteBytes(this.takePendingBytes()); + } + } + } + this.reconcileTimeoutState(); + } + read() { + this.ensureAlive(); + if (this.events.length === 0 && this.forceFlush) { + this.scanPending(); + this.reconcileTimeoutState(); + } + return this.events.shift() ?? null; + } + drain(onEvent) { + this.ensureAlive(); + while (true) { + if (this.destroyed) { + return; + } + const event = this.read(); + if (!event) { + return; + } + onEvent(event); + } + } + flushTimeout(nowMsValue = this.clock.now()) { + this.ensureAlive(); + if (this.pendingSinceMs !== null && (nowMsValue < this.pendingSinceMs || nowMsValue - this.pendingSinceMs < this.timeoutMs)) { + return; + } + this.tryForceFlush(); + } + tryForceFlush() { + if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) { + return; + } + this.forceFlush = true; + } + reset() { + if (this.destroyed) { + return; + } + this.clearTimeout(); + this.resetState(); + } + resetMouseState() { + this.ensureAlive(); + this.mouseParser.reset(); + } + destroy() { + if (this.destroyed) { + return; + } + this.clearTimeout(); + this.destroyed = true; + this.resetState(); + } + ensureAlive() { + if (this.destroyed) { + throw new Error("StdinParser has been destroyed"); + } + } + scanPending() { + while (!this.paste) { + const bytes = this.pending.view(); + if (this.state.tag === "ground" && this.cursor >= bytes.length) { + this.pending.clear(); + this.cursor = 0; + this.unitStart = 0; + this.pendingSinceMs = null; + this.forceFlush = false; + return; + } + const byte = this.cursor < bytes.length ? bytes[this.cursor] : -1; + switch (this.state.tag) { + case "ground": { + this.unitStart = this.cursor; + if (this.justFlushedEsc) { + if (byte === 91) { + this.justFlushedEsc = false; + this.cursor += 1; + this.state = { tag: "esc_recovery" }; + continue; + } + this.justFlushedEsc = false; + } + if (byte === ESC) { + this.cursor += 1; + this.state = { tag: "esc" }; + continue; + } + if (byte < 128) { + this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.cursor, this.cursor + 1))); + this.consumePrefix(this.cursor + 1); + continue; + } + const expected = utf8SequenceLength(byte); + if (expected === 0) { + if (!this.forceFlush && this.cursor + 1 === bytes.length) { + this.markPending(); + return; + } + this.emitLegacyHighByte(byte); + this.consumePrefix(this.cursor + 1); + continue; + } + this.cursor += 1; + this.state = { tag: "utf8", expected, seen: 1 }; + continue; + } + case "utf8": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitLegacyHighByte(bytes[this.unitStart]); + this.state = { tag: "ground" }; + this.consumePrefix(this.unitStart + 1); + continue; + } + if ((byte & 192) !== 128) { + this.emitLegacyHighByte(bytes[this.unitStart]); + this.state = { tag: "ground" }; + this.consumePrefix(this.unitStart + 1); + continue; + } + const nextSeen = this.state.seen + 1; + this.cursor += 1; + if (nextSeen < this.state.expected) { + this.state = { tag: "utf8", expected: this.state.expected, seen: nextSeen }; + continue; + } + this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor))); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + case "esc": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + const flushedLoneEsc = this.cursor === this.unitStart + 1 && bytes[this.unitStart] === ESC; + this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor))); + this.justFlushedEsc = flushedLoneEsc; + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + switch (byte) { + case 91: + this.cursor += 1; + this.state = { tag: "csi" }; + continue; + case 79: + this.cursor += 1; + this.state = { tag: "ss3" }; + continue; + case 93: + this.cursor += 1; + this.state = { tag: "osc", sawEsc: false }; + continue; + case 80: + this.cursor += 1; + this.state = { tag: "dcs", sawEsc: false }; + continue; + case 95: + this.cursor += 1; + this.state = { tag: "apc", sawEsc: false }; + continue; + case ESC: + this.cursor += 1; + continue; + default: + this.cursor += 1; + this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor))); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + } + case "ss3": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + this.cursor += 1; + this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor))); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + case "esc_recovery": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor))); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte === 60) { + this.cursor += 1; + this.state = { tag: "esc_less_mouse" }; + continue; + } + if (byte === 77) { + this.cursor += 1; + this.state = { tag: "esc_less_x10_mouse" }; + continue; + } + this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.unitStart + 1))); + this.state = { tag: "ground" }; + this.consumePrefix(this.unitStart + 1); + continue; + } + case "csi": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte === 77 && this.cursor === this.unitStart + 2) { + const end = this.cursor + 4; + if (bytes.length < end) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, bytes.length)); + this.state = { tag: "ground" }; + this.consumePrefix(bytes.length); + continue; + } + this.emitMouse(bytes.subarray(this.unitStart, end), "x10"); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + if (byte === 36) { + const candidateEnd = this.cursor + 1; + const candidate = decodeUtf8(bytes.subarray(this.unitStart, candidateEnd)); + if (RXVT_DOLLAR_CSI_RE.test(candidate)) { + this.emitKeyOrResponse("csi", candidate); + this.state = { tag: "ground" }; + this.consumePrefix(candidateEnd); + continue; + } + if (!this.forceFlush && candidateEnd >= bytes.length) { + this.markPending(); + return; + } + } + if (byte === 60 && this.cursor === this.unitStart + 2) { + this.cursor += 1; + this.state = { tag: "csi_sgr_mouse", part: 0, hasDigit: false }; + continue; + } + if (byte === 91 && this.cursor === this.unitStart + 2) { + this.cursor += 1; + continue; + } + if (byte === 63 && this.cursor === this.unitStart + 2) { + this.cursor += 1; + this.state = { tag: "csi_private_reply", semicolons: 0, hasDigit: false, sawDollar: false }; + continue; + } + if (byte === 59) { + const firstParamStart = this.unitStart + 2; + const firstParamEnd = this.cursor; + let firstParamValue = parsePositiveDecimalPrefix(bytes, firstParamStart, firstParamEnd); + if (firstParamValue === null && this.protocolContext.kittyKeyboardEnabled) { + firstParamValue = parseKittyFirstFieldCodepoint(bytes, firstParamStart, firstParamEnd); + } + if (firstParamValue !== null) { + this.cursor += 1; + this.state = { + tag: "csi_parametric", + semicolons: 1, + segments: 1, + hasDigit: false, + firstParamValue + }; + continue; + } + } + if (byte >= 64 && byte <= 126) { + const end = this.cursor + 1; + const rawBytes = bytes.subarray(this.unitStart, end); + if (bytesEqual(rawBytes, BRACKETED_PASTE_START)) { + this.state = { tag: "ground" }; + this.consumePrefix(end); + this.paste = createPasteCollector(); + continue; + } + if (isMouseSgrSequence(rawBytes)) { + this.emitMouse(rawBytes, "sgr"); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.emitKeyOrResponse("csi", decodeUtf8(rawBytes)); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.cursor += 1; + continue; + } + case "csi_sgr_mouse": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.state = { tag: "csi_sgr_mouse_deferred", part: this.state.part, hasDigit: this.state.hasDigit }; + this.pendingSinceMs = null; + this.forceFlush = false; + return; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (isAsciiDigit(byte)) { + this.cursor += 1; + this.state = { tag: "csi_sgr_mouse", part: this.state.part, hasDigit: true }; + continue; + } + if (byte === 59 && this.state.hasDigit && this.state.part < 2) { + this.cursor += 1; + this.state = { tag: "csi_sgr_mouse", part: this.state.part + 1, hasDigit: false }; + continue; + } + if (byte >= 64 && byte <= 126) { + const end = this.cursor + 1; + const rawBytes = bytes.subarray(this.unitStart, end); + if (isMouseSgrSequence(rawBytes)) { + this.emitMouse(rawBytes, "sgr"); + } else { + this.emitKeyOrResponse("csi", decodeUtf8(rawBytes)); + } + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.state = { tag: "csi" }; + continue; + } + case "csi_sgr_mouse_deferred": { + if (this.cursor >= bytes.length) { + this.pendingSinceMs = null; + this.forceFlush = false; + return; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (isAsciiDigit(byte) || byte === 59 || byte === 77 || byte === 109) { + this.state = { tag: "csi_sgr_mouse", part: this.state.part, hasDigit: this.state.hasDigit }; + continue; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + case "csi_parametric": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + if (canDeferParametricCsi(this.state, this.protocolContext)) { + this.state = { + tag: "csi_parametric_deferred", + semicolons: this.state.semicolons, + segments: this.state.segments, + hasDigit: this.state.hasDigit, + firstParamValue: this.state.firstParamValue + }; + this.pendingSinceMs = null; + this.forceFlush = false; + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (isAsciiDigit(byte)) { + this.cursor += 1; + this.state = { + tag: "csi_parametric", + semicolons: this.state.semicolons, + segments: this.state.segments, + hasDigit: true, + firstParamValue: this.state.firstParamValue + }; + continue; + } + if (byte === 58 && this.state.hasDigit && this.state.segments < 3) { + this.cursor += 1; + this.state = { + tag: "csi_parametric", + semicolons: this.state.semicolons, + segments: this.state.segments + 1, + hasDigit: false, + firstParamValue: this.state.firstParamValue + }; + continue; + } + if (byte === 59 && this.state.semicolons < 2) { + this.cursor += 1; + this.state = { + tag: "csi_parametric", + semicolons: this.state.semicolons + 1, + segments: 1, + hasDigit: false, + firstParamValue: this.state.firstParamValue + }; + continue; + } + if (byte >= 64 && byte <= 126) { + const end = this.cursor + 1; + const protocol = classifyParametricCsiProtocol(this.state, byte); + this.emitKeyOrResponse(protocol, decodeUtf8(bytes.subarray(this.unitStart, end))); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.state = { tag: "csi" }; + continue; + } + case "csi_parametric_deferred": { + if (this.cursor >= bytes.length) { + this.pendingSinceMs = null; + this.forceFlush = false; + return; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (isAsciiDigit(byte) || byte === 58 || byte === 59) { + this.state = { + tag: "csi_parametric", + semicolons: this.state.semicolons, + segments: this.state.segments, + hasDigit: this.state.hasDigit, + firstParamValue: this.state.firstParamValue + }; + continue; + } + if (canCompleteDeferredParametricCsi(this.state, byte, this.protocolContext)) { + this.state = { + tag: "csi_parametric", + semicolons: this.state.semicolons, + segments: this.state.segments, + hasDigit: this.state.hasDigit, + firstParamValue: this.state.firstParamValue + }; + continue; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + case "csi_parametric_ignored": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte === ESC) { + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (isAsciiDigit(byte)) { + this.cursor += 1; + this.state = { + tag: "csi_parametric_ignored", + semicolons: this.state.semicolons, + segments: this.state.segments, + hasDigit: true, + firstParamValue: this.state.semicolons === 0 ? (this.state.firstParamValue ?? 0) * 10 + (byte - 48) : this.state.firstParamValue + }; + continue; + } + if (byte === 59 && this.state.semicolons === 0 && this.state.hasDigit) { + if (this.protocolContext.explicitWidthCprActive && this.state.firstParamValue === 1) { + this.state = { tag: "csi" }; + continue; + } + this.cursor += 1; + this.state = { + tag: "csi_parametric_ignored", + semicolons: 1, + segments: 1, + hasDigit: false, + firstParamValue: this.state.firstParamValue + }; + continue; + } + if (byte === 82 && this.state.semicolons === 1 && this.state.hasDigit) { + const end = this.cursor + 1; + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + if (this.state.semicolons === 0) { + this.state = { tag: "csi" }; + continue; + } + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + case "csi_private_reply": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + if (canDeferPrivateReplyCsi(this.protocolContext)) { + this.state = { + tag: "csi_private_reply_deferred", + semicolons: this.state.semicolons, + hasDigit: this.state.hasDigit, + sawDollar: this.state.sawDollar + }; + this.pendingSinceMs = null; + this.forceFlush = false; + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (isAsciiDigit(byte)) { + this.cursor += 1; + this.state = { + tag: "csi_private_reply", + semicolons: this.state.semicolons, + hasDigit: true, + sawDollar: this.state.sawDollar + }; + continue; + } + if (byte === 59) { + this.cursor += 1; + this.state = { + tag: "csi_private_reply", + semicolons: this.state.semicolons + 1, + hasDigit: false, + sawDollar: false + }; + continue; + } + if (byte === 36 && this.state.hasDigit && !this.state.sawDollar) { + this.cursor += 1; + this.state = { + tag: "csi_private_reply", + semicolons: this.state.semicolons, + hasDigit: true, + sawDollar: true + }; + continue; + } + if (byte >= 64 && byte <= 126) { + const end = this.cursor + 1; + this.emitOpaqueResponse("csi", bytes.subarray(this.unitStart, end)); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.state = { tag: "csi" }; + continue; + } + case "csi_private_reply_deferred": { + if (this.cursor >= bytes.length) { + this.pendingSinceMs = null; + this.forceFlush = false; + return; + } + if (byte === ESC) { + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (isAsciiDigit(byte) || byte === 59 || byte === 36) { + this.state = { + tag: "csi_private_reply", + semicolons: this.state.semicolons, + hasDigit: this.state.hasDigit, + sawDollar: this.state.sawDollar + }; + continue; + } + if (canCompleteDeferredPrivateReplyCsi(this.state, byte, this.protocolContext)) { + this.state = { + tag: "csi_private_reply", + semicolons: this.state.semicolons, + hasDigit: this.state.hasDigit, + sawDollar: this.state.sawDollar + }; + continue; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + case "osc": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (this.state.sawEsc) { + if (byte === 92) { + const end = this.cursor + 1; + this.emitOpaqueResponse("osc", bytes.subarray(this.unitStart, end)); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.state = { tag: "osc", sawEsc: false }; + continue; + } + if (byte === BEL) { + const end = this.cursor + 1; + this.emitOpaqueResponse("osc", bytes.subarray(this.unitStart, end)); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + if (byte === ESC) { + this.cursor += 1; + this.state = { tag: "osc", sawEsc: true }; + continue; + } + this.cursor += 1; + continue; + } + case "dcs": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (this.state.sawEsc) { + if (byte === 92) { + const end = this.cursor + 1; + this.emitOpaqueResponse("dcs", bytes.subarray(this.unitStart, end)); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.state = { tag: "dcs", sawEsc: false }; + continue; + } + if (byte === ESC) { + this.cursor += 1; + this.state = { tag: "dcs", sawEsc: true }; + continue; + } + this.cursor += 1; + continue; + } + case "apc": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (this.state.sawEsc) { + if (byte === 92) { + const end = this.cursor + 1; + this.emitOpaqueResponse("apc", bytes.subarray(this.unitStart, end)); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.state = { tag: "apc", sawEsc: false }; + continue; + } + if (byte === ESC) { + this.cursor += 1; + this.state = { tag: "apc", sawEsc: true }; + continue; + } + this.cursor += 1; + continue; + } + case "esc_less_mouse": { + if (this.cursor >= bytes.length) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + if (byte >= 48 && byte <= 57 || byte === 59) { + this.cursor += 1; + continue; + } + if (byte === 77 || byte === 109) { + const end = this.cursor + 1; + const rawBytes = bytes.subarray(this.unitStart, end); + const prefixed = withEscPrefix(rawBytes); + if (isMouseSgrSequence(prefixed)) { + this.emitMouse(prefixed, "sgr"); + } else { + this.emitOpaqueResponse("unknown", rawBytes); + } + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + continue; + } + case "esc_less_x10_mouse": { + const end = this.unitStart + 5; + if (bytes.length < end) { + if (!this.forceFlush) { + this.markPending(); + return; + } + this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, bytes.length)); + this.state = { tag: "ground" }; + this.consumePrefix(bytes.length); + continue; + } + const rawBytes = bytes.subarray(this.unitStart, end); + this.emitMouse(withEscPrefix(rawBytes), "x10"); + this.state = { tag: "ground" }; + this.consumePrefix(end); + continue; + } + } + } + } + emitKeyOrResponse(protocol, raw) { + const parsed = parseKeypress(raw, { useKittyKeyboard: this.useKittyKeyboard }); + if (parsed) { + this.events.push({ + type: "key", + raw: parsed.raw, + key: parsed + }); + return; + } + this.events.push({ + type: "response", + protocol, + sequence: raw + }); + } + emitMouse(rawBytes, encoding) { + const event = this.mouseParser.parseMouseEvent(rawBytes); + if (!event) { + this.emitOpaqueResponse("unknown", rawBytes); + return; + } + this.events.push({ + type: "mouse", + raw: decodeLatin1(rawBytes), + encoding, + event + }); + } + emitLegacyHighByte(byte) { + const parsed = parseKeypress(Buffer3.from([byte]), { useKittyKeyboard: this.useKittyKeyboard }); + if (parsed) { + this.events.push({ + type: "key", + raw: parsed.raw, + key: parsed + }); + return; + } + this.events.push({ + type: "response", + protocol: "unknown", + sequence: String.fromCharCode(byte) + }); + } + emitOpaqueResponse(protocol, rawBytes) { + this.events.push({ + type: "response", + protocol, + sequence: decodeLatin1(rawBytes) + }); + } + consumePrefix(endExclusive) { + this.pending.consume(endExclusive); + this.cursor = 0; + this.unitStart = 0; + this.pendingSinceMs = null; + this.forceFlush = false; + } + takePendingBytes() { + const buffered = this.pending.take(); + this.cursor = 0; + this.unitStart = 0; + this.pendingSinceMs = null; + this.forceFlush = false; + return buffered; + } + flushPendingOverflow() { + if (this.pending.length === 0) { + return; + } + this.emitOpaqueResponse("unknown", this.pending.view()); + this.pending.clear(); + this.cursor = 0; + this.unitStart = 0; + this.pendingSinceMs = null; + this.forceFlush = false; + this.state = { tag: "ground" }; + } + markPending() { + this.pendingSinceMs = this.clock.now(); + } + consumePasteBytes(chunk) { + const paste = this.paste; + const combined = concatBytes(paste.tail, chunk); + const endIndex = indexOfBytes(combined, BRACKETED_PASTE_END); + if (endIndex !== -1) { + this.pushPasteBytes(combined.subarray(0, endIndex)); + this.events.push({ + type: "paste", + bytes: joinPasteBytes(paste.parts, paste.totalLength) + }); + this.paste = null; + return combined.subarray(endIndex + BRACKETED_PASTE_END.length); + } + const keep = Math.min(BRACKETED_PASTE_END.length - 1, combined.length); + const stableLength = combined.length - keep; + if (stableLength > 0) { + this.pushPasteBytes(combined.subarray(0, stableLength)); + } + paste.tail = Uint8Array.from(combined.subarray(stableLength)); + return EMPTY_BYTES; + } + pushPasteBytes(bytes) { + if (bytes.length === 0) { + return; + } + this.paste.parts.push(Uint8Array.from(bytes)); + this.paste.totalLength += bytes.length; + } + reconcileDeferredStateWithProtocolContext() { + switch (this.state.tag) { + case "csi_parametric_deferred": + if (!canDeferParametricCsi(this.state, this.protocolContext)) { + this.emitOpaqueResponse("unknown", this.pending.view().subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + } + return; + case "csi_private_reply_deferred": + if (!canDeferPrivateReplyCsi(this.protocolContext)) { + this.emitOpaqueResponse("unknown", this.pending.view().subarray(this.unitStart, this.cursor)); + this.state = { tag: "ground" }; + this.consumePrefix(this.cursor); + } + return; + } + } + reconcileTimeoutState() { + if (!this.armTimeouts) { + return; + } + if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) { + this.clearTimeout(); + return; + } + this.clearTimeout(); + this.timeoutId = this.clock.setTimeout(() => { + this.timeoutId = null; + if (this.destroyed) { + return; + } + try { + this.tryForceFlush(); + this.onTimeoutFlush?.(); + } catch (error) { + console.error("stdin parser timeout flush failed", error); + } + }, this.timeoutMs); + } + clearTimeout() { + if (!this.timeoutId) { + return; + } + this.clock.clearTimeout(this.timeoutId); + this.timeoutId = null; + } + resetState() { + this.pending.reset(INITIAL_PENDING_CAPACITY); + this.events.length = 0; + this.pendingSinceMs = null; + this.forceFlush = false; + this.justFlushedEsc = false; + this.state = { tag: "ground" }; + this.cursor = 0; + this.unitStart = 0; + this.paste = null; + this.mouseParser.reset(); + } +} +// src/lib/tree-sitter-styled-text.ts +registerEnvVar({ name: "OTUI_TS_STYLE_WARN", default: false, description: "Enable warnings for missing syntax styles" }); +function getSpecificity(group) { + return group.split(".").length; +} +function shouldSuppressInInjection(group, meta) { + if (meta?.isInjection) { + return false; + } + return group === "markup.raw.block"; +} +function treeSitterToTextChunks(content, highlights, syntaxStyle, options) { + const chunks = []; + const defaultStyle = syntaxStyle.getStyle("default"); + const concealEnabled = options?.enabled ?? true; + const baseStyle = options?.baseHighlight ? syntaxStyle.getStyle(options.baseHighlight) : undefined; + const injectionContainerRanges = []; + const boundaries = []; + for (let i = 0;i < highlights.length; i++) { + const [start, end, , meta] = highlights[i]; + if (start === end) + continue; + if (meta?.containsInjection) { + injectionContainerRanges.push({ start, end }); + } + boundaries.push({ offset: start, type: "start", highlightIndex: i }); + boundaries.push({ offset: end, type: "end", highlightIndex: i }); + } + boundaries.sort((a, b) => { + if (a.offset !== b.offset) + return a.offset - b.offset; + if (a.type === "end" && b.type === "start") + return -1; + if (a.type === "start" && b.type === "end") + return 1; + return 0; + }); + const activeHighlights = new Set; + let currentOffset = 0; + for (let i = 0;i < boundaries.length; i++) { + const boundary = boundaries[i]; + if (currentOffset < boundary.offset && activeHighlights.size > 0) { + const segmentText = content.slice(currentOffset, boundary.offset); + const activeGroups = []; + for (const idx of activeHighlights) { + const [, , group, meta] = highlights[idx]; + activeGroups.push({ group, meta, index: idx }); + } + const concealHighlight = concealEnabled ? activeGroups.find((h) => h.meta?.conceal !== undefined || h.group === "conceal" || h.group.startsWith("conceal.")) : undefined; + if (concealHighlight) { + let replacementText = ""; + if (concealHighlight.meta?.conceal !== undefined) { + replacementText = concealHighlight.meta.conceal; + } else if (concealHighlight.group === "conceal.with.space") { + replacementText = " "; + } + if (replacementText) { + chunks.push({ + __isChunk: true, + text: replacementText, + fg: defaultStyle?.fg, + bg: defaultStyle?.bg, + attributes: defaultStyle ? createTextAttributes({ + bold: defaultStyle.bold, + italic: defaultStyle.italic, + underline: defaultStyle.underline, + dim: defaultStyle.dim + }) : 0 + }); + } + } else { + const insideInjectionContainer = injectionContainerRanges.some((range) => currentOffset >= range.start && currentOffset < range.end); + const validGroups = activeGroups.filter((h) => { + if (insideInjectionContainer && shouldSuppressInInjection(h.group, h.meta)) { + return false; + } + return true; + }); + const sortedGroups = validGroups.sort((a, b) => { + const aSpec = getSpecificity(a.group); + const bSpec = getSpecificity(b.group); + if (aSpec !== bSpec) + return aSpec - bSpec; + return a.index - b.index; + }); + const mergedStyle = baseStyle ? { ...baseStyle } : {}; + for (const { group } of sortedGroups) { + let styleForGroup = syntaxStyle.getStyle(group); + if (!styleForGroup && group.includes(".")) { + const baseName = group.split(".")[0]; + styleForGroup = syntaxStyle.getStyle(baseName); + } + if (styleForGroup) { + if (styleForGroup.fg !== undefined) + mergedStyle.fg = styleForGroup.fg; + if (styleForGroup.bg !== undefined) + mergedStyle.bg = styleForGroup.bg; + if (styleForGroup.bold !== undefined) + mergedStyle.bold = styleForGroup.bold; + if (styleForGroup.italic !== undefined) + mergedStyle.italic = styleForGroup.italic; + if (styleForGroup.underline !== undefined) + mergedStyle.underline = styleForGroup.underline; + if (styleForGroup.dim !== undefined) + mergedStyle.dim = styleForGroup.dim; + } else { + if (group.includes(".")) { + const baseName = group.split(".")[0]; + if (env.OTUI_TS_STYLE_WARN) { + console.warn(`Syntax style not found for group "${group}" or base scope "${baseName}", using default style`); + } + } else { + if (env.OTUI_TS_STYLE_WARN) { + console.warn(`Syntax style not found for group "${group}", using default style`); + } + } + } + } + const finalStyle = Object.keys(mergedStyle).length > 0 ? mergedStyle : defaultStyle; + chunks.push({ + __isChunk: true, + text: segmentText, + fg: finalStyle?.fg, + bg: finalStyle?.bg, + attributes: finalStyle ? createTextAttributes({ + bold: finalStyle.bold, + italic: finalStyle.italic, + underline: finalStyle.underline, + dim: finalStyle.dim + }) : 0 + }); + } + } else if (currentOffset < boundary.offset) { + const text = content.slice(currentOffset, boundary.offset); + const style = baseStyle ?? defaultStyle; + chunks.push({ + __isChunk: true, + text, + fg: style?.fg, + bg: style?.bg, + attributes: style ? createTextAttributes({ + bold: style.bold, + italic: style.italic, + underline: style.underline, + dim: style.dim + }) : 0 + }); + } + if (boundary.type === "start") { + activeHighlights.add(boundary.highlightIndex); + } else { + activeHighlights.delete(boundary.highlightIndex); + if (concealEnabled) { + const [, , group, meta] = highlights[boundary.highlightIndex]; + if (meta?.concealLines !== undefined) { + if (boundary.offset < content.length && content[boundary.offset] === ` +`) { + currentOffset = boundary.offset + 1; + continue; + } + } + if (meta?.conceal !== undefined) { + if (meta.conceal === " ") { + if (boundary.offset < content.length && content[boundary.offset] === " ") { + currentOffset = boundary.offset + 1; + continue; + } + } else if (meta.conceal === "" && group === "conceal" && !meta.isInjection) { + if (boundary.offset < content.length && content[boundary.offset] === " ") { + currentOffset = boundary.offset + 1; + continue; + } + } + } + } + } + currentOffset = boundary.offset; + } + if (currentOffset < content.length) { + const text = content.slice(currentOffset); + const style = baseStyle ?? defaultStyle; + chunks.push({ + __isChunk: true, + text, + fg: style?.fg, + bg: style?.bg, + attributes: style ? createTextAttributes({ + bold: style.bold, + italic: style.italic, + underline: style.underline, + dim: style.dim + }) : 0 + }); + } + return chunks; +} +async function treeSitterToStyledText(content, filetype, syntaxStyle, client, options) { + const result = await client.highlightOnce(content, filetype); + if (result.highlights && result.highlights.length > 0 || options?.baseHighlight) { + const chunks = treeSitterToTextChunks(content, result.highlights ?? [], syntaxStyle, { + enabled: options?.conceal?.enabled ?? true, + baseHighlight: options?.baseHighlight + }); + return new StyledText(chunks); + } else { + const defaultStyle = syntaxStyle.mergeStyles("default"); + const chunks = [ + { + __isChunk: true, + text: content, + fg: defaultStyle.fg, + bg: defaultStyle.bg, + attributes: defaultStyle.attributes + } + ]; + return new StyledText(chunks); + } +} +// src/lib/tree-sitter/client.ts +import { EventEmitter as EventEmitter2 } from "events"; + +// src/lib/debounce.ts +var TIMERS_MAP = new Map; + +class DebounceController { + scopeId; + constructor(scopeId) { + this.scopeId = scopeId; + if (!TIMERS_MAP.has(this.scopeId)) { + TIMERS_MAP.set(this.scopeId, new Map); + } + } + debounce(id, ms, fn) { + const scopeMap = TIMERS_MAP.get(this.scopeId); + return new Promise((resolve2, reject) => { + if (scopeMap.has(id)) { + clearTimeout(scopeMap.get(id)); + } + const timerId = setTimeout(() => { + try { + resolve2(fn()); + } catch (error) { + reject(error); + } + scopeMap.delete(id); + }, ms); + scopeMap.set(id, timerId); + }); + } + clearDebounce(id) { + const scopeMap = TIMERS_MAP.get(this.scopeId); + if (scopeMap && scopeMap.has(id)) { + clearTimeout(scopeMap.get(id)); + scopeMap.delete(id); + } + } + clear() { + const scopeMap = TIMERS_MAP.get(this.scopeId); + if (scopeMap) { + scopeMap.forEach((timerId) => clearTimeout(timerId)); + scopeMap.clear(); + } + } +} +function createDebounce(scopeId) { + return new DebounceController(scopeId); +} +function clearDebounceScope(scopeId) { + const scopeMap = TIMERS_MAP.get(scopeId); + if (scopeMap) { + scopeMap.forEach((timerId) => clearTimeout(timerId)); + scopeMap.clear(); + } +} + +// src/lib/queue.ts +class ProcessQueue { + processor; + queue = []; + processing = false; + autoProcess = true; + constructor(processor, autoProcess = true) { + this.processor = processor; + this.autoProcess = autoProcess; + } + enqueue(item) { + this.queue.push(item); + if (!this.processing && this.autoProcess) { + this.processQueue(); + } + } + processQueue() { + if (this.queue.length === 0) { + return; + } + this.processing = true; + queueMicrotask(async () => { + if (this.queue.length === 0) { + this.processing = false; + return; + } + const item = this.queue.shift(); + try { + await this.processor(item); + } catch (error) { + console.error("Error processing queue item:", error); + } + if (this.queue.length > 0) { + this.processQueue(); + } else { + this.processing = false; + } + }); + } + clear() { + this.queue = []; + } + isProcessing() { + return this.processing; + } + size() { + return this.queue.length; + } +} + +// src/lib/tree-sitter/default-parsers.ts +var _cachedParsers; +function getParsers() { + if (!_cachedParsers) { + _cachedParsers = loadParsers(); + } + return _cachedParsers; +} +async function loadParsers() { + const javascript_highlights = await resolveBundledFilePath(() => import("./assets/javascript/highlights.scm", { with: { type: "file" } }), "./assets/javascript/highlights.scm", import.meta.url); + const javascript_language = await resolveBundledFilePath(() => import("./assets/javascript/tree-sitter-javascript.wasm", { with: { type: "file" } }), "./assets/javascript/tree-sitter-javascript.wasm", import.meta.url); + const typescript_highlights = await resolveBundledFilePath(() => import("./assets/typescript/highlights.scm", { with: { type: "file" } }), "./assets/typescript/highlights.scm", import.meta.url); + const typescript_language = await resolveBundledFilePath(() => import("./assets/typescript/tree-sitter-typescript.wasm", { with: { type: "file" } }), "./assets/typescript/tree-sitter-typescript.wasm", import.meta.url); + const markdown_highlights = await resolveBundledFilePath(() => import("./assets/markdown/highlights.scm", { with: { type: "file" } }), "./assets/markdown/highlights.scm", import.meta.url); + const markdown_language = await resolveBundledFilePath(() => import("./assets/markdown/tree-sitter-markdown.wasm", { with: { type: "file" } }), "./assets/markdown/tree-sitter-markdown.wasm", import.meta.url); + const markdown_injections = await resolveBundledFilePath(() => import("./assets/markdown/injections.scm", { with: { type: "file" } }), "./assets/markdown/injections.scm", import.meta.url); + const markdown_inline_highlights = await resolveBundledFilePath(() => import("./assets/markdown_inline/highlights.scm", { with: { type: "file" } }), "./assets/markdown_inline/highlights.scm", import.meta.url); + const markdown_inline_language = await resolveBundledFilePath(() => import("./assets/markdown_inline/tree-sitter-markdown_inline.wasm", { with: { type: "file" } }), "./assets/markdown_inline/tree-sitter-markdown_inline.wasm", import.meta.url); + const zig_highlights = await resolveBundledFilePath(() => import("./assets/zig/highlights.scm", { with: { type: "file" } }), "./assets/zig/highlights.scm", import.meta.url); + const zig_language = await resolveBundledFilePath(() => import("./assets/zig/tree-sitter-zig.wasm", { with: { type: "file" } }), "./assets/zig/tree-sitter-zig.wasm", import.meta.url); + return [ + { + filetype: "javascript", + aliases: ["javascriptreact"], + queries: { + highlights: [javascript_highlights] + }, + wasm: javascript_language + }, + { + filetype: "typescript", + aliases: ["typescriptreact"], + queries: { + highlights: [typescript_highlights] + }, + wasm: typescript_language + }, + { + filetype: "markdown", + queries: { + highlights: [markdown_highlights], + injections: [markdown_injections] + }, + wasm: markdown_language, + injectionMapping: { + nodeTypes: { + inline: "markdown_inline", + pipe_table_cell: "markdown_inline" + }, + infoStringMap: { + javascript: "javascript", + js: "javascript", + jsx: "javascriptreact", + javascriptreact: "javascriptreact", + typescript: "typescript", + ts: "typescript", + tsx: "typescriptreact", + typescriptreact: "typescriptreact", + markdown: "markdown", + md: "markdown" + } + } + }, + { + filetype: "markdown_inline", + queries: { + highlights: [markdown_inline_highlights] + }, + wasm: markdown_inline_language + }, + { + filetype: "zig", + queries: { + highlights: [zig_highlights] + }, + wasm: zig_language + } + ]; +} + +// src/lib/tree-sitter/client.ts +import { resolve as resolve2, isAbsolute as isAbsolute2, parse } from "path"; +import { existsSync as existsSync2 } from "fs"; + +// src/lib/bunfs.ts +import { basename, join } from "node:path"; +function isBunfsPath(path) { + return path.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path); +} +function getBunfsRootPath() { + return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root"; +} +function normalizeBunfsPath(fileName) { + return join(getBunfsRootPath(), basename(fileName)); +} + +// src/platform/worker.ts +var WORKER_UNAVAILABLE = "OpenTUI tree-sitter workers are not available for this runtime yet."; +var globalWithWorker = globalThis; +var nodeWorkerThreads = getBuiltinModule("node:worker_threads"); +var runtimeBridge = loadWorkerRuntime(nodeWorkerThreads); + +class UnsupportedWorker { + onmessage = null; + onerror = null; + constructor() { + throw new Error(WORKER_UNAVAILABLE); + } + postMessage() { + throw new Error(WORKER_UNAVAILABLE); + } + terminate() { + throw new Error(WORKER_UNAVAILABLE); + } + addEventListener() { + throw new Error(WORKER_UNAVAILABLE); + } + removeEventListener() { + throw new Error(WORKER_UNAVAILABLE); + } +} +var Worker = loadWorkerConstructor(); +function getBuiltinModule(id) { + if (typeof process === "undefined") { + return; + } + const loader = process.getBuiltinModule; + if (typeof loader !== "function") { + return; + } + try { + return loader(id); + } catch { + return; + } +} +function loadWorkerConstructor() { + if (typeof globalWithWorker.Worker === "function") { + return globalWithWorker.Worker; + } + if (nodeWorkerThreads) { + return createNodeWorkerConstructor(nodeWorkerThreads); + } + return UnsupportedWorker; +} +function createNodeWorkerConstructor(node) { + return class NodeWorkerShim { + onmessage = null; + onerror = null; + errorListeners = new Set; + messageListeners = new Set; + worker; + terminationPromise; + constructor(specifier, options = {}) { + const resolvedSpecifier = resolveWorkerImportSpecifier(specifier); + this.worker = new node.Worker(createWorkerBootstrapSource(resolvedSpecifier), { + eval: true, + type: "module", + name: options.name + }); + this.worker.on("message", this.handleMessage); + this.worker.on("error", this.handleError); + } + postMessage(value) { + this.worker.postMessage(value); + } + terminate() { + if (this.terminationPromise) { + return this.terminationPromise; + } + this.worker.off("message", this.handleMessage); + this.worker.off("error", this.handleError); + const termination = this.worker.terminate().catch((error) => { + this.terminationPromise = undefined; + this.worker.on("message", this.handleMessage); + this.worker.on("error", this.handleError); + throw error; + }); + this.terminationPromise = termination; + return termination; + } + addEventListener(type, listener) { + if (type === "message") { + this.messageListeners.add(listener); + return; + } + this.errorListeners.add(listener); + } + removeEventListener(type, listener) { + if (type === "message") { + this.messageListeners.delete(listener); + return; + } + this.errorListeners.delete(listener); + } + handleMessage = (data) => { + const event = { data }; + this.onmessage?.(event); + for (const listener of this.messageListeners) { + listener(event); + } + }; + handleError = (error) => { + const event = { + error, + message: error.message + }; + this.onerror?.(event); + for (const listener of this.errorListeners) { + listener(event); + } + }; + }; +} +function createWorkerBootstrapSource(specifier) { + return ` + import { parentPort } from "node:worker_threads" + + const pendingMessages = [] + let messageHandler = null + + globalThis.self ??= globalThis + globalThis.postMessage ??= (value) => parentPort?.postMessage(value) + globalThis.__opentuiWorkerMessageBridge = true + Object.defineProperty(globalThis, "onmessage", { + configurable: true, + get: () => messageHandler, + set: (handler) => { + messageHandler = typeof handler === "function" ? handler : null + if (!messageHandler) return + + const messages = pendingMessages.splice(0) + for (const data of messages) { + messageHandler({ data }) + } + }, + }) + parentPort?.on("message", (data) => { + if (messageHandler) { + messageHandler({ data }) + } else { + pendingMessages.push(data) + } + }) + + await import(${JSON.stringify(specifier)}) + `; +} +function resolveWorkerImportSpecifier(specifier) { + if (specifier instanceof URL) { + return specifier.href; + } + if (isRuntimeSpecifier(specifier)) { + return specifier; + } + const nodePath = getBuiltinModule("node:path"); + const nodeUrl = getBuiltinModule("node:url"); + if (!nodePath || !nodeUrl) { + throw new Error(WORKER_UNAVAILABLE); + } + const absolutePath = nodePath.isAbsolute(specifier) ? specifier : nodePath.resolve(specifier); + return nodeUrl.pathToFileURL(absolutePath).href; +} +function isRuntimeSpecifier(specifier) { + return specifier.startsWith("file:") || specifier.startsWith("data:") || specifier.startsWith("node:") || specifier.startsWith("http:") || specifier.startsWith("https:"); +} +function loadWorkerRuntime(node) { + if (node?.parentPort && node.isMainThread === false) { + if (globalWithWorker.__opentuiWorkerMessageBridge) { + return createGlobalWorkerRuntimeBridge(); + } + return { + postMessage(value) { + node.parentPort?.postMessage(value); + }, + setMessageHandler(handler) { + const listener = (data) => { + handler({ data }); + }; + node.parentPort?.on("message", listener); + return () => { + node.parentPort?.off("message", listener); + }; + } + }; + } + if (!isGlobalWorkerRuntime()) { + return; + } + return createGlobalWorkerRuntimeBridge(); +} +function createGlobalWorkerRuntimeBridge() { + let currentRegistration; + return { + postMessage(value) { + globalWithWorker.postMessage?.(value); + }, + setMessageHandler(handler) { + const previousHandler = getGlobalWorkerMessageHandler(); + if (currentRegistration && previousHandler !== currentRegistration.listener) { + currentRegistration = undefined; + } + const listener = (event) => { + const normalizedEvent = normalizeWorkerMessageEvent(event); + handler(normalizedEvent); + }; + const registration = { + active: true, + fallbackHandler: currentRegistration ? currentRegistration.fallbackHandler : previousHandler, + listener, + previous: currentRegistration + }; + currentRegistration = registration; + setGlobalWorkerMessageHandler(listener); + return () => { + registration.active = false; + if (currentRegistration !== registration || getGlobalWorkerMessageHandler() !== listener) { + return; + } + let previous = registration.previous; + while (previous && !previous.active) { + previous = previous.previous; + } + currentRegistration = previous; + setGlobalWorkerMessageHandler(previous?.listener ?? registration.fallbackHandler); + }; + } + }; +} +function isGlobalWorkerRuntime() { + if (typeof globalWithWorker.postMessage !== "function") { + return false; + } + return typeof document === "undefined" && typeof globalWithWorker.close === "function" && "onmessage" in globalThis; +} +function normalizeWorkerMessageEvent(event) { + if (event && typeof event === "object" && "data" in event) { + return event; + } + return { data: event }; +} +function getGlobalWorkerMessageHandler() { + return globalThis.onmessage ?? null; +} +function setGlobalWorkerMessageHandler(handler) { + globalThis.onmessage = handler; +} + +// src/lib/tree-sitter/client.ts +registerEnvVar({ + name: "OTUI_TREE_SITTER_WORKER_PATH", + description: "Path to the TreeSitter worker entry script", + type: "string", + default: "" +}); +var DEFAULT_PARSER_OVERRIDES = []; +function addDefaultParsers(parsers) { + for (const parser of parsers) { + DEFAULT_PARSER_OVERRIDES = [ + ...DEFAULT_PARSER_OVERRIDES.filter((existingParser) => existingParser.filetype !== parser.filetype), + parser + ]; + } +} +var isUrl = (path) => path.startsWith("http://") || path.startsWith("https://"); + +class TreeSitterClient extends EventEmitter2 { + initialized = false; + worker; + buffers = new Map; + initializePromise; + initializeResolvers; + messageCallbacks = new Map; + messageIdCounter = 0; + editQueues = new Map; + debouncer; + options; + destroyCallbacks = new Set; + lifecycleGeneration = 0; + rejectInitialization; + destroyPromise; + workerTerminationFailed = false; + constructor(options, internalOptions = {}) { + super(); + this.options = options; + this.debouncer = createDebounce("tree-sitter-client"); + if (internalOptions.autoStartWorker ?? true) { + this.startWorker(); + } + } + onDestroy(callback) { + this.destroyCallbacks.add(callback); + return () => { + this.destroyCallbacks.delete(callback); + }; + } + emitError(error, bufferId) { + if (this.listenerCount("error") > 0) { + this.emit("error", error, bufferId); + } + } + emitWarning(warning, bufferId) { + if (this.listenerCount("warning") > 0) { + this.emit("warning", warning, bufferId); + } + } + startWorker() { + if (this.worker) { + return; + } + const workerPath = this.resolveWorkerPath(); + const worker = new Worker(workerPath); + this.worker = worker; + worker.onmessage = (event) => { + if (this.worker !== worker) { + return; + } + this.handleWorkerMessage(event); + }; + worker.onerror = (error) => { + if (this.worker !== worker) { + return; + } + console.error("TreeSitter worker error:", error.message); + const workerError = new Error(`Worker error: ${error.message}`, { cause: error.error }); + this.handleWorkerFailure(worker, workerError); + this.emitError(`Worker error: ${error.message}`); + }; + } + sendWorkerMessage(message) { + if (!this.worker) { + throw new Error("TreeSitter worker is not available"); + } + this.worker.postMessage(message); + } + rejectPendingRequests(error) { + const requests = Array.from(this.messageCallbacks.values()); + this.messageCallbacks.clear(); + for (const request of requests) { + request.reject(error); + } + } + rejectActiveInitialization(error) { + if (this.initializeResolvers) { + clearTimeout(this.initializeResolvers.timeoutId); + this.initializeResolvers.reject(error); + this.initializeResolvers = undefined; + } + this.rejectInitialization?.(error); + this.rejectInitialization = undefined; + } + handleWorkerFailure(worker, error) { + if (this.worker !== worker) { + return; + } + worker.onmessage = null; + worker.onerror = null; + this.worker = undefined; + this.lifecycleGeneration++; + this.initialized = false; + this.initializePromise = undefined; + this.rejectActiveInitialization(error); + this.rejectPendingRequests(error); + this.editQueues.clear(); + this.buffers.clear(); + this.debouncer.clear(); + try { + Promise.resolve(worker.terminate()).catch(() => {}); + } catch {} + } + resolveWorkerPath() { + if (this.options.workerPath) { + return this.options.workerPath; + } + if (env.OTUI_TREE_SITTER_WORKER_PATH) { + return env.OTUI_TREE_SITTER_WORKER_PATH; + } + if (typeof OTUI_TREE_SITTER_WORKER_PATH !== "undefined") { + return OTUI_TREE_SITTER_WORKER_PATH; + } + let workerPath = new URL("./parser.worker.js", import.meta.url).href; + if (!existsSync2(resolve2(import.meta.dirname, "parser.worker.js"))) { + workerPath = new URL("./parser.worker.ts", import.meta.url).href; + } + return workerPath; + } + async stopWorker() { + const worker = this.worker; + if (!worker) { + return; + } + const onmessage = worker.onmessage; + const onerror = worker.onerror; + worker.onmessage = null; + worker.onerror = null; + this.worker = undefined; + try { + const termination = worker.terminate(); + if (termination && typeof termination.then === "function") { + await termination; + } + } catch (error) { + if (!this.worker) { + worker.onmessage = onmessage; + worker.onerror = onerror; + this.worker = worker; + } + throw error; + } + } + async handleReset() { + this.buffers.clear(); + await this.stopWorker(); + this.startWorker(); + this.initialized = false; + this.initializePromise = undefined; + this.initializeResolvers = undefined; + return this.initialize(); + } + async initialize() { + if (this.destroyPromise) { + throw new Error("Cannot initialize while client is being destroyed"); + } + if (this.workerTerminationFailed) { + throw new Error("Cannot initialize after worker termination failed; retry destroy()"); + } + if (this.initializePromise) { + return this.initializePromise; + } + if (!this.worker) { + this.startWorker(); + } + const worker = this.worker; + const generation = this.lifecycleGeneration; + let rejectCancellation; + const cancellation = new Promise((_, reject) => { + rejectCancellation = reject; + }); + const initialization = Promise.race([this.initializeClient(generation, worker), cancellation]); + this.rejectInitialization = rejectCancellation; + this.initializePromise = initialization; + initialization.then(() => { + if (this.initializePromise === initialization) { + this.rejectInitialization = undefined; + } + }, () => { + if (this.initializePromise === initialization) { + this.rejectInitialization = undefined; + } + }); + return this.initializePromise; + } + assertCurrentInitialization(generation, worker) { + if (this.lifecycleGeneration !== generation || this.worker !== worker || this.destroyPromise) { + throw new Error("TreeSitter initialization was invalidated"); + } + } + async initializeClient(generation, worker) { + await new Promise((resolve3, reject) => { + const timeoutMs = this.options.initTimeout ?? 1e4; + const timeoutId = setTimeout(() => { + const error = new Error("Worker initialization timed out"); + console.error("TreeSitter client:", error.message); + this.initializeResolvers = undefined; + reject(error); + }, timeoutMs); + this.initializeResolvers = { resolve: resolve3, reject, timeoutId }; + this.sendWorkerMessage({ + type: "INIT", + dataPath: this.options.dataPath + }); + }); + this.assertCurrentInitialization(generation, worker); + await this.registerDefaultParsers(generation, worker); + this.assertCurrentInitialization(generation, worker); + this.initialized = true; + } + async registerDefaultParsers(generation = this.lifecycleGeneration, worker = this.worker) { + const defaultParsers = await getParsers(); + this.assertCurrentInitialization(generation, worker); + const overriddenFiletypes = new Set(DEFAULT_PARSER_OVERRIDES.map((parser) => parser.filetype)); + for (const parser of [ + ...defaultParsers.filter((parser2) => !overriddenFiletypes.has(parser2.filetype)), + ...DEFAULT_PARSER_OVERRIDES + ]) { + worker.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: this.resolveFiletypeParser(parser) }); + } + } + resolvePath(path) { + if (isUrl(path)) { + return path; + } + if (isBunfsPath(path)) { + return normalizeBunfsPath(parse(path).base); + } + if (!isAbsolute2(path)) { + return resolve2(path); + } + return path; + } + addFiletypeParser(filetypeParser) { + this.sendWorkerMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: this.resolveFiletypeParser(filetypeParser) }); + } + resolveFiletypeParser(filetypeParser) { + return { + ...filetypeParser, + aliases: filetypeParser.aliases ? [...new Set(filetypeParser.aliases.filter((alias) => alias !== filetypeParser.filetype))] : undefined, + wasm: this.resolvePath(filetypeParser.wasm), + queries: { + highlights: filetypeParser.queries.highlights.map((path) => this.resolvePath(path)), + injections: filetypeParser.queries.injections?.map((path) => this.resolvePath(path)) + } + }; + } + async getPerformance() { + const messageId = `performance_${this.messageIdCounter++}`; + return new Promise((resolve3, reject) => { + this.messageCallbacks.set(messageId, { resolve: resolve3, reject }); + try { + this.sendWorkerMessage({ type: "GET_PERFORMANCE", messageId }); + } catch (error) { + this.messageCallbacks.delete(messageId); + reject(error instanceof Error ? error : new Error(String(error))); + } + }); + } + async highlightOnce(content, filetype) { + if (!this.initialized) { + try { + await this.initialize(); + } catch (error) { + return { error: "Could not highlight because of initialization error" }; + } + } + const messageId = `oneshot_${this.messageIdCounter++}`; + return new Promise((resolve3, reject) => { + this.messageCallbacks.set(messageId, { resolve: resolve3, reject }); + try { + this.sendWorkerMessage({ + type: "ONESHOT_HIGHLIGHT", + content, + filetype, + messageId + }); + } catch (error) { + this.messageCallbacks.delete(messageId); + reject(error instanceof Error ? error : new Error(String(error))); + } + }); + } + handleWorkerMessage(event) { + const message = event.data; + switch (message.type) { + case "HIGHLIGHT_RESPONSE": { + const buffer = this.buffers.get(message.bufferId); + if (!buffer || !buffer.hasParser) { + return; + } + if (buffer.version !== message.version) { + this.resetBuffer(message.bufferId, buffer.version, buffer.content); + return; + } + this.emit("highlights:response", message.bufferId, message.version, message.highlights); + return; + } + case "INIT_RESPONSE": { + if (!this.initializeResolvers) { + return; + } + clearTimeout(this.initializeResolvers.timeoutId); + if (message.error) { + console.error("TreeSitter client initialization failed:", message.error); + this.initializeResolvers.reject(new Error(message.error)); + } else { + this.initializeResolvers.resolve(); + } + this.initializeResolvers = undefined; + return; + } + case "PARSER_INIT_RESPONSE": { + const callback = this.messageCallbacks.get(message.messageId); + if (callback) { + this.messageCallbacks.delete(message.messageId); + callback.resolve({ hasParser: message.hasParser, warning: message.warning, error: message.error }); + } + return; + } + case "PRELOAD_PARSER_RESPONSE": { + const callback = this.messageCallbacks.get(message.messageId); + if (callback) { + this.messageCallbacks.delete(message.messageId); + callback.resolve({ hasParser: message.hasParser }); + } + return; + } + case "BUFFER_DISPOSED": { + const callback = this.messageCallbacks.get(`dispose_${message.bufferId}`); + if (callback) { + this.messageCallbacks.delete(`dispose_${message.bufferId}`); + callback.resolve(true); + } + this.emit("buffer:disposed", message.bufferId); + return; + } + case "PERFORMANCE_RESPONSE": { + const callback = this.messageCallbacks.get(message.messageId); + if (callback) { + this.messageCallbacks.delete(message.messageId); + callback.resolve(message.performance); + } + return; + } + case "ONESHOT_HIGHLIGHT_RESPONSE": { + const callback = this.messageCallbacks.get(message.messageId); + if (callback) { + this.messageCallbacks.delete(message.messageId); + callback.resolve({ highlights: message.highlights, warning: message.warning, error: message.error }); + } + return; + } + case "UPDATE_DATA_PATH_RESPONSE": { + const callback = this.messageCallbacks.get(message.messageId); + if (callback) { + this.messageCallbacks.delete(message.messageId); + callback.resolve({ error: message.error }); + } + return; + } + case "CLEAR_CACHE_RESPONSE": { + const callback = this.messageCallbacks.get(message.messageId); + if (callback) { + this.messageCallbacks.delete(message.messageId); + callback.resolve({ error: message.error }); + } + return; + } + case "WARNING": { + this.emitWarning(message.warning, message.bufferId); + return; + } + case "ERROR": { + this.emitError(message.error, message.bufferId); + return; + } + case "WORKER_LOG": { + this.emit("worker:log", message.logType, message.data.join(" ")); + return; + } + } + } + async preloadParser(filetype) { + const messageId = `has_parser_${this.messageIdCounter++}`; + const response = await new Promise((resolve3, reject) => { + this.messageCallbacks.set(messageId, { resolve: resolve3, reject }); + try { + this.sendWorkerMessage({ + type: "PRELOAD_PARSER", + filetype, + messageId + }); + } catch (error) { + this.messageCallbacks.delete(messageId); + reject(error instanceof Error ? error : new Error(String(error))); + } + }); + return response.hasParser; + } + async createBuffer(id, content, filetype, version = 1, autoInitialize = true) { + if (!this.initialized) { + if (!autoInitialize) { + this.emitError("Could not create buffer because client is not initialized"); + return false; + } + try { + await this.initialize(); + } catch (error) { + this.emitError("Could not create buffer because of initialization error"); + return false; + } + } + if (this.buffers.has(id)) { + throw new Error(`Buffer with id ${id} already exists`); + } + this.buffers.set(id, { id, content, filetype, version, hasParser: false }); + const messageId = `init_${this.messageIdCounter++}`; + const response = await new Promise((resolve3, reject) => { + this.messageCallbacks.set(messageId, { resolve: resolve3, reject }); + try { + this.sendWorkerMessage({ + type: "INITIALIZE_PARSER", + bufferId: id, + version, + content, + filetype, + messageId + }); + } catch (error) { + this.messageCallbacks.delete(messageId); + reject(error instanceof Error ? error : new Error(String(error))); + } + }); + if (!response.hasParser) { + this.emit("buffer:initialized", id, false); + if (filetype !== "plaintext") { + this.emitWarning(response.warning || response.error || "Buffer has no parser", id); + } + return false; + } + const bufferState = { id, content, filetype, version, hasParser: true }; + this.buffers.set(id, bufferState); + this.emit("buffer:initialized", id, true); + return true; + } + async updateBuffer(id, edits, newContent, version) { + if (!this.initialized) { + return; + } + const buffer = this.buffers.get(id); + if (!buffer || !buffer.hasParser) { + return; + } + this.buffers.set(id, { ...buffer, content: newContent, version }); + if (!this.editQueues.has(id)) { + this.editQueues.set(id, new ProcessQueue((item) => this.processEdit(id, item.edits, item.newContent, item.version, item.isReset))); + } + const bufferQueue = this.editQueues.get(id); + bufferQueue.enqueue({ edits, newContent, version }); + } + async processEdit(bufferId, edits, newContent, version, isReset = false) { + this.sendWorkerMessage({ + type: isReset ? "RESET_BUFFER" : "HANDLE_EDITS", + bufferId, + version, + content: newContent, + edits + }); + } + async removeBuffer(bufferId) { + if (!this.initialized) { + return; + } + this.buffers.delete(bufferId); + if (this.editQueues.has(bufferId)) { + this.editQueues.get(bufferId)?.clear(); + this.editQueues.delete(bufferId); + } + if (this.worker) { + await new Promise((resolve3, reject) => { + const messageId = `dispose_${bufferId}`; + this.messageCallbacks.set(messageId, { resolve: resolve3, reject }); + try { + this.sendWorkerMessage({ + type: "DISPOSE_BUFFER", + bufferId + }); + } catch (error) { + console.error("Error disposing buffer", error); + this.messageCallbacks.delete(messageId); + resolve3(false); + } + setTimeout(() => { + if (this.messageCallbacks.has(messageId)) { + this.messageCallbacks.delete(messageId); + console.warn({ bufferId }, "Timed out waiting for buffer to be disposed"); + resolve3(false); + } + }, 3000); + }); + } + this.debouncer.clearDebounce(`reset-${bufferId}`); + } + destroy() { + if (this.destroyPromise) { + return this.destroyPromise; + } + let resolveDestroy; + let rejectDestroy; + const destroyPromise = new Promise((resolve3, reject) => { + resolveDestroy = resolve3; + rejectDestroy = reject; + }); + this.destroyPromise = destroyPromise; + const destroyError = new Error("Client destroyed during initialization"); + this.lifecycleGeneration++; + this.initialized = false; + this.initializePromise = undefined; + this.rejectActiveInitialization(destroyError); + this.rejectPendingRequests(new Error("TreeSitter client destroyed")); + for (const callback of this.destroyCallbacks) { + try { + callback(); + } catch (error) { + console.error("TreeSitter client destroy callback failed:", error); + } + } + this.destroyCallbacks.clear(); + clearDebounceScope("tree-sitter-client"); + this.debouncer.clear(); + this.editQueues.clear(); + this.buffers.clear(); + this.stopWorker().then(() => { + this.workerTerminationFailed = false; + if (this.destroyPromise === destroyPromise) { + this.destroyPromise = undefined; + } + resolveDestroy(); + }, (error) => { + this.workerTerminationFailed = true; + if (this.destroyPromise === destroyPromise) { + this.destroyPromise = undefined; + } + rejectDestroy(error); + }); + return destroyPromise; + } + async resetBuffer(bufferId, version, content) { + if (!this.initialized) { + return; + } + const buffer = this.buffers.get(bufferId); + if (!buffer || !buffer.hasParser) { + this.emitError("Cannot reset buffer with no parser", bufferId); + return; + } + this.buffers.set(bufferId, { ...buffer, content, version }); + this.debouncer.debounce(`reset-${bufferId}`, 10, () => this.processEdit(bufferId, [], content, version, true)); + } + getBuffer(bufferId) { + return this.buffers.get(bufferId); + } + getAllBuffers() { + return Array.from(this.buffers.values()); + } + isInitialized() { + return this.initialized; + } + async setDataPath(dataPath) { + if (this.options.dataPath === dataPath) { + return; + } + this.options.dataPath = dataPath; + if (this.initialized && this.worker) { + const messageId = `update_datapath_${this.messageIdCounter++}`; + return new Promise((resolve3, reject) => { + this.messageCallbacks.set(messageId, { + resolve: (response) => { + if (response.error) { + reject(new Error(response.error)); + } else { + resolve3(); + } + }, + reject + }); + try { + this.sendWorkerMessage({ + type: "UPDATE_DATA_PATH", + dataPath, + messageId + }); + } catch (error) { + this.messageCallbacks.delete(messageId); + reject(error instanceof Error ? error : new Error(String(error))); + } + }); + } + } + async clearCache() { + if (!this.initialized || !this.worker) { + throw new Error("Cannot clear cache: client is not initialized"); + } + const messageId = `clear_cache_${this.messageIdCounter++}`; + return new Promise((resolve3, reject) => { + this.messageCallbacks.set(messageId, { + resolve: (response) => { + if (response.error) { + reject(new Error(response.error)); + } else { + resolve3(); + } + }, + reject + }); + try { + this.sendWorkerMessage({ + type: "CLEAR_CACHE", + messageId + }); + } catch (error) { + this.messageCallbacks.delete(messageId); + reject(error instanceof Error ? error : new Error(String(error))); + } + }); + } +} + +// src/lib/data-paths.ts +import os from "os"; +import path from "path"; +import { EventEmitter as EventEmitter3 } from "events"; + +// src/lib/validate-dir-name.ts +function isValidDirectoryName(name) { + if (!name || typeof name !== "string") { + return false; + } + if (name.trim().length === 0) { + return false; + } + const reservedNames = [ + "CON", + "PRN", + "AUX", + "NUL", + "COM1", + "COM2", + "COM3", + "COM4", + "COM5", + "COM6", + "COM7", + "COM8", + "COM9", + "LPT1", + "LPT2", + "LPT3", + "LPT4", + "LPT5", + "LPT6", + "LPT7", + "LPT8", + "LPT9" + ]; + if (reservedNames.includes(name.toUpperCase())) { + return false; + } + const invalidChars = /[<>:"|?*/\\\x00-\x1f]/; + if (invalidChars.test(name)) { + return false; + } + if (name.endsWith(".") || name.endsWith(" ")) { + return false; + } + if (name === "." || name === "..") { + return false; + } + return true; +} + +// src/lib/data-paths.ts +registerEnvVar({ + name: "XDG_CONFIG_HOME", + description: "Base directory for user-specific configuration files", + type: "string", + default: "" +}); +registerEnvVar({ + name: "XDG_DATA_HOME", + description: "Base directory for user-specific data files", + type: "string", + default: "" +}); + +class DataPathsManager extends EventEmitter3 { + _appName; + _globalConfigPath; + _globalConfigFile; + _localConfigFile; + _globalDataPath; + constructor() { + super(); + this._appName = "opentui"; + } + get appName() { + return this._appName; + } + set appName(value) { + if (!isValidDirectoryName(value)) { + throw new Error(`Invalid app name "${value}": must be a valid directory name`); + } + if (this._appName !== value) { + this._appName = value; + this._globalConfigPath = undefined; + this._globalConfigFile = undefined; + this._localConfigFile = undefined; + this._globalDataPath = undefined; + this.emit("paths:changed", this.toObject()); + } + } + get globalConfigPath() { + if (this._globalConfigPath === undefined) { + const homeDir = os.homedir(); + const xdgConfigHome = env.XDG_CONFIG_HOME; + const baseConfigDir = xdgConfigHome || path.join(homeDir, ".config"); + this._globalConfigPath = path.join(baseConfigDir, this._appName); + } + return this._globalConfigPath; + } + get globalConfigFile() { + if (this._globalConfigFile === undefined) { + this._globalConfigFile = path.join(this.globalConfigPath, "init.ts"); + } + return this._globalConfigFile; + } + get localConfigFile() { + if (this._localConfigFile === undefined) { + this._localConfigFile = path.join(process.cwd(), `.${this._appName}.ts`); + } + return this._localConfigFile; + } + get globalDataPath() { + if (this._globalDataPath === undefined) { + const homeDir = os.homedir(); + const xdgDataHome = env.XDG_DATA_HOME; + const baseDataDir = xdgDataHome || path.join(homeDir, ".local/share"); + this._globalDataPath = path.join(baseDataDir, this._appName); + } + return this._globalDataPath; + } + toObject() { + return { + globalConfigPath: this.globalConfigPath, + globalConfigFile: this.globalConfigFile, + localConfigFile: this.localConfigFile, + globalDataPath: this.globalDataPath + }; + } +} +function getDataPaths() { + return singleton("data-paths-opentui", () => new DataPathsManager); +} +// src/lib/tree-sitter/resolve-ft.ts +import path2 from "node:path"; +var extensionToFiletype = new Map([ + ["astro", "astro"], + ["bash", "bash"], + ["c", "c"], + ["cc", "cpp"], + ["cjs", "javascript"], + ["clj", "clojure"], + ["cljs", "clojure"], + ["cljc", "clojure"], + ["cpp", "cpp"], + ["cxx", "cpp"], + ["cs", "csharp"], + ["cts", "typescript"], + ["ctsx", "typescriptreact"], + ["dart", "dart"], + ["diff", "diff"], + ["edn", "clojure"], + ["go", "go"], + ["gemspec", "ruby"], + ["groovy", "groovy"], + ["h", "c"], + ["handlebars", "handlebars"], + ["hbs", "handlebars"], + ["hpp", "cpp"], + ["hxx", "cpp"], + ["h++", "cpp"], + ["hh", "cpp"], + ["hrl", "erlang"], + ["hs", "haskell"], + ["htm", "html"], + ["html", "html"], + ["ini", "ini"], + ["js", "javascript"], + ["jsx", "javascriptreact"], + ["jl", "julia"], + ["json", "json"], + ["ksh", "bash"], + ["kt", "kotlin"], + ["kts", "kotlin"], + ["latex", "latex"], + ["less", "less"], + ["lua", "lua"], + ["markdown", "markdown"], + ["md", "markdown"], + ["mdown", "markdown"], + ["mkd", "markdown"], + ["mjs", "javascript"], + ["ml", "ocaml"], + ["mli", "ocaml"], + ["mts", "typescript"], + ["mtsx", "typescriptreact"], + ["patch", "diff"], + ["php", "php"], + ["pl", "perl"], + ["pm", "perl"], + ["ps1", "powershell"], + ["psm1", "powershell"], + ["py", "python"], + ["pyi", "python"], + ["r", "r"], + ["rb", "ruby"], + ["rake", "ruby"], + ["rs", "rust"], + ["ru", "ruby"], + ["sass", "sass"], + ["sc", "scala"], + ["scala", "scala"], + ["scss", "scss"], + ["sh", "bash"], + ["sql", "sql"], + ["svelte", "svelte"], + ["swift", "swift"], + ["ts", "typescript"], + ["tsx", "typescriptreact"], + ["tex", "latex"], + ["toml", "toml"], + ["vue", "vue"], + ["vim", "vim"], + ["xml", "xml"], + ["xsl", "xsl"], + ["yaml", "yaml"], + ["yml", "yaml"], + ["zig", "zig"], + ["zon", "zig"], + ["zsh", "bash"], + ["c++", "cpp"], + ["erl", "erlang"], + ["exs", "elixir"], + ["ex", "elixir"], + ["elm", "elm"], + ["fsharp", "fsharp"], + ["fs", "fsharp"], + ["fsx", "fsharp"], + ["fsscript", "fsharp"], + ["fsi", "fsharp"], + ["java", "java"], + ["css", "css"] +]); +var basenameToFiletype = new Map([ + [".bash_aliases", "bash"], + [".bash_logout", "bash"], + [".bash_profile", "bash"], + [".bashrc", "bash"], + [".kshrc", "bash"], + [".profile", "bash"], + [".vimrc", "vim"], + [".zlogin", "bash"], + [".zlogout", "bash"], + [".zprofile", "bash"], + [".zshenv", "bash"], + [".zshrc", "bash"], + ["appfile", "ruby"], + ["berksfile", "ruby"], + ["brewfile", "ruby"], + ["cheffile", "ruby"], + ["containerfile", "dockerfile"], + ["dockerfile", "dockerfile"], + ["fastfile", "ruby"], + ["gemfile", "ruby"], + ["gnumakefile", "make"], + ["gvimrc", "vim"], + ["guardfile", "ruby"], + ["makefile", "make"], + ["podfile", "ruby"], + ["rakefile", "ruby"], + ["thorfile", "ruby"], + ["vagrantfile", "ruby"] +]); +function normalizeFiletypeToken(value) { + const normalizedValue = value.trim().replace(/^\./, "").toLowerCase(); + return normalizedValue || undefined; +} +function getBasename(value) { + const normalizedValue = value.trim().replaceAll("\\", "/"); + if (!normalizedValue) + return; + const basename2 = path2.posix.basename(normalizedValue).toLowerCase(); + return basename2 || undefined; +} +function extToFiletype(extension) { + const normalizedExtension = normalizeFiletypeToken(extension); + if (!normalizedExtension) + return; + return extensionToFiletype.get(normalizedExtension); +} +function pathToFiletype(path3) { + if (typeof path3 !== "string") + return; + const basename2 = getBasename(path3); + if (!basename2) + return; + const basenameFiletype = basenameToFiletype.get(basename2); + if (basenameFiletype) { + return basenameFiletype; + } + const lastDot = basename2.lastIndexOf("."); + if (lastDot === -1 || lastDot === basename2.length - 1) { + return; + } + const extension = basename2.substring(lastDot + 1); + return extToFiletype(extension); +} +function infoStringToFiletype(infoString) { + if (typeof infoString !== "string") + return; + const token = infoString.trim().split(/\s+/, 1)[0]; + const directBasenameMatch = basenameToFiletype.get(token.toLowerCase()); + if (directBasenameMatch) + return directBasenameMatch; + const normalizedToken = normalizeFiletypeToken(token); + if (!normalizedToken) + return; + return basenameToFiletype.get(normalizedToken) ?? pathToFiletype(normalizedToken) ?? extToFiletype(normalizedToken) ?? normalizedToken; +} + +// src/lib/tree-sitter/index.ts +var TREE_SITTER_CLIENT_KEY = "tree-sitter-client"; +var TREE_SITTER_CLIENT_LISTENER_STATE_KEY = "tree-sitter-client-listener-state"; +function getTreeSitterClientListenerState() { + return singleton(TREE_SITTER_CLIENT_LISTENER_STATE_KEY, () => ({})); +} +function getTreeSitterClient() { + const existingClient = getSingleton(TREE_SITTER_CLIENT_KEY); + if (existingClient) { + return existingClient; + } + const dataPathsManager = getDataPaths(); + const defaultOptions = { + dataPath: dataPathsManager.globalDataPath + }; + return singleton(TREE_SITTER_CLIENT_KEY, () => { + const client2 = new TreeSitterClient(defaultOptions); + const listenerState = getTreeSitterClientListenerState(); + const handlePathsChanged = (paths) => { + client2.setDataPath(paths.globalDataPath).catch((error) => { + console.warn("Failed to update tree-sitter data path:", error); + }); + }; + const removeListener = () => { + dataPathsManager.off("paths:changed", handlePathsChanged); + if (listenerState.removeListener === removeListener) { + listenerState.removeListener = undefined; + } + if (getSingleton(TREE_SITTER_CLIENT_KEY) === client2) { + destroySingleton(TREE_SITTER_CLIENT_KEY); + } + }; + listenerState.removeListener = removeListener; + client2.onDestroy(removeListener); + dataPathsManager.on("paths:changed", handlePathsChanged); + return client2; + }); +} +async function destroyTreeSitterClient() { + const client2 = getSingleton(TREE_SITTER_CLIENT_KEY); + if (!client2) { + const listenerState = getSingleton(TREE_SITTER_CLIENT_LISTENER_STATE_KEY); + listenerState?.removeListener?.(); + if (listenerState) { + listenerState.removeListener = undefined; + } + return; + } + destroySingleton(TREE_SITTER_CLIENT_KEY); + await client2.destroy(); +} +// src/lib/extmarks-history.ts +class ExtmarksHistory { + undoStack = []; + redoStack = []; + saveSnapshot(extmarks, nextId) { + const snapshot = { + extmarks: new Map(Array.from(extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])), + nextId + }; + this.undoStack.push(snapshot); + this.redoStack = []; + } + undo() { + if (this.undoStack.length === 0) + return null; + return this.undoStack.pop(); + } + redo() { + if (this.redoStack.length === 0) + return null; + return this.redoStack.pop(); + } + pushRedo(snapshot) { + this.redoStack.push(snapshot); + } + pushUndo(snapshot) { + this.undoStack.push(snapshot); + } + clear() { + this.undoStack = []; + this.redoStack = []; + } + canUndo() { + return this.undoStack.length > 0; + } + canRedo() { + return this.redoStack.length > 0; + } +} + +// src/lib/extmarks.ts +class ExtmarksController { + editBuffer; + editorView; + extmarks = new Map; + extmarksByTypeId = new Map; + metadata = new Map; + nextId = 1; + destroyed = false; + history = new ExtmarksHistory; + typeNameToId = new Map; + typeIdToName = new Map; + nextTypeId = 1; + originalMoveCursorLeft; + originalMoveCursorRight; + originalSetCursorByOffset; + originalMoveUpVisual; + originalMoveDownVisual; + originalDeleteCharBackward; + originalDeleteChar; + originalInsertText; + originalInsertChar; + originalDeleteRange; + originalSetText; + originalReplaceText; + originalClear; + originalNewLine; + originalDeleteLine; + originalEditorViewDeleteSelectedText; + originalUndo; + originalRedo; + constructor(editBuffer, editorView) { + this.editBuffer = editBuffer; + this.editorView = editorView; + this.originalMoveCursorLeft = editBuffer.moveCursorLeft.bind(editBuffer); + this.originalMoveCursorRight = editBuffer.moveCursorRight.bind(editBuffer); + this.originalSetCursorByOffset = editBuffer.setCursorByOffset.bind(editBuffer); + this.originalMoveUpVisual = editorView.moveUpVisual.bind(editorView); + this.originalMoveDownVisual = editorView.moveDownVisual.bind(editorView); + this.originalDeleteCharBackward = editBuffer.deleteCharBackward.bind(editBuffer); + this.originalDeleteChar = editBuffer.deleteChar.bind(editBuffer); + this.originalInsertText = editBuffer.insertText.bind(editBuffer); + this.originalInsertChar = editBuffer.insertChar.bind(editBuffer); + this.originalDeleteRange = editBuffer.deleteRange.bind(editBuffer); + this.originalSetText = editBuffer.setText.bind(editBuffer); + this.originalReplaceText = editBuffer.replaceText.bind(editBuffer); + this.originalClear = editBuffer.clear.bind(editBuffer); + this.originalNewLine = editBuffer.newLine.bind(editBuffer); + this.originalDeleteLine = editBuffer.deleteLine.bind(editBuffer); + this.originalEditorViewDeleteSelectedText = editorView.deleteSelectedText.bind(editorView); + this.originalUndo = editBuffer.undo.bind(editBuffer); + this.originalRedo = editBuffer.redo.bind(editBuffer); + this.wrapCursorMovement(); + this.wrapDeletion(); + this.wrapInsertion(); + this.wrapEditorViewDeleteSelectedText(); + this.wrapUndoRedo(); + this.setupContentChangeListener(); + } + wrapCursorMovement() { + this.editBuffer.moveCursorLeft = () => { + if (this.destroyed) { + this.originalMoveCursorLeft(); + return; + } + const currentOffset = this.editorView.getVisualCursor().offset; + const hasSelection = this.editorView.hasSelection(); + if (hasSelection) { + this.originalMoveCursorLeft(); + return; + } + const targetOffset = currentOffset - 1; + if (targetOffset < 0) { + this.originalMoveCursorLeft(); + return; + } + const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset); + if (virtualExtmark && currentOffset >= virtualExtmark.end) { + this.editBuffer.setCursorByOffset(virtualExtmark.start - 1); + return; + } + this.originalMoveCursorLeft(); + }; + this.editBuffer.moveCursorRight = () => { + if (this.destroyed) { + this.originalMoveCursorRight(); + return; + } + const currentOffset = this.editorView.getVisualCursor().offset; + const hasSelection = this.editorView.hasSelection(); + if (hasSelection) { + this.originalMoveCursorRight(); + return; + } + const targetOffset = currentOffset + 1; + const textLength = this.editBuffer.getText().length; + if (targetOffset > textLength) { + this.originalMoveCursorRight(); + return; + } + const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset); + if (virtualExtmark && currentOffset <= virtualExtmark.start) { + this.editBuffer.setCursorByOffset(virtualExtmark.end); + return; + } + this.originalMoveCursorRight(); + }; + this.editorView.moveUpVisual = () => { + if (this.destroyed) { + this.originalMoveUpVisual(); + return; + } + const hasSelection = this.editorView.hasSelection(); + if (hasSelection) { + this.originalMoveUpVisual(); + return; + } + const currentOffset = this.editorView.getVisualCursor().offset; + this.originalMoveUpVisual(); + const newOffset = this.editorView.getVisualCursor().offset; + const virtualExtmark = this.findVirtualExtmarkContaining(newOffset); + if (virtualExtmark) { + const distanceToStart = newOffset - virtualExtmark.start; + const distanceToEnd = virtualExtmark.end - newOffset; + if (distanceToStart < distanceToEnd) { + this.editorView.setCursorByOffset(virtualExtmark.start - 1); + } else { + this.editorView.setCursorByOffset(virtualExtmark.end); + } + } + }; + this.editorView.moveDownVisual = () => { + if (this.destroyed) { + this.originalMoveDownVisual(); + return; + } + const hasSelection = this.editorView.hasSelection(); + if (hasSelection) { + this.originalMoveDownVisual(); + return; + } + const currentOffset = this.editorView.getVisualCursor().offset; + this.originalMoveDownVisual(); + const newOffset = this.editorView.getVisualCursor().offset; + const virtualExtmark = this.findVirtualExtmarkContaining(newOffset); + if (virtualExtmark) { + const distanceToStart = newOffset - virtualExtmark.start; + const distanceToEnd = virtualExtmark.end - newOffset; + if (distanceToStart < distanceToEnd) { + const adjustedOffset = virtualExtmark.start - 1; + const targetOffset = adjustedOffset <= currentOffset ? virtualExtmark.end : adjustedOffset; + this.editorView.setCursorByOffset(targetOffset); + } else { + this.editorView.setCursorByOffset(virtualExtmark.end); + } + } + }; + this.editBuffer.setCursorByOffset = (offset) => { + if (this.destroyed) { + this.originalSetCursorByOffset(offset); + return; + } + const currentOffset = this.editorView.getVisualCursor().offset; + const hasSelection = this.editorView.hasSelection(); + if (hasSelection) { + this.originalSetCursorByOffset(offset); + return; + } + const movingForward = offset > currentOffset; + if (movingForward) { + const virtualExtmark = this.findVirtualExtmarkContaining(offset); + if (virtualExtmark && currentOffset <= virtualExtmark.start) { + this.originalSetCursorByOffset(virtualExtmark.end); + return; + } + } else { + for (const extmark of this.extmarks.values()) { + if (extmark.virtual && currentOffset >= extmark.end && offset < extmark.end && offset >= extmark.start) { + this.originalSetCursorByOffset(extmark.start - 1); + return; + } + } + } + this.originalSetCursorByOffset(offset); + }; + } + wrapDeletion() { + this.editBuffer.deleteCharBackward = () => { + if (this.destroyed) { + this.originalDeleteCharBackward(); + return; + } + this.saveSnapshot(); + const currentOffset = this.editorView.getVisualCursor().offset; + const hadSelection = this.editorView.hasSelection(); + if (currentOffset === 0) { + this.originalDeleteCharBackward(); + return; + } + if (hadSelection) { + this.originalDeleteCharBackward(); + return; + } + const targetOffset = currentOffset - 1; + const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset); + if (virtualExtmark && currentOffset === virtualExtmark.end) { + const startCursor = this.offsetToPosition(virtualExtmark.start); + const endCursor = this.offsetToPosition(virtualExtmark.end); + const deleteOffset2 = virtualExtmark.start; + const deleteLength2 = virtualExtmark.end - virtualExtmark.start; + this.deleteExtmarkById(virtualExtmark.id); + this.originalDeleteRange(startCursor.row, startCursor.col, endCursor.row, endCursor.col); + this.adjustExtmarksAfterDeletion(deleteOffset2, deleteLength2); + this.updateHighlights(); + return; + } + this.originalDeleteCharBackward(); + const deleteOffset = this.editorView.getVisualCursor().offset; + const deleteLength = currentOffset - deleteOffset; + if (deleteLength > 0) { + this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength); + } + }; + this.editBuffer.deleteChar = () => { + if (this.destroyed) { + this.originalDeleteChar(); + return; + } + this.saveSnapshot(); + const currentOffset = this.editorView.getVisualCursor().offset; + const hadSelection = this.editorView.hasSelection(); + if (hadSelection) { + this.originalDeleteChar(); + return; + } + const targetOffset = currentOffset; + const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset); + if (virtualExtmark && currentOffset === virtualExtmark.start) { + const startCursor = this.offsetToPosition(virtualExtmark.start); + const endCursor = this.offsetToPosition(virtualExtmark.end); + const deleteOffset = virtualExtmark.start; + const deleteLength2 = virtualExtmark.end - virtualExtmark.start; + this.deleteExtmarkById(virtualExtmark.id); + this.originalDeleteRange(startCursor.row, startCursor.col, endCursor.row, endCursor.col); + this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength2); + this.updateHighlights(); + return; + } + const deleteEndOffset = this.getNextCursorOffset(currentOffset); + const deleteLength = deleteEndOffset - currentOffset; + this.originalDeleteChar(); + if (deleteLength > 0) { + this.adjustExtmarksAfterDeletion(currentOffset, deleteLength); + } + }; + this.editBuffer.deleteRange = (startLine, startCol, endLine, endCol) => { + if (this.destroyed) { + this.originalDeleteRange(startLine, startCol, endLine, endCol); + return; + } + this.saveSnapshot(); + const startOffset = this.positionToOffset(startLine, startCol); + const endOffset = this.positionToOffset(endLine, endCol); + const length = endOffset - startOffset; + this.originalDeleteRange(startLine, startCol, endLine, endCol); + this.adjustExtmarksAfterDeletion(startOffset, length); + }; + this.editBuffer.deleteLine = () => { + if (this.destroyed) { + this.originalDeleteLine(); + return; + } + this.saveSnapshot(); + const text = this.editBuffer.getText(); + const currentOffset = this.editorView.getVisualCursor().offset; + let lineStart = 0; + for (let i = currentOffset - 1;i >= 0; i--) { + if (text[i] === ` +`) { + lineStart = i + 1; + break; + } + } + let lineEnd = text.length; + for (let i = currentOffset;i < text.length; i++) { + if (text[i] === ` +`) { + lineEnd = i + 1; + break; + } + } + const deleteLength = lineEnd - lineStart; + this.originalDeleteLine(); + this.adjustExtmarksAfterDeletion(lineStart, deleteLength); + }; + } + wrapInsertion() { + this.editBuffer.insertText = (text) => { + if (this.destroyed) { + this.originalInsertText(text); + return; + } + this.saveSnapshot(); + const currentOffset = this.editorView.getVisualCursor().offset; + this.originalInsertText(text); + const insertLength = this.editorView.getVisualCursor().offset - currentOffset; + if (insertLength > 0) { + this.adjustExtmarksAfterInsertion(currentOffset, insertLength); + } + }; + this.editBuffer.insertChar = (char) => { + if (this.destroyed) { + this.originalInsertChar(char); + return; + } + this.saveSnapshot(); + const currentOffset = this.editorView.getVisualCursor().offset; + this.originalInsertChar(char); + const insertLength = this.editorView.getVisualCursor().offset - currentOffset; + if (insertLength > 0) { + this.adjustExtmarksAfterInsertion(currentOffset, insertLength); + } + }; + this.editBuffer.setText = (text) => { + if (this.destroyed) { + this.originalSetText(text); + return; + } + this.clear(); + this.originalSetText(text); + }; + this.editBuffer.replaceText = (text) => { + if (this.destroyed) { + this.originalReplaceText(text); + return; + } + this.saveSnapshot(); + this.clear(); + this.originalReplaceText(text); + }; + this.editBuffer.clear = () => { + if (this.destroyed) { + this.originalClear(); + return; + } + this.saveSnapshot(); + this.clear(); + this.originalClear(); + }; + this.editBuffer.newLine = () => { + if (this.destroyed) { + this.originalNewLine(); + return; + } + this.saveSnapshot(); + const currentOffset = this.editorView.getVisualCursor().offset; + this.originalNewLine(); + this.adjustExtmarksAfterInsertion(currentOffset, 1); + }; + } + wrapEditorViewDeleteSelectedText() { + this.editorView.deleteSelectedText = () => { + if (this.destroyed) { + this.originalEditorViewDeleteSelectedText(); + return; + } + this.saveSnapshot(); + const selection = this.editorView.getSelection(); + if (!selection) { + this.originalEditorViewDeleteSelectedText(); + return; + } + const deleteOffset = Math.min(selection.start, selection.end); + const deleteLength = Math.abs(selection.end - selection.start); + this.originalEditorViewDeleteSelectedText(); + if (deleteLength > 0) { + this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength); + } + }; + } + setupContentChangeListener() { + this.editBuffer.on("content-changed", () => { + if (this.destroyed) + return; + this.updateHighlights(); + }); + } + deleteExtmarkById(id) { + const extmark = this.extmarks.get(id); + if (extmark) { + this.extmarks.delete(id); + this.extmarksByTypeId.get(extmark.typeId)?.delete(id); + this.metadata.delete(id); + } + } + findVirtualExtmarkContaining(offset) { + for (const extmark of this.extmarks.values()) { + if (extmark.virtual && offset >= extmark.start && offset < extmark.end) { + return extmark; + } + } + return null; + } + adjustExtmarksAfterInsertion(insertOffset, length) { + for (const extmark of this.extmarks.values()) { + if (extmark.start >= insertOffset) { + extmark.start += length; + extmark.end += length; + } else if (extmark.end > insertOffset) { + extmark.end += length; + } + } + this.updateHighlights(); + } + adjustExtmarksAfterDeletion(deleteOffset, length) { + const toDelete = []; + for (const extmark of this.extmarks.values()) { + if (extmark.end <= deleteOffset) { + continue; + } + if (extmark.start >= deleteOffset + length) { + extmark.start -= length; + extmark.end -= length; + } else if (extmark.start >= deleteOffset && extmark.end <= deleteOffset + length) { + toDelete.push(extmark.id); + } else if (extmark.start < deleteOffset && extmark.end > deleteOffset + length) { + extmark.end -= length; + } else if (extmark.start < deleteOffset && extmark.end > deleteOffset) { + extmark.end -= Math.min(extmark.end, deleteOffset + length) - deleteOffset; + } else if (extmark.start < deleteOffset + length && extmark.end > deleteOffset + length) { + const overlap = deleteOffset + length - extmark.start; + extmark.start = deleteOffset; + extmark.end -= length; + } + } + for (const id of toDelete) { + this.deleteExtmarkById(id); + } + this.updateHighlights(); + } + offsetToPosition(offset) { + const result = this.editBuffer.offsetToPosition(offset); + if (!result) { + return { row: 0, col: 0 }; + } + return result; + } + positionToOffset(row, col) { + return this.editBuffer.positionToOffset(row, col); + } + getNextCursorOffset(currentOffset) { + this.originalMoveCursorRight(); + const nextOffset = this.editorView.getVisualCursor().offset; + this.originalSetCursorByOffset(currentOffset); + return nextOffset; + } + updateHighlights() { + this.editBuffer.clearAllHighlights(); + for (const extmark of this.extmarks.values()) { + if (extmark.styleId !== undefined) { + const startWithoutNewlines = this.offsetExcludingNewlines(extmark.start); + const endWithoutNewlines = this.offsetExcludingNewlines(extmark.end); + this.editBuffer.addHighlightByCharRange({ + start: startWithoutNewlines, + end: endWithoutNewlines, + styleId: extmark.styleId, + priority: extmark.priority ?? 0, + hlRef: extmark.id + }); + } + } + } + offsetExcludingNewlines(offset) { + const text = this.editBuffer.getText(); + let displayWidthSoFar = 0; + let newlineCount = 0; + let i = 0; + while (i < text.length && displayWidthSoFar < offset) { + if (text[i] === ` +`) { + displayWidthSoFar++; + newlineCount++; + i++; + } else { + let j = i; + while (j < text.length && text[j] !== ` +`) { + j++; + } + const chunk = text.substring(i, j); + const chunkWidth = stringWidth2(chunk); + if (displayWidthSoFar + chunkWidth < offset) { + displayWidthSoFar += chunkWidth; + i = j; + } else { + for (let k = i;k < j && displayWidthSoFar < offset; k++) { + const charWidth = stringWidth2(text[k]); + displayWidthSoFar += charWidth; + } + break; + } + } + } + return offset - newlineCount; + } + create(options) { + if (this.destroyed) { + throw new Error("ExtmarksController is destroyed"); + } + const id = this.nextId++; + const typeId = options.typeId ?? 0; + const extmark = { + id, + start: options.start, + end: options.end, + virtual: options.virtual ?? false, + styleId: options.styleId, + priority: options.priority, + data: options.data, + typeId + }; + this.extmarks.set(id, extmark); + if (!this.extmarksByTypeId.has(typeId)) { + this.extmarksByTypeId.set(typeId, new Set); + } + this.extmarksByTypeId.get(typeId).add(id); + if (options.metadata !== undefined) { + this.metadata.set(id, options.metadata); + } + this.updateHighlights(); + return id; + } + delete(id) { + if (this.destroyed) { + throw new Error("ExtmarksController is destroyed"); + } + const extmark = this.extmarks.get(id); + if (!extmark) + return false; + this.deleteExtmarkById(id); + this.updateHighlights(); + return true; + } + get(id) { + if (this.destroyed) + return null; + return this.extmarks.get(id) ?? null; + } + getAll() { + if (this.destroyed) + return []; + return Array.from(this.extmarks.values()); + } + getVirtual() { + if (this.destroyed) + return []; + return Array.from(this.extmarks.values()).filter((e) => e.virtual); + } + getAtOffset(offset) { + if (this.destroyed) + return []; + return Array.from(this.extmarks.values()).filter((e) => offset >= e.start && offset < e.end); + } + getAllForTypeId(typeId) { + if (this.destroyed) + return []; + const ids = this.extmarksByTypeId.get(typeId); + if (!ids) + return []; + return Array.from(ids).map((id) => this.extmarks.get(id)).filter((e) => e !== undefined); + } + clear() { + if (this.destroyed) + return; + this.extmarks.clear(); + this.extmarksByTypeId.clear(); + this.metadata.clear(); + this.updateHighlights(); + } + saveSnapshot() { + this.history.saveSnapshot(this.extmarks, this.nextId); + } + restoreSnapshot(snapshot) { + this.extmarks = new Map(Array.from(snapshot.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])); + this.nextId = snapshot.nextId; + this.updateHighlights(); + } + wrapUndoRedo() { + this.editBuffer.undo = () => { + if (this.destroyed) { + return this.originalUndo(); + } + if (!this.history.canUndo()) { + return this.originalUndo(); + } + const currentSnapshot = { + extmarks: new Map(Array.from(this.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])), + nextId: this.nextId + }; + this.history.pushRedo(currentSnapshot); + const snapshot = this.history.undo(); + this.restoreSnapshot(snapshot); + return this.originalUndo(); + }; + this.editBuffer.redo = () => { + if (this.destroyed) { + return this.originalRedo(); + } + if (!this.history.canRedo()) { + return this.originalRedo(); + } + const currentSnapshot = { + extmarks: new Map(Array.from(this.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])), + nextId: this.nextId + }; + this.history.pushUndo(currentSnapshot); + const snapshot = this.history.redo(); + this.restoreSnapshot(snapshot); + return this.originalRedo(); + }; + } + registerType(typeName) { + if (this.destroyed) { + throw new Error("ExtmarksController is destroyed"); + } + const existing = this.typeNameToId.get(typeName); + if (existing !== undefined) { + return existing; + } + const typeId = this.nextTypeId++; + this.typeNameToId.set(typeName, typeId); + this.typeIdToName.set(typeId, typeName); + return typeId; + } + getTypeId(typeName) { + if (this.destroyed) + return null; + return this.typeNameToId.get(typeName) ?? null; + } + getTypeName(typeId) { + if (this.destroyed) + return null; + return this.typeIdToName.get(typeId) ?? null; + } + getMetadataFor(extmarkId) { + if (this.destroyed) + return; + return this.metadata.get(extmarkId); + } + destroy() { + if (this.destroyed) + return; + this.editBuffer.moveCursorLeft = this.originalMoveCursorLeft; + this.editBuffer.moveCursorRight = this.originalMoveCursorRight; + this.editBuffer.setCursorByOffset = this.originalSetCursorByOffset; + this.editorView.moveUpVisual = this.originalMoveUpVisual; + this.editorView.moveDownVisual = this.originalMoveDownVisual; + this.editBuffer.deleteCharBackward = this.originalDeleteCharBackward; + this.editBuffer.deleteChar = this.originalDeleteChar; + this.editBuffer.insertText = this.originalInsertText; + this.editBuffer.insertChar = this.originalInsertChar; + this.editBuffer.deleteRange = this.originalDeleteRange; + this.editBuffer.setText = this.originalSetText; + this.editBuffer.replaceText = this.originalReplaceText; + this.editBuffer.clear = this.originalClear; + this.editBuffer.newLine = this.originalNewLine; + this.editBuffer.deleteLine = this.originalDeleteLine; + this.editorView.deleteSelectedText = this.originalEditorViewDeleteSelectedText; + this.editBuffer.undo = this.originalUndo; + this.editBuffer.redo = this.originalRedo; + this.extmarks.clear(); + this.extmarksByTypeId.clear(); + this.metadata.clear(); + this.typeNameToId.clear(); + this.typeIdToName.clear(); + this.history.clear(); + this.destroyed = true; + } +} +function createExtmarksController(editBuffer, editorView) { + return new ExtmarksController(editBuffer, editorView); +} +// src/lib/terminal-palette.ts +var SYSTEM_CLOCK2 = new SystemClock; +registerEnvVar({ + name: "OTUI_PALETTE_IDLE_TIMEOUT_MS", + description: "Milliseconds of silence after palette queries before using fallback colors.", + type: "number", + default: 300 +}); +var OSC4_RESPONSE = /\x1b]4;(\d+);(?:(?:rgb:)([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\x07|\x1b\\)/g; +var OSC_SPECIAL_RESPONSE = /\x1b](\d+);(?:(?:rgb:)([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\x07|\x1b\\)/g; +function scaleComponent(comp) { + const val = parseInt(comp, 16); + const maxIn = (1 << 4 * comp.length) - 1; + return Math.round(val / maxIn * 255).toString(16).padStart(2, "0"); +} +function toHex(r, g, b, hex6) { + if (hex6) + return `#${hex6.toLowerCase()}`; + if (r && g && b) + return `#${scaleComponent(r)}${scaleComponent(g)}${scaleComponent(b)}`; + return "#000000"; +} +function wrapForTmux(osc) { + const escaped = osc.replace(/\x1b/g, "\x1B\x1B"); + return `\x1BPtmux;${escaped}\x1B\\`; +} + +class TerminalPalette { + stdin; + stdout; + writeFn; + activeQuerySessions = []; + inLegacyTmux; + inTmux; + oscSource; + clock; + constructor(options) { + const { stdin, stdout, writeFn, isLegacyTmux, isTmux, oscSource, clock } = options; + this.stdin = stdin; + this.stdout = stdout; + this.writeFn = writeFn || ((data) => stdout.write(data)); + this.inLegacyTmux = isLegacyTmux ?? false; + this.inTmux = isTmux ?? this.inLegacyTmux; + this.oscSource = oscSource; + this.clock = clock ?? SYSTEM_CLOCK2; + } + writeOsc(osc, wrapForLegacyTmux = false) { + const data = wrapForLegacyTmux && this.inLegacyTmux ? wrapForTmux(osc) : osc; + return this.writeFn(data); + } + cleanup() { + for (const cleanupSession of [...this.activeQuerySessions]) { + cleanupSession(); + } + this.activeQuerySessions = []; + } + subscribeInput(handler) { + if (this.oscSource) { + return this.oscSource.subscribeOsc((sequence) => { + handler(sequence); + }); + } + this.stdin.on("data", handler); + return () => { + this.stdin.removeListener("data", handler); + }; + } + createQuerySession() { + const timers = new Set; + const subscriptions = new Set; + let closed = false; + const cleanup = () => { + if (closed) + return; + closed = true; + for (const timer of timers) { + this.clock.clearTimeout(timer); + } + timers.clear(); + for (const unsubscribe of subscriptions) { + unsubscribe(); + } + subscriptions.clear(); + const idx = this.activeQuerySessions.indexOf(cleanup); + if (idx !== -1) + this.activeQuerySessions.splice(idx, 1); + }; + this.activeQuerySessions.push(cleanup); + return { + setTimer: (fn, ms) => { + const timer = this.clock.setTimeout(fn, ms); + timers.add(timer); + return timer; + }, + resetTimer: (existing, fn, ms) => { + if (existing) { + this.clock.clearTimeout(existing); + timers.delete(existing); + } + const timer = this.clock.setTimeout(fn, ms); + timers.add(timer); + return timer; + }, + subscribeInput: (handler) => { + const unsubscribe = this.subscribeInput(handler); + subscriptions.add(unsubscribe); + return () => { + if (!subscriptions.has(unsubscribe)) + return; + subscriptions.delete(unsubscribe); + unsubscribe(); + }; + }, + cleanup + }; + } + async detectOSCSupport(timeoutMs = 300) { + const out = this.stdout; + if (!out.isTTY || !this.stdin.isTTY) + return false; + return new Promise((resolve3) => { + const session = this.createQuerySession(); + let buffer = ""; + let settled = false; + const finish = (supported) => { + if (settled) + return; + settled = true; + session.cleanup(); + resolve3(supported); + }; + const onData = (chunk) => { + buffer += chunk.toString(); + OSC4_RESPONSE.lastIndex = 0; + if (OSC4_RESPONSE.test(buffer)) { + finish(true); + } + }; + session.setTimer(() => { + finish(false); + }, timeoutMs); + session.subscribeInput(onData); + this.writeOsc("\x1B]4;0;?\x07", true); + }); + } + async queryPalette(indices, timeoutMs = 1200, idleTimeoutMs = env.OTUI_PALETTE_IDLE_TIMEOUT_MS) { + const out = this.stdout; + const results = new Map; + indices.forEach((i) => results.set(i, null)); + if (!out.isTTY || !this.stdin.isTTY) { + return results; + } + return new Promise((resolve3) => { + const session = this.createQuerySession(); + let buffer = ""; + let idleTimer = null; + let settled = false; + const finish = () => { + if (settled) + return; + settled = true; + session.cleanup(); + resolve3(results); + }; + const onData = (chunk) => { + buffer += chunk.toString(); + let m; + OSC4_RESPONSE.lastIndex = 0; + while (m = OSC4_RESPONSE.exec(buffer)) { + const idx = parseInt(m[1], 10); + if (results.has(idx)) + results.set(idx, toHex(m[2], m[3], m[4], m[5])); + } + if (buffer.length > 8192) + buffer = buffer.slice(-4096); + const done = [...results.values()].filter((v) => v !== null).length; + if (done === results.size) { + finish(); + return; + } + idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs); + }; + session.setTimer(finish, timeoutMs); + session.subscribeInput(onData); + this.writeOsc(indices.map((i) => `\x1B]4;${i};?\x07`).join(""), true); + idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs); + }); + } + async querySpecialColors(timeoutMs = 1200, idleTimeoutMs = env.OTUI_PALETTE_IDLE_TIMEOUT_MS) { + const out = this.stdout; + const results = { + 10: null, + 11: null, + 12: null, + 13: null, + 14: null, + 15: null, + 16: null, + 17: null, + 19: null + }; + const queries = this.inTmux ? [10, 11, 12] : [10, 11, 12, 13, 14, 15, 16, 17, 19]; + if (!out.isTTY || !this.stdin.isTTY) { + return results; + } + return new Promise((resolve3) => { + const session = this.createQuerySession(); + let buffer = ""; + let idleTimer = null; + let settled = false; + const finish = () => { + if (settled) + return; + settled = true; + session.cleanup(); + resolve3(results); + }; + const onData = (chunk) => { + buffer += chunk.toString(); + let updated = false; + let m; + OSC_SPECIAL_RESPONSE.lastIndex = 0; + while (m = OSC_SPECIAL_RESPONSE.exec(buffer)) { + const idx = parseInt(m[1], 10); + if (idx in results) { + results[idx] = toHex(m[2], m[3], m[4], m[5]); + updated = true; + } + } + if (buffer.length > 8192) + buffer = buffer.slice(-4096); + if (queries.every((idx) => results[idx] !== null)) { + finish(); + return; + } + if (!updated) + return; + idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs); + }; + session.setTimer(finish, timeoutMs); + session.subscribeInput(onData); + this.writeOsc(queries.map((idx) => `\x1B]${idx};?\x07`).join("")); + idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs); + }); + } + async detect(options) { + const { timeout = 5000, size = 16 } = options || {}; + const supported = await this.detectOSCSupport(); + if (!supported) { + return { + palette: Array(size).fill(null), + defaultForeground: null, + defaultBackground: null, + cursorColor: null, + mouseForeground: null, + mouseBackground: null, + tekForeground: null, + tekBackground: null, + highlightBackground: null, + highlightForeground: null + }; + } + const indicesToQuery = [...Array(size).keys()]; + const idleTimeout = env.OTUI_PALETTE_IDLE_TIMEOUT_MS; + const [paletteResults, specialColors] = await Promise.all([ + this.queryPalette(indicesToQuery, timeout, idleTimeout), + this.querySpecialColors(timeout, idleTimeout) + ]); + return { + palette: [...Array(size).keys()].map((i) => paletteResults.get(i) ?? null), + defaultForeground: specialColors[10], + defaultBackground: specialColors[11], + cursorColor: specialColors[12], + mouseForeground: specialColors[13], + mouseBackground: specialColors[14], + tekForeground: specialColors[15], + tekBackground: specialColors[16], + highlightBackground: specialColors[17], + highlightForeground: specialColors[19] + }; + } +} +function createTerminalPalette(options) { + return new TerminalPalette(options); +} +var DEFAULT_FOREGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_FOREGROUND_RGB); +var DEFAULT_BACKGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_BACKGROUND_RGB); +var fallbackAnsi256Palette = null; +function getFallbackAnsi256Palette() { + if (!fallbackAnsi256Palette) { + fallbackAnsi256Palette = Array.from({ length: 256 }, (_, index) => { + const [r, g, b] = ansi256IndexToRgb(index); + return RGBA.fromInts(r, g, b); + }); + } + return fallbackAnsi256Palette; +} +function normalizeTerminalPalette(colors) { + const fallbackPalette = getFallbackAnsi256Palette(); + return { + palette: Array.from({ length: 256 }, (_, index) => { + const detected = colors?.palette[index]; + return detected ? RGBA.fromHex(detected) : RGBA.clone(fallbackPalette[index]); + }), + defaultForeground: colors?.defaultForeground ? RGBA.fromHex(colors.defaultForeground) : RGBA.clone(DEFAULT_FOREGROUND_FALLBACK), + defaultBackground: colors?.defaultBackground ? RGBA.fromHex(colors.defaultBackground) : RGBA.clone(DEFAULT_BACKGROUND_FALLBACK) + }; +} +function buildTerminalPaletteSignature(colors) { + const normalized = normalizeTerminalPalette(colors); + const paletteSignature = normalized.palette.map((color) => color.toInts().join(",")).join(";"); + return [ + paletteSignature, + normalized.defaultForeground.toInts().join(","), + normalized.defaultBackground.toInts().join(",") + ].join("|"); +} +// src/lib/paste.ts +var PASTE_TEXT_DECODER = new TextDecoder; +function decodePasteBytes(bytes) { + return PASTE_TEXT_DECODER.decode(bytes); +} +function stripAnsiSequences(text) { + return stripANSI(text); +} +// src/lib/detect-links.ts +var URL_SCOPES = ["markup.link.url", "string.special.url"]; +function detectLinks(chunks, context) { + const content = context.content; + const highlights = context.highlights; + const ranges = []; + for (let i = 0;i < highlights.length; i++) { + const [start, end, group] = highlights[i]; + if (!URL_SCOPES.includes(group)) + continue; + const url = content.slice(start, end); + ranges.push({ start, end, url }); + for (let j = i - 1;j >= 0; j--) { + const [labelStart, labelEnd, prev] = highlights[j]; + if (prev === "markup.link.label") { + ranges.push({ start: labelStart, end: labelEnd, url }); + break; + } + if (!prev.startsWith("markup.link")) + break; + } + } + if (ranges.length === 0) + return chunks; + let contentPos = 0; + for (const chunk of chunks) { + if (chunk.text.length <= 1) + continue; + const idx = content.indexOf(chunk.text, contentPos); + if (idx < 0) + continue; + for (const range of ranges) { + if (idx < range.end && idx + chunk.text.length > range.start) { + chunk.link = { url: range.url }; + break; + } + } + contentPos = idx + chunk.text.length; + } + return chunks; +} +// src/buffer.ts +function packDrawOptions(border2, shouldFill, titleAlignment, bottomTitleAlignment) { + let packed = 0; + if (border2 === true) { + packed |= 15; + } else if (Array.isArray(border2)) { + if (border2.includes("top")) + packed |= 8; + if (border2.includes("right")) + packed |= 4; + if (border2.includes("bottom")) + packed |= 2; + if (border2.includes("left")) + packed |= 1; + } + if (shouldFill) { + packed |= 1 << 4; + } + const alignmentMap = { + left: 0, + center: 1, + right: 2 + }; + const alignment = alignmentMap[titleAlignment]; + const bottomAlignment = alignmentMap[bottomTitleAlignment]; + packed |= alignment << 5; + packed |= bottomAlignment << 7; + return packed; +} + +class OptimizedBuffer { + static fbIdCounter = 0; + id; + lib; + bufferPtr; + _width; + _height; + _widthMethod; + respectAlpha = false; + _rawBuffers = null; + _destroyed = false; + get ptr() { + return this.bufferPtr; + } + guard() { + if (this._destroyed) + throw new Error(`Buffer ${this.id} is destroyed`); + } + ensureRawBufferViews() { + if (this._rawBuffers !== null) { + return; + } + const size = this._width * this._height; + const charPtr = this.lib.bufferGetCharPtr(this.bufferPtr); + const fgPtr = this.lib.bufferGetFgPtr(this.bufferPtr); + const bgPtr = this.lib.bufferGetBgPtr(this.bufferPtr); + const attributesPtr = this.lib.bufferGetAttributesPtr(this.bufferPtr); + this._rawBuffers = { + char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)), + fg: new Uint16Array(toArrayBuffer(fgPtr, 0, size * 4 * 2)), + bg: new Uint16Array(toArrayBuffer(bgPtr, 0, size * 4 * 2)), + attributes: new Uint32Array(toArrayBuffer(attributesPtr, 0, size * 4)) + }; + } + get buffers() { + this.guard(); + this.ensureRawBufferViews(); + return this._rawBuffers; + } + constructor(lib, ptr2, width, height, options) { + this.id = options.id || `fb_${OptimizedBuffer.fbIdCounter++}`; + this.lib = lib; + this.respectAlpha = options.respectAlpha || false; + this._width = width; + this._height = height; + this._widthMethod = options.widthMethod || "unicode"; + this.bufferPtr = ptr2; + } + static create(width, height, widthMethod, options = {}) { + const lib = resolveRenderLib(); + const respectAlpha = options.respectAlpha || false; + const id = options.id && options.id.trim() !== "" ? options.id : "unnamed buffer"; + const buffer = lib.createOptimizedBuffer(width, height, widthMethod, respectAlpha, id); + return buffer; + } + get widthMethod() { + return this._widthMethod; + } + get width() { + return this._width; + } + get height() { + return this._height; + } + setRespectAlpha(respectAlpha) { + this.guard(); + this.lib.bufferSetRespectAlpha(this.bufferPtr, respectAlpha); + this.respectAlpha = respectAlpha; + } + getNativeId() { + this.guard(); + return this.lib.bufferGetId(this.bufferPtr); + } + getRealCharBytes(addLineBreaks = false) { + this.guard(); + const realSize = this.lib.bufferGetRealCharSize(this.bufferPtr); + const outputBuffer = new Uint8Array(realSize); + const bytesWritten = this.lib.bufferWriteResolvedChars(this.bufferPtr, outputBuffer, addLineBreaks); + return outputBuffer.slice(0, bytesWritten); + } + getSpanLines() { + this.guard(); + const { char, fg: fg2, bg: bg2, attributes } = this.buffers; + const lines = []; + const CHAR_FLAG_CONTINUATION = 3221225472 | 0; + const CHAR_FLAG_MASK = 3221225472 | 0; + const realTextBytes = this.getRealCharBytes(true); + const realTextLines = new TextDecoder().decode(realTextBytes).split(` +`); + for (let y = 0;y < this._height; y++) { + const spans = []; + let currentSpan = null; + const lineChars = [...realTextLines[y] || ""]; + let charIdx = 0; + for (let x = 0;x < this._width; x++) { + const i = y * this._width + x; + const cp = char[i]; + const cellFg = RGBA.fromArray(fg2.slice(i * 4, i * 4 + 4)); + const cellBg = RGBA.fromArray(bg2.slice(i * 4, i * 4 + 4)); + const cellAttrs = attributes[i] & 255; + const isContinuation = (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION; + const cellChar = isContinuation ? "" : lineChars[charIdx++] ?? " "; + if (currentSpan && currentSpan.fg.equals(cellFg) && currentSpan.bg.equals(cellBg) && currentSpan.attributes === cellAttrs) { + currentSpan.text += cellChar; + currentSpan.width += 1; + } else { + if (currentSpan) { + spans.push(currentSpan); + } + currentSpan = { + text: cellChar, + fg: cellFg, + bg: cellBg, + attributes: cellAttrs, + width: 1 + }; + } + } + if (currentSpan) { + spans.push(currentSpan); + } + lines.push({ spans }); + } + return lines; + } + clear(bg2 = RGBA.fromValues(0, 0, 0, 1)) { + this.guard(); + this.lib.bufferClear(this.bufferPtr, bg2); + } + setCell(x, y, char, fg2, bg2, attributes = 0) { + this.guard(); + this.lib.bufferSetCell(this.bufferPtr, x, y, char, fg2, bg2, attributes); + } + setCellWithAlphaBlending(x, y, char, fg2, bg2, attributes = 0) { + this.guard(); + this.lib.bufferSetCellWithAlphaBlending(this.bufferPtr, x, y, char, fg2, bg2, attributes); + } + drawText(text, x, y, fg2, bg2, attributes = 0, selection2) { + this.guard(); + if (!selection2) { + this.lib.bufferDrawText(this.bufferPtr, text, x, y, fg2, bg2, attributes); + return; + } + const { start, end } = selection2; + let selectionBg; + let selectionFg; + if (selection2.bgColor) { + selectionBg = selection2.bgColor; + selectionFg = selection2.fgColor || fg2; + } else { + const defaultBg = bg2 || RGBA.fromValues(0, 0, 0, 0); + selectionFg = defaultBg.a > 0 ? defaultBg : RGBA.fromValues(0, 0, 0, 1); + selectionBg = fg2; + } + if (start > 0) { + const beforeText = text.slice(0, start); + this.lib.bufferDrawText(this.bufferPtr, beforeText, x, y, fg2, bg2, attributes); + } + if (end > start) { + const selectedText = text.slice(start, end); + this.lib.bufferDrawText(this.bufferPtr, selectedText, x + start, y, selectionFg, selectionBg, attributes); + } + if (end < text.length) { + const afterText = text.slice(end); + this.lib.bufferDrawText(this.bufferPtr, afterText, x + end, y, fg2, bg2, attributes); + } + } + fillRect(x, y, width, height, bg2) { + this.guard(); + this.lib.bufferFillRect(this.bufferPtr, x, y, width, height, bg2); + } + colorMatrix(matrix, cellMask, strength = 1, target = 3 /* Both */) { + this.guard(); + if (matrix.length !== 16) + throw new RangeError(`colorMatrix matrix must have length 16, got ${matrix.length}`); + const cellMaskCount = Math.floor(cellMask.length / 3); + this.lib.bufferColorMatrix(this.bufferPtr, ptr(matrix), ptr(cellMask), cellMaskCount, strength, target); + } + colorMatrixUniform(matrix, strength = 1, target = 3 /* Both */) { + this.guard(); + if (matrix.length !== 16) + throw new RangeError(`colorMatrixUniform matrix must have length 16, got ${matrix.length}`); + if (strength === 0) + return; + this.lib.bufferColorMatrixUniform(this.bufferPtr, ptr(matrix), strength, target); + } + drawFrameBuffer(destX, destY, frameBuffer, sourceX, sourceY, sourceWidth, sourceHeight) { + this.guard(); + this.lib.drawFrameBuffer(this.bufferPtr, destX, destY, frameBuffer.ptr, sourceX, sourceY, sourceWidth, sourceHeight); + } + destroy() { + if (this._destroyed) + return; + this._destroyed = true; + this._rawBuffers = null; + this.lib.destroyOptimizedBuffer(this.bufferPtr); + } + drawTextBuffer(textBufferView, x, y) { + this.guard(); + this.lib.bufferDrawTextBufferView(this.bufferPtr, textBufferView.ptr, x, y); + } + drawEditorView(editorView, x, y) { + this.guard(); + this.lib.bufferDrawEditorView(this.bufferPtr, editorView.ptr, x, y); + } + drawSuperSampleBuffer(x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow) { + this.guard(); + this.lib.bufferDrawSuperSampleBuffer(this.bufferPtr, x, y, toPointer(pixelDataPtr), pixelDataLength, format, alignedBytesPerRow); + } + drawPackedBuffer(dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) { + this.guard(); + this.lib.bufferDrawPackedBuffer(this.bufferPtr, toPointer(dataPtr), dataLen, posX, posY, terminalWidthCells, terminalHeightCells); + } + drawGrayscaleBuffer(posX, posY, intensities, srcWidth, srcHeight, fg2 = null, bg2 = null) { + this.guard(); + this.lib.bufferDrawGrayscaleBuffer(this.bufferPtr, posX, posY, ptr(intensities), srcWidth, srcHeight, fg2, bg2); + } + drawGrayscaleBufferSupersampled(posX, posY, intensities, srcWidth, srcHeight, fg2 = null, bg2 = null) { + this.guard(); + this.lib.bufferDrawGrayscaleBufferSupersampled(this.bufferPtr, posX, posY, ptr(intensities), srcWidth, srcHeight, fg2, bg2); + } + resize(width, height) { + this.guard(); + if (this._width === width && this._height === height) + return; + this._width = width; + this._height = height; + this._rawBuffers = null; + this.lib.bufferResize(this.bufferPtr, width, height); + } + drawBox(options) { + this.guard(); + const style = parseBorderStyle(options.borderStyle, "single"); + const borderChars = options.customBorderChars ?? BorderCharArrays[style]; + const packedOptions = packDrawOptions(options.border, options.shouldFill ?? false, options.titleAlignment || "left", options.bottomTitleAlignment || "left"); + this.lib.bufferDrawBox(this.bufferPtr, options.x, options.y, options.width, options.height, borderChars, packedOptions, options.borderColor, options.backgroundColor, options.titleColor ?? options.borderColor, options.title ?? null, options.bottomTitle ?? null); + } + pushScissorRect(x, y, width, height) { + this.guard(); + this.lib.bufferPushScissorRect(this.bufferPtr, x, y, width, height); + } + popScissorRect() { + this.guard(); + this.lib.bufferPopScissorRect(this.bufferPtr); + } + clearScissorRects() { + this.guard(); + this.lib.bufferClearScissorRects(this.bufferPtr); + } + pushOpacity(opacity) { + this.guard(); + this.lib.bufferPushOpacity(this.bufferPtr, Math.max(0, Math.min(1, opacity))); + } + popOpacity() { + this.guard(); + this.lib.bufferPopOpacity(this.bufferPtr); + } + getCurrentOpacity() { + this.guard(); + return this.lib.bufferGetCurrentOpacity(this.bufferPtr); + } + clearOpacity() { + this.guard(); + this.lib.bufferClearOpacity(this.bufferPtr); + } + encodeUnicode(text) { + this.guard(); + return this.lib.encodeUnicode(text, this._widthMethod); + } + freeUnicode(encoded) { + this.guard(); + this.lib.freeUnicode(encoded); + } + drawGrid(options) { + this.guard(); + const columnCount = Math.max(0, options.columnOffsets.length - 1); + const rowCount = Math.max(0, options.rowOffsets.length - 1); + this.lib.bufferDrawGrid(this.bufferPtr, options.borderChars, options.borderFg, options.borderBg, options.columnOffsets, columnCount, options.rowOffsets, rowCount, { + drawInner: options.drawInner, + drawOuter: options.drawOuter + }); + } + drawChar(char, x, y, fg2, bg2, attributes = 0) { + this.guard(); + this.lib.bufferDrawChar(this.bufferPtr, char, x, y, fg2, bg2, attributes); + } +} + +// src/text-buffer.ts +class TextBuffer { + lib; + bufferPtr; + _length = 0; + _byteSize = 0; + _lineInfo; + _destroyed = false; + _syntaxStyle; + _textBytes; + _memId; + _appendedChunks = []; + constructor(lib, ptr2) { + this.lib = lib; + this.bufferPtr = ptr2; + } + static create(widthMethod) { + const lib = resolveRenderLib(); + return lib.createTextBuffer(widthMethod); + } + guard() { + if (this._destroyed) + throw new Error("TextBuffer is destroyed"); + } + setText(text) { + this.guard(); + this._textBytes = this.lib.encoder.encode(text); + if (this._memId === undefined) { + this._memId = this.lib.textBufferRegisterMemBuffer(this.bufferPtr, this._textBytes, false); + } else if (!this.lib.textBufferReplaceMemBuffer(this.bufferPtr, this._memId, this._textBytes, false)) { + this._memId = this.lib.textBufferRegisterMemBuffer(this.bufferPtr, this._textBytes, false); + } + this.lib.textBufferSetTextFromMem(this.bufferPtr, this._memId); + this._length = this.lib.textBufferGetLength(this.bufferPtr); + this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr); + this._lineInfo = undefined; + this._appendedChunks = []; + } + append(text) { + this.guard(); + const textBytes = this.lib.encoder.encode(text); + this._appendedChunks.push(textBytes); + this.lib.textBufferAppend(this.bufferPtr, textBytes); + this._length = this.lib.textBufferGetLength(this.bufferPtr); + this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr); + this._lineInfo = undefined; + } + loadFile(path3) { + this.guard(); + const success = this.lib.textBufferLoadFile(this.bufferPtr, path3); + if (!success) { + throw new Error(`Failed to load file: ${path3}`); + } + this._length = this.lib.textBufferGetLength(this.bufferPtr); + this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr); + this._lineInfo = undefined; + this._textBytes = undefined; + } + setStyledText(text) { + this.guard(); + this.lib.textBufferSetStyledText(this.bufferPtr, text.chunks); + this._length = this.lib.textBufferGetLength(this.bufferPtr); + this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr); + this._lineInfo = undefined; + } + setDefaultFg(fg2) { + this.guard(); + this.lib.textBufferSetDefaultFg(this.bufferPtr, fg2); + } + setDefaultBg(bg2) { + this.guard(); + this.lib.textBufferSetDefaultBg(this.bufferPtr, bg2); + } + setDefaultAttributes(attributes) { + this.guard(); + this.lib.textBufferSetDefaultAttributes(this.bufferPtr, attributes); + } + resetDefaults() { + this.guard(); + this.lib.textBufferResetDefaults(this.bufferPtr); + } + getLineCount() { + this.guard(); + return this.lib.textBufferGetLineCount(this.bufferPtr); + } + get length() { + this.guard(); + return this._length; + } + get byteSize() { + this.guard(); + return this._byteSize; + } + get ptr() { + this.guard(); + return this.bufferPtr; + } + getPlainText() { + this.guard(); + if (this._byteSize === 0) + return ""; + const plainBytes = this.lib.getPlainTextBytes(this.bufferPtr, this._byteSize); + if (!plainBytes) + return ""; + return this.lib.decoder.decode(plainBytes); + } + getTextRange(startOffset, endOffset) { + this.guard(); + if (startOffset >= endOffset) + return ""; + if (this._byteSize === 0) + return ""; + const rangeBytes = this.lib.textBufferGetTextRange(this.bufferPtr, startOffset, endOffset, this._byteSize); + if (!rangeBytes) + return ""; + return this.lib.decoder.decode(rangeBytes); + } + addHighlightByCharRange(highlight) { + this.guard(); + this.lib.textBufferAddHighlightByCharRange(this.bufferPtr, highlight); + } + addHighlight(lineIdx, highlight) { + this.guard(); + this.lib.textBufferAddHighlight(this.bufferPtr, lineIdx, highlight); + } + removeHighlightsByRef(hlRef) { + this.guard(); + this.lib.textBufferRemoveHighlightsByRef(this.bufferPtr, hlRef); + } + clearLineHighlights(lineIdx) { + this.guard(); + this.lib.textBufferClearLineHighlights(this.bufferPtr, lineIdx); + } + clearAllHighlights() { + this.guard(); + this.lib.textBufferClearAllHighlights(this.bufferPtr); + } + getLineHighlights(lineIdx) { + this.guard(); + return this.lib.textBufferGetLineHighlights(this.bufferPtr, lineIdx); + } + getHighlightCount() { + this.guard(); + return this.lib.textBufferGetHighlightCount(this.bufferPtr); + } + setSyntaxStyle(style) { + this.guard(); + if (this.lib.textBufferSetSyntaxStyle(this.bufferPtr, style?.ptr ?? null)) { + this._syntaxStyle = style ?? undefined; + } + } + getSyntaxStyle() { + this.guard(); + return this._syntaxStyle ?? null; + } + setTabWidth(width) { + this.guard(); + this.lib.textBufferSetTabWidth(this.bufferPtr, width); + } + getTabWidth() { + this.guard(); + return this.lib.textBufferGetTabWidth(this.bufferPtr); + } + clear() { + this.guard(); + this.lib.textBufferClear(this.bufferPtr); + this._length = 0; + this._byteSize = 0; + this._lineInfo = undefined; + this._textBytes = undefined; + this._appendedChunks = []; + } + reset() { + this.guard(); + this.lib.textBufferReset(this.bufferPtr); + this._length = 0; + this._byteSize = 0; + this._lineInfo = undefined; + this._textBytes = undefined; + this._memId = undefined; + this._appendedChunks = []; + } + destroy() { + if (this._destroyed) + return; + this._destroyed = true; + this.lib.destroyTextBuffer(this.bufferPtr); + } +} + +// ../../node_modules/.bun/bun-ffi-structs@0.2.3+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js +var FFI_LOAD_ERROR = "bun-ffi-structs requires Bun or Node.js with node:ffi enabled (--experimental-ffi --allow-ffi)."; +var backend2 = await loadBackend2(); +function unavailable2(cause) { + throw new Error(FFI_LOAD_ERROR, { + cause: cause instanceof Error ? cause : undefined + }); +} +function createUnsupportedBackend2(cause) { + return { + ptr() { + return unavailable2(cause); + }, + toArrayBuffer() { + return unavailable2(cause); + } + }; +} +async function loadBackend2() { + if (typeof process !== "undefined" && "bun" in process.versions) { + return createBunBackend2(await importModule("bun:ffi")); + } + try { + return createNodeBackend2(await importModule("node:ffi")); + } catch (error) { + return createUnsupportedBackend2(error); + } +} +function importModule(specifier) { + return import(specifier).then((module) => module.default ?? module); +} +function createBunBackend2(bun2) { + return { + ptr: bun2.ptr, + toArrayBuffer(pointer, offset, length) { + return bun2.toArrayBuffer(toBunPointer2(pointer), offset, length); + } + }; +} +function createNodeBackend2(nodeFfi) { + return { + ptr(value) { + if (ArrayBuffer.isView(value)) { + return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset); + } + if (value instanceof ArrayBuffer) { + return nodeFfi.getRawPointer(value); + } + throw new TypeError("node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values."); + }, + toArrayBuffer(pointer, offset, length) { + return nodeFfi.toArrayBuffer(toBigIntPointer2(pointer) + BigInt(offset ?? 0), length, false); + } + }; +} +function toBigIntPointer2(pointer) { + return typeof pointer === "bigint" ? pointer : BigInt(pointer); +} +function toBunPointer2(pointer) { + return typeof pointer === "bigint" ? Number(pointer) : pointer; +} +var ptr2 = backend2.ptr; +var toArrayBuffer2 = backend2.toArrayBuffer; +function fatalError(...args) { + const message = args.join(" "); + console.error("FATAL ERROR:", message); + throw new Error(message); +} +var pointerSize = process.arch === "x64" || process.arch === "arm64" ? 8 : 4; +var isBun2 = typeof process !== "undefined" && "bun" in process.versions; +var typeSizes = { + u8: 1, + bool_u8: 1, + bool_u32: 4, + u16: 2, + i16: 2, + u32: 4, + u64: 8, + f32: 4, + f64: 8, + pointer: pointerSize, + i32: 4, + i64: 8 +}; +var primitiveKeys = Object.keys(typeSizes); +function isPrimitiveType(type) { + return typeof type === "string" && primitiveKeys.includes(type); +} +var typeAlignments = { ...typeSizes }; +var typeGetters = { + u8: (view, offset) => view.getUint8(offset), + bool_u8: (view, offset) => Boolean(view.getUint8(offset)), + bool_u32: (view, offset) => Boolean(view.getUint32(offset, true)), + u16: (view, offset) => view.getUint16(offset, true), + i16: (view, offset) => view.getInt16(offset, true), + u32: (view, offset) => view.getUint32(offset, true), + u64: (view, offset) => view.getBigUint64(offset, true), + f32: (view, offset) => view.getFloat32(offset, true), + f64: (view, offset) => view.getFloat64(offset, true), + i32: (view, offset) => view.getInt32(offset, true), + i64: (view, offset) => view.getBigInt64(offset, true), + pointer: (view, offset) => pointerSize === 8 ? view.getBigUint64(offset, true) : BigInt(view.getUint32(offset, true)) +}; +function isObjectPointerDef(type) { + return typeof type === "object" && type !== null && type.__type === "objectPointer"; +} +function alignOffset(offset, align) { + return offset + (align - 1) & ~(align - 1); +} +function enumTypeError(value) { + throw new TypeError(`Invalid enum value: ${value}`); +} +function defineEnum(mapping, base = "u32") { + const reverse2 = Object.fromEntries(Object.entries(mapping).map(([k, v]) => [v, k])); + return { + __type: "enum", + type: base, + to(value) { + return typeof value === "number" ? value : mapping[value] ?? enumTypeError(String(value)); + }, + from(value) { + return reverse2[value] ?? enumTypeError(String(value)); + }, + enum: mapping + }; +} +function isEnum(type) { + return typeof type === "object" && type.__type === "enum"; +} +function isStruct(type) { + return typeof type === "object" && type.__type === "struct"; +} +function primitivePackers(type) { + let pack; + let unpack; + switch (type) { + case "u8": + pack = (view, off, val) => view.setUint8(off, val); + unpack = (view, off) => view.getUint8(off); + break; + case "bool_u8": + pack = (view, off, val) => view.setUint8(off, val ? 1 : 0); + unpack = (view, off) => Boolean(view.getUint8(off)); + break; + case "bool_u32": + pack = (view, off, val) => view.setUint32(off, val ? 1 : 0, true); + unpack = (view, off) => Boolean(view.getUint32(off, true)); + break; + case "u16": + pack = (view, off, val) => view.setUint16(off, val, true); + unpack = (view, off) => view.getUint16(off, true); + break; + case "i16": + pack = (view, off, val) => view.setInt16(off, val, true); + unpack = (view, off) => view.getInt16(off, true); + break; + case "u32": + pack = (view, off, val) => view.setUint32(off, val, true); + unpack = (view, off) => view.getUint32(off, true); + break; + case "i32": + pack = (view, off, val) => view.setInt32(off, val, true); + unpack = (view, off) => view.getInt32(off, true); + break; + case "i64": + pack = (view, off, val) => view.setBigInt64(off, BigInt(val), true); + unpack = (view, off) => view.getBigInt64(off, true); + break; + case "u64": + pack = (view, off, val) => view.setBigUint64(off, BigInt(val), true); + unpack = (view, off) => view.getBigUint64(off, true); + break; + case "f32": + pack = (view, off, val) => view.setFloat32(off, val, true); + unpack = (view, off) => view.getFloat32(off, true); + break; + case "f64": + pack = (view, off, val) => view.setFloat64(off, val, true); + unpack = (view, off) => view.getFloat64(off, true); + break; + case "pointer": + pack = (view, off, val) => { + pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true); + }; + unpack = (view, off) => { + if (pointerSize === 8) { + const value = view.getBigUint64(off, true); + return isBun2 ? Number(value) : value; + } + return view.getUint32(off, true); + }; + break; + default: + fatalError(`Unsupported primitive type: ${type}`); + } + return { pack, unpack }; +} +var { pack: pointerPacker, unpack: pointerUnpacker } = primitivePackers("pointer"); +var retainedPointerTargets = new WeakMap; +function retainPointerTarget(owner, target) { + const retained = retainedPointerTargets.get(owner); + if (retained) { + retained.push(target); + } else { + retainedPointerTargets.set(owner, [target]); + } +} +function retainIfPointerTargets(owner, target) { + if (retainedPointerTargets.has(target)) { + retainPointerTarget(owner, target); + } +} +function isNullPointer(pointer) { + return pointer == null || pointer === 0 || pointer === 0n; +} +function toItemCount(length) { + return typeof length === "bigint" ? Number(length) : length; +} +function packObjectArray(val) { + const buffer = new ArrayBuffer(val.length * pointerSize); + const bufferView = new DataView(buffer); + for (let i = 0;i < val.length; i++) { + const instance = val[i]; + const ptrValue = instance?.ptr ?? null; + pointerPacker(bufferView, i * pointerSize, ptrValue); + } + return bufferView; +} +var encoder = new TextEncoder; +var decoder = new TextDecoder; +function defineStruct(fields, structDefOptions) { + let offset = 0; + let maxAlign = 1; + const layout = []; + const lengthOfFields = {}; + const lengthOfRequested = []; + const arrayFieldsMetadata = {}; + for (const [name, typeOrStruct, options = {}] of fields) { + if (options.condition && !options.condition()) { + continue; + } + let size = 0, align = 0; + let pack; + let unpack; + let needsLengthOf = false; + let lengthOfDef = null; + if (isPrimitiveType(typeOrStruct)) { + size = typeSizes[typeOrStruct]; + align = typeAlignments[typeOrStruct]; + ({ pack, unpack } = primitivePackers(typeOrStruct)); + } else if (typeof typeOrStruct === "string" && typeOrStruct === "cstring") { + size = pointerSize; + align = pointerSize; + pack = (view, off, val) => { + if (!val) { + pointerPacker(view, off, null); + return; + } + const bytes = encoder.encode(val + "\x00"); + const bufPtr = ptr2(bytes); + pointerPacker(view, off, bufPtr); + retainPointerTarget(view.buffer, bytes); + }; + unpack = (view, off) => { + const ptrVal = pointerUnpacker(view, off); + return ptrVal; + }; + } else if (typeof typeOrStruct === "string" && typeOrStruct === "char*") { + size = pointerSize; + align = pointerSize; + pack = (view, off, val) => { + if (!val) { + pointerPacker(view, off, null); + return; + } + const bytes = encoder.encode(val); + const bufPtr = ptr2(bytes); + pointerPacker(view, off, bufPtr); + retainPointerTarget(view.buffer, bytes); + }; + unpack = (view, off) => { + const ptrVal = pointerUnpacker(view, off); + return ptrVal; + }; + needsLengthOf = true; + } else if (isEnum(typeOrStruct)) { + const base = typeOrStruct.type; + size = typeSizes[base]; + align = typeAlignments[base]; + const { pack: packEnum } = primitivePackers(base); + pack = (view, off, val) => { + const num = typeOrStruct.to(val); + packEnum(view, off, num); + }; + unpack = (view, off) => { + const raw = typeGetters[base](view, off); + return typeOrStruct.from(raw); + }; + } else if (isStruct(typeOrStruct)) { + if (options.asPointer === true) { + size = pointerSize; + align = pointerSize; + pack = (view, off, val, obj, options2) => { + if (!val) { + pointerPacker(view, off, null); + return; + } + const nestedBuf = typeOrStruct.pack(val, options2); + pointerPacker(view, off, ptr2(nestedBuf)); + retainPointerTarget(view.buffer, nestedBuf); + }; + unpack = (view, off) => { + throw new Error("Not implemented yet"); + }; + } else { + size = typeOrStruct.size; + align = typeOrStruct.align; + pack = (view, off, val, obj, options2) => { + const nestedBuf = typeOrStruct.pack(val, options2); + const nestedView = new Uint8Array(nestedBuf); + const dView = new Uint8Array(view.buffer); + dView.set(nestedView, off); + retainIfPointerTargets(view.buffer, nestedBuf); + }; + unpack = (view, off) => { + const slice = view.buffer.slice(off, off + size); + return typeOrStruct.unpack(slice); + }; + } + } else if (isObjectPointerDef(typeOrStruct)) { + size = pointerSize; + align = pointerSize; + pack = (view, off, value) => { + const ptrValue = value?.ptr ?? null; + if (ptrValue === undefined) { + console.warn(`Field '${name}' expected object with '.ptr' property, but got undefined pointer value from:`, value); + pointerPacker(view, off, null); + } else { + pointerPacker(view, off, ptrValue); + } + }; + unpack = (view, off) => { + return pointerUnpacker(view, off); + }; + } else if (Array.isArray(typeOrStruct) && typeOrStruct.length === 1 && typeOrStruct[0] !== undefined) { + const [def] = typeOrStruct; + size = pointerSize; + align = pointerSize; + let arrayElementSize; + if (isEnum(def)) { + arrayElementSize = typeSizes[def.type]; + pack = (view, off, val, obj) => { + if (!val || val.length === 0) { + pointerPacker(view, off, null); + return; + } + const buffer = new ArrayBuffer(val.length * arrayElementSize); + const bufferView = new DataView(buffer); + for (let i = 0;i < val.length; i++) { + const num = def.to(val[i]); + bufferView.setUint32(i * arrayElementSize, num, true); + } + pointerPacker(view, off, ptr2(buffer)); + retainPointerTarget(view.buffer, buffer); + }; + unpack = null; + needsLengthOf = true; + lengthOfDef = def; + } else if (isStruct(def)) { + arrayElementSize = def.size; + pack = (view, off, val, obj, options2) => { + if (!val || val.length === 0) { + pointerPacker(view, off, null); + return; + } + const buffer = new ArrayBuffer(val.length * arrayElementSize); + const bufferView = new DataView(buffer); + for (let i = 0;i < val.length; i++) { + def.packInto(val[i], bufferView, i * arrayElementSize, options2); + } + pointerPacker(view, off, ptr2(buffer)); + retainPointerTarget(view.buffer, buffer); + }; + unpack = (view, off) => { + throw new Error("Not implemented yet"); + }; + } else if (isPrimitiveType(def)) { + arrayElementSize = typeSizes[def]; + const { pack: primitivePack } = primitivePackers(def); + pack = (view, off, val) => { + if (!val || val.length === 0) { + pointerPacker(view, off, null); + return; + } + const buffer = new ArrayBuffer(val.length * arrayElementSize); + const bufferView = new DataView(buffer); + for (let i = 0;i < val.length; i++) { + primitivePack(bufferView, i * arrayElementSize, val[i]); + } + pointerPacker(view, off, ptr2(buffer)); + retainPointerTarget(view.buffer, buffer); + }; + unpack = null; + needsLengthOf = true; + lengthOfDef = def; + } else if (isObjectPointerDef(def)) { + arrayElementSize = pointerSize; + pack = (view, off, val) => { + if (!val || val.length === 0) { + pointerPacker(view, off, null); + return; + } + const packedView = packObjectArray(val); + pointerPacker(view, off, ptr2(packedView.buffer)); + retainPointerTarget(view.buffer, packedView.buffer); + }; + unpack = () => { + throw new Error("not implemented yet"); + }; + } else { + throw new Error(`Unsupported array element type for ${name}: ${JSON.stringify(def)}`); + } + const lengthOfField = Object.values(lengthOfFields).find((f) => f.lengthOf === name); + if (lengthOfField && isPrimitiveType(lengthOfField.type)) { + const { pack: lengthPack } = primitivePackers(lengthOfField.type); + arrayFieldsMetadata[name] = { + elementSize: arrayElementSize, + arrayOffset: offset, + lengthOffset: lengthOfField.offset, + lengthPack + }; + } + } else { + throw new Error(`Unsupported field type for ${name}: ${JSON.stringify(typeOrStruct)}`); + } + offset = alignOffset(offset, align); + if (options.unpackTransform) { + const originalUnpack = unpack; + unpack = (view, off) => options.unpackTransform(originalUnpack(view, off)); + } + if (options.packTransform) { + const originalPack = pack; + pack = (view, off, val, obj, packOptions) => originalPack(view, off, options.packTransform(val), obj, packOptions); + } + if (options.optional) { + const originalPack = pack; + if (isStruct(typeOrStruct) && !options.asPointer) { + pack = (view, off, val, obj, packOptions) => { + if (val || options.mapOptionalInline) { + originalPack(view, off, val, obj, packOptions); + } + }; + } else { + pack = (view, off, val, obj, packOptions) => originalPack(view, off, val ?? 0, obj, packOptions); + } + } + if (options.lengthOf) { + const originalPack = pack; + pack = (view, off, val, obj, packOptions) => { + const targetValue = obj[options.lengthOf]; + let length = 0; + if (targetValue) { + if (typeof targetValue === "string") { + length = Buffer.byteLength(targetValue); + } else { + length = targetValue.length; + } + } + return originalPack(view, off, length, obj, packOptions); + }; + } + let validateFunctions; + if (options.validate) { + validateFunctions = Array.isArray(options.validate) ? options.validate : [options.validate]; + } + const layoutField = { + name, + offset, + size, + align, + validate: validateFunctions, + optional: !!options.optional || !!options.lengthOf || options.default !== undefined, + default: options.default, + pack, + unpack, + type: typeOrStruct, + lengthOf: options.lengthOf + }; + layout.push(layoutField); + if (options.lengthOf) { + lengthOfFields[options.lengthOf] = layoutField; + } + if (needsLengthOf) { + const def = typeof typeOrStruct === "string" && typeOrStruct === "char*" ? "char*" : lengthOfDef; + if (!def) + fatalError(`Internal error: needsLengthOf=true but def is null for ${name}`); + lengthOfRequested.push({ requester: layoutField, def }); + } + offset += size; + maxAlign = Math.max(maxAlign, align); + } + for (const { requester, def } of lengthOfRequested) { + const lengthOfField = lengthOfFields[requester.name]; + if (!lengthOfField) { + if (def === "char*") { + continue; + } + throw new Error(`lengthOf field not found for array field ${requester.name}`); + } + if (def === "char*") { + const relativeOffset = lengthOfField.offset - requester.offset; + requester.unpack = (view, off) => { + const ptrAddress = pointerUnpacker(view, off); + const length = lengthOfField.unpack(view, off + relativeOffset); + if (isNullPointer(ptrAddress)) { + return null; + } + const byteLength = toItemCount(length); + if (byteLength === 0) { + return ""; + } + const buffer = toArrayBuffer2(ptrAddress, 0, byteLength); + return decoder.decode(buffer); + }; + } else if (isPrimitiveType(def)) { + const elemSize = typeSizes[def]; + const { unpack: primitiveUnpack } = primitivePackers(def); + const relativeOffset = lengthOfField.offset - requester.offset; + requester.unpack = (view, off) => { + const result = []; + const length = lengthOfField.unpack(view, off + relativeOffset); + const itemCount = toItemCount(length); + const ptrAddress = pointerUnpacker(view, off); + if (isNullPointer(ptrAddress) && itemCount > 0) { + throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`); + } + if (isNullPointer(ptrAddress) || itemCount === 0) { + return []; + } + const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize); + const bufferView = new DataView(buffer); + for (let i = 0;i < itemCount; i++) { + result.push(primitiveUnpack(bufferView, i * elemSize)); + } + return result; + }; + } else { + const elemSize = def.type === "u32" ? 4 : 8; + const relativeOffset = lengthOfField.offset - requester.offset; + requester.unpack = (view, off) => { + const result = []; + const length = lengthOfField.unpack(view, off + relativeOffset); + const itemCount = toItemCount(length); + const ptrAddress = pointerUnpacker(view, off); + if (isNullPointer(ptrAddress) && itemCount > 0) { + throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`); + } + if (isNullPointer(ptrAddress) || itemCount === 0) { + return []; + } + const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize); + const bufferView = new DataView(buffer); + for (let i = 0;i < itemCount; i++) { + result.push(def.from(bufferView.getUint32(i * elemSize, true))); + } + return result; + }; + } + } + const totalSize = alignOffset(offset, maxAlign); + const description = layout.map((f) => ({ + name: f.name, + offset: f.offset, + size: f.size, + align: f.align, + optional: f.optional, + type: f.type, + lengthOf: f.lengthOf + })); + const layoutByName = new Map(description.map((f) => [f.name, f])); + const arrayFields = new Map(Object.entries(arrayFieldsMetadata)); + return { + __type: "struct", + size: totalSize, + align: maxAlign, + hasMapValue: !!structDefOptions?.mapValue, + layoutByName, + arrayFields, + pack(obj, options) { + const buf = new ArrayBuffer(totalSize); + const view = new DataView(buf); + let mappedObj = obj; + if (structDefOptions?.mapValue) { + mappedObj = structDefOptions.mapValue(obj); + } + for (const field of layout) { + const value = mappedObj[field.name] ?? field.default; + if (!field.optional && value === undefined) { + fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`); + } + if (field.validate) { + for (const validateFn of field.validate) { + validateFn(value, field.name, { + hints: options?.validationHints, + input: mappedObj + }); + } + } + field.pack(view, field.offset, value, mappedObj, options); + } + return view.buffer; + }, + packInto(obj, view, offset2, options) { + let mappedObj = obj; + if (structDefOptions?.mapValue) { + mappedObj = structDefOptions.mapValue(obj); + } + for (const field of layout) { + const value = mappedObj[field.name] ?? field.default; + if (!field.optional && value === undefined) { + console.warn(`packInto missing value for non-optional field '${field.name}' at offset ${offset2 + field.offset}. Writing default or zero.`); + } + if (field.validate) { + for (const validateFn of field.validate) { + validateFn(value, field.name, { + hints: options?.validationHints, + input: mappedObj + }); + } + } + field.pack(view, offset2 + field.offset, value, mappedObj, options); + } + }, + unpack(buf) { + if (buf.byteLength < totalSize) { + fatalError(`Buffer size (${buf.byteLength}) is smaller than struct size (${totalSize}) for unpacking.`); + } + const view = new DataView(buf); + const result = structDefOptions?.default ? { ...structDefOptions.default } : {}; + for (const field of layout) { + if (!field.unpack) { + continue; + } + try { + result[field.name] = field.unpack(view, field.offset); + } catch (e) { + console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, e); + throw e; + } + } + if (structDefOptions?.reduceValue) { + return structDefOptions.reduceValue(result); + } + return result; + }, + packList(objects, options) { + if (objects.length === 0) { + return new ArrayBuffer(0); + } + const buffer = new ArrayBuffer(totalSize * objects.length); + const view = new DataView(buffer); + for (let i = 0;i < objects.length; i++) { + let mappedObj = objects[i]; + if (structDefOptions?.mapValue) { + mappedObj = structDefOptions.mapValue(objects[i]); + } + for (const field of layout) { + const value = mappedObj[field.name] ?? field.default; + if (!field.optional && value === undefined) { + fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`); + } + if (field.validate) { + for (const validateFn of field.validate) { + validateFn(value, field.name, { + hints: options?.validationHints, + input: mappedObj + }); + } + } + field.pack(view, i * totalSize + field.offset, value, mappedObj, options); + } + } + return buffer; + }, + unpackList(buf, count) { + if (count === 0) { + return []; + } + const expectedSize = totalSize * count; + if (buf.byteLength < expectedSize) { + fatalError(`Buffer size (${buf.byteLength}) is smaller than expected size (${expectedSize}) for unpacking ${count} structs.`); + } + const view = new DataView(buf); + const results = []; + for (let i = 0;i < count; i++) { + const offset2 = i * totalSize; + const result = structDefOptions?.default ? { ...structDefOptions.default } : {}; + for (const field of layout) { + if (!field.unpack) { + continue; + } + try { + result[field.name] = field.unpack(view, offset2 + field.offset); + } catch (e) { + console.error(`Error unpacking field '${field.name}' at index ${i}, offset ${offset2 + field.offset}:`, e); + throw e; + } + } + if (structDefOptions?.reduceValue) { + results.push(structDefOptions.reduceValue(result)); + } else { + results.push(result); + } + } + return results; + }, + describe() { + return description; + } + }; +} + +// src/zig-structs.ts +var rgbaPackTransform = (rgba) => rgba ? ptr(rgba.buffer) : null; +var rgbaUnpackTransform = (ptr3) => ptr3 ? RGBA.fromArray(new Uint16Array(toArrayBuffer(ptr3, 0, 8))) : undefined; +var StyledChunkStruct = defineStruct([ + ["text", "char*"], + ["text_len", "u64", { lengthOf: "text" }], + [ + "fg", + "pointer", + { + optional: true, + packTransform: rgbaPackTransform, + unpackTransform: rgbaUnpackTransform + } + ], + [ + "bg", + "pointer", + { + optional: true, + packTransform: rgbaPackTransform, + unpackTransform: rgbaUnpackTransform + } + ], + ["attributes", "u32", { default: 0 }], + ["link", "char*", { default: "" }], + ["link_len", "u64", { lengthOf: "link" }] +], { + mapValue: (chunk) => { + const normalizedFg = normalizeColorValue(chunk.fg ?? null); + const normalizedBg = normalizeColorValue(chunk.bg ?? null); + if (!chunk.link || typeof chunk.link === "string") { + return { + ...chunk, + fg: normalizedFg?.rgba ?? null, + bg: normalizedBg?.rgba ?? null + }; + } + return { + ...chunk, + fg: normalizedFg?.rgba ?? null, + bg: normalizedBg?.rgba ?? null, + link: chunk.link.url + }; + } +}); +var HighlightStruct = defineStruct([ + ["start", "u32"], + ["end", "u32"], + ["styleId", "u32"], + ["priority", "u8", { default: 0 }], + ["hlRef", "u16", { default: 0 }] +]); +var LogicalCursorStruct = defineStruct([ + ["row", "u32"], + ["col", "u32"], + ["offset", "u32"] +]); +var VisualCursorStruct = defineStruct([ + ["visualRow", "u32"], + ["visualCol", "u32"], + ["logicalRow", "u32"], + ["logicalCol", "u32"], + ["offset", "u32"] +]); +var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, "u8"); +var TerminalMultiplexerEnum = defineEnum({ none: 0, tmux: 1, zellij: 2, screen: 3, unknown: 4 }, "u8"); +var TerminalCapabilitiesStruct = defineStruct([ + ["kitty_keyboard", "bool_u8"], + ["kitty_graphics", "bool_u8"], + ["rgb", "bool_u8"], + ["ansi256", "bool_u8"], + ["unicode", UnicodeMethodEnum], + ["sgr_pixels", "bool_u8"], + ["color_scheme_updates", "bool_u8"], + ["explicit_width", "bool_u8"], + ["scaled_text", "bool_u8"], + ["sixel", "bool_u8"], + ["focus_tracking", "bool_u8"], + ["sync", "bool_u8"], + ["bracketed_paste", "bool_u8"], + ["hyperlinks", "bool_u8"], + ["osc52", "bool_u8"], + ["notifications", "bool_u8"], + ["explicit_cursor_positioning", "bool_u8"], + ["remote", "bool_u8"], + ["multiplexer", TerminalMultiplexerEnum], + ["term_name", "char*"], + ["term_name_len", "u64", { lengthOf: "term_name" }], + ["term_version", "char*"], + ["term_version_len", "u64", { lengthOf: "term_version" }], + ["term_from_xtversion", "bool_u8"] +]); +var EncodedCharStruct = defineStruct([ + ["width", "u8"], + ["char", "u32"] +]); +var LineInfoStruct = defineStruct([ + ["startCols", ["u32"]], + ["startColsLen", "u32", { lengthOf: "startCols" }], + ["widthCols", ["u32"]], + ["widthColsLen", "u32", { lengthOf: "widthCols" }], + ["sources", ["u32"]], + ["sourcesLen", "u32", { lengthOf: "sources" }], + ["wraps", ["u32"]], + ["wrapsLen", "u32", { lengthOf: "wraps" }], + ["widthColsMax", "u32"] +]); +var MeasureResultStruct = defineStruct([ + ["lineCount", "u32"], + ["widthColsMax", "u32"] +]); +var CursorStateStruct = defineStruct([ + ["x", "u32"], + ["y", "u32"], + ["visible", "bool_u8"], + ["style", "u8"], + ["blinking", "bool_u8"], + ["r", "f32"], + ["g", "f32"], + ["b", "f32"], + ["a", "f32"] +]); +var CursorStyleOptionsStruct = defineStruct([ + ["style", "u8", { default: 255 }], + ["blinking", "u8", { default: 255 }], + [ + "color", + "pointer", + { + optional: true, + packTransform: rgbaPackTransform, + unpackTransform: rgbaUnpackTransform + } + ], + ["cursor", "u8", { default: 255 }] +]); +var GridDrawOptionsStruct = defineStruct([ + ["drawInner", "bool_u8", { default: true }], + ["drawOuter", "bool_u8", { default: true }] +]); +var BuildOptionsStruct = defineStruct([ + ["gpaSafeStats", "bool_u8"], + ["gpaMemoryLimitTracking", "bool_u8"] +]); +var AllocatorStatsStruct = defineStruct([ + ["totalRequestedBytes", "u64"], + ["activeAllocations", "u64"], + ["smallAllocations", "u64"], + ["largeAllocations", "u64"], + ["requestedBytesValid", "bool_u8"] +]); +var NativeRenderStatsStruct = defineStruct([ + ["lastFrameTime", "f64"], + ["averageFrameTime", "f64"], + ["renderTime", "f64"], + ["stdoutWriteTime", "f64"], + ["frameCount", "u64"], + ["cellsUpdated", "u32"], + ["averageCellsUpdated", "u32"], + ["renderTimeValid", "bool_u8"], + ["stdoutWriteTimeValid", "bool_u8"] +]); +var GrowthPolicyEnum = defineEnum({ grow: 0, block: 1 }, "u8"); +var NativeSpanFeedOptionsStruct = defineStruct([ + ["chunkSize", "u32", { default: 64 * 1024 }], + ["initialChunks", "u32", { default: 2 }], + ["maxBytes", "u64", { default: 0n }], + ["growthPolicy", GrowthPolicyEnum, { default: "grow" }], + ["autoCommitOnFull", "bool_u8", { default: true }], + ["spanQueueCapacity", "u32", { default: 0 }] +]); +var NativeSpanFeedStatsStruct = defineStruct([ + ["bytesWritten", "u64"], + ["spansCommitted", "u64"], + ["chunks", "u32"], + ["pendingSpans", "u32"] +]); +var SpanInfoStruct = defineStruct([ + ["chunkPtr", "pointer"], + ["offset", "u32"], + ["len", "u32"], + ["chunkIndex", "u32"], + ["reserved", "u32", { default: 0 }] +], { + reduceValue: (value) => ({ + chunkPtr: value.chunkPtr, + offset: value.offset, + len: value.len, + chunkIndex: value.chunkIndex + }) +}); +var ReserveInfoStruct = defineStruct([ + ["ptr", "pointer"], + ["len", "u32"], + ["reserved", "u32", { default: 0 }] +], { + reduceValue: (value) => ({ + ptr: value.ptr, + len: value.len + }) +}); +var AudioCreateOptionsStruct = defineStruct([ + ["sampleRate", "u32", { default: 48000 }], + ["playbackChannels", "u32", { default: 2 }] +]); +var AudioStartOptionsStruct = defineStruct([ + ["periodSizeInFrames", "u32", { default: 0 }], + ["periodSizeInMilliseconds", "u32", { default: 0 }], + ["periods", "u32", { default: 0 }], + ["performanceProfile", "u8", { default: 0 }], + ["shareMode", "u8", { default: 0 }], + ["noPreSilencedOutputBuffer", "bool_u8", { default: false }], + ["noClip", "bool_u8", { default: false }], + ["noDisableDenormals", "bool_u8", { default: false }], + ["noFixedSizedCallback", "bool_u8", { default: false }], + ["wasapiNoAutoConvertSrc", "bool_u8", { default: false }], + ["wasapiNoDefaultQualitySrc", "bool_u8", { default: false }], + ["alsaNoMMap", "bool_u8", { default: false }], + ["alsaNoAutoFormat", "bool_u8", { default: false }], + ["alsaNoAutoChannels", "bool_u8", { default: false }], + ["alsaNoAutoResample", "bool_u8", { default: false }] +]); +var AudioVoiceOptionsStruct = defineStruct([ + ["volume", "f32", { default: 1 }], + ["pan", "f32", { default: 0 }], + ["loop", "bool_u8", { default: false }], + ["groupId", "u32", { default: 0 }] +]); +var AudioStatsStruct = defineStruct([ + ["soundsLoaded", "u32"], + ["voicesActive", "u32"], + ["framesMixed", "u64"], + ["lockMisses", "u32"], + ["lastPeak", "f32"], + ["lastRms", "f32"] +]); + +// src/zig.ts +registerEnvVar({ + name: "OPENTUI_LIBC", + description: "Select Linux native libc package. Supported values: glibc, musl.", + type: "string", + default: "" +}); +function validateLinuxLibcOverride() { + const libc = process.env.OPENTUI_LIBC; + if (libc === undefined || libc === "" || libc === "glibc" || libc === "musl") + return; + throw new Error(`On Linux, OPENTUI_LIBC must be unset, empty, "glibc", or "musl", got "${libc}"`); +} +async function resolveNativePackage() { + if (process.platform === "darwin") { + if (process.arch === "x64") + return await import("@opentui/core-darwin-x64"); + if (process.arch === "arm64") + return await import("@opentui/core-darwin-arm64"); + } + if (process.platform === "linux") { + validateLinuxLibcOverride(); + if (process.arch === "x64") { + if (process.env.OPENTUI_LIBC === "musl") { + return await import("@opentui/core-linux-x64-musl"); + } else { + return await import("@opentui/core-linux-x64"); + } + } + if (process.arch === "arm64") { + if (process.env.OPENTUI_LIBC === "musl") { + return await import("@opentui/core-linux-arm64-musl"); + } else { + return await import("@opentui/core-linux-arm64"); + } + } + } + if (process.platform === "win32") { + if (process.arch === "x64") + return await import("@opentui/core-win32-x64"); + if (process.arch === "arm64") + return await import("@opentui/core-win32-arm64"); + } + throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`); +} +var nativePackage = await resolveNativePackage(); +var targetLibPath = nativePackage.default; +if (isBunfsPath(targetLibPath)) { + targetLibPath = targetLibPath.replace("../", ""); +} +if (!existsSync3(targetLibPath)) { + throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`); +} +registerEnvVar({ + name: "OTUI_DEBUG_FFI", + description: "Enable debug logging for the FFI bindings.", + type: "boolean", + default: false +}); +registerEnvVar({ + name: "OTUI_TRACE_FFI", + description: "Enable tracing for the FFI bindings.", + type: "boolean", + default: false +}); +registerEnvVar({ + name: "OPENTUI_FORCE_WCWIDTH", + description: "Use wcwidth for character width calculations", + type: "boolean", + default: false +}); +registerEnvVar({ + name: "OPENTUI_FORCE_UNICODE", + description: "Force Mode 2026 Unicode support in terminal capabilities", + type: "boolean", + default: false +}); +registerEnvVar({ + name: "OPENTUI_GRAPHICS", + description: "Enable Kitty graphics protocol detection", + type: "boolean", + default: true +}); +registerEnvVar({ + name: "OPENTUI_FORCE_NOZWJ", + description: "Use no_zwj width method (Unicode without ZWJ joining)", + type: "boolean", + default: false +}); +var CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2, default: 3 }; +var CURSOR_ID_TO_STYLE = ["block", "line", "underline", "default"]; +var MOUSE_STYLE_TO_ID = { default: 0, pointer: 1, text: 2, crosshair: 3, move: 4, "not-allowed": 5 }; +var MAX_FFI_U32 = 4294967295; +var globalTraceSymbols = null; +var globalFFILogPath = null; +var exitHandlerRegistered = false; +function toNumber(value) { + return typeof value === "bigint" ? Number(value) : value; +} +function toSafeByteCount(value, label) { + if (typeof value !== "bigint") { + return value; + } + if (value > BigInt(Number.MAX_SAFE_INTEGER)) { + throw new RangeError(`${label} exceeds JavaScript safe integer range`); + } + return Number(value); +} +function toSafeFFIU32Length(value, label) { + if (!Number.isSafeInteger(value) || value < 0 || value > MAX_FFI_U32) { + throw new RangeError(`${label} exceeds native u32 length limit`); + } + return value; +} +function ptrOrNull(value) { + return value.byteLength === 0 ? null : ptr(value); +} +function rgbaPtr(value) { + return ptr(value.buffer); +} +function optionalRgbaPtr(value) { + return value ? rgbaPtr(value) : null; +} +function getOpenTUILib(libPath) { + const resolvedLibPath = libPath || targetLibPath; + const rawSymbols = dlopen(resolvedLibPath, { + setLogCallback: { + args: ["ptr"], + returns: "void" + }, + createEventSink: { + args: ["ptr"], + returns: "u32" + }, + destroyEventSink: { + args: ["u32"], + returns: "void" + }, + createRenderer: { + args: ["u32", "u32", "u8", "u8", "ptr"], + returns: "u32" + }, + setTerminalEnvVar: { + args: ["u32", "ptr", "u32", "ptr", "u32"], + returns: "bool" + }, + destroyRenderer: { + args: ["u32"], + returns: "void" + }, + setUseThread: { + args: ["u32", "bool"], + returns: "void" + }, + setClearOnShutdown: { + args: ["u32", "bool"], + returns: "void" + }, + setBackgroundColor: { + args: ["u32", "ptr"], + returns: "void" + }, + setRenderOffset: { + args: ["u32", "u32"], + returns: "void" + }, + resetSplitScrollback: { + args: ["u32", "u32", "u32"], + returns: "u32" + }, + syncSplitScrollback: { + args: ["u32", "u32"], + returns: "u32" + }, + getSplitOutputOffset: { + args: ["u32", "u32"], + returns: "u32" + }, + setPendingSplitFooterTransition: { + args: ["u32", "u8", "u32", "u32", "u32", "u32", "u32"], + returns: "void" + }, + clearPendingSplitFooterTransition: { + args: ["u32"], + returns: "void" + }, + updateStats: { + args: ["u32", "f64", "u32", "f64"], + returns: "void" + }, + updateMemoryStats: { + args: ["u32", "u32", "u32", "u32"], + returns: "void" + }, + getRenderStats: { + args: ["u32", "ptr"], + returns: "void" + }, + render: { + args: ["u32", "bool"], + returns: "u8" + }, + repaintSplitFooter: { + args: ["u32", "u32", "bool"], + returns: "u64" + }, + commitSplitFooterSnapshot: { + args: ["u32", "u32", "u32", "bool", "bool", "u32", "bool", "bool", "bool"], + returns: "u64" + }, + getNextBuffer: { + args: ["u32"], + returns: "u32" + }, + getCurrentBuffer: { + args: ["u32"], + returns: "u32" + }, + rendererSetPaletteState: { + args: ["u32", "ptr", "u32", "ptr", "ptr", "u32"], + returns: "void" + }, + queryPixelResolution: { + args: ["u32"], + returns: "void" + }, + queryThemeColors: { + args: ["u32"], + returns: "void" + }, + createOptimizedBuffer: { + args: ["u32", "u32", "bool", "u8", "ptr", "u32"], + returns: "u32" + }, + destroyOptimizedBuffer: { + args: ["u32"], + returns: "void" + }, + drawFrameBuffer: { + args: ["u32", "i32", "i32", "u32", "u32", "u32", "u32", "u32"], + returns: "void" + }, + getBufferWidth: { + args: ["u32"], + returns: "u32" + }, + getBufferHeight: { + args: ["u32"], + returns: "u32" + }, + bufferClear: { + args: ["u32", "ptr"], + returns: "void" + }, + bufferGetCharPtr: { + args: ["u32"], + returns: "ptr" + }, + bufferGetFgPtr: { + args: ["u32"], + returns: "ptr" + }, + bufferGetBgPtr: { + args: ["u32"], + returns: "ptr" + }, + bufferGetAttributesPtr: { + args: ["u32"], + returns: "ptr" + }, + bufferGetRespectAlpha: { + args: ["u32"], + returns: "bool" + }, + bufferSetRespectAlpha: { + args: ["u32", "bool"], + returns: "void" + }, + bufferGetId: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + bufferGetRealCharSize: { + args: ["u32"], + returns: "u32" + }, + bufferWriteResolvedChars: { + args: ["u32", "ptr", "u32", "bool"], + returns: "u32" + }, + bufferDrawText: { + args: ["u32", "ptr", "u32", "u32", "u32", "ptr", "ptr", "u32"], + returns: "void" + }, + bufferSetCellWithAlphaBlending: { + args: ["u32", "u32", "u32", "u32", "ptr", "ptr", "u32"], + returns: "void" + }, + bufferSetCell: { + args: ["u32", "u32", "u32", "u32", "ptr", "ptr", "u32"], + returns: "void" + }, + bufferFillRect: { + args: ["u32", "u32", "u32", "u32", "u32", "ptr"], + returns: "void" + }, + bufferColorMatrix: { + args: ["u32", "ptr", "ptr", "u32", "f32", "u8"], + returns: "void" + }, + bufferColorMatrixUniform: { + args: ["u32", "ptr", "f32", "u8"], + returns: "void" + }, + bufferResize: { + args: ["u32", "u32", "u32"], + returns: "void" + }, + linkAlloc: { + args: ["ptr", "u32"], + returns: "u32" + }, + linkGetUrl: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + attributesWithLink: { + args: ["u32", "u32"], + returns: "u32" + }, + attributesGetLinkId: { + args: ["u32"], + returns: "u32" + }, + resizeRenderer: { + args: ["u32", "u32", "u32"], + returns: "void" + }, + setCursorPosition: { + args: ["u32", "i32", "i32", "bool"], + returns: "void" + }, + setCursorColor: { + args: ["u32", "ptr"], + returns: "void" + }, + getCursorState: { + args: ["u32", "ptr"], + returns: "void" + }, + setCursorStyleOptions: { + args: ["u32", "ptr"], + returns: "void" + }, + setDebugOverlay: { + args: ["u32", "bool", "u8"], + returns: "void" + }, + clearTerminal: { + args: ["u32"], + returns: "void" + }, + setTerminalTitle: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + copyToClipboardOSC52: { + args: ["u32", "u8", "ptr", "u32"], + returns: "bool" + }, + clearClipboardOSC52: { + args: ["u32", "u8"], + returns: "bool" + }, + triggerNotification: { + args: ["u32", "ptr", "u32", "ptr", "u32"], + returns: "bool" + }, + bufferDrawSuperSampleBuffer: { + args: ["u32", "u32", "u32", "ptr", "u32", "u8", "u32"], + returns: "void" + }, + bufferDrawPackedBuffer: { + args: ["u32", "ptr", "u32", "u32", "u32", "u32", "u32"], + returns: "void" + }, + bufferDrawGrayscaleBuffer: { + args: ["u32", "i32", "i32", "ptr", "u32", "u32", "ptr", "ptr"], + returns: "void" + }, + bufferDrawGrayscaleBufferSupersampled: { + args: ["u32", "i32", "i32", "ptr", "u32", "u32", "ptr", "ptr"], + returns: "void" + }, + bufferDrawGrid: { + args: ["u32", "ptr", "ptr", "ptr", "ptr", "u32", "ptr", "u32", "ptr"], + returns: "void" + }, + bufferDrawBox: { + args: ["u32", "i32", "i32", "u32", "u32", "ptr", "u32", "ptr", "ptr", "ptr", "ptr", "u32", "ptr", "u32"], + returns: "void" + }, + bufferPushScissorRect: { + args: ["u32", "i32", "i32", "u32", "u32"], + returns: "void" + }, + bufferPopScissorRect: { + args: ["u32"], + returns: "void" + }, + bufferClearScissorRects: { + args: ["u32"], + returns: "void" + }, + bufferPushOpacity: { + args: ["u32", "f32"], + returns: "void" + }, + bufferPopOpacity: { + args: ["u32"], + returns: "void" + }, + bufferGetCurrentOpacity: { + args: ["u32"], + returns: "f32" + }, + bufferClearOpacity: { + args: ["u32"], + returns: "void" + }, + addToHitGrid: { + args: ["u32", "i32", "i32", "u32", "u32", "u32"], + returns: "void" + }, + clearCurrentHitGrid: { + args: ["u32"], + returns: "void" + }, + hitGridPushScissorRect: { + args: ["u32", "i32", "i32", "u32", "u32"], + returns: "void" + }, + hitGridPopScissorRect: { + args: ["u32"], + returns: "void" + }, + hitGridClearScissorRects: { + args: ["u32"], + returns: "void" + }, + addToCurrentHitGridClipped: { + args: ["u32", "i32", "i32", "u32", "u32", "u32"], + returns: "void" + }, + checkHit: { + args: ["u32", "u32", "u32"], + returns: "u32" + }, + getHitGridDirty: { + args: ["u32"], + returns: "bool" + }, + dumpHitGrid: { + args: ["u32"], + returns: "void" + }, + dumpBuffers: { + args: ["u32", "i64"], + returns: "void" + }, + dumpOutputBuffer: { + args: ["u32", "i64"], + returns: "void" + }, + restoreTerminalModes: { + args: ["u32"], + returns: "void" + }, + enableMouse: { + args: ["u32", "bool"], + returns: "void" + }, + disableMouse: { + args: ["u32"], + returns: "void" + }, + enableKittyKeyboard: { + args: ["u32", "u8"], + returns: "void" + }, + disableKittyKeyboard: { + args: ["u32"], + returns: "void" + }, + setKittyKeyboardFlags: { + args: ["u32", "u8"], + returns: "void" + }, + getKittyKeyboardFlags: { + args: ["u32"], + returns: "u8" + }, + setupTerminal: { + args: ["u32", "bool"], + returns: "void" + }, + suspendRenderer: { + args: ["u32"], + returns: "void" + }, + resumeRenderer: { + args: ["u32"], + returns: "void" + }, + writeOut: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + createTextBuffer: { + args: ["u8"], + returns: "u32" + }, + destroyTextBuffer: { + args: ["u32"], + returns: "void" + }, + textBufferGetLength: { + args: ["u32"], + returns: "u32" + }, + textBufferGetByteSize: { + args: ["u32"], + returns: "u32" + }, + textBufferReset: { + args: ["u32"], + returns: "void" + }, + textBufferClear: { + args: ["u32"], + returns: "void" + }, + textBufferSetDefaultFg: { + args: ["u32", "ptr"], + returns: "void" + }, + textBufferSetDefaultBg: { + args: ["u32", "ptr"], + returns: "void" + }, + textBufferSetDefaultAttributes: { + args: ["u32", "ptr"], + returns: "void" + }, + textBufferResetDefaults: { + args: ["u32"], + returns: "void" + }, + textBufferGetTabWidth: { + args: ["u32"], + returns: "u8" + }, + textBufferSetTabWidth: { + args: ["u32", "u8"], + returns: "void" + }, + textBufferRegisterMemBuffer: { + args: ["u32", "ptr", "u32", "bool"], + returns: "u16" + }, + textBufferReplaceMemBuffer: { + args: ["u32", "u8", "ptr", "u32", "bool"], + returns: "bool" + }, + textBufferClearMemRegistry: { + args: ["u32"], + returns: "void" + }, + textBufferSetTextFromMem: { + args: ["u32", "u8"], + returns: "void" + }, + textBufferAppend: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + textBufferAppendFromMemId: { + args: ["u32", "u8"], + returns: "void" + }, + textBufferLoadFile: { + args: ["u32", "ptr", "u32"], + returns: "bool" + }, + textBufferSetStyledText: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + textBufferGetLineCount: { + args: ["u32"], + returns: "u32" + }, + textBufferGetPlainText: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + textBufferAddHighlightByCharRange: { + args: ["u32", "ptr"], + returns: "void" + }, + textBufferAddHighlight: { + args: ["u32", "u32", "ptr"], + returns: "void" + }, + textBufferRemoveHighlightsByRef: { + args: ["u32", "u16"], + returns: "void" + }, + textBufferClearLineHighlights: { + args: ["u32", "u32"], + returns: "void" + }, + textBufferClearAllHighlights: { + args: ["u32"], + returns: "void" + }, + textBufferSetSyntaxStyle: { + args: ["u32", "u32"], + returns: "bool" + }, + textBufferGetLineHighlightsPtr: { + args: ["u32", "u32", "ptr"], + returns: "ptr" + }, + textBufferFreeLineHighlights: { + args: ["ptr", "u32"], + returns: "void" + }, + textBufferGetHighlightCount: { + args: ["u32"], + returns: "u32" + }, + textBufferGetTextRange: { + args: ["u32", "u32", "u32", "ptr", "u32"], + returns: "u32" + }, + textBufferGetTextRangeByCoords: { + args: ["u32", "u32", "u32", "u32", "u32", "ptr", "u32"], + returns: "u32" + }, + createTextBufferView: { + args: ["u32"], + returns: "u32" + }, + destroyTextBufferView: { + args: ["u32"], + returns: "void" + }, + textBufferViewSetSelection: { + args: ["u32", "u32", "u32", "ptr", "ptr"], + returns: "void" + }, + textBufferViewResetSelection: { + args: ["u32"], + returns: "void" + }, + textBufferViewGetSelectionInfo: { + args: ["u32"], + returns: "u64" + }, + textBufferViewSetLocalSelection: { + args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr"], + returns: "bool" + }, + textBufferViewUpdateSelection: { + args: ["u32", "u32", "ptr", "ptr"], + returns: "void" + }, + textBufferViewUpdateLocalSelection: { + args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr"], + returns: "bool" + }, + textBufferViewResetLocalSelection: { + args: ["u32"], + returns: "void" + }, + textBufferViewSetWrapWidth: { + args: ["u32", "u32"], + returns: "void" + }, + textBufferViewSetWrapMode: { + args: ["u32", "u8"], + returns: "void" + }, + textBufferViewSetFirstLineOffset: { + args: ["u32", "u32"], + returns: "void" + }, + textBufferViewSetViewportSize: { + args: ["u32", "u32", "u32"], + returns: "void" + }, + textBufferViewSetViewport: { + args: ["u32", "u32", "u32", "u32", "u32"], + returns: "void" + }, + textBufferViewGetVirtualLineCount: { + args: ["u32"], + returns: "u32" + }, + textBufferViewGetLineInfoDirect: { + args: ["u32", "ptr"], + returns: "void" + }, + textBufferViewGetLogicalLineInfoDirect: { + args: ["u32", "ptr"], + returns: "void" + }, + textBufferViewGetSelectedText: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + textBufferViewGetPlainText: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + textBufferViewSetTabIndicator: { + args: ["u32", "u32"], + returns: "void" + }, + textBufferViewSetTabIndicatorColor: { + args: ["u32", "ptr"], + returns: "void" + }, + textBufferViewSetTruncate: { + args: ["u32", "bool"], + returns: "void" + }, + textBufferViewMeasureForDimensions: { + args: ["u32", "u32", "u32", "ptr"], + returns: "bool" + }, + bufferDrawTextBufferView: { + args: ["u32", "u32", "i32", "i32"], + returns: "void" + }, + bufferDrawEditorView: { + args: ["u32", "u32", "i32", "i32"], + returns: "void" + }, + createEditorView: { + args: ["u32", "u32", "u32"], + returns: "u32" + }, + destroyEditorView: { + args: ["u32"], + returns: "void" + }, + editorViewSetViewportSize: { + args: ["u32", "u32", "u32"], + returns: "void" + }, + editorViewSetViewport: { + args: ["u32", "u32", "u32", "u32", "u32", "bool"], + returns: "void" + }, + editorViewGetViewport: { + args: ["u32", "ptr", "ptr", "ptr", "ptr"], + returns: "void" + }, + editorViewSetScrollMargin: { + args: ["u32", "f32"], + returns: "void" + }, + editorViewSetWrapMode: { + args: ["u32", "u8"], + returns: "void" + }, + editorViewGetVirtualLineCount: { + args: ["u32"], + returns: "u32" + }, + editorViewGetTotalVirtualLineCount: { + args: ["u32"], + returns: "u32" + }, + editorViewGetTextBufferView: { + args: ["u32"], + returns: "u32" + }, + editorViewGetLineInfoDirect: { + args: ["u32", "ptr"], + returns: "void" + }, + editorViewGetLogicalLineInfoDirect: { + args: ["u32", "ptr"], + returns: "void" + }, + createEditBuffer: { + args: ["u8", "u32"], + returns: "u32" + }, + destroyEditBuffer: { + args: ["u32"], + returns: "void" + }, + editBufferSetText: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + editBufferSetTextFromMem: { + args: ["u32", "u8"], + returns: "void" + }, + editBufferReplaceText: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + editBufferReplaceTextFromMem: { + args: ["u32", "u8"], + returns: "void" + }, + editBufferGetText: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + editBufferInsertChar: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + editBufferInsertText: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + editBufferDeleteChar: { + args: ["u32"], + returns: "void" + }, + editBufferDeleteCharBackward: { + args: ["u32"], + returns: "void" + }, + editBufferDeleteRange: { + args: ["u32", "u32", "u32", "u32", "u32"], + returns: "void" + }, + editBufferNewLine: { + args: ["u32"], + returns: "void" + }, + editBufferDeleteLine: { + args: ["u32"], + returns: "void" + }, + editBufferMoveCursorLeft: { + args: ["u32"], + returns: "void" + }, + editBufferMoveCursorRight: { + args: ["u32"], + returns: "void" + }, + editBufferMoveCursorUp: { + args: ["u32"], + returns: "void" + }, + editBufferMoveCursorDown: { + args: ["u32"], + returns: "void" + }, + editBufferGotoLine: { + args: ["u32", "u32"], + returns: "void" + }, + editBufferSetCursor: { + args: ["u32", "u32", "u32"], + returns: "void" + }, + editBufferSetCursorToLineCol: { + args: ["u32", "u32", "u32"], + returns: "void" + }, + editBufferSetCursorByOffset: { + args: ["u32", "u32"], + returns: "void" + }, + editBufferGetCursorPosition: { + args: ["u32", "ptr"], + returns: "void" + }, + editBufferGetId: { + args: ["u32"], + returns: "u16" + }, + editBufferGetTextBuffer: { + args: ["u32"], + returns: "u32" + }, + editBufferDebugLogRope: { + args: ["u32"], + returns: "void" + }, + editBufferUndo: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + editBufferRedo: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + editBufferCanUndo: { + args: ["u32"], + returns: "bool" + }, + editBufferCanRedo: { + args: ["u32"], + returns: "bool" + }, + editBufferClearHistory: { + args: ["u32"], + returns: "void" + }, + editBufferClear: { + args: ["u32"], + returns: "void" + }, + editBufferGetNextWordBoundary: { + args: ["u32", "ptr"], + returns: "void" + }, + editBufferGetPrevWordBoundary: { + args: ["u32", "ptr"], + returns: "void" + }, + editBufferGetEOL: { + args: ["u32", "ptr"], + returns: "void" + }, + editBufferOffsetToPosition: { + args: ["u32", "u32", "ptr"], + returns: "bool" + }, + editBufferPositionToOffset: { + args: ["u32", "u32", "u32"], + returns: "u32" + }, + editBufferGetLineStartOffset: { + args: ["u32", "u32"], + returns: "u32" + }, + editBufferGetTextRange: { + args: ["u32", "u32", "u32", "ptr", "u32"], + returns: "u32" + }, + editBufferGetTextRangeByCoords: { + args: ["u32", "u32", "u32", "u32", "u32", "ptr", "u32"], + returns: "u32" + }, + editorViewSetSelection: { + args: ["u32", "u32", "u32", "ptr", "ptr"], + returns: "void" + }, + editorViewResetSelection: { + args: ["u32"], + returns: "void" + }, + editorViewGetSelection: { + args: ["u32"], + returns: "u64" + }, + editorViewSetLocalSelection: { + args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "bool", "bool"], + returns: "bool" + }, + editorViewUpdateSelection: { + args: ["u32", "u32", "ptr", "ptr"], + returns: "void" + }, + editorViewUpdateLocalSelection: { + args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "bool", "bool"], + returns: "bool" + }, + editorViewResetLocalSelection: { + args: ["u32"], + returns: "void" + }, + editorViewGetSelectedTextBytes: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + editorViewGetCursor: { + args: ["u32", "ptr", "ptr"], + returns: "void" + }, + editorViewGetText: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + editorViewGetVisualCursor: { + args: ["u32", "ptr"], + returns: "void" + }, + editorViewMoveUpVisual: { + args: ["u32"], + returns: "void" + }, + editorViewMoveDownVisual: { + args: ["u32"], + returns: "void" + }, + editorViewDeleteSelectedText: { + args: ["u32"], + returns: "void" + }, + editorViewSetCursorByOffset: { + args: ["u32", "u32"], + returns: "void" + }, + editorViewGetNextWordBoundary: { + args: ["u32", "ptr"], + returns: "void" + }, + editorViewGetPrevWordBoundary: { + args: ["u32", "ptr"], + returns: "void" + }, + editorViewGetEOL: { + args: ["u32", "ptr"], + returns: "void" + }, + editorViewGetVisualSOL: { + args: ["u32", "ptr"], + returns: "void" + }, + editorViewGetVisualEOL: { + args: ["u32", "ptr"], + returns: "void" + }, + editorViewSetPlaceholderStyledText: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + editorViewSetTabIndicator: { + args: ["u32", "u32"], + returns: "void" + }, + editorViewSetTabIndicatorColor: { + args: ["u32", "ptr"], + returns: "void" + }, + getArenaAllocatedBytes: { + args: [], + returns: "u64" + }, + getBuildOptions: { + args: ["ptr"], + returns: "void" + }, + getAllocatorStats: { + args: ["ptr"], + returns: "void" + }, + createSyntaxStyle: { + args: [], + returns: "u32" + }, + destroySyntaxStyle: { + args: ["u32"], + returns: "void" + }, + syntaxStyleRegister: { + args: ["u32", "ptr", "u32", "ptr", "ptr", "u32"], + returns: "u32" + }, + syntaxStyleResolveByName: { + args: ["u32", "ptr", "u32"], + returns: "u32" + }, + syntaxStyleGetStyleCount: { + args: ["u32"], + returns: "u32" + }, + getTerminalCapabilities: { + args: ["u32", "ptr"], + returns: "void" + }, + processCapabilityResponse: { + args: ["u32", "ptr", "u32"], + returns: "void" + }, + encodeUnicode: { + args: ["ptr", "u32", "ptr", "ptr", "u8"], + returns: "bool" + }, + freeUnicode: { + args: ["ptr", "u32"], + returns: "void" + }, + bufferDrawChar: { + args: ["u32", "u32", "u32", "u32", "ptr", "ptr", "u32"], + returns: "void" + }, + yogaConfigCreate: { + args: [], + returns: "ptr" + }, + yogaConfigFree: { + args: ["ptr"], + returns: "void" + }, + yogaConfigSetUseWebDefaults: { + args: ["ptr", "bool"], + returns: "void" + }, + yogaConfigGetUseWebDefaults: { + args: ["ptr"], + returns: "bool" + }, + yogaConfigSetPointScaleFactor: { + args: ["ptr", "f32"], + returns: "void" + }, + yogaConfigGetPointScaleFactor: { + args: ["ptr"], + returns: "f32" + }, + yogaConfigSetErrata: { + args: ["ptr", "u32"], + returns: "void" + }, + yogaConfigGetErrata: { + args: ["ptr"], + returns: "u32" + }, + yogaConfigSetExperimentalFeatureEnabled: { + args: ["ptr", "u32", "bool"], + returns: "void" + }, + yogaConfigIsExperimentalFeatureEnabled: { + args: ["ptr", "u32"], + returns: "bool" + }, + yogaNodeCreate: { + args: [], + returns: "ptr" + }, + yogaNodeCreateForOpenTUI: { + args: [], + returns: "ptr" + }, + yogaNodeCreateWithConfig: { + args: ["ptr"], + returns: "ptr" + }, + yogaNodeFree: { + args: ["ptr"], + returns: "void" + }, + yogaNodeFreeRecursive: { + args: ["ptr"], + returns: "void" + }, + yogaNodeReset: { + args: ["ptr"], + returns: "void" + }, + yogaNodeCopyStyle: { + args: ["ptr", "ptr"], + returns: "void" + }, + yogaNodeInsertChild: { + args: ["ptr", "ptr", "u32"], + returns: "void" + }, + yogaNodeRemoveChild: { + args: ["ptr", "ptr"], + returns: "void" + }, + yogaNodeRemoveAllChildren: { + args: ["ptr"], + returns: "void" + }, + yogaNodeGetChild: { + args: ["ptr", "u32"], + returns: "ptr" + }, + yogaNodeGetChildCount: { + args: ["ptr"], + returns: "u32" + }, + yogaNodeGetParent: { + args: ["ptr"], + returns: "ptr" + }, + yogaNodeCalculateLayout: { + args: ["ptr", "f32", "f32", "u32"], + returns: "void" + }, + yogaNodeIsDirty: { + args: ["ptr"], + returns: "bool" + }, + yogaNodeMarkDirty: { + args: ["ptr"], + returns: "void" + }, + yogaNodeGetHasNewLayout: { + args: ["ptr"], + returns: "bool" + }, + yogaNodeSetHasNewLayout: { + args: ["ptr", "bool"], + returns: "void" + }, + yogaNodeSetIsReferenceBaseline: { + args: ["ptr", "bool"], + returns: "void" + }, + yogaNodeIsReferenceBaseline: { + args: ["ptr"], + returns: "bool" + }, + yogaNodeSetAlwaysFormsContainingBlock: { + args: ["ptr", "bool"], + returns: "void" + }, + yogaNodeGetAlwaysFormsContainingBlock: { + args: ["ptr"], + returns: "bool" + }, + yogaNodeGetComputedLayout: { + args: ["ptr", "ptr"], + returns: "void" + }, + yogaNodeLayoutGetEdge: { + args: ["ptr", "u32", "u32"], + returns: "f32" + }, + yogaNodeStyleSetEnum: { + args: ["ptr", "u32", "u32"], + returns: "void" + }, + yogaNodeStyleGetEnum: { + args: ["ptr", "u32"], + returns: "u32" + }, + yogaNodeStyleSetFloat: { + args: ["ptr", "u32", "f32"], + returns: "void" + }, + yogaNodeStyleGetFloat: { + args: ["ptr", "u32"], + returns: "f32" + }, + yogaNodeStyleSetBorder: { + args: ["ptr", "u32", "f32"], + returns: "void" + }, + yogaNodeStyleGetBorder: { + args: ["ptr", "u32"], + returns: "f32" + }, + yogaNodeStyleSetValue: { + args: ["ptr", "u32", "u32", "u32", "f32"], + returns: "void" + }, + yogaNodeStyleGetValue: { + args: ["ptr", "u32", "u32"], + returns: "u64" + }, + yogaNodeSetMeasureFunc: { + args: ["ptr", "ptr"], + returns: "void" + }, + yogaNodeUnsetMeasureFunc: { + args: ["ptr"], + returns: "void" + }, + yogaNodeHasMeasureFunc: { + args: ["ptr"], + returns: "bool" + }, + yogaNodeSetDirtiedFunc: { + args: ["ptr", "ptr"], + returns: "void" + }, + yogaNodeUnsetDirtiedFunc: { + args: ["ptr"], + returns: "void" + }, + yogaStoreMeasureResult: { + args: ["f32", "f32"], + returns: "void" + }, + createAudioEngine: { + args: ["ptr"], + returns: "u32" + }, + destroyAudioEngine: { + args: ["u32"], + returns: "void" + }, + audioRefreshPlaybackDevices: { + args: ["u32"], + returns: "i32" + }, + audioGetPlaybackDeviceCount: { + args: ["u32"], + returns: "u32" + }, + audioGetPlaybackDeviceName: { + args: ["u32", "u32", "ptr", "u32"], + returns: "u32" + }, + audioIsPlaybackDeviceDefault: { + args: ["u32", "u32"], + returns: "bool" + }, + audioSelectPlaybackDevice: { + args: ["u32", "u32"], + returns: "i32" + }, + audioClearPlaybackDeviceSelection: { + args: ["u32"], + returns: "void" + }, + audioStart: { + args: ["u32", "ptr"], + returns: "i32" + }, + audioStartMixer: { + args: ["u32"], + returns: "i32" + }, + audioStop: { + args: ["u32"], + returns: "i32" + }, + audioLoad: { + args: ["u32", "ptr", "u32", "ptr"], + returns: "i32" + }, + audioUnload: { + args: ["u32", "u32"], + returns: "i32" + }, + audioPlay: { + args: ["u32", "u32", "ptr", "ptr"], + returns: "i32" + }, + audioStopVoice: { + args: ["u32", "u32"], + returns: "i32" + }, + audioSetVoiceGroup: { + args: ["u32", "u32", "u32"], + returns: "i32" + }, + audioCreateGroup: { + args: ["u32", "ptr", "u32", "ptr"], + returns: "i32" + }, + audioSetGroupVolume: { + args: ["u32", "u32", "f32"], + returns: "i32" + }, + audioSetMasterVolume: { + args: ["u32", "f32"], + returns: "i32" + }, + audioMixToBuffer: { + args: ["u32", "ptr", "u32", "u8"], + returns: "i32" + }, + audioEnableTap: { + args: ["u32", "bool", "u32"], + returns: "i32" + }, + audioReadTap: { + args: ["u32", "ptr", "u32", "u8", "ptr"], + returns: "i32" + }, + audioGetStats: { + args: ["u32", "ptr"], + returns: "i32" + }, + createNativeSpanFeed: { + args: ["ptr"], + returns: "ptr" + }, + attachNativeSpanFeed: { + args: ["ptr"], + returns: "i32" + }, + destroyNativeSpanFeed: { + args: ["ptr"], + returns: "void" + }, + streamWrite: { + args: ["ptr", "ptr", "u32"], + returns: "i32" + }, + streamCommit: { + args: ["ptr"], + returns: "i32" + }, + streamDrainSpans: { + args: ["ptr", "ptr", "u32"], + returns: "u32" + }, + streamClose: { + args: ["ptr"], + returns: "i32" + }, + streamReserve: { + args: ["ptr", "u32", "ptr"], + returns: "i32" + }, + streamCommitReserved: { + args: ["ptr", "u32"], + returns: "i32" + }, + streamSetOptions: { + args: ["ptr", "ptr"], + returns: "i32" + }, + streamGetStats: { + args: ["ptr", "ptr"], + returns: "i32" + }, + streamSetCallback: { + args: ["ptr", "ptr"], + returns: "void" + } + }); + if (env.OTUI_DEBUG_FFI || env.OTUI_TRACE_FFI) { + return { + ...rawSymbols, + symbols: convertToDebugSymbols(rawSymbols.symbols) + }; + } + return rawSymbols; +} +function convertToDebugSymbols(symbols) { + if (!globalTraceSymbols) { + globalTraceSymbols = {}; + } + if (env.OTUI_DEBUG_FFI && !globalFFILogPath) { + const now = new Date; + const timestamp = now.toISOString().replace(/[:.]/g, "-").replace(/T/, "_").split("Z")[0]; + globalFFILogPath = `ffi_otui_debug_${timestamp}.log`; + } + const debugSymbols = {}; + let hasTracing = false; + Object.entries(symbols).forEach(([key, value]) => { + debugSymbols[key] = value; + }); + if (env.OTUI_DEBUG_FFI && globalFFILogPath) { + const logPath = globalFFILogPath; + const writeSync = (msg) => { + writeFileSync(logPath, msg + ` +`, { flag: "a" }); + }; + Object.entries(symbols).forEach(([key, value]) => { + if (typeof value === "function") { + debugSymbols[key] = (...args) => { + writeSync(`${key}(${args.map((arg) => String(arg)).join(", ")})`); + const result = value(...args); + writeSync(`${key} returned: ${String(result)}`); + return result; + }; + } + }); + } + if (env.OTUI_TRACE_FFI) { + hasTracing = true; + Object.entries(symbols).forEach(([key, value]) => { + if (typeof value === "function") { + if (!globalTraceSymbols[key]) { + globalTraceSymbols[key] = []; + } + const originalFunc = debugSymbols[key]; + debugSymbols[key] = (...args) => { + const start = performance.now(); + const result = originalFunc(...args); + const end = performance.now(); + globalTraceSymbols[key].push(end - start); + return result; + }; + } + }); + } + if ((env.OTUI_DEBUG_FFI || env.OTUI_TRACE_FFI) && !exitHandlerRegistered) { + exitHandlerRegistered = true; + process.on("exit", () => { + if (globalTraceSymbols) { + const allStats = []; + for (const [key, timings] of Object.entries(globalTraceSymbols)) { + if (!Array.isArray(timings) || timings.length === 0) { + continue; + } + const sortedTimings = [...timings].sort((a, b) => a - b); + const count = sortedTimings.length; + const total = sortedTimings.reduce((acc, t2) => acc + t2, 0); + const average = total / count; + const min = sortedTimings[0]; + const max = sortedTimings[count - 1]; + const medianIndex = Math.floor(count / 2); + const p90Index = Math.floor(count * 0.9); + const p99Index = Math.floor(count * 0.99); + const median = sortedTimings[medianIndex]; + const p90 = sortedTimings[Math.min(p90Index, count - 1)]; + const p99 = sortedTimings[Math.min(p99Index, count - 1)]; + allStats.push({ + name: key, + count, + total, + average, + min, + max, + median, + p90, + p99 + }); + } + allStats.sort((a, b) => b.total - a.total); + const lines = []; + lines.push(` +--- OpenTUI FFI Call Performance ---`); + lines.push("Sorted by total time spent (descending)"); + lines.push("-------------------------------------------------------------------------------------------------------------------------"); + if (allStats.length === 0) { + lines.push("No trace data collected or all symbols had zero calls."); + } else { + const nameHeader = "Symbol"; + const callsHeader = "Calls"; + const totalHeader = "Total (ms)"; + const avgHeader = "Avg (ms)"; + const minHeader = "Min (ms)"; + const maxHeader = "Max (ms)"; + const medHeader = "Med (ms)"; + const p90Header = "P90 (ms)"; + const p99Header = "P99 (ms)"; + const nameWidth = Math.max(nameHeader.length, ...allStats.map((s) => s.name.length)); + const countWidth = Math.max(callsHeader.length, ...allStats.map((s) => String(s.count).length)); + const totalWidth = Math.max(totalHeader.length, ...allStats.map((s) => s.total.toFixed(2).length)); + const avgWidth = Math.max(avgHeader.length, ...allStats.map((s) => s.average.toFixed(2).length)); + const statWidthMin = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length)); + const statWidthMax = Math.max(maxHeader.length, ...allStats.map((s) => s.max.toFixed(2).length)); + const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length)); + const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length)); + const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length)); + lines.push(`${nameHeader.padEnd(nameWidth)} | ${callsHeader.padStart(countWidth)} | ${totalHeader.padStart(totalWidth)} | ${avgHeader.padStart(avgWidth)} | ${minHeader.padStart(statWidthMin)} | ${maxHeader.padStart(statWidthMax)} | ${medHeader.padStart(medianWidth)} | ${p90Header.padStart(p90Width)} | ${p99Header.padStart(p99Width)}`); + lines.push(`${"-".repeat(nameWidth)}-+-${"-".repeat(countWidth)}-+-${"-".repeat(totalWidth)}-+-${"-".repeat(avgWidth)}-+-${"-".repeat(statWidthMin)}-+-${"-".repeat(statWidthMax)}-+-${"-".repeat(medianWidth)}-+-${"-".repeat(p90Width)}-+-${"-".repeat(p99Width)}`); + allStats.forEach((stat) => { + lines.push(`${stat.name.padEnd(nameWidth)} | ${String(stat.count).padStart(countWidth)} | ${stat.total.toFixed(2).padStart(totalWidth)} | ${stat.average.toFixed(2).padStart(avgWidth)} | ${stat.min.toFixed(2).padStart(statWidthMin)} | ${stat.max.toFixed(2).padStart(statWidthMax)} | ${stat.median.toFixed(2).padStart(medianWidth)} | ${stat.p90.toFixed(2).padStart(p90Width)} | ${stat.p99.toFixed(2).padStart(p99Width)}`); + }); + } + lines.push("-------------------------------------------------------------------------------------------------------------------------"); + const output = lines.join(` +`); + console.log(output); + try { + const now = new Date; + const timestamp = now.toISOString().replace(/[:.]/g, "-").replace(/T/, "_").split("Z")[0]; + const traceFilePath = `ffi_otui_trace_${timestamp}.log`; + writeFile(traceFilePath, output).catch((error) => { + console.error("Failed to write FFI trace file:", error); + }); + } catch (e) { + console.error("Failed to write FFI trace file:", e); + } + } + }); + } + return debugSymbols; +} +var LogLevel2; +((LogLevel3) => { + LogLevel3[LogLevel3["Error"] = 0] = "Error"; + LogLevel3[LogLevel3["Warn"] = 1] = "Warn"; + LogLevel3[LogLevel3["Info"] = 2] = "Info"; + LogLevel3[LogLevel3["Debug"] = 3] = "Debug"; +})(LogLevel2 ||= {}); + +class FFIRenderLib { + opentui; + encoder = new TextEncoder; + decoder = new TextDecoder; + logCallbackWrapper = null; + eventCallbackWrapper = null; + eventSinkPtr = null; + _nativeEvents = new EventEmitter4; + _anyEventHandlers = []; + nativeSpanFeedCallbackWrapper = null; + nativeSpanFeedHandlers = new Map; + constructor(libPath) { + this.opentui = getOpenTUILib(libPath); + try { + this.setupLogging(); + this.setupEventBus(); + } catch (error) { + this.dispose(); + throw error; + } + } + setupLogging() { + if (this.logCallbackWrapper) { + return; + } + const logCallback = this.opentui.createCallback((level, msgPtr, msgLen) => { + try { + if (msgLen === 0 || !msgPtr) { + return; + } + const msgBuffer = toArrayBuffer(msgPtr, 0, msgLen); + const msgBytes = new Uint8Array(msgBuffer); + const message = this.decoder.decode(msgBytes); + switch (level) { + case 0 /* Error */: + console.error(message); + break; + case 1 /* Warn */: + console.warn(message); + break; + case 2 /* Info */: + console.info(message); + break; + case 3 /* Debug */: + console.debug(message); + break; + default: + console.log(message); + } + } catch (error) { + console.error("Error in Zig log callback:", error); + } + }, { + args: ["u8", "ptr", "u32"], + returns: "void" + }); + this.logCallbackWrapper = logCallback; + if (!logCallback.ptr) { + throw new Error("Failed to create log callback"); + } + this.setLogCallback(logCallback.ptr); + } + setLogCallback(callbackPtr) { + this.opentui.symbols.setLogCallback(callbackPtr); + } + dispose() { + try { + if (this.eventSinkPtr) { + this.opentui.symbols.destroyEventSink(this.eventSinkPtr); + this.eventSinkPtr = null; + } + this.setLogCallback(null); + } finally { + try { + this.opentui.close(); + } finally { + this.eventCallbackWrapper = null; + this.logCallbackWrapper = null; + this.nativeSpanFeedCallbackWrapper = null; + this.nativeSpanFeedHandlers.clear(); + } + } + } + setupEventBus() { + if (this.eventCallbackWrapper) { + return; + } + const eventCallback = this.opentui.createCallback((namePtr, nameLen, dataPtr, dataLen) => { + try { + if (nameLen === 0 || !namePtr) { + return; + } + const eventName = this.decoder.decode(toArrayBuffer(namePtr, 0, nameLen)); + const eventData = dataLen > 0 && dataPtr ? toArrayBuffer(dataPtr, 0, dataLen).slice(0) : new ArrayBuffer(0); + queueMicrotask(() => { + this._nativeEvents.emit(eventName, eventData); + for (const handler of this._anyEventHandlers) { + handler(eventName, eventData); + } + }); + } catch (error) { + console.error("Error in native event callback:", error); + } + }, { + args: ["ptr", "u32", "ptr", "u32"], + returns: "void" + }); + this.eventCallbackWrapper = eventCallback; + if (!eventCallback.ptr) { + throw new Error("Failed to create event callback"); + } + this.eventSinkPtr = this.opentui.symbols.createEventSink(eventCallback.ptr); + if (!this.eventSinkPtr) { + eventCallback.close(); + this.eventCallbackWrapper = null; + throw new Error("Failed to create native event sink"); + } + } + ensureNativeSpanFeedCallback() { + if (this.nativeSpanFeedCallbackWrapper) { + return this.nativeSpanFeedCallbackWrapper; + } + const callback = this.opentui.createCallback((streamPtr, eventId, arg0, arg1) => { + const handler = this.nativeSpanFeedHandlers.get(streamPtr); + if (handler) { + handler(eventId, arg0, arg1); + } + }, { + args: ["ptr", "u32", "ptr", "u64"], + returns: "void" + }); + this.nativeSpanFeedCallbackWrapper = callback; + if (!callback.ptr) { + throw new Error("Failed to create native span feed callback"); + } + return callback; + } + createRenderer(width, height, options = {}) { + const bufferedOutputKind = options.bufferedOutput === "memory" ? 1 : 0; + const remoteMode = options.remote === undefined ? 0 : options.remote ? 2 : 1; + const feedPtr = options.feedPtr ?? null; + const renderer = this.opentui.symbols.createRenderer(width, height, bufferedOutputKind, remoteMode, feedPtr); + return renderer ? renderer : null; + } + setTerminalEnvVar(renderer, key, value) { + const keyBytes = this.encoder.encode(key); + const valueBytes = this.encoder.encode(value); + return this.opentui.symbols.setTerminalEnvVar(renderer, ptrOrNull(keyBytes), keyBytes.byteLength, ptrOrNull(valueBytes), valueBytes.byteLength); + } + destroyRenderer(renderer) { + this.opentui.symbols.destroyRenderer(renderer); + } + setUseThread(renderer, useThread) { + this.opentui.symbols.setUseThread(renderer, ffiBool(useThread)); + } + setClearOnShutdown(renderer, clear) { + this.opentui.symbols.setClearOnShutdown(renderer, ffiBool(clear)); + } + setBackgroundColor(renderer, color) { + this.opentui.symbols.setBackgroundColor(renderer, rgbaPtr(color)); + } + setRenderOffset(renderer, offset) { + this.opentui.symbols.setRenderOffset(renderer, offset); + } + resetSplitScrollback(renderer, seedRows, pinnedRenderOffset) { + return this.opentui.symbols.resetSplitScrollback(renderer, seedRows, pinnedRenderOffset); + } + syncSplitScrollback(renderer, pinnedRenderOffset) { + return this.opentui.symbols.syncSplitScrollback(renderer, pinnedRenderOffset); + } + getSplitOutputOffset(renderer, surfaceOffset) { + return this.opentui.symbols.getSplitOutputOffset(renderer, surfaceOffset); + } + setPendingSplitFooterTransition(renderer, mode, sourceTopLine, sourceHeight, targetTopLine, targetHeight, scrollLines) { + this.opentui.symbols.setPendingSplitFooterTransition(renderer, mode, sourceTopLine, sourceHeight, targetTopLine, targetHeight, scrollLines); + } + clearPendingSplitFooterTransition(renderer) { + this.opentui.symbols.clearPendingSplitFooterTransition(renderer); + } + updateStats(renderer, time, fps, frameCallbackTime) { + this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime); + } + updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers) { + this.opentui.symbols.updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers); + } + getRenderStats(renderer) { + const statsBuffer = new ArrayBuffer(NativeRenderStatsStruct.size); + this.opentui.symbols.getRenderStats(renderer, ptr(statsBuffer)); + const stats = NativeRenderStatsStruct.unpack(statsBuffer); + return { + nativeLastFrameTime: stats.lastFrameTime, + nativeAverageFrameTime: stats.averageFrameTime, + nativeFrameCount: toNumber(stats.frameCount), + cellsUpdated: stats.cellsUpdated, + averageCellsUpdated: stats.averageCellsUpdated, + nativeRenderTime: stats.renderTimeValid ? stats.renderTime : undefined, + nativeStdoutWriteTime: stats.stdoutWriteTimeValid ? stats.stdoutWriteTime : undefined + }; + } + getNextBuffer(renderer) { + const bufferPtr = this.opentui.symbols.getNextBuffer(renderer); + if (!bufferPtr) { + throw new Error("Failed to get next buffer"); + } + const width = this.opentui.symbols.getBufferWidth(bufferPtr); + const height = this.opentui.symbols.getBufferHeight(bufferPtr); + return new OptimizedBuffer(this, bufferPtr, width, height, { id: "next buffer", widthMethod: "unicode" }); + } + getCurrentBuffer(renderer) { + const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer); + if (!bufferPtr) { + throw new Error("Failed to get current buffer"); + } + const width = this.opentui.symbols.getBufferWidth(bufferPtr); + const height = this.opentui.symbols.getBufferHeight(bufferPtr); + return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer", widthMethod: "unicode" }); + } + rendererSetPaletteState(renderer, palette, defaultForeground, defaultBackground, paletteEpoch) { + const paletteBuffer = new Uint16Array(palette.length * 4); + for (let index = 0;index < palette.length; index++) { + paletteBuffer.set(palette[index].buffer, index * 4); + } + this.opentui.symbols.rendererSetPaletteState(renderer, ptr(paletteBuffer), palette.length, rgbaPtr(defaultForeground), rgbaPtr(defaultBackground), paletteEpoch >>> 0); + } + bufferGetCharPtr(buffer) { + const ptr3 = this.opentui.symbols.bufferGetCharPtr(buffer); + if (!ptr3) { + throw new Error("Failed to get char pointer"); + } + return ptr3; + } + bufferGetFgPtr(buffer) { + const ptr3 = this.opentui.symbols.bufferGetFgPtr(buffer); + if (!ptr3) { + throw new Error("Failed to get fg pointer"); + } + return ptr3; + } + bufferGetBgPtr(buffer) { + const ptr3 = this.opentui.symbols.bufferGetBgPtr(buffer); + if (!ptr3) { + throw new Error("Failed to get bg pointer"); + } + return ptr3; + } + bufferGetAttributesPtr(buffer) { + const ptr3 = this.opentui.symbols.bufferGetAttributesPtr(buffer); + if (!ptr3) { + throw new Error("Failed to get attributes pointer"); + } + return ptr3; + } + bufferGetRespectAlpha(buffer) { + return this.opentui.symbols.bufferGetRespectAlpha(buffer); + } + bufferSetRespectAlpha(buffer, respectAlpha) { + this.opentui.symbols.bufferSetRespectAlpha(buffer, ffiBool(respectAlpha)); + } + bufferGetId(buffer) { + const maxLen = 256; + const outBuffer = new Uint8Array(maxLen); + const actualLen = this.opentui.symbols.bufferGetId(buffer, ptr(outBuffer), maxLen); + return this.decoder.decode(outBuffer.slice(0, actualLen)); + } + bufferGetRealCharSize(buffer) { + return this.opentui.symbols.bufferGetRealCharSize(buffer); + } + bufferWriteResolvedChars(buffer, outputBuffer, addLineBreaks) { + return this.opentui.symbols.bufferWriteResolvedChars(buffer, ptrOrNull(outputBuffer), outputBuffer.byteLength, ffiBool(addLineBreaks)); + } + getBufferWidth(buffer) { + return this.opentui.symbols.getBufferWidth(buffer); + } + getBufferHeight(buffer) { + return this.opentui.symbols.getBufferHeight(buffer); + } + bufferClear(buffer, color) { + this.opentui.symbols.bufferClear(buffer, rgbaPtr(color)); + } + bufferDrawText(buffer, text, x, y, color, bgColor, attributes) { + const textBytes = this.encoder.encode(text); + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = rgbaPtr(color); + this.opentui.symbols.bufferDrawText(buffer, ptrOrNull(textBytes), textBytes.byteLength, x, y, fg2, bg2, attributes ?? 0); + } + bufferSetCellWithAlphaBlending(buffer, x, y, char, color, bgColor, attributes) { + const charPtr = char.codePointAt(0) ?? " ".codePointAt(0); + const bg2 = rgbaPtr(bgColor); + const fg2 = rgbaPtr(color); + this.opentui.symbols.bufferSetCellWithAlphaBlending(buffer, x, y, charPtr, fg2, bg2, attributes ?? 0); + } + bufferSetCell(buffer, x, y, char, color, bgColor, attributes) { + const charPtr = char.codePointAt(0) ?? " ".codePointAt(0); + const bg2 = rgbaPtr(bgColor); + const fg2 = rgbaPtr(color); + this.opentui.symbols.bufferSetCell(buffer, x, y, charPtr, fg2, bg2, attributes ?? 0); + } + bufferFillRect(buffer, x, y, width, height, color) { + const bg2 = rgbaPtr(color); + this.opentui.symbols.bufferFillRect(buffer, x, y, width, height, bg2); + } + bufferColorMatrix(buffer, matrixPtr, cellMaskPtr, cellMaskCount, strength, target) { + this.opentui.symbols.bufferColorMatrix(buffer, matrixPtr, cellMaskPtr, cellMaskCount, strength, target); + } + bufferColorMatrixUniform(buffer, matrixPtr, strength, target) { + this.opentui.symbols.bufferColorMatrixUniform(buffer, matrixPtr, strength, target); + } + bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow) { + const formatId = format === "bgra8unorm" ? 0 : 1; + this.opentui.symbols.bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, formatId, alignedBytesPerRow); + } + bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) { + this.opentui.symbols.bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells); + } + bufferDrawGrayscaleBuffer(buffer, posX, posY, intensitiesPtr, srcWidth, srcHeight, fg2, bg2) { + this.opentui.symbols.bufferDrawGrayscaleBuffer(buffer, posX, posY, intensitiesPtr, srcWidth, srcHeight, optionalRgbaPtr(fg2), optionalRgbaPtr(bg2)); + } + bufferDrawGrayscaleBufferSupersampled(buffer, posX, posY, intensitiesPtr, srcWidth, srcHeight, fg2, bg2) { + this.opentui.symbols.bufferDrawGrayscaleBufferSupersampled(buffer, posX, posY, intensitiesPtr, srcWidth, srcHeight, optionalRgbaPtr(fg2), optionalRgbaPtr(bg2)); + } + bufferDrawGrid(buffer, borderChars, borderFg, borderBg, columnOffsets, columnCount, rowOffsets, rowCount, options) { + const optionsBuffer = GridDrawOptionsStruct.pack({ + drawInner: options.drawInner, + drawOuter: options.drawOuter + }); + this.opentui.symbols.bufferDrawGrid(buffer, ptr(borderChars), rgbaPtr(borderFg), rgbaPtr(borderBg), ptr(columnOffsets), columnCount, ptr(rowOffsets), rowCount, ptr(optionsBuffer)); + } + bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, titleColor, title, bottomTitle) { + const titleBytes = title ? this.encoder.encode(title) : null; + const titleLen = titleBytes?.byteLength ?? 0; + const titlePtr = titleBytes ? ptr(titleBytes) : null; + const bottomTitleBytes = bottomTitle ? this.encoder.encode(bottomTitle) : null; + const bottomTitleLen = bottomTitleBytes?.byteLength ?? 0; + const bottomTitlePtr = bottomTitleBytes ? ptr(bottomTitleBytes) : null; + this.opentui.symbols.bufferDrawBox(buffer, x, y, width, height, ptr(borderChars), packedOptions, rgbaPtr(borderColor), rgbaPtr(backgroundColor), rgbaPtr(titleColor), titlePtr, titleLen, bottomTitlePtr, bottomTitleLen); + } + bufferResize(buffer, width, height) { + this.opentui.symbols.bufferResize(buffer, width, height); + } + linkAlloc(url) { + const urlBytes = this.encoder.encode(url); + return this.opentui.symbols.linkAlloc(ptrOrNull(urlBytes), urlBytes.byteLength); + } + linkGetUrl(linkId, maxLen = 512) { + const outBuffer = new Uint8Array(maxLen); + const actualLen = this.opentui.symbols.linkGetUrl(linkId, ptrOrNull(outBuffer), maxLen); + return this.decoder.decode(outBuffer.slice(0, actualLen)); + } + attributesWithLink(baseAttributes, linkId) { + return this.opentui.symbols.attributesWithLink(baseAttributes, linkId); + } + attributesGetLinkId(attributes) { + return this.opentui.symbols.attributesGetLinkId(attributes); + } + resizeRenderer(renderer, width, height) { + this.opentui.symbols.resizeRenderer(renderer, width, height); + } + setCursorPosition(renderer, x, y, visible) { + this.opentui.symbols.setCursorPosition(renderer, x, y, ffiBool(visible)); + } + setCursorColor(renderer, color) { + this.opentui.symbols.setCursorColor(renderer, rgbaPtr(color)); + } + getCursorState(renderer) { + const cursorBuffer = new ArrayBuffer(CursorStateStruct.size); + this.opentui.symbols.getCursorState(renderer, ptr(cursorBuffer)); + const struct = CursorStateStruct.unpack(cursorBuffer); + return { + x: struct.x, + y: struct.y, + visible: struct.visible, + style: CURSOR_ID_TO_STYLE[struct.style] ?? "block", + blinking: struct.blinking, + color: RGBA.fromValues(struct.r, struct.g, struct.b, struct.a) + }; + } + setCursorStyleOptions(renderer, options) { + const style = options.style != null ? CURSOR_STYLE_TO_ID[options.style] : 255; + const blinking = options.blinking != null ? options.blinking ? 1 : 0 : 255; + const cursor = options.cursor != null ? MOUSE_STYLE_TO_ID[options.cursor] : 255; + const buffer = CursorStyleOptionsStruct.pack({ style, blinking, color: options.color, cursor }); + this.opentui.symbols.setCursorStyleOptions(renderer, ptr(buffer)); + } + render(renderer, force) { + return this.opentui.symbols.render(renderer, ffiBool(force)); + } + unpackRenderOperationResult(value) { + const packed = typeof value === "bigint" ? value : BigInt(value); + return { + renderOffset: Number(packed & 0xffffffffn), + status: Number(packed >> 32n & 0xffn) + }; + } + repaintSplitFooter(renderer, pinnedRenderOffset, force) { + return this.unpackRenderOperationResult(this.opentui.symbols.repaintSplitFooter(renderer, pinnedRenderOffset, ffiBool(force))); + } + commitSplitFooterSnapshot(renderer, snapshot, rowColumns, startOnNewLine, trailingNewline, pinnedRenderOffset, force, beginFrame = true, finalizeFrame = true) { + return this.unpackRenderOperationResult(this.opentui.symbols.commitSplitFooterSnapshot(renderer, snapshot.ptr, rowColumns, ffiBool(startOnNewLine), ffiBool(trailingNewline), pinnedRenderOffset, ffiBool(force), ffiBool(beginFrame), ffiBool(finalizeFrame))); + } + createOptimizedBuffer(width, height, widthMethod, respectAlpha = false, id) { + if (Number.isNaN(width) || Number.isNaN(height)) { + console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack); + } + const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1; + const idToUse = id || "unnamed buffer"; + const idBytes = this.encoder.encode(idToUse); + const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, ffiBool(respectAlpha), widthMethodCode, ptr(idBytes), idBytes.byteLength); + if (!bufferPtr) { + throw new Error(`Failed to create optimized buffer: ${width}x${height}`); + } + return new OptimizedBuffer(this, bufferPtr, width, height, { respectAlpha, id, widthMethod }); + } + destroyOptimizedBuffer(bufferPtr) { + this.opentui.symbols.destroyOptimizedBuffer(bufferPtr); + } + drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, sourceX, sourceY, sourceWidth, sourceHeight) { + const srcX = sourceX ?? 0; + const srcY = sourceY ?? 0; + const srcWidth = sourceWidth ?? 0; + const srcHeight = sourceHeight ?? 0; + this.opentui.symbols.drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, srcX, srcY, srcWidth, srcHeight); + } + setDebugOverlay(renderer, enabled, corner) { + this.opentui.symbols.setDebugOverlay(renderer, ffiBool(enabled), corner); + } + clearTerminal(renderer) { + this.opentui.symbols.clearTerminal(renderer); + } + setTerminalTitle(renderer, title) { + const titleBytes = this.encoder.encode(title); + this.opentui.symbols.setTerminalTitle(renderer, ptrOrNull(titleBytes), titleBytes.byteLength); + } + copyToClipboardOSC52(renderer, target, payload) { + return Boolean(this.opentui.symbols.copyToClipboardOSC52(renderer, target, ptrOrNull(payload), payload.byteLength)); + } + clearClipboardOSC52(renderer, target) { + return Boolean(this.opentui.symbols.clearClipboardOSC52(renderer, target)); + } + triggerNotification(renderer, message, title) { + const messageBytes = this.encoder.encode(message); + const titleBytes = title === undefined ? null : this.encoder.encode(title); + return Boolean(this.opentui.symbols.triggerNotification(renderer, messageBytes, messageBytes.length, titleBytes, titleBytes?.length ?? 0)); + } + addToHitGrid(renderer, x, y, width, height, id) { + this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id); + } + clearCurrentHitGrid(renderer) { + this.opentui.symbols.clearCurrentHitGrid(renderer); + } + hitGridPushScissorRect(renderer, x, y, width, height) { + this.opentui.symbols.hitGridPushScissorRect(renderer, x, y, width, height); + } + hitGridPopScissorRect(renderer) { + this.opentui.symbols.hitGridPopScissorRect(renderer); + } + hitGridClearScissorRects(renderer) { + this.opentui.symbols.hitGridClearScissorRects(renderer); + } + addToCurrentHitGridClipped(renderer, x, y, width, height, id) { + this.opentui.symbols.addToCurrentHitGridClipped(renderer, x, y, width, height, id); + } + checkHit(renderer, x, y) { + return this.opentui.symbols.checkHit(renderer, x, y); + } + getHitGridDirty(renderer) { + return this.opentui.symbols.getHitGridDirty(renderer); + } + dumpHitGrid(renderer) { + this.opentui.symbols.dumpHitGrid(renderer); + } + dumpBuffers(renderer, timestamp) { + const ts = timestamp ?? Date.now(); + this.opentui.symbols.dumpBuffers(renderer, ts); + } + dumpOutputBuffer(renderer, timestamp) { + const ts = timestamp ?? Date.now(); + this.opentui.symbols.dumpOutputBuffer(renderer, ts); + } + restoreTerminalModes(renderer) { + this.opentui.symbols.restoreTerminalModes(renderer); + } + enableMouse(renderer, enableMovement) { + this.opentui.symbols.enableMouse(renderer, ffiBool(enableMovement)); + } + disableMouse(renderer) { + this.opentui.symbols.disableMouse(renderer); + } + enableKittyKeyboard(renderer, flags) { + this.opentui.symbols.enableKittyKeyboard(renderer, flags); + } + disableKittyKeyboard(renderer) { + this.opentui.symbols.disableKittyKeyboard(renderer); + } + setKittyKeyboardFlags(renderer, flags) { + this.opentui.symbols.setKittyKeyboardFlags(renderer, flags); + } + getKittyKeyboardFlags(renderer) { + return this.opentui.symbols.getKittyKeyboardFlags(renderer); + } + setupTerminal(renderer, useAlternateScreen) { + this.opentui.symbols.setupTerminal(renderer, ffiBool(useAlternateScreen)); + } + suspendRenderer(renderer) { + this.opentui.symbols.suspendRenderer(renderer); + } + resumeRenderer(renderer) { + this.opentui.symbols.resumeRenderer(renderer); + } + queryPixelResolution(renderer) { + this.opentui.symbols.queryPixelResolution(renderer); + } + queryThemeColors(renderer) { + this.opentui.symbols.queryThemeColors(renderer); + } + writeOut(renderer, data) { + const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data; + if (bytes.length === 0) + return; + this.opentui.symbols.writeOut(renderer, ptrOrNull(bytes), bytes.byteLength); + } + yogaConfigCreate() { + const config = this.opentui.symbols.yogaConfigCreate(); + if (!config) + throw new Error("Failed to create Yoga config"); + return config; + } + yogaConfigFree(config) { + this.opentui.symbols.yogaConfigFree(config); + } + yogaConfigSetUseWebDefaults(config, enabled) { + this.opentui.symbols.yogaConfigSetUseWebDefaults(config, ffiBool(enabled)); + } + yogaConfigGetUseWebDefaults(config) { + return this.opentui.symbols.yogaConfigGetUseWebDefaults(config); + } + yogaConfigSetPointScaleFactor(config, pointScaleFactor) { + this.opentui.symbols.yogaConfigSetPointScaleFactor(config, pointScaleFactor); + } + yogaConfigGetPointScaleFactor(config) { + return this.opentui.symbols.yogaConfigGetPointScaleFactor(config); + } + yogaConfigSetErrata(config, errata) { + this.opentui.symbols.yogaConfigSetErrata(config, errata); + } + yogaConfigGetErrata(config) { + return this.opentui.symbols.yogaConfigGetErrata(config); + } + yogaConfigSetExperimentalFeatureEnabled(config, feature, enabled) { + this.opentui.symbols.yogaConfigSetExperimentalFeatureEnabled(config, feature, ffiBool(enabled)); + } + yogaConfigIsExperimentalFeatureEnabled(config, feature) { + return this.opentui.symbols.yogaConfigIsExperimentalFeatureEnabled(config, feature); + } + yogaNodeCreate() { + const node = this.opentui.symbols.yogaNodeCreate(); + if (!node) + throw new Error("Failed to create Yoga node"); + return node; + } + yogaNodeCreateForOpenTUI() { + const node = this.opentui.symbols.yogaNodeCreateForOpenTUI(); + if (!node) + throw new Error("Failed to create OpenTUI Yoga node"); + return node; + } + yogaNodeCreateWithConfig(config) { + const node = this.opentui.symbols.yogaNodeCreateWithConfig(config); + if (!node) + throw new Error("Failed to create Yoga node"); + return node; + } + yogaNodeFree(node) { + this.opentui.symbols.yogaNodeFree(node); + } + yogaNodeFreeRecursive(node) { + this.opentui.symbols.yogaNodeFreeRecursive(node); + } + yogaNodeReset(node) { + this.opentui.symbols.yogaNodeReset(node); + } + yogaNodeCopyStyle(dstNode, srcNode) { + this.opentui.symbols.yogaNodeCopyStyle(dstNode, srcNode); + } + yogaNodeInsertChild(node, child, index) { + this.opentui.symbols.yogaNodeInsertChild(node, child, index); + } + yogaNodeRemoveChild(node, child) { + this.opentui.symbols.yogaNodeRemoveChild(node, child); + } + yogaNodeRemoveAllChildren(node) { + this.opentui.symbols.yogaNodeRemoveAllChildren(node); + } + yogaNodeGetChild(node, index) { + return this.opentui.symbols.yogaNodeGetChild(node, index) || null; + } + yogaNodeGetChildCount(node) { + return this.opentui.symbols.yogaNodeGetChildCount(node); + } + yogaNodeGetParent(node) { + return this.opentui.symbols.yogaNodeGetParent(node) || null; + } + yogaNodeCalculateLayout(node, width, height, direction) { + this.opentui.symbols.yogaNodeCalculateLayout(node, width, height, direction); + } + yogaNodeIsDirty(node) { + return this.opentui.symbols.yogaNodeIsDirty(node); + } + yogaNodeMarkDirty(node) { + this.opentui.symbols.yogaNodeMarkDirty(node); + } + yogaNodeGetHasNewLayout(node) { + return this.opentui.symbols.yogaNodeGetHasNewLayout(node); + } + yogaNodeSetHasNewLayout(node, hasNewLayout) { + this.opentui.symbols.yogaNodeSetHasNewLayout(node, ffiBool(hasNewLayout)); + } + yogaNodeSetIsReferenceBaseline(node, isReferenceBaseline) { + this.opentui.symbols.yogaNodeSetIsReferenceBaseline(node, ffiBool(isReferenceBaseline)); + } + yogaNodeIsReferenceBaseline(node) { + return this.opentui.symbols.yogaNodeIsReferenceBaseline(node); + } + yogaNodeSetAlwaysFormsContainingBlock(node, alwaysFormsContainingBlock) { + this.opentui.symbols.yogaNodeSetAlwaysFormsContainingBlock(node, ffiBool(alwaysFormsContainingBlock)); + } + yogaNodeGetAlwaysFormsContainingBlock(node) { + return this.opentui.symbols.yogaNodeGetAlwaysFormsContainingBlock(node); + } + yogaNodeGetComputedLayout(node) { + const layout = new Float32Array(6); + this.opentui.symbols.yogaNodeGetComputedLayout(node, ptr(layout)); + return { + left: layout[0], + top: layout[1], + right: layout[2], + bottom: layout[3], + width: layout[4], + height: layout[5] + }; + } + yogaNodeLayoutGetEdge(node, kind, edge) { + return this.opentui.symbols.yogaNodeLayoutGetEdge(node, kind, edge); + } + yogaNodeStyleSetEnum(node, kind, value) { + this.opentui.symbols.yogaNodeStyleSetEnum(node, kind, value); + } + yogaNodeStyleGetEnum(node, kind) { + return this.opentui.symbols.yogaNodeStyleGetEnum(node, kind); + } + yogaNodeStyleSetFloat(node, kind, value) { + this.opentui.symbols.yogaNodeStyleSetFloat(node, kind, value); + } + yogaNodeStyleGetFloat(node, kind) { + return this.opentui.symbols.yogaNodeStyleGetFloat(node, kind); + } + yogaNodeStyleSetBorder(node, edge, border2) { + this.opentui.symbols.yogaNodeStyleSetBorder(node, edge, border2); + } + yogaNodeStyleGetBorder(node, edge) { + return this.opentui.symbols.yogaNodeStyleGetBorder(node, edge); + } + yogaNodeStyleSetValue(node, kind, edgeOrGutter, unit, value) { + this.opentui.symbols.yogaNodeStyleSetValue(node, kind, edgeOrGutter, unit, value); + } + yogaNodeStyleGetValue(node, kind, edgeOrGutter) { + return this.opentui.symbols.yogaNodeStyleGetValue(node, kind, edgeOrGutter); + } + yogaNodeSetMeasureFunc(node, callback) { + this.opentui.symbols.yogaNodeSetMeasureFunc(node, callback); + } + yogaNodeUnsetMeasureFunc(node) { + this.opentui.symbols.yogaNodeUnsetMeasureFunc(node); + } + yogaNodeHasMeasureFunc(node) { + return this.opentui.symbols.yogaNodeHasMeasureFunc(node); + } + yogaNodeSetDirtiedFunc(node, callback) { + this.opentui.symbols.yogaNodeSetDirtiedFunc(node, callback); + } + yogaNodeUnsetDirtiedFunc(node) { + this.opentui.symbols.yogaNodeUnsetDirtiedFunc(node); + } + yogaStoreMeasureResult(width, height) { + this.opentui.symbols.yogaStoreMeasureResult(width, height); + } + createYogaMeasureCallback(callback) { + return this.opentui.createCallback(callback, { + args: ["ptr", "f32", "u32", "f32", "u32"], + returns: "void" + }); + } + createYogaDirtiedCallback(callback) { + return this.opentui.createCallback(callback, { + args: [], + returns: "void" + }); + } + createTextBuffer(widthMethod) { + const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1; + const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode); + if (!bufferPtr) { + throw new Error(`Failed to create TextBuffer`); + } + return new TextBuffer(this, bufferPtr); + } + destroyTextBuffer(buffer) { + this.opentui.symbols.destroyTextBuffer(buffer); + } + textBufferGetLength(buffer) { + return this.opentui.symbols.textBufferGetLength(buffer); + } + textBufferGetByteSize(buffer) { + return this.opentui.symbols.textBufferGetByteSize(buffer); + } + textBufferReset(buffer) { + this.opentui.symbols.textBufferReset(buffer); + } + textBufferClear(buffer) { + this.opentui.symbols.textBufferClear(buffer); + } + textBufferSetDefaultFg(buffer, fg2) { + const fgPtr = optionalRgbaPtr(fg2); + this.opentui.symbols.textBufferSetDefaultFg(buffer, fgPtr); + } + textBufferSetDefaultBg(buffer, bg2) { + const bgPtr = optionalRgbaPtr(bg2); + this.opentui.symbols.textBufferSetDefaultBg(buffer, bgPtr); + } + textBufferSetDefaultAttributes(buffer, attributes) { + const attrValue = attributes === null ? null : new Uint32Array([attributes]); + this.opentui.symbols.textBufferSetDefaultAttributes(buffer, attrValue ? ptr(attrValue) : null); + } + textBufferResetDefaults(buffer) { + this.opentui.symbols.textBufferResetDefaults(buffer); + } + textBufferGetTabWidth(buffer) { + return this.opentui.symbols.textBufferGetTabWidth(buffer); + } + textBufferSetTabWidth(buffer, width) { + this.opentui.symbols.textBufferSetTabWidth(buffer, width); + } + textBufferRegisterMemBuffer(buffer, bytes, owned = false) { + const result = this.opentui.symbols.textBufferRegisterMemBuffer(buffer, ptrOrNull(bytes), bytes.byteLength, ffiBool(owned)); + if (result === 65535) { + throw new Error("Failed to register memory buffer"); + } + return result; + } + textBufferReplaceMemBuffer(buffer, memId, bytes, owned = false) { + return this.opentui.symbols.textBufferReplaceMemBuffer(buffer, memId, ptrOrNull(bytes), bytes.byteLength, ffiBool(owned)); + } + textBufferClearMemRegistry(buffer) { + this.opentui.symbols.textBufferClearMemRegistry(buffer); + } + textBufferSetTextFromMem(buffer, memId) { + this.opentui.symbols.textBufferSetTextFromMem(buffer, memId); + } + textBufferAppend(buffer, bytes) { + this.opentui.symbols.textBufferAppend(buffer, ptrOrNull(bytes), bytes.byteLength); + } + textBufferAppendFromMemId(buffer, memId) { + this.opentui.symbols.textBufferAppendFromMemId(buffer, memId); + } + textBufferLoadFile(buffer, path3) { + const pathBytes = this.encoder.encode(path3); + return this.opentui.symbols.textBufferLoadFile(buffer, ptrOrNull(pathBytes), pathBytes.byteLength); + } + textBufferSetStyledText(buffer, chunks) { + if (chunks.length === 0) { + this.textBufferClear(buffer); + return; + } + const chunksBuffer = StyledChunkStruct.packList(chunks); + this.opentui.symbols.textBufferSetStyledText(buffer, ptr(chunksBuffer), chunks.length); + } + textBufferGetLineCount(buffer) { + return this.opentui.symbols.textBufferGetLineCount(buffer); + } + textBufferGetPlainText(buffer, outPtr, maxLen) { + return this.opentui.symbols.textBufferGetPlainText(buffer, outPtr, maxLen); + } + getPlainTextBytes(buffer, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.textBufferGetPlainText(buffer, ptrOrNull(outBuffer), maxLength); + if (actualLen === 0) { + return null; + } + return outBuffer.slice(0, actualLen); + } + textBufferGetTextRange(buffer, startOffset, endOffset, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.textBufferGetTextRange(buffer, startOffset, endOffset, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) { + return null; + } + return outBuffer.slice(0, len); + } + textBufferGetTextRangeByCoords(buffer, startRow, startCol, endRow, endCol, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.textBufferGetTextRangeByCoords(buffer, startRow, startCol, endRow, endCol, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) { + return null; + } + return outBuffer.slice(0, len); + } + createTextBufferView(textBuffer) { + const viewPtr = this.opentui.symbols.createTextBufferView(textBuffer); + if (!viewPtr) { + throw new Error("Failed to create TextBufferView"); + } + return viewPtr; + } + destroyTextBufferView(view) { + this.opentui.symbols.destroyTextBufferView(view); + } + textBufferViewSetSelection(view, start, end, bgColor, fgColor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + this.opentui.symbols.textBufferViewSetSelection(view, start, end, bg2, fg2); + } + textBufferViewResetSelection(view) { + this.opentui.symbols.textBufferViewResetSelection(view); + } + textBufferViewGetSelection(view) { + const packedInfo = this.textBufferViewGetSelectionInfo(view); + if (packedInfo === 0xffff_ffff_ffff_ffffn) { + return null; + } + const start = Number(packedInfo >> 32n); + const end = Number(packedInfo & 0xffff_ffffn); + return { start, end }; + } + textBufferViewGetSelectionInfo(view) { + return this.opentui.symbols.textBufferViewGetSelectionInfo(view); + } + textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + return Boolean(this.opentui.symbols.textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2)); + } + textBufferViewUpdateSelection(view, end, bgColor, fgColor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + this.opentui.symbols.textBufferViewUpdateSelection(view, end, bg2, fg2); + } + textBufferViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + return Boolean(this.opentui.symbols.textBufferViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2)); + } + textBufferViewResetLocalSelection(view) { + this.opentui.symbols.textBufferViewResetLocalSelection(view); + } + textBufferViewSetWrapWidth(view, width) { + this.opentui.symbols.textBufferViewSetWrapWidth(view, width); + } + textBufferViewSetWrapMode(view, mode) { + const modeValue = mode === "none" ? 0 : mode === "char" ? 1 : 2; + this.opentui.symbols.textBufferViewSetWrapMode(view, modeValue); + } + textBufferViewSetFirstLineOffset(view, offset) { + this.opentui.symbols.textBufferViewSetFirstLineOffset(view, offset); + } + textBufferViewSetViewportSize(view, width, height) { + this.opentui.symbols.textBufferViewSetViewportSize(view, width, height); + } + textBufferViewSetViewport(view, x, y, width, height) { + this.opentui.symbols.textBufferViewSetViewport(view, x, y, width, height); + } + textBufferViewGetLineInfo(view) { + const outBuffer = new ArrayBuffer(LineInfoStruct.size); + this.textBufferViewGetLineInfoDirect(view, ptr(outBuffer)); + const struct = LineInfoStruct.unpack(outBuffer); + const lineStartCols = struct.startCols; + const lineWidthCols = struct.widthCols; + const lineWidthColsMax = struct.widthColsMax; + return { + lineStartCols, + lineWidthCols, + lineWidthColsMax, + lineSources: struct.sources, + lineWraps: struct.wraps + }; + } + textBufferViewGetLogicalLineInfo(view) { + const outBuffer = new ArrayBuffer(LineInfoStruct.size); + this.textBufferViewGetLogicalLineInfoDirect(view, ptr(outBuffer)); + const struct = LineInfoStruct.unpack(outBuffer); + const lineStartCols = struct.startCols; + const lineWidthCols = struct.widthCols; + const lineWidthColsMax = struct.widthColsMax; + return { + lineStartCols, + lineWidthCols, + lineWidthColsMax, + lineSources: struct.sources, + lineWraps: struct.wraps + }; + } + textBufferViewGetVirtualLineCount(view) { + return this.opentui.symbols.textBufferViewGetVirtualLineCount(view); + } + textBufferViewGetLineInfoDirect(view, outPtr) { + this.opentui.symbols.textBufferViewGetLineInfoDirect(view, outPtr); + } + textBufferViewGetLogicalLineInfoDirect(view, outPtr) { + this.opentui.symbols.textBufferViewGetLogicalLineInfoDirect(view, outPtr); + } + textBufferViewGetSelectedText(view, outPtr, maxLen) { + return this.opentui.symbols.textBufferViewGetSelectedText(view, outPtr, maxLen); + } + textBufferViewGetPlainText(view, outPtr, maxLen) { + return this.opentui.symbols.textBufferViewGetPlainText(view, outPtr, maxLen); + } + textBufferViewGetSelectedTextBytes(view, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.textBufferViewGetSelectedText(view, ptrOrNull(outBuffer), maxLength); + if (actualLen === 0) { + return null; + } + return outBuffer.slice(0, actualLen); + } + textBufferViewGetPlainTextBytes(view, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.textBufferViewGetPlainText(view, ptrOrNull(outBuffer), maxLength); + if (actualLen === 0) { + return null; + } + return outBuffer.slice(0, actualLen); + } + textBufferViewSetTabIndicator(view, indicator) { + this.opentui.symbols.textBufferViewSetTabIndicator(view, indicator); + } + textBufferViewSetTabIndicatorColor(view, color) { + this.opentui.symbols.textBufferViewSetTabIndicatorColor(view, rgbaPtr(color)); + } + textBufferViewSetTruncate(view, truncate) { + this.opentui.symbols.textBufferViewSetTruncate(view, ffiBool(truncate)); + } + textBufferViewMeasureForDimensions(view, width, height) { + const resultBuffer = new ArrayBuffer(MeasureResultStruct.size); + const resultPtr = ptr(new Uint8Array(resultBuffer)); + const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, resultPtr); + if (!success) { + return null; + } + const result = MeasureResultStruct.unpack(resultBuffer); + return result; + } + textBufferAddHighlightByCharRange(buffer, highlight) { + const packedHighlight = HighlightStruct.pack(highlight); + this.opentui.symbols.textBufferAddHighlightByCharRange(buffer, ptr(packedHighlight)); + } + textBufferAddHighlight(buffer, lineIdx, highlight) { + const packedHighlight = HighlightStruct.pack(highlight); + this.opentui.symbols.textBufferAddHighlight(buffer, lineIdx, ptr(packedHighlight)); + } + textBufferRemoveHighlightsByRef(buffer, hlRef) { + this.opentui.symbols.textBufferRemoveHighlightsByRef(buffer, hlRef); + } + textBufferClearLineHighlights(buffer, lineIdx) { + this.opentui.symbols.textBufferClearLineHighlights(buffer, lineIdx); + } + textBufferClearAllHighlights(buffer) { + this.opentui.symbols.textBufferClearAllHighlights(buffer); + } + textBufferSetSyntaxStyle(buffer, style) { + return this.opentui.symbols.textBufferSetSyntaxStyle(buffer, style ?? 0); + } + textBufferGetLineHighlights(buffer, lineIdx) { + const outCountBuf = new Uint32Array(1); + const nativePtr = this.opentui.symbols.textBufferGetLineHighlightsPtr(buffer, lineIdx, ptr(outCountBuf)); + if (!nativePtr) + return []; + const count = outCountBuf[0]; + const byteLen = count * HighlightStruct.size; + const raw = toArrayBuffer(nativePtr, 0, byteLen); + const results = HighlightStruct.unpackList(raw, count); + this.opentui.symbols.textBufferFreeLineHighlights(nativePtr, count); + return results; + } + textBufferGetHighlightCount(buffer) { + return this.opentui.symbols.textBufferGetHighlightCount(buffer); + } + getArenaAllocatedBytes() { + const result = this.opentui.symbols.getArenaAllocatedBytes(); + return toSafeByteCount(result, "Arena allocated bytes"); + } + getBuildOptions() { + const optionsBuffer = new ArrayBuffer(BuildOptionsStruct.size); + this.opentui.symbols.getBuildOptions(ptr(optionsBuffer)); + const options = BuildOptionsStruct.unpack(optionsBuffer); + return { + gpaSafeStats: !!options.gpaSafeStats, + gpaMemoryLimitTracking: !!options.gpaMemoryLimitTracking + }; + } + getAllocatorStats() { + const statsBuffer = new ArrayBuffer(AllocatorStatsStruct.size); + this.opentui.symbols.getAllocatorStats(ptr(statsBuffer)); + const stats = AllocatorStatsStruct.unpack(statsBuffer); + return { + totalRequestedBytes: toNumber(stats.totalRequestedBytes), + activeAllocations: toNumber(stats.activeAllocations), + smallAllocations: toNumber(stats.smallAllocations), + largeAllocations: toNumber(stats.largeAllocations), + requestedBytesValid: !!stats.requestedBytesValid + }; + } + bufferDrawTextBufferView(buffer, view, x, y) { + this.opentui.symbols.bufferDrawTextBufferView(buffer, view, x, y); + } + bufferDrawEditorView(buffer, view, x, y) { + this.opentui.symbols.bufferDrawEditorView(buffer, view, x, y); + } + createEditorView(editBufferPtr, viewportWidth, viewportHeight) { + const viewPtr = this.opentui.symbols.createEditorView(editBufferPtr, viewportWidth, viewportHeight); + if (!viewPtr) { + throw new Error("Failed to create EditorView"); + } + return viewPtr; + } + destroyEditorView(view) { + this.opentui.symbols.destroyEditorView(view); + } + editorViewSetViewportSize(view, width, height) { + this.opentui.symbols.editorViewSetViewportSize(view, width, height); + } + editorViewSetViewport(view, x, y, width, height, moveCursor) { + this.opentui.symbols.editorViewSetViewport(view, x, y, width, height, ffiBool(moveCursor)); + } + editorViewGetViewport(view) { + const x = new Uint32Array(1); + const y = new Uint32Array(1); + const width = new Uint32Array(1); + const height = new Uint32Array(1); + this.opentui.symbols.editorViewGetViewport(view, ptr(x), ptr(y), ptr(width), ptr(height)); + return { + offsetX: x[0], + offsetY: y[0], + width: width[0], + height: height[0] + }; + } + editorViewSetScrollMargin(view, margin) { + this.opentui.symbols.editorViewSetScrollMargin(view, margin); + } + editorViewSetWrapMode(view, mode) { + const modeValue = mode === "none" ? 0 : mode === "char" ? 1 : 2; + this.opentui.symbols.editorViewSetWrapMode(view, modeValue); + } + editorViewGetVirtualLineCount(view) { + return this.opentui.symbols.editorViewGetVirtualLineCount(view); + } + editorViewGetTotalVirtualLineCount(view) { + return this.opentui.symbols.editorViewGetTotalVirtualLineCount(view); + } + editorViewGetTextBufferView(view) { + const result = this.opentui.symbols.editorViewGetTextBufferView(view); + if (!result) { + throw new Error("Failed to get TextBufferView from EditorView"); + } + return result; + } + editorViewGetLineInfo(view) { + const outBuffer = new ArrayBuffer(LineInfoStruct.size); + this.opentui.symbols.editorViewGetLineInfoDirect(view, ptr(outBuffer)); + const struct = LineInfoStruct.unpack(outBuffer); + const lineStartCols = struct.startCols; + const lineWidthCols = struct.widthCols; + const lineWidthColsMax = struct.widthColsMax; + return { + lineStartCols, + lineWidthCols, + lineWidthColsMax, + lineSources: struct.sources, + lineWraps: struct.wraps + }; + } + editorViewGetLogicalLineInfo(view) { + const outBuffer = new ArrayBuffer(LineInfoStruct.size); + this.opentui.symbols.editorViewGetLogicalLineInfoDirect(view, ptr(outBuffer)); + const struct = LineInfoStruct.unpack(outBuffer); + const lineStartCols = struct.startCols; + const lineWidthCols = struct.widthCols; + const lineWidthColsMax = struct.widthColsMax; + return { + lineStartCols, + lineWidthCols, + lineWidthColsMax, + lineSources: struct.sources, + lineWraps: struct.wraps + }; + } + createEditBuffer(widthMethod) { + const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1; + const bufferPtr = this.opentui.symbols.createEditBuffer(widthMethodCode, this.eventSinkPtr ?? 0); + if (!bufferPtr) { + throw new Error("Failed to create EditBuffer"); + } + return bufferPtr; + } + destroyEditBuffer(buffer) { + this.opentui.symbols.destroyEditBuffer(buffer); + } + editBufferSetText(buffer, textBytes) { + this.opentui.symbols.editBufferSetText(buffer, ptrOrNull(textBytes), textBytes.byteLength); + } + editBufferSetTextFromMem(buffer, memId) { + this.opentui.symbols.editBufferSetTextFromMem(buffer, memId); + } + editBufferReplaceText(buffer, textBytes) { + this.opentui.symbols.editBufferReplaceText(buffer, ptrOrNull(textBytes), textBytes.byteLength); + } + editBufferReplaceTextFromMem(buffer, memId) { + this.opentui.symbols.editBufferReplaceTextFromMem(buffer, memId); + } + editBufferGetText(buffer, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.editBufferGetText(buffer, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) + return null; + return outBuffer.slice(0, len); + } + editBufferInsertChar(buffer, char) { + const charBytes = this.encoder.encode(char); + this.opentui.symbols.editBufferInsertChar(buffer, ptrOrNull(charBytes), charBytes.byteLength); + } + editBufferInsertText(buffer, text) { + const textBytes = this.encoder.encode(text); + this.opentui.symbols.editBufferInsertText(buffer, ptrOrNull(textBytes), textBytes.byteLength); + } + editBufferDeleteChar(buffer) { + this.opentui.symbols.editBufferDeleteChar(buffer); + } + editBufferDeleteCharBackward(buffer) { + this.opentui.symbols.editBufferDeleteCharBackward(buffer); + } + editBufferDeleteRange(buffer, startLine, startCol, endLine, endCol) { + this.opentui.symbols.editBufferDeleteRange(buffer, startLine, startCol, endLine, endCol); + } + editBufferNewLine(buffer) { + this.opentui.symbols.editBufferNewLine(buffer); + } + editBufferDeleteLine(buffer) { + this.opentui.symbols.editBufferDeleteLine(buffer); + } + editBufferMoveCursorLeft(buffer) { + this.opentui.symbols.editBufferMoveCursorLeft(buffer); + } + editBufferMoveCursorRight(buffer) { + this.opentui.symbols.editBufferMoveCursorRight(buffer); + } + editBufferMoveCursorUp(buffer) { + this.opentui.symbols.editBufferMoveCursorUp(buffer); + } + editBufferMoveCursorDown(buffer) { + this.opentui.symbols.editBufferMoveCursorDown(buffer); + } + editBufferGotoLine(buffer, line) { + this.opentui.symbols.editBufferGotoLine(buffer, line); + } + editBufferSetCursor(buffer, line, byteOffset) { + this.opentui.symbols.editBufferSetCursor(buffer, line, byteOffset); + } + editBufferSetCursorToLineCol(buffer, line, col) { + this.opentui.symbols.editBufferSetCursorToLineCol(buffer, line, col); + } + editBufferSetCursorByOffset(buffer, offset) { + this.opentui.symbols.editBufferSetCursorByOffset(buffer, offset); + } + editBufferGetCursorPosition(buffer) { + const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size); + this.opentui.symbols.editBufferGetCursorPosition(buffer, ptr(cursorBuffer)); + return LogicalCursorStruct.unpack(cursorBuffer); + } + editBufferGetId(buffer) { + return this.opentui.symbols.editBufferGetId(buffer); + } + editBufferGetTextBuffer(buffer) { + const result = this.opentui.symbols.editBufferGetTextBuffer(buffer); + if (!result) { + throw new Error("Failed to get TextBuffer from EditBuffer"); + } + return result; + } + editBufferDebugLogRope(buffer) { + this.opentui.symbols.editBufferDebugLogRope(buffer); + } + editBufferUndo(buffer, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.editBufferUndo(buffer, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) + return null; + return outBuffer.slice(0, len); + } + editBufferRedo(buffer, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.editBufferRedo(buffer, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) + return null; + return outBuffer.slice(0, len); + } + editBufferCanUndo(buffer) { + return Boolean(this.opentui.symbols.editBufferCanUndo(buffer)); + } + editBufferCanRedo(buffer) { + return Boolean(this.opentui.symbols.editBufferCanRedo(buffer)); + } + editBufferClearHistory(buffer) { + this.opentui.symbols.editBufferClearHistory(buffer); + } + editBufferClear(buffer) { + this.opentui.symbols.editBufferClear(buffer); + } + editBufferGetNextWordBoundary(buffer) { + const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size); + this.opentui.symbols.editBufferGetNextWordBoundary(buffer, ptr(cursorBuffer)); + return LogicalCursorStruct.unpack(cursorBuffer); + } + editBufferGetPrevWordBoundary(buffer) { + const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size); + this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, ptr(cursorBuffer)); + return LogicalCursorStruct.unpack(cursorBuffer); + } + editBufferGetEOL(buffer) { + const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size); + this.opentui.symbols.editBufferGetEOL(buffer, ptr(cursorBuffer)); + return LogicalCursorStruct.unpack(cursorBuffer); + } + editBufferOffsetToPosition(buffer, offset) { + const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size); + const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, ptr(cursorBuffer)); + if (!success) + return null; + return LogicalCursorStruct.unpack(cursorBuffer); + } + editBufferPositionToOffset(buffer, row, col) { + return this.opentui.symbols.editBufferPositionToOffset(buffer, row, col); + } + editBufferGetLineStartOffset(buffer, row) { + return this.opentui.symbols.editBufferGetLineStartOffset(buffer, row); + } + editBufferGetTextRange(buffer, startOffset, endOffset, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.editBufferGetTextRange(buffer, startOffset, endOffset, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) + return null; + return outBuffer.slice(0, len); + } + editBufferGetTextRangeByCoords(buffer, startRow, startCol, endRow, endCol, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.editBufferGetTextRangeByCoords(buffer, startRow, startCol, endRow, endCol, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) + return null; + return outBuffer.slice(0, len); + } + editorViewSetSelection(view, start, end, bgColor, fgColor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + this.opentui.symbols.editorViewSetSelection(view, start, end, bg2, fg2); + } + editorViewResetSelection(view) { + this.opentui.symbols.editorViewResetSelection(view); + } + editorViewGetSelection(view) { + const packedInfo = this.opentui.symbols.editorViewGetSelection(view); + if (packedInfo === 0xffff_ffff_ffff_ffffn) { + return null; + } + const start = Number(packedInfo >> 32n); + const end = Number(packedInfo & 0xffff_ffffn); + return { start, end }; + } + editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + return Boolean(this.opentui.symbols.editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, ffiBool(updateCursor), ffiBool(followCursor))); + } + editorViewUpdateSelection(view, end, bgColor, fgColor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + this.opentui.symbols.editorViewUpdateSelection(view, end, bg2, fg2); + } + editorViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) { + const bg2 = optionalRgbaPtr(bgColor); + const fg2 = optionalRgbaPtr(fgColor); + return Boolean(this.opentui.symbols.editorViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, ffiBool(updateCursor), ffiBool(followCursor))); + } + editorViewResetLocalSelection(view) { + this.opentui.symbols.editorViewResetLocalSelection(view); + } + editorViewGetSelectedTextBytes(view, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.editorViewGetSelectedTextBytes(view, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) + return null; + return outBuffer.slice(0, len); + } + editorViewGetCursor(view) { + const row = new Uint32Array(1); + const col = new Uint32Array(1); + this.opentui.symbols.editorViewGetCursor(view, ptr(row), ptr(col)); + return { row: row[0], col: col[0] }; + } + editorViewGetText(view, maxLength) { + const outBuffer = new Uint8Array(maxLength); + const actualLen = this.opentui.symbols.editorViewGetText(view, ptrOrNull(outBuffer), maxLength); + const len = actualLen; + if (len === 0) + return null; + return outBuffer.slice(0, len); + } + editorViewGetVisualCursor(view) { + const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size); + this.opentui.symbols.editorViewGetVisualCursor(view, ptr(cursorBuffer)); + return VisualCursorStruct.unpack(cursorBuffer); + } + editorViewMoveUpVisual(view) { + this.opentui.symbols.editorViewMoveUpVisual(view); + } + editorViewMoveDownVisual(view) { + this.opentui.symbols.editorViewMoveDownVisual(view); + } + editorViewDeleteSelectedText(view) { + this.opentui.symbols.editorViewDeleteSelectedText(view); + } + editorViewSetCursorByOffset(view, offset) { + this.opentui.symbols.editorViewSetCursorByOffset(view, offset); + } + editorViewGetNextWordBoundary(view) { + const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size); + this.opentui.symbols.editorViewGetNextWordBoundary(view, ptr(cursorBuffer)); + return VisualCursorStruct.unpack(cursorBuffer); + } + editorViewGetPrevWordBoundary(view) { + const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size); + this.opentui.symbols.editorViewGetPrevWordBoundary(view, ptr(cursorBuffer)); + return VisualCursorStruct.unpack(cursorBuffer); + } + editorViewGetEOL(view) { + const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size); + this.opentui.symbols.editorViewGetEOL(view, ptr(cursorBuffer)); + return VisualCursorStruct.unpack(cursorBuffer); + } + editorViewGetVisualSOL(view) { + const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size); + this.opentui.symbols.editorViewGetVisualSOL(view, ptr(cursorBuffer)); + return VisualCursorStruct.unpack(cursorBuffer); + } + editorViewGetVisualEOL(view) { + const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size); + this.opentui.symbols.editorViewGetVisualEOL(view, ptr(cursorBuffer)); + return VisualCursorStruct.unpack(cursorBuffer); + } + bufferPushScissorRect(buffer, x, y, width, height) { + this.opentui.symbols.bufferPushScissorRect(buffer, x, y, width, height); + } + bufferPopScissorRect(buffer) { + this.opentui.symbols.bufferPopScissorRect(buffer); + } + bufferClearScissorRects(buffer) { + this.opentui.symbols.bufferClearScissorRects(buffer); + } + bufferPushOpacity(buffer, opacity) { + this.opentui.symbols.bufferPushOpacity(buffer, opacity); + } + bufferPopOpacity(buffer) { + this.opentui.symbols.bufferPopOpacity(buffer); + } + bufferGetCurrentOpacity(buffer) { + return this.opentui.symbols.bufferGetCurrentOpacity(buffer); + } + bufferClearOpacity(buffer) { + this.opentui.symbols.bufferClearOpacity(buffer); + } + getTerminalCapabilities(renderer) { + const capsBuffer = new ArrayBuffer(TerminalCapabilitiesStruct.size); + this.opentui.symbols.getTerminalCapabilities(renderer, ptr(capsBuffer)); + const caps = TerminalCapabilitiesStruct.unpack(capsBuffer); + return { + kitty_keyboard: caps.kitty_keyboard, + kitty_graphics: caps.kitty_graphics, + rgb: caps.rgb, + ansi256: caps.ansi256, + unicode: caps.unicode, + sgr_pixels: caps.sgr_pixels, + color_scheme_updates: caps.color_scheme_updates, + explicit_width: caps.explicit_width, + scaled_text: caps.scaled_text, + sixel: caps.sixel, + focus_tracking: caps.focus_tracking, + sync: caps.sync, + bracketed_paste: caps.bracketed_paste, + hyperlinks: caps.hyperlinks, + osc52: caps.osc52, + notifications: caps.notifications, + explicit_cursor_positioning: caps.explicit_cursor_positioning, + remote: caps.remote, + multiplexer: caps.multiplexer, + terminal: { + name: caps.term_name ?? "", + version: caps.term_version ?? "", + from_xtversion: caps.term_from_xtversion + } + }; + } + processCapabilityResponse(renderer, response) { + const responseBytes = this.encoder.encode(response); + this.opentui.symbols.processCapabilityResponse(renderer, ptrOrNull(responseBytes), responseBytes.byteLength); + } + encodeUnicode(text, widthMethod) { + const textBytes = this.encoder.encode(text); + const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1; + const outPtrBuffer = new ArrayBuffer(8); + const outLenBuffer = new ArrayBuffer(8); + const success = this.opentui.symbols.encodeUnicode(ptrOrNull(textBytes), textBytes.byteLength, ptr(outPtrBuffer), ptr(outLenBuffer), widthMethodCode); + if (!success) { + return null; + } + const outPtrView = new BigUint64Array(outPtrBuffer); + const outLenView = new BigUint64Array(outLenBuffer); + const resultLen = Number(outLenView[0]); + if (resultLen === 0) { + return { ptr: 0, data: [] }; + } + const resultPtr = toPointer(outPtrView[0]); + const byteLen = resultLen * EncodedCharStruct.size; + const raw = toArrayBuffer(resultPtr, 0, byteLen); + const data = EncodedCharStruct.unpackList(raw, resultLen); + return { ptr: resultPtr, data }; + } + freeUnicode(encoded) { + this.opentui.symbols.freeUnicode(encoded.ptr, encoded.data.length); + } + bufferDrawChar(buffer, char, x, y, fg2, bg2, attributes = 0) { + this.opentui.symbols.bufferDrawChar(buffer, char, x, y, rgbaPtr(fg2), rgbaPtr(bg2), attributes); + } + createAudioEngine(options) { + const optionsBuffer = options == null ? null : AudioCreateOptionsStruct.pack(options); + const engineHandle = this.opentui.symbols.createAudioEngine(optionsBuffer ? ptr(optionsBuffer) : null); + return engineHandle ? engineHandle : null; + } + destroyAudioEngine(engine) { + this.opentui.symbols.destroyAudioEngine(engine); + } + audioRefreshPlaybackDevices(engine) { + return this.opentui.symbols.audioRefreshPlaybackDevices(engine); + } + audioGetPlaybackDeviceCount(engine) { + return this.opentui.symbols.audioGetPlaybackDeviceCount(engine); + } + audioGetPlaybackDeviceName(engine, index) { + const outBuffer = new Uint8Array(512); + const bytesWritten = toNumber(this.opentui.symbols.audioGetPlaybackDeviceName(engine, index, ptr(outBuffer), outBuffer.length)); + const safeBytesWritten = Math.max(0, Math.min(outBuffer.length, bytesWritten)); + return this.decoder.decode(outBuffer.subarray(0, safeBytesWritten)); + } + audioIsPlaybackDeviceDefault(engine, index) { + return this.opentui.symbols.audioIsPlaybackDeviceDefault(engine, index); + } + audioSelectPlaybackDevice(engine, index) { + return this.opentui.symbols.audioSelectPlaybackDevice(engine, index); + } + audioClearPlaybackDeviceSelection(engine) { + this.opentui.symbols.audioClearPlaybackDeviceSelection(engine); + } + audioStart(engine, options) { + const optionsBuffer = options == null ? null : AudioStartOptionsStruct.pack(options); + return this.opentui.symbols.audioStart(engine, optionsBuffer ? ptr(optionsBuffer) : null); + } + audioStartMixer(engine) { + return this.opentui.symbols.audioStartMixer(engine); + } + audioStop(engine) { + return this.opentui.symbols.audioStop(engine); + } + audioLoad(engine, data) { + const outBuffer = new ArrayBuffer(4); + const dataLength = toSafeFFIU32Length(data.byteLength, "Audio data length"); + const status = this.opentui.symbols.audioLoad(engine, ptr(data), dataLength, ptr(outBuffer)); + if (status !== 0) { + return { status, soundId: null }; + } + const view = new Uint32Array(outBuffer); + return { status, soundId: view[0] }; + } + audioUnload(engine, soundId) { + return this.opentui.symbols.audioUnload(engine, soundId); + } + audioPlay(engine, soundId, options) { + const outBuffer = new ArrayBuffer(4); + const optionsBuffer = options ? AudioVoiceOptionsStruct.pack(options) : null; + const status = this.opentui.symbols.audioPlay(engine, soundId, optionsBuffer ? ptr(optionsBuffer) : null, ptr(outBuffer)); + if (status !== 0) { + return { status, voiceId: null }; + } + const view = new Uint32Array(outBuffer); + return { status, voiceId: view[0] }; + } + audioStopVoice(engine, voiceId) { + return this.opentui.symbols.audioStopVoice(engine, voiceId); + } + audioSetVoiceGroup(engine, voiceId, groupId) { + return this.opentui.symbols.audioSetVoiceGroup(engine, voiceId, groupId); + } + audioCreateGroup(engine, name) { + const outBuffer = new ArrayBuffer(4); + const nameBytes = this.encoder.encode(name); + const nameLength = toSafeFFIU32Length(nameBytes.byteLength, "Audio group name length"); + const status = this.opentui.symbols.audioCreateGroup(engine, ptr(nameBytes), nameLength, ptr(outBuffer)); + if (status !== 0) { + return { status, groupId: null }; + } + const view = new Uint32Array(outBuffer); + return { status, groupId: view[0] }; + } + audioSetGroupVolume(engine, groupId, volume) { + return this.opentui.symbols.audioSetGroupVolume(engine, groupId, volume); + } + audioSetMasterVolume(engine, volume) { + return this.opentui.symbols.audioSetMasterVolume(engine, volume); + } + audioMixToBuffer(engine, outBuffer, frameCount, channels) { + return this.opentui.symbols.audioMixToBuffer(engine, ptr(outBuffer), frameCount, channels); + } + audioEnableTap(engine, enabled, capacityFrames) { + return this.opentui.symbols.audioEnableTap(engine, ffiBool(enabled), capacityFrames); + } + audioReadTap(engine, outBuffer, frameCount, channels) { + const outFramesReadBuffer = new ArrayBuffer(4); + const status = this.opentui.symbols.audioReadTap(engine, ptr(outBuffer), frameCount, channels, ptr(outFramesReadBuffer)); + if (status !== 0) { + return { status, framesRead: 0 }; + } + const view = new Uint32Array(outFramesReadBuffer); + return { status, framesRead: view[0] ?? 0 }; + } + audioGetStats(engine) { + const statsBuffer = new ArrayBuffer(AudioStatsStruct.size); + const status = this.opentui.symbols.audioGetStats(engine, ptr(statsBuffer)); + if (status !== 0) { + return null; + } + const stats = AudioStatsStruct.unpack(statsBuffer); + return { + soundsLoaded: stats.soundsLoaded, + voicesActive: stats.voicesActive, + framesMixed: typeof stats.framesMixed === "bigint" ? stats.framesMixed : BigInt(stats.framesMixed), + lockMisses: stats.lockMisses, + lastPeak: stats.lastPeak, + lastRms: stats.lastRms + }; + } + registerNativeSpanFeedStream(stream, handler) { + const callback = this.ensureNativeSpanFeedCallback(); + this.nativeSpanFeedHandlers.set(stream, handler); + this.opentui.symbols.streamSetCallback(stream, callback.ptr); + } + unregisterNativeSpanFeedStream(stream) { + this.opentui.symbols.streamSetCallback(stream, null); + this.nativeSpanFeedHandlers.delete(stream); + } + createNativeSpanFeed(options) { + const optionsBuffer = options == null ? null : NativeSpanFeedOptionsStruct.pack(options); + const streamPtr = this.opentui.symbols.createNativeSpanFeed(optionsBuffer ? ptr(optionsBuffer) : null); + if (!streamPtr) { + throw new Error("Failed to create stream"); + } + return streamPtr; + } + attachNativeSpanFeed(stream) { + return this.opentui.symbols.attachNativeSpanFeed(stream); + } + destroyNativeSpanFeed(stream) { + this.opentui.symbols.destroyNativeSpanFeed(stream); + this.nativeSpanFeedHandlers.delete(stream); + } + streamWrite(stream, data) { + const bytes = typeof data === "string" ? this.encoder.encode(data) : data; + return this.opentui.symbols.streamWrite(stream, ptrOrNull(bytes), bytes.byteLength); + } + streamCommit(stream) { + return this.opentui.symbols.streamCommit(stream); + } + streamDrainSpans(stream, outBuffer, maxSpans) { + const count = this.opentui.symbols.streamDrainSpans(stream, ptr(outBuffer), maxSpans); + return toNumber(count); + } + streamClose(stream) { + return this.opentui.symbols.streamClose(stream); + } + streamSetOptions(stream, options) { + const optionsBuffer = NativeSpanFeedOptionsStruct.pack(options); + return this.opentui.symbols.streamSetOptions(stream, ptr(optionsBuffer)); + } + streamGetStats(stream) { + const statsBuffer = new ArrayBuffer(NativeSpanFeedStatsStruct.size); + const status = this.opentui.symbols.streamGetStats(stream, ptr(statsBuffer)); + if (status !== 0) { + return null; + } + const stats = NativeSpanFeedStatsStruct.unpack(statsBuffer); + return { + bytesWritten: typeof stats.bytesWritten === "bigint" ? stats.bytesWritten : BigInt(stats.bytesWritten), + spansCommitted: typeof stats.spansCommitted === "bigint" ? stats.spansCommitted : BigInt(stats.spansCommitted), + chunks: stats.chunks, + pendingSpans: stats.pendingSpans + }; + } + streamReserve(stream, minLen) { + const reserveBuffer = new ArrayBuffer(ReserveInfoStruct.size); + const status = this.opentui.symbols.streamReserve(stream, minLen, ptr(reserveBuffer)); + if (status !== 0) { + return { status, info: null }; + } + return { status, info: ReserveInfoStruct.unpack(reserveBuffer) }; + } + streamCommitReserved(stream, length) { + return this.opentui.symbols.streamCommitReserved(stream, length); + } + createSyntaxStyle() { + const styleHandle = this.opentui.symbols.createSyntaxStyle(); + if (!styleHandle) { + throw new Error("Failed to create SyntaxStyle"); + } + return styleHandle; + } + destroySyntaxStyle(style) { + this.opentui.symbols.destroySyntaxStyle(style); + } + syntaxStyleRegister(style, name, fg2, bg2, attributes) { + const nameBytes = this.encoder.encode(name); + const fgPtr = optionalRgbaPtr(fg2); + const bgPtr = optionalRgbaPtr(bg2); + return this.opentui.symbols.syntaxStyleRegister(style, ptrOrNull(nameBytes), nameBytes.byteLength, fgPtr, bgPtr, attributes); + } + syntaxStyleResolveByName(style, name) { + const nameBytes = this.encoder.encode(name); + const id = this.opentui.symbols.syntaxStyleResolveByName(style, ptrOrNull(nameBytes), nameBytes.byteLength); + return id === 0 ? null : id; + } + syntaxStyleGetStyleCount(style) { + return this.opentui.symbols.syntaxStyleGetStyleCount(style); + } + editorViewSetPlaceholderStyledText(view, chunks) { + const nonEmptyChunks = chunks.filter((c) => c.text.length > 0); + if (nonEmptyChunks.length === 0) { + this.opentui.symbols.editorViewSetPlaceholderStyledText(view, null, 0); + return; + } + const chunksBuffer = StyledChunkStruct.packList(nonEmptyChunks); + this.opentui.symbols.editorViewSetPlaceholderStyledText(view, ptr(chunksBuffer), nonEmptyChunks.length); + } + editorViewSetTabIndicator(view, indicator) { + this.opentui.symbols.editorViewSetTabIndicator(view, indicator); + } + editorViewSetTabIndicatorColor(view, color) { + this.opentui.symbols.editorViewSetTabIndicatorColor(view, rgbaPtr(color)); + } + onNativeEvent(name, handler) { + this._nativeEvents.on(name, handler); + } + onceNativeEvent(name, handler) { + this._nativeEvents.once(name, handler); + } + offNativeEvent(name, handler) { + this._nativeEvents.off(name, handler); + } + onAnyNativeEvent(handler) { + this._anyEventHandlers.push(handler); + } +} +var opentuiLibPath; +var opentuiLib; +var renderLibResolved = false; +function setRenderLibPath(libPath) { + if (opentuiLibPath !== libPath) { + if (renderLibResolved) { + throw new Error("setRenderLibPath() must be called before resolveRenderLib()"); + } + if (opentuiLib instanceof FFIRenderLib) { + opentuiLib.dispose(); + } + opentuiLibPath = libPath; + opentuiLib = undefined; + } +} +function resolveRenderLib() { + if (!opentuiLib) { + try { + opentuiLib = new FFIRenderLib(opentuiLibPath); + } catch (error) { + throw new Error(`Failed to initialize OpenTUI render library: ${error instanceof Error ? error.message : "Unknown error"}`); + } + } + renderLibResolved = true; + return opentuiLib; +} +try { + opentuiLib = new FFIRenderLib(opentuiLibPath); +} catch (error) {} + +// src/yoga.ts +var Align; +((Align2) => { + Align2[Align2["Auto"] = 0] = "Auto"; + Align2[Align2["FlexStart"] = 1] = "FlexStart"; + Align2[Align2["Center"] = 2] = "Center"; + Align2[Align2["FlexEnd"] = 3] = "FlexEnd"; + Align2[Align2["Stretch"] = 4] = "Stretch"; + Align2[Align2["Baseline"] = 5] = "Baseline"; + Align2[Align2["SpaceBetween"] = 6] = "SpaceBetween"; + Align2[Align2["SpaceAround"] = 7] = "SpaceAround"; + Align2[Align2["SpaceEvenly"] = 8] = "SpaceEvenly"; +})(Align ||= {}); +var BoxSizing; +((BoxSizing2) => { + BoxSizing2[BoxSizing2["BorderBox"] = 0] = "BorderBox"; + BoxSizing2[BoxSizing2["ContentBox"] = 1] = "ContentBox"; +})(BoxSizing ||= {}); +var Dimension; +((Dimension2) => { + Dimension2[Dimension2["Width"] = 0] = "Width"; + Dimension2[Dimension2["Height"] = 1] = "Height"; +})(Dimension ||= {}); +var Direction; +((Direction2) => { + Direction2[Direction2["Inherit"] = 0] = "Inherit"; + Direction2[Direction2["LTR"] = 1] = "LTR"; + Direction2[Direction2["RTL"] = 2] = "RTL"; +})(Direction ||= {}); +var Display; +((Display2) => { + Display2[Display2["Flex"] = 0] = "Flex"; + Display2[Display2["None"] = 1] = "None"; + Display2[Display2["Contents"] = 2] = "Contents"; +})(Display ||= {}); +var Edge; +((Edge2) => { + Edge2[Edge2["Left"] = 0] = "Left"; + Edge2[Edge2["Top"] = 1] = "Top"; + Edge2[Edge2["Right"] = 2] = "Right"; + Edge2[Edge2["Bottom"] = 3] = "Bottom"; + Edge2[Edge2["Start"] = 4] = "Start"; + Edge2[Edge2["End"] = 5] = "End"; + Edge2[Edge2["Horizontal"] = 6] = "Horizontal"; + Edge2[Edge2["Vertical"] = 7] = "Vertical"; + Edge2[Edge2["All"] = 8] = "All"; +})(Edge ||= {}); +var Errata; +((Errata2) => { + Errata2[Errata2["None"] = 0] = "None"; + Errata2[Errata2["StretchFlexBasis"] = 1] = "StretchFlexBasis"; + Errata2[Errata2["AbsolutePositionWithoutInsetsExcludesPadding"] = 2] = "AbsolutePositionWithoutInsetsExcludesPadding"; + Errata2[Errata2["AbsolutePercentAgainstInnerSize"] = 4] = "AbsolutePercentAgainstInnerSize"; + Errata2[Errata2["All"] = 2147483647] = "All"; + Errata2[Errata2["Classic"] = 2147483646] = "Classic"; +})(Errata ||= {}); +var ExperimentalFeature; +((ExperimentalFeature2) => { + ExperimentalFeature2[ExperimentalFeature2["WebFlexBasis"] = 0] = "WebFlexBasis"; +})(ExperimentalFeature ||= {}); +var FlexDirection; +((FlexDirection2) => { + FlexDirection2[FlexDirection2["Column"] = 0] = "Column"; + FlexDirection2[FlexDirection2["ColumnReverse"] = 1] = "ColumnReverse"; + FlexDirection2[FlexDirection2["Row"] = 2] = "Row"; + FlexDirection2[FlexDirection2["RowReverse"] = 3] = "RowReverse"; +})(FlexDirection ||= {}); +var Gutter; +((Gutter2) => { + Gutter2[Gutter2["Column"] = 0] = "Column"; + Gutter2[Gutter2["Row"] = 1] = "Row"; + Gutter2[Gutter2["All"] = 2] = "All"; +})(Gutter ||= {}); +var Justify; +((Justify2) => { + Justify2[Justify2["FlexStart"] = 0] = "FlexStart"; + Justify2[Justify2["Center"] = 1] = "Center"; + Justify2[Justify2["FlexEnd"] = 2] = "FlexEnd"; + Justify2[Justify2["SpaceBetween"] = 3] = "SpaceBetween"; + Justify2[Justify2["SpaceAround"] = 4] = "SpaceAround"; + Justify2[Justify2["SpaceEvenly"] = 5] = "SpaceEvenly"; +})(Justify ||= {}); +var LogLevel; +((LogLevel3) => { + LogLevel3[LogLevel3["Error"] = 0] = "Error"; + LogLevel3[LogLevel3["Warn"] = 1] = "Warn"; + LogLevel3[LogLevel3["Info"] = 2] = "Info"; + LogLevel3[LogLevel3["Debug"] = 3] = "Debug"; + LogLevel3[LogLevel3["Verbose"] = 4] = "Verbose"; + LogLevel3[LogLevel3["Fatal"] = 5] = "Fatal"; +})(LogLevel ||= {}); +var MeasureMode; +((MeasureMode2) => { + MeasureMode2[MeasureMode2["Undefined"] = 0] = "Undefined"; + MeasureMode2[MeasureMode2["Exactly"] = 1] = "Exactly"; + MeasureMode2[MeasureMode2["AtMost"] = 2] = "AtMost"; +})(MeasureMode ||= {}); +var NodeType; +((NodeType2) => { + NodeType2[NodeType2["Default"] = 0] = "Default"; + NodeType2[NodeType2["Text"] = 1] = "Text"; +})(NodeType ||= {}); +var Overflow; +((Overflow2) => { + Overflow2[Overflow2["Visible"] = 0] = "Visible"; + Overflow2[Overflow2["Hidden"] = 1] = "Hidden"; + Overflow2[Overflow2["Scroll"] = 2] = "Scroll"; +})(Overflow ||= {}); +var PositionType; +((PositionType2) => { + PositionType2[PositionType2["Static"] = 0] = "Static"; + PositionType2[PositionType2["Relative"] = 1] = "Relative"; + PositionType2[PositionType2["Absolute"] = 2] = "Absolute"; +})(PositionType ||= {}); +var Unit; +((Unit2) => { + Unit2[Unit2["Undefined"] = 0] = "Undefined"; + Unit2[Unit2["Point"] = 1] = "Point"; + Unit2[Unit2["Percent"] = 2] = "Percent"; + Unit2[Unit2["Auto"] = 3] = "Auto"; +})(Unit ||= {}); +var Wrap; +((_Wrap) => { + _Wrap[_Wrap["NoWrap"] = 0] = "NoWrap"; + _Wrap[_Wrap["Wrap"] = 1] = "Wrap"; + _Wrap[_Wrap["WrapReverse"] = 2] = "WrapReverse"; +})(Wrap ||= {}); +var ALIGN_AUTO = 0 /* Auto */; +var ALIGN_FLEX_START = 1 /* FlexStart */; +var ALIGN_CENTER = 2 /* Center */; +var ALIGN_FLEX_END = 3 /* FlexEnd */; +var ALIGN_STRETCH = 4 /* Stretch */; +var ALIGN_BASELINE = 5 /* Baseline */; +var ALIGN_SPACE_BETWEEN = 6 /* SpaceBetween */; +var ALIGN_SPACE_AROUND = 7 /* SpaceAround */; +var ALIGN_SPACE_EVENLY = 8 /* SpaceEvenly */; +var BOX_SIZING_BORDER_BOX = 0 /* BorderBox */; +var BOX_SIZING_CONTENT_BOX = 1 /* ContentBox */; +var DIMENSION_WIDTH = 0 /* Width */; +var DIMENSION_HEIGHT = 1 /* Height */; +var DIRECTION_INHERIT = 0 /* Inherit */; +var DIRECTION_LTR = 1 /* LTR */; +var DIRECTION_RTL = 2 /* RTL */; +var DISPLAY_FLEX = 0 /* Flex */; +var DISPLAY_NONE = 1 /* None */; +var DISPLAY_CONTENTS = 2 /* Contents */; +var EDGE_LEFT = 0 /* Left */; +var EDGE_TOP = 1 /* Top */; +var EDGE_RIGHT = 2 /* Right */; +var EDGE_BOTTOM = 3 /* Bottom */; +var EDGE_START = 4 /* Start */; +var EDGE_END = 5 /* End */; +var EDGE_HORIZONTAL = 6 /* Horizontal */; +var EDGE_VERTICAL = 7 /* Vertical */; +var EDGE_ALL = 8 /* All */; +var ERRATA_NONE = 0 /* None */; +var ERRATA_STRETCH_FLEX_BASIS = 1 /* StretchFlexBasis */; +var ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING = 2 /* AbsolutePositionWithoutInsetsExcludesPadding */; +var ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE = 4 /* AbsolutePercentAgainstInnerSize */; +var ERRATA_ALL = 2147483647 /* All */; +var ERRATA_CLASSIC = 2147483646 /* Classic */; +var EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS = 0 /* WebFlexBasis */; +var FLEX_DIRECTION_COLUMN = 0 /* Column */; +var FLEX_DIRECTION_COLUMN_REVERSE = 1 /* ColumnReverse */; +var FLEX_DIRECTION_ROW = 2 /* Row */; +var FLEX_DIRECTION_ROW_REVERSE = 3 /* RowReverse */; +var GUTTER_COLUMN = 0 /* Column */; +var GUTTER_ROW = 1 /* Row */; +var GUTTER_ALL = 2 /* All */; +var JUSTIFY_FLEX_START = 0 /* FlexStart */; +var JUSTIFY_CENTER = 1 /* Center */; +var JUSTIFY_FLEX_END = 2 /* FlexEnd */; +var JUSTIFY_SPACE_BETWEEN = 3 /* SpaceBetween */; +var JUSTIFY_SPACE_AROUND = 4 /* SpaceAround */; +var JUSTIFY_SPACE_EVENLY = 5 /* SpaceEvenly */; +var LOG_LEVEL_ERROR = 0 /* Error */; +var LOG_LEVEL_WARN = 1 /* Warn */; +var LOG_LEVEL_INFO = 2 /* Info */; +var LOG_LEVEL_DEBUG = 3 /* Debug */; +var LOG_LEVEL_VERBOSE = 4 /* Verbose */; +var LOG_LEVEL_FATAL = 5 /* Fatal */; +var MEASURE_MODE_UNDEFINED = 0 /* Undefined */; +var MEASURE_MODE_EXACTLY = 1 /* Exactly */; +var MEASURE_MODE_AT_MOST = 2 /* AtMost */; +var NODE_TYPE_DEFAULT = 0 /* Default */; +var NODE_TYPE_TEXT = 1 /* Text */; +var OVERFLOW_VISIBLE = 0 /* Visible */; +var OVERFLOW_HIDDEN = 1 /* Hidden */; +var OVERFLOW_SCROLL = 2 /* Scroll */; +var POSITION_TYPE_STATIC = 0 /* Static */; +var POSITION_TYPE_RELATIVE = 1 /* Relative */; +var POSITION_TYPE_ABSOLUTE = 2 /* Absolute */; +var UNIT_UNDEFINED = 0 /* Undefined */; +var UNIT_POINT = 1 /* Point */; +var UNIT_PERCENT = 2 /* Percent */; +var UNIT_AUTO = 3 /* Auto */; +var WRAP_NO_WRAP = 0 /* NoWrap */; +var WRAP_WRAP = 1 /* Wrap */; +var WRAP_WRAP_REVERSE = 2 /* WrapReverse */; +var YogaEnumKind = { + Direction: 0, + FlexDirection: 1, + JustifyContent: 2, + AlignContent: 3, + AlignItems: 4, + AlignSelf: 5, + PositionType: 6, + FlexWrap: 7, + Overflow: 8, + Display: 9, + BoxSizing: 10 +}; +var YogaFloatKind = { + Flex: 0, + FlexGrow: 1, + FlexShrink: 2, + AspectRatio: 3 +}; +var YogaValueKind = { + Width: 0, + Height: 1, + MinWidth: 2, + MinHeight: 3, + MaxWidth: 4, + MaxHeight: 5, + FlexBasis: 6, + Margin: 7, + Padding: 8, + Position: 9, + Gap: 10 +}; +var YogaEdgeLayoutKind = { + Margin: 0, + Padding: 1, + Border: 2 +}; +var UNDEFINED_VALUE = { unit: 0 /* Undefined */, value: NaN }; +var nodeRegistry = new Map; +function lib() { + return resolveRenderLib(); +} +function pointerKey(pointer) { + return String(pointer); +} +function isValueObject(value) { + return typeof value === "object" && value !== null && "unit" in value && "value" in value; +} +function parseValue(value) { + if (isValueObject(value)) { + return value; + } + if (value === undefined) { + return UNDEFINED_VALUE; + } + if (value === "auto") { + return { unit: 3 /* Auto */, value: NaN }; + } + if (typeof value === "string") { + if (!value.endsWith("%")) { + throw new Error(`Invalid Yoga value: ${value}`); + } + const numberValue = Number.parseFloat(value); + if (Number.isNaN(numberValue)) { + throw new Error(`Invalid Yoga percentage value: ${value}`); + } + return { unit: 2 /* Percent */, value: numberValue }; + } + return { unit: 1 /* Point */, value }; +} +function unpackValue(packedValue) { + const packed = typeof packedValue === "bigint" ? packedValue : BigInt(packedValue); + const unit = Number(packed & 0xffffffffn); + const valueBits = Number(packed >> 32n & 0xffffffffn); + const buffer = new ArrayBuffer(4); + const view = new DataView(buffer); + view.setUint32(0, valueBits, true); + return { unit, value: view.getFloat32(0, true) }; +} +function normalizeLayoutInput(value) { + return value === undefined || value === "auto" ? NaN : value; +} + +class Config { + ptr; + freed = false; + constructor(ptr3) { + this.ptr = ptr3; + } + static create() { + return new Config(lib().yogaConfigCreate()); + } + static destroy(config) { + config.free(); + } + free() { + if (this.freed) + return; + this.freed = true; + lib().yogaConfigFree(this.ptr); + } + setUseWebDefaults(useWebDefaults) { + if (this.freed) + return; + lib().yogaConfigSetUseWebDefaults(this.ptr, useWebDefaults); + } + useWebDefaults() { + if (this.freed) + return false; + return lib().yogaConfigGetUseWebDefaults(this.ptr); + } + setPointScaleFactor(pointScaleFactor) { + if (this.freed) + return; + lib().yogaConfigSetPointScaleFactor(this.ptr, pointScaleFactor); + } + getPointScaleFactor() { + if (this.freed) + return 0; + return lib().yogaConfigGetPointScaleFactor(this.ptr); + } + setErrata(errata) { + if (this.freed) + return; + lib().yogaConfigSetErrata(this.ptr, errata); + } + getErrata() { + if (this.freed) + return 0 /* None */; + return lib().yogaConfigGetErrata(this.ptr); + } + setExperimentalFeatureEnabled(feature, enabled) { + if (this.freed) + return; + lib().yogaConfigSetExperimentalFeatureEnabled(this.ptr, feature, enabled); + } + isExperimentalFeatureEnabled(feature) { + if (this.freed) + return false; + return lib().yogaConfigIsExperimentalFeatureEnabled(this.ptr, feature); + } +} + +class Node { + ptr; + freed = false; + measureCallback = null; + dirtiedCallback = null; + constructor(ptr3) { + this.ptr = ptr3; + nodeRegistry.set(pointerKey(ptr3), this); + } + static create(config) { + return Node.fromPointer(config ? lib().yogaNodeCreateWithConfig(config.ptr) : lib().yogaNodeCreate()); + } + static createForOpenTUI() { + return Node.fromPointer(lib().yogaNodeCreateForOpenTUI()); + } + static createDefault() { + return Node.create(); + } + static createWithConfig(config) { + return Node.create(config); + } + static destroy(node) { + node.free(); + } + static fromPointer(ptr3) { + const key = pointerKey(ptr3); + const existing = nodeRegistry.get(key); + if (existing) + return existing; + return new Node(ptr3); + } + isFreed() { + return this.freed; + } + free() { + if (this.freed) + return; + this.unsetMeasureFunc(); + this.unsetDirtiedFunc(); + lib().yogaNodeFree(this.ptr); + this.markFreed(); + } + freeRecursive() { + if (this.freed) + return; + const nodes = this.collectSubtree([]); + for (const node of nodes) { + node.closeMeasureCallback(); + node.closeDirtiedCallback(); + } + lib().yogaNodeFreeRecursive(this.ptr); + for (const node of nodes) { + node.markFreed(); + } + } + reset() { + if (this.freed) + return; + this.unsetMeasureFunc(); + this.unsetDirtiedFunc(); + lib().yogaNodeReset(this.ptr); + } + copyStyle(node) { + if (this.freed) + return; + lib().yogaNodeCopyStyle(this.ptr, node.ptr); + } + insertChild(child, index) { + if (this.freed) + return; + lib().yogaNodeInsertChild(this.ptr, child.ptr, index); + } + removeChild(child) { + if (this.freed) + return; + lib().yogaNodeRemoveChild(this.ptr, child.ptr); + } + removeAllChildren() { + if (this.freed) + return; + lib().yogaNodeRemoveAllChildren(this.ptr); + } + getChild(index) { + if (this.freed) + return null; + const child = lib().yogaNodeGetChild(this.ptr, index); + return child ? Node.fromPointer(child) : null; + } + getChildCount() { + if (this.freed) + return 0; + return lib().yogaNodeGetChildCount(this.ptr); + } + getParent() { + if (this.freed) + return null; + const parent = lib().yogaNodeGetParent(this.ptr); + return parent ? Node.fromPointer(parent) : null; + } + calculateLayout(width, height, direction = 1 /* LTR */) { + if (this.freed) + return; + lib().yogaNodeCalculateLayout(this.ptr, normalizeLayoutInput(width), normalizeLayoutInput(height), direction); + } + hasNewLayout() { + if (this.freed) + return false; + return lib().yogaNodeGetHasNewLayout(this.ptr); + } + markLayoutSeen() { + if (this.freed) + return; + lib().yogaNodeSetHasNewLayout(this.ptr, false); + } + markDirty() { + if (this.freed) + return; + lib().yogaNodeMarkDirty(this.ptr); + } + isDirty() { + if (this.freed) + return true; + return lib().yogaNodeIsDirty(this.ptr); + } + getComputedLayout() { + if (this.freed) + return { left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0 }; + return lib().yogaNodeGetComputedLayout(this.ptr); + } + getComputedLeft() { + return this.getComputedLayout().left; + } + getComputedTop() { + return this.getComputedLayout().top; + } + getComputedRight() { + return this.getComputedLayout().right; + } + getComputedBottom() { + return this.getComputedLayout().bottom; + } + getComputedWidth() { + return this.getComputedLayout().width; + } + getComputedHeight() { + return this.getComputedLayout().height; + } + getComputedMargin(edge) { + if (this.freed) + return 0; + return lib().yogaNodeLayoutGetEdge(this.ptr, YogaEdgeLayoutKind.Margin, edge); + } + getComputedPadding(edge) { + if (this.freed) + return 0; + return lib().yogaNodeLayoutGetEdge(this.ptr, YogaEdgeLayoutKind.Padding, edge); + } + getComputedBorder(edge) { + if (this.freed) + return 0; + return lib().yogaNodeLayoutGetEdge(this.ptr, YogaEdgeLayoutKind.Border, edge); + } + setDirection(direction) { + this.setEnum(YogaEnumKind.Direction, direction); + } + getDirection() { + return this.getEnum(YogaEnumKind.Direction, 0 /* Inherit */); + } + setFlexDirection(flexDirection) { + this.setEnum(YogaEnumKind.FlexDirection, flexDirection); + } + getFlexDirection() { + return this.getEnum(YogaEnumKind.FlexDirection, 0 /* Column */); + } + setJustifyContent(justifyContent) { + this.setEnum(YogaEnumKind.JustifyContent, justifyContent); + } + getJustifyContent() { + return this.getEnum(YogaEnumKind.JustifyContent, 0 /* FlexStart */); + } + setAlignContent(alignContent) { + this.setEnum(YogaEnumKind.AlignContent, alignContent); + } + getAlignContent() { + return this.getEnum(YogaEnumKind.AlignContent, 1 /* FlexStart */); + } + setAlignItems(alignItems) { + this.setEnum(YogaEnumKind.AlignItems, alignItems); + } + getAlignItems() { + return this.getEnum(YogaEnumKind.AlignItems, 4 /* Stretch */); + } + setAlignSelf(alignSelf) { + this.setEnum(YogaEnumKind.AlignSelf, alignSelf); + } + getAlignSelf() { + return this.getEnum(YogaEnumKind.AlignSelf, 0 /* Auto */); + } + setPositionType(positionType) { + this.setEnum(YogaEnumKind.PositionType, positionType); + } + getPositionType() { + return this.getEnum(YogaEnumKind.PositionType, 1 /* Relative */); + } + setFlexWrap(flexWrap) { + this.setEnum(YogaEnumKind.FlexWrap, flexWrap); + } + getFlexWrap() { + return this.getEnum(YogaEnumKind.FlexWrap, 0 /* NoWrap */); + } + setOverflow(overflow) { + this.setEnum(YogaEnumKind.Overflow, overflow); + } + getOverflow() { + return this.getEnum(YogaEnumKind.Overflow, 0 /* Visible */); + } + setDisplay(display) { + this.setEnum(YogaEnumKind.Display, display); + } + getDisplay() { + return this.getEnum(YogaEnumKind.Display, 0 /* Flex */); + } + setBoxSizing(boxSizing) { + this.setEnum(YogaEnumKind.BoxSizing, boxSizing); + } + getBoxSizing() { + return this.getEnum(YogaEnumKind.BoxSizing, 0 /* BorderBox */); + } + setFlex(flex) { + this.setFloat(YogaFloatKind.Flex, flex); + } + getFlex() { + return this.getFloat(YogaFloatKind.Flex); + } + setFlexGrow(flexGrow) { + this.setFloat(YogaFloatKind.FlexGrow, flexGrow); + } + getFlexGrow() { + return this.getFloat(YogaFloatKind.FlexGrow); + } + setFlexShrink(flexShrink) { + this.setFloat(YogaFloatKind.FlexShrink, flexShrink); + } + getFlexShrink() { + return this.getFloat(YogaFloatKind.FlexShrink); + } + setAspectRatio(aspectRatio) { + this.setFloat(YogaFloatKind.AspectRatio, aspectRatio); + } + getAspectRatio() { + return this.getFloat(YogaFloatKind.AspectRatio); + } + setFlexBasis(flexBasis) { + this.setValue(YogaValueKind.FlexBasis, 0, flexBasis); + } + setFlexBasisPercent(flexBasis) { + this.setValue(YogaValueKind.FlexBasis, 0, flexBasis === undefined ? undefined : { unit: 2 /* Percent */, value: flexBasis }); + } + setFlexBasisAuto() { + this.setValue(YogaValueKind.FlexBasis, 0, "auto"); + } + getFlexBasis() { + return this.getValue(YogaValueKind.FlexBasis, 0); + } + setWidth(width) { + this.setValue(YogaValueKind.Width, 0, width); + } + setWidthPercent(width) { + this.setValue(YogaValueKind.Width, 0, width === undefined ? undefined : { unit: 2 /* Percent */, value: width }); + } + setWidthAuto() { + this.setValue(YogaValueKind.Width, 0, "auto"); + } + getWidth() { + return this.getValue(YogaValueKind.Width, 0); + } + setHeight(height) { + this.setValue(YogaValueKind.Height, 0, height); + } + setHeightPercent(height) { + this.setValue(YogaValueKind.Height, 0, height === undefined ? undefined : { unit: 2 /* Percent */, value: height }); + } + setHeightAuto() { + this.setValue(YogaValueKind.Height, 0, "auto"); + } + getHeight() { + return this.getValue(YogaValueKind.Height, 0); + } + setMinWidth(minWidth) { + this.setValue(YogaValueKind.MinWidth, 0, minWidth); + } + setMinWidthPercent(minWidth) { + this.setValue(YogaValueKind.MinWidth, 0, minWidth === undefined ? undefined : { unit: 2 /* Percent */, value: minWidth }); + } + getMinWidth() { + return this.getValue(YogaValueKind.MinWidth, 0); + } + setMinHeight(minHeight) { + this.setValue(YogaValueKind.MinHeight, 0, minHeight); + } + setMinHeightPercent(minHeight) { + this.setValue(YogaValueKind.MinHeight, 0, minHeight === undefined ? undefined : { unit: 2 /* Percent */, value: minHeight }); + } + getMinHeight() { + return this.getValue(YogaValueKind.MinHeight, 0); + } + setMaxWidth(maxWidth) { + this.setValue(YogaValueKind.MaxWidth, 0, maxWidth); + } + setMaxWidthPercent(maxWidth) { + this.setValue(YogaValueKind.MaxWidth, 0, maxWidth === undefined ? undefined : { unit: 2 /* Percent */, value: maxWidth }); + } + getMaxWidth() { + return this.getValue(YogaValueKind.MaxWidth, 0); + } + setMaxHeight(maxHeight) { + this.setValue(YogaValueKind.MaxHeight, 0, maxHeight); + } + setMaxHeightPercent(maxHeight) { + this.setValue(YogaValueKind.MaxHeight, 0, maxHeight === undefined ? undefined : { unit: 2 /* Percent */, value: maxHeight }); + } + getMaxHeight() { + return this.getValue(YogaValueKind.MaxHeight, 0); + } + setMargin(edge, margin) { + this.setValue(YogaValueKind.Margin, edge, margin); + } + setMarginPercent(edge, margin) { + this.setValue(YogaValueKind.Margin, edge, margin === undefined ? undefined : { unit: 2 /* Percent */, value: margin }); + } + setMarginAuto(edge) { + this.setValue(YogaValueKind.Margin, edge, "auto"); + } + getMargin(edge) { + return this.getValue(YogaValueKind.Margin, edge); + } + setPadding(edge, padding) { + this.setValue(YogaValueKind.Padding, edge, padding); + } + setPaddingPercent(edge, padding) { + this.setValue(YogaValueKind.Padding, edge, padding === undefined ? undefined : { unit: 2 /* Percent */, value: padding }); + } + getPadding(edge) { + return this.getValue(YogaValueKind.Padding, edge); + } + setPosition(edge, position) { + this.setValue(YogaValueKind.Position, edge, position); + } + setPositionPercent(edge, position) { + this.setValue(YogaValueKind.Position, edge, position === undefined ? undefined : { unit: 2 /* Percent */, value: position }); + } + setPositionAuto(edge) { + this.setValue(YogaValueKind.Position, edge, "auto"); + } + getPosition(edge) { + return this.getValue(YogaValueKind.Position, edge); + } + setGap(gutter, gap) { + this.setValue(YogaValueKind.Gap, gutter, gap); + } + setGapPercent(gutter, gap) { + this.setValue(YogaValueKind.Gap, gutter, gap === undefined ? undefined : { unit: 2 /* Percent */, value: gap }); + } + getGap(gutter) { + return this.getValue(YogaValueKind.Gap, gutter); + } + setBorder(edge, border2) { + if (this.freed) + return; + lib().yogaNodeStyleSetBorder(this.ptr, edge, border2 ?? NaN); + } + getBorder(edge) { + if (this.freed) + return NaN; + return lib().yogaNodeStyleGetBorder(this.ptr, edge); + } + setIsReferenceBaseline(isReferenceBaseline) { + if (this.freed) + return; + lib().yogaNodeSetIsReferenceBaseline(this.ptr, isReferenceBaseline); + } + isReferenceBaseline() { + if (this.freed) + return false; + return lib().yogaNodeIsReferenceBaseline(this.ptr); + } + setAlwaysFormsContainingBlock(alwaysFormsContainingBlock) { + if (this.freed) + return; + lib().yogaNodeSetAlwaysFormsContainingBlock(this.ptr, alwaysFormsContainingBlock); + } + getAlwaysFormsContainingBlock() { + if (this.freed) + return false; + return lib().yogaNodeGetAlwaysFormsContainingBlock(this.ptr); + } + setMeasureFunc(measureFunc) { + if (this.freed) + return; + this.unsetMeasureFunc(); + if (!measureFunc) + return; + const callback = (_node, width, widthMode, height, heightMode) => { + const result = measureFunc(width, widthMode, height, heightMode); + lib().yogaStoreMeasureResult(result.width ?? NaN, result.height ?? NaN); + }; + this.measureCallback = lib().createYogaMeasureCallback(callback); + if (!this.measureCallback.ptr) { + this.measureCallback.close(); + this.measureCallback = null; + throw new Error("Failed to create Yoga measure callback"); + } + lib().yogaNodeSetMeasureFunc(this.ptr, this.measureCallback.ptr); + } + unsetMeasureFunc() { + if (this.freed) + return; + lib().yogaNodeUnsetMeasureFunc(this.ptr); + this.closeMeasureCallback(); + } + hasMeasureFunc() { + if (this.freed) + return false; + return lib().yogaNodeHasMeasureFunc(this.ptr); + } + setDirtiedFunc(dirtiedFunc) { + if (this.freed) + return; + this.unsetDirtiedFunc(); + if (!dirtiedFunc) + return; + const callback = () => { + dirtiedFunc(this); + }; + this.dirtiedCallback = lib().createYogaDirtiedCallback(callback); + if (!this.dirtiedCallback.ptr) { + this.dirtiedCallback.close(); + this.dirtiedCallback = null; + throw new Error("Failed to create Yoga dirtied callback"); + } + lib().yogaNodeSetDirtiedFunc(this.ptr, this.dirtiedCallback.ptr); + } + unsetDirtiedFunc() { + if (this.freed) + return; + lib().yogaNodeUnsetDirtiedFunc(this.ptr); + this.closeDirtiedCallback(); + } + setEnum(kind, value) { + if (this.freed) + return; + lib().yogaNodeStyleSetEnum(this.ptr, kind, value); + } + getEnum(kind, fallback) { + if (this.freed) + return fallback; + return lib().yogaNodeStyleGetEnum(this.ptr, kind); + } + setFloat(kind, value) { + if (this.freed) + return; + lib().yogaNodeStyleSetFloat(this.ptr, kind, value ?? NaN); + } + getFloat(kind) { + if (this.freed) + return NaN; + return lib().yogaNodeStyleGetFloat(this.ptr, kind); + } + setValue(kind, edgeOrGutter, valueInput) { + if (this.freed) + return; + const value = parseValue(valueInput); + lib().yogaNodeStyleSetValue(this.ptr, kind, edgeOrGutter, value.unit, value.value); + } + getValue(kind, edgeOrGutter) { + if (this.freed) + return UNDEFINED_VALUE; + return unpackValue(lib().yogaNodeStyleGetValue(this.ptr, kind, edgeOrGutter)); + } + collectSubtree(nodes) { + for (let index = 0;index < this.getChildCount(); index++) { + this.getChild(index)?.collectSubtree(nodes); + } + nodes.push(this); + return nodes; + } + closeMeasureCallback() { + if (!this.measureCallback) + return; + this.measureCallback.close(); + this.measureCallback = null; + } + closeDirtiedCallback() { + if (!this.dirtiedCallback) + return; + this.dirtiedCallback.close(); + this.dirtiedCallback = null; + } + markFreed() { + this.freed = true; + nodeRegistry.delete(pointerKey(this.ptr)); + } +} +var Yoga = { + Config, + Node, + Align, + BoxSizing, + Dimension, + Direction, + Display, + Edge, + Errata, + ExperimentalFeature, + FlexDirection, + Gutter, + Justify, + LogLevel, + MeasureMode, + NodeType, + Overflow, + PositionType, + Unit, + Wrap, + ALIGN_AUTO, + ALIGN_FLEX_START, + ALIGN_CENTER, + ALIGN_FLEX_END, + ALIGN_STRETCH, + ALIGN_BASELINE, + ALIGN_SPACE_BETWEEN, + ALIGN_SPACE_AROUND, + ALIGN_SPACE_EVENLY, + BOX_SIZING_BORDER_BOX, + BOX_SIZING_CONTENT_BOX, + DIMENSION_WIDTH, + DIMENSION_HEIGHT, + DIRECTION_INHERIT, + DIRECTION_LTR, + DIRECTION_RTL, + DISPLAY_FLEX, + DISPLAY_NONE, + DISPLAY_CONTENTS, + EDGE_LEFT, + EDGE_TOP, + EDGE_RIGHT, + EDGE_BOTTOM, + EDGE_START, + EDGE_END, + EDGE_HORIZONTAL, + EDGE_VERTICAL, + EDGE_ALL, + ERRATA_NONE, + ERRATA_STRETCH_FLEX_BASIS, + ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, + ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, + ERRATA_ALL, + ERRATA_CLASSIC, + EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, + FLEX_DIRECTION_COLUMN, + FLEX_DIRECTION_COLUMN_REVERSE, + FLEX_DIRECTION_ROW, + FLEX_DIRECTION_ROW_REVERSE, + GUTTER_COLUMN, + GUTTER_ROW, + GUTTER_ALL, + JUSTIFY_FLEX_START, + JUSTIFY_CENTER, + JUSTIFY_FLEX_END, + JUSTIFY_SPACE_BETWEEN, + JUSTIFY_SPACE_AROUND, + JUSTIFY_SPACE_EVENLY, + LOG_LEVEL_ERROR, + LOG_LEVEL_WARN, + LOG_LEVEL_INFO, + LOG_LEVEL_DEBUG, + LOG_LEVEL_VERBOSE, + LOG_LEVEL_FATAL, + MEASURE_MODE_UNDEFINED, + MEASURE_MODE_EXACTLY, + MEASURE_MODE_AT_MOST, + NODE_TYPE_DEFAULT, + NODE_TYPE_TEXT, + OVERFLOW_VISIBLE, + OVERFLOW_HIDDEN, + OVERFLOW_SCROLL, + POSITION_TYPE_STATIC, + POSITION_TYPE_RELATIVE, + POSITION_TYPE_ABSOLUTE, + UNIT_UNDEFINED, + UNIT_POINT, + UNIT_PERCENT, + UNIT_AUTO, + WRAP_NO_WRAP, + WRAP_WRAP, + WRAP_WRAP_REVERSE +}; +var yoga_default = Yoga; + +export { toArrayBuffer, sleep, stringWidth2 as stringWidth, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, RGBA, normalizeColorValue, hexToRgb, rgbToHex, hsvToRgb, parseColor, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, terminalNamedSingleStrokeKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, singleton, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, getTreeSitterClient, destroyTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, normalizeTerminalPalette, buildTerminalPaletteSignature, decodePasteBytes, stripAnsiSequences, detectLinks, OptimizedBuffer, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, Align, BoxSizing, Dimension, Direction, Display, Edge, Errata, ExperimentalFeature, FlexDirection, Gutter, Justify, LogLevel as LogLevel1, MeasureMode, NodeType, Overflow, PositionType, Unit, Wrap, ALIGN_AUTO, ALIGN_FLEX_START, ALIGN_CENTER, ALIGN_FLEX_END, ALIGN_STRETCH, ALIGN_BASELINE, ALIGN_SPACE_BETWEEN, ALIGN_SPACE_AROUND, ALIGN_SPACE_EVENLY, BOX_SIZING_BORDER_BOX, BOX_SIZING_CONTENT_BOX, DIMENSION_WIDTH, DIMENSION_HEIGHT, DIRECTION_INHERIT, DIRECTION_LTR, DIRECTION_RTL, DISPLAY_FLEX, DISPLAY_NONE, DISPLAY_CONTENTS, EDGE_LEFT, EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_START, EDGE_END, EDGE_HORIZONTAL, EDGE_VERTICAL, EDGE_ALL, ERRATA_NONE, ERRATA_STRETCH_FLEX_BASIS, ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, ERRATA_ALL, ERRATA_CLASSIC, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, FLEX_DIRECTION_COLUMN, FLEX_DIRECTION_COLUMN_REVERSE, FLEX_DIRECTION_ROW, FLEX_DIRECTION_ROW_REVERSE, GUTTER_COLUMN, GUTTER_ROW, GUTTER_ALL, JUSTIFY_FLEX_START, JUSTIFY_CENTER, JUSTIFY_FLEX_END, JUSTIFY_SPACE_BETWEEN, JUSTIFY_SPACE_AROUND, JUSTIFY_SPACE_EVENLY, LOG_LEVEL_ERROR, LOG_LEVEL_WARN, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, LOG_LEVEL_FATAL, MEASURE_MODE_UNDEFINED, MEASURE_MODE_EXACTLY, MEASURE_MODE_AT_MOST, NODE_TYPE_DEFAULT, NODE_TYPE_TEXT, OVERFLOW_VISIBLE, OVERFLOW_HIDDEN, OVERFLOW_SCROLL, POSITION_TYPE_STATIC, POSITION_TYPE_RELATIVE, POSITION_TYPE_ABSOLUTE, UNIT_UNDEFINED, UNIT_POINT, UNIT_PERCENT, UNIT_AUTO, WRAP_NO_WRAP, WRAP_WRAP, WRAP_WRAP_REVERSE, Config, Node, exports_yoga, yoga_default }; + +//# debugId=DCFFDFC39A69C1FE64756E2164756E21 +//# sourceMappingURL=index-pcvh9d34.js.map diff --git a/.patches/@opentui/core/index-pcvh9d34.js.map b/.patches/@opentui/core/index-pcvh9d34.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/index-pcvh9d34.js.map @@ -0,0 +1,57 @@ +{ + "version": 3, + "sources": ["../../../node_modules/.bun/emoji-regex@10.6.0/node_modules/emoji-regex/index.js", "../src/platform/ffi.ts", "../src/platform/runtime.ts", "../../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js", "../../../node_modules/.bun/strip-ansi@7.1.2/node_modules/strip-ansi/index.js", "../../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js", "../../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js", "../../../node_modules/.bun/string-width@7.2.0/node_modules/string-width/index.js", "../src/zig.ts", "../src/lib/RGBA.ts", "../src/lib/border.ts", "../src/lib/KeyHandler.ts", "../src/lib/ascii.font.ts", "../src/types.ts", "../src/utils.ts", "../src/lib/styled-text.ts", "../src/lib/hast-styled-text.ts", "../src/lib/clock.ts", "../src/lib/parse.keypress.ts", "../src/lib/parse.keypress-kitty.ts", "../src/lib/scroll-acceleration.ts", "../src/lib/yoga.options.ts", "../src/lib/parse.mouse.ts", "../src/lib/selection.ts", "../src/lib/singleton.ts", "../src/lib/env.ts", "../src/lib/stdin-parser.ts", "../src/lib/tree-sitter-styled-text.ts", "../src/lib/tree-sitter/client.ts", "../src/lib/debounce.ts", "../src/lib/queue.ts", "../src/lib/tree-sitter/default-parsers.ts", "../src/lib/bunfs.ts", "../src/platform/worker.ts", "../src/lib/data-paths.ts", "../src/lib/validate-dir-name.ts", "../src/lib/tree-sitter/resolve-ft.ts", "../src/lib/tree-sitter/index.ts", "../src/lib/extmarks-history.ts", "../src/lib/extmarks.ts", "../src/lib/terminal-palette.ts", "../src/lib/paste.ts", "../src/lib/detect-links.ts", "../src/buffer.ts", "../src/text-buffer.ts", "../../../node_modules/.bun/bun-ffi-structs@0.2.3+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js", "../src/zig-structs.ts", "../src/yoga.ts"], + "sourcesContent": [ + "module.exports = () => {\n\t// https://mths.be/emoji\n\treturn /[#*0-9]\\uFE0F?\\u20E3|[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23ED-\\u23EF\\u23F1\\u23F2\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB\\u25FC\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692\\u2694-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A7\\u26AA\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C8\\u26CF\\u26D1\\u26E9\\u26F0-\\u26F5\\u26F7\\u26F8\\u26FA\\u2702\\u2708\\u2709\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u27A1\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B55\\u3030\\u303D\\u3297\\u3299]\\uFE0F?|[\\u261D\\u270C\\u270D](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\u270A\\u270B](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u2693\\u26A1\\u26AB\\u26C5\\u26CE\\u26D4\\u26EA\\u26FD\\u2705\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2795-\\u2797\\u27B0\\u27BF\\u2B50]|\\u26D3\\uFE0F?(?:\\u200D\\uD83D\\uDCA5)?|\\u26F9(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|\\u2764\\uFE0F?(?:\\u200D(?:\\uD83D\\uDD25|\\uD83E\\uDE79))?|\\uD83C(?:[\\uDC04\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDE02\\uDE37\\uDF21\\uDF24-\\uDF2C\\uDF36\\uDF7D\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E\\uDF9F\\uDFCD\\uDFCE\\uDFD4-\\uDFDF\\uDFF5\\uDFF7]\\uFE0F?|[\\uDF85\\uDFC2\\uDFC7](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDFC4\\uDFCA](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDFCB\\uDFCC](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDE01\\uDE1A\\uDE2F\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF43\\uDF45-\\uDF4A\\uDF4C-\\uDF7C\\uDF7E-\\uDF84\\uDF86-\\uDF93\\uDFA0-\\uDFC1\\uDFC5\\uDFC6\\uDFC8\\uDFC9\\uDFCF-\\uDFD3\\uDFE0-\\uDFF0\\uDFF8-\\uDFFF]|\\uDDE6\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF]|\\uDDE7\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF]|\\uDDE8\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF7\\uDDFA-\\uDDFF]|\\uDDE9\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF]|\\uDDEA\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA]|\\uDDEB\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7]|\\uDDEC\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE]|\\uDDED\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA]|\\uDDEE\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9]|\\uDDEF\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5]|\\uDDF0\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF]|\\uDDF1\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE]|\\uDDF2\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF]|\\uDDF3\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF]|\\uDDF4\\uD83C\\uDDF2|\\uDDF5\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE]|\\uDDF6\\uD83C\\uDDE6|\\uDDF7\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC]|\\uDDF8\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF]|\\uDDF9\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF]|\\uDDFA\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF]|\\uDDFB\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uDDF3\\uDDFA]|\\uDDFC\\uD83C[\\uDDEB\\uDDF8]|\\uDDFD\\uD83C\\uDDF0|\\uDDFE\\uD83C[\\uDDEA\\uDDF9]|\\uDDFF\\uD83C[\\uDDE6\\uDDF2\\uDDFC]|\\uDF44(?:\\u200D\\uD83D\\uDFEB)?|\\uDF4B(?:\\u200D\\uD83D\\uDFE9)?|\\uDFC3(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDFF3\\uFE0F?(?:\\u200D(?:\\u26A7\\uFE0F?|\\uD83C\\uDF08))?|\\uDFF4(?:\\u200D\\u2620\\uFE0F?|\\uDB40\\uDC67\\uDB40\\uDC62\\uDB40(?:\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67|\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73)\\uDB40\\uDC7F)?)|\\uD83D(?:[\\uDC3F\\uDCFD\\uDD49\\uDD4A\\uDD6F\\uDD70\\uDD73\\uDD76-\\uDD79\\uDD87\\uDD8A-\\uDD8D\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA\\uDECB\\uDECD-\\uDECF\\uDEE0-\\uDEE5\\uDEE9\\uDEF0\\uDEF3]\\uFE0F?|[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC6B-\\uDC6D\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDC8F\\uDC91\\uDCAA\\uDD7A\\uDD95\\uDD96\\uDE4C\\uDE4F\\uDEC0\\uDECC](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDC6E-\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4\\uDEB5](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD74\\uDD90](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\uDC00-\\uDC07\\uDC09-\\uDC14\\uDC16-\\uDC25\\uDC27-\\uDC3A\\uDC3C-\\uDC3E\\uDC40\\uDC44\\uDC45\\uDC51-\\uDC65\\uDC6A\\uDC79-\\uDC7B\\uDC7D-\\uDC80\\uDC84\\uDC88-\\uDC8E\\uDC90\\uDC92-\\uDCA9\\uDCAB-\\uDCFC\\uDCFF-\\uDD3D\\uDD4B-\\uDD4E\\uDD50-\\uDD67\\uDDA4\\uDDFB-\\uDE2D\\uDE2F-\\uDE34\\uDE37-\\uDE41\\uDE43\\uDE44\\uDE48-\\uDE4A\\uDE80-\\uDEA2\\uDEA4-\\uDEB3\\uDEB7-\\uDEBF\\uDEC1-\\uDEC5\\uDED0-\\uDED2\\uDED5-\\uDED8\\uDEDC-\\uDEDF\\uDEEB\\uDEEC\\uDEF4-\\uDEFC\\uDFE0-\\uDFEB\\uDFF0]|\\uDC08(?:\\u200D\\u2B1B)?|\\uDC15(?:\\u200D\\uD83E\\uDDBA)?|\\uDC26(?:\\u200D(?:\\u2B1B|\\uD83D\\uDD25))?|\\uDC3B(?:\\u200D\\u2744\\uFE0F?)?|\\uDC41\\uFE0F?(?:\\u200D\\uD83D\\uDDE8\\uFE0F?)?|\\uDC68(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDC68\\uDC69]\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?)|[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?)|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?))?|\\uDC69(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?[\\uDC68\\uDC69]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?|\\uDC69\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?))|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFC-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFE]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDD75(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|\\uDE2E(?:\\u200D\\uD83D\\uDCA8)?|\\uDE35(?:\\u200D\\uD83D\\uDCAB)?|\\uDE36(?:\\u200D\\uD83C\\uDF2B\\uFE0F?)?|\\uDE42(?:\\u200D[\\u2194\\u2195]\\uFE0F?)?|\\uDEB6(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?)|\\uD83E(?:[\\uDD0C\\uDD0F\\uDD18-\\uDD1F\\uDD30-\\uDD34\\uDD36\\uDD77\\uDDB5\\uDDB6\\uDDBB\\uDDD2\\uDDD3\\uDDD5\\uDEC3-\\uDEC5\\uDEF0\\uDEF2-\\uDEF8](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDB8\\uDDB9\\uDDCD\\uDDCF\\uDDD4\\uDDD6-\\uDDDD](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDDDE\\uDDDF](?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD0D\\uDD0E\\uDD10-\\uDD17\\uDD20-\\uDD25\\uDD27-\\uDD2F\\uDD3A\\uDD3F-\\uDD45\\uDD47-\\uDD76\\uDD78-\\uDDB4\\uDDB7\\uDDBA\\uDDBC-\\uDDCC\\uDDD0\\uDDE0-\\uDDFF\\uDE70-\\uDE7C\\uDE80-\\uDE8A\\uDE8E-\\uDEC2\\uDEC6\\uDEC8\\uDECD-\\uDEDC\\uDEDF-\\uDEEA\\uDEEF]|\\uDDCE(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDDD1(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1|\\uDDD1\\u200D\\uD83E\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?|\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDEF1(?:\\uD83C(?:\\uDFFB(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFC-\\uDFFF])?|\\uDFFC(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])?|\\uDFFD(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])?|\\uDFFE(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])?|\\uDFFF(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFE])?))?)/g;\n};\n", + "import { createRequire } from \"node:module\"\nimport { fileURLToPath } from \"node:url\"\n\ndeclare const pointerBrand: unique symbol\n\n// This module owns OpenTUI's native FFI surface. Portable code imports this\n// file instead of bun:ffi, so backends can keep the same call sites.\n\n// External FFI producers may expose their own branded pointer types. Public APIs\n// that consume foreign pointers should accept the raw pointer shape and normalize\n// it before crossing OpenTUI's native boundary.\nexport type PointerInput = number | bigint\n\n// Runtime pointers are numbers in Bun and bigints in Node's experimental FFI.\n// Keep both in our own type, and narrow only inside a backend that requires it.\nexport type Pointer = PointerInput & { readonly [pointerBrand]: \"Pointer\" }\n\ntype PointerSource = ArrayBufferLike | ArrayBufferView\n\n// Bun accepts numeric pointers only. Keep this type private so Bun's pointer\n// model does not leak into the exported surface.\ntype BunPointer = number\n\n// These names match the Bun FFI type strings OpenTUI uses today. Other\n// backends map them at library load time instead of wrapping every native call.\nexport const FFIType = {\n char: \"char\",\n int8_t: \"int8_t\",\n i8: \"i8\",\n uint8_t: \"uint8_t\",\n u8: \"u8\",\n int16_t: \"int16_t\",\n i16: \"i16\",\n uint16_t: \"uint16_t\",\n u16: \"u16\",\n int32_t: \"int32_t\",\n i32: \"i32\",\n int: \"int\",\n uint32_t: \"uint32_t\",\n u32: \"u32\",\n int64_t: \"int64_t\",\n i64: \"i64\",\n uint64_t: \"uint64_t\",\n u64: \"u64\",\n double: \"double\",\n f64: \"f64\",\n float: \"float\",\n f32: \"f32\",\n bool: \"bool\",\n ptr: \"ptr\",\n pointer: \"pointer\",\n void: \"void\",\n cstring: \"cstring\",\n function: \"function\",\n usize: \"usize\",\n callback: \"callback\",\n napi_env: \"napi_env\",\n napi_value: \"napi_value\",\n buffer: \"buffer\",\n} as const\n\nexport type FFIType = (typeof FFIType)[keyof typeof FFIType]\n// Kept as a source-shape compatibility alias for Bun-style call sites.\nexport type FFITypeOrString = FFIType\n\n// A function definition describes one native symbol. `ptr` overrides the symbol\n// address and follows the same pointer safety rules as normal pointer values.\nexport interface FFIFunction {\n readonly args?: readonly FFITypeOrString[]\n readonly returns?: FFITypeOrString\n readonly ptr?: Pointer\n readonly threadsafe?: boolean\n}\n\n// A callback instance owns a native trampoline. `close()` invalidates `ptr`;\n// callers must not pass that pointer to native code after close.\nexport interface FFICallbackInstance {\n readonly ptr: Pointer | null\n readonly threadsafe: boolean\n close(): void\n}\n\n// A loaded library owns callbacks created through `createCallback()`.\n//\n// Typical use:\n// const callback = library.createCallback(handler, { args: [\"ptr\"], returns: \"void\" })\n// library.symbols.setLogCallback(callback.ptr)\n//\n// `close()` first closes the native library, then closes any callbacks that\n// remain open.\nexport interface Library> {\n symbols: { [K in keyof Fns]: (...args: any[]) => any }\n createCallback(callback: (...args: any[]) => any, definition: FFIFunction): FFICallbackInstance\n close(): void\n}\n\n// A backend normalizes runtime differences once. Do not wrap hot symbol calls\n// here unless a backend must adapt them.\ninterface FfiBackend {\n dlopen>(path: string | URL, symbols: Fns): Library\n ptr(value: PointerSource): Pointer\n suffix: string\n toArrayBuffer(pointer: Pointer, offset: number | undefined, length: number): ArrayBuffer\n}\n\ninterface BunFFIFunction {\n readonly args?: readonly FFITypeOrString[]\n readonly returns?: FFITypeOrString\n readonly ptr?: BunPointer\n readonly threadsafe?: boolean\n}\n\ninterface BunFfiLibrary> {\n symbols: { [K in keyof Fns]: (...args: any[]) => any }\n close(): void\n}\n\ninterface BunFfiBackend {\n JSCallback: new (callback: (...args: any[]) => any, definition: BunFFIFunction) => FFICallbackInstance\n dlopen>(path: string | URL, symbols: Fns): BunFfiLibrary\n ptr(value: PointerSource): Pointer\n suffix: string\n toArrayBuffer(pointer: BunPointer, offset: number | undefined, length: number): ArrayBuffer\n}\n\ninterface NodeFFIFunction {\n readonly arguments: readonly string[]\n readonly return: string\n}\n\ninterface NodeDynamicLibrary {\n close(): void\n registerCallback(signature: NodeFFIFunction, callback: (...args: any[]) => any): bigint\n unregisterCallback(pointer: bigint): void\n}\n\ninterface NodeFfiLibrary {\n readonly lib: NodeDynamicLibrary\n readonly functions: Record any>\n}\n\ninterface NodeFfiBackend {\n dlopen(path: string | null, symbols: Record): NodeFfiLibrary\n getRawPointer(source: ArrayBuffer): bigint\n suffix: string\n toArrayBuffer(pointer: bigint, length: number, copy?: boolean): ArrayBuffer\n}\n\nexport const FFI_UNAVAILABLE = \"OpenTUI native FFI is not available for this runtime yet\"\nexport const BUN_DLOPEN_NULL = \"Bun FFI backend does not support dlopen(null)\"\nexport const LIBRARY_CLOSED = \"Cannot create FFI callback after library.close() has been called\"\nexport const NODE_CALLBACK_THREADSAFE =\n \"Node FFI callbacks are same-thread only and do not support threadsafe callbacks\"\nexport const NODE_NAPI_UNSUPPORTED = \"Node FFI backend does not support Bun N-API FFI types\"\nexport const NODE_POINTER_OVERRIDE = \"Node FFI backend does not support FFIFunction.ptr overrides\"\nexport const NODE_POINTER_ARGUMENT = \"Node FFI pointer arguments must be a Pointer, ArrayBuffer, or ArrayBufferView\"\nexport const NODE_PTR_VALUE =\n \"node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values backed by ArrayBuffer\"\nexport const NODE_STRING_RETURN = \"Node FFI backend does not normalize string return values (yet)\"\nexport const NODE_USIZE_UNSUPPORTED = \"Node FFI backend does not support usize yet\"\nexport const POINTER_NEGATIVE = \"Pointer must be non-negative\"\nexport const POINTER_OFFSET_NEGATIVE = \"Pointer offset must be non-negative\"\nexport const POINTER_OFFSET_UNSAFE = \"Pointer offset must be a safe integer\"\nexport const POINTER_UNSAFE = \"Pointer exceeds safe integer range\"\n\nfunction unavailable(cause?: unknown): never {\n throw new Error(FFI_UNAVAILABLE, { cause })\n}\n\n// The placeholder backend lets non-Bun runtimes load without errors.\nfunction createUnsupportedBackend(cause?: unknown): FfiBackend {\n return {\n dlopen() {\n return unavailable(cause)\n },\n ptr() {\n return unavailable(cause)\n },\n suffix: \"\",\n toArrayBuffer() {\n return unavailable(cause)\n },\n }\n}\n\nconst isBun =\n typeof process !== \"undefined\" &&\n typeof process.versions === \"object\" &&\n process.versions !== null &&\n typeof process.versions.bun === \"string\"\n\nconst requireModule = createRequire(import.meta.url)\nconst backend = loadBackend()\n\nfunction loadBackend(): FfiBackend {\n // Keep the Bun module import behind the runtime check so Node does not\n // resolve bun:ffi during import.\n if (isBun) {\n return createBunBackend(requireModule(\"bun:ffi\") as BunFfiBackend)\n }\n\n try {\n const nodeFfi = requireModule(\"node:ffi\") as NodeFfiBackend & { default?: NodeFfiBackend }\n return createNodeBackend(nodeFfi.default ?? nodeFfi)\n } catch (error) {\n return createUnsupportedBackend(error)\n }\n}\n\n// Normalize foreign pointer-like values into the current runtime's pointer\n// representation before passing them to native code.\nexport function toPointer(value: PointerInput): Pointer {\n if (isBun && typeof value === \"bigint\") {\n return toSafeNumberPointer(value) as Pointer\n }\n\n if (!isBun && typeof value === \"number\") {\n return toSafeBigIntPointer(value) as Pointer\n }\n\n return value as Pointer\n}\n\nexport function ffiBool(value: boolean): 0 | 1 {\n return value ? 1 : 0\n}\n\n// Convert a bigint pointer to a number only when JavaScript can represent it\n// exactly. A rounded pointer would target the wrong address.\nfunction toSafeNumberPointer(pointer: bigint): number {\n if (pointer < 0n) {\n throw new Error(POINTER_NEGATIVE)\n }\n\n if (pointer > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(POINTER_UNSAFE)\n }\n\n return Number(pointer)\n}\n\nfunction toSafeBigIntPointer(pointer: number): bigint {\n if (pointer < 0) {\n throw new Error(POINTER_NEGATIVE)\n }\n\n if (!Number.isSafeInteger(pointer)) {\n throw new Error(POINTER_UNSAFE)\n }\n\n return BigInt(pointer)\n}\n\n// Wrap a backend callback so the loaded library can close it later. The wrapper\n// keeps `ptr` live until close, then clears it so callers cannot reuse a stale\n// trampoline pointer.\nfunction createManagedCallback(raw: FFICallbackInstance, callbacks: Set): FFICallbackInstance {\n let ptr = raw.ptr\n let closed = false\n\n const instance: FFICallbackInstance = {\n get ptr() {\n return ptr\n },\n get threadsafe() {\n return raw.threadsafe\n },\n close() {\n if (closed) {\n return\n }\n\n closed = true\n callbacks.delete(instance)\n try {\n raw.close()\n } finally {\n // Clear the pointer even if the backend close throws. The trampoline is\n // no longer safe to use.\n ptr = null\n }\n },\n }\n\n callbacks.add(instance)\n\n return instance\n}\n\nfunction normalizeBunDefinitions>(\n definitions: Fns,\n): { [K in keyof Fns]: BunFFIFunction } {\n // Normalize all Bun definitions before `dlopen()`. Bun rejects bigint pointer\n // overrides, so convert them once before loading the native library.\n return Object.fromEntries(\n Object.entries(definitions).map(([name, definition]) => [name, normalizeBunDefinition(definition)]),\n ) as { [K in keyof Fns]: BunFFIFunction }\n}\n\nfunction normalizeBunDefinition(definition: FFIFunction): BunFFIFunction {\n return {\n args: definition.args,\n returns: definition.returns,\n ptr: definition.ptr == null ? undefined : toBunPointer(definition.ptr),\n threadsafe: definition.threadsafe,\n }\n}\n\n// Convert Pointer pointers to Bun pointers at the Bun boundary only.\nfunction toBunPointer(pointer: Pointer): BunPointer {\n return typeof pointer === \"bigint\" ? toSafeNumberPointer(pointer) : pointer\n}\n\n// Create a Bun backend from bun:ffi.\nexport function createBunBackend(bun: BunFfiBackend): FfiBackend {\n return {\n dlopen(path, symbols) {\n if (path === null) {\n throw new Error(BUN_DLOPEN_NULL)\n }\n\n const library = bun.dlopen(path, normalizeBunDefinitions(symbols))\n const callbacks = new Set()\n let closed = false\n\n return {\n symbols: library.symbols,\n createCallback(callback, definition) {\n if (closed) {\n // A closed library no longer owns native state. New callbacks would\n // have no cleanup path.\n throw new Error(LIBRARY_CLOSED)\n }\n\n // Bun callbacks are standalone objects. OpenTUI treats them as\n // library-owned to match the future Node FFI shape and to avoid\n // leaked trampolines.\n const raw = new bun.JSCallback(callback, normalizeBunDefinition(definition))\n\n return createManagedCallback(raw, callbacks)\n },\n close() {\n if (closed) {\n return\n }\n\n closed = true\n\n try {\n // Close native state while callbacks still point to live\n // trampolines. Native teardown may call back during final cleanup.\n library.close()\n } finally {\n // After native teardown, close any JS trampolines the caller did\n // not close explicitly.\n for (const callback of [...callbacks]) {\n callback.close()\n }\n }\n },\n }\n },\n ptr: bun.ptr,\n suffix: bun.suffix,\n toArrayBuffer(pointer, offset, length) {\n // Bun only accepts numeric pointers here. Keep the coercion at this\n // backend boundary.\n return bun.toArrayBuffer(toBunPointer(pointer), offset, length)\n },\n }\n}\n\n// Create a Node backend from node:ffi.\nexport function createNodeBackend(nodeFfi: NodeFfiBackend): FfiBackend {\n return {\n dlopen(path, symbols) {\n const { lib, functions } = nodeFfi.dlopen(toNodeLibraryPath(path), normalizeNodeDefinitions(symbols))\n const callbacks = new Set()\n let closed = false\n let libraryClosed = false\n\n return {\n symbols: wrapNodeSymbols(functions, symbols, nodeFfi),\n createCallback(callback, definition) {\n if (closed) {\n throw new Error(LIBRARY_CLOSED)\n }\n\n if (definition.threadsafe) {\n throw new Error(NODE_CALLBACK_THREADSAFE)\n }\n\n const callbackPointer = lib.registerCallback(normalizeNodeDefinition(definition), callback)\n const raw: FFICallbackInstance = {\n ptr: callbackPointer as Pointer,\n threadsafe: false,\n close() {\n if (!libraryClosed) {\n lib.unregisterCallback(callbackPointer)\n }\n },\n }\n\n return createManagedCallback(raw, callbacks)\n },\n close() {\n if (closed) {\n return\n }\n\n closed = true\n\n try {\n libraryClosed = true\n lib.close()\n } finally {\n for (const callback of [...callbacks]) {\n callback.close()\n }\n }\n },\n }\n },\n ptr(value) {\n return toNodeSourcePointer(nodeFfi, value) as Pointer\n },\n suffix: nodeFfi.suffix,\n toArrayBuffer(pointer, offset, length) {\n return nodeFfi.toArrayBuffer(toBigIntPointer(pointer) + toNodePointerOffset(offset), length, false)\n },\n }\n}\n\nfunction toNodeLibraryPath(path: string | URL | null): string | null {\n return path instanceof URL ? fileURLToPath(path) : path\n}\n\nfunction normalizeNodeDefinitions>(\n definitions: Fns,\n): Record {\n return Object.fromEntries(\n Object.entries(definitions).map(([name, definition]) => [name, normalizeNodeDefinition(definition)]),\n )\n}\n\nfunction wrapNodeSymbols>(\n functions: Record any>,\n definitions: Fns,\n nodeFfi: NodeFfiBackend,\n): { [K in keyof Fns]: (...args: any[]) => any } {\n return Object.fromEntries(\n Object.entries(functions).map(([name, fn]) => [name, wrapNodeSymbol(fn, definitions[name], nodeFfi)]),\n ) as { [K in keyof Fns]: (...args: any[]) => any }\n}\n\nfunction wrapNodeSymbol(\n fn: (...args: any[]) => any,\n definition: FFIFunction,\n nodeFfi: NodeFfiBackend,\n): (...args: any[]) => any {\n const pointerArgIndexes = (definition.args ?? []).flatMap((type, index) =>\n isNodePointerArgumentType(type) ? [index] : [],\n )\n\n if (pointerArgIndexes.length === 0) {\n return fn\n }\n\n return (...args: any[]) => {\n const normalizedArgs = args.slice()\n\n for (const index of pointerArgIndexes) {\n normalizedArgs[index] = toNodePointerArgument(nodeFfi, normalizedArgs[index])\n }\n\n return fn(...normalizedArgs)\n }\n}\n\nfunction isNodePointerArgumentType(type: FFITypeOrString): boolean {\n return type === FFIType.ptr || type === FFIType.pointer || type === FFIType.function || type === FFIType.callback\n}\n\nfunction toNodePointerArgument(nodeFfi: NodeFfiBackend, value: unknown): bigint {\n if (value == null) {\n return 0n\n }\n\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n return toBigIntPointer(value as Pointer)\n }\n\n if (ArrayBuffer.isView(value)) {\n if (value.byteLength === 0) {\n return 0n\n }\n\n return toNodeSourcePointer(nodeFfi, value)\n }\n\n if (value instanceof ArrayBuffer) {\n if (value.byteLength === 0) {\n return 0n\n }\n\n return toNodeSourcePointer(nodeFfi, value)\n }\n\n throw new TypeError(NODE_POINTER_ARGUMENT)\n}\n\nfunction toNodeSourcePointer(nodeFfi: NodeFfiBackend, value: PointerSource): bigint {\n if (ArrayBuffer.isView(value)) {\n if (!(value.buffer instanceof ArrayBuffer)) {\n throw new TypeError(NODE_PTR_VALUE)\n }\n\n return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset)\n }\n\n if (value instanceof ArrayBuffer) {\n return nodeFfi.getRawPointer(value)\n }\n\n throw new TypeError(NODE_PTR_VALUE)\n}\n\nfunction toNodePointerOffset(offset: number | undefined): bigint {\n if (offset == null) {\n return 0n\n }\n\n if (offset < 0) {\n throw new Error(POINTER_OFFSET_NEGATIVE)\n }\n\n if (!Number.isSafeInteger(offset)) {\n throw new Error(POINTER_OFFSET_UNSAFE)\n }\n\n return BigInt(offset)\n}\n\nfunction normalizeNodeDefinition(definition: FFIFunction): NodeFFIFunction {\n if (definition.ptr != null) {\n throw new Error(NODE_POINTER_OVERRIDE)\n }\n\n return {\n arguments: (definition.args ?? []).map((type) => toNodeFFIType(type, \"parameter\")),\n return: toNodeFFIType(definition.returns ?? FFIType.void, \"result\"),\n }\n}\n\nfunction toNodeFFIType(type: FFITypeOrString, position: \"parameter\" | \"result\"): string {\n switch (type) {\n case FFIType.char:\n return \"char\"\n case FFIType.int8_t:\n case FFIType.i8:\n return \"i8\"\n case FFIType.uint8_t:\n case FFIType.u8:\n return \"u8\"\n case FFIType.int16_t:\n case FFIType.i16:\n return \"i16\"\n case FFIType.uint16_t:\n case FFIType.u16:\n return \"u16\"\n case FFIType.int32_t:\n case FFIType.int:\n case FFIType.i32:\n return \"i32\"\n case FFIType.uint32_t:\n case FFIType.u32:\n return \"u32\"\n case FFIType.int64_t:\n case FFIType.i64:\n return \"i64\"\n case FFIType.uint64_t:\n case FFIType.u64:\n return \"u64\"\n case FFIType.double:\n case FFIType.f64:\n return \"f64\"\n case FFIType.float:\n case FFIType.f32:\n return \"f32\"\n case FFIType.bool:\n return \"bool\"\n case FFIType.ptr:\n case FFIType.pointer:\n return \"pointer\"\n case FFIType.void:\n return \"void\"\n case FFIType.cstring:\n // TODO(audit): cstring vs string semantics differ between backends.\n //\n // The type-name mapping here is intentional, but the runtime marshalling\n // is not equivalent:\n // - Bun's `cstring` parameter rejects raw JavaScript strings; callers\n // must pass a TypedArray, a Pointer, or a CString.\n // - Node's `string` parameter copies a JavaScript string to a\n // temporary NUL-terminated UTF-8 buffer for the duration of the\n // call.\n //\n // Callsites should encode strings into byte buffers and pass pointers\n // instead of relying on either backend's string handling.\n if (position === \"result\") {\n throw new Error(NODE_STRING_RETURN)\n }\n\n return \"string\"\n case FFIType.function:\n case FFIType.callback:\n // Pointer-like types (pointer, string, buffer, arraybuffer, and function)\n // are all passed as pointers in node:ffi.\n return \"pointer\"\n case FFIType.usize:\n // `usize` needs an ABI audit before Node support; use u64 would require\n // BigInt call sites and u32 can truncate pointers.\n throw new Error(NODE_USIZE_UNSUPPORTED)\n case FFIType.napi_env:\n case FFIType.napi_value:\n // Bun's N-API bridge types are not equivalent to raw Node FFI pointers.\n throw new Error(NODE_NAPI_UNSUPPORTED)\n case FFIType.buffer:\n return \"buffer\"\n default:\n return unsupportedNodeFFIType(type)\n }\n}\n\nfunction unsupportedNodeFFIType(type: never): never {\n throw new Error(`Unsupported FFIType for node:ffi: ${String(type)}`)\n}\n\nfunction toBigIntPointer(pointer: Pointer): bigint {\n if (typeof pointer === \"bigint\") {\n if (pointer < 0n) {\n throw new Error(POINTER_NEGATIVE)\n }\n\n return pointer\n }\n\n return toSafeBigIntPointer(pointer)\n}\n\nexport const dlopen = backend.dlopen\nexport const ptr = backend.ptr\nexport const suffix = backend.suffix\nexport const toArrayBuffer = backend.toArrayBuffer\n", + "import { existsSync } from \"node:fs\"\nimport { mkdir, writeFile as writeFileNode } from \"node:fs/promises\"\nimport { dirname, isAbsolute, resolve } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\n\nimport stringWidthLib from \"string-width\"\nimport stripAnsiLib from \"strip-ansi\"\n\nexport interface WriteFileOptions {\n createPath?: boolean\n mode?: number\n}\n\ninterface BunLike {\n sleep(msOrDate: number | Date): Promise\n stringWidth(text: string): number\n stripANSI(text: string): string\n write(destination: string | URL, data: string | ArrayBufferView, options?: WriteFileOptions): Promise\n}\n\ninterface FileImportModule {\n default: string\n}\n\ntype FilePathFallback = string | URL | (() => string | URL)\n\ntype GlobalWithBun = typeof globalThis & { Bun?: BunLike }\n\nconst TEXT_ENCODER = new TextEncoder()\nconst bun = (globalThis as GlobalWithBun).Bun\n\nexport const sleep: (msOrDate: number | Date) => Promise = bun?.sleep ?? standardSleep\nexport const stringWidth: (text: string) => number = bun?.stringWidth ?? stringWidthLib\nexport const stripANSI: (text: string) => string = bun?.stripANSI ?? stripAnsiLib\nexport const writeFile: (\n destination: string | URL,\n data: string | ArrayBufferView,\n options?: WriteFileOptions,\n) => Promise = bun?.write ?? writeFilePortable\n\n// Bun only discovers bundled file-like assets from the literal import expression at the call site.\nexport async function resolveBundledFilePath(\n loadBundledFile: () => Promise,\n fallbackPath: FilePathFallback,\n metaUrl: string,\n): Promise {\n if (!bun) {\n const path = resolveFallbackFilePath(fallbackPath, metaUrl)\n if (existsSync(path)) {\n return path\n }\n\n return (await loadBundledFilePath(loadBundledFile, metaUrl)) ?? path\n }\n\n return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl)\n}\n\nfunction resolveFallbackFilePath(fallbackPath: FilePathFallback, metaUrl: string): string {\n const path = typeof fallbackPath === \"function\" ? fallbackPath() : fallbackPath\n return fileURLToPath(path instanceof URL ? path : new URL(path, metaUrl))\n}\n\nfunction normalizeLoadedFilePath(loadedPath: string, baseUrl: string): string {\n if (loadedPath.startsWith(\"file:\")) {\n return fileURLToPath(loadedPath)\n }\n\n if (isAbsolute(loadedPath)) {\n return loadedPath\n }\n\n return resolve(dirname(fileURLToPath(baseUrl)), loadedPath)\n}\n\nasync function loadBundledFilePath(\n loadBundledFile: () => Promise,\n metaUrl: string,\n): Promise {\n const specifier = extractBundledImportSpecifier(loadBundledFile)\n if (!specifier) {\n return undefined\n }\n\n try {\n const moduleUrl = new URL(specifier, metaUrl)\n const loaded = (await import(moduleUrl.href)) as FileImportModule\n return normalizeLoadedFilePath(loaded.default, moduleUrl.href)\n } catch {\n return undefined\n }\n}\n\nfunction extractBundledImportSpecifier(loadBundledFile: () => Promise): string | undefined {\n const match = String(loadBundledFile).match(/\\bimport\\(\\s*([\"'`])([^\"'`]+)\\1/)\n return match?.[2]\n}\n\nfunction standardSleep(msOrDate: number | Date): Promise {\n const ms = msOrDate instanceof Date ? msOrDate.getTime() - Date.now() : msOrDate\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nasync function writeFilePortable(\n destination: string | URL,\n data: string | ArrayBufferView,\n options?: WriteFileOptions,\n): Promise {\n const destinationPath = destination instanceof URL ? fileURLToPath(destination) : destination\n\n if (options?.createPath) {\n await mkdir(dirname(destinationPath), { recursive: true })\n }\n\n const bytes =\n typeof data === \"string\" ? TEXT_ENCODER.encode(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength)\n\n await writeFileNode(destinationPath, bytes, { mode: options?.mode })\n\n return bytes.byteLength\n}\n", + "export default function ansiRegex({onlyFirst = false} = {}) {\n\t// Valid string terminator sequences are BEL, ESC\\, and 0x9c\n\tconst ST = '(?:\\\\u0007|\\\\u001B\\\\u005C|\\\\u009C)';\n\n\t// OSC sequences only: ESC ] ... ST (non-greedy until the first ST)\n\tconst osc = `(?:\\\\u001B\\\\][\\\\s\\\\S]*?${ST})`;\n\n\t// CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte\n\tconst csi = '[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:\\\\d{1,4}(?:[;:]\\\\d{0,4})*)?[\\\\dA-PR-TZcf-nq-uy=><~]';\n\n\tconst pattern = `${osc}|${csi}`;\n\n\treturn new RegExp(pattern, onlyFirst ? undefined : 'g');\n}\n", + "import ansiRegex from 'ansi-regex';\n\nconst regex = ansiRegex();\n\nexport default function stripAnsi(string) {\n\tif (typeof string !== 'string') {\n\t\tthrow new TypeError(`Expected a \\`string\\`, got \\`${typeof string}\\``);\n\t}\n\n\t// Even though the regex is global, we don't need to reset the `.lastIndex`\n\t// because unlike `.exec()` and `.test()`, `.replace()` does it automatically\n\t// and doing it manually has a performance penalty.\n\treturn string.replace(regex, '');\n}\n", + "// Generated code.\n\nfunction isAmbiguous(x) {\n\treturn x === 0xA1\n\t\t|| x === 0xA4\n\t\t|| x === 0xA7\n\t\t|| x === 0xA8\n\t\t|| x === 0xAA\n\t\t|| x === 0xAD\n\t\t|| x === 0xAE\n\t\t|| x >= 0xB0 && x <= 0xB4\n\t\t|| x >= 0xB6 && x <= 0xBA\n\t\t|| x >= 0xBC && x <= 0xBF\n\t\t|| x === 0xC6\n\t\t|| x === 0xD0\n\t\t|| x === 0xD7\n\t\t|| x === 0xD8\n\t\t|| x >= 0xDE && x <= 0xE1\n\t\t|| x === 0xE6\n\t\t|| x >= 0xE8 && x <= 0xEA\n\t\t|| x === 0xEC\n\t\t|| x === 0xED\n\t\t|| x === 0xF0\n\t\t|| x === 0xF2\n\t\t|| x === 0xF3\n\t\t|| x >= 0xF7 && x <= 0xFA\n\t\t|| x === 0xFC\n\t\t|| x === 0xFE\n\t\t|| x === 0x101\n\t\t|| x === 0x111\n\t\t|| x === 0x113\n\t\t|| x === 0x11B\n\t\t|| x === 0x126\n\t\t|| x === 0x127\n\t\t|| x === 0x12B\n\t\t|| x >= 0x131 && x <= 0x133\n\t\t|| x === 0x138\n\t\t|| x >= 0x13F && x <= 0x142\n\t\t|| x === 0x144\n\t\t|| x >= 0x148 && x <= 0x14B\n\t\t|| x === 0x14D\n\t\t|| x === 0x152\n\t\t|| x === 0x153\n\t\t|| x === 0x166\n\t\t|| x === 0x167\n\t\t|| x === 0x16B\n\t\t|| x === 0x1CE\n\t\t|| x === 0x1D0\n\t\t|| x === 0x1D2\n\t\t|| x === 0x1D4\n\t\t|| x === 0x1D6\n\t\t|| x === 0x1D8\n\t\t|| x === 0x1DA\n\t\t|| x === 0x1DC\n\t\t|| x === 0x251\n\t\t|| x === 0x261\n\t\t|| x === 0x2C4\n\t\t|| x === 0x2C7\n\t\t|| x >= 0x2C9 && x <= 0x2CB\n\t\t|| x === 0x2CD\n\t\t|| x === 0x2D0\n\t\t|| x >= 0x2D8 && x <= 0x2DB\n\t\t|| x === 0x2DD\n\t\t|| x === 0x2DF\n\t\t|| x >= 0x300 && x <= 0x36F\n\t\t|| x >= 0x391 && x <= 0x3A1\n\t\t|| x >= 0x3A3 && x <= 0x3A9\n\t\t|| x >= 0x3B1 && x <= 0x3C1\n\t\t|| x >= 0x3C3 && x <= 0x3C9\n\t\t|| x === 0x401\n\t\t|| x >= 0x410 && x <= 0x44F\n\t\t|| x === 0x451\n\t\t|| x === 0x2010\n\t\t|| x >= 0x2013 && x <= 0x2016\n\t\t|| x === 0x2018\n\t\t|| x === 0x2019\n\t\t|| x === 0x201C\n\t\t|| x === 0x201D\n\t\t|| x >= 0x2020 && x <= 0x2022\n\t\t|| x >= 0x2024 && x <= 0x2027\n\t\t|| x === 0x2030\n\t\t|| x === 0x2032\n\t\t|| x === 0x2033\n\t\t|| x === 0x2035\n\t\t|| x === 0x203B\n\t\t|| x === 0x203E\n\t\t|| x === 0x2074\n\t\t|| x === 0x207F\n\t\t|| x >= 0x2081 && x <= 0x2084\n\t\t|| x === 0x20AC\n\t\t|| x === 0x2103\n\t\t|| x === 0x2105\n\t\t|| x === 0x2109\n\t\t|| x === 0x2113\n\t\t|| x === 0x2116\n\t\t|| x === 0x2121\n\t\t|| x === 0x2122\n\t\t|| x === 0x2126\n\t\t|| x === 0x212B\n\t\t|| x === 0x2153\n\t\t|| x === 0x2154\n\t\t|| x >= 0x215B && x <= 0x215E\n\t\t|| x >= 0x2160 && x <= 0x216B\n\t\t|| x >= 0x2170 && x <= 0x2179\n\t\t|| x === 0x2189\n\t\t|| x >= 0x2190 && x <= 0x2199\n\t\t|| x === 0x21B8\n\t\t|| x === 0x21B9\n\t\t|| x === 0x21D2\n\t\t|| x === 0x21D4\n\t\t|| x === 0x21E7\n\t\t|| x === 0x2200\n\t\t|| x === 0x2202\n\t\t|| x === 0x2203\n\t\t|| x === 0x2207\n\t\t|| x === 0x2208\n\t\t|| x === 0x220B\n\t\t|| x === 0x220F\n\t\t|| x === 0x2211\n\t\t|| x === 0x2215\n\t\t|| x === 0x221A\n\t\t|| x >= 0x221D && x <= 0x2220\n\t\t|| x === 0x2223\n\t\t|| x === 0x2225\n\t\t|| x >= 0x2227 && x <= 0x222C\n\t\t|| x === 0x222E\n\t\t|| x >= 0x2234 && x <= 0x2237\n\t\t|| x === 0x223C\n\t\t|| x === 0x223D\n\t\t|| x === 0x2248\n\t\t|| x === 0x224C\n\t\t|| x === 0x2252\n\t\t|| x === 0x2260\n\t\t|| x === 0x2261\n\t\t|| x >= 0x2264 && x <= 0x2267\n\t\t|| x === 0x226A\n\t\t|| x === 0x226B\n\t\t|| x === 0x226E\n\t\t|| x === 0x226F\n\t\t|| x === 0x2282\n\t\t|| x === 0x2283\n\t\t|| x === 0x2286\n\t\t|| x === 0x2287\n\t\t|| x === 0x2295\n\t\t|| x === 0x2299\n\t\t|| x === 0x22A5\n\t\t|| x === 0x22BF\n\t\t|| x === 0x2312\n\t\t|| x >= 0x2460 && x <= 0x24E9\n\t\t|| x >= 0x24EB && x <= 0x254B\n\t\t|| x >= 0x2550 && x <= 0x2573\n\t\t|| x >= 0x2580 && x <= 0x258F\n\t\t|| x >= 0x2592 && x <= 0x2595\n\t\t|| x === 0x25A0\n\t\t|| x === 0x25A1\n\t\t|| x >= 0x25A3 && x <= 0x25A9\n\t\t|| x === 0x25B2\n\t\t|| x === 0x25B3\n\t\t|| x === 0x25B6\n\t\t|| x === 0x25B7\n\t\t|| x === 0x25BC\n\t\t|| x === 0x25BD\n\t\t|| x === 0x25C0\n\t\t|| x === 0x25C1\n\t\t|| x >= 0x25C6 && x <= 0x25C8\n\t\t|| x === 0x25CB\n\t\t|| x >= 0x25CE && x <= 0x25D1\n\t\t|| x >= 0x25E2 && x <= 0x25E5\n\t\t|| x === 0x25EF\n\t\t|| x === 0x2605\n\t\t|| x === 0x2606\n\t\t|| x === 0x2609\n\t\t|| x === 0x260E\n\t\t|| x === 0x260F\n\t\t|| x === 0x261C\n\t\t|| x === 0x261E\n\t\t|| x === 0x2640\n\t\t|| x === 0x2642\n\t\t|| x === 0x2660\n\t\t|| x === 0x2661\n\t\t|| x >= 0x2663 && x <= 0x2665\n\t\t|| x >= 0x2667 && x <= 0x266A\n\t\t|| x === 0x266C\n\t\t|| x === 0x266D\n\t\t|| x === 0x266F\n\t\t|| x === 0x269E\n\t\t|| x === 0x269F\n\t\t|| x === 0x26BF\n\t\t|| x >= 0x26C6 && x <= 0x26CD\n\t\t|| x >= 0x26CF && x <= 0x26D3\n\t\t|| x >= 0x26D5 && x <= 0x26E1\n\t\t|| x === 0x26E3\n\t\t|| x === 0x26E8\n\t\t|| x === 0x26E9\n\t\t|| x >= 0x26EB && x <= 0x26F1\n\t\t|| x === 0x26F4\n\t\t|| x >= 0x26F6 && x <= 0x26F9\n\t\t|| x === 0x26FB\n\t\t|| x === 0x26FC\n\t\t|| x === 0x26FE\n\t\t|| x === 0x26FF\n\t\t|| x === 0x273D\n\t\t|| x >= 0x2776 && x <= 0x277F\n\t\t|| x >= 0x2B56 && x <= 0x2B59\n\t\t|| x >= 0x3248 && x <= 0x324F\n\t\t|| x >= 0xE000 && x <= 0xF8FF\n\t\t|| x >= 0xFE00 && x <= 0xFE0F\n\t\t|| x === 0xFFFD\n\t\t|| x >= 0x1F100 && x <= 0x1F10A\n\t\t|| x >= 0x1F110 && x <= 0x1F12D\n\t\t|| x >= 0x1F130 && x <= 0x1F169\n\t\t|| x >= 0x1F170 && x <= 0x1F18D\n\t\t|| x === 0x1F18F\n\t\t|| x === 0x1F190\n\t\t|| x >= 0x1F19B && x <= 0x1F1AC\n\t\t|| x >= 0xE0100 && x <= 0xE01EF\n\t\t|| x >= 0xF0000 && x <= 0xFFFFD\n\t\t|| x >= 0x100000 && x <= 0x10FFFD;\n}\n\nfunction isFullWidth(x) {\n\treturn x === 0x3000\n\t\t|| x >= 0xFF01 && x <= 0xFF60\n\t\t|| x >= 0xFFE0 && x <= 0xFFE6;\n}\n\nfunction isWide(x) {\n\treturn x >= 0x1100 && x <= 0x115F\n\t\t|| x === 0x231A\n\t\t|| x === 0x231B\n\t\t|| x === 0x2329\n\t\t|| x === 0x232A\n\t\t|| x >= 0x23E9 && x <= 0x23EC\n\t\t|| x === 0x23F0\n\t\t|| x === 0x23F3\n\t\t|| x === 0x25FD\n\t\t|| x === 0x25FE\n\t\t|| x === 0x2614\n\t\t|| x === 0x2615\n\t\t|| x >= 0x2630 && x <= 0x2637\n\t\t|| x >= 0x2648 && x <= 0x2653\n\t\t|| x === 0x267F\n\t\t|| x >= 0x268A && x <= 0x268F\n\t\t|| x === 0x2693\n\t\t|| x === 0x26A1\n\t\t|| x === 0x26AA\n\t\t|| x === 0x26AB\n\t\t|| x === 0x26BD\n\t\t|| x === 0x26BE\n\t\t|| x === 0x26C4\n\t\t|| x === 0x26C5\n\t\t|| x === 0x26CE\n\t\t|| x === 0x26D4\n\t\t|| x === 0x26EA\n\t\t|| x === 0x26F2\n\t\t|| x === 0x26F3\n\t\t|| x === 0x26F5\n\t\t|| x === 0x26FA\n\t\t|| x === 0x26FD\n\t\t|| x === 0x2705\n\t\t|| x === 0x270A\n\t\t|| x === 0x270B\n\t\t|| x === 0x2728\n\t\t|| x === 0x274C\n\t\t|| x === 0x274E\n\t\t|| x >= 0x2753 && x <= 0x2755\n\t\t|| x === 0x2757\n\t\t|| x >= 0x2795 && x <= 0x2797\n\t\t|| x === 0x27B0\n\t\t|| x === 0x27BF\n\t\t|| x === 0x2B1B\n\t\t|| x === 0x2B1C\n\t\t|| x === 0x2B50\n\t\t|| x === 0x2B55\n\t\t|| x >= 0x2E80 && x <= 0x2E99\n\t\t|| x >= 0x2E9B && x <= 0x2EF3\n\t\t|| x >= 0x2F00 && x <= 0x2FD5\n\t\t|| x >= 0x2FF0 && x <= 0x2FFF\n\t\t|| x >= 0x3001 && x <= 0x303E\n\t\t|| x >= 0x3041 && x <= 0x3096\n\t\t|| x >= 0x3099 && x <= 0x30FF\n\t\t|| x >= 0x3105 && x <= 0x312F\n\t\t|| x >= 0x3131 && x <= 0x318E\n\t\t|| x >= 0x3190 && x <= 0x31E5\n\t\t|| x >= 0x31EF && x <= 0x321E\n\t\t|| x >= 0x3220 && x <= 0x3247\n\t\t|| x >= 0x3250 && x <= 0xA48C\n\t\t|| x >= 0xA490 && x <= 0xA4C6\n\t\t|| x >= 0xA960 && x <= 0xA97C\n\t\t|| x >= 0xAC00 && x <= 0xD7A3\n\t\t|| x >= 0xF900 && x <= 0xFAFF\n\t\t|| x >= 0xFE10 && x <= 0xFE19\n\t\t|| x >= 0xFE30 && x <= 0xFE52\n\t\t|| x >= 0xFE54 && x <= 0xFE66\n\t\t|| x >= 0xFE68 && x <= 0xFE6B\n\t\t|| x >= 0x16FE0 && x <= 0x16FE4\n\t\t|| x >= 0x16FF0 && x <= 0x16FF6\n\t\t|| x >= 0x17000 && x <= 0x18CD5\n\t\t|| x >= 0x18CFF && x <= 0x18D1E\n\t\t|| x >= 0x18D80 && x <= 0x18DF2\n\t\t|| x >= 0x1AFF0 && x <= 0x1AFF3\n\t\t|| x >= 0x1AFF5 && x <= 0x1AFFB\n\t\t|| x === 0x1AFFD\n\t\t|| x === 0x1AFFE\n\t\t|| x >= 0x1B000 && x <= 0x1B122\n\t\t|| x === 0x1B132\n\t\t|| x >= 0x1B150 && x <= 0x1B152\n\t\t|| x === 0x1B155\n\t\t|| x >= 0x1B164 && x <= 0x1B167\n\t\t|| x >= 0x1B170 && x <= 0x1B2FB\n\t\t|| x >= 0x1D300 && x <= 0x1D356\n\t\t|| x >= 0x1D360 && x <= 0x1D376\n\t\t|| x === 0x1F004\n\t\t|| x === 0x1F0CF\n\t\t|| x === 0x1F18E\n\t\t|| x >= 0x1F191 && x <= 0x1F19A\n\t\t|| x >= 0x1F200 && x <= 0x1F202\n\t\t|| x >= 0x1F210 && x <= 0x1F23B\n\t\t|| x >= 0x1F240 && x <= 0x1F248\n\t\t|| x === 0x1F250\n\t\t|| x === 0x1F251\n\t\t|| x >= 0x1F260 && x <= 0x1F265\n\t\t|| x >= 0x1F300 && x <= 0x1F320\n\t\t|| x >= 0x1F32D && x <= 0x1F335\n\t\t|| x >= 0x1F337 && x <= 0x1F37C\n\t\t|| x >= 0x1F37E && x <= 0x1F393\n\t\t|| x >= 0x1F3A0 && x <= 0x1F3CA\n\t\t|| x >= 0x1F3CF && x <= 0x1F3D3\n\t\t|| x >= 0x1F3E0 && x <= 0x1F3F0\n\t\t|| x === 0x1F3F4\n\t\t|| x >= 0x1F3F8 && x <= 0x1F43E\n\t\t|| x === 0x1F440\n\t\t|| x >= 0x1F442 && x <= 0x1F4FC\n\t\t|| x >= 0x1F4FF && x <= 0x1F53D\n\t\t|| x >= 0x1F54B && x <= 0x1F54E\n\t\t|| x >= 0x1F550 && x <= 0x1F567\n\t\t|| x === 0x1F57A\n\t\t|| x === 0x1F595\n\t\t|| x === 0x1F596\n\t\t|| x === 0x1F5A4\n\t\t|| x >= 0x1F5FB && x <= 0x1F64F\n\t\t|| x >= 0x1F680 && x <= 0x1F6C5\n\t\t|| x === 0x1F6CC\n\t\t|| x >= 0x1F6D0 && x <= 0x1F6D2\n\t\t|| x >= 0x1F6D5 && x <= 0x1F6D8\n\t\t|| x >= 0x1F6DC && x <= 0x1F6DF\n\t\t|| x === 0x1F6EB\n\t\t|| x === 0x1F6EC\n\t\t|| x >= 0x1F6F4 && x <= 0x1F6FC\n\t\t|| x >= 0x1F7E0 && x <= 0x1F7EB\n\t\t|| x === 0x1F7F0\n\t\t|| x >= 0x1F90C && x <= 0x1F93A\n\t\t|| x >= 0x1F93C && x <= 0x1F945\n\t\t|| x >= 0x1F947 && x <= 0x1F9FF\n\t\t|| x >= 0x1FA70 && x <= 0x1FA7C\n\t\t|| x >= 0x1FA80 && x <= 0x1FA8A\n\t\t|| x >= 0x1FA8E && x <= 0x1FAC6\n\t\t|| x === 0x1FAC8\n\t\t|| x >= 0x1FACD && x <= 0x1FADC\n\t\t|| x >= 0x1FADF && x <= 0x1FAEA\n\t\t|| x >= 0x1FAEF && x <= 0x1FAF8\n\t\t|| x >= 0x20000 && x <= 0x2FFFD\n\t\t|| x >= 0x30000 && x <= 0x3FFFD;\n}\n\nfunction getCategory(x) {\n\tif (isAmbiguous(x)) return 'ambiguous';\n\n\tif (isFullWidth(x)) return 'fullwidth';\n\n\tif (\n\t\tx === 0x20A9\n\t\t|| x >= 0xFF61 && x <= 0xFFBE\n\t\t|| x >= 0xFFC2 && x <= 0xFFC7\n\t\t|| x >= 0xFFCA && x <= 0xFFCF\n\t\t|| x >= 0xFFD2 && x <= 0xFFD7\n\t\t|| x >= 0xFFDA && x <= 0xFFDC\n\t\t|| x >= 0xFFE8 && x <= 0xFFEE\n\t) {\n\t\treturn 'halfwidth';\n\t}\n\n\tif (\n\t\tx >= 0x20 && x <= 0x7E\n\t\t|| x === 0xA2\n\t\t|| x === 0xA3\n\t\t|| x === 0xA5\n\t\t|| x === 0xA6\n\t\t|| x === 0xAC\n\t\t|| x === 0xAF\n\t\t|| x >= 0x27E6 && x <= 0x27ED\n\t\t|| x === 0x2985\n\t\t|| x === 0x2986\n\t) {\n\t\treturn 'narrow';\n\t}\n\n\tif (isWide(x)) return 'wide';\n\n\treturn 'neutral';\n}\n\nexport {isAmbiguous, isFullWidth, isWide, getCategory};\n", + "import {getCategory, isAmbiguous, isFullWidth, isWide} from './lookup.js';\n\nfunction validate(codePoint) {\n\tif (!Number.isSafeInteger(codePoint)) {\n\t\tthrow new TypeError(`Expected a code point, got \\`${typeof codePoint}\\`.`);\n\t}\n}\n\nexport function eastAsianWidthType(codePoint) {\n\tvalidate(codePoint);\n\n\treturn getCategory(codePoint);\n}\n\nexport function eastAsianWidth(codePoint, {ambiguousAsWide = false} = {}) {\n\tvalidate(codePoint);\n\n\tif (\n\t\tisFullWidth(codePoint)\n\t\t|| isWide(codePoint)\n\t\t|| (ambiguousAsWide && isAmbiguous(codePoint))\n\t) {\n\t\treturn 2;\n\t}\n\n\treturn 1;\n}\n\n// Private exports for https://github.com/sindresorhus/is-fullwidth-code-point\nexport {isFullWidth as _isFullWidth, isWide as _isWide} from './lookup.js';\n", + "import stripAnsi from 'strip-ansi';\nimport {eastAsianWidth} from 'get-east-asian-width';\nimport emojiRegex from 'emoji-regex';\n\nconst segmenter = new Intl.Segmenter();\n\nconst defaultIgnorableCodePointRegex = /^\\p{Default_Ignorable_Code_Point}$/u;\n\nexport default function stringWidth(string, options = {}) {\n\tif (typeof string !== 'string' || string.length === 0) {\n\t\treturn 0;\n\t}\n\n\tconst {\n\t\tambiguousIsNarrow = true,\n\t\tcountAnsiEscapeCodes = false,\n\t} = options;\n\n\tif (!countAnsiEscapeCodes) {\n\t\tstring = stripAnsi(string);\n\t}\n\n\tif (string.length === 0) {\n\t\treturn 0;\n\t}\n\n\tlet width = 0;\n\tconst eastAsianWidthOptions = {ambiguousAsWide: !ambiguousIsNarrow};\n\n\tfor (const {segment: character} of segmenter.segment(string)) {\n\t\tconst codePoint = character.codePointAt(0);\n\n\t\t// Ignore control characters\n\t\tif (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore zero-width characters\n\t\tif (\n\t\t\t(codePoint >= 0x20_0B && codePoint <= 0x20_0F) // Zero-width space, non-joiner, joiner, left-to-right mark, right-to-left mark\n\t\t\t|| codePoint === 0xFE_FF // Zero-width no-break space\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore combining characters\n\t\tif (\n\t\t\t(codePoint >= 0x3_00 && codePoint <= 0x3_6F) // Combining diacritical marks\n\t\t\t|| (codePoint >= 0x1A_B0 && codePoint <= 0x1A_FF) // Combining diacritical marks extended\n\t\t\t|| (codePoint >= 0x1D_C0 && codePoint <= 0x1D_FF) // Combining diacritical marks supplement\n\t\t\t|| (codePoint >= 0x20_D0 && codePoint <= 0x20_FF) // Combining diacritical marks for symbols\n\t\t\t|| (codePoint >= 0xFE_20 && codePoint <= 0xFE_2F) // Combining half marks\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore surrogate pairs\n\t\tif (codePoint >= 0xD8_00 && codePoint <= 0xDF_FF) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore variation selectors\n\t\tif (codePoint >= 0xFE_00 && codePoint <= 0xFE_0F) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// This covers some of the above cases, but we still keep them for performance reasons.\n\t\tif (defaultIgnorableCodePointRegex.test(character)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// TODO: Use `/\\p{RGI_Emoji}/v` when targeting Node.js 20.\n\t\tif (emojiRegex().test(character)) {\n\t\t\twidth += 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\twidth += eastAsianWidth(codePoint, eastAsianWidthOptions);\n\t}\n\n\treturn width;\n}\n", + "import {\n dlopen,\n ffiBool,\n toArrayBuffer,\n ptr,\n toPointer,\n type FFICallbackInstance,\n type Pointer,\n} from \"./platform/ffi.js\"\nimport { writeFile } from \"./platform/runtime.js\"\nimport { existsSync, writeFileSync } from \"fs\"\nimport { EventEmitter } from \"events\"\nimport {\n type CursorStyle,\n type CursorStyleOptions,\n type TargetChannel,\n type DebugOverlayCorner,\n type WidthMethod,\n type TerminalCapabilities,\n type Highlight,\n type LineInfo,\n type MousePointerStyle,\n} from \"./types.js\"\nexport type { LineInfo, AllocatorStats, BuildOptions, NativeRenderStats }\n\nimport { RGBA } from \"./lib/RGBA.js\"\nimport { OptimizedBuffer } from \"./buffer.js\"\nimport { TextBuffer } from \"./text-buffer.js\"\nimport { env, registerEnvVar } from \"./lib/env.js\"\nimport {\n StyledChunkStruct,\n HighlightStruct,\n LogicalCursorStruct,\n VisualCursorStruct,\n TerminalCapabilitiesStruct,\n EncodedCharStruct,\n LineInfoStruct,\n MeasureResultStruct,\n CursorStateStruct,\n CursorStyleOptionsStruct,\n GridDrawOptionsStruct,\n NativeSpanFeedOptionsStruct,\n NativeSpanFeedStatsStruct,\n ReserveInfoStruct,\n AudioCreateOptionsStruct,\n AudioStartOptionsStruct,\n AudioVoiceOptionsStruct,\n AudioStatsStruct,\n BuildOptionsStruct,\n AllocatorStatsStruct,\n NativeRenderStatsStruct,\n} from \"./zig-structs.js\"\nimport type {\n NativeSpanFeedOptions,\n NativeSpanFeedStats,\n ReserveInfo,\n AudioCreateOptions,\n AudioStartOptions,\n AudioVoiceOptions,\n AudioStats,\n BuildOptions,\n AllocatorStats,\n NativeRenderStats,\n} from \"./zig-structs.js\"\nimport { isBunfsPath } from \"./lib/bunfs.js\"\n\nregisterEnvVar({\n name: \"OPENTUI_LIBC\",\n description: \"Select Linux native libc package. Supported values: glibc, musl.\",\n type: \"string\",\n default: \"\",\n})\n\nfunction validateLinuxLibcOverride(): void {\n const libc = process.env.OPENTUI_LIBC\n if (libc === undefined || libc === \"\" || libc === \"glibc\" || libc === \"musl\") return\n throw new Error(`On Linux, OPENTUI_LIBC must be unset, empty, \"glibc\", or \"musl\", got \"${libc}\"`)\n}\n\nasync function resolveNativePackage() {\n if (process.platform === \"darwin\") {\n // @ts-ignore Optional native package may be absent when building on another platform.\n if (process.arch === \"x64\") return await import(\"@opentui/core-darwin-x64\")\n // @ts-ignore Optional native package may be absent when building on another platform.\n if (process.arch === \"arm64\") return await import(\"@opentui/core-darwin-arm64\")\n }\n\n if (process.platform === \"linux\") {\n validateLinuxLibcOverride()\n\n if (process.arch === \"x64\") {\n if (process.env.OPENTUI_LIBC === \"musl\") {\n // @ts-ignore Optional native package may be absent unless building a musl target.\n return await import(\"@opentui/core-linux-x64-musl\")\n } else {\n // @ts-ignore Optional native package may be absent when building on another platform.\n return await import(\"@opentui/core-linux-x64\")\n }\n }\n\n if (process.arch === \"arm64\") {\n if (process.env.OPENTUI_LIBC === \"musl\") {\n // @ts-ignore Optional native package may be absent unless building a musl target.\n return await import(\"@opentui/core-linux-arm64-musl\")\n } else {\n // @ts-ignore Optional native package may be absent when building on another platform.\n return await import(\"@opentui/core-linux-arm64\")\n }\n }\n }\n\n if (process.platform === \"win32\") {\n // @ts-ignore Optional native package may be absent when building on another platform.\n if (process.arch === \"x64\") return await import(\"@opentui/core-win32-x64\")\n // @ts-ignore Optional native package may be absent when building on another platform.\n if (process.arch === \"arm64\") return await import(\"@opentui/core-win32-arm64\")\n }\n\n throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`)\n}\nconst nativePackage = await resolveNativePackage()\n\nexport type NativeHandle = Pointer & { readonly __nativeHandle: T }\nexport type RendererHandle = NativeHandle<\"renderer\">\nexport type OptimizedBufferHandle = NativeHandle<\"optimized_buffer\">\nexport type TextBufferHandle = NativeHandle<\"text_buffer\">\nexport type TextBufferViewHandle = NativeHandle<\"text_buffer_view\">\nexport type EditBufferHandle = NativeHandle<\"edit_buffer\">\nexport type EditorViewHandle = NativeHandle<\"editor_view\">\nexport type SyntaxStyleHandle = NativeHandle<\"syntax_style\">\nexport type EventSinkHandle = NativeHandle<\"event_sink\">\nexport type AudioEngineHandle = NativeHandle<\"audio_engine\">\nlet targetLibPath = nativePackage.default\n\nif (isBunfsPath(targetLibPath)) {\n targetLibPath = targetLibPath.replace(\"../\", \"\")\n}\n\nif (!existsSync(targetLibPath)) {\n throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`)\n}\n\nregisterEnvVar({\n name: \"OTUI_DEBUG_FFI\",\n description: \"Enable debug logging for the FFI bindings.\",\n type: \"boolean\",\n default: false,\n})\n\nregisterEnvVar({\n name: \"OTUI_TRACE_FFI\",\n description: \"Enable tracing for the FFI bindings.\",\n type: \"boolean\",\n default: false,\n})\n\n// Env vars used in terminal.zig\nregisterEnvVar({\n name: \"OPENTUI_FORCE_WCWIDTH\",\n description: \"Use wcwidth for character width calculations\",\n type: \"boolean\",\n default: false,\n})\nregisterEnvVar({\n name: \"OPENTUI_FORCE_UNICODE\",\n description: \"Force Mode 2026 Unicode support in terminal capabilities\",\n type: \"boolean\",\n default: false,\n})\nregisterEnvVar({\n name: \"OPENTUI_GRAPHICS\",\n description: \"Enable Kitty graphics protocol detection\",\n type: \"boolean\",\n default: true,\n})\nregisterEnvVar({\n name: \"OPENTUI_FORCE_NOZWJ\",\n description: \"Use no_zwj width method (Unicode without ZWJ joining)\",\n type: \"boolean\",\n default: false,\n})\n\n// Cursor & mouse pointer style mappings (avoid recreation on each call)\nconst CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2, default: 3 } as const\nconst CURSOR_ID_TO_STYLE = [\"block\", \"line\", \"underline\", \"default\"] as const\nconst MOUSE_STYLE_TO_ID = { default: 0, pointer: 1, text: 2, crosshair: 3, move: 4, \"not-allowed\": 5 } as const\nconst MAX_FFI_U32 = 0xffff_ffff\n// Global singleton state for FFI tracing to prevent duplicate exit handlers\nlet globalTraceSymbols: Record | null = null\nlet globalFFILogPath: string | null = null\nlet exitHandlerRegistered = false\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === \"bigint\" ? Number(value) : value\n}\n\nfunction toSafeByteCount(value: number | bigint, label: string): number {\n if (typeof value !== \"bigint\") {\n return value\n }\n\n if (value > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new RangeError(`${label} exceeds JavaScript safe integer range`)\n }\n\n return Number(value)\n}\n\nfunction toSafeFFIU32Length(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 0 || value > MAX_FFI_U32) {\n throw new RangeError(`${label} exceeds native u32 length limit`)\n }\n\n return value\n}\n\nfunction ptrOrNull(value: ArrayBufferView): Pointer | null {\n return value.byteLength === 0 ? null : ptr(value)\n}\n\nfunction rgbaPtr(value: RGBA): Pointer {\n return ptr(value.buffer)\n}\n\nfunction optionalRgbaPtr(value: RGBA | null | undefined): Pointer | null {\n return value ? rgbaPtr(value) : null\n}\n\nfunction getOpenTUILib(libPath?: string) {\n const resolvedLibPath = libPath || targetLibPath\n\n const rawSymbols = dlopen(resolvedLibPath, {\n // Logging\n setLogCallback: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n // Event bus\n createEventSink: {\n args: [\"ptr\"],\n returns: \"u32\",\n },\n destroyEventSink: {\n args: [\"u32\"],\n returns: \"void\",\n },\n // Renderer management\n createRenderer: {\n args: [\"u32\", \"u32\", \"u8\", \"u8\", \"ptr\"],\n returns: \"u32\",\n },\n setTerminalEnvVar: {\n args: [\"u32\", \"ptr\", \"u32\", \"ptr\", \"u32\"],\n returns: \"bool\",\n },\n destroyRenderer: {\n args: [\"u32\"],\n returns: \"void\",\n },\n setUseThread: {\n args: [\"u32\", \"bool\"],\n returns: \"void\",\n },\n setClearOnShutdown: {\n args: [\"u32\", \"bool\"],\n returns: \"void\",\n },\n setBackgroundColor: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n setRenderOffset: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n resetSplitScrollback: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"u32\",\n },\n syncSplitScrollback: {\n args: [\"u32\", \"u32\"],\n returns: \"u32\",\n },\n getSplitOutputOffset: {\n args: [\"u32\", \"u32\"],\n returns: \"u32\",\n },\n setPendingSplitFooterTransition: {\n args: [\"u32\", \"u8\", \"u32\", \"u32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n clearPendingSplitFooterTransition: {\n args: [\"u32\"],\n returns: \"void\",\n },\n updateStats: {\n args: [\"u32\", \"f64\", \"u32\", \"f64\"],\n returns: \"void\",\n },\n updateMemoryStats: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n getRenderStats: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n render: {\n args: [\"u32\", \"bool\"],\n returns: \"u8\",\n },\n repaintSplitFooter: {\n args: [\"u32\", \"u32\", \"bool\"],\n returns: \"u64\",\n },\n // Single FFI entrypoint for split commit append. beginFrame/finalizeFrame let\n // native code decide whether this call is a standalone commit or part of a\n // larger batched frame envelope.\n commitSplitFooterSnapshot: {\n args: [\"u32\", \"u32\", \"u32\", \"bool\", \"bool\", \"u32\", \"bool\", \"bool\", \"bool\"],\n returns: \"u64\",\n },\n getNextBuffer: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n getCurrentBuffer: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n rendererSetPaletteState: {\n args: [\"u32\", \"ptr\", \"u32\", \"ptr\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n\n queryPixelResolution: {\n args: [\"u32\"],\n returns: \"void\",\n },\n queryThemeColors: {\n args: [\"u32\"],\n returns: \"void\",\n },\n\n createOptimizedBuffer: {\n args: [\"u32\", \"u32\", \"bool\", \"u8\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n destroyOptimizedBuffer: {\n args: [\"u32\"],\n returns: \"void\",\n },\n\n drawFrameBuffer: {\n args: [\"u32\", \"i32\", \"i32\", \"u32\", \"u32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n getBufferWidth: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n getBufferHeight: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n bufferClear: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n bufferGetCharPtr: {\n args: [\"u32\"],\n returns: \"ptr\",\n },\n bufferGetFgPtr: {\n args: [\"u32\"],\n returns: \"ptr\",\n },\n bufferGetBgPtr: {\n args: [\"u32\"],\n returns: \"ptr\",\n },\n bufferGetAttributesPtr: {\n args: [\"u32\"],\n returns: \"ptr\",\n },\n bufferGetRespectAlpha: {\n args: [\"u32\"],\n returns: \"bool\",\n },\n bufferSetRespectAlpha: {\n args: [\"u32\", \"bool\"],\n returns: \"void\",\n },\n bufferGetId: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n bufferGetRealCharSize: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n bufferWriteResolvedChars: {\n args: [\"u32\", \"ptr\", \"u32\", \"bool\"],\n returns: \"u32\",\n },\n\n bufferDrawText: {\n args: [\"u32\", \"ptr\", \"u32\", \"u32\", \"u32\", \"ptr\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n bufferSetCellWithAlphaBlending: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"ptr\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n bufferSetCell: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"ptr\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n bufferFillRect: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"u32\", \"ptr\"],\n returns: \"void\",\n },\n bufferColorMatrix: {\n args: [\"u32\", \"ptr\", \"ptr\", \"u32\", \"f32\", \"u8\"],\n returns: \"void\",\n },\n bufferColorMatrixUniform: {\n args: [\"u32\", \"ptr\", \"f32\", \"u8\"],\n returns: \"void\",\n },\n bufferResize: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n\n // Link API\n linkAlloc: {\n args: [\"ptr\", \"u32\"],\n returns: \"u32\",\n },\n linkGetUrl: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n attributesWithLink: {\n args: [\"u32\", \"u32\"],\n returns: \"u32\",\n },\n attributesGetLinkId: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n\n resizeRenderer: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n\n // Cursor functions (now renderer-scoped)\n setCursorPosition: {\n args: [\"u32\", \"i32\", \"i32\", \"bool\"],\n returns: \"void\",\n },\n setCursorColor: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n getCursorState: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n\n // Cursor and mouse pointer style (combined)\n setCursorStyleOptions: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n\n // Debug overlay\n setDebugOverlay: {\n args: [\"u32\", \"bool\", \"u8\"],\n returns: \"void\",\n },\n\n // Terminal control\n clearTerminal: {\n args: [\"u32\"],\n returns: \"void\",\n },\n setTerminalTitle: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n copyToClipboardOSC52: {\n args: [\"u32\", \"u8\", \"ptr\", \"u32\"],\n returns: \"bool\",\n },\n clearClipboardOSC52: {\n args: [\"u32\", \"u8\"],\n returns: \"bool\",\n },\n triggerNotification: {\n args: [\"u32\", \"ptr\", \"u32\", \"ptr\", \"u32\"],\n returns: \"bool\",\n },\n\n bufferDrawSuperSampleBuffer: {\n args: [\"u32\", \"u32\", \"u32\", \"ptr\", \"u32\", \"u8\", \"u32\"],\n returns: \"void\",\n },\n bufferDrawPackedBuffer: {\n args: [\"u32\", \"ptr\", \"u32\", \"u32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n bufferDrawGrayscaleBuffer: {\n args: [\"u32\", \"i32\", \"i32\", \"ptr\", \"u32\", \"u32\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n bufferDrawGrayscaleBufferSupersampled: {\n args: [\"u32\", \"i32\", \"i32\", \"ptr\", \"u32\", \"u32\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n bufferDrawGrid: {\n args: [\"u32\", \"ptr\", \"ptr\", \"ptr\", \"ptr\", \"u32\", \"ptr\", \"u32\", \"ptr\"],\n returns: \"void\",\n },\n bufferDrawBox: {\n args: [\"u32\", \"i32\", \"i32\", \"u32\", \"u32\", \"ptr\", \"u32\", \"ptr\", \"ptr\", \"ptr\", \"ptr\", \"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n bufferPushScissorRect: {\n args: [\"u32\", \"i32\", \"i32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n bufferPopScissorRect: {\n args: [\"u32\"],\n returns: \"void\",\n },\n bufferClearScissorRects: {\n args: [\"u32\"],\n returns: \"void\",\n },\n bufferPushOpacity: {\n args: [\"u32\", \"f32\"],\n returns: \"void\",\n },\n bufferPopOpacity: {\n args: [\"u32\"],\n returns: \"void\",\n },\n bufferGetCurrentOpacity: {\n args: [\"u32\"],\n returns: \"f32\",\n },\n bufferClearOpacity: {\n args: [\"u32\"],\n returns: \"void\",\n },\n\n addToHitGrid: {\n args: [\"u32\", \"i32\", \"i32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n clearCurrentHitGrid: {\n args: [\"u32\"],\n returns: \"void\",\n },\n hitGridPushScissorRect: {\n args: [\"u32\", \"i32\", \"i32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n hitGridPopScissorRect: {\n args: [\"u32\"],\n returns: \"void\",\n },\n hitGridClearScissorRects: {\n args: [\"u32\"],\n returns: \"void\",\n },\n addToCurrentHitGridClipped: {\n args: [\"u32\", \"i32\", \"i32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n checkHit: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"u32\",\n },\n getHitGridDirty: {\n args: [\"u32\"],\n returns: \"bool\",\n },\n dumpHitGrid: {\n args: [\"u32\"],\n returns: \"void\",\n },\n dumpBuffers: {\n args: [\"u32\", \"i64\"],\n returns: \"void\",\n },\n dumpOutputBuffer: {\n args: [\"u32\", \"i64\"],\n returns: \"void\",\n },\n restoreTerminalModes: {\n args: [\"u32\"],\n returns: \"void\",\n },\n enableMouse: {\n args: [\"u32\", \"bool\"],\n returns: \"void\",\n },\n disableMouse: {\n args: [\"u32\"],\n returns: \"void\",\n },\n enableKittyKeyboard: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n disableKittyKeyboard: {\n args: [\"u32\"],\n returns: \"void\",\n },\n setKittyKeyboardFlags: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n getKittyKeyboardFlags: {\n args: [\"u32\"],\n returns: \"u8\",\n },\n setupTerminal: {\n args: [\"u32\", \"bool\"],\n returns: \"void\",\n },\n suspendRenderer: {\n args: [\"u32\"],\n returns: \"void\",\n },\n resumeRenderer: {\n args: [\"u32\"],\n returns: \"void\",\n },\n writeOut: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n\n // TextBuffer functions\n createTextBuffer: {\n args: [\"u8\"],\n returns: \"u32\",\n },\n destroyTextBuffer: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferGetLength: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n textBufferGetByteSize: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n\n textBufferReset: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferClear: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferSetDefaultFg: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferSetDefaultBg: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferSetDefaultAttributes: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferResetDefaults: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferGetTabWidth: {\n args: [\"u32\"],\n returns: \"u8\",\n },\n textBufferSetTabWidth: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n textBufferRegisterMemBuffer: {\n args: [\"u32\", \"ptr\", \"u32\", \"bool\"],\n returns: \"u16\",\n },\n textBufferReplaceMemBuffer: {\n args: [\"u32\", \"u8\", \"ptr\", \"u32\", \"bool\"],\n returns: \"bool\",\n },\n textBufferClearMemRegistry: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferSetTextFromMem: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n textBufferAppend: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n textBufferAppendFromMemId: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n textBufferLoadFile: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"bool\",\n },\n textBufferSetStyledText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n textBufferGetLineCount: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n textBufferGetPlainText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n textBufferAddHighlightByCharRange: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferAddHighlight: {\n args: [\"u32\", \"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferRemoveHighlightsByRef: {\n args: [\"u32\", \"u16\"],\n returns: \"void\",\n },\n textBufferClearLineHighlights: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n textBufferClearAllHighlights: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferSetSyntaxStyle: {\n args: [\"u32\", \"u32\"],\n returns: \"bool\",\n },\n textBufferGetLineHighlightsPtr: {\n args: [\"u32\", \"u32\", \"ptr\"],\n returns: \"ptr\",\n },\n textBufferFreeLineHighlights: {\n args: [\"ptr\", \"u32\"],\n returns: \"void\",\n },\n textBufferGetHighlightCount: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n textBufferGetTextRange: {\n args: [\"u32\", \"u32\", \"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n textBufferGetTextRangeByCoords: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n\n // TextBufferView functions\n createTextBufferView: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n destroyTextBufferView: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferViewSetSelection: {\n args: [\"u32\", \"u32\", \"u32\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n textBufferViewResetSelection: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferViewGetSelectionInfo: {\n args: [\"u32\"],\n returns: \"u64\",\n },\n textBufferViewSetLocalSelection: {\n args: [\"u32\", \"i32\", \"i32\", \"i32\", \"i32\", \"ptr\", \"ptr\"],\n returns: \"bool\",\n },\n textBufferViewUpdateSelection: {\n args: [\"u32\", \"u32\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n textBufferViewUpdateLocalSelection: {\n args: [\"u32\", \"i32\", \"i32\", \"i32\", \"i32\", \"ptr\", \"ptr\"],\n returns: \"bool\",\n },\n textBufferViewResetLocalSelection: {\n args: [\"u32\"],\n returns: \"void\",\n },\n textBufferViewSetWrapWidth: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n textBufferViewSetWrapMode: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n textBufferViewSetFirstLineOffset: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n textBufferViewSetViewportSize: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n textBufferViewSetViewport: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n textBufferViewGetVirtualLineCount: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n textBufferViewGetLineInfoDirect: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferViewGetLogicalLineInfoDirect: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferViewGetSelectedText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n textBufferViewGetPlainText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n textBufferViewSetTabIndicator: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n textBufferViewSetTabIndicatorColor: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n textBufferViewSetTruncate: {\n args: [\"u32\", \"bool\"],\n returns: \"void\",\n },\n textBufferViewMeasureForDimensions: {\n args: [\"u32\", \"u32\", \"u32\", \"ptr\"],\n returns: \"bool\",\n },\n bufferDrawTextBufferView: {\n args: [\"u32\", \"u32\", \"i32\", \"i32\"],\n returns: \"void\",\n },\n bufferDrawEditorView: {\n args: [\"u32\", \"u32\", \"i32\", \"i32\"],\n returns: \"void\",\n },\n\n // EditorView functions\n createEditorView: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"u32\",\n },\n destroyEditorView: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editorViewSetViewportSize: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n editorViewSetViewport: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"u32\", \"bool\"],\n returns: \"void\",\n },\n editorViewGetViewport: {\n args: [\"u32\", \"ptr\", \"ptr\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n editorViewSetScrollMargin: {\n args: [\"u32\", \"f32\"],\n returns: \"void\",\n },\n editorViewSetWrapMode: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n editorViewGetVirtualLineCount: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n editorViewGetTotalVirtualLineCount: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n editorViewGetTextBufferView: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n editorViewGetLineInfoDirect: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editorViewGetLogicalLineInfoDirect: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n\n // EditBuffer functions\n createEditBuffer: {\n args: [\"u8\", \"u32\"],\n returns: \"u32\",\n },\n destroyEditBuffer: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferSetText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n editBufferSetTextFromMem: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n editBufferReplaceText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n editBufferReplaceTextFromMem: {\n args: [\"u32\", \"u8\"],\n returns: \"void\",\n },\n editBufferGetText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n editBufferInsertChar: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n editBufferInsertText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n editBufferDeleteChar: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferDeleteCharBackward: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferDeleteRange: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n editBufferNewLine: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferDeleteLine: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferMoveCursorLeft: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferMoveCursorRight: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferMoveCursorUp: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferMoveCursorDown: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferGotoLine: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n editBufferSetCursor: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n editBufferSetCursorToLineCol: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n editBufferSetCursorByOffset: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n editBufferGetCursorPosition: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editBufferGetId: {\n args: [\"u32\"],\n returns: \"u16\",\n },\n editBufferGetTextBuffer: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n editBufferDebugLogRope: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferUndo: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n editBufferRedo: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n editBufferCanUndo: {\n args: [\"u32\"],\n returns: \"bool\",\n },\n editBufferCanRedo: {\n args: [\"u32\"],\n returns: \"bool\",\n },\n editBufferClearHistory: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferClear: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editBufferGetNextWordBoundary: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editBufferGetPrevWordBoundary: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editBufferGetEOL: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editBufferOffsetToPosition: {\n args: [\"u32\", \"u32\", \"ptr\"],\n returns: \"bool\",\n },\n editBufferPositionToOffset: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"u32\",\n },\n editBufferGetLineStartOffset: {\n args: [\"u32\", \"u32\"],\n returns: \"u32\",\n },\n editBufferGetTextRange: {\n args: [\"u32\", \"u32\", \"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n editBufferGetTextRangeByCoords: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n\n // EditorView selection and editing methods\n editorViewSetSelection: {\n args: [\"u32\", \"u32\", \"u32\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n editorViewResetSelection: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editorViewGetSelection: {\n args: [\"u32\"],\n returns: \"u64\",\n },\n editorViewSetLocalSelection: {\n args: [\"u32\", \"i32\", \"i32\", \"i32\", \"i32\", \"ptr\", \"ptr\", \"bool\", \"bool\"],\n returns: \"bool\",\n },\n editorViewUpdateSelection: {\n args: [\"u32\", \"u32\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n editorViewUpdateLocalSelection: {\n args: [\"u32\", \"i32\", \"i32\", \"i32\", \"i32\", \"ptr\", \"ptr\", \"bool\", \"bool\"],\n returns: \"bool\",\n },\n editorViewResetLocalSelection: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editorViewGetSelectedTextBytes: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n editorViewGetCursor: {\n args: [\"u32\", \"ptr\", \"ptr\"],\n returns: \"void\",\n },\n editorViewGetText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n\n // EditorView VisualCursor methods\n editorViewGetVisualCursor: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n\n editorViewMoveUpVisual: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editorViewMoveDownVisual: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editorViewDeleteSelectedText: {\n args: [\"u32\"],\n returns: \"void\",\n },\n editorViewSetCursorByOffset: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n editorViewGetNextWordBoundary: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editorViewGetPrevWordBoundary: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editorViewGetEOL: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editorViewGetVisualSOL: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editorViewGetVisualEOL: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n editorViewSetPlaceholderStyledText: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n editorViewSetTabIndicator: {\n args: [\"u32\", \"u32\"],\n returns: \"void\",\n },\n editorViewSetTabIndicatorColor: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n\n getArenaAllocatedBytes: {\n args: [],\n returns: \"u64\",\n },\n getBuildOptions: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n getAllocatorStats: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n\n // SyntaxStyle functions\n createSyntaxStyle: {\n args: [],\n returns: \"u32\",\n },\n destroySyntaxStyle: {\n args: [\"u32\"],\n returns: \"void\",\n },\n syntaxStyleRegister: {\n args: [\"u32\", \"ptr\", \"u32\", \"ptr\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n syntaxStyleResolveByName: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n syntaxStyleGetStyleCount: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n\n // Terminal capability functions\n getTerminalCapabilities: {\n args: [\"u32\", \"ptr\"],\n returns: \"void\",\n },\n processCapabilityResponse: {\n args: [\"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n\n // Unicode encoding API\n encodeUnicode: {\n args: [\"ptr\", \"u32\", \"ptr\", \"ptr\", \"u8\"],\n returns: \"bool\",\n },\n freeUnicode: {\n args: [\"ptr\", \"u32\"],\n returns: \"void\",\n },\n bufferDrawChar: {\n args: [\"u32\", \"u32\", \"u32\", \"u32\", \"ptr\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n\n // Yoga layout\n yogaConfigCreate: {\n args: [],\n returns: \"ptr\",\n },\n yogaConfigFree: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaConfigSetUseWebDefaults: {\n args: [\"ptr\", \"bool\"],\n returns: \"void\",\n },\n yogaConfigGetUseWebDefaults: {\n args: [\"ptr\"],\n returns: \"bool\",\n },\n yogaConfigSetPointScaleFactor: {\n args: [\"ptr\", \"f32\"],\n returns: \"void\",\n },\n yogaConfigGetPointScaleFactor: {\n args: [\"ptr\"],\n returns: \"f32\",\n },\n yogaConfigSetErrata: {\n args: [\"ptr\", \"u32\"],\n returns: \"void\",\n },\n yogaConfigGetErrata: {\n args: [\"ptr\"],\n returns: \"u32\",\n },\n yogaConfigSetExperimentalFeatureEnabled: {\n args: [\"ptr\", \"u32\", \"bool\"],\n returns: \"void\",\n },\n yogaConfigIsExperimentalFeatureEnabled: {\n args: [\"ptr\", \"u32\"],\n returns: \"bool\",\n },\n yogaNodeCreate: {\n args: [],\n returns: \"ptr\",\n },\n yogaNodeCreateForOpenTUI: {\n args: [],\n returns: \"ptr\",\n },\n yogaNodeCreateWithConfig: {\n args: [\"ptr\"],\n returns: \"ptr\",\n },\n yogaNodeFree: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaNodeFreeRecursive: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaNodeReset: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaNodeCopyStyle: {\n args: [\"ptr\", \"ptr\"],\n returns: \"void\",\n },\n yogaNodeInsertChild: {\n args: [\"ptr\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n yogaNodeRemoveChild: {\n args: [\"ptr\", \"ptr\"],\n returns: \"void\",\n },\n yogaNodeRemoveAllChildren: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaNodeGetChild: {\n args: [\"ptr\", \"u32\"],\n returns: \"ptr\",\n },\n yogaNodeGetChildCount: {\n args: [\"ptr\"],\n returns: \"u32\",\n },\n yogaNodeGetParent: {\n args: [\"ptr\"],\n returns: \"ptr\",\n },\n yogaNodeCalculateLayout: {\n args: [\"ptr\", \"f32\", \"f32\", \"u32\"],\n returns: \"void\",\n },\n yogaNodeIsDirty: {\n args: [\"ptr\"],\n returns: \"bool\",\n },\n yogaNodeMarkDirty: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaNodeGetHasNewLayout: {\n args: [\"ptr\"],\n returns: \"bool\",\n },\n yogaNodeSetHasNewLayout: {\n args: [\"ptr\", \"bool\"],\n returns: \"void\",\n },\n yogaNodeSetIsReferenceBaseline: {\n args: [\"ptr\", \"bool\"],\n returns: \"void\",\n },\n yogaNodeIsReferenceBaseline: {\n args: [\"ptr\"],\n returns: \"bool\",\n },\n yogaNodeSetAlwaysFormsContainingBlock: {\n args: [\"ptr\", \"bool\"],\n returns: \"void\",\n },\n yogaNodeGetAlwaysFormsContainingBlock: {\n args: [\"ptr\"],\n returns: \"bool\",\n },\n yogaNodeGetComputedLayout: {\n args: [\"ptr\", \"ptr\"],\n returns: \"void\",\n },\n yogaNodeLayoutGetEdge: {\n args: [\"ptr\", \"u32\", \"u32\"],\n returns: \"f32\",\n },\n yogaNodeStyleSetEnum: {\n args: [\"ptr\", \"u32\", \"u32\"],\n returns: \"void\",\n },\n yogaNodeStyleGetEnum: {\n args: [\"ptr\", \"u32\"],\n returns: \"u32\",\n },\n yogaNodeStyleSetFloat: {\n args: [\"ptr\", \"u32\", \"f32\"],\n returns: \"void\",\n },\n yogaNodeStyleGetFloat: {\n args: [\"ptr\", \"u32\"],\n returns: \"f32\",\n },\n yogaNodeStyleSetBorder: {\n args: [\"ptr\", \"u32\", \"f32\"],\n returns: \"void\",\n },\n yogaNodeStyleGetBorder: {\n args: [\"ptr\", \"u32\"],\n returns: \"f32\",\n },\n yogaNodeStyleSetValue: {\n args: [\"ptr\", \"u32\", \"u32\", \"u32\", \"f32\"],\n returns: \"void\",\n },\n yogaNodeStyleGetValue: {\n args: [\"ptr\", \"u32\", \"u32\"],\n returns: \"u64\",\n },\n yogaNodeSetMeasureFunc: {\n args: [\"ptr\", \"ptr\"],\n returns: \"void\",\n },\n yogaNodeUnsetMeasureFunc: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaNodeHasMeasureFunc: {\n args: [\"ptr\"],\n returns: \"bool\",\n },\n yogaNodeSetDirtiedFunc: {\n args: [\"ptr\", \"ptr\"],\n returns: \"void\",\n },\n yogaNodeUnsetDirtiedFunc: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n yogaStoreMeasureResult: {\n args: [\"f32\", \"f32\"],\n returns: \"void\",\n },\n\n // Audio\n createAudioEngine: {\n args: [\"ptr\"],\n returns: \"u32\",\n },\n destroyAudioEngine: {\n args: [\"u32\"],\n returns: \"void\",\n },\n audioRefreshPlaybackDevices: {\n args: [\"u32\"],\n returns: \"i32\",\n },\n audioGetPlaybackDeviceCount: {\n args: [\"u32\"],\n returns: \"u32\",\n },\n audioGetPlaybackDeviceName: {\n args: [\"u32\", \"u32\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n audioIsPlaybackDeviceDefault: {\n args: [\"u32\", \"u32\"],\n returns: \"bool\",\n },\n audioSelectPlaybackDevice: {\n args: [\"u32\", \"u32\"],\n returns: \"i32\",\n },\n audioClearPlaybackDeviceSelection: {\n args: [\"u32\"],\n returns: \"void\",\n },\n audioStart: {\n args: [\"u32\", \"ptr\"],\n returns: \"i32\",\n },\n audioStartMixer: {\n args: [\"u32\"],\n returns: \"i32\",\n },\n audioStop: {\n args: [\"u32\"],\n returns: \"i32\",\n },\n audioLoad: {\n args: [\"u32\", \"ptr\", \"u32\", \"ptr\"],\n returns: \"i32\",\n },\n audioUnload: {\n args: [\"u32\", \"u32\"],\n returns: \"i32\",\n },\n audioPlay: {\n args: [\"u32\", \"u32\", \"ptr\", \"ptr\"],\n returns: \"i32\",\n },\n audioStopVoice: {\n args: [\"u32\", \"u32\"],\n returns: \"i32\",\n },\n audioSetVoiceGroup: {\n args: [\"u32\", \"u32\", \"u32\"],\n returns: \"i32\",\n },\n audioCreateGroup: {\n args: [\"u32\", \"ptr\", \"u32\", \"ptr\"],\n returns: \"i32\",\n },\n audioSetGroupVolume: {\n args: [\"u32\", \"u32\", \"f32\"],\n returns: \"i32\",\n },\n audioSetMasterVolume: {\n args: [\"u32\", \"f32\"],\n returns: \"i32\",\n },\n audioMixToBuffer: {\n args: [\"u32\", \"ptr\", \"u32\", \"u8\"],\n returns: \"i32\",\n },\n audioEnableTap: {\n args: [\"u32\", \"bool\", \"u32\"],\n returns: \"i32\",\n },\n audioReadTap: {\n args: [\"u32\", \"ptr\", \"u32\", \"u8\", \"ptr\"],\n returns: \"i32\",\n },\n audioGetStats: {\n args: [\"u32\", \"ptr\"],\n returns: \"i32\",\n },\n\n // NativeSpanFeed\n createNativeSpanFeed: {\n args: [\"ptr\"],\n returns: \"ptr\",\n },\n attachNativeSpanFeed: {\n args: [\"ptr\"],\n returns: \"i32\",\n },\n destroyNativeSpanFeed: {\n args: [\"ptr\"],\n returns: \"void\",\n },\n streamWrite: {\n args: [\"ptr\", \"ptr\", \"u32\"],\n returns: \"i32\",\n },\n streamCommit: {\n args: [\"ptr\"],\n returns: \"i32\",\n },\n streamDrainSpans: {\n args: [\"ptr\", \"ptr\", \"u32\"],\n returns: \"u32\",\n },\n streamClose: {\n args: [\"ptr\"],\n returns: \"i32\",\n },\n streamReserve: {\n args: [\"ptr\", \"u32\", \"ptr\"],\n returns: \"i32\",\n },\n streamCommitReserved: {\n args: [\"ptr\", \"u32\"],\n returns: \"i32\",\n },\n streamSetOptions: {\n args: [\"ptr\", \"ptr\"],\n returns: \"i32\",\n },\n streamGetStats: {\n args: [\"ptr\", \"ptr\"],\n returns: \"i32\",\n },\n streamSetCallback: {\n args: [\"ptr\", \"ptr\"],\n returns: \"void\",\n },\n })\n\n if (env.OTUI_DEBUG_FFI || env.OTUI_TRACE_FFI) {\n return {\n ...rawSymbols,\n symbols: convertToDebugSymbols(rawSymbols.symbols),\n }\n }\n\n return rawSymbols\n}\n\nfunction convertToDebugSymbols>(symbols: T): T {\n // Initialize global state on first call\n if (!globalTraceSymbols) {\n globalTraceSymbols = {}\n }\n\n // Initialize global debug log path on first call\n if (env.OTUI_DEBUG_FFI && !globalFFILogPath) {\n const now = new Date()\n const timestamp = now.toISOString().replace(/[:.]/g, \"-\").replace(/T/, \"_\").split(\"Z\")[0]\n globalFFILogPath = `ffi_otui_debug_${timestamp}.log`\n }\n\n const debugSymbols: Record = {}\n let hasTracing = false\n\n Object.entries(symbols).forEach(([key, value]) => {\n debugSymbols[key] = value\n })\n\n if (env.OTUI_DEBUG_FFI && globalFFILogPath) {\n const logPath = globalFFILogPath\n const writeSync = (msg: string) => {\n writeFileSync(logPath, msg + \"\\n\", { flag: \"a\" })\n }\n\n Object.entries(symbols).forEach(([key, value]) => {\n if (typeof value === \"function\") {\n debugSymbols[key] = (...args: any[]) => {\n writeSync(`${key}(${args.map((arg) => String(arg)).join(\", \")})`)\n const result = value(...args)\n writeSync(`${key} returned: ${String(result)}`)\n return result\n }\n }\n })\n }\n\n if (env.OTUI_TRACE_FFI) {\n hasTracing = true\n Object.entries(symbols).forEach(([key, value]) => {\n if (typeof value === \"function\") {\n // Initialize trace array for this symbol if not exists\n if (!globalTraceSymbols![key]) {\n globalTraceSymbols![key] = []\n }\n\n const originalFunc = debugSymbols[key]\n debugSymbols[key] = (...args: any[]) => {\n const start = performance.now()\n const result = originalFunc(...args)\n const end = performance.now()\n globalTraceSymbols![key].push(end - start)\n return result\n }\n }\n })\n }\n\n // Register exit handler only once\n if ((env.OTUI_DEBUG_FFI || env.OTUI_TRACE_FFI) && !exitHandlerRegistered) {\n exitHandlerRegistered = true\n\n process.on(\"exit\", () => {\n if (globalTraceSymbols) {\n const allStats: Array<{\n name: string\n count: number\n total: number\n average: number\n min: number\n max: number\n median: number\n p90: number\n p99: number\n }> = []\n\n for (const [key, timings] of Object.entries(globalTraceSymbols)) {\n if (!Array.isArray(timings) || timings.length === 0) {\n continue\n }\n\n const sortedTimings = [...timings].sort((a, b) => a - b)\n const count = sortedTimings.length\n\n const total = sortedTimings.reduce((acc, t) => acc + t, 0)\n const average = total / count\n const min = sortedTimings[0]\n const max = sortedTimings[count - 1]\n\n const medianIndex = Math.floor(count / 2)\n const p90Index = Math.floor(count * 0.9)\n const p99Index = Math.floor(count * 0.99)\n\n const median = sortedTimings[medianIndex]\n const p90 = sortedTimings[Math.min(p90Index, count - 1)]\n const p99 = sortedTimings[Math.min(p99Index, count - 1)]\n\n allStats.push({\n name: key,\n count,\n total,\n average,\n min,\n max,\n median,\n p90,\n p99,\n })\n }\n\n allStats.sort((a, b) => b.total - a.total)\n\n const lines: string[] = []\n lines.push(\"\\n--- OpenTUI FFI Call Performance ---\")\n lines.push(\"Sorted by total time spent (descending)\")\n lines.push(\n \"-------------------------------------------------------------------------------------------------------------------------\",\n )\n\n if (allStats.length === 0) {\n lines.push(\"No trace data collected or all symbols had zero calls.\")\n } else {\n const nameHeader = \"Symbol\"\n const callsHeader = \"Calls\"\n const totalHeader = \"Total (ms)\"\n const avgHeader = \"Avg (ms)\"\n const minHeader = \"Min (ms)\"\n const maxHeader = \"Max (ms)\"\n const medHeader = \"Med (ms)\"\n const p90Header = \"P90 (ms)\"\n const p99Header = \"P99 (ms)\"\n\n const nameWidth = Math.max(nameHeader.length, ...allStats.map((s) => s.name.length))\n const countWidth = Math.max(callsHeader.length, ...allStats.map((s) => String(s.count).length))\n const totalWidth = Math.max(totalHeader.length, ...allStats.map((s) => s.total.toFixed(2).length))\n const avgWidth = Math.max(avgHeader.length, ...allStats.map((s) => s.average.toFixed(2).length))\n const statWidthMin = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length))\n const statWidthMax = Math.max(maxHeader.length, ...allStats.map((s) => s.max.toFixed(2).length))\n const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length))\n const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length))\n const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length))\n\n lines.push(\n `${nameHeader.padEnd(nameWidth)} | ` +\n `${callsHeader.padStart(countWidth)} | ` +\n `${totalHeader.padStart(totalWidth)} | ` +\n `${avgHeader.padStart(avgWidth)} | ` +\n `${minHeader.padStart(statWidthMin)} | ` +\n `${maxHeader.padStart(statWidthMax)} | ` +\n `${medHeader.padStart(medianWidth)} | ` +\n `${p90Header.padStart(p90Width)} | ` +\n `${p99Header.padStart(p99Width)}`,\n )\n lines.push(\n `${\"-\".repeat(nameWidth)}-+-${\"-\".repeat(countWidth)}-+-${\"-\".repeat(totalWidth)}-+-${\"-\".repeat(avgWidth)}-+-${\"-\".repeat(statWidthMin)}-+-${\"-\".repeat(statWidthMax)}-+-${\"-\".repeat(medianWidth)}-+-${\"-\".repeat(p90Width)}-+-${\"-\".repeat(p99Width)}`,\n )\n\n allStats.forEach((stat) => {\n lines.push(\n `${stat.name.padEnd(nameWidth)} | ` +\n `${String(stat.count).padStart(countWidth)} | ` +\n `${stat.total.toFixed(2).padStart(totalWidth)} | ` +\n `${stat.average.toFixed(2).padStart(avgWidth)} | ` +\n `${stat.min.toFixed(2).padStart(statWidthMin)} | ` +\n `${stat.max.toFixed(2).padStart(statWidthMax)} | ` +\n `${stat.median.toFixed(2).padStart(medianWidth)} | ` +\n `${stat.p90.toFixed(2).padStart(p90Width)} | ` +\n `${stat.p99.toFixed(2).padStart(p99Width)}`,\n )\n })\n }\n lines.push(\n \"-------------------------------------------------------------------------------------------------------------------------\",\n )\n\n const output = lines.join(\"\\n\")\n console.log(output)\n\n try {\n const now = new Date()\n const timestamp = now.toISOString().replace(/[:.]/g, \"-\").replace(/T/, \"_\").split(\"Z\")[0]\n const traceFilePath = `ffi_otui_trace_${timestamp}.log`\n void writeFile(traceFilePath, output).catch((error) => {\n console.error(\"Failed to write FFI trace file:\", error)\n })\n } catch (e) {\n console.error(\"Failed to write FFI trace file:\", e)\n }\n }\n })\n }\n\n return debugSymbols as T\n}\n\n// Log levels matching Zig's LogLevel enum\nexport enum LogLevel {\n Error = 0,\n Warn = 1,\n Info = 2,\n Debug = 3,\n}\n\n/**\n * VisualCursor represents a cursor position with both visual and logical coordinates.\n * Visual coordinates (visualRow, visualCol) are VIEWPORT-RELATIVE.\n * This means visualRow=0 is the first visible line in the viewport, not the first line in the document.\n * Logical coordinates (logicalRow, logicalCol) are document-absolute.\n */\nexport interface VisualCursor {\n visualRow: number // Viewport-relative row (0 = top of viewport)\n visualCol: number // Viewport-relative column (0 = left edge of viewport when not wrapping)\n logicalRow: number // Document-absolute row\n logicalCol: number // Document-absolute column\n offset: number // Global display-width offset from buffer start\n}\n\nexport interface LogicalCursor {\n row: number\n col: number\n offset: number\n}\n\nexport interface CursorState {\n x: number\n y: number\n visible: boolean\n style: CursorStyle\n blinking: boolean\n color: RGBA\n}\n\nexport type NativeSpanFeedEventHandler = (eventId: number, arg0: Pointer, arg1: number | bigint) => void\n\nexport type NativeBufferedOutput = \"stdout\" | \"memory\"\n\nexport interface NativeRendererCreateOptions {\n remote?: boolean\n feedPtr?: Pointer | null\n bufferedOutput?: NativeBufferedOutput\n}\n\nexport interface NativeRenderOperationResult {\n renderOffset: number\n status: number\n}\n\nexport interface NativeYogaLayout {\n left: number\n top: number\n right: number\n bottom: number\n width: number\n height: number\n}\n\nexport type NativeYogaMeasureCallback = (\n node: Pointer | null,\n width: number,\n widthMode: number,\n height: number,\n heightMode: number,\n) => void\n\nexport type NativeYogaDirtiedCallback = () => void\n\nexport interface AudioEngineLib {\n createAudioEngine: (options?: AudioCreateOptions | null) => AudioEngineHandle | null\n destroyAudioEngine: (engine: AudioEngineHandle) => void\n audioRefreshPlaybackDevices: (engine: AudioEngineHandle) => number\n audioGetPlaybackDeviceCount: (engine: AudioEngineHandle) => number\n audioGetPlaybackDeviceName: (engine: AudioEngineHandle, index: number) => string\n audioIsPlaybackDeviceDefault: (engine: AudioEngineHandle, index: number) => boolean\n audioSelectPlaybackDevice: (engine: AudioEngineHandle, index: number) => number\n audioClearPlaybackDeviceSelection: (engine: AudioEngineHandle) => void\n audioStart: (engine: AudioEngineHandle, options?: AudioStartOptions | null) => number\n audioStartMixer: (engine: AudioEngineHandle) => number\n audioStop: (engine: AudioEngineHandle) => number\n audioLoad: (engine: AudioEngineHandle, data: Uint8Array) => { status: number; soundId: number | null }\n audioUnload: (engine: AudioEngineHandle, soundId: number) => number\n audioPlay: (\n engine: AudioEngineHandle,\n soundId: number,\n options?: AudioVoiceOptions,\n ) => { status: number; voiceId: number | null }\n audioStopVoice: (engine: AudioEngineHandle, voiceId: number) => number\n audioSetVoiceGroup: (engine: AudioEngineHandle, voiceId: number, groupId: number) => number\n audioCreateGroup: (engine: AudioEngineHandle, name: string) => { status: number; groupId: number | null }\n audioSetGroupVolume: (engine: AudioEngineHandle, groupId: number, volume: number) => number\n audioSetMasterVolume: (engine: AudioEngineHandle, volume: number) => number\n audioMixToBuffer: (engine: AudioEngineHandle, outBuffer: Float32Array, frameCount: number, channels: number) => number\n audioEnableTap: (engine: AudioEngineHandle, enabled: boolean, capacityFrames: number) => number\n audioReadTap: (\n engine: AudioEngineHandle,\n outBuffer: Float32Array,\n frameCount: number,\n channels: number,\n ) => { status: number; framesRead: number }\n audioGetStats: (engine: AudioEngineHandle) => AudioStats | null\n}\n\nexport interface RenderLib extends AudioEngineLib {\n createRenderer: (width: number, height: number, options?: NativeRendererCreateOptions) => RendererHandle | null\n setTerminalEnvVar: (renderer: RendererHandle, key: string, value: string) => boolean\n destroyRenderer: (renderer: RendererHandle) => void\n setUseThread: (renderer: RendererHandle, useThread: boolean) => void\n setClearOnShutdown: (renderer: RendererHandle, clear: boolean) => void\n setBackgroundColor: (renderer: RendererHandle, color: RGBA) => void\n setRenderOffset: (renderer: RendererHandle, offset: number) => void\n resetSplitScrollback: (renderer: RendererHandle, seedRows: number, pinnedRenderOffset: number) => number\n syncSplitScrollback: (renderer: RendererHandle, pinnedRenderOffset: number) => number\n getSplitOutputOffset: (renderer: RendererHandle, surfaceOffset: number) => number\n setPendingSplitFooterTransition: (\n renderer: RendererHandle,\n mode: number,\n sourceTopLine: number,\n sourceHeight: number,\n targetTopLine: number,\n targetHeight: number,\n scrollLines: number,\n ) => void\n clearPendingSplitFooterTransition: (renderer: RendererHandle) => void\n updateStats: (renderer: RendererHandle, time: number, fps: number, frameCallbackTime: number) => void\n updateMemoryStats: (renderer: RendererHandle, heapUsed: number, heapTotal: number, arrayBuffers: number) => void\n getRenderStats: (renderer: RendererHandle) => NativeRenderStats\n render: (renderer: RendererHandle, force: boolean) => number\n repaintSplitFooter: (\n renderer: RendererHandle,\n pinnedRenderOffset: number,\n force: boolean,\n ) => NativeRenderOperationResult\n commitSplitFooterSnapshot: (\n renderer: RendererHandle,\n snapshot: OptimizedBuffer,\n rowColumns: number,\n startOnNewLine: boolean,\n trailingNewline: boolean,\n pinnedRenderOffset: number,\n force: boolean,\n // beginFrame/finalizeFrame mark commit boundaries when one JS flush contains\n // multiple stdout snapshots. Defaults preserve old one-call behavior.\n beginFrame?: boolean,\n finalizeFrame?: boolean,\n ) => NativeRenderOperationResult\n getNextBuffer: (renderer: RendererHandle) => OptimizedBuffer\n getCurrentBuffer: (renderer: RendererHandle) => OptimizedBuffer\n rendererSetPaletteState: (\n renderer: RendererHandle,\n palette: readonly RGBA[],\n defaultForeground: RGBA,\n defaultBackground: RGBA,\n paletteEpoch: number,\n ) => void\n createOptimizedBuffer: (\n width: number,\n height: number,\n widthMethod: WidthMethod,\n respectAlpha?: boolean,\n id?: string,\n ) => OptimizedBuffer\n destroyOptimizedBuffer: (bufferPtr: OptimizedBufferHandle) => void\n drawFrameBuffer: (\n targetBufferPtr: OptimizedBufferHandle,\n destX: number,\n destY: number,\n bufferPtr: OptimizedBufferHandle,\n sourceX?: number,\n sourceY?: number,\n sourceWidth?: number,\n sourceHeight?: number,\n ) => void\n getBufferWidth: (buffer: OptimizedBufferHandle) => number\n getBufferHeight: (buffer: OptimizedBufferHandle) => number\n bufferClear: (buffer: OptimizedBufferHandle, color: RGBA) => void\n bufferGetCharPtr: (buffer: OptimizedBufferHandle) => Pointer\n bufferGetFgPtr: (buffer: OptimizedBufferHandle) => Pointer\n bufferGetBgPtr: (buffer: OptimizedBufferHandle) => Pointer\n bufferGetAttributesPtr: (buffer: OptimizedBufferHandle) => Pointer\n bufferGetRespectAlpha: (buffer: OptimizedBufferHandle) => boolean\n bufferSetRespectAlpha: (buffer: OptimizedBufferHandle, respectAlpha: boolean) => void\n bufferGetId: (buffer: OptimizedBufferHandle) => string\n bufferGetRealCharSize: (buffer: OptimizedBufferHandle) => number\n bufferWriteResolvedChars: (buffer: OptimizedBufferHandle, outputBuffer: Uint8Array, addLineBreaks: boolean) => number\n bufferDrawText: (\n buffer: OptimizedBufferHandle,\n text: string,\n x: number,\n y: number,\n color: RGBA,\n bgColor?: RGBA,\n attributes?: number,\n ) => void\n bufferSetCellWithAlphaBlending: (\n buffer: OptimizedBufferHandle,\n x: number,\n y: number,\n char: string,\n color: RGBA,\n bgColor: RGBA,\n attributes?: number,\n ) => void\n bufferSetCell: (\n buffer: OptimizedBufferHandle,\n x: number,\n y: number,\n char: string,\n color: RGBA,\n bgColor: RGBA,\n attributes?: number,\n ) => void\n bufferFillRect: (\n buffer: OptimizedBufferHandle,\n x: number,\n y: number,\n width: number,\n height: number,\n color: RGBA,\n ) => void\n bufferColorMatrix: (\n buffer: OptimizedBufferHandle,\n matrixPtr: Pointer,\n cellMaskPtr: Pointer,\n cellMaskCount: number,\n strength: number,\n target: TargetChannel,\n ) => void\n bufferColorMatrixUniform: (\n buffer: OptimizedBufferHandle,\n matrixPtr: Pointer,\n strength: number,\n target: TargetChannel,\n ) => void\n bufferDrawSuperSampleBuffer: (\n buffer: OptimizedBufferHandle,\n x: number,\n y: number,\n pixelDataPtr: Pointer,\n pixelDataLength: number,\n format: \"bgra8unorm\" | \"rgba8unorm\",\n alignedBytesPerRow: number,\n ) => void\n bufferDrawPackedBuffer: (\n buffer: OptimizedBufferHandle,\n dataPtr: Pointer,\n dataLen: number,\n posX: number,\n posY: number,\n terminalWidthCells: number,\n terminalHeightCells: number,\n ) => void\n bufferDrawGrayscaleBuffer: (\n buffer: OptimizedBufferHandle,\n posX: number,\n posY: number,\n intensitiesPtr: Pointer,\n srcWidth: number,\n srcHeight: number,\n fg: RGBA | null,\n bg: RGBA | null,\n ) => void\n bufferDrawGrayscaleBufferSupersampled: (\n buffer: OptimizedBufferHandle,\n posX: number,\n posY: number,\n intensitiesPtr: Pointer,\n srcWidth: number,\n srcHeight: number,\n fg: RGBA | null,\n bg: RGBA | null,\n ) => void\n bufferDrawGrid: (\n buffer: OptimizedBufferHandle,\n borderChars: Uint32Array,\n borderFg: RGBA,\n borderBg: RGBA,\n columnOffsets: Int32Array,\n columnCount: number,\n rowOffsets: Int32Array,\n rowCount: number,\n options: { drawInner: boolean; drawOuter: boolean },\n ) => void\n bufferDrawBox: (\n buffer: OptimizedBufferHandle,\n x: number,\n y: number,\n width: number,\n height: number,\n borderChars: Uint32Array,\n packedOptions: number,\n borderColor: RGBA,\n backgroundColor: RGBA,\n titleColor: RGBA,\n title: string | null,\n bottomTitle: string | null,\n ) => void\n bufferResize: (buffer: OptimizedBufferHandle, width: number, height: number) => void\n resizeRenderer: (renderer: RendererHandle, width: number, height: number) => void\n setCursorPosition: (renderer: RendererHandle, x: number, y: number, visible: boolean) => void\n setCursorColor: (renderer: RendererHandle, color: RGBA) => void\n getCursorState: (renderer: RendererHandle) => CursorState\n setCursorStyleOptions: (renderer: RendererHandle, options: CursorStyleOptions) => void\n setDebugOverlay: (renderer: RendererHandle, enabled: boolean, corner: DebugOverlayCorner) => void\n clearTerminal: (renderer: RendererHandle) => void\n setTerminalTitle: (renderer: RendererHandle, title: string) => void\n copyToClipboardOSC52: (renderer: RendererHandle, target: number, payload: Uint8Array) => boolean\n clearClipboardOSC52: (renderer: RendererHandle, target: number) => boolean\n triggerNotification: (renderer: RendererHandle, message: string, title?: string) => boolean\n addToHitGrid: (renderer: RendererHandle, x: number, y: number, width: number, height: number, id: number) => void\n clearCurrentHitGrid: (renderer: RendererHandle) => void\n hitGridPushScissorRect: (renderer: RendererHandle, x: number, y: number, width: number, height: number) => void\n hitGridPopScissorRect: (renderer: RendererHandle) => void\n hitGridClearScissorRects: (renderer: RendererHandle) => void\n addToCurrentHitGridClipped: (\n renderer: RendererHandle,\n x: number,\n y: number,\n width: number,\n height: number,\n id: number,\n ) => void\n checkHit: (renderer: RendererHandle, x: number, y: number) => number\n getHitGridDirty: (renderer: RendererHandle) => boolean\n dumpHitGrid: (renderer: RendererHandle) => void\n dumpBuffers: (renderer: RendererHandle, timestamp?: number) => void\n dumpOutputBuffer: (renderer: RendererHandle, timestamp?: number) => void\n restoreTerminalModes: (renderer: RendererHandle) => void\n enableMouse: (renderer: RendererHandle, enableMovement: boolean) => void\n disableMouse: (renderer: RendererHandle) => void\n enableKittyKeyboard: (renderer: RendererHandle, flags: number) => void\n disableKittyKeyboard: (renderer: RendererHandle) => void\n setKittyKeyboardFlags: (renderer: RendererHandle, flags: number) => void\n getKittyKeyboardFlags: (renderer: RendererHandle) => number\n setupTerminal: (renderer: RendererHandle, useAlternateScreen: boolean) => void\n suspendRenderer: (renderer: RendererHandle) => void\n resumeRenderer: (renderer: RendererHandle) => void\n queryPixelResolution: (renderer: RendererHandle) => void\n queryThemeColors: (renderer: RendererHandle) => void\n writeOut: (renderer: RendererHandle, data: string | Uint8Array) => void\n\n // Yoga layout methods\n yogaConfigCreate: () => Pointer\n yogaConfigFree: (config: Pointer) => void\n yogaConfigSetUseWebDefaults: (config: Pointer, enabled: boolean) => void\n yogaConfigGetUseWebDefaults: (config: Pointer) => boolean\n yogaConfigSetPointScaleFactor: (config: Pointer, pointScaleFactor: number) => void\n yogaConfigGetPointScaleFactor: (config: Pointer) => number\n yogaConfigSetErrata: (config: Pointer, errata: number) => void\n yogaConfigGetErrata: (config: Pointer) => number\n yogaConfigSetExperimentalFeatureEnabled: (config: Pointer, feature: number, enabled: boolean) => void\n yogaConfigIsExperimentalFeatureEnabled: (config: Pointer, feature: number) => boolean\n yogaNodeCreate: () => Pointer\n yogaNodeCreateForOpenTUI: () => Pointer\n yogaNodeCreateWithConfig: (config: Pointer) => Pointer\n yogaNodeFree: (node: Pointer) => void\n yogaNodeFreeRecursive: (node: Pointer) => void\n yogaNodeReset: (node: Pointer) => void\n yogaNodeCopyStyle: (dstNode: Pointer, srcNode: Pointer) => void\n yogaNodeInsertChild: (node: Pointer, child: Pointer, index: number) => void\n yogaNodeRemoveChild: (node: Pointer, child: Pointer) => void\n yogaNodeRemoveAllChildren: (node: Pointer) => void\n yogaNodeGetChild: (node: Pointer, index: number) => Pointer | null\n yogaNodeGetChildCount: (node: Pointer) => number\n yogaNodeGetParent: (node: Pointer) => Pointer | null\n yogaNodeCalculateLayout: (node: Pointer, width: number, height: number, direction: number) => void\n yogaNodeIsDirty: (node: Pointer) => boolean\n yogaNodeMarkDirty: (node: Pointer) => void\n yogaNodeGetHasNewLayout: (node: Pointer) => boolean\n yogaNodeSetHasNewLayout: (node: Pointer, hasNewLayout: boolean) => void\n yogaNodeSetIsReferenceBaseline: (node: Pointer, isReferenceBaseline: boolean) => void\n yogaNodeIsReferenceBaseline: (node: Pointer) => boolean\n yogaNodeSetAlwaysFormsContainingBlock: (node: Pointer, alwaysFormsContainingBlock: boolean) => void\n yogaNodeGetAlwaysFormsContainingBlock: (node: Pointer) => boolean\n yogaNodeGetComputedLayout: (node: Pointer) => NativeYogaLayout\n yogaNodeLayoutGetEdge: (node: Pointer, kind: number, edge: number) => number\n yogaNodeStyleSetEnum: (node: Pointer, kind: number, value: number) => void\n yogaNodeStyleGetEnum: (node: Pointer, kind: number) => number\n yogaNodeStyleSetFloat: (node: Pointer, kind: number, value: number) => void\n yogaNodeStyleGetFloat: (node: Pointer, kind: number) => number\n yogaNodeStyleSetBorder: (node: Pointer, edge: number, border: number) => void\n yogaNodeStyleGetBorder: (node: Pointer, edge: number) => number\n yogaNodeStyleSetValue: (node: Pointer, kind: number, edgeOrGutter: number, unit: number, value: number) => void\n yogaNodeStyleGetValue: (node: Pointer, kind: number, edgeOrGutter: number) => number | bigint\n yogaNodeSetMeasureFunc: (node: Pointer, callback: Pointer | null) => void\n yogaNodeUnsetMeasureFunc: (node: Pointer) => void\n yogaNodeHasMeasureFunc: (node: Pointer) => boolean\n yogaNodeSetDirtiedFunc: (node: Pointer, callback: Pointer | null) => void\n yogaNodeUnsetDirtiedFunc: (node: Pointer) => void\n yogaStoreMeasureResult: (width: number, height: number) => void\n createYogaMeasureCallback: (callback: NativeYogaMeasureCallback) => FFICallbackInstance\n createYogaDirtiedCallback: (callback: NativeYogaDirtiedCallback) => FFICallbackInstance\n\n // TextBuffer methods\n createTextBuffer: (widthMethod: WidthMethod) => TextBuffer\n destroyTextBuffer: (buffer: TextBufferHandle) => void\n textBufferGetLength: (buffer: TextBufferHandle) => number\n textBufferGetByteSize: (buffer: TextBufferHandle) => number\n\n textBufferReset: (buffer: TextBufferHandle) => void\n textBufferClear: (buffer: TextBufferHandle) => void\n textBufferRegisterMemBuffer: (buffer: TextBufferHandle, bytes: Uint8Array, owned?: boolean) => number\n textBufferReplaceMemBuffer: (buffer: TextBufferHandle, memId: number, bytes: Uint8Array, owned?: boolean) => boolean\n textBufferClearMemRegistry: (buffer: TextBufferHandle) => void\n textBufferSetTextFromMem: (buffer: TextBufferHandle, memId: number) => void\n textBufferAppend: (buffer: TextBufferHandle, bytes: Uint8Array) => void\n textBufferAppendFromMemId: (buffer: TextBufferHandle, memId: number) => void\n textBufferLoadFile: (buffer: TextBufferHandle, path: string) => boolean\n textBufferSetStyledText: (\n buffer: TextBufferHandle,\n chunks: Array<{ text: string; fg?: RGBA | null; bg?: RGBA | null; attributes?: number; link?: { url: string } }>,\n ) => void\n textBufferSetDefaultFg: (buffer: TextBufferHandle, fg: RGBA | null) => void\n textBufferSetDefaultBg: (buffer: TextBufferHandle, bg: RGBA | null) => void\n textBufferSetDefaultAttributes: (buffer: TextBufferHandle, attributes: number | null) => void\n textBufferResetDefaults: (buffer: TextBufferHandle) => void\n textBufferGetTabWidth: (buffer: TextBufferHandle) => number\n textBufferSetTabWidth: (buffer: TextBufferHandle, width: number) => void\n textBufferGetLineCount: (buffer: TextBufferHandle) => number\n getPlainTextBytes: (buffer: TextBufferHandle, maxLength: number) => Uint8Array | null\n textBufferGetTextRange: (\n buffer: TextBufferHandle,\n startOffset: number,\n endOffset: number,\n maxLength: number,\n ) => Uint8Array | null\n textBufferGetTextRangeByCoords: (\n buffer: TextBufferHandle,\n startRow: number,\n startCol: number,\n endRow: number,\n endCol: number,\n maxLength: number,\n ) => Uint8Array | null\n\n // TextBufferView methods\n createTextBufferView: (textBuffer: TextBufferHandle) => TextBufferViewHandle\n destroyTextBufferView: (view: TextBufferViewHandle) => void\n textBufferViewSetSelection: (\n view: TextBufferViewHandle,\n start: number,\n end: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ) => void\n textBufferViewResetSelection: (view: TextBufferViewHandle) => void\n textBufferViewGetSelection: (view: TextBufferViewHandle) => { start: number; end: number } | null\n textBufferViewSetLocalSelection: (\n view: TextBufferViewHandle,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ) => boolean\n textBufferViewUpdateSelection: (\n view: TextBufferViewHandle,\n end: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ) => void\n textBufferViewUpdateLocalSelection: (\n view: TextBufferViewHandle,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ) => boolean\n textBufferViewResetLocalSelection: (view: TextBufferViewHandle) => void\n textBufferViewSetWrapWidth: (view: TextBufferViewHandle, width: number) => void\n textBufferViewSetWrapMode: (view: TextBufferViewHandle, mode: \"none\" | \"char\" | \"word\") => void\n textBufferViewSetFirstLineOffset: (view: TextBufferViewHandle, offset: number) => void\n textBufferViewSetViewportSize: (view: TextBufferViewHandle, width: number, height: number) => void\n textBufferViewSetViewport: (view: TextBufferViewHandle, x: number, y: number, width: number, height: number) => void\n textBufferViewGetLineInfo: (view: TextBufferViewHandle) => LineInfo\n textBufferViewGetLogicalLineInfo: (view: TextBufferViewHandle) => LineInfo\n textBufferViewGetSelectedTextBytes: (view: TextBufferViewHandle, maxLength: number) => Uint8Array | null\n textBufferViewGetPlainTextBytes: (view: TextBufferViewHandle, maxLength: number) => Uint8Array | null\n textBufferViewSetTabIndicator: (view: TextBufferViewHandle, indicator: number) => void\n textBufferViewSetTabIndicatorColor: (view: TextBufferViewHandle, color: RGBA) => void\n textBufferViewSetTruncate: (view: TextBufferViewHandle, truncate: boolean) => void\n textBufferViewMeasureForDimensions: (\n view: TextBufferViewHandle,\n width: number,\n height: number,\n ) => { lineCount: number; widthColsMax: number } | null\n textBufferViewGetVirtualLineCount: (view: TextBufferViewHandle) => number\n\n readonly encoder: TextEncoder\n readonly decoder: TextDecoder\n bufferDrawTextBufferView: (buffer: OptimizedBufferHandle, view: TextBufferViewHandle, x: number, y: number) => void\n bufferDrawEditorView: (buffer: OptimizedBufferHandle, view: EditorViewHandle, x: number, y: number) => void\n\n // EditBuffer methods\n createEditBuffer: (widthMethod: WidthMethod) => EditBufferHandle\n destroyEditBuffer: (buffer: EditBufferHandle) => void\n editBufferSetText: (buffer: EditBufferHandle, textBytes: Uint8Array) => void\n editBufferSetTextFromMem: (buffer: EditBufferHandle, memId: number) => void\n editBufferReplaceText: (buffer: EditBufferHandle, textBytes: Uint8Array) => void\n editBufferReplaceTextFromMem: (buffer: EditBufferHandle, memId: number) => void\n editBufferGetText: (buffer: EditBufferHandle, maxLength: number) => Uint8Array | null\n editBufferInsertChar: (buffer: EditBufferHandle, char: string) => void\n editBufferInsertText: (buffer: EditBufferHandle, text: string) => void\n editBufferDeleteChar: (buffer: EditBufferHandle) => void\n editBufferDeleteCharBackward: (buffer: EditBufferHandle) => void\n editBufferDeleteRange: (\n buffer: EditBufferHandle,\n startLine: number,\n startCol: number,\n endLine: number,\n endCol: number,\n ) => void\n editBufferNewLine: (buffer: EditBufferHandle) => void\n editBufferDeleteLine: (buffer: EditBufferHandle) => void\n editBufferMoveCursorLeft: (buffer: EditBufferHandle) => void\n editBufferMoveCursorRight: (buffer: EditBufferHandle) => void\n editBufferMoveCursorUp: (buffer: EditBufferHandle) => void\n editBufferMoveCursorDown: (buffer: EditBufferHandle) => void\n editBufferGotoLine: (buffer: EditBufferHandle, line: number) => void\n editBufferSetCursor: (buffer: EditBufferHandle, line: number, col: number) => void\n editBufferSetCursorToLineCol: (buffer: EditBufferHandle, line: number, col: number) => void\n editBufferSetCursorByOffset: (buffer: EditBufferHandle, offset: number) => void\n editBufferGetCursorPosition: (buffer: EditBufferHandle) => LogicalCursor\n editBufferGetId: (buffer: EditBufferHandle) => number\n editBufferGetTextBuffer: (buffer: EditBufferHandle) => TextBufferHandle\n editBufferDebugLogRope: (buffer: EditBufferHandle) => void\n editBufferUndo: (buffer: EditBufferHandle, maxLength: number) => Uint8Array | null\n editBufferRedo: (buffer: EditBufferHandle, maxLength: number) => Uint8Array | null\n editBufferCanUndo: (buffer: EditBufferHandle) => boolean\n editBufferCanRedo: (buffer: EditBufferHandle) => boolean\n editBufferClearHistory: (buffer: EditBufferHandle) => void\n editBufferClear: (buffer: EditBufferHandle) => void\n editBufferGetNextWordBoundary: (buffer: EditBufferHandle) => { row: number; col: number; offset: number }\n editBufferGetPrevWordBoundary: (buffer: EditBufferHandle) => { row: number; col: number; offset: number }\n editBufferGetEOL: (buffer: EditBufferHandle) => { row: number; col: number; offset: number }\n editBufferOffsetToPosition: (\n buffer: EditBufferHandle,\n offset: number,\n ) => { row: number; col: number; offset: number } | null\n editBufferPositionToOffset: (buffer: EditBufferHandle, row: number, col: number) => number\n editBufferGetLineStartOffset: (buffer: EditBufferHandle, row: number) => number\n editBufferGetTextRange: (\n buffer: EditBufferHandle,\n startOffset: number,\n endOffset: number,\n maxLength: number,\n ) => Uint8Array | null\n editBufferGetTextRangeByCoords: (\n buffer: EditBufferHandle,\n startRow: number,\n startCol: number,\n endRow: number,\n endCol: number,\n maxLength: number,\n ) => Uint8Array | null\n\n // EditorView methods\n createEditorView: (editBufferPtr: EditBufferHandle, viewportWidth: number, viewportHeight: number) => EditorViewHandle\n destroyEditorView: (view: EditorViewHandle) => void\n editorViewSetViewportSize: (view: EditorViewHandle, width: number, height: number) => void\n editorViewSetViewport: (\n view: EditorViewHandle,\n x: number,\n y: number,\n width: number,\n height: number,\n moveCursor: boolean,\n ) => void\n editorViewGetViewport: (view: EditorViewHandle) => { offsetY: number; offsetX: number; height: number; width: number }\n editorViewSetScrollMargin: (view: EditorViewHandle, margin: number) => void\n editorViewSetWrapMode: (view: EditorViewHandle, mode: \"none\" | \"char\" | \"word\") => void\n editorViewGetVirtualLineCount: (view: EditorViewHandle) => number\n editorViewGetTotalVirtualLineCount: (view: EditorViewHandle) => number\n editorViewGetTextBufferView: (view: EditorViewHandle) => TextBufferViewHandle\n editorViewSetSelection: (\n view: EditorViewHandle,\n start: number,\n end: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ) => void\n editorViewResetSelection: (view: EditorViewHandle) => void\n editorViewGetSelection: (view: EditorViewHandle) => { start: number; end: number } | null\n editorViewSetLocalSelection: (\n view: EditorViewHandle,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n updateCursor: boolean,\n followCursor: boolean,\n ) => boolean\n\n editorViewUpdateSelection: (view: EditorViewHandle, end: number, bgColor: RGBA | null, fgColor: RGBA | null) => void\n editorViewUpdateLocalSelection: (\n view: EditorViewHandle,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n updateCursor: boolean,\n followCursor: boolean,\n ) => boolean\n\n editorViewResetLocalSelection: (view: EditorViewHandle) => void\n editorViewGetSelectedTextBytes: (view: EditorViewHandle, maxLength: number) => Uint8Array | null\n editorViewGetCursor: (view: EditorViewHandle) => { row: number; col: number }\n editorViewGetText: (view: EditorViewHandle, maxLength: number) => Uint8Array | null\n editorViewGetVisualCursor: (view: EditorViewHandle) => VisualCursor\n editorViewMoveUpVisual: (view: EditorViewHandle) => void\n editorViewMoveDownVisual: (view: EditorViewHandle) => void\n editorViewDeleteSelectedText: (view: EditorViewHandle) => void\n editorViewSetCursorByOffset: (view: EditorViewHandle, offset: number) => void\n editorViewGetNextWordBoundary: (view: EditorViewHandle) => VisualCursor\n editorViewGetPrevWordBoundary: (view: EditorViewHandle) => VisualCursor\n editorViewGetEOL: (view: EditorViewHandle) => VisualCursor\n editorViewGetVisualSOL: (view: EditorViewHandle) => VisualCursor\n editorViewGetVisualEOL: (view: EditorViewHandle) => VisualCursor\n editorViewGetLineInfo: (view: EditorViewHandle) => LineInfo\n editorViewGetLogicalLineInfo: (view: EditorViewHandle) => LineInfo\n editorViewSetPlaceholderStyledText: (\n view: EditorViewHandle,\n chunks: Array<{ text: string; fg?: RGBA | null; bg?: RGBA | null; attributes?: number }>,\n ) => void\n editorViewSetTabIndicator: (view: EditorViewHandle, indicator: number) => void\n editorViewSetTabIndicatorColor: (view: EditorViewHandle, color: RGBA) => void\n\n bufferPushScissorRect: (buffer: OptimizedBufferHandle, x: number, y: number, width: number, height: number) => void\n bufferPopScissorRect: (buffer: OptimizedBufferHandle) => void\n bufferClearScissorRects: (buffer: OptimizedBufferHandle) => void\n bufferPushOpacity: (buffer: OptimizedBufferHandle, opacity: number) => void\n bufferPopOpacity: (buffer: OptimizedBufferHandle) => void\n bufferGetCurrentOpacity: (buffer: OptimizedBufferHandle) => number\n bufferClearOpacity: (buffer: OptimizedBufferHandle) => void\n textBufferAddHighlightByCharRange: (buffer: TextBufferHandle, highlight: Highlight) => void\n textBufferAddHighlight: (buffer: TextBufferHandle, lineIdx: number, highlight: Highlight) => void\n textBufferRemoveHighlightsByRef: (buffer: TextBufferHandle, hlRef: number) => void\n textBufferClearLineHighlights: (buffer: TextBufferHandle, lineIdx: number) => void\n textBufferClearAllHighlights: (buffer: TextBufferHandle) => void\n textBufferSetSyntaxStyle: (buffer: TextBufferHandle, style: SyntaxStyleHandle | null) => boolean\n textBufferGetLineHighlights: (buffer: TextBufferHandle, lineIdx: number) => Array\n textBufferGetHighlightCount: (buffer: TextBufferHandle) => number\n\n getArenaAllocatedBytes: () => number\n getBuildOptions: () => BuildOptions\n getAllocatorStats: () => AllocatorStats\n\n createSyntaxStyle: () => SyntaxStyleHandle\n destroySyntaxStyle: (style: SyntaxStyleHandle) => void\n syntaxStyleRegister: (\n style: SyntaxStyleHandle,\n name: string,\n fg: RGBA | null,\n bg: RGBA | null,\n attributes: number,\n ) => number\n syntaxStyleResolveByName: (style: SyntaxStyleHandle, name: string) => number | null\n syntaxStyleGetStyleCount: (style: SyntaxStyleHandle) => number\n\n getTerminalCapabilities: (renderer: RendererHandle) => TerminalCapabilities\n processCapabilityResponse: (renderer: RendererHandle, response: string) => void\n\n encodeUnicode: (\n text: string,\n widthMethod: WidthMethod,\n ) => { ptr: Pointer; data: Array<{ width: number; char: number }> } | null\n freeUnicode: (encoded: { ptr: Pointer; data: Array<{ width: number; char: number }> }) => void\n bufferDrawChar: (\n buffer: OptimizedBufferHandle,\n char: number,\n x: number,\n y: number,\n fg: RGBA,\n bg: RGBA,\n attributes?: number,\n ) => void\n\n registerNativeSpanFeedStream: (stream: Pointer, handler: NativeSpanFeedEventHandler) => void\n unregisterNativeSpanFeedStream: (stream: Pointer) => void\n createNativeSpanFeed: (options?: NativeSpanFeedOptions | null) => Pointer\n attachNativeSpanFeed: (stream: Pointer) => number\n destroyNativeSpanFeed: (stream: Pointer) => void\n streamWrite: (stream: Pointer, data: Uint8Array | string) => number\n streamCommit: (stream: Pointer) => number\n streamDrainSpans: (stream: Pointer, outBuffer: Uint8Array, maxSpans: number) => number\n streamClose: (stream: Pointer) => number\n streamSetOptions: (stream: Pointer, options: NativeSpanFeedOptions) => number\n streamGetStats: (stream: Pointer) => NativeSpanFeedStats | null\n streamReserve: (stream: Pointer, minLen: number) => { status: number; info: ReserveInfo | null }\n streamCommitReserved: (stream: Pointer, length: number) => number\n onNativeEvent: (name: string, handler: (data: ArrayBuffer) => void) => void\n onceNativeEvent: (name: string, handler: (data: ArrayBuffer) => void) => void\n offNativeEvent: (name: string, handler: (data: ArrayBuffer) => void) => void\n onAnyNativeEvent: (handler: (name: string, data: ArrayBuffer) => void) => void\n}\n\nclass FFIRenderLib implements RenderLib {\n private opentui: ReturnType\n public readonly encoder: TextEncoder = new TextEncoder()\n public readonly decoder: TextDecoder = new TextDecoder()\n private logCallbackWrapper: FFICallbackInstance | null = null\n private eventCallbackWrapper: FFICallbackInstance | null = null\n private eventSinkPtr: EventSinkHandle | null = null\n private _nativeEvents: EventEmitter = new EventEmitter()\n private _anyEventHandlers: Array<(name: string, data: ArrayBuffer) => void> = []\n private nativeSpanFeedCallbackWrapper: FFICallbackInstance | null = null\n private nativeSpanFeedHandlers = new Map()\n\n constructor(libPath?: string) {\n this.opentui = getOpenTUILib(libPath)\n try {\n this.setupLogging()\n this.setupEventBus()\n } catch (error) {\n this.dispose()\n throw error\n }\n }\n\n private setupLogging() {\n if (this.logCallbackWrapper) {\n return\n }\n\n const logCallback = this.opentui.createCallback(\n (level: number, msgPtr: Pointer, msgLen: number) => {\n try {\n if (msgLen === 0 || !msgPtr) {\n return\n }\n\n const msgBuffer = toArrayBuffer(msgPtr, 0, msgLen)\n const msgBytes = new Uint8Array(msgBuffer)\n const message = this.decoder.decode(msgBytes)\n\n switch (level) {\n case LogLevel.Error:\n console.error(message)\n break\n case LogLevel.Warn:\n console.warn(message)\n break\n case LogLevel.Info:\n console.info(message)\n break\n case LogLevel.Debug:\n console.debug(message)\n break\n default:\n console.log(message)\n }\n } catch (error) {\n console.error(\"Error in Zig log callback:\", error)\n }\n },\n {\n args: [\"u8\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n )\n\n this.logCallbackWrapper = logCallback\n\n if (!logCallback.ptr) {\n throw new Error(\"Failed to create log callback\")\n }\n\n this.setLogCallback(logCallback.ptr)\n }\n\n private setLogCallback(callbackPtr: Pointer | null) {\n this.opentui.symbols.setLogCallback(callbackPtr)\n }\n\n public dispose(): void {\n try {\n if (this.eventSinkPtr) {\n this.opentui.symbols.destroyEventSink(this.eventSinkPtr)\n this.eventSinkPtr = null\n }\n\n this.setLogCallback(null)\n } finally {\n try {\n this.opentui.close()\n } finally {\n this.eventCallbackWrapper = null\n this.logCallbackWrapper = null\n this.nativeSpanFeedCallbackWrapper = null\n this.nativeSpanFeedHandlers.clear()\n }\n }\n }\n\n private setupEventBus() {\n if (this.eventCallbackWrapper) {\n return\n }\n\n const eventCallback = this.opentui.createCallback(\n (namePtr: Pointer, nameLen: number, dataPtr: Pointer, dataLen: number) => {\n try {\n if (nameLen === 0 || !namePtr) {\n return\n }\n\n const eventName = this.decoder.decode(toArrayBuffer(namePtr, 0, nameLen))\n const eventData = dataLen > 0 && dataPtr ? toArrayBuffer(dataPtr, 0, dataLen).slice(0) : new ArrayBuffer(0)\n\n queueMicrotask(() => {\n this._nativeEvents.emit(eventName, eventData)\n\n for (const handler of this._anyEventHandlers) {\n handler(eventName, eventData)\n }\n })\n } catch (error) {\n console.error(\"Error in native event callback:\", error)\n }\n },\n {\n args: [\"ptr\", \"u32\", \"ptr\", \"u32\"],\n returns: \"void\",\n },\n )\n\n this.eventCallbackWrapper = eventCallback\n\n if (!eventCallback.ptr) {\n throw new Error(\"Failed to create event callback\")\n }\n\n this.eventSinkPtr = this.opentui.symbols.createEventSink(eventCallback.ptr)\n if (!this.eventSinkPtr) {\n eventCallback.close()\n this.eventCallbackWrapper = null\n throw new Error(\"Failed to create native event sink\")\n }\n }\n\n private ensureNativeSpanFeedCallback(): FFICallbackInstance {\n if (this.nativeSpanFeedCallbackWrapper) {\n return this.nativeSpanFeedCallbackWrapper\n }\n\n const callback = this.opentui.createCallback(\n (streamPtr: Pointer, eventId: number, arg0: Pointer, arg1: number | bigint) => {\n const handler = this.nativeSpanFeedHandlers.get(streamPtr)\n if (handler) {\n handler(eventId, arg0, arg1)\n }\n },\n {\n args: [\"ptr\", \"u32\", \"ptr\", \"u64\"],\n returns: \"void\",\n },\n )\n\n this.nativeSpanFeedCallbackWrapper = callback\n\n if (!callback.ptr) {\n throw new Error(\"Failed to create native span feed callback\")\n }\n\n return callback\n }\n\n public createRenderer(width: number, height: number, options: NativeRendererCreateOptions = {}) {\n const bufferedOutputKind = options.bufferedOutput === \"memory\" ? 1 : 0\n const remoteMode = options.remote === undefined ? 0 : options.remote ? 2 : 1\n // `feedPtr` is an internal wiring detail: non-null selects the feed backend\n // used for custom Writable output. When null, `bufferedOutput` selects the\n // buffered stdout or memory backend.\n const feedPtr = options.feedPtr ?? null\n const renderer = this.opentui.symbols.createRenderer(\n width,\n height,\n bufferedOutputKind,\n remoteMode,\n feedPtr,\n ) as RendererHandle\n return renderer ? renderer : null\n }\n\n public setTerminalEnvVar(renderer: Pointer, key: string, value: string): boolean {\n const keyBytes = this.encoder.encode(key)\n const valueBytes = this.encoder.encode(value)\n return this.opentui.symbols.setTerminalEnvVar(\n renderer,\n ptrOrNull(keyBytes),\n keyBytes.byteLength,\n ptrOrNull(valueBytes),\n valueBytes.byteLength,\n )\n }\n\n public destroyRenderer(renderer: Pointer): void {\n this.opentui.symbols.destroyRenderer(renderer)\n }\n\n public setUseThread(renderer: Pointer, useThread: boolean) {\n this.opentui.symbols.setUseThread(renderer, ffiBool(useThread))\n }\n\n public setClearOnShutdown(renderer: Pointer, clear: boolean) {\n this.opentui.symbols.setClearOnShutdown(renderer, ffiBool(clear))\n }\n\n public setBackgroundColor(renderer: Pointer, color: RGBA) {\n this.opentui.symbols.setBackgroundColor(renderer, rgbaPtr(color))\n }\n\n public setRenderOffset(renderer: Pointer, offset: number) {\n this.opentui.symbols.setRenderOffset(renderer, offset)\n }\n\n public resetSplitScrollback(renderer: Pointer, seedRows: number, pinnedRenderOffset: number): number {\n return this.opentui.symbols.resetSplitScrollback(renderer, seedRows, pinnedRenderOffset)\n }\n\n public syncSplitScrollback(renderer: Pointer, pinnedRenderOffset: number): number {\n return this.opentui.symbols.syncSplitScrollback(renderer, pinnedRenderOffset)\n }\n\n public getSplitOutputOffset(renderer: Pointer, surfaceOffset: number): number {\n return this.opentui.symbols.getSplitOutputOffset(renderer, surfaceOffset)\n }\n\n public setPendingSplitFooterTransition(\n renderer: Pointer,\n mode: number,\n sourceTopLine: number,\n sourceHeight: number,\n targetTopLine: number,\n targetHeight: number,\n scrollLines: number,\n ): void {\n this.opentui.symbols.setPendingSplitFooterTransition(\n renderer,\n mode,\n sourceTopLine,\n sourceHeight,\n targetTopLine,\n targetHeight,\n scrollLines,\n )\n }\n\n public clearPendingSplitFooterTransition(renderer: Pointer): void {\n this.opentui.symbols.clearPendingSplitFooterTransition(renderer)\n }\n\n public updateStats(renderer: Pointer, time: number, fps: number, frameCallbackTime: number) {\n this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime)\n }\n\n public updateMemoryStats(renderer: Pointer, heapUsed: number, heapTotal: number, arrayBuffers: number) {\n this.opentui.symbols.updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers)\n }\n\n public getRenderStats(renderer: Pointer): NativeRenderStats {\n const statsBuffer = new ArrayBuffer(NativeRenderStatsStruct.size)\n this.opentui.symbols.getRenderStats(renderer, ptr(statsBuffer))\n const stats = NativeRenderStatsStruct.unpack(statsBuffer)\n\n return {\n nativeLastFrameTime: stats.lastFrameTime,\n nativeAverageFrameTime: stats.averageFrameTime,\n nativeFrameCount: toNumber(stats.frameCount),\n cellsUpdated: stats.cellsUpdated,\n averageCellsUpdated: stats.averageCellsUpdated,\n nativeRenderTime: stats.renderTimeValid ? stats.renderTime : undefined,\n nativeStdoutWriteTime: stats.stdoutWriteTimeValid ? stats.stdoutWriteTime : undefined,\n }\n }\n\n public getNextBuffer(renderer: Pointer): OptimizedBuffer {\n const bufferPtr = this.opentui.symbols.getNextBuffer(renderer)\n if (!bufferPtr) {\n throw new Error(\"Failed to get next buffer\")\n }\n\n const width = this.opentui.symbols.getBufferWidth(bufferPtr)\n const height = this.opentui.symbols.getBufferHeight(bufferPtr)\n\n return new OptimizedBuffer(this, bufferPtr, width, height, { id: \"next buffer\", widthMethod: \"unicode\" })\n }\n\n public getCurrentBuffer(renderer: Pointer): OptimizedBuffer {\n const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer)\n if (!bufferPtr) {\n throw new Error(\"Failed to get current buffer\")\n }\n\n const width = this.opentui.symbols.getBufferWidth(bufferPtr)\n const height = this.opentui.symbols.getBufferHeight(bufferPtr)\n\n return new OptimizedBuffer(this, bufferPtr, width, height, { id: \"current buffer\", widthMethod: \"unicode\" })\n }\n\n public rendererSetPaletteState(\n renderer: Pointer,\n palette: readonly RGBA[],\n defaultForeground: RGBA,\n defaultBackground: RGBA,\n paletteEpoch: number,\n ): void {\n const paletteBuffer = new Uint16Array(palette.length * 4)\n\n for (let index = 0; index < palette.length; index++) {\n paletteBuffer.set(palette[index].buffer, index * 4)\n }\n\n this.opentui.symbols.rendererSetPaletteState(\n renderer,\n ptr(paletteBuffer),\n palette.length,\n rgbaPtr(defaultForeground),\n rgbaPtr(defaultBackground),\n paletteEpoch >>> 0,\n )\n }\n\n public bufferGetCharPtr(buffer: Pointer): Pointer {\n const ptr = this.opentui.symbols.bufferGetCharPtr(buffer)\n if (!ptr) {\n throw new Error(\"Failed to get char pointer\")\n }\n return ptr\n }\n\n public bufferGetFgPtr(buffer: Pointer): Pointer {\n const ptr = this.opentui.symbols.bufferGetFgPtr(buffer)\n if (!ptr) {\n throw new Error(\"Failed to get fg pointer\")\n }\n return ptr\n }\n\n public bufferGetBgPtr(buffer: Pointer): Pointer {\n const ptr = this.opentui.symbols.bufferGetBgPtr(buffer)\n if (!ptr) {\n throw new Error(\"Failed to get bg pointer\")\n }\n return ptr\n }\n\n public bufferGetAttributesPtr(buffer: Pointer): Pointer {\n const ptr = this.opentui.symbols.bufferGetAttributesPtr(buffer)\n if (!ptr) {\n throw new Error(\"Failed to get attributes pointer\")\n }\n return ptr\n }\n\n public bufferGetRespectAlpha(buffer: Pointer): boolean {\n return this.opentui.symbols.bufferGetRespectAlpha(buffer)\n }\n\n public bufferSetRespectAlpha(buffer: Pointer, respectAlpha: boolean): void {\n this.opentui.symbols.bufferSetRespectAlpha(buffer, ffiBool(respectAlpha))\n }\n\n public bufferGetId(buffer: Pointer): string {\n const maxLen = 256\n const outBuffer = new Uint8Array(maxLen)\n const actualLen = this.opentui.symbols.bufferGetId(buffer, ptr(outBuffer), maxLen)\n return this.decoder.decode(outBuffer.slice(0, actualLen))\n }\n\n public bufferGetRealCharSize(buffer: Pointer): number {\n return this.opentui.symbols.bufferGetRealCharSize(buffer)\n }\n\n public bufferWriteResolvedChars(buffer: Pointer, outputBuffer: Uint8Array, addLineBreaks: boolean): number {\n return this.opentui.symbols.bufferWriteResolvedChars(\n buffer,\n ptrOrNull(outputBuffer),\n outputBuffer.byteLength,\n ffiBool(addLineBreaks),\n )\n }\n\n public getBufferWidth(buffer: Pointer): number {\n return this.opentui.symbols.getBufferWidth(buffer)\n }\n\n public getBufferHeight(buffer: Pointer): number {\n return this.opentui.symbols.getBufferHeight(buffer)\n }\n\n public bufferClear(buffer: Pointer, color: RGBA) {\n this.opentui.symbols.bufferClear(buffer, rgbaPtr(color))\n }\n\n public bufferDrawText(\n buffer: Pointer,\n text: string,\n x: number,\n y: number,\n color: RGBA,\n bgColor?: RGBA,\n attributes?: number,\n ) {\n const textBytes = this.encoder.encode(text)\n const bg = optionalRgbaPtr(bgColor)\n const fg = rgbaPtr(color)\n\n this.opentui.symbols.bufferDrawText(\n buffer,\n ptrOrNull(textBytes),\n textBytes.byteLength,\n x,\n y,\n fg,\n bg,\n attributes ?? 0,\n )\n }\n\n public bufferSetCellWithAlphaBlending(\n buffer: Pointer,\n x: number,\n y: number,\n char: string,\n color: RGBA,\n bgColor: RGBA,\n attributes?: number,\n ) {\n const charPtr = char.codePointAt(0) ?? \" \".codePointAt(0)!\n const bg = rgbaPtr(bgColor)\n const fg = rgbaPtr(color)\n\n this.opentui.symbols.bufferSetCellWithAlphaBlending(buffer, x, y, charPtr, fg, bg, attributes ?? 0)\n }\n\n public bufferSetCell(\n buffer: Pointer,\n x: number,\n y: number,\n char: string,\n color: RGBA,\n bgColor: RGBA,\n attributes?: number,\n ) {\n const charPtr = char.codePointAt(0) ?? \" \".codePointAt(0)!\n const bg = rgbaPtr(bgColor)\n const fg = rgbaPtr(color)\n\n this.opentui.symbols.bufferSetCell(buffer, x, y, charPtr, fg, bg, attributes ?? 0)\n }\n\n public bufferFillRect(buffer: Pointer, x: number, y: number, width: number, height: number, color: RGBA) {\n const bg = rgbaPtr(color)\n this.opentui.symbols.bufferFillRect(buffer, x, y, width, height, bg)\n }\n\n public bufferColorMatrix(\n buffer: Pointer,\n matrixPtr: Pointer,\n cellMaskPtr: Pointer,\n cellMaskCount: number,\n strength: number,\n target: TargetChannel,\n ): void {\n this.opentui.symbols.bufferColorMatrix(buffer, matrixPtr, cellMaskPtr, cellMaskCount, strength, target)\n }\n\n public bufferColorMatrixUniform(buffer: Pointer, matrixPtr: Pointer, strength: number, target: TargetChannel): void {\n this.opentui.symbols.bufferColorMatrixUniform(buffer, matrixPtr, strength, target)\n }\n\n public bufferDrawSuperSampleBuffer(\n buffer: Pointer,\n x: number,\n y: number,\n pixelDataPtr: Pointer,\n pixelDataLength: number,\n format: \"bgra8unorm\" | \"rgba8unorm\",\n alignedBytesPerRow: number,\n ): void {\n const formatId = format === \"bgra8unorm\" ? 0 : 1\n this.opentui.symbols.bufferDrawSuperSampleBuffer(\n buffer,\n x,\n y,\n pixelDataPtr,\n pixelDataLength,\n formatId,\n alignedBytesPerRow,\n )\n }\n\n public bufferDrawPackedBuffer(\n buffer: Pointer,\n dataPtr: Pointer,\n dataLen: number,\n posX: number,\n posY: number,\n terminalWidthCells: number,\n terminalHeightCells: number,\n ): void {\n this.opentui.symbols.bufferDrawPackedBuffer(\n buffer,\n dataPtr,\n dataLen,\n posX,\n posY,\n terminalWidthCells,\n terminalHeightCells,\n )\n }\n\n public bufferDrawGrayscaleBuffer(\n buffer: Pointer,\n posX: number,\n posY: number,\n intensitiesPtr: Pointer,\n srcWidth: number,\n srcHeight: number,\n fg: RGBA | null,\n bg: RGBA | null,\n ): void {\n this.opentui.symbols.bufferDrawGrayscaleBuffer(\n buffer,\n posX,\n posY,\n intensitiesPtr,\n srcWidth,\n srcHeight,\n optionalRgbaPtr(fg),\n optionalRgbaPtr(bg),\n )\n }\n\n public bufferDrawGrayscaleBufferSupersampled(\n buffer: Pointer,\n posX: number,\n posY: number,\n intensitiesPtr: Pointer,\n srcWidth: number,\n srcHeight: number,\n fg: RGBA | null,\n bg: RGBA | null,\n ): void {\n this.opentui.symbols.bufferDrawGrayscaleBufferSupersampled(\n buffer,\n posX,\n posY,\n intensitiesPtr,\n srcWidth,\n srcHeight,\n optionalRgbaPtr(fg),\n optionalRgbaPtr(bg),\n )\n }\n\n public bufferDrawGrid(\n buffer: Pointer,\n borderChars: Uint32Array,\n borderFg: RGBA,\n borderBg: RGBA,\n columnOffsets: Int32Array,\n columnCount: number,\n rowOffsets: Int32Array,\n rowCount: number,\n options: { drawInner: boolean; drawOuter: boolean },\n ): void {\n const optionsBuffer = GridDrawOptionsStruct.pack({\n drawInner: options.drawInner,\n drawOuter: options.drawOuter,\n })\n\n this.opentui.symbols.bufferDrawGrid(\n buffer,\n ptr(borderChars),\n rgbaPtr(borderFg),\n rgbaPtr(borderBg),\n ptr(columnOffsets),\n columnCount,\n ptr(rowOffsets),\n rowCount,\n ptr(optionsBuffer),\n )\n }\n\n public bufferDrawBox(\n buffer: Pointer,\n x: number,\n y: number,\n width: number,\n height: number,\n borderChars: Uint32Array,\n packedOptions: number,\n borderColor: RGBA,\n backgroundColor: RGBA,\n titleColor: RGBA,\n title: string | null,\n bottomTitle: string | null,\n ): void {\n const titleBytes = title ? this.encoder.encode(title) : null\n const titleLen = titleBytes?.byteLength ?? 0\n const titlePtr = titleBytes ? ptr(titleBytes) : null\n\n const bottomTitleBytes = bottomTitle ? this.encoder.encode(bottomTitle) : null\n const bottomTitleLen = bottomTitleBytes?.byteLength ?? 0\n const bottomTitlePtr = bottomTitleBytes ? ptr(bottomTitleBytes) : null\n\n this.opentui.symbols.bufferDrawBox(\n buffer,\n x,\n y,\n width,\n height,\n ptr(borderChars),\n packedOptions,\n rgbaPtr(borderColor),\n rgbaPtr(backgroundColor),\n rgbaPtr(titleColor),\n titlePtr,\n titleLen,\n bottomTitlePtr,\n bottomTitleLen,\n )\n }\n\n public bufferResize(buffer: Pointer, width: number, height: number): void {\n this.opentui.symbols.bufferResize(buffer, width, height)\n }\n\n // Link API\n public linkAlloc(url: string): number {\n const urlBytes = this.encoder.encode(url)\n return this.opentui.symbols.linkAlloc(ptrOrNull(urlBytes), urlBytes.byteLength)\n }\n\n public linkGetUrl(linkId: number, maxLen: number = 512): string {\n const outBuffer = new Uint8Array(maxLen)\n const actualLen = this.opentui.symbols.linkGetUrl(linkId, ptrOrNull(outBuffer), maxLen)\n return this.decoder.decode(outBuffer.slice(0, actualLen))\n }\n\n public attributesWithLink(baseAttributes: number, linkId: number): number {\n return this.opentui.symbols.attributesWithLink(baseAttributes, linkId)\n }\n\n public attributesGetLinkId(attributes: number): number {\n return this.opentui.symbols.attributesGetLinkId(attributes)\n }\n\n public resizeRenderer(renderer: Pointer, width: number, height: number) {\n this.opentui.symbols.resizeRenderer(renderer, width, height)\n }\n\n public setCursorPosition(renderer: Pointer, x: number, y: number, visible: boolean) {\n this.opentui.symbols.setCursorPosition(renderer, x, y, ffiBool(visible))\n }\n\n public setCursorColor(renderer: Pointer, color: RGBA) {\n this.opentui.symbols.setCursorColor(renderer, rgbaPtr(color))\n }\n\n public getCursorState(renderer: Pointer): CursorState {\n const cursorBuffer = new ArrayBuffer(CursorStateStruct.size)\n this.opentui.symbols.getCursorState(renderer, ptr(cursorBuffer))\n const struct = CursorStateStruct.unpack(cursorBuffer)\n\n return {\n x: struct.x,\n y: struct.y,\n visible: struct.visible,\n style: CURSOR_ID_TO_STYLE[struct.style] ?? \"block\",\n blinking: struct.blinking,\n color: RGBA.fromValues(struct.r, struct.g, struct.b, struct.a),\n }\n }\n\n public setCursorStyleOptions(renderer: Pointer, options: CursorStyleOptions): void {\n const style = options.style != null ? CURSOR_STYLE_TO_ID[options.style] : 255\n const blinking = options.blinking != null ? (options.blinking ? 1 : 0) : 255\n const cursor = options.cursor != null ? MOUSE_STYLE_TO_ID[options.cursor] : 255\n\n const buffer = CursorStyleOptionsStruct.pack({ style, blinking, color: options.color, cursor })\n this.opentui.symbols.setCursorStyleOptions(renderer, ptr(buffer))\n }\n\n public render(renderer: Pointer, force: boolean): number {\n return this.opentui.symbols.render(renderer, ffiBool(force))\n }\n\n private unpackRenderOperationResult(value: number | bigint): NativeRenderOperationResult {\n const packed = typeof value === \"bigint\" ? value : BigInt(value)\n return {\n renderOffset: Number(packed & 0xffffffffn),\n status: Number((packed >> 32n) & 0xffn),\n }\n }\n\n public repaintSplitFooter(\n renderer: Pointer,\n pinnedRenderOffset: number,\n force: boolean,\n ): NativeRenderOperationResult {\n return this.unpackRenderOperationResult(\n this.opentui.symbols.repaintSplitFooter(renderer, pinnedRenderOffset, ffiBool(force)),\n )\n }\n\n public commitSplitFooterSnapshot(\n renderer: Pointer,\n snapshot: OptimizedBuffer,\n rowColumns: number,\n startOnNewLine: boolean,\n trailingNewline: boolean,\n pinnedRenderOffset: number,\n force: boolean,\n beginFrame: boolean = true,\n finalizeFrame: boolean = true,\n ): NativeRenderOperationResult {\n return this.unpackRenderOperationResult(\n this.opentui.symbols.commitSplitFooterSnapshot(\n renderer,\n snapshot.ptr,\n rowColumns,\n ffiBool(startOnNewLine),\n ffiBool(trailingNewline),\n pinnedRenderOffset,\n ffiBool(force),\n ffiBool(beginFrame),\n ffiBool(finalizeFrame),\n ),\n )\n }\n\n public createOptimizedBuffer(\n width: number,\n height: number,\n widthMethod: WidthMethod,\n respectAlpha: boolean = false,\n id?: string,\n ): OptimizedBuffer {\n if (Number.isNaN(width) || Number.isNaN(height)) {\n console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack)\n }\n\n const widthMethodCode = widthMethod === \"wcwidth\" ? 0 : 1\n const idToUse = id || \"unnamed buffer\"\n const idBytes = this.encoder.encode(idToUse)\n const bufferPtr = this.opentui.symbols.createOptimizedBuffer(\n width,\n height,\n ffiBool(respectAlpha),\n widthMethodCode,\n ptr(idBytes),\n idBytes.byteLength,\n )\n if (!bufferPtr) {\n throw new Error(`Failed to create optimized buffer: ${width}x${height}`)\n }\n\n return new OptimizedBuffer(this, bufferPtr, width, height, { respectAlpha, id, widthMethod })\n }\n\n public destroyOptimizedBuffer(bufferPtr: Pointer) {\n this.opentui.symbols.destroyOptimizedBuffer(bufferPtr)\n }\n\n public drawFrameBuffer(\n targetBufferPtr: Pointer,\n destX: number,\n destY: number,\n bufferPtr: Pointer,\n sourceX?: number,\n sourceY?: number,\n sourceWidth?: number,\n sourceHeight?: number,\n ) {\n const srcX = sourceX ?? 0\n const srcY = sourceY ?? 0\n const srcWidth = sourceWidth ?? 0\n const srcHeight = sourceHeight ?? 0\n this.opentui.symbols.drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, srcX, srcY, srcWidth, srcHeight)\n }\n\n public setDebugOverlay(renderer: Pointer, enabled: boolean, corner: DebugOverlayCorner) {\n this.opentui.symbols.setDebugOverlay(renderer, ffiBool(enabled), corner)\n }\n\n public clearTerminal(renderer: Pointer) {\n this.opentui.symbols.clearTerminal(renderer)\n }\n\n public setTerminalTitle(renderer: Pointer, title: string) {\n const titleBytes = this.encoder.encode(title)\n this.opentui.symbols.setTerminalTitle(renderer, ptrOrNull(titleBytes), titleBytes.byteLength)\n }\n\n public copyToClipboardOSC52(renderer: Pointer, target: number, payload: Uint8Array): boolean {\n return Boolean(this.opentui.symbols.copyToClipboardOSC52(renderer, target, ptrOrNull(payload), payload.byteLength))\n }\n\n public clearClipboardOSC52(renderer: Pointer, target: number): boolean {\n return Boolean(this.opentui.symbols.clearClipboardOSC52(renderer, target))\n }\n\n public triggerNotification(renderer: Pointer, message: string, title?: string): boolean {\n const messageBytes = this.encoder.encode(message)\n const titleBytes = title === undefined ? null : this.encoder.encode(title)\n return Boolean(\n this.opentui.symbols.triggerNotification(\n renderer,\n messageBytes,\n messageBytes.length,\n titleBytes,\n titleBytes?.length ?? 0,\n ),\n )\n }\n\n public addToHitGrid(renderer: Pointer, x: number, y: number, width: number, height: number, id: number) {\n this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id)\n }\n\n public clearCurrentHitGrid(renderer: Pointer) {\n this.opentui.symbols.clearCurrentHitGrid(renderer)\n }\n\n public hitGridPushScissorRect(renderer: Pointer, x: number, y: number, width: number, height: number) {\n this.opentui.symbols.hitGridPushScissorRect(renderer, x, y, width, height)\n }\n\n public hitGridPopScissorRect(renderer: Pointer) {\n this.opentui.symbols.hitGridPopScissorRect(renderer)\n }\n\n public hitGridClearScissorRects(renderer: Pointer) {\n this.opentui.symbols.hitGridClearScissorRects(renderer)\n }\n\n public addToCurrentHitGridClipped(\n renderer: Pointer,\n x: number,\n y: number,\n width: number,\n height: number,\n id: number,\n ) {\n this.opentui.symbols.addToCurrentHitGridClipped(renderer, x, y, width, height, id)\n }\n\n public checkHit(renderer: Pointer, x: number, y: number): number {\n return this.opentui.symbols.checkHit(renderer, x, y)\n }\n\n public getHitGridDirty(renderer: Pointer): boolean {\n return this.opentui.symbols.getHitGridDirty(renderer)\n }\n\n public dumpHitGrid(renderer: Pointer): void {\n this.opentui.symbols.dumpHitGrid(renderer)\n }\n\n public dumpBuffers(renderer: Pointer, timestamp?: number): void {\n const ts = timestamp ?? Date.now()\n this.opentui.symbols.dumpBuffers(renderer, ts)\n }\n\n public dumpOutputBuffer(renderer: Pointer, timestamp?: number): void {\n const ts = timestamp ?? Date.now()\n this.opentui.symbols.dumpOutputBuffer(renderer, ts)\n }\n\n public restoreTerminalModes(renderer: Pointer): void {\n this.opentui.symbols.restoreTerminalModes(renderer)\n }\n\n public enableMouse(renderer: Pointer, enableMovement: boolean): void {\n this.opentui.symbols.enableMouse(renderer, ffiBool(enableMovement))\n }\n\n public disableMouse(renderer: Pointer): void {\n this.opentui.symbols.disableMouse(renderer)\n }\n\n public enableKittyKeyboard(renderer: Pointer, flags: number): void {\n this.opentui.symbols.enableKittyKeyboard(renderer, flags)\n }\n\n public disableKittyKeyboard(renderer: Pointer): void {\n this.opentui.symbols.disableKittyKeyboard(renderer)\n }\n\n public setKittyKeyboardFlags(renderer: Pointer, flags: number): void {\n this.opentui.symbols.setKittyKeyboardFlags(renderer, flags)\n }\n\n public getKittyKeyboardFlags(renderer: Pointer): number {\n return this.opentui.symbols.getKittyKeyboardFlags(renderer)\n }\n\n public setupTerminal(renderer: Pointer, useAlternateScreen: boolean): void {\n this.opentui.symbols.setupTerminal(renderer, ffiBool(useAlternateScreen))\n }\n\n public suspendRenderer(renderer: Pointer): void {\n this.opentui.symbols.suspendRenderer(renderer)\n }\n\n public resumeRenderer(renderer: Pointer): void {\n this.opentui.symbols.resumeRenderer(renderer)\n }\n\n public queryPixelResolution(renderer: Pointer): void {\n this.opentui.symbols.queryPixelResolution(renderer)\n }\n\n public queryThemeColors(renderer: Pointer): void {\n this.opentui.symbols.queryThemeColors(renderer)\n }\n\n /**\n * Write data to stdout, synchronizing with the render thread if necessary.\n * This should be used for ALL stdout writes to avoid race conditions when\n * the render thread is active.\n */\n public writeOut(renderer: Pointer, data: string | Uint8Array): void {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data\n if (bytes.length === 0) return\n this.opentui.symbols.writeOut(renderer, ptrOrNull(bytes), bytes.byteLength)\n }\n\n public yogaConfigCreate(): Pointer {\n const config = this.opentui.symbols.yogaConfigCreate()\n if (!config) throw new Error(\"Failed to create Yoga config\")\n return config\n }\n\n public yogaConfigFree(config: Pointer): void {\n this.opentui.symbols.yogaConfigFree(config)\n }\n\n public yogaConfigSetUseWebDefaults(config: Pointer, enabled: boolean): void {\n this.opentui.symbols.yogaConfigSetUseWebDefaults(config, ffiBool(enabled))\n }\n\n public yogaConfigGetUseWebDefaults(config: Pointer): boolean {\n return this.opentui.symbols.yogaConfigGetUseWebDefaults(config)\n }\n\n public yogaConfigSetPointScaleFactor(config: Pointer, pointScaleFactor: number): void {\n this.opentui.symbols.yogaConfigSetPointScaleFactor(config, pointScaleFactor)\n }\n\n public yogaConfigGetPointScaleFactor(config: Pointer): number {\n return this.opentui.symbols.yogaConfigGetPointScaleFactor(config)\n }\n\n public yogaConfigSetErrata(config: Pointer, errata: number): void {\n this.opentui.symbols.yogaConfigSetErrata(config, errata)\n }\n\n public yogaConfigGetErrata(config: Pointer): number {\n return this.opentui.symbols.yogaConfigGetErrata(config)\n }\n\n public yogaConfigSetExperimentalFeatureEnabled(config: Pointer, feature: number, enabled: boolean): void {\n this.opentui.symbols.yogaConfigSetExperimentalFeatureEnabled(config, feature, ffiBool(enabled))\n }\n\n public yogaConfigIsExperimentalFeatureEnabled(config: Pointer, feature: number): boolean {\n return this.opentui.symbols.yogaConfigIsExperimentalFeatureEnabled(config, feature)\n }\n\n public yogaNodeCreate(): Pointer {\n const node = this.opentui.symbols.yogaNodeCreate()\n if (!node) throw new Error(\"Failed to create Yoga node\")\n return node\n }\n\n public yogaNodeCreateForOpenTUI(): Pointer {\n const node = this.opentui.symbols.yogaNodeCreateForOpenTUI()\n if (!node) throw new Error(\"Failed to create OpenTUI Yoga node\")\n return node\n }\n\n public yogaNodeCreateWithConfig(config: Pointer): Pointer {\n const node = this.opentui.symbols.yogaNodeCreateWithConfig(config)\n if (!node) throw new Error(\"Failed to create Yoga node\")\n return node\n }\n\n public yogaNodeFree(node: Pointer): void {\n this.opentui.symbols.yogaNodeFree(node)\n }\n\n public yogaNodeFreeRecursive(node: Pointer): void {\n this.opentui.symbols.yogaNodeFreeRecursive(node)\n }\n\n public yogaNodeReset(node: Pointer): void {\n this.opentui.symbols.yogaNodeReset(node)\n }\n\n public yogaNodeCopyStyle(dstNode: Pointer, srcNode: Pointer): void {\n this.opentui.symbols.yogaNodeCopyStyle(dstNode, srcNode)\n }\n\n public yogaNodeInsertChild(node: Pointer, child: Pointer, index: number): void {\n this.opentui.symbols.yogaNodeInsertChild(node, child, index)\n }\n\n public yogaNodeRemoveChild(node: Pointer, child: Pointer): void {\n this.opentui.symbols.yogaNodeRemoveChild(node, child)\n }\n\n public yogaNodeRemoveAllChildren(node: Pointer): void {\n this.opentui.symbols.yogaNodeRemoveAllChildren(node)\n }\n\n public yogaNodeGetChild(node: Pointer, index: number): Pointer | null {\n return this.opentui.symbols.yogaNodeGetChild(node, index) || null\n }\n\n public yogaNodeGetChildCount(node: Pointer): number {\n return this.opentui.symbols.yogaNodeGetChildCount(node)\n }\n\n public yogaNodeGetParent(node: Pointer): Pointer | null {\n return this.opentui.symbols.yogaNodeGetParent(node) || null\n }\n\n public yogaNodeCalculateLayout(node: Pointer, width: number, height: number, direction: number): void {\n this.opentui.symbols.yogaNodeCalculateLayout(node, width, height, direction)\n }\n\n public yogaNodeIsDirty(node: Pointer): boolean {\n return this.opentui.symbols.yogaNodeIsDirty(node)\n }\n\n public yogaNodeMarkDirty(node: Pointer): void {\n this.opentui.symbols.yogaNodeMarkDirty(node)\n }\n\n public yogaNodeGetHasNewLayout(node: Pointer): boolean {\n return this.opentui.symbols.yogaNodeGetHasNewLayout(node)\n }\n\n public yogaNodeSetHasNewLayout(node: Pointer, hasNewLayout: boolean): void {\n this.opentui.symbols.yogaNodeSetHasNewLayout(node, ffiBool(hasNewLayout))\n }\n\n public yogaNodeSetIsReferenceBaseline(node: Pointer, isReferenceBaseline: boolean): void {\n this.opentui.symbols.yogaNodeSetIsReferenceBaseline(node, ffiBool(isReferenceBaseline))\n }\n\n public yogaNodeIsReferenceBaseline(node: Pointer): boolean {\n return this.opentui.symbols.yogaNodeIsReferenceBaseline(node)\n }\n\n public yogaNodeSetAlwaysFormsContainingBlock(node: Pointer, alwaysFormsContainingBlock: boolean): void {\n this.opentui.symbols.yogaNodeSetAlwaysFormsContainingBlock(node, ffiBool(alwaysFormsContainingBlock))\n }\n\n public yogaNodeGetAlwaysFormsContainingBlock(node: Pointer): boolean {\n return this.opentui.symbols.yogaNodeGetAlwaysFormsContainingBlock(node)\n }\n\n public yogaNodeGetComputedLayout(node: Pointer): NativeYogaLayout {\n const layout = new Float32Array(6)\n this.opentui.symbols.yogaNodeGetComputedLayout(node, ptr(layout))\n return {\n left: layout[0]!,\n top: layout[1]!,\n right: layout[2]!,\n bottom: layout[3]!,\n width: layout[4]!,\n height: layout[5]!,\n }\n }\n\n public yogaNodeLayoutGetEdge(node: Pointer, kind: number, edge: number): number {\n return this.opentui.symbols.yogaNodeLayoutGetEdge(node, kind, edge)\n }\n\n public yogaNodeStyleSetEnum(node: Pointer, kind: number, value: number): void {\n this.opentui.symbols.yogaNodeStyleSetEnum(node, kind, value)\n }\n\n public yogaNodeStyleGetEnum(node: Pointer, kind: number): number {\n return this.opentui.symbols.yogaNodeStyleGetEnum(node, kind)\n }\n\n public yogaNodeStyleSetFloat(node: Pointer, kind: number, value: number): void {\n this.opentui.symbols.yogaNodeStyleSetFloat(node, kind, value)\n }\n\n public yogaNodeStyleGetFloat(node: Pointer, kind: number): number {\n return this.opentui.symbols.yogaNodeStyleGetFloat(node, kind)\n }\n\n public yogaNodeStyleSetBorder(node: Pointer, edge: number, border: number): void {\n this.opentui.symbols.yogaNodeStyleSetBorder(node, edge, border)\n }\n\n public yogaNodeStyleGetBorder(node: Pointer, edge: number): number {\n return this.opentui.symbols.yogaNodeStyleGetBorder(node, edge)\n }\n\n public yogaNodeStyleSetValue(node: Pointer, kind: number, edgeOrGutter: number, unit: number, value: number): void {\n this.opentui.symbols.yogaNodeStyleSetValue(node, kind, edgeOrGutter, unit, value)\n }\n\n public yogaNodeStyleGetValue(node: Pointer, kind: number, edgeOrGutter: number): number | bigint {\n return this.opentui.symbols.yogaNodeStyleGetValue(node, kind, edgeOrGutter)\n }\n\n public yogaNodeSetMeasureFunc(node: Pointer, callback: Pointer | null): void {\n this.opentui.symbols.yogaNodeSetMeasureFunc(node, callback)\n }\n\n public yogaNodeUnsetMeasureFunc(node: Pointer): void {\n this.opentui.symbols.yogaNodeUnsetMeasureFunc(node)\n }\n\n public yogaNodeHasMeasureFunc(node: Pointer): boolean {\n return this.opentui.symbols.yogaNodeHasMeasureFunc(node)\n }\n\n public yogaNodeSetDirtiedFunc(node: Pointer, callback: Pointer | null): void {\n this.opentui.symbols.yogaNodeSetDirtiedFunc(node, callback)\n }\n\n public yogaNodeUnsetDirtiedFunc(node: Pointer): void {\n this.opentui.symbols.yogaNodeUnsetDirtiedFunc(node)\n }\n\n public yogaStoreMeasureResult(width: number, height: number): void {\n this.opentui.symbols.yogaStoreMeasureResult(width, height)\n }\n\n public createYogaMeasureCallback(callback: NativeYogaMeasureCallback): FFICallbackInstance {\n return this.opentui.createCallback(callback, {\n args: [\"ptr\", \"f32\", \"u32\", \"f32\", \"u32\"],\n returns: \"void\",\n })\n }\n\n public createYogaDirtiedCallback(callback: NativeYogaDirtiedCallback): FFICallbackInstance {\n return this.opentui.createCallback(callback, {\n args: [],\n returns: \"void\",\n })\n }\n\n // TextBuffer methods\n public createTextBuffer(widthMethod: WidthMethod): TextBuffer {\n const widthMethodCode = widthMethod === \"wcwidth\" ? 0 : 1\n const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode)\n if (!bufferPtr) {\n throw new Error(`Failed to create TextBuffer`)\n }\n\n return new TextBuffer(this, bufferPtr)\n }\n\n public destroyTextBuffer(buffer: Pointer): void {\n this.opentui.symbols.destroyTextBuffer(buffer)\n }\n\n public textBufferGetLength(buffer: Pointer): number {\n return this.opentui.symbols.textBufferGetLength(buffer)\n }\n\n public textBufferGetByteSize(buffer: Pointer): number {\n return this.opentui.symbols.textBufferGetByteSize(buffer)\n }\n\n public textBufferReset(buffer: Pointer): void {\n this.opentui.symbols.textBufferReset(buffer)\n }\n\n public textBufferClear(buffer: Pointer): void {\n this.opentui.symbols.textBufferClear(buffer)\n }\n\n public textBufferSetDefaultFg(buffer: Pointer, fg: RGBA | null): void {\n const fgPtr = optionalRgbaPtr(fg)\n this.opentui.symbols.textBufferSetDefaultFg(buffer, fgPtr)\n }\n\n public textBufferSetDefaultBg(buffer: Pointer, bg: RGBA | null): void {\n const bgPtr = optionalRgbaPtr(bg)\n this.opentui.symbols.textBufferSetDefaultBg(buffer, bgPtr)\n }\n\n public textBufferSetDefaultAttributes(buffer: Pointer, attributes: number | null): void {\n const attrValue = attributes === null ? null : new Uint32Array([attributes])\n this.opentui.symbols.textBufferSetDefaultAttributes(buffer, attrValue ? ptr(attrValue) : null)\n }\n\n public textBufferResetDefaults(buffer: Pointer): void {\n this.opentui.symbols.textBufferResetDefaults(buffer)\n }\n\n public textBufferGetTabWidth(buffer: Pointer): number {\n return this.opentui.symbols.textBufferGetTabWidth(buffer)\n }\n\n public textBufferSetTabWidth(buffer: Pointer, width: number): void {\n this.opentui.symbols.textBufferSetTabWidth(buffer, width)\n }\n\n public textBufferRegisterMemBuffer(buffer: Pointer, bytes: Uint8Array, owned: boolean = false): number {\n const result = this.opentui.symbols.textBufferRegisterMemBuffer(\n buffer,\n ptrOrNull(bytes),\n bytes.byteLength,\n ffiBool(owned),\n )\n if (result === 0xffff) {\n throw new Error(\"Failed to register memory buffer\")\n }\n return result\n }\n\n public textBufferReplaceMemBuffer(\n buffer: Pointer,\n memId: number,\n bytes: Uint8Array,\n owned: boolean = false,\n ): boolean {\n return this.opentui.symbols.textBufferReplaceMemBuffer(\n buffer,\n memId,\n ptrOrNull(bytes),\n bytes.byteLength,\n ffiBool(owned),\n )\n }\n\n public textBufferClearMemRegistry(buffer: Pointer): void {\n this.opentui.symbols.textBufferClearMemRegistry(buffer)\n }\n\n public textBufferSetTextFromMem(buffer: Pointer, memId: number): void {\n this.opentui.symbols.textBufferSetTextFromMem(buffer, memId)\n }\n\n public textBufferAppend(buffer: Pointer, bytes: Uint8Array): void {\n this.opentui.symbols.textBufferAppend(buffer, ptrOrNull(bytes), bytes.byteLength)\n }\n\n public textBufferAppendFromMemId(buffer: Pointer, memId: number): void {\n this.opentui.symbols.textBufferAppendFromMemId(buffer, memId)\n }\n\n public textBufferLoadFile(buffer: Pointer, path: string): boolean {\n const pathBytes = this.encoder.encode(path)\n return this.opentui.symbols.textBufferLoadFile(buffer, ptrOrNull(pathBytes), pathBytes.byteLength)\n }\n\n public textBufferSetStyledText(\n buffer: Pointer,\n chunks: Array<{ text: string; fg?: RGBA | null; bg?: RGBA | null; attributes?: number; link?: { url: string } }>,\n ): void {\n if (chunks.length === 0) {\n this.textBufferClear(buffer)\n return\n }\n\n const chunksBuffer = StyledChunkStruct.packList(chunks)\n this.opentui.symbols.textBufferSetStyledText(buffer, ptr(chunksBuffer), chunks.length)\n }\n\n public textBufferGetLineCount(buffer: Pointer): number {\n return this.opentui.symbols.textBufferGetLineCount(buffer)\n }\n\n private textBufferGetPlainText(buffer: Pointer, outPtr: Pointer | null, maxLen: number): number {\n return this.opentui.symbols.textBufferGetPlainText(buffer, outPtr, maxLen)\n }\n\n public getPlainTextBytes(buffer: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n\n const actualLen = this.textBufferGetPlainText(buffer, ptrOrNull(outBuffer), maxLength)\n\n if (actualLen === 0) {\n return null\n }\n\n return outBuffer.slice(0, actualLen)\n }\n\n public textBufferGetTextRange(\n buffer: Pointer,\n startOffset: number,\n endOffset: number,\n maxLength: number,\n ): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n\n const actualLen = this.opentui.symbols.textBufferGetTextRange(\n buffer,\n startOffset,\n endOffset,\n ptrOrNull(outBuffer),\n maxLength,\n )\n\n const len = actualLen\n\n if (len === 0) {\n return null\n }\n\n return outBuffer.slice(0, len)\n }\n\n public textBufferGetTextRangeByCoords(\n buffer: Pointer,\n startRow: number,\n startCol: number,\n endRow: number,\n endCol: number,\n maxLength: number,\n ): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n\n const actualLen = this.opentui.symbols.textBufferGetTextRangeByCoords(\n buffer,\n startRow,\n startCol,\n endRow,\n endCol,\n ptrOrNull(outBuffer),\n maxLength,\n )\n\n const len = actualLen\n\n if (len === 0) {\n return null\n }\n\n return outBuffer.slice(0, len)\n }\n\n // TextBufferView methods\n public createTextBufferView(textBuffer: TextBufferHandle): TextBufferViewHandle {\n const viewPtr = this.opentui.symbols.createTextBufferView(textBuffer) as TextBufferViewHandle\n if (!viewPtr) {\n throw new Error(\"Failed to create TextBufferView\")\n }\n return viewPtr\n }\n\n public destroyTextBufferView(view: Pointer): void {\n this.opentui.symbols.destroyTextBufferView(view)\n }\n\n public textBufferViewSetSelection(\n view: Pointer,\n start: number,\n end: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ): void {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n this.opentui.symbols.textBufferViewSetSelection(view, start, end, bg, fg)\n }\n\n public textBufferViewResetSelection(view: Pointer): void {\n this.opentui.symbols.textBufferViewResetSelection(view)\n }\n\n public textBufferViewGetSelection(view: Pointer): { start: number; end: number } | null {\n const packedInfo = this.textBufferViewGetSelectionInfo(view)\n\n // Check for no selection marker (0xFFFFFFFF_FFFFFFFF)\n if (packedInfo === 0xffff_ffff_ffff_ffffn) {\n return null\n }\n\n const start = Number(packedInfo >> 32n)\n const end = Number(packedInfo & 0xffff_ffffn)\n\n return { start, end }\n }\n\n private textBufferViewGetSelectionInfo(view: Pointer): bigint {\n return this.opentui.symbols.textBufferViewGetSelectionInfo(view)\n }\n\n public textBufferViewSetLocalSelection(\n view: Pointer,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ): boolean {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n return Boolean(this.opentui.symbols.textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg, fg))\n }\n\n public textBufferViewUpdateSelection(view: Pointer, end: number, bgColor: RGBA | null, fgColor: RGBA | null): void {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n this.opentui.symbols.textBufferViewUpdateSelection(view, end, bg, fg)\n }\n\n public textBufferViewUpdateLocalSelection(\n view: Pointer,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ): boolean {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n return Boolean(\n this.opentui.symbols.textBufferViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bg, fg),\n )\n }\n\n public textBufferViewResetLocalSelection(view: Pointer): void {\n this.opentui.symbols.textBufferViewResetLocalSelection(view)\n }\n\n public textBufferViewSetWrapWidth(view: Pointer, width: number): void {\n this.opentui.symbols.textBufferViewSetWrapWidth(view, width)\n }\n\n public textBufferViewSetWrapMode(view: Pointer, mode: \"none\" | \"char\" | \"word\"): void {\n const modeValue = mode === \"none\" ? 0 : mode === \"char\" ? 1 : 2\n this.opentui.symbols.textBufferViewSetWrapMode(view, modeValue)\n }\n\n public textBufferViewSetFirstLineOffset(view: Pointer, offset: number): void {\n this.opentui.symbols.textBufferViewSetFirstLineOffset(view, offset)\n }\n\n public textBufferViewSetViewportSize(view: Pointer, width: number, height: number): void {\n this.opentui.symbols.textBufferViewSetViewportSize(view, width, height)\n }\n\n public textBufferViewSetViewport(view: Pointer, x: number, y: number, width: number, height: number): void {\n this.opentui.symbols.textBufferViewSetViewport(view, x, y, width, height)\n }\n\n public textBufferViewGetLineInfo(view: Pointer): LineInfo {\n const outBuffer = new ArrayBuffer(LineInfoStruct.size)\n this.textBufferViewGetLineInfoDirect(view, ptr(outBuffer))\n const struct = LineInfoStruct.unpack(outBuffer)\n\n const lineStartCols = struct.startCols as number[]\n const lineWidthCols = struct.widthCols as number[]\n const lineWidthColsMax = struct.widthColsMax\n\n return {\n lineStartCols,\n lineWidthCols,\n lineWidthColsMax,\n lineSources: struct.sources as number[],\n lineWraps: struct.wraps as number[],\n }\n }\n\n public textBufferViewGetLogicalLineInfo(view: Pointer): LineInfo {\n const outBuffer = new ArrayBuffer(LineInfoStruct.size)\n this.textBufferViewGetLogicalLineInfoDirect(view, ptr(outBuffer))\n const struct = LineInfoStruct.unpack(outBuffer)\n\n const lineStartCols = struct.startCols as number[]\n const lineWidthCols = struct.widthCols as number[]\n const lineWidthColsMax = struct.widthColsMax\n\n return {\n lineStartCols,\n lineWidthCols,\n lineWidthColsMax,\n lineSources: struct.sources as number[],\n lineWraps: struct.wraps as number[],\n }\n }\n\n public textBufferViewGetVirtualLineCount(view: Pointer): number {\n return this.opentui.symbols.textBufferViewGetVirtualLineCount(view)\n }\n\n private textBufferViewGetLineInfoDirect(view: Pointer, outPtr: Pointer): void {\n this.opentui.symbols.textBufferViewGetLineInfoDirect(view, outPtr)\n }\n\n private textBufferViewGetLogicalLineInfoDirect(view: Pointer, outPtr: Pointer): void {\n this.opentui.symbols.textBufferViewGetLogicalLineInfoDirect(view, outPtr)\n }\n\n private textBufferViewGetSelectedText(view: Pointer, outPtr: Pointer | null, maxLen: number): number {\n return this.opentui.symbols.textBufferViewGetSelectedText(view, outPtr, maxLen)\n }\n\n private textBufferViewGetPlainText(view: Pointer, outPtr: Pointer | null, maxLen: number): number {\n return this.opentui.symbols.textBufferViewGetPlainText(view, outPtr, maxLen)\n }\n\n public textBufferViewGetSelectedTextBytes(view: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n\n const actualLen = this.textBufferViewGetSelectedText(view, ptrOrNull(outBuffer), maxLength)\n\n if (actualLen === 0) {\n return null\n }\n\n return outBuffer.slice(0, actualLen)\n }\n\n public textBufferViewGetPlainTextBytes(view: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n\n const actualLen = this.textBufferViewGetPlainText(view, ptrOrNull(outBuffer), maxLength)\n\n if (actualLen === 0) {\n return null\n }\n\n return outBuffer.slice(0, actualLen)\n }\n\n public textBufferViewSetTabIndicator(view: Pointer, indicator: number): void {\n this.opentui.symbols.textBufferViewSetTabIndicator(view, indicator)\n }\n\n public textBufferViewSetTabIndicatorColor(view: Pointer, color: RGBA): void {\n this.opentui.symbols.textBufferViewSetTabIndicatorColor(view, rgbaPtr(color))\n }\n\n public textBufferViewSetTruncate(view: Pointer, truncate: boolean): void {\n this.opentui.symbols.textBufferViewSetTruncate(view, ffiBool(truncate))\n }\n\n public textBufferViewMeasureForDimensions(\n view: Pointer,\n width: number,\n height: number,\n ): { lineCount: number; widthColsMax: number } | null {\n const resultBuffer = new ArrayBuffer(MeasureResultStruct.size)\n const resultPtr = ptr(new Uint8Array(resultBuffer))\n const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, resultPtr)\n if (!success) {\n return null\n }\n const result = MeasureResultStruct.unpack(resultBuffer)\n return result\n }\n\n public textBufferAddHighlightByCharRange(buffer: Pointer, highlight: Highlight): void {\n const packedHighlight = HighlightStruct.pack(highlight)\n this.opentui.symbols.textBufferAddHighlightByCharRange(buffer, ptr(packedHighlight))\n }\n\n public textBufferAddHighlight(buffer: Pointer, lineIdx: number, highlight: Highlight): void {\n const packedHighlight = HighlightStruct.pack(highlight)\n this.opentui.symbols.textBufferAddHighlight(buffer, lineIdx, ptr(packedHighlight))\n }\n\n public textBufferRemoveHighlightsByRef(buffer: Pointer, hlRef: number): void {\n this.opentui.symbols.textBufferRemoveHighlightsByRef(buffer, hlRef)\n }\n\n public textBufferClearLineHighlights(buffer: Pointer, lineIdx: number): void {\n this.opentui.symbols.textBufferClearLineHighlights(buffer, lineIdx)\n }\n\n public textBufferClearAllHighlights(buffer: Pointer): void {\n this.opentui.symbols.textBufferClearAllHighlights(buffer)\n }\n\n public textBufferSetSyntaxStyle(buffer: Pointer, style: Pointer | null): boolean {\n return this.opentui.symbols.textBufferSetSyntaxStyle(buffer, style ?? 0)\n }\n\n public textBufferGetLineHighlights(buffer: Pointer, lineIdx: number): Array {\n const outCountBuf = new Uint32Array(1)\n\n const nativePtr = this.opentui.symbols.textBufferGetLineHighlightsPtr(buffer, lineIdx, ptr(outCountBuf))\n if (!nativePtr) return []\n\n const count = outCountBuf[0]\n const byteLen = count * HighlightStruct.size\n const raw = toArrayBuffer(nativePtr, 0, byteLen)\n const results = HighlightStruct.unpackList(raw, count)\n\n this.opentui.symbols.textBufferFreeLineHighlights(nativePtr, count)\n\n return results\n }\n\n public textBufferGetHighlightCount(buffer: Pointer): number {\n return this.opentui.symbols.textBufferGetHighlightCount(buffer)\n }\n\n public getArenaAllocatedBytes(): number {\n const result = this.opentui.symbols.getArenaAllocatedBytes()\n return toSafeByteCount(result, \"Arena allocated bytes\")\n }\n\n public getBuildOptions(): BuildOptions {\n const optionsBuffer = new ArrayBuffer(BuildOptionsStruct.size)\n this.opentui.symbols.getBuildOptions(ptr(optionsBuffer))\n const options = BuildOptionsStruct.unpack(optionsBuffer)\n\n return {\n gpaSafeStats: !!options.gpaSafeStats,\n gpaMemoryLimitTracking: !!options.gpaMemoryLimitTracking,\n }\n }\n\n public getAllocatorStats(): AllocatorStats {\n const statsBuffer = new ArrayBuffer(AllocatorStatsStruct.size)\n this.opentui.symbols.getAllocatorStats(ptr(statsBuffer))\n const stats = AllocatorStatsStruct.unpack(statsBuffer)\n\n return {\n totalRequestedBytes: toNumber(stats.totalRequestedBytes),\n activeAllocations: toNumber(stats.activeAllocations),\n smallAllocations: toNumber(stats.smallAllocations),\n largeAllocations: toNumber(stats.largeAllocations),\n requestedBytesValid: !!stats.requestedBytesValid,\n }\n }\n\n public bufferDrawTextBufferView(buffer: Pointer, view: Pointer, x: number, y: number): void {\n this.opentui.symbols.bufferDrawTextBufferView(buffer, view, x, y)\n }\n\n public bufferDrawEditorView(buffer: Pointer, view: Pointer, x: number, y: number): void {\n this.opentui.symbols.bufferDrawEditorView(buffer, view, x, y)\n }\n\n // EditorView methods\n public createEditorView(\n editBufferPtr: EditBufferHandle,\n viewportWidth: number,\n viewportHeight: number,\n ): EditorViewHandle {\n const viewPtr = this.opentui.symbols.createEditorView(\n editBufferPtr,\n viewportWidth,\n viewportHeight,\n ) as EditorViewHandle\n if (!viewPtr) {\n throw new Error(\"Failed to create EditorView\")\n }\n return viewPtr\n }\n\n public destroyEditorView(view: Pointer): void {\n this.opentui.symbols.destroyEditorView(view)\n }\n\n public editorViewSetViewportSize(view: Pointer, width: number, height: number): void {\n this.opentui.symbols.editorViewSetViewportSize(view, width, height)\n }\n\n public editorViewSetViewport(\n view: Pointer,\n x: number,\n y: number,\n width: number,\n height: number,\n moveCursor: boolean,\n ): void {\n this.opentui.symbols.editorViewSetViewport(view, x, y, width, height, ffiBool(moveCursor))\n }\n\n public editorViewGetViewport(view: Pointer): { offsetY: number; offsetX: number; height: number; width: number } {\n const x = new Uint32Array(1)\n const y = new Uint32Array(1)\n const width = new Uint32Array(1)\n const height = new Uint32Array(1)\n\n this.opentui.symbols.editorViewGetViewport(view, ptr(x), ptr(y), ptr(width), ptr(height))\n\n return {\n offsetX: x[0],\n offsetY: y[0],\n width: width[0],\n height: height[0],\n }\n }\n\n public editorViewSetScrollMargin(view: Pointer, margin: number): void {\n this.opentui.symbols.editorViewSetScrollMargin(view, margin)\n }\n\n public editorViewSetWrapMode(view: Pointer, mode: \"none\" | \"char\" | \"word\"): void {\n const modeValue = mode === \"none\" ? 0 : mode === \"char\" ? 1 : 2\n this.opentui.symbols.editorViewSetWrapMode(view, modeValue)\n }\n\n public editorViewGetVirtualLineCount(view: Pointer): number {\n return this.opentui.symbols.editorViewGetVirtualLineCount(view)\n }\n\n public editorViewGetTotalVirtualLineCount(view: Pointer): number {\n return this.opentui.symbols.editorViewGetTotalVirtualLineCount(view)\n }\n\n public editorViewGetTextBufferView(view: EditorViewHandle): TextBufferViewHandle {\n const result = this.opentui.symbols.editorViewGetTextBufferView(view) as TextBufferViewHandle\n if (!result) {\n throw new Error(\"Failed to get TextBufferView from EditorView\")\n }\n return result\n }\n\n public editorViewGetLineInfo(view: Pointer): LineInfo {\n const outBuffer = new ArrayBuffer(LineInfoStruct.size)\n this.opentui.symbols.editorViewGetLineInfoDirect(view, ptr(outBuffer))\n const struct = LineInfoStruct.unpack(outBuffer)\n\n const lineStartCols = struct.startCols as number[]\n const lineWidthCols = struct.widthCols as number[]\n const lineWidthColsMax = struct.widthColsMax\n\n return {\n lineStartCols,\n lineWidthCols,\n lineWidthColsMax,\n lineSources: struct.sources as number[],\n lineWraps: struct.wraps as number[],\n }\n }\n\n public editorViewGetLogicalLineInfo(view: Pointer): LineInfo {\n const outBuffer = new ArrayBuffer(LineInfoStruct.size)\n this.opentui.symbols.editorViewGetLogicalLineInfoDirect(view, ptr(outBuffer))\n const struct = LineInfoStruct.unpack(outBuffer)\n\n const lineStartCols = struct.startCols as number[]\n const lineWidthCols = struct.widthCols as number[]\n const lineWidthColsMax = struct.widthColsMax\n\n return {\n lineStartCols,\n lineWidthCols,\n lineWidthColsMax,\n lineSources: struct.sources as number[],\n lineWraps: struct.wraps as number[],\n }\n }\n\n // EditBuffer implementations\n public createEditBuffer(widthMethod: WidthMethod): EditBufferHandle {\n const widthMethodCode = widthMethod === \"wcwidth\" ? 0 : 1\n const bufferPtr = this.opentui.symbols.createEditBuffer(widthMethodCode, this.eventSinkPtr ?? 0) as EditBufferHandle\n if (!bufferPtr) {\n throw new Error(\"Failed to create EditBuffer\")\n }\n return bufferPtr\n }\n\n public destroyEditBuffer(buffer: Pointer): void {\n this.opentui.symbols.destroyEditBuffer(buffer)\n }\n\n public editBufferSetText(buffer: Pointer, textBytes: Uint8Array): void {\n this.opentui.symbols.editBufferSetText(buffer, ptrOrNull(textBytes), textBytes.byteLength)\n }\n\n public editBufferSetTextFromMem(buffer: Pointer, memId: number): void {\n this.opentui.symbols.editBufferSetTextFromMem(buffer, memId)\n }\n\n public editBufferReplaceText(buffer: Pointer, textBytes: Uint8Array): void {\n this.opentui.symbols.editBufferReplaceText(buffer, ptrOrNull(textBytes), textBytes.byteLength)\n }\n\n public editBufferReplaceTextFromMem(buffer: Pointer, memId: number): void {\n this.opentui.symbols.editBufferReplaceTextFromMem(buffer, memId)\n }\n\n public editBufferGetText(buffer: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n const actualLen = this.opentui.symbols.editBufferGetText(buffer, ptrOrNull(outBuffer), maxLength)\n const len = actualLen\n if (len === 0) return null\n return outBuffer.slice(0, len)\n }\n\n public editBufferInsertChar(buffer: Pointer, char: string): void {\n const charBytes = this.encoder.encode(char)\n this.opentui.symbols.editBufferInsertChar(buffer, ptrOrNull(charBytes), charBytes.byteLength)\n }\n\n public editBufferInsertText(buffer: Pointer, text: string): void {\n const textBytes = this.encoder.encode(text)\n this.opentui.symbols.editBufferInsertText(buffer, ptrOrNull(textBytes), textBytes.byteLength)\n }\n\n public editBufferDeleteChar(buffer: Pointer): void {\n this.opentui.symbols.editBufferDeleteChar(buffer)\n }\n\n public editBufferDeleteCharBackward(buffer: Pointer): void {\n this.opentui.symbols.editBufferDeleteCharBackward(buffer)\n }\n\n public editBufferDeleteRange(\n buffer: Pointer,\n startLine: number,\n startCol: number,\n endLine: number,\n endCol: number,\n ): void {\n this.opentui.symbols.editBufferDeleteRange(buffer, startLine, startCol, endLine, endCol)\n }\n\n public editBufferNewLine(buffer: Pointer): void {\n this.opentui.symbols.editBufferNewLine(buffer)\n }\n\n public editBufferDeleteLine(buffer: Pointer): void {\n this.opentui.symbols.editBufferDeleteLine(buffer)\n }\n\n public editBufferMoveCursorLeft(buffer: Pointer): void {\n this.opentui.symbols.editBufferMoveCursorLeft(buffer)\n }\n\n public editBufferMoveCursorRight(buffer: Pointer): void {\n this.opentui.symbols.editBufferMoveCursorRight(buffer)\n }\n\n public editBufferMoveCursorUp(buffer: Pointer): void {\n this.opentui.symbols.editBufferMoveCursorUp(buffer)\n }\n\n public editBufferMoveCursorDown(buffer: Pointer): void {\n this.opentui.symbols.editBufferMoveCursorDown(buffer)\n }\n\n public editBufferGotoLine(buffer: Pointer, line: number): void {\n this.opentui.symbols.editBufferGotoLine(buffer, line)\n }\n\n public editBufferSetCursor(buffer: Pointer, line: number, byteOffset: number): void {\n this.opentui.symbols.editBufferSetCursor(buffer, line, byteOffset)\n }\n\n public editBufferSetCursorToLineCol(buffer: Pointer, line: number, col: number): void {\n this.opentui.symbols.editBufferSetCursorToLineCol(buffer, line, col)\n }\n\n public editBufferSetCursorByOffset(buffer: Pointer, offset: number): void {\n this.opentui.symbols.editBufferSetCursorByOffset(buffer, offset)\n }\n\n public editBufferGetCursorPosition(buffer: Pointer): LogicalCursor {\n const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size)\n this.opentui.symbols.editBufferGetCursorPosition(buffer, ptr(cursorBuffer))\n return LogicalCursorStruct.unpack(cursorBuffer)\n }\n\n public editBufferGetId(buffer: Pointer): number {\n return this.opentui.symbols.editBufferGetId(buffer)\n }\n\n public editBufferGetTextBuffer(buffer: EditBufferHandle): TextBufferHandle {\n const result = this.opentui.symbols.editBufferGetTextBuffer(buffer) as TextBufferHandle\n if (!result) {\n throw new Error(\"Failed to get TextBuffer from EditBuffer\")\n }\n return result\n }\n\n public editBufferDebugLogRope(buffer: Pointer): void {\n this.opentui.symbols.editBufferDebugLogRope(buffer)\n }\n\n public editBufferUndo(buffer: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n const actualLen = this.opentui.symbols.editBufferUndo(buffer, ptrOrNull(outBuffer), maxLength)\n const len = actualLen\n if (len === 0) return null\n return outBuffer.slice(0, len)\n }\n\n public editBufferRedo(buffer: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n const actualLen = this.opentui.symbols.editBufferRedo(buffer, ptrOrNull(outBuffer), maxLength)\n const len = actualLen\n if (len === 0) return null\n return outBuffer.slice(0, len)\n }\n\n public editBufferCanUndo(buffer: Pointer): boolean {\n return Boolean(this.opentui.symbols.editBufferCanUndo(buffer))\n }\n\n public editBufferCanRedo(buffer: Pointer): boolean {\n return Boolean(this.opentui.symbols.editBufferCanRedo(buffer))\n }\n\n public editBufferClearHistory(buffer: Pointer): void {\n this.opentui.symbols.editBufferClearHistory(buffer)\n }\n\n public editBufferClear(buffer: Pointer): void {\n this.opentui.symbols.editBufferClear(buffer)\n }\n\n public editBufferGetNextWordBoundary(buffer: Pointer): LogicalCursor {\n const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size)\n this.opentui.symbols.editBufferGetNextWordBoundary(buffer, ptr(cursorBuffer))\n return LogicalCursorStruct.unpack(cursorBuffer)\n }\n\n public editBufferGetPrevWordBoundary(buffer: Pointer): LogicalCursor {\n const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size)\n this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, ptr(cursorBuffer))\n return LogicalCursorStruct.unpack(cursorBuffer)\n }\n\n public editBufferGetEOL(buffer: Pointer): LogicalCursor {\n const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size)\n this.opentui.symbols.editBufferGetEOL(buffer, ptr(cursorBuffer))\n return LogicalCursorStruct.unpack(cursorBuffer)\n }\n\n public editBufferOffsetToPosition(buffer: Pointer, offset: number): LogicalCursor | null {\n const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size)\n const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, ptr(cursorBuffer))\n if (!success) return null\n return LogicalCursorStruct.unpack(cursorBuffer)\n }\n\n public editBufferPositionToOffset(buffer: Pointer, row: number, col: number): number {\n return this.opentui.symbols.editBufferPositionToOffset(buffer, row, col)\n }\n\n public editBufferGetLineStartOffset(buffer: Pointer, row: number): number {\n return this.opentui.symbols.editBufferGetLineStartOffset(buffer, row)\n }\n\n public editBufferGetTextRange(\n buffer: Pointer,\n startOffset: number,\n endOffset: number,\n maxLength: number,\n ): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n const actualLen = this.opentui.symbols.editBufferGetTextRange(\n buffer,\n startOffset,\n endOffset,\n ptrOrNull(outBuffer),\n maxLength,\n )\n const len = actualLen\n if (len === 0) return null\n return outBuffer.slice(0, len)\n }\n\n public editBufferGetTextRangeByCoords(\n buffer: Pointer,\n startRow: number,\n startCol: number,\n endRow: number,\n endCol: number,\n maxLength: number,\n ): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n const actualLen = this.opentui.symbols.editBufferGetTextRangeByCoords(\n buffer,\n startRow,\n startCol,\n endRow,\n endCol,\n ptrOrNull(outBuffer),\n maxLength,\n )\n const len = actualLen\n if (len === 0) return null\n return outBuffer.slice(0, len)\n }\n\n // EditorView selection and editing implementations\n public editorViewSetSelection(\n view: Pointer,\n start: number,\n end: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n ): void {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n this.opentui.symbols.editorViewSetSelection(view, start, end, bg, fg)\n }\n\n public editorViewResetSelection(view: Pointer): void {\n this.opentui.symbols.editorViewResetSelection(view)\n }\n\n public editorViewGetSelection(view: Pointer): { start: number; end: number } | null {\n const packedInfo = this.opentui.symbols.editorViewGetSelection(view)\n if (packedInfo === 0xffff_ffff_ffff_ffffn) {\n return null\n }\n const start = Number(packedInfo >> 32n)\n const end = Number(packedInfo & 0xffff_ffffn)\n return { start, end }\n }\n\n public editorViewSetLocalSelection(\n view: Pointer,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n updateCursor: boolean,\n followCursor: boolean,\n ): boolean {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n return Boolean(\n this.opentui.symbols.editorViewSetLocalSelection(\n view,\n anchorX,\n anchorY,\n focusX,\n focusY,\n bg,\n fg,\n ffiBool(updateCursor),\n ffiBool(followCursor),\n ),\n )\n }\n\n public editorViewUpdateSelection(view: Pointer, end: number, bgColor: RGBA | null, fgColor: RGBA | null): void {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n this.opentui.symbols.editorViewUpdateSelection(view, end, bg, fg)\n }\n\n public editorViewUpdateLocalSelection(\n view: Pointer,\n anchorX: number,\n anchorY: number,\n focusX: number,\n focusY: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null,\n updateCursor: boolean,\n followCursor: boolean,\n ): boolean {\n const bg = optionalRgbaPtr(bgColor)\n const fg = optionalRgbaPtr(fgColor)\n return Boolean(\n this.opentui.symbols.editorViewUpdateLocalSelection(\n view,\n anchorX,\n anchorY,\n focusX,\n focusY,\n bg,\n fg,\n ffiBool(updateCursor),\n ffiBool(followCursor),\n ),\n )\n }\n\n public editorViewResetLocalSelection(view: Pointer): void {\n this.opentui.symbols.editorViewResetLocalSelection(view)\n }\n\n public editorViewGetSelectedTextBytes(view: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n const actualLen = this.opentui.symbols.editorViewGetSelectedTextBytes(view, ptrOrNull(outBuffer), maxLength)\n const len = actualLen\n if (len === 0) return null\n return outBuffer.slice(0, len)\n }\n\n public editorViewGetCursor(view: Pointer): { row: number; col: number } {\n const row = new Uint32Array(1)\n const col = new Uint32Array(1)\n this.opentui.symbols.editorViewGetCursor(view, ptr(row), ptr(col))\n return { row: row[0], col: col[0] }\n }\n\n public editorViewGetText(view: Pointer, maxLength: number): Uint8Array | null {\n const outBuffer = new Uint8Array(maxLength)\n const actualLen = this.opentui.symbols.editorViewGetText(view, ptrOrNull(outBuffer), maxLength)\n const len = actualLen\n if (len === 0) return null\n return outBuffer.slice(0, len)\n }\n\n public editorViewGetVisualCursor(view: Pointer): VisualCursor {\n const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size)\n this.opentui.symbols.editorViewGetVisualCursor(view, ptr(cursorBuffer))\n return VisualCursorStruct.unpack(cursorBuffer)\n }\n\n public editorViewMoveUpVisual(view: Pointer): void {\n this.opentui.symbols.editorViewMoveUpVisual(view)\n }\n\n public editorViewMoveDownVisual(view: Pointer): void {\n this.opentui.symbols.editorViewMoveDownVisual(view)\n }\n\n public editorViewDeleteSelectedText(view: Pointer): void {\n this.opentui.symbols.editorViewDeleteSelectedText(view)\n }\n\n public editorViewSetCursorByOffset(view: Pointer, offset: number): void {\n this.opentui.symbols.editorViewSetCursorByOffset(view, offset)\n }\n\n public editorViewGetNextWordBoundary(view: Pointer): VisualCursor {\n const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size)\n this.opentui.symbols.editorViewGetNextWordBoundary(view, ptr(cursorBuffer))\n return VisualCursorStruct.unpack(cursorBuffer)\n }\n\n public editorViewGetPrevWordBoundary(view: Pointer): VisualCursor {\n const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size)\n this.opentui.symbols.editorViewGetPrevWordBoundary(view, ptr(cursorBuffer))\n return VisualCursorStruct.unpack(cursorBuffer)\n }\n\n public editorViewGetEOL(view: Pointer): VisualCursor {\n const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size)\n this.opentui.symbols.editorViewGetEOL(view, ptr(cursorBuffer))\n return VisualCursorStruct.unpack(cursorBuffer)\n }\n\n public editorViewGetVisualSOL(view: Pointer): VisualCursor {\n const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size)\n this.opentui.symbols.editorViewGetVisualSOL(view, ptr(cursorBuffer))\n return VisualCursorStruct.unpack(cursorBuffer)\n }\n\n public editorViewGetVisualEOL(view: Pointer): VisualCursor {\n const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size)\n this.opentui.symbols.editorViewGetVisualEOL(view, ptr(cursorBuffer))\n return VisualCursorStruct.unpack(cursorBuffer)\n }\n\n public bufferPushScissorRect(buffer: Pointer, x: number, y: number, width: number, height: number): void {\n this.opentui.symbols.bufferPushScissorRect(buffer, x, y, width, height)\n }\n\n public bufferPopScissorRect(buffer: Pointer): void {\n this.opentui.symbols.bufferPopScissorRect(buffer)\n }\n\n public bufferClearScissorRects(buffer: Pointer): void {\n this.opentui.symbols.bufferClearScissorRects(buffer)\n }\n\n public bufferPushOpacity(buffer: Pointer, opacity: number): void {\n this.opentui.symbols.bufferPushOpacity(buffer, opacity)\n }\n\n public bufferPopOpacity(buffer: Pointer): void {\n this.opentui.symbols.bufferPopOpacity(buffer)\n }\n\n public bufferGetCurrentOpacity(buffer: Pointer): number {\n return this.opentui.symbols.bufferGetCurrentOpacity(buffer)\n }\n\n public bufferClearOpacity(buffer: Pointer): void {\n this.opentui.symbols.bufferClearOpacity(buffer)\n }\n\n public getTerminalCapabilities(renderer: Pointer): TerminalCapabilities {\n const capsBuffer = new ArrayBuffer(TerminalCapabilitiesStruct.size)\n this.opentui.symbols.getTerminalCapabilities(renderer, ptr(capsBuffer))\n\n const caps = TerminalCapabilitiesStruct.unpack(capsBuffer)\n\n return {\n kitty_keyboard: caps.kitty_keyboard,\n kitty_graphics: caps.kitty_graphics,\n rgb: caps.rgb,\n ansi256: caps.ansi256,\n unicode: caps.unicode,\n sgr_pixels: caps.sgr_pixels,\n color_scheme_updates: caps.color_scheme_updates,\n explicit_width: caps.explicit_width,\n scaled_text: caps.scaled_text,\n sixel: caps.sixel,\n focus_tracking: caps.focus_tracking,\n sync: caps.sync,\n bracketed_paste: caps.bracketed_paste,\n hyperlinks: caps.hyperlinks,\n osc52: caps.osc52,\n notifications: caps.notifications,\n explicit_cursor_positioning: caps.explicit_cursor_positioning,\n remote: caps.remote,\n multiplexer: caps.multiplexer,\n terminal: {\n name: caps.term_name ?? \"\",\n version: caps.term_version ?? \"\",\n from_xtversion: caps.term_from_xtversion,\n },\n }\n }\n\n public processCapabilityResponse(renderer: Pointer, response: string): void {\n const responseBytes = this.encoder.encode(response)\n this.opentui.symbols.processCapabilityResponse(renderer, ptrOrNull(responseBytes), responseBytes.byteLength)\n }\n\n public encodeUnicode(\n text: string,\n widthMethod: WidthMethod,\n ): { ptr: Pointer; data: Array<{ width: number; char: number }> } | null {\n const textBytes = this.encoder.encode(text)\n const widthMethodCode = widthMethod === \"wcwidth\" ? 0 : 1\n\n const outPtrBuffer = new ArrayBuffer(8) // Pointer-sized out slot\n const outLenBuffer = new ArrayBuffer(8) // Native length out slot\n\n const success = this.opentui.symbols.encodeUnicode(\n ptrOrNull(textBytes),\n textBytes.byteLength,\n ptr(outPtrBuffer),\n ptr(outLenBuffer),\n widthMethodCode,\n )\n\n if (!success) {\n return null\n }\n\n const outPtrView = new BigUint64Array(outPtrBuffer)\n const outLenView = new BigUint64Array(outLenBuffer)\n\n const resultLen = Number(outLenView[0])\n\n if (resultLen === 0) {\n return { ptr: 0 as Pointer, data: [] }\n }\n\n const resultPtr = toPointer(outPtrView[0])\n\n // Convert pointer to ArrayBuffer and use EncodedCharStruct to unpack the list\n const byteLen = resultLen * EncodedCharStruct.size\n const raw = toArrayBuffer(resultPtr, 0, byteLen)\n const data = EncodedCharStruct.unpackList(raw, resultLen)\n\n return { ptr: resultPtr, data }\n }\n\n public freeUnicode(encoded: { ptr: Pointer; data: Array<{ width: number; char: number }> }): void {\n this.opentui.symbols.freeUnicode(encoded.ptr, encoded.data.length)\n }\n\n public bufferDrawChar(\n buffer: Pointer,\n char: number,\n x: number,\n y: number,\n fg: RGBA,\n bg: RGBA,\n attributes: number = 0,\n ): void {\n this.opentui.symbols.bufferDrawChar(buffer, char, x, y, rgbaPtr(fg), rgbaPtr(bg), attributes)\n }\n\n public createAudioEngine(options?: AudioCreateOptions | null): AudioEngineHandle | null {\n const optionsBuffer = options == null ? null : AudioCreateOptionsStruct.pack(options)\n const engineHandle = this.opentui.symbols.createAudioEngine(\n optionsBuffer ? ptr(optionsBuffer) : null,\n ) as AudioEngineHandle\n return engineHandle ? engineHandle : null\n }\n\n public destroyAudioEngine(engine: AudioEngineHandle): void {\n this.opentui.symbols.destroyAudioEngine(engine)\n }\n\n public audioRefreshPlaybackDevices(engine: Pointer): number {\n return this.opentui.symbols.audioRefreshPlaybackDevices(engine)\n }\n\n public audioGetPlaybackDeviceCount(engine: Pointer): number {\n return this.opentui.symbols.audioGetPlaybackDeviceCount(engine)\n }\n\n public audioGetPlaybackDeviceName(engine: Pointer, index: number): string {\n const outBuffer = new Uint8Array(512)\n const bytesWritten = toNumber(\n this.opentui.symbols.audioGetPlaybackDeviceName(engine, index, ptr(outBuffer), outBuffer.length),\n )\n const safeBytesWritten = Math.max(0, Math.min(outBuffer.length, bytesWritten))\n return this.decoder.decode(outBuffer.subarray(0, safeBytesWritten))\n }\n\n public audioIsPlaybackDeviceDefault(engine: Pointer, index: number): boolean {\n return this.opentui.symbols.audioIsPlaybackDeviceDefault(engine, index)\n }\n\n public audioSelectPlaybackDevice(engine: Pointer, index: number): number {\n return this.opentui.symbols.audioSelectPlaybackDevice(engine, index)\n }\n\n public audioClearPlaybackDeviceSelection(engine: Pointer): void {\n this.opentui.symbols.audioClearPlaybackDeviceSelection(engine)\n }\n\n public audioStart(engine: Pointer, options?: AudioStartOptions | null): number {\n const optionsBuffer = options == null ? null : AudioStartOptionsStruct.pack(options)\n return this.opentui.symbols.audioStart(engine, optionsBuffer ? ptr(optionsBuffer) : null)\n }\n\n public audioStartMixer(engine: Pointer): number {\n return this.opentui.symbols.audioStartMixer(engine)\n }\n\n public audioStop(engine: Pointer): number {\n return this.opentui.symbols.audioStop(engine)\n }\n\n public audioLoad(engine: Pointer, data: Uint8Array): { status: number; soundId: number | null } {\n const outBuffer = new ArrayBuffer(4)\n const dataLength = toSafeFFIU32Length(data.byteLength, \"Audio data length\")\n const status = this.opentui.symbols.audioLoad(engine, ptr(data), dataLength, ptr(outBuffer))\n if (status !== 0) {\n return { status, soundId: null }\n }\n const view = new Uint32Array(outBuffer)\n return { status, soundId: view[0] }\n }\n\n public audioUnload(engine: Pointer, soundId: number): number {\n return this.opentui.symbols.audioUnload(engine, soundId)\n }\n\n public audioPlay(\n engine: Pointer,\n soundId: number,\n options?: AudioVoiceOptions,\n ): { status: number; voiceId: number | null } {\n const outBuffer = new ArrayBuffer(4)\n const optionsBuffer = options ? AudioVoiceOptionsStruct.pack(options) : null\n const status = this.opentui.symbols.audioPlay(\n engine,\n soundId,\n optionsBuffer ? ptr(optionsBuffer) : null,\n ptr(outBuffer),\n )\n if (status !== 0) {\n return { status, voiceId: null }\n }\n const view = new Uint32Array(outBuffer)\n return { status, voiceId: view[0] }\n }\n\n public audioStopVoice(engine: Pointer, voiceId: number): number {\n return this.opentui.symbols.audioStopVoice(engine, voiceId)\n }\n\n public audioSetVoiceGroup(engine: Pointer, voiceId: number, groupId: number): number {\n return this.opentui.symbols.audioSetVoiceGroup(engine, voiceId, groupId)\n }\n\n public audioCreateGroup(engine: Pointer, name: string): { status: number; groupId: number | null } {\n const outBuffer = new ArrayBuffer(4)\n const nameBytes = this.encoder.encode(name)\n const nameLength = toSafeFFIU32Length(nameBytes.byteLength, \"Audio group name length\")\n const status = this.opentui.symbols.audioCreateGroup(engine, ptr(nameBytes), nameLength, ptr(outBuffer))\n if (status !== 0) {\n return { status, groupId: null }\n }\n const view = new Uint32Array(outBuffer)\n return { status, groupId: view[0] }\n }\n\n public audioSetGroupVolume(engine: Pointer, groupId: number, volume: number): number {\n return this.opentui.symbols.audioSetGroupVolume(engine, groupId, volume)\n }\n\n public audioSetMasterVolume(engine: Pointer, volume: number): number {\n return this.opentui.symbols.audioSetMasterVolume(engine, volume)\n }\n\n public audioMixToBuffer(engine: Pointer, outBuffer: Float32Array, frameCount: number, channels: number): number {\n return this.opentui.symbols.audioMixToBuffer(engine, ptr(outBuffer), frameCount, channels)\n }\n\n public audioEnableTap(engine: Pointer, enabled: boolean, capacityFrames: number): number {\n return this.opentui.symbols.audioEnableTap(engine, ffiBool(enabled), capacityFrames)\n }\n\n public audioReadTap(\n engine: Pointer,\n outBuffer: Float32Array,\n frameCount: number,\n channels: number,\n ): { status: number; framesRead: number } {\n const outFramesReadBuffer = new ArrayBuffer(4)\n const status = this.opentui.symbols.audioReadTap(\n engine,\n ptr(outBuffer),\n frameCount,\n channels,\n ptr(outFramesReadBuffer),\n )\n if (status !== 0) {\n return { status, framesRead: 0 }\n }\n const view = new Uint32Array(outFramesReadBuffer)\n return { status, framesRead: view[0] ?? 0 }\n }\n\n public audioGetStats(engine: Pointer): AudioStats | null {\n const statsBuffer = new ArrayBuffer(AudioStatsStruct.size)\n const status = this.opentui.symbols.audioGetStats(engine, ptr(statsBuffer))\n if (status !== 0) {\n return null\n }\n const stats = AudioStatsStruct.unpack(statsBuffer)\n return {\n soundsLoaded: stats.soundsLoaded,\n voicesActive: stats.voicesActive,\n framesMixed: typeof stats.framesMixed === \"bigint\" ? stats.framesMixed : BigInt(stats.framesMixed),\n lockMisses: stats.lockMisses,\n lastPeak: stats.lastPeak,\n lastRms: stats.lastRms,\n }\n }\n\n public registerNativeSpanFeedStream(stream: Pointer, handler: NativeSpanFeedEventHandler): void {\n const callback = this.ensureNativeSpanFeedCallback()\n this.nativeSpanFeedHandlers.set(stream, handler)\n this.opentui.symbols.streamSetCallback(stream, callback.ptr)\n }\n\n public unregisterNativeSpanFeedStream(stream: Pointer): void {\n this.opentui.symbols.streamSetCallback(stream, null)\n this.nativeSpanFeedHandlers.delete(stream)\n }\n\n public createNativeSpanFeed(options?: NativeSpanFeedOptions | null): Pointer {\n const optionsBuffer = options == null ? null : NativeSpanFeedOptionsStruct.pack(options)\n const streamPtr = this.opentui.symbols.createNativeSpanFeed(optionsBuffer ? ptr(optionsBuffer) : null)\n if (!streamPtr) {\n throw new Error(\"Failed to create stream\")\n }\n return streamPtr\n }\n\n public attachNativeSpanFeed(stream: Pointer): number {\n return this.opentui.symbols.attachNativeSpanFeed(stream)\n }\n\n public destroyNativeSpanFeed(stream: Pointer): void {\n this.opentui.symbols.destroyNativeSpanFeed(stream)\n this.nativeSpanFeedHandlers.delete(stream)\n }\n\n public streamWrite(stream: Pointer, data: Uint8Array | string): number {\n const bytes = typeof data === \"string\" ? this.encoder.encode(data) : data\n return this.opentui.symbols.streamWrite(stream, ptrOrNull(bytes), bytes.byteLength)\n }\n\n public streamCommit(stream: Pointer): number {\n return this.opentui.symbols.streamCommit(stream)\n }\n\n public streamDrainSpans(stream: Pointer, outBuffer: Uint8Array, maxSpans: number): number {\n const count = this.opentui.symbols.streamDrainSpans(stream, ptr(outBuffer), maxSpans)\n return toNumber(count)\n }\n\n public streamClose(stream: Pointer): number {\n return this.opentui.symbols.streamClose(stream)\n }\n\n public streamSetOptions(stream: Pointer, options: NativeSpanFeedOptions): number {\n const optionsBuffer = NativeSpanFeedOptionsStruct.pack(options)\n return this.opentui.symbols.streamSetOptions(stream, ptr(optionsBuffer))\n }\n\n public streamGetStats(stream: Pointer): NativeSpanFeedStats | null {\n const statsBuffer = new ArrayBuffer(NativeSpanFeedStatsStruct.size)\n const status = this.opentui.symbols.streamGetStats(stream, ptr(statsBuffer))\n if (status !== 0) {\n return null\n }\n const stats = NativeSpanFeedStatsStruct.unpack(statsBuffer)\n return {\n bytesWritten: typeof stats.bytesWritten === \"bigint\" ? stats.bytesWritten : BigInt(stats.bytesWritten),\n spansCommitted: typeof stats.spansCommitted === \"bigint\" ? stats.spansCommitted : BigInt(stats.spansCommitted),\n chunks: stats.chunks,\n pendingSpans: stats.pendingSpans,\n }\n }\n\n public streamReserve(stream: Pointer, minLen: number): { status: number; info: ReserveInfo | null } {\n const reserveBuffer = new ArrayBuffer(ReserveInfoStruct.size)\n const status = this.opentui.symbols.streamReserve(stream, minLen, ptr(reserveBuffer))\n if (status !== 0) {\n return { status, info: null }\n }\n return { status, info: ReserveInfoStruct.unpack(reserveBuffer) }\n }\n\n public streamCommitReserved(stream: Pointer, length: number): number {\n return this.opentui.symbols.streamCommitReserved(stream, length)\n }\n\n public createSyntaxStyle(): SyntaxStyleHandle {\n const styleHandle = this.opentui.symbols.createSyntaxStyle() as SyntaxStyleHandle\n if (!styleHandle) {\n throw new Error(\"Failed to create SyntaxStyle\")\n }\n return styleHandle\n }\n\n public destroySyntaxStyle(style: SyntaxStyleHandle): void {\n this.opentui.symbols.destroySyntaxStyle(style)\n }\n\n public syntaxStyleRegister(\n style: SyntaxStyleHandle,\n name: string,\n fg: RGBA | null,\n bg: RGBA | null,\n attributes: number,\n ): number {\n const nameBytes = this.encoder.encode(name)\n const fgPtr = optionalRgbaPtr(fg)\n const bgPtr = optionalRgbaPtr(bg)\n return this.opentui.symbols.syntaxStyleRegister(\n style,\n ptrOrNull(nameBytes),\n nameBytes.byteLength,\n fgPtr,\n bgPtr,\n attributes,\n )\n }\n\n public syntaxStyleResolveByName(style: SyntaxStyleHandle, name: string): number | null {\n const nameBytes = this.encoder.encode(name)\n const id = this.opentui.symbols.syntaxStyleResolveByName(style, ptrOrNull(nameBytes), nameBytes.byteLength)\n return id === 0 ? null : id\n }\n\n public syntaxStyleGetStyleCount(style: SyntaxStyleHandle): number {\n return this.opentui.symbols.syntaxStyleGetStyleCount(style)\n }\n\n public editorViewSetPlaceholderStyledText(\n view: EditorViewHandle,\n chunks: Array<{ text: string; fg?: RGBA | null; bg?: RGBA | null; attributes?: number }>,\n ): void {\n const nonEmptyChunks = chunks.filter((c) => c.text.length > 0)\n if (nonEmptyChunks.length === 0) {\n this.opentui.symbols.editorViewSetPlaceholderStyledText(view, null, 0)\n return\n }\n\n const chunksBuffer = StyledChunkStruct.packList(nonEmptyChunks)\n this.opentui.symbols.editorViewSetPlaceholderStyledText(view, ptr(chunksBuffer), nonEmptyChunks.length)\n }\n\n public editorViewSetTabIndicator(view: EditorViewHandle, indicator: number): void {\n this.opentui.symbols.editorViewSetTabIndicator(view, indicator)\n }\n\n public editorViewSetTabIndicatorColor(view: EditorViewHandle, color: RGBA): void {\n this.opentui.symbols.editorViewSetTabIndicatorColor(view, rgbaPtr(color))\n }\n\n public onNativeEvent(name: string, handler: (data: ArrayBuffer) => void): void {\n this._nativeEvents.on(name, handler)\n }\n\n public onceNativeEvent(name: string, handler: (data: ArrayBuffer) => void): void {\n this._nativeEvents.once(name, handler)\n }\n\n public offNativeEvent(name: string, handler: (data: ArrayBuffer) => void): void {\n this._nativeEvents.off(name, handler)\n }\n\n public onAnyNativeEvent(handler: (name: string, data: ArrayBuffer) => void): void {\n this._anyEventHandlers.push(handler)\n }\n}\n\nlet opentuiLibPath: string | undefined\nlet opentuiLib: RenderLib | undefined\nlet renderLibResolved = false\n\nexport function setRenderLibPath(libPath: string) {\n if (opentuiLibPath !== libPath) {\n if (renderLibResolved) {\n throw new Error(\"setRenderLibPath() must be called before resolveRenderLib()\")\n }\n if (opentuiLib instanceof FFIRenderLib) {\n opentuiLib.dispose()\n }\n opentuiLibPath = libPath\n opentuiLib = undefined\n }\n}\n\nexport function resolveRenderLib(): RenderLib {\n if (!opentuiLib) {\n try {\n opentuiLib = new FFIRenderLib(opentuiLibPath)\n } catch (error) {\n throw new Error(\n `Failed to initialize OpenTUI render library: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n )\n }\n }\n renderLibResolved = true\n return opentuiLib\n}\n\n// Try eager loading\ntry {\n opentuiLib = new FFIRenderLib(opentuiLibPath)\n} catch (error) {}\n", + "export type RGBTriplet = readonly [number, number, number]\nexport type ColorIntent = \"rgb\" | \"indexed\" | \"default\"\nexport type ColorInput = string | RGBA\n\nexport const DEFAULT_FOREGROUND_RGB: RGBTriplet = [255, 255, 255]\nexport const DEFAULT_BACKGROUND_RGB: RGBTriplet = [0, 0, 0]\n\nconst INTENT_RGB = 0\nconst INTENT_INDEXED = 1\nconst INTENT_DEFAULT = 2\n\nconst ANSI16_RGB: readonly RGBTriplet[] = [\n [0x00, 0x00, 0x00],\n [0x80, 0x00, 0x00],\n [0x00, 0x80, 0x00],\n [0x80, 0x80, 0x00],\n [0x00, 0x00, 0x80],\n [0x80, 0x00, 0x80],\n [0x00, 0x80, 0x80],\n [0xc0, 0xc0, 0xc0],\n [0x80, 0x80, 0x80],\n [0xff, 0x00, 0x00],\n [0x00, 0xff, 0x00],\n [0xff, 0xff, 0x00],\n [0x00, 0x00, 0xff],\n [0xff, 0x00, 0xff],\n [0x00, 0xff, 0xff],\n [0xff, 0xff, 0xff],\n]\n\nconst ANSI_256_CUBE_LEVELS = [0, 95, 135, 175, 215, 255] as const\n\nexport interface NormalizedColorValue {\n rgba: RGBA\n}\n\nfunction packMeta(intent: number, slot = 0): number {\n return ((slot & 0xff) | ((intent & 0xff) << 8)) >>> 0\n}\n\nfunction toU8(value: number): number {\n return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255)\n}\n\nfunction toByte(value: number): number {\n return Math.round(Math.max(0, Math.min(255, Number.isFinite(value) ? value : 0)))\n}\n\nfunction packRGBA8(r: number, g: number, b: number, a: number, meta: number): Uint16Array {\n return new Uint16Array([\n (toByte(r) & 0xff) | (((meta >>> 0) & 0xff) << 8),\n (toByte(g) & 0xff) | (((meta >>> 8) & 0xff) << 8),\n (toByte(b) & 0xff) | (((meta >>> 16) & 0xff) << 8),\n (toByte(a) & 0xff) | (((meta >>> 24) & 0xff) << 8),\n ])\n}\n\nfunction rgbaForAnsi256Index(index: number): RGBA {\n const [r, g, b] = ansi256IndexToRgb(index)\n return RGBA.fromInts(r, g, b)\n}\n\nexport function normalizeIndexedColorIndex(index: number): number {\n if (!Number.isInteger(index) || index < 0 || index > 255) {\n throw new RangeError(`Indexed color must be an integer in the range 0..255, got ${index}`)\n }\n\n return index\n}\n\nexport function ansi256IndexToRgb(index: number): RGBTriplet {\n const normalizedIndex = normalizeIndexedColorIndex(index)\n\n if (normalizedIndex < ANSI16_RGB.length) {\n return ANSI16_RGB[normalizedIndex]\n }\n\n if (normalizedIndex < 232) {\n const cubeIndex = normalizedIndex - 16\n const r = Math.floor(cubeIndex / 36)\n const g = Math.floor(cubeIndex / 6) % 6\n const b = cubeIndex % 6\n return [ANSI_256_CUBE_LEVELS[r], ANSI_256_CUBE_LEVELS[g], ANSI_256_CUBE_LEVELS[b]]\n }\n\n const value = 8 + (normalizedIndex - 232) * 10\n return [value, value, value]\n}\n\nexport class RGBA {\n buffer: Uint16Array\n\n constructor(buffer: Uint16Array) {\n this.buffer = new Uint16Array(4)\n this.buffer.set(buffer.subarray(0, 4))\n }\n\n static fromArray(array: Uint16Array): RGBA {\n return new RGBA(array)\n }\n\n static fromValues(r: number, g: number, b: number, a: number = 1): RGBA {\n return new RGBA(packRGBA8(toU8(r), toU8(g), toU8(b), toU8(a), packMeta(INTENT_RGB)))\n }\n\n static clone(rgba: RGBA): RGBA {\n return new RGBA(rgba.buffer)\n }\n\n static fromInts(r: number, g: number, b: number, a: number = 255): RGBA {\n return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_RGB)))\n }\n\n static fromHex(hex: string): RGBA {\n return hexToRgb(hex)\n }\n\n static fromIndex(index: number, snapshot?: ColorInput): RGBA {\n const normalized = normalizeIndexedColorIndex(index)\n const rgba = snapshot ? parseColor(snapshot) : rgbaForAnsi256Index(normalized)\n const [r, g, b, a] = rgba.toInts()\n return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_INDEXED, normalized)))\n }\n\n static defaultForeground(snapshot?: ColorInput): RGBA {\n const rgba = snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_FOREGROUND_RGB)\n const [r, g, b, a] = rgba.toInts()\n return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_DEFAULT)))\n }\n\n static defaultBackground(snapshot?: ColorInput): RGBA {\n const rgba = snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_BACKGROUND_RGB)\n const [r, g, b, a] = rgba.toInts()\n return new RGBA(packRGBA8(r, g, b, a, packMeta(INTENT_DEFAULT)))\n }\n\n toInts(): [number, number, number, number] {\n return [this.buffer[0] & 0xff, this.buffer[1] & 0xff, this.buffer[2] & 0xff, this.buffer[3] & 0xff]\n }\n\n get r(): number {\n return (this.buffer[0] & 0xff) / 255\n }\n\n set r(value: number) {\n this.buffer[0] = (this.buffer[0] & 0xff00) | toU8(value)\n }\n\n get g(): number {\n return (this.buffer[1] & 0xff) / 255\n }\n\n set g(value: number) {\n this.buffer[1] = (this.buffer[1] & 0xff00) | toU8(value)\n }\n\n get b(): number {\n return (this.buffer[2] & 0xff) / 255\n }\n\n set b(value: number) {\n this.buffer[2] = (this.buffer[2] & 0xff00) | toU8(value)\n }\n\n get a(): number {\n return (this.buffer[3] & 0xff) / 255\n }\n\n set a(value: number) {\n this.buffer[3] = (this.buffer[3] & 0xff00) | toU8(value)\n }\n\n get meta(): number {\n return (\n ((this.buffer[0] >>> 8) |\n ((this.buffer[1] >>> 8) << 8) |\n ((this.buffer[2] >>> 8) << 16) |\n ((this.buffer[3] >>> 8) << 24)) >>>\n 0\n )\n }\n\n get intent(): ColorIntent {\n switch ((this.meta >>> 8) & 0xff) {\n case INTENT_INDEXED:\n return \"indexed\"\n case INTENT_DEFAULT:\n return \"default\"\n default:\n return \"rgb\"\n }\n }\n\n get slot(): number {\n return this.meta & 0xff\n }\n\n map(fn: (value: number) => R): [R, R, R, R] {\n return [fn(this.r), fn(this.g), fn(this.b), fn(this.a)]\n }\n\n toString(): string {\n return `rgba(${this.r.toFixed(2)}, ${this.g.toFixed(2)}, ${this.b.toFixed(2)}, ${this.a.toFixed(2)})`\n }\n\n equals(other?: RGBA): boolean {\n if (!other) return false\n return (\n this.buffer[0] === other.buffer[0] &&\n this.buffer[1] === other.buffer[1] &&\n this.buffer[2] === other.buffer[2] &&\n this.buffer[3] === other.buffer[3]\n )\n }\n}\n\nexport function normalizeColorValue(value: ColorInput | null | undefined): NormalizedColorValue | null {\n if (value == null) return null\n return { rgba: parseColor(value) }\n}\n\nexport function hexToRgb(hex: string): RGBA {\n hex = hex.replace(/^#/, \"\")\n\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]\n } else if (hex.length === 4) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3]\n }\n\n if (!/^[0-9A-Fa-f]{6}$/.test(hex) && !/^[0-9A-Fa-f]{8}$/.test(hex)) {\n console.warn(`Invalid hex color: ${hex}, defaulting to magenta`)\n return RGBA.fromValues(1, 0, 1, 1)\n }\n\n const r = parseInt(hex.substring(0, 2), 16)\n const g = parseInt(hex.substring(2, 4), 16)\n const b = parseInt(hex.substring(4, 6), 16)\n const a = hex.length === 8 ? parseInt(hex.substring(6, 8), 16) : 255\n\n return RGBA.fromInts(r, g, b, a)\n}\n\nexport function rgbToHex(rgb: RGBA): string {\n const [r, g, b, a] = rgb.toInts()\n const components = a === 255 ? [r, g, b] : [r, g, b, a]\n return \"#\" + components.map((x) => x.toString(16).padStart(2, \"0\")).join(\"\")\n}\n\nexport function hsvToRgb(h: number, s: number, v: number): RGBA {\n let r = 0,\n g = 0,\n b = 0\n\n const i = Math.floor(h / 60) % 6\n const f = h / 60 - Math.floor(h / 60)\n const p = v * (1 - s)\n const q = v * (1 - f * s)\n const t = v * (1 - (1 - f) * s)\n\n switch (i) {\n case 0:\n r = v\n g = t\n b = p\n break\n case 1:\n r = q\n g = v\n b = p\n break\n case 2:\n r = p\n g = v\n b = t\n break\n case 3:\n r = p\n g = q\n b = v\n break\n case 4:\n r = t\n g = p\n b = v\n break\n case 5:\n r = v\n g = p\n b = q\n break\n }\n\n return RGBA.fromValues(r, g, b, 1)\n}\n\nconst CSS_COLOR_NAMES: Record = {\n black: \"#000000\",\n white: \"#FFFFFF\",\n red: \"#FF0000\",\n green: \"#008000\",\n blue: \"#0000FF\",\n yellow: \"#FFFF00\",\n cyan: \"#00FFFF\",\n magenta: \"#FF00FF\",\n silver: \"#C0C0C0\",\n gray: \"#808080\",\n grey: \"#808080\",\n maroon: \"#800000\",\n olive: \"#808000\",\n lime: \"#00FF00\",\n aqua: \"#00FFFF\",\n teal: \"#008080\",\n navy: \"#000080\",\n fuchsia: \"#FF00FF\",\n purple: \"#800080\",\n orange: \"#FFA500\",\n brightblack: \"#666666\",\n brightred: \"#FF6666\",\n brightgreen: \"#66FF66\",\n brightblue: \"#6666FF\",\n brightyellow: \"#FFFF66\",\n brightcyan: \"#66FFFF\",\n brightmagenta: \"#FF66FF\",\n brightwhite: \"#FFFFFF\",\n}\n\nexport function parseColor(color: ColorInput): RGBA {\n if (typeof color === \"string\") {\n const lowerColor = color.toLowerCase()\n\n if (lowerColor === \"transparent\") {\n return RGBA.fromValues(0, 0, 0, 0)\n }\n\n if (CSS_COLOR_NAMES[lowerColor]) {\n return hexToRgb(CSS_COLOR_NAMES[lowerColor])\n }\n\n return hexToRgb(color)\n }\n return color\n}\n", + "import type { ColorInput } from \"./RGBA.js\"\n\nexport interface BorderCharacters {\n topLeft: string\n topRight: string\n bottomLeft: string\n bottomRight: string\n horizontal: string\n vertical: string\n topT: string\n bottomT: string\n leftT: string\n rightT: string\n cross: string\n}\n\nexport type BorderStyle = \"single\" | \"double\" | \"rounded\" | \"heavy\"\nexport type BorderSides = \"top\" | \"right\" | \"bottom\" | \"left\"\n\nconst VALID_BORDER_STYLES: readonly BorderStyle[] = [\"single\", \"double\", \"rounded\", \"heavy\"] as const\n\nexport function isValidBorderStyle(value: unknown): value is BorderStyle {\n return typeof value === \"string\" && VALID_BORDER_STYLES.includes(value as BorderStyle)\n}\n\nexport function parseBorderStyle(value: unknown, fallback: BorderStyle = \"single\"): BorderStyle {\n if (isValidBorderStyle(value)) {\n return value\n }\n\n if (value !== undefined && value !== null) {\n console.warn(\n `Invalid borderStyle \"${value}\", falling back to \"${fallback}\". Valid values are: ${VALID_BORDER_STYLES.join(\", \")}`,\n )\n }\n return fallback\n}\n\nexport const BorderChars: Record = {\n single: {\n topLeft: \"┌\",\n topRight: \"┐\",\n bottomLeft: \"└\",\n bottomRight: \"┘\",\n horizontal: \"─\",\n vertical: \"│\",\n topT: \"┬\",\n bottomT: \"┴\",\n leftT: \"├\",\n rightT: \"┤\",\n cross: \"┼\",\n },\n double: {\n topLeft: \"╔\",\n topRight: \"╗\",\n bottomLeft: \"╚\",\n bottomRight: \"╝\",\n horizontal: \"═\",\n vertical: \"║\",\n topT: \"╦\",\n bottomT: \"╩\",\n leftT: \"╠\",\n rightT: \"╣\",\n cross: \"╬\",\n },\n rounded: {\n topLeft: \"╭\",\n topRight: \"╮\",\n bottomLeft: \"╰\",\n bottomRight: \"╯\",\n horizontal: \"─\",\n vertical: \"│\",\n topT: \"┬\",\n bottomT: \"┴\",\n leftT: \"├\",\n rightT: \"┤\",\n cross: \"┼\",\n },\n heavy: {\n topLeft: \"┏\",\n topRight: \"┓\",\n bottomLeft: \"┗\",\n bottomRight: \"┛\",\n horizontal: \"━\",\n vertical: \"┃\",\n topT: \"┳\",\n bottomT: \"┻\",\n leftT: \"┣\",\n rightT: \"┫\",\n cross: \"╋\",\n },\n}\n\nexport interface BorderConfig {\n borderStyle: BorderStyle\n border: boolean | BorderSides[]\n borderColor?: ColorInput\n customBorderChars?: BorderCharacters\n}\n\nexport interface BoxDrawOptions {\n x: number\n y: number\n width: number\n height: number\n borderStyle: BorderStyle\n border: boolean | BorderSides[]\n borderColor: ColorInput\n customBorderChars?: BorderCharacters\n backgroundColor: ColorInput\n shouldFill?: boolean\n title?: string\n titleAlignment?: \"left\" | \"center\" | \"right\"\n bottomTitle?: string\n bottomTitleAlignment?: \"left\" | \"center\" | \"right\"\n}\n\nexport interface BorderSidesConfig {\n top: boolean\n right: boolean\n bottom: boolean\n left: boolean\n}\n\nexport function getBorderFromSides(sides: BorderSidesConfig): boolean | BorderSides[] {\n const result: BorderSides[] = []\n if (sides.top) result.push(\"top\")\n if (sides.right) result.push(\"right\")\n if (sides.bottom) result.push(\"bottom\")\n if (sides.left) result.push(\"left\")\n return result.length > 0 ? result : false\n}\n\nexport function getBorderSides(border: boolean | BorderSides[]): BorderSidesConfig {\n return border === true\n ? { top: true, right: true, bottom: true, left: true }\n : Array.isArray(border)\n ? {\n top: border.includes(\"top\"),\n right: border.includes(\"right\"),\n bottom: border.includes(\"bottom\"),\n left: border.includes(\"left\"),\n }\n : { top: false, right: false, bottom: false, left: false }\n}\n\n// Convert BorderCharacters to Uint32Array for passing to Zig\nexport function borderCharsToArray(chars: BorderCharacters): Uint32Array {\n const array = new Uint32Array(11)\n array[0] = chars.topLeft.codePointAt(0)!\n array[1] = chars.topRight.codePointAt(0)!\n array[2] = chars.bottomLeft.codePointAt(0)!\n array[3] = chars.bottomRight.codePointAt(0)!\n array[4] = chars.horizontal.codePointAt(0)!\n array[5] = chars.vertical.codePointAt(0)!\n array[6] = chars.topT.codePointAt(0)!\n array[7] = chars.bottomT.codePointAt(0)!\n array[8] = chars.leftT.codePointAt(0)!\n array[9] = chars.rightT.codePointAt(0)!\n array[10] = chars.cross.codePointAt(0)!\n return array\n}\n\n// Pre-converted border character arrays for performance\nexport const BorderCharArrays: Record = {\n single: borderCharsToArray(BorderChars.single),\n double: borderCharsToArray(BorderChars.double),\n rounded: borderCharsToArray(BorderChars.rounded),\n heavy: borderCharsToArray(BorderChars.heavy),\n}\n", + "import { EventEmitter } from \"events\"\nimport { type KeyEventType, type ParsedKey } from \"./parse.keypress.js\"\nimport type { PasteMetadata } from \"./paste.js\"\n\nexport class KeyEvent implements ParsedKey {\n name: string\n ctrl: boolean\n meta: boolean\n shift: boolean\n option: boolean\n sequence: string\n number: boolean\n raw: string\n eventType: KeyEventType\n source: \"raw\" | \"kitty\"\n code?: string\n super?: boolean\n hyper?: boolean\n capsLock?: boolean\n numLock?: boolean\n baseCode?: number\n repeated?: boolean\n\n private _defaultPrevented: boolean = false\n private _propagationStopped: boolean = false\n\n constructor(key: ParsedKey) {\n this.name = key.name\n this.ctrl = key.ctrl\n this.meta = key.meta\n this.shift = key.shift\n this.option = key.option\n this.sequence = key.sequence\n this.number = key.number\n this.raw = key.raw\n this.eventType = key.eventType\n this.source = key.source\n this.code = key.code\n this.super = key.super\n this.hyper = key.hyper\n this.capsLock = key.capsLock\n this.numLock = key.numLock\n this.baseCode = key.baseCode\n this.repeated = key.repeated\n }\n\n get defaultPrevented(): boolean {\n return this._defaultPrevented\n }\n\n get propagationStopped(): boolean {\n return this._propagationStopped\n }\n\n preventDefault(): void {\n this._defaultPrevented = true\n }\n\n stopPropagation(): void {\n this._propagationStopped = true\n }\n}\n\nexport class PasteEvent {\n type = \"paste\" as const\n bytes: Uint8Array\n metadata?: PasteMetadata\n private _defaultPrevented: boolean = false\n private _propagationStopped: boolean = false\n\n constructor(bytes: Uint8Array, metadata?: PasteMetadata) {\n this.bytes = bytes\n this.metadata = metadata\n }\n\n get defaultPrevented(): boolean {\n return this._defaultPrevented\n }\n\n get propagationStopped(): boolean {\n return this._propagationStopped\n }\n\n preventDefault(): void {\n this._defaultPrevented = true\n }\n\n stopPropagation(): void {\n this._propagationStopped = true\n }\n}\n\nexport type KeyHandlerEventMap = {\n keypress: [KeyEvent]\n keyrelease: [KeyEvent]\n paste: [PasteEvent]\n}\n\nexport class KeyHandler extends EventEmitter {\n public processParsedKey(parsedKey: ParsedKey): boolean {\n try {\n switch (parsedKey.eventType) {\n case \"press\":\n this.emit(\"keypress\", new KeyEvent(parsedKey))\n break\n case \"release\":\n this.emit(\"keyrelease\", new KeyEvent(parsedKey))\n break\n default:\n this.emit(\"keypress\", new KeyEvent(parsedKey))\n break\n }\n } catch (error) {\n console.error(`[KeyHandler] Error processing parsed key:`, error)\n return true\n }\n\n return true\n }\n\n public processPaste(bytes: Uint8Array, metadata?: PasteMetadata): void {\n try {\n this.emit(\"paste\", new PasteEvent(bytes, metadata))\n } catch (error) {\n console.error(`[KeyHandler] Error processing paste:`, error)\n }\n }\n}\n\n/**\n * This class is used internally by the renderer to ensure global handlers\n * can preventDefault before renderable handlers process events.\n */\nexport class InternalKeyHandler extends KeyHandler {\n private renderableHandlers: Map> = new Map()\n\n public emit(event: K, ...args: KeyHandlerEventMap[K]): boolean {\n return this.emitWithPriority(event, ...args)\n }\n\n private emitWithPriority(event: K, ...args: KeyHandlerEventMap[K]): boolean {\n let hasGlobalListeners = false\n\n // Check if we should emit to global handlers\n // Global handlers are emitted using the parent EventEmitter which calls all listeners\n // We need to manually iterate to check for stopPropagation between handlers\n const globalListeners = this.listeners(event as any)\n if (globalListeners.length > 0) {\n hasGlobalListeners = true\n\n for (const listener of globalListeners) {\n try {\n listener(...args)\n } catch (error) {\n console.error(`[KeyHandler] Error in global ${event} handler:`, error)\n }\n\n // Check if propagation was stopped after this handler\n if (event === \"keypress\" || event === \"keyrelease\" || event === \"paste\") {\n const keyEvent = args[0]\n if (keyEvent.propagationStopped) {\n return hasGlobalListeners\n }\n }\n }\n }\n\n const renderableSet = this.renderableHandlers.get(event)\n // Snapshot the handler list so listeners added during dispatch (e.g., via focus changes)\n // do not receive the in-flight key event.\n const renderableHandlers = renderableSet && renderableSet.size > 0 ? [...renderableSet] : []\n let hasRenderableListeners = false\n\n if (renderableSet && renderableSet.size > 0) {\n hasRenderableListeners = true\n\n if (event === \"keypress\" || event === \"keyrelease\" || event === \"paste\") {\n const keyEvent = args[0]\n if (keyEvent.defaultPrevented) return hasGlobalListeners || hasRenderableListeners\n if (keyEvent.propagationStopped) return hasGlobalListeners || hasRenderableListeners\n }\n\n for (const handler of renderableHandlers) {\n try {\n handler(...args)\n } catch (error) {\n console.error(`[KeyHandler] Error in renderable ${event} handler:`, error)\n }\n\n // Check if propagation was stopped after this handler\n if (event === \"keypress\" || event === \"keyrelease\" || event === \"paste\") {\n const keyEvent = args[0]\n if (keyEvent.propagationStopped) {\n return hasGlobalListeners || hasRenderableListeners\n }\n }\n }\n }\n\n return hasGlobalListeners || hasRenderableListeners\n }\n\n public onInternal(\n event: K,\n handler: (...args: KeyHandlerEventMap[K]) => void,\n ): void {\n if (!this.renderableHandlers.has(event)) {\n this.renderableHandlers.set(event, new Set())\n }\n this.renderableHandlers.get(event)!.add(handler)\n }\n\n public offInternal(\n event: K,\n handler: (...args: KeyHandlerEventMap[K]) => void,\n ): void {\n const handlers = this.renderableHandlers.get(event)\n if (handlers) {\n handlers.delete(handler)\n }\n }\n}\n", + "import { OptimizedBuffer } from \"../buffer.js\"\nimport { parseColor, RGBA, type ColorInput } from \"./RGBA.js\"\nimport block from \"./fonts/block.json\" with { type: \"json\" }\nimport shade from \"./fonts/shade.json\" with { type: \"json\" }\nimport slick from \"./fonts/slick.json\" with { type: \"json\" }\nimport tiny from \"./fonts/tiny.json\" with { type: \"json\" }\nimport huge from \"./fonts/huge.json\" with { type: \"json\" }\nimport grid from \"./fonts/grid.json\" with { type: \"json\" }\nimport pallet from \"./fonts/pallet.json\" with { type: \"json\" }\n\n/*\n * Renders ASCII fonts to a buffer.\n * Font definitions plugged from cfonts - https://github.com/dominikwilkowski/cfonts\n */\n\nexport type ASCIIFontName = \"tiny\" | \"block\" | \"shade\" | \"slick\" | \"huge\" | \"grid\" | \"pallet\"\n\nexport const fonts = {\n tiny,\n block,\n shade,\n slick,\n huge,\n grid,\n pallet,\n}\n\ntype FontSegment = {\n text: string\n colorIndex: number\n}\n\ntype FontDefinition = {\n name: string\n lines: number\n letterspace_size: number\n letterspace: string[]\n colors?: number\n chars: Record\n}\n\ntype ParsedFontDefinition = {\n name: string\n lines: number\n letterspace_size: number\n letterspace: string[]\n colors: number\n chars: Record\n}\n\nconst parsedFonts: Record = {}\n\nfunction parseColorTags(text: string): FontSegment[] {\n const segments: FontSegment[] = []\n let currentIndex = 0\n\n const colorTagRegex = /(.*?)<\\/c\\d+>/g\n let lastIndex = 0\n let match\n\n while ((match = colorTagRegex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n const plainText = text.slice(lastIndex, match.index)\n if (plainText) {\n segments.push({ text: plainText, colorIndex: 0 })\n }\n }\n\n const colorIndex = parseInt(match[1]) - 1\n const taggedText = match[2]\n segments.push({ text: taggedText, colorIndex: Math.max(0, colorIndex) })\n\n lastIndex = match.index + match[0].length\n }\n\n if (lastIndex < text.length) {\n const remainingText = text.slice(lastIndex)\n if (remainingText) {\n segments.push({ text: remainingText, colorIndex: 0 })\n }\n }\n\n return segments\n}\n\nfunction getParsedFont(fontKey: keyof typeof fonts): ParsedFontDefinition {\n if (!parsedFonts[fontKey]) {\n const fontDef = fonts[fontKey] as FontDefinition\n const parsedChars: Record = {}\n\n for (const [char, lines] of Object.entries(fontDef.chars)) {\n parsedChars[char] = lines.map((line) => parseColorTags(line))\n }\n\n parsedFonts[fontKey] = {\n ...fontDef,\n colors: fontDef.colors || 1,\n chars: parsedChars,\n }\n }\n\n return parsedFonts[fontKey]\n}\n\nexport function measureText({ text, font = \"tiny\" }: { text: string; font?: keyof typeof fonts }): {\n width: number\n height: number\n} {\n const fontDef = getParsedFont(font)\n if (!fontDef) {\n console.warn(`Font '${font}' not found`)\n return { width: 0, height: 0 }\n }\n\n let currentX = 0\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i].toUpperCase()\n const charDef = fontDef.chars[char]\n\n if (!charDef) {\n const spaceChar = fontDef.chars[\" \"]\n if (spaceChar && spaceChar[0]) {\n let spaceWidth = 0\n for (const segment of spaceChar[0]) {\n spaceWidth += segment.text.length\n }\n currentX += spaceWidth\n } else {\n currentX += 1\n }\n continue\n }\n\n let charWidth = 0\n if (charDef[0]) {\n for (const segment of charDef[0]) {\n charWidth += segment.text.length\n }\n }\n\n currentX += charWidth\n\n if (i < text.length - 1) {\n currentX += fontDef.letterspace_size\n }\n }\n\n return {\n width: currentX,\n height: fontDef.lines,\n }\n}\n\nexport function getCharacterPositions(text: string, font: keyof typeof fonts = \"tiny\"): number[] {\n const fontDef = getParsedFont(font)\n if (!fontDef) {\n return [0]\n }\n\n const positions: number[] = [0]\n let currentX = 0\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i].toUpperCase()\n const charDef = fontDef.chars[char]\n\n let charWidth = 0\n if (!charDef) {\n const spaceChar = fontDef.chars[\" \"]\n if (spaceChar && spaceChar[0]) {\n for (const segment of spaceChar[0]) {\n charWidth += segment.text.length\n }\n } else {\n charWidth = 1\n }\n } else if (charDef[0]) {\n for (const segment of charDef[0]) {\n charWidth += segment.text.length\n }\n }\n\n currentX += charWidth\n\n if (i < text.length - 1) {\n currentX += fontDef.letterspace_size\n }\n\n positions.push(currentX)\n }\n\n return positions\n}\n\nexport function coordinateToCharacterIndex(x: number, text: string, font: keyof typeof fonts = \"tiny\"): number {\n const positions = getCharacterPositions(text, font)\n\n if (x < 0) {\n return 0\n }\n\n for (let i = 0; i < positions.length - 1; i++) {\n const currentPos = positions[i]\n const nextPos = positions[i + 1]\n\n if (x >= currentPos && x < nextPos) {\n const charMidpoint = currentPos + (nextPos - currentPos) / 2\n return x < charMidpoint ? i : i + 1\n }\n }\n\n if (positions.length > 0 && x >= positions[positions.length - 1]) {\n return text.length\n }\n\n return 0\n}\n\nexport function renderFontToFrameBuffer(\n buffer: OptimizedBuffer,\n {\n text,\n x = 0,\n y = 0,\n color = [RGBA.fromInts(255, 255, 255, 255)],\n backgroundColor = RGBA.fromInts(0, 0, 0, 255),\n font = \"tiny\",\n }: {\n text: string\n x?: number\n y?: number\n color?: ColorInput | ColorInput[]\n backgroundColor?: ColorInput\n font?: keyof typeof fonts\n },\n): { width: number; height: number } {\n const width = buffer.width\n const height = buffer.height\n\n const fontDef = getParsedFont(font)\n if (!fontDef) {\n console.warn(`Font '${font}' not found`)\n return { width: 0, height: 0 }\n }\n\n const colors = Array.isArray(color) ? color : [color]\n\n if (y < 0 || y + fontDef.lines > height) {\n return { width: 0, height: fontDef.lines }\n }\n\n let currentX = x\n const startX = x\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i].toUpperCase()\n const charDef = fontDef.chars[char]\n\n if (!charDef) {\n const spaceChar = fontDef.chars[\" \"]\n if (spaceChar && spaceChar[0]) {\n let spaceWidth = 0\n for (const segment of spaceChar[0]) {\n spaceWidth += segment.text.length\n }\n currentX += spaceWidth\n } else {\n currentX += 1\n }\n continue\n }\n\n let charWidth = 0\n if (charDef[0]) {\n for (const segment of charDef[0]) {\n charWidth += segment.text.length\n }\n }\n\n if (currentX >= width) break\n if (currentX + charWidth < 0) {\n currentX += charWidth + fontDef.letterspace_size\n continue\n }\n\n for (let lineIdx = 0; lineIdx < fontDef.lines && lineIdx < charDef.length; lineIdx++) {\n const segments = charDef[lineIdx]\n const renderY = y + lineIdx\n\n if (renderY >= 0 && renderY < height) {\n let segmentX = currentX\n\n for (const segment of segments) {\n const segmentColor = colors[segment.colorIndex] || colors[0]\n\n for (let charIdx = 0; charIdx < segment.text.length; charIdx++) {\n const renderX = segmentX + charIdx\n\n if (renderX >= 0 && renderX < width) {\n const fontChar = segment.text[charIdx]\n if (fontChar !== \" \") {\n buffer.setCellWithAlphaBlending(\n renderX,\n renderY,\n fontChar,\n parseColor(segmentColor),\n parseColor(backgroundColor),\n )\n }\n }\n }\n\n segmentX += segment.text.length\n }\n }\n }\n\n currentX += charWidth\n\n if (i < text.length - 1) {\n currentX += fontDef.letterspace_size\n }\n }\n\n return {\n width: currentX - startX,\n height: fontDef.lines,\n }\n}\n", + "import type { RGBA } from \"./lib/RGBA.js\"\nimport type { EventEmitter } from \"events\"\nimport type { Selection } from \"./lib/selection.js\"\nimport type { Renderable } from \"./Renderable.js\"\nimport type { InternalKeyHandler, KeyHandler } from \"./lib/KeyHandler.js\"\nimport type { EditBufferRenderable } from \"./renderables/EditBufferRenderable.js\"\n\nexport const TextAttributes = {\n NONE: 0,\n BOLD: 1 << 0, // 1\n DIM: 1 << 1, // 2\n ITALIC: 1 << 2, // 4\n UNDERLINE: 1 << 3, // 8\n BLINK: 1 << 4, // 16\n INVERSE: 1 << 5, // 32\n HIDDEN: 1 << 6, // 64\n STRIKETHROUGH: 1 << 7, // 128\n}\n\n// Constants for attribute bit packing\nexport const ATTRIBUTE_BASE_BITS = 8\nexport const ATTRIBUTE_BASE_MASK = 0xff\n\n/**\n * Extract the base 8 bits of attributes from a u32 attribute value.\n * Currently we only use the first 8 bits for standard text attributes.\n */\nexport function getBaseAttributes(attr: number): number {\n return attr & ATTRIBUTE_BASE_MASK\n}\n\nexport type ThemeMode = \"dark\" | \"light\"\n\nexport type CursorStyle = \"block\" | \"line\" | \"underline\" | \"default\"\n\nexport type MousePointerStyle = \"default\" | \"pointer\" | \"text\" | \"crosshair\" | \"move\" | \"not-allowed\"\n\nexport interface CursorStyleOptions {\n style?: CursorStyle\n blinking?: boolean\n color?: RGBA\n cursor?: MousePointerStyle\n}\n\nexport enum DebugOverlayCorner {\n topLeft = 0,\n topRight = 1,\n bottomLeft = 2,\n bottomRight = 3,\n}\n\nexport enum TargetChannel {\n FG = 1,\n BG = 2,\n Both = 3,\n}\n\nexport type WidthMethod = \"wcwidth\" | \"unicode\"\nexport type TerminalMultiplexer = \"none\" | \"tmux\" | \"zellij\" | \"screen\" | \"unknown\"\n\nexport interface TerminalInfo {\n name: string\n version: string\n from_xtversion: boolean\n}\n\nexport interface TerminalCapabilities {\n kitty_keyboard: boolean\n kitty_graphics: boolean\n rgb: boolean\n ansi256: boolean\n unicode: WidthMethod\n sgr_pixels: boolean\n color_scheme_updates: boolean\n explicit_width: boolean\n scaled_text: boolean\n sixel: boolean\n focus_tracking: boolean\n sync: boolean\n bracketed_paste: boolean\n hyperlinks: boolean\n osc52: boolean\n notifications: boolean\n explicit_cursor_positioning: boolean\n remote: boolean\n multiplexer: TerminalMultiplexer\n terminal: TerminalInfo\n}\n\nexport interface RendererEvents {\n resize: (width: number, height: number) => void\n key: (data: Buffer) => void\n \"memory:snapshot\": (snapshot: { heapUsed: number; heapTotal: number; arrayBuffers: number }) => void\n capabilities: (capabilities: TerminalCapabilities) => void\n selection: (selection: Selection) => void\n focused_renderable: (current: Renderable | null, previous: Renderable | null) => void\n focused_editor: (current: EditBufferRenderable | null, previous: EditBufferRenderable | null) => void\n \"debugOverlay:toggle\": (enabled: boolean) => void\n theme_mode: (mode: ThemeMode) => void\n}\n\nexport interface RenderContext extends EventEmitter {\n addToHitGrid: (x: number, y: number, width: number, height: number, id: number) => void\n pushHitGridScissorRect: (x: number, y: number, width: number, height: number) => void\n popHitGridScissorRect: () => void\n clearHitGridScissorRects: () => void\n width: number\n height: number\n /** Monotonic, bumped once per `loop()` iteration. Lets renderables dedupe per-frame work. */\n frameId: number\n requestRender: () => void\n setCursorPosition: (x: number, y: number, visible: boolean) => void\n setCursorStyle: (options: CursorStyleOptions) => void\n setCursorColor: (color: RGBA) => void\n setMousePointer: (shape: MousePointerStyle) => void\n widthMethod: WidthMethod\n capabilities: TerminalCapabilities | null\n requestLive: () => void\n dropLive: () => void\n hasSelection: boolean\n getSelection: () => Selection | null\n requestSelectionUpdate: () => void\n currentFocusedRenderable: Renderable | null\n currentFocusedEditor: EditBufferRenderable | null\n focusRenderable: (renderable: Renderable) => void\n blurRenderable: (renderable: Renderable) => void\n claimFirstLineOffset?: (renderable?: Renderable) => number\n registerLifecyclePass: (renderable: Renderable) => void\n unregisterLifecyclePass: (renderable: Renderable) => void\n getLifecyclePasses: () => Set\n keyInput: KeyHandler\n _internalKeyInput: InternalKeyHandler\n clearSelection: () => void\n startSelection: (renderable: Renderable, x: number, y: number) => void\n updateSelection: (\n currentRenderable: Renderable | undefined,\n x: number,\n y: number,\n options?: { finishDragging?: boolean },\n ) => void\n}\n\nexport type Timeout = ReturnType | undefined\n\nexport interface ViewportBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface Highlight {\n start: number\n end: number\n styleId: number\n priority?: number | null\n hlRef?: number | null\n}\n\nexport interface LineInfo {\n /** Display-column offset for each visual line start. */\n lineStartCols: number[]\n /** Display-column width for each visual line. */\n lineWidthCols: number[]\n /** Maximum display-column width across the reported lines. */\n lineWidthColsMax: number\n /** Source logical line index for each visual line. */\n lineSources: number[]\n /** Wrap index within each source logical line. */\n lineWraps: number[]\n}\n\nexport interface LineInfoProvider {\n get lineInfo(): LineInfo\n get lineCount(): number\n get virtualLineCount(): number\n get scrollY(): number\n}\n\nexport interface CapturedSpan {\n text: string\n fg: RGBA\n bg: RGBA\n attributes: number\n width: number\n}\n\nexport interface CapturedLine {\n spans: CapturedSpan[]\n}\n\nexport interface CapturedFrame {\n cols: number\n rows: number\n cursor: [number, number]\n lines: CapturedLine[]\n}\n", + "import { TextAttributes } from \"./types.js\"\nimport { Renderable } from \"./Renderable.js\"\n\nexport function createTextAttributes({\n bold = false,\n italic = false,\n underline = false,\n dim = false,\n blink = false,\n inverse = false,\n hidden = false,\n strikethrough = false,\n}: {\n bold?: boolean\n italic?: boolean\n underline?: boolean\n dim?: boolean\n blink?: boolean\n inverse?: boolean\n hidden?: boolean\n strikethrough?: boolean\n} = {}): number {\n let attributes = TextAttributes.NONE\n\n if (bold) attributes |= TextAttributes.BOLD\n if (italic) attributes |= TextAttributes.ITALIC\n if (underline) attributes |= TextAttributes.UNDERLINE\n if (dim) attributes |= TextAttributes.DIM\n if (blink) attributes |= TextAttributes.BLINK\n if (inverse) attributes |= TextAttributes.INVERSE\n if (hidden) attributes |= TextAttributes.HIDDEN\n if (strikethrough) attributes |= TextAttributes.STRIKETHROUGH\n\n return attributes\n}\n\n// Link attribute helpers (bits 8-31 encode link_id)\nconst ATTRIBUTE_BASE_MASK = 0xff\nconst LINK_ID_SHIFT = 8\nconst LINK_ID_PAYLOAD_MASK = 0xffffff\n\nexport function attributesWithLink(baseAttributes: number, linkId: number): number {\n const base = baseAttributes & ATTRIBUTE_BASE_MASK\n const linkBits = (linkId & LINK_ID_PAYLOAD_MASK) << LINK_ID_SHIFT\n return base | linkBits\n}\n\nexport function getLinkId(attributes: number): number {\n return (attributes >>> LINK_ID_SHIFT) & LINK_ID_PAYLOAD_MASK\n}\n\n// For debugging purposes\nexport function visualizeRenderableTree(renderable: Renderable, maxDepth: number = 10): void {\n function buildTreeLines(\n node: Renderable,\n prefix: string = \"\",\n parentPrefix: string = \"\",\n isLastChild: boolean = true,\n depth: number = 0,\n ): string[] {\n if (depth >= maxDepth) {\n return [`${prefix}${node.id} ... (max depth reached)`]\n }\n\n const lines: string[] = []\n const children = node.getChildren()\n\n // Add current node\n lines.push(`${prefix}${node.id}`)\n\n if (children.length > 0) {\n const lastChildIndex = children.length - 1\n\n children.forEach((child, index) => {\n const childIsLast = index === lastChildIndex\n const connector = childIsLast ? \"└── \" : \"├── \"\n const childPrefix = parentPrefix + (isLastChild ? \" \" : \"│ \")\n const childLines = buildTreeLines(child, childPrefix + connector, childPrefix, childIsLast, depth + 1)\n lines.push(...childLines)\n })\n }\n\n return lines\n }\n\n const treeLines = buildTreeLines(renderable)\n console.log(\"Renderable Tree:\\n\" + treeLines.join(\"\\n\"))\n}\n", + "import type { TextRenderable } from \"../renderables/Text.js\"\nimport type { TextBuffer, TextChunk } from \"../text-buffer.js\"\nimport { createTextAttributes } from \"../utils.js\"\nimport { parseColor, type ColorInput } from \"./RGBA.js\"\n\nconst BrandedStyledText: unique symbol = Symbol.for(\"@opentui/core/StyledText\")\n\nexport type Color = ColorInput\n\nexport interface StyleAttrs {\n fg?: Color\n bg?: Color\n bold?: boolean\n italic?: boolean\n underline?: boolean\n strikethrough?: boolean\n dim?: boolean\n reverse?: boolean\n blink?: boolean\n}\n\nexport function isStyledText(obj: any): obj is StyledText {\n return obj && obj[BrandedStyledText]\n}\n\nexport class StyledText {\n [BrandedStyledText] = true\n\n public chunks: TextChunk[]\n\n constructor(chunks: TextChunk[]) {\n this.chunks = chunks\n }\n}\n\nexport function stringToStyledText(content: string): StyledText {\n const chunk = {\n __isChunk: true as const,\n text: content,\n }\n return new StyledText([chunk])\n}\n\nexport type StylableInput = string | number | boolean | TextChunk\n\nfunction applyStyle(input: StylableInput, style: StyleAttrs): TextChunk {\n if (typeof input === \"object\" && \"__isChunk\" in input) {\n const existingChunk = input as TextChunk\n\n const fg = style.fg ? parseColor(style.fg) : existingChunk.fg\n const bg = style.bg ? parseColor(style.bg) : existingChunk.bg\n\n const newAttrs = createTextAttributes(style)\n const mergedAttrs = existingChunk.attributes ? existingChunk.attributes | newAttrs : newAttrs\n\n return {\n __isChunk: true,\n text: existingChunk.text,\n fg,\n bg,\n attributes: mergedAttrs,\n link: existingChunk.link,\n }\n } else {\n const plainTextStr = String(input)\n const fg = style.fg ? parseColor(style.fg) : undefined\n const bg = style.bg ? parseColor(style.bg) : undefined\n const attributes = createTextAttributes(style)\n\n return {\n __isChunk: true,\n text: plainTextStr,\n fg,\n bg,\n attributes,\n }\n }\n}\n\n// Color functions\nexport const black = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"black\" })\nexport const red = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"red\" })\nexport const green = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"green\" })\nexport const yellow = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"yellow\" })\nexport const blue = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"blue\" })\nexport const magenta = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"magenta\" })\nexport const cyan = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"cyan\" })\nexport const white = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"white\" })\n\n// Bright color functions\nexport const brightBlack = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightBlack\" })\nexport const brightRed = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightRed\" })\nexport const brightGreen = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightGreen\" })\nexport const brightYellow = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightYellow\" })\nexport const brightBlue = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightBlue\" })\nexport const brightMagenta = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightMagenta\" })\nexport const brightCyan = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightCyan\" })\nexport const brightWhite = (input: StylableInput): TextChunk => applyStyle(input, { fg: \"brightWhite\" })\n\n// Background color functions\nexport const bgBlack = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"black\" })\nexport const bgRed = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"red\" })\nexport const bgGreen = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"green\" })\nexport const bgYellow = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"yellow\" })\nexport const bgBlue = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"blue\" })\nexport const bgMagenta = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"magenta\" })\nexport const bgCyan = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"cyan\" })\nexport const bgWhite = (input: StylableInput): TextChunk => applyStyle(input, { bg: \"white\" })\n\n// Style functions\nexport const bold = (input: StylableInput): TextChunk => applyStyle(input, { bold: true })\nexport const italic = (input: StylableInput): TextChunk => applyStyle(input, { italic: true })\nexport const underline = (input: StylableInput): TextChunk => applyStyle(input, { underline: true })\nexport const strikethrough = (input: StylableInput): TextChunk => applyStyle(input, { strikethrough: true })\nexport const dim = (input: StylableInput): TextChunk => applyStyle(input, { dim: true })\nexport const reverse = (input: StylableInput): TextChunk => applyStyle(input, { reverse: true })\nexport const blink = (input: StylableInput): TextChunk => applyStyle(input, { blink: true })\n\n// Custom color functions\nexport const fg =\n (color: Color) =>\n (input: StylableInput): TextChunk =>\n applyStyle(input, { fg: color })\nexport const bg =\n (color: Color) =>\n (input: StylableInput): TextChunk =>\n applyStyle(input, { bg: color })\n\nexport const link =\n (url: string) =>\n (input: StylableInput): TextChunk => {\n const chunk =\n typeof input === \"object\" && \"__isChunk\" in input\n ? (input as TextChunk)\n : {\n __isChunk: true as const,\n text: String(input),\n }\n\n return {\n ...chunk,\n link: { url },\n }\n }\n\n/**\n * Template literal handler for styled text (non-cached version).\n * Returns a StyledText object containing chunks of text with optional styles.\n */\nexport function t(strings: TemplateStringsArray, ...values: StylableInput[]): StyledText {\n const chunks: TextChunk[] = []\n\n for (let i = 0; i < strings.length; i++) {\n const raw = strings[i]\n\n if (raw) {\n chunks.push({\n __isChunk: true,\n text: raw,\n attributes: 0,\n })\n }\n\n const val = values[i]\n if (typeof val === \"object\" && \"__isChunk\" in val) {\n chunks.push(val as TextChunk)\n } else if (val !== undefined) {\n const plainTextStr = String(val)\n chunks.push({\n __isChunk: true,\n text: plainTextStr,\n attributes: 0,\n })\n }\n }\n\n return new StyledText(chunks)\n}\n", + "import type { TextChunk } from \"../text-buffer.js\"\nimport { StyledText } from \"./styled-text.js\"\nimport { SyntaxStyle } from \"../syntax-style.js\"\n\nexport interface HASTText {\n type: \"text\"\n value: string\n}\n\nexport interface HASTElement {\n type: \"element\"\n tagName: string\n properties?: {\n className?: string\n }\n children: HASTNode[]\n}\n\nexport type HASTNode = HASTText | HASTElement\n\nexport type { StyleDefinition } from \"../syntax-style.js\"\n\nfunction hastToTextChunks(node: HASTNode, syntaxStyle: SyntaxStyle, parentStyles: string[] = []): TextChunk[] {\n const chunks: TextChunk[] = []\n\n if (node.type === \"text\") {\n const stylesToMerge = parentStyles.length > 0 ? parentStyles : [\"default\"]\n const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge)\n\n chunks.push({\n __isChunk: true,\n text: node.value,\n fg: mergedStyle.fg,\n bg: mergedStyle.bg,\n attributes: mergedStyle.attributes,\n })\n } else if (node.type === \"element\") {\n let currentStyles = [...parentStyles]\n\n if (node.properties?.className) {\n const classes = node.properties.className.split(\" \")\n\n for (const cls of classes) {\n currentStyles.push(cls)\n }\n }\n\n for (const child of node.children) {\n chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles))\n }\n }\n\n return chunks\n}\n\nexport function hastToStyledText(hast: HASTNode, syntaxStyle: SyntaxStyle): StyledText {\n const chunks = hastToTextChunks(hast, syntaxStyle)\n return new StyledText(chunks)\n}\n", + "export type TimerHandle = ReturnType | number\n\nexport interface Clock {\n now(): number\n setTimeout(fn: () => void, delayMs: number): TimerHandle\n clearTimeout(handle: TimerHandle): void\n setInterval(fn: () => void, delayMs: number): TimerHandle\n clearInterval(handle: TimerHandle): void\n}\n\nexport class SystemClock implements Clock {\n public now(): number {\n if (!globalThis.performance || typeof globalThis.performance.now !== \"function\") {\n throw new Error(\"SystemClock requires globalThis.performance.now()\")\n }\n\n return globalThis.performance.now()\n }\n\n public setTimeout(fn: () => void, delayMs: number): TimerHandle {\n return globalThis.setTimeout(fn, delayMs)\n }\n\n public clearTimeout(handle: TimerHandle): void {\n globalThis.clearTimeout(handle as ReturnType)\n }\n\n public setInterval(fn: () => void, delayMs: number): TimerHandle {\n return globalThis.setInterval(fn, delayMs)\n }\n\n public clearInterval(handle: TimerHandle): void {\n globalThis.clearInterval(handle as ReturnType)\n }\n}\n", + "// Copied from https://github.com/enquirer/enquirer/blob/36785f3399a41cd61e9d28d1eb9c2fcd73d69b4c/lib/keypress.js\nimport { Buffer } from \"node:buffer\"\nimport { kittyNamedSingleStrokeKeys, parseKittyKeyboard } from \"./parse.keypress-kitty.js\"\n\nconst metaKeyCodeRe = /^(?:\\x1b)([a-zA-Z0-9])$/\n\nconst fnKeyRe = /^(?:\\x1b+)(O|N|\\[|\\[\\[)(?:(\\d+)(?:;(\\d+))?([~^$])|(?:1;)?(\\d+)?([a-zA-Z]))/\n\nconst keyName: Record = {\n /* xterm/gnome ESC O letter */\n OP: \"f1\",\n OQ: \"f2\",\n OR: \"f3\",\n OS: \"f4\",\n /* xterm/rxvt ESC [ number ~ */\n \"[11~\": \"f1\",\n \"[12~\": \"f2\",\n \"[13~\": \"f3\",\n \"[14~\": \"f4\",\n /* from Cygwin and used in libuv */\n \"[[A\": \"f1\",\n \"[[B\": \"f2\",\n \"[[C\": \"f3\",\n \"[[D\": \"f4\",\n \"[[E\": \"f5\",\n /* common */\n \"[15~\": \"f5\",\n \"[17~\": \"f6\",\n \"[18~\": \"f7\",\n \"[19~\": \"f8\",\n \"[20~\": \"f9\",\n \"[21~\": \"f10\",\n \"[23~\": \"f11\",\n \"[24~\": \"f12\",\n \"[29~\": \"menu\",\n \"[57427~\": \"clear\",\n /* xterm ESC [ letter */\n \"[A\": \"up\",\n \"[B\": \"down\",\n \"[C\": \"right\",\n \"[D\": \"left\",\n \"[E\": \"clear\",\n \"[F\": \"end\",\n \"[H\": \"home\",\n \"[P\": \"f1\",\n \"[Q\": \"f2\",\n \"[S\": \"f4\",\n /* xterm/gnome ESC O letter */\n OA: \"up\",\n OB: \"down\",\n OC: \"right\",\n OD: \"left\",\n OE: \"clear\",\n OF: \"end\",\n OH: \"home\",\n /* VT100 application keypad (SS3) — sent when terminal enables DECKPAM (ESC =).\n * macOS Terminal.app and other xterm-based terminals emit these when running\n * full-screen apps with the alternate screen. */\n OM: \"return\",\n Oj: \"*\",\n Ok: \"+\",\n Ol: \",\",\n Om: \"-\",\n On: \".\",\n Oo: \"/\",\n Op: \"0\",\n Oq: \"1\",\n Or: \"2\",\n Os: \"3\",\n Ot: \"4\",\n Ou: \"5\",\n Ov: \"6\",\n Ow: \"7\",\n Ox: \"8\",\n Oy: \"9\",\n OX: \"=\",\n /* xterm/rxvt ESC [ number ~ */\n \"[1~\": \"home\",\n \"[2~\": \"insert\",\n \"[3~\": \"delete\",\n \"[4~\": \"end\",\n \"[5~\": \"pageup\",\n \"[6~\": \"pagedown\",\n /* putty */\n \"[[5~\": \"pageup\",\n \"[[6~\": \"pagedown\",\n /* rxvt */\n \"[7~\": \"home\",\n \"[8~\": \"end\",\n /* rxvt keys with modifiers */\n \"[a\": \"up\",\n \"[b\": \"down\",\n \"[c\": \"right\",\n \"[d\": \"left\",\n \"[e\": \"clear\",\n /* option + arrow keys (old style) */\n f: \"right\",\n b: \"left\",\n p: \"up\",\n n: \"down\",\n\n \"[2$\": \"insert\",\n \"[3$\": \"delete\",\n \"[5$\": \"pageup\",\n \"[6$\": \"pagedown\",\n \"[7$\": \"home\",\n \"[8$\": \"end\",\n\n Oa: \"up\",\n Ob: \"down\",\n Oc: \"right\",\n Od: \"left\",\n Oe: \"clear\",\n\n \"[2^\": \"insert\",\n \"[3^\": \"delete\",\n \"[5^\": \"pageup\",\n \"[6^\": \"pagedown\",\n \"[7^\": \"home\",\n \"[8^\": \"end\",\n /* misc. */\n \"[Z\": \"tab\",\n}\n\nexport const nonAlphanumericKeys = [...Object.values(keyName), \"backspace\"]\n\nexport const terminalNamedSingleStrokeKeys = [\n ...new Set([\"return\", \"linefeed\", \"tab\", \"escape\", \"space\", ...nonAlphanumericKeys, ...kittyNamedSingleStrokeKeys]),\n]\n\nconst isShiftKey = (code: string) => {\n return [\"[a\", \"[b\", \"[c\", \"[d\", \"[e\", \"[2$\", \"[3$\", \"[5$\", \"[6$\", \"[7$\", \"[8$\", \"[Z\"].includes(code)\n}\n\nconst isCtrlKey = (code: string) => {\n return [\"Oa\", \"Ob\", \"Oc\", \"Od\", \"Oe\", \"[2^\", \"[3^\", \"[5^\", \"[6^\", \"[7^\", \"[8^\"].includes(code)\n}\n\n// Map raw control bytes to the key names that bindings expect. Terminals send\n// Ctrl+A..Ctrl+Z as 0x01..0x1a, and they send Ctrl+\\\\..Ctrl+_ as 0x1c..0x1f.\n// The ESC-prefixed meta+ctrl path reuses this mapping, so the raw and meta\n// forms stay aligned.\nconst getCtrlKeyName = (charCode: number): string | undefined => {\n if (charCode === 0) {\n return \"space\"\n }\n\n if (charCode >= 1 && charCode <= 26) {\n return String.fromCharCode(charCode + \"a\".charCodeAt(0) - 1)\n }\n\n if (charCode >= 28 && charCode <= 31) {\n return String.fromCharCode(charCode + 64)\n }\n\n return undefined\n}\n\nexport type KeyEventType = \"press\" | \"repeat\" | \"release\"\n\nexport interface ParsedKey {\n name: string\n ctrl: boolean\n meta: boolean\n shift: boolean\n option: boolean\n sequence: string\n number: boolean\n raw: string\n eventType: KeyEventType\n source: \"raw\" | \"kitty\"\n code?: string\n super?: boolean\n hyper?: boolean\n capsLock?: boolean\n numLock?: boolean\n // Kitty's base-layout codepoint as a Unicode number. Example: 99 means \"c\".\n // This lets shortcut matching recover Ctrl+C from an event whose printed name\n // is something else under the active layout or IME.\n baseCode?: number\n repeated?: boolean\n}\n\nexport type ParseKeypressOptions = {\n useKittyKeyboard?: boolean\n}\n\n// Printable characters for VT100 SS3 application-keypad sequences.\n// When the terminal is in application keypad mode (DECKPAM / ESC =), numpad keys\n// send these SS3 codes instead of raw ASCII characters. The keys map to the same\n// printable output as their regular-keyboard equivalents.\nconst ss3NumpadPrintable: Record = {\n Op: \"0\",\n Oq: \"1\",\n Or: \"2\",\n Os: \"3\",\n Ot: \"4\",\n Ou: \"5\",\n Ov: \"6\",\n Ow: \"7\",\n Ox: \"8\",\n Oy: \"9\",\n Oj: \"*\",\n Ok: \"+\",\n Ol: \",\",\n Om: \"-\",\n On: \".\",\n Oo: \"/\",\n OX: \"=\",\n}\n\nconst modifyOtherKeysRe = /^\\x1b\\[27;(\\d+);(\\d+)~$/\n\nexport const parseKeypress = (s: Buffer | string = \"\", options: ParseKeypressOptions = {}): ParsedKey | null => {\n let parts\n\n if (Buffer.isBuffer(s)) {\n if (s[0]! > 127 && s[1] === undefined) {\n ;(s[0] as unknown as number) -= 128\n s = \"\\x1b\" + String(s)\n } else {\n s = String(s)\n }\n } else if (s !== undefined && typeof s !== \"string\") {\n s = String(s)\n } else if (!s) {\n s = \"\"\n }\n\n // Filter out mouse events (SGR and basic)\n // Complete SGR mouse: ESC[= 6) {\n return null\n }\n\n // Filter out terminal response sequences (not keyboard events)\n // These are responses to terminal queries and should not be treated as key presses\n\n // Window/cell size reports: ESC[4;height;width t or ESC[8;rows;cols t\n if (/^\\x1b\\[\\d+;\\d+;\\d+t$/.test(s)) {\n return null\n }\n\n // Cursor position reports (DSR): ESC[row;col R\n if (/^\\x1b\\[\\d+;\\d+R$/.test(s)) {\n return null\n }\n\n // Device Attributes (DA) responses: ESC[?...c\n if (/^\\x1b\\[\\?[\\d;]+c$/.test(s)) {\n return null\n }\n\n // Mode reports: ESC[?...;...$y\n if (/^\\x1b\\[\\?[\\d;]+\\$y$/.test(s)) {\n return null\n }\n\n // Focus events: ESC[I (focus in), ESC[O (focus out)\n // Note: ESC[O is also used for SS3 sequences (like arrow keys), but those have a character after O\n if (s === \"\\x1b[I\" || s === \"\\x1b[O\") {\n return null\n }\n\n // OSC (Operating System Command) responses: ESC]...ESC\\ or ESC]...BEL\n if (/^\\x1b\\][\\d;].*(\\x1b\\\\|\\x07)$/.test(s)) {\n return null\n }\n\n // Bracketed paste mode markers: ESC[200~ (start), ESC[201~ (end)\n if (s === \"\\x1b[200~\" || s === \"\\x1b[201~\") {\n return null\n }\n\n const key: ParsedKey = {\n name: \"\",\n ctrl: false,\n meta: false,\n shift: false,\n option: false,\n number: false,\n sequence: s,\n raw: s,\n eventType: \"press\",\n source: \"raw\",\n }\n\n key.sequence = key.sequence || s || key.name\n\n const ctrlKeyName = s.length === 1 ? getCtrlKeyName(s.charCodeAt(0)) : undefined\n const metaCtrlKeyName = s.length === 2 && s[0] === \"\\x1b\" ? getCtrlKeyName(s.charCodeAt(1)) : undefined\n\n // Check for Kitty keyboard protocol if enabled\n if (options.useKittyKeyboard) {\n const kittyResult = parseKittyKeyboard(s)\n if (kittyResult) {\n return kittyResult\n }\n }\n\n // Check for modifyOtherKeys sequences (CSI u protocol variant)\n // Format: CSI 27 ; modifier ; code ~\n // This is sent by terminals (xterm, iTerm2, Ghostty, etc.) with modifyOtherKeys mode enabled\n // to encode modified versions of keys that don't normally have modifier variants\n // Examples: CSI 27;2;13~ (shift+enter), CSI 27;5;13~ (ctrl+enter), CSI 27;5;27~ (ctrl+escape)\n const modifyOtherKeysMatch = modifyOtherKeysRe.exec(s)\n if (modifyOtherKeysMatch) {\n const modifier = parseInt(modifyOtherKeysMatch[1]!, 10) - 1\n const charCode = parseInt(modifyOtherKeysMatch[2]!, 10)\n\n key.ctrl = !!(modifier & 4)\n key.meta = !!(modifier & 2) // Alt/Option sets meta\n key.shift = !!(modifier & 1)\n key.option = !!(modifier & 2)\n key.super = !!(modifier & 8)\n key.hyper = !!(modifier & 16)\n\n // Handle common keys by their ASCII codes\n if (charCode === 13) {\n key.name = \"return\"\n } else if (charCode === 27) {\n key.name = \"escape\"\n } else if (charCode === 9) {\n key.name = \"tab\"\n } else if (charCode === 32) {\n key.name = \"space\"\n } else if (charCode === 127 || charCode === 8) {\n key.name = \"backspace\"\n } else {\n // For other character codes, use the character itself\n const char = String.fromCharCode(charCode)\n key.name = char\n key.sequence = char\n if (charCode >= 48 && charCode <= 57) {\n key.number = true\n }\n }\n\n return key\n }\n\n if (s === \"\\r\" || s === \"\\x1b\\r\") {\n // carriage return\n key.name = \"return\"\n key.meta = s.length === 2\n } else if (s === \"\\n\" || s === \"\\x1b\\n\") {\n // linefeed\n key.name = \"linefeed\"\n key.meta = s.length === 2\n } else if (s === \"\\t\") {\n // tab\n key.name = \"tab\"\n } else if (s === \"\\b\" || s === \"\\x1b\\b\" || s === \"\\x7f\" || s === \"\\x1b\\x7f\") {\n // backspace or ctrl+h\n // On OSX, \\x7f is also backspace\n key.name = \"backspace\"\n key.meta = s.charAt(0) === \"\\x1b\"\n } else if (s === \"\\x1b\" || s === \"\\x1b\\x1b\") {\n // escape key\n key.name = \"escape\"\n key.meta = s.length === 2\n } else if (s === \" \" || s === \"\\x1b \") {\n key.name = \"space\"\n key.meta = s.length === 2\n } else if (ctrlKeyName) {\n // ctrl+space, ctrl+letter, ctrl+\\\\, ctrl+], ctrl+^, ctrl+_\n key.name = ctrlKeyName\n key.ctrl = true\n } else if (s.length === 1 && s >= \"0\" && s <= \"9\") {\n // number - keep the actual number character for vim commands\n key.name = s\n key.number = true\n } else if (s.length === 1 && s >= \"a\" && s <= \"z\") {\n // lowercase letter\n key.name = s\n } else if (s.length === 1 && s >= \"A\" && s <= \"Z\") {\n // shift+letter\n key.name = s.toLowerCase()\n key.shift = true\n } else if (s.length === 1 || (s.length === 2 && s.codePointAt(0)! > 0xffff)) {\n // Single character (including emoji/surrogate pairs above BMP)\n key.name = s\n } else if ((parts = metaKeyCodeRe.exec(s))) {\n // meta+character key\n key.meta = true\n const char = parts[1]!\n const isUpperCase = /^[A-Z]$/.test(char)\n\n // Check if uppercase F or B map to arrow keys (old terminal style)\n if (char === \"F\") {\n key.name = \"right\"\n } else if (char === \"B\") {\n key.name = \"left\"\n } else if (isUpperCase) {\n key.shift = true\n key.name = char\n } else {\n key.name = char\n }\n } else if (metaCtrlKeyName) {\n // ESC + control byte is the raw meta+ctrl form. Reuse the same names as\n // the plain ctrl path, so meta+ctrl+\\\\ and friends resolve consistently.\n key.meta = true\n key.ctrl = true\n key.name = metaCtrlKeyName\n } else if ((parts = fnKeyRe.exec(s))) {\n const segs = [...s]\n\n if (segs[0] === \"\\u001b\" && segs[1] === \"\\u001b\") {\n key.option = true\n key.meta = true\n }\n\n // ansi escape sequence\n // reassemble the key code leaving out leading \\x1b's,\n // the modifier key bitflag and any meaningless \"1;\" sequence\n const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join(\"\")\n\n const modifier = parseInt(parts[3] || parts[5] || \"1\", 10) - 1\n\n // Parse the key modifier\n // Terminal modifier bits: 1=Shift, 2=Alt/Option, 4=Ctrl, 8=Super, 16=Hyper\n // Note: meta flag is set for Alt/Option (bit 2)\n key.ctrl = key.ctrl || !!(modifier & 4)\n key.meta = key.meta || !!(modifier & 2)\n key.shift = key.shift || !!(modifier & 1)\n key.option = key.option || !!(modifier & 2)\n key.super = !!(modifier & 8)\n key.hyper = !!(modifier & 16)\n key.code = code\n\n const keyNameResult = keyName[code]\n if (keyNameResult) {\n key.name = keyNameResult\n key.shift = isShiftKey(code) || key.shift\n key.ctrl = isCtrlKey(code) || key.ctrl\n\n // SS3 application-keypad sequences have a raw sequence starting with ESC\n // which the text-insertion branch would filter out (charCode 27 < 32).\n // Override sequence with the printable character so text input works.\n const ss3Char = ss3NumpadPrintable[code]\n if (ss3Char !== undefined) {\n key.sequence = ss3Char\n if (key.name >= \"0\" && key.name <= \"9\") {\n key.number = true\n }\n }\n } else {\n // If we matched the regex but didn't find a valid key name,\n // reset the key to default state (unknown sequence)\n key.name = \"\"\n key.code = undefined\n }\n } else if (s === \"\\x1b[3~\") {\n // delete key\n key.name = \"delete\"\n key.meta = false\n key.code = \"[3~\"\n }\n\n return key\n}\n", + "// Kitty Keyboard Protocol parser\n// Based on https://sw.kovidgoyal.net/kitty/keyboard-protocol/\n\nimport type { ParsedKey } from \"./parse.keypress.js\"\n\nconst kittyKeyMap: Record = {\n // Standard keys\n 27: \"escape\",\n 9: \"tab\",\n 13: \"return\",\n 127: \"backspace\",\n\n // Arrow keys\n 57344: \"escape\",\n 57345: \"return\",\n 57346: \"tab\",\n 57347: \"backspace\",\n 57348: \"insert\",\n 57349: \"delete\",\n 57350: \"left\",\n 57351: \"right\",\n 57352: \"up\",\n 57353: \"down\",\n 57354: \"pageup\",\n 57355: \"pagedown\",\n 57356: \"home\",\n 57357: \"end\",\n 57358: \"capslock\",\n 57359: \"scrolllock\",\n 57360: \"numlock\",\n 57361: \"printscreen\",\n 57362: \"pause\",\n 57363: \"menu\",\n\n // Function keys\n 57364: \"f1\",\n 57365: \"f2\",\n 57366: \"f3\",\n 57367: \"f4\",\n 57368: \"f5\",\n 57369: \"f6\",\n 57370: \"f7\",\n 57371: \"f8\",\n 57372: \"f9\",\n 57373: \"f10\",\n 57374: \"f11\",\n 57375: \"f12\",\n 57376: \"f13\",\n 57377: \"f14\",\n 57378: \"f15\",\n 57379: \"f16\",\n 57380: \"f17\",\n 57381: \"f18\",\n 57382: \"f19\",\n 57383: \"f20\",\n 57384: \"f21\",\n 57385: \"f22\",\n 57386: \"f23\",\n 57387: \"f24\",\n 57388: \"f25\",\n 57389: \"f26\",\n 57390: \"f27\",\n 57391: \"f28\",\n 57392: \"f29\",\n 57393: \"f30\",\n 57394: \"f31\",\n 57395: \"f32\",\n 57396: \"f33\",\n 57397: \"f34\",\n 57398: \"f35\",\n\n // Keypad\n 57399: \"kp0\",\n 57400: \"kp1\",\n 57401: \"kp2\",\n 57402: \"kp3\",\n 57403: \"kp4\",\n 57404: \"kp5\",\n 57405: \"kp6\",\n 57406: \"kp7\",\n 57407: \"kp8\",\n 57408: \"kp9\",\n 57409: \"kpdecimal\",\n 57410: \"kpdivide\",\n 57411: \"kpmultiply\",\n 57412: \"kpminus\",\n 57413: \"kpplus\",\n 57414: \"kpenter\",\n 57415: \"kpequal\",\n 57416: \"kpseparator\",\n 57417: \"kpleft\",\n 57418: \"kpright\",\n 57419: \"kpup\",\n 57420: \"kpdown\",\n 57421: \"kppageup\",\n 57422: \"kppagedown\",\n 57423: \"kphome\",\n 57424: \"kpend\",\n 57425: \"kpinsert\",\n 57426: \"kpdelete\",\n 57427: \"clear\",\n\n // Media keys\n 57428: \"mediaplay\",\n 57429: \"mediapause\",\n 57430: \"mediaplaypause\",\n 57431: \"mediareverse\",\n 57432: \"mediastop\",\n 57433: \"mediafastforward\",\n 57434: \"mediarewind\",\n 57435: \"medianext\",\n 57436: \"mediaprev\",\n 57437: \"mediarecord\",\n\n // Volume keys\n 57438: \"volumedown\",\n 57439: \"volumeup\",\n 57440: \"mute\",\n\n // Modifiers\n 57441: \"leftshift\",\n 57442: \"leftctrl\",\n 57443: \"leftalt\",\n 57444: \"leftsuper\",\n 57445: \"lefthyper\",\n 57446: \"leftmeta\",\n 57447: \"rightshift\",\n 57448: \"rightctrl\",\n 57449: \"rightalt\",\n 57450: \"rightsuper\",\n 57451: \"righthyper\",\n 57452: \"rightmeta\",\n\n // Special\n 57453: \"iso_level3_shift\",\n 57454: \"iso_level5_shift\",\n}\n\nexport const kittyNamedSingleStrokeKeys = [...new Set(Object.values(kittyKeyMap))]\n\nconst printableKeypadText: Record = {\n kp0: \"0\",\n kp1: \"1\",\n kp2: \"2\",\n kp3: \"3\",\n kp4: \"4\",\n kp5: \"5\",\n kp6: \"6\",\n kp7: \"7\",\n kp8: \"8\",\n kp9: \"9\",\n kpdecimal: \".\",\n kpdivide: \"/\",\n kpmultiply: \"*\",\n kpminus: \"-\",\n kpplus: \"+\",\n kpequal: \"=\",\n kpseparator: \",\",\n}\n\nfunction getPrintableKittyKeyText(key: ParsedKey): string | undefined {\n return printableKeypadText[key.name]\n}\n\nfunction fromKittyMods(mod: number): {\n shift: boolean\n alt: boolean\n ctrl: boolean\n super: boolean\n hyper: boolean\n meta: boolean\n capsLock: boolean\n numLock: boolean\n} {\n return {\n shift: !!(mod & 1),\n alt: !!(mod & 2),\n ctrl: !!(mod & 4),\n super: !!(mod & 8),\n hyper: !!(mod & 16),\n meta: !!(mod & 32),\n capsLock: !!(mod & 64),\n numLock: !!(mod & 128),\n }\n}\n\n// Map functional key CSI codes to key names\nconst functionalKeyMap: Record = {\n A: \"up\",\n B: \"down\",\n C: \"right\",\n D: \"left\",\n H: \"home\",\n F: \"end\",\n E: \"clear\",\n P: \"f1\",\n Q: \"f2\",\n S: \"f4\",\n}\n\n// Map tilde key numbers to key names (CSI number ~ format)\nconst tildeKeyMap: Record = {\n \"1\": \"home\",\n \"2\": \"insert\",\n \"3\": \"delete\",\n \"4\": \"end\",\n \"5\": \"pageup\",\n \"6\": \"pagedown\",\n \"7\": \"home\", // rxvt\n \"8\": \"end\", // rxvt\n \"11\": \"f1\",\n \"12\": \"f2\",\n \"13\": \"f3\",\n \"14\": \"f4\",\n \"15\": \"f5\",\n \"17\": \"f6\",\n \"18\": \"f7\",\n \"19\": \"f8\",\n \"20\": \"f9\",\n \"21\": \"f10\",\n \"23\": \"f11\",\n \"24\": \"f12\",\n \"29\": \"menu\",\n \"57427\": \"clear\",\n}\n\n/**\n * Parse Kitty keyboard protocol special keys (functional and tilde) with event type\n * Formats:\n * Functional: CSI 1;modifiers:event_type LETTER (e.g., \\x1b[1;1:1A = up arrow press)\n * Tilde: CSI number;modifiers:event_type ~ (e.g., \\x1b[5;1:1~ = pageup press)\n */\nfunction parseKittySpecialKey(sequence: string): ParsedKey | null {\n // Combined regex: matches both functional keys (letter) and tilde keys (~)\n const specialKeyRe = /^\\x1b\\[(\\d+);(\\d+):(\\d+)([A-Z~])$/\n const match = specialKeyRe.exec(sequence)\n\n if (!match) return null\n\n const keyNumOrOne = match[1]\n const modifierStr = match[2]\n const eventTypeStr = match[3]\n const terminator = match[4]\n\n // Determine key name based on terminator\n let keyName: string | undefined\n if (terminator === \"~\") {\n // Tilde key: lookup by number\n keyName = tildeKeyMap[keyNumOrOne]\n } else {\n // Functional key: must have \"1\" as first param, lookup by letter\n if (keyNumOrOne !== \"1\") return null\n keyName = functionalKeyMap[terminator]\n }\n\n if (!keyName) return null\n\n const key: ParsedKey = {\n name: keyName,\n ctrl: false,\n meta: false,\n shift: false,\n option: false,\n number: false,\n sequence,\n raw: sequence,\n eventType: \"press\",\n source: \"kitty\",\n super: false,\n hyper: false,\n capsLock: false,\n numLock: false,\n }\n\n // Parse modifiers\n if (modifierStr) {\n const modifierMask = parseInt(modifierStr, 10)\n if (!isNaN(modifierMask) && modifierMask > 1) {\n const mods = fromKittyMods(modifierMask - 1)\n key.shift = mods.shift\n key.ctrl = mods.ctrl\n key.meta = mods.alt || mods.meta\n key.option = mods.alt\n key.super = mods.super\n key.hyper = mods.hyper\n key.capsLock = mods.capsLock\n key.numLock = mods.numLock\n }\n }\n\n // Parse event type: 1 = press, 2 = repeat, 3 = release\n if (eventTypeStr === \"1\" || !eventTypeStr) {\n key.eventType = \"press\"\n } else if (eventTypeStr === \"2\") {\n key.eventType = \"press\"\n key.repeated = true\n } else if (eventTypeStr === \"3\") {\n key.eventType = \"release\"\n }\n\n return key\n}\n\nexport function parseKittyKeyboard(sequence: string): ParsedKey | null {\n // Try special key format (functional letters or tilde keys with event type)\n const specialResult = parseKittySpecialKey(sequence)\n if (specialResult) return specialResult\n\n // Kitty keyboard protocol: CSI unicode-key-code:alternate-key-codes ; modifiers:event-type ; text-as-codepoints u\n const kittyRe = /^\\x1b\\[([^\\x1b]+)u$/\n const match = kittyRe.exec(sequence)\n\n if (!match) return null\n\n const params = match[1]\n const fields = params.split(\";\")\n\n if (fields.length < 1) return null\n\n const key: ParsedKey = {\n name: \"\",\n ctrl: false,\n meta: false,\n shift: false,\n option: false,\n number: false,\n sequence,\n raw: sequence,\n eventType: \"press\",\n source: \"kitty\",\n super: false,\n hyper: false,\n capsLock: false,\n numLock: false,\n }\n\n let text = \"\"\n\n // Parse field 1: unicode-key-code:shifted_codepoint:base_layout_codepoint.\n // The character this key produced, the shifted variant, and what the same\n // physical key would be on the base layout. Example: a key can produce `ㅊ`\n // but still report base-layout codepoint 99, which is Unicode `c`.\n const field1 = fields[0]?.split(\":\") || []\n const codepointStr = field1[0]\n if (!codepointStr) return null\n\n const codepoint = parseInt(codepointStr, 10)\n if (isNaN(codepoint)) return null\n\n let shiftedCodepoint: number | undefined\n let baseCodepoint: number | undefined\n\n // Parse shifted and base codepoints\n if (field1[1]) {\n const shifted = parseInt(field1[1], 10)\n if (!isNaN(shifted) && shifted > 0 && shifted <= 0x10ffff) {\n shiftedCodepoint = shifted\n }\n }\n if (field1[2]) {\n const base = parseInt(field1[2], 10)\n if (!isNaN(base) && base > 0 && base <= 0x10ffff) {\n baseCodepoint = base\n }\n }\n\n const knownKey = kittyKeyMap[codepoint]\n if (knownKey) {\n key.name = knownKey\n key.code = `[${codepoint}u`\n } else if (codepoint === 0) {\n key.name = \"\"\n } else {\n // It's a Unicode character\n if (codepoint > 0 && codepoint <= 0x10ffff) {\n const char = String.fromCodePoint(codepoint)\n key.name = char === \" \" ? \"space\" : char\n\n // Keep the raw Unicode codepoint from Kitty so higher-level matching can\n // later turn `99` into `c` and use that as a layout-stable fallback.\n if (baseCodepoint) {\n key.baseCode = baseCodepoint\n }\n } else {\n return null // Invalid codepoint\n }\n }\n\n // Parse field 2: modifier_mask:event_type\n if (fields[1]) {\n const field2 = fields[1].split(\":\")\n const modifierStr = field2[0]\n const eventTypeStr = field2[1]\n\n if (modifierStr) {\n const modifierMask = parseInt(modifierStr, 10)\n if (!isNaN(modifierMask) && modifierMask > 1) {\n const mods = fromKittyMods(modifierMask - 1) // Kitty modifiers start from 1\n key.shift = mods.shift\n key.ctrl = mods.ctrl\n key.meta = mods.alt || mods.meta\n key.option = mods.alt\n key.super = mods.super\n key.hyper = mods.hyper\n key.capsLock = mods.capsLock\n key.numLock = mods.numLock\n }\n }\n\n // Parse event type: 1 = press (default), 2 = repeat, 3 = release\n if (eventTypeStr === \"1\" || !eventTypeStr) {\n key.eventType = \"press\"\n } else if (eventTypeStr === \"2\") {\n key.eventType = \"press\"\n key.repeated = true\n } else if (eventTypeStr === \"3\") {\n key.eventType = \"release\"\n } else {\n key.eventType = \"press\"\n }\n }\n\n // Parse field 3: text_as_codepoint[:text_as_codepoint]\n if (fields[2]) {\n const codepoints = fields[2].split(\":\")\n for (const cpStr of codepoints) {\n const cp = parseInt(cpStr, 10)\n if (!isNaN(cp) && cp > 0 && cp <= 0x10ffff) {\n text += String.fromCodePoint(cp)\n }\n }\n }\n\n if (text === \"\") {\n text = getPrintableKittyKeyText(key) ?? \"\"\n }\n\n // Handle text generation for printable characters\n if (text === \"\") {\n // Check if this is a printable character (not a key name like \"up\", \"f1\", etc.)\n const isPrintable = key.name.length > 0 && !kittyKeyMap[codepoint]\n if (isPrintable) {\n // Use shifted codepoint if shift is active and we have one\n if (codepoint === 32) {\n text = \" \"\n } else if (key.shift && shiftedCodepoint) {\n text = String.fromCodePoint(shiftedCodepoint)\n } else if (key.shift && key.name.length === 1) {\n // When shift is pressed but terminal didn't provide shifted codepoint,\n // convert the character to uppercase (works for Unicode including Cyrillic)\n text = key.name.toLocaleUpperCase()\n } else {\n text = key.name\n }\n }\n }\n\n if (text) {\n if (codepoint === 0) {\n key.name = text\n }\n key.sequence = text\n }\n\n if (codepoint === 0 && text === \"\") {\n return null\n }\n\n return key\n}\n", + "export interface ScrollAcceleration {\n tick(now?: number): number\n reset(): void\n}\n\nexport class LinearScrollAccel implements ScrollAcceleration {\n tick(_now?: number): number {\n return 1\n }\n\n reset(): void {}\n}\n\n/**\n * macOS-inspired scroll acceleration.\n *\n * The class measures the time between consecutive scroll events and keeps a short\n * moving window of the latest intervals. The average interval determines which\n * multiplier to apply so that quick bursts accelerate and slower gestures stay precise.\n *\n * For intuition, treat the streak as a continuous timeline and compare it with the\n * exponential distance curve from the pointer-acceleration research post:\n * d(t) = v₀ * ( t + A * (exp(t/τ) - 1 - t/τ) ).\n * Small t stays near the base multiplier, medium streaks settle on multiplier1, and\n * sustained bursts reach multiplier2, mirroring how the exponential curve bends up.\n *\n * Options:\n * - threshold1: upper bound (ms) of the \"medium\" band. Raise to delay the ramp.\n * - threshold2: upper bound (ms) of the \"fast\" band. Lower to demand tighter bursts.\n * - multiplier1: scale for medium speed streaks.\n * - multiplier2: scale for sustained fast streaks.\n * - baseMultiplier: scale for relaxed scrolling; set to 1 for linear behaviour.\n */\nexport class MacOSScrollAccel implements ScrollAcceleration {\n private lastTickTime = 0\n private velocityHistory: number[] = []\n private readonly historySize = 3\n private readonly streakTimeout = 150\n // Some terminals send 2 or more ticks for each mouse wheel tick, for example Ghostty, with a small delay between each tick, about 4ms on average.\n // We ignore these ticks otherwise they would cause faster acceleration to kick in\n // https://github.com/ghostty-org/ghostty/discussions/7577\n private readonly minTickInterval = 6\n\n constructor(\n private opts: {\n A?: number\n tau?: number\n maxMultiplier?: number\n } = {},\n ) {}\n\n tick(now = Date.now()): number {\n const A = this.opts.A ?? 0.8\n const tau = this.opts.tau ?? 3\n const maxMultiplier = this.opts.maxMultiplier ?? 6\n\n const dt = this.lastTickTime ? now - this.lastTickTime : Infinity\n\n // Reset streak if too much time has passed or first tick\n if (dt === Infinity || dt > this.streakTimeout) {\n this.lastTickTime = now\n this.velocityHistory = []\n return 1\n }\n\n // Ignore ticks closer than minTickInterval (they're part of the same logical tick)\n if (dt < this.minTickInterval) {\n return 1\n }\n\n this.lastTickTime = now\n\n this.velocityHistory.push(dt)\n if (this.velocityHistory.length > this.historySize) {\n this.velocityHistory.shift()\n }\n\n // Calculate average interval (lower = faster scrolling)\n const avgInterval = this.velocityHistory.reduce((a, b) => a + b, 0) / this.velocityHistory.length\n\n // Convert interval to velocity: faster ticks = higher velocity\n // Normalize to a reference interval (e.g., 100ms = velocity of 1)\n const referenceInterval = 100\n const velocity = referenceInterval / avgInterval\n\n // Apply exponential curve based on velocity\n // Higher velocity (tighter ticks) = more acceleration\n const x = velocity / tau\n const multiplier = 1 + A * (Math.exp(x) - 1)\n\n return Math.min(multiplier, maxMultiplier)\n }\n\n reset(): void {\n this.lastTickTime = 0\n this.velocityHistory = []\n }\n}\n", + "import {\n BoxSizing,\n Align,\n Dimension,\n Direction,\n Display,\n Edge,\n FlexDirection,\n Gutter,\n Justify,\n LogLevel,\n MeasureMode,\n Overflow,\n PositionType,\n Unit,\n Wrap,\n} from \"../yoga.js\"\n\nexport type AlignString =\n | \"auto\"\n | \"flex-start\"\n | \"center\"\n | \"flex-end\"\n | \"stretch\"\n | \"baseline\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\"\nexport type BoxSizingString = \"border-box\" | \"content-box\"\nexport type DimensionString = \"width\" | \"height\"\nexport type DirectionString = \"inherit\" | \"ltr\" | \"rtl\"\nexport type DisplayString = \"flex\" | \"none\" | \"contents\"\nexport type EdgeString = \"left\" | \"top\" | \"right\" | \"bottom\" | \"start\" | \"end\" | \"horizontal\" | \"vertical\" | \"all\"\nexport type FlexDirectionString = \"column\" | \"column-reverse\" | \"row\" | \"row-reverse\"\nexport type GutterString = \"column\" | \"row\" | \"all\"\nexport type JustifyString = \"flex-start\" | \"center\" | \"flex-end\" | \"space-between\" | \"space-around\" | \"space-evenly\"\nexport type LogLevelString = \"error\" | \"warn\" | \"info\" | \"debug\" | \"verbose\" | \"fatal\"\nexport type MeasureModeString = \"undefined\" | \"exactly\" | \"at-most\"\nexport type OverflowString = \"visible\" | \"hidden\" | \"scroll\"\nexport type PositionTypeString = \"static\" | \"relative\" | \"absolute\"\nexport type UnitString = \"undefined\" | \"point\" | \"percent\" | \"auto\"\nexport type WrapString = \"no-wrap\" | \"wrap\" | \"wrap-reverse\"\n\nexport function parseAlign(value: string | null | undefined): Align {\n if (value == null) {\n return Align.Auto\n }\n switch (value.toLowerCase()) {\n case \"auto\":\n return Align.Auto\n case \"flex-start\":\n return Align.FlexStart\n case \"center\":\n return Align.Center\n case \"flex-end\":\n return Align.FlexEnd\n case \"stretch\":\n return Align.Stretch\n case \"baseline\":\n return Align.Baseline\n case \"space-between\":\n return Align.SpaceBetween\n case \"space-around\":\n return Align.SpaceAround\n case \"space-evenly\":\n return Align.SpaceEvenly\n default:\n return Align.Auto\n }\n}\n\nexport function parseAlignItems(value: string | null | undefined): Align {\n if (value == null) {\n return Align.Stretch\n }\n switch (value.toLowerCase()) {\n case \"auto\":\n return Align.Auto\n case \"flex-start\":\n return Align.FlexStart\n case \"center\":\n return Align.Center\n case \"flex-end\":\n return Align.FlexEnd\n case \"stretch\":\n return Align.Stretch\n case \"baseline\":\n return Align.Baseline\n case \"space-between\":\n return Align.SpaceBetween\n case \"space-around\":\n return Align.SpaceAround\n case \"space-evenly\":\n return Align.SpaceEvenly\n default:\n return Align.Stretch\n }\n}\n\nexport function parseBoxSizing(value: string): BoxSizing {\n if (value == null) {\n return BoxSizing.BorderBox\n }\n switch (value.toLowerCase()) {\n case \"border-box\":\n return BoxSizing.BorderBox\n case \"content-box\":\n return BoxSizing.ContentBox\n default:\n return BoxSizing.BorderBox\n }\n}\n\nexport function parseDimension(value: string): Dimension {\n if (value == null) {\n return Dimension.Width\n }\n switch (value.toLowerCase()) {\n case \"width\":\n return Dimension.Width\n case \"height\":\n return Dimension.Height\n default:\n return Dimension.Width\n }\n}\n\nexport function parseDirection(value: string): Direction {\n if (value == null) {\n return Direction.LTR\n }\n switch (value.toLowerCase()) {\n case \"inherit\":\n return Direction.Inherit\n case \"ltr\":\n return Direction.LTR\n case \"rtl\":\n return Direction.RTL\n default:\n return Direction.LTR\n }\n}\n\nexport function parseDisplay(value: string): Display {\n if (value == null) {\n return Display.Flex\n }\n switch (value.toLowerCase()) {\n case \"flex\":\n return Display.Flex\n case \"none\":\n return Display.None\n case \"contents\":\n return Display.Contents\n default:\n return Display.Flex\n }\n}\n\nexport function parseEdge(value: string): Edge {\n if (value == null) {\n return Edge.All\n }\n switch (value.toLowerCase()) {\n case \"left\":\n return Edge.Left\n case \"top\":\n return Edge.Top\n case \"right\":\n return Edge.Right\n case \"bottom\":\n return Edge.Bottom\n case \"start\":\n return Edge.Start\n case \"end\":\n return Edge.End\n case \"horizontal\":\n return Edge.Horizontal\n case \"vertical\":\n return Edge.Vertical\n case \"all\":\n return Edge.All\n default:\n return Edge.All\n }\n}\n\nexport function parseFlexDirection(value: string | null | undefined): FlexDirection {\n if (value == null) {\n return FlexDirection.Column\n }\n switch (value.toLowerCase()) {\n case \"column\":\n return FlexDirection.Column\n case \"column-reverse\":\n return FlexDirection.ColumnReverse\n case \"row\":\n return FlexDirection.Row\n case \"row-reverse\":\n return FlexDirection.RowReverse\n default:\n return FlexDirection.Column\n }\n}\n\nexport function parseGutter(value: string): Gutter {\n if (value == null) {\n return Gutter.All\n }\n switch (value.toLowerCase()) {\n case \"column\":\n return Gutter.Column\n case \"row\":\n return Gutter.Row\n case \"all\":\n return Gutter.All\n default:\n return Gutter.All\n }\n}\n\nexport function parseJustify(value: string | null | undefined): Justify {\n if (value == null) {\n return Justify.FlexStart\n }\n switch (value.toLowerCase()) {\n case \"flex-start\":\n return Justify.FlexStart\n case \"center\":\n return Justify.Center\n case \"flex-end\":\n return Justify.FlexEnd\n case \"space-between\":\n return Justify.SpaceBetween\n case \"space-around\":\n return Justify.SpaceAround\n case \"space-evenly\":\n return Justify.SpaceEvenly\n default:\n return Justify.FlexStart\n }\n}\n\nexport function parseLogLevel(value: string): LogLevel {\n if (value == null) {\n return LogLevel.Info\n }\n switch (value.toLowerCase()) {\n case \"error\":\n return LogLevel.Error\n case \"warn\":\n return LogLevel.Warn\n case \"info\":\n return LogLevel.Info\n case \"debug\":\n return LogLevel.Debug\n case \"verbose\":\n return LogLevel.Verbose\n case \"fatal\":\n return LogLevel.Fatal\n default:\n return LogLevel.Info\n }\n}\n\nexport function parseMeasureMode(value: string): MeasureMode {\n if (value == null) {\n return MeasureMode.Undefined\n }\n switch (value.toLowerCase()) {\n case \"undefined\":\n return MeasureMode.Undefined\n case \"exactly\":\n return MeasureMode.Exactly\n case \"at-most\":\n return MeasureMode.AtMost\n default:\n return MeasureMode.Undefined\n }\n}\n\nexport function parseOverflow(value: string | null | undefined): Overflow {\n if (value == null) {\n return Overflow.Visible\n }\n switch (value.toLowerCase()) {\n case \"visible\":\n return Overflow.Visible\n case \"hidden\":\n return Overflow.Hidden\n case \"scroll\":\n return Overflow.Scroll\n default:\n return Overflow.Visible\n }\n}\n\nexport function parsePositionType(value: string | null | undefined): PositionType {\n if (value == null) {\n return PositionType.Relative\n }\n switch (value.toLowerCase()) {\n case \"static\":\n return PositionType.Static\n case \"relative\":\n return PositionType.Relative\n case \"absolute\":\n return PositionType.Absolute\n default:\n return PositionType.Static\n }\n}\n\nexport function parseUnit(value: string): Unit {\n if (value == null) {\n return Unit.Point\n }\n switch (value.toLowerCase()) {\n case \"undefined\":\n return Unit.Undefined\n case \"point\":\n return Unit.Point\n case \"percent\":\n return Unit.Percent\n case \"auto\":\n return Unit.Auto\n default:\n return Unit.Point\n }\n}\n\nexport function parseWrap(value: string | null | undefined): Wrap {\n if (value == null) {\n return Wrap.NoWrap\n }\n switch (value.toLowerCase()) {\n case \"no-wrap\":\n return Wrap.NoWrap\n case \"wrap\":\n return Wrap.Wrap\n case \"wrap-reverse\":\n return Wrap.WrapReverse\n default:\n return Wrap.NoWrap\n }\n}\n", + "export type MouseEventType = \"down\" | \"up\" | \"move\" | \"drag\" | \"drag-end\" | \"drop\" | \"over\" | \"out\" | \"scroll\"\n\nexport interface ScrollInfo {\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n delta: number\n}\n\nexport type RawMouseEvent = {\n type: MouseEventType\n button: number\n x: number\n y: number\n modifiers: { shift: boolean; alt: boolean; ctrl: boolean }\n scroll?: ScrollInfo\n}\n\ntype ParsedMouseSequence = {\n event: RawMouseEvent\n consumed: number\n}\n\nexport class MouseParser {\n private mouseButtonsPressed = new Set()\n\n private static readonly SCROLL_DIRECTIONS: Record = {\n 0: \"up\",\n 1: \"down\",\n 2: \"left\",\n 3: \"right\",\n }\n\n public reset(): void {\n this.mouseButtonsPressed.clear()\n }\n\n // Preserve raw byte values so X10 payload bytes >= 0x80 remain intact.\n // SGR sequences are ASCII digits + separators and are unaffected either way.\n private decodeInput(data: Buffer | Uint8Array): string {\n const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength)\n return buf.toString(\"latin1\")\n }\n\n public parseMouseEvent(data: Buffer | Uint8Array): RawMouseEvent | null {\n const str = this.decodeInput(data)\n const parsed = this.parseMouseSequenceAt(str, 0)\n return parsed?.event ?? null\n }\n\n public parseAllMouseEvents(data: Buffer | Uint8Array): RawMouseEvent[] {\n const str = this.decodeInput(data)\n const events: RawMouseEvent[] = []\n let offset = 0\n\n while (offset < str.length) {\n const parsed = this.parseMouseSequenceAt(str, offset)\n if (!parsed) {\n // Stop at the first non-mouse sequence. Callers can decide whether to\n // route any remaining data through keyboard/terminal input handling.\n break\n }\n\n events.push(parsed.event)\n offset += parsed.consumed\n }\n\n return events\n }\n\n private parseMouseSequenceAt(str: string, offset: number): ParsedMouseSequence | null {\n if (!str.startsWith(\"\\x1b[\", offset)) return null\n const introducer = str[offset + 2]\n\n if (introducer === \"<\") {\n return this.parseSgrSequence(str, offset)\n }\n\n if (introducer === \"M\") {\n return this.parseBasicSequence(str, offset)\n }\n\n return null\n }\n\n private parseSgrSequence(str: string, offset: number): ParsedMouseSequence | null {\n let index = offset + 3\n const values = [0, 0, 0]\n let part = 0\n let hasDigit = false\n\n while (index < str.length) {\n const char = str[index]\n const charCode = str.charCodeAt(index)\n\n if (charCode >= 48 && charCode <= 57) {\n hasDigit = true\n values[part] = values[part]! * 10 + (charCode - 48)\n index++\n continue\n }\n\n switch (char) {\n case \";\": {\n if (!hasDigit || part >= 2) return null\n part++\n hasDigit = false\n index++\n break\n }\n case \"M\":\n case \"m\": {\n if (!hasDigit || part !== 2) return null\n\n return {\n event: this.decodeSgrEvent(values[0]!, values[1]!, values[2]!, char),\n consumed: index - offset + 1,\n }\n }\n default:\n return null\n }\n }\n\n return null\n }\n\n private parseBasicSequence(str: string, offset: number): ParsedMouseSequence | null {\n // ESC [ M + 3 bytes\n if (offset + 6 > str.length) return null\n\n const buttonByte = str.charCodeAt(offset + 3) - 32\n // Convert from 1-based to 0-based\n const x = str.charCodeAt(offset + 4) - 33\n const y = str.charCodeAt(offset + 5) - 33\n\n return {\n event: this.decodeBasicEvent(buttonByte, x, y),\n consumed: 6,\n }\n }\n\n private decodeSgrEvent(rawButtonCode: number, wireX: number, wireY: number, pressRelease: \"M\" | \"m\"): RawMouseEvent {\n const button = rawButtonCode & 3\n const isScroll = (rawButtonCode & 64) !== 0\n const scrollDirection = !isScroll ? undefined : MouseParser.SCROLL_DIRECTIONS[button]\n\n const isMotion = (rawButtonCode & 32) !== 0\n const modifiers = {\n shift: (rawButtonCode & 4) !== 0,\n alt: (rawButtonCode & 8) !== 0,\n ctrl: (rawButtonCode & 16) !== 0,\n }\n\n let type: MouseEventType\n let scrollInfo: ScrollInfo | undefined\n\n if (isMotion) {\n const isDragging = this.mouseButtonsPressed.size > 0\n\n if (button === 3) {\n type = \"move\"\n } else if (isDragging) {\n type = \"drag\"\n } else {\n type = \"move\"\n }\n } else if (isScroll && pressRelease === \"M\") {\n type = \"scroll\"\n scrollInfo = {\n direction: scrollDirection!,\n delta: 1,\n }\n } else {\n type = pressRelease === \"M\" ? \"down\" : \"up\"\n\n if (type === \"down\" && button !== 3) {\n this.mouseButtonsPressed.add(button)\n } else if (type === \"up\") {\n this.mouseButtonsPressed.clear()\n }\n }\n\n return {\n type,\n button: button === 3 ? 0 : button,\n x: wireX - 1,\n y: wireY - 1,\n modifiers,\n scroll: scrollInfo,\n }\n }\n\n private decodeBasicEvent(buttonByte: number, x: number, y: number): RawMouseEvent {\n const button = buttonByte & 3\n const isScroll = (buttonByte & 64) !== 0\n const isMotion = (buttonByte & 32) !== 0\n const scrollDirection = !isScroll ? undefined : MouseParser.SCROLL_DIRECTIONS[button]\n\n const modifiers = {\n shift: (buttonByte & 4) !== 0,\n alt: (buttonByte & 8) !== 0,\n ctrl: (buttonByte & 16) !== 0,\n }\n\n let type: MouseEventType\n let actualButton: number\n let scrollInfo: ScrollInfo | undefined\n\n if (isMotion) {\n type = \"move\"\n actualButton = button === 3 ? -1 : button\n } else if (isScroll) {\n type = \"scroll\"\n actualButton = 0\n scrollInfo = {\n direction: scrollDirection!,\n delta: 1,\n }\n } else {\n type = button === 3 ? \"up\" : \"down\"\n actualButton = button === 3 ? 0 : button\n }\n\n return {\n type,\n button: actualButton,\n x,\n y,\n modifiers,\n scroll: scrollInfo,\n }\n }\n}\n", + "import { Renderable } from \"../Renderable.js\"\nimport type { ViewportBounds } from \"../types.js\"\nimport { coordinateToCharacterIndex, fonts } from \"./ascii.font.js\"\n\nclass SelectionAnchor {\n private relativeX: number\n private relativeY: number\n\n constructor(\n private renderable: Renderable,\n absoluteX: number,\n absoluteY: number,\n ) {\n this.relativeX = absoluteX - this.renderable.x\n this.relativeY = absoluteY - this.renderable.y\n }\n\n get x(): number {\n return this.renderable.x + this.relativeX\n }\n\n get y(): number {\n return this.renderable.y + this.relativeY\n }\n}\n\nexport class Selection {\n private _anchor: SelectionAnchor\n private _focus: { x: number; y: number }\n private _selectedRenderables: Renderable[] = []\n private _touchedRenderables: Renderable[] = []\n private _isActive: boolean = true\n private _isDragging: boolean = true\n private _isStart: boolean = false\n\n constructor(anchorRenderable: Renderable, anchor: { x: number; y: number }, focus: { x: number; y: number }) {\n this._anchor = new SelectionAnchor(anchorRenderable, anchor.x, anchor.y)\n this._focus = { ...focus }\n }\n\n get isStart(): boolean {\n return this._isStart\n }\n\n set isStart(value: boolean) {\n this._isStart = value\n }\n\n get anchor(): { x: number; y: number } {\n return { x: this._anchor.x, y: this._anchor.y }\n }\n\n get focus(): { x: number; y: number } {\n return { ...this._focus }\n }\n\n set focus(value: { x: number; y: number }) {\n this._focus = { ...value }\n }\n\n get isActive(): boolean {\n return this._isActive\n }\n\n set isActive(value: boolean) {\n this._isActive = value\n }\n\n get isDragging(): boolean {\n return this._isDragging\n }\n\n set isDragging(value: boolean) {\n this._isDragging = value\n }\n\n get bounds(): ViewportBounds {\n const minX = Math.min(this._anchor.x, this._focus.x)\n const maxX = Math.max(this._anchor.x, this._focus.x)\n const minY = Math.min(this._anchor.y, this._focus.y)\n const maxY = Math.max(this._anchor.y, this._focus.y)\n\n // Selection bounds are inclusive of both anchor and focus\n // A selection from (0,0) to (0,0) covers 1 cell\n // A selection from (0,0) to (5,3) covers cells from (0,0) to (5,3) inclusive\n const width = maxX - minX + 1\n const height = maxY - minY + 1\n\n return {\n x: minX,\n y: minY,\n width,\n height,\n }\n }\n\n updateSelectedRenderables(selectedRenderables: Renderable[]): void {\n this._selectedRenderables = selectedRenderables\n }\n\n get selectedRenderables(): Renderable[] {\n return this._selectedRenderables\n }\n\n updateTouchedRenderables(touchedRenderables: Renderable[]): void {\n this._touchedRenderables = touchedRenderables\n }\n\n get touchedRenderables(): Renderable[] {\n return this._touchedRenderables\n }\n\n getSelectedText(): string {\n const selectedTextsByLine = new Map>()\n const selectedRenderables = this._selectedRenderables\n // Sort by reading order: top-to-bottom, then left-to-right\n .sort((a, b) => {\n const aY = a.y\n const bY = b.y\n if (aY !== bY) {\n return aY - bY\n }\n return a.x - b.x\n })\n .filter((renderable) => !renderable.isDestroyed)\n\n for (const renderable of selectedRenderables) {\n const text = renderable.getSelectedText()\n if (!text) continue\n const lines = text.split(\"\\n\")\n for (let index = 0; index < lines.length; index += 1) {\n const y = renderable.y + index\n const line = selectedTextsByLine.get(y) ?? []\n line.push({ x: renderable.x, text: lines[index] })\n selectedTextsByLine.set(y, line)\n }\n }\n\n return [...selectedTextsByLine.entries()]\n .sort(([leftY], [rightY]) => leftY - rightY)\n .map(([, line]) =>\n line\n .sort((left, right) => left.x - right.x)\n .map((segment) => segment.text)\n .join(\"\"),\n )\n .join(\"\\n\")\n }\n}\n\nexport interface LocalSelectionBounds {\n anchorX: number\n anchorY: number\n focusX: number\n focusY: number\n isActive: boolean\n}\n\nexport function convertGlobalToLocalSelection(\n globalSelection: Selection | null,\n localX: number,\n localY: number,\n): LocalSelectionBounds | null {\n if (!globalSelection?.isActive) {\n return null\n }\n\n return {\n anchorX: globalSelection.anchor.x - localX,\n anchorY: globalSelection.anchor.y - localY,\n focusX: globalSelection.focus.x - localX,\n focusY: globalSelection.focus.y - localY,\n isActive: true,\n }\n}\n\nexport class ASCIIFontSelectionHelper {\n private localSelection: { start: number; end: number } | null = null\n\n constructor(\n private getText: () => string,\n private getFont: () => keyof typeof fonts,\n ) {}\n\n hasSelection(): boolean {\n return this.localSelection !== null\n }\n\n getSelection(): { start: number; end: number } | null {\n return this.localSelection\n }\n\n shouldStartSelection(localX: number, localY: number, width: number, height: number): boolean {\n if (localX < 0 || localX >= width || localY < 0 || localY >= height) {\n return false\n }\n\n const text = this.getText()\n const font = this.getFont()\n const charIndex = coordinateToCharacterIndex(localX, text, font)\n\n return charIndex >= 0 && charIndex <= text.length\n }\n\n onLocalSelectionChanged(localSelection: LocalSelectionBounds | null, width: number, height: number): boolean {\n const previousSelection = this.localSelection\n\n if (!localSelection?.isActive) {\n this.localSelection = null\n return previousSelection !== null\n }\n\n const text = this.getText()\n const font = this.getFont()\n\n const selStart = { x: localSelection.anchorX, y: localSelection.anchorY }\n const selEnd = { x: localSelection.focusX, y: localSelection.focusY }\n\n if (height - 1 < selStart.y || 0 > selEnd.y) {\n this.localSelection = null\n return previousSelection !== null\n }\n\n let startCharIndex = 0\n let endCharIndex = text.length\n\n if (selStart.y > height - 1) {\n // Selection starts below us - we're not selected\n this.localSelection = null\n return previousSelection !== null\n } else if (selStart.y >= 0 && selStart.y <= height - 1) {\n // Selection starts within our Y range - use the actual start X coordinate\n if (selStart.x > 0) {\n startCharIndex = coordinateToCharacterIndex(selStart.x, text, font)\n }\n }\n\n if (selEnd.y < 0) {\n // Selection ends above us - we're not selected\n this.localSelection = null\n return previousSelection !== null\n } else if (selEnd.y >= 0 && selEnd.y <= height - 1) {\n // Selection ends within our Y range - use the actual end X coordinate\n if (selEnd.x >= 0) {\n endCharIndex = coordinateToCharacterIndex(selEnd.x, text, font)\n } else {\n endCharIndex = 0\n }\n }\n\n if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) {\n this.localSelection = { start: startCharIndex, end: endCharIndex }\n } else {\n this.localSelection = null\n }\n\n return (\n previousSelection?.start !== this.localSelection?.start || previousSelection?.end !== this.localSelection?.end\n )\n }\n}\n", + "const singletonCacheSymbol = Symbol.for(\"@opentui/core/singleton\")\n\n/**\n * Ensures a value is initialized once per process,\n * persists across Bun hot reloads, and is type-safe.\n */\nexport function singleton(key: string, factory: () => T): T {\n // @ts-expect-error this symbol is only used in this file and is not part of the public API\n const bag = (globalThis[singletonCacheSymbol] ??= {})\n if (!(key in bag)) {\n bag[key] = factory()\n }\n return bag[key] as T\n}\n\nexport function getSingleton(key: string): T | undefined {\n // @ts-expect-error this symbol is only used in this file and is not part of the public API\n const bag = globalThis[singletonCacheSymbol]\n return bag?.[key] as T | undefined\n}\n\nexport function destroySingleton(key: string): void {\n // @ts-expect-error this symbol is only used in this file and is not part of the public API\n const bag = globalThis[singletonCacheSymbol]\n if (bag && key in bag) {\n delete bag[key]\n }\n}\n\nexport function hasSingleton(key: string): boolean {\n // @ts-expect-error this symbol is only used in this file and is not part of the public API\n const bag = globalThis[singletonCacheSymbol]\n return bag && key in bag\n}\n", + "import { singleton } from \"./singleton.js\"\n\n/**\n * Environment variable registry\n *\n * Usage:\n * ```ts\n * import { registerEnvVar, env } from \"./lib/env.ts\";\n *\n * // Register environment variables\n * registerEnvVar({\n * name: \"DEBUG\",\n * description: \"Enable debug logging\",\n * type: \"boolean\",\n * default: false\n * });\n *\n * registerEnvVar({\n * name: \"PORT\",\n * description: \"Server port number\",\n * type: \"number\",\n * default: 3000\n * });\n *\n * // Access environment variables\n * if (env.DEBUG) {\n * console.log(\"Debug mode enabled\");\n * }\n *\n * const port = env.PORT; // number\n * ```\n */\n\nexport interface EnvVarConfig {\n name: string\n description: string\n default?: string | boolean | number\n type?: \"string\" | \"boolean\" | \"number\"\n}\n\nexport const envRegistry: Record = singleton(\"env-registry\", () => ({}))\n\nexport function registerEnvVar(config: EnvVarConfig): void {\n const existing = envRegistry[config.name]\n if (existing) {\n if (\n existing.description !== config.description ||\n existing.type !== config.type ||\n existing.default !== config.default\n ) {\n throw new Error(\n `Environment variable \"${config.name}\" is already registered with different configuration. ` +\n `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`,\n )\n }\n return\n }\n envRegistry[config.name] = config\n}\n\nfunction normalizeBoolean(value: string): boolean {\n const lowerValue = value.toLowerCase()\n return [\"true\", \"1\", \"on\", \"yes\"].includes(lowerValue)\n}\n\nfunction parseEnvValue(config: EnvVarConfig): string | boolean | number {\n const envValue = process.env[config.name]\n\n if (envValue === undefined && config.default !== undefined) {\n return config.default\n }\n\n if (envValue === undefined) {\n throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`)\n }\n\n switch (config.type) {\n case \"boolean\":\n return typeof envValue === \"boolean\" ? envValue : normalizeBoolean(envValue)\n case \"number\":\n const numValue = Number(envValue)\n if (isNaN(numValue)) {\n throw new Error(`Environment variable ${config.name} must be a valid number, got: ${envValue}`)\n }\n return numValue\n case \"string\":\n default:\n return envValue\n }\n}\n\nclass EnvStore {\n private parsedValues: Map = new Map()\n\n get(key: string): any {\n if (this.parsedValues.has(key)) {\n return this.parsedValues.get(key)!\n }\n\n if (!(key in envRegistry)) {\n throw new Error(`Environment variable ${key} is not registered.`)\n }\n\n try {\n const value = parseEnvValue(envRegistry[key])\n this.parsedValues.set(key, value)\n return value\n } catch (error) {\n throw new Error(`Failed to parse env var ${key}: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n has(key: string): boolean {\n return key in envRegistry\n }\n\n clearCache(): void {\n this.parsedValues.clear()\n }\n}\n\nconst envStore = singleton(\"env-store\", () => new EnvStore())\n\nexport function clearEnvCache(): void {\n envStore.clearCache()\n}\n\nexport function generateEnvMarkdown(): string {\n const configs = Object.values(envRegistry)\n\n if (configs.length === 0) {\n return \"# Environment Variables\\n\\nNo environment variables registered.\\n\"\n }\n\n let markdown = \"# Environment Variables\\n\\n\"\n\n for (const config of configs) {\n markdown += `## ${config.name}\\n\\n`\n markdown += `${config.description}\\n\\n`\n\n markdown += `**Type:** \\`${config.type || \"string\"}\\` \\n`\n\n if (config.default !== undefined) {\n const defaultValue = typeof config.default === \"string\" ? `\"${config.default}\"` : String(config.default)\n markdown += `**Default:** \\`${defaultValue}\\`\\n`\n } else {\n markdown += \"**Default:** *Required*\\n\"\n }\n\n markdown += \"\\n\"\n }\n\n return markdown\n}\n\nexport function generateEnvColored(): string {\n const configs = Object.values(envRegistry)\n\n if (configs.length === 0) {\n return \"\\x1b[1;36mEnvironment Variables\\x1b[0m\\n\\nNo environment variables registered.\\n\"\n }\n\n let output = \"\\x1b[1;36mEnvironment Variables\\x1b[0m\\n\\n\"\n\n for (const config of configs) {\n output += `\\x1b[1;33m${config.name}\\x1b[0m\\n`\n output += `${config.description}\\n`\n output += `\\x1b[32mType:\\x1b[0m \\x1b[36m${config.type || \"string\"}\\x1b[0m\\n`\n\n if (config.default !== undefined) {\n const defaultValue = typeof config.default === \"string\" ? `\"${config.default}\"` : String(config.default)\n output += `\\x1b[32mDefault:\\x1b[0m \\x1b[35m${defaultValue}\\x1b[0m\\n`\n } else {\n output += `\\x1b[32mDefault:\\x1b[0m \\x1b[31mRequired\\x1b[0m\\n`\n }\n\n output += \"\\n\"\n }\n\n return output\n}\n\nexport const env = new Proxy({} as Record, {\n get(target, prop: string) {\n if (typeof prop !== \"string\") {\n return undefined\n }\n return envStore.get(prop)\n },\n\n has(target, prop: string) {\n return envStore.has(prop)\n },\n\n ownKeys() {\n return Object.keys(envRegistry)\n },\n\n getOwnPropertyDescriptor(target, prop: string) {\n if (envStore.has(prop)) {\n return {\n enumerable: true,\n configurable: true,\n get: () => envStore.get(prop),\n }\n }\n return undefined\n },\n})\n", + "// Byte-level stdin parser that turns raw terminal input into typed StdinEvents.\n//\n// This replaces a two-phase token -> decode pipeline with a single state machine\n// that produces fully typed events (key, mouse, paste, response) directly from\n// bytes. The parser owns all byte framing and protocol recognition. It does NOT\n// own event dispatch — that belongs to KeyHandler and the renderer.\n\nimport { Buffer } from \"node:buffer\"\nimport { SystemClock, type Clock, type TimerHandle } from \"./clock.js\"\nimport { parseKeypress, type ParsedKey } from \"./parse.keypress.js\"\nimport { MouseParser, type RawMouseEvent } from \"./parse.mouse.js\"\nimport type { PasteMetadata } from \"./paste.js\"\n\nexport { SystemClock, type Clock, type TimerHandle } from \"./clock.js\"\n\nexport type StdinResponseProtocol = \"csi\" | \"cpr\" | \"osc\" | \"dcs\" | \"apc\" | \"unknown\"\n\n// The four event types the parser produces. Everything stdin sends becomes\n// exactly one of these.\nexport type StdinEvent =\n | {\n type: \"key\"\n raw: string\n key: ParsedKey\n }\n | {\n type: \"mouse\"\n raw: string\n encoding: \"sgr\" | \"x10\"\n event: RawMouseEvent\n }\n | {\n type: \"paste\"\n bytes: Uint8Array\n metadata?: PasteMetadata\n }\n | {\n type: \"response\"\n protocol: StdinResponseProtocol\n sequence: string\n }\n\nexport interface StdinParserProtocolContext {\n kittyKeyboardEnabled: boolean\n privateCapabilityRepliesActive: boolean\n pixelResolutionQueryActive: boolean\n explicitWidthCprActive: boolean\n startupCursorCprActive: boolean\n}\n\nexport interface StdinParserOptions {\n timeoutMs?: number\n maxPendingBytes?: number\n armTimeouts?: boolean\n onTimeoutFlush?: () => void\n useKittyKeyboard?: boolean\n protocolContext?: Partial\n clock?: Clock\n}\n\n// State machine tags for the byte scanner. Each tag represents which protocol\n// framing mode the parser is currently inside. The sawEsc flag in osc/dcs/apc\n// tracks whether the previous byte was ESC, since the two-byte ST terminator\n// (ESC \\) can split across push() calls.\ntype ParserState =\n | { tag: \"ground\" }\n | { tag: \"utf8\"; expected: number; seen: number }\n | { tag: \"esc\" }\n | { tag: \"ss3\" }\n | { tag: \"csi\" }\n | { tag: \"csi_sgr_mouse\"; part: number; hasDigit: boolean }\n | { tag: \"csi_sgr_mouse_deferred\"; part: number; hasDigit: boolean }\n | { tag: \"csi_parametric\"; semicolons: number; segments: number; hasDigit: boolean; firstParamValue: number | null }\n | {\n tag: \"csi_parametric_deferred\"\n semicolons: number\n segments: number\n hasDigit: boolean\n firstParamValue: number | null\n }\n | {\n // Startup cursor CPR cancellation can happen before the parser has enough\n // bytes to distinguish a stale reply from ordinary CSI input. This state\n // keeps consuming that one pending reply until it is either discarded as\n // CPR noise or handed back to normal CSI parsing.\n tag: \"csi_parametric_ignored\"\n semicolons: number\n segments: number\n hasDigit: boolean\n firstParamValue: number | null\n }\n | { tag: \"csi_private_reply\"; semicolons: number; hasDigit: boolean; sawDollar: boolean }\n | { tag: \"csi_private_reply_deferred\"; semicolons: number; hasDigit: boolean; sawDollar: boolean }\n | { tag: \"osc\"; sawEsc: boolean }\n | { tag: \"dcs\"; sawEsc: boolean }\n | { tag: \"apc\"; sawEsc: boolean }\n | { tag: \"esc_recovery\" }\n | { tag: \"esc_less_mouse\" }\n | { tag: \"esc_less_x10_mouse\" }\n\n// Collects paste body incrementally, bypassing the main ByteQueue so large\n// pastes don't grow the parser buffer. Keeps only a small tail for end-marker\n// detection across chunk boundaries.\ninterface PasteCollector {\n tail: Uint8Array\n parts: Uint8Array[]\n totalLength: number\n}\n\n// 20ms is to distinguish a lone ESC keypress from the start of an\n// escape sequence. Gemini/Claude uses 50ms, Codex uses 20ms, trying\n// this as a balanced default for now.\nconst DEFAULT_TIMEOUT_MS = 20\nconst DEFAULT_MAX_PENDING_BYTES = 64 * 1024\nconst INITIAL_PENDING_CAPACITY = 256\nconst ESC = 0x1b\nconst BEL = 0x07\nconst BRACKETED_PASTE_START = Buffer.from(\"\\x1b[200~\")\nconst BRACKETED_PASTE_END = Buffer.from(\"\\x1b[201~\")\nconst EMPTY_BYTES = new Uint8Array(0)\nconst KEY_DECODER = new TextDecoder()\nconst DEFAULT_PROTOCOL_CONTEXT: StdinParserProtocolContext = {\n kittyKeyboardEnabled: false,\n privateCapabilityRepliesActive: false,\n pixelResolutionQueryActive: false,\n explicitWidthCprActive: false,\n startupCursorCprActive: false,\n}\n// rxvt uses $-terminated CSI sequences for shifted function keys (e.g. ESC[2$).\n// Standard CSI treats $ as an intermediate byte, not a final, so we match these\n// explicitly to avoid waiting for a \"real\" final byte that never arrives.\nconst RXVT_DOLLAR_CSI_RE = /^\\x1b\\[\\d+\\$$/\n\nconst SYSTEM_CLOCK = new SystemClock()\n\n// Byte buffer for pending input. Uses start/end offsets so consume() just\n// advances the start pointer without copying. Compacts (via copyWithin) only\n// when the consumed prefix exceeds half the buffer, keeping amortized cost low.\nclass ByteQueue {\n private buf: Uint8Array\n private start = 0\n private end = 0\n\n constructor(capacity = INITIAL_PENDING_CAPACITY) {\n this.buf = new Uint8Array(capacity)\n }\n\n get length(): number {\n return this.end - this.start\n }\n\n get capacity(): number {\n return this.buf.length\n }\n\n view(): Uint8Array {\n return this.buf.subarray(this.start, this.end)\n }\n\n // Returns a view of the contents and resets the queue. The view shares\n // the underlying buffer, so it becomes invalid on the next append().\n take(): Uint8Array {\n const chunk = this.view()\n this.start = 0\n this.end = 0\n return chunk\n }\n\n append(chunk: Uint8Array): void {\n if (chunk.length === 0) {\n return\n }\n\n this.ensureCapacity(this.length + chunk.length)\n this.buf.set(chunk, this.end)\n this.end += chunk.length\n }\n\n // Drops the first `count` bytes. Compacts when the consumed prefix\n // exceeds half the buffer to reclaim wasted space at the front.\n consume(count: number): void {\n if (count <= 0) {\n return\n }\n\n if (count >= this.length) {\n this.start = 0\n this.end = 0\n return\n }\n\n this.start += count\n if (this.start >= this.buf.length / 2) {\n this.buf.copyWithin(0, this.start, this.end)\n this.end -= this.start\n this.start = 0\n }\n }\n\n clear(): void {\n this.start = 0\n this.end = 0\n }\n\n reset(capacity = INITIAL_PENDING_CAPACITY): void {\n this.buf = new Uint8Array(capacity)\n this.start = 0\n this.end = 0\n }\n\n // Tries reclaiming space by compacting data to the front first.\n // Doubles the allocation if that still isn't enough.\n private ensureCapacity(requiredLength: number): void {\n const currentLength = this.length\n if (requiredLength <= this.buf.length) {\n const availableAtEnd = this.buf.length - this.end\n if (availableAtEnd >= requiredLength - currentLength) {\n return\n }\n\n this.buf.copyWithin(0, this.start, this.end)\n this.end = currentLength\n this.start = 0\n if (requiredLength <= this.buf.length) {\n return\n }\n }\n\n let nextCapacity = this.buf.length\n while (nextCapacity < requiredLength) {\n nextCapacity *= 2\n }\n\n const next = new Uint8Array(nextCapacity)\n next.set(this.view(), 0)\n this.buf = next\n this.start = 0\n this.end = currentLength\n }\n}\n\nfunction normalizePositiveOption(value: number | undefined, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return fallback\n }\n\n return Math.floor(value)\n}\n\n// Returns the expected byte count for a UTF-8 sequence given its lead byte,\n// or 0 for bytes that aren't valid UTF-8 leads. Returning 0 tells the parser\n// this is a legacy high-byte character (0x80–0xBF, 0xC0–0xC1, 0xF5+) that\n// goes through the parseKeypress() meta-key path instead.\nfunction utf8SequenceLength(first: number): number {\n if (first < 0x80) return 1\n if (first >= 0xc2 && first <= 0xdf) return 2\n if (first >= 0xe0 && first <= 0xef) return 3\n if (first >= 0xf0 && first <= 0xf4) return 4\n return 0\n}\n\nfunction bytesEqual(left: Uint8Array, right: Uint8Array): boolean {\n if (left.length !== right.length) {\n return false\n }\n\n for (let index = 0; index < left.length; index += 1) {\n if (left[index] !== right[index]) {\n return false\n }\n }\n\n return true\n}\n\n// Checks whether a byte sequence is a complete SGR mouse report:\n// ESC [ < Ps ; Ps ; Ps M/m (three semicolon-separated digit groups).\nfunction isMouseSgrSequence(sequence: Uint8Array): boolean {\n if (sequence.length < 7) {\n return false\n }\n\n if (sequence[0] !== ESC || sequence[1] !== 0x5b || sequence[2] !== 0x3c) {\n return false\n }\n\n const final = sequence[sequence.length - 1]\n if (final !== 0x4d && final !== 0x6d) {\n return false\n }\n\n let part = 0\n let hasDigit = false\n for (let index = 3; index < sequence.length - 1; index += 1) {\n const byte = sequence[index]!\n if (byte >= 0x30 && byte <= 0x39) {\n hasDigit = true\n continue\n }\n\n if (byte === 0x3b && hasDigit && part < 2) {\n part += 1\n hasDigit = false\n continue\n }\n\n return false\n }\n\n return part === 2 && hasDigit\n}\n\nfunction isAsciiDigit(byte: number): boolean {\n return byte >= 0x30 && byte <= 0x39\n}\n\ninterface ParametricCsiLike {\n semicolons: number\n segments: number\n hasDigit: boolean\n firstParamValue: number | null\n}\n\ninterface PrivateReplyCsiLike {\n semicolons: number\n hasDigit: boolean\n sawDollar: boolean\n}\n\nfunction parsePositiveDecimalPrefix(sequence: Uint8Array, start: number, endExclusive: number): number | null {\n if (start >= endExclusive) return null\n\n let value = 0\n let sawDigit = false\n for (let index = start; index < endExclusive; index += 1) {\n const byte = sequence[index]!\n if (!isAsciiDigit(byte)) return null\n sawDigit = true\n value = value * 10 + (byte - 0x30)\n }\n\n return sawDigit ? value : null\n}\n\n// Returns the leading kitty codepoint from field 1, like `97` in `97:65`.\n// The CSI scanner uses this at `;` boundaries to recognize alternate-key\n// forms (`codepoint[:shifted[:base]]`). That keeps split kitty sequences\n// pending, instead of flushing them as unknown on timeout.\nfunction parseKittyFirstFieldCodepoint(sequence: Uint8Array, start: number, endExclusive: number): number | null {\n if (start >= endExclusive) return null\n\n let firstColon = -1\n for (let index = start; index < endExclusive; index += 1) {\n if (sequence[index] === 0x3a) {\n firstColon = index\n break\n }\n }\n\n if (firstColon === -1) return null\n\n const codepoint = parsePositiveDecimalPrefix(sequence, start, firstColon)\n if (codepoint === null) return null\n\n // Remaining bytes in field 1 must stay kitty-compatible: digits or colons.\n for (let index = firstColon + 1; index < endExclusive; index += 1) {\n const byte = sequence[index]!\n if (byte !== 0x3a && !isAsciiDigit(byte)) return null\n }\n\n return codepoint\n}\n\nfunction canStillBeKittyU(state: ParametricCsiLike): boolean {\n return state.semicolons >= 1\n}\n\nfunction canStillBeKittySpecial(state: ParametricCsiLike): boolean {\n return state.semicolons === 1 && state.segments > 1\n}\n\nfunction canStillBeExplicitWidthCpr(state: ParametricCsiLike): boolean {\n return state.firstParamValue === 1 && state.semicolons === 1\n}\n\nfunction canStillBeStartupCursorCpr(state: ParametricCsiLike): boolean {\n return state.semicolons === 1\n}\n\nfunction canStillBeStartupCursorCprPrefix(state: ParametricCsiLike): boolean {\n return state.segments === 1 && state.semicolons <= 1\n}\n\nfunction canStillBePixelResolution(state: ParametricCsiLike): boolean {\n return state.firstParamValue === 4 && state.semicolons === 2\n}\n\nfunction canDeferParametricCsi(state: ParametricCsiLike, context: StdinParserProtocolContext): boolean {\n return (\n (context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state))) ||\n (context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state)) ||\n (context.startupCursorCprActive && canStillBeStartupCursorCpr(state)) ||\n (context.pixelResolutionQueryActive && canStillBePixelResolution(state))\n )\n}\n\nfunction canCompleteDeferredParametricCsi(\n state: ParametricCsiLike,\n byte: number,\n context: StdinParserProtocolContext,\n): boolean {\n if (context.kittyKeyboardEnabled) {\n if (state.hasDigit && byte === 0x75) return true\n if (\n state.hasDigit &&\n state.semicolons === 1 &&\n state.segments > 1 &&\n (byte === 0x7e || (byte >= 0x41 && byte <= 0x5a))\n ) {\n return true\n }\n }\n\n if (\n context.explicitWidthCprActive &&\n state.hasDigit &&\n state.firstParamValue === 1 &&\n state.semicolons === 1 &&\n byte === 0x52\n ) {\n return true\n }\n\n if (context.startupCursorCprActive && state.hasDigit && state.semicolons === 1 && byte === 0x52) {\n return true\n }\n\n if (\n context.pixelResolutionQueryActive &&\n state.hasDigit &&\n state.firstParamValue === 4 &&\n state.semicolons === 2 &&\n byte === 0x74\n ) {\n return true\n }\n\n return false\n}\n\nfunction classifyParametricCsiProtocol(state: ParametricCsiLike, finalByte: number): StdinResponseProtocol {\n if (finalByte === 0x52 && state.semicolons === 1 && state.segments === 1 && state.hasDigit) {\n return \"cpr\"\n }\n\n return \"csi\"\n}\n\nfunction canDeferPrivateReplyCsi(context: StdinParserProtocolContext): boolean {\n return context.privateCapabilityRepliesActive\n}\n\nfunction canCompleteDeferredPrivateReplyCsi(\n state: PrivateReplyCsiLike,\n byte: number,\n context: StdinParserProtocolContext,\n): boolean {\n if (!context.privateCapabilityRepliesActive) return false\n if (state.sawDollar) return state.hasDigit && byte === 0x79\n if (byte === 0x63) return state.hasDigit || state.semicolons > 0\n if (byte === 0x6e) return state.hasDigit\n return state.hasDigit && byte === 0x75\n}\n\nfunction concatBytes(left: Uint8Array, right: Uint8Array): Uint8Array {\n if (left.length === 0) {\n return right\n }\n\n if (right.length === 0) {\n return left\n }\n\n const combined = new Uint8Array(left.length + right.length)\n combined.set(left, 0)\n combined.set(right, left.length)\n return combined\n}\n\nfunction withEscPrefix(bytes: Uint8Array): Uint8Array {\n const prefixed = new Uint8Array(bytes.length + 1)\n prefixed[0] = ESC\n prefixed.set(bytes, 1)\n return prefixed\n}\n\nfunction indexOfBytes(haystack: Uint8Array, needle: Uint8Array): number {\n if (needle.length === 0) {\n return 0\n }\n\n const limit = haystack.length - needle.length\n for (let offset = 0; offset <= limit; offset += 1) {\n let matched = true\n for (let index = 0; index < needle.length; index += 1) {\n if (haystack[offset + index] !== needle[index]) {\n matched = false\n break\n }\n }\n\n if (matched) {\n return offset\n }\n }\n\n return -1\n}\n\n// Decodes raw protocol bytes as latin1. Used for mouse and response events\n// where the wire bytes may not be valid UTF-8 but need a lossless string\n// form for downstream sequence handlers.\nfunction decodeLatin1(bytes: Uint8Array): string {\n return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString(\"latin1\")\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n return KEY_DECODER.decode(bytes)\n}\n\nfunction createPasteCollector(): PasteCollector {\n return {\n tail: EMPTY_BYTES,\n parts: [],\n totalLength: 0,\n }\n}\n\nfunction joinPasteBytes(parts: Uint8Array[], totalLength: number): Uint8Array {\n if (totalLength === 0) {\n return EMPTY_BYTES\n }\n\n if (parts.length === 1) {\n return parts[0]!\n }\n\n const bytes = new Uint8Array(totalLength)\n let offset = 0\n for (const part of parts) {\n bytes.set(part, offset)\n offset += part.length\n }\n\n return bytes\n}\n\n// Push-driven stdin parser. Callers feed raw bytes via push(), then read\n// typed events via read() or drain(). At most one incomplete protocol unit\n// is buffered at a time; everything else is immediately converted to events.\n//\n// The parser guarantees chunk-shape invariance: the same bytes always produce\n// the same events, regardless of chunk boundaries. A lone ESC resolves via\n// timeout, split UTF-8 codepoints reassemble correctly, and bracketed paste\n// markers may split across any chunk boundary.\nexport class StdinParser {\n private readonly pending = new ByteQueue(INITIAL_PENDING_CAPACITY)\n private readonly events: StdinEvent[] = []\n private readonly timeoutMs: number\n private readonly maxPendingBytes: number\n private readonly armTimeouts: boolean\n private readonly onTimeoutFlush: (() => void) | null\n private readonly useKittyKeyboard: boolean\n private readonly mouseParser = new MouseParser()\n private readonly clock: Clock\n private protocolContext: StdinParserProtocolContext\n private timeoutId: TimerHandle | null = null\n private destroyed = false\n // When the current incomplete unit first appeared. Null when nothing is pending.\n private pendingSinceMs: number | null = null\n // When true, the state machine treats the current incomplete prefix as\n // final and emits it as one atomic event (e.g. a lone ESC becomes an\n // Escape key). Set by the timeout, consumed by the next read() or drain().\n private forceFlush = false\n // True only immediately after a timeout flush emits a lone ESC key. The next\n // `[` may begin a delayed `[<...M/m` mouse continuation recovery path.\n private justFlushedEsc = false\n private state: ParserState = { tag: \"ground\" }\n // Scan position within pending.view() during scanPending().\n private cursor = 0\n // Start of the protocol unit currently being parsed. The bytes from\n // unitStart through cursor all belong to one atomic unit.\n private unitStart = 0\n // When non-null, the parser is inside a bracketed paste. All incoming\n // bytes flow through consumePasteBytes() instead of the normal state machine.\n private paste: PasteCollector | null = null\n\n constructor(options: StdinParserOptions = {}) {\n this.timeoutMs = normalizePositiveOption(options.timeoutMs, DEFAULT_TIMEOUT_MS)\n this.maxPendingBytes = normalizePositiveOption(options.maxPendingBytes, DEFAULT_MAX_PENDING_BYTES)\n this.armTimeouts = options.armTimeouts ?? true\n this.onTimeoutFlush = options.onTimeoutFlush ?? null\n this.useKittyKeyboard = options.useKittyKeyboard ?? true\n this.clock = options.clock ?? SYSTEM_CLOCK\n this.protocolContext = {\n ...DEFAULT_PROTOCOL_CONTEXT,\n kittyKeyboardEnabled: options.protocolContext?.kittyKeyboardEnabled ?? false,\n privateCapabilityRepliesActive: options.protocolContext?.privateCapabilityRepliesActive ?? false,\n pixelResolutionQueryActive: options.protocolContext?.pixelResolutionQueryActive ?? false,\n explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false,\n startupCursorCprActive: options.protocolContext?.startupCursorCprActive ?? false,\n }\n }\n\n public get bufferCapacity(): number {\n return this.pending.capacity\n }\n\n public updateProtocolContext(patch: Partial): void {\n this.ensureAlive()\n this.protocolContext = { ...this.protocolContext, ...patch }\n this.reconcileDeferredStateWithProtocolContext()\n this.reconcileTimeoutState()\n }\n\n // A startup CPR can be split either after `ESC[` or after the first `;`.\n // Normalize both shapes into one ignore-state so leaving split-footer can\n // cancel the stale reply without also swallowing unrelated CSI sequences.\n private getAbortableStartupCursorCprState(): Extract | null {\n if (this.pending.length === 0) {\n return null\n }\n\n switch (this.state.tag) {\n case \"csi\": {\n const bytes = this.pending.view()\n const firstParamStart = this.unitStart + 2\n if (this.cursor < firstParamStart) {\n return null\n }\n\n let firstParamValue: number | null = null\n for (let index = firstParamStart; index < this.cursor; index += 1) {\n const byte = bytes[index]!\n if (!isAsciiDigit(byte)) {\n return null\n }\n\n firstParamValue = (firstParamValue ?? 0) * 10 + (byte - 0x30)\n }\n\n return {\n tag: \"csi_parametric_ignored\",\n semicolons: 0,\n segments: 1,\n hasDigit: this.cursor > firstParamStart,\n firstParamValue,\n }\n }\n\n case \"csi_parametric\":\n case \"csi_parametric_deferred\":\n if (\n !canStillBeStartupCursorCprPrefix(this.state) ||\n (this.protocolContext.explicitWidthCprActive && canStillBeExplicitWidthCpr(this.state))\n ) {\n return null\n }\n\n return {\n tag: \"csi_parametric_ignored\",\n semicolons: this.state.semicolons,\n segments: this.state.segments,\n hasDigit: this.state.hasDigit,\n firstParamValue: this.state.firstParamValue,\n }\n }\n\n return null\n }\n\n public abortPendingStartupCursorCpr(): void {\n this.ensureAlive()\n\n const nextState = this.getAbortableStartupCursorCprState()\n if (!nextState) {\n return\n }\n\n this.state = nextState\n\n if (this.pendingSinceMs === null) {\n this.markPending()\n }\n\n this.forceFlush = false\n this.reconcileTimeoutState()\n }\n\n // Feeds raw stdin bytes into the parser. Converts as much as possible into\n // queued events and leaves at most one incomplete unit behind in pending.\n //\n // When a chunk contains a paste start marker, bytes before the marker go\n // through normal parsing, then paste mode takes over for the rest. This\n // prevents large pastes from growing the main buffer.\n public push(data: Uint8Array): void {\n this.ensureAlive()\n if (data.length === 0) {\n // Preserve the existing empty-chunk -> empty-keypress behavior.\n this.emitKeyOrResponse(\"unknown\", \"\")\n return\n }\n\n let remainder = data\n while (remainder.length > 0) {\n if (this.paste) {\n remainder = this.consumePasteBytes(remainder)\n continue\n }\n\n // If we're in ground state with nothing pending, scan the incoming\n // chunk for a paste start marker. Only append through the marker so\n // scanPending() enters paste mode without buffering the full paste.\n const immediatePasteStartIndex =\n this.state.tag === \"ground\" && this.pending.length === 0 ? indexOfBytes(remainder, BRACKETED_PASTE_START) : -1\n const appendEnd =\n immediatePasteStartIndex === -1 ? remainder.length : immediatePasteStartIndex + BRACKETED_PASTE_START.length\n\n this.pending.append(remainder.subarray(0, appendEnd))\n remainder = remainder.subarray(appendEnd)\n this.scanPending()\n\n if (this.paste && this.pending.length > 0) {\n remainder = this.consumePasteBytes(this.takePendingBytes())\n continue\n }\n\n if (!this.paste && this.pending.length > this.maxPendingBytes) {\n this.flushPendingOverflow()\n this.scanPending()\n\n if (this.paste && this.pending.length > 0) {\n remainder = this.consumePasteBytes(this.takePendingBytes())\n }\n }\n }\n\n this.reconcileTimeoutState()\n }\n\n // Pops one event from the queue. If the queue is empty and a timeout has\n // set forceFlush, re-scans pending to convert the timed-out incomplete\n // unit into one final event before returning it.\n public read(): StdinEvent | null {\n this.ensureAlive()\n\n if (this.events.length === 0 && this.forceFlush) {\n this.scanPending()\n this.reconcileTimeoutState()\n }\n\n return this.events.shift() ?? null\n }\n\n // Delivers all queued events. Stops early if the parser is destroyed\n // during a callback (e.g. an event handler triggers teardown).\n public drain(onEvent: (event: StdinEvent) => void): void {\n this.ensureAlive()\n\n while (true) {\n if (this.destroyed) {\n return\n }\n\n const event = this.read()\n if (!event) {\n return\n }\n\n onEvent(event)\n }\n }\n\n // Marks the parser for forced flush if enough time has passed since\n // incomplete data arrived. Does not immediately emit events — the next\n // read() or drain() does the actual flush. This separation keeps the\n // timer callback from emitting events mid-flight in user code.\n public flushTimeout(nowMsValue: number = this.clock.now()): void {\n this.ensureAlive()\n\n if (\n this.pendingSinceMs !== null &&\n (nowMsValue < this.pendingSinceMs || nowMsValue - this.pendingSinceMs < this.timeoutMs)\n ) {\n return\n }\n\n this.tryForceFlush()\n }\n\n // Sets forceFlush when there are pending bytes outside of a paste.\n // Extracted so the setTimeout callback in reconcileTimeoutState() can\n // bypass flushTimeout()'s elapsed-time comparison. Timer scheduling and\n // clock.now() sampling can disagree by a small amount; re-checking elapsed\n // time in the callback can skip a flush and leave pending bytes stuck.\n private tryForceFlush(): void {\n if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {\n return\n }\n\n this.forceFlush = true\n }\n\n public reset(): void {\n if (this.destroyed) {\n return\n }\n\n this.clearTimeout()\n this.resetState()\n }\n\n public resetMouseState(): void {\n this.ensureAlive()\n this.mouseParser.reset()\n }\n\n public destroy(): void {\n if (this.destroyed) {\n return\n }\n\n this.clearTimeout()\n this.destroyed = true\n this.resetState()\n }\n\n private ensureAlive(): void {\n if (this.destroyed) {\n throw new Error(\"StdinParser has been destroyed\")\n }\n }\n\n // Scans the pending byte buffer one byte at a time, dispatching on the\n // current parser state. All protocol framing lives in this single switch\n // — intentionally not split into per-mode scan helpers.\n //\n // Exits when: all bytes consumed (ground), more bytes needed (incomplete\n // unit), or paste mode entered (body handled by consumePasteBytes).\n private scanPending(): void {\n while (!this.paste) {\n const bytes = this.pending.view()\n if (this.state.tag === \"ground\" && this.cursor >= bytes.length) {\n this.pending.clear()\n this.cursor = 0\n this.unitStart = 0\n this.pendingSinceMs = null\n this.forceFlush = false\n return\n }\n\n const byte = this.cursor < bytes.length ? bytes[this.cursor]! : -1\n switch (this.state.tag) {\n case \"ground\": {\n this.unitStart = this.cursor\n\n // After a timeout-flushed lone ESC, a following `[` may be the start\n // of a delayed `[<...M/m` mouse continuation. Recover only this narrow\n // case; otherwise clear the recovery flag and parse bytes normally.\n if (this.justFlushedEsc) {\n if (byte === 0x5b) {\n this.justFlushedEsc = false\n this.cursor += 1\n this.state = { tag: \"esc_recovery\" }\n continue\n }\n\n this.justFlushedEsc = false\n }\n\n if (byte === ESC) {\n this.cursor += 1\n this.state = { tag: \"esc\" }\n continue\n }\n\n if (byte < 0x80) {\n this.emitKeyOrResponse(\"unknown\", decodeUtf8(bytes.subarray(this.cursor, this.cursor + 1)))\n this.consumePrefix(this.cursor + 1)\n continue\n }\n\n // Invalid UTF-8 lead byte. Could be a legacy high-byte from an\n // older terminal. If it's the last byte in the buffer, wait for\n // more data or a timeout before committing. On timeout, emit\n // through parseKeypress() which handles meta-key behavior.\n const expected = utf8SequenceLength(byte)\n if (expected === 0) {\n if (!this.forceFlush && this.cursor + 1 === bytes.length) {\n this.markPending()\n return\n }\n\n this.emitLegacyHighByte(byte)\n this.consumePrefix(this.cursor + 1)\n continue\n }\n\n this.cursor += 1\n this.state = { tag: \"utf8\", expected, seen: 1 }\n continue\n }\n\n case \"utf8\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitLegacyHighByte(bytes[this.unitStart]!)\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.unitStart + 1)\n continue\n }\n\n // Not a valid continuation byte. Treat the lead byte as a legacy\n // high-byte character and restart parsing from this position.\n if ((byte & 0xc0) !== 0x80) {\n this.emitLegacyHighByte(bytes[this.unitStart]!)\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.unitStart + 1)\n continue\n }\n\n const nextSeen = this.state.seen + 1\n this.cursor += 1\n if (nextSeen < this.state.expected) {\n this.state = { tag: \"utf8\", expected: this.state.expected, seen: nextSeen }\n continue\n }\n\n this.emitKeyOrResponse(\"unknown\", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n case \"esc\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n const flushedLoneEsc = this.cursor === this.unitStart + 1 && bytes[this.unitStart] === ESC\n this.emitKeyOrResponse(\"unknown\", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)))\n this.justFlushedEsc = flushedLoneEsc\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n // The byte after ESC determines the sub-protocol:\n // [ -> CSI, O -> SS3, ] -> OSC, P -> DCS, _ -> APC.\n switch (byte) {\n case 0x5b:\n this.cursor += 1\n this.state = { tag: \"csi\" }\n continue\n case 0x4f:\n this.cursor += 1\n this.state = { tag: \"ss3\" }\n continue\n case 0x5d:\n this.cursor += 1\n this.state = { tag: \"osc\", sawEsc: false }\n continue\n case 0x50:\n this.cursor += 1\n this.state = { tag: \"dcs\", sawEsc: false }\n continue\n case 0x5f:\n this.cursor += 1\n this.state = { tag: \"apc\", sawEsc: false }\n continue\n // ESC ESC: stay in esc state. Terminals encode Alt+ESC and\n // similar sequences as ESC ESC [...], so we keep scanning.\n case ESC:\n this.cursor += 1\n continue\n default:\n this.cursor += 1\n this.emitKeyOrResponse(\"unknown\", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n }\n\n case \"ss3\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n this.cursor += 1\n this.emitKeyOrResponse(\"unknown\", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n // Narrow recovery path for delayed mouse continuations after a\n // timeout-flushed lone ESC. Wait for either `<` (SGR) or `M` (X10); if\n // neither arrives, flush `[` as a normal key.\n case \"esc_recovery\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitKeyOrResponse(\"unknown\", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (byte === 0x3c) {\n this.cursor += 1\n this.state = { tag: \"esc_less_mouse\" }\n continue\n }\n\n if (byte === 0x4d) {\n this.cursor += 1\n this.state = { tag: \"esc_less_x10_mouse\" }\n continue\n }\n\n this.emitKeyOrResponse(\"unknown\", decodeUtf8(bytes.subarray(this.unitStart, this.unitStart + 1)))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.unitStart + 1)\n continue\n }\n\n case \"csi\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n // A new ESC inside an incomplete CSI means the previous sequence\n // was interrupted. Flush everything before the new ESC as one\n // opaque response, then restart parsing at the new ESC.\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n // X10 mouse: ESC [ M plus 3 raw payload bytes (button, x, y).\n // cursor === unitStart + 2 confirms M comes right after ESC[,\n // not as a later final byte in a different CSI sequence.\n if (byte === 0x4d && this.cursor === this.unitStart + 2) {\n const end = this.cursor + 4\n if (bytes.length < end) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, bytes.length))\n this.state = { tag: \"ground\" }\n this.consumePrefix(bytes.length)\n continue\n }\n\n this.emitMouse(bytes.subarray(this.unitStart, end), \"x10\")\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n if (byte === 0x24) {\n const candidateEnd = this.cursor + 1\n const candidate = decodeUtf8(bytes.subarray(this.unitStart, candidateEnd))\n if (RXVT_DOLLAR_CSI_RE.test(candidate)) {\n this.emitKeyOrResponse(\"csi\", candidate)\n this.state = { tag: \"ground\" }\n this.consumePrefix(candidateEnd)\n continue\n }\n\n if (!this.forceFlush && candidateEnd >= bytes.length) {\n this.markPending()\n return\n }\n }\n\n if (byte === 0x3c && this.cursor === this.unitStart + 2) {\n this.cursor += 1\n this.state = { tag: \"csi_sgr_mouse\", part: 0, hasDigit: false }\n continue\n }\n\n // Some terminals use ESC [[A..E / ESC [[5~ / ESC [[6~ variants.\n // Treat the second `[` immediately after ESC[ as part of the CSI\n // payload instead of as a final byte so parseKeypress() can match\n // `[[A`, `[[B`, `[[5~`, etc.\n if (byte === 0x5b && this.cursor === this.unitStart + 2) {\n this.cursor += 1\n continue\n }\n\n if (byte === 0x3f && this.cursor === this.unitStart + 2) {\n this.cursor += 1\n this.state = { tag: \"csi_private_reply\", semicolons: 0, hasDigit: false, sawDollar: false }\n continue\n }\n\n if (byte === 0x3b) {\n const firstParamStart = this.unitStart + 2\n const firstParamEnd = this.cursor\n let firstParamValue = parsePositiveDecimalPrefix(bytes, firstParamStart, firstParamEnd)\n\n if (firstParamValue === null && this.protocolContext.kittyKeyboardEnabled) {\n firstParamValue = parseKittyFirstFieldCodepoint(bytes, firstParamStart, firstParamEnd)\n }\n\n if (firstParamValue !== null) {\n this.cursor += 1\n this.state = {\n tag: \"csi_parametric\",\n semicolons: 1,\n segments: 1,\n hasDigit: false,\n firstParamValue,\n }\n continue\n }\n }\n\n // Standard CSI final byte (0x40–0x7E). Check for bracketed paste\n // start, SGR mouse, or a regular CSI key/response.\n if (byte >= 0x40 && byte <= 0x7e) {\n const end = this.cursor + 1\n const rawBytes = bytes.subarray(this.unitStart, end)\n\n if (bytesEqual(rawBytes, BRACKETED_PASTE_START)) {\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n this.paste = createPasteCollector()\n continue\n }\n\n if (isMouseSgrSequence(rawBytes)) {\n this.emitMouse(rawBytes, \"sgr\")\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.emitKeyOrResponse(\"csi\", decodeUtf8(rawBytes))\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.cursor += 1\n continue\n }\n\n case \"csi_sgr_mouse\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.state = { tag: \"csi_sgr_mouse_deferred\", part: this.state.part, hasDigit: this.state.hasDigit }\n this.pendingSinceMs = null\n this.forceFlush = false\n return\n }\n\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (isAsciiDigit(byte)) {\n this.cursor += 1\n this.state = { tag: \"csi_sgr_mouse\", part: this.state.part, hasDigit: true }\n continue\n }\n\n if (byte === 0x3b && this.state.hasDigit && this.state.part < 2) {\n this.cursor += 1\n this.state = { tag: \"csi_sgr_mouse\", part: this.state.part + 1, hasDigit: false }\n continue\n }\n\n if (byte >= 0x40 && byte <= 0x7e) {\n const end = this.cursor + 1\n const rawBytes = bytes.subarray(this.unitStart, end)\n if (isMouseSgrSequence(rawBytes)) {\n this.emitMouse(rawBytes, \"sgr\")\n } else {\n this.emitKeyOrResponse(\"csi\", decodeUtf8(rawBytes))\n }\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.state = { tag: \"csi\" }\n continue\n }\n\n case \"csi_sgr_mouse_deferred\": {\n if (this.cursor >= bytes.length) {\n this.pendingSinceMs = null\n this.forceFlush = false\n return\n }\n\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (isAsciiDigit(byte) || byte === 0x3b || byte === 0x4d || byte === 0x6d) {\n this.state = { tag: \"csi_sgr_mouse\", part: this.state.part, hasDigit: this.state.hasDigit }\n continue\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n case \"csi_parametric\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n if (canDeferParametricCsi(this.state, this.protocolContext)) {\n this.state = {\n tag: \"csi_parametric_deferred\",\n semicolons: this.state.semicolons,\n segments: this.state.segments,\n hasDigit: this.state.hasDigit,\n firstParamValue: this.state.firstParamValue,\n }\n this.pendingSinceMs = null\n this.forceFlush = false\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (isAsciiDigit(byte)) {\n this.cursor += 1\n this.state = {\n tag: \"csi_parametric\",\n semicolons: this.state.semicolons,\n segments: this.state.segments,\n hasDigit: true,\n firstParamValue: this.state.firstParamValue,\n }\n continue\n }\n\n if (byte === 0x3a && this.state.hasDigit && this.state.segments < 3) {\n this.cursor += 1\n this.state = {\n tag: \"csi_parametric\",\n semicolons: this.state.semicolons,\n segments: this.state.segments + 1,\n hasDigit: false,\n firstParamValue: this.state.firstParamValue,\n }\n continue\n }\n\n if (byte === 0x3b && this.state.semicolons < 2) {\n this.cursor += 1\n this.state = {\n tag: \"csi_parametric\",\n semicolons: this.state.semicolons + 1,\n segments: 1,\n hasDigit: false,\n firstParamValue: this.state.firstParamValue,\n }\n continue\n }\n\n if (byte >= 0x40 && byte <= 0x7e) {\n const end = this.cursor + 1\n const protocol = classifyParametricCsiProtocol(this.state, byte)\n this.emitKeyOrResponse(protocol, decodeUtf8(bytes.subarray(this.unitStart, end)))\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.state = { tag: \"csi\" }\n continue\n }\n\n case \"csi_parametric_deferred\": {\n if (this.cursor >= bytes.length) {\n this.pendingSinceMs = null\n this.forceFlush = false\n return\n }\n\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (isAsciiDigit(byte) || byte === 0x3a || byte === 0x3b) {\n this.state = {\n tag: \"csi_parametric\",\n semicolons: this.state.semicolons,\n segments: this.state.segments,\n hasDigit: this.state.hasDigit,\n firstParamValue: this.state.firstParamValue,\n }\n continue\n }\n\n if (canCompleteDeferredParametricCsi(this.state, byte, this.protocolContext)) {\n this.state = {\n tag: \"csi_parametric\",\n semicolons: this.state.semicolons,\n segments: this.state.segments,\n hasDigit: this.state.hasDigit,\n firstParamValue: this.state.firstParamValue,\n }\n continue\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n case \"csi_parametric_ignored\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (byte === ESC) {\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (isAsciiDigit(byte)) {\n this.cursor += 1\n this.state = {\n tag: \"csi_parametric_ignored\",\n semicolons: this.state.semicolons,\n segments: this.state.segments,\n hasDigit: true,\n firstParamValue:\n this.state.semicolons === 0\n ? (this.state.firstParamValue ?? 0) * 10 + (byte - 0x30)\n : this.state.firstParamValue,\n }\n continue\n }\n\n if (byte === 0x3b && this.state.semicolons === 0 && this.state.hasDigit) {\n // `CSI 1;...R` is also used by the explicit-width probe, so once we\n // learn that first param we must hand control back to normal CSI\n // parsing instead of discarding the rest of the reply.\n if (this.protocolContext.explicitWidthCprActive && this.state.firstParamValue === 1) {\n this.state = { tag: \"csi\" }\n continue\n }\n\n this.cursor += 1\n this.state = {\n tag: \"csi_parametric_ignored\",\n semicolons: 1,\n segments: 1,\n hasDigit: false,\n firstParamValue: this.state.firstParamValue,\n }\n continue\n }\n\n if (byte === 0x52 && this.state.semicolons === 1 && this.state.hasDigit) {\n const end = this.cursor + 1\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n if (this.state.semicolons === 0) {\n this.state = { tag: \"csi\" }\n continue\n }\n\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n case \"csi_private_reply\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n if (canDeferPrivateReplyCsi(this.protocolContext)) {\n this.state = {\n tag: \"csi_private_reply_deferred\",\n semicolons: this.state.semicolons,\n hasDigit: this.state.hasDigit,\n sawDollar: this.state.sawDollar,\n }\n this.pendingSinceMs = null\n this.forceFlush = false\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (isAsciiDigit(byte)) {\n this.cursor += 1\n this.state = {\n tag: \"csi_private_reply\",\n semicolons: this.state.semicolons,\n hasDigit: true,\n sawDollar: this.state.sawDollar,\n }\n continue\n }\n\n if (byte === 0x3b) {\n this.cursor += 1\n this.state = {\n tag: \"csi_private_reply\",\n semicolons: this.state.semicolons + 1,\n hasDigit: false,\n sawDollar: false,\n }\n continue\n }\n\n if (byte === 0x24 && this.state.hasDigit && !this.state.sawDollar) {\n this.cursor += 1\n this.state = {\n tag: \"csi_private_reply\",\n semicolons: this.state.semicolons,\n hasDigit: true,\n sawDollar: true,\n }\n continue\n }\n\n if (byte >= 0x40 && byte <= 0x7e) {\n const end = this.cursor + 1\n this.emitOpaqueResponse(\"csi\", bytes.subarray(this.unitStart, end))\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.state = { tag: \"csi\" }\n continue\n }\n\n case \"csi_private_reply_deferred\": {\n if (this.cursor >= bytes.length) {\n this.pendingSinceMs = null\n this.forceFlush = false\n return\n }\n\n if (byte === ESC) {\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (isAsciiDigit(byte) || byte === 0x3b || byte === 0x24) {\n this.state = {\n tag: \"csi_private_reply\",\n semicolons: this.state.semicolons,\n hasDigit: this.state.hasDigit,\n sawDollar: this.state.sawDollar,\n }\n continue\n }\n\n if (canCompleteDeferredPrivateReplyCsi(this.state, byte, this.protocolContext)) {\n this.state = {\n tag: \"csi_private_reply\",\n semicolons: this.state.semicolons,\n hasDigit: this.state.hasDigit,\n sawDollar: this.state.sawDollar,\n }\n continue\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n // OSC sequences end at BEL or ESC \\. DCS and APC end at ESC \\\n // only. The sawEsc flag tracks whether the previous byte was ESC,\n // since the two-byte ESC \\ can split across push() calls.\n case \"osc\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (this.state.sawEsc) {\n if (byte === 0x5c) {\n const end = this.cursor + 1\n this.emitOpaqueResponse(\"osc\", bytes.subarray(this.unitStart, end))\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.state = { tag: \"osc\", sawEsc: false }\n continue\n }\n\n if (byte === BEL) {\n const end = this.cursor + 1\n this.emitOpaqueResponse(\"osc\", bytes.subarray(this.unitStart, end))\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n if (byte === ESC) {\n this.cursor += 1\n this.state = { tag: \"osc\", sawEsc: true }\n continue\n }\n\n this.cursor += 1\n continue\n }\n\n case \"dcs\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (this.state.sawEsc) {\n if (byte === 0x5c) {\n const end = this.cursor + 1\n this.emitOpaqueResponse(\"dcs\", bytes.subarray(this.unitStart, end))\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.state = { tag: \"dcs\", sawEsc: false }\n continue\n }\n\n if (byte === ESC) {\n this.cursor += 1\n this.state = { tag: \"dcs\", sawEsc: true }\n continue\n }\n\n this.cursor += 1\n continue\n }\n\n case \"apc\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if (this.state.sawEsc) {\n if (byte === 0x5c) {\n const end = this.cursor + 1\n this.emitOpaqueResponse(\"apc\", bytes.subarray(this.unitStart, end))\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.state = { tag: \"apc\", sawEsc: false }\n continue\n }\n\n if (byte === ESC) {\n this.cursor += 1\n this.state = { tag: \"apc\", sawEsc: true }\n continue\n }\n\n this.cursor += 1\n continue\n }\n\n // Delayed SGR mouse continuation after `esc_recovery` has consumed the\n // leading `[`. Reconstruct the already-flushed ESC for valid mouse\n // reports so wheel/click input still works; keep malformed or partial\n // bytes opaque so they never leak into text input.\n case \"esc_less_mouse\": {\n if (this.cursor >= bytes.length) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n if ((byte >= 0x30 && byte <= 0x39) || byte === 0x3b) {\n this.cursor += 1\n continue\n }\n\n if (byte === 0x4d || byte === 0x6d) {\n const end = this.cursor + 1\n const rawBytes = bytes.subarray(this.unitStart, end)\n const prefixed = withEscPrefix(rawBytes)\n if (isMouseSgrSequence(prefixed)) {\n this.emitMouse(prefixed, \"sgr\")\n } else {\n this.emitOpaqueResponse(\"unknown\", rawBytes)\n }\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n continue\n }\n\n // Delayed X10 mouse continuation after `esc_recovery` has consumed the\n // leading `[`. Reconstruct the already-flushed ESC for valid mouse\n // reports so wheel/click input still works; keep malformed or partial\n // bytes opaque so they never leak into text input.\n case \"esc_less_x10_mouse\": {\n const end = this.unitStart + 5\n\n if (bytes.length < end) {\n if (!this.forceFlush) {\n this.markPending()\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", bytes.subarray(this.unitStart, bytes.length))\n this.state = { tag: \"ground\" }\n this.consumePrefix(bytes.length)\n continue\n }\n\n const rawBytes = bytes.subarray(this.unitStart, end)\n this.emitMouse(withEscPrefix(rawBytes), \"x10\")\n this.state = { tag: \"ground\" }\n this.consumePrefix(end)\n continue\n }\n }\n }\n }\n\n // Tries to parse the raw string as a key via parseKeypress(). If it\n // recognizes the sequence (printable char, arrow, function key, etc.),\n // emits a key event. Otherwise emits a response event — this is how\n // capability responses, focus sequences, and other non-key CSI traffic\n // avoids becoming text.\n private emitKeyOrResponse(protocol: StdinResponseProtocol, raw: string): void {\n const parsed = parseKeypress(raw, { useKittyKeyboard: this.useKittyKeyboard })\n if (parsed) {\n this.events.push({\n type: \"key\",\n raw: parsed.raw,\n key: parsed,\n })\n return\n }\n\n this.events.push({\n type: \"response\",\n protocol,\n sequence: raw,\n })\n }\n\n private emitMouse(rawBytes: Uint8Array, encoding: \"sgr\" | \"x10\"): void {\n const event = this.mouseParser.parseMouseEvent(rawBytes)\n if (!event) {\n this.emitOpaqueResponse(\"unknown\", rawBytes)\n return\n }\n\n this.events.push({\n type: \"mouse\",\n raw: decodeLatin1(rawBytes),\n encoding,\n event,\n })\n }\n\n // Handles single bytes in the 0x80–0xFF range that aren't valid UTF-8\n // leads. Passes them through parseKeypress() which maps them to the\n // existing meta-key behavior (e.g. Alt+letter in terminals that send\n // high bytes instead of ESC-prefixed sequences).\n private emitLegacyHighByte(byte: number): void {\n const parsed = parseKeypress(Buffer.from([byte]), { useKittyKeyboard: this.useKittyKeyboard })\n if (parsed) {\n this.events.push({\n type: \"key\",\n raw: parsed.raw,\n key: parsed,\n })\n return\n }\n\n this.events.push({\n type: \"response\",\n protocol: \"unknown\",\n sequence: String.fromCharCode(byte),\n })\n }\n\n private emitOpaqueResponse(protocol: StdinResponseProtocol, rawBytes: Uint8Array): void {\n this.events.push({\n type: \"response\",\n protocol,\n sequence: decodeLatin1(rawBytes),\n })\n }\n\n // Advances past a completed protocol unit. Resets cursor, unitStart,\n // and timeout state so the next scan iteration starts clean.\n private consumePrefix(endExclusive: number): void {\n this.pending.consume(endExclusive)\n this.cursor = 0\n this.unitStart = 0\n this.pendingSinceMs = null\n this.forceFlush = false\n }\n\n // Removes all bytes from the pending queue and returns them. Used when\n // entering paste mode — leftover bytes after the paste start marker\n // need to flow through consumePasteBytes() instead.\n private takePendingBytes(): Uint8Array {\n const buffered = this.pending.take()\n this.cursor = 0\n this.unitStart = 0\n this.pendingSinceMs = null\n this.forceFlush = false\n return buffered\n }\n\n // Emits all pending bytes as one opaque response and clears the buffer.\n // This keeps the parser buffer bounded at maxPendingBytes without\n // dropping data or splitting it into per-character events.\n private flushPendingOverflow(): void {\n if (this.pending.length === 0) {\n return\n }\n\n this.emitOpaqueResponse(\"unknown\", this.pending.view())\n this.pending.clear()\n this.cursor = 0\n this.unitStart = 0\n this.pendingSinceMs = null\n this.forceFlush = false\n this.state = { tag: \"ground\" }\n }\n\n // Records when incomplete data first appeared so flushTimeout() can\n // decide whether enough time has elapsed to force-flush it.\n private markPending(): void {\n this.pendingSinceMs = this.clock.now()\n }\n\n // Processes bytes during an active bracketed paste. Searches for the end\n // marker (ESC[201~) using a sliding tail window so the marker can split\n // across chunk boundaries. Bytes that can't be part of the end marker are\n // appended to the paste collector without decoding.\n //\n // Returns any bytes that follow the end marker — those go back through\n // normal parsing in the push() loop.\n private consumePasteBytes(chunk: Uint8Array): Uint8Array {\n const paste = this.paste!\n const combined = concatBytes(paste.tail, chunk)\n const endIndex = indexOfBytes(combined, BRACKETED_PASTE_END)\n\n if (endIndex !== -1) {\n this.pushPasteBytes(combined.subarray(0, endIndex))\n\n this.events.push({\n type: \"paste\",\n bytes: joinPasteBytes(paste.parts, paste.totalLength),\n })\n\n this.paste = null\n return combined.subarray(endIndex + BRACKETED_PASTE_END.length)\n }\n\n // Keep enough trailing bytes to detect an end marker split across chunks.\n // Everything before that point is safe to retain immediately.\n const keep = Math.min(BRACKETED_PASTE_END.length - 1, combined.length)\n const stableLength = combined.length - keep\n if (stableLength > 0) {\n this.pushPasteBytes(combined.subarray(0, stableLength))\n }\n\n paste.tail = Uint8Array.from(combined.subarray(stableLength))\n return EMPTY_BYTES\n }\n\n private pushPasteBytes(bytes: Uint8Array): void {\n if (bytes.length === 0) {\n return\n }\n\n // Copy here because subarray() inputs may alias the caller's chunk or the\n // parser's pending buffer across pushes. The emitted paste event must keep\n // the original bytes even if those backing buffers are later reused.\n this.paste!.parts.push(Uint8Array.from(bytes))\n this.paste!.totalLength += bytes.length\n }\n\n private reconcileDeferredStateWithProtocolContext(): void {\n switch (this.state.tag) {\n case \"csi_parametric_deferred\":\n if (!canDeferParametricCsi(this.state, this.protocolContext)) {\n this.emitOpaqueResponse(\"unknown\", this.pending.view().subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n }\n return\n\n case \"csi_private_reply_deferred\":\n if (!canDeferPrivateReplyCsi(this.protocolContext)) {\n this.emitOpaqueResponse(\"unknown\", this.pending.view().subarray(this.unitStart, this.cursor))\n this.state = { tag: \"ground\" }\n this.consumePrefix(this.cursor)\n }\n return\n }\n }\n\n // Arms or disarms the timeout after every push(). If there's an incomplete\n // unit in the buffer, starts a timer. When the timer fires, it sets\n // forceFlush so the next read() converts the incomplete unit into one\n // atomic event (e.g. a lone ESC becoming an Escape key).\n private reconcileTimeoutState(): void {\n if (!this.armTimeouts) {\n return\n }\n\n if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {\n this.clearTimeout()\n return\n }\n\n this.clearTimeout()\n this.timeoutId = this.clock.setTimeout(() => {\n this.timeoutId = null\n if (this.destroyed) {\n return\n }\n\n try {\n this.tryForceFlush()\n this.onTimeoutFlush?.()\n } catch (error) {\n console.error(\"stdin parser timeout flush failed\", error)\n }\n }, this.timeoutMs)\n }\n\n private clearTimeout(): void {\n if (!this.timeoutId) {\n return\n }\n\n this.clock.clearTimeout(this.timeoutId)\n this.timeoutId = null\n }\n\n // Clears all parser state: pending bytes, queued events, timeout tracking,\n // and any active paste collector. Called by both reset() (suspend/resume)\n // and destroy() to ensure no stale state survives.\n private resetState(): void {\n this.pending.reset(INITIAL_PENDING_CAPACITY)\n this.events.length = 0\n this.pendingSinceMs = null\n this.forceFlush = false\n this.justFlushedEsc = false\n this.state = { tag: \"ground\" }\n this.cursor = 0\n this.unitStart = 0\n this.paste = null\n this.mouseParser.reset()\n }\n}\n", + "import type { TextChunk } from \"../text-buffer.js\"\nimport { StyledText } from \"./styled-text.js\"\nimport { SyntaxStyle, type StyleDefinition } from \"../syntax-style.js\"\nimport { TreeSitterClient } from \"./tree-sitter/client.js\"\nimport type { SimpleHighlight } from \"./tree-sitter/types.js\"\nimport { createTextAttributes } from \"../utils.js\"\nimport { registerEnvVar, env } from \"./env.js\"\n\nregisterEnvVar({ name: \"OTUI_TS_STYLE_WARN\", default: false, description: \"Enable warnings for missing syntax styles\" })\n\ninterface TextChunkOptions {\n enabled?: boolean\n baseHighlight?: string\n}\n\ninterface Boundary {\n offset: number\n type: \"start\" | \"end\"\n highlightIndex: number\n}\n\nfunction getSpecificity(group: string): number {\n return group.split(\".\").length\n}\n\nfunction shouldSuppressInInjection(group: string, meta: any): boolean {\n if (meta?.isInjection) {\n return false\n }\n\n // Check if this is a parent block that should be suppressed\n // TODO: This is language/highlight specific,\n // not generic enough. Needs a more generic solution.\n // The styles need to be more like a stack that gets merged\n // and for a container with injections we just don't push that container style\n return group === \"markup.raw.block\"\n}\n\nexport function treeSitterToTextChunks(\n content: string,\n highlights: SimpleHighlight[],\n syntaxStyle: SyntaxStyle,\n options?: TextChunkOptions,\n): TextChunk[] {\n const chunks: TextChunk[] = []\n const defaultStyle = syntaxStyle.getStyle(\"default\")\n const concealEnabled = options?.enabled ?? true\n const baseStyle = options?.baseHighlight ? syntaxStyle.getStyle(options.baseHighlight) : undefined\n\n const injectionContainerRanges: Array<{ start: number; end: number }> = []\n const boundaries: Boundary[] = []\n\n for (let i = 0; i < highlights.length; i++) {\n const [start, end, , meta] = highlights[i]\n if (start === end) continue // Skip zero-length ranges\n if (meta?.containsInjection) {\n injectionContainerRanges.push({ start, end })\n }\n boundaries.push({ offset: start, type: \"start\", highlightIndex: i })\n boundaries.push({ offset: end, type: \"end\", highlightIndex: i })\n }\n\n // Sort boundaries by offset, with ends before starts at same offset\n // This ensures we close old ranges before opening new ones at the same position\n boundaries.sort((a, b) => {\n if (a.offset !== b.offset) return a.offset - b.offset\n if (a.type === \"end\" && b.type === \"start\") return -1\n if (a.type === \"start\" && b.type === \"end\") return 1\n return 0\n })\n\n const activeHighlights = new Set()\n let currentOffset = 0\n\n for (let i = 0; i < boundaries.length; i++) {\n const boundary = boundaries[i]\n\n if (currentOffset < boundary.offset && activeHighlights.size > 0) {\n const segmentText = content.slice(currentOffset, boundary.offset)\n\n const activeGroups: Array<{ group: string; meta: any; index: number }> = []\n for (const idx of activeHighlights) {\n const [, , group, meta] = highlights[idx]\n activeGroups.push({ group, meta, index: idx })\n }\n\n // Check if any active highlight has a conceal property\n // Priority: 1. Check meta.conceal first 2. Check group === \"conceal\" or starts with \"conceal.\"\n const concealHighlight = concealEnabled\n ? activeGroups.find(\n (h) => h.meta?.conceal !== undefined || h.group === \"conceal\" || h.group.startsWith(\"conceal.\"),\n )\n : undefined\n\n if (concealHighlight) {\n let replacementText = \"\"\n\n if (concealHighlight.meta?.conceal !== undefined) {\n // If meta.conceal is set, use it (this would come from (#set! conceal \"...\") if supported)\n replacementText = concealHighlight.meta.conceal\n } else if (concealHighlight.group === \"conceal.with.space\") {\n // Special group name means replace with space\n replacementText = \" \"\n }\n\n if (replacementText) {\n chunks.push({\n __isChunk: true,\n text: replacementText,\n fg: defaultStyle?.fg,\n bg: defaultStyle?.bg,\n attributes: defaultStyle\n ? createTextAttributes({\n bold: defaultStyle.bold,\n italic: defaultStyle.italic,\n underline: defaultStyle.underline,\n dim: defaultStyle.dim,\n })\n : 0,\n })\n }\n } else {\n const insideInjectionContainer = injectionContainerRanges.some(\n (range) => currentOffset >= range.start && currentOffset < range.end,\n )\n\n // Filter out highlights that should be suppressed\n // Suppress highlights when we're inside an injection container\n const validGroups = activeGroups.filter((h) => {\n // If we're inside an injection container, suppress all markup.raw.block highlights\n // This includes both the container itself and any nested markup.raw.block\n if (insideInjectionContainer && shouldSuppressInInjection(h.group, h.meta)) {\n return false\n }\n return true\n })\n\n // Sort groups by specificity (least to most), then by index (earlier to later)\n // This ensures we merge styles in the correct order: parent styles first, then child overrides\n const sortedGroups = validGroups.sort((a, b) => {\n const aSpec = getSpecificity(a.group)\n const bSpec = getSpecificity(b.group)\n if (aSpec !== bSpec) return aSpec - bSpec // Lower specificity first\n return a.index - b.index // Earlier index first\n })\n\n // Merge all active styles in order (like CSS cascade)\n // Later/more specific styles override earlier/less specific ones\n const mergedStyle: StyleDefinition = baseStyle ? { ...baseStyle } : {}\n\n for (const { group } of sortedGroups) {\n let styleForGroup = syntaxStyle.getStyle(group)\n\n if (!styleForGroup && group.includes(\".\")) {\n // Fallback to base scope\n const baseName = group.split(\".\")[0]\n styleForGroup = syntaxStyle.getStyle(baseName)\n }\n\n if (styleForGroup) {\n // Merge properties - later styles override earlier ones\n if (styleForGroup.fg !== undefined) mergedStyle.fg = styleForGroup.fg\n if (styleForGroup.bg !== undefined) mergedStyle.bg = styleForGroup.bg\n if (styleForGroup.bold !== undefined) mergedStyle.bold = styleForGroup.bold\n if (styleForGroup.italic !== undefined) mergedStyle.italic = styleForGroup.italic\n if (styleForGroup.underline !== undefined) mergedStyle.underline = styleForGroup.underline\n if (styleForGroup.dim !== undefined) mergedStyle.dim = styleForGroup.dim\n } else {\n if (group.includes(\".\")) {\n const baseName = group.split(\".\")[0]\n if (env.OTUI_TS_STYLE_WARN) {\n console.warn(\n `Syntax style not found for group \"${group}\" or base scope \"${baseName}\", using default style`,\n )\n }\n } else {\n if (env.OTUI_TS_STYLE_WARN) {\n console.warn(`Syntax style not found for group \"${group}\", using default style`)\n }\n }\n }\n }\n\n // Use merged style, falling back to default if nothing was merged\n const finalStyle = Object.keys(mergedStyle).length > 0 ? mergedStyle : defaultStyle\n\n chunks.push({\n __isChunk: true,\n text: segmentText,\n fg: finalStyle?.fg,\n bg: finalStyle?.bg,\n attributes: finalStyle\n ? createTextAttributes({\n bold: finalStyle.bold,\n italic: finalStyle.italic,\n underline: finalStyle.underline,\n dim: finalStyle.dim,\n })\n : 0,\n })\n }\n } else if (currentOffset < boundary.offset) {\n const text = content.slice(currentOffset, boundary.offset)\n const style = baseStyle ?? defaultStyle\n chunks.push({\n __isChunk: true,\n text,\n fg: style?.fg,\n bg: style?.bg,\n attributes: style\n ? createTextAttributes({\n bold: style.bold,\n italic: style.italic,\n underline: style.underline,\n dim: style.dim,\n })\n : 0,\n })\n }\n\n if (boundary.type === \"start\") {\n activeHighlights.add(boundary.highlightIndex)\n } else {\n activeHighlights.delete(boundary.highlightIndex)\n\n if (concealEnabled) {\n const [, , group, meta] = highlights[boundary.highlightIndex]\n if (meta?.concealLines !== undefined) {\n if (boundary.offset < content.length && content[boundary.offset] === \"\\n\") {\n currentOffset = boundary.offset + 1\n continue\n }\n }\n\n // TODO: This is also a query specific workaround, needs improvement\n if (meta?.conceal !== undefined) {\n // Skip the next space if we replaced with a space (prevents double spaces like \"text] (url)\")\n if (meta.conceal === \" \") {\n if (boundary.offset < content.length && content[boundary.offset] === \" \") {\n currentOffset = boundary.offset + 1\n continue\n }\n }\n // For heading markers specifically, also skip the trailing space\n // The group is just \"conceal\" for heading markers from the markdown query\n // We need to check if this conceal is NOT from an injection (markdown_inline)\n else if (meta.conceal === \"\" && group === \"conceal\" && !meta.isInjection) {\n if (boundary.offset < content.length && content[boundary.offset] === \" \") {\n currentOffset = boundary.offset + 1\n continue\n }\n }\n }\n }\n }\n\n currentOffset = boundary.offset\n }\n\n if (currentOffset < content.length) {\n const text = content.slice(currentOffset)\n const style = baseStyle ?? defaultStyle\n chunks.push({\n __isChunk: true,\n text,\n fg: style?.fg,\n bg: style?.bg,\n attributes: style\n ? createTextAttributes({\n bold: style.bold,\n italic: style.italic,\n underline: style.underline,\n dim: style.dim,\n })\n : 0,\n })\n }\n\n return chunks\n}\n\nexport interface TreeSitterToStyledTextOptions {\n conceal?: Pick\n baseHighlight?: string\n}\n\nexport async function treeSitterToStyledText(\n content: string,\n filetype: string,\n syntaxStyle: SyntaxStyle,\n client: TreeSitterClient,\n options?: TreeSitterToStyledTextOptions,\n): Promise {\n const result = await client.highlightOnce(content, filetype)\n if ((result.highlights && result.highlights.length > 0) || options?.baseHighlight) {\n const chunks = treeSitterToTextChunks(content, result.highlights ?? [], syntaxStyle, {\n enabled: options?.conceal?.enabled ?? true,\n baseHighlight: options?.baseHighlight,\n })\n return new StyledText(chunks)\n } else {\n const defaultStyle = syntaxStyle.mergeStyles(\"default\")\n const chunks: TextChunk[] = [\n {\n __isChunk: true,\n text: content,\n fg: defaultStyle.fg,\n bg: defaultStyle.bg,\n attributes: defaultStyle.attributes,\n },\n ]\n return new StyledText(chunks)\n }\n}\n", + "import { EventEmitter } from \"events\"\nimport { createDebounce, clearDebounceScope, DebounceController } from \"../debounce.js\"\nimport { ProcessQueue } from \"../queue.js\"\nimport type {\n TreeSitterClientOptions,\n TreeSitterClientEvents,\n BufferState,\n ParsedBuffer,\n FiletypeParserOptions,\n Edit,\n PerformanceStats,\n SimpleHighlight,\n TreeSitterWorkerRequest,\n TreeSitterWorkerResponse,\n} from \"./types.js\"\nimport { getParsers } from \"./default-parsers.js\"\nimport { resolve, isAbsolute, parse } from \"path\"\nimport { existsSync } from \"fs\"\nimport { registerEnvVar, env } from \"../env.js\"\nimport { isBunfsPath, normalizeBunfsPath } from \"../bunfs.js\"\nimport {\n type PlatformWorkerHandle,\n type WorkerErrorEvent,\n type WorkerMessageEvent,\n Worker as PlatformWorker,\n} from \"../../platform/worker.js\"\n\nregisterEnvVar({\n name: \"OTUI_TREE_SITTER_WORKER_PATH\",\n description: \"Path to the TreeSitter worker entry script\",\n type: \"string\",\n default: \"\",\n})\n\ndeclare global {\n const OTUI_TREE_SITTER_WORKER_PATH: string\n}\n\ninterface EditQueueItem {\n edits: Edit[]\n newContent: string\n version: number\n isReset?: boolean\n}\n\ntype TreeSitterWorkerPath = string | URL\ntype TreeSitterWorkerHandle = Pick\n\ninterface TreeSitterClientInternalOptions {\n autoStartWorker?: boolean\n}\n\ninterface PendingRequest {\n resolve: (response: any) => void\n reject: (error: Error) => void\n}\n\nlet DEFAULT_PARSER_OVERRIDES: FiletypeParserOptions[] = []\n\nexport function addDefaultParsers(parsers: FiletypeParserOptions[]): void {\n for (const parser of parsers) {\n DEFAULT_PARSER_OVERRIDES = [\n ...DEFAULT_PARSER_OVERRIDES.filter((existingParser) => existingParser.filetype !== parser.filetype),\n parser,\n ]\n }\n}\n\nconst isUrl = (path: string) => path.startsWith(\"http://\") || path.startsWith(\"https://\")\n\n// Parser options now support both URLs and local file paths\n// TODO: TreeSitterClient should have a setOptions method, passing it on to the worker etc.\nexport class TreeSitterClient extends EventEmitter {\n private initialized = false\n private worker: TreeSitterWorkerHandle | undefined\n private buffers: Map = new Map()\n private initializePromise: Promise | undefined\n private initializeResolvers:\n | { resolve: () => void; reject: (error: Error) => void; timeoutId: ReturnType }\n | undefined\n private messageCallbacks = new Map()\n private messageIdCounter: number = 0\n private editQueues: Map> = new Map()\n private debouncer: DebounceController\n private options: TreeSitterClientOptions\n private destroyCallbacks = new Set<() => void>()\n private lifecycleGeneration = 0\n private rejectInitialization: ((error: Error) => void) | undefined\n private destroyPromise: Promise | undefined\n private workerTerminationFailed = false\n\n constructor(options: TreeSitterClientOptions, internalOptions: TreeSitterClientInternalOptions = {}) {\n super()\n this.options = options\n this.debouncer = createDebounce(\"tree-sitter-client\")\n if (internalOptions.autoStartWorker ?? true) {\n this.startWorker()\n }\n }\n\n public onDestroy(callback: () => void): () => void {\n this.destroyCallbacks.add(callback)\n return () => {\n this.destroyCallbacks.delete(callback)\n }\n }\n\n private emitError(error: string, bufferId?: number): void {\n if (this.listenerCount(\"error\") > 0) {\n this.emit(\"error\", error, bufferId)\n }\n }\n\n private emitWarning(warning: string, bufferId?: number): void {\n if (this.listenerCount(\"warning\") > 0) {\n this.emit(\"warning\", warning, bufferId)\n }\n }\n\n private startWorker() {\n if (this.worker) {\n return\n }\n\n const workerPath = this.resolveWorkerPath()\n\n const worker = new PlatformWorker(workerPath)\n this.worker = worker\n\n worker.onmessage = (event) => {\n if (this.worker !== worker) {\n return\n }\n\n this.handleWorkerMessage(event as WorkerMessageEvent)\n }\n\n worker.onerror = (error: WorkerErrorEvent) => {\n if (this.worker !== worker) {\n return\n }\n\n console.error(\"TreeSitter worker error:\", error.message)\n const workerError = new Error(`Worker error: ${error.message}`, { cause: error.error })\n this.handleWorkerFailure(worker, workerError)\n this.emitError(`Worker error: ${error.message}`)\n }\n }\n\n private sendWorkerMessage(message: TreeSitterWorkerRequest): void {\n if (!this.worker) {\n throw new Error(\"TreeSitter worker is not available\")\n }\n this.worker.postMessage(message)\n }\n\n private rejectPendingRequests(error: Error): void {\n const requests = Array.from(this.messageCallbacks.values())\n this.messageCallbacks.clear()\n for (const request of requests) {\n request.reject(error)\n }\n }\n\n private rejectActiveInitialization(error: Error): void {\n if (this.initializeResolvers) {\n clearTimeout(this.initializeResolvers.timeoutId)\n this.initializeResolvers.reject(error)\n this.initializeResolvers = undefined\n }\n this.rejectInitialization?.(error)\n this.rejectInitialization = undefined\n }\n\n private handleWorkerFailure(worker: TreeSitterWorkerHandle, error: Error): void {\n if (this.worker !== worker) {\n return\n }\n\n worker.onmessage = null\n worker.onerror = null\n this.worker = undefined\n this.lifecycleGeneration++\n this.initialized = false\n this.initializePromise = undefined\n this.rejectActiveInitialization(error)\n this.rejectPendingRequests(error)\n this.editQueues.clear()\n this.buffers.clear()\n this.debouncer.clear()\n\n try {\n void Promise.resolve(worker.terminate()).catch(() => {})\n } catch {\n // The worker has already failed; cleanup is best effort.\n }\n }\n\n // Path resolution stays in the client for now; runtime-specific Worker construction lives in platform/worker.\n private resolveWorkerPath(): TreeSitterWorkerPath {\n if (this.options.workerPath) {\n return this.options.workerPath\n }\n\n if (env.OTUI_TREE_SITTER_WORKER_PATH) {\n return env.OTUI_TREE_SITTER_WORKER_PATH\n }\n\n if (typeof OTUI_TREE_SITTER_WORKER_PATH !== \"undefined\") {\n return OTUI_TREE_SITTER_WORKER_PATH\n }\n\n let workerPath = new URL(\"./parser.worker.js\", import.meta.url).href\n\n if (!existsSync(resolve(import.meta.dirname, \"parser.worker.js\"))) {\n workerPath = new URL(\"./parser.worker.ts\", import.meta.url).href\n }\n\n return workerPath\n }\n\n private async stopWorker(): Promise {\n const worker = this.worker\n if (!worker) {\n return\n }\n\n const onmessage = worker.onmessage\n const onerror = worker.onerror\n worker.onmessage = null\n worker.onerror = null\n this.worker = undefined\n\n try {\n const termination = worker.terminate()\n if (termination && typeof (termination as PromiseLike).then === \"function\") {\n await termination\n }\n } catch (error) {\n if (!this.worker) {\n worker.onmessage = onmessage\n worker.onerror = onerror\n this.worker = worker\n }\n throw error\n }\n }\n\n // NOTE: Unused, but useful for debugging and testing\n private async handleReset() {\n this.buffers.clear()\n await this.stopWorker()\n this.startWorker()\n this.initialized = false\n this.initializePromise = undefined\n this.initializeResolvers = undefined\n return this.initialize()\n }\n\n async initialize(): Promise {\n if (this.destroyPromise) {\n throw new Error(\"Cannot initialize while client is being destroyed\")\n }\n if (this.workerTerminationFailed) {\n throw new Error(\"Cannot initialize after worker termination failed; retry destroy()\")\n }\n\n if (this.initializePromise) {\n return this.initializePromise\n }\n\n if (!this.worker) {\n this.startWorker()\n }\n\n const worker = this.worker!\n const generation = this.lifecycleGeneration\n let rejectCancellation!: (error: Error) => void\n const cancellation = new Promise((_, reject) => {\n rejectCancellation = reject\n })\n const initialization = Promise.race([this.initializeClient(generation, worker), cancellation])\n this.rejectInitialization = rejectCancellation\n this.initializePromise = initialization\n\n void initialization.then(\n () => {\n if (this.initializePromise === initialization) {\n this.rejectInitialization = undefined\n }\n },\n () => {\n if (this.initializePromise === initialization) {\n this.rejectInitialization = undefined\n }\n },\n )\n\n return this.initializePromise\n }\n\n private assertCurrentInitialization(generation: number, worker: TreeSitterWorkerHandle): void {\n if (this.lifecycleGeneration !== generation || this.worker !== worker || this.destroyPromise) {\n throw new Error(\"TreeSitter initialization was invalidated\")\n }\n }\n\n private async initializeClient(generation: number, worker: TreeSitterWorkerHandle): Promise {\n await new Promise((resolve, reject) => {\n const timeoutMs = this.options.initTimeout ?? 10000 // Default to 10 seconds\n const timeoutId = setTimeout(() => {\n const error = new Error(\"Worker initialization timed out\")\n console.error(\"TreeSitter client:\", error.message)\n this.initializeResolvers = undefined\n reject(error)\n }, timeoutMs)\n\n this.initializeResolvers = { resolve, reject, timeoutId }\n this.sendWorkerMessage({\n type: \"INIT\",\n dataPath: this.options.dataPath,\n })\n })\n\n this.assertCurrentInitialization(generation, worker)\n await this.registerDefaultParsers(generation, worker)\n this.assertCurrentInitialization(generation, worker)\n this.initialized = true\n }\n\n private async registerDefaultParsers(\n generation: number = this.lifecycleGeneration,\n worker: TreeSitterWorkerHandle = this.worker!,\n ): Promise {\n const defaultParsers = await getParsers()\n this.assertCurrentInitialization(generation, worker)\n const overriddenFiletypes = new Set(DEFAULT_PARSER_OVERRIDES.map((parser) => parser.filetype))\n\n for (const parser of [\n ...defaultParsers.filter((parser) => !overriddenFiletypes.has(parser.filetype)),\n ...DEFAULT_PARSER_OVERRIDES,\n ]) {\n worker.postMessage({ type: \"ADD_FILETYPE_PARSER\", filetypeParser: this.resolveFiletypeParser(parser) })\n }\n }\n\n private resolvePath(path: string): string {\n if (isUrl(path)) {\n return path\n }\n if (isBunfsPath(path)) {\n return normalizeBunfsPath(parse(path).base)\n }\n if (!isAbsolute(path)) {\n return resolve(path)\n }\n return path\n }\n\n public addFiletypeParser(filetypeParser: FiletypeParserOptions): void {\n this.sendWorkerMessage({ type: \"ADD_FILETYPE_PARSER\", filetypeParser: this.resolveFiletypeParser(filetypeParser) })\n }\n\n private resolveFiletypeParser(filetypeParser: FiletypeParserOptions): FiletypeParserOptions {\n return {\n ...filetypeParser,\n aliases: filetypeParser.aliases\n ? [...new Set(filetypeParser.aliases.filter((alias) => alias !== filetypeParser.filetype))]\n : undefined,\n wasm: this.resolvePath(filetypeParser.wasm),\n queries: {\n highlights: filetypeParser.queries.highlights.map((path) => this.resolvePath(path)),\n injections: filetypeParser.queries.injections?.map((path) => this.resolvePath(path)),\n },\n }\n }\n\n public async getPerformance(): Promise {\n const messageId = `performance_${this.messageIdCounter++}`\n return new Promise((resolve, reject) => {\n this.messageCallbacks.set(messageId, { resolve, reject })\n try {\n this.sendWorkerMessage({ type: \"GET_PERFORMANCE\", messageId })\n } catch (error) {\n this.messageCallbacks.delete(messageId)\n reject(error instanceof Error ? error : new Error(String(error)))\n }\n })\n }\n\n public async highlightOnce(\n content: string,\n filetype: string,\n ): Promise<{ highlights?: SimpleHighlight[]; warning?: string; error?: string }> {\n if (!this.initialized) {\n try {\n await this.initialize()\n } catch (error) {\n return { error: \"Could not highlight because of initialization error\" }\n }\n }\n\n const messageId = `oneshot_${this.messageIdCounter++}`\n return new Promise((resolve, reject) => {\n this.messageCallbacks.set(messageId, { resolve, reject })\n try {\n this.sendWorkerMessage({\n type: \"ONESHOT_HIGHLIGHT\",\n content,\n filetype,\n messageId,\n })\n } catch (error) {\n this.messageCallbacks.delete(messageId)\n reject(error instanceof Error ? error : new Error(String(error)))\n }\n })\n }\n\n private handleWorkerMessage(event: WorkerMessageEvent) {\n const message = event.data\n\n switch (message.type) {\n case \"HIGHLIGHT_RESPONSE\": {\n const buffer = this.buffers.get(message.bufferId)\n if (!buffer || !buffer.hasParser) {\n return\n }\n\n if (buffer.version !== message.version) {\n this.resetBuffer(message.bufferId, buffer.version, buffer.content)\n return\n }\n\n this.emit(\"highlights:response\", message.bufferId, message.version, message.highlights)\n return\n }\n\n case \"INIT_RESPONSE\": {\n if (!this.initializeResolvers) {\n return\n }\n\n clearTimeout(this.initializeResolvers.timeoutId)\n\n if (message.error) {\n console.error(\"TreeSitter client initialization failed:\", message.error)\n this.initializeResolvers.reject(new Error(message.error))\n } else {\n this.initializeResolvers.resolve()\n }\n\n this.initializeResolvers = undefined\n return\n }\n\n case \"PARSER_INIT_RESPONSE\": {\n const callback = this.messageCallbacks.get(message.messageId)\n if (callback) {\n this.messageCallbacks.delete(message.messageId)\n callback.resolve({ hasParser: message.hasParser, warning: message.warning, error: message.error })\n }\n return\n }\n\n case \"PRELOAD_PARSER_RESPONSE\": {\n const callback = this.messageCallbacks.get(message.messageId)\n if (callback) {\n this.messageCallbacks.delete(message.messageId)\n callback.resolve({ hasParser: message.hasParser })\n }\n return\n }\n\n case \"BUFFER_DISPOSED\": {\n const callback = this.messageCallbacks.get(`dispose_${message.bufferId}`)\n if (callback) {\n this.messageCallbacks.delete(`dispose_${message.bufferId}`)\n callback.resolve(true)\n }\n\n this.emit(\"buffer:disposed\", message.bufferId)\n return\n }\n\n case \"PERFORMANCE_RESPONSE\": {\n const callback = this.messageCallbacks.get(message.messageId)\n if (callback) {\n this.messageCallbacks.delete(message.messageId)\n callback.resolve(message.performance)\n }\n return\n }\n\n case \"ONESHOT_HIGHLIGHT_RESPONSE\": {\n const callback = this.messageCallbacks.get(message.messageId)\n if (callback) {\n this.messageCallbacks.delete(message.messageId)\n callback.resolve({ highlights: message.highlights, warning: message.warning, error: message.error })\n }\n return\n }\n\n case \"UPDATE_DATA_PATH_RESPONSE\": {\n const callback = this.messageCallbacks.get(message.messageId)\n if (callback) {\n this.messageCallbacks.delete(message.messageId)\n callback.resolve({ error: message.error })\n }\n return\n }\n\n case \"CLEAR_CACHE_RESPONSE\": {\n const callback = this.messageCallbacks.get(message.messageId)\n if (callback) {\n this.messageCallbacks.delete(message.messageId)\n callback.resolve({ error: message.error })\n }\n return\n }\n\n case \"WARNING\": {\n this.emitWarning(message.warning, message.bufferId)\n return\n }\n\n case \"ERROR\": {\n this.emitError(message.error, message.bufferId)\n return\n }\n\n case \"WORKER_LOG\": {\n this.emit(\"worker:log\", message.logType, message.data.join(\" \"))\n return\n }\n }\n }\n\n public async preloadParser(filetype: string): Promise {\n const messageId = `has_parser_${this.messageIdCounter++}`\n const response = await new Promise<{ hasParser: boolean; warning?: string; error?: string }>((resolve, reject) => {\n this.messageCallbacks.set(messageId, { resolve, reject })\n try {\n this.sendWorkerMessage({\n type: \"PRELOAD_PARSER\",\n filetype,\n messageId,\n })\n } catch (error) {\n this.messageCallbacks.delete(messageId)\n reject(error instanceof Error ? error : new Error(String(error)))\n }\n })\n return response.hasParser\n }\n\n public async createBuffer(\n id: number,\n content: string,\n filetype: string,\n version: number = 1,\n autoInitialize: boolean = true,\n ): Promise {\n if (!this.initialized) {\n if (!autoInitialize) {\n this.emitError(\"Could not create buffer because client is not initialized\")\n return false\n }\n try {\n await this.initialize()\n } catch (error) {\n this.emitError(\"Could not create buffer because of initialization error\")\n return false\n }\n }\n\n if (this.buffers.has(id)) {\n throw new Error(`Buffer with id ${id} already exists`)\n }\n\n // Set buffer state immediately to avoid race conditions\n this.buffers.set(id, { id, content, filetype, version, hasParser: false })\n\n const messageId = `init_${this.messageIdCounter++}`\n const response = await new Promise<{ hasParser: boolean; warning?: string; error?: string }>((resolve, reject) => {\n this.messageCallbacks.set(messageId, { resolve, reject })\n try {\n this.sendWorkerMessage({\n type: \"INITIALIZE_PARSER\",\n bufferId: id,\n version,\n content,\n filetype,\n messageId,\n })\n } catch (error) {\n this.messageCallbacks.delete(messageId)\n reject(error instanceof Error ? error : new Error(String(error)))\n }\n })\n\n if (!response.hasParser) {\n this.emit(\"buffer:initialized\", id, false)\n if (filetype !== \"plaintext\") {\n this.emitWarning(response.warning || response.error || \"Buffer has no parser\", id)\n }\n return false\n }\n\n // Update buffer state to indicate it has a parser\n const bufferState: ParsedBuffer = { id, content, filetype, version, hasParser: true }\n this.buffers.set(id, bufferState)\n\n this.emit(\"buffer:initialized\", id, true)\n return true\n }\n\n public async updateBuffer(id: number, edits: Edit[], newContent: string, version: number): Promise {\n if (!this.initialized) {\n return\n }\n\n const buffer = this.buffers.get(id)\n if (!buffer || !buffer.hasParser) {\n return\n }\n\n // Update buffer state\n this.buffers.set(id, { ...buffer, content: newContent, version })\n\n if (!this.editQueues.has(id)) {\n this.editQueues.set(\n id,\n new ProcessQueue((item) =>\n this.processEdit(id, item.edits, item.newContent, item.version, item.isReset),\n ),\n )\n }\n\n const bufferQueue = this.editQueues.get(id)!\n bufferQueue.enqueue({ edits, newContent, version })\n }\n\n private async processEdit(\n bufferId: number,\n edits: Edit[],\n newContent: string,\n version: number,\n isReset = false,\n ): Promise {\n this.sendWorkerMessage({\n type: isReset ? \"RESET_BUFFER\" : \"HANDLE_EDITS\",\n bufferId,\n version,\n content: newContent,\n edits,\n })\n }\n\n public async removeBuffer(bufferId: number): Promise {\n if (!this.initialized) {\n return\n }\n\n this.buffers.delete(bufferId)\n\n if (this.editQueues.has(bufferId)) {\n this.editQueues.get(bufferId)?.clear()\n this.editQueues.delete(bufferId)\n }\n\n if (this.worker) {\n await new Promise((resolve, reject) => {\n const messageId = `dispose_${bufferId}`\n this.messageCallbacks.set(messageId, { resolve, reject })\n try {\n this.sendWorkerMessage({\n type: \"DISPOSE_BUFFER\",\n bufferId,\n })\n } catch (error) {\n console.error(\"Error disposing buffer\", error)\n this.messageCallbacks.delete(messageId)\n resolve(false)\n }\n\n // Add a timeout in case the worker doesn't respond\n setTimeout(() => {\n if (this.messageCallbacks.has(messageId)) {\n this.messageCallbacks.delete(messageId)\n console.warn({ bufferId }, \"Timed out waiting for buffer to be disposed\")\n resolve(false)\n }\n }, 3000)\n })\n }\n\n this.debouncer.clearDebounce(`reset-${bufferId}`)\n }\n\n public destroy(): Promise {\n if (this.destroyPromise) {\n return this.destroyPromise\n }\n\n let resolveDestroy!: () => void\n let rejectDestroy!: (error: unknown) => void\n const destroyPromise = new Promise((resolve, reject) => {\n resolveDestroy = resolve\n rejectDestroy = reject\n })\n this.destroyPromise = destroyPromise\n\n const destroyError = new Error(\"Client destroyed during initialization\")\n this.lifecycleGeneration++\n this.initialized = false\n this.initializePromise = undefined\n this.rejectActiveInitialization(destroyError)\n this.rejectPendingRequests(new Error(\"TreeSitter client destroyed\"))\n\n for (const callback of this.destroyCallbacks) {\n try {\n callback()\n } catch (error) {\n console.error(\"TreeSitter client destroy callback failed:\", error)\n }\n }\n this.destroyCallbacks.clear()\n\n clearDebounceScope(\"tree-sitter-client\")\n this.debouncer.clear()\n\n this.editQueues.clear()\n this.buffers.clear()\n\n void this.stopWorker().then(\n () => {\n this.workerTerminationFailed = false\n if (this.destroyPromise === destroyPromise) {\n this.destroyPromise = undefined\n }\n resolveDestroy()\n },\n (error) => {\n this.workerTerminationFailed = true\n if (this.destroyPromise === destroyPromise) {\n this.destroyPromise = undefined\n }\n rejectDestroy(error)\n },\n )\n return destroyPromise\n }\n\n public async resetBuffer(bufferId: number, version: number, content: string): Promise {\n if (!this.initialized) {\n return\n }\n\n const buffer = this.buffers.get(bufferId)\n if (!buffer || !buffer.hasParser) {\n this.emitError(\"Cannot reset buffer with no parser\", bufferId)\n return\n }\n\n // Update buffer state\n this.buffers.set(bufferId, { ...buffer, content, version })\n\n // Use debouncer to avoid excessive resets\n this.debouncer.debounce(`reset-${bufferId}`, 10, () => this.processEdit(bufferId, [], content, version, true))\n }\n\n public getBuffer(bufferId: number): BufferState | undefined {\n return this.buffers.get(bufferId)\n }\n\n public getAllBuffers(): BufferState[] {\n return Array.from(this.buffers.values())\n }\n\n public isInitialized(): boolean {\n return this.initialized\n }\n\n public async setDataPath(dataPath: string): Promise {\n if (this.options.dataPath === dataPath) {\n return\n }\n\n this.options.dataPath = dataPath\n\n if (this.initialized && this.worker) {\n const messageId = `update_datapath_${this.messageIdCounter++}`\n return new Promise((resolve, reject) => {\n this.messageCallbacks.set(messageId, {\n resolve: (response: any) => {\n if (response.error) {\n reject(new Error(response.error))\n } else {\n resolve()\n }\n },\n reject,\n })\n try {\n this.sendWorkerMessage({\n type: \"UPDATE_DATA_PATH\",\n dataPath,\n messageId,\n })\n } catch (error) {\n this.messageCallbacks.delete(messageId)\n reject(error instanceof Error ? error : new Error(String(error)))\n }\n })\n }\n }\n\n public async clearCache(): Promise {\n if (!this.initialized || !this.worker) {\n throw new Error(\"Cannot clear cache: client is not initialized\")\n }\n\n const messageId = `clear_cache_${this.messageIdCounter++}`\n return new Promise((resolve, reject) => {\n this.messageCallbacks.set(messageId, {\n resolve: (response: any) => {\n if (response.error) {\n reject(new Error(response.error))\n } else {\n resolve()\n }\n },\n reject,\n })\n try {\n this.sendWorkerMessage({\n type: \"CLEAR_CACHE\",\n messageId,\n })\n } catch (error) {\n this.messageCallbacks.delete(messageId)\n reject(error instanceof Error ? error : new Error(String(error)))\n }\n })\n }\n}\n", + "/**\n * A module-level map to store timeout IDs for all debounced functions\n * Structure: Map>\n */\nconst TIMERS_MAP = new Map>>()\n\n/**\n * Debounce controller that manages debounce instances for a specific scope\n */\nexport class DebounceController {\n constructor(private scopeId: string | number) {\n // Initialize the scope map if it doesn't exist\n if (!TIMERS_MAP.has(this.scopeId)) {\n TIMERS_MAP.set(this.scopeId, new Map())\n }\n }\n\n /**\n * Debounces the provided function with the given ID\n *\n * @param id Unique identifier within this scope\n * @param ms Milliseconds to wait before executing\n * @param fn Function to execute\n */\n debounce(id: string | number, ms: number, fn: () => Promise): Promise {\n const scopeMap = TIMERS_MAP.get(this.scopeId)!\n\n return new Promise((resolve, reject) => {\n // Clear any existing timeout for this ID\n if (scopeMap.has(id)) {\n clearTimeout(scopeMap.get(id))\n }\n\n // Set a new timeout\n const timerId = setTimeout(() => {\n try {\n resolve(fn())\n } catch (error) {\n reject(error)\n }\n scopeMap.delete(id)\n }, ms)\n\n // Store the new timeout ID\n scopeMap.set(id, timerId)\n })\n }\n\n /**\n * Clear a specific debounce timer in this scope\n *\n * @param id The debounce ID to clear\n */\n clearDebounce(id: string | number): void {\n const scopeMap = TIMERS_MAP.get(this.scopeId)\n if (scopeMap && scopeMap.has(id)) {\n clearTimeout(scopeMap.get(id))\n scopeMap.delete(id)\n }\n }\n\n /**\n * Clear all debounce timers in this scope\n */\n clear(): void {\n const scopeMap = TIMERS_MAP.get(this.scopeId)\n if (scopeMap) {\n scopeMap.forEach((timerId) => clearTimeout(timerId))\n scopeMap.clear()\n }\n }\n}\n\n/**\n * Creates a new debounce controller for a specific scope\n *\n * @param scopeId Unique identifier for this debounce scope\n * @returns A DebounceController for the specified scope\n */\nexport function createDebounce(scopeId: string | number): DebounceController {\n return new DebounceController(scopeId)\n}\n\n/**\n * Clears all debounce timers for a specific scope\n *\n * @param scopeId The scope identifier\n */\nexport function clearDebounceScope(scopeId: string | number): void {\n const scopeMap = TIMERS_MAP.get(scopeId)\n if (scopeMap) {\n scopeMap.forEach((timerId) => clearTimeout(timerId))\n scopeMap.clear()\n }\n}\n\n/**\n * Clears all active debounce timers across all scopes\n */\nexport function clearAllDebounces(): void {\n TIMERS_MAP.forEach((scopeMap) => {\n scopeMap.forEach((timerId) => clearTimeout(timerId))\n scopeMap.clear()\n })\n TIMERS_MAP.clear()\n}\n", + "/**\n * Generic processing queue that handles asynchronous job processing\n */\nexport class ProcessQueue {\n private queue: T[] = []\n private processing: boolean = false\n private autoProcess: boolean = true\n\n constructor(\n private processor: (item: T) => Promise | void,\n autoProcess: boolean = true,\n ) {\n this.autoProcess = autoProcess\n }\n\n enqueue(item: T): void {\n this.queue.push(item)\n\n if (!this.processing && this.autoProcess) {\n this.processQueue()\n }\n }\n\n private processQueue(): void {\n if (this.queue.length === 0) {\n return\n }\n\n this.processing = true\n\n queueMicrotask(async () => {\n if (this.queue.length === 0) {\n this.processing = false\n return\n }\n\n // Get the next item to process (FIFO)\n const item = this.queue.shift()!\n\n try {\n await this.processor(item)\n } catch (error) {\n console.error(\"Error processing queue item:\", error)\n }\n\n if (this.queue.length > 0) {\n this.processQueue()\n } else {\n this.processing = false\n }\n })\n }\n\n clear(): void {\n this.queue = []\n }\n\n isProcessing(): boolean {\n return this.processing\n }\n\n size(): number {\n return this.queue.length\n }\n}\n", + "// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY\n// Run 'bun assets/update.ts' to regenerate this file\n// Last generated: 2026-05-05T07:27:08.000Z\n\nimport type { FiletypeParserOptions } from \"./types.js\"\nimport { resolveBundledFilePath } from \"../../platform/runtime.js\"\n\n// Cached parsers to avoid re-resolving paths on every call\nlet _cachedParsers: Promise | undefined\n\nexport function getParsers(): Promise {\n if (!_cachedParsers) {\n _cachedParsers = loadParsers()\n }\n return _cachedParsers\n}\n\nasync function loadParsers(): Promise {\n const javascript_highlights = await resolveBundledFilePath(\n () => import(\"./assets/javascript/highlights.scm\" as string, { with: { type: \"file\" } }),\n \"./assets/javascript/highlights.scm\",\n import.meta.url,\n )\n const javascript_language = await resolveBundledFilePath(\n () => import(\"./assets/javascript/tree-sitter-javascript.wasm\" as string, { with: { type: \"file\" } }),\n \"./assets/javascript/tree-sitter-javascript.wasm\",\n import.meta.url,\n )\n const typescript_highlights = await resolveBundledFilePath(\n () => import(\"./assets/typescript/highlights.scm\" as string, { with: { type: \"file\" } }),\n \"./assets/typescript/highlights.scm\",\n import.meta.url,\n )\n const typescript_language = await resolveBundledFilePath(\n () => import(\"./assets/typescript/tree-sitter-typescript.wasm\" as string, { with: { type: \"file\" } }),\n \"./assets/typescript/tree-sitter-typescript.wasm\",\n import.meta.url,\n )\n const markdown_highlights = await resolveBundledFilePath(\n () => import(\"./assets/markdown/highlights.scm\" as string, { with: { type: \"file\" } }),\n \"./assets/markdown/highlights.scm\",\n import.meta.url,\n )\n const markdown_language = await resolveBundledFilePath(\n () => import(\"./assets/markdown/tree-sitter-markdown.wasm\" as string, { with: { type: \"file\" } }),\n \"./assets/markdown/tree-sitter-markdown.wasm\",\n import.meta.url,\n )\n const markdown_injections = await resolveBundledFilePath(\n () => import(\"./assets/markdown/injections.scm\" as string, { with: { type: \"file\" } }),\n \"./assets/markdown/injections.scm\",\n import.meta.url,\n )\n const markdown_inline_highlights = await resolveBundledFilePath(\n () => import(\"./assets/markdown_inline/highlights.scm\" as string, { with: { type: \"file\" } }),\n \"./assets/markdown_inline/highlights.scm\",\n import.meta.url,\n )\n const markdown_inline_language = await resolveBundledFilePath(\n () => import(\"./assets/markdown_inline/tree-sitter-markdown_inline.wasm\" as string, { with: { type: \"file\" } }),\n \"./assets/markdown_inline/tree-sitter-markdown_inline.wasm\",\n import.meta.url,\n )\n const zig_highlights = await resolveBundledFilePath(\n () => import(\"./assets/zig/highlights.scm\" as string, { with: { type: \"file\" } }),\n \"./assets/zig/highlights.scm\",\n import.meta.url,\n )\n const zig_language = await resolveBundledFilePath(\n () => import(\"./assets/zig/tree-sitter-zig.wasm\" as string, { with: { type: \"file\" } }),\n \"./assets/zig/tree-sitter-zig.wasm\",\n import.meta.url,\n )\n\n return [\n {\n filetype: \"javascript\",\n aliases: [\"javascriptreact\"],\n queries: {\n highlights: [javascript_highlights],\n },\n wasm: javascript_language,\n },\n {\n filetype: \"typescript\",\n aliases: [\"typescriptreact\"],\n queries: {\n highlights: [typescript_highlights],\n },\n wasm: typescript_language,\n },\n {\n filetype: \"markdown\",\n queries: {\n highlights: [markdown_highlights],\n injections: [markdown_injections],\n },\n wasm: markdown_language,\n injectionMapping: {\n \"nodeTypes\": {\n \"inline\": \"markdown_inline\",\n \"pipe_table_cell\": \"markdown_inline\"\n },\n \"infoStringMap\": {\n \"javascript\": \"javascript\",\n \"js\": \"javascript\",\n \"jsx\": \"javascriptreact\",\n \"javascriptreact\": \"javascriptreact\",\n \"typescript\": \"typescript\",\n \"ts\": \"typescript\",\n \"tsx\": \"typescriptreact\",\n \"typescriptreact\": \"typescriptreact\",\n \"markdown\": \"markdown\",\n \"md\": \"markdown\"\n }\n},\n },\n {\n filetype: \"markdown_inline\",\n queries: {\n highlights: [markdown_inline_highlights],\n },\n wasm: markdown_inline_language,\n },\n {\n filetype: \"zig\",\n queries: {\n highlights: [zig_highlights],\n },\n wasm: zig_language,\n },\n ]\n}\n", + "import { basename, join } from \"node:path\"\n\nexport function isBunfsPath(path: string): boolean {\n // Removed ambiguous '//' check\n return path.includes(\"$bunfs\") || /^B:[\\\\/]~BUN/i.test(path)\n}\n\nexport function getBunfsRootPath(): string {\n return process.platform === \"win32\" ? \"B:\\\\~BUN\\\\root\" : \"/$bunfs/root\"\n}\n\n/**\n * Normalizes a path to the embedded root.\n * Flattens directory structure to ensure file exists at root.\n */\nexport function normalizeBunfsPath(fileName: string): string {\n return join(getBunfsRootPath(), basename(fileName))\n}\n", + "export const WORKER_UNAVAILABLE = \"OpenTUI tree-sitter workers are not available for this runtime yet.\"\n\nexport interface WorkerMessageEvent {\n readonly data: T\n}\n\nexport interface WorkerErrorEvent {\n readonly error?: unknown\n readonly message: string\n}\n\nexport type WorkerMessageHandler = (event: WorkerMessageEvent) => void | Promise\nexport type WorkerErrorHandler = (event: WorkerErrorEvent) => void\n\ntype AnyWorkerMessageHandler = WorkerMessageHandler\n\nexport interface PlatformWorkerOptions {\n name?: string\n}\n\nexport interface PlatformWorkerHandle {\n onmessage: WorkerMessageHandler | null\n onerror: WorkerErrorHandler | null\n postMessage(value: unknown): void\n terminate(): void | Promise\n addEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void\n removeEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void\n}\n\nexport type PlatformWorkerConstructor = new (\n specifier: string | URL,\n options?: PlatformWorkerOptions,\n) => PlatformWorkerHandle\n\ninterface NodeMessagePort {\n postMessage(value: unknown): void\n on(event: \"message\", listener: (value: unknown) => void): void\n off(event: \"message\", listener: (value: unknown) => void): void\n}\n\ninterface NodeWorkerThread {\n postMessage(value: unknown): void\n on(event: \"message\", listener: (value: unknown) => void): void\n on(event: \"error\", listener: (error: Error) => void): void\n off(event: \"message\", listener: (value: unknown) => void): void\n off(event: \"error\", listener: (error: Error) => void): void\n terminate(): Promise\n}\n\ninterface NodeWorkerThreadsModule {\n Worker: new (\n filename: string,\n options: {\n eval: true\n type: \"module\"\n name?: string\n },\n ) => NodeWorkerThread\n readonly parentPort: NodeMessagePort | null\n readonly isMainThread: boolean\n}\n\ninterface WorkerRuntimeBridge {\n postMessage(value: unknown): void\n setMessageHandler(handler: WorkerMessageHandler): () => void\n}\n\ntype GlobalWithWorker = typeof globalThis & {\n Worker?: PlatformWorkerConstructor\n __opentuiWorkerMessageBridge?: true\n close?: () => void\n postMessage?: (value: unknown) => void\n}\n\ninterface NodePathModule {\n isAbsolute(path: string): boolean\n resolve(...paths: string[]): string\n}\n\ninterface NodeUrlModule {\n pathToFileURL(path: string): URL\n}\n\ninterface ProcessWithBuiltinModule {\n readonly getBuiltinModule?: (id: string) => unknown\n}\n\nconst globalWithWorker = globalThis as GlobalWithWorker\nconst nodeWorkerThreads = getBuiltinModule(\"node:worker_threads\")\nconst runtimeBridge = loadWorkerRuntime(nodeWorkerThreads)\n\nclass UnsupportedWorker implements PlatformWorkerHandle {\n public onmessage: WorkerMessageHandler | null = null\n public onerror: WorkerErrorHandler | null = null\n\n constructor() {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n postMessage(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n terminate(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n addEventListener(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n removeEventListener(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n}\n\nexport const Worker: PlatformWorkerConstructor = loadWorkerConstructor()\nexport const isWorkerRuntime = runtimeBridge !== undefined\n\nexport function postWorkerMessage(value: unknown): void {\n if (!runtimeBridge) {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n runtimeBridge.postMessage(value)\n}\n\nexport function setWorkerMessageHandler(handler: WorkerMessageHandler): () => void {\n if (!runtimeBridge) {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n return runtimeBridge.setMessageHandler(handler)\n}\n\nfunction getBuiltinModule(id: string): T | undefined {\n if (typeof process === \"undefined\") {\n return undefined\n }\n\n const loader = (process as typeof process & ProcessWithBuiltinModule).getBuiltinModule\n if (typeof loader !== \"function\") {\n return undefined\n }\n\n try {\n return loader(id) as T\n } catch {\n return undefined\n }\n}\n\nfunction loadWorkerConstructor(): PlatformWorkerConstructor {\n if (typeof globalWithWorker.Worker === \"function\") {\n return globalWithWorker.Worker\n }\n\n if (nodeWorkerThreads) {\n return createNodeWorkerConstructor(nodeWorkerThreads)\n }\n\n return UnsupportedWorker\n}\n\nfunction createNodeWorkerConstructor(node: NodeWorkerThreadsModule): PlatformWorkerConstructor {\n return class NodeWorkerShim implements PlatformWorkerHandle {\n public onmessage: WorkerMessageHandler | null = null\n public onerror: WorkerErrorHandler | null = null\n\n private readonly errorListeners = new Set()\n private readonly messageListeners = new Set()\n private readonly worker: NodeWorkerThread\n private terminationPromise: Promise | undefined\n\n constructor(specifier: string | URL, options: PlatformWorkerOptions = {}) {\n const resolvedSpecifier = resolveWorkerImportSpecifier(specifier)\n\n this.worker = new node.Worker(createWorkerBootstrapSource(resolvedSpecifier), {\n eval: true,\n type: \"module\",\n name: options.name,\n })\n\n this.worker.on(\"message\", this.handleMessage)\n this.worker.on(\"error\", this.handleError)\n }\n\n postMessage(value: unknown): void {\n this.worker.postMessage(value)\n }\n\n terminate(): Promise {\n if (this.terminationPromise) {\n return this.terminationPromise\n }\n\n this.worker.off(\"message\", this.handleMessage)\n this.worker.off(\"error\", this.handleError)\n const termination = this.worker.terminate().catch((error: unknown) => {\n this.terminationPromise = undefined\n this.worker.on(\"message\", this.handleMessage)\n this.worker.on(\"error\", this.handleError)\n throw error\n })\n this.terminationPromise = termination\n return termination\n }\n\n addEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void {\n if (type === \"message\") {\n this.messageListeners.add(listener as WorkerMessageHandler)\n return\n }\n\n this.errorListeners.add(listener as WorkerErrorHandler)\n }\n\n removeEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void {\n if (type === \"message\") {\n this.messageListeners.delete(listener as WorkerMessageHandler)\n return\n }\n\n this.errorListeners.delete(listener as WorkerErrorHandler)\n }\n\n private readonly handleMessage = (data: unknown): void => {\n const event: WorkerMessageEvent = { data }\n\n this.onmessage?.(event)\n\n for (const listener of this.messageListeners) {\n listener(event)\n }\n }\n\n private readonly handleError = (error: Error): void => {\n const event: WorkerErrorEvent = {\n error,\n message: error.message,\n }\n\n this.onerror?.(event)\n\n for (const listener of this.errorListeners) {\n listener(event)\n }\n }\n }\n}\n\nfunction createWorkerBootstrapSource(specifier: string): string {\n return `\n import { parentPort } from \"node:worker_threads\"\n\n const pendingMessages = []\n let messageHandler = null\n\n globalThis.self ??= globalThis\n globalThis.postMessage ??= (value) => parentPort?.postMessage(value)\n globalThis.__opentuiWorkerMessageBridge = true\n Object.defineProperty(globalThis, \"onmessage\", {\n configurable: true,\n get: () => messageHandler,\n set: (handler) => {\n messageHandler = typeof handler === \"function\" ? handler : null\n if (!messageHandler) return\n\n const messages = pendingMessages.splice(0)\n for (const data of messages) {\n messageHandler({ data })\n }\n },\n })\n parentPort?.on(\"message\", (data) => {\n if (messageHandler) {\n messageHandler({ data })\n } else {\n pendingMessages.push(data)\n }\n })\n\n await import(${JSON.stringify(specifier)})\n `\n}\n\nfunction resolveWorkerImportSpecifier(specifier: string | URL): string {\n if (specifier instanceof URL) {\n return specifier.href\n }\n\n if (isRuntimeSpecifier(specifier)) {\n return specifier\n }\n\n // The Node shim cannot infer the caller module URL for plain strings, so\n // relative override strings resolve from the current working directory.\n // Callers that need module-relative behavior should pass a URL instead.\n const nodePath = getBuiltinModule(\"node:path\")\n const nodeUrl = getBuiltinModule(\"node:url\")\n if (!nodePath || !nodeUrl) {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n const absolutePath = nodePath.isAbsolute(specifier) ? specifier : nodePath.resolve(specifier)\n\n return nodeUrl.pathToFileURL(absolutePath).href\n}\n\nfunction isRuntimeSpecifier(specifier: string): boolean {\n return (\n specifier.startsWith(\"file:\") ||\n specifier.startsWith(\"data:\") ||\n specifier.startsWith(\"node:\") ||\n specifier.startsWith(\"http:\") ||\n specifier.startsWith(\"https:\")\n )\n}\n\nfunction loadWorkerRuntime(node: NodeWorkerThreadsModule | undefined): WorkerRuntimeBridge | undefined {\n if (node?.parentPort && node.isMainThread === false) {\n if (globalWithWorker.__opentuiWorkerMessageBridge) {\n return createGlobalWorkerRuntimeBridge()\n }\n\n return {\n postMessage(value: unknown): void {\n node.parentPort?.postMessage(value)\n },\n setMessageHandler(handler: WorkerMessageHandler): () => void {\n const listener = (data: unknown): void => {\n void handler({ data: data as T })\n }\n\n node.parentPort?.on(\"message\", listener)\n\n return () => {\n node.parentPort?.off(\"message\", listener)\n }\n },\n }\n }\n\n if (!isGlobalWorkerRuntime()) {\n return undefined\n }\n\n return createGlobalWorkerRuntimeBridge()\n}\n\nfunction createGlobalWorkerRuntimeBridge(): WorkerRuntimeBridge {\n interface HandlerRegistration {\n active: boolean\n fallbackHandler: AnyWorkerMessageHandler | null\n listener: AnyWorkerMessageHandler\n previous?: HandlerRegistration\n }\n\n let currentRegistration: HandlerRegistration | undefined\n\n return {\n postMessage(value: unknown): void {\n globalWithWorker.postMessage?.(value)\n },\n setMessageHandler(handler: WorkerMessageHandler): () => void {\n const previousHandler = getGlobalWorkerMessageHandler()\n if (currentRegistration && previousHandler !== currentRegistration.listener) {\n currentRegistration = undefined\n }\n\n const listener: WorkerMessageHandler = (event): void => {\n const normalizedEvent = normalizeWorkerMessageEvent(event)\n void handler(normalizedEvent)\n }\n const registration: HandlerRegistration = {\n active: true,\n fallbackHandler: currentRegistration ? currentRegistration.fallbackHandler : previousHandler,\n listener,\n previous: currentRegistration,\n }\n\n currentRegistration = registration\n setGlobalWorkerMessageHandler(listener)\n\n return () => {\n registration.active = false\n if (currentRegistration !== registration || getGlobalWorkerMessageHandler() !== listener) {\n return\n }\n\n let previous = registration.previous\n while (previous && !previous.active) {\n previous = previous.previous\n }\n\n currentRegistration = previous\n setGlobalWorkerMessageHandler(previous?.listener ?? registration.fallbackHandler)\n }\n },\n }\n}\n\nfunction isGlobalWorkerRuntime(): boolean {\n if (typeof globalWithWorker.postMessage !== \"function\") {\n return false\n }\n\n return typeof document === \"undefined\" && typeof globalWithWorker.close === \"function\" && \"onmessage\" in globalThis\n}\n\nfunction normalizeWorkerMessageEvent(event: unknown): WorkerMessageEvent {\n if (event && typeof event === \"object\" && \"data\" in event) {\n return event as WorkerMessageEvent\n }\n\n return { data: event as T }\n}\n\nfunction getGlobalWorkerMessageHandler(): AnyWorkerMessageHandler | null {\n return ((globalThis as { onmessage?: unknown }).onmessage as AnyWorkerMessageHandler | null | undefined) ?? null\n}\n\nfunction setGlobalWorkerMessageHandler(handler: AnyWorkerMessageHandler | null): void {\n ;(globalThis as { onmessage?: unknown }).onmessage = handler\n}\n", + "import os from \"os\"\nimport path from \"path\"\nimport { EventEmitter } from \"events\"\nimport { singleton } from \"./singleton.js\"\nimport { env, registerEnvVar } from \"./env.js\"\nimport { isValidDirectoryName } from \"./validate-dir-name.js\"\n\n// Register environment variables for XDG directories\nregisterEnvVar({\n name: \"XDG_CONFIG_HOME\",\n description: \"Base directory for user-specific configuration files\",\n type: \"string\",\n default: \"\",\n})\n\nregisterEnvVar({\n name: \"XDG_DATA_HOME\",\n description: \"Base directory for user-specific data files\",\n type: \"string\",\n default: \"\",\n})\n\nexport interface DataPaths {\n globalConfigPath: string\n globalConfigFile: string\n localConfigFile: string\n globalDataPath: string\n}\n\nexport interface DataPathsEvents {\n \"paths:changed\": [paths: DataPaths]\n}\n\nexport class DataPathsManager extends EventEmitter {\n private _appName: string\n private _globalConfigPath?: string\n private _globalConfigFile?: string\n private _localConfigFile?: string\n private _globalDataPath?: string\n constructor() {\n super()\n this._appName = \"opentui\"\n }\n\n get appName(): string {\n return this._appName\n }\n\n set appName(value: string) {\n if (!isValidDirectoryName(value)) {\n throw new Error(`Invalid app name \"${value}\": must be a valid directory name`)\n }\n if (this._appName !== value) {\n this._appName = value\n this._globalConfigPath = undefined\n this._globalConfigFile = undefined\n this._localConfigFile = undefined\n this._globalDataPath = undefined\n this.emit(\"paths:changed\", this.toObject())\n }\n }\n\n get globalConfigPath(): string {\n if (this._globalConfigPath === undefined) {\n const homeDir = os.homedir()\n const xdgConfigHome = env.XDG_CONFIG_HOME\n const baseConfigDir = xdgConfigHome || path.join(homeDir, \".config\")\n this._globalConfigPath = path.join(baseConfigDir, this._appName)\n }\n return this._globalConfigPath\n }\n\n get globalConfigFile(): string {\n if (this._globalConfigFile === undefined) {\n this._globalConfigFile = path.join(this.globalConfigPath, \"init.ts\")\n }\n return this._globalConfigFile\n }\n\n get localConfigFile(): string {\n if (this._localConfigFile === undefined) {\n this._localConfigFile = path.join(process.cwd(), `.${this._appName}.ts`)\n }\n return this._localConfigFile\n }\n\n get globalDataPath(): string {\n if (this._globalDataPath === undefined) {\n const homeDir = os.homedir()\n const xdgDataHome = env.XDG_DATA_HOME\n const baseDataDir = xdgDataHome || path.join(homeDir, \".local/share\")\n this._globalDataPath = path.join(baseDataDir, this._appName)\n }\n return this._globalDataPath\n }\n\n toObject(): DataPaths {\n return {\n globalConfigPath: this.globalConfigPath,\n globalConfigFile: this.globalConfigFile,\n localConfigFile: this.localConfigFile,\n globalDataPath: this.globalDataPath,\n }\n }\n}\n\nexport function getDataPaths(): DataPathsManager {\n return singleton(\"data-paths-opentui\", () => new DataPathsManager())\n}\n", + "export function isValidDirectoryName(name: string): boolean {\n if (!name || typeof name !== \"string\") {\n return false\n }\n\n if (name.trim().length === 0) {\n return false\n }\n\n const reservedNames = [\n \"CON\",\n \"PRN\",\n \"AUX\",\n \"NUL\",\n \"COM1\",\n \"COM2\",\n \"COM3\",\n \"COM4\",\n \"COM5\",\n \"COM6\",\n \"COM7\",\n \"COM8\",\n \"COM9\",\n \"LPT1\",\n \"LPT2\",\n \"LPT3\",\n \"LPT4\",\n \"LPT5\",\n \"LPT6\",\n \"LPT7\",\n \"LPT8\",\n \"LPT9\",\n ]\n if (reservedNames.includes(name.toUpperCase())) {\n return false\n }\n\n // Check for invalid characters\n // Windows: < > : \" | ? * \\ and control characters (0-31)\n // Unix: null character and forward slash\n const invalidChars = /[<>:\"|?*/\\\\\\x00-\\x1f]/\n if (invalidChars.test(name)) {\n return false\n }\n\n if (name.endsWith(\".\") || name.endsWith(\" \")) {\n return false\n }\n\n if (name === \".\" || name === \"..\") {\n return false\n }\n\n return true\n}\n", + "import path from \"node:path\"\n\nexport const extensionToFiletype: Map = new Map([\n [\"astro\", \"astro\"],\n [\"bash\", \"bash\"],\n [\"c\", \"c\"],\n [\"cc\", \"cpp\"],\n [\"cjs\", \"javascript\"],\n [\"clj\", \"clojure\"],\n [\"cljs\", \"clojure\"],\n [\"cljc\", \"clojure\"],\n [\"cpp\", \"cpp\"],\n [\"cxx\", \"cpp\"],\n [\"cs\", \"csharp\"],\n [\"cts\", \"typescript\"],\n [\"ctsx\", \"typescriptreact\"],\n [\"dart\", \"dart\"],\n [\"diff\", \"diff\"],\n [\"edn\", \"clojure\"],\n [\"go\", \"go\"],\n [\"gemspec\", \"ruby\"],\n [\"groovy\", \"groovy\"],\n [\"h\", \"c\"],\n [\"handlebars\", \"handlebars\"],\n [\"hbs\", \"handlebars\"],\n [\"hpp\", \"cpp\"],\n [\"hxx\", \"cpp\"],\n [\"h++\", \"cpp\"],\n [\"hh\", \"cpp\"],\n [\"hrl\", \"erlang\"],\n [\"hs\", \"haskell\"],\n [\"htm\", \"html\"],\n [\"html\", \"html\"],\n [\"ini\", \"ini\"],\n [\"js\", \"javascript\"],\n [\"jsx\", \"javascriptreact\"],\n [\"jl\", \"julia\"],\n [\"json\", \"json\"],\n [\"ksh\", \"bash\"],\n [\"kt\", \"kotlin\"],\n [\"kts\", \"kotlin\"],\n [\"latex\", \"latex\"],\n [\"less\", \"less\"],\n [\"lua\", \"lua\"],\n [\"markdown\", \"markdown\"],\n [\"md\", \"markdown\"],\n [\"mdown\", \"markdown\"],\n [\"mkd\", \"markdown\"],\n [\"mjs\", \"javascript\"],\n [\"ml\", \"ocaml\"],\n [\"mli\", \"ocaml\"],\n [\"mts\", \"typescript\"],\n [\"mtsx\", \"typescriptreact\"],\n [\"patch\", \"diff\"],\n [\"php\", \"php\"],\n [\"pl\", \"perl\"],\n [\"pm\", \"perl\"],\n [\"ps1\", \"powershell\"],\n [\"psm1\", \"powershell\"],\n [\"py\", \"python\"],\n [\"pyi\", \"python\"],\n [\"r\", \"r\"],\n [\"rb\", \"ruby\"],\n [\"rake\", \"ruby\"],\n [\"rs\", \"rust\"],\n [\"ru\", \"ruby\"],\n [\"sass\", \"sass\"],\n [\"sc\", \"scala\"],\n [\"scala\", \"scala\"],\n [\"scss\", \"scss\"],\n [\"sh\", \"bash\"],\n [\"sql\", \"sql\"],\n [\"svelte\", \"svelte\"],\n [\"swift\", \"swift\"],\n [\"ts\", \"typescript\"],\n [\"tsx\", \"typescriptreact\"],\n [\"tex\", \"latex\"],\n [\"toml\", \"toml\"],\n [\"vue\", \"vue\"],\n [\"vim\", \"vim\"],\n [\"xml\", \"xml\"],\n [\"xsl\", \"xsl\"],\n [\"yaml\", \"yaml\"],\n [\"yml\", \"yaml\"],\n [\"zig\", \"zig\"],\n [\"zon\", \"zig\"],\n [\"zsh\", \"bash\"],\n [\"c++\", \"cpp\"],\n [\"erl\", \"erlang\"],\n [\"exs\", \"elixir\"],\n [\"ex\", \"elixir\"],\n [\"elm\", \"elm\"],\n [\"fsharp\", \"fsharp\"],\n [\"fs\", \"fsharp\"],\n [\"fsx\", \"fsharp\"],\n [\"fsscript\", \"fsharp\"],\n [\"fsi\", \"fsharp\"],\n [\"java\", \"java\"],\n [\"css\", \"css\"],\n])\n\nexport const basenameToFiletype: Map = new Map([\n [\".bash_aliases\", \"bash\"],\n [\".bash_logout\", \"bash\"],\n [\".bash_profile\", \"bash\"],\n [\".bashrc\", \"bash\"],\n [\".kshrc\", \"bash\"],\n [\".profile\", \"bash\"],\n [\".vimrc\", \"vim\"],\n [\".zlogin\", \"bash\"],\n [\".zlogout\", \"bash\"],\n [\".zprofile\", \"bash\"],\n [\".zshenv\", \"bash\"],\n [\".zshrc\", \"bash\"],\n [\"appfile\", \"ruby\"],\n [\"berksfile\", \"ruby\"],\n [\"brewfile\", \"ruby\"],\n [\"cheffile\", \"ruby\"],\n [\"containerfile\", \"dockerfile\"],\n [\"dockerfile\", \"dockerfile\"],\n [\"fastfile\", \"ruby\"],\n [\"gemfile\", \"ruby\"],\n [\"gnumakefile\", \"make\"],\n [\"gvimrc\", \"vim\"],\n [\"guardfile\", \"ruby\"],\n [\"makefile\", \"make\"],\n [\"podfile\", \"ruby\"],\n [\"rakefile\", \"ruby\"],\n [\"thorfile\", \"ruby\"],\n [\"vagrantfile\", \"ruby\"],\n])\n\nfunction normalizeFiletypeToken(value: string): string | undefined {\n const normalizedValue = value.trim().replace(/^\\./, \"\").toLowerCase()\n return normalizedValue || undefined\n}\n\nfunction getBasename(value: string): string | undefined {\n const normalizedValue = value.trim().replaceAll(\"\\\\\", \"/\")\n if (!normalizedValue) return undefined\n\n const basename = path.posix.basename(normalizedValue).toLowerCase()\n return basename || undefined\n}\n\nexport function extToFiletype(extension: string): string | undefined {\n const normalizedExtension = normalizeFiletypeToken(extension)\n if (!normalizedExtension) return undefined\n\n return extensionToFiletype.get(normalizedExtension)\n}\n\nexport function pathToFiletype(path: string): string | undefined {\n if (typeof path !== \"string\") return undefined\n\n const basename = getBasename(path)\n if (!basename) return undefined\n\n const basenameFiletype = basenameToFiletype.get(basename)\n if (basenameFiletype) {\n return basenameFiletype\n }\n\n const lastDot = basename.lastIndexOf(\".\")\n if (lastDot === -1 || lastDot === basename.length - 1) {\n return undefined\n }\n\n const extension = basename.substring(lastDot + 1)\n return extToFiletype(extension)\n}\n\nexport function infoStringToFiletype(infoString: string): string | undefined {\n if (typeof infoString !== \"string\") return undefined\n\n const token = infoString.trim().split(/\\s+/, 1)[0]\n const directBasenameMatch = basenameToFiletype.get(token.toLowerCase())\n if (directBasenameMatch) return directBasenameMatch\n\n const normalizedToken = normalizeFiletypeToken(token)\n if (!normalizedToken) return undefined\n\n return (\n basenameToFiletype.get(normalizedToken) ??\n pathToFiletype(normalizedToken) ??\n extToFiletype(normalizedToken) ??\n normalizedToken\n )\n}\n", + "import { destroySingleton, getSingleton, singleton } from \"../singleton.js\"\nimport { TreeSitterClient } from \"./client.js\"\nimport type { TreeSitterClientOptions } from \"./types.js\"\nimport { getDataPaths } from \"../data-paths.js\"\n\nexport * from \"./client.js\"\nexport * from \"../tree-sitter-styled-text.js\"\nexport * from \"./types.js\"\nexport * from \"./resolve-ft.js\"\n\nconst TREE_SITTER_CLIENT_KEY = \"tree-sitter-client\"\nconst TREE_SITTER_CLIENT_LISTENER_STATE_KEY = \"tree-sitter-client-listener-state\"\n\ninterface TreeSitterClientListenerState {\n removeListener?: () => void\n}\n\nfunction getTreeSitterClientListenerState(): TreeSitterClientListenerState {\n return singleton(TREE_SITTER_CLIENT_LISTENER_STATE_KEY, () => ({}))\n}\n\nexport function getTreeSitterClient(): TreeSitterClient {\n const existingClient = getSingleton(TREE_SITTER_CLIENT_KEY)\n if (existingClient) {\n return existingClient\n }\n\n const dataPathsManager = getDataPaths()\n const defaultOptions: TreeSitterClientOptions = {\n dataPath: dataPathsManager.globalDataPath,\n }\n\n return singleton(TREE_SITTER_CLIENT_KEY, () => {\n const client = new TreeSitterClient(defaultOptions)\n const listenerState = getTreeSitterClientListenerState()\n\n const handlePathsChanged = (paths: { globalDataPath: string }) => {\n void client.setDataPath(paths.globalDataPath).catch((error) => {\n console.warn(\"Failed to update tree-sitter data path:\", error)\n })\n }\n\n const removeListener = () => {\n dataPathsManager.off(\"paths:changed\", handlePathsChanged)\n if (listenerState.removeListener === removeListener) {\n listenerState.removeListener = undefined\n }\n if (getSingleton(TREE_SITTER_CLIENT_KEY) === client) {\n destroySingleton(TREE_SITTER_CLIENT_KEY)\n }\n }\n\n listenerState.removeListener = removeListener\n client.onDestroy(removeListener)\n\n dataPathsManager.on(\"paths:changed\", handlePathsChanged)\n\n return client\n })\n}\n\nexport async function destroyTreeSitterClient(): Promise {\n const client = getSingleton(TREE_SITTER_CLIENT_KEY)\n if (!client) {\n const listenerState = getSingleton(TREE_SITTER_CLIENT_LISTENER_STATE_KEY)\n listenerState?.removeListener?.()\n if (listenerState) {\n listenerState.removeListener = undefined\n }\n return\n }\n\n destroySingleton(TREE_SITTER_CLIENT_KEY)\n await client.destroy()\n}\n", + "import type { Extmark } from \"./extmarks.js\"\n\nexport interface ExtmarksSnapshot {\n extmarks: Map\n nextId: number\n}\n\nexport class ExtmarksHistory {\n private undoStack: ExtmarksSnapshot[] = []\n private redoStack: ExtmarksSnapshot[] = []\n\n saveSnapshot(extmarks: Map, nextId: number): void {\n const snapshot: ExtmarksSnapshot = {\n extmarks: new Map(Array.from(extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])),\n nextId,\n }\n this.undoStack.push(snapshot)\n this.redoStack = []\n }\n\n undo(): ExtmarksSnapshot | null {\n if (this.undoStack.length === 0) return null\n return this.undoStack.pop()!\n }\n\n redo(): ExtmarksSnapshot | null {\n if (this.redoStack.length === 0) return null\n return this.redoStack.pop()!\n }\n\n pushRedo(snapshot: ExtmarksSnapshot): void {\n this.redoStack.push(snapshot)\n }\n\n pushUndo(snapshot: ExtmarksSnapshot): void {\n this.undoStack.push(snapshot)\n }\n\n clear(): void {\n this.undoStack = []\n this.redoStack = []\n }\n\n canUndo(): boolean {\n return this.undoStack.length > 0\n }\n\n canRedo(): boolean {\n return this.redoStack.length > 0\n }\n}\n", + "import type { EditBuffer } from \"../edit-buffer.js\"\nimport type { EditorView } from \"../editor-view.js\"\nimport { stringWidth } from \"../platform/runtime.js\"\nimport { ExtmarksHistory, type ExtmarksSnapshot } from \"./extmarks-history.js\"\n\nexport interface Extmark {\n id: number\n start: number // Display-width offset (including newlines), NOT JS string index\n end: number // Display-width offset (including newlines), NOT JS string index\n virtual: boolean\n styleId?: number\n priority?: number\n data?: any\n typeId: number\n}\n\nexport interface ExtmarkOptions {\n start: number // Display-width offset (including newlines), NOT JS string index\n end: number // Display-width offset (including newlines), NOT JS string index\n virtual?: boolean\n styleId?: number\n priority?: number\n data?: any\n typeId?: number\n metadata?: any\n}\n\n/**\n * WARNING: This is simulating extmarks in the edit buffer\n * and will move to a real native implementation in the future.\n * Use with caution.\n */\nexport class ExtmarksController {\n private editBuffer: EditBuffer\n private editorView: EditorView\n private extmarks = new Map()\n private extmarksByTypeId = new Map>()\n private metadata = new Map()\n private nextId = 1\n private destroyed = false\n private history = new ExtmarksHistory()\n private typeNameToId = new Map()\n private typeIdToName = new Map()\n private nextTypeId = 1\n\n private originalMoveCursorLeft: typeof EditBuffer.prototype.moveCursorLeft\n private originalMoveCursorRight: typeof EditBuffer.prototype.moveCursorRight\n private originalSetCursorByOffset: typeof EditBuffer.prototype.setCursorByOffset\n private originalMoveUpVisual: typeof EditorView.prototype.moveUpVisual\n private originalMoveDownVisual: typeof EditorView.prototype.moveDownVisual\n private originalDeleteCharBackward: typeof EditBuffer.prototype.deleteCharBackward\n private originalDeleteChar: typeof EditBuffer.prototype.deleteChar\n private originalInsertText: typeof EditBuffer.prototype.insertText\n private originalInsertChar: typeof EditBuffer.prototype.insertChar\n private originalDeleteRange: typeof EditBuffer.prototype.deleteRange\n private originalSetText: typeof EditBuffer.prototype.setText\n private originalReplaceText: typeof EditBuffer.prototype.replaceText\n private originalClear: typeof EditBuffer.prototype.clear\n private originalNewLine: typeof EditBuffer.prototype.newLine\n private originalDeleteLine: typeof EditBuffer.prototype.deleteLine\n private originalEditorViewDeleteSelectedText: typeof EditorView.prototype.deleteSelectedText\n private originalUndo: typeof EditBuffer.prototype.undo\n private originalRedo: typeof EditBuffer.prototype.redo\n\n constructor(editBuffer: EditBuffer, editorView: EditorView) {\n this.editBuffer = editBuffer\n this.editorView = editorView\n\n this.originalMoveCursorLeft = editBuffer.moveCursorLeft.bind(editBuffer)\n this.originalMoveCursorRight = editBuffer.moveCursorRight.bind(editBuffer)\n this.originalSetCursorByOffset = editBuffer.setCursorByOffset.bind(editBuffer)\n this.originalMoveUpVisual = editorView.moveUpVisual.bind(editorView)\n this.originalMoveDownVisual = editorView.moveDownVisual.bind(editorView)\n this.originalDeleteCharBackward = editBuffer.deleteCharBackward.bind(editBuffer)\n this.originalDeleteChar = editBuffer.deleteChar.bind(editBuffer)\n this.originalInsertText = editBuffer.insertText.bind(editBuffer)\n this.originalInsertChar = editBuffer.insertChar.bind(editBuffer)\n this.originalDeleteRange = editBuffer.deleteRange.bind(editBuffer)\n this.originalSetText = editBuffer.setText.bind(editBuffer)\n this.originalReplaceText = editBuffer.replaceText.bind(editBuffer)\n this.originalClear = editBuffer.clear.bind(editBuffer)\n this.originalNewLine = editBuffer.newLine.bind(editBuffer)\n this.originalDeleteLine = editBuffer.deleteLine.bind(editBuffer)\n this.originalEditorViewDeleteSelectedText = editorView.deleteSelectedText.bind(editorView)\n this.originalUndo = editBuffer.undo.bind(editBuffer)\n this.originalRedo = editBuffer.redo.bind(editBuffer)\n\n this.wrapCursorMovement()\n this.wrapDeletion()\n this.wrapInsertion()\n this.wrapEditorViewDeleteSelectedText()\n this.wrapUndoRedo()\n this.setupContentChangeListener()\n }\n\n private wrapCursorMovement(): void {\n this.editBuffer.moveCursorLeft = (): void => {\n if (this.destroyed) {\n this.originalMoveCursorLeft()\n return\n }\n\n const currentOffset = this.editorView.getVisualCursor().offset\n const hasSelection = this.editorView.hasSelection()\n\n if (hasSelection) {\n this.originalMoveCursorLeft()\n return\n }\n\n const targetOffset = currentOffset - 1\n if (targetOffset < 0) {\n this.originalMoveCursorLeft()\n return\n }\n\n const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset)\n if (virtualExtmark && currentOffset >= virtualExtmark.end) {\n this.editBuffer.setCursorByOffset(virtualExtmark.start - 1)\n return\n }\n\n this.originalMoveCursorLeft()\n }\n\n this.editBuffer.moveCursorRight = (): void => {\n if (this.destroyed) {\n this.originalMoveCursorRight()\n return\n }\n\n const currentOffset = this.editorView.getVisualCursor().offset\n const hasSelection = this.editorView.hasSelection()\n\n if (hasSelection) {\n this.originalMoveCursorRight()\n return\n }\n\n const targetOffset = currentOffset + 1\n const textLength = this.editBuffer.getText().length\n\n if (targetOffset > textLength) {\n this.originalMoveCursorRight()\n return\n }\n\n const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset)\n if (virtualExtmark && currentOffset <= virtualExtmark.start) {\n this.editBuffer.setCursorByOffset(virtualExtmark.end)\n return\n }\n\n this.originalMoveCursorRight()\n }\n\n this.editorView.moveUpVisual = (): void => {\n if (this.destroyed) {\n this.originalMoveUpVisual()\n return\n }\n\n const hasSelection = this.editorView.hasSelection()\n\n if (hasSelection) {\n this.originalMoveUpVisual()\n return\n }\n\n const currentOffset = this.editorView.getVisualCursor().offset\n this.originalMoveUpVisual()\n const newOffset = this.editorView.getVisualCursor().offset\n\n const virtualExtmark = this.findVirtualExtmarkContaining(newOffset)\n if (virtualExtmark) {\n const distanceToStart = newOffset - virtualExtmark.start\n const distanceToEnd = virtualExtmark.end - newOffset\n\n if (distanceToStart < distanceToEnd) {\n this.editorView.setCursorByOffset(virtualExtmark.start - 1)\n } else {\n this.editorView.setCursorByOffset(virtualExtmark.end)\n }\n }\n }\n\n this.editorView.moveDownVisual = (): void => {\n if (this.destroyed) {\n this.originalMoveDownVisual()\n return\n }\n\n const hasSelection = this.editorView.hasSelection()\n\n if (hasSelection) {\n this.originalMoveDownVisual()\n return\n }\n\n const currentOffset = this.editorView.getVisualCursor().offset\n this.originalMoveDownVisual()\n const newOffset = this.editorView.getVisualCursor().offset\n\n const virtualExtmark = this.findVirtualExtmarkContaining(newOffset)\n if (virtualExtmark) {\n const distanceToStart = newOffset - virtualExtmark.start\n const distanceToEnd = virtualExtmark.end - newOffset\n\n if (distanceToStart < distanceToEnd) {\n const adjustedOffset = virtualExtmark.start - 1\n const targetOffset = adjustedOffset <= currentOffset ? virtualExtmark.end : adjustedOffset\n this.editorView.setCursorByOffset(targetOffset)\n } else {\n this.editorView.setCursorByOffset(virtualExtmark.end)\n }\n }\n }\n\n this.editBuffer.setCursorByOffset = (offset: number): void => {\n if (this.destroyed) {\n this.originalSetCursorByOffset(offset)\n return\n }\n\n const currentOffset = this.editorView.getVisualCursor().offset\n const hasSelection = this.editorView.hasSelection()\n\n if (hasSelection) {\n this.originalSetCursorByOffset(offset)\n return\n }\n\n const movingForward = offset > currentOffset\n\n if (movingForward) {\n const virtualExtmark = this.findVirtualExtmarkContaining(offset)\n if (virtualExtmark && currentOffset <= virtualExtmark.start) {\n this.originalSetCursorByOffset(virtualExtmark.end)\n return\n }\n } else {\n for (const extmark of this.extmarks.values()) {\n if (extmark.virtual && currentOffset >= extmark.end && offset < extmark.end && offset >= extmark.start) {\n this.originalSetCursorByOffset(extmark.start - 1)\n return\n }\n }\n }\n\n this.originalSetCursorByOffset(offset)\n }\n }\n\n private wrapDeletion(): void {\n this.editBuffer.deleteCharBackward = (): void => {\n if (this.destroyed) {\n this.originalDeleteCharBackward()\n return\n }\n\n this.saveSnapshot()\n\n const currentOffset = this.editorView.getVisualCursor().offset\n const hadSelection = this.editorView.hasSelection()\n\n if (currentOffset === 0) {\n this.originalDeleteCharBackward()\n return\n }\n\n if (hadSelection) {\n this.originalDeleteCharBackward()\n return\n }\n\n const targetOffset = currentOffset - 1\n const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset)\n\n if (virtualExtmark && currentOffset === virtualExtmark.end) {\n const startCursor = this.offsetToPosition(virtualExtmark.start)\n const endCursor = this.offsetToPosition(virtualExtmark.end)\n const deleteOffset = virtualExtmark.start\n const deleteLength = virtualExtmark.end - virtualExtmark.start\n\n this.deleteExtmarkById(virtualExtmark.id)\n\n this.originalDeleteRange(startCursor.row, startCursor.col, endCursor.row, endCursor.col)\n this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength)\n\n this.updateHighlights()\n\n return\n }\n\n this.originalDeleteCharBackward()\n const deleteOffset = this.editorView.getVisualCursor().offset\n const deleteLength = currentOffset - deleteOffset\n if (deleteLength > 0) {\n this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength)\n }\n }\n\n this.editBuffer.deleteChar = (): void => {\n if (this.destroyed) {\n this.originalDeleteChar()\n return\n }\n\n this.saveSnapshot()\n\n const currentOffset = this.editorView.getVisualCursor().offset\n const hadSelection = this.editorView.hasSelection()\n\n if (hadSelection) {\n this.originalDeleteChar()\n return\n }\n\n const targetOffset = currentOffset\n const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset)\n\n if (virtualExtmark && currentOffset === virtualExtmark.start) {\n const startCursor = this.offsetToPosition(virtualExtmark.start)\n const endCursor = this.offsetToPosition(virtualExtmark.end)\n const deleteOffset = virtualExtmark.start\n const deleteLength = virtualExtmark.end - virtualExtmark.start\n\n this.deleteExtmarkById(virtualExtmark.id)\n\n this.originalDeleteRange(startCursor.row, startCursor.col, endCursor.row, endCursor.col)\n this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength)\n\n this.updateHighlights()\n\n return\n }\n\n const deleteEndOffset = this.getNextCursorOffset(currentOffset)\n const deleteLength = deleteEndOffset - currentOffset\n\n this.originalDeleteChar()\n\n if (deleteLength > 0) {\n this.adjustExtmarksAfterDeletion(currentOffset, deleteLength)\n }\n }\n\n this.editBuffer.deleteRange = (startLine: number, startCol: number, endLine: number, endCol: number): void => {\n if (this.destroyed) {\n this.originalDeleteRange(startLine, startCol, endLine, endCol)\n return\n }\n\n this.saveSnapshot()\n\n const startOffset = this.positionToOffset(startLine, startCol)\n const endOffset = this.positionToOffset(endLine, endCol)\n const length = endOffset - startOffset\n\n this.originalDeleteRange(startLine, startCol, endLine, endCol)\n this.adjustExtmarksAfterDeletion(startOffset, length)\n }\n\n this.editBuffer.deleteLine = (): void => {\n if (this.destroyed) {\n this.originalDeleteLine()\n return\n }\n\n this.saveSnapshot()\n\n const text = this.editBuffer.getText()\n const currentOffset = this.editorView.getVisualCursor().offset\n\n let lineStart = 0\n for (let i = currentOffset - 1; i >= 0; i--) {\n if (text[i] === \"\\n\") {\n lineStart = i + 1\n break\n }\n }\n\n let lineEnd = text.length\n for (let i = currentOffset; i < text.length; i++) {\n if (text[i] === \"\\n\") {\n lineEnd = i + 1\n break\n }\n }\n\n const deleteLength = lineEnd - lineStart\n\n this.originalDeleteLine()\n this.adjustExtmarksAfterDeletion(lineStart, deleteLength)\n }\n }\n\n private wrapInsertion(): void {\n this.editBuffer.insertText = (text: string): void => {\n if (this.destroyed) {\n this.originalInsertText(text)\n return\n }\n\n this.saveSnapshot()\n\n const currentOffset = this.editorView.getVisualCursor().offset\n this.originalInsertText(text)\n const insertLength = this.editorView.getVisualCursor().offset - currentOffset\n if (insertLength > 0) {\n this.adjustExtmarksAfterInsertion(currentOffset, insertLength)\n }\n }\n\n this.editBuffer.insertChar = (char: string): void => {\n if (this.destroyed) {\n this.originalInsertChar(char)\n return\n }\n\n this.saveSnapshot()\n\n const currentOffset = this.editorView.getVisualCursor().offset\n this.originalInsertChar(char)\n const insertLength = this.editorView.getVisualCursor().offset - currentOffset\n if (insertLength > 0) {\n this.adjustExtmarksAfterInsertion(currentOffset, insertLength)\n }\n }\n\n this.editBuffer.setText = (text: string): void => {\n if (this.destroyed) {\n this.originalSetText(text)\n return\n }\n\n this.clear()\n this.originalSetText(text)\n }\n\n this.editBuffer.replaceText = (text: string): void => {\n if (this.destroyed) {\n this.originalReplaceText(text)\n return\n }\n\n this.saveSnapshot()\n this.clear()\n this.originalReplaceText(text)\n }\n\n this.editBuffer.clear = (): void => {\n if (this.destroyed) {\n this.originalClear()\n return\n }\n\n this.saveSnapshot()\n\n this.clear()\n this.originalClear()\n }\n\n this.editBuffer.newLine = (): void => {\n if (this.destroyed) {\n this.originalNewLine()\n return\n }\n\n this.saveSnapshot()\n\n const currentOffset = this.editorView.getVisualCursor().offset\n this.originalNewLine()\n this.adjustExtmarksAfterInsertion(currentOffset, 1)\n }\n }\n\n private wrapEditorViewDeleteSelectedText(): void {\n this.editorView.deleteSelectedText = (): void => {\n if (this.destroyed) {\n this.originalEditorViewDeleteSelectedText()\n return\n }\n\n this.saveSnapshot()\n\n const selection = this.editorView.getSelection()\n if (!selection) {\n this.originalEditorViewDeleteSelectedText()\n return\n }\n\n const deleteOffset = Math.min(selection.start, selection.end)\n const deleteLength = Math.abs(selection.end - selection.start)\n\n this.originalEditorViewDeleteSelectedText()\n\n if (deleteLength > 0) {\n this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength)\n }\n }\n }\n\n private setupContentChangeListener(): void {\n this.editBuffer.on(\"content-changed\", () => {\n if (this.destroyed) return\n this.updateHighlights()\n })\n }\n\n private deleteExtmarkById(id: number): void {\n const extmark = this.extmarks.get(id)\n if (extmark) {\n this.extmarks.delete(id)\n this.extmarksByTypeId.get(extmark.typeId)?.delete(id)\n this.metadata.delete(id)\n }\n }\n\n private findVirtualExtmarkContaining(offset: number): Extmark | null {\n for (const extmark of this.extmarks.values()) {\n if (extmark.virtual && offset >= extmark.start && offset < extmark.end) {\n return extmark\n }\n }\n return null\n }\n\n private adjustExtmarksAfterInsertion(insertOffset: number, length: number): void {\n for (const extmark of this.extmarks.values()) {\n if (extmark.start >= insertOffset) {\n extmark.start += length\n extmark.end += length\n } else if (extmark.end > insertOffset) {\n extmark.end += length\n }\n }\n this.updateHighlights()\n }\n\n public adjustExtmarksAfterDeletion(deleteOffset: number, length: number): void {\n const toDelete: number[] = []\n\n for (const extmark of this.extmarks.values()) {\n if (extmark.end <= deleteOffset) {\n continue\n }\n\n if (extmark.start >= deleteOffset + length) {\n extmark.start -= length\n extmark.end -= length\n } else if (extmark.start >= deleteOffset && extmark.end <= deleteOffset + length) {\n toDelete.push(extmark.id)\n } else if (extmark.start < deleteOffset && extmark.end > deleteOffset + length) {\n extmark.end -= length\n } else if (extmark.start < deleteOffset && extmark.end > deleteOffset) {\n extmark.end -= Math.min(extmark.end, deleteOffset + length) - deleteOffset\n } else if (extmark.start < deleteOffset + length && extmark.end > deleteOffset + length) {\n const overlap = deleteOffset + length - extmark.start\n extmark.start = deleteOffset\n extmark.end -= length\n }\n }\n\n for (const id of toDelete) {\n this.deleteExtmarkById(id)\n }\n\n this.updateHighlights()\n }\n\n private offsetToPosition(offset: number): { row: number; col: number } {\n const result = this.editBuffer.offsetToPosition(offset)\n if (!result) {\n return { row: 0, col: 0 }\n }\n return result\n }\n\n private positionToOffset(row: number, col: number): number {\n return this.editBuffer.positionToOffset(row, col)\n }\n\n private getNextCursorOffset(currentOffset: number): number {\n this.originalMoveCursorRight()\n const nextOffset = this.editorView.getVisualCursor().offset\n this.originalSetCursorByOffset(currentOffset)\n return nextOffset\n }\n\n private updateHighlights(): void {\n this.editBuffer.clearAllHighlights()\n\n for (const extmark of this.extmarks.values()) {\n if (extmark.styleId !== undefined) {\n // extmark.start/end are display-width offsets including newlines (from cursor operations)\n // addHighlightByCharRange expects display-width offsets excluding newlines\n // So we need to subtract the number of newlines before each position\n const startWithoutNewlines = this.offsetExcludingNewlines(extmark.start)\n const endWithoutNewlines = this.offsetExcludingNewlines(extmark.end)\n\n this.editBuffer.addHighlightByCharRange({\n start: startWithoutNewlines,\n end: endWithoutNewlines,\n styleId: extmark.styleId,\n priority: extmark.priority ?? 0,\n hlRef: extmark.id,\n })\n }\n }\n }\n\n private offsetExcludingNewlines(offset: number): number {\n // offset is a display-width offset from the start of the buffer (includes newlines)\n // We need to convert to display-width excluding newlines\n // This means: subtract 1 for each newline encountered before this offset\n const text = this.editBuffer.getText()\n let displayWidthSoFar = 0\n let newlineCount = 0\n\n // Walk through the text and calculate display widths\n let i = 0\n while (i < text.length && displayWidthSoFar < offset) {\n if (text[i] === \"\\n\") {\n displayWidthSoFar++ // newline counts as width 1 in cursor offset\n newlineCount++\n i++\n } else {\n // Find the next newline or end of string\n let j = i\n while (j < text.length && text[j] !== \"\\n\") {\n j++\n }\n const chunk = text.substring(i, j)\n const chunkWidth = stringWidth(chunk)\n\n if (displayWidthSoFar + chunkWidth < offset) {\n // Entire chunk fits before offset\n displayWidthSoFar += chunkWidth\n i = j\n } else {\n // Offset is within this chunk - need to find exact position\n // Walk character by character\n for (let k = i; k < j && displayWidthSoFar < offset; k++) {\n const charWidth = stringWidth(text[k])\n displayWidthSoFar += charWidth\n }\n break\n }\n }\n }\n\n return offset - newlineCount\n }\n\n public create(options: ExtmarkOptions): number {\n if (this.destroyed) {\n throw new Error(\"ExtmarksController is destroyed\")\n }\n\n const id = this.nextId++\n const typeId = options.typeId ?? 0\n const extmark: Extmark = {\n id,\n start: options.start,\n end: options.end,\n virtual: options.virtual ?? false,\n styleId: options.styleId,\n priority: options.priority,\n data: options.data,\n typeId,\n }\n\n this.extmarks.set(id, extmark)\n\n if (!this.extmarksByTypeId.has(typeId)) {\n this.extmarksByTypeId.set(typeId, new Set())\n }\n this.extmarksByTypeId.get(typeId)!.add(id)\n\n if (options.metadata !== undefined) {\n this.metadata.set(id, options.metadata)\n }\n\n this.updateHighlights()\n\n return id\n }\n\n public delete(id: number): boolean {\n if (this.destroyed) {\n throw new Error(\"ExtmarksController is destroyed\")\n }\n\n const extmark = this.extmarks.get(id)\n if (!extmark) return false\n\n this.deleteExtmarkById(id)\n this.updateHighlights()\n\n return true\n }\n\n public get(id: number): Extmark | null {\n if (this.destroyed) return null\n return this.extmarks.get(id) ?? null\n }\n\n public getAll(): Extmark[] {\n if (this.destroyed) return []\n return Array.from(this.extmarks.values())\n }\n\n public getVirtual(): Extmark[] {\n if (this.destroyed) return []\n return Array.from(this.extmarks.values()).filter((e) => e.virtual)\n }\n\n public getAtOffset(offset: number): Extmark[] {\n if (this.destroyed) return []\n return Array.from(this.extmarks.values()).filter((e) => offset >= e.start && offset < e.end)\n }\n\n public getAllForTypeId(typeId: number): Extmark[] {\n if (this.destroyed) return []\n const ids = this.extmarksByTypeId.get(typeId)\n if (!ids) return []\n return Array.from(ids)\n .map((id) => this.extmarks.get(id))\n .filter((e): e is Extmark => e !== undefined)\n }\n\n public clear(): void {\n if (this.destroyed) return\n\n this.extmarks.clear()\n this.extmarksByTypeId.clear()\n this.metadata.clear()\n this.updateHighlights()\n }\n\n private saveSnapshot(): void {\n this.history.saveSnapshot(this.extmarks, this.nextId)\n }\n\n private restoreSnapshot(snapshot: ExtmarksSnapshot): void {\n this.extmarks = new Map(Array.from(snapshot.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }]))\n this.nextId = snapshot.nextId\n this.updateHighlights()\n }\n\n private wrapUndoRedo(): void {\n this.editBuffer.undo = (): string | null => {\n if (this.destroyed) {\n return this.originalUndo()\n }\n\n if (!this.history.canUndo()) {\n return this.originalUndo()\n }\n\n const currentSnapshot: ExtmarksSnapshot = {\n extmarks: new Map(Array.from(this.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])),\n nextId: this.nextId,\n }\n this.history.pushRedo(currentSnapshot)\n\n const snapshot = this.history.undo()!\n this.restoreSnapshot(snapshot)\n\n return this.originalUndo()\n }\n\n this.editBuffer.redo = (): string | null => {\n if (this.destroyed) {\n return this.originalRedo()\n }\n\n if (!this.history.canRedo()) {\n return this.originalRedo()\n }\n\n const currentSnapshot: ExtmarksSnapshot = {\n extmarks: new Map(Array.from(this.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])),\n nextId: this.nextId,\n }\n this.history.pushUndo(currentSnapshot)\n\n const snapshot = this.history.redo()!\n this.restoreSnapshot(snapshot)\n\n return this.originalRedo()\n }\n }\n\n public registerType(typeName: string): number {\n if (this.destroyed) {\n throw new Error(\"ExtmarksController is destroyed\")\n }\n\n const existing = this.typeNameToId.get(typeName)\n if (existing !== undefined) {\n return existing\n }\n\n const typeId = this.nextTypeId++\n this.typeNameToId.set(typeName, typeId)\n this.typeIdToName.set(typeId, typeName)\n return typeId\n }\n\n public getTypeId(typeName: string): number | null {\n if (this.destroyed) return null\n return this.typeNameToId.get(typeName) ?? null\n }\n\n public getTypeName(typeId: number): string | null {\n if (this.destroyed) return null\n return this.typeIdToName.get(typeId) ?? null\n }\n\n public getMetadataFor(extmarkId: number): any {\n if (this.destroyed) return undefined\n return this.metadata.get(extmarkId)\n }\n\n public destroy(): void {\n if (this.destroyed) return\n\n this.editBuffer.moveCursorLeft = this.originalMoveCursorLeft\n this.editBuffer.moveCursorRight = this.originalMoveCursorRight\n this.editBuffer.setCursorByOffset = this.originalSetCursorByOffset\n this.editorView.moveUpVisual = this.originalMoveUpVisual\n this.editorView.moveDownVisual = this.originalMoveDownVisual\n this.editBuffer.deleteCharBackward = this.originalDeleteCharBackward\n this.editBuffer.deleteChar = this.originalDeleteChar\n this.editBuffer.insertText = this.originalInsertText\n this.editBuffer.insertChar = this.originalInsertChar\n this.editBuffer.deleteRange = this.originalDeleteRange\n this.editBuffer.setText = this.originalSetText\n this.editBuffer.replaceText = this.originalReplaceText\n this.editBuffer.clear = this.originalClear\n this.editBuffer.newLine = this.originalNewLine\n this.editBuffer.deleteLine = this.originalDeleteLine\n this.editorView.deleteSelectedText = this.originalEditorViewDeleteSelectedText\n this.editBuffer.undo = this.originalUndo\n this.editBuffer.redo = this.originalRedo\n\n this.extmarks.clear()\n this.extmarksByTypeId.clear()\n this.metadata.clear()\n this.typeNameToId.clear()\n this.typeIdToName.clear()\n this.history.clear()\n this.destroyed = true\n }\n}\n\nexport function createExtmarksController(editBuffer: EditBuffer, editorView: EditorView): ExtmarksController {\n return new ExtmarksController(editBuffer, editorView)\n}\n", + "import { RGBA, DEFAULT_BACKGROUND_RGB, DEFAULT_FOREGROUND_RGB, ansi256IndexToRgb } from \"./RGBA.js\"\nimport { SystemClock, type Clock, type TimerHandle } from \"./clock.js\"\nimport { env, registerEnvVar } from \"./env.js\"\n\ntype Hex = string | null\n\nconst SYSTEM_CLOCK = new SystemClock()\n\nregisterEnvVar({\n name: \"OTUI_PALETTE_IDLE_TIMEOUT_MS\",\n description: \"Milliseconds of silence after palette queries before using fallback colors.\",\n type: \"number\",\n default: 300,\n})\n\nconst OSC4_RESPONSE =\n /\\x1b]4;(\\d+);(?:(?:rgb:)([0-9a-fA-F]+)\\/([0-9a-fA-F]+)\\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\\x07|\\x1b\\\\)/g\n\nconst OSC_SPECIAL_RESPONSE =\n /\\x1b](\\d+);(?:(?:rgb:)([0-9a-fA-F]+)\\/([0-9a-fA-F]+)\\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\\x07|\\x1b\\\\)/g\n\nexport type WriteFunction = (data: string | Buffer) => boolean\n\nexport interface TerminalColors {\n palette: Hex[]\n defaultForeground: Hex\n defaultBackground: Hex\n cursorColor: Hex\n mouseForeground: Hex\n mouseBackground: Hex\n tekForeground: Hex\n tekBackground: Hex\n highlightBackground: Hex\n highlightForeground: Hex\n}\n\nexport interface GetPaletteOptions {\n timeout?: number\n size?: number\n}\n\nexport interface TerminalPaletteDetector {\n detect(options?: GetPaletteOptions): Promise\n detectOSCSupport(timeoutMs?: number): Promise\n cleanup(): void\n}\n\nexport interface NormalizedTerminalPalette {\n palette: RGBA[]\n defaultForeground: RGBA\n defaultBackground: RGBA\n}\n\nexport type OscSubscriptionSource = {\n subscribeOsc(handler: (sequence: string) => void): () => void\n}\n\nexport interface TerminalPaletteOptions {\n stdin: NodeJS.ReadStream\n stdout: NodeJS.WriteStream\n writeFn?: WriteFunction\n isLegacyTmux?: boolean\n isTmux?: boolean\n oscSource?: OscSubscriptionSource\n clock?: Clock\n}\n\nfunction scaleComponent(comp: string): string {\n const val = parseInt(comp, 16)\n const maxIn = (1 << (4 * comp.length)) - 1\n return Math.round((val / maxIn) * 255)\n .toString(16)\n .padStart(2, \"0\")\n}\n\nfunction toHex(r?: string, g?: string, b?: string, hex6?: string): string {\n if (hex6) return `#${hex6.toLowerCase()}`\n if (r && g && b) return `#${scaleComponent(r)}${scaleComponent(g)}${scaleComponent(b)}`\n return \"#000000\"\n}\n\n/**\n * Wrap OSC sequence for tmux passthrough\n * tmux requires DCS sequences to pass OSC to the underlying terminal\n * Format: ESC P tmux; ESC ESC \\\n */\nfunction wrapForTmux(osc: string): string {\n // Replace ESC with ESC ESC for tmux (escape the escape)\n const escaped = osc.replace(/\\x1b/g, \"\\x1b\\x1b\")\n return `\\x1bPtmux;${escaped}\\x1b\\\\`\n}\n\nexport class TerminalPalette implements TerminalPaletteDetector {\n private stdin: NodeJS.ReadStream\n private stdout: NodeJS.WriteStream\n private writeFn: WriteFunction\n private activeQuerySessions: Array<() => void> = []\n private inLegacyTmux: boolean\n private inTmux: boolean\n private oscSource?: OscSubscriptionSource\n private readonly clock: Clock\n\n constructor(options: TerminalPaletteOptions) {\n const { stdin, stdout, writeFn, isLegacyTmux, isTmux, oscSource, clock } = options\n\n this.stdin = stdin\n this.stdout = stdout\n this.writeFn = writeFn || ((data: string | Buffer) => stdout.write(data))\n this.inLegacyTmux = isLegacyTmux ?? false\n this.inTmux = isTmux ?? this.inLegacyTmux\n this.oscSource = oscSource\n this.clock = clock ?? SYSTEM_CLOCK\n }\n\n private writeOsc(osc: string, wrapForLegacyTmux = false): boolean {\n const data = wrapForLegacyTmux && this.inLegacyTmux ? wrapForTmux(osc) : osc\n return this.writeFn(data)\n }\n\n cleanup(): void {\n for (const cleanupSession of [...this.activeQuerySessions]) {\n cleanupSession()\n }\n this.activeQuerySessions = []\n }\n\n private subscribeInput(handler: (chunk: string | Buffer) => void): () => void {\n if (this.oscSource) {\n return this.oscSource.subscribeOsc((sequence) => {\n handler(sequence)\n })\n }\n\n this.stdin.on(\"data\", handler)\n return () => {\n this.stdin.removeListener(\"data\", handler)\n }\n }\n\n private createQuerySession() {\n const timers = new Set()\n const subscriptions = new Set<() => void>()\n let closed = false\n\n const cleanup = () => {\n if (closed) return\n closed = true\n\n for (const timer of timers) {\n this.clock.clearTimeout(timer)\n }\n timers.clear()\n\n for (const unsubscribe of subscriptions) {\n unsubscribe()\n }\n subscriptions.clear()\n\n const idx = this.activeQuerySessions.indexOf(cleanup)\n if (idx !== -1) this.activeQuerySessions.splice(idx, 1)\n }\n\n this.activeQuerySessions.push(cleanup)\n\n return {\n setTimer: (fn: () => void, ms: number): TimerHandle => {\n const timer = this.clock.setTimeout(fn, ms)\n timers.add(timer)\n return timer\n },\n resetTimer: (existing: TimerHandle | null, fn: () => void, ms: number): TimerHandle => {\n if (existing) {\n this.clock.clearTimeout(existing)\n timers.delete(existing)\n }\n\n const timer = this.clock.setTimeout(fn, ms)\n timers.add(timer)\n return timer\n },\n subscribeInput: (handler: (chunk: string | Buffer) => void): (() => void) => {\n const unsubscribe = this.subscribeInput(handler)\n subscriptions.add(unsubscribe)\n return () => {\n if (!subscriptions.has(unsubscribe)) return\n subscriptions.delete(unsubscribe)\n unsubscribe()\n }\n },\n cleanup,\n }\n }\n\n async detectOSCSupport(timeoutMs = 300): Promise {\n const out = this.stdout\n\n if (!out.isTTY || !this.stdin.isTTY) return false\n\n return new Promise((resolve) => {\n const session = this.createQuerySession()\n let buffer = \"\"\n let settled = false\n\n const finish = (supported: boolean) => {\n if (settled) return\n settled = true\n session.cleanup()\n resolve(supported)\n }\n\n const onData = (chunk: string | Buffer) => {\n buffer += chunk.toString()\n // Reset regex lastIndex before testing due to global flag\n OSC4_RESPONSE.lastIndex = 0\n if (OSC4_RESPONSE.test(buffer)) {\n finish(true)\n }\n }\n\n session.setTimer(() => {\n finish(false)\n }, timeoutMs)\n session.subscribeInput(onData)\n // Only OSC 4 needs legacy tmux passthrough; tmux routes OSC 4 replies back to the pane.\n this.writeOsc(\"\\x1b]4;0;?\\x07\", true)\n })\n }\n\n private async queryPalette(\n indices: number[],\n timeoutMs = 1200,\n idleTimeoutMs = env.OTUI_PALETTE_IDLE_TIMEOUT_MS,\n ): Promise> {\n const out = this.stdout\n const results = new Map()\n indices.forEach((i) => results.set(i, null))\n\n if (!out.isTTY || !this.stdin.isTTY) {\n return results\n }\n\n return new Promise>((resolve) => {\n const session = this.createQuerySession()\n let buffer = \"\"\n let idleTimer: TimerHandle | null = null\n let settled = false\n\n const finish = () => {\n if (settled) return\n settled = true\n session.cleanup()\n resolve(results)\n }\n\n const onData = (chunk: string | Buffer) => {\n buffer += chunk.toString()\n\n let m: RegExpExecArray | null\n OSC4_RESPONSE.lastIndex = 0\n while ((m = OSC4_RESPONSE.exec(buffer))) {\n const idx = parseInt(m[1], 10)\n if (results.has(idx)) results.set(idx, toHex(m[2], m[3], m[4], m[5]))\n }\n\n if (buffer.length > 8192) buffer = buffer.slice(-4096)\n\n const done = [...results.values()].filter((v) => v !== null).length\n if (done === results.size) {\n finish()\n return\n }\n\n idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs)\n }\n\n session.setTimer(finish, timeoutMs)\n session.subscribeInput(onData)\n // Only OSC 4 needs legacy tmux passthrough; tmux routes OSC 4 replies back to the pane.\n this.writeOsc(indices.map((i) => `\\x1b]4;${i};?\\x07`).join(\"\"), true)\n idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs)\n })\n }\n\n private async querySpecialColors(\n timeoutMs = 1200,\n idleTimeoutMs = env.OTUI_PALETTE_IDLE_TIMEOUT_MS,\n ): Promise> {\n const out = this.stdout\n const results: Record = {\n 10: null,\n 11: null,\n 12: null,\n 13: null,\n 14: null,\n 15: null,\n 16: null,\n 17: null,\n 19: null,\n }\n // tmux handles plain OSC 10/11/12 only; it has no OSC 13-17/19 handlers or reply routing.\n const queries = this.inTmux ? [10, 11, 12] : [10, 11, 12, 13, 14, 15, 16, 17, 19]\n\n if (!out.isTTY || !this.stdin.isTTY) {\n return results\n }\n\n return new Promise>((resolve) => {\n const session = this.createQuerySession()\n let buffer = \"\"\n let idleTimer: TimerHandle | null = null\n let settled = false\n\n const finish = () => {\n if (settled) return\n settled = true\n session.cleanup()\n resolve(results)\n }\n\n const onData = (chunk: string | Buffer) => {\n buffer += chunk.toString()\n let updated = false\n\n let m: RegExpExecArray | null\n OSC_SPECIAL_RESPONSE.lastIndex = 0\n while ((m = OSC_SPECIAL_RESPONSE.exec(buffer))) {\n const idx = parseInt(m[1], 10)\n if (idx in results) {\n results[idx] = toHex(m[2], m[3], m[4], m[5])\n updated = true\n }\n }\n\n if (buffer.length > 8192) buffer = buffer.slice(-4096)\n\n if (queries.every((idx) => results[idx] !== null)) {\n finish()\n return\n }\n\n if (!updated) return\n\n idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs)\n }\n\n session.setTimer(finish, timeoutMs)\n session.subscribeInput(onData)\n // OSC 10/11/12 are plain tmux handlers. DCS passthrough does not help other special colors.\n this.writeOsc(queries.map((idx) => `\\x1b]${idx};?\\x07`).join(\"\"))\n idleTimer = session.resetTimer(idleTimer, finish, idleTimeoutMs)\n })\n }\n\n async detect(options?: GetPaletteOptions): Promise {\n const { timeout = 5000, size = 16 } = options || {}\n const supported = await this.detectOSCSupport()\n\n if (!supported) {\n return {\n palette: Array(size).fill(null),\n defaultForeground: null,\n defaultBackground: null,\n cursorColor: null,\n mouseForeground: null,\n mouseBackground: null,\n tekForeground: null,\n tekBackground: null,\n highlightBackground: null,\n highlightForeground: null,\n }\n }\n\n const indicesToQuery = [...Array(size).keys()]\n const idleTimeout = env.OTUI_PALETTE_IDLE_TIMEOUT_MS\n const [paletteResults, specialColors] = await Promise.all([\n this.queryPalette(indicesToQuery, timeout, idleTimeout),\n this.querySpecialColors(timeout, idleTimeout),\n ])\n\n return {\n palette: [...Array(size).keys()].map((i) => paletteResults.get(i) ?? null),\n defaultForeground: specialColors[10],\n defaultBackground: specialColors[11],\n cursorColor: specialColors[12],\n mouseForeground: specialColors[13],\n mouseBackground: specialColors[14],\n tekForeground: specialColors[15],\n tekBackground: specialColors[16],\n highlightBackground: specialColors[17],\n highlightForeground: specialColors[19],\n }\n }\n}\n\nexport function createTerminalPalette(options: TerminalPaletteOptions): TerminalPaletteDetector {\n return new TerminalPalette(options)\n}\n\nconst DEFAULT_FOREGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_FOREGROUND_RGB)\nconst DEFAULT_BACKGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_BACKGROUND_RGB)\n\nlet fallbackAnsi256Palette: RGBA[] | null = null\n\nfunction getFallbackAnsi256Palette(): readonly RGBA[] {\n if (!fallbackAnsi256Palette) {\n fallbackAnsi256Palette = Array.from({ length: 256 }, (_, index) => {\n const [r, g, b] = ansi256IndexToRgb(index)\n return RGBA.fromInts(r, g, b)\n })\n }\n\n return fallbackAnsi256Palette\n}\n\nexport function normalizeTerminalPalette(colors?: TerminalColors | null): NormalizedTerminalPalette {\n const fallbackPalette = getFallbackAnsi256Palette()\n\n return {\n palette: Array.from({ length: 256 }, (_, index) => {\n const detected = colors?.palette[index]\n return detected ? RGBA.fromHex(detected) : RGBA.clone(fallbackPalette[index])\n }),\n defaultForeground: colors?.defaultForeground\n ? RGBA.fromHex(colors.defaultForeground)\n : RGBA.clone(DEFAULT_FOREGROUND_FALLBACK),\n defaultBackground: colors?.defaultBackground\n ? RGBA.fromHex(colors.defaultBackground)\n : RGBA.clone(DEFAULT_BACKGROUND_FALLBACK),\n }\n}\n\nexport function buildTerminalPaletteSignature(colors?: TerminalColors | null): string {\n const normalized = normalizeTerminalPalette(colors)\n const paletteSignature = normalized.palette.map((color) => color.toInts().join(\",\")).join(\";\")\n\n return [\n paletteSignature,\n normalized.defaultForeground.toInts().join(\",\"),\n normalized.defaultBackground.toInts().join(\",\"),\n ].join(\"|\")\n}\n", + "import { stripANSI } from \"../platform/runtime.js\"\n\nexport type PasteKind = \"text\" | \"binary\" | \"unknown\"\n\nexport interface PasteMetadata {\n mimeType?: string\n kind?: PasteKind\n}\n\nconst PASTE_TEXT_DECODER = new TextDecoder()\n\nexport function decodePasteBytes(bytes: Uint8Array): string {\n return PASTE_TEXT_DECODER.decode(bytes)\n}\n\nexport function stripAnsiSequences(text: string): string {\n return stripANSI(text)\n}\n", + "import type { TextChunk } from \"../text-buffer.js\"\nimport type { SimpleHighlight } from \"./tree-sitter/types.js\"\n\nconst URL_SCOPES = [\"markup.link.url\", \"string.special.url\"]\n\nexport function detectLinks(\n chunks: TextChunk[],\n context: { content: string; highlights: SimpleHighlight[] },\n): TextChunk[] {\n const content = context.content\n const highlights = context.highlights\n\n const ranges: Array<{ start: number; end: number; url: string }> = []\n\n for (let i = 0; i < highlights.length; i++) {\n const [start, end, group] = highlights[i]\n if (!URL_SCOPES.includes(group)) continue\n\n const url = content.slice(start, end)\n ranges.push({ start, end, url })\n\n for (let j = i - 1; j >= 0; j--) {\n const [labelStart, labelEnd, prev] = highlights[j]\n if (prev === \"markup.link.label\") {\n ranges.push({ start: labelStart, end: labelEnd, url })\n break\n }\n if (!prev.startsWith(\"markup.link\")) break\n }\n }\n\n if (ranges.length === 0) return chunks\n\n // Use content.indexOf to find each chunk's position in the original content.\n // This handles concealed text correctly because concealed chunks are either\n // empty (length 0, skipped) or single-char replacements (length 1, skipped).\n // Non-concealed chunks with length > 1 are exact substrings of content in order.\n let contentPos = 0\n for (const chunk of chunks) {\n if (chunk.text.length <= 1) continue\n\n const idx = content.indexOf(chunk.text, contentPos)\n if (idx < 0) continue\n\n for (const range of ranges) {\n if (idx < range.end && idx + chunk.text.length > range.start) {\n chunk.link = { url: range.url }\n break\n }\n }\n\n contentPos = idx + chunk.text.length\n }\n\n return chunks\n}\n", + "import { RGBA } from \"./lib/index.js\"\nimport { resolveRenderLib, type OptimizedBufferHandle, type RenderLib } from \"./zig.js\"\nimport { type Pointer, type PointerInput, toArrayBuffer, toPointer, ptr } from \"./platform/ffi.js\"\nimport { type BorderStyle, type BorderSides, BorderCharArrays, parseBorderStyle } from \"./lib/index.js\"\nimport { TargetChannel, type WidthMethod, type CapturedSpan, type CapturedLine } from \"./types.js\"\nimport type { TextBufferView } from \"./text-buffer-view.js\"\nimport type { EditorView } from \"./editor-view.js\"\n\n// Pack drawing options into a single u32\n// bits 0-3: borderSides, bit 4: shouldFill, bits 5-6: titleAlignment, bits 7-8: bottomTitleAlignment\nfunction packDrawOptions(\n border: boolean | BorderSides[],\n shouldFill: boolean,\n titleAlignment: \"left\" | \"center\" | \"right\",\n bottomTitleAlignment: \"left\" | \"center\" | \"right\",\n): number {\n let packed = 0\n\n if (border === true) {\n packed |= 0b1111 // All sides\n } else if (Array.isArray(border)) {\n if (border.includes(\"top\")) packed |= 0b1000\n if (border.includes(\"right\")) packed |= 0b0100\n if (border.includes(\"bottom\")) packed |= 0b0010\n if (border.includes(\"left\")) packed |= 0b0001\n }\n\n if (shouldFill) {\n packed |= 1 << 4\n }\n\n const alignmentMap: Record = {\n left: 0,\n center: 1,\n right: 2,\n }\n const alignment = alignmentMap[titleAlignment]\n const bottomAlignment = alignmentMap[bottomTitleAlignment]\n\n packed |= alignment << 5\n packed |= bottomAlignment << 7\n\n return packed\n}\n\nexport class OptimizedBuffer {\n private static fbIdCounter = 0\n public id: string\n public lib: RenderLib\n private bufferPtr: OptimizedBufferHandle\n private _width: number\n private _height: number\n private _widthMethod: WidthMethod\n public respectAlpha: boolean = false\n private _rawBuffers: {\n char: Uint32Array\n fg: Uint16Array\n bg: Uint16Array\n attributes: Uint32Array\n } | null = null\n private _destroyed: boolean = false\n\n get ptr(): OptimizedBufferHandle {\n return this.bufferPtr\n }\n\n // Fail loud and clear\n // Instead of trying to return values that could work or not,\n // this at least will show a stack trace to know where the call to a destroyed Buffer was made\n private guard(): void {\n if (this._destroyed) throw new Error(`Buffer ${this.id} is destroyed`)\n }\n\n private ensureRawBufferViews(): void {\n if (this._rawBuffers !== null) {\n return\n }\n\n const size = this._width * this._height\n const charPtr = this.lib.bufferGetCharPtr(this.bufferPtr)\n const fgPtr = this.lib.bufferGetFgPtr(this.bufferPtr)\n const bgPtr = this.lib.bufferGetBgPtr(this.bufferPtr)\n const attributesPtr = this.lib.bufferGetAttributesPtr(this.bufferPtr)\n\n this._rawBuffers = {\n char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),\n fg: new Uint16Array(toArrayBuffer(fgPtr, 0, size * 4 * 2)),\n bg: new Uint16Array(toArrayBuffer(bgPtr, 0, size * 4 * 2)),\n attributes: new Uint32Array(toArrayBuffer(attributesPtr, 0, size * 4)),\n }\n }\n\n get buffers(): {\n char: Uint32Array\n fg: Uint16Array\n bg: Uint16Array\n attributes: Uint32Array\n } {\n this.guard()\n this.ensureRawBufferViews()\n return this._rawBuffers!\n }\n\n constructor(\n lib: RenderLib,\n ptr: OptimizedBufferHandle,\n width: number,\n height: number,\n options: { respectAlpha?: boolean; id?: string; widthMethod?: WidthMethod },\n ) {\n this.id = options.id || `fb_${OptimizedBuffer.fbIdCounter++}`\n this.lib = lib\n this.respectAlpha = options.respectAlpha || false\n this._width = width\n this._height = height\n this._widthMethod = options.widthMethod || \"unicode\"\n this.bufferPtr = ptr\n }\n\n static create(\n width: number,\n height: number,\n widthMethod: WidthMethod,\n options: { respectAlpha?: boolean; id?: string } = {},\n ): OptimizedBuffer {\n const lib = resolveRenderLib()\n const respectAlpha = options.respectAlpha || false\n const id = options.id && options.id.trim() !== \"\" ? options.id : \"unnamed buffer\"\n const buffer = lib.createOptimizedBuffer(width, height, widthMethod, respectAlpha, id)\n return buffer\n }\n\n public get widthMethod(): WidthMethod {\n return this._widthMethod\n }\n\n public get width(): number {\n return this._width\n }\n\n public get height(): number {\n return this._height\n }\n\n public setRespectAlpha(respectAlpha: boolean): void {\n this.guard()\n this.lib.bufferSetRespectAlpha(this.bufferPtr, respectAlpha)\n this.respectAlpha = respectAlpha\n }\n\n public getNativeId(): string {\n this.guard()\n return this.lib.bufferGetId(this.bufferPtr)\n }\n\n public getRealCharBytes(addLineBreaks: boolean = false): Uint8Array {\n this.guard()\n const realSize = this.lib.bufferGetRealCharSize(this.bufferPtr)\n const outputBuffer = new Uint8Array(realSize)\n const bytesWritten = this.lib.bufferWriteResolvedChars(this.bufferPtr, outputBuffer, addLineBreaks)\n return outputBuffer.slice(0, bytesWritten)\n }\n\n public getSpanLines(): CapturedLine[] {\n this.guard()\n const { char, fg, bg, attributes } = this.buffers\n const lines: CapturedLine[] = []\n\n const CHAR_FLAG_CONTINUATION = 0xc0000000 | 0\n const CHAR_FLAG_MASK = 0xc0000000 | 0\n\n const realTextBytes = this.getRealCharBytes(true)\n const realTextLines = new TextDecoder().decode(realTextBytes).split(\"\\n\")\n\n for (let y = 0; y < this._height; y++) {\n const spans: CapturedSpan[] = []\n let currentSpan: CapturedSpan | null = null\n\n const lineChars = [...(realTextLines[y] || \"\")]\n let charIdx = 0\n\n for (let x = 0; x < this._width; x++) {\n const i = y * this._width + x\n const cp = char[i]\n const cellFg = RGBA.fromArray(fg.slice(i * 4, i * 4 + 4))\n const cellBg = RGBA.fromArray(bg.slice(i * 4, i * 4 + 4))\n const cellAttrs = attributes[i] & 0xff\n\n // Continuation cells are placeholders for wide characters (emojis, CJK)\n const isContinuation = (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION\n const cellChar = isContinuation ? \"\" : (lineChars[charIdx++] ?? \" \")\n\n // Check if this cell continues the current span\n if (\n currentSpan &&\n currentSpan.fg.equals(cellFg) &&\n currentSpan.bg.equals(cellBg) &&\n currentSpan.attributes === cellAttrs\n ) {\n currentSpan.text += cellChar\n currentSpan.width += 1\n } else {\n // Start a new span\n if (currentSpan) {\n spans.push(currentSpan)\n }\n currentSpan = {\n text: cellChar,\n fg: cellFg,\n bg: cellBg,\n attributes: cellAttrs,\n width: 1,\n }\n }\n }\n\n // Push the last span\n if (currentSpan) {\n spans.push(currentSpan)\n }\n\n lines.push({ spans })\n }\n\n return lines\n }\n\n public clear(bg: RGBA = RGBA.fromValues(0, 0, 0, 1)): void {\n this.guard()\n this.lib.bufferClear(this.bufferPtr, bg)\n }\n\n public setCell(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number = 0): void {\n this.guard()\n this.lib.bufferSetCell(this.bufferPtr, x, y, char, fg, bg, attributes)\n }\n\n public setCellWithAlphaBlending(\n x: number,\n y: number,\n char: string,\n fg: RGBA,\n bg: RGBA,\n attributes: number = 0,\n ): void {\n this.guard()\n this.lib.bufferSetCellWithAlphaBlending(this.bufferPtr, x, y, char, fg, bg, attributes)\n }\n\n public drawText(\n text: string,\n x: number,\n y: number,\n fg: RGBA,\n bg?: RGBA,\n attributes: number = 0,\n selection?: { start: number; end: number; bgColor?: RGBA; fgColor?: RGBA } | null,\n ): void {\n this.guard()\n if (!selection) {\n this.lib.bufferDrawText(this.bufferPtr, text, x, y, fg, bg, attributes)\n return\n }\n\n const { start, end } = selection\n\n let selectionBg: RGBA\n let selectionFg: RGBA\n\n if (selection.bgColor) {\n selectionBg = selection.bgColor\n selectionFg = selection.fgColor || fg\n } else {\n const defaultBg = bg || RGBA.fromValues(0, 0, 0, 0)\n selectionFg = defaultBg.a > 0 ? defaultBg : RGBA.fromValues(0, 0, 0, 1)\n selectionBg = fg\n }\n\n if (start > 0) {\n const beforeText = text.slice(0, start)\n this.lib.bufferDrawText(this.bufferPtr, beforeText, x, y, fg, bg, attributes)\n }\n\n if (end > start) {\n const selectedText = text.slice(start, end)\n this.lib.bufferDrawText(this.bufferPtr, selectedText, x + start, y, selectionFg, selectionBg, attributes)\n }\n\n if (end < text.length) {\n const afterText = text.slice(end)\n this.lib.bufferDrawText(this.bufferPtr, afterText, x + end, y, fg, bg, attributes)\n }\n }\n\n public fillRect(x: number, y: number, width: number, height: number, bg: RGBA): void {\n this.guard()\n this.lib.bufferFillRect(this.bufferPtr, x, y, width, height, bg)\n }\n\n public colorMatrix(\n matrix: Float32Array,\n cellMask: Float32Array,\n strength: number = 1.0,\n target: TargetChannel = TargetChannel.Both,\n ): void {\n this.guard()\n if (matrix.length !== 16) throw new RangeError(`colorMatrix matrix must have length 16, got ${matrix.length}`)\n const cellMaskCount = Math.floor(cellMask.length / 3)\n this.lib.bufferColorMatrix(this.bufferPtr, ptr(matrix), ptr(cellMask), cellMaskCount, strength, target)\n }\n\n public colorMatrixUniform(\n matrix: Float32Array,\n strength: number = 1.0,\n target: TargetChannel = TargetChannel.Both,\n ): void {\n this.guard()\n if (matrix.length !== 16)\n throw new RangeError(`colorMatrixUniform matrix must have length 16, got ${matrix.length}`)\n if (strength === 0.0) return\n this.lib.bufferColorMatrixUniform(this.bufferPtr, ptr(matrix), strength, target)\n }\n\n public drawFrameBuffer(\n destX: number,\n destY: number,\n frameBuffer: OptimizedBuffer,\n sourceX?: number,\n sourceY?: number,\n sourceWidth?: number,\n sourceHeight?: number,\n ): void {\n this.guard()\n this.lib.drawFrameBuffer(this.bufferPtr, destX, destY, frameBuffer.ptr, sourceX, sourceY, sourceWidth, sourceHeight)\n }\n\n public destroy(): void {\n if (this._destroyed) return\n this._destroyed = true\n // Cached typed arrays alias native memory and are invalid after destroy.\n this._rawBuffers = null\n this.lib.destroyOptimizedBuffer(this.bufferPtr)\n }\n\n public drawTextBuffer(textBufferView: TextBufferView, x: number, y: number): void {\n this.guard()\n this.lib.bufferDrawTextBufferView(this.bufferPtr, textBufferView.ptr, x, y)\n }\n\n public drawEditorView(editorView: EditorView, x: number, y: number): void {\n this.guard()\n this.lib.bufferDrawEditorView(this.bufferPtr, editorView.ptr, x, y)\n }\n\n public drawSuperSampleBuffer(\n x: number,\n y: number,\n pixelDataPtr: PointerInput,\n pixelDataLength: number,\n format: \"bgra8unorm\" | \"rgba8unorm\",\n alignedBytesPerRow: number,\n ): void {\n this.guard()\n this.lib.bufferDrawSuperSampleBuffer(\n this.bufferPtr,\n x,\n y,\n toPointer(pixelDataPtr),\n pixelDataLength,\n format,\n alignedBytesPerRow,\n )\n }\n\n public drawPackedBuffer(\n dataPtr: PointerInput,\n dataLen: number,\n posX: number,\n posY: number,\n terminalWidthCells: number,\n terminalHeightCells: number,\n ): void {\n this.guard()\n this.lib.bufferDrawPackedBuffer(\n this.bufferPtr,\n toPointer(dataPtr),\n dataLen,\n posX,\n posY,\n terminalWidthCells,\n terminalHeightCells,\n )\n }\n\n public drawGrayscaleBuffer(\n posX: number,\n posY: number,\n intensities: Float32Array,\n srcWidth: number,\n srcHeight: number,\n fg: RGBA | null = null,\n bg: RGBA | null = null,\n ): void {\n this.guard()\n this.lib.bufferDrawGrayscaleBuffer(this.bufferPtr, posX, posY, ptr(intensities), srcWidth, srcHeight, fg, bg)\n }\n\n public drawGrayscaleBufferSupersampled(\n posX: number,\n posY: number,\n intensities: Float32Array,\n srcWidth: number,\n srcHeight: number,\n fg: RGBA | null = null,\n bg: RGBA | null = null,\n ): void {\n this.guard()\n this.lib.bufferDrawGrayscaleBufferSupersampled(\n this.bufferPtr,\n posX,\n posY,\n ptr(intensities),\n srcWidth,\n srcHeight,\n fg,\n bg,\n )\n }\n\n public resize(width: number, height: number): void {\n this.guard()\n if (this._width === width && this._height === height) return\n\n this._width = width\n this._height = height\n this._rawBuffers = null\n\n this.lib.bufferResize(this.bufferPtr, width, height)\n }\n\n public drawBox(options: {\n x: number\n y: number\n width: number\n height: number\n borderStyle?: BorderStyle\n customBorderChars?: Uint32Array\n border: boolean | BorderSides[]\n borderColor: RGBA\n backgroundColor: RGBA\n shouldFill?: boolean\n title?: string\n titleColor?: RGBA\n titleAlignment?: \"left\" | \"center\" | \"right\"\n bottomTitle?: string\n bottomTitleAlignment?: \"left\" | \"center\" | \"right\"\n }): void {\n this.guard()\n const style = parseBorderStyle(options.borderStyle, \"single\")\n const borderChars: Uint32Array = options.customBorderChars ?? BorderCharArrays[style]\n\n const packedOptions = packDrawOptions(\n options.border,\n options.shouldFill ?? false,\n options.titleAlignment || \"left\",\n options.bottomTitleAlignment || \"left\",\n )\n\n this.lib.bufferDrawBox(\n this.bufferPtr,\n options.x,\n options.y,\n options.width,\n options.height,\n borderChars,\n packedOptions,\n options.borderColor,\n options.backgroundColor,\n options.titleColor ?? options.borderColor,\n options.title ?? null,\n options.bottomTitle ?? null,\n )\n }\n\n public pushScissorRect(x: number, y: number, width: number, height: number): void {\n this.guard()\n this.lib.bufferPushScissorRect(this.bufferPtr, x, y, width, height)\n }\n\n public popScissorRect(): void {\n this.guard()\n this.lib.bufferPopScissorRect(this.bufferPtr)\n }\n\n public clearScissorRects(): void {\n this.guard()\n this.lib.bufferClearScissorRects(this.bufferPtr)\n }\n\n public pushOpacity(opacity: number): void {\n this.guard()\n this.lib.bufferPushOpacity(this.bufferPtr, Math.max(0, Math.min(1, opacity)))\n }\n\n public popOpacity(): void {\n this.guard()\n this.lib.bufferPopOpacity(this.bufferPtr)\n }\n\n public getCurrentOpacity(): number {\n this.guard()\n return this.lib.bufferGetCurrentOpacity(this.bufferPtr)\n }\n\n public clearOpacity(): void {\n this.guard()\n this.lib.bufferClearOpacity(this.bufferPtr)\n }\n\n public encodeUnicode(text: string): { ptr: Pointer; data: Array<{ width: number; char: number }> } | null {\n this.guard()\n return this.lib.encodeUnicode(text, this._widthMethod)\n }\n\n public freeUnicode(encoded: { ptr: Pointer; data: Array<{ width: number; char: number }> }): void {\n this.guard()\n this.lib.freeUnicode(encoded)\n }\n\n public drawGrid(options: {\n borderChars: Uint32Array\n borderFg: RGBA\n borderBg: RGBA\n columnOffsets: Int32Array\n rowOffsets: Int32Array\n drawInner: boolean\n drawOuter: boolean\n }): void {\n this.guard()\n\n const columnCount = Math.max(0, options.columnOffsets.length - 1)\n const rowCount = Math.max(0, options.rowOffsets.length - 1)\n\n this.lib.bufferDrawGrid(\n this.bufferPtr,\n options.borderChars,\n options.borderFg,\n options.borderBg,\n options.columnOffsets,\n columnCount,\n options.rowOffsets,\n rowCount,\n {\n drawInner: options.drawInner,\n drawOuter: options.drawOuter,\n },\n )\n }\n\n public drawChar(char: number, x: number, y: number, fg: RGBA, bg: RGBA, attributes: number = 0): void {\n this.guard()\n this.lib.bufferDrawChar(this.bufferPtr, char, x, y, fg, bg, attributes)\n }\n}\n", + "import type { StyledText } from \"./lib/styled-text.js\"\nimport { RGBA } from \"./lib/RGBA.js\"\nimport { resolveRenderLib, type LineInfo, type RenderLib, type TextBufferHandle } from \"./zig.js\"\nimport { type WidthMethod, type Highlight } from \"./types.js\"\nimport type { SyntaxStyle } from \"./syntax-style.js\"\n\nexport interface TextChunk {\n __isChunk: true\n text: string\n fg?: RGBA\n bg?: RGBA\n attributes?: number\n link?: { url: string }\n}\n\nexport class TextBuffer {\n private lib: RenderLib\n private bufferPtr: TextBufferHandle\n private _length: number = 0\n private _byteSize: number = 0\n private _lineInfo?: LineInfo\n private _destroyed: boolean = false\n private _syntaxStyle?: SyntaxStyle\n private _textBytes?: Uint8Array\n private _memId?: number\n private _appendedChunks: Uint8Array[] = []\n\n constructor(lib: RenderLib, ptr: TextBufferHandle) {\n this.lib = lib\n this.bufferPtr = ptr\n }\n\n static create(widthMethod: WidthMethod): TextBuffer {\n const lib = resolveRenderLib()\n return lib.createTextBuffer(widthMethod)\n }\n\n // Fail loud and clear\n // Instead of trying to return values that could work or not,\n // this at least will show a stack trace to know where the call to a destroyed TextBuffer was made\n private guard(): void {\n if (this._destroyed) throw new Error(\"TextBuffer is destroyed\")\n }\n\n public setText(text: string): void {\n this.guard()\n this._textBytes = this.lib.encoder.encode(text)\n\n if (this._memId === undefined) {\n this._memId = this.lib.textBufferRegisterMemBuffer(this.bufferPtr, this._textBytes, false)\n } else if (!this.lib.textBufferReplaceMemBuffer(this.bufferPtr, this._memId, this._textBytes, false)) {\n this._memId = this.lib.textBufferRegisterMemBuffer(this.bufferPtr, this._textBytes, false)\n }\n\n this.lib.textBufferSetTextFromMem(this.bufferPtr, this._memId)\n this._length = this.lib.textBufferGetLength(this.bufferPtr)\n this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr)\n this._lineInfo = undefined\n this._appendedChunks = [] // Clear any previously appended chunks\n }\n\n public append(text: string): void {\n this.guard()\n const textBytes = this.lib.encoder.encode(text)\n // Keep the bytes alive to prevent garbage collection\n this._appendedChunks.push(textBytes)\n this.lib.textBufferAppend(this.bufferPtr, textBytes)\n this._length = this.lib.textBufferGetLength(this.bufferPtr)\n this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr)\n this._lineInfo = undefined\n }\n\n public loadFile(path: string): void {\n this.guard()\n const success = this.lib.textBufferLoadFile(this.bufferPtr, path)\n if (!success) {\n throw new Error(`Failed to load file: ${path}`)\n }\n this._length = this.lib.textBufferGetLength(this.bufferPtr)\n this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr)\n this._lineInfo = undefined\n this._textBytes = undefined\n }\n\n public setStyledText(text: StyledText): void {\n this.guard()\n\n this.lib.textBufferSetStyledText(this.bufferPtr, text.chunks)\n\n this._length = this.lib.textBufferGetLength(this.bufferPtr)\n this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr)\n this._lineInfo = undefined\n }\n\n public setDefaultFg(fg: RGBA | null): void {\n this.guard()\n this.lib.textBufferSetDefaultFg(this.bufferPtr, fg)\n }\n\n public setDefaultBg(bg: RGBA | null): void {\n this.guard()\n this.lib.textBufferSetDefaultBg(this.bufferPtr, bg)\n }\n\n public setDefaultAttributes(attributes: number | null): void {\n this.guard()\n this.lib.textBufferSetDefaultAttributes(this.bufferPtr, attributes)\n }\n\n public resetDefaults(): void {\n this.guard()\n this.lib.textBufferResetDefaults(this.bufferPtr)\n }\n\n public getLineCount(): number {\n this.guard()\n return this.lib.textBufferGetLineCount(this.bufferPtr)\n }\n\n public get length(): number {\n this.guard()\n return this._length\n }\n\n public get byteSize(): number {\n this.guard()\n return this._byteSize\n }\n\n public get ptr(): TextBufferHandle {\n this.guard()\n return this.bufferPtr\n }\n\n public getPlainText(): string {\n this.guard()\n if (this._byteSize === 0) return \"\"\n // Use byteSize for accurate buffer allocation (includes newlines in byte count)\n const plainBytes = this.lib.getPlainTextBytes(this.bufferPtr, this._byteSize)\n\n if (!plainBytes) return \"\"\n\n return this.lib.decoder.decode(plainBytes)\n }\n\n public getTextRange(startOffset: number, endOffset: number): string {\n this.guard()\n if (startOffset >= endOffset) return \"\"\n if (this._byteSize === 0) return \"\"\n\n const rangeBytes = this.lib.textBufferGetTextRange(this.bufferPtr, startOffset, endOffset, this._byteSize)\n\n if (!rangeBytes) return \"\"\n\n return this.lib.decoder.decode(rangeBytes)\n }\n\n /**\n * Add a highlight using character offsets into the full text.\n * start/end in highlight represent absolute character positions.\n */\n public addHighlightByCharRange(highlight: Highlight): void {\n this.guard()\n this.lib.textBufferAddHighlightByCharRange(this.bufferPtr, highlight)\n }\n\n /**\n * Add a highlight to a specific line by column positions.\n * start/end in highlight represent column offsets.\n */\n public addHighlight(lineIdx: number, highlight: Highlight): void {\n this.guard()\n this.lib.textBufferAddHighlight(this.bufferPtr, lineIdx, highlight)\n }\n\n public removeHighlightsByRef(hlRef: number): void {\n this.guard()\n this.lib.textBufferRemoveHighlightsByRef(this.bufferPtr, hlRef)\n }\n\n public clearLineHighlights(lineIdx: number): void {\n this.guard()\n this.lib.textBufferClearLineHighlights(this.bufferPtr, lineIdx)\n }\n\n public clearAllHighlights(): void {\n this.guard()\n this.lib.textBufferClearAllHighlights(this.bufferPtr)\n }\n\n public getLineHighlights(lineIdx: number): Array {\n this.guard()\n return this.lib.textBufferGetLineHighlights(this.bufferPtr, lineIdx)\n }\n\n public getHighlightCount(): number {\n this.guard()\n return this.lib.textBufferGetHighlightCount(this.bufferPtr)\n }\n\n public setSyntaxStyle(style: SyntaxStyle | null): void {\n this.guard()\n if (this.lib.textBufferSetSyntaxStyle(this.bufferPtr, style?.ptr ?? null)) {\n this._syntaxStyle = style ?? undefined\n }\n }\n\n public getSyntaxStyle(): SyntaxStyle | null {\n this.guard()\n return this._syntaxStyle ?? null\n }\n\n public setTabWidth(width: number): void {\n this.guard()\n this.lib.textBufferSetTabWidth(this.bufferPtr, width)\n }\n\n public getTabWidth(): number {\n this.guard()\n return this.lib.textBufferGetTabWidth(this.bufferPtr)\n }\n\n public clear(): void {\n this.guard()\n this.lib.textBufferClear(this.bufferPtr)\n this._length = 0\n this._byteSize = 0\n this._lineInfo = undefined\n this._textBytes = undefined\n this._appendedChunks = []\n // Note: _memId is NOT cleared - it can be reused for next setText\n }\n\n public reset(): void {\n this.guard()\n this.lib.textBufferReset(this.bufferPtr)\n this._length = 0\n this._byteSize = 0\n this._lineInfo = undefined\n this._textBytes = undefined\n this._memId = undefined // Reset clears the registry, so clear our ID\n this._appendedChunks = []\n }\n\n public destroy(): void {\n if (this._destroyed) return\n this._destroyed = true\n this.lib.destroyTextBuffer(this.bufferPtr)\n }\n}\n", + "// src/ffi.ts\nvar FFI_LOAD_ERROR = \"bun-ffi-structs requires Bun or Node.js with node:ffi enabled (--experimental-ffi --allow-ffi).\";\nvar backend = await loadBackend();\nfunction unavailable(cause) {\n throw new Error(FFI_LOAD_ERROR, {\n cause: cause instanceof Error ? cause : undefined\n });\n}\nfunction createUnsupportedBackend(cause) {\n return {\n ptr() {\n return unavailable(cause);\n },\n toArrayBuffer() {\n return unavailable(cause);\n }\n };\n}\nasync function loadBackend() {\n if (typeof process !== \"undefined\" && \"bun\" in process.versions) {\n return createBunBackend(await importModule(\"bun:ffi\"));\n }\n try {\n return createNodeBackend(await importModule(\"node:ffi\"));\n } catch (error) {\n return createUnsupportedBackend(error);\n }\n}\nfunction importModule(specifier) {\n return import(specifier).then((module) => module.default ?? module);\n}\nfunction createBunBackend(bun) {\n return {\n ptr: bun.ptr,\n toArrayBuffer(pointer, offset, length) {\n return bun.toArrayBuffer(toBunPointer(pointer), offset, length);\n }\n };\n}\nfunction createNodeBackend(nodeFfi) {\n return {\n ptr(value) {\n if (ArrayBuffer.isView(value)) {\n return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset);\n }\n if (value instanceof ArrayBuffer) {\n return nodeFfi.getRawPointer(value);\n }\n throw new TypeError(\"node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values.\");\n },\n toArrayBuffer(pointer, offset, length) {\n return nodeFfi.toArrayBuffer(toBigIntPointer(pointer) + BigInt(offset ?? 0), length, false);\n }\n };\n}\nfunction toBigIntPointer(pointer) {\n return typeof pointer === \"bigint\" ? pointer : BigInt(pointer);\n}\nfunction toBunPointer(pointer) {\n return typeof pointer === \"bigint\" ? Number(pointer) : pointer;\n}\nvar ptr = backend.ptr;\nvar toArrayBuffer = backend.toArrayBuffer;\n\n// src/structs_ffi.ts\nfunction fatalError(...args) {\n const message = args.join(\" \");\n console.error(\"FATAL ERROR:\", message);\n throw new Error(message);\n}\nvar pointerSize = process.arch === \"x64\" || process.arch === \"arm64\" ? 8 : 4;\nvar isBun = typeof process !== \"undefined\" && \"bun\" in process.versions;\nvar typeSizes = {\n u8: 1,\n bool_u8: 1,\n bool_u32: 4,\n u16: 2,\n i16: 2,\n u32: 4,\n u64: 8,\n f32: 4,\n f64: 8,\n pointer: pointerSize,\n i32: 4,\n i64: 8\n};\nvar primitiveKeys = Object.keys(typeSizes);\nfunction isPrimitiveType(type) {\n return typeof type === \"string\" && primitiveKeys.includes(type);\n}\nvar typeAlignments = { ...typeSizes };\nvar typeGetters = {\n u8: (view, offset) => view.getUint8(offset),\n bool_u8: (view, offset) => Boolean(view.getUint8(offset)),\n bool_u32: (view, offset) => Boolean(view.getUint32(offset, true)),\n u16: (view, offset) => view.getUint16(offset, true),\n i16: (view, offset) => view.getInt16(offset, true),\n u32: (view, offset) => view.getUint32(offset, true),\n u64: (view, offset) => view.getBigUint64(offset, true),\n f32: (view, offset) => view.getFloat32(offset, true),\n f64: (view, offset) => view.getFloat64(offset, true),\n i32: (view, offset) => view.getInt32(offset, true),\n i64: (view, offset) => view.getBigInt64(offset, true),\n pointer: (view, offset) => pointerSize === 8 ? view.getBigUint64(offset, true) : BigInt(view.getUint32(offset, true))\n};\nfunction objectPtr() {\n return {\n __type: \"objectPointer\"\n };\n}\nfunction isObjectPointerDef(type) {\n return typeof type === \"object\" && type !== null && type.__type === \"objectPointer\";\n}\nfunction allocStruct(structDef, options) {\n const buffer = new ArrayBuffer(structDef.size);\n const view = new DataView(buffer);\n const result = { buffer, view };\n const { pack: pointerPacker } = primitivePackers(\"pointer\");\n if (options?.lengths) {\n const subBuffers = {};\n for (const [arrayFieldName, length] of Object.entries(options.lengths)) {\n const arrayMeta = structDef.arrayFields.get(arrayFieldName);\n if (!arrayMeta) {\n throw new Error(`Field '${arrayFieldName}' is not an array field with a lengthOf field`);\n }\n const subBuffer = new ArrayBuffer(length * arrayMeta.elementSize);\n subBuffers[arrayFieldName] = subBuffer;\n const pointer = length > 0 ? ptr(subBuffer) : null;\n pointerPacker(view, arrayMeta.arrayOffset, pointer);\n retainPointerTarget(buffer, subBuffer);\n arrayMeta.lengthPack(view, arrayMeta.lengthOffset, length);\n }\n if (Object.keys(subBuffers).length > 0) {\n result.subBuffers = subBuffers;\n }\n }\n return result;\n}\nfunction alignOffset(offset, align) {\n return offset + (align - 1) & ~(align - 1);\n}\nfunction enumTypeError(value) {\n throw new TypeError(`Invalid enum value: ${value}`);\n}\nfunction defineEnum(mapping, base = \"u32\") {\n const reverse = Object.fromEntries(Object.entries(mapping).map(([k, v]) => [v, k]));\n return {\n __type: \"enum\",\n type: base,\n to(value) {\n return typeof value === \"number\" ? value : mapping[value] ?? enumTypeError(String(value));\n },\n from(value) {\n return reverse[value] ?? enumTypeError(String(value));\n },\n enum: mapping\n };\n}\nfunction isEnum(type) {\n return typeof type === \"object\" && type.__type === \"enum\";\n}\nfunction isStruct(type) {\n return typeof type === \"object\" && type.__type === \"struct\";\n}\nfunction primitivePackers(type) {\n let pack;\n let unpack;\n switch (type) {\n case \"u8\":\n pack = (view, off, val) => view.setUint8(off, val);\n unpack = (view, off) => view.getUint8(off);\n break;\n case \"bool_u8\":\n pack = (view, off, val) => view.setUint8(off, val ? 1 : 0);\n unpack = (view, off) => Boolean(view.getUint8(off));\n break;\n case \"bool_u32\":\n pack = (view, off, val) => view.setUint32(off, val ? 1 : 0, true);\n unpack = (view, off) => Boolean(view.getUint32(off, true));\n break;\n case \"u16\":\n pack = (view, off, val) => view.setUint16(off, val, true);\n unpack = (view, off) => view.getUint16(off, true);\n break;\n case \"i16\":\n pack = (view, off, val) => view.setInt16(off, val, true);\n unpack = (view, off) => view.getInt16(off, true);\n break;\n case \"u32\":\n pack = (view, off, val) => view.setUint32(off, val, true);\n unpack = (view, off) => view.getUint32(off, true);\n break;\n case \"i32\":\n pack = (view, off, val) => view.setInt32(off, val, true);\n unpack = (view, off) => view.getInt32(off, true);\n break;\n case \"i64\":\n pack = (view, off, val) => view.setBigInt64(off, BigInt(val), true);\n unpack = (view, off) => view.getBigInt64(off, true);\n break;\n case \"u64\":\n pack = (view, off, val) => view.setBigUint64(off, BigInt(val), true);\n unpack = (view, off) => view.getBigUint64(off, true);\n break;\n case \"f32\":\n pack = (view, off, val) => view.setFloat32(off, val, true);\n unpack = (view, off) => view.getFloat32(off, true);\n break;\n case \"f64\":\n pack = (view, off, val) => view.setFloat64(off, val, true);\n unpack = (view, off) => view.getFloat64(off, true);\n break;\n case \"pointer\":\n pack = (view, off, val) => {\n pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);\n };\n unpack = (view, off) => {\n if (pointerSize === 8) {\n const value = view.getBigUint64(off, true);\n return isBun ? Number(value) : value;\n }\n return view.getUint32(off, true);\n };\n break;\n default:\n fatalError(`Unsupported primitive type: ${type}`);\n }\n return { pack, unpack };\n}\nvar { pack: pointerPacker, unpack: pointerUnpacker } = primitivePackers(\"pointer\");\nvar retainedPointerTargets = new WeakMap;\nfunction retainPointerTarget(owner, target) {\n const retained = retainedPointerTargets.get(owner);\n if (retained) {\n retained.push(target);\n } else {\n retainedPointerTargets.set(owner, [target]);\n }\n}\nfunction retainIfPointerTargets(owner, target) {\n if (retainedPointerTargets.has(target)) {\n retainPointerTarget(owner, target);\n }\n}\nfunction isNullPointer(pointer) {\n return pointer == null || pointer === 0 || pointer === 0n;\n}\nfunction toItemCount(length) {\n return typeof length === \"bigint\" ? Number(length) : length;\n}\nfunction packObjectArray(val) {\n const buffer = new ArrayBuffer(val.length * pointerSize);\n const bufferView = new DataView(buffer);\n for (let i = 0;i < val.length; i++) {\n const instance = val[i];\n const ptrValue = instance?.ptr ?? null;\n pointerPacker(bufferView, i * pointerSize, ptrValue);\n }\n return bufferView;\n}\nvar encoder = new TextEncoder;\nvar decoder = new TextDecoder;\nfunction defineStruct(fields, structDefOptions) {\n let offset = 0;\n let maxAlign = 1;\n const layout = [];\n const lengthOfFields = {};\n const lengthOfRequested = [];\n const arrayFieldsMetadata = {};\n for (const [name, typeOrStruct, options = {}] of fields) {\n if (options.condition && !options.condition()) {\n continue;\n }\n let size = 0, align = 0;\n let pack;\n let unpack;\n let needsLengthOf = false;\n let lengthOfDef = null;\n if (isPrimitiveType(typeOrStruct)) {\n size = typeSizes[typeOrStruct];\n align = typeAlignments[typeOrStruct];\n ({ pack, unpack } = primitivePackers(typeOrStruct));\n } else if (typeof typeOrStruct === \"string\" && typeOrStruct === \"cstring\") {\n size = pointerSize;\n align = pointerSize;\n pack = (view, off, val) => {\n if (!val) {\n pointerPacker(view, off, null);\n return;\n }\n const bytes = encoder.encode(val + \"\\x00\");\n const bufPtr = ptr(bytes);\n pointerPacker(view, off, bufPtr);\n retainPointerTarget(view.buffer, bytes);\n };\n unpack = (view, off) => {\n const ptrVal = pointerUnpacker(view, off);\n return ptrVal;\n };\n } else if (typeof typeOrStruct === \"string\" && typeOrStruct === \"char*\") {\n size = pointerSize;\n align = pointerSize;\n pack = (view, off, val) => {\n if (!val) {\n pointerPacker(view, off, null);\n return;\n }\n const bytes = encoder.encode(val);\n const bufPtr = ptr(bytes);\n pointerPacker(view, off, bufPtr);\n retainPointerTarget(view.buffer, bytes);\n };\n unpack = (view, off) => {\n const ptrVal = pointerUnpacker(view, off);\n return ptrVal;\n };\n needsLengthOf = true;\n } else if (isEnum(typeOrStruct)) {\n const base = typeOrStruct.type;\n size = typeSizes[base];\n align = typeAlignments[base];\n const { pack: packEnum } = primitivePackers(base);\n pack = (view, off, val) => {\n const num = typeOrStruct.to(val);\n packEnum(view, off, num);\n };\n unpack = (view, off) => {\n const raw = typeGetters[base](view, off);\n return typeOrStruct.from(raw);\n };\n } else if (isStruct(typeOrStruct)) {\n if (options.asPointer === true) {\n size = pointerSize;\n align = pointerSize;\n pack = (view, off, val, obj, options2) => {\n if (!val) {\n pointerPacker(view, off, null);\n return;\n }\n const nestedBuf = typeOrStruct.pack(val, options2);\n pointerPacker(view, off, ptr(nestedBuf));\n retainPointerTarget(view.buffer, nestedBuf);\n };\n unpack = (view, off) => {\n throw new Error(\"Not implemented yet\");\n };\n } else {\n size = typeOrStruct.size;\n align = typeOrStruct.align;\n pack = (view, off, val, obj, options2) => {\n const nestedBuf = typeOrStruct.pack(val, options2);\n const nestedView = new Uint8Array(nestedBuf);\n const dView = new Uint8Array(view.buffer);\n dView.set(nestedView, off);\n retainIfPointerTargets(view.buffer, nestedBuf);\n };\n unpack = (view, off) => {\n const slice = view.buffer.slice(off, off + size);\n return typeOrStruct.unpack(slice);\n };\n }\n } else if (isObjectPointerDef(typeOrStruct)) {\n size = pointerSize;\n align = pointerSize;\n pack = (view, off, value) => {\n const ptrValue = value?.ptr ?? null;\n if (ptrValue === undefined) {\n console.warn(`Field '${name}' expected object with '.ptr' property, but got undefined pointer value from:`, value);\n pointerPacker(view, off, null);\n } else {\n pointerPacker(view, off, ptrValue);\n }\n };\n unpack = (view, off) => {\n return pointerUnpacker(view, off);\n };\n } else if (Array.isArray(typeOrStruct) && typeOrStruct.length === 1 && typeOrStruct[0] !== undefined) {\n const [def] = typeOrStruct;\n size = pointerSize;\n align = pointerSize;\n let arrayElementSize;\n if (isEnum(def)) {\n arrayElementSize = typeSizes[def.type];\n pack = (view, off, val, obj) => {\n if (!val || val.length === 0) {\n pointerPacker(view, off, null);\n return;\n }\n const buffer = new ArrayBuffer(val.length * arrayElementSize);\n const bufferView = new DataView(buffer);\n for (let i = 0;i < val.length; i++) {\n const num = def.to(val[i]);\n bufferView.setUint32(i * arrayElementSize, num, true);\n }\n pointerPacker(view, off, ptr(buffer));\n retainPointerTarget(view.buffer, buffer);\n };\n unpack = null;\n needsLengthOf = true;\n lengthOfDef = def;\n } else if (isStruct(def)) {\n arrayElementSize = def.size;\n pack = (view, off, val, obj, options2) => {\n if (!val || val.length === 0) {\n pointerPacker(view, off, null);\n return;\n }\n const buffer = new ArrayBuffer(val.length * arrayElementSize);\n const bufferView = new DataView(buffer);\n for (let i = 0;i < val.length; i++) {\n def.packInto(val[i], bufferView, i * arrayElementSize, options2);\n }\n pointerPacker(view, off, ptr(buffer));\n retainPointerTarget(view.buffer, buffer);\n };\n unpack = (view, off) => {\n throw new Error(\"Not implemented yet\");\n };\n } else if (isPrimitiveType(def)) {\n arrayElementSize = typeSizes[def];\n const { pack: primitivePack } = primitivePackers(def);\n pack = (view, off, val) => {\n if (!val || val.length === 0) {\n pointerPacker(view, off, null);\n return;\n }\n const buffer = new ArrayBuffer(val.length * arrayElementSize);\n const bufferView = new DataView(buffer);\n for (let i = 0;i < val.length; i++) {\n primitivePack(bufferView, i * arrayElementSize, val[i]);\n }\n pointerPacker(view, off, ptr(buffer));\n retainPointerTarget(view.buffer, buffer);\n };\n unpack = null;\n needsLengthOf = true;\n lengthOfDef = def;\n } else if (isObjectPointerDef(def)) {\n arrayElementSize = pointerSize;\n pack = (view, off, val) => {\n if (!val || val.length === 0) {\n pointerPacker(view, off, null);\n return;\n }\n const packedView = packObjectArray(val);\n pointerPacker(view, off, ptr(packedView.buffer));\n retainPointerTarget(view.buffer, packedView.buffer);\n };\n unpack = () => {\n throw new Error(\"not implemented yet\");\n };\n } else {\n throw new Error(`Unsupported array element type for ${name}: ${JSON.stringify(def)}`);\n }\n const lengthOfField = Object.values(lengthOfFields).find((f) => f.lengthOf === name);\n if (lengthOfField && isPrimitiveType(lengthOfField.type)) {\n const { pack: lengthPack } = primitivePackers(lengthOfField.type);\n arrayFieldsMetadata[name] = {\n elementSize: arrayElementSize,\n arrayOffset: offset,\n lengthOffset: lengthOfField.offset,\n lengthPack\n };\n }\n } else {\n throw new Error(`Unsupported field type for ${name}: ${JSON.stringify(typeOrStruct)}`);\n }\n offset = alignOffset(offset, align);\n if (options.unpackTransform) {\n const originalUnpack = unpack;\n unpack = (view, off) => options.unpackTransform(originalUnpack(view, off));\n }\n if (options.packTransform) {\n const originalPack = pack;\n pack = (view, off, val, obj, packOptions) => originalPack(view, off, options.packTransform(val), obj, packOptions);\n }\n if (options.optional) {\n const originalPack = pack;\n if (isStruct(typeOrStruct) && !options.asPointer) {\n pack = (view, off, val, obj, packOptions) => {\n if (val || options.mapOptionalInline) {\n originalPack(view, off, val, obj, packOptions);\n }\n };\n } else {\n pack = (view, off, val, obj, packOptions) => originalPack(view, off, val ?? 0, obj, packOptions);\n }\n }\n if (options.lengthOf) {\n const originalPack = pack;\n pack = (view, off, val, obj, packOptions) => {\n const targetValue = obj[options.lengthOf];\n let length = 0;\n if (targetValue) {\n if (typeof targetValue === \"string\") {\n length = Buffer.byteLength(targetValue);\n } else {\n length = targetValue.length;\n }\n }\n return originalPack(view, off, length, obj, packOptions);\n };\n }\n let validateFunctions;\n if (options.validate) {\n validateFunctions = Array.isArray(options.validate) ? options.validate : [options.validate];\n }\n const layoutField = {\n name,\n offset,\n size,\n align,\n validate: validateFunctions,\n optional: !!options.optional || !!options.lengthOf || options.default !== undefined,\n default: options.default,\n pack,\n unpack,\n type: typeOrStruct,\n lengthOf: options.lengthOf\n };\n layout.push(layoutField);\n if (options.lengthOf) {\n lengthOfFields[options.lengthOf] = layoutField;\n }\n if (needsLengthOf) {\n const def = typeof typeOrStruct === \"string\" && typeOrStruct === \"char*\" ? \"char*\" : lengthOfDef;\n if (!def)\n fatalError(`Internal error: needsLengthOf=true but def is null for ${name}`);\n lengthOfRequested.push({ requester: layoutField, def });\n }\n offset += size;\n maxAlign = Math.max(maxAlign, align);\n }\n for (const { requester, def } of lengthOfRequested) {\n const lengthOfField = lengthOfFields[requester.name];\n if (!lengthOfField) {\n if (def === \"char*\") {\n continue;\n }\n throw new Error(`lengthOf field not found for array field ${requester.name}`);\n }\n if (def === \"char*\") {\n const relativeOffset = lengthOfField.offset - requester.offset;\n requester.unpack = (view, off) => {\n const ptrAddress = pointerUnpacker(view, off);\n const length = lengthOfField.unpack(view, off + relativeOffset);\n if (isNullPointer(ptrAddress)) {\n return null;\n }\n const byteLength = toItemCount(length);\n if (byteLength === 0) {\n return \"\";\n }\n const buffer = toArrayBuffer(ptrAddress, 0, byteLength);\n return decoder.decode(buffer);\n };\n } else if (isPrimitiveType(def)) {\n const elemSize = typeSizes[def];\n const { unpack: primitiveUnpack } = primitivePackers(def);\n const relativeOffset = lengthOfField.offset - requester.offset;\n requester.unpack = (view, off) => {\n const result = [];\n const length = lengthOfField.unpack(view, off + relativeOffset);\n const itemCount = toItemCount(length);\n const ptrAddress = pointerUnpacker(view, off);\n if (isNullPointer(ptrAddress) && itemCount > 0) {\n throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);\n }\n if (isNullPointer(ptrAddress) || itemCount === 0) {\n return [];\n }\n const buffer = toArrayBuffer(ptrAddress, 0, itemCount * elemSize);\n const bufferView = new DataView(buffer);\n for (let i = 0;i < itemCount; i++) {\n result.push(primitiveUnpack(bufferView, i * elemSize));\n }\n return result;\n };\n } else {\n const elemSize = def.type === \"u32\" ? 4 : 8;\n const relativeOffset = lengthOfField.offset - requester.offset;\n requester.unpack = (view, off) => {\n const result = [];\n const length = lengthOfField.unpack(view, off + relativeOffset);\n const itemCount = toItemCount(length);\n const ptrAddress = pointerUnpacker(view, off);\n if (isNullPointer(ptrAddress) && itemCount > 0) {\n throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);\n }\n if (isNullPointer(ptrAddress) || itemCount === 0) {\n return [];\n }\n const buffer = toArrayBuffer(ptrAddress, 0, itemCount * elemSize);\n const bufferView = new DataView(buffer);\n for (let i = 0;i < itemCount; i++) {\n result.push(def.from(bufferView.getUint32(i * elemSize, true)));\n }\n return result;\n };\n }\n }\n const totalSize = alignOffset(offset, maxAlign);\n const description = layout.map((f) => ({\n name: f.name,\n offset: f.offset,\n size: f.size,\n align: f.align,\n optional: f.optional,\n type: f.type,\n lengthOf: f.lengthOf\n }));\n const layoutByName = new Map(description.map((f) => [f.name, f]));\n const arrayFields = new Map(Object.entries(arrayFieldsMetadata));\n return {\n __type: \"struct\",\n size: totalSize,\n align: maxAlign,\n hasMapValue: !!structDefOptions?.mapValue,\n layoutByName,\n arrayFields,\n pack(obj, options) {\n const buf = new ArrayBuffer(totalSize);\n const view = new DataView(buf);\n let mappedObj = obj;\n if (structDefOptions?.mapValue) {\n mappedObj = structDefOptions.mapValue(obj);\n }\n for (const field of layout) {\n const value = mappedObj[field.name] ?? field.default;\n if (!field.optional && value === undefined) {\n fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);\n }\n if (field.validate) {\n for (const validateFn of field.validate) {\n validateFn(value, field.name, {\n hints: options?.validationHints,\n input: mappedObj\n });\n }\n }\n field.pack(view, field.offset, value, mappedObj, options);\n }\n return view.buffer;\n },\n packInto(obj, view, offset2, options) {\n let mappedObj = obj;\n if (structDefOptions?.mapValue) {\n mappedObj = structDefOptions.mapValue(obj);\n }\n for (const field of layout) {\n const value = mappedObj[field.name] ?? field.default;\n if (!field.optional && value === undefined) {\n console.warn(`packInto missing value for non-optional field '${field.name}' at offset ${offset2 + field.offset}. Writing default or zero.`);\n }\n if (field.validate) {\n for (const validateFn of field.validate) {\n validateFn(value, field.name, {\n hints: options?.validationHints,\n input: mappedObj\n });\n }\n }\n field.pack(view, offset2 + field.offset, value, mappedObj, options);\n }\n },\n unpack(buf) {\n if (buf.byteLength < totalSize) {\n fatalError(`Buffer size (${buf.byteLength}) is smaller than struct size (${totalSize}) for unpacking.`);\n }\n const view = new DataView(buf);\n const result = structDefOptions?.default ? { ...structDefOptions.default } : {};\n for (const field of layout) {\n if (!field.unpack) {\n continue;\n }\n try {\n result[field.name] = field.unpack(view, field.offset);\n } catch (e) {\n console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, e);\n throw e;\n }\n }\n if (structDefOptions?.reduceValue) {\n return structDefOptions.reduceValue(result);\n }\n return result;\n },\n packList(objects, options) {\n if (objects.length === 0) {\n return new ArrayBuffer(0);\n }\n const buffer = new ArrayBuffer(totalSize * objects.length);\n const view = new DataView(buffer);\n for (let i = 0;i < objects.length; i++) {\n let mappedObj = objects[i];\n if (structDefOptions?.mapValue) {\n mappedObj = structDefOptions.mapValue(objects[i]);\n }\n for (const field of layout) {\n const value = mappedObj[field.name] ?? field.default;\n if (!field.optional && value === undefined) {\n fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);\n }\n if (field.validate) {\n for (const validateFn of field.validate) {\n validateFn(value, field.name, {\n hints: options?.validationHints,\n input: mappedObj\n });\n }\n }\n field.pack(view, i * totalSize + field.offset, value, mappedObj, options);\n }\n }\n return buffer;\n },\n unpackList(buf, count) {\n if (count === 0) {\n return [];\n }\n const expectedSize = totalSize * count;\n if (buf.byteLength < expectedSize) {\n fatalError(`Buffer size (${buf.byteLength}) is smaller than expected size (${expectedSize}) for unpacking ${count} structs.`);\n }\n const view = new DataView(buf);\n const results = [];\n for (let i = 0;i < count; i++) {\n const offset2 = i * totalSize;\n const result = structDefOptions?.default ? { ...structDefOptions.default } : {};\n for (const field of layout) {\n if (!field.unpack) {\n continue;\n }\n try {\n result[field.name] = field.unpack(view, offset2 + field.offset);\n } catch (e) {\n console.error(`Error unpacking field '${field.name}' at index ${i}, offset ${offset2 + field.offset}:`, e);\n throw e;\n }\n }\n if (structDefOptions?.reduceValue) {\n results.push(structDefOptions.reduceValue(result));\n } else {\n results.push(result);\n }\n }\n return results;\n },\n describe() {\n return description;\n }\n };\n}\nexport {\n pointerSize,\n packObjectArray,\n objectPtr,\n defineStruct,\n defineEnum,\n allocStruct\n};\n", + "import { defineStruct, defineEnum } from \"bun-ffi-structs\"\nimport { ptr, toArrayBuffer, type Pointer } from \"./platform/ffi.js\"\nimport { RGBA, normalizeColorValue } from \"./lib/RGBA.js\"\n\nconst rgbaPackTransform = (rgba?: RGBA) => (rgba ? ptr(rgba.buffer) : null)\nconst rgbaUnpackTransform = (ptr?: Pointer) =>\n ptr ? RGBA.fromArray(new Uint16Array(toArrayBuffer(ptr, 0, 8))) : undefined\n\ntype StyledChunkInput = {\n text: string\n fg?: RGBA | null\n bg?: RGBA | null\n attributes?: number | null\n link?: { url: string } | string | null\n}\n\nexport const StyledChunkStruct = defineStruct(\n [\n [\"text\", \"char*\"],\n [\"text_len\", \"u64\", { lengthOf: \"text\" }],\n [\n \"fg\",\n \"pointer\",\n {\n optional: true,\n packTransform: rgbaPackTransform,\n unpackTransform: rgbaUnpackTransform,\n },\n ],\n [\n \"bg\",\n \"pointer\",\n {\n optional: true,\n packTransform: rgbaPackTransform,\n unpackTransform: rgbaUnpackTransform,\n },\n ],\n [\"attributes\", \"u32\", { default: 0 }],\n [\"link\", \"char*\", { default: \"\" }],\n [\"link_len\", \"u64\", { lengthOf: \"link\" }],\n ],\n {\n mapValue: (chunk: StyledChunkInput): StyledChunkInput => {\n const normalizedFg = normalizeColorValue(chunk.fg ?? null)\n const normalizedBg = normalizeColorValue(chunk.bg ?? null)\n\n if (!chunk.link || typeof chunk.link === \"string\") {\n return {\n ...chunk,\n fg: normalizedFg?.rgba ?? null,\n bg: normalizedBg?.rgba ?? null,\n }\n }\n\n return {\n ...chunk,\n fg: normalizedFg?.rgba ?? null,\n bg: normalizedBg?.rgba ?? null,\n link: chunk.link.url,\n }\n },\n },\n)\n\nexport const HighlightStruct = defineStruct([\n [\"start\", \"u32\"],\n [\"end\", \"u32\"],\n [\"styleId\", \"u32\"],\n [\"priority\", \"u8\", { default: 0 }],\n [\"hlRef\", \"u16\", { default: 0 }],\n])\n\nexport const LogicalCursorStruct = defineStruct([\n [\"row\", \"u32\"],\n [\"col\", \"u32\"],\n [\"offset\", \"u32\"],\n])\n\nexport const VisualCursorStruct = defineStruct([\n [\"visualRow\", \"u32\"],\n [\"visualCol\", \"u32\"],\n [\"logicalRow\", \"u32\"],\n [\"logicalCol\", \"u32\"],\n [\"offset\", \"u32\"],\n])\n\nconst UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, \"u8\")\nconst TerminalMultiplexerEnum = defineEnum({ none: 0, tmux: 1, zellij: 2, screen: 3, unknown: 4 }, \"u8\")\n\nexport const TerminalCapabilitiesStruct = defineStruct([\n [\"kitty_keyboard\", \"bool_u8\"],\n [\"kitty_graphics\", \"bool_u8\"],\n [\"rgb\", \"bool_u8\"],\n [\"ansi256\", \"bool_u8\"],\n [\"unicode\", UnicodeMethodEnum],\n [\"sgr_pixels\", \"bool_u8\"],\n [\"color_scheme_updates\", \"bool_u8\"],\n [\"explicit_width\", \"bool_u8\"],\n [\"scaled_text\", \"bool_u8\"],\n [\"sixel\", \"bool_u8\"],\n [\"focus_tracking\", \"bool_u8\"],\n [\"sync\", \"bool_u8\"],\n [\"bracketed_paste\", \"bool_u8\"],\n [\"hyperlinks\", \"bool_u8\"],\n [\"osc52\", \"bool_u8\"],\n [\"notifications\", \"bool_u8\"],\n [\"explicit_cursor_positioning\", \"bool_u8\"],\n [\"remote\", \"bool_u8\"],\n [\"multiplexer\", TerminalMultiplexerEnum],\n [\"term_name\", \"char*\"],\n [\"term_name_len\", \"u64\", { lengthOf: \"term_name\" }],\n [\"term_version\", \"char*\"],\n [\"term_version_len\", \"u64\", { lengthOf: \"term_version\" }],\n [\"term_from_xtversion\", \"bool_u8\"],\n])\n\nexport const EncodedCharStruct = defineStruct([\n [\"width\", \"u8\"],\n [\"char\", \"u32\"],\n])\n\nexport const LineInfoStruct = defineStruct([\n [\"startCols\", [\"u32\"]],\n [\"startColsLen\", \"u32\", { lengthOf: \"startCols\" }],\n [\"widthCols\", [\"u32\"]],\n [\"widthColsLen\", \"u32\", { lengthOf: \"widthCols\" }],\n [\"sources\", [\"u32\"]],\n [\"sourcesLen\", \"u32\", { lengthOf: \"sources\" }],\n [\"wraps\", [\"u32\"]],\n [\"wrapsLen\", \"u32\", { lengthOf: \"wraps\" }],\n [\"widthColsMax\", \"u32\"],\n])\n\nexport const MeasureResultStruct = defineStruct([\n [\"lineCount\", \"u32\"],\n [\"widthColsMax\", \"u32\"],\n])\n\nexport const CursorStateStruct = defineStruct([\n [\"x\", \"u32\"],\n [\"y\", \"u32\"],\n [\"visible\", \"bool_u8\"],\n [\"style\", \"u8\"],\n [\"blinking\", \"bool_u8\"],\n [\"r\", \"f32\"],\n [\"g\", \"f32\"],\n [\"b\", \"f32\"],\n [\"a\", \"f32\"],\n])\n\nexport const CursorStyleOptionsStruct = defineStruct([\n [\"style\", \"u8\", { default: 255 }],\n [\"blinking\", \"u8\", { default: 255 }],\n [\n \"color\",\n \"pointer\",\n {\n optional: true,\n packTransform: rgbaPackTransform,\n unpackTransform: rgbaUnpackTransform,\n },\n ],\n [\"cursor\", \"u8\", { default: 255 }],\n])\n\nexport const GridDrawOptionsStruct = defineStruct([\n [\"drawInner\", \"bool_u8\", { default: true }],\n [\"drawOuter\", \"bool_u8\", { default: true }],\n])\n\nexport type BuildOptions = {\n gpaSafeStats: boolean\n gpaMemoryLimitTracking: boolean\n}\n\nexport const BuildOptionsStruct = defineStruct([\n [\"gpaSafeStats\", \"bool_u8\"],\n [\"gpaMemoryLimitTracking\", \"bool_u8\"],\n])\n\nexport type AllocatorStats = {\n totalRequestedBytes: number\n activeAllocations: number\n smallAllocations: number\n largeAllocations: number\n requestedBytesValid: boolean\n}\n\nexport const AllocatorStatsStruct = defineStruct([\n [\"totalRequestedBytes\", \"u64\"],\n [\"activeAllocations\", \"u64\"],\n [\"smallAllocations\", \"u64\"],\n [\"largeAllocations\", \"u64\"],\n [\"requestedBytesValid\", \"bool_u8\"],\n])\n\nexport type NativeRenderStats = {\n nativeLastFrameTime: number\n nativeAverageFrameTime: number\n nativeFrameCount: number\n cellsUpdated: number\n averageCellsUpdated: number\n nativeRenderTime?: number\n nativeStdoutWriteTime?: number\n}\n\nexport const NativeRenderStatsStruct = defineStruct([\n [\"lastFrameTime\", \"f64\"],\n [\"averageFrameTime\", \"f64\"],\n [\"renderTime\", \"f64\"],\n [\"stdoutWriteTime\", \"f64\"],\n [\"frameCount\", \"u64\"],\n [\"cellsUpdated\", \"u32\"],\n [\"averageCellsUpdated\", \"u32\"],\n [\"renderTimeValid\", \"bool_u8\"],\n [\"stdoutWriteTimeValid\", \"bool_u8\"],\n])\n\nexport type GrowthPolicy = \"grow\" | \"block\"\n\nexport type NativeSpanFeedOptions = {\n chunkSize?: number\n initialChunks?: number\n maxBytes?: bigint\n growthPolicy?: GrowthPolicy\n autoCommitOnFull?: boolean\n spanQueueCapacity?: number\n}\n\nexport type NativeSpanFeedStats = {\n bytesWritten: bigint\n spansCommitted: bigint\n chunks: number\n pendingSpans: number\n}\n\nexport type SpanInfo = {\n chunkPtr: Pointer\n offset: number\n len: number\n chunkIndex: number\n}\n\nexport type ReserveInfo = {\n ptr: Pointer\n len: number\n}\n\nconst GrowthPolicyEnum = defineEnum({ grow: 0, block: 1 }, \"u8\")\n\nexport const NativeSpanFeedOptionsStruct = defineStruct([\n [\"chunkSize\", \"u32\", { default: 64 * 1024 }],\n [\"initialChunks\", \"u32\", { default: 2 }],\n [\"maxBytes\", \"u64\", { default: 0n }],\n [\"growthPolicy\", GrowthPolicyEnum, { default: \"grow\" }],\n [\"autoCommitOnFull\", \"bool_u8\", { default: true }],\n [\"spanQueueCapacity\", \"u32\", { default: 0 }],\n])\n\nexport const NativeSpanFeedStatsStruct = defineStruct([\n [\"bytesWritten\", \"u64\"],\n [\"spansCommitted\", \"u64\"],\n [\"chunks\", \"u32\"],\n [\"pendingSpans\", \"u32\"],\n])\n\nexport const SpanInfoStruct = defineStruct(\n [\n [\"chunkPtr\", \"pointer\"],\n [\"offset\", \"u32\"],\n [\"len\", \"u32\"],\n [\"chunkIndex\", \"u32\"],\n [\"reserved\", \"u32\", { default: 0 }],\n ],\n {\n reduceValue: (value: { chunkPtr: Pointer; offset: number; len: number; chunkIndex: number }) => ({\n chunkPtr: value.chunkPtr as Pointer,\n offset: value.offset,\n len: value.len,\n chunkIndex: value.chunkIndex,\n }),\n },\n)\n\nexport const ReserveInfoStruct = defineStruct(\n [\n [\"ptr\", \"pointer\"],\n [\"len\", \"u32\"],\n [\"reserved\", \"u32\", { default: 0 }],\n ],\n {\n reduceValue: (value: { ptr: Pointer; len: number }) => ({\n ptr: value.ptr as Pointer,\n len: value.len,\n }),\n },\n)\n\nexport type AudioCreateOptions = {\n sampleRate?: number\n playbackChannels?: number\n}\n\nexport type AudioStartOptions = {\n periodSizeInFrames?: number\n periodSizeInMilliseconds?: number\n periods?: number\n performanceProfile?: number\n shareMode?: number\n noPreSilencedOutputBuffer?: boolean\n noClip?: boolean\n noDisableDenormals?: boolean\n noFixedSizedCallback?: boolean\n wasapiNoAutoConvertSrc?: boolean\n wasapiNoDefaultQualitySrc?: boolean\n alsaNoMMap?: boolean\n alsaNoAutoFormat?: boolean\n alsaNoAutoChannels?: boolean\n alsaNoAutoResample?: boolean\n}\n\nexport type AudioVoiceOptions = {\n volume?: number\n pan?: number\n loop?: boolean\n groupId?: number\n}\n\nexport type AudioStats = {\n soundsLoaded: number\n voicesActive: number\n framesMixed: bigint\n lockMisses: number\n lastPeak: number\n lastRms: number\n}\n\nexport const AudioCreateOptionsStruct = defineStruct([\n [\"sampleRate\", \"u32\", { default: 48_000 }],\n [\"playbackChannels\", \"u32\", { default: 2 }],\n])\n\nexport const AudioStartOptionsStruct = defineStruct([\n [\"periodSizeInFrames\", \"u32\", { default: 0 }],\n [\"periodSizeInMilliseconds\", \"u32\", { default: 0 }],\n [\"periods\", \"u32\", { default: 0 }],\n [\"performanceProfile\", \"u8\", { default: 0 }],\n [\"shareMode\", \"u8\", { default: 0 }],\n [\"noPreSilencedOutputBuffer\", \"bool_u8\", { default: false }],\n [\"noClip\", \"bool_u8\", { default: false }],\n [\"noDisableDenormals\", \"bool_u8\", { default: false }],\n [\"noFixedSizedCallback\", \"bool_u8\", { default: false }],\n [\"wasapiNoAutoConvertSrc\", \"bool_u8\", { default: false }],\n [\"wasapiNoDefaultQualitySrc\", \"bool_u8\", { default: false }],\n [\"alsaNoMMap\", \"bool_u8\", { default: false }],\n [\"alsaNoAutoFormat\", \"bool_u8\", { default: false }],\n [\"alsaNoAutoChannels\", \"bool_u8\", { default: false }],\n [\"alsaNoAutoResample\", \"bool_u8\", { default: false }],\n])\n\nexport const AudioVoiceOptionsStruct = defineStruct([\n [\"volume\", \"f32\", { default: 1 }],\n [\"pan\", \"f32\", { default: 0 }],\n [\"loop\", \"bool_u8\", { default: false }],\n [\"groupId\", \"u32\", { default: 0 }],\n])\n\nexport const AudioStatsStruct = defineStruct([\n [\"soundsLoaded\", \"u32\"],\n [\"voicesActive\", \"u32\"],\n [\"framesMixed\", \"u64\"],\n [\"lockMisses\", \"u32\"],\n [\"lastPeak\", \"f32\"],\n [\"lastRms\", \"f32\"],\n])\n", + "import {\n resolveRenderLib,\n type NativeYogaDirtiedCallback,\n type NativeYogaMeasureCallback,\n type RenderLib,\n} from \"./zig.js\"\nimport type { FFICallbackInstance, Pointer } from \"./platform/ffi.js\"\n\nexport enum Align {\n Auto = 0,\n FlexStart = 1,\n Center = 2,\n FlexEnd = 3,\n Stretch = 4,\n Baseline = 5,\n SpaceBetween = 6,\n SpaceAround = 7,\n SpaceEvenly = 8,\n}\n\nexport enum BoxSizing {\n BorderBox = 0,\n ContentBox = 1,\n}\n\nexport enum Dimension {\n Width = 0,\n Height = 1,\n}\n\nexport enum Direction {\n Inherit = 0,\n LTR = 1,\n RTL = 2,\n}\n\nexport enum Display {\n Flex = 0,\n None = 1,\n Contents = 2,\n}\n\nexport enum Edge {\n Left = 0,\n Top = 1,\n Right = 2,\n Bottom = 3,\n Start = 4,\n End = 5,\n Horizontal = 6,\n Vertical = 7,\n All = 8,\n}\n\nexport enum Errata {\n None = 0,\n StretchFlexBasis = 1,\n AbsolutePositionWithoutInsetsExcludesPadding = 2,\n AbsolutePercentAgainstInnerSize = 4,\n All = 2147483647,\n Classic = 2147483646,\n}\n\nexport enum ExperimentalFeature {\n WebFlexBasis = 0,\n}\n\nexport enum FlexDirection {\n Column = 0,\n ColumnReverse = 1,\n Row = 2,\n RowReverse = 3,\n}\n\nexport enum Gutter {\n Column = 0,\n Row = 1,\n All = 2,\n}\n\nexport enum Justify {\n FlexStart = 0,\n Center = 1,\n FlexEnd = 2,\n SpaceBetween = 3,\n SpaceAround = 4,\n SpaceEvenly = 5,\n}\n\nexport enum LogLevel {\n Error = 0,\n Warn = 1,\n Info = 2,\n Debug = 3,\n Verbose = 4,\n Fatal = 5,\n}\n\nexport enum MeasureMode {\n Undefined = 0,\n Exactly = 1,\n AtMost = 2,\n}\n\nexport enum NodeType {\n Default = 0,\n Text = 1,\n}\n\nexport enum Overflow {\n Visible = 0,\n Hidden = 1,\n Scroll = 2,\n}\n\nexport enum PositionType {\n Static = 0,\n Relative = 1,\n Absolute = 2,\n}\n\nexport enum Unit {\n Undefined = 0,\n Point = 1,\n Percent = 2,\n Auto = 3,\n}\n\nexport enum Wrap {\n NoWrap = 0,\n Wrap = 1,\n WrapReverse = 2,\n}\n\nexport const ALIGN_AUTO = Align.Auto\nexport const ALIGN_FLEX_START = Align.FlexStart\nexport const ALIGN_CENTER = Align.Center\nexport const ALIGN_FLEX_END = Align.FlexEnd\nexport const ALIGN_STRETCH = Align.Stretch\nexport const ALIGN_BASELINE = Align.Baseline\nexport const ALIGN_SPACE_BETWEEN = Align.SpaceBetween\nexport const ALIGN_SPACE_AROUND = Align.SpaceAround\nexport const ALIGN_SPACE_EVENLY = Align.SpaceEvenly\n\nexport const BOX_SIZING_BORDER_BOX = BoxSizing.BorderBox\nexport const BOX_SIZING_CONTENT_BOX = BoxSizing.ContentBox\n\nexport const DIMENSION_WIDTH = Dimension.Width\nexport const DIMENSION_HEIGHT = Dimension.Height\n\nexport const DIRECTION_INHERIT = Direction.Inherit\nexport const DIRECTION_LTR = Direction.LTR\nexport const DIRECTION_RTL = Direction.RTL\n\nexport const DISPLAY_FLEX = Display.Flex\nexport const DISPLAY_NONE = Display.None\nexport const DISPLAY_CONTENTS = Display.Contents\n\nexport const EDGE_LEFT = Edge.Left\nexport const EDGE_TOP = Edge.Top\nexport const EDGE_RIGHT = Edge.Right\nexport const EDGE_BOTTOM = Edge.Bottom\nexport const EDGE_START = Edge.Start\nexport const EDGE_END = Edge.End\nexport const EDGE_HORIZONTAL = Edge.Horizontal\nexport const EDGE_VERTICAL = Edge.Vertical\nexport const EDGE_ALL = Edge.All\n\nexport const ERRATA_NONE = Errata.None\nexport const ERRATA_STRETCH_FLEX_BASIS = Errata.StretchFlexBasis\nexport const ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING =\n Errata.AbsolutePositionWithoutInsetsExcludesPadding\nexport const ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE = Errata.AbsolutePercentAgainstInnerSize\nexport const ERRATA_ALL = Errata.All\nexport const ERRATA_CLASSIC = Errata.Classic\n\nexport const EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS = ExperimentalFeature.WebFlexBasis\n\nexport const FLEX_DIRECTION_COLUMN = FlexDirection.Column\nexport const FLEX_DIRECTION_COLUMN_REVERSE = FlexDirection.ColumnReverse\nexport const FLEX_DIRECTION_ROW = FlexDirection.Row\nexport const FLEX_DIRECTION_ROW_REVERSE = FlexDirection.RowReverse\n\nexport const GUTTER_COLUMN = Gutter.Column\nexport const GUTTER_ROW = Gutter.Row\nexport const GUTTER_ALL = Gutter.All\n\nexport const JUSTIFY_FLEX_START = Justify.FlexStart\nexport const JUSTIFY_CENTER = Justify.Center\nexport const JUSTIFY_FLEX_END = Justify.FlexEnd\nexport const JUSTIFY_SPACE_BETWEEN = Justify.SpaceBetween\nexport const JUSTIFY_SPACE_AROUND = Justify.SpaceAround\nexport const JUSTIFY_SPACE_EVENLY = Justify.SpaceEvenly\n\nexport const LOG_LEVEL_ERROR = LogLevel.Error\nexport const LOG_LEVEL_WARN = LogLevel.Warn\nexport const LOG_LEVEL_INFO = LogLevel.Info\nexport const LOG_LEVEL_DEBUG = LogLevel.Debug\nexport const LOG_LEVEL_VERBOSE = LogLevel.Verbose\nexport const LOG_LEVEL_FATAL = LogLevel.Fatal\n\nexport const MEASURE_MODE_UNDEFINED = MeasureMode.Undefined\nexport const MEASURE_MODE_EXACTLY = MeasureMode.Exactly\nexport const MEASURE_MODE_AT_MOST = MeasureMode.AtMost\n\nexport const NODE_TYPE_DEFAULT = NodeType.Default\nexport const NODE_TYPE_TEXT = NodeType.Text\n\nexport const OVERFLOW_VISIBLE = Overflow.Visible\nexport const OVERFLOW_HIDDEN = Overflow.Hidden\nexport const OVERFLOW_SCROLL = Overflow.Scroll\n\nexport const POSITION_TYPE_STATIC = PositionType.Static\nexport const POSITION_TYPE_RELATIVE = PositionType.Relative\nexport const POSITION_TYPE_ABSOLUTE = PositionType.Absolute\n\nexport const UNIT_UNDEFINED = Unit.Undefined\nexport const UNIT_POINT = Unit.Point\nexport const UNIT_PERCENT = Unit.Percent\nexport const UNIT_AUTO = Unit.Auto\n\nexport const WRAP_NO_WRAP = Wrap.NoWrap\nexport const WRAP_WRAP = Wrap.Wrap\nexport const WRAP_WRAP_REVERSE = Wrap.WrapReverse\n\nexport interface Layout {\n left: number\n right: number\n top: number\n bottom: number\n width: number\n height: number\n}\n\nexport interface Size {\n width: number\n height: number\n}\n\nexport interface Value {\n unit: Unit\n value: number\n}\n\nexport type MeasureFunction = (width: number, widthMode: MeasureMode, height: number, heightMode: MeasureMode) => Size\nexport type DirtiedFunction = (node: Node) => void\n\ntype ValueInput = number | \"auto\" | `${number}%` | Value | undefined\ntype ValueInputNoAuto = number | `${number}%` | Value | undefined\n\nconst YogaEnumKind = {\n Direction: 0,\n FlexDirection: 1,\n JustifyContent: 2,\n AlignContent: 3,\n AlignItems: 4,\n AlignSelf: 5,\n PositionType: 6,\n FlexWrap: 7,\n Overflow: 8,\n Display: 9,\n BoxSizing: 10,\n} as const\n\nconst YogaFloatKind = {\n Flex: 0,\n FlexGrow: 1,\n FlexShrink: 2,\n AspectRatio: 3,\n} as const\n\nconst YogaValueKind = {\n Width: 0,\n Height: 1,\n MinWidth: 2,\n MinHeight: 3,\n MaxWidth: 4,\n MaxHeight: 5,\n FlexBasis: 6,\n Margin: 7,\n Padding: 8,\n Position: 9,\n Gap: 10,\n} as const\n\nconst YogaEdgeLayoutKind = {\n Margin: 0,\n Padding: 1,\n Border: 2,\n} as const\n\nconst UNDEFINED_VALUE: Value = { unit: Unit.Undefined, value: NaN }\n\nconst nodeRegistry = new Map()\n\nfunction lib(): RenderLib {\n return resolveRenderLib()\n}\n\nfunction pointerKey(pointer: Pointer): string {\n return String(pointer)\n}\n\nfunction isValueObject(value: unknown): value is Value {\n return typeof value === \"object\" && value !== null && \"unit\" in value && \"value\" in value\n}\n\nfunction parseValue(value: ValueInput): Value {\n if (isValueObject(value)) {\n return value\n }\n if (value === undefined) {\n return UNDEFINED_VALUE\n }\n if (value === \"auto\") {\n return { unit: Unit.Auto, value: NaN }\n }\n if (typeof value === \"string\") {\n if (!value.endsWith(\"%\")) {\n throw new Error(`Invalid Yoga value: ${value}`)\n }\n const numberValue = Number.parseFloat(value)\n if (Number.isNaN(numberValue)) {\n throw new Error(`Invalid Yoga percentage value: ${value}`)\n }\n return { unit: Unit.Percent, value: numberValue }\n }\n return { unit: Unit.Point, value }\n}\n\nfunction unpackValue(packedValue: number | bigint): Value {\n const packed = typeof packedValue === \"bigint\" ? packedValue : BigInt(packedValue)\n const unit = Number(packed & 0xffffffffn) as Unit\n const valueBits = Number((packed >> 32n) & 0xffffffffn)\n const buffer = new ArrayBuffer(4)\n const view = new DataView(buffer)\n view.setUint32(0, valueBits, true)\n return { unit, value: view.getFloat32(0, true) }\n}\n\nfunction normalizeLayoutInput(value: number | \"auto\" | undefined): number {\n return value === undefined || value === \"auto\" ? NaN : value\n}\n\nexport class Config {\n readonly ptr: Pointer\n private freed = false\n\n private constructor(ptr: Pointer) {\n this.ptr = ptr\n }\n\n static create(): Config {\n return new Config(lib().yogaConfigCreate())\n }\n\n static destroy(config: Config): void {\n config.free()\n }\n\n free(): void {\n if (this.freed) return\n this.freed = true\n lib().yogaConfigFree(this.ptr)\n }\n\n setUseWebDefaults(useWebDefaults: boolean): void {\n if (this.freed) return\n lib().yogaConfigSetUseWebDefaults(this.ptr, useWebDefaults)\n }\n\n useWebDefaults(): boolean {\n if (this.freed) return false\n return lib().yogaConfigGetUseWebDefaults(this.ptr)\n }\n\n setPointScaleFactor(pointScaleFactor: number): void {\n if (this.freed) return\n lib().yogaConfigSetPointScaleFactor(this.ptr, pointScaleFactor)\n }\n\n getPointScaleFactor(): number {\n if (this.freed) return 0\n return lib().yogaConfigGetPointScaleFactor(this.ptr)\n }\n\n setErrata(errata: Errata): void {\n if (this.freed) return\n lib().yogaConfigSetErrata(this.ptr, errata)\n }\n\n getErrata(): Errata {\n if (this.freed) return Errata.None\n return lib().yogaConfigGetErrata(this.ptr) as Errata\n }\n\n setExperimentalFeatureEnabled(feature: ExperimentalFeature, enabled: boolean): void {\n if (this.freed) return\n lib().yogaConfigSetExperimentalFeatureEnabled(this.ptr, feature, enabled)\n }\n\n isExperimentalFeatureEnabled(feature: ExperimentalFeature): boolean {\n if (this.freed) return false\n return lib().yogaConfigIsExperimentalFeatureEnabled(this.ptr, feature)\n }\n}\n\nexport class Node {\n readonly ptr: Pointer\n private freed = false\n private measureCallback: FFICallbackInstance | null = null\n private dirtiedCallback: FFICallbackInstance | null = null\n\n private constructor(ptr: Pointer) {\n this.ptr = ptr\n nodeRegistry.set(pointerKey(ptr), this)\n }\n\n static create(config?: Config): Node {\n return Node.fromPointer(config ? lib().yogaNodeCreateWithConfig(config.ptr) : lib().yogaNodeCreate())\n }\n\n static createForOpenTUI(): Node {\n return Node.fromPointer(lib().yogaNodeCreateForOpenTUI())\n }\n\n static createDefault(): Node {\n return Node.create()\n }\n\n static createWithConfig(config: Config): Node {\n return Node.create(config)\n }\n\n static destroy(node: Node): void {\n node.free()\n }\n\n private static fromPointer(ptr: Pointer): Node {\n const key = pointerKey(ptr)\n const existing = nodeRegistry.get(key)\n if (existing) return existing\n return new Node(ptr)\n }\n\n isFreed(): boolean {\n return this.freed\n }\n\n free(): void {\n if (this.freed) return\n this.unsetMeasureFunc()\n this.unsetDirtiedFunc()\n lib().yogaNodeFree(this.ptr)\n this.markFreed()\n }\n\n freeRecursive(): void {\n if (this.freed) return\n const nodes = this.collectSubtree([])\n for (const node of nodes) {\n node.closeMeasureCallback()\n node.closeDirtiedCallback()\n }\n lib().yogaNodeFreeRecursive(this.ptr)\n for (const node of nodes) {\n node.markFreed()\n }\n }\n\n reset(): void {\n if (this.freed) return\n this.unsetMeasureFunc()\n this.unsetDirtiedFunc()\n lib().yogaNodeReset(this.ptr)\n }\n\n copyStyle(node: Node): void {\n if (this.freed) return\n lib().yogaNodeCopyStyle(this.ptr, node.ptr)\n }\n\n insertChild(child: Node, index: number): void {\n if (this.freed) return\n lib().yogaNodeInsertChild(this.ptr, child.ptr, index)\n }\n\n removeChild(child: Node): void {\n if (this.freed) return\n lib().yogaNodeRemoveChild(this.ptr, child.ptr)\n }\n\n removeAllChildren(): void {\n if (this.freed) return\n lib().yogaNodeRemoveAllChildren(this.ptr)\n }\n\n getChild(index: number): Node | null {\n if (this.freed) return null\n const child = lib().yogaNodeGetChild(this.ptr, index)\n return child ? Node.fromPointer(child) : null\n }\n\n getChildCount(): number {\n if (this.freed) return 0\n return lib().yogaNodeGetChildCount(this.ptr)\n }\n\n getParent(): Node | null {\n if (this.freed) return null\n const parent = lib().yogaNodeGetParent(this.ptr)\n return parent ? Node.fromPointer(parent) : null\n }\n\n calculateLayout(width?: number | \"auto\", height?: number | \"auto\", direction: Direction = Direction.LTR): void {\n if (this.freed) return\n lib().yogaNodeCalculateLayout(this.ptr, normalizeLayoutInput(width), normalizeLayoutInput(height), direction)\n }\n\n hasNewLayout(): boolean {\n if (this.freed) return false\n return lib().yogaNodeGetHasNewLayout(this.ptr)\n }\n\n markLayoutSeen(): void {\n if (this.freed) return\n lib().yogaNodeSetHasNewLayout(this.ptr, false)\n }\n\n markDirty(): void {\n if (this.freed) return\n lib().yogaNodeMarkDirty(this.ptr)\n }\n\n isDirty(): boolean {\n if (this.freed) return true\n return lib().yogaNodeIsDirty(this.ptr)\n }\n\n getComputedLayout(): Layout {\n if (this.freed) return { left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0 }\n return lib().yogaNodeGetComputedLayout(this.ptr)\n }\n\n getComputedLeft(): number {\n return this.getComputedLayout().left\n }\n\n getComputedTop(): number {\n return this.getComputedLayout().top\n }\n\n getComputedRight(): number {\n return this.getComputedLayout().right\n }\n\n getComputedBottom(): number {\n return this.getComputedLayout().bottom\n }\n\n getComputedWidth(): number {\n return this.getComputedLayout().width\n }\n\n getComputedHeight(): number {\n return this.getComputedLayout().height\n }\n\n getComputedMargin(edge: Edge): number {\n if (this.freed) return 0\n return lib().yogaNodeLayoutGetEdge(this.ptr, YogaEdgeLayoutKind.Margin, edge)\n }\n\n getComputedPadding(edge: Edge): number {\n if (this.freed) return 0\n return lib().yogaNodeLayoutGetEdge(this.ptr, YogaEdgeLayoutKind.Padding, edge)\n }\n\n getComputedBorder(edge: Edge): number {\n if (this.freed) return 0\n return lib().yogaNodeLayoutGetEdge(this.ptr, YogaEdgeLayoutKind.Border, edge)\n }\n\n setDirection(direction: Direction): void {\n this.setEnum(YogaEnumKind.Direction, direction)\n }\n\n getDirection(): Direction {\n return this.getEnum(YogaEnumKind.Direction, Direction.Inherit) as Direction\n }\n\n setFlexDirection(flexDirection: FlexDirection): void {\n this.setEnum(YogaEnumKind.FlexDirection, flexDirection)\n }\n\n getFlexDirection(): FlexDirection {\n return this.getEnum(YogaEnumKind.FlexDirection, FlexDirection.Column) as FlexDirection\n }\n\n setJustifyContent(justifyContent: Justify): void {\n this.setEnum(YogaEnumKind.JustifyContent, justifyContent)\n }\n\n getJustifyContent(): Justify {\n return this.getEnum(YogaEnumKind.JustifyContent, Justify.FlexStart) as Justify\n }\n\n setAlignContent(alignContent: Align): void {\n this.setEnum(YogaEnumKind.AlignContent, alignContent)\n }\n\n getAlignContent(): Align {\n return this.getEnum(YogaEnumKind.AlignContent, Align.FlexStart) as Align\n }\n\n setAlignItems(alignItems: Align): void {\n this.setEnum(YogaEnumKind.AlignItems, alignItems)\n }\n\n getAlignItems(): Align {\n return this.getEnum(YogaEnumKind.AlignItems, Align.Stretch) as Align\n }\n\n setAlignSelf(alignSelf: Align): void {\n this.setEnum(YogaEnumKind.AlignSelf, alignSelf)\n }\n\n getAlignSelf(): Align {\n return this.getEnum(YogaEnumKind.AlignSelf, Align.Auto) as Align\n }\n\n setPositionType(positionType: PositionType): void {\n this.setEnum(YogaEnumKind.PositionType, positionType)\n }\n\n getPositionType(): PositionType {\n return this.getEnum(YogaEnumKind.PositionType, PositionType.Relative) as PositionType\n }\n\n setFlexWrap(flexWrap: Wrap): void {\n this.setEnum(YogaEnumKind.FlexWrap, flexWrap)\n }\n\n getFlexWrap(): Wrap {\n return this.getEnum(YogaEnumKind.FlexWrap, Wrap.NoWrap) as Wrap\n }\n\n setOverflow(overflow: Overflow): void {\n this.setEnum(YogaEnumKind.Overflow, overflow)\n }\n\n getOverflow(): Overflow {\n return this.getEnum(YogaEnumKind.Overflow, Overflow.Visible) as Overflow\n }\n\n setDisplay(display: Display): void {\n this.setEnum(YogaEnumKind.Display, display)\n }\n\n getDisplay(): Display {\n return this.getEnum(YogaEnumKind.Display, Display.Flex) as Display\n }\n\n setBoxSizing(boxSizing: BoxSizing): void {\n this.setEnum(YogaEnumKind.BoxSizing, boxSizing)\n }\n\n getBoxSizing(): BoxSizing {\n return this.getEnum(YogaEnumKind.BoxSizing, BoxSizing.BorderBox) as BoxSizing\n }\n\n setFlex(flex: number | undefined): void {\n this.setFloat(YogaFloatKind.Flex, flex)\n }\n\n getFlex(): number {\n return this.getFloat(YogaFloatKind.Flex)\n }\n\n setFlexGrow(flexGrow: number | undefined): void {\n this.setFloat(YogaFloatKind.FlexGrow, flexGrow)\n }\n\n getFlexGrow(): number {\n return this.getFloat(YogaFloatKind.FlexGrow)\n }\n\n setFlexShrink(flexShrink: number | undefined): void {\n this.setFloat(YogaFloatKind.FlexShrink, flexShrink)\n }\n\n getFlexShrink(): number {\n return this.getFloat(YogaFloatKind.FlexShrink)\n }\n\n setAspectRatio(aspectRatio: number | undefined): void {\n this.setFloat(YogaFloatKind.AspectRatio, aspectRatio)\n }\n\n getAspectRatio(): number {\n return this.getFloat(YogaFloatKind.AspectRatio)\n }\n\n setFlexBasis(flexBasis: ValueInput): void {\n this.setValue(YogaValueKind.FlexBasis, 0, flexBasis)\n }\n\n setFlexBasisPercent(flexBasis: number | undefined): void {\n this.setValue(\n YogaValueKind.FlexBasis,\n 0,\n flexBasis === undefined ? undefined : { unit: Unit.Percent, value: flexBasis },\n )\n }\n\n setFlexBasisAuto(): void {\n this.setValue(YogaValueKind.FlexBasis, 0, \"auto\")\n }\n\n getFlexBasis(): Value {\n return this.getValue(YogaValueKind.FlexBasis, 0)\n }\n\n setWidth(width: ValueInput): void {\n this.setValue(YogaValueKind.Width, 0, width)\n }\n\n setWidthPercent(width: number | undefined): void {\n this.setValue(YogaValueKind.Width, 0, width === undefined ? undefined : { unit: Unit.Percent, value: width })\n }\n\n setWidthAuto(): void {\n this.setValue(YogaValueKind.Width, 0, \"auto\")\n }\n\n getWidth(): Value {\n return this.getValue(YogaValueKind.Width, 0)\n }\n\n setHeight(height: ValueInput): void {\n this.setValue(YogaValueKind.Height, 0, height)\n }\n\n setHeightPercent(height: number | undefined): void {\n this.setValue(YogaValueKind.Height, 0, height === undefined ? undefined : { unit: Unit.Percent, value: height })\n }\n\n setHeightAuto(): void {\n this.setValue(YogaValueKind.Height, 0, \"auto\")\n }\n\n getHeight(): Value {\n return this.getValue(YogaValueKind.Height, 0)\n }\n\n setMinWidth(minWidth: ValueInputNoAuto): void {\n this.setValue(YogaValueKind.MinWidth, 0, minWidth)\n }\n\n setMinWidthPercent(minWidth: number | undefined): void {\n this.setValue(\n YogaValueKind.MinWidth,\n 0,\n minWidth === undefined ? undefined : { unit: Unit.Percent, value: minWidth },\n )\n }\n\n getMinWidth(): Value {\n return this.getValue(YogaValueKind.MinWidth, 0)\n }\n\n setMinHeight(minHeight: ValueInputNoAuto): void {\n this.setValue(YogaValueKind.MinHeight, 0, minHeight)\n }\n\n setMinHeightPercent(minHeight: number | undefined): void {\n this.setValue(\n YogaValueKind.MinHeight,\n 0,\n minHeight === undefined ? undefined : { unit: Unit.Percent, value: minHeight },\n )\n }\n\n getMinHeight(): Value {\n return this.getValue(YogaValueKind.MinHeight, 0)\n }\n\n setMaxWidth(maxWidth: ValueInputNoAuto): void {\n this.setValue(YogaValueKind.MaxWidth, 0, maxWidth)\n }\n\n setMaxWidthPercent(maxWidth: number | undefined): void {\n this.setValue(\n YogaValueKind.MaxWidth,\n 0,\n maxWidth === undefined ? undefined : { unit: Unit.Percent, value: maxWidth },\n )\n }\n\n getMaxWidth(): Value {\n return this.getValue(YogaValueKind.MaxWidth, 0)\n }\n\n setMaxHeight(maxHeight: ValueInputNoAuto): void {\n this.setValue(YogaValueKind.MaxHeight, 0, maxHeight)\n }\n\n setMaxHeightPercent(maxHeight: number | undefined): void {\n this.setValue(\n YogaValueKind.MaxHeight,\n 0,\n maxHeight === undefined ? undefined : { unit: Unit.Percent, value: maxHeight },\n )\n }\n\n getMaxHeight(): Value {\n return this.getValue(YogaValueKind.MaxHeight, 0)\n }\n\n setMargin(edge: Edge, margin: ValueInput): void {\n this.setValue(YogaValueKind.Margin, edge, margin)\n }\n\n setMarginPercent(edge: Edge, margin: number | undefined): void {\n this.setValue(YogaValueKind.Margin, edge, margin === undefined ? undefined : { unit: Unit.Percent, value: margin })\n }\n\n setMarginAuto(edge: Edge): void {\n this.setValue(YogaValueKind.Margin, edge, \"auto\")\n }\n\n getMargin(edge: Edge): Value {\n return this.getValue(YogaValueKind.Margin, edge)\n }\n\n setPadding(edge: Edge, padding: ValueInputNoAuto): void {\n this.setValue(YogaValueKind.Padding, edge, padding)\n }\n\n setPaddingPercent(edge: Edge, padding: number | undefined): void {\n this.setValue(\n YogaValueKind.Padding,\n edge,\n padding === undefined ? undefined : { unit: Unit.Percent, value: padding },\n )\n }\n\n getPadding(edge: Edge): Value {\n return this.getValue(YogaValueKind.Padding, edge)\n }\n\n setPosition(edge: Edge, position: ValueInput): void {\n this.setValue(YogaValueKind.Position, edge, position)\n }\n\n setPositionPercent(edge: Edge, position: number | undefined): void {\n this.setValue(\n YogaValueKind.Position,\n edge,\n position === undefined ? undefined : { unit: Unit.Percent, value: position },\n )\n }\n\n setPositionAuto(edge: Edge): void {\n this.setValue(YogaValueKind.Position, edge, \"auto\")\n }\n\n getPosition(edge: Edge): Value {\n return this.getValue(YogaValueKind.Position, edge)\n }\n\n setGap(gutter: Gutter, gap: ValueInputNoAuto): void {\n this.setValue(YogaValueKind.Gap, gutter, gap)\n }\n\n setGapPercent(gutter: Gutter, gap: number | undefined): void {\n this.setValue(YogaValueKind.Gap, gutter, gap === undefined ? undefined : { unit: Unit.Percent, value: gap })\n }\n\n getGap(gutter: Gutter): Value {\n return this.getValue(YogaValueKind.Gap, gutter)\n }\n\n setBorder(edge: Edge, border: number | undefined): void {\n if (this.freed) return\n lib().yogaNodeStyleSetBorder(this.ptr, edge, border ?? NaN)\n }\n\n getBorder(edge: Edge): number {\n if (this.freed) return NaN\n return lib().yogaNodeStyleGetBorder(this.ptr, edge)\n }\n\n setIsReferenceBaseline(isReferenceBaseline: boolean): void {\n if (this.freed) return\n lib().yogaNodeSetIsReferenceBaseline(this.ptr, isReferenceBaseline)\n }\n\n isReferenceBaseline(): boolean {\n if (this.freed) return false\n return lib().yogaNodeIsReferenceBaseline(this.ptr)\n }\n\n setAlwaysFormsContainingBlock(alwaysFormsContainingBlock: boolean): void {\n if (this.freed) return\n lib().yogaNodeSetAlwaysFormsContainingBlock(this.ptr, alwaysFormsContainingBlock)\n }\n\n getAlwaysFormsContainingBlock(): boolean {\n if (this.freed) return false\n return lib().yogaNodeGetAlwaysFormsContainingBlock(this.ptr)\n }\n\n setMeasureFunc(measureFunc: MeasureFunction | null): void {\n if (this.freed) return\n this.unsetMeasureFunc()\n\n if (!measureFunc) return\n\n const callback: NativeYogaMeasureCallback = (_node, width, widthMode, height, heightMode) => {\n const result = measureFunc(width, widthMode as MeasureMode, height, heightMode as MeasureMode)\n lib().yogaStoreMeasureResult(result.width ?? NaN, result.height ?? NaN)\n }\n\n this.measureCallback = lib().createYogaMeasureCallback(callback)\n if (!this.measureCallback.ptr) {\n this.measureCallback.close()\n this.measureCallback = null\n throw new Error(\"Failed to create Yoga measure callback\")\n }\n\n lib().yogaNodeSetMeasureFunc(this.ptr, this.measureCallback.ptr)\n }\n\n unsetMeasureFunc(): void {\n if (this.freed) return\n lib().yogaNodeUnsetMeasureFunc(this.ptr)\n this.closeMeasureCallback()\n }\n\n hasMeasureFunc(): boolean {\n if (this.freed) return false\n return lib().yogaNodeHasMeasureFunc(this.ptr)\n }\n\n setDirtiedFunc(dirtiedFunc: DirtiedFunction | null): void {\n if (this.freed) return\n this.unsetDirtiedFunc()\n\n if (!dirtiedFunc) return\n\n const callback: NativeYogaDirtiedCallback = () => {\n dirtiedFunc(this)\n }\n\n this.dirtiedCallback = lib().createYogaDirtiedCallback(callback)\n if (!this.dirtiedCallback.ptr) {\n this.dirtiedCallback.close()\n this.dirtiedCallback = null\n throw new Error(\"Failed to create Yoga dirtied callback\")\n }\n\n lib().yogaNodeSetDirtiedFunc(this.ptr, this.dirtiedCallback.ptr)\n }\n\n unsetDirtiedFunc(): void {\n if (this.freed) return\n lib().yogaNodeUnsetDirtiedFunc(this.ptr)\n this.closeDirtiedCallback()\n }\n\n private setEnum(kind: number, value: number): void {\n if (this.freed) return\n lib().yogaNodeStyleSetEnum(this.ptr, kind, value)\n }\n\n private getEnum(kind: number, fallback: number): number {\n if (this.freed) return fallback\n return lib().yogaNodeStyleGetEnum(this.ptr, kind)\n }\n\n private setFloat(kind: number, value: number | undefined): void {\n if (this.freed) return\n lib().yogaNodeStyleSetFloat(this.ptr, kind, value ?? NaN)\n }\n\n private getFloat(kind: number): number {\n if (this.freed) return NaN\n return lib().yogaNodeStyleGetFloat(this.ptr, kind)\n }\n\n private setValue(kind: number, edgeOrGutter: number, valueInput: ValueInput): void {\n if (this.freed) return\n const value = parseValue(valueInput)\n lib().yogaNodeStyleSetValue(this.ptr, kind, edgeOrGutter, value.unit, value.value)\n }\n\n private getValue(kind: number, edgeOrGutter: number): Value {\n if (this.freed) return UNDEFINED_VALUE\n return unpackValue(lib().yogaNodeStyleGetValue(this.ptr, kind, edgeOrGutter))\n }\n\n private collectSubtree(nodes: Node[]): Node[] {\n for (let index = 0; index < this.getChildCount(); index++) {\n this.getChild(index)?.collectSubtree(nodes)\n }\n nodes.push(this)\n return nodes\n }\n\n private closeMeasureCallback(): void {\n if (!this.measureCallback) return\n this.measureCallback.close()\n this.measureCallback = null\n }\n\n private closeDirtiedCallback(): void {\n if (!this.dirtiedCallback) return\n this.dirtiedCallback.close()\n this.dirtiedCallback = null\n }\n\n private markFreed(): void {\n this.freed = true\n nodeRegistry.delete(pointerKey(this.ptr))\n }\n}\n\nconst Yoga = {\n Config,\n Node,\n Align,\n BoxSizing,\n Dimension,\n Direction,\n Display,\n Edge,\n Errata,\n ExperimentalFeature,\n FlexDirection,\n Gutter,\n Justify,\n LogLevel,\n MeasureMode,\n NodeType,\n Overflow,\n PositionType,\n Unit,\n Wrap,\n ALIGN_AUTO,\n ALIGN_FLEX_START,\n ALIGN_CENTER,\n ALIGN_FLEX_END,\n ALIGN_STRETCH,\n ALIGN_BASELINE,\n ALIGN_SPACE_BETWEEN,\n ALIGN_SPACE_AROUND,\n ALIGN_SPACE_EVENLY,\n BOX_SIZING_BORDER_BOX,\n BOX_SIZING_CONTENT_BOX,\n DIMENSION_WIDTH,\n DIMENSION_HEIGHT,\n DIRECTION_INHERIT,\n DIRECTION_LTR,\n DIRECTION_RTL,\n DISPLAY_FLEX,\n DISPLAY_NONE,\n DISPLAY_CONTENTS,\n EDGE_LEFT,\n EDGE_TOP,\n EDGE_RIGHT,\n EDGE_BOTTOM,\n EDGE_START,\n EDGE_END,\n EDGE_HORIZONTAL,\n EDGE_VERTICAL,\n EDGE_ALL,\n ERRATA_NONE,\n ERRATA_STRETCH_FLEX_BASIS,\n ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING,\n ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE,\n ERRATA_ALL,\n ERRATA_CLASSIC,\n EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS,\n FLEX_DIRECTION_COLUMN,\n FLEX_DIRECTION_COLUMN_REVERSE,\n FLEX_DIRECTION_ROW,\n FLEX_DIRECTION_ROW_REVERSE,\n GUTTER_COLUMN,\n GUTTER_ROW,\n GUTTER_ALL,\n JUSTIFY_FLEX_START,\n JUSTIFY_CENTER,\n JUSTIFY_FLEX_END,\n JUSTIFY_SPACE_BETWEEN,\n JUSTIFY_SPACE_AROUND,\n JUSTIFY_SPACE_EVENLY,\n LOG_LEVEL_ERROR,\n LOG_LEVEL_WARN,\n LOG_LEVEL_INFO,\n LOG_LEVEL_DEBUG,\n LOG_LEVEL_VERBOSE,\n LOG_LEVEL_FATAL,\n MEASURE_MODE_UNDEFINED,\n MEASURE_MODE_EXACTLY,\n MEASURE_MODE_AT_MOST,\n NODE_TYPE_DEFAULT,\n NODE_TYPE_TEXT,\n OVERFLOW_VISIBLE,\n OVERFLOW_HIDDEN,\n OVERFLOW_SCROLL,\n POSITION_TYPE_STATIC,\n POSITION_TYPE_RELATIVE,\n POSITION_TYPE_ABSOLUTE,\n UNIT_UNDEFINED,\n UNIT_POINT,\n UNIT_PERCENT,\n UNIT_AUTO,\n WRAP_NO_WRAP,\n WRAP_WRAP,\n WRAP_WRAP_REVERSE,\n}\n\nexport default Yoga\n" + ], + "mappings": "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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EAGP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EAGP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EAGP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP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", + "debugId": "DCFFDFC39A69C1FE64756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/.patches/@opentui/core/index.d.ts b/.patches/@opentui/core/index.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/index.d.ts @@ -0,0 +1,24 @@ +export * from "./Renderable.js"; +export * from "./types.js"; +export * from "./utils.js"; +export * from "./buffer.js"; +export * from "./text-buffer.js"; +export * from "./text-buffer-view.js"; +export * from "./edit-buffer.js"; +export * from "./editor-view.js"; +export * from "./syntax-style.js"; +export * from "./post/effects.js"; +export * from "./post/filters.js"; +export * from "./post/matrices.js"; +export * from "./animation/Timeline.js"; +export * from "./lib/index.js"; +export * from "./renderer.js"; +export * from "./plugins/types.js"; +export * from "./plugins/registry.js"; +export * from "./plugins/core-slot.js"; +export * from "./NativeSpanFeed.js"; +export * from "./audio.js"; +export * from "./renderables/index.js"; +export * from "./zig.js"; +export * from "./console.js"; +export * as Yoga from "./yoga.js"; diff --git a/.patches/@opentui/core/index.js b/.patches/@opentui/core/index.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/index.js @@ -0,0 +1,11680 @@ +import { + BaseRenderable, + BoxRenderable, + CliRenderEvents, + CliRenderer, + CodeRenderable, + ConsolePosition, + EditBuffer, + EditBufferRenderable, + EditBufferRenderableEvents, + EditorView, + LayoutEvents, + MouseButton, + MouseEvent, + NativeSpanFeed, + Renderable, + RenderableEvents, + RendererControlState, + RootRenderable, + RootTextNodeRenderable, + SyntaxStyle, + TerminalConsole, + TextBufferRenderable, + TextBufferView, + TextNodeRenderable, + TextRenderable, + buildKeyBindingsMap, + buildKittyKeyboardFlags, + capture, + convertThemeToStyles, + createCliRenderer, + defaultKeyAliases, + delegate, + getKeyBindingAction, + getObjectsInViewport, + h, + instantiate, + isEditBufferRenderable, + isRenderable, + isTextNodeRenderable, + isVNode, + maybeMakeRenderable, + mergeKeyAliases, + mergeKeyBindings, + wrapWithDelegates +} from "./index-07zpr2dg.js"; +import { + ASCIIFontSelectionHelper, + ATTRIBUTE_BASE_BITS, + ATTRIBUTE_BASE_MASK, + BorderCharArrays, + BorderChars, + DEFAULT_BACKGROUND_RGB, + DEFAULT_FOREGROUND_RGB, + DataPathsManager, + DebugOverlayCorner, + ExtmarksController, + InternalKeyHandler, + KeyEvent, + KeyHandler, + LinearScrollAccel, + LogLevel, + MacOSScrollAccel, + MouseParser, + OptimizedBuffer, + PasteEvent, + RGBA, + Selection, + StdinParser, + StyledText, + SystemClock, + TargetChannel, + TerminalPalette, + TextAttributes, + TextBuffer, + TreeSitterClient, + addDefaultParsers, + ansi256IndexToRgb, + attributesWithLink, + basenameToFiletype, + bg, + bgBlack, + bgBlue, + bgCyan, + bgGreen, + bgMagenta, + bgRed, + bgWhite, + bgYellow, + black, + blink, + blue, + bold, + borderCharsToArray, + brightBlack, + brightBlue, + brightCyan, + brightGreen, + brightMagenta, + brightRed, + brightWhite, + brightYellow, + buildTerminalPaletteSignature, + clearEnvCache, + convertGlobalToLocalSelection, + coordinateToCharacterIndex, + createExtmarksController, + createTerminalPalette, + createTextAttributes, + cyan, + decodePasteBytes, + destroyTreeSitterClient, + detectLinks, + dim, + env, + envRegistry, + exports_yoga, + extToFiletype, + extensionToFiletype, + fg, + fonts, + generateEnvColored, + generateEnvMarkdown, + getBaseAttributes, + getBorderFromSides, + getBorderSides, + getCharacterPositions, + getDataPaths, + getLinkId, + getTreeSitterClient, + green, + hastToStyledText, + hexToRgb, + hsvToRgb, + infoStringToFiletype, + isStyledText, + isValidBorderStyle, + italic, + link, + magenta, + measureText, + nonAlphanumericKeys, + normalizeColorValue, + normalizeIndexedColorIndex, + normalizeTerminalPalette, + parseAlign, + parseAlignItems, + parseBorderStyle, + parseBoxSizing, + parseColor, + parseDimension, + parseDirection, + parseDisplay, + parseEdge, + parseFlexDirection, + parseGutter, + parseJustify, + parseKeypress, + parseLogLevel, + parseMeasureMode, + parseOverflow, + parsePositionType, + parseUnit, + parseWrap, + pathToFiletype, + red, + registerEnvVar, + renderFontToFrameBuffer, + resolveRenderLib, + reverse, + rgbToHex, + setRenderLibPath, + strikethrough, + stringToStyledText, + stringWidth, + stripAnsiSequences, + t, + terminalNamedSingleStrokeKeys, + treeSitterToStyledText, + treeSitterToTextChunks, + underline, + visualizeRenderableTree, + white, + yellow +} from "./index-pcvh9d34.js"; +// src/post/effects.ts +function toU8(value) { + return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255); +} +function channel(buffer, index) { + return (buffer[index] & 255) / 255; +} +function setRgb(buffer, base, r, g, b) { + const a = buffer[base + 3] & 255; + buffer[base] = toU8(r); + buffer[base + 1] = toU8(g); + buffer[base + 2] = toU8(b); + buffer[base + 3] = a; +} + +class DistortionEffect { + glitchChancePerSecond = 0.5; + maxGlitchLines = 3; + minGlitchDuration = 0.05; + maxGlitchDuration = 0.2; + maxShiftAmount = 10; + shiftFlipRatio = 0.6; + colorGlitchChance = 0.2; + lastGlitchTime = 0; + glitchDuration = 0; + activeGlitches = []; + constructor(options) { + if (options) { + Object.assign(this, options); + } + } + apply(buffer, deltaTime) { + const width = buffer.width; + const height = buffer.height; + const buf = buffer.buffers; + this.lastGlitchTime += deltaTime; + if (this.activeGlitches.length > 0 && this.lastGlitchTime >= this.glitchDuration) { + this.activeGlitches = []; + this.glitchDuration = 0; + } + if (this.activeGlitches.length === 0 && Math.random() < this.glitchChancePerSecond * deltaTime) { + this.lastGlitchTime = 0; + this.glitchDuration = this.minGlitchDuration + Math.random() * (this.maxGlitchDuration - this.minGlitchDuration); + const numGlitches = 1 + Math.floor(Math.random() * this.maxGlitchLines); + for (let i = 0;i < numGlitches; i++) { + const y = Math.floor(Math.random() * height); + let type; + let amount = 0; + const typeRoll = Math.random(); + if (typeRoll < this.colorGlitchChance) { + type = "color"; + } else { + const shiftRoll = (typeRoll - this.colorGlitchChance) / (1 - this.colorGlitchChance); + if (shiftRoll < this.shiftFlipRatio) { + type = "shift"; + amount = Math.floor((Math.random() - 0.5) * 2 * this.maxShiftAmount); + } else { + type = "flip"; + } + } + if (!this.activeGlitches.some((g) => g.y === y)) { + this.activeGlitches.push({ y, type, amount }); + } + } + } + if (this.activeGlitches.length > 0) { + let tempChar = null; + let tempFg = null; + let tempBg = null; + let tempAttr = null; + for (const glitch of this.activeGlitches) { + const y = glitch.y; + if (y < 0 || y >= height) + continue; + const baseIndex = y * width; + if (glitch.type === "shift" || glitch.type === "flip") { + if (!tempChar) { + tempChar = new Uint32Array(width); + tempFg = new Uint16Array(width * 4); + tempBg = new Uint16Array(width * 4); + tempAttr = new Uint8Array(width); + } + try { + tempChar.set(buf.char.subarray(baseIndex, baseIndex + width)); + tempFg.set(buf.fg.subarray(baseIndex * 4, (baseIndex + width) * 4)); + tempBg.set(buf.bg.subarray(baseIndex * 4, (baseIndex + width) * 4)); + tempAttr.set(buf.attributes.subarray(baseIndex, baseIndex + width)); + } catch (e) { + console.error(`Error copying row ${y} for distortion:`, e); + continue; + } + if (glitch.type === "shift") { + const shift = glitch.amount; + for (let x = 0;x < width; x++) { + const srcX = (x - shift + width) % width; + const destIndex = baseIndex + x; + const srcTempIndex = srcX; + buf.char[destIndex] = tempChar[srcTempIndex]; + buf.attributes[destIndex] = tempAttr[srcTempIndex]; + const destColorIndex = destIndex * 4; + const srcTempColorIndex = srcTempIndex * 4; + buf.fg.set(tempFg.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex); + buf.bg.set(tempBg.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex); + } + } else { + for (let x = 0;x < width; x++) { + const srcX = width - 1 - x; + const destIndex = baseIndex + x; + const srcTempIndex = srcX; + buf.char[destIndex] = tempChar[srcTempIndex]; + buf.attributes[destIndex] = tempAttr[srcTempIndex]; + const destColorIndex = destIndex * 4; + const srcTempColorIndex = srcTempIndex * 4; + buf.fg.set(tempFg.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex); + buf.bg.set(tempBg.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex); + } + } + } else if (glitch.type === "color") { + const glitchStart = Math.floor(Math.random() * width); + const maxPossibleLength = width - glitchStart; + let glitchLength = Math.floor(Math.random() * maxPossibleLength) + 1; + if (Math.random() < 0.2) { + glitchLength = Math.floor(Math.random() * (width / 4)) + 1; + } + glitchLength = Math.min(glitchLength, maxPossibleLength); + for (let x = glitchStart;x < glitchStart + glitchLength; x++) { + if (x >= width) + break; + const destIndex = baseIndex + x; + const destColorIndex = destIndex * 4; + let rFg, gFg, bFg, rBg, gBg, bBg; + const colorMode = Math.random(); + if (colorMode < 0.33) { + rFg = Math.random(); + gFg = Math.random(); + bFg = Math.random(); + rBg = Math.random(); + gBg = Math.random(); + bBg = Math.random(); + } else if (colorMode < 0.66) { + const emphasis = Math.random(); + if (emphasis < 0.25) { + rFg = Math.random(); + gFg = 0; + bFg = 0; + } else if (emphasis < 0.5) { + rFg = 0; + gFg = Math.random(); + bFg = 0; + } else if (emphasis < 0.75) { + rFg = 0; + gFg = 0; + bFg = Math.random(); + } else { + const glitchColorRoll = Math.random(); + if (glitchColorRoll < 0.33) { + rFg = 1; + gFg = 0; + bFg = 1; + } else if (glitchColorRoll < 0.66) { + rFg = 0; + gFg = 1; + bFg = 1; + } else { + rFg = 1; + gFg = 1; + bFg = 0; + } + } + if (Math.random() < 0.5) { + rBg = 1 - rFg; + gBg = 1 - gFg; + bBg = 1 - bFg; + } else { + rBg = rFg * (Math.random() * 0.5 + 0.2); + gBg = gFg * (Math.random() * 0.5 + 0.2); + bBg = bFg * (Math.random() * 0.5 + 0.2); + } + } else { + rFg = Math.random() > 0.5 ? 1 : 0; + gFg = Math.random() > 0.5 ? 1 : 0; + bFg = Math.random() > 0.5 ? 1 : 0; + rBg = 1 - rFg; + gBg = 1 - gFg; + bBg = 1 - bFg; + } + setRgb(buf.fg, destColorIndex, rFg, gFg, bFg); + setRgb(buf.bg, destColorIndex, rBg, gBg, bBg); + } + } + } + } + } +} + +class VignetteEffect { + _strength; + precomputedAttenuationCellMask = null; + cachedWidth = -1; + cachedHeight = -1; + static zeroMatrix = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + constructor(strength = 0.5) { + this._strength = strength; + } + set strength(newStrength) { + this._strength = Math.max(0, newStrength); + this.cachedWidth = -1; + this.cachedHeight = -1; + this.precomputedAttenuationCellMask = null; + } + get strength() { + return this._strength; + } + _computeFactors(width, height) { + this.precomputedAttenuationCellMask = new Float32Array(width * height * 3); + const centerX = width / 2; + const centerY = height / 2; + const maxDistSq = centerX * centerX + centerY * centerY; + const safeMaxDistSq = maxDistSq === 0 ? 1 : maxDistSq; + const strength = this._strength; + let i = 0; + for (let y = 0;y < height; y++) { + const dy = y - centerY; + const dySq = dy * dy; + for (let x = 0;x < width; x++) { + const dx = x - centerX; + const distSq = dx * dx + dySq; + const baseAttenuation = Math.min(1, distSq / safeMaxDistSq); + const attenuation = baseAttenuation * strength; + this.precomputedAttenuationCellMask[i++] = x; + this.precomputedAttenuationCellMask[i++] = y; + this.precomputedAttenuationCellMask[i++] = attenuation; + } + } + this.cachedWidth = width; + this.cachedHeight = height; + } + apply(buffer) { + const width = buffer.width; + const height = buffer.height; + if (width !== this.cachedWidth || height !== this.cachedHeight || !this.precomputedAttenuationCellMask) { + this._computeFactors(width, height); + } + buffer.colorMatrix(VignetteEffect.zeroMatrix, this.precomputedAttenuationCellMask, 1, 3); + } +} + +class PerlinNoise { + perm; + grad3 = [ + [1, 1, 0], + [-1, 1, 0], + [1, -1, 0], + [-1, -1, 0], + [1, 0, 1], + [-1, 0, 1], + [1, 0, -1], + [-1, 0, -1], + [0, 1, 1], + [0, -1, 1], + [0, 1, -1], + [0, -1, -1] + ]; + constructor() { + this.perm = new Uint8Array(512); + const p = new Uint8Array(256); + for (let i = 0;i < 256; i++) { + p[i] = i; + } + for (let i = 255;i > 0; i--) { + const r = Math.floor(Math.random() * (i + 1)); + [p[i], p[r]] = [p[r], p[i]]; + } + for (let i = 0;i < 512; i++) { + this.perm[i] = p[i & 255]; + } + } + dot(g, x, y, z) { + return g[0] * x + g[1] * y + g[2] * z; + } + mix(a, b, t2) { + return a + (b - a) * t2; + } + fade(t2) { + return t2 * t2 * t2 * (t2 * (t2 * 6 - 15) + 10); + } + noise3d(x, y, z) { + const X = Math.floor(x) & 255; + const Y = Math.floor(y) & 255; + const Z = Math.floor(z) & 255; + const xf = x - Math.floor(x); + const yf = y - Math.floor(y); + const zf = z - Math.floor(z); + const u = this.fade(xf); + const v = this.fade(yf); + const w = this.fade(zf); + const A = this.perm[X] + Y; + const AA = this.perm[A] + Z; + const AB = this.perm[A + 1] + Z; + const B = this.perm[X + 1] + Y; + const BA = this.perm[B] + Z; + const BB = this.perm[B + 1] + Z; + let res = this.mix(this.mix(this.mix(this.dot(this.grad3[this.perm[AA] % 12], xf, yf, zf), this.dot(this.grad3[this.perm[BA] % 12], xf - 1, yf, zf), u), this.mix(this.dot(this.grad3[this.perm[AB] % 12], xf, yf - 1, zf), this.dot(this.grad3[this.perm[BB] % 12], xf - 1, yf - 1, zf), u), v), this.mix(this.mix(this.dot(this.grad3[this.perm[AA + 1] % 12], xf, yf, zf - 1), this.dot(this.grad3[this.perm[BA + 1] % 12], xf - 1, yf, zf - 1), u), this.mix(this.dot(this.grad3[this.perm[AB + 1] % 12], xf, yf - 1, zf - 1), this.dot(this.grad3[this.perm[BB + 1] % 12], xf - 1, yf - 1, zf - 1), u), v), w); + return res; + } +} + +class CloudsEffect { + noise; + _scale; + _speed; + _density; + _darkness; + time = 0; + constructor(scale = 0.02, speed = 0.5, density = 0.6, darkness = 0.7) { + this.noise = new PerlinNoise; + this._scale = scale; + this._speed = speed; + this._density = density; + this._darkness = darkness; + } + set scale(newScale) { + this._scale = Math.max(0.001, newScale); + } + get scale() { + return this._scale; + } + set speed(newSpeed) { + this._speed = Math.max(0, newSpeed); + } + get speed() { + return this._speed; + } + set density(newDensity) { + this._density = Math.max(0, Math.min(1, newDensity)); + } + get density() { + return this._density; + } + set darkness(newDarkness) { + this._darkness = Math.max(0, Math.min(1, newDarkness)); + } + get darkness() { + return this._darkness; + } + apply(buffer, deltaTime) { + const width = buffer.width; + const height = buffer.height; + this.time += deltaTime * this._speed; + const scale = this._scale; + const timeOffset = this.time; + const cellMask = new Float32Array(width * height * 3); + let maskIdx = 0; + for (let y = 0;y < height; y++) { + for (let x = 0;x < width; x++) { + let noiseValue = 0; + let amplitude = 1; + let frequency = 1; + let maxValue = 0; + for (let i = 0;i < 4; i++) { + const nx = (x * scale * frequency + timeOffset) * 0.5; + const ny = y * scale * frequency * 0.5; + const nz = timeOffset * 0.3; + noiseValue += this.noise.noise3d(nx, ny, nz) * amplitude; + maxValue += amplitude; + amplitude *= 0.5; + frequency *= 2; + } + noiseValue = (noiseValue / maxValue + 1) * 0.5; + const cloudDensity = Math.max(0, noiseValue - (1 - this._density)); + const attenuation = cloudDensity * this._darkness; + cellMask[maskIdx++] = x; + cellMask[maskIdx++] = y; + cellMask[maskIdx++] = attenuation; + } + } + const zeroMatrix = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + buffer.colorMatrix(zeroMatrix, cellMask, 1, 2); + } +} + +class FlamesEffect { + noise; + _scale; + _speed; + _intensity; + time = 0; + constructor(scale = 0.03, speed = 0.02, intensity = 0.8) { + this.noise = new PerlinNoise; + this._scale = scale; + this._speed = speed; + this._intensity = intensity; + } + set scale(newScale) { + this._scale = Math.max(0.001, newScale); + } + get scale() { + return this._scale; + } + set speed(newSpeed) { + this._speed = Math.max(0, newSpeed); + } + get speed() { + return this._speed; + } + set intensity(newIntensity) { + this._intensity = Math.max(0, Math.min(1, newIntensity)); + } + get intensity() { + return this._intensity; + } + apply(buffer, deltaTime) { + const width = buffer.width; + const height = buffer.height; + const bg2 = buffer.buffers.bg; + this.time += deltaTime * this._speed; + const scale = this._scale; + const timeOffset = this.time; + for (let y = 0;y < height; y++) { + const heightFactor = 1 - y / height; + for (let x = 0;x < width; x++) { + let noiseValue = 0; + let amplitude = 1; + let frequency = 1; + let maxValue = 0; + for (let i = 0;i < 3; i++) { + const nx = (x * scale * frequency + timeOffset) * 0.5; + const ny = (height - y) * scale * frequency * 2 * 0.5; + const nz = timeOffset * 2; + noiseValue += this.noise.noise3d(nx, ny, nz) * amplitude; + maxValue += amplitude; + amplitude *= 0.5; + frequency *= 2; + } + noiseValue = (noiseValue / maxValue + 1) * 0.5; + const flameIntensity = noiseValue * heightFactor * this._intensity; + if (flameIntensity > 0) { + const colorIndex = (y * width + x) * 4; + let r, g, b; + if (flameIntensity > 0.7) { + r = 1; + g = 1; + b = 0.3 + (flameIntensity - 0.7) * 2.3; + } else if (flameIntensity > 0.4) { + r = 1; + g = 0.5 + (flameIntensity - 0.4) * 1.67; + b = 0; + } else { + r = 0.3 + flameIntensity * 1.75; + g = flameIntensity * 0.5; + b = 0; + } + setRgb(bg2, colorIndex, Math.max(channel(bg2, colorIndex), r * flameIntensity), Math.max(channel(bg2, colorIndex + 1), g * flameIntensity), Math.max(channel(bg2, colorIndex + 2), b * flameIntensity)); + } + } + } + } +} + +class CRTRollingBarEffect { + _speed; + _height; + _intensity; + _fadeDistance; + position = 0; + constructor(speed = 0.5, height = 0.15, intensity = 0.3, fadeDistance = 0.3) { + this._speed = speed; + this._height = Math.max(0.01, Math.min(0.5, height)); + this._intensity = Math.max(0, Math.min(1, intensity)); + this._fadeDistance = Math.max(0, Math.min(1, fadeDistance)); + } + set speed(newSpeed) { + this._speed = newSpeed; + } + get speed() { + return this._speed; + } + set height(newHeight) { + this._height = Math.max(0.01, Math.min(0.5, newHeight)); + } + get height() { + return this._height; + } + set intensity(newIntensity) { + this._intensity = Math.max(0, Math.min(1, newIntensity)); + } + get intensity() { + return this._intensity; + } + set fadeDistance(newFadeDistance) { + this._fadeDistance = Math.max(0, Math.min(1, newFadeDistance)); + } + get fadeDistance() { + return this._fadeDistance; + } + apply(buffer, deltaTime) { + const width = buffer.width; + const height = buffer.height; + const fg2 = buffer.buffers.fg; + const bg2 = buffer.buffers.bg; + this.position += deltaTime / 1000 * this._speed; + const cycleHeight = height + this._height * height * 2; + this.position = this.position % cycleHeight; + const barPixelHeight = this._height * height; + const fadePixelDistance = this._fadeDistance * barPixelHeight; + const totalEffectHeight = barPixelHeight + fadePixelDistance * 2; + const effectCenter = this.position - totalEffectHeight / 2 + barPixelHeight / 2; + for (let y = 0;y < height; y++) { + const distFromCenter = Math.abs(y - effectCenter); + let barFactor = 0; + if (distFromCenter <= totalEffectHeight / 2) { + const normalizedDist = distFromCenter / (totalEffectHeight / 2); + barFactor = Math.cos(normalizedDist * Math.PI / 2); + } + if (barFactor > 0.001) { + const rowMultiplier = 1 + this._intensity * barFactor; + for (let x = 0;x < width; x++) { + const colorIndex = (y * width + x) * 4; + setRgb(fg2, colorIndex, Math.min(1, channel(fg2, colorIndex) * rowMultiplier), Math.min(1, channel(fg2, colorIndex + 1) * rowMultiplier), Math.min(1, channel(fg2, colorIndex + 2) * rowMultiplier)); + setRgb(bg2, colorIndex, Math.min(1, channel(bg2, colorIndex) * rowMultiplier), Math.min(1, channel(bg2, colorIndex + 1) * rowMultiplier), Math.min(1, channel(bg2, colorIndex + 2) * rowMultiplier)); + } + } + } + } +} + +class RainbowTextEffect { + _speed; + _saturation; + _value; + _repeats; + time = 0; + constructor(speed = 0.01, saturation = 1, value = 1, repeats = 3) { + this._speed = speed; + this._saturation = saturation; + this._value = value; + this._repeats = repeats; + } + set speed(newSpeed) { + this._speed = Math.max(0, newSpeed); + } + get speed() { + return this._speed; + } + set saturation(newSaturation) { + this._saturation = Math.max(0, Math.min(1, newSaturation)); + } + get saturation() { + return this._saturation; + } + set value(newValue) { + this._value = Math.max(0, Math.min(1, newValue)); + } + get value() { + return this._value; + } + set repeats(newRepeats) { + this._repeats = Math.max(0.1, newRepeats); + } + get repeats() { + return this._repeats; + } + hsvToRgb(h2, s, v) { + let r = 0, g = 0, b = 0; + const i = Math.floor(h2 * 6); + const f = h2 * 6 - i; + const p = v * (1 - s); + const q = v * (1 - f * s); + const t2 = v * (1 - (1 - f) * s); + switch (i % 6) { + case 0: + r = v; + g = t2; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t2; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t2; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; + } + return [r, g, b]; + } + apply(buffer, deltaTime) { + const width = buffer.width; + const height = buffer.height; + const fg2 = buffer.buffers.fg; + this.time += deltaTime * this._speed; + const saturation = this._saturation; + const value = this._value; + const repeats = this._repeats; + const angleRad = 25 * Math.PI / 180; + const cosAngle = Math.cos(angleRad); + const sinAngle = Math.sin(angleRad); + const whiteThreshold = 0.9; + for (let y = 0;y < height; y++) { + for (let x = 0;x < width; x++) { + const colorIndex = (y * width + x) * 4; + const r = channel(fg2, colorIndex); + const g = channel(fg2, colorIndex + 1); + const b = channel(fg2, colorIndex + 2); + if (r >= whiteThreshold && g >= whiteThreshold && b >= whiteThreshold) { + const projection = x * cosAngle + y * sinAngle; + const maxProjection = width * cosAngle + height * sinAngle; + const hue = (projection / maxProjection * repeats + this.time * 0.1) % 1; + const [newR, newG, newB] = this.hsvToRgb(hue, saturation, value); + setRgb(fg2, colorIndex, newR, newG, newB); + } + } + } + } +} +// src/post/filters.ts +function toU82(value) { + return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255); +} +function channel2(buffer, index) { + return (buffer[index] & 255) / 255; +} +function setRgb2(buffer, base, r, g, b) { + const a = buffer[base + 3] & 255; + buffer[base] = toU82(r); + buffer[base + 1] = toU82(g); + buffer[base + 2] = toU82(b); + buffer[base + 3] = a; +} +function applyScanlines(buffer, strength = 0.8, step = 2) { + if (strength === 1 || step < 1) + return; + const width = buffer.width; + const height = buffer.height; + const affectedRows = Math.ceil(height / step); + const cellCount = width * affectedRows; + const cellMask = new Float32Array(cellCount * 3); + let maskIdx = 0; + for (let y = 0;y < height; y += step) { + for (let x = 0;x < width; x++) { + cellMask[maskIdx++] = x; + cellMask[maskIdx++] = y; + cellMask[maskIdx++] = 1; + } + } + const s = strength; + const matrix = new Float32Array([ + s, + 0, + 0, + 0, + 0, + s, + 0, + 0, + 0, + 0, + s, + 0, + 0, + 0, + 0, + 1 + ]); + buffer.colorMatrix(matrix, cellMask, 1, 2); +} +function applyInvert(buffer, strength = 1) { + if (strength === 0) + return; + const matrix = new Float32Array([ + -1, + 0, + 0, + 1, + 0, + -1, + 0, + 1, + 0, + 0, + -1, + 1, + 0, + 0, + 0, + 1 + ]); + buffer.colorMatrixUniform(matrix, strength, 3); +} +function applyNoise(buffer, strength = 0.1) { + const width = buffer.width; + const height = buffer.height; + const size = width * height; + if (strength === 0) + return; + const cellMask = new Float32Array(size * 3); + let cellMaskIndex = 0; + for (let y = 0;y < height; y++) { + for (let x = 0;x < width; x++) { + cellMask[cellMaskIndex++] = x; + cellMask[cellMaskIndex++] = y; + cellMask[cellMaskIndex++] = (Math.random() - 0.5) * 2; + } + } + const b = 1 + strength; + const matrix = new Float32Array([ + b, + 0, + 0, + 0, + 0, + b, + 0, + 0, + 0, + 0, + b, + 0, + 0, + 0, + 0, + 1 + ]); + buffer.colorMatrix(matrix, cellMask, 1, 3); +} +function applyChromaticAberration(buffer, strength = 1) { + const width = buffer.width; + const height = buffer.height; + const srcFg = Uint16Array.from(buffer.buffers.fg); + const destFg = buffer.buffers.fg; + const centerX = width / 2; + const centerY = height / 2; + for (let y = 0;y < height; y++) { + for (let x = 0;x < width; x++) { + const dx = x - centerX; + const dy = y - centerY; + const offset = Math.round(Math.sqrt(dx * dx + dy * dy) / Math.max(centerX, centerY) * strength); + const rX = Math.max(0, Math.min(width - 1, x - offset)); + const bX = Math.max(0, Math.min(width - 1, x + offset)); + const rIndex = (y * width + rX) * 4; + const gIndex = (y * width + x) * 4; + const bIndex = (y * width + bX) * 4; + const destIndex = (y * width + x) * 4; + setRgb2(destFg, destIndex, channel2(srcFg, rIndex), channel2(srcFg, gIndex + 1), channel2(srcFg, bIndex + 2)); + } + } +} +function applyAsciiArt(buffer, ramp = ' .\'`^"",:;Il!i><~+_-?][}{1)(|\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$', fgColor = { r: 1, g: 1, b: 1 }, bgColor = { r: 0, g: 0, b: 0 }) { + const width = buffer.width; + const height = buffer.height; + const chars = buffer.buffers.char; + const bg2 = buffer.buffers.bg; + const rampLength = ramp.length; + for (let y = 0;y < height; y++) { + for (let x = 0;x < width; x++) { + const index = y * width + x; + const colorIndex = index * 4; + const bgR = channel2(bg2, colorIndex); + const bgG = channel2(bg2, colorIndex + 1); + const bgB = channel2(bg2, colorIndex + 2); + const lum = 0.299 * bgR + 0.587 * bgG + 0.114 * bgB; + const rampIndex = Math.min(rampLength - 1, Math.floor(lum * rampLength)); + chars[index] = ramp[rampIndex].charCodeAt(0); + } + } + const fgMatrix = new Float32Array([ + 0, + 0, + 0, + fgColor.r, + 0, + 0, + 0, + fgColor.g, + 0, + 0, + 0, + fgColor.b, + 0, + 0, + 0, + 1 + ]); + const bgMatrix = new Float32Array([ + 0, + 0, + 0, + bgColor.r, + 0, + 0, + 0, + bgColor.g, + 0, + 0, + 0, + bgColor.b, + 0, + 0, + 0, + 1 + ]); + buffer.colorMatrixUniform(fgMatrix, 1, 1); + buffer.colorMatrixUniform(bgMatrix, 1, 2); +} +function applyBrightness(buffer, brightness = 0, cellMask) { + if (brightness === 0) + return; + const b = brightness; + const matrix = new Float32Array([ + 1, + 0, + 0, + b, + 0, + 1, + 0, + b, + 0, + 0, + 1, + b, + 0, + 0, + 0, + 1 + ]); + if (!cellMask || cellMask.length === 0) { + buffer.colorMatrixUniform(matrix, 1, 3); + } else { + buffer.colorMatrix(matrix, cellMask, 1, 3); + } +} +function applyGain(buffer, gain = 1, cellMask) { + if (gain === 1) + return; + const g = Math.max(0, gain); + const matrix = new Float32Array([ + g, + 0, + 0, + 0, + 0, + g, + 0, + 0, + 0, + 0, + g, + 0, + 0, + 0, + 0, + 1 + ]); + if (!cellMask || cellMask.length === 0) { + buffer.colorMatrixUniform(matrix, 1, 3); + } else { + buffer.colorMatrix(matrix, cellMask, 1, 3); + } +} +function createSaturationMatrix(saturation) { + const s = Math.max(0, saturation); + const sr = 0.299 * (1 - s); + const sg = 0.587 * (1 - s); + const sb = 0.114 * (1 - s); + const m00 = sr + s; + const m01 = sg; + const m02 = sb; + const m10 = sr; + const m11 = sg + s; + const m12 = sb; + const m20 = sr; + const m21 = sg; + const m22 = sb + s; + return new Float32Array([ + m00, + m01, + m02, + 0, + m10, + m11, + m12, + 0, + m20, + m21, + m22, + 0, + 0, + 0, + 0, + 1 + ]); +} +function applySaturation(buffer, cellMask, strength = 1) { + if (strength === 1 || strength === 0) { + return; + } + const matrix = createSaturationMatrix(strength); + if (!cellMask || cellMask.length === 0) { + buffer.colorMatrixUniform(matrix, 1, 3); + } else { + buffer.colorMatrix(matrix, cellMask, 1, 3); + } +} + +class BloomEffect { + _threshold; + _strength; + _radius; + constructor(threshold = 0.8, strength = 0.2, radius = 2) { + this._threshold = Math.max(0, Math.min(1, threshold)); + this._strength = Math.max(0, strength); + this._radius = Math.max(0, Math.round(radius)); + } + set threshold(newThreshold) { + this._threshold = Math.max(0, Math.min(1, newThreshold)); + } + get threshold() { + return this._threshold; + } + set strength(newStrength) { + this._strength = Math.max(0, newStrength); + } + get strength() { + return this._strength; + } + set radius(newRadius) { + this._radius = Math.max(0, Math.round(newRadius)); + } + get radius() { + return this._radius; + } + apply(buffer) { + const threshold = this._threshold; + const strength = this._strength; + const radius = this._radius; + if (strength <= 0 || radius <= 0) + return; + const width = buffer.width; + const height = buffer.height; + const srcFg = Uint16Array.from(buffer.buffers.fg); + const srcBg = Uint16Array.from(buffer.buffers.bg); + const destFg = buffer.buffers.fg; + const destBg = buffer.buffers.bg; + const brightPixels = []; + for (let y = 0;y < height; y++) { + for (let x = 0;x < width; x++) { + const index = (y * width + x) * 4; + const fgLum = 0.299 * channel2(srcFg, index) + 0.587 * channel2(srcFg, index + 1) + 0.114 * channel2(srcFg, index + 2); + const bgLum = 0.299 * channel2(srcBg, index) + 0.587 * channel2(srcBg, index + 1) + 0.114 * channel2(srcBg, index + 2); + const lum = Math.max(fgLum, bgLum); + if (lum > threshold) { + const intensity = (lum - threshold) / (1 - threshold + 0.000001); + brightPixels.push({ x, y, intensity: Math.max(0, intensity) }); + } + } + } + if (brightPixels.length === 0) + return; + destFg.set(srcFg); + destBg.set(srcBg); + for (const bright of brightPixels) { + for (let ky = -radius;ky <= radius; ky++) { + for (let kx = -radius;kx <= radius; kx++) { + if (kx === 0 && ky === 0) + continue; + const sampleX = bright.x + kx; + const sampleY = bright.y + ky; + if (sampleX >= 0 && sampleX < width && sampleY >= 0 && sampleY < height) { + const distSq = kx * kx + ky * ky; + const radiusSq = radius * radius; + if (distSq <= radiusSq) { + const falloff = 1 - distSq / radiusSq; + const bloomAmount = bright.intensity * strength * falloff; + const destIndex = (sampleY * width + sampleX) * 4; + setRgb2(destFg, destIndex, Math.min(1, channel2(destFg, destIndex) + bloomAmount), Math.min(1, channel2(destFg, destIndex + 1) + bloomAmount), Math.min(1, channel2(destFg, destIndex + 2) + bloomAmount)); + setRgb2(destBg, destIndex, Math.min(1, channel2(destBg, destIndex) + bloomAmount), Math.min(1, channel2(destBg, destIndex + 1) + bloomAmount), Math.min(1, channel2(destBg, destIndex + 2) + bloomAmount)); + } + } + } + } + } + } +} +// src/post/matrices.ts +var SEPIA_MATRIX = new Float32Array([ + 0.393, + 0.769, + 0.189, + 0, + 0.349, + 0.686, + 0.168, + 0, + 0.272, + 0.534, + 0.131, + 0, + 0, + 0, + 0, + 1 +]); +var PROTANOPIA_SIM_MATRIX = new Float32Array([ + 0.567, + 0.433, + 0, + 0, + 0.558, + 0.442, + 0, + 0, + 0, + 0.242, + 0.758, + 0, + 0, + 0, + 0, + 1 +]); +var DEUTERANOPIA_SIM_MATRIX = new Float32Array([ + 0.625, + 0.375, + 0, + 0, + 0.7, + 0.3, + 0, + 0, + 0, + 0.3, + 0.7, + 0, + 0, + 0, + 0, + 1 +]); +var TRITANOPIA_SIM_MATRIX = new Float32Array([ + 0.95, + 0.05, + 0, + 0, + 0, + 0.433, + 0.567, + 0, + 0, + 0.475, + 0.525, + 0, + 0, + 0, + 0, + 1 +]); +var ACHROMATOPSIA_MATRIX = new Float32Array([ + 0.299, + 0.587, + 0.114, + 0, + 0.299, + 0.587, + 0.114, + 0, + 0.299, + 0.587, + 0.114, + 0, + 0, + 0, + 0, + 1 +]); +var PROTANOPIA_COMP_MATRIX = new Float32Array([ + 1, + 0.2, + 0, + 0, + 0, + 0.9, + 0.1, + 0, + 0, + 0.1, + 0.9, + 0, + 0, + 0, + 0, + 1 +]); +var DEUTERANOPIA_COMP_MATRIX = new Float32Array([ + 0.9, + 0.1, + 0, + 0, + 0.2, + 0.8, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 +]); +var TRITANOPIA_COMP_MATRIX = new Float32Array([ + 1, + 0, + 0, + 0, + 0, + 0.9, + 0.1, + 0, + 0.1, + 0, + 0.9, + 0, + 0, + 0, + 0, + 1 +]); +var TECHNICOLOR_MATRIX = new Float32Array([ + 1.5, + -0.2, + -0.3, + 0, + -0.3, + 1.4, + -0.1, + 0, + -0.2, + -0.2, + 1.4, + 0, + 0, + 0, + 0, + 1 +]); +var SOLARIZATION_MATRIX = new Float32Array([ + -0.5, + 0.5, + 0.5, + 0, + 0.5, + -0.5, + 0.5, + 0, + 0.5, + 0.5, + -0.5, + 0, + 0, + 0, + 0, + 1 +]); +var SYNTHWAVE_MATRIX = new Float32Array([ + 1, + 0, + 0.25, + 0, + 0.1, + 0.1, + 0.1, + 0, + 0.25, + 0, + 1, + 0, + 0, + 0, + 0, + 1 +]); +var GREENSCALE_MATRIX = new Float32Array([ + 0, + 0, + 0, + 0, + 0.299, + 0.587, + 0.114, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 +]); +var GRAYSCALE_MATRIX = new Float32Array([ + 0.299, + 0.587, + 0.114, + 0, + 0.299, + 0.587, + 0.114, + 0, + 0.299, + 0.587, + 0.114, + 0, + 0, + 0, + 0, + 1 +]); +var INVERT_MATRIX = new Float32Array([ + -1, + 0, + 0, + 1, + 0, + -1, + 0, + 1, + 0, + 0, + -1, + 1, + 0, + 0, + 0, + 1 +]); +// src/animation/Timeline.ts +var easingFunctions = { + linear: (t2) => t2, + inQuad: (t2) => t2 * t2, + outQuad: (t2) => t2 * (2 - t2), + inOutQuad: (t2) => t2 < 0.5 ? 2 * t2 * t2 : -1 + (4 - 2 * t2) * t2, + inExpo: (t2) => t2 === 0 ? 0 : Math.pow(2, 10 * (t2 - 1)), + outExpo: (t2) => t2 === 1 ? 1 : 1 - Math.pow(2, -10 * t2), + inOutSine: (t2) => -(Math.cos(Math.PI * t2) - 1) / 2, + outBounce: (t2) => { + const n1 = 7.5625; + const d1 = 2.75; + if (t2 < 1 / d1) { + return n1 * t2 * t2; + } else if (t2 < 2 / d1) { + return n1 * (t2 -= 1.5 / d1) * t2 + 0.75; + } else if (t2 < 2.5 / d1) { + return n1 * (t2 -= 2.25 / d1) * t2 + 0.9375; + } else { + return n1 * (t2 -= 2.625 / d1) * t2 + 0.984375; + } + }, + outElastic: (t2) => { + const c4 = 2 * Math.PI / 3; + return t2 === 0 ? 0 : t2 === 1 ? 1 : Math.pow(2, -10 * t2) * Math.sin((t2 * 10 - 0.75) * c4) + 1; + }, + inBounce: (t2) => 1 - easingFunctions.outBounce(1 - t2), + inCirc: (t2) => 1 - Math.sqrt(1 - t2 * t2), + outCirc: (t2) => Math.sqrt(1 - Math.pow(t2 - 1, 2)), + inOutCirc: (t2) => { + if ((t2 *= 2) < 1) + return -0.5 * (Math.sqrt(1 - t2 * t2) - 1); + return 0.5 * (Math.sqrt(1 - (t2 -= 2) * t2) + 1); + }, + inBack: (t2, s = 1.70158) => t2 * t2 * ((s + 1) * t2 - s), + outBack: (t2, s = 1.70158) => --t2 * t2 * ((s + 1) * t2 + s) + 1, + inOutBack: (t2, s = 1.70158) => { + s *= 1.525; + if ((t2 *= 2) < 1) + return 0.5 * (t2 * t2 * ((s + 1) * t2 - s)); + return 0.5 * ((t2 -= 2) * t2 * ((s + 1) * t2 + s) + 2); + } +}; +function captureInitialValues(item) { + if (!item.properties) + return; + if (!item.initialValues || item.initialValues.length === 0) { + const initialValues = []; + for (let i = 0;i < item.target.length; i++) { + const target = item.target[i]; + const targetInitialValues = {}; + for (const key of Object.keys(item.properties)) { + if (typeof target[key] === "number") { + targetInitialValues[key] = target[key]; + } + } + initialValues.push(targetInitialValues); + } + item.initialValues = initialValues; + } +} +function applyAnimationAtProgress(item, progress, reversed, timelineTime, deltaTime = 0) { + if (!item.properties || !item.initialValues) + return; + const easingFn = easingFunctions[item.ease || "linear"] || easingFunctions.linear; + const easedProgress = easingFn(Math.max(0, Math.min(1, progress))); + const finalProgress = reversed ? 1 - easedProgress : easedProgress; + for (let i = 0;i < item.target.length; i++) { + const target = item.target[i]; + const targetInitialValues = item.initialValues[i]; + if (!targetInitialValues) + continue; + for (const [key, endValue] of Object.entries(item.properties)) { + const startValue = targetInitialValues[key]; + const newValue = startValue + (endValue - startValue) * finalProgress; + target[key] = newValue; + } + } + if (item.onUpdate) { + const animation = { + targets: item.target, + progress: easedProgress, + currentTime: timelineTime, + deltaTime + }; + item.onUpdate(animation); + } +} +function evaluateAnimation(item, timelineTime, deltaTime = 0) { + if (timelineTime < item.startTime) { + return; + } + const animationTime = timelineTime - item.startTime; + const duration = item.duration || 0; + if (timelineTime >= item.startTime && !item.started) { + captureInitialValues(item); + if (item.onStart) { + item.onStart(); + } + item.started = true; + } + if (duration === 0) { + if (!item.completed) { + applyAnimationAtProgress(item, 1, false, timelineTime, deltaTime); + if (item.onComplete) { + item.onComplete(); + } + item.completed = true; + } + return; + } + const maxLoops = !item.loop || item.loop === 1 ? 1 : typeof item.loop === "number" ? item.loop : Infinity; + const loopDelay = item.loopDelay || 0; + const cycleTime = duration + loopDelay; + let currentCycle = Math.floor(animationTime / cycleTime); + let timeInCycle = animationTime % cycleTime; + if (item.onLoop && item.currentLoop !== undefined && currentCycle > item.currentLoop && currentCycle < maxLoops) { + item.onLoop(); + } + item.currentLoop = currentCycle; + if (item.onComplete && !item.completed && currentCycle === maxLoops - 1 && timeInCycle >= duration) { + const finalLoopReversed = (item.alternate || false) && currentCycle % 2 === 1; + applyAnimationAtProgress(item, 1, finalLoopReversed, timelineTime, deltaTime); + item.onComplete(); + item.completed = true; + return; + } + if (currentCycle >= maxLoops) { + if (!item.completed) { + const finalReversed = (item.alternate || false) && (maxLoops - 1) % 2 === 1; + applyAnimationAtProgress(item, 1, finalReversed, timelineTime, deltaTime); + if (item.onComplete) { + item.onComplete(); + } + item.completed = true; + } + return; + } + if (timeInCycle === 0 && animationTime > 0 && currentCycle < maxLoops) { + currentCycle = currentCycle - 1; + timeInCycle = cycleTime; + } + if (timeInCycle >= duration) { + const isReversed2 = (item.alternate || false) && currentCycle % 2 === 1; + applyAnimationAtProgress(item, 1, isReversed2, timelineTime, deltaTime); + return; + } + const progress = timeInCycle / duration; + const isReversed = (item.alternate || false) && currentCycle % 2 === 1; + applyAnimationAtProgress(item, progress, isReversed, timelineTime, deltaTime); +} +function evaluateCallback(item, timelineTime) { + if (!item.executed && timelineTime >= item.startTime && item.callback) { + item.callback(); + item.executed = true; + } +} +function evaluateTimelineSync(item, timelineTime, deltaTime = 0) { + if (!item.timeline) + return; + if (timelineTime < item.startTime) { + return; + } + if (!item.timelineStarted) { + item.timelineStarted = true; + item.timeline.play(); + const overshoot = timelineTime - item.startTime; + item.timeline.update(overshoot); + return; + } + item.timeline.update(deltaTime); +} +function evaluateItem(item, timelineTime, deltaTime = 0) { + if (item.type === "animation") { + evaluateAnimation(item, timelineTime, deltaTime); + } else if (item.type === "callback") { + evaluateCallback(item, timelineTime); + } +} + +class Timeline { + items = []; + subTimelines = []; + currentTime = 0; + isPlaying = false; + isComplete = false; + duration; + loop; + synced = false; + autoplay; + onComplete; + onPause; + stateChangeListeners = []; + constructor(options = {}) { + this.duration = options.duration || 1000; + this.loop = options.loop === true; + this.autoplay = options.autoplay !== false; + this.onComplete = options.onComplete; + this.onPause = options.onPause; + } + addStateChangeListener(listener) { + this.stateChangeListeners.push(listener); + } + removeStateChangeListener(listener) { + this.stateChangeListeners = this.stateChangeListeners.filter((l) => l !== listener); + } + notifyStateChange() { + for (const listener of this.stateChangeListeners) { + listener(this); + } + } + add(target, properties, startTime = 0) { + const resolvedStartTime = typeof startTime === "string" ? 0 : startTime; + const animationProperties = {}; + for (const key in properties) { + if (!["duration", "ease", "onUpdate", "onComplete", "onStart", "onLoop", "loop", "loopDelay", "alternate"].includes(key)) { + if (typeof properties[key] === "number") { + animationProperties[key] = properties[key]; + } + } + } + this.items.push({ + type: "animation", + startTime: resolvedStartTime, + target: Array.isArray(target) ? target : [target], + properties: animationProperties, + initialValues: [], + duration: properties.duration !== undefined ? properties.duration : 1000, + ease: properties.ease || "linear", + loop: properties.loop, + loopDelay: properties.loopDelay || 0, + alternate: properties.alternate || false, + onUpdate: properties.onUpdate, + onComplete: properties.onComplete, + onStart: properties.onStart, + onLoop: properties.onLoop, + completed: false, + started: false, + currentLoop: 0, + once: properties.once ?? false + }); + return this; + } + once(target, properties) { + this.add(target, { + ...properties, + once: true + }, this.currentTime); + return this; + } + call(callback, startTime = 0) { + const resolvedStartTime = typeof startTime === "string" ? 0 : startTime; + this.items.push({ + type: "callback", + startTime: resolvedStartTime, + callback, + executed: false + }); + return this; + } + sync(timeline, startTime = 0) { + if (timeline.synced) { + throw new Error("Timeline already synced"); + } + this.subTimelines.push({ + type: "timeline", + startTime, + timeline + }); + timeline.synced = true; + return this; + } + play() { + if (this.isComplete) { + return this.restart(); + } + this.subTimelines.forEach((subTimeline) => { + if (subTimeline.timelineStarted) { + subTimeline.timeline.play(); + } + }); + this.isPlaying = true; + this.notifyStateChange(); + return this; + } + pause() { + this.subTimelines.forEach((subTimeline) => { + subTimeline.timeline.pause(); + }); + this.isPlaying = false; + if (this.onPause) { + this.onPause(); + } + this.notifyStateChange(); + return this; + } + resetItems() { + this.items.forEach((item) => { + if (item.type === "callback") { + item.executed = false; + } else if (item.type === "animation") { + item.completed = false; + item.started = false; + item.currentLoop = 0; + } + }); + this.subTimelines.forEach((subTimeline) => { + subTimeline.timelineStarted = false; + if (subTimeline.timeline) { + subTimeline.timeline.restart(); + subTimeline.timeline.pause(); + } + }); + } + restart() { + this.isComplete = false; + this.currentTime = 0; + this.isPlaying = true; + this.resetItems(); + this.notifyStateChange(); + return this; + } + update(deltaTime) { + for (const subTimeline of this.subTimelines) { + evaluateTimelineSync(subTimeline, this.currentTime + deltaTime, deltaTime); + } + if (!this.isPlaying) + return; + this.currentTime += deltaTime; + for (const item of this.items) { + evaluateItem(item, this.currentTime, deltaTime); + } + for (let i = this.items.length - 1;i >= 0; i--) { + const item = this.items[i]; + if (item.type === "animation" && item.once && item.completed) { + this.items.splice(i, 1); + } + } + if (this.loop && this.currentTime >= this.duration) { + const overshoot = this.currentTime % this.duration; + this.resetItems(); + this.currentTime = 0; + if (overshoot > 0) { + this.update(overshoot); + } + } else if (!this.loop && this.currentTime >= this.duration) { + this.currentTime = this.duration; + this.isPlaying = false; + this.isComplete = true; + if (this.onComplete) { + this.onComplete(); + } + this.notifyStateChange(); + } + } +} + +class TimelineEngine { + timelines = new Set; + renderer = null; + frameCallback = null; + isLive = false; + defaults = { + frameRate: 60 + }; + attach(renderer) { + if (this.renderer) { + this.detach(); + } + this.renderer = renderer; + this.frameCallback = async (deltaTime) => { + this.update(deltaTime); + }; + renderer.setFrameCallback(this.frameCallback); + } + detach() { + if (this.renderer && this.frameCallback) { + this.renderer.removeFrameCallback(this.frameCallback); + if (this.isLive) { + this.renderer.dropLive(); + this.isLive = false; + } + } + this.renderer = null; + this.frameCallback = null; + } + updateLiveState() { + if (!this.renderer) + return; + const hasRunningTimelines = Array.from(this.timelines).some((timeline) => !timeline.synced && timeline.isPlaying && !timeline.isComplete); + if (hasRunningTimelines && !this.isLive) { + this.renderer.requestLive(); + this.isLive = true; + } else if (!hasRunningTimelines && this.isLive) { + this.renderer.dropLive(); + this.isLive = false; + } + } + onTimelineStateChange = (timeline) => { + this.updateLiveState(); + }; + register(timeline) { + if (!this.timelines.has(timeline)) { + this.timelines.add(timeline); + timeline.addStateChangeListener(this.onTimelineStateChange); + this.updateLiveState(); + } + } + unregister(timeline) { + if (this.timelines.has(timeline)) { + this.timelines.delete(timeline); + timeline.removeStateChangeListener(this.onTimelineStateChange); + this.updateLiveState(); + } + } + clear() { + for (const timeline of this.timelines) { + timeline.removeStateChangeListener(this.onTimelineStateChange); + } + this.timelines.clear(); + this.updateLiveState(); + } + update(deltaTime) { + for (const timeline of this.timelines) { + if (!timeline.synced) { + timeline.update(deltaTime); + } + } + } +} +var engine = new TimelineEngine; +function createTimeline(options = {}) { + const timeline = new Timeline(options); + if (options.autoplay !== false) { + timeline.play(); + } + engine.register(timeline); + return timeline; +} +// src/plugins/registry.ts +var noop = () => {}; +var DEFAULT_DEBUG_PLUGIN_ERRORS = false; +var DEFAULT_MAX_PLUGIN_ERRORS = 100; +function normalizeError(error) { + if (error instanceof Error) { + return error; + } + if (typeof error === "string") { + return new Error(error); + } + return new Error(`Unknown plugin error: ${String(error)}`); +} + +class SlotRegistry { + plugins = []; + sortedPluginsCache = null; + listeners = new Set; + errorListeners = new Set; + pluginErrors = []; + registrationOrder = 0; + batchDepth = 0; + batchedNotify = false; + rendererInstance; + hostContext; + options; + constructor(renderer, context, options = {}) { + this.rendererInstance = renderer; + this.hostContext = context; + this.options = { + debugPluginErrors: options.debugPluginErrors ?? DEFAULT_DEBUG_PLUGIN_ERRORS, + maxPluginErrors: options.maxPluginErrors ?? DEFAULT_MAX_PLUGIN_ERRORS, + onPluginError: options.onPluginError + }; + } + get renderer() { + return this.rendererInstance; + } + get context() { + return this.hostContext; + } + configure(options) { + if ("debugPluginErrors" in options) { + this.options.debugPluginErrors = options.debugPluginErrors ?? DEFAULT_DEBUG_PLUGIN_ERRORS; + } + if ("maxPluginErrors" in options) { + this.options.maxPluginErrors = options.maxPluginErrors ?? DEFAULT_MAX_PLUGIN_ERRORS; + } + if ("onPluginError" in options) { + this.options.onPluginError = options.onPluginError; + } + } + register(plugin) { + if (this.plugins.some((entry) => entry.plugin.id === plugin.id)) { + throw new Error(`Plugin with id "${plugin.id}" is already registered`); + } + try { + plugin.setup?.(this.hostContext, this.rendererInstance); + } catch (error) { + this.reportPluginError({ + pluginId: plugin.id, + phase: "setup", + source: "registry", + error + }); + return noop; + } + this.plugins.push({ + plugin, + registrationOrder: this.registrationOrder++, + cachedOrder: plugin.order ?? 0, + cachedId: plugin.id + }); + this.invalidateSortedPluginsCache(); + this.notifyListeners(); + return () => { + this.unregister(plugin.id); + }; + } + unregister(id) { + const index = this.plugins.findIndex((entry2) => entry2.plugin.id === id); + if (index === -1) { + return false; + } + const [entry] = this.plugins.splice(index, 1); + this.invalidateSortedPluginsCache(); + try { + entry?.plugin.dispose?.(); + } catch (error) { + this.reportPluginError({ + pluginId: id, + phase: "dispose", + source: "registry", + error + }); + } + this.notifyListeners(); + return true; + } + updateOrder(id, order) { + const entry = this.plugins.find((pluginEntry) => pluginEntry.plugin.id === id); + if (!entry) { + return false; + } + if ((entry.plugin.order ?? 0) === order) { + return true; + } + entry.plugin.order = order; + entry.cachedOrder = order; + this.invalidateSortedPluginsCache(); + this.notifyListeners(); + return true; + } + clear() { + if (this.plugins.length === 0) { + return; + } + const plugins = [...this.plugins]; + this.plugins = []; + this.invalidateSortedPluginsCache(); + for (const entry of plugins) { + try { + entry.plugin.dispose?.(); + } catch (error) { + this.reportPluginError({ + pluginId: entry.plugin.id, + phase: "dispose", + source: "registry", + error + }); + } + } + this.notifyListeners(); + } + subscribe(listener) { + this.listeners.add(listener); + return () => { + this.listeners.delete(listener); + }; + } + onPluginError(listener) { + this.errorListeners.add(listener); + return () => { + this.errorListeners.delete(listener); + }; + } + batch(run) { + this.batchDepth += 1; + try { + return run(); + } finally { + this.batchDepth -= 1; + if (this.batchDepth === 0 && this.batchedNotify) { + this.batchedNotify = false; + this.flushListeners(); + } + } + } + getPluginErrors() { + return this.pluginErrors; + } + clearPluginErrors() { + this.pluginErrors = []; + } + reportPluginError(report) { + const event = { + pluginId: report.pluginId, + slot: report.slot, + phase: report.phase, + source: report.source ?? "registry", + error: normalizeError(report.error), + timestamp: Date.now() + }; + this.pluginErrors.push(event); + if (this.pluginErrors.length > this.options.maxPluginErrors) { + this.pluginErrors.splice(0, this.pluginErrors.length - this.options.maxPluginErrors); + } + if (this.options.debugPluginErrors) { + const slotLabel = event.slot ? ` slot="${event.slot}"` : ""; + console.debug(`[SlotRegistry][PluginError] plugin="${event.pluginId}" phase="${event.phase}" source="${event.source}"${slotLabel}`); + console.debug(event.error); + } + for (const listener of this.errorListeners) { + try { + listener(event); + } catch (error) { + console.error("Error in plugin error listener:", error); + } + } + try { + this.options.onPluginError?.(event); + } catch (error) { + console.error("Error in plugin error callback:", error); + } + return event; + } + resolve(slot) { + return this.resolveEntries(slot).map((entry) => entry.renderer); + } + resolveEntries(slot) { + const slotRenderers = []; + for (const entry of this.getSortedPlugins()) { + const renderer = entry.plugin.slots[slot]; + if (renderer) { + slotRenderers.push({ + id: entry.plugin.id, + renderer + }); + } + } + return slotRenderers; + } + getSortedPlugins() { + this.syncPluginSortMetadata(); + if (this.sortedPluginsCache) { + return this.sortedPluginsCache; + } + this.sortedPluginsCache = [...this.plugins].sort((left, right) => { + const leftOrder = left.cachedOrder; + const rightOrder = right.cachedOrder; + if (leftOrder !== rightOrder) { + return leftOrder - rightOrder; + } + if (left.registrationOrder !== right.registrationOrder) { + return left.registrationOrder - right.registrationOrder; + } + return left.cachedId.localeCompare(right.cachedId); + }); + return this.sortedPluginsCache; + } + syncPluginSortMetadata() { + let hasChanges = false; + for (const entry of this.plugins) { + const nextOrder = entry.plugin.order ?? 0; + const nextId = entry.plugin.id; + if (entry.cachedOrder !== nextOrder || entry.cachedId !== nextId) { + entry.cachedOrder = nextOrder; + entry.cachedId = nextId; + hasChanges = true; + } + } + if (hasChanges) { + this.invalidateSortedPluginsCache(); + } + } + invalidateSortedPluginsCache() { + this.sortedPluginsCache = null; + } + notifyListeners() { + if (this.batchDepth > 0) { + this.batchedNotify = true; + return; + } + this.flushListeners(); + } + flushListeners() { + for (const listener of this.listeners) { + try { + listener(); + } catch (error) { + console.error("Error in slot registry listener:", error); + } + } + } +} +var slotRegistriesByRenderer = new WeakMap; +function getSlotRegistryStore(renderer) { + const existingStore = slotRegistriesByRenderer.get(renderer); + if (existingStore) { + return existingStore; + } + const createdStore = new Map; + slotRegistriesByRenderer.set(renderer, createdStore); + renderer.once("destroy", () => { + for (const registry of createdStore.values()) { + try { + registry.clear(); + } catch (error) { + console.error("Error disposing slot registry:", error); + } + } + createdStore.clear(); + slotRegistriesByRenderer.delete(renderer); + }); + return createdStore; +} +function createSlotRegistry(renderer, key, context, options = {}) { + const store = getSlotRegistryStore(renderer); + const existing = store.get(key); + if (existing) { + if (existing.context !== context) { + throw new Error(`createSlotRegistry called with a different context for renderer key "${key}". Reuse the original context object.`); + } + const typedExisting = existing; + typedExisting.configure(options); + return typedExisting; + } + const created = new SlotRegistry(renderer, context, options); + store.set(key, created); + return created; +} +// src/plugins/core-slot.ts +function isCoreManagedSlot(contribution) { + return typeof contribution === "object" && contribution !== null && "render" in contribution; +} +function toCorePlugin(plugin) { + const slots = {}; + for (const [slotName, contribution] of Object.entries(plugin.slots)) { + const wrappedRenderer = (ctx, data) => { + if (isCoreManagedSlot(contribution)) { + return contribution.render(ctx, data); + } + return contribution(ctx, data); + }; + if (isCoreManagedSlot(contribution)) { + wrappedRenderer.__coreSlotOwnership = "plugin"; + wrappedRenderer.__coreManagedSlot = contribution; + } else { + wrappedRenderer.__coreSlotOwnership = "host"; + } + slots[slotName] = wrappedRenderer; + } + return { + id: plugin.id, + order: plugin.order, + setup: plugin.setup, + dispose: plugin.dispose, + slots + }; +} +function asArray(value) { + if (!value) { + return []; + } + return Array.isArray(value) ? [...value] : [value]; +} +function ensureValidNode(node, pluginId, mount) { + if (!node) { + throw new Error(`Plugin "${pluginId}" did not return a renderable node`); + } + if (typeof node.then === "function") { + throw new Error(`Plugin "${pluginId}" returned an async value. Core slots require synchronous renderers.`); + } + if (!(node instanceof BaseRenderable)) { + throw new Error(`Plugin "${pluginId}" must return a BaseRenderable`); + } + if (node === mount) { + throw new Error(`Plugin "${pluginId}" returned the slot mount container as its node`); + } + if (node.parent && node.parent !== mount) { + throw new Error(`Plugin "${pluginId}" returned a renderable already attached to another parent`); + } +} +function createCoreSlotRegistry(renderer, context, options = {}) { + return createSlotRegistry(renderer, "core:slot-registry", context, options); +} +function registerCorePlugin(registry, plugin) { + return registry.register(toCorePlugin(plugin)); +} +function resolveCoreSlot(registry, slot) { + return resolveCoreSlotEntries(registry, slot).map((entry) => { + return { + id: entry.id, + renderer: entry.renderer + }; + }); +} +function resolveCoreSlotEntries(registry, slot) { + return registry.resolveEntries(slot).map((entry) => { + const wrappedRenderer = entry.renderer; + return { + id: entry.id, + renderer: (ctx, data) => wrappedRenderer(ctx, data), + ownership: wrappedRenderer.__coreSlotOwnership ?? "host", + managedSlot: wrappedRenderer.__coreManagedSlot + }; + }); +} + +class SlotRenderable extends Renderable { + _mode; + _slotRegistry; + _slotName; + _data; + _fallbackOption; + _pluginFailurePlaceholder; + _disposed = false; + _mountedNodes = []; + _pluginNodes = new Map; + _activePluginIds = new Set; + _fallbackNodes = null; + _unsubscribe = null; + constructor(ctx, options) { + super(ctx, options); + this._slotRegistry = options.registry; + this._slotName = options.name; + this._data = options.data ?? {}; + this._mode = options.mode ?? "append"; + this._fallbackOption = options.fallback; + this._pluginFailurePlaceholder = options.pluginFailurePlaceholder; + this._unsubscribe = this._slotRegistry.subscribe(() => this.refresh()); + try { + this.refresh(); + } catch (error) { + this._cleanupAll(); + throw error; + } + } + get mode() { + return this._mode; + } + set mode(value) { + this._mode = value; + this.refresh(); + } + get data() { + return this._data; + } + set data(value) { + this._data = value; + this.refresh(); + } + refresh() { + if (this._disposed) { + return; + } + const allEntries = resolveCoreSlotEntries(this._slotRegistry, this._slotName); + const activeEntries = this._mode === "single_winner" && allEntries.length > 0 ? [allEntries[0]] : allEntries; + const nextActivePluginIds = new Set(activeEntries.map((entry) => entry.id)); + const registeredPluginIds = new Set(allEntries.map((entry) => entry.id)); + this._cleanupInactivePluginNodes(nextActivePluginIds, registeredPluginIds); + for (const entry of activeEntries) { + let state = this._pluginNodes.get(entry.id); + const shouldRender = !state || state.ownership === "plugin" && state.nodes.length === 0 || state.dataRef !== this._data; + if (shouldRender) { + const previousState = state; + try { + const node = entry.renderer(this._slotRegistry.context, this._data); + ensureValidNode(node, entry.id, this); + state = { + nodes: [node], + ownership: entry.ownership, + managedSlot: entry.managedSlot ?? state?.managedSlot, + dataRef: this._data + }; + } catch (error) { + const failure = this._slotRegistry.reportPluginError({ + pluginId: entry.id, + slot: String(this._slotName), + phase: "render", + source: "core", + error + }); + state = { + nodes: this._resolvePluginFailurePlaceholder(failure), + ownership: "host", + managedSlot: entry.managedSlot ?? state?.managedSlot, + dataRef: this._data + }; + } + if (previousState) { + this._cleanupReplacedPluginNodes(previousState, state.nodes); + } + this._pluginNodes.set(entry.id, state); + } + if (!this._activePluginIds.has(entry.id)) { + const activeState = this._pluginNodes.get(entry.id); + if (activeState) { + this._callManagedHook(entry.id, activeState.managedSlot, "onActivate", "setup"); + } + } + } + const desiredNodes = []; + if (this._mode === "append" || activeEntries.length === 0) { + desiredNodes.push(...this._ensureFallbackNodes()); + } + for (const entry of activeEntries) { + const state = this._pluginNodes.get(entry.id); + if (state) { + desiredNodes.push(...state.nodes); + } + } + if (this._mode !== "append" && desiredNodes.length === 0) { + desiredNodes.push(...this._ensureFallbackNodes()); + } + this._reconcileMountedNodes(desiredNodes); + this._activePluginIds = nextActivePluginIds; + } + destroySelf() { + this._cleanupAll(); + } + _cleanupAll() { + if (this._disposed) { + return; + } + this._disposed = true; + this._unsubscribe?.(); + this._unsubscribe = null; + for (const [pluginId, state] of this._pluginNodes) { + if (this._activePluginIds.has(pluginId)) { + this._callManagedHook(pluginId, state.managedSlot, "onDeactivate", "dispose"); + } + this._callManagedHook(pluginId, state.managedSlot, "onDispose", "dispose"); + for (const node of state.nodes) { + this._detachNodeFromMount(node); + } + if (state.ownership === "host") { + for (const node of state.nodes) { + node.destroyRecursively(); + } + } + } + this._pluginNodes.clear(); + this._activePluginIds = new Set; + if (this._fallbackNodes) { + for (const node of this._fallbackNodes) { + node.destroyRecursively(); + } + this._fallbackNodes = null; + } + this._mountedNodes = []; + } + _ensureFallbackNodes() { + if (this._fallbackNodes !== null) { + return this._fallbackNodes; + } + const source = typeof this._fallbackOption === "function" ? this._fallbackOption() : this._fallbackOption; + const nodes = asArray(source); + for (const node of nodes) { + ensureValidNode(node, "fallback", this); + } + this._fallbackNodes = nodes; + return this._fallbackNodes; + } + _callManagedHook(pluginId, managedSlot, hook, phase) { + const callback = managedSlot?.[hook]; + if (!callback) { + return; + } + try { + callback(this._slotRegistry.context); + } catch (error) { + this._slotRegistry.reportPluginError({ + pluginId, + slot: String(this._slotName), + phase, + source: "core", + error + }); + } + } + _detachNodeFromMount(node) { + if (node.parent === this) { + this.remove(node.id); + } + } + _cleanupInactivePluginNodes(nextActivePluginIds, registeredPluginIds) { + for (const [pluginId, state] of this._pluginNodes) { + if (nextActivePluginIds.has(pluginId)) { + continue; + } + if (this._activePluginIds.has(pluginId)) { + this._callManagedHook(pluginId, state.managedSlot, "onDeactivate", "dispose"); + } + for (const node of state.nodes) { + this._detachNodeFromMount(node); + } + if (!registeredPluginIds.has(pluginId)) { + this._callManagedHook(pluginId, state.managedSlot, "onDispose", "dispose"); + if (state.ownership === "host") { + for (const node of state.nodes) { + node.destroyRecursively(); + } + } + this._pluginNodes.delete(pluginId); + continue; + } + if (state.ownership === "host") { + for (const node of state.nodes) { + node.destroyRecursively(); + } + this._pluginNodes.delete(pluginId); + continue; + } + state.nodes = []; + } + } + _cleanupReplacedPluginNodes(previousState, nextNodes) { + const retainedNodes = new Set(nextNodes); + for (const node of previousState.nodes) { + if (retainedNodes.has(node)) { + continue; + } + this._detachNodeFromMount(node); + if (previousState.ownership === "host") { + node.destroyRecursively(); + } + } + } + _resolvePluginFailurePlaceholder(failure) { + if (!this._pluginFailurePlaceholder) { + return []; + } + try { + const placeholderSource = this._pluginFailurePlaceholder(failure, this._slotRegistry.context); + const placeholderNodes = asArray(placeholderSource); + for (const node of placeholderNodes) { + ensureValidNode(node, `${failure.pluginId}:error-placeholder`, this); + } + return placeholderNodes; + } catch (placeholderError) { + this._slotRegistry.reportPluginError({ + pluginId: failure.pluginId, + slot: String(this._slotName), + phase: "error_placeholder", + source: "core", + error: placeholderError + }); + return []; + } + } + _reconcileMountedNodes(desiredNodes) { + const desiredNodeSet = new Set(desiredNodes); + for (const node of this._mountedNodes) { + if (!desiredNodeSet.has(node)) { + if (node.parent === this) { + this.remove(node.id); + } + } + } + for (let index = 0;index < desiredNodes.length; index++) { + const node = desiredNodes[index]; + if (node.parent !== this) { + this.add(node, index); + continue; + } + const childAtIndex = this.getChildren()[index]; + if (childAtIndex?.id !== node.id) { + this.add(node, index); + } + } + this._mountedNodes = [...desiredNodes]; + } +} +// src/audio.ts +import { EventEmitter } from "events"; +import { readFile } from "node:fs/promises"; +function statusToError(action, status) { + return new Error(`Audio ${action} failed: ${status}`); +} +function toBytes(data) { + return data instanceof Uint8Array ? data : new Uint8Array(data); +} + +class Audio extends EventEmitter { + static create(options = {}) { + return new Audio(resolveRenderLib(), options); + } + lib; + defaultStartOptions; + engine = null; + groups = new Map; + playbackStarted = false; + mixerStarted = false; + constructor(lib, options) { + super(); + this.lib = lib; + this.defaultStartOptions = options.startOptions; + const createOptions = options.sampleRate == null && options.playbackChannels == null ? undefined : { + sampleRate: options.sampleRate == null ? undefined : Math.max(0, Math.trunc(options.sampleRate)), + playbackChannels: options.playbackChannels == null ? undefined : Math.max(0, Math.trunc(options.playbackChannels)) + }; + this.engine = this.lib.createAudioEngine(createOptions); + if (!this.engine) { + this.emitError("createAudioEngine", undefined, "Audio createAudioEngine returned null"); + return; + } + if (options.autoStart ?? false) { + this.start(this.defaultStartOptions); + } + } + emitError(action, status, message, cause) { + const error = message ? new Error(message) : statusToError(action, status ?? -1); + if (cause) + error.cause = cause; + this.emit("error", error, { action, status }); + } + start(options) { + if (this.playbackStarted) + return true; + const engine2 = this.engine; + if (!engine2) { + this.emitError("start", undefined, "Audio engine unavailable during start"); + return false; + } + const startOptions = options ?? this.defaultStartOptions; + const status = this.lib.audioStart(engine2, startOptions); + if (status !== 0) { + this.emitError("start", status); + return false; + } + this.playbackStarted = true; + this.mixerStarted = true; + this.emit("started"); + return true; + } + startMixer() { + if (this.mixerStarted) + return true; + const engine2 = this.engine; + if (!engine2) { + this.emitError("startMixer", undefined, "Audio engine unavailable during startMixer"); + return false; + } + const status = this.lib.audioStartMixer(engine2); + if (status !== 0) { + this.emitError("startMixer", status); + return false; + } + this.mixerStarted = true; + this.emit("mixerStarted"); + return true; + } + stop() { + if (!this.mixerStarted) + return true; + const engine2 = this.engine; + if (!engine2) { + this.emitError("stop", undefined, "Audio engine unavailable during stop"); + return false; + } + const status = this.lib.audioStop(engine2); + if (status !== 0) { + this.emitError("stop", status); + return false; + } + this.playbackStarted = false; + this.mixerStarted = false; + this.emit("stopped"); + return true; + } + isStarted() { + return this.playbackStarted; + } + isMixerStarted() { + return this.mixerStarted; + } + loadSound(data) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("loadSound", undefined, "Audio engine unavailable during loadSound"); + return null; + } + const result = this.lib.audioLoad(engine2, toBytes(data)); + if (result.status !== 0 || result.soundId == null) { + this.emitError("loadSound", result.status); + return null; + } + return result.soundId; + } + async loadSoundFile(filePath) { + const bytes = await readFile(filePath).catch((err) => { + this.emitError("loadSoundFile", undefined, `Failed to read file '${filePath}': ${err.message}`, err); + return null; + }); + if (bytes == null) + return null; + return this.loadSound(bytes); + } + unloadSound(sound) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("unloadSound", undefined, "Audio engine unavailable during unloadSound"); + return false; + } + const status = this.lib.audioUnload(engine2, sound); + if (status !== 0) { + this.emitError("unloadSound", status); + return false; + } + return true; + } + group(name) { + const existing = this.groups.get(name); + if (existing != null) { + return existing; + } + const engine2 = this.engine; + if (!engine2) { + this.emitError("group", undefined, "Audio engine unavailable during group"); + return null; + } + const result = this.lib.audioCreateGroup(engine2, name); + if (result.status !== 0 || result.groupId == null) { + this.emitError("group", result.status); + return null; + } + this.groups.set(name, result.groupId); + return result.groupId; + } + play(sound, options) { + const rawOptions = options ? { + volume: options.volume, + pan: options.pan, + loop: options.loop, + groupId: options.groupId ?? 0 + } : undefined; + const engine2 = this.engine; + if (!engine2) { + this.emitError("play", undefined, "Audio engine unavailable during play"); + return null; + } + const result = this.lib.audioPlay(engine2, sound, rawOptions); + if (result.status !== 0 || result.voiceId == null) { + this.emitError("play", result.status); + return null; + } + return result.voiceId; + } + stopVoice(voice) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("stopVoice", undefined, "Audio engine unavailable during stopVoice"); + return false; + } + const status = this.lib.audioStopVoice(engine2, voice); + if (status !== 0) { + this.emitError("stopVoice", status); + return false; + } + return true; + } + setVoiceGroup(voice, group) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("setVoiceGroup", undefined, "Audio engine unavailable during setVoiceGroup"); + return false; + } + const status = this.lib.audioSetVoiceGroup(engine2, voice, group); + if (status !== 0) { + this.emitError("setVoiceGroup", status); + return false; + } + return true; + } + setGroupVolume(group, volume) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("setGroupVolume", undefined, "Audio engine unavailable during setGroupVolume"); + return false; + } + const status = this.lib.audioSetGroupVolume(engine2, group, volume); + if (status !== 0) { + this.emitError("setGroupVolume", status); + return false; + } + return true; + } + setMasterVolume(volume) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("setMasterVolume", undefined, "Audio engine unavailable during setMasterVolume"); + return false; + } + const status = this.lib.audioSetMasterVolume(engine2, volume); + if (status !== 0) { + this.emitError("setMasterVolume", status); + return false; + } + return true; + } + mixFrames(frameCount, channels = 2) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("mixFrames", undefined, "Audio engine unavailable during mixFrames"); + return null; + } + const output = new Float32Array(frameCount * channels); + const status = this.lib.audioMixToBuffer(engine2, output, frameCount, channels); + if (status !== 0) { + this.emitError("mixFrames", status); + return null; + } + return output; + } + enableTap(capacityFrames = 8192) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("enableTap", undefined, "Audio engine unavailable during enableTap"); + return false; + } + const status = this.lib.audioEnableTap(engine2, true, capacityFrames); + if (status !== 0) { + this.emitError("enableTap", status); + return false; + } + return true; + } + disableTap() { + const engine2 = this.engine; + if (!engine2) { + this.emitError("enableTap", undefined, "Audio engine unavailable during disableTap"); + return false; + } + const status = this.lib.audioEnableTap(engine2, false, 0); + if (status !== 0) { + this.emitError("enableTap", status); + return false; + } + return true; + } + readTapFrames(frameCount, channels = 2) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("readTapFrames", undefined, "Audio engine unavailable during readTapFrames"); + return null; + } + const output = new Float32Array(frameCount * channels); + const result = this.lib.audioReadTap(engine2, output, frameCount, channels); + if (result.status !== 0) { + this.emitError("readTapFrames", result.status); + return null; + } + return { frames: output, framesRead: result.framesRead }; + } + listPlaybackDevices() { + const engine2 = this.engine; + if (!engine2) { + this.emitError("listPlaybackDevices", undefined, "Audio engine unavailable during listPlaybackDevices"); + return null; + } + const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine2); + if (refreshStatus !== 0) { + this.emitError("listPlaybackDevices", refreshStatus); + return null; + } + const count = this.lib.audioGetPlaybackDeviceCount(engine2); + const devices = []; + for (let index = 0;index < count; index += 1) { + devices.push({ + index, + name: this.lib.audioGetPlaybackDeviceName(engine2, index), + isDefault: this.lib.audioIsPlaybackDeviceDefault(engine2, index) + }); + } + return devices; + } + selectPlaybackDevice(index) { + const engine2 = this.engine; + if (!engine2) { + this.emitError("selectPlaybackDevice", undefined, "Audio engine unavailable during selectPlaybackDevice"); + return false; + } + const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine2); + if (refreshStatus !== 0) { + this.emitError("selectPlaybackDevice", refreshStatus); + return false; + } + const status = this.lib.audioSelectPlaybackDevice(engine2, index); + if (status !== 0) { + this.emitError("selectPlaybackDevice", status); + return false; + } + return true; + } + clearPlaybackDeviceSelection() { + const engine2 = this.engine; + if (!engine2) { + this.emitError("clearPlaybackDeviceSelection", undefined, "Audio engine unavailable during clearPlaybackDeviceSelection"); + return; + } + this.lib.audioClearPlaybackDeviceSelection(engine2); + } + getStats() { + const engine2 = this.engine; + if (!engine2) { + this.emitError("getStats", undefined, "Audio engine unavailable during getStats"); + return null; + } + const stats = this.lib.audioGetStats(engine2); + if (stats == null) { + this.emitError("getStats", undefined, "Failed to retrieve audio stats"); + } + return stats; + } + dispose() { + if (!this.engine) + return; + if (this.mixerStarted) { + this.stop(); + } + this.groups.clear(); + this.lib.destroyAudioEngine(this.engine); + this.engine = null; + this.emit("disposed"); + } +} +function setupAudio(options = {}) { + return Audio.create(options); +} +// src/renderables/FrameBuffer.ts +class FrameBufferRenderable extends Renderable { + frameBuffer; + respectAlpha; + constructor(ctx, options) { + super(ctx, options); + this.respectAlpha = options.respectAlpha || false; + this.frameBuffer = OptimizedBuffer.create(options.width, options.height, this._ctx.widthMethod, { + respectAlpha: this.respectAlpha, + id: options.id || `framebufferrenderable-${this.id}` + }); + } + onResize(width, height) { + if (width <= 0 || height <= 0) { + throw new Error(`Invalid resize dimensions for FrameBufferRenderable ${this.id}: ${width}x${height}`); + } + this.frameBuffer.resize(width, height); + super.onResize(width, height); + this.requestRender(); + } + renderSelf(buffer) { + if (!this.visible || this.isDestroyed) + return; + buffer.drawFrameBuffer(this.x, this.y, this.frameBuffer); + } + destroySelf() { + this.frameBuffer?.destroy(); + super.destroySelf(); + } +} + +// src/renderables/ASCIIFont.ts +class ASCIIFontRenderable extends FrameBufferRenderable { + selectable = true; + static _defaultOptions = { + text: "", + font: "tiny", + color: "#FFFFFF", + backgroundColor: "transparent", + selectionBg: undefined, + selectionFg: undefined, + selectable: true + }; + _text; + _font; + _color; + _backgroundColor; + _selectionBg; + _selectionFg; + lastLocalSelection = null; + selectionHelper; + constructor(ctx, options) { + const defaultOptions = ASCIIFontRenderable._defaultOptions; + const font = options.font || defaultOptions.font; + const text = options.text || defaultOptions.text; + const measurements = measureText({ text, font }); + super(ctx, { + flexShrink: 0, + ...options, + width: measurements.width || 1, + height: measurements.height || 1, + respectAlpha: true + }); + this._text = text; + this._font = font; + this._color = options.color || defaultOptions.color; + this._backgroundColor = options.backgroundColor || defaultOptions.backgroundColor; + this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : undefined; + this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : undefined; + this.selectable = options.selectable ?? true; + this.selectionHelper = new ASCIIFontSelectionHelper(() => this._text, () => this._font); + this.renderFontToBuffer(); + } + get text() { + return this._text; + } + set text(value) { + this._text = value; + this.updateDimensions(); + if (this.lastLocalSelection) { + this.selectionHelper.onLocalSelectionChanged(this.lastLocalSelection, this.width, this.height); + } + this.renderFontToBuffer(); + this.requestRender(); + } + get font() { + return this._font; + } + set font(value) { + this._font = value; + this.updateDimensions(); + if (this.lastLocalSelection) { + this.selectionHelper.onLocalSelectionChanged(this.lastLocalSelection, this.width, this.height); + } + this.renderFontToBuffer(); + this.requestRender(); + } + get color() { + return this._color; + } + set color(value) { + this._color = value; + this.renderFontToBuffer(); + this.requestRender(); + } + get backgroundColor() { + return this._backgroundColor; + } + set backgroundColor(value) { + this._backgroundColor = value; + this.renderFontToBuffer(); + this.requestRender(); + } + updateDimensions() { + const measurements = measureText({ text: this._text, font: this._font }); + this.width = measurements.width; + this.height = measurements.height; + } + shouldStartSelection(x, y) { + const localX = x - this.x; + const localY = y - this.y; + return this.selectionHelper.shouldStartSelection(localX, localY, this.width, this.height); + } + onSelectionChanged(selection) { + const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y); + this.lastLocalSelection = localSelection; + const changed = this.selectionHelper.onLocalSelectionChanged(localSelection, this.width, this.height); + if (changed) { + this.renderFontToBuffer(); + this.requestRender(); + } + return changed; + } + getSelectedText() { + const selection = this.selectionHelper.getSelection(); + if (!selection) + return ""; + return this._text.slice(selection.start, selection.end); + } + hasSelection() { + return this.selectionHelper.hasSelection(); + } + onResize(width, height) { + super.onResize(width, height); + this.renderFontToBuffer(); + } + renderFontToBuffer() { + if (this.isDestroyed) + return; + this.frameBuffer.clear(parseColor(this._backgroundColor)); + renderFontToFrameBuffer(this.frameBuffer, { + text: this._text, + x: 0, + y: 0, + color: this.color, + backgroundColor: this._backgroundColor, + font: this._font + }); + const selection = this.selectionHelper.getSelection(); + if (selection && (this._selectionBg || this._selectionFg)) { + this.renderSelectionHighlight(selection); + } + } + renderSelectionHighlight(selection) { + if (!this._selectionBg && !this._selectionFg) + return; + const selectedText = this._text.slice(selection.start, selection.end); + if (!selectedText) + return; + const positions = getCharacterPositions(this._text, this._font); + const startX = positions[selection.start] || 0; + const endX = selection.end < positions.length ? positions[selection.end] : measureText({ text: this._text, font: this._font }).width; + if (this._selectionBg) { + this.frameBuffer.fillRect(startX, 0, endX - startX, this.height, parseColor(this._selectionBg)); + } + if (this._selectionFg || this._selectionBg) { + renderFontToFrameBuffer(this.frameBuffer, { + text: selectedText, + x: startX, + y: 0, + color: this._selectionFg ? this._selectionFg : this._color, + backgroundColor: this._selectionBg ? this._selectionBg : this._backgroundColor, + font: this._font + }); + } + } +} +// src/renderables/composition/constructs.ts +function Generic(props, ...children) { + return h(VRenderable, props || {}, ...children); +} +function Box(props, ...children) { + return h(BoxRenderable, props || {}, ...children); +} +function Text(props, ...children) { + return h(TextRenderable, props || {}, ...children); +} +function ASCIIFont(props, ...children) { + return h(ASCIIFontRenderable, props || {}, ...children); +} +function Input(props, ...children) { + return h(InputRenderable, props || {}, ...children); +} +function Select(props, ...children) { + return h(SelectRenderable, props || {}, ...children); +} +function TabSelect(props, ...children) { + return h(TabSelectRenderable, props || {}, ...children); +} +function FrameBuffer(props, ...children) { + return h(FrameBufferRenderable, props, ...children); +} +function Code(props, ...children) { + return h(CodeRenderable, props, ...children); +} +function ScrollBox(props, ...children) { + return h(ScrollBoxRenderable, props || {}, ...children); +} +function StyledText2(props, ...children) { + const styledProps = props; + const textNodeOptions = { + ...styledProps, + attributes: styledProps?.attributes ?? 0 + }; + const textNode = new TextNodeRenderable(textNodeOptions); + for (const child of children) { + textNode.add(child); + } + return textNode; +} +var vstyles = { + bold: (...children) => StyledText2({ attributes: TextAttributes.BOLD }, ...children), + italic: (...children) => StyledText2({ attributes: TextAttributes.ITALIC }, ...children), + underline: (...children) => StyledText2({ attributes: TextAttributes.UNDERLINE }, ...children), + dim: (...children) => StyledText2({ attributes: TextAttributes.DIM }, ...children), + blink: (...children) => StyledText2({ attributes: TextAttributes.BLINK }, ...children), + inverse: (...children) => StyledText2({ attributes: TextAttributes.INVERSE }, ...children), + hidden: (...children) => StyledText2({ attributes: TextAttributes.HIDDEN }, ...children), + strikethrough: (...children) => StyledText2({ attributes: TextAttributes.STRIKETHROUGH }, ...children), + boldItalic: (...children) => StyledText2({ attributes: TextAttributes.BOLD | TextAttributes.ITALIC }, ...children), + boldUnderline: (...children) => StyledText2({ attributes: TextAttributes.BOLD | TextAttributes.UNDERLINE }, ...children), + italicUnderline: (...children) => StyledText2({ attributes: TextAttributes.ITALIC | TextAttributes.UNDERLINE }, ...children), + boldItalicUnderline: (...children) => StyledText2({ attributes: TextAttributes.BOLD | TextAttributes.ITALIC | TextAttributes.UNDERLINE }, ...children), + color: (color, ...children) => StyledText2({ fg: color }, ...children), + bgColor: (bgColor, ...children) => StyledText2({ bg: bgColor }, ...children), + fg: (color, ...children) => StyledText2({ fg: color }, ...children), + bg: (bgColor, ...children) => StyledText2({ bg: bgColor }, ...children), + styled: (attributes = 0, ...children) => StyledText2({ attributes }, ...children) +}; +// src/renderables/composition/VRenderable.ts +class VRenderable extends Renderable { + options; + constructor(ctx, options) { + super(ctx, options); + this.options = options; + } + renderSelf(buffer, deltaTime) { + if (this.options.render) { + this.options.render.call(this.options, buffer, deltaTime, this); + } + } +} +// src/renderables/LineNumberRenderable.ts +var DEFAULT_GUTTER_FG = "#888888"; +var DEFAULT_GUTTER_BG = "transparent"; + +class GutterRenderable extends Renderable { + target; + _fg; + _bg; + _minWidth; + _paddingRight; + _lineColorsGutter; + _lineColorsContent; + _lineSigns; + _lineNumberOffset; + _hideLineNumbers; + _lineNumbers; + _maxBeforeWidth = 0; + _maxAfterWidth = 0; + _lastKnownLineCount = 0; + _lastKnownScrollY = 0; + constructor(ctx, target, options) { + super(ctx, { + id: options.id, + width: "auto", + height: "auto", + flexGrow: 0, + flexShrink: 0, + buffered: options.buffered + }); + this.target = target; + this._fg = options.fg; + this._bg = options.bg; + this._minWidth = options.minWidth; + this._paddingRight = options.paddingRight; + this._lineColorsGutter = options.lineColorsGutter; + this._lineColorsContent = options.lineColorsContent; + this._lineSigns = options.lineSigns; + this._lineNumberOffset = options.lineNumberOffset; + this._hideLineNumbers = options.hideLineNumbers; + this._lineNumbers = options.lineNumbers ?? new Map; + this._lastKnownLineCount = this.target.virtualLineCount; + this._lastKnownScrollY = this.target.scrollY; + this.calculateSignWidths(); + this.setupMeasureFunc(); + this.onLifecyclePass = () => { + const currentLineCount = this.target.virtualLineCount; + if (currentLineCount !== this._lastKnownLineCount) { + this._lastKnownLineCount = currentLineCount; + this.yogaNode.markDirty(); + this.requestRender(); + } + }; + } + setupMeasureFunc() { + const measureFunc = (width, widthMode, height, heightMode) => { + const gutterWidth = this.calculateWidth(); + const gutterHeight = this.target.virtualLineCount; + return { + width: gutterWidth, + height: gutterHeight + }; + }; + this.yogaNode.setMeasureFunc(measureFunc); + } + remeasure() { + this.yogaNode.markDirty(); + } + setLineNumberOffset(offset) { + if (this._lineNumberOffset !== offset) { + this._lineNumberOffset = offset; + this.yogaNode.markDirty(); + this.requestRender(); + } + } + setHideLineNumbers(hideLineNumbers) { + this._hideLineNumbers = hideLineNumbers; + this.yogaNode.markDirty(); + this.requestRender(); + } + setLineNumbers(lineNumbers) { + this._lineNumbers = lineNumbers; + this.yogaNode.markDirty(); + this.requestRender(); + } + calculateSignWidths() { + this._maxBeforeWidth = 0; + this._maxAfterWidth = 0; + for (const sign of this._lineSigns.values()) { + if (sign.before) { + const width = stringWidth(sign.before); + this._maxBeforeWidth = Math.max(this._maxBeforeWidth, width); + } + if (sign.after) { + const width = stringWidth(sign.after); + this._maxAfterWidth = Math.max(this._maxAfterWidth, width); + } + } + } + calculateWidth() { + const totalLines = this.target.virtualLineCount; + let maxLineNumber = totalLines + this._lineNumberOffset; + if (this._lineNumbers.size > 0) { + for (const customLineNum of this._lineNumbers.values()) { + maxLineNumber = Math.max(maxLineNumber, customLineNum); + } + } + const digits = maxLineNumber > 0 ? Math.floor(Math.log10(maxLineNumber)) + 1 : 1; + const baseWidth = Math.max(this._minWidth, digits + this._paddingRight + 1); + return baseWidth + this._maxBeforeWidth + this._maxAfterWidth; + } + setLineColors(lineColorsGutter, lineColorsContent) { + this._lineColorsGutter = lineColorsGutter; + this._lineColorsContent = lineColorsContent; + this.requestRender(); + } + get fg() { + return this._fg; + } + setFg(fg2) { + if (this._fg !== fg2) { + this._fg = fg2; + this.requestRender(); + } + } + get bg() { + return this._bg; + } + setBg(bg2) { + if (this._bg !== bg2) { + this._bg = bg2; + this.requestRender(); + } + } + getLineColors() { + return { + gutter: this._lineColorsGutter, + content: this._lineColorsContent + }; + } + setLineSigns(lineSigns) { + const oldMaxBefore = this._maxBeforeWidth; + const oldMaxAfter = this._maxAfterWidth; + this._lineSigns = lineSigns; + this.calculateSignWidths(); + if (this._maxBeforeWidth !== oldMaxBefore || this._maxAfterWidth !== oldMaxAfter) { + this.yogaNode.markDirty(); + } + this.requestRender(); + } + getLineSigns() { + return this._lineSigns; + } + renderSelf(buffer) { + const currentScrollY = this.target.scrollY; + const scrollChanged = currentScrollY !== this._lastKnownScrollY; + if (this.buffered && !this.isDirty && !scrollChanged) { + return; + } + this._lastKnownScrollY = currentScrollY; + this.refreshFrameBuffer(buffer); + } + refreshFrameBuffer(buffer) { + const startX = this.buffered ? 0 : this.x; + const startY = this.buffered ? 0 : this.y; + if (this.buffered) { + buffer.clear(this._bg); + } else if (this._bg.a > 0) { + buffer.fillRect(startX, startY, this.width, this.height, this._bg); + } + const lineInfo = this.target.lineInfo; + if (!lineInfo || !lineInfo.lineSources) + return; + const sources = lineInfo.lineSources; + let lastSource = -1; + const startLine = this.target.scrollY; + if (startLine >= sources.length) + return; + lastSource = startLine > 0 ? sources[startLine - 1] : -1; + for (let i = 0;i < this.height; i++) { + const visualLineIndex = startLine + i; + if (visualLineIndex >= sources.length) + break; + const logicalLine = sources[visualLineIndex]; + const lineBg = this._lineColorsGutter.get(logicalLine) ?? this._bg; + if (lineBg !== this._bg) { + buffer.fillRect(startX, startY + i, this.width, 1, lineBg); + } + if (logicalLine === lastSource) {} else { + let currentX = startX; + const sign = this._lineSigns.get(logicalLine); + if (sign?.before) { + const beforeWidth = stringWidth(sign.before); + const padding = this._maxBeforeWidth - beforeWidth; + currentX += padding; + const beforeColor = sign.beforeColor ? parseColor(sign.beforeColor) : this._fg; + buffer.drawText(sign.before, currentX, startY + i, beforeColor, lineBg); + currentX += beforeWidth; + } else if (this._maxBeforeWidth > 0) { + currentX += this._maxBeforeWidth; + } + if (!this._hideLineNumbers.has(logicalLine)) { + const customLineNum = this._lineNumbers.get(logicalLine); + const lineNum = customLineNum !== undefined ? customLineNum : logicalLine + 1 + this._lineNumberOffset; + const lineNumStr = lineNum.toString(); + const lineNumWidth = lineNumStr.length; + const availableSpace = this.width - this._maxBeforeWidth - this._maxAfterWidth - this._paddingRight; + const lineNumX = startX + this._maxBeforeWidth + 1 + availableSpace - lineNumWidth - 1; + if (lineNumX >= startX + this._maxBeforeWidth + 1) { + buffer.drawText(lineNumStr, lineNumX, startY + i, this._fg, lineBg); + } + } + if (sign?.after) { + const afterX = startX + this.width - this._paddingRight - this._maxAfterWidth; + const afterColor = sign.afterColor ? parseColor(sign.afterColor) : this._fg; + buffer.drawText(sign.after, afterX, startY + i, afterColor, lineBg); + } + } + lastSource = logicalLine; + } + } +} +function darkenColor(color) { + return RGBA.fromValues(color.r * 0.8, color.g * 0.8, color.b * 0.8, color.a); +} + +class LineNumberRenderable extends Renderable { + gutter = null; + target = null; + _lineColorsGutter; + _lineColorsContent; + _lineSigns; + _fg; + _bg; + _minWidth; + _paddingRight; + _lineNumberOffset; + _hideLineNumbers; + _lineNumbers; + _isDestroying = false; + handleLineInfoChange = () => { + this.gutter?.remeasure(); + this.requestRender(); + }; + parseLineColor(line, color) { + if (typeof color === "object" && "gutter" in color) { + const config = color; + if (config.gutter) { + this._lineColorsGutter.set(line, parseColor(config.gutter)); + } + if (config.content) { + this._lineColorsContent.set(line, parseColor(config.content)); + } else if (config.gutter) { + this._lineColorsContent.set(line, darkenColor(parseColor(config.gutter))); + } + } else { + const parsedColor = parseColor(color); + this._lineColorsGutter.set(line, parsedColor); + this._lineColorsContent.set(line, darkenColor(parsedColor)); + } + } + constructor(ctx, options) { + super(ctx, { + ...options, + flexDirection: "row", + height: "auto" + }); + this._fg = parseColor(options.fg ?? DEFAULT_GUTTER_FG); + this._bg = parseColor(options.bg ?? DEFAULT_GUTTER_BG); + this._minWidth = options.minWidth ?? 3; + this._paddingRight = options.paddingRight ?? 1; + this._lineNumberOffset = options.lineNumberOffset ?? 0; + this._hideLineNumbers = options.hideLineNumbers ?? new Set; + this._lineNumbers = options.lineNumbers ?? new Map; + this._lineColorsGutter = new Map; + this._lineColorsContent = new Map; + if (options.lineColors) { + for (const [line, color] of options.lineColors) { + this.parseLineColor(line, color); + } + } + this._lineSigns = new Map; + if (options.lineSigns) { + for (const [line, sign] of options.lineSigns) { + this._lineSigns.set(line, sign); + } + } + if (options.target) { + this.setTarget(options.target); + } + } + setTarget(target) { + if (this.target === target) + return; + if (this.target) { + this.target.off("line-info-change", this.handleLineInfoChange); + super.remove(this.target.id); + } + if (this.gutter) { + super.remove(this.gutter.id); + this.gutter = null; + } + this.target = target; + this.target.on("line-info-change", this.handleLineInfoChange); + this.gutter = new GutterRenderable(this.ctx, this.target, { + fg: this._fg, + bg: this._bg, + minWidth: this._minWidth, + paddingRight: this._paddingRight, + lineColorsGutter: this._lineColorsGutter, + lineColorsContent: this._lineColorsContent, + lineSigns: this._lineSigns, + lineNumberOffset: this._lineNumberOffset, + hideLineNumbers: this._hideLineNumbers, + lineNumbers: this._lineNumbers, + id: this.id ? `${this.id}-gutter` : undefined, + buffered: true + }); + super.add(this.gutter); + super.add(this.target); + } + add(child) { + if (!this.target && "lineInfo" in child && "lineCount" in child && "virtualLineCount" in child && "scrollY" in child) { + this.setTarget(child); + return this.getChildrenCount() - 1; + } + return -1; + } + remove(id) { + if (this._isDestroying) { + super.remove(id); + return; + } + if (this.gutter && id === this.gutter.id) { + throw new Error("LineNumberRenderable: Cannot remove gutter directly."); + } + if (this.target && id === this.target.id) { + throw new Error("LineNumberRenderable: Cannot remove target directly. Use clearTarget() instead."); + } + super.remove(id); + } + destroyRecursively() { + this._isDestroying = true; + if (this.target) { + this.target.off("line-info-change", this.handleLineInfoChange); + } + super.destroyRecursively(); + this.gutter = null; + this.target = null; + } + clearTarget() { + if (this.target) { + this.target.off("line-info-change", this.handleLineInfoChange); + super.remove(this.target.id); + this.target = null; + } + if (this.gutter) { + super.remove(this.gutter.id); + this.gutter = null; + } + } + renderSelf(buffer) { + if (!this.target || !this.gutter) + return; + const lineInfo = this.target.lineInfo; + if (!lineInfo || !lineInfo.lineSources) + return; + const sources = lineInfo.lineSources; + const startLine = this.target.scrollY; + if (startLine >= sources.length) + return; + const gutterWidth = this.gutter.visible ? this.gutter.width : 0; + const contentWidth = this.width - gutterWidth; + for (let i = 0;i < this.height; i++) { + const visualLineIndex = startLine + i; + if (visualLineIndex >= sources.length) + break; + const logicalLine = sources[visualLineIndex]; + const lineBg = this._lineColorsContent.get(logicalLine); + if (lineBg) { + buffer.fillRect(this.x + gutterWidth, this.y + i, contentWidth, 1, lineBg); + } + } + } + set showLineNumbers(value) { + if (this.gutter) { + this.gutter.visible = value; + } + } + get showLineNumbers() { + return this.gutter?.visible ?? false; + } + get fg() { + return this._fg; + } + set fg(value) { + const parsed = parseColor(value ?? DEFAULT_GUTTER_FG); + if (this._fg !== parsed) { + this._fg = parsed; + this.gutter?.setFg(parsed); + } + } + get bg() { + return this._bg; + } + set bg(value) { + const parsed = parseColor(value ?? DEFAULT_GUTTER_BG); + if (this._bg !== parsed) { + this._bg = parsed; + this.gutter?.setBg(parsed); + } + } + setLineColor(line, color) { + this.parseLineColor(line, color); + if (this.gutter) { + this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent); + } + } + clearLineColor(line) { + this._lineColorsGutter.delete(line); + this._lineColorsContent.delete(line); + if (this.gutter) { + this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent); + } + } + clearAllLineColors() { + this._lineColorsGutter.clear(); + this._lineColorsContent.clear(); + if (this.gutter) { + this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent); + } + } + setLineColors(lineColors) { + this._lineColorsGutter.clear(); + this._lineColorsContent.clear(); + for (const [line, color] of lineColors) { + this.parseLineColor(line, color); + } + if (this.gutter) { + this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent); + } + } + getLineColors() { + return { + gutter: this._lineColorsGutter, + content: this._lineColorsContent + }; + } + setLineSign(line, sign) { + this._lineSigns.set(line, sign); + if (this.gutter) { + this.gutter.setLineSigns(this._lineSigns); + } + } + clearLineSign(line) { + this._lineSigns.delete(line); + if (this.gutter) { + this.gutter.setLineSigns(this._lineSigns); + } + } + clearAllLineSigns() { + this._lineSigns.clear(); + if (this.gutter) { + this.gutter.setLineSigns(this._lineSigns); + } + } + setLineSigns(lineSigns) { + this._lineSigns.clear(); + for (const [line, sign] of lineSigns) { + this._lineSigns.set(line, sign); + } + if (this.gutter) { + this.gutter.setLineSigns(this._lineSigns); + } + } + getLineSigns() { + return this._lineSigns; + } + set lineNumberOffset(value) { + if (this._lineNumberOffset !== value) { + this._lineNumberOffset = value; + if (this.gutter) { + this.gutter.setLineNumberOffset(value); + } + } + } + get lineNumberOffset() { + return this._lineNumberOffset; + } + setHideLineNumbers(hideLineNumbers) { + this._hideLineNumbers = hideLineNumbers; + if (this.gutter) { + this.gutter.setHideLineNumbers(hideLineNumbers); + } + } + getHideLineNumbers() { + return this._hideLineNumbers; + } + setLineNumbers(lineNumbers) { + this._lineNumbers = lineNumbers; + if (this.gutter) { + this.gutter.setLineNumbers(lineNumbers); + } + } + getLineNumbers() { + return this._lineNumbers; + } + highlightLines(startLine, endLine, color) { + for (let i = startLine;i <= endLine; i++) { + this.parseLineColor(i, color); + } + if (this.gutter) { + this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent); + } + } + clearHighlightLines(startLine, endLine) { + for (let i = startLine;i <= endLine; i++) { + this._lineColorsGutter.delete(i); + this._lineColorsContent.delete(i); + } + if (this.gutter) { + this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent); + } + } +} +// ../../node_modules/.bun/diff@9.0.0/node_modules/diff/libesm/patch/parse.js +function parsePatch(uniDiff) { + const diffstr = uniDiff.split(/\n/), list = []; + let i = 0; + function isGitDiffHeader(line) { + return /^diff --git /.test(line); + } + function isDiffHeader(line) { + return isGitDiffHeader(line) || /^Index:\s/.test(line) || /^diff(?: -r \w+)+\s/.test(line); + } + function isFileHeader(line) { + return /^(---|\+\+\+)\s/.test(line); + } + function isHunkHeader(line) { + return /^@@\s/.test(line); + } + function parseIndex() { + var _a; + const index = {}; + index.hunks = []; + list.push(index); + let seenDiffHeader = false; + while (i < diffstr.length) { + const line = diffstr[i]; + if (isFileHeader(line) || isHunkHeader(line)) { + break; + } + if (isGitDiffHeader(line)) { + if (seenDiffHeader) { + return; + } + seenDiffHeader = true; + index.isGit = true; + const paths = parseGitDiffHeader(line); + if (paths) { + index.oldFileName = paths.oldFileName; + index.newFileName = paths.newFileName; + } + i++; + while (i < diffstr.length) { + const extLine = diffstr[i]; + if (isFileHeader(extLine) || isHunkHeader(extLine) || isDiffHeader(extLine)) { + break; + } + const renameFromMatch = /^rename from (.*)/.exec(extLine); + if (renameFromMatch) { + index.oldFileName = "a/" + unquoteIfQuoted(renameFromMatch[1]); + index.isRename = true; + } + const renameToMatch = /^rename to (.*)/.exec(extLine); + if (renameToMatch) { + index.newFileName = "b/" + unquoteIfQuoted(renameToMatch[1]); + index.isRename = true; + } + const copyFromMatch = /^copy from (.*)/.exec(extLine); + if (copyFromMatch) { + index.oldFileName = "a/" + unquoteIfQuoted(copyFromMatch[1]); + index.isCopy = true; + } + const copyToMatch = /^copy to (.*)/.exec(extLine); + if (copyToMatch) { + index.newFileName = "b/" + unquoteIfQuoted(copyToMatch[1]); + index.isCopy = true; + } + const newFileModeMatch = /^new file mode (\d+)/.exec(extLine); + if (newFileModeMatch) { + index.isCreate = true; + index.newMode = newFileModeMatch[1]; + } + const deletedFileModeMatch = /^deleted file mode (\d+)/.exec(extLine); + if (deletedFileModeMatch) { + index.isDelete = true; + index.oldMode = deletedFileModeMatch[1]; + } + const oldModeMatch = /^old mode (\d+)/.exec(extLine); + if (oldModeMatch) { + index.oldMode = oldModeMatch[1]; + } + const newModeMatch = /^new mode (\d+)/.exec(extLine); + if (newModeMatch) { + index.newMode = newModeMatch[1]; + } + if (/^Binary files /.test(extLine)) { + index.isBinary = true; + } + i++; + } + continue; + } else if (isDiffHeader(line)) { + if (seenDiffHeader) { + return; + } + seenDiffHeader = true; + const headerMatch = /^(?:Index:|diff(?: -r \w+)+)\s+/.exec(line); + if (headerMatch) { + index.index = line.substring(headerMatch[0].length).trim(); + } + } + i++; + } + parseFileHeader(index); + parseFileHeader(index); + if (index.oldFileName === undefined !== (index.newFileName === undefined)) { + throw new Error("Missing " + (index.oldFileName !== undefined ? '"+++ ..."' : '"--- ..."') + " file header for " + ((_a = index.oldFileName) !== null && _a !== undefined ? _a : index.newFileName)); + } + while (i < diffstr.length) { + const line = diffstr[i]; + if (isDiffHeader(line) || isFileHeader(line) || /^===================================================================/.test(line)) { + break; + } else if (isHunkHeader(line)) { + index.hunks.push(parseHunk()); + } else { + i++; + } + } + } + function parseGitDiffHeader(line) { + const rest = line.substring("diff --git ".length); + if (rest.startsWith('"')) { + const oldPath = parseQuotedFileName(rest); + if (oldPath === null) { + return null; + } + const afterOld = rest.substring(oldPath.rawLength + 1); + let newFileName; + if (afterOld.startsWith('"')) { + const newPath = parseQuotedFileName(afterOld); + if (newPath === null) { + return null; + } + newFileName = newPath.fileName; + } else { + newFileName = afterOld; + } + return { + oldFileName: oldPath.fileName, + newFileName + }; + } + const quoteIdx = rest.indexOf('"'); + if (quoteIdx > 0) { + const oldFileName = rest.substring(0, quoteIdx - 1); + const newPath = parseQuotedFileName(rest.substring(quoteIdx)); + if (newPath === null) { + return null; + } + return { + oldFileName, + newFileName: newPath.fileName + }; + } + if (rest.startsWith("a/")) { + const splits = []; + let idx = 0; + while (true) { + idx = rest.indexOf(" b/", idx + 1); + if (idx === -1) { + break; + } + splits.push(idx); + } + if (splits.length > 0) { + const mid = splits[Math.floor(splits.length / 2)]; + return { + oldFileName: rest.substring(0, mid), + newFileName: rest.substring(mid + 1) + }; + } + } + return null; + } + function unquoteIfQuoted(s) { + if (s.startsWith('"')) { + const parsed = parseQuotedFileName(s); + if (parsed) { + return parsed.fileName; + } + } + return s; + } + function parseQuotedFileName(s) { + if (!s.startsWith('"')) { + return null; + } + let result = ""; + let j = 1; + while (j < s.length) { + if (s[j] === '"') { + return { fileName: result, rawLength: j + 1 }; + } + if (s[j] === "\\" && j + 1 < s.length) { + j++; + switch (s[j]) { + case "a": + result += "\x07"; + break; + case "b": + result += "\b"; + break; + case "f": + result += "\f"; + break; + case "n": + result += ` +`; + break; + case "r": + result += "\r"; + break; + case "t": + result += "\t"; + break; + case "v": + result += "\v"; + break; + case "\\": + result += "\\"; + break; + case '"': + result += '"'; + break; + case "0": + case "1": + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": { + if (j + 2 >= s.length || s[j + 1] < "0" || s[j + 1] > "7" || s[j + 2] < "0" || s[j + 2] > "7") { + return null; + } + const bytes = [parseInt(s.substring(j, j + 3), 8)]; + j += 3; + while (s[j] === "\\" && s[j + 1] >= "0" && s[j + 1] <= "7") { + if (j + 3 >= s.length || s[j + 2] < "0" || s[j + 2] > "7" || s[j + 3] < "0" || s[j + 3] > "7") { + return null; + } + bytes.push(parseInt(s.substring(j + 1, j + 4), 8)); + j += 4; + } + result += new TextDecoder("utf-8").decode(new Uint8Array(bytes)); + continue; + } + default: + return null; + } + } else { + result += s[j]; + } + j++; + } + return null; + } + function parseFileHeader(index) { + const fileHeaderMatch = /^(---|\+\+\+)\s+/.exec(diffstr[i]); + if (fileHeaderMatch) { + const prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split("\t", 2), header = (data[1] || "").trim(); + let fileName = data[0]; + if (fileName.startsWith('"')) { + fileName = unquoteIfQuoted(fileName); + } else { + fileName = fileName.replace(/\\\\/g, "\\"); + } + if (prefix === "---") { + index.oldFileName = fileName; + index.oldHeader = header; + } else { + index.newFileName = fileName; + index.newHeader = header; + } + i++; + } + } + function parseHunk() { + var _a; + const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); + const hunk = { + oldStart: +chunkHeader[1], + oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2], + newStart: +chunkHeader[3], + newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4], + lines: [] + }; + if (hunk.oldLines === 0) { + hunk.oldStart += 1; + } + if (hunk.newLines === 0) { + hunk.newStart += 1; + } + let addCount = 0, removeCount = 0; + for (;i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a = diffstr[i]) === null || _a === undefined ? undefined : _a.startsWith("\\"))); i++) { + const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0]; + if (operation === "+" || operation === "-" || operation === " " || operation === "\\") { + hunk.lines.push(diffstr[i]); + if (operation === "+") { + addCount++; + } else if (operation === "-") { + removeCount++; + } else if (operation === " ") { + addCount++; + removeCount++; + } + } else { + throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`); + } + } + if (!addCount && hunk.newLines === 1) { + hunk.newLines = 0; + } + if (!removeCount && hunk.oldLines === 1) { + hunk.oldLines = 0; + } + if (addCount !== hunk.newLines) { + throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1)); + } + if (removeCount !== hunk.oldLines) { + throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1)); + } + if (i < diffstr.length && diffstr[i] && /^[+ -]/.test(diffstr[i]) && !isFileHeader(diffstr[i])) { + throw new Error("Hunk at line " + (chunkHeaderIndex + 1) + " has more lines than expected (expected " + hunk.oldLines + " old lines and " + hunk.newLines + " new lines)"); + } + return hunk; + } + while (i < diffstr.length) { + parseIndex(); + } + return list; +} +// src/renderables/Diff.ts +class DiffRenderable extends Renderable { + _diff; + _syncScroll = false; + _view; + _parsedDiff = null; + _parseError = null; + _hunkStartLines = []; + _hunkRowOffsets = null; + _fg; + _filetype; + _syntaxStyle; + _wrapMode; + _conceal; + _selectionBg; + _selectionFg; + _treeSitterClient; + _showLineNumbers; + _lineNumberFg; + _lineNumberBg; + _addedBg; + _removedBg; + _contextBg; + _addedContentBg; + _removedContentBg; + _contextContentBg; + _addedSignColor; + _removedSignColor; + _addedLineNumberBg; + _removedLineNumberBg; + leftSide = null; + rightSide = null; + leftSideAdded = false; + rightSideAdded = false; + leftCodeRenderable = null; + rightCodeRenderable = null; + pendingRebuild = false; + _lastWidth = 0; + errorTextRenderable = null; + errorCodeRenderable = null; + _waitingForHighlight = false; + _lineInfoChangeHandler = null; + constructor(ctx, options) { + super(ctx, { + ...options, + flexDirection: options.view === "split" ? "row" : "column" + }); + this._diff = options.diff ?? ""; + this._syncScroll = options.syncScroll ?? false; + this._view = options.view ?? "unified"; + this._fg = options.fg ? parseColor(options.fg) : undefined; + this._filetype = options.filetype; + this._syntaxStyle = options.syntaxStyle; + this._wrapMode = options.wrapMode; + this._conceal = options.conceal ?? false; + this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : undefined; + this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : undefined; + this._treeSitterClient = options.treeSitterClient; + this._showLineNumbers = options.showLineNumbers ?? true; + this._lineNumberFg = parseColor(options.lineNumberFg ?? "#888888"); + this._lineNumberBg = parseColor(options.lineNumberBg ?? "transparent"); + this._addedBg = parseColor(options.addedBg ?? "#1a4d1a"); + this._removedBg = parseColor(options.removedBg ?? "#4d1a1a"); + this._contextBg = parseColor(options.contextBg ?? "transparent"); + this._addedContentBg = options.addedContentBg ? parseColor(options.addedContentBg) : null; + this._removedContentBg = options.removedContentBg ? parseColor(options.removedContentBg) : null; + this._contextContentBg = options.contextContentBg ? parseColor(options.contextContentBg) : null; + this._addedSignColor = parseColor(options.addedSignColor ?? "#22c55e"); + this._removedSignColor = parseColor(options.removedSignColor ?? "#ef4444"); + this._addedLineNumberBg = parseColor(options.addedLineNumberBg ?? "transparent"); + this._removedLineNumberBg = parseColor(options.removedLineNumberBg ?? "transparent"); + if (this._diff) { + this.parseDiff(); + this.buildView(); + } + } + parseDiff() { + if (!this._diff) { + this._parsedDiff = null; + this._parseError = null; + return; + } + try { + const patches = parsePatch(this._diff); + if (patches.length === 0) { + this._parsedDiff = null; + this._parseError = null; + return; + } + this._parsedDiff = patches[0]; + this._parseError = null; + } catch (error) { + this._parsedDiff = null; + this._parseError = error instanceof Error ? error : new Error(String(error)); + } + } + buildView() { + this._hunkStartLines = []; + this.invalidateHunkRowOffsets(); + if (this._parseError) { + this.buildErrorView(); + return; + } + if (!this._parsedDiff || this._parsedDiff.hunks.length === 0) { + return; + } + if (this._view === "unified") { + this.buildUnifiedView(); + } else { + this.buildSplitView(); + } + } + onMouseEvent(event) { + if (event.type !== "scroll" || this._view !== "split" || !this._syncScroll) + return; + if (!this.leftCodeRenderable || !this.rightCodeRenderable) + return; + if (!event.target) + return; + if (this.isInsideSide(event.target, "left")) { + this.rightCodeRenderable.scrollY = this.leftCodeRenderable.scrollY; + this.rightCodeRenderable.scrollX = this.leftCodeRenderable.scrollX; + } else if (this.isInsideSide(event.target, "right")) { + this.leftCodeRenderable.scrollY = this.rightCodeRenderable.scrollY; + this.leftCodeRenderable.scrollX = this.rightCodeRenderable.scrollX; + } + } + isInsideSide(target, side) { + const container = side === "left" ? this.leftCodeRenderable : this.rightCodeRenderable; + let current = target; + while (current) { + if (current === container) + return true; + current = current.parent; + } + return false; + } + onResize(width, height) { + super.onResize(width, height); + if (this._view === "split" && this._wrapMode !== "none" && this._wrapMode !== undefined) { + if (this._lastWidth !== width) { + this._lastWidth = width; + this.requestRebuild(); + } + } + } + requestRebuild() { + if (this.pendingRebuild) { + return; + } + this.pendingRebuild = true; + queueMicrotask(() => { + if (!this.isDestroyed && this.pendingRebuild) { + this.pendingRebuild = false; + this.buildView(); + this.requestRender(); + } + }); + } + invalidateHunkRowOffsets() { + this._hunkRowOffsets = null; + } + rebuildView() { + if (this._view === "split") { + this.requestRebuild(); + } else { + this.buildView(); + } + } + handleLineInfoChange = () => { + this.invalidateHunkRowOffsets(); + if (!this._waitingForHighlight) + return; + if (!this.leftCodeRenderable || !this.rightCodeRenderable) + return; + const leftIsHighlighting = this.leftCodeRenderable.isHighlighting; + const rightIsHighlighting = this.rightCodeRenderable.isHighlighting; + if (!leftIsHighlighting && !rightIsHighlighting) { + this._waitingForHighlight = false; + this.requestRebuild(); + } + }; + attachLineInfoListeners() { + if (!this.leftCodeRenderable && !this.rightCodeRenderable) + return; + this._lineInfoChangeHandler ??= this.handleLineInfoChange; + if (this.leftCodeRenderable) { + this.leftCodeRenderable.off("line-info-change", this._lineInfoChangeHandler); + this.leftCodeRenderable.on("line-info-change", this._lineInfoChangeHandler); + } + if (this.rightCodeRenderable) { + this.rightCodeRenderable.off("line-info-change", this._lineInfoChangeHandler); + this.rightCodeRenderable.on("line-info-change", this._lineInfoChangeHandler); + } + } + detachLineInfoListeners() { + if (!this._lineInfoChangeHandler) + return; + if (this.leftCodeRenderable) { + this.leftCodeRenderable.off("line-info-change", this._lineInfoChangeHandler); + } + if (this.rightCodeRenderable) { + this.rightCodeRenderable.off("line-info-change", this._lineInfoChangeHandler); + } + this._lineInfoChangeHandler = null; + } + destroyRecursively() { + this.detachLineInfoListeners(); + this.pendingRebuild = false; + this.leftSideAdded = false; + this.rightSideAdded = false; + super.destroyRecursively(); + } + buildErrorView() { + this.flexDirection = "column"; + if (this.leftSide && this.leftSideAdded) { + super.remove(this.leftSide.id); + this.leftSideAdded = false; + } + if (this.rightSide && this.rightSideAdded) { + super.remove(this.rightSide.id); + this.rightSideAdded = false; + } + const errorMessage = `Error parsing diff: ${this._parseError?.message || "Unknown error"} +`; + if (!this.errorTextRenderable) { + this.errorTextRenderable = new TextRenderable(this.ctx, { + id: this.id ? `${this.id}-error-text` : undefined, + content: errorMessage, + fg: "#ef4444", + width: "100%", + flexShrink: 0 + }); + super.add(this.errorTextRenderable); + } else { + this.errorTextRenderable.content = errorMessage; + const errorTextIndex = this.getChildren().indexOf(this.errorTextRenderable); + if (errorTextIndex === -1) { + super.add(this.errorTextRenderable); + } + } + if (!this.errorCodeRenderable) { + this.errorCodeRenderable = new CodeRenderable(this.ctx, { + id: this.id ? `${this.id}-error-code` : undefined, + content: this._diff, + filetype: "diff", + syntaxStyle: this._syntaxStyle ?? SyntaxStyle.create(), + wrapMode: this._wrapMode, + conceal: this._conceal, + width: "100%", + flexGrow: 1, + flexShrink: 1, + ...this._treeSitterClient !== undefined && { treeSitterClient: this._treeSitterClient } + }); + super.add(this.errorCodeRenderable); + } else { + this.errorCodeRenderable.content = this._diff; + this.errorCodeRenderable.wrapMode = this._wrapMode ?? "none"; + if (this._syntaxStyle) { + this.errorCodeRenderable.syntaxStyle = this._syntaxStyle; + } + const errorCodeIndex = this.getChildren().indexOf(this.errorCodeRenderable); + if (errorCodeIndex === -1) { + super.add(this.errorCodeRenderable); + } + } + } + createOrUpdateCodeRenderable(side, content, wrapMode, drawUnstyledText) { + const existingRenderable = side === "left" ? this.leftCodeRenderable : this.rightCodeRenderable; + if (!existingRenderable) { + const codeOptions = { + id: this.id ? `${this.id}-${side}-code` : undefined, + content, + filetype: this._filetype, + wrapMode, + conceal: this._conceal, + syntaxStyle: this._syntaxStyle ?? SyntaxStyle.create(), + width: "100%", + height: "100%", + ...this._fg !== undefined && { fg: this._fg }, + ...drawUnstyledText !== undefined && { drawUnstyledText }, + ...this._selectionBg !== undefined && { selectionBg: this._selectionBg }, + ...this._selectionFg !== undefined && { selectionFg: this._selectionFg }, + ...this._treeSitterClient !== undefined && { treeSitterClient: this._treeSitterClient } + }; + const newRenderable = new CodeRenderable(this.ctx, codeOptions); + if (side === "left") { + this.leftCodeRenderable = newRenderable; + } else { + this.rightCodeRenderable = newRenderable; + } + return newRenderable; + } else { + existingRenderable.content = content; + existingRenderable.wrapMode = wrapMode ?? "none"; + existingRenderable.conceal = this._conceal; + if (drawUnstyledText !== undefined) { + existingRenderable.drawUnstyledText = drawUnstyledText; + } + if (this._filetype !== undefined) { + existingRenderable.filetype = this._filetype; + } + if (this._syntaxStyle !== undefined) { + existingRenderable.syntaxStyle = this._syntaxStyle; + } + if (this._selectionBg !== undefined) { + existingRenderable.selectionBg = this._selectionBg; + } + if (this._selectionFg !== undefined) { + existingRenderable.selectionFg = this._selectionFg; + } + if (this._fg !== undefined) { + existingRenderable.fg = this._fg; + } + return existingRenderable; + } + } + createOrUpdateSide(side, target, lineColors, lineSigns, lineNumbers, hideLineNumbers, width) { + const sideRef = side === "left" ? this.leftSide : this.rightSide; + const addedFlag = side === "left" ? this.leftSideAdded : this.rightSideAdded; + if (!sideRef) { + const newSide = new LineNumberRenderable(this.ctx, { + id: this.id ? `${this.id}-${side}` : undefined, + target, + fg: this._lineNumberFg, + bg: this._lineNumberBg, + lineColors, + lineSigns, + lineNumbers, + lineNumberOffset: 0, + hideLineNumbers, + width, + height: "100%" + }); + newSide.showLineNumbers = this._showLineNumbers; + super.add(newSide); + if (side === "left") { + this.leftSide = newSide; + this.leftSideAdded = true; + } else { + this.rightSide = newSide; + this.rightSideAdded = true; + } + } else { + sideRef.width = width; + sideRef.fg = this._lineNumberFg; + sideRef.bg = this._lineNumberBg; + sideRef.setLineColors(lineColors); + sideRef.setLineSigns(lineSigns); + sideRef.setLineNumbers(lineNumbers); + sideRef.setHideLineNumbers(hideLineNumbers); + if (!addedFlag) { + super.add(sideRef); + if (side === "left") { + this.leftSideAdded = true; + } else { + this.rightSideAdded = true; + } + } + } + } + buildUnifiedView() { + if (!this._parsedDiff) + return; + this.flexDirection = "column"; + if (this.errorTextRenderable) { + const errorTextIndex = this.getChildren().indexOf(this.errorTextRenderable); + if (errorTextIndex !== -1) { + super.remove(this.errorTextRenderable.id); + } + } + if (this.errorCodeRenderable) { + const errorCodeIndex = this.getChildren().indexOf(this.errorCodeRenderable); + if (errorCodeIndex !== -1) { + super.remove(this.errorCodeRenderable.id); + } + } + const contentLines = []; + const lineColors = new Map; + const lineSigns = new Map; + const lineNumbers = new Map; + let lineIndex = 0; + for (const hunk of this._parsedDiff.hunks) { + this._hunkStartLines.push(lineIndex); + let oldLineNum = hunk.oldStart; + let newLineNum = hunk.newStart; + for (const line of hunk.lines) { + const firstChar = line[0]; + const content2 = line.slice(1); + if (firstChar === "+") { + contentLines.push(content2); + const config = { + gutter: this._addedLineNumberBg + }; + if (this._addedContentBg) { + config.content = this._addedContentBg; + } else { + config.content = this._addedBg; + } + lineColors.set(lineIndex, config); + lineSigns.set(lineIndex, { + after: " +", + afterColor: this._addedSignColor + }); + lineNumbers.set(lineIndex, newLineNum); + newLineNum++; + lineIndex++; + } else if (firstChar === "-") { + contentLines.push(content2); + const config = { + gutter: this._removedLineNumberBg + }; + if (this._removedContentBg) { + config.content = this._removedContentBg; + } else { + config.content = this._removedBg; + } + lineColors.set(lineIndex, config); + lineSigns.set(lineIndex, { + after: " -", + afterColor: this._removedSignColor + }); + lineNumbers.set(lineIndex, oldLineNum); + oldLineNum++; + lineIndex++; + } else if (firstChar === " ") { + contentLines.push(content2); + const config = { + gutter: this._lineNumberBg + }; + if (this._contextContentBg) { + config.content = this._contextContentBg; + } else { + config.content = this._contextBg; + } + lineColors.set(lineIndex, config); + lineNumbers.set(lineIndex, newLineNum); + oldLineNum++; + newLineNum++; + lineIndex++; + } + } + } + const content = contentLines.join(` +`); + const codeRenderable = this.createOrUpdateCodeRenderable("left", content, this._wrapMode); + this.attachLineInfoListeners(); + this.createOrUpdateSide("left", codeRenderable, lineColors, lineSigns, lineNumbers, new Set, "100%"); + if (this.rightSide && this.rightSideAdded) { + super.remove(this.rightSide.id); + this.rightSideAdded = false; + } + } + buildSplitView() { + if (!this._parsedDiff) + return; + this.flexDirection = "row"; + if (this.errorTextRenderable) { + const errorTextIndex = this.getChildren().indexOf(this.errorTextRenderable); + if (errorTextIndex !== -1) { + super.remove(this.errorTextRenderable.id); + } + } + if (this.errorCodeRenderable) { + const errorCodeIndex = this.getChildren().indexOf(this.errorCodeRenderable); + if (errorCodeIndex !== -1) { + super.remove(this.errorCodeRenderable.id); + } + } + const leftLogicalLines = []; + const rightLogicalLines = []; + const hunkFirstLeftLine = []; + for (const hunk of this._parsedDiff.hunks) { + hunkFirstLeftLine.push(leftLogicalLines.length); + let oldLineNum = hunk.oldStart; + let newLineNum = hunk.newStart; + let i = 0; + while (i < hunk.lines.length) { + const line = hunk.lines[i]; + const firstChar = line[0]; + if (firstChar === " ") { + const content = line.slice(1); + leftLogicalLines.push({ + content, + lineNum: oldLineNum, + color: this._contextBg, + type: "context" + }); + rightLogicalLines.push({ + content, + lineNum: newLineNum, + color: this._contextBg, + type: "context" + }); + oldLineNum++; + newLineNum++; + i++; + } else if (firstChar === "\\") { + i++; + } else { + const removes = []; + const adds = []; + while (i < hunk.lines.length) { + const currentLine = hunk.lines[i]; + const currentChar = currentLine[0]; + if (currentChar === " " || currentChar === "\\") { + break; + } + const content = currentLine.slice(1); + if (currentChar === "-") { + removes.push({ content, lineNum: oldLineNum }); + oldLineNum++; + } else if (currentChar === "+") { + adds.push({ content, lineNum: newLineNum }); + newLineNum++; + } + i++; + } + const maxLength = Math.max(removes.length, adds.length); + for (let j = 0;j < maxLength; j++) { + if (j < removes.length) { + leftLogicalLines.push({ + content: removes[j].content, + lineNum: removes[j].lineNum, + color: this._removedBg, + sign: { + after: " -", + afterColor: this._removedSignColor + }, + type: "remove" + }); + } else { + leftLogicalLines.push({ + content: "", + hideLineNumber: true, + type: "empty" + }); + } + if (j < adds.length) { + rightLogicalLines.push({ + content: adds[j].content, + lineNum: adds[j].lineNum, + color: this._addedBg, + sign: { + after: " +", + afterColor: this._addedSignColor + }, + type: "add" + }); + } else { + rightLogicalLines.push({ + content: "", + hideLineNumber: true, + type: "empty" + }); + } + } + } + } + } + for (const startIndex of hunkFirstLeftLine) { + const firstLine = leftLogicalLines[startIndex]; + if (firstLine) + firstLine.hunkStart = true; + } + const canDoWrapAlignment = this.width > 0 && (this._wrapMode === "word" || this._wrapMode === "char"); + const preLeftContent = leftLogicalLines.map((l) => l.content).join(` +`); + const preRightContent = rightLogicalLines.map((l) => l.content).join(` +`); + const needsConsistentConcealing = (this._wrapMode === "word" || this._wrapMode === "char") && this._conceal && this._filetype; + const drawUnstyledText = !needsConsistentConcealing; + const leftCodeRenderable = this.createOrUpdateCodeRenderable("left", preLeftContent, this._wrapMode, drawUnstyledText); + const rightCodeRenderable = this.createOrUpdateCodeRenderable("right", preRightContent, this._wrapMode, drawUnstyledText); + this.attachLineInfoListeners(); + let finalLeftLines; + let finalRightLines; + const leftIsHighlighting = leftCodeRenderable.isHighlighting; + const rightIsHighlighting = rightCodeRenderable.isHighlighting; + const highlightingInProgress = needsConsistentConcealing && (leftIsHighlighting || rightIsHighlighting); + if (highlightingInProgress) { + this._waitingForHighlight = true; + this.attachLineInfoListeners(); + } + const shouldDoAlignment = canDoWrapAlignment && !highlightingInProgress; + if (shouldDoAlignment) { + const leftLineInfo = leftCodeRenderable.lineInfo; + const rightLineInfo = rightCodeRenderable.lineInfo; + const leftSources = leftLineInfo.lineSources || []; + const rightSources = rightLineInfo.lineSources || []; + const leftVisualCounts = new Map; + const rightVisualCounts = new Map; + for (const logicalLine of leftSources) { + leftVisualCounts.set(logicalLine, (leftVisualCounts.get(logicalLine) || 0) + 1); + } + for (const logicalLine of rightSources) { + rightVisualCounts.set(logicalLine, (rightVisualCounts.get(logicalLine) || 0) + 1); + } + finalLeftLines = []; + finalRightLines = []; + let leftVisualPos = 0; + let rightVisualPos = 0; + for (let i = 0;i < leftLogicalLines.length; i++) { + const leftLine = leftLogicalLines[i]; + const rightLine = rightLogicalLines[i]; + const leftVisualCount = leftVisualCounts.get(i) ?? 0; + const rightVisualCount = rightVisualCounts.get(i) ?? 0; + if (leftVisualPos < rightVisualPos) { + const pad = rightVisualPos - leftVisualPos; + for (let p = 0;p < pad; p++) { + finalLeftLines.push({ content: "", hideLineNumber: true, type: "empty" }); + } + leftVisualPos += pad; + } else if (rightVisualPos < leftVisualPos) { + const pad = leftVisualPos - rightVisualPos; + for (let p = 0;p < pad; p++) { + finalRightLines.push({ content: "", hideLineNumber: true, type: "empty" }); + } + rightVisualPos += pad; + } + finalLeftLines.push(leftLine); + finalRightLines.push(rightLine); + leftVisualPos += leftVisualCount; + rightVisualPos += rightVisualCount; + } + if (leftVisualPos < rightVisualPos) { + const pad = rightVisualPos - leftVisualPos; + for (let p = 0;p < pad; p++) { + finalLeftLines.push({ content: "", hideLineNumber: true, type: "empty" }); + } + } else if (rightVisualPos < leftVisualPos) { + const pad = leftVisualPos - rightVisualPos; + for (let p = 0;p < pad; p++) { + finalRightLines.push({ content: "", hideLineNumber: true, type: "empty" }); + } + } + } else { + finalLeftLines = leftLogicalLines; + finalRightLines = rightLogicalLines; + } + const leftLineColors = new Map; + const rightLineColors = new Map; + const leftLineSigns = new Map; + const rightLineSigns = new Map; + const leftHideLineNumbers = new Set; + const rightHideLineNumbers = new Set; + const leftLineNumbers = new Map; + const rightLineNumbers = new Map; + finalLeftLines.forEach((line, index) => { + if (line.hunkStart) { + this._hunkStartLines.push(index); + } + if (line.lineNum !== undefined) { + leftLineNumbers.set(index, line.lineNum); + } + if (line.hideLineNumber) { + leftHideLineNumbers.add(index); + } + if (line.type === "remove") { + const config = { + gutter: this._removedLineNumberBg + }; + if (this._removedContentBg) { + config.content = this._removedContentBg; + } else { + config.content = this._removedBg; + } + leftLineColors.set(index, config); + } else if (line.type === "context") { + const config = { + gutter: this._lineNumberBg + }; + if (this._contextContentBg) { + config.content = this._contextContentBg; + } else { + config.content = this._contextBg; + } + leftLineColors.set(index, config); + } + if (line.sign) { + leftLineSigns.set(index, line.sign); + } + }); + finalRightLines.forEach((line, index) => { + if (line.lineNum !== undefined) { + rightLineNumbers.set(index, line.lineNum); + } + if (line.hideLineNumber) { + rightHideLineNumbers.add(index); + } + if (line.type === "add") { + const config = { + gutter: this._addedLineNumberBg + }; + if (this._addedContentBg) { + config.content = this._addedContentBg; + } else { + config.content = this._addedBg; + } + rightLineColors.set(index, config); + } else if (line.type === "context") { + const config = { + gutter: this._lineNumberBg + }; + if (this._contextContentBg) { + config.content = this._contextContentBg; + } else { + config.content = this._contextBg; + } + rightLineColors.set(index, config); + } + if (line.sign) { + rightLineSigns.set(index, line.sign); + } + }); + const leftContentFinal = finalLeftLines.map((l) => l.content).join(` +`); + const rightContentFinal = finalRightLines.map((l) => l.content).join(` +`); + leftCodeRenderable.content = leftContentFinal; + rightCodeRenderable.content = rightContentFinal; + this.createOrUpdateSide("left", leftCodeRenderable, leftLineColors, leftLineSigns, leftLineNumbers, leftHideLineNumbers, "50%"); + this.createOrUpdateSide("right", rightCodeRenderable, rightLineColors, rightLineSigns, rightLineNumbers, rightHideLineNumbers, "50%"); + } + get diff() { + return this._diff; + } + set diff(value) { + if (this._diff !== value) { + this._diff = value; + this._waitingForHighlight = false; + this.parseDiff(); + this.rebuildView(); + } + } + get syncScroll() { + return this._syncScroll; + } + set syncScroll(value) { + if (this._syncScroll !== value) { + this._syncScroll = value; + } + } + get view() { + return this._view; + } + set view(value) { + if (this._view !== value) { + this._view = value; + this.flexDirection = value === "split" ? "row" : "column"; + this.buildView(); + } + } + get filetype() { + return this._filetype; + } + set filetype(value) { + if (this._filetype !== value) { + this._filetype = value; + this.rebuildView(); + } + } + get syntaxStyle() { + return this._syntaxStyle; + } + set syntaxStyle(value) { + if (this._syntaxStyle !== value) { + this._syntaxStyle = value; + this.rebuildView(); + } + } + get wrapMode() { + return this._wrapMode; + } + set wrapMode(value) { + if (this._wrapMode !== value) { + this._wrapMode = value; + this.invalidateHunkRowOffsets(); + if (this._view === "unified" && this.leftCodeRenderable) { + this.leftCodeRenderable.wrapMode = value ?? "none"; + } else if (this._view === "split") { + this.requestRebuild(); + } + } + } + get showLineNumbers() { + return this._showLineNumbers; + } + set showLineNumbers(value) { + if (this._showLineNumbers !== value) { + this._showLineNumbers = value; + if (this.leftSide) { + this.leftSide.showLineNumbers = value; + } + if (this.rightSide) { + this.rightSide.showLineNumbers = value; + } + } + } + get addedBg() { + return this._addedBg; + } + set addedBg(value) { + const parsed = parseColor(value); + if (this._addedBg !== parsed) { + this._addedBg = parsed; + this.rebuildView(); + } + } + get removedBg() { + return this._removedBg; + } + set removedBg(value) { + const parsed = parseColor(value); + if (this._removedBg !== parsed) { + this._removedBg = parsed; + this.rebuildView(); + } + } + get contextBg() { + return this._contextBg; + } + set contextBg(value) { + const parsed = parseColor(value); + if (this._contextBg !== parsed) { + this._contextBg = parsed; + this.rebuildView(); + } + } + get addedSignColor() { + return this._addedSignColor; + } + set addedSignColor(value) { + const parsed = parseColor(value); + if (this._addedSignColor !== parsed) { + this._addedSignColor = parsed; + this.rebuildView(); + } + } + get removedSignColor() { + return this._removedSignColor; + } + set removedSignColor(value) { + const parsed = parseColor(value); + if (this._removedSignColor !== parsed) { + this._removedSignColor = parsed; + this.rebuildView(); + } + } + get addedLineNumberBg() { + return this._addedLineNumberBg; + } + set addedLineNumberBg(value) { + const parsed = parseColor(value); + if (this._addedLineNumberBg !== parsed) { + this._addedLineNumberBg = parsed; + this.rebuildView(); + } + } + get removedLineNumberBg() { + return this._removedLineNumberBg; + } + set removedLineNumberBg(value) { + const parsed = parseColor(value); + if (this._removedLineNumberBg !== parsed) { + this._removedLineNumberBg = parsed; + this.rebuildView(); + } + } + get lineNumberFg() { + return this._lineNumberFg; + } + set lineNumberFg(value) { + const parsed = parseColor(value); + if (this._lineNumberFg !== parsed) { + this._lineNumberFg = parsed; + this.rebuildView(); + } + } + get lineNumberBg() { + return this._lineNumberBg; + } + set lineNumberBg(value) { + const parsed = parseColor(value); + if (this._lineNumberBg !== parsed) { + this._lineNumberBg = parsed; + this.rebuildView(); + } + } + get addedContentBg() { + return this._addedContentBg; + } + set addedContentBg(value) { + const parsed = value ? parseColor(value) : null; + if (this._addedContentBg !== parsed) { + this._addedContentBg = parsed; + this.rebuildView(); + } + } + get removedContentBg() { + return this._removedContentBg; + } + set removedContentBg(value) { + const parsed = value ? parseColor(value) : null; + if (this._removedContentBg !== parsed) { + this._removedContentBg = parsed; + this.rebuildView(); + } + } + get contextContentBg() { + return this._contextContentBg; + } + set contextContentBg(value) { + const parsed = value ? parseColor(value) : null; + if (this._contextContentBg !== parsed) { + this._contextContentBg = parsed; + this.rebuildView(); + } + } + get selectionBg() { + return this._selectionBg; + } + set selectionBg(value) { + const parsed = value ? parseColor(value) : undefined; + if (this._selectionBg !== parsed) { + this._selectionBg = parsed; + if (this.leftCodeRenderable) { + this.leftCodeRenderable.selectionBg = parsed; + } + if (this.rightCodeRenderable) { + this.rightCodeRenderable.selectionBg = parsed; + } + } + } + get selectionFg() { + return this._selectionFg; + } + set selectionFg(value) { + const parsed = value ? parseColor(value) : undefined; + if (this._selectionFg !== parsed) { + this._selectionFg = parsed; + if (this.leftCodeRenderable) { + this.leftCodeRenderable.selectionFg = parsed; + } + if (this.rightCodeRenderable) { + this.rightCodeRenderable.selectionFg = parsed; + } + } + } + get conceal() { + return this._conceal; + } + set conceal(value) { + if (this._conceal !== value) { + this._conceal = value; + this.rebuildView(); + } + } + get fg() { + return this._fg; + } + set fg(value) { + const parsed = value ? parseColor(value) : undefined; + if (this._fg !== parsed) { + this._fg = parsed; + if (this.leftCodeRenderable) { + this.leftCodeRenderable.fg = parsed; + } + if (this.rightCodeRenderable) { + this.rightCodeRenderable.fg = parsed; + } + } + } + setLineColor(line, color) { + this.leftSide?.setLineColor(line, color); + this.rightSide?.setLineColor(line, color); + } + clearLineColor(line) { + this.leftSide?.clearLineColor(line); + this.rightSide?.clearLineColor(line); + } + setLineColors(lineColors) { + this.leftSide?.setLineColors(lineColors); + this.rightSide?.setLineColors(lineColors); + } + clearAllLineColors() { + this.leftSide?.clearAllLineColors(); + this.rightSide?.clearAllLineColors(); + } + highlightLines(startLine, endLine, color) { + this.leftSide?.highlightLines(startLine, endLine, color); + this.rightSide?.highlightLines(startLine, endLine, color); + } + clearHighlightLines(startLine, endLine) { + this.leftSide?.clearHighlightLines(startLine, endLine); + this.rightSide?.clearHighlightLines(startLine, endLine); + } + getHunkRowOffsets() { + if (this._hunkRowOffsets) + return [...this._hunkRowOffsets]; + this._hunkRowOffsets = this.computeHunkRowOffsets(); + return [...this._hunkRowOffsets]; + } + computeHunkRowOffsets() { + if (this._hunkStartLines.length === 0) + return []; + const sources = this.leftCodeRenderable?.lineInfo.lineSources; + if (!sources || sources.length === 0) + return [...this._hunkStartLines]; + const offsets = []; + let visualRow = 0; + for (const hunkStartLine of this._hunkStartLines) { + while (visualRow < sources.length && sources[visualRow] < hunkStartLine) { + visualRow++; + } + offsets.push(visualRow < sources.length ? visualRow : hunkStartLine); + } + return offsets; + } +} +// src/renderables/Textarea.ts +var defaultTextareaKeyBindings = [ + { name: "left", action: "move-left" }, + { name: "right", action: "move-right" }, + { name: "up", action: "move-up" }, + { name: "down", action: "move-down" }, + { name: "left", shift: true, action: "select-left" }, + { name: "right", shift: true, action: "select-right" }, + { name: "up", shift: true, action: "select-up" }, + { name: "down", shift: true, action: "select-down" }, + { name: "home", action: "buffer-home" }, + { name: "end", action: "buffer-end" }, + { name: "home", shift: true, action: "select-buffer-home" }, + { name: "end", shift: true, action: "select-buffer-end" }, + { name: "a", ctrl: true, action: "line-home" }, + { name: "e", ctrl: true, action: "line-end" }, + { name: "a", ctrl: true, shift: true, action: "select-line-home" }, + { name: "e", ctrl: true, shift: true, action: "select-line-end" }, + { name: "a", meta: true, action: "visual-line-home" }, + { name: "e", meta: true, action: "visual-line-end" }, + { name: "a", meta: true, shift: true, action: "select-visual-line-home" }, + { name: "e", meta: true, shift: true, action: "select-visual-line-end" }, + { name: "f", ctrl: true, action: "move-right" }, + { name: "b", ctrl: true, action: "move-left" }, + { name: "w", ctrl: true, action: "delete-word-backward" }, + { name: "backspace", ctrl: true, action: "delete-word-backward" }, + { name: "d", meta: true, action: "delete-word-forward" }, + { name: "delete", meta: true, action: "delete-word-forward" }, + { name: "delete", ctrl: true, action: "delete-word-forward" }, + { name: "d", ctrl: true, shift: true, action: "delete-line" }, + { name: "k", ctrl: true, action: "delete-to-line-end" }, + { name: "u", ctrl: true, action: "delete-to-line-start" }, + { name: "backspace", action: "backspace" }, + { name: "backspace", shift: true, action: "backspace" }, + { name: "d", ctrl: true, action: "delete" }, + { name: "delete", action: "delete" }, + { name: "delete", shift: true, action: "delete" }, + { name: "return", action: "newline" }, + { name: "kpenter", action: "newline" }, + { name: "linefeed", action: "newline" }, + { name: "return", meta: true, action: "submit" }, + { name: "kpenter", meta: true, action: "submit" }, + { name: "-", ctrl: true, action: "undo" }, + { name: ".", ctrl: true, action: "redo" }, + { name: "z", super: true, action: "undo" }, + { name: "z", super: true, shift: true, action: "redo" }, + { name: "f", meta: true, action: "word-forward" }, + { name: "b", meta: true, action: "word-backward" }, + { name: "right", meta: true, action: "word-forward" }, + { name: "left", meta: true, action: "word-backward" }, + { name: "right", ctrl: true, action: "word-forward" }, + { name: "left", ctrl: true, action: "word-backward" }, + { name: "f", meta: true, shift: true, action: "select-word-forward" }, + { name: "b", meta: true, shift: true, action: "select-word-backward" }, + { name: "right", meta: true, shift: true, action: "select-word-forward" }, + { name: "left", meta: true, shift: true, action: "select-word-backward" }, + { name: "backspace", meta: true, action: "delete-word-backward" }, + { name: "left", super: true, action: "visual-line-home" }, + { name: "right", super: true, action: "visual-line-end" }, + { name: "up", super: true, action: "buffer-home" }, + { name: "down", super: true, action: "buffer-end" }, + { name: "left", super: true, shift: true, action: "select-visual-line-home" }, + { name: "right", super: true, shift: true, action: "select-visual-line-end" }, + { name: "up", super: true, shift: true, action: "select-buffer-home" }, + { name: "down", super: true, shift: true, action: "select-buffer-end" }, + { name: "a", super: true, action: "select-all" } +]; + +class TextareaRenderable extends EditBufferRenderable { + _placeholder; + _placeholderColor; + _unfocusedBackgroundColor; + _unfocusedTextColor; + _focusedBackgroundColor; + _focusedTextColor; + _keyBindingsMap; + _keyAliasMap; + _keyBindings; + _actionHandlers; + _initialValueSet = false; + _submitListener = undefined; + static defaults = { + backgroundColor: "transparent", + textColor: "#FFFFFF", + focusedBackgroundColor: "transparent", + focusedTextColor: "#FFFFFF", + placeholder: null, + placeholderColor: "#666666" + }; + constructor(ctx, options) { + const defaults = TextareaRenderable.defaults; + const baseOptions = { + ...options, + backgroundColor: options.backgroundColor || defaults.backgroundColor, + textColor: options.textColor || defaults.textColor + }; + super(ctx, baseOptions); + this._unfocusedBackgroundColor = parseColor(options.backgroundColor || defaults.backgroundColor); + this._unfocusedTextColor = parseColor(options.textColor || defaults.textColor); + this._focusedBackgroundColor = parseColor(options.focusedBackgroundColor || options.backgroundColor || defaults.focusedBackgroundColor); + this._focusedTextColor = parseColor(options.focusedTextColor || options.textColor || defaults.focusedTextColor); + this._placeholder = options.placeholder ?? defaults.placeholder; + this._placeholderColor = parseColor(options.placeholderColor ?? defaults.placeholderColor); + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {}); + this._keyBindings = options.keyBindings || []; + const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + this._actionHandlers = this.buildActionHandlers(); + this._submitListener = options.onSubmit; + if (options.initialValue) { + this.setText(options.initialValue); + this._initialValueSet = true; + } + this.updateColors(); + this.applyPlaceholder(this._placeholder); + } + applyPlaceholder(placeholder) { + if (placeholder === null) { + this.editorView.setPlaceholderStyledText([]); + return; + } + if (typeof placeholder === "string") { + const colorStyle = fg(this._placeholderColor); + const chunks = [colorStyle(placeholder)]; + this.editorView.setPlaceholderStyledText(chunks); + } else { + this.editorView.setPlaceholderStyledText(placeholder.chunks); + } + } + buildActionHandlers() { + return new Map([ + ["move-left", () => this.moveCursorLeft()], + ["move-right", () => this.moveCursorRight()], + ["move-up", () => this.moveCursorUp()], + ["move-down", () => this.moveCursorDown()], + ["select-left", () => this.moveCursorLeft({ select: true })], + ["select-right", () => this.moveCursorRight({ select: true })], + ["select-up", () => this.moveCursorUp({ select: true })], + ["select-down", () => this.moveCursorDown({ select: true })], + ["line-home", () => this.gotoLineHome()], + ["line-end", () => this.gotoLineEnd()], + ["select-line-home", () => this.gotoLineHome({ select: true })], + ["select-line-end", () => this.gotoLineEnd({ select: true })], + ["visual-line-home", () => this.gotoVisualLineHome()], + ["visual-line-end", () => this.gotoVisualLineEnd()], + ["select-visual-line-home", () => this.gotoVisualLineHome({ select: true })], + ["select-visual-line-end", () => this.gotoVisualLineEnd({ select: true })], + ["select-buffer-home", () => this.gotoBufferHome({ select: true })], + ["select-buffer-end", () => this.gotoBufferEnd({ select: true })], + ["buffer-home", () => this.gotoBufferHome()], + ["buffer-end", () => this.gotoBufferEnd()], + ["delete-line", () => this.deleteLine()], + ["delete-to-line-end", () => this.deleteToLineEnd()], + ["delete-to-line-start", () => this.deleteToLineStart()], + ["backspace", () => this.deleteCharBackward()], + ["delete", () => this.deleteChar()], + ["newline", () => this.newLine()], + ["undo", () => this.undo()], + ["redo", () => this.redo()], + ["word-forward", () => this.moveWordForward()], + ["word-backward", () => this.moveWordBackward()], + ["select-word-forward", () => this.moveWordForward({ select: true })], + ["select-word-backward", () => this.moveWordBackward({ select: true })], + ["delete-word-forward", () => this.deleteWordForward()], + ["delete-word-backward", () => this.deleteWordBackward()], + ["select-all", () => this.selectAll()], + ["submit", () => this.submit()] + ]); + } + handlePaste(event) { + this.insertText(stripAnsiSequences(decodePasteBytes(event.bytes))); + } + handleKeyPress(key) { + if (this.traits.suspend !== true) { + const action = getKeyBindingAction(this._keyBindingsMap, key); + if (action) { + const handler = this._actionHandlers.get(action); + if (handler) { + return handler(); + } + } + } + if (!key.ctrl && !key.meta && !key.super && !key.hyper) { + if (key.name === "space") { + this.insertText(" "); + return true; + } + if (key.sequence) { + const firstCharCode = key.sequence.charCodeAt(0); + if (firstCharCode < 32) { + return false; + } + if (firstCharCode === 127) { + return false; + } + this.insertText(key.sequence); + return true; + } + } + return false; + } + updateColors() { + const effectiveBg = this._focused ? this._focusedBackgroundColor : this._unfocusedBackgroundColor; + const effectiveFg = this._focused ? this._focusedTextColor : this._unfocusedTextColor; + super.backgroundColor = effectiveBg; + super.textColor = effectiveFg; + } + focus() { + super.focus(); + this.updateColors(); + } + blur() { + super.blur(); + if (!this.isDestroyed) { + this.updateColors(); + } + } + get placeholder() { + return this._placeholder; + } + set placeholder(value) { + const normalizedValue = value ?? null; + if (this._placeholder !== normalizedValue) { + this._placeholder = normalizedValue; + this.applyPlaceholder(normalizedValue); + this.requestRender(); + } + } + get placeholderColor() { + return this._placeholderColor; + } + set placeholderColor(value) { + const newColor = parseColor(value ?? TextareaRenderable.defaults.placeholderColor); + if (this._placeholderColor !== newColor) { + this._placeholderColor = newColor; + this.applyPlaceholder(this._placeholder); + this.requestRender(); + } + } + get backgroundColor() { + return this._unfocusedBackgroundColor; + } + set backgroundColor(value) { + const newColor = parseColor(value ?? TextareaRenderable.defaults.backgroundColor); + if (this._unfocusedBackgroundColor !== newColor) { + this._unfocusedBackgroundColor = newColor; + this.updateColors(); + } + } + get textColor() { + return this._unfocusedTextColor; + } + set textColor(value) { + const newColor = parseColor(value ?? TextareaRenderable.defaults.textColor); + if (this._unfocusedTextColor !== newColor) { + this._unfocusedTextColor = newColor; + this.updateColors(); + } + } + set focusedBackgroundColor(value) { + const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedBackgroundColor); + if (this._focusedBackgroundColor !== newColor) { + this._focusedBackgroundColor = newColor; + this.updateColors(); + } + } + set focusedTextColor(value) { + const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedTextColor); + if (this._focusedTextColor !== newColor) { + this._focusedTextColor = newColor; + this.updateColors(); + } + } + set initialValue(value) { + if (!this._initialValueSet) { + this.setText(value); + this._initialValueSet = true; + } + } + submit() { + if (this._submitListener) { + this._submitListener({}); + } + return true; + } + set onSubmit(handler) { + this._submitListener = handler; + } + get onSubmit() { + return this._submitListener; + } + set keyBindings(bindings) { + this._keyBindings = bindings; + const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, bindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + } + set keyAliasMap(aliases) { + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases); + const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + } + get extmarks() { + return this.editorView.extmarks; + } +} + +// src/renderables/Input.ts +var InputRenderableEvents; +((InputRenderableEvents2) => { + InputRenderableEvents2["INPUT"] = "input"; + InputRenderableEvents2["CHANGE"] = "change"; + InputRenderableEvents2["ENTER"] = "enter"; +})(InputRenderableEvents ||= {}); + +class InputRenderable extends TextareaRenderable { + _maxLength; + _minLength; + _lastCommittedValue = ""; + static defaultOptions = { + placeholder: "", + maxLength: 1000, + minLength: 0, + value: "" + }; + constructor(ctx, options) { + const defaults = InputRenderable.defaultOptions; + const maxLength = options.maxLength ?? defaults.maxLength; + const minLength = options.minLength ?? defaults.minLength; + const rawValue = options.value ?? defaults.value; + const initialValue = rawValue.replace(/[\n\r]/g, "").substring(0, maxLength); + if (minLength > maxLength) { + throw new Error(`InputRenderable: minLength (${minLength}) cannot be greater than maxLength (${maxLength})`); + } + super(ctx, { + ...options, + placeholder: options.placeholder ?? defaults.placeholder, + initialValue, + height: 1, + wrapMode: "none", + keyBindings: [ + { name: "return", action: "submit" }, + { name: "kpenter", action: "submit" }, + { name: "linefeed", action: "submit" }, + ...options.keyBindings || [] + ] + }); + this._maxLength = maxLength; + this._minLength = minLength; + this._lastCommittedValue = this.plainText; + if (initialValue) { + this.cursorOffset = initialValue.length; + } + } + newLine() { + return false; + } + handlePaste(event) { + const sanitized = stripAnsiSequences(decodePasteBytes(event.bytes)).replace(/[\n\r]/g, ""); + if (sanitized) { + this.insertText(sanitized); + } + } + insertText(text) { + const sanitized = text.replace(/[\n\r]/g, ""); + if (!sanitized) + return; + const currentLength = this.plainText.length; + const remaining = this._maxLength - currentLength; + if (remaining <= 0) + return; + const toInsert = sanitized.substring(0, remaining); + super.insertText(toInsert); + this.emit("input" /* INPUT */, this.plainText); + } + get value() { + return this.plainText; + } + set value(value) { + const newValue = value.substring(0, this._maxLength).replace(/[\n\r]/g, ""); + const currentValue = this.plainText; + if (currentValue !== newValue) { + this.setText(newValue); + this.cursorOffset = newValue.length; + this.emit("input" /* INPUT */, newValue); + } + } + focus() { + super.focus(); + this._lastCommittedValue = this.plainText; + } + blur() { + if (!this.isDestroyed) { + const currentValue = this.plainText; + if (currentValue !== this._lastCommittedValue) { + this._lastCommittedValue = currentValue; + this.emit("change" /* CHANGE */, currentValue); + } + } + super.blur(); + } + submit() { + const currentValue = this.plainText; + if (currentValue.length < this._minLength) { + return false; + } + if (currentValue !== this._lastCommittedValue) { + this._lastCommittedValue = currentValue; + this.emit("change" /* CHANGE */, currentValue); + } + this.emit("enter" /* ENTER */, currentValue); + return true; + } + deleteCharBackward() { + const result = super.deleteCharBackward(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + deleteChar() { + const result = super.deleteChar(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + deleteLine() { + const result = super.deleteLine(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + deleteWordBackward() { + const result = super.deleteWordBackward(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + deleteWordForward() { + const result = super.deleteWordForward(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + deleteToLineStart() { + const result = super.deleteToLineStart(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + deleteToLineEnd() { + const result = super.deleteToLineEnd(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + undo() { + const result = super.undo(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + redo() { + const result = super.redo(); + this.emit("input" /* INPUT */, this.plainText); + return result; + } + deleteCharacter(direction) { + if (direction === "backward") { + this.deleteCharBackward(); + } else { + this.deleteChar(); + } + } + set maxLength(maxLength) { + this._maxLength = maxLength; + const currentValue = this.plainText; + if (currentValue.length > maxLength) { + this.setText(currentValue.substring(0, maxLength)); + } + } + get maxLength() { + return this._maxLength; + } + set minLength(minLength) { + if (minLength > this._maxLength) { + throw new Error(`InputRenderable: minLength (${minLength}) cannot be greater than maxLength (${this._maxLength})`); + } + this._minLength = minLength; + } + get minLength() { + return this._minLength; + } + set placeholder(placeholder) { + super.placeholder = placeholder; + } + get placeholder() { + const p = super.placeholder; + return typeof p === "string" ? p : ""; + } + set initialValue(value) {} +} +// ../../node_modules/.bun/marked@17.0.1/node_modules/marked/lib/marked.esm.js +function L() { + return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null }; +} +var T = L(); +function Z(u) { + T = u; +} +var C = { exec: () => null }; +function k(u, e = "") { + let t2 = typeof u == "string" ? u : u.source, n = { replace: (r, i) => { + let s = typeof i == "string" ? i : i.source; + return s = s.replace(m.caret, "$1"), t2 = t2.replace(r, s), n; + }, getRegex: () => new RegExp(t2, e) }; + return n; +} +var me = (() => { + try { + return !!new RegExp("(?<=1)(?/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceTabs: /^\t+/, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (u) => new RegExp(`^( {0,3}${u})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (u) => new RegExp(`^ {0,${Math.min(3, u - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (u) => new RegExp(`^ {0,${Math.min(3, u - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (u) => new RegExp(`^ {0,${Math.min(3, u - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (u) => new RegExp(`^ {0,${Math.min(3, u - 1)}}#`), htmlBeginRegex: (u) => new RegExp(`^ {0,${Math.min(3, u - 1)}}<(?:[a-z].*>|!--)`, "i") }; +var xe = /^(?:[ \t]*(?:\n|$))+/; +var be = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/; +var Re = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/; +var I = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/; +var Te = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/; +var N = /(?:[*+-]|\d{1,9}[.)])/; +var re = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/; +var se = k(re).replace(/bull/g, N).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex(); +var Oe = k(re).replace(/bull/g, N).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(); +var Q = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/; +var we = /^[^\n]+/; +var F = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/; +var ye = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", F).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(); +var Pe = k(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, N).getRegex(); +var v = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul"; +var j = /|$))/; +var Se = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$))", "i").replace("comment", j).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); +var ie = k(Q).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex(); +var $e = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", ie).getRegex(); +var U = { blockquote: $e, code: be, def: ye, fences: Re, heading: Te, hr: I, html: Se, lheading: se, list: Pe, newline: xe, paragraph: ie, table: C, text: we }; +var te = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3}\t)[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex(); +var _e = { ...U, lheading: Oe, table: te, paragraph: k(Q).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", te).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() }; +var Le = { ...U, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", j).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: C, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(Q).replace("hr", I).replace("heading", ` *#{1,6} *[^ +]`).replace("lheading", se).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() }; +var Me = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/; +var ze = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/; +var oe = /^( {2,}|\\)\n(?!\s*$)/; +var Ae = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`+)[^`]+\k(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", me ? "(?`+)[^`]+\k(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex(); +var ue = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/; +var qe = k(ue, "u").replace(/punct/g, D).getRegex(); +var ve = k(ue, "u").replace(/punct/g, le).getRegex(); +var pe = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)"; +var De = k(pe, "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, K).replace(/punct/g, D).getRegex(); +var He = k(pe, "gu").replace(/notPunctSpace/g, Ee).replace(/punctSpace/g, Ie).replace(/punct/g, le).getRegex(); +var Ze = k("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, K).replace(/punct/g, D).getRegex(); +var Ge = k(/\\(punct)/, "gu").replace(/punct/g, D).getRegex(); +var Ne = k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(); +var Qe = k(j).replace("(?:-->|$)", "-->").getRegex(); +var Fe = k("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment", Qe).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(); +var q = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/; +var je = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(); +var ce = k(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", F).getRegex(); +var he = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", F).getRegex(); +var Ue = k("reflink|nolink(?!\\()", "g").replace("reflink", ce).replace("nolink", he).getRegex(); +var ne = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/; +var W = { _backpedal: C, anyPunctuation: Ge, autolink: Ne, blockSkip: Be, br: oe, code: ze, del: C, emStrongLDelim: qe, emStrongRDelimAst: De, emStrongRDelimUnd: Ze, escape: Me, link: je, nolink: he, punctuation: Ce, reflink: ce, reflinkSearch: Ue, tag: Fe, text: Ae, url: C }; +var Ke = { ...W, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() }; +var G = { ...W, emStrongRDelimAst: He, emStrongLDelim: ve, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ne).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\": ">", '"': """, "'": "'" }; +var ke = (u) => Xe[u]; +function w(u, e) { + if (e) { + if (m.escapeTest.test(u)) + return u.replace(m.escapeReplace, ke); + } else if (m.escapeTestNoEncode.test(u)) + return u.replace(m.escapeReplaceNoEncode, ke); + return u; +} +function X(u) { + try { + u = encodeURI(u).replace(m.percentDecode, "%"); + } catch { + return null; + } + return u; +} +function J(u, e) { + let t2 = u.replace(m.findPipe, (i, s, a) => { + let o = false, l = s; + for (;--l >= 0 && a[l] === "\\"; ) + o = !o; + return o ? "|" : " |"; + }), n = t2.split(m.splitPipe), r = 0; + if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) + if (n.length > e) + n.splice(e); + else + for (;n.length < e; ) + n.push(""); + for (;r < n.length; r++) + n[r] = n[r].trim().replace(m.slashPipe, "|"); + return n; +} +function z(u, e, t2) { + let n = u.length; + if (n === 0) + return ""; + let r = 0; + for (;r < n; ) { + let i = u.charAt(n - r - 1); + if (i === e && !t2) + r++; + else if (i !== e && t2) + r++; + else + break; + } + return u.slice(0, n - r); +} +function de(u, e) { + if (u.indexOf(e[1]) === -1) + return -1; + let t2 = 0; + for (let n = 0;n < u.length; n++) + if (u[n] === "\\") + n++; + else if (u[n] === e[0]) + t2++; + else if (u[n] === e[1] && (t2--, t2 < 0)) + return n; + return t2 > 0 ? -2 : -1; +} +function ge(u, e, t2, n, r) { + let i = e.href, s = e.title || null, a = u[1].replace(r.other.outputLinkReplace, "$1"); + n.state.inLink = true; + let o = { type: u[0].charAt(0) === "!" ? "image" : "link", raw: t2, href: i, title: s, text: a, tokens: n.inlineTokens(a) }; + return n.state.inLink = false, o; +} +function Je(u, e, t2) { + let n = u.match(t2.other.indentCodeCompensation); + if (n === null) + return e; + let r = n[1]; + return e.split(` +`).map((i) => { + let s = i.match(t2.other.beginningSpace); + if (s === null) + return i; + let [a] = s; + return a.length >= r.length ? i.slice(r.length) : i; + }).join(` +`); +} +var y = class { + options; + rules; + lexer; + constructor(e) { + this.options = e || T; + } + space(e) { + let t2 = this.rules.block.newline.exec(e); + if (t2 && t2[0].length > 0) + return { type: "space", raw: t2[0] }; + } + code(e) { + let t2 = this.rules.block.code.exec(e); + if (t2) { + let n = t2[0].replace(this.rules.other.codeRemoveIndent, ""); + return { type: "code", raw: t2[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : z(n, ` +`) }; + } + } + fences(e) { + let t2 = this.rules.block.fences.exec(e); + if (t2) { + let n = t2[0], r = Je(n, t2[3] || "", this.rules); + return { type: "code", raw: n, lang: t2[2] ? t2[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t2[2], text: r }; + } + } + heading(e) { + let t2 = this.rules.block.heading.exec(e); + if (t2) { + let n = t2[2].trim(); + if (this.rules.other.endingHash.test(n)) { + let r = z(n, "#"); + (this.options.pedantic || !r || this.rules.other.endingSpaceChar.test(r)) && (n = r.trim()); + } + return { type: "heading", raw: t2[0], depth: t2[1].length, text: n, tokens: this.lexer.inline(n) }; + } + } + hr(e) { + let t2 = this.rules.block.hr.exec(e); + if (t2) + return { type: "hr", raw: z(t2[0], ` +`) }; + } + blockquote(e) { + let t2 = this.rules.block.blockquote.exec(e); + if (t2) { + let n = z(t2[0], ` +`).split(` +`), r = "", i = "", s = []; + for (;n.length > 0; ) { + let a = false, o = [], l; + for (l = 0;l < n.length; l++) + if (this.rules.other.blockquoteStart.test(n[l])) + o.push(n[l]), a = true; + else if (!a) + o.push(n[l]); + else + break; + n = n.slice(l); + let p = o.join(` +`), c = p.replace(this.rules.other.blockquoteSetextReplace, ` + $1`).replace(this.rules.other.blockquoteSetextReplace2, ""); + r = r ? `${r} +${p}` : p, i = i ? `${i} +${c}` : c; + let g = this.lexer.state.top; + if (this.lexer.state.top = true, this.lexer.blockTokens(c, s, true), this.lexer.state.top = g, n.length === 0) + break; + let h2 = s.at(-1); + if (h2?.type === "code") + break; + if (h2?.type === "blockquote") { + let R = h2, f = R.raw + ` +` + n.join(` +`), O = this.blockquote(f); + s[s.length - 1] = O, r = r.substring(0, r.length - R.raw.length) + O.raw, i = i.substring(0, i.length - R.text.length) + O.text; + break; + } else if (h2?.type === "list") { + let R = h2, f = R.raw + ` +` + n.join(` +`), O = this.list(f); + s[s.length - 1] = O, r = r.substring(0, r.length - h2.raw.length) + O.raw, i = i.substring(0, i.length - R.raw.length) + O.raw, n = f.substring(s.at(-1).raw.length).split(` +`); + continue; + } + } + return { type: "blockquote", raw: r, tokens: s, text: i }; + } + } + list(e) { + let t2 = this.rules.block.list.exec(e); + if (t2) { + let n = t2[1].trim(), r = n.length > 1, i = { type: "list", raw: "", ordered: r, start: r ? +n.slice(0, -1) : "", loose: false, items: [] }; + n = r ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = r ? n : "[*+-]"); + let s = this.rules.other.listItemRegex(n), a = false; + for (;e; ) { + let l = false, p = "", c = ""; + if (!(t2 = s.exec(e)) || this.rules.block.hr.test(e)) + break; + p = t2[0], e = e.substring(p.length); + let g = t2[2].split(` +`, 1)[0].replace(this.rules.other.listReplaceTabs, (O) => " ".repeat(3 * O.length)), h2 = e.split(` +`, 1)[0], R = !g.trim(), f = 0; + if (this.options.pedantic ? (f = 2, c = g.trimStart()) : R ? f = t2[1].length + 1 : (f = t2[2].search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, c = g.slice(f), f += t2[1].length), R && this.rules.other.blankLine.test(h2) && (p += h2 + ` +`, e = e.substring(h2.length + 1), l = true), !l) { + let O = this.rules.other.nextBulletRegex(f), V = this.rules.other.hrRegex(f), Y = this.rules.other.fencesBeginRegex(f), ee = this.rules.other.headingBeginRegex(f), fe = this.rules.other.htmlBeginRegex(f); + for (;e; ) { + let H = e.split(` +`, 1)[0], A; + if (h2 = H, this.options.pedantic ? (h2 = h2.replace(this.rules.other.listReplaceNesting, " "), A = h2) : A = h2.replace(this.rules.other.tabCharGlobal, " "), Y.test(h2) || ee.test(h2) || fe.test(h2) || O.test(h2) || V.test(h2)) + break; + if (A.search(this.rules.other.nonSpaceChar) >= f || !h2.trim()) + c += ` +` + A.slice(f); + else { + if (R || g.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || Y.test(g) || ee.test(g) || V.test(g)) + break; + c += ` +` + h2; + } + !R && !h2.trim() && (R = true), p += H + ` +`, e = e.substring(H.length + 1), g = A.slice(f); + } + } + i.loose || (a ? i.loose = true : this.rules.other.doubleBlankLine.test(p) && (a = true)), i.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), i.raw += p; + } + let o = i.items.at(-1); + if (o) + o.raw = o.raw.trimEnd(), o.text = o.text.trimEnd(); + else + return; + i.raw = i.raw.trimEnd(); + for (let l of i.items) { + if (this.lexer.state.top = false, l.tokens = this.lexer.blockTokens(l.text, []), l.task) { + if (l.text = l.text.replace(this.rules.other.listReplaceTask, ""), l.tokens[0]?.type === "text" || l.tokens[0]?.type === "paragraph") { + l.tokens[0].raw = l.tokens[0].raw.replace(this.rules.other.listReplaceTask, ""), l.tokens[0].text = l.tokens[0].text.replace(this.rules.other.listReplaceTask, ""); + for (let c = this.lexer.inlineQueue.length - 1;c >= 0; c--) + if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[c].src)) { + this.lexer.inlineQueue[c].src = this.lexer.inlineQueue[c].src.replace(this.rules.other.listReplaceTask, ""); + break; + } + } + let p = this.rules.other.listTaskCheckbox.exec(l.raw); + if (p) { + let c = { type: "checkbox", raw: p[0] + " ", checked: p[0] !== "[ ]" }; + l.checked = c.checked, i.loose ? l.tokens[0] && ["paragraph", "text"].includes(l.tokens[0].type) && "tokens" in l.tokens[0] && l.tokens[0].tokens ? (l.tokens[0].raw = c.raw + l.tokens[0].raw, l.tokens[0].text = c.raw + l.tokens[0].text, l.tokens[0].tokens.unshift(c)) : l.tokens.unshift({ type: "paragraph", raw: c.raw, text: c.raw, tokens: [c] }) : l.tokens.unshift(c); + } + } + if (!i.loose) { + let p = l.tokens.filter((g) => g.type === "space"), c = p.length > 0 && p.some((g) => this.rules.other.anyLine.test(g.raw)); + i.loose = c; + } + } + if (i.loose) + for (let l of i.items) { + l.loose = true; + for (let p of l.tokens) + p.type === "text" && (p.type = "paragraph"); + } + return i; + } + } + html(e) { + let t2 = this.rules.block.html.exec(e); + if (t2) + return { type: "html", block: true, raw: t2[0], pre: t2[1] === "pre" || t2[1] === "script" || t2[1] === "style", text: t2[0] }; + } + def(e) { + let t2 = this.rules.block.def.exec(e); + if (t2) { + let n = t2[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), r = t2[2] ? t2[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t2[3] ? t2[3].substring(1, t2[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t2[3]; + return { type: "def", tag: n, raw: t2[0], href: r, title: i }; + } + } + table(e) { + let t2 = this.rules.block.table.exec(e); + if (!t2 || !this.rules.other.tableDelimiter.test(t2[2])) + return; + let n = J(t2[1]), r = t2[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t2[3]?.trim() ? t2[3].replace(this.rules.other.tableRowBlankLine, "").split(` +`) : [], s = { type: "table", raw: t2[0], header: [], align: [], rows: [] }; + if (n.length === r.length) { + for (let a of r) + this.rules.other.tableAlignRight.test(a) ? s.align.push("right") : this.rules.other.tableAlignCenter.test(a) ? s.align.push("center") : this.rules.other.tableAlignLeft.test(a) ? s.align.push("left") : s.align.push(null); + for (let a = 0;a < n.length; a++) + s.header.push({ text: n[a], tokens: this.lexer.inline(n[a]), header: true, align: s.align[a] }); + for (let a of i) + s.rows.push(J(a, s.header.length).map((o, l) => ({ text: o, tokens: this.lexer.inline(o), header: false, align: s.align[l] }))); + return s; + } + } + lheading(e) { + let t2 = this.rules.block.lheading.exec(e); + if (t2) + return { type: "heading", raw: t2[0], depth: t2[2].charAt(0) === "=" ? 1 : 2, text: t2[1], tokens: this.lexer.inline(t2[1]) }; + } + paragraph(e) { + let t2 = this.rules.block.paragraph.exec(e); + if (t2) { + let n = t2[1].charAt(t2[1].length - 1) === ` +` ? t2[1].slice(0, -1) : t2[1]; + return { type: "paragraph", raw: t2[0], text: n, tokens: this.lexer.inline(n) }; + } + } + text(e) { + let t2 = this.rules.block.text.exec(e); + if (t2) + return { type: "text", raw: t2[0], text: t2[0], tokens: this.lexer.inline(t2[0]) }; + } + escape(e) { + let t2 = this.rules.inline.escape.exec(e); + if (t2) + return { type: "escape", raw: t2[0], text: t2[1] }; + } + tag(e) { + let t2 = this.rules.inline.tag.exec(e); + if (t2) + return !this.lexer.state.inLink && this.rules.other.startATag.test(t2[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t2[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t2[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t2[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t2[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t2[0] }; + } + link(e) { + let t2 = this.rules.inline.link.exec(e); + if (t2) { + let n = t2[2].trim(); + if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) { + if (!this.rules.other.endAngleBracket.test(n)) + return; + let s = z(n.slice(0, -1), "\\"); + if ((n.length - s.length) % 2 === 0) + return; + } else { + let s = de(t2[2], "()"); + if (s === -2) + return; + if (s > -1) { + let o = (t2[0].indexOf("!") === 0 ? 5 : 4) + t2[1].length + s; + t2[2] = t2[2].substring(0, s), t2[0] = t2[0].substring(0, o).trim(), t2[3] = ""; + } + } + let r = t2[2], i = ""; + if (this.options.pedantic) { + let s = this.rules.other.pedanticHrefTitle.exec(r); + s && (r = s[1], i = s[3]); + } else + i = t2[3] ? t2[3].slice(1, -1) : ""; + return r = r.trim(), this.rules.other.startAngleBracket.test(r) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? r = r.slice(1) : r = r.slice(1, -1)), ge(t2, { href: r && r.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t2[0], this.lexer, this.rules); + } + } + reflink(e, t2) { + let n; + if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) { + let r = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t2[r.toLowerCase()]; + if (!i) { + let s = n[0].charAt(0); + return { type: "text", raw: s, text: s }; + } + return ge(n, i, n[0], this.lexer, this.rules); + } + } + emStrong(e, t2, n = "") { + let r = this.rules.inline.emStrongLDelim.exec(e); + if (!r || r[3] && n.match(this.rules.other.unicodeAlphaNumeric)) + return; + if (!(r[1] || r[2] || "") || !n || this.rules.inline.punctuation.exec(n)) { + let s = [...r[0]].length - 1, a, o, l = s, p = 0, c = r[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd; + for (c.lastIndex = 0, t2 = t2.slice(-1 * e.length + s);(r = c.exec(t2)) != null; ) { + if (a = r[1] || r[2] || r[3] || r[4] || r[5] || r[6], !a) + continue; + if (o = [...a].length, r[3] || r[4]) { + l += o; + continue; + } else if ((r[5] || r[6]) && s % 3 && !((s + o) % 3)) { + p += o; + continue; + } + if (l -= o, l > 0) + continue; + o = Math.min(o, o + l + p); + let g = [...r[0]][0].length, h2 = e.slice(0, s + r.index + g + o); + if (Math.min(s, o) % 2) { + let f = h2.slice(1, -1); + return { type: "em", raw: h2, text: f, tokens: this.lexer.inlineTokens(f) }; + } + let R = h2.slice(2, -2); + return { type: "strong", raw: h2, text: R, tokens: this.lexer.inlineTokens(R) }; + } + } + } + codespan(e) { + let t2 = this.rules.inline.code.exec(e); + if (t2) { + let n = t2[2].replace(this.rules.other.newLineCharGlobal, " "), r = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n); + return r && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t2[0], text: n }; + } + } + br(e) { + let t2 = this.rules.inline.br.exec(e); + if (t2) + return { type: "br", raw: t2[0] }; + } + del(e) { + let t2 = this.rules.inline.del.exec(e); + if (t2) + return { type: "del", raw: t2[0], text: t2[2], tokens: this.lexer.inlineTokens(t2[2]) }; + } + autolink(e) { + let t2 = this.rules.inline.autolink.exec(e); + if (t2) { + let n, r; + return t2[2] === "@" ? (n = t2[1], r = "mailto:" + n) : (n = t2[1], r = n), { type: "link", raw: t2[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] }; + } + } + url(e) { + let t2; + if (t2 = this.rules.inline.url.exec(e)) { + let n, r; + if (t2[2] === "@") + n = t2[0], r = "mailto:" + n; + else { + let i; + do + i = t2[0], t2[0] = this.rules.inline._backpedal.exec(t2[0])?.[0] ?? ""; + while (i !== t2[0]); + n = t2[0], t2[1] === "www." ? r = "http://" + t2[0] : r = t2[0]; + } + return { type: "link", raw: t2[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] }; + } + } + inlineText(e) { + let t2 = this.rules.inline.text.exec(e); + if (t2) { + let n = this.lexer.state.inRawBlock; + return { type: "text", raw: t2[0], text: t2[0], escaped: n }; + } + } +}; +var x = class u { + tokens; + options; + state; + inlineQueue; + tokenizer; + constructor(e) { + this.tokens = [], this.tokens.links = Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new y, this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true }; + let t2 = { other: m, block: E.normal, inline: M.normal }; + this.options.pedantic ? (t2.block = E.pedantic, t2.inline = M.pedantic) : this.options.gfm && (t2.block = E.gfm, this.options.breaks ? t2.inline = M.breaks : t2.inline = M.gfm), this.tokenizer.rules = t2; + } + static get rules() { + return { block: E, inline: M }; + } + static lex(e, t2) { + return new u(t2).lex(e); + } + static lexInline(e, t2) { + return new u(t2).inlineTokens(e); + } + lex(e) { + e = e.replace(m.carriageReturn, ` +`), this.blockTokens(e, this.tokens); + for (let t2 = 0;t2 < this.inlineQueue.length; t2++) { + let n = this.inlineQueue[t2]; + this.inlineTokens(n.src, n.tokens); + } + return this.inlineQueue = [], this.tokens; + } + blockTokens(e, t2 = [], n = false) { + for (this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, ""));e; ) { + let r; + if (this.options.extensions?.block?.some((s) => (r = s.call({ lexer: this }, e, t2)) ? (e = e.substring(r.raw.length), t2.push(r), true) : false)) + continue; + if (r = this.tokenizer.space(e)) { + e = e.substring(r.raw.length); + let s = t2.at(-1); + r.raw.length === 1 && s !== undefined ? s.raw += ` +` : t2.push(r); + continue; + } + if (r = this.tokenizer.code(e)) { + e = e.substring(r.raw.length); + let s = t2.at(-1); + s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(` +`) ? "" : ` +`) + r.raw, s.text += ` +` + r.text, this.inlineQueue.at(-1).src = s.text) : t2.push(r); + continue; + } + if (r = this.tokenizer.fences(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + if (r = this.tokenizer.heading(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + if (r = this.tokenizer.hr(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + if (r = this.tokenizer.blockquote(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + if (r = this.tokenizer.list(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + if (r = this.tokenizer.html(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + if (r = this.tokenizer.def(e)) { + e = e.substring(r.raw.length); + let s = t2.at(-1); + s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(` +`) ? "" : ` +`) + r.raw, s.text += ` +` + r.raw, this.inlineQueue.at(-1).src = s.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t2.push(r)); + continue; + } + if (r = this.tokenizer.table(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + if (r = this.tokenizer.lheading(e)) { + e = e.substring(r.raw.length), t2.push(r); + continue; + } + let i = e; + if (this.options.extensions?.startBlock) { + let s = 1 / 0, a = e.slice(1), o; + this.options.extensions.startBlock.forEach((l) => { + o = l.call({ lexer: this }, a), typeof o == "number" && o >= 0 && (s = Math.min(s, o)); + }), s < 1 / 0 && s >= 0 && (i = e.substring(0, s + 1)); + } + if (this.state.top && (r = this.tokenizer.paragraph(i))) { + let s = t2.at(-1); + n && s?.type === "paragraph" ? (s.raw += (s.raw.endsWith(` +`) ? "" : ` +`) + r.raw, s.text += ` +` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t2.push(r), n = i.length !== e.length, e = e.substring(r.raw.length); + continue; + } + if (r = this.tokenizer.text(e)) { + e = e.substring(r.raw.length); + let s = t2.at(-1); + s?.type === "text" ? (s.raw += (s.raw.endsWith(` +`) ? "" : ` +`) + r.raw, s.text += ` +` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t2.push(r); + continue; + } + if (e) { + let s = "Infinite loop on byte: " + e.charCodeAt(0); + if (this.options.silent) { + console.error(s); + break; + } else + throw new Error(s); + } + } + return this.state.top = true, t2; + } + inline(e, t2 = []) { + return this.inlineQueue.push({ src: e, tokens: t2 }), t2; + } + inlineTokens(e, t2 = []) { + let n = e, r = null; + if (this.tokens.links) { + let o = Object.keys(this.tokens.links); + if (o.length > 0) + for (;(r = this.tokenizer.rules.inline.reflinkSearch.exec(n)) != null; ) + o.includes(r[0].slice(r[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, r.index) + "[" + "a".repeat(r[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex)); + } + for (;(r = this.tokenizer.rules.inline.anyPunctuation.exec(n)) != null; ) + n = n.slice(0, r.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); + let i; + for (;(r = this.tokenizer.rules.inline.blockSkip.exec(n)) != null; ) + i = r[2] ? r[2].length : 0, n = n.slice(0, r.index + i) + "[" + "a".repeat(r[0].length - i - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n; + let s = false, a = ""; + for (;e; ) { + s || (a = ""), s = false; + let o; + if (this.options.extensions?.inline?.some((p) => (o = p.call({ lexer: this }, e, t2)) ? (e = e.substring(o.raw.length), t2.push(o), true) : false)) + continue; + if (o = this.tokenizer.escape(e)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (o = this.tokenizer.tag(e)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (o = this.tokenizer.link(e)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (o = this.tokenizer.reflink(e, this.tokens.links)) { + e = e.substring(o.raw.length); + let p = t2.at(-1); + o.type === "text" && p?.type === "text" ? (p.raw += o.raw, p.text += o.text) : t2.push(o); + continue; + } + if (o = this.tokenizer.emStrong(e, n, a)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (o = this.tokenizer.codespan(e)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (o = this.tokenizer.br(e)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (o = this.tokenizer.del(e)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (o = this.tokenizer.autolink(e)) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + if (!this.state.inLink && (o = this.tokenizer.url(e))) { + e = e.substring(o.raw.length), t2.push(o); + continue; + } + let l = e; + if (this.options.extensions?.startInline) { + let p = 1 / 0, c = e.slice(1), g; + this.options.extensions.startInline.forEach((h2) => { + g = h2.call({ lexer: this }, c), typeof g == "number" && g >= 0 && (p = Math.min(p, g)); + }), p < 1 / 0 && p >= 0 && (l = e.substring(0, p + 1)); + } + if (o = this.tokenizer.inlineText(l)) { + e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (a = o.raw.slice(-1)), s = true; + let p = t2.at(-1); + p?.type === "text" ? (p.raw += o.raw, p.text += o.text) : t2.push(o); + continue; + } + if (e) { + let p = "Infinite loop on byte: " + e.charCodeAt(0); + if (this.options.silent) { + console.error(p); + break; + } else + throw new Error(p); + } + } + return t2; + } +}; +var P = class { + options; + parser; + constructor(e) { + this.options = e || T; + } + space(e) { + return ""; + } + code({ text: e, lang: t2, escaped: n }) { + let r = (t2 || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + ` +`; + return r ? '

' + (n ? i : w(i, true)) + `
+` : "
" + (n ? i : w(i, true)) + `
+`; + } + blockquote({ tokens: e }) { + return `
+${this.parser.parse(e)}
+`; + } + html({ text: e }) { + return e; + } + def(e) { + return ""; + } + heading({ tokens: e, depth: t2 }) { + return `${this.parser.parseInline(e)} +`; + } + hr(e) { + return `
+`; + } + list(e) { + let { ordered: t2, start: n } = e, r = ""; + for (let a = 0;a < e.items.length; a++) { + let o = e.items[a]; + r += this.listitem(o); + } + let i = t2 ? "ol" : "ul", s = t2 && n !== 1 ? ' start="' + n + '"' : ""; + return "<" + i + s + `> +` + r + " +`; + } + listitem(e) { + return `
  • ${this.parser.parse(e.tokens)}
  • +`; + } + checkbox({ checked: e }) { + return " '; + } + paragraph({ tokens: e }) { + return `

    ${this.parser.parseInline(e)}

    +`; + } + table(e) { + let t2 = "", n = ""; + for (let i = 0;i < e.header.length; i++) + n += this.tablecell(e.header[i]); + t2 += this.tablerow({ text: n }); + let r = ""; + for (let i = 0;i < e.rows.length; i++) { + let s = e.rows[i]; + n = ""; + for (let a = 0;a < s.length; a++) + n += this.tablecell(s[a]); + r += this.tablerow({ text: n }); + } + return r && (r = `${r}`), ` + +` + t2 + ` +` + r + `
    +`; + } + tablerow({ text: e }) { + return ` +${e} +`; + } + tablecell(e) { + let t2 = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td"; + return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t2 + ` +`; + } + strong({ tokens: e }) { + return `${this.parser.parseInline(e)}`; + } + em({ tokens: e }) { + return `${this.parser.parseInline(e)}`; + } + codespan({ text: e }) { + return `${w(e, true)}`; + } + br(e) { + return "
    "; + } + del({ tokens: e }) { + return `${this.parser.parseInline(e)}`; + } + link({ href: e, title: t2, tokens: n }) { + let r = this.parser.parseInline(n), i = X(e); + if (i === null) + return r; + e = i; + let s = '
    ", s; + } + image({ href: e, title: t2, text: n, tokens: r }) { + r && (n = this.parser.parseInline(r, this.parser.textRenderer)); + let i = X(e); + if (i === null) + return w(n); + e = i; + let s = `${n} { + let a = i[s].flat(1 / 0); + n = n.concat(this.walkTokens(a, t2)); + }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t2))); + } + } + return n; + } + use(...e) { + let t2 = this.defaults.extensions || { renderers: {}, childTokens: {} }; + return e.forEach((n) => { + let r = { ...n }; + if (r.async = this.defaults.async || r.async || false, n.extensions && (n.extensions.forEach((i) => { + if (!i.name) + throw new Error("extension name required"); + if ("renderer" in i) { + let s = t2.renderers[i.name]; + s ? t2.renderers[i.name] = function(...a) { + let o = i.renderer.apply(this, a); + return o === false && (o = s.apply(this, a)), o; + } : t2.renderers[i.name] = i.renderer; + } + if ("tokenizer" in i) { + if (!i.level || i.level !== "block" && i.level !== "inline") + throw new Error("extension level must be 'block' or 'inline'"); + let s = t2[i.level]; + s ? s.unshift(i.tokenizer) : t2[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t2.startBlock ? t2.startBlock.push(i.start) : t2.startBlock = [i.start] : i.level === "inline" && (t2.startInline ? t2.startInline.push(i.start) : t2.startInline = [i.start])); + } + "childTokens" in i && i.childTokens && (t2.childTokens[i.name] = i.childTokens); + }), r.extensions = t2), n.renderer) { + let i = this.defaults.renderer || new P(this.defaults); + for (let s in n.renderer) { + if (!(s in i)) + throw new Error(`renderer '${s}' does not exist`); + if (["options", "parser"].includes(s)) + continue; + let a = s, o = n.renderer[a], l = i[a]; + i[a] = (...p) => { + let c = o.apply(i, p); + return c === false && (c = l.apply(i, p)), c || ""; + }; + } + r.renderer = i; + } + if (n.tokenizer) { + let i = this.defaults.tokenizer || new y(this.defaults); + for (let s in n.tokenizer) { + if (!(s in i)) + throw new Error(`tokenizer '${s}' does not exist`); + if (["options", "rules", "lexer"].includes(s)) + continue; + let a = s, o = n.tokenizer[a], l = i[a]; + i[a] = (...p) => { + let c = o.apply(i, p); + return c === false && (c = l.apply(i, p)), c; + }; + } + r.tokenizer = i; + } + if (n.hooks) { + let i = this.defaults.hooks || new S; + for (let s in n.hooks) { + if (!(s in i)) + throw new Error(`hook '${s}' does not exist`); + if (["options", "block"].includes(s)) + continue; + let a = s, o = n.hooks[a], l = i[a]; + S.passThroughHooks.has(s) ? i[a] = (p) => { + if (this.defaults.async && S.passThroughHooksRespectAsync.has(s)) + return (async () => { + let g = await o.call(i, p); + return l.call(i, g); + })(); + let c = o.call(i, p); + return l.call(i, c); + } : i[a] = (...p) => { + if (this.defaults.async) + return (async () => { + let g = await o.apply(i, p); + return g === false && (g = await l.apply(i, p)), g; + })(); + let c = o.apply(i, p); + return c === false && (c = l.apply(i, p)), c; + }; + } + r.hooks = i; + } + if (n.walkTokens) { + let i = this.defaults.walkTokens, s = n.walkTokens; + r.walkTokens = function(a) { + let o = []; + return o.push(s.call(this, a)), i && (o = o.concat(i.call(this, a))), o; + }; + } + this.defaults = { ...this.defaults, ...r }; + }), this; + } + setOptions(e) { + return this.defaults = { ...this.defaults, ...e }, this; + } + lexer(e, t2) { + return x.lex(e, t2 ?? this.defaults); + } + parser(e, t2) { + return b.parse(e, t2 ?? this.defaults); + } + parseMarkdown(e) { + return (n, r) => { + let i = { ...r }, s = { ...this.defaults, ...i }, a = this.onError(!!s.silent, !!s.async); + if (this.defaults.async === true && i.async === false) + return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.")); + if (typeof n > "u" || n === null) + return a(new Error("marked(): input parameter is undefined or null")); + if (typeof n != "string") + return a(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected")); + if (s.hooks && (s.hooks.options = s, s.hooks.block = e), s.async) + return (async () => { + let o = s.hooks ? await s.hooks.preprocess(n) : n, p = await (s.hooks ? await s.hooks.provideLexer() : e ? x.lex : x.lexInline)(o, s), c = s.hooks ? await s.hooks.processAllTokens(p) : p; + s.walkTokens && await Promise.all(this.walkTokens(c, s.walkTokens)); + let h2 = await (s.hooks ? await s.hooks.provideParser() : e ? b.parse : b.parseInline)(c, s); + return s.hooks ? await s.hooks.postprocess(h2) : h2; + })().catch(a); + try { + s.hooks && (n = s.hooks.preprocess(n)); + let l = (s.hooks ? s.hooks.provideLexer() : e ? x.lex : x.lexInline)(n, s); + s.hooks && (l = s.hooks.processAllTokens(l)), s.walkTokens && this.walkTokens(l, s.walkTokens); + let c = (s.hooks ? s.hooks.provideParser() : e ? b.parse : b.parseInline)(l, s); + return s.hooks && (c = s.hooks.postprocess(c)), c; + } catch (o) { + return a(o); + } + }; + } + onError(e, t2) { + return (n) => { + if (n.message += ` +Please report this to https://github.com/markedjs/marked.`, e) { + let r = "

    An error occurred:

    " + w(n.message + "", true) + "
    "; + return t2 ? Promise.resolve(r) : r; + } + if (t2) + return Promise.reject(n); + throw n; + }; + } +}; +var _ = new B; +function d(u3, e) { + return _.parse(u3, e); +} +d.options = d.setOptions = function(u3) { + return _.setOptions(u3), d.defaults = _.defaults, Z(d.defaults), d; +}; +d.getDefaults = L; +d.defaults = T; +d.use = function(...u3) { + return _.use(...u3), d.defaults = _.defaults, Z(d.defaults), d; +}; +d.walkTokens = function(u3, e) { + return _.walkTokens(u3, e); +}; +d.parseInline = _.parseInline; +d.Parser = b; +d.parser = b.parse; +d.Renderer = P; +d.TextRenderer = $; +d.Lexer = x; +d.lexer = x.lex; +d.Tokenizer = y; +d.Hooks = S; +d.parse = d; +var Dt = d.options; +var Ht = d.setOptions; +var Zt = d.use; +var Gt = d.walkTokens; +var Nt = d.parseInline; +var Ft = b.parse; +var jt = x.lex; + +// src/renderables/TextTable.ts +var MEASURE_HEIGHT = 1e4; + +class TextTableRenderable extends Renderable { + _content; + _wrapMode; + _columnWidthMode; + _columnFitter; + _cellPaddingX; + _cellPaddingY; + _columnGap; + _showBorders; + _border; + _outerBorder; + _hasExplicitOuterBorder; + _borderStyle; + _borderColor; + _borderBackgroundColor; + _backgroundColor; + _defaultFg; + _defaultBg; + _defaultAttributes; + _selectionBg; + _selectionFg; + _lastLocalSelection = null; + _lastSelectionMode = null; + _cells = []; + _prevCellContent = []; + _rowCount = 0; + _columnCount = 0; + _layout = this.createEmptyLayout(); + _layoutDirty = true; + _rasterDirty = true; + _cachedMeasureLayout = null; + _cachedMeasureWidth = undefined; + _defaultOptions = { + content: [], + wrapMode: "word", + columnWidthMode: "full", + columnFitter: "proportional", + cellPadding: 0, + cellPaddingX: undefined, + cellPaddingY: undefined, + columnGap: 0, + showBorders: true, + border: true, + outerBorder: true, + selectable: true, + selectionBg: undefined, + selectionFg: undefined, + borderStyle: "single", + borderColor: "#FFFFFF", + borderBackgroundColor: "transparent", + backgroundColor: "transparent", + fg: "#FFFFFF", + bg: "transparent", + attributes: 0 + }; + constructor(ctx, options = {}) { + super(ctx, { ...options, flexShrink: options.flexShrink ?? 0, buffered: true }); + this._content = options.content ?? this._defaultOptions.content; + this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode; + this._columnWidthMode = options.columnWidthMode ?? this._defaultOptions.columnWidthMode; + this._columnFitter = this.resolveColumnFitter(options.columnFitter); + this._cellPaddingX = this.resolveCellPadding(options.cellPaddingX ?? options.cellPadding); + this._cellPaddingY = this.resolveCellPadding(options.cellPaddingY ?? options.cellPadding); + this._columnGap = this.resolveColumnGap(options.columnGap); + this._showBorders = options.showBorders ?? this._defaultOptions.showBorders; + this._border = options.border ?? this._defaultOptions.border; + this._hasExplicitOuterBorder = options.outerBorder !== undefined; + this._outerBorder = options.outerBorder ?? this._border; + this.selectable = options.selectable ?? this._defaultOptions.selectable; + this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : undefined; + this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : undefined; + this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle); + this._borderColor = parseColor(options.borderColor ?? this._defaultOptions.borderColor); + this._borderBackgroundColor = parseColor(options.borderBackgroundColor ?? this._defaultOptions.borderBackgroundColor); + this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor); + this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg); + this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg); + this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes; + this.setupMeasureFunc(); + this.rebuildCells(); + } + get content() { + return this._content; + } + set content(value) { + this._content = value ?? []; + this.rebuildCells(); + } + get wrapMode() { + return this._wrapMode; + } + set wrapMode(value) { + if (this._wrapMode === value) + return; + this._wrapMode = value; + for (const row of this._cells) { + for (const cell of row) { + cell.textBufferView.setWrapMode(value); + } + } + this.invalidateLayoutAndRaster(); + } + get columnWidthMode() { + return this._columnWidthMode; + } + set columnWidthMode(value) { + if (this._columnWidthMode === value) + return; + this._columnWidthMode = value; + this.invalidateLayoutAndRaster(); + } + get columnFitter() { + return this._columnFitter; + } + set columnFitter(value) { + const next = this.resolveColumnFitter(value); + if (this._columnFitter === next) + return; + this._columnFitter = next; + this.invalidateLayoutAndRaster(); + } + get cellPadding() { + return this._cellPaddingX === this._cellPaddingY ? this._cellPaddingX : 0; + } + set cellPadding(value) { + const next = this.resolveCellPadding(value); + if (this._cellPaddingX === next && this._cellPaddingY === next) + return; + this._cellPaddingX = next; + this._cellPaddingY = next; + this.invalidateLayoutAndRaster(); + } + get cellPaddingX() { + return this._cellPaddingX; + } + set cellPaddingX(value) { + const next = this.resolveCellPadding(value); + if (this._cellPaddingX === next) + return; + this._cellPaddingX = next; + this.invalidateLayoutAndRaster(); + } + get cellPaddingY() { + return this._cellPaddingY; + } + set cellPaddingY(value) { + const next = this.resolveCellPadding(value); + if (this._cellPaddingY === next) + return; + this._cellPaddingY = next; + this.invalidateLayoutAndRaster(); + } + get columnGap() { + return this._columnGap; + } + set columnGap(value) { + const next = this.resolveColumnGap(value); + if (this._columnGap === next) + return; + this._columnGap = next; + this.invalidateLayoutAndRaster(); + } + get showBorders() { + return this._showBorders; + } + set showBorders(value) { + if (this._showBorders === value) + return; + this._showBorders = value; + this.invalidateRasterOnly(); + } + get outerBorder() { + return this._outerBorder; + } + set outerBorder(value) { + if (this._outerBorder === value) + return; + this._hasExplicitOuterBorder = true; + this._outerBorder = value; + this.invalidateLayoutAndRaster(); + } + get border() { + return this._border; + } + set border(value) { + if (this._border === value) + return; + this._border = value; + if (!this._hasExplicitOuterBorder) { + this._outerBorder = value; + } + this.invalidateLayoutAndRaster(); + } + get borderStyle() { + return this._borderStyle; + } + set borderStyle(value) { + const next = parseBorderStyle(value, this._defaultOptions.borderStyle); + if (this._borderStyle === next) + return; + this._borderStyle = next; + this.invalidateRasterOnly(); + } + get borderColor() { + return this._borderColor; + } + set borderColor(value) { + const next = parseColor(value); + if (this._borderColor === next) + return; + this._borderColor = next; + this.invalidateRasterOnly(); + } + shouldStartSelection(x2, y2) { + if (!this.selectable) + return false; + this.ensureLayoutReady(); + const localX = x2 - this.x; + const localY = y2 - this.y; + return this.getCellAtLocalPosition(localX, localY) !== null; + } + onSelectionChanged(selection) { + this.ensureLayoutReady(); + const previousLocalSelection = this._lastLocalSelection; + const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y); + this._lastLocalSelection = localSelection; + const dirtyRows = this.getDirtySelectionRowRange(previousLocalSelection, localSelection); + if (!localSelection?.isActive) { + this.resetCellSelections(); + this._lastSelectionMode = null; + } else { + this.applySelectionToCells(localSelection, selection?.isStart ?? false); + } + if (dirtyRows !== null) { + this.redrawSelectionRows(dirtyRows.firstRow, dirtyRows.lastRow); + } + return this.hasSelection(); + } + hasSelection() { + for (const row of this._cells) { + for (const cell of row) { + if (cell.textBufferView.hasSelection()) { + return true; + } + } + } + return false; + } + getSelection() { + for (const row of this._cells) { + for (const cell of row) { + const selection = cell.textBufferView.getSelection(); + if (selection) { + return selection; + } + } + } + return null; + } + getSelectedText() { + const selectedRows = []; + for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) { + const rowSelections = []; + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const cell = this._cells[rowIdx]?.[colIdx]; + if (!cell || !cell.textBufferView.hasSelection()) + continue; + const selectedText = cell.textBufferView.getSelectedText(); + if (selectedText.length > 0) { + rowSelections.push(selectedText); + } + } + if (rowSelections.length > 0) { + selectedRows.push(rowSelections.join("\t")); + } + } + return selectedRows.join(` +`); + } + onResize(width, height) { + this.invalidateLayoutAndRaster(false); + super.onResize(width, height); + } + renderSelf(buffer) { + if (!this.visible || this.isDestroyed) + return; + if (this._layoutDirty) { + this.rebuildLayoutForCurrentWidth(); + } + if (!this._rasterDirty) + return; + buffer.clear(this._backgroundColor); + if (this._rowCount === 0 || this._columnCount === 0) { + this._rasterDirty = false; + return; + } + this.drawBorders(buffer); + this.drawCells(buffer); + this._rasterDirty = false; + } + destroySelf() { + this.destroyCells(); + super.destroySelf(); + } + setupMeasureFunc() { + const measureFunc = (width, widthMode, _height, _heightMode) => { + const hasWidthConstraint = widthMode !== 0 /* Undefined */ && Number.isFinite(width); + const rawWidthConstraint = hasWidthConstraint ? Math.max(1, Math.floor(width)) : undefined; + const widthConstraint = this.resolveLayoutWidthConstraint(rawWidthConstraint); + const measuredLayout = this.computeLayout(widthConstraint); + this._cachedMeasureLayout = measuredLayout; + this._cachedMeasureWidth = widthConstraint; + let measuredWidth = measuredLayout.tableWidth > 0 ? measuredLayout.tableWidth : 1; + let measuredHeight = measuredLayout.tableHeight > 0 ? measuredLayout.tableHeight : 1; + if (widthMode === 2 /* AtMost */ && rawWidthConstraint !== undefined && this._positionType !== "absolute") { + measuredWidth = Math.min(rawWidthConstraint, measuredWidth); + } + return { + width: measuredWidth, + height: measuredHeight + }; + }; + this.yogaNode.setMeasureFunc(measureFunc); + } + rebuildCells() { + const newRowCount = this._content.length; + const newColumnCount = this._content.reduce((max, row) => Math.max(max, row.length), 0); + if (this._cells.length === 0) { + this._rowCount = newRowCount; + this._columnCount = newColumnCount; + this._cells = []; + this._prevCellContent = []; + for (let rowIdx = 0;rowIdx < newRowCount; rowIdx++) { + const row = this._content[rowIdx] ?? []; + const rowCells = []; + const rowRefs = []; + for (let colIdx = 0;colIdx < newColumnCount; colIdx++) { + const cellContent = row[colIdx]; + rowCells.push(this.createCell(cellContent)); + rowRefs.push(cellContent); + } + this._cells.push(rowCells); + this._prevCellContent.push(rowRefs); + } + this.invalidateLayoutAndRaster(); + return; + } + this.updateCellsDiff(newRowCount, newColumnCount); + this.invalidateLayoutAndRaster(); + } + updateCellsDiff(newRowCount, newColumnCount) { + const oldRowCount = this._rowCount; + const oldColumnCount = this._columnCount; + const keepRows = Math.min(oldRowCount, newRowCount); + const keepCols = Math.min(oldColumnCount, newColumnCount); + for (let rowIdx = 0;rowIdx < keepRows; rowIdx++) { + const newRow = this._content[rowIdx] ?? []; + const cellRow = this._cells[rowIdx]; + const refRow = this._prevCellContent[rowIdx]; + for (let colIdx = 0;colIdx < keepCols; colIdx++) { + const cellContent = newRow[colIdx]; + if (cellContent === refRow[colIdx]) + continue; + const oldCell = cellRow[colIdx]; + oldCell.textBufferView.destroy(); + oldCell.textBuffer.destroy(); + oldCell.syntaxStyle.destroy(); + cellRow[colIdx] = this.createCell(cellContent); + refRow[colIdx] = cellContent; + } + if (newColumnCount > oldColumnCount) { + for (let colIdx = oldColumnCount;colIdx < newColumnCount; colIdx++) { + const cellContent = newRow[colIdx]; + cellRow.push(this.createCell(cellContent)); + refRow.push(cellContent); + } + } else if (newColumnCount < oldColumnCount) { + for (let colIdx = newColumnCount;colIdx < oldColumnCount; colIdx++) { + const cell = cellRow[colIdx]; + cell.textBufferView.destroy(); + cell.textBuffer.destroy(); + cell.syntaxStyle.destroy(); + } + cellRow.length = newColumnCount; + refRow.length = newColumnCount; + } + } + if (newRowCount > oldRowCount) { + for (let rowIdx = oldRowCount;rowIdx < newRowCount; rowIdx++) { + const newRow = this._content[rowIdx] ?? []; + const rowCells = []; + const rowRefs = []; + for (let colIdx = 0;colIdx < newColumnCount; colIdx++) { + const cellContent = newRow[colIdx]; + rowCells.push(this.createCell(cellContent)); + rowRefs.push(cellContent); + } + this._cells.push(rowCells); + this._prevCellContent.push(rowRefs); + } + } else if (newRowCount < oldRowCount) { + for (let rowIdx = newRowCount;rowIdx < oldRowCount; rowIdx++) { + const row = this._cells[rowIdx]; + for (const cell of row) { + cell.textBufferView.destroy(); + cell.textBuffer.destroy(); + cell.syntaxStyle.destroy(); + } + } + this._cells.length = newRowCount; + this._prevCellContent.length = newRowCount; + } + this._rowCount = newRowCount; + this._columnCount = newColumnCount; + } + createCell(content) { + const styledText = this.toStyledText(content); + const textBuffer = TextBuffer.create(this._ctx.widthMethod); + const syntaxStyle = SyntaxStyle.create(); + textBuffer.setDefaultFg(this._defaultFg); + textBuffer.setDefaultBg(this._defaultBg); + textBuffer.setDefaultAttributes(this._defaultAttributes); + textBuffer.setSyntaxStyle(syntaxStyle); + textBuffer.setStyledText(styledText); + const textBufferView = TextBufferView.create(textBuffer); + textBufferView.setWrapMode(this._wrapMode); + return { textBuffer, textBufferView, syntaxStyle }; + } + toStyledText(content) { + if (Array.isArray(content)) { + return new StyledText(content); + } + if (content === null || content === undefined) { + return stringToStyledText(""); + } + return stringToStyledText(String(content)); + } + destroyCells() { + for (const row of this._cells) { + for (const cell of row) { + cell.textBufferView.destroy(); + cell.textBuffer.destroy(); + cell.syntaxStyle.destroy(); + } + } + this._cells = []; + this._prevCellContent = []; + this._rowCount = 0; + this._columnCount = 0; + this._layout = this.createEmptyLayout(); + } + rebuildLayoutForCurrentWidth() { + const maxTableWidth = this.resolveLayoutWidthConstraint(this.width); + let layout; + if (this._cachedMeasureLayout !== null && this._cachedMeasureWidth === maxTableWidth) { + layout = this._cachedMeasureLayout; + } else { + layout = this.computeLayout(maxTableWidth); + } + this._cachedMeasureLayout = null; + this._cachedMeasureWidth = undefined; + this._layout = layout; + this.applyLayoutToViews(layout); + this._layoutDirty = false; + if (this._lastLocalSelection?.isActive) { + this.applySelectionToCells(this._lastLocalSelection, true); + } + } + computeLayout(maxTableWidth) { + if (this._rowCount === 0 || this._columnCount === 0) { + return this.createEmptyLayout(); + } + const borderLayout = this.resolveBorderLayout(); + const columnWidths = this.computeColumnWidths(maxTableWidth, borderLayout); + const rowHeights = this.computeRowHeights(columnWidths); + const columnOffsets = this.computeOffsets(columnWidths, borderLayout.left, borderLayout.right, borderLayout.innerVertical, this.getInterColumnGap(borderLayout)); + const rowOffsets = this.computeOffsets(rowHeights, borderLayout.top, borderLayout.bottom, borderLayout.innerHorizontal); + return { + columnWidths, + rowHeights, + columnOffsets, + rowOffsets, + columnOffsetsI32: new Int32Array(columnOffsets), + rowOffsetsI32: new Int32Array(rowOffsets), + tableWidth: (columnOffsets[columnOffsets.length - 1] ?? 0) + 1, + tableHeight: (rowOffsets[rowOffsets.length - 1] ?? 0) + 1 + }; + } + isFullWidthMode() { + return this._columnWidthMode === "full"; + } + computeColumnWidths(maxTableWidth, borderLayout) { + const horizontalPadding = this.getHorizontalCellPadding(); + const intrinsicWidths = new Array(this._columnCount).fill(1 + horizontalPadding); + for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) { + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const cell = this._cells[rowIdx]?.[colIdx]; + if (!cell) + continue; + const measure = cell.textBufferView.measureForDimensions(0, MEASURE_HEIGHT); + const measuredWidth = Math.max(1, measure?.widthColsMax ?? 0) + horizontalPadding; + intrinsicWidths[colIdx] = Math.max(intrinsicWidths[colIdx], measuredWidth); + } + } + if (maxTableWidth === undefined || !Number.isFinite(maxTableWidth) || maxTableWidth <= 0) { + return intrinsicWidths; + } + const maxContentWidth = Math.max(1, Math.floor(maxTableWidth) - this.getVerticalBorderCount(borderLayout) - this.getTotalInterColumnGap(borderLayout)); + const currentWidth = intrinsicWidths.reduce((sum, width) => sum + width, 0); + if (currentWidth === maxContentWidth) { + return intrinsicWidths; + } + if (currentWidth < maxContentWidth) { + if (this.isFullWidthMode()) { + return this.expandColumnWidths(intrinsicWidths, maxContentWidth); + } + return intrinsicWidths; + } + if (this._wrapMode === "none") { + return intrinsicWidths; + } + return this.fitColumnWidths(intrinsicWidths, maxContentWidth); + } + expandColumnWidths(widths, targetContentWidth) { + const baseWidths = widths.map((width) => Math.max(1, Math.floor(width))); + const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0); + if (totalBaseWidth >= targetContentWidth) { + return baseWidths; + } + const expanded = [...baseWidths]; + const columns = expanded.length; + const extraWidth = targetContentWidth - totalBaseWidth; + const sharedWidth = Math.floor(extraWidth / columns); + const remainder = extraWidth % columns; + for (let idx = 0;idx < columns; idx++) { + expanded[idx] += sharedWidth; + if (idx < remainder) { + expanded[idx] += 1; + } + } + return expanded; + } + fitColumnWidths(widths, targetContentWidth) { + if (this._columnFitter === "balanced") { + return this.fitColumnWidthsBalanced(widths, targetContentWidth); + } + return this.fitColumnWidthsProportional(widths, targetContentWidth); + } + fitColumnWidthsProportional(widths, targetContentWidth) { + const minWidth = 1 + this.getHorizontalCellPadding(); + const hardMinWidths = new Array(widths.length).fill(minWidth); + const baseWidths = widths.map((width) => Math.max(1, Math.floor(width))); + const preferredMinWidths = baseWidths.map((width) => Math.min(width, minWidth + 1)); + const preferredMinTotal = preferredMinWidths.reduce((sum, width) => sum + width, 0); + const floorWidths = preferredMinTotal <= targetContentWidth ? preferredMinWidths : hardMinWidths; + const floorTotal = floorWidths.reduce((sum, width) => sum + width, 0); + const clampedTarget = Math.max(floorTotal, targetContentWidth); + const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0); + if (totalBaseWidth <= clampedTarget) { + return baseWidths; + } + const shrinkable = baseWidths.map((width, idx) => width - floorWidths[idx]); + const totalShrinkable = shrinkable.reduce((sum, value) => sum + value, 0); + if (totalShrinkable <= 0) { + return [...floorWidths]; + } + const targetShrink = totalBaseWidth - clampedTarget; + const integerShrink = new Array(baseWidths.length).fill(0); + const fractions = new Array(baseWidths.length).fill(0); + let usedShrink = 0; + for (let idx = 0;idx < baseWidths.length; idx++) { + if (shrinkable[idx] <= 0) + continue; + const exact = shrinkable[idx] / totalShrinkable * targetShrink; + const whole = Math.min(shrinkable[idx], Math.floor(exact)); + integerShrink[idx] = whole; + fractions[idx] = exact - whole; + usedShrink += whole; + } + let remainingShrink = targetShrink - usedShrink; + while (remainingShrink > 0) { + let bestIdx = -1; + let bestFraction = -1; + for (let idx = 0;idx < baseWidths.length; idx++) { + if (shrinkable[idx] - integerShrink[idx] <= 0) + continue; + if (fractions[idx] > bestFraction) { + bestFraction = fractions[idx]; + bestIdx = idx; + } + } + if (bestIdx === -1) + break; + integerShrink[bestIdx] += 1; + fractions[bestIdx] = 0; + remainingShrink -= 1; + } + return baseWidths.map((width, idx) => Math.max(floorWidths[idx], width - integerShrink[idx])); + } + fitColumnWidthsBalanced(widths, targetContentWidth) { + const minWidth = 1 + this.getHorizontalCellPadding(); + const hardMinWidths = new Array(widths.length).fill(minWidth); + const baseWidths = widths.map((width) => Math.max(1, Math.floor(width))); + const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0); + const columns = baseWidths.length; + if (columns === 0 || totalBaseWidth <= targetContentWidth) { + return baseWidths; + } + const evenShare = Math.max(minWidth, Math.floor(targetContentWidth / columns)); + const preferredMinWidths = baseWidths.map((width) => Math.min(width, evenShare)); + const preferredMinTotal = preferredMinWidths.reduce((sum, width) => sum + width, 0); + const floorWidths = preferredMinTotal <= targetContentWidth ? preferredMinWidths : hardMinWidths; + const floorTotal = floorWidths.reduce((sum, width) => sum + width, 0); + const clampedTarget = Math.max(floorTotal, targetContentWidth); + if (totalBaseWidth <= clampedTarget) { + return baseWidths; + } + const shrinkable = baseWidths.map((width, idx) => width - floorWidths[idx]); + const totalShrinkable = shrinkable.reduce((sum, value) => sum + value, 0); + if (totalShrinkable <= 0) { + return [...floorWidths]; + } + const targetShrink = totalBaseWidth - clampedTarget; + const shrink = this.allocateShrinkByWeight(shrinkable, targetShrink, "sqrt"); + return baseWidths.map((width, idx) => Math.max(floorWidths[idx], width - shrink[idx])); + } + allocateShrinkByWeight(shrinkable, targetShrink, mode) { + const shrink = new Array(shrinkable.length).fill(0); + if (targetShrink <= 0) { + return shrink; + } + const weights = shrinkable.map((value) => { + if (value <= 0) { + return 0; + } + return mode === "sqrt" ? Math.sqrt(value) : value; + }); + const totalWeight = weights.reduce((sum, value) => sum + value, 0); + if (totalWeight <= 0) { + return shrink; + } + const fractions = new Array(shrinkable.length).fill(0); + let usedShrink = 0; + for (let idx = 0;idx < shrinkable.length; idx++) { + if (shrinkable[idx] <= 0 || weights[idx] <= 0) + continue; + const exact = weights[idx] / totalWeight * targetShrink; + const whole = Math.min(shrinkable[idx], Math.floor(exact)); + shrink[idx] = whole; + fractions[idx] = exact - whole; + usedShrink += whole; + } + let remainingShrink = targetShrink - usedShrink; + while (remainingShrink > 0) { + let bestIdx = -1; + let bestFraction = -1; + for (let idx = 0;idx < shrinkable.length; idx++) { + if (shrinkable[idx] - shrink[idx] <= 0) + continue; + if (bestIdx === -1 || fractions[idx] > bestFraction || fractions[idx] === bestFraction && shrinkable[idx] > shrinkable[bestIdx]) { + bestIdx = idx; + bestFraction = fractions[idx]; + } + } + if (bestIdx === -1) { + break; + } + shrink[bestIdx] += 1; + fractions[bestIdx] = 0; + remainingShrink -= 1; + } + return shrink; + } + computeRowHeights(columnWidths) { + const horizontalPadding = this.getHorizontalCellPadding(); + const verticalPadding = this.getVerticalCellPadding(); + const rowHeights = new Array(this._rowCount).fill(1 + verticalPadding); + for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) { + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const cell = this._cells[rowIdx]?.[colIdx]; + if (!cell) + continue; + const width = Math.max(1, (columnWidths[colIdx] ?? 1) - horizontalPadding); + const measure = cell.textBufferView.measureForDimensions(width, MEASURE_HEIGHT); + const lineCount = Math.max(1, measure?.lineCount ?? 1); + rowHeights[rowIdx] = Math.max(rowHeights[rowIdx], lineCount + verticalPadding); + } + } + return rowHeights; + } + computeOffsets(parts, startBoundary, endBoundary, includeInnerBoundaries, innerGap = 0) { + const offsets = [startBoundary ? 0 : -1]; + let cursor = offsets[0] ?? 0; + for (let idx = 0;idx < parts.length; idx++) { + const size = parts[idx] ?? 1; + const separatorAfter = idx < parts.length - 1 ? includeInnerBoundaries ? 1 : innerGap : endBoundary ? 1 : 0; + cursor += size + separatorAfter; + offsets.push(cursor); + } + return offsets; + } + getInterColumnGap(borderLayout) { + if (borderLayout.innerVertical) { + return 0; + } + return this._columnGap; + } + getTotalInterColumnGap(borderLayout) { + return Math.max(0, this._columnCount - 1) * this.getInterColumnGap(borderLayout); + } + applyLayoutToViews(layout) { + const horizontalPadding = this.getHorizontalCellPadding(); + const verticalPadding = this.getVerticalCellPadding(); + for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) { + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const cell = this._cells[rowIdx]?.[colIdx]; + if (!cell) + continue; + const colWidth = layout.columnWidths[colIdx] ?? 1; + const rowHeight = layout.rowHeights[rowIdx] ?? 1; + const contentWidth = Math.max(1, colWidth - horizontalPadding); + const contentHeight = Math.max(1, rowHeight - verticalPadding); + if (this._wrapMode === "none") { + cell.textBufferView.setWrapWidth(null); + } else { + cell.textBufferView.setWrapWidth(contentWidth); + } + cell.textBufferView.setViewport(0, 0, contentWidth, contentHeight); + } + } + } + resolveBorderLayout() { + return { + left: this._outerBorder, + right: this._outerBorder, + top: this._outerBorder, + bottom: this._outerBorder, + innerVertical: this._border && this._columnCount > 1, + innerHorizontal: this._border && this._rowCount > 1 + }; + } + getVerticalBorderCount(borderLayout) { + return (borderLayout.left ? 1 : 0) + (borderLayout.right ? 1 : 0) + (borderLayout.innerVertical ? Math.max(0, this._columnCount - 1) : 0); + } + getHorizontalBorderCount(borderLayout) { + return (borderLayout.top ? 1 : 0) + (borderLayout.bottom ? 1 : 0) + (borderLayout.innerHorizontal ? Math.max(0, this._rowCount - 1) : 0); + } + drawBorders(buffer) { + if (!this._showBorders) { + return; + } + const borderLayout = this.resolveBorderLayout(); + if (this.getVerticalBorderCount(borderLayout) === 0 && this.getHorizontalBorderCount(borderLayout) === 0) { + return; + } + buffer.drawGrid({ + borderChars: BorderCharArrays[this._borderStyle], + borderFg: this._borderColor, + borderBg: this._borderBackgroundColor, + columnOffsets: this._layout.columnOffsetsI32, + rowOffsets: this._layout.rowOffsetsI32, + drawInner: this._border, + drawOuter: this._outerBorder + }); + } + drawCells(buffer) { + this.drawCellRange(buffer, 0, this._rowCount - 1); + } + drawCellRange(buffer, firstRow, lastRow) { + const colOffsets = this._layout.columnOffsets; + const rowOffsets = this._layout.rowOffsets; + const cellPaddingX = this._cellPaddingX; + const cellPaddingY = this._cellPaddingY; + for (let rowIdx = firstRow;rowIdx <= lastRow; rowIdx++) { + const cellY = (rowOffsets[rowIdx] ?? 0) + 1 + cellPaddingY; + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const cell = this._cells[rowIdx]?.[colIdx]; + if (!cell) + continue; + buffer.drawTextBuffer(cell.textBufferView, (colOffsets[colIdx] ?? 0) + 1 + cellPaddingX, cellY); + } + } + } + redrawSelectionRows(firstRow, lastRow) { + if (firstRow > lastRow) + return; + if (this._backgroundColor.a < 1) { + this.invalidateRasterOnly(); + return; + } + const buffer = this.frameBuffer; + if (!buffer) + return; + this.clearCellRange(buffer, firstRow, lastRow); + this.drawCellRange(buffer, firstRow, lastRow); + this.requestRender(); + } + clearCellRange(buffer, firstRow, lastRow) { + const colWidths = this._layout.columnWidths; + const rowHeights = this._layout.rowHeights; + const colOffsets = this._layout.columnOffsets; + const rowOffsets = this._layout.rowOffsets; + for (let rowIdx = firstRow;rowIdx <= lastRow; rowIdx++) { + const cellY = (rowOffsets[rowIdx] ?? 0) + 1; + const rowHeight = rowHeights[rowIdx] ?? 1; + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const cellX = (colOffsets[colIdx] ?? 0) + 1; + const colWidth = colWidths[colIdx] ?? 1; + if (this._backgroundColor.a < 1) { + for (let y2 = cellY;y2 < cellY + rowHeight; y2++) { + for (let x2 = cellX;x2 < cellX + colWidth; x2++) { + buffer.setCell(x2, y2, " ", this._defaultFg, this._backgroundColor, this._defaultAttributes); + } + } + } else { + buffer.fillRect(cellX, cellY, colWidth, rowHeight, this._backgroundColor); + } + } + } + } + ensureLayoutReady() { + if (!this._layoutDirty) + return; + this.rebuildLayoutForCurrentWidth(); + } + getCellAtLocalPosition(localX, localY) { + if (this._rowCount === 0 || this._columnCount === 0) + return null; + if (localX < 0 || localY < 0 || localX >= this._layout.tableWidth || localY >= this._layout.tableHeight) { + return null; + } + let rowIdx = -1; + for (let idx = 0;idx < this._rowCount; idx++) { + const top = (this._layout.rowOffsets[idx] ?? 0) + 1; + const bottom = top + (this._layout.rowHeights[idx] ?? 1) - 1; + if (localY >= top && localY <= bottom) { + rowIdx = idx; + break; + } + } + if (rowIdx < 0) + return null; + let colIdx = -1; + for (let idx = 0;idx < this._columnCount; idx++) { + const left = (this._layout.columnOffsets[idx] ?? 0) + 1; + const right = left + (this._layout.columnWidths[idx] ?? 1) - 1; + if (localX >= left && localX <= right) { + colIdx = idx; + break; + } + } + if (colIdx < 0) + return null; + return { rowIdx, colIdx }; + } + applySelectionToCells(localSelection, isStart) { + if (localSelection.anchorX === localSelection.focusX && localSelection.anchorY === localSelection.focusY) { + this.resetCellSelections(); + this._lastSelectionMode = null; + return; + } + const minSelY = Math.min(localSelection.anchorY, localSelection.focusY); + const maxSelY = Math.max(localSelection.anchorY, localSelection.focusY); + const firstRow = this.findRowForLocalY(minSelY); + const lastRow = this.findRowForLocalY(maxSelY); + const selection = this.resolveSelectionResolution(localSelection); + const modeChanged = this._lastSelectionMode !== selection.mode; + this._lastSelectionMode = selection.mode; + const lockToAnchorColumn = selection.mode === "column-locked" && selection.anchorColumn !== null; + for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) { + if (rowIdx < firstRow || rowIdx > lastRow) { + this.resetRowSelection(rowIdx); + continue; + } + const cellTop = (this._layout.rowOffsets[rowIdx] ?? 0) + 1 + this._cellPaddingY; + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const cell = this._cells[rowIdx]?.[colIdx]; + if (!cell) + continue; + if (lockToAnchorColumn && colIdx !== selection.anchorColumn) { + cell.textBufferView.resetLocalSelection(); + continue; + } + const cellLeft = (this._layout.columnOffsets[colIdx] ?? 0) + 1 + this._cellPaddingX; + let coords = { + anchorX: localSelection.anchorX - cellLeft, + anchorY: localSelection.anchorY - cellTop, + focusX: localSelection.focusX - cellLeft, + focusY: localSelection.focusY - cellTop + }; + const isAnchorCell = selection.anchorCell !== null && selection.anchorCell.rowIdx === rowIdx && selection.anchorCell.colIdx === colIdx; + if (selection.mode === "single-cell" && !isAnchorCell) { + cell.textBufferView.resetLocalSelection(); + continue; + } + const forceSet = isAnchorCell && selection.mode !== "single-cell"; + if (forceSet) { + coords = this.getFullCellSelectionCoords(rowIdx, colIdx); + } + const shouldUseSet = isStart || modeChanged || forceSet; + if (shouldUseSet) { + cell.textBufferView.setLocalSelection(coords.anchorX, coords.anchorY, coords.focusX, coords.focusY, this._selectionBg, this._selectionFg); + } else { + cell.textBufferView.updateLocalSelection(coords.anchorX, coords.anchorY, coords.focusX, coords.focusY, this._selectionBg, this._selectionFg); + } + } + } + } + resolveSelectionResolution(localSelection) { + const anchorCell = this.getCellAtLocalPosition(localSelection.anchorX, localSelection.anchorY); + const focusCell = this.getCellAtLocalPosition(localSelection.focusX, localSelection.focusY); + const anchorColumn = anchorCell?.colIdx ?? this.getColumnAtLocalX(localSelection.anchorX); + if (anchorCell !== null && focusCell !== null && anchorCell.rowIdx === focusCell.rowIdx && anchorCell.colIdx === focusCell.colIdx) { + return { + mode: "single-cell", + anchorCell, + anchorColumn + }; + } + const focusColumn = this.getColumnAtLocalX(localSelection.focusX); + if (anchorColumn !== null && focusColumn === anchorColumn) { + return { + mode: "column-locked", + anchorCell, + anchorColumn + }; + } + return { + mode: "grid", + anchorCell, + anchorColumn + }; + } + getColumnAtLocalX(localX) { + if (this._columnCount === 0) + return null; + if (localX < 0 || localX >= this._layout.tableWidth) + return null; + for (let colIdx = 0;colIdx < this._columnCount; colIdx++) { + const colStart = (this._layout.columnOffsets[colIdx] ?? 0) + 1; + const colEnd = colStart + (this._layout.columnWidths[colIdx] ?? 1) - 1; + if (localX >= colStart && localX <= colEnd) { + return colIdx; + } + } + return null; + } + getFullCellSelectionCoords(rowIdx, colIdx) { + const colWidth = this._layout.columnWidths[colIdx] ?? 1; + const rowHeight = this._layout.rowHeights[rowIdx] ?? 1; + const contentWidth = Math.max(1, colWidth - this.getHorizontalCellPadding()); + const contentHeight = Math.max(1, rowHeight - this.getVerticalCellPadding()); + return { + anchorX: -1, + anchorY: 0, + focusX: contentWidth, + focusY: contentHeight + }; + } + findRowForLocalY(localY) { + if (this._rowCount === 0) + return 0; + if (localY < 0) + return 0; + for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) { + const rowStart = (this._layout.rowOffsets[rowIdx] ?? 0) + 1; + const rowEnd = rowStart + (this._layout.rowHeights[rowIdx] ?? 1) - 1; + if (localY <= rowEnd) + return rowIdx; + } + return this._rowCount - 1; + } + getSelectionRowRange(selection) { + if (!selection?.isActive || this._rowCount === 0) + return null; + const minSelY = Math.min(selection.anchorY, selection.focusY); + const maxSelY = Math.max(selection.anchorY, selection.focusY); + return { + firstRow: this.findRowForLocalY(minSelY), + lastRow: this.findRowForLocalY(maxSelY) + }; + } + getDirtySelectionRowRange(previousSelection, currentSelection) { + const previousRange = this.getSelectionRowRange(previousSelection); + const currentRange = this.getSelectionRowRange(currentSelection); + if (previousRange === null) + return currentRange; + if (currentRange === null) + return previousRange; + return { + firstRow: Math.min(previousRange.firstRow, currentRange.firstRow), + lastRow: Math.max(previousRange.lastRow, currentRange.lastRow) + }; + } + resetRowSelection(rowIdx) { + const row = this._cells[rowIdx]; + if (!row) + return; + for (const cell of row) { + cell.textBufferView.resetLocalSelection(); + } + } + resetCellSelections() { + for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) { + this.resetRowSelection(rowIdx); + } + } + createEmptyLayout() { + return { + columnWidths: [], + rowHeights: [], + columnOffsets: [0], + rowOffsets: [0], + columnOffsetsI32: new Int32Array([0]), + rowOffsetsI32: new Int32Array([0]), + tableWidth: 0, + tableHeight: 0 + }; + } + resolveLayoutWidthConstraint(width) { + if (width === undefined || !Number.isFinite(width) || width <= 0) { + return; + } + if (this._wrapMode !== "none" || this.isFullWidthMode()) { + return Math.max(1, Math.floor(width)); + } + return; + } + getHorizontalCellPadding() { + return this._cellPaddingX * 2; + } + getVerticalCellPadding() { + return this._cellPaddingY * 2; + } + resolveColumnFitter(value) { + if (value === undefined) { + return this._defaultOptions.columnFitter; + } + return value === "balanced" ? "balanced" : "proportional"; + } + resolveCellPadding(value) { + if (value === undefined || !Number.isFinite(value)) { + return this._defaultOptions.cellPadding; + } + return Math.max(0, Math.floor(value)); + } + resolveColumnGap(value) { + if (value === undefined || !Number.isFinite(value)) { + return this._defaultOptions.columnGap; + } + return Math.max(0, Math.floor(value)); + } + invalidateLayoutAndRaster(markYogaDirty = true) { + this._layoutDirty = true; + this._rasterDirty = true; + this._cachedMeasureLayout = null; + this._cachedMeasureWidth = undefined; + if (markYogaDirty) { + this.yogaNode.markDirty(); + } + this.requestRender(); + } + invalidateRasterOnly() { + this._rasterDirty = true; + this.requestRender(); + } +} + +// src/renderables/markdown-parser.ts +function parseMarkdownIncremental(newContent, prevState, trailingUnstable = 2) { + if (!prevState || prevState.tokens.length === 0) { + try { + const tokens = x.lex(newContent, { gfm: true }); + return { + content: newContent, + tokens, + stableTokenCount: Math.max(0, tokens.length - trailingUnstable) + }; + } catch { + return { content: newContent, tokens: [], stableTokenCount: 0 }; + } + } + let offset = 0; + let reuseCount = 0; + for (const token of prevState.tokens) { + const tokenLength = token.raw.length; + if (offset + tokenLength <= newContent.length && newContent.startsWith(token.raw, offset)) { + reuseCount++; + offset += tokenLength; + } else { + break; + } + } + reuseCount = Math.max(0, reuseCount - trailingUnstable); + offset = 0; + for (let i = 0;i < reuseCount; i++) { + offset += prevState.tokens[i].raw.length; + } + const stableTokens = prevState.tokens.slice(0, reuseCount); + const remainingContent = newContent.slice(offset); + if (!remainingContent) { + return { + content: newContent, + tokens: stableTokens, + stableTokenCount: stableTokens.length + }; + } + try { + const newTokens = x.lex(remainingContent, { gfm: true }); + return { + content: newContent, + tokens: [...stableTokens, ...newTokens], + stableTokenCount: trailingUnstable === 0 ? stableTokens.length + newTokens.length : stableTokens.length + }; + } catch { + try { + const fullTokens = x.lex(newContent, { gfm: true }); + return { content: newContent, tokens: fullTokens, stableTokenCount: 0 }; + } catch { + return { content: newContent, tokens: [], stableTokenCount: 0 }; + } + } +} + +// src/renderables/Markdown.ts +function normalizeMarkdownCodeBlockRenderers(renderers) { + const rendererMap = new Map; + const maybeMap = renderers; + if (typeof maybeMap.forEach === "function") { + maybeMap.forEach((renderer, language) => { + rendererMap.set(language, renderer); + }); + return rendererMap; + } + const rendererRecord = renderers; + for (const [language, renderer] of Object.entries(rendererRecord)) { + rendererMap.set(language, renderer); + } + return rendererMap; +} +function createMarkdownCodeBlockRenderer(renderers) { + const rendererMap = normalizeMarkdownCodeBlockRenderers(renderers); + const renderNode = (token, context) => { + if (token.type !== "code") { + return; + } + const language = infoStringToFiletype(token.lang ?? ""); + if (!language) + return; + return rendererMap.get(language)?.(token, context); + }; + renderNode.codeBlockOnly = true; + return renderNode; +} +var TRAILING_MARKDOWN_BLOCK_BREAKS_RE = /(?:\r?\n){2,}$/; +var TRAILING_MARKDOWN_BLOCK_NEWLINES_RE = /(?:\r?\n)+$/; +function colorsEqual(left, right) { + if (!left || !right) + return left === right; + return left.equals(right); +} + +class MarkdownRenderable extends Renderable { + _content = ""; + _syntaxStyle; + _fg; + _bg; + _conceal; + _concealCode; + _treeSitterClient; + _tableOptions; + _renderNode; + _internalBlockMode; + _parseState = null; + _streaming = false; + _blockStates = []; + _stableBlockCount = 0; + _styleDirty = false; + _linkifyMarkdownChunks = (chunks, context) => detectLinks(chunks, { + content: context.content, + highlights: context.highlights + }); + _contentDefaultOptions = { + content: "", + conceal: true, + concealCode: false, + streaming: false, + internalBlockMode: "coalesced" + }; + constructor(ctx, options) { + super(ctx, { + ...options, + flexDirection: "column", + flexShrink: options.flexShrink ?? 0 + }); + this._syntaxStyle = options.syntaxStyle; + this._fg = options.fg ? parseColor(options.fg) : undefined; + this._bg = options.bg ? parseColor(options.bg) : undefined; + this._conceal = options.conceal ?? this._contentDefaultOptions.conceal; + this._concealCode = options.concealCode ?? this._contentDefaultOptions.concealCode; + this._content = options.content ?? this._contentDefaultOptions.content; + this._treeSitterClient = options.treeSitterClient; + this._tableOptions = options.tableOptions; + this._renderNode = options.renderNode; + this._streaming = options.streaming ?? this._contentDefaultOptions.streaming; + this._internalBlockMode = options.internalBlockMode ?? this._contentDefaultOptions.internalBlockMode; + this.updateBlocks(); + } + get content() { + return this._content; + } + set content(value) { + if (this.isDestroyed) + return; + if (this._content !== value) { + this._content = value; + this.updateBlocks(); + this.requestRender(); + } + } + get syntaxStyle() { + return this._syntaxStyle; + } + set syntaxStyle(value) { + if (this._syntaxStyle !== value) { + this._syntaxStyle = value; + this._styleDirty = true; + } + } + get fg() { + return this._fg; + } + set fg(value) { + const next = value ? parseColor(value) : undefined; + if (!colorsEqual(this._fg, next)) { + this._fg = next; + this._styleDirty = true; + } + } + get bg() { + return this._bg; + } + set bg(value) { + const next = value ? parseColor(value) : undefined; + if (!colorsEqual(this._bg, next)) { + this._bg = next; + this._styleDirty = true; + } + } + get conceal() { + return this._conceal; + } + set conceal(value) { + if (this._conceal !== value) { + this._conceal = value; + this._styleDirty = true; + } + } + get concealCode() { + return this._concealCode; + } + set concealCode(value) { + if (this._concealCode !== value) { + this._concealCode = value; + this._styleDirty = true; + } + } + get streaming() { + return this._streaming; + } + set streaming(value) { + if (this.isDestroyed) + return; + if (this._streaming !== value) { + this._streaming = value; + this.updateBlocks(true); + } + } + get tableOptions() { + return this._tableOptions; + } + set tableOptions(value) { + this._tableOptions = value; + this.applyTableOptionsToBlocks(); + } + get renderNode() { + return this._renderNode; + } + set renderNode(value) { + if (this._renderNode === value) + return; + this._renderNode = value; + this.clearBlockStates(); + this._parseState = null; + this.updateBlocks(true); + this.requestRender(); + } + get internalBlockMode() { + return this._internalBlockMode; + } + set internalBlockMode(value) { + if (this._internalBlockMode === value) + return; + this._internalBlockMode = value; + this.updateBlocks(true); + this.requestRender(); + } + getStyle(group) { + if (!this._syntaxStyle) + return; + let style = this._syntaxStyle.getStyle(group); + if (!style && group.includes(".")) { + const baseName = group.split(".")[0]; + style = this._syntaxStyle.getStyle(baseName); + } + return style; + } + createChunk(text, group, link2) { + const style = this.getStyle(group) || this.getStyle("default"); + return { + __isChunk: true, + text, + fg: style?.fg, + bg: style?.bg, + attributes: style ? createTextAttributes({ + bold: style.bold, + italic: style.italic, + underline: style.underline, + dim: style.dim + }) : 0, + link: link2 + }; + } + createDefaultChunk(text) { + return this.createChunk(text, "default"); + } + createInitialStyledText(token) { + if (!this._streaming) + return; + const chunks = []; + if ("tokens" in token && Array.isArray(token.tokens)) { + this.renderInlineContent(token.tokens, chunks); + } + if (chunks.length === 0 && "text" in token && typeof token.text === "string") { + this.renderInlineContent(x.lexInline(token.text), chunks); + } + return chunks.length > 0 ? new StyledText(chunks) : undefined; + } + renderInlineContent(tokens, chunks) { + for (const token of tokens) { + this.renderInlineToken(token, chunks); + } + } + renderInlineToken(token, chunks) { + switch (token.type) { + case "text": + chunks.push(this.createDefaultChunk(token.text)); + break; + case "escape": + chunks.push(this.createDefaultChunk(token.text)); + break; + case "codespan": + if (this._conceal) { + chunks.push(this.createChunk(token.text, "markup.raw")); + } else { + chunks.push(this.createChunk("`", "markup.raw")); + chunks.push(this.createChunk(token.text, "markup.raw")); + chunks.push(this.createChunk("`", "markup.raw")); + } + break; + case "strong": + if (!this._conceal) { + chunks.push(this.createChunk("**", "markup.strong")); + } + for (const child of token.tokens) { + this.renderInlineTokenWithStyle(child, chunks, "markup.strong"); + } + if (!this._conceal) { + chunks.push(this.createChunk("**", "markup.strong")); + } + break; + case "em": + if (!this._conceal) { + chunks.push(this.createChunk("*", "markup.italic")); + } + for (const child of token.tokens) { + this.renderInlineTokenWithStyle(child, chunks, "markup.italic"); + } + if (!this._conceal) { + chunks.push(this.createChunk("*", "markup.italic")); + } + break; + case "del": + if (!this._conceal) { + chunks.push(this.createChunk("~~", "markup.strikethrough")); + } + for (const child of token.tokens) { + this.renderInlineTokenWithStyle(child, chunks, "markup.strikethrough"); + } + if (!this._conceal) { + chunks.push(this.createChunk("~~", "markup.strikethrough")); + } + break; + case "link": { + const linkHref = { url: token.href }; + if (this._conceal) { + for (const child of token.tokens) { + this.renderInlineTokenWithStyle(child, chunks, "markup.link.label", linkHref); + } + chunks.push(this.createChunk(" (", "markup.link", linkHref)); + chunks.push(this.createChunk(token.href, "markup.link.url", linkHref)); + chunks.push(this.createChunk(")", "markup.link", linkHref)); + } else { + chunks.push(this.createChunk("[", "markup.link", linkHref)); + for (const child of token.tokens) { + this.renderInlineTokenWithStyle(child, chunks, "markup.link.label", linkHref); + } + chunks.push(this.createChunk("](", "markup.link", linkHref)); + chunks.push(this.createChunk(token.href, "markup.link.url", linkHref)); + chunks.push(this.createChunk(")", "markup.link", linkHref)); + } + break; + } + case "image": { + const imageHref = { url: token.href }; + if (this._conceal) { + chunks.push(this.createChunk(token.text || "image", "markup.link.label", imageHref)); + } else { + chunks.push(this.createChunk("![", "markup.link", imageHref)); + chunks.push(this.createChunk(token.text || "", "markup.link.label", imageHref)); + chunks.push(this.createChunk("](", "markup.link", imageHref)); + chunks.push(this.createChunk(token.href, "markup.link.url", imageHref)); + chunks.push(this.createChunk(")", "markup.link", imageHref)); + } + break; + } + case "br": + chunks.push(this.createDefaultChunk(` +`)); + break; + default: + if ("tokens" in token && Array.isArray(token.tokens)) { + this.renderInlineContent(token.tokens, chunks); + } else if ("text" in token && typeof token.text === "string") { + chunks.push(this.createDefaultChunk(token.text)); + } + break; + } + } + renderInlineTokenWithStyle(token, chunks, styleGroup, link2) { + switch (token.type) { + case "text": + chunks.push(this.createChunk(token.text, styleGroup, link2)); + break; + case "escape": + chunks.push(this.createChunk(token.text, styleGroup, link2)); + break; + case "codespan": + if (this._conceal) { + chunks.push(this.createChunk(token.text, "markup.raw", link2)); + } else { + chunks.push(this.createChunk("`", "markup.raw", link2)); + chunks.push(this.createChunk(token.text, "markup.raw", link2)); + chunks.push(this.createChunk("`", "markup.raw", link2)); + } + break; + default: + this.renderInlineToken(token, chunks); + break; + } + } + applyMargins(renderable, marginTop, marginBottom) { + renderable.marginTop = marginTop; + renderable.marginBottom = marginBottom; + } + createMarkdownCodeRenderable(content, id, marginBottom = 0, onChunks = this._linkifyMarkdownChunks, baseHighlight, initialStyledText) { + return new CodeRenderable(this.ctx, { + id, + content, + filetype: "markdown", + syntaxStyle: this._syntaxStyle, + fg: this._fg, + bg: this._bg, + conceal: this._conceal, + drawUnstyledText: initialStyledText !== undefined, + streaming: true, + initialStyledText, + baseHighlight, + onChunks, + treeSitterClient: this._treeSitterClient, + width: "100%", + marginBottom + }); + } + getBlockquoteContent(token) { + return "text" in token && typeof token.text === "string" && token.text ? token.text : " "; + } + getBlockquoteBorderColor() { + return this.getStyle("conceal")?.fg ?? this.getStyle("default")?.fg ?? this._fg ?? "#FFFFFF"; + } + createBlockquoteRenderable(token, id, marginBottom = 0) { + const renderable = new BoxRenderable(this.ctx, { + id, + width: "100%", + border: ["left"], + borderColor: this.getBlockquoteBorderColor(), + paddingLeft: 1, + flexShrink: 0, + marginBottom + }); + renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token), `${id}-content`, 0, this._linkifyMarkdownChunks, "markup.quote")); + return renderable; + } + createListRenderable(token, id, marginBottom = 0) { + const list = new BoxRenderable(this.ctx, { + id, + width: "100%", + flexDirection: "column", + flexShrink: 0, + marginBottom + }); + for (const item of this.getListItemInputs(token, id)) { + list.add(this.createListItemRenderable(item)); + } + return list; + } + getListItemInputs(token, id) { + const items = token.items ?? []; + const start = token.start === "" || token.start === undefined || token.start === null ? 1 : Number(token.start); + const markerWidth = Math.max(1, ...items.map((_2, index) => (token.ordered ? `${start + index}.` : "-").length)); + return items.map((item, index) => ({ + item, + marker: token.ordered ? `${start + index}.` : "-", + markerWidth, + id: `${id}-item-${index}` + })); + } + applyListRenderable(renderable, token, previousToken, id, marginBottom = 0) { + if (!(renderable instanceof BoxRenderable)) + return false; + renderable.marginBottom = marginBottom; + const inputs = this.getListItemInputs(token, id); + const previousItems = previousToken?.items ?? []; + const rows = renderable.getChildren(); + for (let index = 0;index < inputs.length; index += 1) { + const input = inputs[index]; + const existing = rows[index]; + if (existing instanceof BoxRenderable && this.applyListItemRenderable(existing, input, previousItems[index])) { + continue; + } + existing?.destroyRecursively(); + renderable.add(this.createListItemRenderable(input), index); + } + for (let index = rows.length - 1;index >= inputs.length; index -= 1) { + rows[index]?.destroyRecursively(); + } + return true; + } + createListItemRenderable(input) { + const row = new BoxRenderable(this.ctx, { + id: input.id, + width: "100%", + flexDirection: "row", + flexShrink: 0, + marginBottom: /\n[ \t]*\n$/.test(input.item.raw) ? 1 : 0 + }); + row.add(new TextRenderable(this.ctx, { + id: `${input.id}-marker`, + content: new StyledText([this.createChunk(input.marker.padStart(input.markerWidth) + " ", "markup.list")]), + width: input.markerWidth + 1, + flexShrink: 0 + })); + const content = new BoxRenderable(this.ctx, { + id: `${input.id}-content`, + flexDirection: "column", + flexGrow: 1, + flexShrink: 1 + }); + row.add(content); + let pendingMarginTop = 0; + for (let index = 0;index < input.item.tokens.length; index += 1) { + const child = input.item.tokens[index]; + if (!child) + continue; + if (child.type === "checkbox") + continue; + if (child.type === "space") { + pendingMarginTop = Math.max(pendingMarginTop, 1); + continue; + } + const renderable = this.createListChildRenderable(child, `${input.id}-child-${index}`); + if (!renderable) + continue; + renderable.marginTop = child.type === "list" ? 0 : pendingMarginTop; + pendingMarginTop = 0; + content.add(renderable); + } + return row; + } + applyListItemRenderable(row, input, previousItem) { + this.applyListItemMarker(row, input); + const content = row.getChildren()[1]; + if (!(content instanceof BoxRenderable)) + return false; + if (previousItem && previousItem.raw === input.item.raw) { + return true; + } + return this.applyListItemChildren(content, input.item, previousItem, input.id); + } + applyListItemChildren(content, item, previousItem, id) { + const previousTokens = previousItem ? this.getRenderableListItemTokens(previousItem) : []; + const children = content.getChildren(); + let childIndex = 0; + let pendingMarginTop = 0; + for (let tokenIndex = 0;tokenIndex < item.tokens.length; tokenIndex += 1) { + const token = item.tokens[tokenIndex]; + if (!token) + continue; + if (token.type === "checkbox") + continue; + if (token.type === "space") { + pendingMarginTop = Math.max(pendingMarginTop, 1); + continue; + } + const existing = children[childIndex]; + const childId = `${id}-child-${tokenIndex}`; + const marginTop = token.type === "list" ? 0 : pendingMarginTop; + pendingMarginTop = 0; + if (!existing) { + const renderable = this.createListChildRenderable(token, childId); + if (!renderable) + return false; + renderable.marginTop = marginTop; + content.add(renderable, childIndex); + childIndex += 1; + continue; + } + if (!this.applyListChildRenderable(existing, token, previousTokens[childIndex], childId)) { + return false; + } + existing.marginTop = marginTop; + childIndex += 1; + } + this.destroyListItemChildrenAfter(content, childIndex); + return true; + } + getRenderableListItemTokens(item) { + const tokens = []; + for (const token of item.tokens) { + if (token.type === "checkbox" || token.type === "space") + continue; + tokens.push(token); + } + return tokens; + } + applyListChildRenderable(renderable, token, previousToken, id) { + if ((token.type === "text" || token.type === "paragraph") && renderable instanceof CodeRenderable) { + this.applyMarkdownCodeRenderable(renderable, this.normalizeScrollbackMarkdownBlockRaw(token.raw), 0); + return true; + } + if (token.type === "list" && renderable instanceof BoxRenderable) { + return this.applyListRenderable(renderable, token, previousToken, id); + } + if (token.type === "code" && renderable instanceof CodeRenderable) { + this.applyCodeBlockRenderable(renderable, token, 0); + return true; + } + return previousToken?.raw === token.raw; + } + destroyListItemChildrenAfter(content, index) { + const children = content.getChildren(); + for (let i = children.length - 1;i >= index; i -= 1) { + children[i]?.destroyRecursively(); + } + } + applyListItemMarker(row, input) { + const marker = row.getChildren()[0]; + if (!(marker instanceof TextRenderable)) + return; + const marginBottom = /\n[ \t]*\n$/.test(input.item.raw) ? 1 : 0; + const markerWidth = input.markerWidth + 1; + const markerText = input.marker.padStart(input.markerWidth) + " "; + if (row.marginBottom !== marginBottom) + row.marginBottom = marginBottom; + if (marker.width !== markerWidth) + marker.width = markerWidth; + if (marker.chunks[0]?.text !== markerText) { + marker.content = new StyledText([this.createChunk(markerText, "markup.list")]); + } + } + createListChildRenderable(token, id) { + if (token.type === "text" || token.type === "paragraph") { + return this.createMarkdownCodeRenderable(this.normalizeScrollbackMarkdownBlockRaw(token.raw), id, 0, this._linkifyMarkdownChunks, undefined, this.createInitialStyledText(token)); + } + if (token.type === "list") + return this.createListRenderable(token, id); + if (token.type === "code") + return this.createCodeRenderable(token, id); + if (token.type === "blockquote") + return this.createBlockquoteRenderable(token, id); + if (token.type === "hr") + return this.createHorizontalRuleRenderable(id); + if (token.type === "table") + return this.createTableBlock(token, id).renderable; + return token.raw ? this.createMarkdownCodeRenderable(token.raw, id, 0, this._linkifyMarkdownChunks, undefined, this.createInitialStyledText(token)) : null; + } + createHorizontalRuleRenderable(id, marginBottom = 0) { + return new BoxRenderable(this.ctx, { + id, + width: "100%", + height: 1, + border: ["top"], + borderColor: this.getStyle("conceal")?.fg ?? this._fg ?? "#888888", + flexShrink: 0, + marginBottom + }); + } + createCodeRenderable(token, id, marginBottom = 0) { + return new CodeRenderable(this.ctx, { + id, + content: token.text, + filetype: infoStringToFiletype(token.lang ?? ""), + syntaxStyle: this._syntaxStyle, + fg: this._fg, + bg: this._bg, + conceal: this._concealCode, + drawUnstyledText: !this._streaming, + streaming: this._streaming, + treeSitterClient: this._treeSitterClient, + width: "100%", + marginBottom + }); + } + applyMarkdownCodeRenderable(renderable, content, marginBottom, baseHighlight, initialStyledText) { + renderable.initialStyledText = initialStyledText; + renderable.filetype = "markdown"; + renderable.syntaxStyle = this._syntaxStyle; + renderable.fg = this._fg; + renderable.bg = this._bg; + renderable.conceal = this._conceal; + renderable.drawUnstyledText = initialStyledText !== undefined; + renderable.streaming = true; + renderable.baseHighlight = baseHighlight; + renderable.content = content; + renderable.marginBottom = marginBottom; + } + applyBlockquoteRenderable(renderable, token, marginBottom) { + if (!(renderable instanceof BoxRenderable)) + return; + renderable.borderColor = this.getBlockquoteBorderColor(); + renderable.marginBottom = marginBottom; + const child = renderable.getChildren()[0]; + if (child instanceof CodeRenderable) { + this.applyMarkdownCodeRenderable(child, this.getBlockquoteContent(token), 0, "markup.quote"); + return; + } + for (const existing of renderable.getChildren()) { + existing.destroyRecursively(); + } + renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token), `${renderable.id}-content`, 0, this._linkifyMarkdownChunks, "markup.quote")); + } + applyCodeBlockRenderable(renderable, token, marginBottom) { + if (!(renderable instanceof CodeRenderable)) + return; + renderable.filetype = infoStringToFiletype(token.lang ?? ""); + renderable.syntaxStyle = this._syntaxStyle; + renderable.fg = this._fg; + renderable.bg = this._bg; + renderable.conceal = this._concealCode; + renderable.drawUnstyledText = !this._streaming; + renderable.streaming = this._streaming; + renderable.content = token.text; + renderable.marginBottom = marginBottom; + } + shouldRenderSeparately(token) { + return token.type === "code" || token.type === "table" || token.type === "blockquote" || token.type === "hr"; + } + getInterBlockMargin(token, nextToken) { + if (!nextToken) + return 0; + if (this.shouldRenderSeparately(token)) + return 1; + if (!this.shouldRenderSeparately(nextToken)) + return 0; + return TRAILING_MARKDOWN_BLOCK_NEWLINES_RE.test(token.raw) ? 0 : 1; + } + applyInterBlockMargin(state, token, nextToken) { + if (state.tracksInterBlockMargin === false) + return; + state.renderable.marginBottom = this.getInterBlockMargin(token, nextToken); + } + createMarkdownBlockToken(raw) { + return { + type: "paragraph", + raw, + text: raw, + tokens: [] + }; + } + normalizeMarkdownBlockRaw(raw) { + return raw.replace(TRAILING_MARKDOWN_BLOCK_BREAKS_RE, ` +`); + } + normalizeScrollbackMarkdownBlockRaw(raw) { + return raw.replace(TRAILING_MARKDOWN_BLOCK_NEWLINES_RE, ""); + } + isCodeBlockOnlyRenderer() { + return this._renderNode?.codeBlockOnly === true; + } + buildRenderableTokens(tokens) { + if (this._renderNode && !this.isCodeBlockOnlyRenderer()) { + return tokens.filter((token) => token.type !== "space"); + } + const renderTokens = []; + let markdownRaw = ""; + const flushMarkdownRaw = () => { + if (markdownRaw.length === 0) + return; + const normalizedRaw = this.normalizeMarkdownBlockRaw(markdownRaw); + if (normalizedRaw.length > 0) { + renderTokens.push(this.createMarkdownBlockToken(normalizedRaw)); + } + markdownRaw = ""; + }; + for (let i = 0;i < tokens.length; i += 1) { + const token = tokens[i]; + if (token.type === "space") { + if (markdownRaw.length === 0) { + continue; + } + let nextIndex = i + 1; + while (nextIndex < tokens.length && tokens[nextIndex].type === "space") { + nextIndex += 1; + } + const nextToken = tokens[nextIndex]; + if (nextToken && !this.shouldRenderSeparately(nextToken)) { + markdownRaw += token.raw; + } + continue; + } + if (this.shouldRenderSeparately(token)) { + flushMarkdownRaw(); + renderTokens.push(token); + continue; + } + markdownRaw += token.raw; + } + flushMarkdownRaw(); + return renderTokens; + } + buildTopLevelRenderBlocks(tokens) { + const blocks = []; + let gapBefore = ""; + for (let i = 0;i < tokens.length; i += 1) { + const token = tokens[i]; + if (token.type === "space") { + gapBefore += token.raw; + continue; + } + const prev = blocks[blocks.length - 1]; + const marginTop = prev && this.shouldAddTopLevelMargin(prev.token, token, gapBefore) ? 1 : 0; + blocks.push({ + token, + sourceTokenEnd: i + 1, + marginTop + }); + gapBefore = ""; + } + return blocks; + } + shouldAddTopLevelMargin(prev, current, gapBefore) { + if (this.isSeparatedTopLevelBlock(prev) || this.isSeparatedTopLevelBlock(current)) + return true; + if (prev.type !== "paragraph" || current.type !== "paragraph") + return false; + return TRAILING_MARKDOWN_BLOCK_BREAKS_RE.test(prev.raw + gapBefore); + } + isSeparatedTopLevelBlock(token) { + return token.type === "heading" || token.type === "list" || this.shouldRenderSeparately(token); + } + getTableRowsToRender(table) { + return table.rows; + } + hashString(value, seed) { + let hash = seed >>> 0; + for (let i = 0;i < value.length; i += 1) { + hash ^= value.charCodeAt(i); + hash = Math.imul(hash, 16777619); + } + return hash >>> 0; + } + hashTableToken(token, seed, depth = 0) { + let hash = this.hashString(token.type, seed); + if ("raw" in token && typeof token.raw === "string") { + return this.hashString(token.raw, hash); + } + if ("text" in token && typeof token.text === "string") { + hash = this.hashString(token.text, hash); + } + if (depth < 2 && "tokens" in token && Array.isArray(token.tokens)) { + for (const child of token.tokens) { + hash = this.hashTableToken(child, hash, depth + 1); + } + } + return hash >>> 0; + } + getTableCellKey(cell, isHeader) { + const seed = isHeader ? 2902232141 : 1371922141; + if (!cell) { + return seed; + } + if (typeof cell.text === "string") { + return this.hashString(cell.text, seed); + } + if (Array.isArray(cell.tokens) && cell.tokens.length > 0) { + let hash = seed ^ cell.tokens.length; + for (const token of cell.tokens) { + hash = this.hashTableToken(token, hash); + } + return hash >>> 0; + } + return (seed ^ 2654435769) >>> 0; + } + createTableDataCellChunks(cell) { + const chunks = []; + if (cell) { + this.renderInlineContent(cell.tokens, chunks); + } + return chunks.length > 0 ? chunks : [this.createDefaultChunk(" ")]; + } + createTableHeaderCellChunks(cell) { + const chunks = []; + this.renderInlineContent(cell.tokens, chunks); + const baseChunks = chunks.length > 0 ? chunks : [this.createDefaultChunk(" ")]; + const headingStyle = this.getStyle("markup.heading") || this.getStyle("default"); + if (!headingStyle) { + return baseChunks; + } + const headingAttributes = createTextAttributes({ + bold: headingStyle.bold, + italic: headingStyle.italic, + underline: headingStyle.underline, + dim: headingStyle.dim + }); + return baseChunks.map((chunk) => ({ + ...chunk, + fg: headingStyle.fg ?? chunk.fg, + bg: headingStyle.bg ?? chunk.bg, + attributes: headingAttributes + })); + } + buildTableContentCache(table, previous, forceRegenerate = false) { + const colCount = table.header.length; + const rowsToRender = this.getTableRowsToRender(table); + if (colCount === 0 || rowsToRender.length === 0) { + return { cache: null, changed: previous !== undefined }; + } + const content = []; + const cellKeys = []; + const totalRows = rowsToRender.length + 1; + let changed = forceRegenerate || !previous; + for (let rowIndex = 0;rowIndex < totalRows; rowIndex += 1) { + const rowContent = []; + const rowKeys = new Uint32Array(colCount); + for (let colIndex = 0;colIndex < colCount; colIndex += 1) { + const isHeader = rowIndex === 0; + const cell = isHeader ? table.header[colIndex] : rowsToRender[rowIndex - 1]?.[colIndex]; + const cellKey = this.getTableCellKey(cell, isHeader); + rowKeys[colIndex] = cellKey; + const previousCellKey = previous?.cellKeys[rowIndex]?.[colIndex]; + const previousCellContent = previous?.content[rowIndex]?.[colIndex]; + if (!forceRegenerate && previousCellKey === cellKey && Array.isArray(previousCellContent)) { + rowContent.push(previousCellContent); + continue; + } + changed = true; + rowContent.push(isHeader ? this.createTableHeaderCellChunks(table.header[colIndex]) : this.createTableDataCellChunks(cell)); + } + content.push(rowContent); + cellKeys.push(rowKeys); + } + if (previous && !changed) { + if (previous.content.length !== content.length) { + changed = true; + } else { + for (let rowIndex = 0;rowIndex < content.length; rowIndex += 1) { + if ((previous.content[rowIndex]?.length ?? 0) !== content[rowIndex].length) { + changed = true; + break; + } + } + } + } + return { + cache: { + content, + cellKeys + }, + changed + }; + } + resolveTableStyle(options = this._tableOptions) { + if (options?.style === "columns") { + return "columns"; + } + if (options?.style === "grid") { + return "grid"; + } + return this._internalBlockMode === "top-level" ? "columns" : "grid"; + } + usesBorderlessColumnSpacing(options = this._tableOptions) { + const style = this.resolveTableStyle(options); + const borders = options?.borders ?? style === "grid"; + return style === "columns" && !borders; + } + resolveTableRenderableOptions() { + const style = this.resolveTableStyle(); + const borders = this._tableOptions?.borders ?? style === "grid"; + return { + columnWidthMode: this._tableOptions?.widthMode ?? (style === "columns" ? "content" : "full"), + columnFitter: this._tableOptions?.columnFitter ?? "proportional", + wrapMode: this._tableOptions?.wrapMode ?? "word", + cellPadding: this._tableOptions?.cellPadding ?? 0, + cellPaddingX: this._tableOptions?.cellPaddingX ?? this._tableOptions?.cellPadding ?? 0, + cellPaddingY: this._tableOptions?.cellPaddingY ?? this._tableOptions?.cellPadding ?? 0, + columnGap: this.usesBorderlessColumnSpacing() ? 2 : 0, + border: borders, + outerBorder: this._tableOptions?.outerBorder ?? borders, + showBorders: borders, + borderStyle: this._tableOptions?.borderStyle ?? "single", + borderColor: this._tableOptions?.borderColor ?? this.getStyle("conceal")?.fg ?? "#888888", + selectable: this._tableOptions?.selectable ?? true + }; + } + applyTableRenderableOptions(tableRenderable, options) { + tableRenderable.columnWidthMode = options.columnWidthMode; + tableRenderable.columnFitter = options.columnFitter; + tableRenderable.wrapMode = options.wrapMode; + tableRenderable.cellPaddingX = options.cellPaddingX; + tableRenderable.cellPaddingY = options.cellPaddingY; + tableRenderable.columnGap = options.columnGap; + tableRenderable.border = options.border; + tableRenderable.outerBorder = options.outerBorder; + tableRenderable.showBorders = options.showBorders; + tableRenderable.borderStyle = options.borderStyle; + tableRenderable.borderColor = options.borderColor; + tableRenderable.selectable = options.selectable; + } + applyTableOptionsToBlocks() { + const options = this.resolveTableRenderableOptions(); + let updated = false; + for (const state of this._blockStates) { + if (state.renderable instanceof TextTableRenderable) { + this.applyTableRenderableOptions(state.renderable, options); + updated = true; + } + } + if (updated) { + this.requestRender(); + } + } + createTextTableRenderable(content, id, marginBottom = 0) { + const options = this.resolveTableRenderableOptions(); + return new TextTableRenderable(this.ctx, { + id, + content, + width: "100%", + marginBottom, + columnWidthMode: options.columnWidthMode, + columnFitter: options.columnFitter, + wrapMode: options.wrapMode, + cellPadding: options.cellPadding, + cellPaddingX: options.cellPaddingX, + cellPaddingY: options.cellPaddingY, + columnGap: options.columnGap, + border: options.border, + outerBorder: options.outerBorder, + showBorders: options.showBorders, + borderStyle: options.borderStyle, + borderColor: options.borderColor, + selectable: options.selectable + }); + } + createTableBlock(table, id, marginBottom = 0, previousCache, forceRegenerate = false) { + const { cache } = this.buildTableContentCache(table, previousCache, forceRegenerate); + if (!cache) { + return { + renderable: this.createMarkdownCodeRenderable(table.raw, id, marginBottom) + }; + } + return { + renderable: this.createTextTableRenderable(cache.content, id, marginBottom), + tableContentCache: cache + }; + } + getStableBlockCount(blocks, stableTokenCount) { + if (this._internalBlockMode !== "top-level") { + return 0; + } + let stableBlockCount = 0; + for (const block of blocks) { + if (block.sourceTokenEnd <= stableTokenCount) { + stableBlockCount += 1; + continue; + } + break; + } + return stableBlockCount; + } + syncTopLevelBlockState(state, block, tableContentCache = state.tableContentCache) { + state.token = block.token; + state.tokenRaw = block.token.raw; + state.marginTop = block.marginTop; + state.tableContentCache = tableContentCache; + } + getTopLevelBlockRaw(token) { + if (!token.raw) { + return; + } + return this.shouldRenderSeparately(token) ? token.raw : this.normalizeScrollbackMarkdownBlockRaw(token.raw); + } + createTopLevelDefaultRenderable(block, index) { + const { token, marginTop } = block; + const id = `${this.id}-block-${index}`; + if (token.type === "code") { + const renderable2 = this.createCodeRenderable(token, id); + renderable2.marginTop = marginTop; + return { renderable: renderable2, canUpdateInPlace: true }; + } + if (token.type === "table") { + const next = this.createTableBlock(token, id); + next.renderable.marginTop = marginTop; + return { ...next, canUpdateInPlace: true }; + } + if (token.type === "blockquote") { + const renderable2 = this.createBlockquoteRenderable(token, id); + renderable2.marginTop = marginTop; + return { renderable: renderable2, canUpdateInPlace: true }; + } + if (token.type === "list") { + const renderable2 = this.createListRenderable(token, id); + renderable2.marginTop = marginTop; + return { renderable: renderable2, canUpdateInPlace: true }; + } + if (token.type === "hr") { + const renderable2 = this.createHorizontalRuleRenderable(id); + renderable2.marginTop = marginTop; + return { renderable: renderable2, canUpdateInPlace: true }; + } + const markdownRaw = this.getTopLevelBlockRaw(token); + if (!markdownRaw) { + return { renderable: undefined, canUpdateInPlace: true }; + } + const renderable = this.createMarkdownCodeRenderable(markdownRaw, id, 0, this._linkifyMarkdownChunks, undefined, this.createInitialStyledText(token)); + renderable.marginTop = marginTop; + return { renderable, canUpdateInPlace: true }; + } + createTopLevelRenderable(block, index) { + if (!this._renderNode) { + return this.createTopLevelDefaultRenderable(block, index); + } + const custom = this.createTopLevelCustomRenderable(block, index); + if (!custom.renderable) + return this.createTopLevelDefaultRenderable(block, index); + const marginTop = typeof custom.renderable.marginTop === "number" ? Math.max(custom.renderable.marginTop, block.marginTop) : block.marginTop; + this.applyMargins(custom.renderable, marginTop, 0); + return { + renderable: custom.renderable, + tableContentCache: custom.tableContentCache, + canUpdateInPlace: custom.canUpdateInPlace + }; + } + createDefaultRenderable(token, index, nextToken) { + const id = `${this.id}-block-${index}`; + const marginBottom = this.getInterBlockMargin(token, nextToken); + if (token.type === "code") { + return this.createCodeRenderable(token, id, marginBottom); + } + if (token.type === "blockquote") { + return this.createBlockquoteRenderable(token, id, marginBottom); + } + if (token.type === "list") { + return this.createListRenderable(token, id, marginBottom); + } + if (token.type === "hr") { + return this.createHorizontalRuleRenderable(id, marginBottom); + } + if (token.type === "table") { + return this.createTableBlock(token, id, marginBottom).renderable; + } + if (token.type === "space") { + return null; + } + if (!token.raw) { + return null; + } + return this.createMarkdownCodeRenderable(token.raw, id, marginBottom, this._linkifyMarkdownChunks, undefined, this.createInitialStyledText(token)); + } + createCustomRenderable(token, index, nextToken) { + const custom = this.renderCustomNode(token, () => { + return { renderable: this.createDefaultRenderable(token, index, nextToken) }; + }); + if (!custom.renderable) { + return { tracksInterBlockMargin: true, canUpdateInPlace: true }; + } + const canUpdateInPlace = custom.renderable === custom.defaultResult?.renderable; + return { + renderable: custom.renderable, + tracksInterBlockMargin: canUpdateInPlace, + canUpdateInPlace + }; + } + createTopLevelCustomRenderable(block, index) { + const custom = this.renderCustomNode(block.token, () => { + return this.createTopLevelDefaultRenderable(block, index); + }); + if (!custom.renderable) { + return { tracksInterBlockMargin: true, canUpdateInPlace: true }; + } + const canUpdateInPlace = custom.renderable === custom.defaultResult?.renderable; + return { + renderable: custom.renderable, + tableContentCache: canUpdateInPlace ? custom.defaultResult?.tableContentCache : undefined, + tracksInterBlockMargin: canUpdateInPlace, + canUpdateInPlace + }; + } + renderCustomNode(token, createDefault) { + if (!this._renderNode) + return {}; + let defaultResult; + const custom = this._renderNode(token, { + syntaxStyle: this._syntaxStyle, + conceal: this._conceal, + concealCode: this._concealCode, + treeSitterClient: this._treeSitterClient, + defaultRender: () => { + defaultResult = createDefault(); + return defaultResult.renderable ?? null; + } + }); + this.destroyUnusedDefaultRenderable(defaultResult?.renderable, custom ?? undefined); + return custom ? { renderable: custom, defaultResult } : {}; + } + destroyUnusedDefaultRenderable(renderable, usedRenderable) { + if (!renderable || renderable === usedRenderable || renderable.parent) + return; + renderable.destroyRecursively(); + } + updateBlockRenderable(state, token, index, nextToken, forceListRefresh = false) { + const marginBottom = this.getInterBlockMargin(token, nextToken); + if (token.type === "code") { + this.applyCodeBlockRenderable(state.renderable, token, marginBottom); + return; + } + if (token.type === "blockquote") { + this.applyBlockquoteRenderable(state.renderable, token, marginBottom); + return; + } + if (token.type === "list") { + if (!this.applyListRenderable(state.renderable, token, forceListRefresh ? undefined : state.token, `${this.id}-block-${index}`, marginBottom)) { + state.renderable.destroyRecursively(); + state.renderable = this.createListRenderable(token, `${this.id}-block-${index}`, marginBottom); + this.add(state.renderable, index); + } + return; + } + if (token.type === "hr") { + state.renderable.marginBottom = marginBottom; + return; + } + if (token.type === "table") { + const tableToken = token; + const { cache, changed } = this.buildTableContentCache(tableToken, state.tableContentCache); + if (!cache) { + if (state.renderable instanceof CodeRenderable) { + this.applyMarkdownCodeRenderable(state.renderable, tableToken.raw, marginBottom); + state.tableContentCache = undefined; + return; + } + state.renderable.destroyRecursively(); + const fallbackRenderable = this.createMarkdownCodeRenderable(tableToken.raw, `${this.id}-block-${index}`, marginBottom); + this.add(fallbackRenderable, index); + state.renderable = fallbackRenderable; + state.tableContentCache = undefined; + return; + } + if (state.renderable instanceof TextTableRenderable) { + if (changed) { + state.renderable.content = cache.content; + } + this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions()); + state.renderable.marginBottom = marginBottom; + state.tableContentCache = cache; + return; + } + state.renderable.destroyRecursively(); + const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${index}`, marginBottom); + this.add(tableRenderable, index); + state.renderable = tableRenderable; + state.tableContentCache = cache; + return; + } + if (state.renderable instanceof CodeRenderable) { + this.applyMarkdownCodeRenderable(state.renderable, this.getTopLevelBlockRaw(token) ?? token.raw, marginBottom, undefined, this.createInitialStyledText(token)); + return; + } + state.renderable.destroyRecursively(); + const markdownRenderable = this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(token) ?? token.raw, `${this.id}-block-${index}`, marginBottom, this._linkifyMarkdownChunks, undefined, this.createInitialStyledText(token)); + this.add(markdownRenderable, index); + state.renderable = markdownRenderable; + } + updateTopLevelBlocks(tokens, forceTableRefresh) { + const blocks = this.buildTopLevelRenderBlocks(tokens); + this._stableBlockCount = this.getStableBlockCount(blocks, this._parseState?.stableTokenCount ?? 0); + let blockIndex = 0; + for (let i = 0;i < blocks.length; i += 1) { + const block = blocks[i]; + const existing = this._blockStates[blockIndex]; + if (existing && existing.token === block.token && !forceTableRefresh) { + if (existing.marginTop !== block.marginTop) { + this.applyMargins(existing.renderable, block.marginTop, 0); + } + this.syncTopLevelBlockState(existing, block); + blockIndex++; + continue; + } + if (existing && existing.tokenRaw === block.token.raw && existing.token.type === block.token.type && !forceTableRefresh) { + if (existing.marginTop !== block.marginTop) { + this.applyMargins(existing.renderable, block.marginTop, 0); + } + this.syncTopLevelBlockState(existing, block); + blockIndex++; + continue; + } + if (existing && !forceTableRefresh && existing.canUpdateInPlace && existing.token.type === block.token.type && this.canUpdateBlockRenderable(existing.renderable, block.token)) { + if (this._renderNode) { + const custom = this.createTopLevelCustomRenderable(block, blockIndex); + if (custom.renderable && !custom.canUpdateInPlace) { + const marginTop = typeof custom.renderable.marginTop === "number" ? Math.max(custom.renderable.marginTop, block.marginTop) : block.marginTop; + this.applyMargins(custom.renderable, marginTop, 0); + if (custom.renderable !== existing.renderable) { + existing.renderable.destroyRecursively(); + this.add(custom.renderable, blockIndex); + } + this._blockStates[blockIndex] = { + token: block.token, + tokenRaw: block.token.raw, + marginTop: block.marginTop, + renderable: custom.renderable, + tableContentCache: custom.tableContentCache, + canUpdateInPlace: custom.canUpdateInPlace + }; + blockIndex++; + continue; + } + this.destroyUnusedDefaultRenderable(custom.renderable); + } + this.updateBlockRenderable(existing, block.token, blockIndex, blocks[i + 1]?.token); + existing.renderable.marginBottom = 0; + if (existing.marginTop !== block.marginTop) { + this.applyMargins(existing.renderable, block.marginTop, 0); + } + this.syncTopLevelBlockState(existing, block); + blockIndex++; + continue; + } + if (existing) { + existing.renderable.destroyRecursively(); + } + const next = this.createTopLevelRenderable(block, blockIndex); + if (next.renderable) { + this.add(next.renderable, blockIndex); + this._blockStates[blockIndex] = { + token: block.token, + tokenRaw: block.token.raw, + marginTop: block.marginTop, + renderable: next.renderable, + tableContentCache: next.tableContentCache, + canUpdateInPlace: next.canUpdateInPlace + }; + } + blockIndex++; + } + while (this._blockStates.length > blockIndex) { + const removed = this._blockStates.pop(); + removed.renderable.destroyRecursively(); + } + } + canUpdateBlockRenderable(renderable, token) { + if (token.type === "code") + return renderable instanceof CodeRenderable; + if (token.type === "table") + return renderable instanceof TextTableRenderable; + if (token.type === "blockquote") + return renderable instanceof BoxRenderable; + if (token.type === "list") + return renderable instanceof BoxRenderable; + if (token.type === "hr") + return renderable instanceof BoxRenderable; + return renderable instanceof CodeRenderable; + } + updateBlocks(forceTableRefresh = false) { + if (this.isDestroyed) + return; + if (!this._content) { + this.clearBlockStates(); + this._parseState = null; + this._stableBlockCount = 0; + return; + } + const trailingUnstable = this._streaming ? 2 : 0; + this._parseState = parseMarkdownIncremental(this._content, this._parseState, trailingUnstable); + const tokens = this._parseState.tokens; + if (tokens.length === 0 && this._content.length > 0) { + this.clearBlockStates(); + this._stableBlockCount = 0; + const fallback = this.createMarkdownCodeRenderable(this._content, `${this.id}-fallback`); + this.add(fallback); + this._blockStates = [ + { + token: { type: "text", raw: this._content, text: this._content }, + tokenRaw: this._content, + marginTop: 0, + renderable: fallback, + tracksInterBlockMargin: true, + canUpdateInPlace: true + } + ]; + return; + } + if (this._internalBlockMode === "top-level") { + this.updateTopLevelBlocks(tokens, forceTableRefresh); + return; + } + this._stableBlockCount = 0; + const blockTokens = this.buildRenderableTokens(tokens); + let blockIndex = 0; + for (let i = 0;i < blockTokens.length; i++) { + const token = blockTokens[i]; + const nextToken = blockTokens[i + 1]; + const existing = this._blockStates[blockIndex]; + const shouldForceRefresh = forceTableRefresh; + if (existing && existing.token === token) { + if (shouldForceRefresh) { + this.updateBlockRenderable(existing, token, blockIndex, nextToken); + existing.tokenRaw = token.raw; + } else { + this.applyInterBlockMargin(existing, token, nextToken); + } + blockIndex++; + continue; + } + if (existing && existing.tokenRaw === token.raw && existing.token.type === token.type) { + existing.token = token; + if (shouldForceRefresh) { + this.updateBlockRenderable(existing, token, blockIndex, nextToken); + existing.tokenRaw = token.raw; + } else { + this.applyInterBlockMargin(existing, token, nextToken); + } + blockIndex++; + continue; + } + if (existing && existing.canUpdateInPlace && existing.token.type === token.type) { + const custom2 = this.createCustomRenderable(token, blockIndex, nextToken); + if (custom2.renderable && !custom2.canUpdateInPlace) { + if (custom2.renderable !== existing.renderable) { + existing.renderable.destroyRecursively(); + this.add(custom2.renderable, blockIndex); + } + this._blockStates[blockIndex] = { + token, + tokenRaw: token.raw, + renderable: custom2.renderable, + tracksInterBlockMargin: custom2.tracksInterBlockMargin, + canUpdateInPlace: custom2.canUpdateInPlace + }; + blockIndex++; + continue; + } + this.destroyUnusedDefaultRenderable(custom2.renderable); + this.updateBlockRenderable(existing, token, blockIndex, nextToken); + existing.token = token; + existing.tokenRaw = token.raw; + existing.tracksInterBlockMargin = true; + blockIndex++; + continue; + } + if (existing) { + existing.renderable.destroyRecursively(); + } + let renderable; + let tableContentCache; + let tracksInterBlockMargin = true; + let canUpdateInPlace = true; + const custom = this.createCustomRenderable(token, blockIndex, nextToken); + if (custom.renderable) { + renderable = custom.renderable; + tracksInterBlockMargin = custom.tracksInterBlockMargin; + canUpdateInPlace = custom.canUpdateInPlace; + } + if (!renderable) { + if (token.type === "table") { + const tableBlock = this.createTableBlock(token, `${this.id}-block-${blockIndex}`, this.getInterBlockMargin(token, nextToken)); + renderable = tableBlock.renderable; + tableContentCache = tableBlock.tableContentCache; + } else { + renderable = this.createDefaultRenderable(token, blockIndex, nextToken) ?? undefined; + } + } + if (token.type === "table" && !tableContentCache && renderable instanceof TextTableRenderable) { + const { cache } = this.buildTableContentCache(token); + tableContentCache = cache ?? undefined; + } + if (renderable) { + this.add(renderable, blockIndex); + this._blockStates[blockIndex] = { + token, + tokenRaw: token.raw, + renderable, + tableContentCache, + tracksInterBlockMargin, + canUpdateInPlace + }; + } + blockIndex++; + } + while (this._blockStates.length > blockIndex) { + const removed = this._blockStates.pop(); + removed.renderable.destroyRecursively(); + } + } + clearBlockStates() { + for (const state of this._blockStates) { + state.renderable.destroyRecursively(); + } + this._blockStates = []; + this._stableBlockCount = 0; + } + rerenderBlocks() { + if (this._internalBlockMode === "top-level") { + this.updateBlocks(true); + return; + } + for (let i = 0;i < this._blockStates.length; i++) { + const state = this._blockStates[i]; + const marginBottom = this.getInterBlockMargin(state.token, this._blockStates[i + 1]?.token); + if (state.token.type === "code") { + this.applyCodeBlockRenderable(state.renderable, state.token, marginBottom); + continue; + } + if (state.token.type === "blockquote") { + this.applyBlockquoteRenderable(state.renderable, state.token, marginBottom); + continue; + } + if (state.token.type === "list") { + this.updateBlockRenderable(state, state.token, i, this._blockStates[i + 1]?.token, true); + continue; + } + if (state.token.type === "hr") { + state.renderable.marginBottom = marginBottom; + continue; + } + if (state.token.type === "table") { + const tableToken = state.token; + const { cache } = this.buildTableContentCache(tableToken, state.tableContentCache, true); + if (!cache) { + if (state.renderable instanceof CodeRenderable) { + this.applyMarkdownCodeRenderable(state.renderable, tableToken.raw, marginBottom); + } else { + state.renderable.destroyRecursively(); + const fallbackRenderable = this.createMarkdownCodeRenderable(tableToken.raw, `${this.id}-block-${i}`, marginBottom); + this.add(fallbackRenderable, i); + state.renderable = fallbackRenderable; + } + state.tableContentCache = undefined; + continue; + } + if (state.renderable instanceof TextTableRenderable) { + state.renderable.content = cache.content; + this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions()); + state.renderable.marginBottom = marginBottom; + state.tableContentCache = cache; + continue; + } + state.renderable.destroyRecursively(); + const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${i}`, marginBottom); + this.add(tableRenderable, i); + state.renderable = tableRenderable; + state.tableContentCache = cache; + continue; + } + if (state.renderable instanceof CodeRenderable) { + this.applyMarkdownCodeRenderable(state.renderable, this.getTopLevelBlockRaw(state.token) ?? state.token.raw, marginBottom, undefined, this.createInitialStyledText(state.token)); + continue; + } + state.renderable.destroyRecursively(); + const markdownRenderable = this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(state.token) ?? state.token.raw, `${this.id}-block-${i}`, marginBottom, this._linkifyMarkdownChunks, undefined, this.createInitialStyledText(state.token)); + this.add(markdownRenderable, i); + state.renderable = markdownRenderable; + } + } + clearCache() { + this._parseState = null; + this.clearBlockStates(); + this.updateBlocks(); + this.requestRender(); + } + refreshStyles() { + this._styleDirty = false; + this.rerenderBlocks(); + this.requestRender(); + } + renderSelf(buffer, deltaTime) { + if (this._styleDirty) { + this._styleDirty = false; + this.rerenderBlocks(); + } + super.renderSelf(buffer, deltaTime); + } +} +// src/renderables/Slider.ts +var defaultThumbBackgroundColor = RGBA.fromHex("#9a9ea3"); +var defaultTrackBackgroundColor = RGBA.fromHex("#252527"); + +class SliderRenderable extends Renderable { + orientation; + _value; + _min; + _max; + _viewPortSize; + _backgroundColor; + _foregroundColor; + _onChange; + constructor(ctx, options) { + super(ctx, { flexShrink: 0, ...options }); + this.orientation = options.orientation; + this._min = options.min ?? 0; + this._max = options.max ?? 100; + this._value = options.value ?? this._min; + this._viewPortSize = options.viewPortSize ?? Math.max(1, (this._max - this._min) * 0.1); + this._onChange = options.onChange; + this._backgroundColor = options.backgroundColor ? parseColor(options.backgroundColor) : defaultTrackBackgroundColor; + this._foregroundColor = options.foregroundColor ? parseColor(options.foregroundColor) : defaultThumbBackgroundColor; + this.setupMouseHandling(); + } + get value() { + return this._value; + } + set value(newValue) { + const clamped = Math.max(this._min, Math.min(this._max, newValue)); + if (clamped !== this._value) { + this._value = clamped; + this._onChange?.(clamped); + this.emit("change", { value: clamped }); + this.requestRender(); + } + } + get min() { + return this._min; + } + set min(newMin) { + if (newMin !== this._min) { + this._min = newMin; + if (this._value < newMin) { + this.value = newMin; + } + this.requestRender(); + } + } + get max() { + return this._max; + } + set max(newMax) { + if (newMax !== this._max) { + this._max = newMax; + if (this._value > newMax) { + this.value = newMax; + } + this.requestRender(); + } + } + set viewPortSize(size) { + const clampedSize = Math.max(0.01, Math.min(size, this._max - this._min)); + if (clampedSize !== this._viewPortSize) { + this._viewPortSize = clampedSize; + this.requestRender(); + } + } + get viewPortSize() { + return this._viewPortSize; + } + get backgroundColor() { + return this._backgroundColor; + } + set backgroundColor(value) { + this._backgroundColor = parseColor(value); + this.requestRender(); + } + get foregroundColor() { + return this._foregroundColor; + } + set foregroundColor(value) { + this._foregroundColor = parseColor(value); + this.requestRender(); + } + calculateDragOffsetVirtual(event) { + const trackStart = this.orientation === "vertical" ? this.y : this.x; + const mousePos = (this.orientation === "vertical" ? event.y : event.x) - trackStart; + const virtualMousePos = Math.max(0, Math.min((this.orientation === "vertical" ? this.height : this.width) * 2, mousePos * 2)); + const virtualThumbStart = this.getVirtualThumbStart(); + const virtualThumbSize = this.getVirtualThumbSize(); + return Math.max(0, Math.min(virtualThumbSize, virtualMousePos - virtualThumbStart)); + } + setupMouseHandling() { + let isDragging = false; + let dragOffsetVirtual = 0; + this.onMouseDown = (event) => { + event.stopPropagation(); + event.preventDefault(); + const thumb = this.getThumbRect(); + const inThumb = event.x >= thumb.x && event.x < thumb.x + thumb.width && event.y >= thumb.y && event.y < thumb.y + thumb.height; + if (inThumb) { + isDragging = true; + dragOffsetVirtual = this.calculateDragOffsetVirtual(event); + } else { + this.updateValueFromMouseDirect(event); + isDragging = true; + dragOffsetVirtual = this.calculateDragOffsetVirtual(event); + } + }; + this.onMouseDrag = (event) => { + if (!isDragging) + return; + event.stopPropagation(); + this.updateValueFromMouseWithOffset(event, dragOffsetVirtual); + }; + this.onMouseUp = (event) => { + if (isDragging) { + this.updateValueFromMouseWithOffset(event, dragOffsetVirtual); + } + isDragging = false; + }; + } + updateValueFromMouseDirect(event) { + const trackStart = this.orientation === "vertical" ? this.y : this.x; + const trackSize = this.orientation === "vertical" ? this.height : this.width; + const mousePos = this.orientation === "vertical" ? event.y : event.x; + const relativeMousePos = mousePos - trackStart; + const clampedMousePos = Math.max(0, Math.min(trackSize, relativeMousePos)); + const ratio = trackSize === 0 ? 0 : clampedMousePos / trackSize; + const range = this._max - this._min; + const newValue = this._min + ratio * range; + this.value = newValue; + } + updateValueFromMouseWithOffset(event, offsetVirtual) { + const trackStart = this.orientation === "vertical" ? this.y : this.x; + const trackSize = this.orientation === "vertical" ? this.height : this.width; + const mousePos = this.orientation === "vertical" ? event.y : event.x; + const virtualTrackSize = trackSize * 2; + const relativeMousePos = mousePos - trackStart; + const clampedMousePos = Math.max(0, Math.min(trackSize, relativeMousePos)); + const virtualMousePos = clampedMousePos * 2; + const virtualThumbSize = this.getVirtualThumbSize(); + const maxThumbStart = Math.max(0, virtualTrackSize - virtualThumbSize); + let desiredThumbStart = virtualMousePos - offsetVirtual; + desiredThumbStart = Math.max(0, Math.min(maxThumbStart, desiredThumbStart)); + const ratio = maxThumbStart === 0 ? 0 : desiredThumbStart / maxThumbStart; + const range = this._max - this._min; + const newValue = this._min + ratio * range; + this.value = newValue; + } + getThumbRect() { + const virtualThumbSize = this.getVirtualThumbSize(); + const virtualThumbStart = this.getVirtualThumbStart(); + const realThumbStart = Math.floor(virtualThumbStart / 2); + const realThumbSize = Math.ceil((virtualThumbStart + virtualThumbSize) / 2) - realThumbStart; + if (this.orientation === "vertical") { + return { + x: this.x, + y: this.y + realThumbStart, + width: this.width, + height: Math.max(1, realThumbSize) + }; + } else { + return { + x: this.x + realThumbStart, + y: this.y, + width: Math.max(1, realThumbSize), + height: this.height + }; + } + } + renderSelf(buffer) { + if (this.orientation === "horizontal") { + this.renderHorizontal(buffer); + } else { + this.renderVertical(buffer); + } + } + renderHorizontal(buffer) { + const virtualThumbSize = this.getVirtualThumbSize(); + const virtualThumbStart = this.getVirtualThumbStart(); + const virtualThumbEnd = virtualThumbStart + virtualThumbSize; + buffer.fillRect(this.x, this.y, this.width, this.height, this._backgroundColor); + const realStartCell = Math.floor(virtualThumbStart / 2); + const realEndCell = Math.ceil(virtualThumbEnd / 2) - 1; + const startX = Math.max(0, realStartCell); + const endX = Math.min(this.width - 1, realEndCell); + for (let realX = startX;realX <= endX; realX++) { + const virtualCellStart = realX * 2; + const virtualCellEnd = virtualCellStart + 2; + const thumbStartInCell = Math.max(virtualThumbStart, virtualCellStart); + const thumbEndInCell = Math.min(virtualThumbEnd, virtualCellEnd); + const coverage = thumbEndInCell - thumbStartInCell; + let char = " "; + if (coverage >= 2) { + char = "█"; + } else { + const isLeftHalf = thumbStartInCell === virtualCellStart; + if (isLeftHalf) { + char = "▌"; + } else { + char = "▐"; + } + } + for (let y2 = 0;y2 < this.height; y2++) { + buffer.setCellWithAlphaBlending(this.x + realX, this.y + y2, char, this._foregroundColor, this._backgroundColor); + } + } + } + renderVertical(buffer) { + const virtualThumbSize = this.getVirtualThumbSize(); + const virtualThumbStart = this.getVirtualThumbStart(); + const virtualThumbEnd = virtualThumbStart + virtualThumbSize; + buffer.fillRect(this.x, this.y, this.width, this.height, this._backgroundColor); + const realStartCell = Math.floor(virtualThumbStart / 2); + const realEndCell = Math.ceil(virtualThumbEnd / 2) - 1; + const startY = Math.max(0, realStartCell); + const endY = Math.min(this.height - 1, realEndCell); + for (let realY = startY;realY <= endY; realY++) { + const virtualCellStart = realY * 2; + const virtualCellEnd = virtualCellStart + 2; + const thumbStartInCell = Math.max(virtualThumbStart, virtualCellStart); + const thumbEndInCell = Math.min(virtualThumbEnd, virtualCellEnd); + const coverage = thumbEndInCell - thumbStartInCell; + let char = " "; + if (coverage >= 2) { + char = "█"; + } else if (coverage > 0) { + const virtualPositionInCell = thumbStartInCell - virtualCellStart; + if (virtualPositionInCell === 0) { + char = "▀"; + } else { + char = "▄"; + } + } + for (let x2 = 0;x2 < this.width; x2++) { + buffer.setCellWithAlphaBlending(this.x + x2, this.y + realY, char, this._foregroundColor, this._backgroundColor); + } + } + } + getVirtualThumbSize() { + const virtualTrackSize = this.orientation === "vertical" ? this.height * 2 : this.width * 2; + const range = this._max - this._min; + if (range === 0) + return virtualTrackSize; + const viewportSize = Math.max(1, this._viewPortSize); + const contentSize = range + viewportSize; + if (contentSize <= viewportSize) + return virtualTrackSize; + const thumbRatio = viewportSize / contentSize; + const calculatedSize = Math.floor(virtualTrackSize * thumbRatio); + return Math.max(1, Math.min(calculatedSize, virtualTrackSize)); + } + getVirtualThumbStart() { + const virtualTrackSize = this.orientation === "vertical" ? this.height * 2 : this.width * 2; + const range = this._max - this._min; + if (range === 0) + return 0; + const valueRatio = (this._value - this._min) / range; + const virtualThumbSize = this.getVirtualThumbSize(); + return Math.round(valueRatio * (virtualTrackSize - virtualThumbSize)); + } +} + +// src/renderables/ScrollBar.ts +class ScrollBarRenderable extends Renderable { + slider; + startArrow; + endArrow; + orientation; + _focusable = true; + _scrollSize = 0; + _scrollPosition = 0; + _viewportSize = 0; + _showArrows = false; + _manualVisibility = false; + _onChange; + scrollStep = null; + get visible() { + return super.visible; + } + set visible(value) { + this._manualVisibility = true; + super.visible = value; + } + resetVisibilityControl() { + this._manualVisibility = false; + this.recalculateVisibility(); + } + get scrollSize() { + return this._scrollSize; + } + get scrollPosition() { + return this._scrollPosition; + } + get viewportSize() { + return this._viewportSize; + } + set scrollSize(value) { + if (value === this.scrollSize) + return; + this._scrollSize = value; + this.recalculateVisibility(); + this.updateSliderFromScrollState(); + this.scrollPosition = this.scrollPosition; + } + set scrollPosition(value) { + const newPosition = Math.round(Math.min(Math.max(0, value), this.scrollSize - this.viewportSize)); + if (newPosition !== this._scrollPosition) { + this._scrollPosition = newPosition; + this.updateSliderFromScrollState(); + } + } + set viewportSize(value) { + if (value === this.viewportSize) + return; + this._viewportSize = value; + this.slider.viewPortSize = Math.max(1, this._viewportSize); + this.recalculateVisibility(); + this.updateSliderFromScrollState(); + this.scrollPosition = this.scrollPosition; + } + get showArrows() { + return this._showArrows; + } + set showArrows(value) { + if (value === this._showArrows) + return; + this._showArrows = value; + this.startArrow.visible = value; + this.endArrow.visible = value; + } + constructor(ctx, { trackOptions, arrowOptions, orientation, showArrows = false, ...options }) { + super(ctx, { + flexDirection: orientation === "vertical" ? "column" : "row", + alignSelf: "stretch", + alignItems: "stretch", + ...options + }); + this._onChange = options.onChange; + this.orientation = orientation; + this._showArrows = showArrows; + const scrollRange = Math.max(0, this._scrollSize - this._viewportSize); + const defaultStepSize = Math.max(1, this._viewportSize); + const stepSize = trackOptions?.viewPortSize ?? defaultStepSize; + this.slider = new SliderRenderable(ctx, { + orientation, + min: 0, + max: scrollRange, + value: this._scrollPosition, + viewPortSize: stepSize, + onChange: (value) => { + this._scrollPosition = Math.round(value); + this._onChange?.(this._scrollPosition); + this.emit("change", { position: this._scrollPosition }); + }, + ...orientation === "vertical" ? { + width: Math.max(1, Math.min(2, this.width)), + height: "100%", + marginLeft: "auto" + } : { + width: "100%", + height: 1, + marginTop: "auto" + }, + flexGrow: 1, + flexShrink: 1, + ...trackOptions + }); + this.updateSliderFromScrollState(); + const arrowOpts = arrowOptions ? { + foregroundColor: arrowOptions.backgroundColor, + backgroundColor: arrowOptions.backgroundColor, + attributes: arrowOptions.attributes, + ...arrowOptions + } : {}; + this.startArrow = new ArrowRenderable(ctx, { + alignSelf: "center", + visible: this.showArrows, + direction: this.orientation === "vertical" ? "up" : "left", + height: this.orientation === "vertical" ? 1 : 1, + ...arrowOpts + }); + this.endArrow = new ArrowRenderable(ctx, { + alignSelf: "center", + visible: this.showArrows, + direction: this.orientation === "vertical" ? "down" : "right", + height: this.orientation === "vertical" ? 1 : 1, + ...arrowOpts + }); + this.add(this.startArrow); + this.add(this.slider); + this.add(this.endArrow); + let startArrowMouseTimeout = undefined; + let endArrowMouseTimeout = undefined; + this.startArrow.onMouseDown = (event) => { + event.stopPropagation(); + event.preventDefault(); + this.scrollBy(-0.5, "viewport"); + startArrowMouseTimeout = setTimeout(() => { + this.scrollBy(-0.5, "viewport"); + startArrowMouseTimeout = setInterval(() => { + this.scrollBy(-0.2, "viewport"); + }, 200); + }, 500); + }; + this.startArrow.onMouseUp = (event) => { + event.stopPropagation(); + clearInterval(startArrowMouseTimeout); + }; + this.endArrow.onMouseDown = (event) => { + event.stopPropagation(); + event.preventDefault(); + this.scrollBy(0.5, "viewport"); + endArrowMouseTimeout = setTimeout(() => { + this.scrollBy(0.5, "viewport"); + endArrowMouseTimeout = setInterval(() => { + this.scrollBy(0.2, "viewport"); + }, 200); + }, 500); + }; + this.endArrow.onMouseUp = (event) => { + event.stopPropagation(); + clearInterval(endArrowMouseTimeout); + }; + } + set arrowOptions(options) { + Object.assign(this.startArrow, options); + Object.assign(this.endArrow, options); + this.requestRender(); + } + set trackOptions(options) { + Object.assign(this.slider, options); + this.requestRender(); + } + updateSliderFromScrollState() { + const scrollRange = Math.max(0, this._scrollSize - this._viewportSize); + this.slider.min = 0; + this.slider.max = scrollRange; + this.slider.value = Math.min(this._scrollPosition, scrollRange); + } + scrollBy(delta, unit = "absolute") { + const multiplier = unit === "viewport" ? this.viewportSize : unit === "content" ? this.scrollSize : unit === "step" ? this.scrollStep ?? 1 : 1; + const resolvedDelta = multiplier * delta; + this.scrollPosition += resolvedDelta; + } + recalculateVisibility() { + if (!this._manualVisibility) { + const sizeRatio = this.scrollSize <= this.viewportSize ? 1 : this.viewportSize / this.scrollSize; + super.visible = sizeRatio < 1; + } + } + handleKeyPress(key) { + switch (key.name) { + case "left": + case "h": + if (this.orientation !== "horizontal") + return false; + this.scrollBy(-1 / 5, "viewport"); + return true; + case "right": + case "l": + if (this.orientation !== "horizontal") + return false; + this.scrollBy(1 / 5, "viewport"); + return true; + case "up": + case "k": + if (this.orientation !== "vertical") + return false; + this.scrollBy(-1 / 5, "viewport"); + return true; + case "down": + case "j": + if (this.orientation !== "vertical") + return false; + this.scrollBy(1 / 5, "viewport"); + return true; + case "pageup": + this.scrollBy(-1 / 2, "viewport"); + return true; + case "pagedown": + this.scrollBy(1 / 2, "viewport"); + return true; + case "home": + this.scrollBy(-1, "content"); + return true; + case "end": + this.scrollBy(1, "content"); + return true; + } + return false; + } +} + +class ArrowRenderable extends Renderable { + _direction; + _foregroundColor; + _backgroundColor; + _attributes; + _arrowChars; + constructor(ctx, options) { + super(ctx, options); + this._direction = options.direction; + this._foregroundColor = options.foregroundColor ? parseColor(options.foregroundColor) : RGBA.fromValues(1, 1, 1, 1); + this._backgroundColor = options.backgroundColor ? parseColor(options.backgroundColor) : RGBA.fromValues(0, 0, 0, 0); + this._attributes = options.attributes ?? 0; + this._arrowChars = { + up: "▲", + down: "▼", + left: "◀", + right: "▶", + ...options.arrowChars + }; + if (!options.width) { + this.width = stringWidth(this.getArrowChar()); + } + } + get direction() { + return this._direction; + } + set direction(value) { + if (this._direction !== value) { + this._direction = value; + this.requestRender(); + } + } + get foregroundColor() { + return this._foregroundColor; + } + set foregroundColor(value) { + if (this._foregroundColor !== value) { + this._foregroundColor = parseColor(value); + this.requestRender(); + } + } + get backgroundColor() { + return this._backgroundColor; + } + set backgroundColor(value) { + if (this._backgroundColor !== value) { + this._backgroundColor = parseColor(value); + this.requestRender(); + } + } + get attributes() { + return this._attributes; + } + set attributes(value) { + if (this._attributes !== value) { + this._attributes = value; + this.requestRender(); + } + } + set arrowChars(value) { + this._arrowChars = { + ...this._arrowChars, + ...value + }; + this.requestRender(); + } + renderSelf(buffer) { + const char = this.getArrowChar(); + buffer.drawText(char, this.x, this.y, this._foregroundColor, this._backgroundColor, this._attributes); + } + getArrowChar() { + switch (this._direction) { + case "up": + return this._arrowChars.up; + case "down": + return this._arrowChars.down; + case "left": + return this._arrowChars.left; + case "right": + return this._arrowChars.right; + default: + return "?"; + } + } +} +// src/renderables/ScrollBox.ts +class ContentRenderable extends BoxRenderable { + viewport; + _viewportCulling; + constructor(ctx, viewport, viewportCulling, options) { + super(ctx, options); + this.viewport = viewport; + this._viewportCulling = viewportCulling; + } + get viewportCulling() { + return this._viewportCulling; + } + set viewportCulling(value) { + this._viewportCulling = value; + } + _hasVisibleChildFilter() { + return this._viewportCulling; + } + _getVisibleChildren() { + if (this._viewportCulling) { + return getObjectsInViewport({ + x: this.viewport.screenX, + y: this.viewport.screenY, + width: this.viewport.width, + height: this.viewport.height + }, this.getChildrenSortedByPrimaryAxis(), this.primaryAxis, 0).map((child) => child.num); + } + return super._getVisibleChildren(); + } +} +var SCROLLBOX_PADDING_KEYS = [ + "padding", + "paddingX", + "paddingY", + "paddingTop", + "paddingRight", + "paddingBottom", + "paddingLeft" +]; +function pickScrollBoxPadding(options) { + if (!options) + return {}; + const picked = {}; + for (const key of SCROLLBOX_PADDING_KEYS) { + const value = options[key]; + if (value !== undefined) { + picked[key] = value; + } + } + return picked; +} +function stripScrollBoxPadding(options) { + const sanitized = { ...options }; + for (const key of SCROLLBOX_PADDING_KEYS) { + delete sanitized[key]; + } + return sanitized; +} + +class ScrollBoxRenderable extends BoxRenderable { + static idCounter = 0; + internalId = 0; + wrapper; + viewport; + content; + horizontalScrollBar; + verticalScrollBar; + _focusable = true; + selectionListener; + autoScrollMouseX = 0; + autoScrollMouseY = 0; + autoScrollThresholdVertical = 3; + autoScrollThresholdHorizontal = 3; + autoScrollSpeedSlow = 6; + autoScrollSpeedMedium = 36; + autoScrollSpeedFast = 72; + isAutoScrolling = false; + cachedAutoScrollSpeed = 3; + autoScrollAccumulatorX = 0; + autoScrollAccumulatorY = 0; + scrollAccumulatorX = 0; + scrollAccumulatorY = 0; + _stickyScroll; + _stickyScrollTop = false; + _stickyScrollBottom = false; + _stickyScrollLeft = false; + _stickyScrollRight = false; + _stickyStart; + _hasManualScroll = false; + _isApplyingStickyScroll = false; + scrollAccel; + get stickyScroll() { + return this._stickyScroll; + } + set stickyScroll(value) { + this._stickyScroll = value; + this.updateStickyState(); + } + get stickyStart() { + return this._stickyStart; + } + set stickyStart(value) { + this._stickyStart = value; + this.updateStickyState(); + } + get scrollTop() { + return this.verticalScrollBar.scrollPosition; + } + set scrollTop(value) { + this.verticalScrollBar.scrollPosition = value; + this.updateStickyState(); + } + get scrollLeft() { + return this.horizontalScrollBar.scrollPosition; + } + set scrollLeft(value) { + this.horizontalScrollBar.scrollPosition = value; + this.updateStickyState(); + } + get scrollWidth() { + return this.horizontalScrollBar.scrollSize; + } + get scrollHeight() { + return this.verticalScrollBar.scrollSize; + } + updateStickyState() { + if (!this._stickyScroll) { + this.syncManualScrollState(); + return; + } + const maxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height); + const maxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width); + if (this.scrollTop <= 0) { + this._stickyScrollTop = true; + this._stickyScrollBottom = false; + } else if (this.scrollTop >= maxScrollTop) { + this._stickyScrollTop = false; + this._stickyScrollBottom = true; + } else { + this._stickyScrollTop = false; + this._stickyScrollBottom = false; + } + if (this.scrollLeft <= 0) { + this._stickyScrollLeft = true; + this._stickyScrollRight = false; + } else if (this.scrollLeft >= maxScrollLeft) { + this._stickyScrollLeft = false; + this._stickyScrollRight = true; + } else { + this._stickyScrollLeft = false; + this._stickyScrollRight = false; + } + this.syncManualScrollState(); + } + syncManualScrollState() { + if (!this._stickyScroll) { + this._hasManualScroll = false; + return; + } + const maxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height); + const maxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width); + const hasScrollableContent = maxScrollTop > 1 || maxScrollLeft > 1; + if (this._isApplyingStickyScroll) { + if (this._hasManualScroll && hasScrollableContent && this.isAtStickyPosition()) { + this._hasManualScroll = false; + } + return; + } + this._hasManualScroll = hasScrollableContent && !this.isAtStickyPosition(); + } + applyStickyStart(stickyStart) { + const wasApplyingStickyScroll = this._isApplyingStickyScroll; + this._isApplyingStickyScroll = true; + try { + switch (stickyStart) { + case "top": + this._stickyScrollTop = true; + this._stickyScrollBottom = false; + this.verticalScrollBar.scrollPosition = 0; + break; + case "bottom": + this._stickyScrollTop = false; + this._stickyScrollBottom = true; + this.verticalScrollBar.scrollPosition = Math.max(0, this.scrollHeight - this.viewport.height); + break; + case "left": + this._stickyScrollLeft = true; + this._stickyScrollRight = false; + this.horizontalScrollBar.scrollPosition = 0; + break; + case "right": + this._stickyScrollLeft = false; + this._stickyScrollRight = true; + this.horizontalScrollBar.scrollPosition = Math.max(0, this.scrollWidth - this.viewport.width); + break; + } + } finally { + this._isApplyingStickyScroll = wasApplyingStickyScroll; + } + } + constructor(ctx, options) { + const { + wrapperOptions, + viewportOptions, + contentOptions, + rootOptions, + scrollbarOptions, + verticalScrollbarOptions, + horizontalScrollbarOptions, + stickyScroll = false, + stickyStart, + scrollX = false, + scrollY = true, + scrollAcceleration, + viewportCulling = true, + ...rootBoxOptions + } = options; + const forwardedContentPadding = { + ...pickScrollBoxPadding(rootBoxOptions), + ...pickScrollBoxPadding(rootOptions) + }; + const sanitizedRootBoxOptions = stripScrollBoxPadding(rootBoxOptions); + const sanitizedRootOptions = rootOptions ? stripScrollBoxPadding(rootOptions) : undefined; + const mergedContentOptions = { + ...forwardedContentPadding, + ...contentOptions + }; + super(ctx, { + flexDirection: "row", + alignItems: "stretch", + ...sanitizedRootBoxOptions, + ...sanitizedRootOptions + }); + this.internalId = ScrollBoxRenderable.idCounter++; + this._stickyScroll = stickyScroll; + this._stickyStart = stickyStart; + this.scrollAccel = scrollAcceleration ?? new LinearScrollAccel; + this.wrapper = new BoxRenderable(ctx, { + flexDirection: "column", + flexGrow: 1, + ...wrapperOptions, + id: `scroll-box-wrapper-${this.internalId}` + }); + super.add(this.wrapper); + this.viewport = new BoxRenderable(ctx, { + flexDirection: "column", + flexGrow: 1, + overflow: "hidden", + onSizeChange: () => { + this.recalculateBarProps(); + }, + ...viewportOptions, + id: `scroll-box-viewport-${this.internalId}` + }); + this.wrapper.add(this.viewport); + this.content = new ContentRenderable(ctx, this.viewport, viewportCulling, { + alignSelf: "flex-start", + flexShrink: 0, + ...scrollX ? { minWidth: "100%" } : { minWidth: "100%", maxWidth: "100%" }, + ...scrollY ? { minHeight: "100%" } : { minHeight: "100%", maxHeight: "100%" }, + onSizeChange: () => { + this.recalculateBarProps(); + }, + ...mergedContentOptions, + id: `scroll-box-content-${this.internalId}` + }); + this.viewport.add(this.content); + this.verticalScrollBar = new ScrollBarRenderable(ctx, { + ...scrollbarOptions, + ...verticalScrollbarOptions, + arrowOptions: { + ...scrollbarOptions?.arrowOptions, + ...verticalScrollbarOptions?.arrowOptions + }, + id: `scroll-box-vertical-scrollbar-${this.internalId}`, + orientation: "vertical", + onChange: (position) => { + this.content.translateY = -position; + this.updateStickyState(); + } + }); + super.add(this.verticalScrollBar); + this.horizontalScrollBar = new ScrollBarRenderable(ctx, { + ...scrollbarOptions, + ...horizontalScrollbarOptions, + arrowOptions: { + ...scrollbarOptions?.arrowOptions, + ...horizontalScrollbarOptions?.arrowOptions + }, + id: `scroll-box-horizontal-scrollbar-${this.internalId}`, + orientation: "horizontal", + onChange: (position) => { + this.content.translateX = -position; + this.updateStickyState(); + } + }); + this.wrapper.add(this.horizontalScrollBar); + this.recalculateBarProps(); + if (stickyStart && stickyScroll) { + this.applyStickyStart(stickyStart); + } + this.selectionListener = () => { + const selection = this._ctx.getSelection(); + if (!selection || !selection.isDragging) { + this.stopAutoScroll(); + } + }; + this._ctx.on("selection", this.selectionListener); + } + onUpdate(deltaTime) { + this.handleAutoScroll(deltaTime); + } + scrollBy(delta, unit = "absolute") { + if (typeof delta === "number") { + this.verticalScrollBar.scrollBy(delta, unit); + } else { + this.verticalScrollBar.scrollBy(delta.y, unit); + this.horizontalScrollBar.scrollBy(delta.x, unit); + } + } + scrollChildIntoView(childId) { + const child = this.content.findDescendantById(childId); + if (!child) + return; + const getNearestDelta = (elementStart, elementEnd, viewportStart, viewportEnd) => { + const elementSize = elementEnd - elementStart; + const viewportSize = viewportEnd - viewportStart; + const elementStartOutside = elementStart < viewportStart; + const elementEndOutside = elementEnd > viewportEnd; + if (elementStartOutside && elementEndOutside) { + return 0; + } + if (elementStartOutside && elementSize < viewportSize || elementEndOutside && elementSize > viewportSize) { + return elementStart - viewportStart; + } + if (elementStartOutside && elementSize > viewportSize || elementEndOutside && elementSize < viewportSize) { + return elementEnd - viewportEnd; + } + return 0; + }; + const childTop = child.y; + const childBottom = child.y + child.height; + const viewportTop = this.viewport.y; + const viewportBottom = this.viewport.y + this.viewport.height; + const dy = getNearestDelta(childTop, childBottom, viewportTop, viewportBottom); + const childLeft = child.x; + const childRight = child.x + child.width; + const viewportLeft = this.viewport.x; + const viewportRight = this.viewport.x + this.viewport.width; + const dx = getNearestDelta(childLeft, childRight, viewportLeft, viewportRight); + if (dx !== 0 || dy !== 0) { + this.scrollBy({ x: dx, y: dy }); + } + } + scrollTo(position) { + if (typeof position === "number") { + this.scrollTop = position; + } else { + this.scrollTop = position.y; + this.scrollLeft = position.x; + } + } + isAtStickyPosition() { + if (!this._stickyScroll || !this._stickyStart) { + return false; + } + const maxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height); + const maxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width); + switch (this._stickyStart) { + case "top": + return this.scrollTop === 0; + case "bottom": + return this.scrollTop >= maxScrollTop; + case "left": + return this.scrollLeft === 0; + case "right": + return this.scrollLeft >= maxScrollLeft; + default: + return false; + } + } + isAtStickyReengagePoint(stickyStart, maxScrollTop, maxScrollLeft) { + switch (stickyStart) { + case "top": + return maxScrollTop > 0 && this.scrollTop <= 0; + case "bottom": + return maxScrollTop > 0 && this.scrollTop >= maxScrollTop - 1; + case "left": + return maxScrollLeft > 0 && this.scrollLeft <= 0; + case "right": + return maxScrollLeft > 0 && this.scrollLeft >= maxScrollLeft - 1; + } + } + add(obj, index) { + return this.content.add(obj, index); + } + insertBefore(obj, anchor) { + return this.content.insertBefore(obj, anchor); + } + remove(id) { + this.content.remove(id); + } + getChildren() { + return this.content.getChildren(); + } + onMouseEvent(event) { + if (event.type === "scroll") { + let dir = event.scroll?.direction; + if (event.modifiers.shift) + dir = dir === "up" ? "left" : dir === "down" ? "right" : dir === "right" ? "down" : "up"; + const baseDelta = event.scroll?.delta ?? 0; + const now = Date.now(); + const multiplier = this.scrollAccel.tick(now); + const scrollAmount = baseDelta * multiplier; + if (dir === "up") { + this.scrollAccumulatorY -= scrollAmount; + const integerScroll = Math.trunc(this.scrollAccumulatorY); + if (integerScroll !== 0) { + this.scrollTop += integerScroll; + this.scrollAccumulatorY -= integerScroll; + } + } else if (dir === "down") { + this.scrollAccumulatorY += scrollAmount; + const integerScroll = Math.trunc(this.scrollAccumulatorY); + if (integerScroll !== 0) { + this.scrollTop += integerScroll; + this.scrollAccumulatorY -= integerScroll; + } + } else if (dir === "left") { + this.scrollAccumulatorX -= scrollAmount; + const integerScroll = Math.trunc(this.scrollAccumulatorX); + if (integerScroll !== 0) { + this.scrollLeft += integerScroll; + this.scrollAccumulatorX -= integerScroll; + } + } else if (dir === "right") { + this.scrollAccumulatorX += scrollAmount; + const integerScroll = Math.trunc(this.scrollAccumulatorX); + if (integerScroll !== 0) { + this.scrollLeft += integerScroll; + this.scrollAccumulatorX -= integerScroll; + } + } + this.syncManualScrollState(); + } + if (event.type === "drag" && event.isDragging) { + this.updateAutoScroll(event.x, event.y); + } else if (event.type === "up") { + this.stopAutoScroll(); + } + } + handleKeyPress(key) { + if (this.verticalScrollBar.handleKeyPress(key)) { + this.scrollAccel.reset(); + this.resetScrollAccumulators(); + this.syncManualScrollState(); + return true; + } + if (this.horizontalScrollBar.handleKeyPress(key)) { + this.scrollAccel.reset(); + this.resetScrollAccumulators(); + this.syncManualScrollState(); + return true; + } + return false; + } + resetScrollAccumulators() { + this.scrollAccumulatorX = 0; + this.scrollAccumulatorY = 0; + } + startAutoScroll(mouseX, mouseY) { + this.stopAutoScroll(); + this.autoScrollMouseX = mouseX; + this.autoScrollMouseY = mouseY; + this.cachedAutoScrollSpeed = this.getAutoScrollSpeed(mouseX, mouseY); + this.isAutoScrolling = true; + if (!this.live) { + this.live = true; + } + } + updateAutoScroll(mouseX, mouseY) { + this.autoScrollMouseX = mouseX; + this.autoScrollMouseY = mouseY; + this.cachedAutoScrollSpeed = this.getAutoScrollSpeed(mouseX, mouseY); + const scrollX = this.getAutoScrollDirectionX(mouseX); + const scrollY = this.getAutoScrollDirectionY(mouseY); + if (scrollX === 0 && scrollY === 0) { + this.stopAutoScroll(); + } else if (!this.isAutoScrolling) { + this.startAutoScroll(mouseX, mouseY); + } + } + stopAutoScroll() { + const wasAutoScrolling = this.isAutoScrolling; + this.isAutoScrolling = false; + this.autoScrollAccumulatorX = 0; + this.autoScrollAccumulatorY = 0; + if (wasAutoScrolling && !this.hasOtherLiveReasons()) { + this.live = false; + } + } + hasOtherLiveReasons() { + return false; + } + handleAutoScroll(deltaTime) { + if (!this.isAutoScrolling) + return; + const scrollX = this.getAutoScrollDirectionX(this.autoScrollMouseX); + const scrollY = this.getAutoScrollDirectionY(this.autoScrollMouseY); + const scrollAmount = this.cachedAutoScrollSpeed * (deltaTime / 1000); + let scrolled = false; + if (scrollX !== 0) { + this.autoScrollAccumulatorX += scrollX * scrollAmount; + const integerScrollX = Math.trunc(this.autoScrollAccumulatorX); + if (integerScrollX !== 0) { + this.scrollLeft += integerScrollX; + this.autoScrollAccumulatorX -= integerScrollX; + scrolled = true; + } + } + if (scrollY !== 0) { + this.autoScrollAccumulatorY += scrollY * scrollAmount; + const integerScrollY = Math.trunc(this.autoScrollAccumulatorY); + if (integerScrollY !== 0) { + this.scrollTop += integerScrollY; + this.autoScrollAccumulatorY -= integerScrollY; + scrolled = true; + } + } + if (scrolled) { + this._ctx.requestSelectionUpdate(); + } + if (scrollX === 0 && scrollY === 0) { + this.stopAutoScroll(); + } + } + getAutoScrollDirectionX(mouseX) { + const relativeX = mouseX - this.x; + const distToLeft = relativeX; + const distToRight = this.width - relativeX; + if (distToLeft <= this.autoScrollThresholdHorizontal) { + return this.scrollLeft > 0 ? -1 : 0; + } else if (distToRight <= this.autoScrollThresholdHorizontal) { + const maxScrollLeft = this.scrollWidth - this.viewport.width; + return this.scrollLeft < maxScrollLeft ? 1 : 0; + } + return 0; + } + getAutoScrollDirectionY(mouseY) { + const relativeY = mouseY - this.y; + const distToTop = relativeY; + const distToBottom = this.height - relativeY; + if (distToTop <= this.autoScrollThresholdVertical) { + return this.scrollTop > 0 ? -1 : 0; + } else if (distToBottom <= this.autoScrollThresholdVertical) { + const maxScrollTop = this.scrollHeight - this.viewport.height; + return this.scrollTop < maxScrollTop ? 1 : 0; + } + return 0; + } + getAutoScrollSpeed(mouseX, mouseY) { + const relativeX = mouseX - this.x; + const relativeY = mouseY - this.y; + const distToLeft = relativeX; + const distToRight = this.width - relativeX; + const distToTop = relativeY; + const distToBottom = this.height - relativeY; + const minDistance = Math.min(distToLeft, distToRight, distToTop, distToBottom); + if (minDistance <= 1) { + return this.autoScrollSpeedFast; + } else if (minDistance <= 2) { + return this.autoScrollSpeedMedium; + } else { + return this.autoScrollSpeedSlow; + } + } + recalculateBarProps() { + const wasApplyingStickyScroll = this._isApplyingStickyScroll; + this._isApplyingStickyScroll = true; + try { + this.verticalScrollBar.scrollSize = this.content.height; + this.verticalScrollBar.viewportSize = this.viewport.height; + this.horizontalScrollBar.scrollSize = this.content.width; + this.horizontalScrollBar.viewportSize = this.viewport.width; + if (this._stickyScroll) { + const newMaxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height); + const newMaxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width); + const stickyStart = this._stickyStart; + if (stickyStart && !this._hasManualScroll) { + this.applyStickyStart(stickyStart); + } else if (stickyStart && this._hasManualScroll && this.isAtStickyReengagePoint(stickyStart, newMaxScrollTop, newMaxScrollLeft)) { + this._hasManualScroll = false; + this.applyStickyStart(stickyStart); + } else if (!this._hasManualScroll) { + if (this._stickyScrollTop) { + this.scrollTop = 0; + } else if (this._stickyScrollBottom && newMaxScrollTop > 0) { + this.scrollTop = newMaxScrollTop; + } + if (this._stickyScrollLeft) { + this.scrollLeft = 0; + } else if (this._stickyScrollRight && newMaxScrollLeft > 0) { + this.scrollLeft = newMaxScrollLeft; + } + } + } + } finally { + this._isApplyingStickyScroll = wasApplyingStickyScroll; + } + process.nextTick(() => { + this.requestRender(); + }); + } + set padding(value) { + this.content.padding = value; + this.requestRender(); + } + set paddingX(value) { + this.content.paddingX = value; + this.requestRender(); + } + set paddingY(value) { + this.content.paddingY = value; + this.requestRender(); + } + set paddingTop(value) { + this.content.paddingTop = value; + this.requestRender(); + } + set paddingRight(value) { + this.content.paddingRight = value; + this.requestRender(); + } + set paddingBottom(value) { + this.content.paddingBottom = value; + this.requestRender(); + } + set paddingLeft(value) { + this.content.paddingLeft = value; + this.requestRender(); + } + set rootOptions(options) { + Object.assign(this, options); + this.requestRender(); + } + set wrapperOptions(options) { + Object.assign(this.wrapper, options); + this.requestRender(); + } + set viewportOptions(options) { + Object.assign(this.viewport, options); + this.requestRender(); + } + set contentOptions(options) { + Object.assign(this.content, options); + this.requestRender(); + } + set scrollbarOptions(options) { + Object.assign(this.verticalScrollBar, options); + Object.assign(this.horizontalScrollBar, options); + this.requestRender(); + } + set verticalScrollbarOptions(options) { + Object.assign(this.verticalScrollBar, options); + this.requestRender(); + } + set horizontalScrollbarOptions(options) { + Object.assign(this.horizontalScrollBar, options); + this.requestRender(); + } + get scrollAcceleration() { + return this.scrollAccel; + } + set scrollAcceleration(value) { + this.scrollAccel = value; + } + get viewportCulling() { + return this.content.viewportCulling; + } + set viewportCulling(value) { + this.content.viewportCulling = value; + this.requestRender(); + } + destroySelf() { + if (this.selectionListener) { + this._ctx.off("selection", this.selectionListener); + this.selectionListener = undefined; + } + super.destroySelf(); + } +} +// src/renderables/Select.ts +var defaultSelectKeybindings = [ + { name: "up", action: "move-up" }, + { name: "k", action: "move-up" }, + { name: "down", action: "move-down" }, + { name: "j", action: "move-down" }, + { name: "up", shift: true, action: "move-up-fast" }, + { name: "down", shift: true, action: "move-down-fast" }, + { name: "return", action: "select-current" }, + { name: "linefeed", action: "select-current" } +]; +var SelectRenderableEvents; +((SelectRenderableEvents2) => { + SelectRenderableEvents2["SELECTION_CHANGED"] = "selectionChanged"; + SelectRenderableEvents2["ITEM_SELECTED"] = "itemSelected"; +})(SelectRenderableEvents ||= {}); + +class SelectRenderable extends Renderable { + _focusable = true; + _options = []; + _selectedIndex = 0; + scrollOffset = 0; + maxVisibleItems; + _backgroundColor; + _textColor; + _focusedBackgroundColor; + _focusedTextColor; + _selectedBackgroundColor; + _selectedTextColor; + _descriptionColor; + _selectedDescriptionColor; + _showScrollIndicator; + _wrapSelection; + _showDescription; + _font; + _itemSpacing; + linesPerItem; + fontHeight; + _fastScrollStep; + _keyBindingsMap; + _keyAliasMap; + _keyBindings; + _defaultOptions = { + backgroundColor: "transparent", + textColor: "#FFFFFF", + focusedBackgroundColor: "#1a1a1a", + focusedTextColor: "#FFFFFF", + selectedBackgroundColor: "#334455", + selectedTextColor: "#FFFF00", + selectedIndex: 0, + descriptionColor: "#888888", + selectedDescriptionColor: "#CCCCCC", + showScrollIndicator: false, + wrapSelection: false, + showDescription: true, + itemSpacing: 0, + fastScrollStep: 5 + }; + constructor(ctx, options) { + super(ctx, { ...options, buffered: true }); + this._options = options.options || []; + const requestedIndex = options.selectedIndex ?? this._defaultOptions.selectedIndex; + this._selectedIndex = this._options.length > 0 ? Math.min(requestedIndex, this._options.length - 1) : 0; + this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor); + this._textColor = parseColor(options.textColor || this._defaultOptions.textColor); + this._focusedBackgroundColor = parseColor(options.focusedBackgroundColor || this._defaultOptions.focusedBackgroundColor); + this._focusedTextColor = parseColor(options.focusedTextColor || this._defaultOptions.focusedTextColor); + this._showScrollIndicator = options.showScrollIndicator ?? this._defaultOptions.showScrollIndicator; + this._wrapSelection = options.wrapSelection ?? this._defaultOptions.wrapSelection; + this._showDescription = options.showDescription ?? this._defaultOptions.showDescription; + this._font = options.font; + this._itemSpacing = options.itemSpacing || this._defaultOptions.itemSpacing; + this.fontHeight = this._font ? measureText({ text: "A", font: this._font }).height : 1; + this.linesPerItem = this._showDescription ? this._font ? this.fontHeight + 1 : 2 : this._font ? this.fontHeight : 1; + this.linesPerItem += this._itemSpacing; + this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem)); + this._selectedBackgroundColor = parseColor(options.selectedBackgroundColor || this._defaultOptions.selectedBackgroundColor); + this._selectedTextColor = parseColor(options.selectedTextColor || this._defaultOptions.selectedTextColor); + this._descriptionColor = parseColor(options.descriptionColor || this._defaultOptions.descriptionColor); + this._selectedDescriptionColor = parseColor(options.selectedDescriptionColor || this._defaultOptions.selectedDescriptionColor); + this._fastScrollStep = options.fastScrollStep || this._defaultOptions.fastScrollStep; + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {}); + this._keyBindings = options.keyBindings || []; + const mergedBindings = mergeKeyBindings(defaultSelectKeybindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + this.requestRender(); + } + renderSelf(buffer, deltaTime) { + if (!this.visible || !this.frameBuffer) + return; + if (this.isDirty) { + this.refreshFrameBuffer(); + } + } + refreshFrameBuffer() { + if (!this.frameBuffer) + return; + const bgColor = this._focused ? this._focusedBackgroundColor : this._backgroundColor; + this.frameBuffer.clear(bgColor); + if (this._options.length === 0) + return; + const contentX = 0; + const contentY = 0; + const contentWidth = this.width; + const contentHeight = this.height; + const visibleOptions = this._options.slice(this.scrollOffset, this.scrollOffset + this.maxVisibleItems); + for (let i = 0;i < visibleOptions.length; i++) { + const actualIndex = this.scrollOffset + i; + const option = visibleOptions[i]; + const isSelected = actualIndex === this._selectedIndex; + const itemY = contentY + i * this.linesPerItem; + if (itemY + this.linesPerItem - 1 >= contentY + contentHeight) + break; + if (isSelected) { + const contentHeight2 = this.linesPerItem - this._itemSpacing; + this.frameBuffer.fillRect(contentX, itemY, contentWidth, contentHeight2, this._selectedBackgroundColor); + } + const nameContent = `${isSelected ? "▶ " : " "}${option.name}`; + const baseTextColor = this._focused ? this._focusedTextColor : this._textColor; + const nameColor = isSelected ? this._selectedTextColor : baseTextColor; + let descX = contentX + 3; + if (this._font) { + const indicator = isSelected ? "▶ " : " "; + this.frameBuffer.drawText(indicator, contentX + 1, itemY, nameColor); + const indicatorWidth = 2; + renderFontToFrameBuffer(this.frameBuffer, { + text: option.name, + x: contentX + 1 + indicatorWidth, + y: itemY, + color: nameColor, + backgroundColor: isSelected ? this._selectedBackgroundColor : bgColor, + font: this._font + }); + descX = contentX + 1 + indicatorWidth; + } else { + this.frameBuffer.drawText(nameContent, contentX + 1, itemY, nameColor); + } + if (this._showDescription && itemY + this.fontHeight < contentY + contentHeight) { + const descColor = isSelected ? this._selectedDescriptionColor : this._descriptionColor; + this.frameBuffer.drawText(option.description, descX, itemY + this.fontHeight, descColor); + } + } + if (this._showScrollIndicator && this._options.length > this.maxVisibleItems) { + this.renderScrollIndicatorToFrameBuffer(contentX, contentY, contentWidth, contentHeight); + } + } + renderScrollIndicatorToFrameBuffer(contentX, contentY, contentWidth, contentHeight) { + if (!this.frameBuffer) + return; + const scrollPercent = this._selectedIndex / Math.max(1, this._options.length - 1); + const indicatorHeight = Math.max(1, contentHeight - 2); + const indicatorY = contentY + 1 + Math.floor(scrollPercent * indicatorHeight); + const indicatorX = contentX + contentWidth - 1; + this.frameBuffer.drawText("█", indicatorX, indicatorY, parseColor("#666666")); + } + get options() { + return this._options; + } + set options(options) { + this._options = options; + this._selectedIndex = Math.min(this._selectedIndex, Math.max(0, options.length - 1)); + this.updateScrollOffset(); + this.requestRender(); + } + getSelectedOption() { + return this._options[this._selectedIndex] || null; + } + getSelectedIndex() { + return this._selectedIndex; + } + moveUp(steps = 1) { + const newIndex = this._selectedIndex - steps; + if (newIndex >= 0) { + this._selectedIndex = newIndex; + } else if (this._wrapSelection && this._options.length > 0) { + this._selectedIndex = this._options.length - 1; + } else { + this._selectedIndex = 0; + } + this.updateScrollOffset(); + this.requestRender(); + this.emit("selectionChanged" /* SELECTION_CHANGED */, this._selectedIndex, this.getSelectedOption()); + } + moveDown(steps = 1) { + const newIndex = this._selectedIndex + steps; + if (newIndex < this._options.length) { + this._selectedIndex = newIndex; + } else if (this._wrapSelection && this._options.length > 0) { + this._selectedIndex = 0; + } else { + this._selectedIndex = this._options.length - 1; + } + this.updateScrollOffset(); + this.requestRender(); + this.emit("selectionChanged" /* SELECTION_CHANGED */, this._selectedIndex, this.getSelectedOption()); + } + selectCurrent() { + const selected = this.getSelectedOption(); + if (selected) { + this.emit("itemSelected" /* ITEM_SELECTED */, this._selectedIndex, selected); + } + } + setSelectedIndex(index) { + if (index >= 0 && index < this._options.length) { + this._selectedIndex = index; + this.updateScrollOffset(); + this.requestRender(); + this.emit("selectionChanged" /* SELECTION_CHANGED */, this._selectedIndex, this.getSelectedOption()); + } + } + updateScrollOffset() { + if (!this._options) + return; + const halfVisible = Math.floor(this.maxVisibleItems / 2); + const newScrollOffset = Math.max(0, Math.min(this._selectedIndex - halfVisible, this._options.length - this.maxVisibleItems)); + if (newScrollOffset !== this.scrollOffset) { + this.scrollOffset = newScrollOffset; + this.requestRender(); + } + } + onResize(width, height) { + this.maxVisibleItems = Math.max(1, Math.floor(height / this.linesPerItem)); + this.updateScrollOffset(); + this.requestRender(); + } + handleKeyPress(key) { + const action = getKeyBindingAction(this._keyBindingsMap, key); + if (action) { + switch (action) { + case "move-up": + this.moveUp(1); + return true; + case "move-down": + this.moveDown(1); + return true; + case "move-up-fast": + this.moveUp(this._fastScrollStep); + return true; + case "move-down-fast": + this.moveDown(this._fastScrollStep); + return true; + case "select-current": + this.selectCurrent(); + return true; + } + } + return false; + } + get showScrollIndicator() { + return this._showScrollIndicator; + } + set showScrollIndicator(show) { + this._showScrollIndicator = show; + this.requestRender(); + } + get showDescription() { + return this._showDescription; + } + set showDescription(show) { + if (this._showDescription !== show) { + this._showDescription = show; + this.linesPerItem = this._showDescription ? this._font ? this.fontHeight + 1 : 2 : this._font ? this.fontHeight : 1; + this.linesPerItem += this._itemSpacing; + this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem)); + this.updateScrollOffset(); + this.requestRender(); + } + } + get wrapSelection() { + return this._wrapSelection; + } + set wrapSelection(wrap) { + this._wrapSelection = wrap; + } + set backgroundColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.backgroundColor); + if (this._backgroundColor !== newColor) { + this._backgroundColor = newColor; + this.requestRender(); + } + } + set textColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.textColor); + if (this._textColor !== newColor) { + this._textColor = newColor; + this.requestRender(); + } + } + set focusedBackgroundColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.focusedBackgroundColor); + if (this._focusedBackgroundColor !== newColor) { + this._focusedBackgroundColor = newColor; + this.requestRender(); + } + } + set focusedTextColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.focusedTextColor); + if (this._focusedTextColor !== newColor) { + this._focusedTextColor = newColor; + this.requestRender(); + } + } + set selectedBackgroundColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.selectedBackgroundColor); + if (this._selectedBackgroundColor !== newColor) { + this._selectedBackgroundColor = newColor; + this.requestRender(); + } + } + set selectedTextColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.selectedTextColor); + if (this._selectedTextColor !== newColor) { + this._selectedTextColor = newColor; + this.requestRender(); + } + } + set descriptionColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.descriptionColor); + if (this._descriptionColor !== newColor) { + this._descriptionColor = newColor; + this.requestRender(); + } + } + set selectedDescriptionColor(value) { + const newColor = parseColor(value ?? this._defaultOptions.selectedDescriptionColor); + if (this._selectedDescriptionColor !== newColor) { + this._selectedDescriptionColor = newColor; + this.requestRender(); + } + } + set font(font) { + this._font = font; + this.fontHeight = measureText({ text: "A", font: this._font }).height; + this.linesPerItem = this._showDescription ? this._font ? this.fontHeight + 1 : 2 : this._font ? this.fontHeight : 1; + this.linesPerItem += this._itemSpacing; + this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem)); + this.updateScrollOffset(); + this.requestRender(); + } + set itemSpacing(spacing) { + this._itemSpacing = spacing; + this.linesPerItem = this._showDescription ? this._font ? this.fontHeight + 1 : 2 : this._font ? this.fontHeight : 1; + this.linesPerItem += this._itemSpacing; + this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem)); + this.updateScrollOffset(); + this.requestRender(); + } + set fastScrollStep(step) { + this._fastScrollStep = step; + } + set keyBindings(bindings) { + this._keyBindings = bindings; + const mergedBindings = mergeKeyBindings(defaultSelectKeybindings, bindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + } + set keyAliasMap(aliases) { + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases); + const mergedBindings = mergeKeyBindings(defaultSelectKeybindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + } + set selectedIndex(value) { + const newIndex = value ?? this._defaultOptions.selectedIndex; + const clampedIndex = this._options.length > 0 ? Math.min(Math.max(0, newIndex), this._options.length - 1) : 0; + if (this._selectedIndex !== clampedIndex) { + this._selectedIndex = clampedIndex; + this.updateScrollOffset(); + this.requestRender(); + } + } +} +// src/renderables/TabSelect.ts +var defaultTabSelectKeybindings = [ + { name: "left", action: "move-left" }, + { name: "[", action: "move-left" }, + { name: "right", action: "move-right" }, + { name: "]", action: "move-right" }, + { name: "return", action: "select-current" }, + { name: "linefeed", action: "select-current" } +]; +var TabSelectRenderableEvents; +((TabSelectRenderableEvents2) => { + TabSelectRenderableEvents2["SELECTION_CHANGED"] = "selectionChanged"; + TabSelectRenderableEvents2["ITEM_SELECTED"] = "itemSelected"; +})(TabSelectRenderableEvents ||= {}); +function calculateDynamicHeight(showUnderline, showDescription) { + let height = 1; + if (showUnderline) { + height += 1; + } + if (showDescription) { + height += 1; + } + return height; +} + +class TabSelectRenderable extends Renderable { + _focusable = true; + _options = []; + selectedIndex = 0; + scrollOffset = 0; + _tabWidth; + maxVisibleTabs; + _backgroundColor; + _textColor; + _focusedBackgroundColor; + _focusedTextColor; + _selectedBackgroundColor; + _selectedTextColor; + _selectedDescriptionColor; + _showScrollArrows; + _showDescription; + _showUnderline; + _wrapSelection; + _keyBindingsMap; + _keyAliasMap; + _keyBindings; + constructor(ctx, options) { + const calculatedHeight = calculateDynamicHeight(options.showUnderline ?? true, options.showDescription ?? true); + super(ctx, { ...options, height: calculatedHeight, buffered: true }); + this._backgroundColor = parseColor(options.backgroundColor || "transparent"); + this._textColor = parseColor(options.textColor || "#FFFFFF"); + this._focusedBackgroundColor = parseColor(options.focusedBackgroundColor || options.backgroundColor || "#1a1a1a"); + this._focusedTextColor = parseColor(options.focusedTextColor || options.textColor || "#FFFFFF"); + this._options = options.options || []; + this._tabWidth = options.tabWidth || 20; + this._showDescription = options.showDescription ?? true; + this._showUnderline = options.showUnderline ?? true; + this._showScrollArrows = options.showScrollArrows ?? true; + this._wrapSelection = options.wrapSelection ?? false; + this.maxVisibleTabs = Math.max(1, Math.floor(this.width / this._tabWidth)); + this._selectedBackgroundColor = parseColor(options.selectedBackgroundColor || "#334455"); + this._selectedTextColor = parseColor(options.selectedTextColor || "#FFFF00"); + this._selectedDescriptionColor = parseColor(options.selectedDescriptionColor || "#CCCCCC"); + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {}); + this._keyBindings = options.keyBindings || []; + const mergedBindings = mergeKeyBindings(defaultTabSelectKeybindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + } + calculateDynamicHeight() { + return calculateDynamicHeight(this._showUnderline, this._showDescription); + } + renderSelf(buffer, deltaTime) { + if (!this.visible || !this.frameBuffer) + return; + if (this.isDirty) { + this.refreshFrameBuffer(); + } + } + refreshFrameBuffer() { + if (!this.frameBuffer) + return; + const bgColor = this._focused ? this._focusedBackgroundColor : this._backgroundColor; + this.frameBuffer.clear(bgColor); + if (this._options.length === 0) + return; + const contentX = 0; + const contentY = 0; + const contentWidth = this.width; + const contentHeight = this.height; + const visibleOptions = this._options.slice(this.scrollOffset, this.scrollOffset + this.maxVisibleTabs); + for (let i = 0;i < visibleOptions.length; i++) { + const actualIndex = this.scrollOffset + i; + const option = visibleOptions[i]; + const isSelected = actualIndex === this.selectedIndex; + const tabX = contentX + i * this._tabWidth; + if (tabX >= contentX + contentWidth) + break; + const actualTabWidth = Math.min(this._tabWidth, contentWidth - i * this._tabWidth); + if (isSelected) { + this.frameBuffer.fillRect(tabX, contentY, actualTabWidth, 1, this._selectedBackgroundColor); + } + const baseTextColor = this._focused ? this._focusedTextColor : this._textColor; + const nameColor = isSelected ? this._selectedTextColor : baseTextColor; + const nameContent = this.truncateText(option.name, actualTabWidth - 2); + this.frameBuffer.drawText(nameContent, tabX + 1, contentY, nameColor); + if (isSelected && this._showUnderline && contentHeight >= 2) { + const underlineY = contentY + 1; + const underlineBg = isSelected ? this._selectedBackgroundColor : bgColor; + this.frameBuffer.drawText("▬".repeat(actualTabWidth), tabX, underlineY, nameColor, underlineBg); + } + } + if (this._showDescription && contentHeight >= (this._showUnderline ? 3 : 2)) { + const selectedOption = this.getSelectedOption(); + if (selectedOption) { + const descriptionY = contentY + (this._showUnderline ? 2 : 1); + const descColor = this._selectedDescriptionColor; + const descContent = this.truncateText(selectedOption.description, contentWidth - 2); + this.frameBuffer.drawText(descContent, contentX + 1, descriptionY, descColor); + } + } + if (this._showScrollArrows && this._options.length > this.maxVisibleTabs) { + this.renderScrollArrowsToFrameBuffer(contentX, contentY, contentWidth, contentHeight); + } + } + truncateText(text, maxWidth) { + if (text.length <= maxWidth) + return text; + return text.substring(0, Math.max(0, maxWidth - 1)) + "…"; + } + renderScrollArrowsToFrameBuffer(contentX, contentY, contentWidth, contentHeight) { + if (!this.frameBuffer) + return; + const hasMoreLeft = this.scrollOffset > 0; + const hasMoreRight = this.scrollOffset + this.maxVisibleTabs < this._options.length; + if (hasMoreLeft) { + this.frameBuffer.drawText("‹", contentX, contentY, parseColor("#AAAAAA")); + } + if (hasMoreRight) { + this.frameBuffer.drawText("›", contentX + contentWidth - 1, contentY, parseColor("#AAAAAA")); + } + } + setOptions(options) { + this._options = options; + this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, options.length - 1)); + this.updateScrollOffset(); + this.requestRender(); + } + getSelectedOption() { + return this._options[this.selectedIndex] || null; + } + getSelectedIndex() { + return this.selectedIndex; + } + moveLeft() { + if (this.selectedIndex > 0) { + this.selectedIndex--; + } else if (this._wrapSelection && this._options.length > 0) { + this.selectedIndex = this._options.length - 1; + } else { + return; + } + this.updateScrollOffset(); + this.requestRender(); + this.emit("selectionChanged" /* SELECTION_CHANGED */, this.selectedIndex, this.getSelectedOption()); + } + moveRight() { + if (this.selectedIndex < this._options.length - 1) { + this.selectedIndex++; + } else if (this._wrapSelection && this._options.length > 0) { + this.selectedIndex = 0; + } else { + return; + } + this.updateScrollOffset(); + this.requestRender(); + this.emit("selectionChanged" /* SELECTION_CHANGED */, this.selectedIndex, this.getSelectedOption()); + } + selectCurrent() { + const selected = this.getSelectedOption(); + if (selected) { + this.emit("itemSelected" /* ITEM_SELECTED */, this.selectedIndex, selected); + } + } + setSelectedIndex(index) { + if (index >= 0 && index < this._options.length) { + this.selectedIndex = index; + this.updateScrollOffset(); + this.requestRender(); + this.emit("selectionChanged" /* SELECTION_CHANGED */, this.selectedIndex, this.getSelectedOption()); + } + } + updateScrollOffset() { + const halfVisible = Math.floor(this.maxVisibleTabs / 2); + const newScrollOffset = Math.max(0, Math.min(this.selectedIndex - halfVisible, this._options.length - this.maxVisibleTabs)); + if (newScrollOffset !== this.scrollOffset) { + this.scrollOffset = newScrollOffset; + this.requestRender(); + } + } + onResize(width, height) { + this.maxVisibleTabs = Math.max(1, Math.floor(width / this._tabWidth)); + this.updateScrollOffset(); + this.requestRender(); + } + setTabWidth(tabWidth) { + if (this._tabWidth === tabWidth) + return; + this._tabWidth = tabWidth; + this.maxVisibleTabs = Math.max(1, Math.floor(this.width / this._tabWidth)); + this.updateScrollOffset(); + this.requestRender(); + } + getTabWidth() { + return this._tabWidth; + } + handleKeyPress(key) { + const action = getKeyBindingAction(this._keyBindingsMap, key); + if (action) { + switch (action) { + case "move-left": + this.moveLeft(); + return true; + case "move-right": + this.moveRight(); + return true; + case "select-current": + this.selectCurrent(); + return true; + } + } + return false; + } + get options() { + return this._options; + } + set options(options) { + this._options = options; + this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, options.length - 1)); + this.updateScrollOffset(); + this.requestRender(); + } + set backgroundColor(color) { + this._backgroundColor = parseColor(color); + this.requestRender(); + } + set textColor(color) { + this._textColor = parseColor(color); + this.requestRender(); + } + set focusedBackgroundColor(color) { + this._focusedBackgroundColor = parseColor(color); + this.requestRender(); + } + set focusedTextColor(color) { + this._focusedTextColor = parseColor(color); + this.requestRender(); + } + set selectedBackgroundColor(color) { + this._selectedBackgroundColor = parseColor(color); + this.requestRender(); + } + set selectedTextColor(color) { + this._selectedTextColor = parseColor(color); + this.requestRender(); + } + set selectedDescriptionColor(color) { + this._selectedDescriptionColor = parseColor(color); + this.requestRender(); + } + get showDescription() { + return this._showDescription; + } + set showDescription(show) { + if (this._showDescription !== show) { + this._showDescription = show; + const newHeight = this.calculateDynamicHeight(); + this.height = newHeight; + this.requestRender(); + } + } + get showUnderline() { + return this._showUnderline; + } + set showUnderline(show) { + if (this._showUnderline !== show) { + this._showUnderline = show; + const newHeight = this.calculateDynamicHeight(); + this.height = newHeight; + this.requestRender(); + } + } + get showScrollArrows() { + return this._showScrollArrows; + } + set showScrollArrows(show) { + if (this._showScrollArrows !== show) { + this._showScrollArrows = show; + this.requestRender(); + } + } + get wrapSelection() { + return this._wrapSelection; + } + set wrapSelection(wrap) { + this._wrapSelection = wrap; + } + get tabWidth() { + return this._tabWidth; + } + set tabWidth(tabWidth) { + if (this._tabWidth === tabWidth) + return; + this._tabWidth = tabWidth; + this.maxVisibleTabs = Math.max(1, Math.floor(this.width / this._tabWidth)); + this.updateScrollOffset(); + this.requestRender(); + } + set keyBindings(bindings) { + this._keyBindings = bindings; + const mergedBindings = mergeKeyBindings(defaultTabSelectKeybindings, bindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + } + set keyAliasMap(aliases) { + this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases); + const mergedBindings = mergeKeyBindings(defaultTabSelectKeybindings, this._keyBindings); + this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap); + } +} +// src/renderables/TimeToFirstDraw.ts +class TimeToFirstDrawRenderable extends Renderable { + _runtimeMs = null; + textColor; + label; + precision; + constructor(ctx, options = {}) { + super(ctx, { + width: "100%", + height: 1, + flexShrink: 0, + alignSelf: "center", + ...options + }); + this.textColor = parseColor(options.fg ?? "#AAAAAA"); + this.label = options.label ?? "Time to first draw"; + this.precision = this.normalizePrecision(options.precision ?? 2); + } + get runtimeMs() { + return this._runtimeMs; + } + set fg(value) { + this.textColor = parseColor(value); + this.requestRender(); + } + set color(value) { + this.fg = value; + } + set textLabel(value) { + if (value === this.label) { + return; + } + this.label = value; + this.requestRender(); + } + set decimals(value) { + const nextPrecision = this.normalizePrecision(value); + if (nextPrecision === this.precision) { + return; + } + this.precision = nextPrecision; + this.requestRender(); + } + reset() { + this._runtimeMs = null; + this.requestRender(); + } + renderSelf(buffer) { + if (this._runtimeMs === null) { + this._runtimeMs = performance.now(); + } + const content = `${this.label}: ${this._runtimeMs.toFixed(this.precision)}ms`; + const maxWidth = Math.max(this.width, 1); + const visibleContent = content.length > maxWidth ? content.slice(0, maxWidth) : content; + const centeredX = this.x + Math.max(0, Math.floor((maxWidth - visibleContent.length) / 2)); + buffer.drawText(visibleContent, centeredX, this.y, this.textColor); + } + normalizePrecision(value) { + if (!Number.isFinite(value)) { + return 2; + } + return Math.max(0, Math.floor(value)); + } +} +export { + yellow, + wrapWithDelegates, + white, + vstyles, + visualizeRenderableTree, + underline, + treeSitterToTextChunks, + treeSitterToStyledText, + terminalNamedSingleStrokeKeys, + t, + stripAnsiSequences, + stringToStyledText, + strikethrough, + setupAudio, + setRenderLibPath, + rgbToHex, + reverse, + resolveRenderLib, + resolveCoreSlot, + renderFontToFrameBuffer, + registerEnvVar, + registerCorePlugin, + red, + pathToFiletype, + parseWrap, + parseUnit, + parsePositionType, + parseOverflow, + parseMeasureMode, + parseLogLevel, + parseKeypress, + parseJustify, + parseGutter, + parseFlexDirection, + parseEdge, + parseDisplay, + parseDirection, + parseDimension, + parseColor, + parseBoxSizing, + parseBorderStyle, + parseAlignItems, + parseAlign, + normalizeTerminalPalette, + normalizeIndexedColorIndex, + normalizeColorValue, + nonAlphanumericKeys, + measureText, + maybeMakeRenderable, + magenta, + link, + italic, + isValidBorderStyle, + isVNode, + isTextNodeRenderable, + isStyledText, + isRenderable, + isEditBufferRenderable, + instantiate, + infoStringToFiletype, + hsvToRgb, + hexToRgb, + hastToStyledText, + h, + green, + getTreeSitterClient, + getLinkId, + getDataPaths, + getCharacterPositions, + getBorderSides, + getBorderFromSides, + getBaseAttributes, + generateEnvMarkdown, + generateEnvColored, + fonts, + fg, + extensionToFiletype, + extToFiletype, + envRegistry, + env, + engine, + dim, + detectLinks, + destroyTreeSitterClient, + delegate, + defaultTextareaKeyBindings, + decodePasteBytes, + cyan, + createTimeline, + createTextAttributes, + createTerminalPalette, + createSlotRegistry, + createMarkdownCodeBlockRenderer, + createExtmarksController, + createCoreSlotRegistry, + createCliRenderer, + coordinateToCharacterIndex, + convertThemeToStyles, + convertGlobalToLocalSelection, + clearEnvCache, + capture, + buildTerminalPaletteSignature, + buildKittyKeyboardFlags, + brightYellow, + brightWhite, + brightRed, + brightMagenta, + brightGreen, + brightCyan, + brightBlue, + brightBlack, + borderCharsToArray, + bold, + blue, + blink, + black, + bgYellow, + bgWhite, + bgRed, + bgMagenta, + bgGreen, + bgCyan, + bgBlue, + bgBlack, + bg, + basenameToFiletype, + attributesWithLink, + applyScanlines, + applySaturation, + applyNoise, + applyInvert, + applyGain, + applyChromaticAberration, + applyBrightness, + applyAsciiArt, + ansi256IndexToRgb, + addDefaultParsers, + exports_yoga as Yoga, + VignetteEffect, + VRenderable, + TreeSitterClient, + Timeline, + TimeToFirstDrawRenderable, + TextareaRenderable, + TextTableRenderable, + TextRenderable, + TextNodeRenderable, + TextBufferView, + TextBufferRenderable, + TextBuffer, + TextAttributes, + Text, + TerminalPalette, + TerminalConsole, + TargetChannel, + TabSelectRenderableEvents, + TabSelectRenderable, + TabSelect, + TRITANOPIA_SIM_MATRIX, + TRITANOPIA_COMP_MATRIX, + TECHNICOLOR_MATRIX, + SystemClock, + SyntaxStyle, + StyledText, + StdinParser, + SlotRenderable, + SlotRegistry, + SliderRenderable, + Selection, + SelectRenderableEvents, + SelectRenderable, + Select, + ScrollBoxRenderable, + ScrollBox, + ScrollBarRenderable, + SYNTHWAVE_MATRIX, + SOLARIZATION_MATRIX, + SEPIA_MATRIX, + RootTextNodeRenderable, + RootRenderable, + RendererControlState, + RenderableEvents, + Renderable, + RainbowTextEffect, + RGBA, + PasteEvent, + PROTANOPIA_SIM_MATRIX, + PROTANOPIA_COMP_MATRIX, + OptimizedBuffer, + NativeSpanFeed, + MouseParser, + MouseEvent, + MouseButton, + MarkdownRenderable, + MacOSScrollAccel, + LogLevel, + LinearScrollAccel, + LineNumberRenderable, + LayoutEvents, + KeyHandler, + KeyEvent, + InternalKeyHandler, + InputRenderableEvents, + InputRenderable, + Input, + INVERT_MATRIX, + Generic, + GREENSCALE_MATRIX, + GRAYSCALE_MATRIX, + FrameBufferRenderable, + FrameBuffer, + FlamesEffect, + ExtmarksController, + EditorView, + EditBufferRenderableEvents, + EditBufferRenderable, + EditBuffer, + DistortionEffect, + DiffRenderable, + DebugOverlayCorner, + DataPathsManager, + DEUTERANOPIA_SIM_MATRIX, + DEUTERANOPIA_COMP_MATRIX, + DEFAULT_FOREGROUND_RGB, + DEFAULT_BACKGROUND_RGB, + ConsolePosition, + CodeRenderable, + Code, + CloudsEffect, + CliRenderer, + CliRenderEvents, + CRTRollingBarEffect, + BoxRenderable, + Box, + BorderChars, + BorderCharArrays, + BloomEffect, + BaseRenderable, + Audio, + ArrowRenderable, + ATTRIBUTE_BASE_MASK, + ATTRIBUTE_BASE_BITS, + ASCIIFontSelectionHelper, + ASCIIFontRenderable, + ASCIIFont, + ACHROMATOPSIA_MATRIX +}; + +//# debugId=0C019ED1790BA7F464756E2164756E21 +//# sourceMappingURL=index.js.map diff --git a/.patches/@opentui/core/index.js.map b/.patches/@opentui/core/index.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/index.js.map @@ -0,0 +1,35 @@ +{ + "version": 3, + "sources": ["../src/post/effects.ts", "../src/post/filters.ts", "../src/post/matrices.ts", "../src/animation/Timeline.ts", "../src/plugins/registry.ts", "../src/plugins/core-slot.ts", "../src/audio.ts", "../src/renderables/FrameBuffer.ts", "../src/renderables/ASCIIFont.ts", "../src/renderables/composition/constructs.ts", "../src/renderables/composition/VRenderable.ts", "../src/renderables/LineNumberRenderable.ts", "../../../node_modules/.bun/diff@9.0.0/node_modules/diff/libesm/patch/parse.js", "../src/renderables/Diff.ts", "../src/renderables/Textarea.ts", "../src/renderables/Input.ts", "../../../node_modules/.bun/marked@17.0.1/node_modules/marked/lib/marked.esm.js", "../src/renderables/TextTable.ts", "../src/renderables/markdown-parser.ts", "../src/renderables/Markdown.ts", "../src/renderables/Slider.ts", "../src/renderables/ScrollBar.ts", "../src/renderables/ScrollBox.ts", "../src/renderables/Select.ts", "../src/renderables/TabSelect.ts", "../src/renderables/TimeToFirstDraw.ts"], + "sourcesContent": [ + "import type { OptimizedBuffer } from \"../buffer.js\"\n\nfunction toU8(value: number): number {\n return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255)\n}\n\nfunction channel(buffer: Uint16Array, index: number): number {\n return (buffer[index] & 0xff) / 255\n}\n\nfunction setRgb(buffer: Uint16Array, base: number, r: number, g: number, b: number): void {\n const a = buffer[base + 3] & 0xff\n buffer[base] = toU8(r)\n buffer[base + 1] = toU8(g)\n buffer[base + 2] = toU8(b)\n buffer[base + 3] = a\n}\n\ninterface ActiveGlitch {\n y: number\n type: \"shift\" | \"flip\" | \"color\"\n amount: number\n}\n\nexport class DistortionEffect {\n // --- Configurable Parameters ---\n public glitchChancePerSecond: number = 0.5\n public maxGlitchLines: number = 3\n public minGlitchDuration: number = 0.05\n public maxGlitchDuration: number = 0.2\n public maxShiftAmount: number = 10\n public shiftFlipRatio: number = 0.6\n public colorGlitchChance: number = 0.2\n\n // --- Internal State ---\n private lastGlitchTime: number = 0\n private glitchDuration: number = 0\n private activeGlitches: ActiveGlitch[] = []\n\n constructor(options?: Partial) {\n if (options) {\n Object.assign(this, options)\n }\n }\n\n /**\n * Applies the animated distortion/glitch effect to the buffer.\n */\n public apply(buffer: OptimizedBuffer, deltaTime: number): void {\n const width = buffer.width\n const height = buffer.height\n const buf = buffer.buffers\n // Note: Using internal timer based on deltaTime is more reliable than Date.now()\n\n // Update glitch timer\n this.lastGlitchTime += deltaTime\n\n // End current glitch if duration is over\n if (this.activeGlitches.length > 0 && this.lastGlitchTime >= this.glitchDuration) {\n this.activeGlitches = []\n this.glitchDuration = 0\n }\n\n // Chance to start a new glitch\n if (this.activeGlitches.length === 0 && Math.random() < this.glitchChancePerSecond * deltaTime) {\n this.lastGlitchTime = 0\n this.glitchDuration = this.minGlitchDuration + Math.random() * (this.maxGlitchDuration - this.minGlitchDuration)\n const numGlitches = 1 + Math.floor(Math.random() * this.maxGlitchLines)\n\n for (let i = 0; i < numGlitches; i++) {\n const y = Math.floor(Math.random() * height)\n let type: ActiveGlitch[\"type\"]\n let amount = 0\n\n const typeRoll = Math.random()\n if (typeRoll < this.colorGlitchChance) {\n type = \"color\"\n } else {\n // Determine shift or flip based on remaining probability\n const shiftRoll = (typeRoll - this.colorGlitchChance) / (1 - this.colorGlitchChance)\n if (shiftRoll < this.shiftFlipRatio) {\n type = \"shift\"\n amount = Math.floor((Math.random() - 0.5) * 2 * this.maxShiftAmount)\n } else {\n type = \"flip\"\n }\n }\n\n // Avoid glitching the same line twice in one burst\n if (!this.activeGlitches.some((g) => g.y === y)) {\n this.activeGlitches.push({ y, type, amount })\n }\n }\n }\n\n // Apply active glitches\n if (this.activeGlitches.length > 0) {\n // Create temporary arrays lazily if needed (minor optimization for shift/flip)\n let tempChar: Uint32Array | null = null\n let tempFg: Uint16Array | null = null\n let tempBg: Uint16Array | null = null\n let tempAttr: Uint8Array | null = null\n\n for (const glitch of this.activeGlitches) {\n const y = glitch.y\n // Ensure y is within bounds (safer)\n if (y < 0 || y >= height) continue\n const baseIndex = y * width\n\n if (glitch.type === \"shift\" || glitch.type === \"flip\") {\n // Lazily create temp buffers only when needed for shift/flip\n if (!tempChar) {\n tempChar = new Uint32Array(width)\n tempFg = new Uint16Array(width * 4)\n tempBg = new Uint16Array(width * 4)\n tempAttr = new Uint8Array(width)\n }\n\n // 1. Copy original row data to temp buffers\n try {\n tempChar.set(buf.char.subarray(baseIndex, baseIndex + width))\n tempFg!.set(buf.fg.subarray(baseIndex * 4, (baseIndex + width) * 4))\n tempBg!.set(buf.bg.subarray(baseIndex * 4, (baseIndex + width) * 4))\n tempAttr!.set(buf.attributes.subarray(baseIndex, baseIndex + width))\n } catch (e) {\n // Handle potential range errors if buffer size changes unexpectedly\n console.error(`Error copying row ${y} for distortion:`, e)\n continue\n }\n\n if (glitch.type === \"shift\") {\n const shift = glitch.amount\n for (let x = 0; x < width; x++) {\n const srcX = (x - shift + width) % width // Wrap around shift\n const destIndex = baseIndex + x\n const srcTempIndex = srcX\n\n buf.char[destIndex] = tempChar[srcTempIndex]\n buf.attributes[destIndex] = tempAttr![srcTempIndex]\n\n const destColorIndex = destIndex * 4\n const srcTempColorIndex = srcTempIndex * 4\n\n buf.fg.set(tempFg!.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex)\n buf.bg.set(tempBg!.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex)\n }\n } else {\n // type === 'flip'\n for (let x = 0; x < width; x++) {\n const srcX = width - 1 - x // Flipped index\n const destIndex = baseIndex + x\n const srcTempIndex = srcX\n\n buf.char[destIndex] = tempChar[srcTempIndex]\n buf.attributes[destIndex] = tempAttr![srcTempIndex]\n\n const destColorIndex = destIndex * 4\n const srcTempColorIndex = srcTempIndex * 4\n\n buf.fg.set(tempFg!.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex)\n buf.bg.set(tempBg!.subarray(srcTempColorIndex, srcTempColorIndex + 4), destColorIndex)\n }\n }\n } else if (glitch.type === \"color\") {\n const glitchStart = Math.floor(Math.random() * width)\n // Make glitch length at least 1 pixel, up to the rest of the line\n const maxPossibleLength = width - glitchStart\n // Introduce more variability: sometimes short, sometimes long, but not always full width\n let glitchLength = Math.floor(Math.random() * maxPossibleLength) + 1\n if (Math.random() < 0.2) {\n // 20% chance of a shorter, more intense glitch segment\n glitchLength = Math.floor(Math.random() * (width / 4)) + 1\n }\n glitchLength = Math.min(glitchLength, maxPossibleLength)\n\n for (let x = glitchStart; x < glitchStart + glitchLength; x++) {\n if (x >= width) break // Boundary check\n\n const destIndex = baseIndex + x\n const destColorIndex = destIndex * 4\n\n let rFg, gFg, bFg, rBg, gBg, bBg\n\n // More varied and \"glitchy\" colors\n const colorMode = Math.random()\n if (colorMode < 0.33) {\n // Pure random\n rFg = Math.random()\n gFg = Math.random()\n bFg = Math.random()\n rBg = Math.random()\n gBg = Math.random()\n bBg = Math.random()\n } else if (colorMode < 0.66) {\n // Single channel emphasis or block color\n const emphasis = Math.random()\n if (emphasis < 0.25) {\n rFg = Math.random()\n gFg = 0\n bFg = 0\n } // Red\n else if (emphasis < 0.5) {\n rFg = 0\n gFg = Math.random()\n bFg = 0\n } // Green\n else if (emphasis < 0.75) {\n rFg = 0\n gFg = 0\n bFg = Math.random()\n } // Blue\n else {\n // Bright glitch color\n const glitchColorRoll = Math.random()\n if (glitchColorRoll < 0.33) {\n rFg = 1\n gFg = 0\n bFg = 1\n } // Magenta\n else if (glitchColorRoll < 0.66) {\n rFg = 0\n gFg = 1\n bFg = 1\n } // Cyan\n else {\n rFg = 1\n gFg = 1\n bFg = 0\n } // Yellow\n }\n // Background can be inverted or similar to FG\n if (Math.random() < 0.5) {\n rBg = 1 - rFg\n gBg = 1 - gFg\n bBg = 1 - bFg\n } else {\n rBg = rFg * (Math.random() * 0.5 + 0.2) // Darker shade of fg\n gBg = gFg * (Math.random() * 0.5 + 0.2)\n bBg = bFg * (Math.random() * 0.5 + 0.2)\n }\n } else {\n // Inverted or high contrast\n rFg = Math.random() > 0.5 ? 1 : 0\n gFg = Math.random() > 0.5 ? 1 : 0\n bFg = Math.random() > 0.5 ? 1 : 0\n rBg = 1 - rFg\n gBg = 1 - gFg\n bBg = 1 - bFg\n }\n\n setRgb(buf.fg, destColorIndex, rFg, gFg, bFg)\n setRgb(buf.bg, destColorIndex, rBg, gBg, bBg)\n }\n }\n }\n }\n }\n}\n\n/**\n * Applies a vignette effect by darkening the corners, optimized with precomputation.\n * Uses native colorMatrix with a zero matrix for attenuation.\n */\nexport class VignetteEffect {\n private _strength: number\n // Stores packed cell masks [x, y, attenuation] per pixel\n private precomputedAttenuationCellMask: Float32Array | null = null\n private cachedWidth: number = -1\n private cachedHeight: number = -1\n // Zero matrix for attenuation (maps everything toward black based on strength)\n private static zeroMatrix = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])\n\n constructor(strength: number = 0.5) {\n this._strength = strength\n }\n\n public set strength(newStrength: number) {\n this._strength = Math.max(0, newStrength) // Ensure strength is non-negative\n // Invalidate cached cell masks when strength changes\n this.cachedWidth = -1\n this.cachedHeight = -1\n this.precomputedAttenuationCellMask = null\n }\n\n public get strength(): number {\n return this._strength\n }\n\n private _computeFactors(width: number, height: number): void {\n this.precomputedAttenuationCellMask = new Float32Array(width * height * 3)\n const centerX = width / 2\n const centerY = height / 2\n const maxDistSq = centerX * centerX + centerY * centerY\n const safeMaxDistSq = maxDistSq === 0 ? 1 : maxDistSq // Avoid division by zero\n const strength = this._strength\n let i = 0\n\n for (let y = 0; y < height; y++) {\n const dy = y - centerY\n const dySq = dy * dy\n for (let x = 0; x < width; x++) {\n const dx = x - centerX\n const distSq = dx * dx + dySq\n // Calculate base attenuation (0 to 1 based on distance)\n const baseAttenuation = Math.min(1, distSq / safeMaxDistSq)\n // Precompute final attenuation value including strength\n const attenuation = baseAttenuation * strength\n this.precomputedAttenuationCellMask[i++] = x\n this.precomputedAttenuationCellMask[i++] = y\n this.precomputedAttenuationCellMask[i++] = attenuation\n }\n }\n this.cachedWidth = width\n this.cachedHeight = height\n }\n\n /**\n * Applies the vignette effect using native colorMatrix with a zero matrix.\n * The zero matrix maps all colors to black, and the attenuation cell masks\n * control how much of the effect is applied (strength-based blending).\n */\n public apply(buffer: OptimizedBuffer): void {\n const width = buffer.width\n const height = buffer.height\n\n // Recompute attenuation cell masks if dimensions changed, strength changed,\n // or factors haven't been computed yet\n if (width !== this.cachedWidth || height !== this.cachedHeight || !this.precomputedAttenuationCellMask) {\n this._computeFactors(width, height)\n }\n\n // Use colorMatrix with zero matrix to apply attenuation\n // colorMatrix blends: result = original + (transformed - original) × strength\n // With zero matrix: transformed = 0\n // Result = original + (0 - original) × attenuation = original × (1 - attenuation)\n buffer.colorMatrix(VignetteEffect.zeroMatrix, this.precomputedAttenuationCellMask!, 1.0, 3)\n }\n}\n\n/**\n * Simple Perlin noise implementation for procedural cloud generation.\n * Uses gradient vectors and smooth interpolation.\n */\nclass PerlinNoise {\n private perm: Uint8Array\n private grad3: number[][] = [\n [1, 1, 0],\n [-1, 1, 0],\n [1, -1, 0],\n [-1, -1, 0],\n [1, 0, 1],\n [-1, 0, 1],\n [1, 0, -1],\n [-1, 0, -1],\n [0, 1, 1],\n [0, -1, 1],\n [0, 1, -1],\n [0, -1, -1],\n ]\n\n constructor() {\n // Permutation table for pseudo-random gradient selection\n this.perm = new Uint8Array(512)\n const p = new Uint8Array(256)\n for (let i = 0; i < 256; i++) {\n p[i] = i\n }\n // Shuffle\n for (let i = 255; i > 0; i--) {\n const r = Math.floor(Math.random() * (i + 1))\n ;[p[i], p[r]] = [p[r], p[i]]\n }\n // Duplicate for overflow handling\n for (let i = 0; i < 512; i++) {\n this.perm[i] = p[i & 255]\n }\n }\n\n private dot(g: number[], x: number, y: number, z: number): number {\n return g[0] * x + g[1] * y + g[2] * z\n }\n\n private mix(a: number, b: number, t: number): number {\n return a + (b - a) * t\n }\n\n private fade(t: number): number {\n return t * t * t * (t * (t * 6 - 15) + 10)\n }\n\n /**\n * 3D Perlin noise at coordinates (x, y, z)\n * Returns value in range [-1, 1]\n */\n noise3d(x: number, y: number, z: number): number {\n // Find unit grid cell containing point\n const X = Math.floor(x) & 255\n const Y = Math.floor(y) & 255\n const Z = Math.floor(z) & 255\n\n // Get relative xyz coordinates of point within that cell\n const xf = x - Math.floor(x)\n const yf = y - Math.floor(y)\n const zf = z - Math.floor(z)\n\n // Compute fade curves for each of x, y, z\n const u = this.fade(xf)\n const v = this.fade(yf)\n const w = this.fade(zf)\n\n // Hash coordinates of the 8 cube corners\n const A = this.perm[X] + Y\n const AA = this.perm[A] + Z\n const AB = this.perm[A + 1] + Z\n const B = this.perm[X + 1] + Y\n const BA = this.perm[B] + Z\n const BB = this.perm[B + 1] + Z\n\n // Add blended results from 8 corners of the cube\n let res = this.mix(\n this.mix(\n this.mix(\n this.dot(this.grad3[this.perm[AA] % 12], xf, yf, zf),\n this.dot(this.grad3[this.perm[BA] % 12], xf - 1, yf, zf),\n u,\n ),\n this.mix(\n this.dot(this.grad3[this.perm[AB] % 12], xf, yf - 1, zf),\n this.dot(this.grad3[this.perm[BB] % 12], xf - 1, yf - 1, zf),\n u,\n ),\n v,\n ),\n this.mix(\n this.mix(\n this.dot(this.grad3[this.perm[AA + 1] % 12], xf, yf, zf - 1),\n this.dot(this.grad3[this.perm[BA + 1] % 12], xf - 1, yf, zf - 1),\n u,\n ),\n this.mix(\n this.dot(this.grad3[this.perm[AB + 1] % 12], xf, yf - 1, zf - 1),\n this.dot(this.grad3[this.perm[BB + 1] % 12], xf - 1, yf - 1, zf - 1),\n u,\n ),\n v,\n ),\n w,\n )\n\n return res\n }\n}\n\n/**\n * Applies animated cloud shadows using Perlin noise.\n * Darkens the background buffer based on procedural cloud density.\n */\nexport class CloudsEffect {\n private noise: PerlinNoise\n private _scale: number\n private _speed: number\n private _density: number\n private _darkness: number\n private time: number = 0\n\n constructor(scale: number = 0.02, speed: number = 0.5, density: number = 0.6, darkness: number = 0.7) {\n this.noise = new PerlinNoise()\n this._scale = scale\n this._speed = speed\n this._density = density\n this._darkness = darkness\n }\n\n public set scale(newScale: number) {\n this._scale = Math.max(0.001, newScale)\n }\n public get scale(): number {\n return this._scale\n }\n\n public set speed(newSpeed: number) {\n this._speed = Math.max(0, newSpeed)\n }\n public get speed(): number {\n return this._speed\n }\n\n public set density(newDensity: number) {\n this._density = Math.max(0, Math.min(1, newDensity))\n }\n public get density(): number {\n return this._density\n }\n\n public set darkness(newDarkness: number) {\n this._darkness = Math.max(0, Math.min(1, newDarkness))\n }\n public get darkness(): number {\n return this._darkness\n }\n\n /**\n * Applies cloud shadow effect using Perlin noise mask with native colorMatrix.\n * Uses FBM (Fractal Brownian Motion) for detailed clouds, offloaded to native code.\n */\n public apply(buffer: OptimizedBuffer, deltaTime: number): void {\n const width = buffer.width\n const height = buffer.height\n\n // Update time for animation\n this.time += deltaTime * this._speed\n\n const scale = this._scale\n const timeOffset = this.time\n\n // Build cell mask with per-pixel attenuation values\n // Format: [x, y, attenuation] for each pixel\n const cellMask = new Float32Array(width * height * 3)\n let maskIdx = 0\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n // FBM - combine multiple octaves for detail\n let noiseValue = 0\n let amplitude = 1\n let frequency = 1\n let maxValue = 0\n\n // 4 octaves of noise\n for (let i = 0; i < 4; i++) {\n const nx = (x * scale * frequency + timeOffset) * 0.5\n const ny = y * scale * frequency * 0.5\n const nz = timeOffset * 0.3 // Use time as z for evolution\n\n noiseValue += this.noise.noise3d(nx, ny, nz) * amplitude\n maxValue += amplitude\n amplitude *= 0.5\n frequency *= 2\n }\n\n // Normalize to [0, 1]\n noiseValue = (noiseValue / maxValue + 1) * 0.5\n\n // Apply density threshold - lower density = more clouds\n const cloudDensity = Math.max(0, noiseValue - (1 - this._density))\n\n // Scale to actual darkness (0 = no change, 1 = full darkness)\n const attenuation = cloudDensity * this._darkness\n\n // Add to cell mask\n cellMask[maskIdx++] = x\n cellMask[maskIdx++] = y\n cellMask[maskIdx++] = attenuation\n }\n }\n\n // Use native colorMatrix with zero matrix to apply attenuation\n // Zero matrix: transformed = 0 (black)\n // Result = original + (0 - original) × attenuation = original × (1 - attenuation)\n const zeroMatrix = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])\n buffer.colorMatrix(zeroMatrix, cellMask, 1.0, 2) // target = 2 (background only)\n }\n}\n\n/**\n * Applies animated flames rising from the bottom using Perlin noise.\n * Creates warm fire effect that fades as it rises.\n */\nexport class FlamesEffect {\n private noise: PerlinNoise\n private _scale: number\n private _speed: number\n private _intensity: number\n private time: number = 0\n\n constructor(scale: number = 0.03, speed: number = 0.02, intensity: number = 0.8) {\n this.noise = new PerlinNoise()\n this._scale = scale\n this._speed = speed\n this._intensity = intensity\n }\n\n public set scale(newScale: number) {\n this._scale = Math.max(0.001, newScale)\n }\n public get scale(): number {\n return this._scale\n }\n\n public set speed(newSpeed: number) {\n this._speed = Math.max(0, newSpeed)\n }\n public get speed(): number {\n return this._speed\n }\n\n public set intensity(newIntensity: number) {\n this._intensity = Math.max(0, Math.min(1, newIntensity))\n }\n public get intensity(): number {\n return this._intensity\n }\n\n /**\n * Applies flame effect rising from bottom using Perlin noise.\n * Flames get cooler (redder) and fade as they rise.\n */\n public apply(buffer: OptimizedBuffer, deltaTime: number): void {\n const width = buffer.width\n const height = buffer.height\n const bg = buffer.buffers.bg\n\n // Update time for animation\n this.time += deltaTime * this._speed\n\n const scale = this._scale\n const timeOffset = this.time\n\n for (let y = 0; y < height; y++) {\n // Calculate height factor - stronger at bottom (1.0), fading toward top (0.0)\n const heightFactor = 1.0 - y / height\n\n for (let x = 0; x < width; x++) {\n // FBM - combine multiple octaves for organic flame detail\n let noiseValue = 0\n let amplitude = 1\n let frequency = 1\n let maxValue = 0\n\n // 3 octaves of noise for flames\n for (let i = 0; i < 3; i++) {\n // Flip y coordinate so flames rise from bottom\n const nx = (x * scale * frequency + timeOffset) * 0.5\n const ny = (height - y) * scale * frequency * 2 * 0.5\n const nz = timeOffset * 2.0 // Faster z evolution for more flicker\n\n noiseValue += this.noise.noise3d(nx, ny, nz) * amplitude\n maxValue += amplitude\n amplitude *= 0.5\n frequency *= 2\n }\n\n // Normalize to [0, 1]\n noiseValue = (noiseValue / maxValue + 1) * 0.5\n\n // Combine with height factor for rising fade effect\n const flameIntensity = noiseValue * heightFactor * this._intensity\n\n if (flameIntensity > 0) {\n const colorIndex = (y * width + x) * 4\n\n // Fire color gradient based on intensity\n // High intensity = white/yellow (hottest), low = red (coolest)\n let r: number, g: number, b: number\n\n if (flameIntensity > 0.7) {\n // White/yellow hot core\n r = 1.0\n g = 1.0\n b = 0.3 + (flameIntensity - 0.7) * 2.3 // 0.3 to 1.0\n } else if (flameIntensity > 0.4) {\n // Orange\n r = 1.0\n g = 0.5 + (flameIntensity - 0.4) * 1.67 // 0.5 to 1.0\n b = 0.0\n } else {\n // Red fading to dark\n r = 0.3 + flameIntensity * 1.75 // 0.3 to 1.0\n g = flameIntensity * 0.5 // 0.0 to 0.2\n b = 0.0\n }\n\n // Blend with existing background\n setRgb(\n bg,\n colorIndex,\n Math.max(channel(bg, colorIndex), r * flameIntensity),\n Math.max(channel(bg, colorIndex + 1), g * flameIntensity),\n Math.max(channel(bg, colorIndex + 2), b * flameIntensity),\n )\n }\n }\n }\n }\n}\n\n/**\n * Applies a CRT rolling bar effect - a horizontal bar that slowly scans down the screen.\n * Simulates the classic CRT monitor rolling bar artifact.\n */\nexport class CRTRollingBarEffect {\n private _speed: number\n private _height: number\n private _intensity: number\n private _fadeDistance: number\n private position: number = 0\n\n constructor(speed: number = 0.5, height: number = 0.15, intensity: number = 0.3, fadeDistance: number = 0.3) {\n this._speed = speed\n this._height = Math.max(0.01, Math.min(0.5, height))\n this._intensity = Math.max(0, Math.min(1, intensity))\n this._fadeDistance = Math.max(0, Math.min(1, fadeDistance))\n }\n\n public set speed(newSpeed: number) {\n this._speed = newSpeed\n }\n public get speed(): number {\n return this._speed\n }\n\n public set height(newHeight: number) {\n this._height = Math.max(0.01, Math.min(0.5, newHeight))\n }\n public get height(): number {\n return this._height\n }\n\n public set intensity(newIntensity: number) {\n this._intensity = Math.max(0, Math.min(1, newIntensity))\n }\n public get intensity(): number {\n return this._intensity\n }\n\n public set fadeDistance(newFadeDistance: number) {\n this._fadeDistance = Math.max(0, Math.min(1, newFadeDistance))\n }\n public get fadeDistance(): number {\n return this._fadeDistance\n }\n\n /**\n * Applies the rolling bar effect to the buffer.\n * Creates a smooth horizontal bar that scans down the screen with a bell-curve gradient.\n * The bar has a bright center that smoothly fades to the edges.\n */\n public apply(buffer: OptimizedBuffer, deltaTime: number): void {\n const width = buffer.width\n const height = buffer.height\n const fg = buffer.buffers.fg\n const bg = buffer.buffers.bg\n\n // Update bar position (convert deltaTime from ms to seconds)\n this.position += (deltaTime / 1000) * this._speed\n // Wrap position to keep it rolling continuously\n const cycleHeight = height + this._height * height * 2\n this.position = this.position % cycleHeight\n\n const barPixelHeight = this._height * height\n const fadePixelDistance = this._fadeDistance * barPixelHeight\n const totalEffectHeight = barPixelHeight + fadePixelDistance * 2\n const effectCenter = this.position - totalEffectHeight / 2 + barPixelHeight / 2\n\n for (let y = 0; y < height; y++) {\n // Calculate distance from the bar center\n const distFromCenter = Math.abs(y - effectCenter)\n\n // Create a smooth bell-curve effect\n // Full intensity at center, smooth falloff using Gaussian-like curve\n let barFactor = 0\n\n if (distFromCenter <= totalEffectHeight / 2) {\n // Normalize distance to 0-1 range across the whole effect\n const normalizedDist = distFromCenter / (totalEffectHeight / 2)\n // Cosine falloff: 1 at center, 0 at edge\n // cos(0) = 1, cos(π/2) = 0\n barFactor = Math.cos((normalizedDist * Math.PI) / 2)\n }\n\n if (barFactor > 0.001) {\n const rowMultiplier = 1 + this._intensity * barFactor\n\n for (let x = 0; x < width; x++) {\n const colorIndex = (y * width + x) * 4\n\n // Brighten foreground\n setRgb(\n fg,\n colorIndex,\n Math.min(1, channel(fg, colorIndex) * rowMultiplier),\n Math.min(1, channel(fg, colorIndex + 1) * rowMultiplier),\n Math.min(1, channel(fg, colorIndex + 2) * rowMultiplier),\n )\n\n // Brighten background\n setRgb(\n bg,\n colorIndex,\n Math.min(1, channel(bg, colorIndex) * rowMultiplier),\n Math.min(1, channel(bg, colorIndex + 1) * rowMultiplier),\n Math.min(1, channel(bg, colorIndex + 2) * rowMultiplier),\n )\n }\n }\n }\n }\n}\n\n/**\n * Applies animated rainbow colors to cells with white foreground.\n * Cycles through HSV hue spectrum over time.\n */\nexport class RainbowTextEffect {\n private _speed: number\n private _saturation: number\n private _value: number\n private _repeats: number\n private time: number = 0\n\n constructor(speed: number = 0.01, saturation: number = 1.0, value: number = 1.0, repeats: number = 3.0) {\n this._speed = speed\n this._saturation = saturation\n this._value = value\n this._repeats = repeats\n }\n\n public set speed(newSpeed: number) {\n this._speed = Math.max(0, newSpeed)\n }\n public get speed(): number {\n return this._speed\n }\n\n public set saturation(newSaturation: number) {\n this._saturation = Math.max(0, Math.min(1, newSaturation))\n }\n public get saturation(): number {\n return this._saturation\n }\n\n public set value(newValue: number) {\n this._value = Math.max(0, Math.min(1, newValue))\n }\n public get value(): number {\n return this._value\n }\n\n public set repeats(newRepeats: number) {\n this._repeats = Math.max(0.1, newRepeats)\n }\n public get repeats(): number {\n return this._repeats\n }\n\n /**\n * Converts HSV color to RGB\n * @param h - Hue [0, 1]\n * @param s - Saturation [0, 1]\n * @param v - Value [0, 1]\n * @returns [r, g, b] each in [0, 1]\n */\n private hsvToRgb(h: number, s: number, v: number): [number, number, number] {\n let r = 0,\n g = 0,\n b = 0\n\n const i = Math.floor(h * 6)\n const f = h * 6 - i\n const p = v * (1 - s)\n const q = v * (1 - f * s)\n const t = v * (1 - (1 - f) * s)\n\n switch (i % 6) {\n case 0:\n r = v\n g = t\n b = p\n break\n case 1:\n r = q\n g = v\n b = p\n break\n case 2:\n r = p\n g = v\n b = t\n break\n case 3:\n r = p\n g = q\n b = v\n break\n case 4:\n r = t\n g = p\n b = v\n break\n case 5:\n r = v\n g = p\n b = q\n break\n }\n\n return [r, g, b]\n }\n\n /**\n * Applies rainbow colors to cells with white foreground.\n * White is defined as R, G, B all >= 0.9\n */\n public apply(buffer: OptimizedBuffer, deltaTime: number): void {\n const width = buffer.width\n const height = buffer.height\n const fg = buffer.buffers.fg\n\n // Update time for animation\n this.time += deltaTime * this._speed\n\n const saturation = this._saturation\n const value = this._value\n const repeats = this._repeats\n\n // 25 degree angle for diagonal rainbow\n const angleRad = (25 * Math.PI) / 180\n const cosAngle = Math.cos(angleRad)\n const sinAngle = Math.sin(angleRad)\n\n // Define white threshold\n const whiteThreshold = 0.9\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const colorIndex = (y * width + x) * 4\n\n const r = channel(fg, colorIndex)\n const g = channel(fg, colorIndex + 1)\n const b = channel(fg, colorIndex + 2)\n\n // Check if foreground is white-ish (all components >= threshold)\n if (r >= whiteThreshold && g >= whiteThreshold && b >= whiteThreshold) {\n // Calculate hue based on position projected at 25-degree angle\n // Creates a diagonal moving rainbow wave effect\n const projection = x * cosAngle + y * sinAngle\n const maxProjection = width * cosAngle + height * sinAngle\n const hue = ((projection / maxProjection) * repeats + this.time * 0.1) % 1.0\n\n // Convert HSV to RGB\n const [newR, newG, newB] = this.hsvToRgb(hue, saturation, value)\n\n setRgb(fg, colorIndex, newR, newG, newB)\n }\n }\n }\n }\n}\n", + "import type { OptimizedBuffer } from \"../buffer.js\"\n\nfunction toU8(value: number): number {\n return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255)\n}\n\nfunction channel(buffer: Uint16Array, index: number): number {\n return (buffer[index] & 0xff) / 255\n}\n\nfunction setRgb(buffer: Uint16Array, base: number, r: number, g: number, b: number): void {\n const a = buffer[base + 3] & 0xff\n buffer[base] = toU8(r)\n buffer[base + 1] = toU8(g)\n buffer[base + 2] = toU8(b)\n buffer[base + 3] = a\n}\n\n/**\n * Applies a scanline effect by darkening every nth row using native color matrix.\n * Only affects the background buffer to maintain text readability.\n */\nexport function applyScanlines(buffer: OptimizedBuffer, strength: number = 0.8, step: number = 2): void {\n if (strength === 1.0 || step < 1) return\n\n const width = buffer.width\n const height = buffer.height\n\n // Calculate number of affected rows\n const affectedRows = Math.ceil(height / step)\n const cellCount = width * affectedRows\n const cellMask = new Float32Array(cellCount * 3)\n\n let maskIdx = 0\n for (let y = 0; y < height; y += step) {\n for (let x = 0; x < width; x++) {\n cellMask[maskIdx++] = x\n cellMask[maskIdx++] = y\n cellMask[maskIdx++] = 1.0 // full strength\n }\n }\n\n // Gain matrix to scale down background colors\n const s = strength\n const matrix = new Float32Array([\n s,\n 0,\n 0,\n 0, // Row 0: Red output\n 0,\n s,\n 0,\n 0, // Row 1: Green output\n 0,\n 0,\n s,\n 0, // Row 2: Blue output\n 0,\n 0,\n 0,\n 1, // Row 3: Alpha output (identity)\n ])\n\n // Apply only to background buffer (target = 2)\n buffer.colorMatrix(matrix, cellMask, 1.0, 2)\n}\n\n/**\n * Inverts the colors in the buffer using native color matrix.\n * Uses negative matrix with alpha offset: output = 1.0 - input for each RGB channel.\n */\nexport function applyInvert(buffer: OptimizedBuffer, strength: number = 1.0): void {\n if (strength === 0.0) return\n\n // Invert matrix: output = -1*input + 1*alpha = 1.0 - input (assuming alpha=1.0)\n // Row format: [R_coeff, G_coeff, B_coeff, A_coeff]\n const matrix = new Float32Array([\n -1,\n 0,\n 0,\n 1, // Row 0: Red output = -1*R + 0*G + 0*B + 1*A = 1 - R\n 0,\n -1,\n 0,\n 1, // Row 1: Green output = 1 - G\n 0,\n 0,\n -1,\n 1, // Row 2: Blue output = 1 - B\n 0,\n 0,\n 0,\n 1, // Row 3: Alpha output = A\n ])\n\n buffer.colorMatrixUniform(matrix, strength, 3)\n}\n\n/**\n * Adds random noise to the buffer colors using colorMatrix with brightness matrix.\n * Uses per-pixel random strength values to dim/brighten each cell.\n */\nexport function applyNoise(buffer: OptimizedBuffer, strength: number = 0.1): void {\n const width = buffer.width\n const height = buffer.height\n const size = width * height\n\n // Skip if no effect\n if (strength === 0) return\n\n // Generate random cellMask with per-pixel strength values\n // Each pixel gets [x, y, random_strength] where random_strength ranges from -1 to 1\n const cellMask = new Float32Array(size * 3)\n let cellMaskIndex = 0\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n cellMask[cellMaskIndex++] = x\n cellMask[cellMaskIndex++] = y\n // Random strength from -1 to 1\n cellMask[cellMaskIndex++] = (Math.random() - 0.5) * 2\n }\n }\n\n // Brightness matrix: scales all channels by (1 + strength)\n // With cellMask strength S, result = original * (1 + (B - 1) * S)\n // where B = 1 + strength\n // So: S=1 → original * (1 + strength), S=-1 → original * (1 - strength)\n const b = 1.0 + strength\n const matrix = new Float32Array([\n b,\n 0,\n 0,\n 0, // Row 0 (Red output)\n 0,\n b,\n 0,\n 0, // Row 1 (Green output)\n 0,\n 0,\n b,\n 0, // Row 2 (Blue output)\n 0,\n 0,\n 0,\n 1, // Row 3 (Alpha output - identity)\n ])\n\n buffer.colorMatrix(matrix, cellMask, 1.0, 3)\n}\n\n/**\n * Applies a simplified chromatic aberration effect.\n */\nexport function applyChromaticAberration(buffer: OptimizedBuffer, strength: number = 1): void {\n const width = buffer.width\n const height = buffer.height\n const srcFg = Uint16Array.from(buffer.buffers.fg) // Copy original fg data\n const destFg = buffer.buffers.fg\n const centerX = width / 2\n const centerY = height / 2\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = x - centerX\n const dy = y - centerY\n const offset = Math.round((Math.sqrt(dx * dx + dy * dy) / Math.max(centerX, centerY)) * strength)\n\n const rX = Math.max(0, Math.min(width - 1, x - offset))\n const bX = Math.max(0, Math.min(width - 1, x + offset))\n\n const rIndex = (y * width + rX) * 4\n const gIndex = (y * width + x) * 4 // Green from original position\n const bIndex = (y * width + bX) * 4\n const destIndex = (y * width + x) * 4\n\n setRgb(destFg, destIndex, channel(srcFg, rIndex), channel(srcFg, gIndex + 1), channel(srcFg, bIndex + 2))\n }\n }\n}\n\n/**\n * Converts the buffer to ASCII art based on background brightness.\n * Uses native colorMatrix for efficient color corrections.\n */\nexport function applyAsciiArt(\n buffer: OptimizedBuffer,\n ramp: string = ' .\\'`^\"\",:;Il!i><~+_-?][}{1)(|\\\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$',\n fgColor: { r: number; g: number; b: number } = { r: 1.0, g: 1.0, b: 1.0 },\n bgColor: { r: number; g: number; b: number } = { r: 0.0, g: 0.0, b: 0.0 },\n): void {\n const width = buffer.width\n const height = buffer.height\n const chars = buffer.buffers.char\n const bg = buffer.buffers.bg\n const rampLength = ramp.length\n\n // Set ASCII characters based on background luminance\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const index = y * width + x\n const colorIndex = index * 4\n const bgR = channel(bg, colorIndex)\n const bgG = channel(bg, colorIndex + 1)\n const bgB = channel(bg, colorIndex + 2)\n const lum = 0.299 * bgR + 0.587 * bgG + 0.114 * bgB // Luminance\n const rampIndex = Math.min(rampLength - 1, Math.floor(lum * rampLength))\n chars[index] = ramp[rampIndex].charCodeAt(0)\n }\n }\n\n // Create color matrix that sets all pixels to the target color\n // Matrix: output = target_color * input (where input is 1.0 from alpha)\n const fgMatrix = new Float32Array([\n 0,\n 0,\n 0,\n fgColor.r, // Red output\n 0,\n 0,\n 0,\n fgColor.g, // Green output\n 0,\n 0,\n 0,\n fgColor.b, // Blue output\n 0,\n 0,\n 0,\n 1, // Alpha output (identity)\n ])\n\n const bgMatrix = new Float32Array([\n 0,\n 0,\n 0,\n bgColor.r, // Red output\n 0,\n 0,\n 0,\n bgColor.g, // Green output\n 0,\n 0,\n 0,\n bgColor.b, // Blue output\n 0,\n 0,\n 0,\n 1, // Alpha output (identity)\n ])\n\n // Apply uniform color transformation to foreground (target = 1)\n buffer.colorMatrixUniform(fgMatrix, 1.0, 1)\n // Apply uniform color transformation to background (target = 2)\n buffer.colorMatrixUniform(bgMatrix, 1.0, 2)\n}\n\n/**\n * Adjusts the brightness of the buffer using color matrix transformation.\n * Brightness adds the brightness value to all RGB channels (additive brightness).\n * If not provided, applies uniform brightness to entire buffer.\n */\nexport function applyBrightness(buffer: OptimizedBuffer, brightness: number = 0.0, cellMask?: Float32Array): void {\n // No need to process if brightness is 0 (no change)\n if (brightness === 0.0) return\n\n const b = brightness\n // Additive brightness matrix: adds brightness to all channels via alpha column\n const matrix = new Float32Array([\n 1,\n 0,\n 0,\n b, // Row 0 (Red output = R + brightness*A)\n 0,\n 1,\n 0,\n b, // Row 1 (Green output = G + brightness*A)\n 0,\n 0,\n 1,\n b, // Row 2 (Blue output = B + brightness*A)\n 0,\n 0,\n 0,\n 1, // Row 3 (Alpha output = A)\n ])\n\n if (!cellMask || cellMask.length === 0) {\n buffer.colorMatrixUniform(matrix, 1.0, 3)\n } else {\n buffer.colorMatrix(matrix, cellMask, 1.0, 3)\n }\n}\n\n/**\n * Adjusts the gain of the buffer using color matrix transformation.\n * Gain multiplies all RGB channels by the gain factor (no clamping).\n * If not provided, applies uniform gain to entire buffer.\n */\nexport function applyGain(buffer: OptimizedBuffer, gain: number = 1.0, cellMask?: Float32Array): void {\n // No need to process if gain is 1 (no change)\n if (gain === 1.0) return\n\n const g = Math.max(0, gain)\n const matrix = new Float32Array([\n g,\n 0,\n 0,\n 0, // Row 0 (Red output)\n 0,\n g,\n 0,\n 0, // Row 1 (Green output)\n 0,\n 0,\n g,\n 0, // Row 2 (Blue output)\n 0,\n 0,\n 0,\n 1, // Row 3 (Alpha output - identity)\n ])\n\n if (!cellMask || cellMask.length === 0) {\n buffer.colorMatrixUniform(matrix, 1.0, 3)\n } else {\n buffer.colorMatrix(matrix, cellMask, 1.0, 3)\n }\n}\n\n/**\n * Generates a saturation color matrix (4x4 RGBA with alpha identity).\n */\nfunction createSaturationMatrix(saturation: number): Float32Array {\n const s = Math.max(0, saturation)\n const sr = 0.299 * (1 - s)\n const sg = 0.587 * (1 - s)\n const sb = 0.114 * (1 - s)\n\n // Row 0 (Red output)\n const m00 = sr + s // 0.299 + 0.701*s\n const m01 = sg // 0.587 * (1 - s)\n const m02 = sb // 0.114 * (1 - s)\n\n // Row 1 (Green output)\n const m10 = sr // 0.299 * (1 - s)\n const m11 = sg + s // 0.587 + 0.413*s\n const m12 = sb // 0.114 * (1 - s)\n\n // Row 2 (Blue output)\n const m20 = sr // 0.299 * (1 - s)\n const m21 = sg // 0.587 * (1 - s)\n const m22 = sb + s // 0.114 + 0.886*s\n\n // 4x4 matrix with alpha identity\n return new Float32Array([\n m00,\n m01,\n m02,\n 0, // Red output row\n m10,\n m11,\n m12,\n 0, // Green output row\n m20,\n m21,\n m22,\n 0, // Blue output row\n 0,\n 0,\n 0,\n 1, // Alpha output row (identity)\n ])\n}\n\n/**\n * Applies a saturation adjustment to the buffer.\n */\nexport function applySaturation(buffer: OptimizedBuffer, cellMask?: Float32Array, strength: number = 1.0): void {\n // No need to process if saturation is 1 (no change) or strength is 0\n if (strength === 1.0 || strength === 0) {\n return\n }\n\n const matrix = createSaturationMatrix(strength)\n\n // If no cellMask provided, use uniform saturation (much faster)\n if (!cellMask || cellMask.length === 0) {\n buffer.colorMatrixUniform(matrix, 1.0, 3)\n } else {\n buffer.colorMatrix(matrix, cellMask, 1.0, 3)\n }\n}\n\n/**\n * Applies a bloom effect based on bright areas (Simplified).\n */\nexport class BloomEffect {\n private _threshold: number\n private _strength: number\n private _radius: number\n\n constructor(threshold: number = 0.8, strength: number = 0.2, radius: number = 2) {\n this._threshold = Math.max(0, Math.min(1, threshold))\n this._strength = Math.max(0, strength)\n this._radius = Math.max(0, Math.round(radius))\n }\n\n public set threshold(newThreshold: number) {\n this._threshold = Math.max(0, Math.min(1, newThreshold))\n }\n public get threshold(): number {\n return this._threshold\n }\n\n public set strength(newStrength: number) {\n this._strength = Math.max(0, newStrength)\n }\n public get strength(): number {\n return this._strength\n }\n\n public set radius(newRadius: number) {\n this._radius = Math.max(0, Math.round(newRadius))\n }\n public get radius(): number {\n return this._radius\n }\n\n public apply(buffer: OptimizedBuffer): void {\n const threshold = this._threshold\n const strength = this._strength\n const radius = this._radius\n\n if (strength <= 0 || radius <= 0) return // No bloom if strength or radius is non-positive\n\n const width = buffer.width\n const height = buffer.height\n // Operate directly on the buffer's data for bloom, but need a source copy temporarily\n const srcFg = Uint16Array.from(buffer.buffers.fg)\n const srcBg = Uint16Array.from(buffer.buffers.bg)\n const destFg = buffer.buffers.fg\n const destBg = buffer.buffers.bg\n\n const brightPixels: { x: number; y: number; intensity: number }[] = []\n\n // 1. Find bright pixels based on original data\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const index = (y * width + x) * 4\n // Consider max component brightness, or luminance? Using luminance.\n const fgLum =\n 0.299 * channel(srcFg, index) + 0.587 * channel(srcFg, index + 1) + 0.114 * channel(srcFg, index + 2)\n const bgLum =\n 0.299 * channel(srcBg, index) + 0.587 * channel(srcBg, index + 1) + 0.114 * channel(srcBg, index + 2)\n const lum = Math.max(fgLum, bgLum)\n if (lum > threshold) {\n const intensity = (lum - threshold) / (1 - threshold + 1e-6) // Add epsilon to avoid div by zero\n brightPixels.push({ x, y, intensity: Math.max(0, intensity) })\n }\n }\n }\n\n // If no bright pixels found, exit early\n if (brightPixels.length === 0) return\n\n // Initialize destination buffers by copying original state before applying bloom\n // This prevents bloom from compounding on itself within one frame pass\n destFg.set(srcFg)\n destBg.set(srcBg)\n\n // 2. Apply bloom spread from bright pixels onto the destination buffers\n for (const bright of brightPixels) {\n for (let ky = -radius; ky <= radius; ky++) {\n for (let kx = -radius; kx <= radius; kx++) {\n if (kx === 0 && ky === 0) continue // Don't bloom self\n\n const sampleX = bright.x + kx\n const sampleY = bright.y + ky\n\n if (sampleX >= 0 && sampleX < width && sampleY >= 0 && sampleY < height) {\n const distSq = kx * kx + ky * ky // Use squared distance for falloff calculation\n const radiusSq = radius * radius\n if (distSq <= radiusSq) {\n // Simple linear falloff based on squared distance\n const falloff = 1 - distSq / radiusSq\n const bloomAmount = bright.intensity * strength * falloff\n const destIndex = (sampleY * width + sampleX) * 4\n\n // Add bloom to both fg and bg, clamping at 1.0\n setRgb(\n destFg,\n destIndex,\n Math.min(1.0, channel(destFg, destIndex) + bloomAmount),\n Math.min(1.0, channel(destFg, destIndex + 1) + bloomAmount),\n Math.min(1.0, channel(destFg, destIndex + 2) + bloomAmount),\n )\n\n setRgb(\n destBg,\n destIndex,\n Math.min(1.0, channel(destBg, destIndex) + bloomAmount),\n Math.min(1.0, channel(destBg, destIndex + 1) + bloomAmount),\n Math.min(1.0, channel(destBg, destIndex + 2) + bloomAmount),\n )\n }\n }\n }\n }\n }\n }\n}\n", + "// Standard sepia transformation matrix (4x4 RGBA with alpha identity)\nexport const SEPIA_MATRIX = new Float32Array([\n 0.393,\n 0.769,\n 0.189,\n 0, // Red output (r->r, g->r, b->r, a->r)\n 0.349,\n 0.686,\n 0.168,\n 0, // Green output (r->g, g->g, b->g, a->g)\n 0.272,\n 0.534,\n 0.131,\n 0, // Blue output (r->b, g->b, b->b, a->b)\n 0,\n 0,\n 0,\n 1, // Alpha output (r->a, g->a, b->a, a->a) - identity\n])\n\n/**\n * Colorblindness simulation and compensation filters using color matrix transformations.\n */\n\n// Protanopia (Red-blind) simulation matrix - shows how colors appear to someone with red-blindness\nexport const PROTANOPIA_SIM_MATRIX = new Float32Array([\n 0.567,\n 0.433,\n 0.0,\n 0, // Red output\n 0.558,\n 0.442,\n 0.0,\n 0, // Green output\n 0.0,\n 0.242,\n 0.758,\n 0, // Blue output\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Deuteranopia (Green-blind) simulation matrix - shows how colors appear to someone with green-blindness\nexport const DEUTERANOPIA_SIM_MATRIX = new Float32Array([\n 0.625,\n 0.375,\n 0.0,\n 0, // Red output\n 0.7,\n 0.3,\n 0.0,\n 0, // Green output\n 0.0,\n 0.3,\n 0.7,\n 0, // Blue output\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Tritanopia (Blue-blind) simulation matrix - shows how colors appear to someone with blue-blindness\nexport const TRITANOPIA_SIM_MATRIX = new Float32Array([\n 0.95,\n 0.05,\n 0.0,\n 0, // Red output\n 0.0,\n 0.433,\n 0.567,\n 0, // Green output\n 0.0,\n 0.475,\n 0.525,\n 0, // Blue output\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Achromatopsia (Complete color blindness) - grayscale\nexport const ACHROMATOPSIA_MATRIX = new Float32Array([\n 0.299,\n 0.587,\n 0.114,\n 0, // Red output (luminance)\n 0.299,\n 0.587,\n 0.114,\n 0, // Green output (luminance)\n 0.299,\n 0.587,\n 0.114,\n 0, // Blue output (luminance)\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Protanopia compensation matrix - shifts colors to make them more distinguishable\nexport const PROTANOPIA_COMP_MATRIX = new Float32Array([\n 1.0,\n 0.2,\n 0.0,\n 0, // Boost red channel\n 0.0,\n 0.9,\n 0.1,\n 0, // Adjust green\n 0.0,\n 0.1,\n 0.9,\n 0, // Enhance blue\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Deuteranopia compensation matrix - shifts colors to make them more distinguishable\nexport const DEUTERANOPIA_COMP_MATRIX = new Float32Array([\n 0.9,\n 0.1,\n 0.0,\n 0, // Adjust red\n 0.2,\n 0.8,\n 0.0,\n 0, // Boost green channel\n 0.0,\n 0.0,\n 1.0,\n 0, // Keep blue\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Tritanopia compensation matrix - shifts colors to make them more distinguishable\nexport const TRITANOPIA_COMP_MATRIX = new Float32Array([\n 1.0,\n 0.0,\n 0.0,\n 0, // Keep red\n 0.0,\n 0.9,\n 0.1,\n 0, // Adjust green\n 0.1,\n 0.0,\n 0.9,\n 0, // Boost blue channel\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n/**\n * Creative color effect matrices.\n */\n\n// Technicolor effect - enhances reds and greens for a vintage Hollywood look\nexport const TECHNICOLOR_MATRIX = new Float32Array([\n 1.5,\n -0.2,\n -0.3,\n 0, // Red output - boosted with reduced green/blue influence\n -0.3,\n 1.4,\n -0.1,\n 0, // Green output - boosted with reduced red/blue influence\n -0.2,\n -0.2,\n 1.4,\n 0, // Blue output - slightly boosted\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Solarization effect - partial negative that creates a surreal look\n// Inverts blue channel strongly, partially inverts others\nexport const SOLARIZATION_MATRIX = new Float32Array([\n -0.5,\n 0.5,\n 0.5,\n 0, // Red output - partial negative\n 0.5,\n -0.5,\n 0.5,\n 0, // Green output - partial negative\n 0.5,\n 0.5,\n -0.5,\n 0, // Blue output - partial negative\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Synthwave effect - eliminates green and shifts red toward magenta for that retro neon aesthetic\nexport const SYNTHWAVE_MATRIX = new Float32Array([\n 1.0,\n 0.0,\n 0.25,\n 0, // Red output - full red + some blue = magenta when bright\n 0.1,\n 0.1,\n 0.1,\n 0, // Green output - heavily suppressed, minimal contribution\n 0.25,\n 0.0,\n 1.0,\n 0, // Blue output - full blue + some red = enhances magenta tones\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Greenscale effect - converts image to monochrome green by mapping luminance to green channel only\nexport const GREENSCALE_MATRIX = new Float32Array([\n 0,\n 0,\n 0,\n 0, // Red output - zeroed out\n 0.299,\n 0.587,\n 0.114,\n 0, // Green output - full luminance from all channels\n 0,\n 0,\n 0,\n 0, // Blue output - zeroed out\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Grayscale effect - converts image to monochrome gray using luminance weights\nexport const GRAYSCALE_MATRIX = new Float32Array([\n 0.299,\n 0.587,\n 0.114,\n 0, // Red output - luminance from all channels\n 0.299,\n 0.587,\n 0.114,\n 0, // Green output - luminance from all channels\n 0.299,\n 0.587,\n 0.114,\n 0, // Blue output - luminance from all channels\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n\n// Invert effect - inverts all color channels (photographic negative)\nexport const INVERT_MATRIX = new Float32Array([\n -1,\n 0,\n 0,\n 1, // Red output = 1 - R\n 0,\n -1,\n 0,\n 1, // Green output = 1 - G\n 0,\n 0,\n -1,\n 1, // Blue output = 1 - B\n 0,\n 0,\n 0,\n 1, // Alpha output - identity\n])\n", + "import type { CliRenderer } from \"../renderer.js\"\n\nexport interface TimelineOptions {\n duration?: number\n loop?: boolean\n autoplay?: boolean\n onComplete?: () => void\n onPause?: () => void\n}\n\nexport interface AnimationOptions {\n duration: number\n ease?: EasingFunctions\n onUpdate?: (animation: JSAnimation) => void\n onComplete?: () => void\n onStart?: () => void\n onLoop?: () => void\n loop?: boolean | number\n loopDelay?: number\n alternate?: boolean\n once?: boolean\n [key: string]: any\n}\n\nexport interface JSAnimation {\n targets: any[]\n deltaTime: number\n progress: number\n currentTime: number\n}\n\ninterface TimelineItem {\n type: \"animation\" | \"callback\" | \"timeline\"\n startTime: number\n}\n\ninterface TimelineTimelineItem extends TimelineItem {\n type: \"timeline\"\n timeline: Timeline\n timelineStarted?: boolean\n}\n\ninterface TimelineCallbackItem extends TimelineItem {\n type: \"callback\"\n callback: () => void\n executed: boolean\n}\n\ninterface TimelineAnimationItem extends TimelineItem {\n type: \"animation\"\n\n target: any[]\n properties?: Record\n initialValues?: Record[]\n duration?: number\n ease?: keyof typeof easingFunctions\n loop?: boolean | number\n loopDelay?: number\n alternate?: boolean\n onUpdate?: (animation: JSAnimation) => void\n onComplete?: () => void\n onStart?: () => void\n onLoop?: () => void\n completed?: boolean\n started?: boolean\n currentLoop?: number\n once?: boolean\n}\n\nexport type EasingFunctions = keyof typeof easingFunctions\n\nconst easingFunctions = {\n linear: (t: number) => t,\n inQuad: (t: number) => t * t,\n outQuad: (t: number) => t * (2 - t),\n inOutQuad: (t: number) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),\n inExpo: (t: number) => (t === 0 ? 0 : Math.pow(2, 10 * (t - 1))),\n outExpo: (t: number) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)),\n inOutSine: (t: number) => -(Math.cos(Math.PI * t) - 1) / 2,\n outBounce: (t: number) => {\n const n1 = 7.5625\n const d1 = 2.75\n if (t < 1 / d1) {\n return n1 * t * t\n } else if (t < 2 / d1) {\n return n1 * (t -= 1.5 / d1) * t + 0.75\n } else if (t < 2.5 / d1) {\n return n1 * (t -= 2.25 / d1) * t + 0.9375\n } else {\n return n1 * (t -= 2.625 / d1) * t + 0.984375\n }\n },\n outElastic: (t: number) => {\n const c4 = (2 * Math.PI) / 3\n return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1\n },\n inBounce: (t: number) => 1 - easingFunctions.outBounce(1 - t),\n inCirc: (t: number) => 1 - Math.sqrt(1 - t * t),\n outCirc: (t: number) => Math.sqrt(1 - Math.pow(t - 1, 2)),\n inOutCirc: (t: number) => {\n if ((t *= 2) < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1)\n return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1)\n },\n inBack: (t: number, s: number = 1.70158) => t * t * ((s + 1) * t - s),\n outBack: (t: number, s: number = 1.70158) => --t * t * ((s + 1) * t + s) + 1,\n inOutBack: (t: number, s: number = 1.70158) => {\n s *= 1.525\n if ((t *= 2) < 1) return 0.5 * (t * t * ((s + 1) * t - s))\n return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2)\n },\n}\n\nfunction captureInitialValues(item: TimelineAnimationItem): void {\n if (!item.properties) return\n if (!item.initialValues || item.initialValues.length === 0) {\n const initialValues: Record[] = []\n\n for (let i = 0; i < item.target.length; i++) {\n const target = item.target[i]\n const targetInitialValues: Record = {}\n\n for (const key of Object.keys(item.properties)) {\n if (typeof target[key] === \"number\") {\n targetInitialValues[key] = target[key]\n }\n }\n\n initialValues.push(targetInitialValues)\n }\n\n item.initialValues = initialValues\n }\n}\n\nfunction applyAnimationAtProgress(\n item: TimelineAnimationItem,\n progress: number,\n reversed: boolean,\n timelineTime: number,\n deltaTime: number = 0,\n): void {\n if (!item.properties || !item.initialValues) return\n\n const easingFn = easingFunctions[item.ease || \"linear\"] || easingFunctions.linear\n const easedProgress = easingFn(Math.max(0, Math.min(1, progress)))\n const finalProgress = reversed ? 1 - easedProgress : easedProgress\n\n for (let i = 0; i < item.target.length; i++) {\n const target = item.target[i]\n const targetInitialValues = item.initialValues[i]\n\n if (!targetInitialValues) continue\n\n for (const [key, endValue] of Object.entries(item.properties)) {\n const startValue = targetInitialValues[key]\n const newValue = startValue + (endValue - startValue) * finalProgress\n target[key] = newValue\n }\n }\n\n if (item.onUpdate) {\n const animation: JSAnimation = {\n targets: item.target,\n progress: easedProgress,\n currentTime: timelineTime,\n deltaTime: deltaTime,\n }\n item.onUpdate(animation)\n }\n}\n\nfunction evaluateAnimation(item: TimelineAnimationItem, timelineTime: number, deltaTime: number = 0): void {\n if (timelineTime < item.startTime) {\n return\n }\n\n const animationTime = timelineTime - item.startTime\n const duration = item.duration || 0\n\n if (timelineTime >= item.startTime && !item.started) {\n captureInitialValues(item)\n if (item.onStart) {\n item.onStart()\n }\n item.started = true\n }\n\n if (duration === 0) {\n if (!item.completed) {\n applyAnimationAtProgress(item, 1, false, timelineTime, deltaTime)\n if (item.onComplete) {\n item.onComplete()\n }\n item.completed = true\n }\n return\n }\n\n // Unified looping logic - single execution is just maxLoops = 1\n const maxLoops = !item.loop || item.loop === 1 ? 1 : typeof item.loop === \"number\" ? item.loop : Infinity\n const loopDelay = item.loopDelay || 0\n const cycleTime = duration + loopDelay\n let currentCycle = Math.floor(animationTime / cycleTime)\n let timeInCycle = animationTime % cycleTime\n\n // Trigger onLoop if a loop cycle (not the final one) completes\n if (item.onLoop && item.currentLoop !== undefined && currentCycle > item.currentLoop && currentCycle < maxLoops) {\n item.onLoop()\n }\n item.currentLoop = currentCycle\n\n // Check if the animation part of the *final loop* has just completed\n if (item.onComplete && !item.completed && currentCycle === maxLoops - 1 && timeInCycle >= duration) {\n const finalLoopReversed = (item.alternate || false) && currentCycle % 2 === 1\n applyAnimationAtProgress(item, 1, finalLoopReversed, timelineTime, deltaTime)\n\n item.onComplete()\n item.completed = true\n return\n }\n\n if (currentCycle >= maxLoops) {\n if (!item.completed) {\n const finalReversed = (item.alternate || false) && (maxLoops - 1) % 2 === 1\n applyAnimationAtProgress(item, 1, finalReversed, timelineTime, deltaTime)\n\n if (item.onComplete) {\n item.onComplete()\n }\n item.completed = true\n }\n return\n }\n\n if (timeInCycle === 0 && animationTime > 0 && currentCycle < maxLoops) {\n currentCycle = currentCycle - 1\n timeInCycle = cycleTime\n }\n\n if (timeInCycle >= duration) {\n const isReversed = (item.alternate || false) && currentCycle % 2 === 1\n applyAnimationAtProgress(item, 1, isReversed, timelineTime, deltaTime)\n return\n }\n\n const progress = timeInCycle / duration\n const isReversed = (item.alternate || false) && currentCycle % 2 === 1\n applyAnimationAtProgress(item, progress, isReversed, timelineTime, deltaTime)\n}\n\nfunction evaluateCallback(item: TimelineCallbackItem, timelineTime: number): void {\n if (!item.executed && timelineTime >= item.startTime && item.callback) {\n item.callback()\n item.executed = true\n }\n}\n\nfunction evaluateTimelineSync(item: TimelineTimelineItem, timelineTime: number, deltaTime: number = 0): void {\n if (!item.timeline) return\n if (timelineTime < item.startTime) {\n return\n }\n\n if (!item.timelineStarted) {\n item.timelineStarted = true\n item.timeline.play()\n\n const overshoot = timelineTime - item.startTime\n item.timeline.update(overshoot)\n return\n }\n\n item.timeline.update(deltaTime)\n}\n\nfunction evaluateItem(item: TimelineItem, timelineTime: number, deltaTime: number = 0): void {\n if (item.type === \"animation\") {\n evaluateAnimation(item as TimelineAnimationItem, timelineTime, deltaTime)\n } else if (item.type === \"callback\") {\n evaluateCallback(item as TimelineCallbackItem, timelineTime)\n }\n}\n\nexport class Timeline {\n public items: (TimelineAnimationItem | TimelineCallbackItem)[] = []\n public subTimelines: TimelineTimelineItem[] = []\n public currentTime: number = 0\n public isPlaying: boolean = false\n public isComplete: boolean = false\n public duration: number\n public loop: boolean\n public synced: boolean = false\n private autoplay: boolean\n private onComplete?: () => void\n private onPause?: () => void\n private stateChangeListeners: ((timeline: Timeline) => void)[] = []\n\n constructor(options: TimelineOptions = {}) {\n this.duration = options.duration || 1000\n this.loop = options.loop === true\n this.autoplay = options.autoplay !== false\n this.onComplete = options.onComplete\n this.onPause = options.onPause\n }\n\n public addStateChangeListener(listener: (timeline: Timeline) => void): void {\n this.stateChangeListeners.push(listener)\n }\n\n public removeStateChangeListener(listener: (timeline: Timeline) => void): void {\n this.stateChangeListeners = this.stateChangeListeners.filter((l) => l !== listener)\n }\n\n private notifyStateChange(): void {\n for (const listener of this.stateChangeListeners) {\n listener(this)\n }\n }\n\n add(target: any, properties: AnimationOptions, startTime: number | string = 0): this {\n const resolvedStartTime = typeof startTime === \"string\" ? 0 : startTime\n\n const animationProperties: Record = {}\n\n // Extract animation properties (don't capture initial values here)\n for (const key in properties) {\n if (\n ![\"duration\", \"ease\", \"onUpdate\", \"onComplete\", \"onStart\", \"onLoop\", \"loop\", \"loopDelay\", \"alternate\"].includes(\n key,\n )\n ) {\n if (typeof properties[key] === \"number\") {\n animationProperties[key] = properties[key]\n }\n }\n }\n\n this.items.push({\n type: \"animation\",\n startTime: resolvedStartTime,\n target: Array.isArray(target) ? target : [target],\n properties: animationProperties,\n initialValues: [], // Will be captured when animation starts\n duration: properties.duration !== undefined ? properties.duration : 1000,\n ease: properties.ease || \"linear\",\n loop: properties.loop,\n loopDelay: properties.loopDelay || 0,\n alternate: properties.alternate || false,\n onUpdate: properties.onUpdate,\n onComplete: properties.onComplete,\n onStart: properties.onStart,\n onLoop: properties.onLoop,\n completed: false,\n started: false,\n currentLoop: 0,\n once: properties.once ?? false,\n })\n\n return this\n }\n\n once(target: any, properties: AnimationOptions): this {\n this.add(\n target,\n {\n ...properties,\n once: true,\n },\n this.currentTime,\n )\n\n return this\n }\n\n call(callback: () => void, startTime: number | string = 0): this {\n const resolvedStartTime = typeof startTime === \"string\" ? 0 : startTime\n\n this.items.push({\n type: \"callback\",\n startTime: resolvedStartTime,\n callback,\n executed: false,\n })\n\n return this\n }\n\n sync(timeline: Timeline, startTime: number = 0): this {\n if (timeline.synced) {\n throw new Error(\"Timeline already synced\")\n }\n this.subTimelines.push({\n type: \"timeline\",\n startTime,\n timeline,\n })\n timeline.synced = true\n\n return this\n }\n\n play(): this {\n if (this.isComplete) {\n return this.restart()\n }\n this.subTimelines.forEach((subTimeline) => {\n if (subTimeline.timelineStarted) {\n subTimeline.timeline.play()\n }\n })\n this.isPlaying = true\n this.notifyStateChange()\n return this\n }\n\n pause(): this {\n this.subTimelines.forEach((subTimeline) => {\n subTimeline.timeline.pause()\n })\n this.isPlaying = false\n if (this.onPause) {\n this.onPause()\n }\n this.notifyStateChange()\n return this\n }\n\n resetItems() {\n this.items.forEach((item) => {\n if (item.type === \"callback\") {\n item.executed = false\n } else if (item.type === \"animation\") {\n item.completed = false\n item.started = false\n item.currentLoop = 0\n }\n })\n this.subTimelines.forEach((subTimeline) => {\n subTimeline.timelineStarted = false\n if (subTimeline.timeline) {\n subTimeline.timeline.restart()\n subTimeline.timeline.pause()\n }\n })\n }\n\n restart(): this {\n this.isComplete = false\n this.currentTime = 0\n this.isPlaying = true\n this.resetItems()\n this.notifyStateChange()\n\n return this\n }\n\n update(deltaTime: number): void {\n for (const subTimeline of this.subTimelines) {\n evaluateTimelineSync(subTimeline, this.currentTime + deltaTime, deltaTime)\n }\n\n if (!this.isPlaying) return\n\n this.currentTime += deltaTime\n\n for (const item of this.items) {\n evaluateItem(item, this.currentTime, deltaTime)\n }\n\n // Remove completed \"once\" items (iterate backwards to avoid index shifting)\n for (let i = this.items.length - 1; i >= 0; i--) {\n const item = this.items[i]\n if (item.type === \"animation\" && item.once && item.completed) {\n this.items.splice(i, 1)\n }\n }\n\n if (this.loop && this.currentTime >= this.duration) {\n const overshoot = this.currentTime % this.duration\n\n this.resetItems()\n this.currentTime = 0\n\n if (overshoot > 0) {\n this.update(overshoot)\n }\n } else if (!this.loop && this.currentTime >= this.duration) {\n this.currentTime = this.duration\n this.isPlaying = false\n this.isComplete = true\n\n if (this.onComplete) {\n this.onComplete()\n }\n this.notifyStateChange()\n }\n }\n}\n\nclass TimelineEngine {\n private timelines: Set = new Set()\n private renderer: CliRenderer | null = null\n private frameCallback: ((deltaTime: number) => Promise) | null = null\n private isLive: boolean = false\n public defaults = {\n frameRate: 60,\n }\n\n attach(renderer: CliRenderer): void {\n if (this.renderer) {\n this.detach()\n }\n\n this.renderer = renderer\n this.frameCallback = async (deltaTime: number) => {\n this.update(deltaTime)\n }\n\n renderer.setFrameCallback(this.frameCallback)\n }\n\n detach(): void {\n if (this.renderer && this.frameCallback) {\n this.renderer.removeFrameCallback(this.frameCallback)\n if (this.isLive) {\n this.renderer.dropLive()\n this.isLive = false\n }\n }\n this.renderer = null\n this.frameCallback = null\n }\n\n private updateLiveState(): void {\n if (!this.renderer) return\n\n const hasRunningTimelines = Array.from(this.timelines).some(\n (timeline) => !timeline.synced && timeline.isPlaying && !timeline.isComplete,\n )\n\n if (hasRunningTimelines && !this.isLive) {\n this.renderer.requestLive()\n this.isLive = true\n } else if (!hasRunningTimelines && this.isLive) {\n this.renderer.dropLive()\n this.isLive = false\n }\n }\n\n private onTimelineStateChange = (timeline: Timeline): void => {\n this.updateLiveState()\n }\n\n register(timeline: Timeline): void {\n if (!this.timelines.has(timeline)) {\n this.timelines.add(timeline)\n timeline.addStateChangeListener(this.onTimelineStateChange)\n this.updateLiveState()\n }\n }\n\n unregister(timeline: Timeline): void {\n if (this.timelines.has(timeline)) {\n this.timelines.delete(timeline)\n timeline.removeStateChangeListener(this.onTimelineStateChange)\n this.updateLiveState()\n }\n }\n\n clear(): void {\n for (const timeline of this.timelines) {\n timeline.removeStateChangeListener(this.onTimelineStateChange)\n }\n this.timelines.clear()\n this.updateLiveState()\n }\n\n update(deltaTime: number): void {\n for (const timeline of this.timelines) {\n if (!timeline.synced) {\n timeline.update(deltaTime)\n }\n }\n }\n}\n\nexport const engine = new TimelineEngine()\n\nexport function createTimeline(options: TimelineOptions = {}): Timeline {\n const timeline = new Timeline(options)\n if (options.autoplay !== false) {\n timeline.play()\n }\n\n engine.register(timeline)\n\n return timeline\n}\n", + "import type { CliRenderer } from \"../renderer.js\"\nimport type {\n Plugin,\n PluginContext,\n PluginErrorEvent,\n PluginErrorReport,\n ResolvedSlotRenderer,\n SlotRenderer,\n} from \"./types.js\"\n\nconst noop = () => {}\nconst DEFAULT_DEBUG_PLUGIN_ERRORS = false\nconst DEFAULT_MAX_PLUGIN_ERRORS = 100\n\nfunction normalizeError(error: unknown): Error {\n if (error instanceof Error) {\n return error\n }\n\n if (typeof error === \"string\") {\n return new Error(error)\n }\n\n return new Error(`Unknown plugin error: ${String(error)}`)\n}\n\nexport interface SlotRegistryOptions {\n onPluginError?: (event: PluginErrorEvent) => void\n debugPluginErrors?: boolean\n maxPluginErrors?: number\n}\n\ninterface RegisteredPlugin {\n plugin: Plugin\n registrationOrder: number\n cachedOrder: number\n cachedId: string\n}\n\nexport class SlotRegistry {\n private plugins: RegisteredPlugin[] = []\n private sortedPluginsCache: RegisteredPlugin[] | null = null\n private listeners: Set<() => void> = new Set()\n private errorListeners: Set<(event: PluginErrorEvent) => void> = new Set()\n private pluginErrors: PluginErrorEvent[] = []\n private registrationOrder = 0\n private batchDepth = 0\n private batchedNotify = false\n private rendererInstance: CliRenderer\n private hostContext: Readonly\n private options: Required> &\n Pick\n\n constructor(renderer: CliRenderer, context: TContext, options: SlotRegistryOptions = {}) {\n this.rendererInstance = renderer\n this.hostContext = context\n this.options = {\n debugPluginErrors: options.debugPluginErrors ?? DEFAULT_DEBUG_PLUGIN_ERRORS,\n maxPluginErrors: options.maxPluginErrors ?? DEFAULT_MAX_PLUGIN_ERRORS,\n onPluginError: options.onPluginError,\n }\n }\n\n public get renderer(): CliRenderer {\n return this.rendererInstance\n }\n\n public get context(): Readonly {\n return this.hostContext\n }\n\n public configure(options: SlotRegistryOptions): void {\n if (\"debugPluginErrors\" in options) {\n this.options.debugPluginErrors = options.debugPluginErrors ?? DEFAULT_DEBUG_PLUGIN_ERRORS\n }\n\n if (\"maxPluginErrors\" in options) {\n this.options.maxPluginErrors = options.maxPluginErrors ?? DEFAULT_MAX_PLUGIN_ERRORS\n }\n\n if (\"onPluginError\" in options) {\n this.options.onPluginError = options.onPluginError\n }\n }\n\n public register(plugin: Plugin): () => void {\n if (this.plugins.some((entry) => entry.plugin.id === plugin.id)) {\n throw new Error(`Plugin with id \"${plugin.id}\" is already registered`)\n }\n\n try {\n plugin.setup?.(this.hostContext, this.rendererInstance)\n } catch (error) {\n this.reportPluginError({\n pluginId: plugin.id,\n phase: \"setup\",\n source: \"registry\",\n error,\n })\n\n return noop\n }\n\n this.plugins.push({\n plugin,\n registrationOrder: this.registrationOrder++,\n cachedOrder: plugin.order ?? 0,\n cachedId: plugin.id,\n })\n\n this.invalidateSortedPluginsCache()\n this.notifyListeners()\n\n return () => {\n this.unregister(plugin.id)\n }\n }\n\n public unregister(id: string): boolean {\n const index = this.plugins.findIndex((entry) => entry.plugin.id === id)\n if (index === -1) {\n return false\n }\n\n const [entry] = this.plugins.splice(index, 1)\n\n this.invalidateSortedPluginsCache()\n\n try {\n entry?.plugin.dispose?.()\n } catch (error) {\n this.reportPluginError({\n pluginId: id,\n phase: \"dispose\",\n source: \"registry\",\n error,\n })\n }\n\n this.notifyListeners()\n\n return true\n }\n\n public updateOrder(id: string, order: number): boolean {\n const entry = this.plugins.find((pluginEntry) => pluginEntry.plugin.id === id)\n if (!entry) {\n return false\n }\n\n if ((entry.plugin.order ?? 0) === order) {\n return true\n }\n\n entry.plugin.order = order\n entry.cachedOrder = order\n this.invalidateSortedPluginsCache()\n this.notifyListeners()\n return true\n }\n\n public clear(): void {\n if (this.plugins.length === 0) {\n return\n }\n\n const plugins = [...this.plugins]\n this.plugins = []\n this.invalidateSortedPluginsCache()\n\n for (const entry of plugins) {\n try {\n entry.plugin.dispose?.()\n } catch (error) {\n this.reportPluginError({\n pluginId: entry.plugin.id,\n phase: \"dispose\",\n source: \"registry\",\n error,\n })\n }\n }\n\n this.notifyListeners()\n }\n\n public subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n public onPluginError(listener: (event: PluginErrorEvent) => void): () => void {\n this.errorListeners.add(listener)\n return () => {\n this.errorListeners.delete(listener)\n }\n }\n\n public batch(run: () => T): T {\n this.batchDepth += 1\n\n try {\n return run()\n } finally {\n this.batchDepth -= 1\n if (this.batchDepth === 0 && this.batchedNotify) {\n this.batchedNotify = false\n this.flushListeners()\n }\n }\n }\n\n public getPluginErrors(): readonly PluginErrorEvent[] {\n return this.pluginErrors\n }\n\n public clearPluginErrors(): void {\n this.pluginErrors = []\n }\n\n public reportPluginError(report: PluginErrorReport): PluginErrorEvent {\n const event: PluginErrorEvent = {\n pluginId: report.pluginId,\n slot: report.slot,\n phase: report.phase,\n source: report.source ?? \"registry\",\n error: normalizeError(report.error),\n timestamp: Date.now(),\n }\n\n this.pluginErrors.push(event)\n if (this.pluginErrors.length > this.options.maxPluginErrors) {\n this.pluginErrors.splice(0, this.pluginErrors.length - this.options.maxPluginErrors)\n }\n\n if (this.options.debugPluginErrors) {\n const slotLabel = event.slot ? ` slot=\"${event.slot}\"` : \"\"\n console.debug(\n `[SlotRegistry][PluginError] plugin=\"${event.pluginId}\" phase=\"${event.phase}\" source=\"${event.source}\"${slotLabel}`,\n )\n console.debug(event.error)\n }\n\n for (const listener of this.errorListeners) {\n try {\n listener(event)\n } catch (error) {\n console.error(\"Error in plugin error listener:\", error)\n }\n }\n\n try {\n this.options.onPluginError?.(event)\n } catch (error) {\n console.error(\"Error in plugin error callback:\", error)\n }\n\n return event\n }\n\n public resolve(slot: K): Array> {\n return this.resolveEntries(slot).map((entry) => entry.renderer)\n }\n\n public resolveEntries(slot: K): Array> {\n const slotRenderers: Array> = []\n\n for (const entry of this.getSortedPlugins()) {\n const renderer = entry.plugin.slots[slot]\n if (renderer) {\n slotRenderers.push({\n id: entry.plugin.id,\n renderer: renderer as SlotRenderer,\n })\n }\n }\n\n return slotRenderers\n }\n\n private getSortedPlugins(): RegisteredPlugin[] {\n this.syncPluginSortMetadata()\n\n if (this.sortedPluginsCache) {\n return this.sortedPluginsCache\n }\n\n this.sortedPluginsCache = [...this.plugins].sort((left, right) => {\n const leftOrder = left.cachedOrder\n const rightOrder = right.cachedOrder\n\n if (leftOrder !== rightOrder) {\n return leftOrder - rightOrder\n }\n\n if (left.registrationOrder !== right.registrationOrder) {\n return left.registrationOrder - right.registrationOrder\n }\n\n return left.cachedId.localeCompare(right.cachedId)\n })\n\n return this.sortedPluginsCache\n }\n\n private syncPluginSortMetadata(): void {\n let hasChanges = false\n\n for (const entry of this.plugins) {\n const nextOrder = entry.plugin.order ?? 0\n const nextId = entry.plugin.id\n\n if (entry.cachedOrder !== nextOrder || entry.cachedId !== nextId) {\n entry.cachedOrder = nextOrder\n entry.cachedId = nextId\n hasChanges = true\n }\n }\n\n if (hasChanges) {\n this.invalidateSortedPluginsCache()\n }\n }\n\n private invalidateSortedPluginsCache(): void {\n this.sortedPluginsCache = null\n }\n\n private notifyListeners(): void {\n if (this.batchDepth > 0) {\n this.batchedNotify = true\n return\n }\n\n this.flushListeners()\n }\n\n private flushListeners(): void {\n for (const listener of this.listeners) {\n try {\n listener()\n } catch (error) {\n console.error(\"Error in slot registry listener:\", error)\n }\n }\n }\n}\n\nconst slotRegistriesByRenderer = new WeakMap>>()\n\nfunction getSlotRegistryStore(renderer: CliRenderer): Map> {\n const existingStore = slotRegistriesByRenderer.get(renderer)\n if (existingStore) {\n return existingStore\n }\n\n const createdStore = new Map>()\n slotRegistriesByRenderer.set(renderer, createdStore)\n\n renderer.once(\"destroy\", () => {\n for (const registry of createdStore.values()) {\n try {\n registry.clear()\n } catch (error) {\n console.error(\"Error disposing slot registry:\", error)\n }\n }\n\n createdStore.clear()\n slotRegistriesByRenderer.delete(renderer)\n })\n\n return createdStore\n}\n\nexport function createSlotRegistry(\n renderer: CliRenderer,\n key: string,\n context: TContext,\n options: SlotRegistryOptions = {},\n): SlotRegistry {\n const store = getSlotRegistryStore(renderer)\n const existing = store.get(key)\n\n if (existing) {\n if (existing.context !== context) {\n throw new Error(\n `createSlotRegistry called with a different context for renderer key \"${key}\". Reuse the original context object.`,\n )\n }\n\n const typedExisting = existing as SlotRegistry\n typedExisting.configure(options)\n return typedExisting\n }\n\n const created = new SlotRegistry(renderer, context, options)\n store.set(key, created as SlotRegistry)\n return created\n}\n", + "import { BaseRenderable, Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport type { CliRenderer } from \"../renderer.js\"\nimport type { RenderContext } from \"../types.js\"\nimport { createSlotRegistry, SlotRegistry, type SlotRegistryOptions } from \"./registry.js\"\nimport type { Plugin, PluginContext, PluginErrorEvent, SlotMode } from \"./types.js\"\n\nexport type CoreSlotMode = SlotMode\n\ntype CoreSlotProps = {\n [K in TSlotName]: TData\n}\n\nexport type CoreSlotRegistry<\n TSlotName extends string,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> = SlotRegistry, TContext>\n\nexport type CoreSlotRenderer<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> = (ctx: Readonly, data: TData) => BaseRenderable\n\nexport interface CoreManagedSlot<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> {\n render: CoreSlotRenderer\n onActivate?: (ctx: Readonly) => void\n onDeactivate?: (ctx: Readonly) => void\n onDispose?: (ctx: Readonly) => void\n}\n\nexport type CoreSlotContribution<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> = CoreSlotRenderer | CoreManagedSlot\n\nexport interface CorePlugin<\n TSlotName extends string,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> {\n id: string\n order?: number\n setup?: (ctx: Readonly, renderer: CliRenderer) => void\n dispose?: () => void\n slots: Partial>>\n}\n\nexport interface CoreResolvedSlotRenderer<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> {\n id: string\n renderer: CoreSlotRenderer\n}\n\ntype FallbackNodes = BaseRenderable | BaseRenderable[] | undefined\n\nexport type CoreSlotFailurePlaceholder = (\n failure: PluginErrorEvent,\n ctx: Readonly,\n) => FallbackNodes\n\ntype CoreSlotOwnership = \"host\" | \"plugin\"\n\ntype WrappedCoreSlotRenderer<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> = ((ctx: Readonly, props: TData) => BaseRenderable) & {\n __coreSlotOwnership?: CoreSlotOwnership\n __coreManagedSlot?: CoreManagedSlot\n}\n\ninterface ResolvedCoreSlotEntry<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> extends CoreResolvedSlotRenderer {\n ownership: CoreSlotOwnership\n managedSlot?: CoreManagedSlot\n}\n\ninterface SlotNodeState<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> {\n nodes: BaseRenderable[]\n ownership: CoreSlotOwnership\n managedSlot?: CoreManagedSlot\n dataRef: TData\n}\n\nfunction isCoreManagedSlot<\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n>(contribution: CoreSlotContribution): contribution is CoreManagedSlot {\n return typeof contribution === \"object\" && contribution !== null && \"render\" in contribution\n}\n\nfunction toCorePlugin<\n TSlotName extends string,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n>(plugin: CorePlugin): Plugin, TContext> {\n const slots: Partial>> = {}\n\n for (const [slotName, contribution] of Object.entries(plugin.slots) as Array<\n [TSlotName, CoreSlotContribution]\n >) {\n const wrappedRenderer: WrappedCoreSlotRenderer = (ctx: Readonly, data: TData) => {\n if (isCoreManagedSlot(contribution)) {\n return contribution.render(ctx, data)\n }\n\n return contribution(ctx, data)\n }\n\n if (isCoreManagedSlot(contribution)) {\n wrappedRenderer.__coreSlotOwnership = \"plugin\"\n wrappedRenderer.__coreManagedSlot = contribution\n } else {\n wrappedRenderer.__coreSlotOwnership = \"host\"\n }\n\n slots[slotName] = wrappedRenderer\n }\n\n return {\n id: plugin.id,\n order: plugin.order,\n setup: plugin.setup,\n dispose: plugin.dispose,\n slots,\n }\n}\n\nfunction asArray(value: FallbackNodes): BaseRenderable[] {\n if (!value) {\n return []\n }\n\n return Array.isArray(value) ? [...value] : [value]\n}\n\nfunction ensureValidNode(node: unknown, pluginId: string, mount: BaseRenderable): asserts node is BaseRenderable {\n if (!node) {\n throw new Error(`Plugin \"${pluginId}\" did not return a renderable node`)\n }\n\n if (typeof (node as { then?: unknown }).then === \"function\") {\n throw new Error(`Plugin \"${pluginId}\" returned an async value. Core slots require synchronous renderers.`)\n }\n\n if (!(node instanceof BaseRenderable)) {\n throw new Error(`Plugin \"${pluginId}\" must return a BaseRenderable`)\n }\n\n if (node === mount) {\n throw new Error(`Plugin \"${pluginId}\" returned the slot mount container as its node`)\n }\n\n if (node.parent && node.parent !== mount) {\n throw new Error(`Plugin \"${pluginId}\" returned a renderable already attached to another parent`)\n }\n}\n\nexport function createCoreSlotRegistry<\n TSlotName extends string,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n>(\n renderer: CliRenderer,\n context: TContext,\n options: SlotRegistryOptions = {},\n): CoreSlotRegistry {\n return createSlotRegistry, TContext>(\n renderer,\n \"core:slot-registry\",\n context,\n options,\n )\n}\n\nexport function registerCorePlugin<\n TSlotName extends string,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n>(registry: CoreSlotRegistry, plugin: CorePlugin): () => void {\n return registry.register(toCorePlugin(plugin))\n}\n\nexport function resolveCoreSlot<\n TSlotName extends string,\n K extends TSlotName,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n>(registry: CoreSlotRegistry, slot: K): Array> {\n return resolveCoreSlotEntries(registry, slot).map((entry) => {\n return {\n id: entry.id,\n renderer: entry.renderer,\n }\n })\n}\n\nfunction resolveCoreSlotEntries<\n TSlotName extends string,\n K extends TSlotName,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n>(registry: CoreSlotRegistry, slot: K): Array> {\n return registry.resolveEntries(slot).map((entry) => {\n const wrappedRenderer = entry.renderer as WrappedCoreSlotRenderer\n\n return {\n id: entry.id,\n renderer: (ctx: Readonly, data: TData) => wrappedRenderer(ctx, data),\n ownership: wrappedRenderer.__coreSlotOwnership ?? \"host\",\n managedSlot: wrappedRenderer.__coreManagedSlot,\n }\n })\n}\n\n// -- SlotRenderable ---------------------------------------------------------\n\nexport interface SlotRenderableOptions<\n TSlotName extends string,\n K extends TSlotName,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> extends RenderableOptions {\n registry: CoreSlotRegistry\n name: K\n data?: TData\n mode?: CoreSlotMode\n fallback?: FallbackNodes | (() => FallbackNodes)\n pluginFailurePlaceholder?: CoreSlotFailurePlaceholder\n}\n\nexport class SlotRenderable<\n TSlotName extends string = string,\n TContext extends PluginContext = PluginContext,\n TData extends object = Record,\n> extends Renderable {\n private _mode: CoreSlotMode\n private _slotRegistry: CoreSlotRegistry\n private _slotName: TSlotName\n private _data: TData\n private _fallbackOption: FallbackNodes | (() => FallbackNodes)\n private _pluginFailurePlaceholder?: CoreSlotFailurePlaceholder\n private _disposed = false\n private _mountedNodes: BaseRenderable[] = []\n private _pluginNodes = new Map>()\n private _activePluginIds = new Set()\n private _fallbackNodes: BaseRenderable[] | null = null\n private _unsubscribe: (() => void) | null = null\n\n constructor(ctx: RenderContext, options: SlotRenderableOptions) {\n super(ctx, options)\n\n this._slotRegistry = options.registry\n this._slotName = options.name\n this._data = options.data ?? ({} as TData)\n this._mode = options.mode ?? \"append\"\n this._fallbackOption = options.fallback\n this._pluginFailurePlaceholder = options.pluginFailurePlaceholder\n\n this._unsubscribe = this._slotRegistry.subscribe(() => this.refresh())\n\n try {\n this.refresh()\n } catch (error) {\n this._cleanupAll()\n throw error\n }\n }\n\n public get mode(): CoreSlotMode {\n return this._mode\n }\n\n public set mode(value: CoreSlotMode) {\n this._mode = value\n this.refresh()\n }\n\n public get data(): TData {\n return this._data\n }\n\n public set data(value: TData) {\n this._data = value\n this.refresh()\n }\n\n public refresh(): void {\n if (this._disposed) {\n return\n }\n\n const allEntries = resolveCoreSlotEntries(this._slotRegistry, this._slotName)\n const activeEntries = this._mode === \"single_winner\" && allEntries.length > 0 ? [allEntries[0]] : allEntries\n const nextActivePluginIds = new Set(activeEntries.map((entry) => entry.id))\n const registeredPluginIds = new Set(allEntries.map((entry) => entry.id))\n\n this._cleanupInactivePluginNodes(nextActivePluginIds, registeredPluginIds)\n\n for (const entry of activeEntries) {\n let state = this._pluginNodes.get(entry.id)\n const shouldRender =\n !state || (state.ownership === \"plugin\" && state.nodes.length === 0) || state.dataRef !== this._data\n\n if (shouldRender) {\n const previousState = state\n\n try {\n const node = entry.renderer(this._slotRegistry.context, this._data)\n ensureValidNode(node, entry.id, this)\n state = {\n nodes: [node],\n ownership: entry.ownership,\n managedSlot: entry.managedSlot ?? state?.managedSlot,\n dataRef: this._data,\n }\n } catch (error) {\n const failure = this._slotRegistry.reportPluginError({\n pluginId: entry.id,\n slot: String(this._slotName),\n phase: \"render\",\n source: \"core\",\n error,\n })\n\n state = {\n nodes: this._resolvePluginFailurePlaceholder(failure),\n ownership: \"host\",\n managedSlot: entry.managedSlot ?? state?.managedSlot,\n dataRef: this._data,\n }\n }\n\n if (previousState) {\n this._cleanupReplacedPluginNodes(previousState, state.nodes)\n }\n\n this._pluginNodes.set(entry.id, state)\n }\n\n if (!this._activePluginIds.has(entry.id)) {\n const activeState = this._pluginNodes.get(entry.id)\n if (activeState) {\n this._callManagedHook(entry.id, activeState.managedSlot, \"onActivate\", \"setup\")\n }\n }\n }\n\n const desiredNodes: BaseRenderable[] = []\n\n if (this._mode === \"append\" || activeEntries.length === 0) {\n desiredNodes.push(...this._ensureFallbackNodes())\n }\n\n for (const entry of activeEntries) {\n const state = this._pluginNodes.get(entry.id)\n if (state) {\n desiredNodes.push(...state.nodes)\n }\n }\n\n if (this._mode !== \"append\" && desiredNodes.length === 0) {\n desiredNodes.push(...this._ensureFallbackNodes())\n }\n\n this._reconcileMountedNodes(desiredNodes)\n this._activePluginIds = nextActivePluginIds\n }\n\n protected override destroySelf(): void {\n this._cleanupAll()\n }\n\n private _cleanupAll(): void {\n if (this._disposed) {\n return\n }\n this._disposed = true\n\n this._unsubscribe?.()\n this._unsubscribe = null\n\n for (const [pluginId, state] of this._pluginNodes) {\n if (this._activePluginIds.has(pluginId)) {\n this._callManagedHook(pluginId, state.managedSlot, \"onDeactivate\", \"dispose\")\n }\n\n this._callManagedHook(pluginId, state.managedSlot, \"onDispose\", \"dispose\")\n\n for (const node of state.nodes) {\n this._detachNodeFromMount(node)\n }\n\n if (state.ownership === \"host\") {\n for (const node of state.nodes) {\n node.destroyRecursively()\n }\n }\n }\n\n this._pluginNodes.clear()\n this._activePluginIds = new Set()\n\n if (this._fallbackNodes) {\n for (const node of this._fallbackNodes) {\n node.destroyRecursively()\n }\n this._fallbackNodes = null\n }\n\n this._mountedNodes = []\n }\n\n private _ensureFallbackNodes(): BaseRenderable[] {\n if (this._fallbackNodes !== null) {\n return this._fallbackNodes\n }\n\n const source = typeof this._fallbackOption === \"function\" ? this._fallbackOption() : this._fallbackOption\n const nodes = asArray(source)\n for (const node of nodes) {\n ensureValidNode(node, \"fallback\", this)\n }\n\n this._fallbackNodes = nodes\n return this._fallbackNodes\n }\n\n private _callManagedHook(\n pluginId: string,\n managedSlot: CoreManagedSlot | undefined,\n hook: \"onActivate\" | \"onDeactivate\" | \"onDispose\",\n phase: \"setup\" | \"dispose\",\n ): void {\n const callback = managedSlot?.[hook]\n if (!callback) {\n return\n }\n\n try {\n callback(this._slotRegistry.context)\n } catch (error) {\n this._slotRegistry.reportPluginError({\n pluginId,\n slot: String(this._slotName),\n phase,\n source: \"core\",\n error,\n })\n }\n }\n\n private _detachNodeFromMount(node: BaseRenderable): void {\n if (node.parent === this) {\n this.remove(node.id)\n }\n }\n\n private _cleanupInactivePluginNodes(nextActivePluginIds: Set, registeredPluginIds: Set): void {\n for (const [pluginId, state] of this._pluginNodes) {\n if (nextActivePluginIds.has(pluginId)) {\n continue\n }\n\n if (this._activePluginIds.has(pluginId)) {\n this._callManagedHook(pluginId, state.managedSlot, \"onDeactivate\", \"dispose\")\n }\n\n for (const node of state.nodes) {\n this._detachNodeFromMount(node)\n }\n\n if (!registeredPluginIds.has(pluginId)) {\n this._callManagedHook(pluginId, state.managedSlot, \"onDispose\", \"dispose\")\n\n if (state.ownership === \"host\") {\n for (const node of state.nodes) {\n node.destroyRecursively()\n }\n }\n\n this._pluginNodes.delete(pluginId)\n continue\n }\n\n if (state.ownership === \"host\") {\n for (const node of state.nodes) {\n node.destroyRecursively()\n }\n this._pluginNodes.delete(pluginId)\n continue\n }\n\n state.nodes = []\n }\n }\n\n private _cleanupReplacedPluginNodes(\n previousState: SlotNodeState,\n nextNodes: BaseRenderable[],\n ): void {\n const retainedNodes = new Set(nextNodes)\n\n for (const node of previousState.nodes) {\n if (retainedNodes.has(node)) {\n continue\n }\n\n this._detachNodeFromMount(node)\n\n if (previousState.ownership === \"host\") {\n node.destroyRecursively()\n }\n }\n }\n\n private _resolvePluginFailurePlaceholder(failure: PluginErrorEvent): BaseRenderable[] {\n if (!this._pluginFailurePlaceholder) {\n return []\n }\n\n try {\n const placeholderSource = this._pluginFailurePlaceholder(failure, this._slotRegistry.context)\n const placeholderNodes = asArray(placeholderSource)\n\n for (const node of placeholderNodes) {\n ensureValidNode(node, `${failure.pluginId}:error-placeholder`, this)\n }\n\n return placeholderNodes\n } catch (placeholderError) {\n this._slotRegistry.reportPluginError({\n pluginId: failure.pluginId,\n slot: String(this._slotName),\n phase: \"error_placeholder\",\n source: \"core\",\n error: placeholderError,\n })\n return []\n }\n }\n\n private _reconcileMountedNodes(desiredNodes: BaseRenderable[]): void {\n const desiredNodeSet = new Set(desiredNodes)\n\n for (const node of this._mountedNodes) {\n if (!desiredNodeSet.has(node)) {\n if (node.parent === this) {\n this.remove(node.id)\n }\n }\n }\n\n for (let index = 0; index < desiredNodes.length; index++) {\n const node = desiredNodes[index]\n\n if (node.parent !== this) {\n this.add(node, index)\n continue\n }\n\n const childAtIndex = this.getChildren()[index]\n if (childAtIndex?.id !== node.id) {\n this.add(node, index)\n }\n }\n\n this._mountedNodes = [...desiredNodes]\n }\n}\n", + "import { EventEmitter } from \"events\"\nimport { readFile } from \"node:fs/promises\"\nimport { resolveRenderLib, type AudioEngineHandle, type RenderLib } from \"./zig.js\"\nimport type { AudioStats } from \"./zig-structs.js\"\n\nexport interface AudioSetupOptions {\n autoStart?: boolean\n sampleRate?: number\n playbackChannels?: number\n startOptions?: AudioStartOptions\n}\n\nexport interface AudioStartOptions {\n periodSizeInFrames?: number\n periodSizeInMilliseconds?: number\n periods?: number\n performanceProfile?: number\n shareMode?: number\n noPreSilencedOutputBuffer?: boolean\n noClip?: boolean\n noDisableDenormals?: boolean\n noFixedSizedCallback?: boolean\n wasapiNoAutoConvertSrc?: boolean\n wasapiNoDefaultQualitySrc?: boolean\n alsaNoMMap?: boolean\n alsaNoAutoFormat?: boolean\n alsaNoAutoChannels?: boolean\n alsaNoAutoResample?: boolean\n}\n\nexport interface AudioPlayOptions {\n volume?: number\n pan?: number\n loop?: boolean\n groupId?: number\n}\n\nexport type AudioGroup = number\nexport type AudioVoice = number\nexport type AudioSound = number\n\nexport interface AudioPlaybackDevice {\n index: number\n name: string\n isDefault: boolean\n}\n\nexport type AudioAction =\n | \"createAudioEngine\"\n | \"start\"\n | \"startMixer\"\n | \"stop\"\n | \"loadSound\"\n | \"loadSoundFile\"\n | \"unloadSound\"\n | \"group\"\n | \"play\"\n | \"stopVoice\"\n | \"setVoiceGroup\"\n | \"setGroupVolume\"\n | \"setMasterVolume\"\n | \"mixFrames\"\n | \"enableTap\"\n | \"readTapFrames\"\n | \"listPlaybackDevices\"\n | \"selectPlaybackDevice\"\n | \"clearPlaybackDeviceSelection\"\n | \"getStats\"\n\nexport interface AudioErrorContext {\n action: AudioAction\n status?: number\n}\n\nexport interface AudioEvents {\n error: [error: Error, context: AudioErrorContext]\n started: []\n mixerStarted: []\n stopped: []\n disposed: []\n}\n\nfunction statusToError(action: string, status: number): Error {\n return new Error(`Audio ${action} failed: ${status}`)\n}\n\nfunction toBytes(data: Uint8Array | ArrayBuffer): Uint8Array {\n return data instanceof Uint8Array ? data : new Uint8Array(data)\n}\n\nexport class Audio extends EventEmitter {\n static create(options: AudioSetupOptions = {}): Audio {\n return new Audio(resolveRenderLib(), options)\n }\n\n private readonly lib: RenderLib\n private readonly defaultStartOptions: AudioStartOptions | undefined\n private engine: AudioEngineHandle | null = null\n private readonly groups = new Map()\n private playbackStarted = false\n private mixerStarted = false\n\n private constructor(lib: RenderLib, options: AudioSetupOptions) {\n super()\n this.lib = lib\n this.defaultStartOptions = options.startOptions\n const createOptions =\n options.sampleRate == null && options.playbackChannels == null\n ? undefined\n : {\n sampleRate: options.sampleRate == null ? undefined : Math.max(0, Math.trunc(options.sampleRate)),\n playbackChannels:\n options.playbackChannels == null ? undefined : Math.max(0, Math.trunc(options.playbackChannels)),\n }\n this.engine = this.lib.createAudioEngine(createOptions)\n if (!this.engine) {\n this.emitError(\"createAudioEngine\", undefined, \"Audio createAudioEngine returned null\")\n return\n }\n\n if (options.autoStart ?? false) {\n this.start(this.defaultStartOptions)\n }\n }\n\n private emitError(action: AudioAction, status?: number, message?: string, cause?: unknown): void {\n const error = message ? new Error(message) : statusToError(action, status ?? -1)\n if (cause) (error as Error & { cause?: unknown }).cause = cause\n this.emit(\"error\", error, { action, status })\n }\n\n start(options?: AudioStartOptions): boolean {\n if (this.playbackStarted) return true\n const engine = this.engine\n if (!engine) {\n this.emitError(\"start\", undefined, \"Audio engine unavailable during start\")\n return false\n }\n const startOptions = options ?? this.defaultStartOptions\n const status = this.lib.audioStart(engine, startOptions)\n if (status !== 0) {\n this.emitError(\"start\", status)\n return false\n }\n this.playbackStarted = true\n this.mixerStarted = true\n this.emit(\"started\")\n return true\n }\n\n startMixer(): boolean {\n if (this.mixerStarted) return true\n const engine = this.engine\n if (!engine) {\n this.emitError(\"startMixer\", undefined, \"Audio engine unavailable during startMixer\")\n return false\n }\n const status = this.lib.audioStartMixer(engine)\n if (status !== 0) {\n this.emitError(\"startMixer\", status)\n return false\n }\n this.mixerStarted = true\n this.emit(\"mixerStarted\")\n return true\n }\n\n stop(): boolean {\n if (!this.mixerStarted) return true\n const engine = this.engine\n if (!engine) {\n this.emitError(\"stop\", undefined, \"Audio engine unavailable during stop\")\n return false\n }\n const status = this.lib.audioStop(engine)\n if (status !== 0) {\n this.emitError(\"stop\", status)\n return false\n }\n this.playbackStarted = false\n this.mixerStarted = false\n this.emit(\"stopped\")\n return true\n }\n\n isStarted(): boolean {\n return this.playbackStarted\n }\n\n isMixerStarted(): boolean {\n return this.mixerStarted\n }\n\n loadSound(data: Uint8Array | ArrayBuffer): AudioSound | null {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"loadSound\", undefined, \"Audio engine unavailable during loadSound\")\n return null\n }\n const result = this.lib.audioLoad(engine, toBytes(data))\n if (result.status !== 0 || result.soundId == null) {\n this.emitError(\"loadSound\", result.status)\n return null\n }\n return result.soundId\n }\n\n async loadSoundFile(filePath: string): Promise {\n const bytes = await readFile(filePath).catch((err) => {\n this.emitError(\"loadSoundFile\", undefined, `Failed to read file '${filePath}': ${err.message}`, err)\n return null\n })\n if (bytes == null) return null\n return this.loadSound(bytes)\n }\n\n unloadSound(sound: AudioSound): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"unloadSound\", undefined, \"Audio engine unavailable during unloadSound\")\n return false\n }\n\n const status = this.lib.audioUnload(engine, sound)\n if (status !== 0) {\n this.emitError(\"unloadSound\", status)\n return false\n }\n return true\n }\n\n group(name: string): AudioGroup | null {\n const existing = this.groups.get(name)\n if (existing != null) {\n return existing\n }\n\n const engine = this.engine\n if (!engine) {\n this.emitError(\"group\", undefined, \"Audio engine unavailable during group\")\n return null\n }\n const result = this.lib.audioCreateGroup(engine, name)\n if (result.status !== 0 || result.groupId == null) {\n this.emitError(\"group\", result.status)\n return null\n }\n\n this.groups.set(name, result.groupId)\n return result.groupId\n }\n\n play(sound: AudioSound, options?: AudioPlayOptions): AudioVoice | null {\n const rawOptions = options\n ? {\n volume: options.volume,\n pan: options.pan,\n loop: options.loop,\n groupId: options.groupId ?? 0,\n }\n : undefined\n\n const engine = this.engine\n if (!engine) {\n this.emitError(\"play\", undefined, \"Audio engine unavailable during play\")\n return null\n }\n const result = this.lib.audioPlay(engine, sound, rawOptions)\n if (result.status !== 0 || result.voiceId == null) {\n this.emitError(\"play\", result.status)\n return null\n }\n\n return result.voiceId\n }\n\n stopVoice(voice: AudioVoice): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"stopVoice\", undefined, \"Audio engine unavailable during stopVoice\")\n return false\n }\n const status = this.lib.audioStopVoice(engine, voice)\n if (status !== 0) {\n this.emitError(\"stopVoice\", status)\n return false\n }\n return true\n }\n\n setVoiceGroup(voice: AudioVoice, group: AudioGroup): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"setVoiceGroup\", undefined, \"Audio engine unavailable during setVoiceGroup\")\n return false\n }\n const status = this.lib.audioSetVoiceGroup(engine, voice, group)\n if (status !== 0) {\n this.emitError(\"setVoiceGroup\", status)\n return false\n }\n return true\n }\n\n setGroupVolume(group: AudioGroup, volume: number): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"setGroupVolume\", undefined, \"Audio engine unavailable during setGroupVolume\")\n return false\n }\n const status = this.lib.audioSetGroupVolume(engine, group, volume)\n if (status !== 0) {\n this.emitError(\"setGroupVolume\", status)\n return false\n }\n return true\n }\n\n setMasterVolume(volume: number): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"setMasterVolume\", undefined, \"Audio engine unavailable during setMasterVolume\")\n return false\n }\n const status = this.lib.audioSetMasterVolume(engine, volume)\n if (status !== 0) {\n this.emitError(\"setMasterVolume\", status)\n return false\n }\n return true\n }\n\n mixFrames(frameCount: number, channels: number = 2): Float32Array | null {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"mixFrames\", undefined, \"Audio engine unavailable during mixFrames\")\n return null\n }\n const output = new Float32Array(frameCount * channels)\n const status = this.lib.audioMixToBuffer(engine, output, frameCount, channels)\n if (status !== 0) {\n this.emitError(\"mixFrames\", status)\n return null\n }\n return output\n }\n\n enableTap(capacityFrames: number = 8192): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"enableTap\", undefined, \"Audio engine unavailable during enableTap\")\n return false\n }\n const status = this.lib.audioEnableTap(engine, true, capacityFrames)\n if (status !== 0) {\n this.emitError(\"enableTap\", status)\n return false\n }\n return true\n }\n\n disableTap(): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"enableTap\", undefined, \"Audio engine unavailable during disableTap\")\n return false\n }\n const status = this.lib.audioEnableTap(engine, false, 0)\n if (status !== 0) {\n this.emitError(\"enableTap\", status)\n return false\n }\n return true\n }\n\n readTapFrames(frameCount: number, channels: number = 2): { frames: Float32Array; framesRead: number } | null {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"readTapFrames\", undefined, \"Audio engine unavailable during readTapFrames\")\n return null\n }\n const output = new Float32Array(frameCount * channels)\n const result = this.lib.audioReadTap(engine, output, frameCount, channels)\n if (result.status !== 0) {\n this.emitError(\"readTapFrames\", result.status)\n return null\n }\n return { frames: output, framesRead: result.framesRead }\n }\n\n listPlaybackDevices(): AudioPlaybackDevice[] | null {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"listPlaybackDevices\", undefined, \"Audio engine unavailable during listPlaybackDevices\")\n return null\n }\n\n const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine)\n if (refreshStatus !== 0) {\n this.emitError(\"listPlaybackDevices\", refreshStatus)\n return null\n }\n\n const count = this.lib.audioGetPlaybackDeviceCount(engine)\n const devices: AudioPlaybackDevice[] = []\n for (let index = 0; index < count; index += 1) {\n devices.push({\n index,\n name: this.lib.audioGetPlaybackDeviceName(engine, index),\n isDefault: this.lib.audioIsPlaybackDeviceDefault(engine, index),\n })\n }\n\n return devices\n }\n\n selectPlaybackDevice(index: number): boolean {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"selectPlaybackDevice\", undefined, \"Audio engine unavailable during selectPlaybackDevice\")\n return false\n }\n\n const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine)\n if (refreshStatus !== 0) {\n this.emitError(\"selectPlaybackDevice\", refreshStatus)\n return false\n }\n\n const status = this.lib.audioSelectPlaybackDevice(engine, index)\n if (status !== 0) {\n this.emitError(\"selectPlaybackDevice\", status)\n return false\n }\n\n return true\n }\n\n clearPlaybackDeviceSelection(): void {\n const engine = this.engine\n if (!engine) {\n this.emitError(\n \"clearPlaybackDeviceSelection\",\n undefined,\n \"Audio engine unavailable during clearPlaybackDeviceSelection\",\n )\n return\n }\n this.lib.audioClearPlaybackDeviceSelection(engine)\n }\n\n getStats(): AudioStats | null {\n const engine = this.engine\n if (!engine) {\n this.emitError(\"getStats\", undefined, \"Audio engine unavailable during getStats\")\n return null\n }\n const stats = this.lib.audioGetStats(engine)\n if (stats == null) {\n this.emitError(\"getStats\", undefined, \"Failed to retrieve audio stats\")\n }\n return stats\n }\n\n dispose(): void {\n if (!this.engine) return\n if (this.mixerStarted) {\n this.stop()\n }\n this.groups.clear()\n this.lib.destroyAudioEngine(this.engine)\n this.engine = null\n this.emit(\"disposed\")\n }\n}\n\nexport function setupAudio(options: AudioSetupOptions = {}): Audio {\n return Audio.create(options)\n}\n", + "import { type RenderableOptions, Renderable } from \"../Renderable.js\"\nimport { OptimizedBuffer } from \"../buffer.js\"\nimport type { RenderContext } from \"../types.js\"\n\nexport interface FrameBufferOptions extends RenderableOptions {\n width: number\n height: number\n respectAlpha?: boolean\n}\n\nexport class FrameBufferRenderable extends Renderable {\n public frameBuffer: OptimizedBuffer\n protected respectAlpha: boolean\n\n constructor(ctx: RenderContext, options: FrameBufferOptions) {\n super(ctx, options)\n this.respectAlpha = options.respectAlpha || false\n this.frameBuffer = OptimizedBuffer.create(options.width, options.height, this._ctx.widthMethod, {\n respectAlpha: this.respectAlpha,\n id: options.id || `framebufferrenderable-${this.id}`,\n })\n }\n\n protected onResize(width: number, height: number): void {\n if (width <= 0 || height <= 0) {\n throw new Error(`Invalid resize dimensions for FrameBufferRenderable ${this.id}: ${width}x${height}`)\n }\n\n this.frameBuffer.resize(width, height)\n super.onResize(width, height)\n this.requestRender()\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n if (!this.visible || this.isDestroyed) return\n buffer.drawFrameBuffer(this.x, this.y, this.frameBuffer)\n }\n\n protected destroySelf(): void {\n // TODO: framebuffer collides with buffered Renderable, which holds a framebuffer\n // and destroys it if it exists already. Maybe instead of extending FrameBufferRenderable,\n // subclasses can use the buffered option on the base renderable instead,\n // then this would become something that takes in an external framebuffer to bring it into layout.\n this.frameBuffer?.destroy()\n super.destroySelf()\n }\n}\n", + "import {\n getCharacterPositions,\n measureText,\n renderFontToFrameBuffer,\n type ASCIIFontName,\n type fonts,\n} from \"../lib/ascii.font.js\"\nimport { parseColor, type ColorInput } from \"../lib/RGBA.js\"\nimport {\n ASCIIFontSelectionHelper,\n convertGlobalToLocalSelection,\n Selection,\n type LocalSelectionBounds,\n} from \"../lib/selection.js\"\nimport type { RenderableOptions } from \"../Renderable.js\"\nimport type { RenderContext } from \"../types.js\"\nimport { FrameBufferRenderable, type FrameBufferOptions } from \"./FrameBuffer.js\"\n\nexport interface ASCIIFontOptions extends Omit, \"width\" | \"height\"> {\n text?: string\n font?: ASCIIFontName\n color?: ColorInput | ColorInput[]\n backgroundColor?: ColorInput\n selectionBg?: ColorInput\n selectionFg?: ColorInput\n selectable?: boolean\n}\n\nexport class ASCIIFontRenderable extends FrameBufferRenderable {\n public selectable: boolean = true\n\n protected static readonly _defaultOptions = {\n text: \"\",\n font: \"tiny\",\n color: \"#FFFFFF\",\n backgroundColor: \"transparent\",\n selectionBg: undefined,\n selectionFg: undefined,\n selectable: true,\n } satisfies Partial\n\n protected _text: string\n protected _font: keyof typeof fonts\n protected _color: ColorInput | ColorInput[]\n protected _backgroundColor: ColorInput\n protected _selectionBg: ColorInput | undefined\n protected _selectionFg: ColorInput | undefined\n protected lastLocalSelection: LocalSelectionBounds | null = null\n\n private selectionHelper: ASCIIFontSelectionHelper\n\n constructor(ctx: RenderContext, options: ASCIIFontOptions) {\n const defaultOptions = ASCIIFontRenderable._defaultOptions\n const font = options.font || defaultOptions.font\n const text = options.text || defaultOptions.text\n const measurements = measureText({ text: text, font })\n\n super(ctx, {\n flexShrink: 0,\n ...options,\n width: measurements.width || 1,\n height: measurements.height || 1,\n respectAlpha: true,\n } as FrameBufferOptions)\n\n this._text = text\n this._font = font\n this._color = options.color || defaultOptions.color\n this._backgroundColor = options.backgroundColor || defaultOptions.backgroundColor\n this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : undefined\n this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : undefined\n this.selectable = options.selectable ?? true\n\n this.selectionHelper = new ASCIIFontSelectionHelper(\n () => this._text,\n () => this._font,\n )\n\n this.renderFontToBuffer()\n }\n\n get text(): string {\n return this._text\n }\n\n set text(value: string) {\n this._text = value\n this.updateDimensions()\n\n if (this.lastLocalSelection) {\n this.selectionHelper.onLocalSelectionChanged(this.lastLocalSelection, this.width, this.height)\n }\n\n this.renderFontToBuffer()\n this.requestRender()\n }\n\n get font(): keyof typeof fonts {\n return this._font\n }\n\n set font(value: keyof typeof fonts) {\n this._font = value\n this.updateDimensions()\n\n if (this.lastLocalSelection) {\n this.selectionHelper.onLocalSelectionChanged(this.lastLocalSelection, this.width, this.height)\n }\n\n this.renderFontToBuffer()\n this.requestRender()\n }\n\n get color(): ColorInput | ColorInput[] {\n return this._color\n }\n\n set color(value: ColorInput | ColorInput[]) {\n this._color = value\n this.renderFontToBuffer()\n this.requestRender()\n }\n\n get backgroundColor(): ColorInput {\n return this._backgroundColor\n }\n\n set backgroundColor(value: ColorInput) {\n this._backgroundColor = value\n this.renderFontToBuffer()\n this.requestRender()\n }\n\n private updateDimensions(): void {\n const measurements = measureText({ text: this._text, font: this._font })\n this.width = measurements.width\n this.height = measurements.height\n }\n\n shouldStartSelection(x: number, y: number): boolean {\n const localX = x - this.x\n const localY = y - this.y\n return this.selectionHelper.shouldStartSelection(localX, localY, this.width, this.height)\n }\n\n onSelectionChanged(selection: Selection | null): boolean {\n const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y)\n this.lastLocalSelection = localSelection\n const changed = this.selectionHelper.onLocalSelectionChanged(localSelection, this.width, this.height)\n if (changed) {\n this.renderFontToBuffer()\n this.requestRender()\n }\n return changed\n }\n\n getSelectedText(): string {\n const selection = this.selectionHelper.getSelection()\n if (!selection) return \"\"\n return this._text.slice(selection.start, selection.end)\n }\n\n hasSelection(): boolean {\n return this.selectionHelper.hasSelection()\n }\n\n protected onResize(width: number, height: number): void {\n super.onResize(width, height)\n this.renderFontToBuffer()\n }\n\n private renderFontToBuffer(): void {\n if (this.isDestroyed) return\n this.frameBuffer.clear(parseColor(this._backgroundColor))\n\n renderFontToFrameBuffer(this.frameBuffer, {\n text: this._text,\n x: 0,\n y: 0,\n color: this.color,\n backgroundColor: this._backgroundColor,\n font: this._font,\n })\n\n const selection = this.selectionHelper.getSelection()\n if (selection && (this._selectionBg || this._selectionFg)) {\n this.renderSelectionHighlight(selection)\n }\n }\n\n private renderSelectionHighlight(selection: { start: number; end: number }): void {\n if (!this._selectionBg && !this._selectionFg) return\n\n const selectedText = this._text.slice(selection.start, selection.end)\n if (!selectedText) return\n\n const positions = getCharacterPositions(this._text, this._font)\n const startX = positions[selection.start] || 0\n const endX =\n selection.end < positions.length\n ? positions[selection.end]\n : measureText({ text: this._text, font: this._font }).width\n\n if (this._selectionBg) {\n this.frameBuffer.fillRect(startX, 0, endX - startX, this.height, parseColor(this._selectionBg))\n }\n\n if (this._selectionFg || this._selectionBg) {\n renderFontToFrameBuffer(this.frameBuffer, {\n text: selectedText,\n x: startX,\n y: 0,\n color: this._selectionFg ? this._selectionFg : this._color,\n backgroundColor: this._selectionBg ? this._selectionBg : this._backgroundColor,\n font: this._font,\n })\n }\n }\n}\n", + "import {\n ASCIIFontRenderable,\n BoxRenderable,\n CodeRenderable,\n InputRenderable,\n ScrollBoxRenderable,\n SelectRenderable,\n TabSelectRenderable,\n TextRenderable,\n VRenderable,\n FrameBufferRenderable,\n type ASCIIFontOptions,\n type BoxOptions,\n type CodeOptions,\n type TextOptions,\n type VRenderableOptions,\n type InputRenderableOptions,\n type ScrollBoxOptions,\n type SelectRenderableOptions,\n type TabSelectRenderableOptions,\n type FrameBufferOptions,\n} from \"..//index.js\"\nimport { TextNodeRenderable, type TextNodeOptions } from \"../TextNode.js\"\nimport { h, type VChild } from \"./vnode.js\"\nimport { TextAttributes } from \"../../types.js\"\nimport type { RGBA } from \"../../lib/RGBA.js\"\n\nexport function Generic(props?: VRenderableOptions, ...children: VChild[]) {\n return h(VRenderable, props || {}, ...children)\n}\n\nexport function Box(props?: BoxOptions, ...children: VChild[]) {\n return h(BoxRenderable, props || {}, ...children)\n}\n\nexport function Text(props?: TextOptions & { content?: any }, ...children: VChild[] | TextNodeRenderable[]) {\n return h(TextRenderable, props || {}, ...(children as VChild[]))\n}\n\nexport function ASCIIFont(props?: ASCIIFontOptions, ...children: VChild[]) {\n return h(ASCIIFontRenderable, props || {}, ...children)\n}\n\nexport function Input(props?: InputRenderableOptions, ...children: VChild[]) {\n return h(InputRenderable, props || {}, ...children)\n}\n\nexport function Select(props?: SelectRenderableOptions, ...children: VChild[]) {\n return h(SelectRenderable, props || {}, ...children)\n}\n\nexport function TabSelect(props?: TabSelectRenderableOptions, ...children: VChild[]) {\n return h(TabSelectRenderable, props || {}, ...children)\n}\n\nexport function FrameBuffer(props: FrameBufferOptions, ...children: VChild[]) {\n return h(FrameBufferRenderable, props, ...children)\n}\n\nexport function Code(props: CodeOptions, ...children: VChild[]) {\n return h(CodeRenderable, props, ...children)\n}\n\nexport function ScrollBox(props?: ScrollBoxOptions, ...children: VChild[]) {\n return h(ScrollBoxRenderable, props || {}, ...children)\n}\n\ninterface StyledTextProps extends Omit {\n attributes?: number\n}\n\nfunction StyledText(props?: StyledTextProps, ...children: (string | TextNodeRenderable)[]): TextNodeRenderable {\n const styledProps = props as StyledTextProps\n const textNodeOptions: TextNodeOptions = {\n ...styledProps,\n attributes: styledProps?.attributes ?? 0,\n }\n\n const textNode = new TextNodeRenderable(textNodeOptions)\n\n for (const child of children) {\n textNode.add(child)\n }\n\n return textNode\n}\n\n// Text styling convenience functions - these create TextNodeRenderable instances that can be nested and stacked\nexport const vstyles = {\n // Basic text styles\n bold: (...children: (string | TextNodeRenderable)[]) => StyledText({ attributes: TextAttributes.BOLD }, ...children),\n italic: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.ITALIC }, ...children),\n underline: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.UNDERLINE }, ...children),\n dim: (...children: (string | TextNodeRenderable)[]) => StyledText({ attributes: TextAttributes.DIM }, ...children),\n blink: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.BLINK }, ...children),\n inverse: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.INVERSE }, ...children),\n hidden: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.HIDDEN }, ...children),\n strikethrough: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.STRIKETHROUGH }, ...children),\n\n // Combined styles\n boldItalic: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.BOLD | TextAttributes.ITALIC }, ...children),\n boldUnderline: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.BOLD | TextAttributes.UNDERLINE }, ...children),\n italicUnderline: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.ITALIC | TextAttributes.UNDERLINE }, ...children),\n boldItalicUnderline: (...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes: TextAttributes.BOLD | TextAttributes.ITALIC | TextAttributes.UNDERLINE }, ...children),\n\n // Color helpers\n color: (color: string | RGBA, ...children: (string | TextNodeRenderable)[]) => StyledText({ fg: color }, ...children),\n bgColor: (bgColor: string | RGBA, ...children: (string | TextNodeRenderable)[]) =>\n StyledText({ bg: bgColor }, ...children),\n fg: (color: string | RGBA, ...children: (string | TextNodeRenderable)[]) => StyledText({ fg: color }, ...children),\n bg: (bgColor: string | RGBA, ...children: (string | TextNodeRenderable)[]) =>\n StyledText({ bg: bgColor }, ...children),\n\n // Custom styling function\n styled: (attributes: number = 0, ...children: (string | TextNodeRenderable)[]) =>\n StyledText({ attributes }, ...children),\n}\n", + "import { Renderable, type RenderableOptions } from \"../../Renderable.js\"\nimport type { OptimizedBuffer } from \"../../buffer.js\"\nimport type { RenderContext } from \"../../types.js\"\n\nexport interface VRenderableOptions extends RenderableOptions {\n render?: (\n this: VRenderable | VRenderableOptions,\n buffer: OptimizedBuffer,\n deltaTime: number,\n renderable: VRenderable,\n ) => void\n}\n\n/**\n * A generic renderable that accepts a custom render function as a prop.\n * This allows functional constructs to specify custom rendering behavior\n * without needing to subclass Renderable.\n */\nexport class VRenderable extends Renderable {\n private options: VRenderableOptions\n\n constructor(ctx: RenderContext, options: VRenderableOptions) {\n super(ctx, options)\n this.options = options\n }\n\n protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void {\n if (this.options.render) {\n this.options.render.call(this.options, buffer, deltaTime, this)\n }\n }\n}\n", + "import { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport { OptimizedBuffer } from \"../buffer.js\"\nimport type { RenderContext, LineInfoProvider } from \"../types.js\"\nimport { RGBA, parseColor } from \"../lib/RGBA.js\"\nimport { stringWidth } from \"../platform/runtime.js\"\nimport { MeasureMode } from \"../yoga.js\"\n\nexport interface LineSign {\n before?: string\n beforeColor?: string | RGBA\n after?: string\n afterColor?: string | RGBA\n}\n\nexport interface LineColorConfig {\n gutter?: string | RGBA\n content?: string | RGBA\n}\n\nexport interface LineNumberOptions extends RenderableOptions {\n target?: Renderable & LineInfoProvider\n fg?: string | RGBA\n bg?: string | RGBA\n minWidth?: number\n paddingRight?: number\n lineColors?: Map\n lineSigns?: Map\n lineNumberOffset?: number\n hideLineNumbers?: Set\n lineNumbers?: Map\n showLineNumbers?: boolean\n}\n\nconst DEFAULT_GUTTER_FG = \"#888888\"\nconst DEFAULT_GUTTER_BG = \"transparent\"\n\nclass GutterRenderable extends Renderable {\n private target: Renderable & LineInfoProvider\n private _fg: RGBA\n private _bg: RGBA\n private _minWidth: number\n private _paddingRight: number\n private _lineColorsGutter: Map\n private _lineColorsContent: Map\n private _lineSigns: Map\n private _lineNumberOffset: number\n private _hideLineNumbers: Set\n private _lineNumbers: Map\n private _maxBeforeWidth: number = 0\n private _maxAfterWidth: number = 0\n private _lastKnownLineCount: number = 0\n private _lastKnownScrollY: number = 0\n\n constructor(\n ctx: RenderContext,\n target: Renderable & LineInfoProvider,\n options: {\n fg: RGBA\n bg: RGBA\n minWidth: number\n paddingRight: number\n lineColorsGutter: Map\n lineColorsContent: Map\n lineSigns: Map\n lineNumberOffset: number\n hideLineNumbers: Set\n lineNumbers?: Map\n id?: string\n buffered?: boolean\n },\n ) {\n super(ctx, {\n id: options.id,\n width: \"auto\",\n height: \"auto\",\n flexGrow: 0,\n flexShrink: 0,\n buffered: options.buffered,\n })\n this.target = target\n this._fg = options.fg\n this._bg = options.bg\n this._minWidth = options.minWidth\n this._paddingRight = options.paddingRight\n this._lineColorsGutter = options.lineColorsGutter\n this._lineColorsContent = options.lineColorsContent\n this._lineSigns = options.lineSigns\n this._lineNumberOffset = options.lineNumberOffset\n this._hideLineNumbers = options.hideLineNumbers\n this._lineNumbers = options.lineNumbers ?? new Map()\n this._lastKnownLineCount = this.target.virtualLineCount\n this._lastKnownScrollY = this.target.scrollY\n this.calculateSignWidths()\n this.setupMeasureFunc()\n\n // Use lifecycle pass to detect line count changes BEFORE layout\n this.onLifecyclePass = () => {\n const currentLineCount = this.target.virtualLineCount\n if (currentLineCount !== this._lastKnownLineCount) {\n this._lastKnownLineCount = currentLineCount\n this.yogaNode.markDirty()\n this.requestRender()\n }\n }\n }\n\n private setupMeasureFunc(): void {\n const measureFunc = (\n width: number,\n widthMode: MeasureMode,\n height: number,\n heightMode: MeasureMode,\n ): { width: number; height: number } => {\n // Calculate the gutter width based on the target's line count\n const gutterWidth = this.calculateWidth()\n\n // Calculate gutter height based on target's actual virtual line count\n // The gutter should match the height of the content it's numbering\n const gutterHeight = this.target.virtualLineCount\n\n // Return calculated dimensions based on content, not parent constraints\n return {\n width: gutterWidth,\n height: gutterHeight,\n }\n }\n\n this.yogaNode.setMeasureFunc(measureFunc)\n }\n\n public remeasure(): void {\n // Mark the yoga node as dirty to trigger re-measurement\n this.yogaNode.markDirty()\n }\n\n public setLineNumberOffset(offset: number): void {\n if (this._lineNumberOffset !== offset) {\n this._lineNumberOffset = offset\n this.yogaNode.markDirty()\n this.requestRender()\n }\n }\n\n public setHideLineNumbers(hideLineNumbers: Set): void {\n this._hideLineNumbers = hideLineNumbers\n this.yogaNode.markDirty()\n this.requestRender()\n }\n\n public setLineNumbers(lineNumbers: Map): void {\n this._lineNumbers = lineNumbers\n this.yogaNode.markDirty()\n this.requestRender()\n }\n\n private calculateSignWidths(): void {\n this._maxBeforeWidth = 0\n this._maxAfterWidth = 0\n\n for (const sign of this._lineSigns.values()) {\n if (sign.before) {\n const width = stringWidth(sign.before)\n this._maxBeforeWidth = Math.max(this._maxBeforeWidth, width)\n }\n if (sign.after) {\n const width = stringWidth(sign.after)\n this._maxAfterWidth = Math.max(this._maxAfterWidth, width)\n }\n }\n }\n\n private calculateWidth(): number {\n const totalLines = this.target.virtualLineCount\n\n // Find max line number, considering both calculated and custom line numbers\n let maxLineNumber = totalLines + this._lineNumberOffset\n if (this._lineNumbers.size > 0) {\n for (const customLineNum of this._lineNumbers.values()) {\n maxLineNumber = Math.max(maxLineNumber, customLineNum)\n }\n }\n\n const digits = maxLineNumber > 0 ? Math.floor(Math.log10(maxLineNumber)) + 1 : 1\n const baseWidth = Math.max(this._minWidth, digits + this._paddingRight + 1) // +1 for left padding\n return baseWidth + this._maxBeforeWidth + this._maxAfterWidth\n }\n\n public setLineColors(lineColorsGutter: Map, lineColorsContent: Map): void {\n this._lineColorsGutter = lineColorsGutter\n this._lineColorsContent = lineColorsContent\n this.requestRender()\n }\n\n public get fg(): RGBA {\n return this._fg\n }\n\n public setFg(fg: RGBA): void {\n if (this._fg !== fg) {\n this._fg = fg\n this.requestRender()\n }\n }\n\n public get bg(): RGBA {\n return this._bg\n }\n\n public setBg(bg: RGBA): void {\n if (this._bg !== bg) {\n this._bg = bg\n this.requestRender()\n }\n }\n\n public getLineColors(): { gutter: Map; content: Map } {\n return {\n gutter: this._lineColorsGutter,\n content: this._lineColorsContent,\n }\n }\n\n public setLineSigns(lineSigns: Map): void {\n const oldMaxBefore = this._maxBeforeWidth\n const oldMaxAfter = this._maxAfterWidth\n\n this._lineSigns = lineSigns\n this.calculateSignWidths()\n\n // Mark dirty if sign widths changed - this will trigger remeasure\n if (this._maxBeforeWidth !== oldMaxBefore || this._maxAfterWidth !== oldMaxAfter) {\n this.yogaNode.markDirty()\n }\n\n // Always request render since signs themselves may have changed\n this.requestRender()\n }\n\n public getLineSigns(): Map {\n return this._lineSigns\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n // For buffered rendering, only re-render when dirty OR when scroll position changed\n const currentScrollY = this.target.scrollY\n const scrollChanged = currentScrollY !== this._lastKnownScrollY\n\n if (this.buffered && !this.isDirty && !scrollChanged) {\n return\n }\n\n this._lastKnownScrollY = currentScrollY\n this.refreshFrameBuffer(buffer)\n }\n\n private refreshFrameBuffer(buffer: OptimizedBuffer): void {\n const startX = this.buffered ? 0 : this.x\n const startY = this.buffered ? 0 : this.y\n\n if (this.buffered) {\n buffer.clear(this._bg)\n } else if (this._bg.a > 0) {\n // Fill background if not buffered and opaque (if buffered, clear handles it)\n // Note: this.height might be determined by parent (flex stretch)\n buffer.fillRect(startX, startY, this.width, this.height, this._bg)\n }\n\n const lineInfo = this.target.lineInfo\n if (!lineInfo || !lineInfo.lineSources) return\n\n const sources = lineInfo.lineSources\n let lastSource = -1\n\n // lineSources contains the logical line index for each visual line\n // We start iterating from the scroll offset (first visible line)\n const startLine = this.target.scrollY\n\n // If scrolled past content (shouldn't happen normally but good to be safe)\n if (startLine >= sources.length) return\n\n // Get the logical line index of the line *before* the first visible line\n // This helps determine if the first visible line is a wrapped continuation\n lastSource = startLine > 0 ? sources[startLine - 1] : -1\n\n for (let i = 0; i < this.height; i++) {\n const visualLineIndex = startLine + i\n if (visualLineIndex >= sources.length) break\n\n const logicalLine = sources[visualLineIndex]\n const lineBg = this._lineColorsGutter.get(logicalLine) ?? this._bg\n\n // Fill background for this line if it has a custom color\n if (lineBg !== this._bg) {\n buffer.fillRect(startX, startY + i, this.width, 1, lineBg)\n }\n\n // Draw line number only for the first visual line of a logical line (wrapping)\n if (logicalLine === lastSource) {\n // Continuation line, maybe draw a dot or nothing\n } else {\n let currentX = startX\n\n // Draw 'before' sign if present\n const sign = this._lineSigns.get(logicalLine)\n if (sign?.before) {\n const beforeWidth = stringWidth(sign.before)\n // Pad to max before width for alignment\n const padding = this._maxBeforeWidth - beforeWidth\n currentX += padding\n const beforeColor = sign.beforeColor ? parseColor(sign.beforeColor) : this._fg\n buffer.drawText(sign.before, currentX, startY + i, beforeColor, lineBg)\n currentX += beforeWidth\n } else if (this._maxBeforeWidth > 0) {\n currentX += this._maxBeforeWidth\n }\n\n // Draw line number (right-aligned in its space with left padding of 1)\n if (!this._hideLineNumbers.has(logicalLine)) {\n // Use custom line number if provided, otherwise use calculated line number\n const customLineNum = this._lineNumbers.get(logicalLine)\n const lineNum = customLineNum !== undefined ? customLineNum : logicalLine + 1 + this._lineNumberOffset\n const lineNumStr = lineNum.toString()\n const lineNumWidth = lineNumStr.length\n const availableSpace = this.width - this._maxBeforeWidth - this._maxAfterWidth - this._paddingRight\n const lineNumX = startX + this._maxBeforeWidth + 1 + availableSpace - lineNumWidth - 1\n\n if (lineNumX >= startX + this._maxBeforeWidth + 1) {\n buffer.drawText(lineNumStr, lineNumX, startY + i, this._fg, lineBg)\n }\n }\n\n // Draw 'after' sign if present\n if (sign?.after) {\n const afterX = startX + this.width - this._paddingRight - this._maxAfterWidth\n const afterColor = sign.afterColor ? parseColor(sign.afterColor) : this._fg\n buffer.drawText(sign.after, afterX, startY + i, afterColor, lineBg)\n }\n }\n\n lastSource = logicalLine\n }\n }\n}\n\n// Helper function to darken an RGBA color by 20%\nfunction darkenColor(color: RGBA): RGBA {\n return RGBA.fromValues(color.r * 0.8, color.g * 0.8, color.b * 0.8, color.a)\n}\n\nexport class LineNumberRenderable extends Renderable {\n private gutter: GutterRenderable | null = null\n private target: (Renderable & LineInfoProvider) | null = null\n private _lineColorsGutter: Map\n private _lineColorsContent: Map\n private _lineSigns: Map\n private _fg: RGBA\n private _bg: RGBA\n private _minWidth: number\n private _paddingRight: number\n private _lineNumberOffset: number\n private _hideLineNumbers: Set\n private _lineNumbers: Map\n private _isDestroying: boolean = false\n private handleLineInfoChange = (): void => {\n // When line info changes in the target, remeasure the gutter\n this.gutter?.remeasure()\n this.requestRender()\n }\n\n private parseLineColor(line: number, color: string | RGBA | LineColorConfig): void {\n if (typeof color === \"object\" && \"gutter\" in color) {\n // LineColorConfig format\n const config = color as LineColorConfig\n if (config.gutter) {\n this._lineColorsGutter.set(line, parseColor(config.gutter))\n }\n if (config.content) {\n this._lineColorsContent.set(line, parseColor(config.content))\n } else if (config.gutter) {\n // If only gutter is specified, use a darker version for content\n this._lineColorsContent.set(line, darkenColor(parseColor(config.gutter)))\n }\n } else {\n // Simple format - same color for both, but content is darker\n const parsedColor = parseColor(color as string | RGBA)\n this._lineColorsGutter.set(line, parsedColor)\n this._lineColorsContent.set(line, darkenColor(parsedColor))\n }\n }\n\n constructor(ctx: RenderContext, options: LineNumberOptions) {\n super(ctx, {\n ...options,\n flexDirection: \"row\",\n // CRITICAL:\n // By forcing height=auto, we ensure the parent box properly accounts for our full height.\n height: \"auto\",\n })\n\n this._fg = parseColor(options.fg ?? DEFAULT_GUTTER_FG)\n this._bg = parseColor(options.bg ?? DEFAULT_GUTTER_BG)\n this._minWidth = options.minWidth ?? 3\n this._paddingRight = options.paddingRight ?? 1\n this._lineNumberOffset = options.lineNumberOffset ?? 0\n this._hideLineNumbers = options.hideLineNumbers ?? new Set()\n this._lineNumbers = options.lineNumbers ?? new Map()\n\n this._lineColorsGutter = new Map()\n this._lineColorsContent = new Map()\n if (options.lineColors) {\n for (const [line, color] of options.lineColors) {\n this.parseLineColor(line, color)\n }\n }\n\n this._lineSigns = new Map()\n if (options.lineSigns) {\n for (const [line, sign] of options.lineSigns) {\n this._lineSigns.set(line, sign)\n }\n }\n\n // If target is provided in constructor, set it up immediately\n if (options.target) {\n this.setTarget(options.target)\n }\n }\n\n private setTarget(target: Renderable & LineInfoProvider): void {\n if (this.target === target) return\n\n if (this.target) {\n // Remove event listener from old target\n this.target.off(\"line-info-change\", this.handleLineInfoChange)\n super.remove(this.target.id)\n }\n\n if (this.gutter) {\n super.remove(this.gutter.id)\n this.gutter = null\n }\n\n this.target = target\n\n // Listen for line info changes from target\n this.target.on(\"line-info-change\", this.handleLineInfoChange)\n\n this.gutter = new GutterRenderable(this.ctx, this.target, {\n fg: this._fg,\n bg: this._bg,\n minWidth: this._minWidth,\n paddingRight: this._paddingRight,\n lineColorsGutter: this._lineColorsGutter,\n lineColorsContent: this._lineColorsContent,\n lineSigns: this._lineSigns,\n lineNumberOffset: this._lineNumberOffset,\n hideLineNumbers: this._hideLineNumbers,\n lineNumbers: this._lineNumbers,\n id: this.id ? `${this.id}-gutter` : undefined,\n buffered: true,\n })\n\n super.add(this.gutter)\n super.add(this.target)\n }\n\n // Override add to intercept and set as target if it's a LineInfoProvider\n public override add(child: Renderable): number {\n // If this is a LineInfoProvider and we don't have a target yet, set it\n if (\n !this.target &&\n \"lineInfo\" in child &&\n \"lineCount\" in child &&\n \"virtualLineCount\" in child &&\n \"scrollY\" in child\n ) {\n this.setTarget(child as Renderable & LineInfoProvider)\n return this.getChildrenCount() - 1\n }\n // Otherwise ignore - SolidJS may try to add layout slots or other helpers\n return -1\n }\n\n // Override remove to prevent removing gutter/target directly\n public override remove(id: string): void {\n if (this._isDestroying) {\n super.remove(id)\n return\n }\n\n if (this.gutter && id === this.gutter.id) {\n throw new Error(\"LineNumberRenderable: Cannot remove gutter directly.\")\n }\n if (this.target && id === this.target.id) {\n throw new Error(\"LineNumberRenderable: Cannot remove target directly. Use clearTarget() instead.\")\n }\n super.remove(id)\n }\n\n // Override destroyRecursively to properly clean up internal components\n public override destroyRecursively(): void {\n this._isDestroying = true\n\n if (this.target) {\n this.target.off(\"line-info-change\", this.handleLineInfoChange)\n }\n\n super.destroyRecursively()\n\n this.gutter = null\n this.target = null\n }\n\n public clearTarget(): void {\n if (this.target) {\n this.target.off(\"line-info-change\", this.handleLineInfoChange)\n super.remove(this.target.id)\n this.target = null\n }\n if (this.gutter) {\n super.remove(this.gutter.id)\n this.gutter = null\n }\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n // Draw full-width line backgrounds before children render\n if (!this.target || !this.gutter) return\n\n const lineInfo = this.target.lineInfo\n if (!lineInfo || !lineInfo.lineSources) return\n\n const sources = lineInfo.lineSources\n const startLine = this.target.scrollY\n\n if (startLine >= sources.length) return\n\n // Calculate the area to fill: from after the gutter (if visible) to the end of our width\n const gutterWidth = this.gutter.visible ? this.gutter.width : 0\n const contentWidth = this.width - gutterWidth\n\n // Draw full-width background colors for lines with custom colors\n for (let i = 0; i < this.height; i++) {\n const visualLineIndex = startLine + i\n if (visualLineIndex >= sources.length) break\n\n const logicalLine = sources[visualLineIndex]\n const lineBg = this._lineColorsContent.get(logicalLine)\n\n if (lineBg) {\n // Fill from after gutter to the end of the LineNumberRenderable\n buffer.fillRect(this.x + gutterWidth, this.y + i, contentWidth, 1, lineBg)\n }\n }\n }\n\n public set showLineNumbers(value: boolean) {\n if (this.gutter) {\n this.gutter.visible = value\n }\n }\n\n public get showLineNumbers(): boolean {\n return this.gutter?.visible ?? false\n }\n\n public get fg(): RGBA {\n return this._fg\n }\n\n public set fg(value: string | RGBA | undefined) {\n const parsed = parseColor(value ?? DEFAULT_GUTTER_FG)\n if (this._fg !== parsed) {\n this._fg = parsed\n this.gutter?.setFg(parsed)\n }\n }\n\n public get bg(): RGBA {\n return this._bg\n }\n\n public set bg(value: string | RGBA | undefined) {\n const parsed = parseColor(value ?? DEFAULT_GUTTER_BG)\n if (this._bg !== parsed) {\n this._bg = parsed\n this.gutter?.setBg(parsed)\n }\n }\n\n public setLineColor(line: number, color: string | RGBA | LineColorConfig): void {\n this.parseLineColor(line, color)\n // Update gutter if it exists\n if (this.gutter) {\n this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent)\n }\n }\n\n public clearLineColor(line: number): void {\n this._lineColorsGutter.delete(line)\n this._lineColorsContent.delete(line)\n if (this.gutter) {\n this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent)\n }\n }\n\n public clearAllLineColors(): void {\n this._lineColorsGutter.clear()\n this._lineColorsContent.clear()\n if (this.gutter) {\n this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent)\n }\n }\n\n public setLineColors(lineColors: Map): void {\n this._lineColorsGutter.clear()\n this._lineColorsContent.clear()\n for (const [line, color] of lineColors) {\n this.parseLineColor(line, color)\n }\n // Update gutter once after all colors are set\n if (this.gutter) {\n this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent)\n }\n }\n\n public getLineColors(): { gutter: Map; content: Map } {\n return {\n gutter: this._lineColorsGutter,\n content: this._lineColorsContent,\n }\n }\n\n public setLineSign(line: number, sign: LineSign): void {\n this._lineSigns.set(line, sign)\n if (this.gutter) {\n this.gutter.setLineSigns(this._lineSigns)\n }\n }\n\n public clearLineSign(line: number): void {\n this._lineSigns.delete(line)\n if (this.gutter) {\n this.gutter.setLineSigns(this._lineSigns)\n }\n }\n\n public clearAllLineSigns(): void {\n this._lineSigns.clear()\n if (this.gutter) {\n this.gutter.setLineSigns(this._lineSigns)\n }\n }\n\n public setLineSigns(lineSigns: Map): void {\n this._lineSigns.clear()\n for (const [line, sign] of lineSigns) {\n this._lineSigns.set(line, sign)\n }\n if (this.gutter) {\n this.gutter.setLineSigns(this._lineSigns)\n }\n }\n\n public getLineSigns(): Map {\n return this._lineSigns\n }\n\n public set lineNumberOffset(value: number) {\n if (this._lineNumberOffset !== value) {\n this._lineNumberOffset = value\n if (this.gutter) {\n // Update the gutter's offset using its setter\n this.gutter.setLineNumberOffset(value)\n }\n }\n }\n\n public get lineNumberOffset(): number {\n return this._lineNumberOffset\n }\n\n public setHideLineNumbers(hideLineNumbers: Set): void {\n this._hideLineNumbers = hideLineNumbers\n if (this.gutter) {\n // Update the gutter's hideLineNumbers using its setter\n this.gutter.setHideLineNumbers(hideLineNumbers)\n }\n }\n\n public getHideLineNumbers(): Set {\n return this._hideLineNumbers\n }\n\n public setLineNumbers(lineNumbers: Map): void {\n this._lineNumbers = lineNumbers\n if (this.gutter) {\n // Update the gutter's lineNumbers using its setter\n this.gutter.setLineNumbers(lineNumbers)\n }\n }\n\n public getLineNumbers(): Map {\n return this._lineNumbers\n }\n\n public highlightLines(startLine: number, endLine: number, color: string | RGBA | LineColorConfig): void {\n for (let i = startLine; i <= endLine; i++) {\n this.parseLineColor(i, color)\n }\n if (this.gutter) {\n this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent)\n }\n }\n\n public clearHighlightLines(startLine: number, endLine: number): void {\n for (let i = startLine; i <= endLine; i++) {\n this._lineColorsGutter.delete(i)\n this._lineColorsContent.delete(i)\n }\n if (this.gutter) {\n this.gutter.setLineColors(this._lineColorsGutter, this._lineColorsContent)\n }\n }\n}\n", + "/**\n * Parses a unified diff format patch into a structured patch object.\n *\n * `parsePatch` has some understanding of Git's particular dialect of unified diff format.\n * When parsing a Git patch, each index in the result may contain additional\n * fields (`isRename`, `isBinary`, etc) not included in the data structure returned by\n * `structuredPatch`; see the `StructuredPatch` interface for a full list.\n *\n * @return a JSON object representation of the patch, suitable for use with the `applyPatch`\n * method. This parses to the same structure returned by `structuredPatch`, except that\n * `oldFileName` and `newFileName` may be `undefined` if the patch doesn't contain enough\n * information to determine them (e.g. a hunk-only patch with no file headers).\n */\nexport function parsePatch(uniDiff) {\n const diffstr = uniDiff.split(/\\n/), list = [];\n let i = 0;\n // These helper functions identify line types that can appear between files\n // in a multi-file patch. Keeping them in one place avoids subtle\n // inconsistencies from having the same regexes duplicated in multiple places.\n // Matches `diff --git ...` lines specifically.\n function isGitDiffHeader(line) {\n return (/^diff --git /).test(line);\n }\n // Matches lines that denote the start of a new diff's section in a\n // multi-file patch: `diff --git ...`, `Index: ...`, or `diff -r ...`.\n function isDiffHeader(line) {\n return isGitDiffHeader(line)\n || (/^Index:\\s/).test(line)\n || (/^diff(?: -r \\w+)+\\s/).test(line);\n }\n // Matches `--- ...` and `+++ ...` file header lines.\n function isFileHeader(line) {\n return (/^(---|\\+\\+\\+)\\s/).test(line);\n }\n // Matches `@@ ...` hunk header lines.\n function isHunkHeader(line) {\n return (/^@@\\s/).test(line);\n }\n function parseIndex() {\n var _a;\n const index = {};\n index.hunks = [];\n list.push(index);\n // Parse diff metadata\n let seenDiffHeader = false;\n while (i < diffstr.length) {\n const line = diffstr[i];\n // File header (---, +++) or hunk header (@@) found; end parsing diff metadata\n if (isFileHeader(line) || isHunkHeader(line)) {\n break;\n }\n // The next two branches handle recognized diff headers. Note that\n // isDiffHeader deliberately does NOT match arbitrary `diff`\n // commands like `diff -u -p -r1.1 -r1.2`, because in some\n // formats (e.g. CVS diffs) such lines appear as metadata within\n // a single file's header section, after an `Index:` line. See the\n // diffx documentation (https://diffx.org) for examples.\n //\n // In both branches: if we've already seen a diff header for *this*\n // file and now we encounter another one, it must belong to the\n // next file, so break.\n if (isGitDiffHeader(line)) {\n if (seenDiffHeader) {\n return;\n }\n seenDiffHeader = true;\n index.isGit = true;\n // Parse the old and new filenames from the `diff --git` header and\n // tentatively set oldFileName and newFileName from them. These may\n // be overridden below by `rename from` / `rename to` or `copy from` /\n // `copy to` extended headers, or by --- and +++ lines. But for Git\n // diffs that lack all of those (e.g. mode-only changes, binary\n // file changes without rename), these are the only filenames we\n // get.\n // parseGitDiffHeader returns null if the header can't be parsed\n // (e.g. unterminated quoted filename, or unexpected format). In\n // that case we skip setting filenames here; they may still be\n // set from --- / +++ or rename from / rename to lines below.\n const paths = parseGitDiffHeader(line);\n if (paths) {\n index.oldFileName = paths.oldFileName;\n index.newFileName = paths.newFileName;\n }\n // Consume Git extended headers (`old mode`, `new mode`, `rename from`,\n // `rename to`, `similarity index`, `index`, `Binary files ... differ`,\n // etc.)\n i++;\n while (i < diffstr.length) {\n const extLine = diffstr[i];\n // Stop consuming extended headers if we hit a file header,\n // hunk header, or another diff header.\n if (isFileHeader(extLine) || isHunkHeader(extLine) || isDiffHeader(extLine)) {\n break;\n }\n // Parse `rename from` / `rename to` lines - these give us\n // unambiguous filenames. These lines don't include the\n // a/ and b/ prefixes that appear in the `diff --git` header\n // and --- / +++ lines, so we add them for consistency.\n // Git C-style quotes filenames containing special characters\n // (tabs, newlines, backslashes, double quotes), so we must\n // unquote them when present.\n const renameFromMatch = (/^rename from (.*)/).exec(extLine);\n if (renameFromMatch) {\n index.oldFileName = 'a/' + unquoteIfQuoted(renameFromMatch[1]);\n index.isRename = true;\n }\n const renameToMatch = (/^rename to (.*)/).exec(extLine);\n if (renameToMatch) {\n index.newFileName = 'b/' + unquoteIfQuoted(renameToMatch[1]);\n index.isRename = true;\n }\n // Parse copy from / copy to lines similarly\n const copyFromMatch = (/^copy from (.*)/).exec(extLine);\n if (copyFromMatch) {\n index.oldFileName = 'a/' + unquoteIfQuoted(copyFromMatch[1]);\n index.isCopy = true;\n }\n const copyToMatch = (/^copy to (.*)/).exec(extLine);\n if (copyToMatch) {\n index.newFileName = 'b/' + unquoteIfQuoted(copyToMatch[1]);\n index.isCopy = true;\n }\n const newFileModeMatch = (/^new file mode (\\d+)/).exec(extLine);\n if (newFileModeMatch) {\n index.isCreate = true;\n index.newMode = newFileModeMatch[1];\n }\n const deletedFileModeMatch = (/^deleted file mode (\\d+)/).exec(extLine);\n if (deletedFileModeMatch) {\n index.isDelete = true;\n index.oldMode = deletedFileModeMatch[1];\n }\n const oldModeMatch = (/^old mode (\\d+)/).exec(extLine);\n if (oldModeMatch) {\n index.oldMode = oldModeMatch[1];\n }\n const newModeMatch = (/^new mode (\\d+)/).exec(extLine);\n if (newModeMatch) {\n index.newMode = newModeMatch[1];\n }\n if ((/^Binary files /).test(extLine)) {\n index.isBinary = true;\n }\n i++;\n }\n continue;\n }\n else if (isDiffHeader(line)) {\n if (seenDiffHeader) {\n return;\n }\n seenDiffHeader = true;\n // For Mercurial-style headers like\n // diff -r 9117c6561b0b -r 273ce12ad8f1 .hgignore\n // or Index: headers like\n // Index: something with multiple words\n // we extract the trailing filename as the index.\n //\n // TODO: It seems awkward that we indiscriminately trim off\n // trailing whitespace here. Theoretically, couldn't that\n // be meaningful - e.g. if the patch represents a diff of a\n // file whose name ends with a space? Seems wrong to nuke\n // it. But this behaviour has been around since v2.2.1 in\n // 2015, so if it's going to change, it should be done\n // cautiously and in a new major release, for\n // backwards-compat reasons.\n // -- ExplodingCabbage\n const headerMatch = (/^(?:Index:|diff(?: -r \\w+)+)\\s+/).exec(line);\n if (headerMatch) {\n index.index = line.substring(headerMatch[0].length).trim();\n }\n }\n i++;\n }\n // Parse file headers if they are defined. Unified diff requires them, but\n // there's no technical issues to have an isolated hunk without file header\n parseFileHeader(index);\n parseFileHeader(index);\n // If we got one file header but not the other, that's a malformed patch.\n if ((index.oldFileName === undefined) !== (index.newFileName === undefined)) {\n throw new Error('Missing ' + (index.oldFileName !== undefined ? '\"+++ ...\"' : '\"--- ...\"')\n + ' file header for ' + ((_a = index.oldFileName) !== null && _a !== void 0 ? _a : index.newFileName));\n }\n while (i < diffstr.length) {\n const line = diffstr[i];\n if (isDiffHeader(line) || isFileHeader(line) || (/^===================================================================/).test(line)) {\n break;\n }\n else if (isHunkHeader(line)) {\n index.hunks.push(parseHunk());\n }\n else {\n // Skip blank lines and any other unrecognized content between\n // or after hunks. Real-world examples of such content include:\n // - `Only in
    : ` from GNU `diff -r`\n // - `Property changes on:` sections from `svn diff`\n // - Trailing prose or commentary in email patches\n // GNU `patch` tolerates all of these, and so do we.\n i++;\n }\n }\n }\n /**\n * Parses the old and new filenames from a `diff --git` header line.\n *\n * The format is:\n * diff --git a/ b/\n *\n * When filenames contain special characters (including newlines, tabs,\n * backslashes, or double quotes), Git quotes them with C-style escaping:\n * diff --git \"a/file\\twith\\ttabs.txt\" \"b/file\\twith\\ttabs.txt\"\n *\n * When filenames don't contain special characters and the old and new names\n * are the same, we can unambiguously split on ` b/` by finding where the\n * two halves (including their a/ and b/ prefixes) yield matching bare names.\n *\n * A pathological case exists in which we cannot reliably determine the paths\n * from the `diff --git` header. This case is when the following are true:\n * - the old and new file paths differ\n * - they are both unquoted (i.e. contain no special characters)\n * - at least one of the underlying file paths includes the substring ` b/`\n * In this scenario, we do not know which occurrence of ` b/` indicates the\n * start of the new file path, so the header is inherently ambiguous. We thus\n * select a possible interpretation arbitrarily and return that.\n *\n * Fortunately, this ambiguity should never matter, because in any patch\n * genuinely output by Git in which this pathological scenario occurs, there\n * must also be `rename from`/`rename to` or `copy from`/`copy to` extended\n * headers present below the `diff --git` header. `parseIndex` will parse\n * THOSE headers, from which we CAN unambiguously determine the filenames,\n * and will discard the result returned by this function.\n *\n * Returns null if the header can't be parsed at all — e.g. a quoted filename\n * has an unterminated quote, or if the unquoted header doesn't match the\n * expected `a/... b/...` format. In that case, the caller (parseIndex)\n * skips setting oldFileName/newFileName from this header, but they may\n * still be set later from `---`/`+++` lines or `rename from`/`rename to`\n * extended headers; if none of those are present either, they'll remain\n * undefined in the output.\n */\n function parseGitDiffHeader(line) {\n // Strip the \"diff --git \" prefix\n const rest = line.substring('diff --git '.length);\n // Handle quoted paths: \"a/path\" \"b/path\"\n // Git quotes paths when they contain characters like newlines, tabs,\n // backslashes, or double quotes (but notably not spaces).\n if (rest.startsWith('\"')) {\n const oldPath = parseQuotedFileName(rest);\n if (oldPath === null) {\n return null;\n }\n const afterOld = rest.substring(oldPath.rawLength + 1); // +1 for space\n let newFileName;\n if (afterOld.startsWith('\"')) {\n const newPath = parseQuotedFileName(afterOld);\n if (newPath === null) {\n return null;\n }\n newFileName = newPath.fileName;\n }\n else {\n newFileName = afterOld;\n }\n return {\n oldFileName: oldPath.fileName,\n newFileName\n };\n }\n // Check if the second path is quoted\n // e.g. diff --git a/simple \"b/renamed\\nnewline.txt\"\n const quoteIdx = rest.indexOf('\"');\n if (quoteIdx > 0) {\n const oldFileName = rest.substring(0, quoteIdx - 1);\n const newPath = parseQuotedFileName(rest.substring(quoteIdx));\n if (newPath === null) {\n return null;\n }\n return {\n oldFileName,\n newFileName: newPath.fileName\n };\n }\n // Unquoted paths. Try to find the split point.\n // The format is: a/ b/\n //\n // Note the potential ambiguity caused by the possibility of the file paths\n // themselves containing the substring ` b/`, plus the pathological case\n // described in the comment above.\n //\n // Strategy: find all occurrences of \" b/\" and split on the middle\n // one. When old and new names are the same (which is the only case where\n // we can't rely on extended headers later in the patch so HAVE to get\n // this right), this will always be the correct split.\n if (rest.startsWith('a/')) {\n const splits = [];\n let idx = 0;\n while (true) {\n idx = rest.indexOf(' b/', idx + 1);\n if (idx === -1) {\n break;\n }\n splits.push(idx);\n }\n if (splits.length > 0) {\n const mid = splits[Math.floor(splits.length / 2)];\n return {\n oldFileName: rest.substring(0, mid),\n newFileName: rest.substring(mid + 1)\n };\n }\n }\n // Fallback: can't parse, return null\n return null;\n }\n /**\n * If `s` starts with a double quote, unquotes it using C-style escape\n * rules (as used by Git). Otherwise returns `s` as-is.\n */\n function unquoteIfQuoted(s) {\n if (s.startsWith('\"')) {\n const parsed = parseQuotedFileName(s);\n if (parsed) {\n return parsed.fileName;\n }\n }\n return s;\n }\n /**\n * Parses a C-style quoted filename as used by Git or GNU `diff -u`.\n * Returns the unescaped filename and the raw length consumed (including quotes).\n */\n function parseQuotedFileName(s) {\n if (!s.startsWith('\"')) {\n return null;\n }\n let result = '';\n let j = 1; // skip opening quote\n while (j < s.length) {\n if (s[j] === '\"') {\n return { fileName: result, rawLength: j + 1 };\n }\n if (s[j] === '\\\\' && j + 1 < s.length) {\n j++;\n switch (s[j]) {\n case 'a':\n result += '\\x07';\n break;\n case 'b':\n result += '\\b';\n break;\n case 'f':\n result += '\\f';\n break;\n case 'n':\n result += '\\n';\n break;\n case 'r':\n result += '\\r';\n break;\n case 't':\n result += '\\t';\n break;\n case 'v':\n result += '\\v';\n break;\n case '\\\\':\n result += '\\\\';\n break;\n case '\"':\n result += '\"';\n break;\n case '0':\n case '1':\n case '2':\n case '3':\n case '4':\n case '5':\n case '6':\n case '7': {\n // C-style octal escapes represent raw bytes. Collect\n // consecutive octal-escaped bytes and decode as UTF-8.\n // Validate that we have a full 3-digit octal escape\n if (j + 2 >= s.length || s[j + 1] < '0' || s[j + 1] > '7' || s[j + 2] < '0' || s[j + 2] > '7') {\n return null;\n }\n const bytes = [parseInt(s.substring(j, j + 3), 8)];\n j += 3;\n while (s[j] === '\\\\' && s[j + 1] >= '0' && s[j + 1] <= '7') {\n if (j + 3 >= s.length || s[j + 2] < '0' || s[j + 2] > '7' || s[j + 3] < '0' || s[j + 3] > '7') {\n return null;\n }\n bytes.push(parseInt(s.substring(j + 1, j + 4), 8));\n j += 4;\n }\n result += new TextDecoder('utf-8').decode(new Uint8Array(bytes));\n continue; // j already points at the next character\n }\n // Note that in C, there are also three kinds of hex escape sequences:\n // - \\xhh\n // - \\uhhhh\n // - \\Uhhhhhhhh\n // We do not bother to parse them here because, so far as we know,\n // they are never emitted by any tools that generate unified diff\n // format diffs, and so for now jsdiff does not consider them legal.\n default: return null;\n }\n }\n else {\n result += s[j];\n }\n j++;\n }\n // Unterminated quote\n return null;\n }\n // Parses the --- and +++ headers, if none are found, no lines\n // are consumed.\n function parseFileHeader(index) {\n const fileHeaderMatch = (/^(---|\\+\\+\\+)\\s+/).exec(diffstr[i]);\n if (fileHeaderMatch) {\n const prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split('\\t', 2), header = (data[1] || '').trim();\n let fileName = data[0];\n if (fileName.startsWith('\"')) {\n fileName = unquoteIfQuoted(fileName);\n }\n else {\n fileName = fileName.replace(/\\\\\\\\/g, '\\\\');\n }\n if (prefix === '---') {\n index.oldFileName = fileName;\n index.oldHeader = header;\n }\n else {\n index.newFileName = fileName;\n index.newHeader = header;\n }\n i++;\n }\n }\n // Parses a hunk\n // This assumes that we are at the start of a hunk.\n function parseHunk() {\n var _a;\n const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/);\n const hunk = {\n oldStart: +chunkHeader[1],\n oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2],\n newStart: +chunkHeader[3],\n newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4],\n lines: []\n };\n // Unified Diff Format quirk: If the chunk size is 0,\n // the first number is one lower than one would expect.\n // https://www.artima.com/weblogs/viewpost.jsp?thread=164293\n if (hunk.oldLines === 0) {\n hunk.oldStart += 1;\n }\n if (hunk.newLines === 0) {\n hunk.newStart += 1;\n }\n let addCount = 0, removeCount = 0;\n for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a = diffstr[i]) === null || _a === void 0 ? void 0 : _a.startsWith('\\\\'))); i++) {\n const operation = (diffstr[i].length == 0 && i != (diffstr.length - 1)) ? ' ' : diffstr[i][0];\n if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\\\') {\n hunk.lines.push(diffstr[i]);\n if (operation === '+') {\n addCount++;\n }\n else if (operation === '-') {\n removeCount++;\n }\n else if (operation === ' ') {\n addCount++;\n removeCount++;\n }\n }\n else {\n throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);\n }\n }\n // Handle the empty block count case\n if (!addCount && hunk.newLines === 1) {\n hunk.newLines = 0;\n }\n if (!removeCount && hunk.oldLines === 1) {\n hunk.oldLines = 0;\n }\n // Perform sanity checking\n if (addCount !== hunk.newLines) {\n throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1));\n }\n if (removeCount !== hunk.oldLines) {\n throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1));\n }\n // Check for extra hunk-body-like lines after the declared line counts\n // were exhausted. If the very next line starts with ' ', '+', or '-',\n // the hunk's line counts were probably wrong — unless it's a file\n // header (--- or +++), which legitimately appears immediately after a\n // hunk in multi-file diffs without Index lines.\n if (i < diffstr.length && diffstr[i] && (/^[+ -]/).test(diffstr[i])\n && !isFileHeader(diffstr[i])) {\n throw new Error('Hunk at line ' + (chunkHeaderIndex + 1)\n + ' has more lines than expected (expected '\n + hunk.oldLines + ' old lines and ' + hunk.newLines + ' new lines)');\n }\n return hunk;\n }\n while (i < diffstr.length) {\n parseIndex();\n }\n return list;\n}\n", + "import { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport type { RenderContext } from \"../types.js\"\nimport { CodeRenderable, type CodeOptions } from \"./Code.js\"\nimport { LineNumberRenderable, type LineSign, type LineColorConfig } from \"./LineNumberRenderable.js\"\nimport { RGBA, parseColor } from \"../lib/RGBA.js\"\nimport { SyntaxStyle } from \"../syntax-style.js\"\nimport { parsePatch, type StructuredPatch } from \"diff\"\nimport { TextRenderable } from \"./Text.js\"\nimport type { TreeSitterClient } from \"../lib/tree-sitter/index.js\"\nimport type { MouseEvent } from \"../renderer.js\"\n\ninterface LogicalLine {\n content: string\n lineNum?: number\n hideLineNumber?: boolean\n color?: string | RGBA\n sign?: LineSign\n type: \"context\" | \"add\" | \"remove\" | \"empty\"\n hunkStart?: boolean\n}\n\nexport interface DiffRenderableOptions extends RenderableOptions {\n diff?: string\n syncScroll?: boolean\n view?: \"unified\" | \"split\"\n\n // CodeRenderable options\n fg?: string | RGBA\n filetype?: string\n syntaxStyle?: SyntaxStyle\n wrapMode?: \"word\" | \"char\" | \"none\"\n conceal?: boolean\n selectionBg?: string | RGBA\n selectionFg?: string | RGBA\n treeSitterClient?: TreeSitterClient\n\n // LineNumberRenderable options\n showLineNumbers?: boolean\n lineNumberFg?: string | RGBA\n lineNumberBg?: string | RGBA\n\n // Diff styling\n addedBg?: string | RGBA\n removedBg?: string | RGBA\n contextBg?: string | RGBA\n addedContentBg?: string | RGBA\n removedContentBg?: string | RGBA\n contextContentBg?: string | RGBA\n addedSignColor?: string | RGBA\n removedSignColor?: string | RGBA\n addedLineNumberBg?: string | RGBA\n removedLineNumberBg?: string | RGBA\n}\n\nexport class DiffRenderable extends Renderable {\n private _diff: string\n private _syncScroll: boolean = false\n private _view: \"unified\" | \"split\"\n private _parsedDiff: StructuredPatch | null = null\n private _parseError: Error | null = null\n // Source-line anchors for hunk starts; native extmarks should eventually own these anchors.\n private _hunkStartLines: number[] = []\n private _hunkRowOffsets: number[] | null = null\n\n // CodeRenderable options\n private _fg?: RGBA\n private _filetype?: string\n private _syntaxStyle?: SyntaxStyle\n private _wrapMode?: \"word\" | \"char\" | \"none\"\n private _conceal: boolean\n private _selectionBg?: RGBA\n private _selectionFg?: RGBA\n private _treeSitterClient?: TreeSitterClient\n\n // LineNumberRenderable options\n private _showLineNumbers: boolean\n private _lineNumberFg: RGBA\n private _lineNumberBg: RGBA\n\n // Diff styling\n private _addedBg: RGBA\n private _removedBg: RGBA\n private _contextBg: RGBA\n private _addedContentBg: RGBA | null\n private _removedContentBg: RGBA | null\n private _contextContentBg: RGBA | null\n private _addedSignColor: RGBA\n private _removedSignColor: RGBA\n private _addedLineNumberBg: RGBA\n private _removedLineNumberBg: RGBA\n\n private leftSide: LineNumberRenderable | null = null\n private rightSide: LineNumberRenderable | null = null\n\n private leftSideAdded: boolean = false\n private rightSideAdded: boolean = false\n\n private leftCodeRenderable: CodeRenderable | null = null\n private rightCodeRenderable: CodeRenderable | null = null\n\n private pendingRebuild: boolean = false\n private _lastWidth: number = 0\n\n private errorTextRenderable: TextRenderable | null = null\n private errorCodeRenderable: CodeRenderable | null = null\n\n private _waitingForHighlight: boolean = false\n private _lineInfoChangeHandler: (() => void) | null = null\n\n constructor(ctx: RenderContext, options: DiffRenderableOptions) {\n super(ctx, {\n ...options,\n flexDirection: options.view === \"split\" ? \"row\" : \"column\",\n })\n\n this._diff = options.diff ?? \"\"\n this._syncScroll = options.syncScroll ?? false\n this._view = options.view ?? \"unified\"\n\n // CodeRenderable options\n this._fg = options.fg ? parseColor(options.fg) : undefined\n this._filetype = options.filetype\n this._syntaxStyle = options.syntaxStyle\n this._wrapMode = options.wrapMode\n this._conceal = options.conceal ?? false\n this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : undefined\n this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : undefined\n this._treeSitterClient = options.treeSitterClient\n\n // LineNumberRenderable options\n this._showLineNumbers = options.showLineNumbers ?? true\n this._lineNumberFg = parseColor(options.lineNumberFg ?? \"#888888\")\n this._lineNumberBg = parseColor(options.lineNumberBg ?? \"transparent\")\n\n // Diff styling\n this._addedBg = parseColor(options.addedBg ?? \"#1a4d1a\")\n this._removedBg = parseColor(options.removedBg ?? \"#4d1a1a\")\n this._contextBg = parseColor(options.contextBg ?? \"transparent\")\n this._addedContentBg = options.addedContentBg ? parseColor(options.addedContentBg) : null\n this._removedContentBg = options.removedContentBg ? parseColor(options.removedContentBg) : null\n this._contextContentBg = options.contextContentBg ? parseColor(options.contextContentBg) : null\n this._addedSignColor = parseColor(options.addedSignColor ?? \"#22c55e\")\n this._removedSignColor = parseColor(options.removedSignColor ?? \"#ef4444\")\n this._addedLineNumberBg = parseColor(options.addedLineNumberBg ?? \"transparent\")\n this._removedLineNumberBg = parseColor(options.removedLineNumberBg ?? \"transparent\")\n\n if (this._diff) {\n this.parseDiff()\n this.buildView()\n }\n }\n\n private parseDiff(): void {\n if (!this._diff) {\n this._parsedDiff = null\n this._parseError = null\n return\n }\n\n try {\n const patches = parsePatch(this._diff)\n\n if (patches.length === 0) {\n this._parsedDiff = null\n this._parseError = null\n return\n }\n\n this._parsedDiff = patches[0]\n this._parseError = null\n } catch (error) {\n this._parsedDiff = null\n this._parseError = error instanceof Error ? error : new Error(String(error))\n }\n }\n\n private buildView(): void {\n this._hunkStartLines = []\n this.invalidateHunkRowOffsets()\n\n if (this._parseError) {\n this.buildErrorView()\n return\n }\n\n if (!this._parsedDiff || this._parsedDiff.hunks.length === 0) {\n return\n }\n\n if (this._view === \"unified\") {\n this.buildUnifiedView()\n } else {\n this.buildSplitView()\n }\n }\n\n protected override onMouseEvent(event: MouseEvent): void {\n if (event.type !== \"scroll\" || this._view !== \"split\" || !this._syncScroll) return\n if (!this.leftCodeRenderable || !this.rightCodeRenderable) return\n if (!event.target) return\n\n if (this.isInsideSide(event.target, \"left\")) {\n this.rightCodeRenderable.scrollY = this.leftCodeRenderable.scrollY\n this.rightCodeRenderable.scrollX = this.leftCodeRenderable.scrollX\n } else if (this.isInsideSide(event.target, \"right\")) {\n this.leftCodeRenderable.scrollY = this.rightCodeRenderable.scrollY\n this.leftCodeRenderable.scrollX = this.rightCodeRenderable.scrollX\n }\n }\n\n private isInsideSide(target: Renderable | null, side: \"left\" | \"right\"): boolean {\n const container = side === \"left\" ? this.leftCodeRenderable : this.rightCodeRenderable\n let current = target\n while (current) {\n if (current === container) return true\n current = current.parent\n }\n return false\n }\n\n protected override onResize(width: number, height: number): void {\n super.onResize(width, height)\n\n if (this._view === \"split\" && this._wrapMode !== \"none\" && this._wrapMode !== undefined) {\n if (this._lastWidth !== width) {\n this._lastWidth = width\n this.requestRebuild()\n }\n }\n }\n\n private requestRebuild(): void {\n if (this.pendingRebuild) {\n return\n }\n\n this.pendingRebuild = true\n queueMicrotask(() => {\n if (!this.isDestroyed && this.pendingRebuild) {\n this.pendingRebuild = false\n this.buildView()\n this.requestRender()\n }\n })\n }\n\n private invalidateHunkRowOffsets(): void {\n this._hunkRowOffsets = null\n }\n\n private rebuildView(): void {\n if (this._view === \"split\") {\n this.requestRebuild()\n } else {\n this.buildView()\n }\n }\n\n private handleLineInfoChange = (): void => {\n // Wrapping or async concealment can change the visual row for an existing hunk anchor.\n this.invalidateHunkRowOffsets()\n\n if (!this._waitingForHighlight) return\n if (!this.leftCodeRenderable || !this.rightCodeRenderable) return\n\n const leftIsHighlighting = this.leftCodeRenderable.isHighlighting\n const rightIsHighlighting = this.rightCodeRenderable.isHighlighting\n\n if (!leftIsHighlighting && !rightIsHighlighting) {\n this._waitingForHighlight = false\n this.requestRebuild()\n }\n }\n\n private attachLineInfoListeners(): void {\n if (!this.leftCodeRenderable && !this.rightCodeRenderable) return\n\n // Hunk offsets depend on lineInfo even when syncScroll is off.\n this._lineInfoChangeHandler ??= this.handleLineInfoChange\n if (this.leftCodeRenderable) {\n this.leftCodeRenderable.off(\"line-info-change\", this._lineInfoChangeHandler)\n this.leftCodeRenderable.on(\"line-info-change\", this._lineInfoChangeHandler)\n }\n if (this.rightCodeRenderable) {\n this.rightCodeRenderable.off(\"line-info-change\", this._lineInfoChangeHandler)\n this.rightCodeRenderable.on(\"line-info-change\", this._lineInfoChangeHandler)\n }\n }\n\n private detachLineInfoListeners(): void {\n if (!this._lineInfoChangeHandler) return\n\n if (this.leftCodeRenderable) {\n this.leftCodeRenderable.off(\"line-info-change\", this._lineInfoChangeHandler)\n }\n if (this.rightCodeRenderable) {\n this.rightCodeRenderable.off(\"line-info-change\", this._lineInfoChangeHandler)\n }\n this._lineInfoChangeHandler = null\n }\n\n public override destroyRecursively(): void {\n this.detachLineInfoListeners()\n this.pendingRebuild = false\n this.leftSideAdded = false\n this.rightSideAdded = false\n super.destroyRecursively()\n }\n\n private buildErrorView(): void {\n this.flexDirection = \"column\"\n\n if (this.leftSide && this.leftSideAdded) {\n super.remove(this.leftSide.id)\n this.leftSideAdded = false\n }\n if (this.rightSide && this.rightSideAdded) {\n super.remove(this.rightSide.id)\n this.rightSideAdded = false\n }\n\n const errorMessage = `Error parsing diff: ${this._parseError?.message || \"Unknown error\"}\\n`\n if (!this.errorTextRenderable) {\n this.errorTextRenderable = new TextRenderable(this.ctx, {\n id: this.id ? `${this.id}-error-text` : undefined,\n content: errorMessage,\n fg: \"#ef4444\",\n width: \"100%\",\n flexShrink: 0,\n })\n super.add(this.errorTextRenderable)\n } else {\n this.errorTextRenderable.content = errorMessage\n const errorTextIndex = this.getChildren().indexOf(this.errorTextRenderable)\n if (errorTextIndex === -1) {\n super.add(this.errorTextRenderable)\n }\n }\n\n if (!this.errorCodeRenderable) {\n this.errorCodeRenderable = new CodeRenderable(this.ctx, {\n id: this.id ? `${this.id}-error-code` : undefined,\n content: this._diff,\n filetype: \"diff\",\n syntaxStyle: this._syntaxStyle ?? SyntaxStyle.create(),\n wrapMode: this._wrapMode,\n conceal: this._conceal,\n width: \"100%\",\n flexGrow: 1,\n flexShrink: 1,\n ...(this._treeSitterClient !== undefined && { treeSitterClient: this._treeSitterClient }),\n })\n super.add(this.errorCodeRenderable)\n } else {\n this.errorCodeRenderable.content = this._diff\n this.errorCodeRenderable.wrapMode = this._wrapMode ?? \"none\"\n if (this._syntaxStyle) {\n this.errorCodeRenderable.syntaxStyle = this._syntaxStyle\n }\n const errorCodeIndex = this.getChildren().indexOf(this.errorCodeRenderable)\n if (errorCodeIndex === -1) {\n super.add(this.errorCodeRenderable)\n }\n }\n }\n\n private createOrUpdateCodeRenderable(\n side: \"left\" | \"right\",\n content: string,\n wrapMode: \"word\" | \"char\" | \"none\" | undefined,\n drawUnstyledText?: boolean,\n ): CodeRenderable {\n const existingRenderable = side === \"left\" ? this.leftCodeRenderable : this.rightCodeRenderable\n\n if (!existingRenderable) {\n const codeOptions: CodeOptions = {\n id: this.id ? `${this.id}-${side}-code` : undefined,\n content,\n filetype: this._filetype,\n wrapMode,\n conceal: this._conceal,\n syntaxStyle: this._syntaxStyle ?? SyntaxStyle.create(),\n width: \"100%\",\n height: \"100%\",\n ...(this._fg !== undefined && { fg: this._fg }),\n ...(drawUnstyledText !== undefined && { drawUnstyledText }),\n ...(this._selectionBg !== undefined && { selectionBg: this._selectionBg }),\n ...(this._selectionFg !== undefined && { selectionFg: this._selectionFg }),\n ...(this._treeSitterClient !== undefined && { treeSitterClient: this._treeSitterClient }),\n }\n const newRenderable = new CodeRenderable(this.ctx, codeOptions)\n\n if (side === \"left\") {\n this.leftCodeRenderable = newRenderable\n } else {\n this.rightCodeRenderable = newRenderable\n }\n\n return newRenderable\n } else {\n existingRenderable.content = content\n existingRenderable.wrapMode = wrapMode ?? \"none\"\n existingRenderable.conceal = this._conceal\n if (drawUnstyledText !== undefined) {\n existingRenderable.drawUnstyledText = drawUnstyledText\n }\n if (this._filetype !== undefined) {\n existingRenderable.filetype = this._filetype\n }\n if (this._syntaxStyle !== undefined) {\n existingRenderable.syntaxStyle = this._syntaxStyle\n }\n if (this._selectionBg !== undefined) {\n existingRenderable.selectionBg = this._selectionBg\n }\n if (this._selectionFg !== undefined) {\n existingRenderable.selectionFg = this._selectionFg\n }\n if (this._fg !== undefined) {\n existingRenderable.fg = this._fg\n }\n\n return existingRenderable\n }\n }\n\n private createOrUpdateSide(\n side: \"left\" | \"right\",\n target: CodeRenderable,\n lineColors: Map,\n lineSigns: Map,\n lineNumbers: Map,\n hideLineNumbers: Set,\n width: \"50%\" | \"100%\",\n ): void {\n const sideRef = side === \"left\" ? this.leftSide : this.rightSide\n const addedFlag = side === \"left\" ? this.leftSideAdded : this.rightSideAdded\n\n if (!sideRef) {\n const newSide = new LineNumberRenderable(this.ctx, {\n id: this.id ? `${this.id}-${side}` : undefined,\n target,\n fg: this._lineNumberFg,\n bg: this._lineNumberBg,\n lineColors,\n lineSigns,\n lineNumbers,\n lineNumberOffset: 0,\n hideLineNumbers,\n width,\n height: \"100%\",\n })\n newSide.showLineNumbers = this._showLineNumbers\n super.add(newSide)\n\n if (side === \"left\") {\n this.leftSide = newSide\n this.leftSideAdded = true\n } else {\n this.rightSide = newSide\n this.rightSideAdded = true\n }\n } else {\n sideRef.width = width\n sideRef.fg = this._lineNumberFg\n sideRef.bg = this._lineNumberBg\n sideRef.setLineColors(lineColors)\n sideRef.setLineSigns(lineSigns)\n sideRef.setLineNumbers(lineNumbers)\n sideRef.setHideLineNumbers(hideLineNumbers)\n\n if (!addedFlag) {\n super.add(sideRef)\n if (side === \"left\") {\n this.leftSideAdded = true\n } else {\n this.rightSideAdded = true\n }\n }\n }\n }\n\n private buildUnifiedView(): void {\n if (!this._parsedDiff) return\n\n this.flexDirection = \"column\"\n\n if (this.errorTextRenderable) {\n const errorTextIndex = this.getChildren().indexOf(this.errorTextRenderable)\n if (errorTextIndex !== -1) {\n super.remove(this.errorTextRenderable.id)\n }\n }\n if (this.errorCodeRenderable) {\n const errorCodeIndex = this.getChildren().indexOf(this.errorCodeRenderable)\n if (errorCodeIndex !== -1) {\n super.remove(this.errorCodeRenderable.id)\n }\n }\n\n const contentLines: string[] = []\n const lineColors = new Map()\n const lineSigns = new Map()\n const lineNumbers = new Map()\n\n let lineIndex = 0\n\n for (const hunk of this._parsedDiff.hunks) {\n // Unified view flattens hunks directly into the left CodeRenderable line stream.\n this._hunkStartLines.push(lineIndex)\n\n let oldLineNum = hunk.oldStart\n let newLineNum = hunk.newStart\n\n for (const line of hunk.lines) {\n const firstChar = line[0]\n const content = line.slice(1)\n\n if (firstChar === \"+\") {\n contentLines.push(content)\n const config: LineColorConfig = {\n gutter: this._addedLineNumberBg,\n }\n if (this._addedContentBg) {\n config.content = this._addedContentBg\n } else {\n config.content = this._addedBg\n }\n lineColors.set(lineIndex, config)\n lineSigns.set(lineIndex, {\n after: \" +\",\n afterColor: this._addedSignColor,\n })\n lineNumbers.set(lineIndex, newLineNum)\n newLineNum++\n lineIndex++\n } else if (firstChar === \"-\") {\n contentLines.push(content)\n const config: LineColorConfig = {\n gutter: this._removedLineNumberBg,\n }\n if (this._removedContentBg) {\n config.content = this._removedContentBg\n } else {\n config.content = this._removedBg\n }\n lineColors.set(lineIndex, config)\n lineSigns.set(lineIndex, {\n after: \" -\",\n afterColor: this._removedSignColor,\n })\n lineNumbers.set(lineIndex, oldLineNum)\n oldLineNum++\n lineIndex++\n } else if (firstChar === \" \") {\n contentLines.push(content)\n const config: LineColorConfig = {\n gutter: this._lineNumberBg,\n }\n if (this._contextContentBg) {\n config.content = this._contextContentBg\n } else {\n config.content = this._contextBg\n }\n lineColors.set(lineIndex, config)\n lineNumbers.set(lineIndex, newLineNum)\n oldLineNum++\n newLineNum++\n lineIndex++\n }\n }\n }\n\n const content = contentLines.join(\"\\n\")\n\n const codeRenderable = this.createOrUpdateCodeRenderable(\"left\", content, this._wrapMode)\n this.attachLineInfoListeners()\n\n this.createOrUpdateSide(\"left\", codeRenderable, lineColors, lineSigns, lineNumbers, new Set(), \"100%\")\n\n if (this.rightSide && this.rightSideAdded) {\n super.remove(this.rightSide.id)\n this.rightSideAdded = false\n }\n }\n\n private buildSplitView(): void {\n if (!this._parsedDiff) return\n\n this.flexDirection = \"row\"\n\n if (this.errorTextRenderable) {\n const errorTextIndex = this.getChildren().indexOf(this.errorTextRenderable)\n if (errorTextIndex !== -1) {\n super.remove(this.errorTextRenderable.id)\n }\n }\n if (this.errorCodeRenderable) {\n const errorCodeIndex = this.getChildren().indexOf(this.errorCodeRenderable)\n if (errorCodeIndex !== -1) {\n super.remove(this.errorCodeRenderable.id)\n }\n }\n\n const leftLogicalLines: LogicalLine[] = []\n const rightLogicalLines: LogicalLine[] = []\n const hunkFirstLeftLine: number[] = []\n\n for (const hunk of this._parsedDiff.hunks) {\n // Split view may insert padding later, so carry hunk starts through LogicalLine metadata.\n hunkFirstLeftLine.push(leftLogicalLines.length)\n\n let oldLineNum = hunk.oldStart\n let newLineNum = hunk.newStart\n\n let i = 0\n while (i < hunk.lines.length) {\n const line = hunk.lines[i]\n const firstChar = line[0]\n\n if (firstChar === \" \") {\n const content = line.slice(1)\n leftLogicalLines.push({\n content,\n lineNum: oldLineNum,\n color: this._contextBg,\n type: \"context\",\n })\n rightLogicalLines.push({\n content,\n lineNum: newLineNum,\n color: this._contextBg,\n type: \"context\",\n })\n oldLineNum++\n newLineNum++\n i++\n } else if (firstChar === \"\\\\\") {\n i++\n } else {\n const removes: { content: string; lineNum: number }[] = []\n const adds: { content: string; lineNum: number }[] = []\n\n while (i < hunk.lines.length) {\n const currentLine = hunk.lines[i]\n const currentChar = currentLine[0]\n\n if (currentChar === \" \" || currentChar === \"\\\\\") {\n break\n }\n\n const content = currentLine.slice(1)\n\n if (currentChar === \"-\") {\n removes.push({ content, lineNum: oldLineNum })\n oldLineNum++\n } else if (currentChar === \"+\") {\n adds.push({ content, lineNum: newLineNum })\n newLineNum++\n }\n i++\n }\n\n const maxLength = Math.max(removes.length, adds.length)\n\n for (let j = 0; j < maxLength; j++) {\n if (j < removes.length) {\n leftLogicalLines.push({\n content: removes[j].content,\n lineNum: removes[j].lineNum,\n color: this._removedBg,\n sign: {\n after: \" -\",\n afterColor: this._removedSignColor,\n },\n type: \"remove\",\n })\n } else {\n leftLogicalLines.push({\n content: \"\",\n hideLineNumber: true,\n type: \"empty\",\n })\n }\n\n if (j < adds.length) {\n rightLogicalLines.push({\n content: adds[j].content,\n lineNum: adds[j].lineNum,\n color: this._addedBg,\n sign: {\n after: \" +\",\n afterColor: this._addedSignColor,\n },\n type: \"add\",\n })\n } else {\n rightLogicalLines.push({\n content: \"\",\n hideLineNumber: true,\n type: \"empty\",\n })\n }\n }\n }\n }\n }\n\n // Mark before wrap-alignment so padding does not lose the hunk start.\n for (const startIndex of hunkFirstLeftLine) {\n const firstLine = leftLogicalLines[startIndex]\n if (firstLine) firstLine.hunkStart = true\n }\n\n const canDoWrapAlignment = this.width > 0 && (this._wrapMode === \"word\" || this._wrapMode === \"char\")\n\n const preLeftContent = leftLogicalLines.map((l) => l.content).join(\"\\n\")\n const preRightContent = rightLogicalLines.map((l) => l.content).join(\"\\n\")\n\n const needsConsistentConcealing =\n (this._wrapMode === \"word\" || this._wrapMode === \"char\") && this._conceal && this._filetype\n const drawUnstyledText = !needsConsistentConcealing\n const leftCodeRenderable = this.createOrUpdateCodeRenderable(\n \"left\",\n preLeftContent,\n this._wrapMode,\n drawUnstyledText,\n )\n const rightCodeRenderable = this.createOrUpdateCodeRenderable(\n \"right\",\n preRightContent,\n this._wrapMode,\n drawUnstyledText,\n )\n this.attachLineInfoListeners()\n\n let finalLeftLines: LogicalLine[]\n let finalRightLines: LogicalLine[]\n\n const leftIsHighlighting = leftCodeRenderable.isHighlighting\n const rightIsHighlighting = rightCodeRenderable.isHighlighting\n const highlightingInProgress = needsConsistentConcealing && (leftIsHighlighting || rightIsHighlighting)\n\n if (highlightingInProgress) {\n this._waitingForHighlight = true\n this.attachLineInfoListeners()\n }\n\n const shouldDoAlignment = canDoWrapAlignment && !highlightingInProgress\n\n if (shouldDoAlignment) {\n const leftLineInfo = leftCodeRenderable.lineInfo\n const rightLineInfo = rightCodeRenderable.lineInfo\n\n const leftSources = leftLineInfo.lineSources || []\n const rightSources = rightLineInfo.lineSources || []\n\n const leftVisualCounts = new Map()\n const rightVisualCounts = new Map()\n\n for (const logicalLine of leftSources) {\n leftVisualCounts.set(logicalLine, (leftVisualCounts.get(logicalLine) || 0) + 1)\n }\n for (const logicalLine of rightSources) {\n rightVisualCounts.set(logicalLine, (rightVisualCounts.get(logicalLine) || 0) + 1)\n }\n\n finalLeftLines = []\n finalRightLines = []\n\n let leftVisualPos = 0\n let rightVisualPos = 0\n\n for (let i = 0; i < leftLogicalLines.length; i++) {\n const leftLine = leftLogicalLines[i]\n const rightLine = rightLogicalLines[i]\n\n // Concealed logical lines have zero visual rows; counting them as one misaligns split panes.\n const leftVisualCount = leftVisualCounts.get(i) ?? 0\n const rightVisualCount = rightVisualCounts.get(i) ?? 0\n\n if (leftVisualPos < rightVisualPos) {\n const pad = rightVisualPos - leftVisualPos\n for (let p = 0; p < pad; p++) {\n finalLeftLines.push({ content: \"\", hideLineNumber: true, type: \"empty\" })\n }\n leftVisualPos += pad\n } else if (rightVisualPos < leftVisualPos) {\n const pad = leftVisualPos - rightVisualPos\n for (let p = 0; p < pad; p++) {\n finalRightLines.push({ content: \"\", hideLineNumber: true, type: \"empty\" })\n }\n rightVisualPos += pad\n }\n\n finalLeftLines.push(leftLine)\n finalRightLines.push(rightLine)\n\n leftVisualPos += leftVisualCount\n rightVisualPos += rightVisualCount\n }\n\n if (leftVisualPos < rightVisualPos) {\n const pad = rightVisualPos - leftVisualPos\n for (let p = 0; p < pad; p++) {\n finalLeftLines.push({ content: \"\", hideLineNumber: true, type: \"empty\" })\n }\n } else if (rightVisualPos < leftVisualPos) {\n const pad = leftVisualPos - rightVisualPos\n for (let p = 0; p < pad; p++) {\n finalRightLines.push({ content: \"\", hideLineNumber: true, type: \"empty\" })\n }\n }\n } else {\n finalLeftLines = leftLogicalLines\n finalRightLines = rightLogicalLines\n }\n\n const leftLineColors = new Map()\n const rightLineColors = new Map()\n const leftLineSigns = new Map()\n const rightLineSigns = new Map()\n const leftHideLineNumbers = new Set()\n const rightHideLineNumbers = new Set()\n const leftLineNumbers = new Map()\n const rightLineNumbers = new Map()\n\n finalLeftLines.forEach((line, index) => {\n if (line.hunkStart) {\n // After padding, this is the line index CodeRenderable.lineInfo can resolve to a row.\n this._hunkStartLines.push(index)\n }\n if (line.lineNum !== undefined) {\n leftLineNumbers.set(index, line.lineNum)\n }\n if (line.hideLineNumber) {\n leftHideLineNumbers.add(index)\n }\n if (line.type === \"remove\") {\n const config: LineColorConfig = {\n gutter: this._removedLineNumberBg,\n }\n if (this._removedContentBg) {\n config.content = this._removedContentBg\n } else {\n config.content = this._removedBg\n }\n leftLineColors.set(index, config)\n } else if (line.type === \"context\") {\n const config: LineColorConfig = {\n gutter: this._lineNumberBg,\n }\n if (this._contextContentBg) {\n config.content = this._contextContentBg\n } else {\n config.content = this._contextBg\n }\n leftLineColors.set(index, config)\n }\n if (line.sign) {\n leftLineSigns.set(index, line.sign)\n }\n })\n\n finalRightLines.forEach((line, index) => {\n if (line.lineNum !== undefined) {\n rightLineNumbers.set(index, line.lineNum)\n }\n if (line.hideLineNumber) {\n rightHideLineNumbers.add(index)\n }\n if (line.type === \"add\") {\n const config: LineColorConfig = {\n gutter: this._addedLineNumberBg,\n }\n if (this._addedContentBg) {\n config.content = this._addedContentBg\n } else {\n config.content = this._addedBg\n }\n rightLineColors.set(index, config)\n } else if (line.type === \"context\") {\n const config: LineColorConfig = {\n gutter: this._lineNumberBg,\n }\n if (this._contextContentBg) {\n config.content = this._contextContentBg\n } else {\n config.content = this._contextBg\n }\n rightLineColors.set(index, config)\n }\n if (line.sign) {\n rightLineSigns.set(index, line.sign)\n }\n })\n\n const leftContentFinal = finalLeftLines.map((l) => l.content).join(\"\\n\")\n const rightContentFinal = finalRightLines.map((l) => l.content).join(\"\\n\")\n\n leftCodeRenderable.content = leftContentFinal\n rightCodeRenderable.content = rightContentFinal\n\n this.createOrUpdateSide(\n \"left\",\n leftCodeRenderable,\n leftLineColors,\n leftLineSigns,\n leftLineNumbers,\n leftHideLineNumbers,\n \"50%\",\n )\n this.createOrUpdateSide(\n \"right\",\n rightCodeRenderable,\n rightLineColors,\n rightLineSigns,\n rightLineNumbers,\n rightHideLineNumbers,\n \"50%\",\n )\n }\n\n public get diff(): string {\n return this._diff\n }\n\n public set diff(value: string) {\n if (this._diff !== value) {\n this._diff = value\n this._waitingForHighlight = false\n this.parseDiff()\n this.rebuildView()\n }\n }\n\n public get syncScroll(): boolean {\n return this._syncScroll\n }\n\n public set syncScroll(value: boolean) {\n if (this._syncScroll !== value) {\n this._syncScroll = value\n }\n }\n\n public get view(): \"unified\" | \"split\" {\n return this._view\n }\n\n public set view(value: \"unified\" | \"split\") {\n if (this._view !== value) {\n this._view = value\n this.flexDirection = value === \"split\" ? \"row\" : \"column\"\n this.buildView()\n }\n }\n\n public get filetype(): string | undefined {\n return this._filetype\n }\n\n public set filetype(value: string | undefined) {\n if (this._filetype !== value) {\n this._filetype = value\n this.rebuildView()\n }\n }\n\n public get syntaxStyle(): SyntaxStyle | undefined {\n return this._syntaxStyle\n }\n\n public set syntaxStyle(value: SyntaxStyle | undefined) {\n if (this._syntaxStyle !== value) {\n this._syntaxStyle = value\n this.rebuildView()\n }\n }\n\n public get wrapMode(): \"word\" | \"char\" | \"none\" | undefined {\n return this._wrapMode\n }\n\n public set wrapMode(value: \"word\" | \"char\" | \"none\" | undefined) {\n if (this._wrapMode !== value) {\n this._wrapMode = value\n this.invalidateHunkRowOffsets()\n\n if (this._view === \"unified\" && this.leftCodeRenderable) {\n this.leftCodeRenderable.wrapMode = value ?? \"none\"\n } else if (this._view === \"split\") {\n this.requestRebuild()\n }\n }\n }\n\n public get showLineNumbers(): boolean {\n return this._showLineNumbers\n }\n\n public set showLineNumbers(value: boolean) {\n if (this._showLineNumbers !== value) {\n this._showLineNumbers = value\n if (this.leftSide) {\n this.leftSide.showLineNumbers = value\n }\n if (this.rightSide) {\n this.rightSide.showLineNumbers = value\n }\n }\n }\n\n public get addedBg(): RGBA {\n return this._addedBg\n }\n\n public set addedBg(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._addedBg !== parsed) {\n this._addedBg = parsed\n this.rebuildView()\n }\n }\n\n public get removedBg(): RGBA {\n return this._removedBg\n }\n\n public set removedBg(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._removedBg !== parsed) {\n this._removedBg = parsed\n this.rebuildView()\n }\n }\n\n public get contextBg(): RGBA {\n return this._contextBg\n }\n\n public set contextBg(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._contextBg !== parsed) {\n this._contextBg = parsed\n this.rebuildView()\n }\n }\n\n public get addedSignColor(): RGBA {\n return this._addedSignColor\n }\n\n public set addedSignColor(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._addedSignColor !== parsed) {\n this._addedSignColor = parsed\n this.rebuildView()\n }\n }\n\n public get removedSignColor(): RGBA {\n return this._removedSignColor\n }\n\n public set removedSignColor(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._removedSignColor !== parsed) {\n this._removedSignColor = parsed\n this.rebuildView()\n }\n }\n\n public get addedLineNumberBg(): RGBA {\n return this._addedLineNumberBg\n }\n\n public set addedLineNumberBg(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._addedLineNumberBg !== parsed) {\n this._addedLineNumberBg = parsed\n this.rebuildView()\n }\n }\n\n public get removedLineNumberBg(): RGBA {\n return this._removedLineNumberBg\n }\n\n public set removedLineNumberBg(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._removedLineNumberBg !== parsed) {\n this._removedLineNumberBg = parsed\n this.rebuildView()\n }\n }\n\n public get lineNumberFg(): RGBA {\n return this._lineNumberFg\n }\n\n public set lineNumberFg(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._lineNumberFg !== parsed) {\n this._lineNumberFg = parsed\n this.rebuildView()\n }\n }\n\n public get lineNumberBg(): RGBA {\n return this._lineNumberBg\n }\n\n public set lineNumberBg(value: string | RGBA) {\n const parsed = parseColor(value)\n if (this._lineNumberBg !== parsed) {\n this._lineNumberBg = parsed\n this.rebuildView()\n }\n }\n\n public get addedContentBg(): RGBA | null {\n return this._addedContentBg\n }\n\n public set addedContentBg(value: string | RGBA | null) {\n const parsed = value ? parseColor(value) : null\n if (this._addedContentBg !== parsed) {\n this._addedContentBg = parsed\n this.rebuildView()\n }\n }\n\n public get removedContentBg(): RGBA | null {\n return this._removedContentBg\n }\n\n public set removedContentBg(value: string | RGBA | null) {\n const parsed = value ? parseColor(value) : null\n if (this._removedContentBg !== parsed) {\n this._removedContentBg = parsed\n this.rebuildView()\n }\n }\n\n public get contextContentBg(): RGBA | null {\n return this._contextContentBg\n }\n\n public set contextContentBg(value: string | RGBA | null) {\n const parsed = value ? parseColor(value) : null\n if (this._contextContentBg !== parsed) {\n this._contextContentBg = parsed\n this.rebuildView()\n }\n }\n\n public get selectionBg(): RGBA | undefined {\n return this._selectionBg\n }\n\n public set selectionBg(value: string | RGBA | undefined) {\n const parsed = value ? parseColor(value) : undefined\n if (this._selectionBg !== parsed) {\n this._selectionBg = parsed\n if (this.leftCodeRenderable) {\n this.leftCodeRenderable.selectionBg = parsed\n }\n if (this.rightCodeRenderable) {\n this.rightCodeRenderable.selectionBg = parsed\n }\n }\n }\n\n public get selectionFg(): RGBA | undefined {\n return this._selectionFg\n }\n\n public set selectionFg(value: string | RGBA | undefined) {\n const parsed = value ? parseColor(value) : undefined\n if (this._selectionFg !== parsed) {\n this._selectionFg = parsed\n if (this.leftCodeRenderable) {\n this.leftCodeRenderable.selectionFg = parsed\n }\n if (this.rightCodeRenderable) {\n this.rightCodeRenderable.selectionFg = parsed\n }\n }\n }\n\n public get conceal(): boolean {\n return this._conceal\n }\n\n public set conceal(value: boolean) {\n if (this._conceal !== value) {\n this._conceal = value\n this.rebuildView()\n }\n }\n\n public get fg(): RGBA | undefined {\n return this._fg\n }\n\n public set fg(value: string | RGBA | undefined) {\n const parsed = value ? parseColor(value) : undefined\n if (this._fg !== parsed) {\n this._fg = parsed\n if (this.leftCodeRenderable) {\n this.leftCodeRenderable.fg = parsed\n }\n if (this.rightCodeRenderable) {\n this.rightCodeRenderable.fg = parsed\n }\n }\n }\n\n public setLineColor(line: number, color: string | RGBA | LineColorConfig): void {\n this.leftSide?.setLineColor(line, color)\n this.rightSide?.setLineColor(line, color)\n }\n\n public clearLineColor(line: number): void {\n this.leftSide?.clearLineColor(line)\n this.rightSide?.clearLineColor(line)\n }\n\n public setLineColors(lineColors: Map): void {\n this.leftSide?.setLineColors(lineColors)\n this.rightSide?.setLineColors(lineColors)\n }\n\n public clearAllLineColors(): void {\n this.leftSide?.clearAllLineColors()\n this.rightSide?.clearAllLineColors()\n }\n\n public highlightLines(startLine: number, endLine: number, color: string | RGBA | LineColorConfig): void {\n this.leftSide?.highlightLines(startLine, endLine, color)\n this.rightSide?.highlightLines(startLine, endLine, color)\n }\n\n public clearHighlightLines(startLine: number, endLine: number): void {\n this.leftSide?.clearHighlightLines(startLine, endLine)\n this.rightSide?.clearHighlightLines(startLine, endLine)\n }\n\n public getHunkRowOffsets(): number[] {\n if (this._hunkRowOffsets) return [...this._hunkRowOffsets]\n\n this._hunkRowOffsets = this.computeHunkRowOffsets()\n return [...this._hunkRowOffsets]\n }\n\n private computeHunkRowOffsets(): number[] {\n if (this._hunkStartLines.length === 0) return []\n\n // lineInfo composes native wrapping with CodeRenderable's temporary conceal source map.\n // Native extmark row resolution should replace this scan with direct anchor queries.\n const sources = this.leftCodeRenderable?.lineInfo.lineSources\n if (!sources || sources.length === 0) return [...this._hunkStartLines]\n\n const offsets: number[] = []\n let visualRow = 0\n\n for (const hunkStartLine of this._hunkStartLines) {\n // If the exact hunk line is concealed, navigate to the next visible row.\n while (visualRow < sources.length && sources[visualRow] < hunkStartLine) {\n visualRow++\n }\n offsets.push(visualRow < sources.length ? visualRow : hunkStartLine)\n }\n\n return offsets\n }\n}\n", + "import type { KeyEvent, PasteEvent } from \"../lib/KeyHandler.js\"\nimport { decodePasteBytes, stripAnsiSequences } from \"../lib/paste.js\"\nimport { RGBA, parseColor, type ColorInput } from \"../lib/RGBA.js\"\nimport { type RenderContext } from \"../types.js\"\nimport { EditBufferRenderable, type EditBufferOptions } from \"./EditBufferRenderable.js\"\nimport {\n type KeyBinding as BaseKeyBinding,\n mergeKeyBindings,\n buildKeyBindingsMap,\n getKeyBindingAction,\n defaultKeyAliases,\n mergeKeyAliases,\n} from \"../lib/keybinding.internal.js\"\nimport { type StyledText, fg } from \"../lib/styled-text.js\"\nimport type { ExtmarksController } from \"../lib/extmarks.js\"\n\nexport type TextareaAction =\n | \"move-left\"\n | \"move-right\"\n | \"move-up\"\n | \"move-down\"\n | \"select-left\"\n | \"select-right\"\n | \"select-up\"\n | \"select-down\"\n | \"line-home\"\n | \"line-end\"\n | \"select-line-home\"\n | \"select-line-end\"\n | \"visual-line-home\"\n | \"visual-line-end\"\n | \"select-visual-line-home\"\n | \"select-visual-line-end\"\n | \"buffer-home\"\n | \"buffer-end\"\n | \"select-buffer-home\"\n | \"select-buffer-end\"\n | \"delete-line\"\n | \"delete-to-line-end\"\n | \"delete-to-line-start\"\n | \"backspace\"\n | \"delete\"\n | \"newline\"\n | \"undo\"\n | \"redo\"\n | \"word-forward\"\n | \"word-backward\"\n | \"select-word-forward\"\n | \"select-word-backward\"\n | \"delete-word-forward\"\n | \"delete-word-backward\"\n | \"select-all\"\n | \"submit\"\n\nexport type KeyBinding = BaseKeyBinding\nexport type TextareaKeyAliasMap = Record\n\nexport const defaultTextareaKeyBindings: KeyBinding[] = [\n { name: \"left\", action: \"move-left\" },\n { name: \"right\", action: \"move-right\" },\n { name: \"up\", action: \"move-up\" },\n { name: \"down\", action: \"move-down\" },\n { name: \"left\", shift: true, action: \"select-left\" },\n { name: \"right\", shift: true, action: \"select-right\" },\n { name: \"up\", shift: true, action: \"select-up\" },\n { name: \"down\", shift: true, action: \"select-down\" },\n { name: \"home\", action: \"buffer-home\" },\n { name: \"end\", action: \"buffer-end\" },\n { name: \"home\", shift: true, action: \"select-buffer-home\" },\n { name: \"end\", shift: true, action: \"select-buffer-end\" },\n { name: \"a\", ctrl: true, action: \"line-home\" },\n { name: \"e\", ctrl: true, action: \"line-end\" },\n { name: \"a\", ctrl: true, shift: true, action: \"select-line-home\" },\n { name: \"e\", ctrl: true, shift: true, action: \"select-line-end\" },\n { name: \"a\", meta: true, action: \"visual-line-home\" },\n { name: \"e\", meta: true, action: \"visual-line-end\" },\n { name: \"a\", meta: true, shift: true, action: \"select-visual-line-home\" },\n { name: \"e\", meta: true, shift: true, action: \"select-visual-line-end\" },\n { name: \"f\", ctrl: true, action: \"move-right\" },\n { name: \"b\", ctrl: true, action: \"move-left\" },\n { name: \"w\", ctrl: true, action: \"delete-word-backward\" },\n { name: \"backspace\", ctrl: true, action: \"delete-word-backward\" },\n { name: \"d\", meta: true, action: \"delete-word-forward\" },\n { name: \"delete\", meta: true, action: \"delete-word-forward\" },\n { name: \"delete\", ctrl: true, action: \"delete-word-forward\" },\n { name: \"d\", ctrl: true, shift: true, action: \"delete-line\" },\n { name: \"k\", ctrl: true, action: \"delete-to-line-end\" },\n { name: \"u\", ctrl: true, action: \"delete-to-line-start\" },\n { name: \"backspace\", action: \"backspace\" },\n { name: \"backspace\", shift: true, action: \"backspace\" },\n { name: \"d\", ctrl: true, action: \"delete\" },\n { name: \"delete\", action: \"delete\" },\n { name: \"delete\", shift: true, action: \"delete\" },\n { name: \"return\", action: \"newline\" },\n { name: \"kpenter\", action: \"newline\" },\n { name: \"linefeed\", action: \"newline\" },\n { name: \"return\", meta: true, action: \"submit\" },\n { name: \"kpenter\", meta: true, action: \"submit\" },\n\n // undo/redo\n { name: \"-\", ctrl: true, action: \"undo\" },\n { name: \".\", ctrl: true, action: \"redo\" },\n { name: \"z\", super: true, action: \"undo\" },\n { name: \"z\", super: true, shift: true, action: \"redo\" },\n\n { name: \"f\", meta: true, action: \"word-forward\" },\n { name: \"b\", meta: true, action: \"word-backward\" },\n { name: \"right\", meta: true, action: \"word-forward\" },\n { name: \"left\", meta: true, action: \"word-backward\" },\n { name: \"right\", ctrl: true, action: \"word-forward\" },\n { name: \"left\", ctrl: true, action: \"word-backward\" },\n { name: \"f\", meta: true, shift: true, action: \"select-word-forward\" },\n { name: \"b\", meta: true, shift: true, action: \"select-word-backward\" },\n { name: \"right\", meta: true, shift: true, action: \"select-word-forward\" },\n { name: \"left\", meta: true, shift: true, action: \"select-word-backward\" },\n { name: \"backspace\", meta: true, action: \"delete-word-backward\" },\n\n // super (cmd/win) + arrow keys for Kitty Keyboard mode\n { name: \"left\", super: true, action: \"visual-line-home\" },\n { name: \"right\", super: true, action: \"visual-line-end\" },\n { name: \"up\", super: true, action: \"buffer-home\" },\n { name: \"down\", super: true, action: \"buffer-end\" },\n { name: \"left\", super: true, shift: true, action: \"select-visual-line-home\" },\n { name: \"right\", super: true, shift: true, action: \"select-visual-line-end\" },\n { name: \"up\", super: true, shift: true, action: \"select-buffer-home\" },\n { name: \"down\", super: true, shift: true, action: \"select-buffer-end\" },\n { name: \"a\", super: true, action: \"select-all\" },\n]\n\nexport interface SubmitEvent {}\n\nexport interface TextareaOptions extends EditBufferOptions {\n initialValue?: string\n backgroundColor?: ColorInput\n textColor?: ColorInput\n focusedBackgroundColor?: ColorInput\n focusedTextColor?: ColorInput\n placeholder?: StyledText | string | null\n placeholderColor?: ColorInput\n keyBindings?: KeyBinding[]\n keyAliasMap?: TextareaKeyAliasMap\n onSubmit?: (event: SubmitEvent) => void\n}\n\nexport class TextareaRenderable extends EditBufferRenderable {\n private _placeholder: StyledText | string | null\n private _placeholderColor: RGBA\n private _unfocusedBackgroundColor: RGBA\n private _unfocusedTextColor: RGBA\n private _focusedBackgroundColor: RGBA\n private _focusedTextColor: RGBA\n private _keyBindingsMap: Map\n private _keyAliasMap: TextareaKeyAliasMap\n private _keyBindings: KeyBinding[]\n private _actionHandlers: Map boolean>\n private _initialValueSet: boolean = false\n private _submitListener: ((event: SubmitEvent) => void) | undefined = undefined\n\n private static readonly defaults = {\n backgroundColor: \"transparent\",\n textColor: \"#FFFFFF\",\n focusedBackgroundColor: \"transparent\",\n focusedTextColor: \"#FFFFFF\",\n placeholder: null,\n placeholderColor: \"#666666\",\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: TextareaOptions) {\n const defaults = TextareaRenderable.defaults\n\n // Pass base colors to parent constructor (these become the unfocused colors)\n const baseOptions = {\n ...options,\n backgroundColor: options.backgroundColor || defaults.backgroundColor,\n textColor: options.textColor || defaults.textColor,\n }\n super(ctx, baseOptions)\n\n // Store unfocused colors separately (parent's properties get overwritten when focused)\n this._unfocusedBackgroundColor = parseColor(options.backgroundColor || defaults.backgroundColor)\n this._unfocusedTextColor = parseColor(options.textColor || defaults.textColor)\n this._focusedBackgroundColor = parseColor(\n options.focusedBackgroundColor || options.backgroundColor || defaults.focusedBackgroundColor,\n )\n this._focusedTextColor = parseColor(options.focusedTextColor || options.textColor || defaults.focusedTextColor)\n this._placeholder = options.placeholder ?? defaults.placeholder\n this._placeholderColor = parseColor(options.placeholderColor ?? defaults.placeholderColor)\n\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {})\n this._keyBindings = options.keyBindings || []\n const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n this._actionHandlers = this.buildActionHandlers()\n this._submitListener = options.onSubmit\n\n if (options.initialValue) {\n this.setText(options.initialValue)\n this._initialValueSet = true\n }\n this.updateColors()\n\n this.applyPlaceholder(this._placeholder)\n }\n\n private applyPlaceholder(placeholder: StyledText | string | null): void {\n if (placeholder === null) {\n this.editorView.setPlaceholderStyledText([])\n return\n }\n\n if (typeof placeholder === \"string\") {\n const colorStyle = fg(this._placeholderColor)\n const chunks = [colorStyle(placeholder)]\n this.editorView.setPlaceholderStyledText(chunks)\n } else {\n this.editorView.setPlaceholderStyledText(placeholder.chunks)\n }\n }\n\n private buildActionHandlers(): Map boolean> {\n return new Map([\n [\"move-left\", () => this.moveCursorLeft()],\n [\"move-right\", () => this.moveCursorRight()],\n [\"move-up\", () => this.moveCursorUp()],\n [\"move-down\", () => this.moveCursorDown()],\n [\"select-left\", () => this.moveCursorLeft({ select: true })],\n [\"select-right\", () => this.moveCursorRight({ select: true })],\n [\"select-up\", () => this.moveCursorUp({ select: true })],\n [\"select-down\", () => this.moveCursorDown({ select: true })],\n [\"line-home\", () => this.gotoLineHome()],\n [\"line-end\", () => this.gotoLineEnd()],\n [\"select-line-home\", () => this.gotoLineHome({ select: true })],\n [\"select-line-end\", () => this.gotoLineEnd({ select: true })],\n [\"visual-line-home\", () => this.gotoVisualLineHome()],\n [\"visual-line-end\", () => this.gotoVisualLineEnd()],\n [\"select-visual-line-home\", () => this.gotoVisualLineHome({ select: true })],\n [\"select-visual-line-end\", () => this.gotoVisualLineEnd({ select: true })],\n [\"select-buffer-home\", () => this.gotoBufferHome({ select: true })],\n [\"select-buffer-end\", () => this.gotoBufferEnd({ select: true })],\n [\"buffer-home\", () => this.gotoBufferHome()],\n [\"buffer-end\", () => this.gotoBufferEnd()],\n [\"delete-line\", () => this.deleteLine()],\n [\"delete-to-line-end\", () => this.deleteToLineEnd()],\n [\"delete-to-line-start\", () => this.deleteToLineStart()],\n [\"backspace\", () => this.deleteCharBackward()],\n [\"delete\", () => this.deleteChar()],\n [\"newline\", () => this.newLine()],\n [\"undo\", () => this.undo()],\n [\"redo\", () => this.redo()],\n [\"word-forward\", () => this.moveWordForward()],\n [\"word-backward\", () => this.moveWordBackward()],\n [\"select-word-forward\", () => this.moveWordForward({ select: true })],\n [\"select-word-backward\", () => this.moveWordBackward({ select: true })],\n [\"delete-word-forward\", () => this.deleteWordForward()],\n [\"delete-word-backward\", () => this.deleteWordBackward()],\n [\"select-all\", () => this.selectAll()],\n [\"submit\", () => this.submit()],\n ])\n }\n\n public handlePaste(event: PasteEvent): void {\n this.insertText(stripAnsiSequences(decodePasteBytes(event.bytes)))\n }\n\n public handleKeyPress(key: KeyEvent): boolean {\n if (this.traits.suspend !== true) {\n const action = getKeyBindingAction(this._keyBindingsMap, key)\n\n if (action) {\n const handler = this._actionHandlers.get(action)\n if (handler) {\n return handler()\n }\n }\n }\n\n if (!key.ctrl && !key.meta && !key.super && !key.hyper) {\n if (key.name === \"space\") {\n this.insertText(\" \")\n return true\n }\n\n if (key.sequence) {\n const firstCharCode = key.sequence.charCodeAt(0)\n\n if (firstCharCode < 32) {\n return false\n }\n\n if (firstCharCode === 127) {\n return false\n }\n\n this.insertText(key.sequence)\n return true\n }\n }\n\n return false\n }\n\n private updateColors(): void {\n const effectiveBg = this._focused ? this._focusedBackgroundColor : this._unfocusedBackgroundColor\n const effectiveFg = this._focused ? this._focusedTextColor : this._unfocusedTextColor\n\n super.backgroundColor = effectiveBg\n super.textColor = effectiveFg\n }\n\n public focus(): void {\n super.focus()\n this.updateColors()\n }\n\n public blur(): void {\n super.blur()\n if (!this.isDestroyed) {\n this.updateColors()\n }\n }\n\n get placeholder(): StyledText | string | null {\n return this._placeholder\n }\n\n set placeholder(value: StyledText | string | null | undefined) {\n const normalizedValue = value ?? null\n if (this._placeholder !== normalizedValue) {\n this._placeholder = normalizedValue\n this.applyPlaceholder(normalizedValue)\n this.requestRender()\n }\n }\n\n get placeholderColor(): RGBA {\n return this._placeholderColor\n }\n\n set placeholderColor(value: ColorInput) {\n const newColor = parseColor(value ?? TextareaRenderable.defaults.placeholderColor)\n if (this._placeholderColor !== newColor) {\n this._placeholderColor = newColor\n this.applyPlaceholder(this._placeholder)\n this.requestRender()\n }\n }\n\n override get backgroundColor(): RGBA {\n return this._unfocusedBackgroundColor\n }\n\n override set backgroundColor(value: RGBA | string | undefined) {\n const newColor = parseColor(value ?? TextareaRenderable.defaults.backgroundColor)\n if (this._unfocusedBackgroundColor !== newColor) {\n this._unfocusedBackgroundColor = newColor\n this.updateColors()\n }\n }\n\n override get textColor(): RGBA {\n return this._unfocusedTextColor\n }\n\n override set textColor(value: RGBA | string | undefined) {\n const newColor = parseColor(value ?? TextareaRenderable.defaults.textColor)\n if (this._unfocusedTextColor !== newColor) {\n this._unfocusedTextColor = newColor\n this.updateColors()\n }\n }\n\n set focusedBackgroundColor(value: ColorInput) {\n const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedBackgroundColor)\n if (this._focusedBackgroundColor !== newColor) {\n this._focusedBackgroundColor = newColor\n this.updateColors()\n }\n }\n\n set focusedTextColor(value: ColorInput) {\n const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedTextColor)\n if (this._focusedTextColor !== newColor) {\n this._focusedTextColor = newColor\n this.updateColors()\n }\n }\n\n set initialValue(value: string) {\n if (!this._initialValueSet) {\n this.setText(value)\n this._initialValueSet = true\n }\n }\n\n public submit(): boolean {\n if (this._submitListener) {\n this._submitListener({})\n }\n return true\n }\n\n public set onSubmit(handler: ((event: SubmitEvent) => void) | undefined) {\n this._submitListener = handler\n }\n\n public get onSubmit(): ((event: SubmitEvent) => void) | undefined {\n return this._submitListener\n }\n\n public set keyBindings(bindings: KeyBinding[]) {\n this._keyBindings = bindings\n const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, bindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n }\n\n public set keyAliasMap(aliases: TextareaKeyAliasMap) {\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases)\n const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n }\n\n public get extmarks(): ExtmarksController {\n return this.editorView.extmarks\n }\n}\n", + "import type { PasteEvent } from \"../lib/KeyHandler.js\"\nimport { decodePasteBytes, stripAnsiSequences } from \"../lib/paste.js\"\nimport type { RenderContext } from \"../types.js\"\nimport {\n TextareaRenderable,\n type TextareaOptions,\n type TextareaAction,\n type KeyBinding as TextareaKeyBinding,\n} from \"./Textarea.js\"\n\nexport type InputAction = TextareaAction\nexport type InputKeyBinding = TextareaKeyBinding\n\nexport interface InputRenderableOptions extends Omit<\n TextareaOptions,\n \"height\" | \"minHeight\" | \"maxHeight\" | \"initialValue\"\n> {\n /** Initial text value (newlines are stripped) */\n value?: string\n /** Minimum number of characters allowed */\n minLength?: number\n /** Maximum number of characters allowed */\n maxLength?: number\n /** Placeholder text (Input only supports string, not StyledText) */\n placeholder?: string\n}\n\n// TODO: make this just plain strings instead of an enum (same for other events)\nexport enum InputRenderableEvents {\n INPUT = \"input\",\n CHANGE = \"change\",\n ENTER = \"enter\",\n}\n\n/**\n * InputRenderable - A single-line text input component.\n *\n * Extends TextareaRenderable with single-line constraints:\n * - Height is always 1\n * - No text wrapping\n * - Newlines are stripped from input\n * - Enter key submits instead of inserting newline\n *\n * Inherits all keybindings from TextareaRenderable.\n */\nexport class InputRenderable extends TextareaRenderable {\n private _maxLength: number\n private _minLength: number\n private _lastCommittedValue: string = \"\"\n\n // Only specify defaults that differ from TextareaRenderable/EditBufferRenderable\n private static readonly defaultOptions = {\n // Different from Textarea's null\n placeholder: \"\",\n // Input-specific\n maxLength: 1000,\n minLength: 0,\n value: \"\",\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: InputRenderableOptions) {\n const defaults = InputRenderable.defaultOptions\n const maxLength = options.maxLength ?? defaults.maxLength\n const minLength = options.minLength ?? defaults.minLength\n // Sanitize initial value: strip newlines and enforce maxLength\n const rawValue = options.value ?? defaults.value\n const initialValue = rawValue.replace(/[\\n\\r]/g, \"\").substring(0, maxLength)\n\n if (minLength > maxLength) {\n throw new Error(`InputRenderable: minLength (${minLength}) cannot be greater than maxLength (${maxLength})`)\n }\n\n super(ctx, {\n ...options,\n placeholder: options.placeholder ?? defaults.placeholder,\n initialValue,\n // Single-line constraints\n height: 1,\n wrapMode: \"none\",\n // Override return/linefeed to submit instead of newline\n keyBindings: [\n { name: \"return\", action: \"submit\" },\n { name: \"kpenter\", action: \"submit\" },\n { name: \"linefeed\", action: \"submit\" },\n ...(options.keyBindings || []),\n ],\n })\n\n this._maxLength = maxLength\n this._minLength = minLength\n this._lastCommittedValue = this.plainText\n\n // Set cursor to end of initial value\n if (initialValue) {\n this.cursorOffset = initialValue.length\n }\n }\n\n /**\n * Prevent newlines in single-line input\n */\n public override newLine(): boolean {\n return false\n }\n\n /**\n * Handle paste - strip newlines and enforce maxLength\n */\n public override handlePaste(event: PasteEvent): void {\n const sanitized = stripAnsiSequences(decodePasteBytes(event.bytes)).replace(/[\\n\\r]/g, \"\")\n if (sanitized) {\n this.insertText(sanitized)\n }\n }\n\n /**\n * Insert text - strip newlines and enforce maxLength\n */\n public override insertText(text: string): void {\n const sanitized = text.replace(/[\\n\\r]/g, \"\")\n if (!sanitized) return\n\n const currentLength = this.plainText.length\n const remaining = this._maxLength - currentLength\n if (remaining <= 0) return\n\n const toInsert = sanitized.substring(0, remaining)\n super.insertText(toInsert)\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n }\n\n public get value(): string {\n return this.plainText\n }\n\n public set value(value: string) {\n const newValue = value.substring(0, this._maxLength).replace(/[\\n\\r]/g, \"\")\n const currentValue = this.plainText\n if (currentValue !== newValue) {\n this.setText(newValue)\n this.cursorOffset = newValue.length\n this.emit(InputRenderableEvents.INPUT, newValue)\n }\n }\n\n public override focus(): void {\n super.focus()\n this._lastCommittedValue = this.plainText\n }\n\n public override blur(): void {\n if (!this.isDestroyed) {\n const currentValue = this.plainText\n if (currentValue !== this._lastCommittedValue) {\n this._lastCommittedValue = currentValue\n this.emit(InputRenderableEvents.CHANGE, currentValue)\n }\n }\n super.blur()\n }\n\n public override submit(): boolean {\n const currentValue = this.plainText\n if (currentValue.length < this._minLength) {\n return false\n }\n\n if (currentValue !== this._lastCommittedValue) {\n this._lastCommittedValue = currentValue\n this.emit(InputRenderableEvents.CHANGE, currentValue)\n }\n this.emit(InputRenderableEvents.ENTER, currentValue)\n return true\n }\n\n public override deleteCharBackward(): boolean {\n const result = super.deleteCharBackward()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override deleteChar(): boolean {\n const result = super.deleteChar()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override deleteLine(): boolean {\n const result = super.deleteLine()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override deleteWordBackward(): boolean {\n const result = super.deleteWordBackward()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override deleteWordForward(): boolean {\n const result = super.deleteWordForward()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override deleteToLineStart(): boolean {\n const result = super.deleteToLineStart()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override deleteToLineEnd(): boolean {\n const result = super.deleteToLineEnd()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override undo(): boolean {\n const result = super.undo()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public override redo(): boolean {\n const result = super.redo()\n this.emit(InputRenderableEvents.INPUT, this.plainText)\n return result\n }\n\n public deleteCharacter(direction: \"backward\" | \"forward\"): void {\n if (direction === \"backward\") {\n this.deleteCharBackward()\n } else {\n this.deleteChar()\n }\n }\n\n public set maxLength(maxLength: number) {\n this._maxLength = maxLength\n const currentValue = this.plainText\n if (currentValue.length > maxLength) {\n this.setText(currentValue.substring(0, maxLength))\n }\n }\n\n public get maxLength(): number {\n return this._maxLength\n }\n\n public set minLength(minLength: number) {\n if (minLength > this._maxLength) {\n throw new Error(`InputRenderable: minLength (${minLength}) cannot be greater than maxLength (${this._maxLength})`)\n }\n this._minLength = minLength\n }\n\n public get minLength(): number {\n return this._minLength\n }\n\n public override set placeholder(placeholder: string) {\n super.placeholder = placeholder\n }\n\n public override get placeholder(): string {\n const p = super.placeholder\n return typeof p === \"string\" ? p : \"\"\n }\n\n public override set initialValue(value: string) {\n void 0\n }\n}\n", + "/**\n * marked v17.0.1 - a markdown parser\n * Copyright (c) 2018-2025, MarkedJS. (MIT License)\n * Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)\n * https://github.com/markedjs/marked\n */\n\n/**\n * DO NOT EDIT THIS FILE\n * The code in this file is generated from files in ./src/\n */\n\nfunction L(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var T=L();function Z(u){T=u}var C={exec:()=>null};function k(u,e=\"\"){let t=typeof u==\"string\"?u:u.source,n={replace:(r,i)=>{let s=typeof i==\"string\"?i:i.source;return s=s.replace(m.caret,\"$1\"),t=t.replace(r,s),n},getRegex:()=>new RegExp(t,e)};return n}var me=(()=>{try{return!!new RegExp(\"(?<=1)(?/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceTabs:/^\\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] +\\S/,listReplaceTask:/^\\[[ xX]\\] +/,listTaskCheckbox:/\\[[ xX]\\]/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>\"']/,escapeReplace:/[&<>\"']/g,escapeTestNoEncode:/[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,unescapeTest:/&(#(?:\\d+)|(?:#x[0-9A-Fa-f]+)|(?:\\w+));?/ig,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:u=>new RegExp(`^( {0,3}${u})((?:[\t ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \t][^\\\\n]*)?(?:\\\\n|$))`),hrRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`),fencesBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}(?:\\`\\`\\`|~~~)`),headingBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}#`),htmlBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}<(?:[a-z].*>|!--)`,\"i\")},xe=/^(?:[ \\t]*(?:\\n|$))+/,be=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Re=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,I=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Te=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,N=/(?:[*+-]|\\d{1,9}[.)])/,re=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,se=k(re).replace(/bull/g,N).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/\\|table/g,\"\").getRegex(),Oe=k(re).replace(/bull/g,N).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/table/g,/ {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/).getRegex(),Q=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/,we=/^[^\\n]+/,F=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,ye=k(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace(\"label\",F).replace(\"title\",/(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/).getRegex(),Pe=k(/^( {0,3}bull)([ \\t][^\\n]+?)?(?:\\n|$)/).replace(/bull/g,N).getRegex(),v=\"address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul\",j=/|$))/,Se=k(\"^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:[^\\\\n]*\\\\n+|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)|\\\\n*|$)|\\\\n*|$)|)[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$)|(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$))\",\"i\").replace(\"comment\",j).replace(\"tag\",v).replace(\"attribute\",/ +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/).getRegex(),ie=k(Q).replace(\"hr\",I).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"|lheading\",\"\").replace(\"|table\",\"\").replace(\"blockquote\",\" {0,3}>\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\")|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex(),$e=k(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace(\"paragraph\",ie).getRegex(),U={blockquote:$e,code:be,def:ye,fences:Re,heading:Te,hr:I,html:Se,lheading:se,list:Pe,newline:xe,paragraph:ie,table:C,text:we},te=k(\"^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)\").replace(\"hr\",I).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"blockquote\",\" {0,3}>\").replace(\"code\",\"(?: {4}| {0,3}\t)[^\\\\n]\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\")|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex(),_e={...U,lheading:Oe,table:te,paragraph:k(Q).replace(\"hr\",I).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"|lheading\",\"\").replace(\"table\",te).replace(\"blockquote\",\" {0,3}>\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\")|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex()},Le={...U,html:k(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+? *(?:\\\\n{2,}|\\\\s*$)|\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace(\"comment\",j).replace(/tag/g,\"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b\").getRegex(),def:/^ *\\[([^\\]]+)\\]: *]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:C,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:k(Q).replace(\"hr\",I).replace(\"heading\",` *#{1,6} *[^\n]`).replace(\"lheading\",se).replace(\"|table\",\"\").replace(\"blockquote\",\" {0,3}>\").replace(\"|fences\",\"\").replace(\"|list\",\"\").replace(\"|html\",\"\").replace(\"|tag\",\"\").getRegex()},Me=/^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,ze=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,oe=/^( {2,}|\\\\)\\n(?!\\s*$)/,Ae=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\`+)[^`]+\\k(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace(\"precode-\",me?\"(?`+)[^`]+\\k(?!`)/).replace(\"html\",/<(?! )[^<>]*?>/).getRegex(),ue=/^(?:\\*+(?:((?!\\*)punct)|[^\\s*]))|^_+(?:((?!_)punct)|([^\\s_]))/,qe=k(ue,\"u\").replace(/punct/g,D).getRegex(),ve=k(ue,\"u\").replace(/punct/g,le).getRegex(),pe=\"^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)\",De=k(pe,\"gu\").replace(/notPunctSpace/g,ae).replace(/punctSpace/g,K).replace(/punct/g,D).getRegex(),He=k(pe,\"gu\").replace(/notPunctSpace/g,Ee).replace(/punctSpace/g,Ie).replace(/punct/g,le).getRegex(),Ze=k(\"^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)\",\"gu\").replace(/notPunctSpace/g,ae).replace(/punctSpace/g,K).replace(/punct/g,D).getRegex(),Ge=k(/\\\\(punct)/,\"gu\").replace(/punct/g,D).getRegex(),Ne=k(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace(\"scheme\",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace(\"email\",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Qe=k(j).replace(\"(?:-->|$)\",\"-->\").getRegex(),Fe=k(\"^comment|^|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^|^\").replace(\"comment\",Qe).replace(\"attribute\",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/).getRegex(),q=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+[^`]*?`+(?!`)|[^\\[\\]\\\\`])*?/,je=k(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]*(?:\\n[ \\t]*)?)(title))?\\s*\\)/).replace(\"label\",q).replace(\"href\",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]*/).replace(\"title\",/\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),ce=k(/^!?\\[(label)\\]\\[(ref)\\]/).replace(\"label\",q).replace(\"ref\",F).getRegex(),he=k(/^!?\\[(ref)\\](?:\\[\\])?/).replace(\"ref\",F).getRegex(),Ue=k(\"reflink|nolink(?!\\\\()\",\"g\").replace(\"reflink\",ce).replace(\"nolink\",he).getRegex(),ne=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,W={_backpedal:C,anyPunctuation:Ge,autolink:Ne,blockSkip:Be,br:oe,code:ze,del:C,emStrongLDelim:qe,emStrongRDelimAst:De,emStrongRDelimUnd:Ze,escape:Me,link:je,nolink:he,punctuation:Ce,reflink:ce,reflinkSearch:Ue,tag:Fe,text:Ae,url:C},Ke={...W,link:k(/^!?\\[(label)\\]\\((.*?)\\)/).replace(\"label\",q).getRegex(),reflink:k(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace(\"label\",q).getRegex()},G={...W,emStrongRDelimAst:He,emStrongLDelim:ve,url:k(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace(\"protocol\",ne).replace(\"email\",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:k(/^([`~]+|[^`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\\":\">\",'\"':\""\",\"'\":\"'\"},ke=u=>Xe[u];function w(u,e){if(e){if(m.escapeTest.test(u))return u.replace(m.escapeReplace,ke)}else if(m.escapeTestNoEncode.test(u))return u.replace(m.escapeReplaceNoEncode,ke);return u}function X(u){try{u=encodeURI(u).replace(m.percentDecode,\"%\")}catch{return null}return u}function J(u,e){let t=u.replace(m.findPipe,(i,s,a)=>{let o=!1,l=s;for(;--l>=0&&a[l]===\"\\\\\";)o=!o;return o?\"|\":\" |\"}),n=t.split(m.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length0?-2:-1}function ge(u,e,t,n,r){let i=e.href,s=e.title||null,a=u[1].replace(r.other.outputLinkReplace,\"$1\");n.state.inLink=!0;let o={type:u[0].charAt(0)===\"!\"?\"image\":\"link\",raw:t,href:i,title:s,text:a,tokens:n.inlineTokens(a)};return n.state.inLink=!1,o}function Je(u,e,t){let n=u.match(t.other.indentCodeCompensation);if(n===null)return e;let r=n[1];return e.split(`\n`).map(i=>{let s=i.match(t.other.beginningSpace);if(s===null)return i;let[a]=s;return a.length>=r.length?i.slice(r.length):i}).join(`\n`)}var y=class{options;rules;lexer;constructor(e){this.options=e||T}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:\"space\",raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let n=t[0].replace(this.rules.other.codeRemoveIndent,\"\");return{type:\"code\",raw:t[0],codeBlockStyle:\"indented\",text:this.options.pedantic?n:z(n,`\n`)}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let n=t[0],r=Je(n,t[3]||\"\",this.rules);return{type:\"code\",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,\"$1\"):t[2],text:r}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(this.rules.other.endingHash.test(n)){let r=z(n,\"#\");(this.options.pedantic||!r||this.rules.other.endingSpaceChar.test(r))&&(n=r.trim())}return{type:\"heading\",raw:t[0],depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return{type:\"hr\",raw:z(t[0],`\n`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=z(t[0],`\n`).split(`\n`),r=\"\",i=\"\",s=[];for(;n.length>0;){let a=!1,o=[],l;for(l=0;l1,i={type:\"list\",raw:\"\",ordered:r,start:r?+n.slice(0,-1):\"\",loose:!1,items:[]};n=r?`\\\\d{1,9}\\\\${n.slice(-1)}`:`\\\\${n}`,this.options.pedantic&&(n=r?n:\"[*+-]\");let s=this.rules.other.listItemRegex(n),a=!1;for(;e;){let l=!1,p=\"\",c=\"\";if(!(t=s.exec(e))||this.rules.block.hr.test(e))break;p=t[0],e=e.substring(p.length);let g=t[2].split(`\n`,1)[0].replace(this.rules.other.listReplaceTabs,O=>\" \".repeat(3*O.length)),h=e.split(`\n`,1)[0],R=!g.trim(),f=0;if(this.options.pedantic?(f=2,c=g.trimStart()):R?f=t[1].length+1:(f=t[2].search(this.rules.other.nonSpaceChar),f=f>4?1:f,c=g.slice(f),f+=t[1].length),R&&this.rules.other.blankLine.test(h)&&(p+=h+`\n`,e=e.substring(h.length+1),l=!0),!l){let O=this.rules.other.nextBulletRegex(f),V=this.rules.other.hrRegex(f),Y=this.rules.other.fencesBeginRegex(f),ee=this.rules.other.headingBeginRegex(f),fe=this.rules.other.htmlBeginRegex(f);for(;e;){let H=e.split(`\n`,1)[0],A;if(h=H,this.options.pedantic?(h=h.replace(this.rules.other.listReplaceNesting,\" \"),A=h):A=h.replace(this.rules.other.tabCharGlobal,\" \"),Y.test(h)||ee.test(h)||fe.test(h)||O.test(h)||V.test(h))break;if(A.search(this.rules.other.nonSpaceChar)>=f||!h.trim())c+=`\n`+A.slice(f);else{if(R||g.replace(this.rules.other.tabCharGlobal,\" \").search(this.rules.other.nonSpaceChar)>=4||Y.test(g)||ee.test(g)||V.test(g))break;c+=`\n`+h}!R&&!h.trim()&&(R=!0),p+=H+`\n`,e=e.substring(H.length+1),g=A.slice(f)}}i.loose||(a?i.loose=!0:this.rules.other.doubleBlankLine.test(p)&&(a=!0)),i.items.push({type:\"list_item\",raw:p,task:!!this.options.gfm&&this.rules.other.listIsTask.test(c),loose:!1,text:c,tokens:[]}),i.raw+=p}let o=i.items.at(-1);if(o)o.raw=o.raw.trimEnd(),o.text=o.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let l of i.items){if(this.lexer.state.top=!1,l.tokens=this.lexer.blockTokens(l.text,[]),l.task){if(l.text=l.text.replace(this.rules.other.listReplaceTask,\"\"),l.tokens[0]?.type===\"text\"||l.tokens[0]?.type===\"paragraph\"){l.tokens[0].raw=l.tokens[0].raw.replace(this.rules.other.listReplaceTask,\"\"),l.tokens[0].text=l.tokens[0].text.replace(this.rules.other.listReplaceTask,\"\");for(let c=this.lexer.inlineQueue.length-1;c>=0;c--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[c].src)){this.lexer.inlineQueue[c].src=this.lexer.inlineQueue[c].src.replace(this.rules.other.listReplaceTask,\"\");break}}let p=this.rules.other.listTaskCheckbox.exec(l.raw);if(p){let c={type:\"checkbox\",raw:p[0]+\" \",checked:p[0]!==\"[ ]\"};l.checked=c.checked,i.loose?l.tokens[0]&&[\"paragraph\",\"text\"].includes(l.tokens[0].type)&&\"tokens\"in l.tokens[0]&&l.tokens[0].tokens?(l.tokens[0].raw=c.raw+l.tokens[0].raw,l.tokens[0].text=c.raw+l.tokens[0].text,l.tokens[0].tokens.unshift(c)):l.tokens.unshift({type:\"paragraph\",raw:c.raw,text:c.raw,tokens:[c]}):l.tokens.unshift(c)}}if(!i.loose){let p=l.tokens.filter(g=>g.type===\"space\"),c=p.length>0&&p.some(g=>this.rules.other.anyLine.test(g.raw));i.loose=c}}if(i.loose)for(let l of i.items){l.loose=!0;for(let p of l.tokens)p.type===\"text\"&&(p.type=\"paragraph\")}return i}}html(e){let t=this.rules.block.html.exec(e);if(t)return{type:\"html\",block:!0,raw:t[0],pre:t[1]===\"pre\"||t[1]===\"script\"||t[1]===\"style\",text:t[0]}}def(e){let t=this.rules.block.def.exec(e);if(t){let n=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal,\" \"),r=t[2]?t[2].replace(this.rules.other.hrefBrackets,\"$1\").replace(this.rules.inline.anyPunctuation,\"$1\"):\"\",i=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,\"$1\"):t[3];return{type:\"def\",tag:n,raw:t[0],href:r,title:i}}}table(e){let t=this.rules.block.table.exec(e);if(!t||!this.rules.other.tableDelimiter.test(t[2]))return;let n=J(t[1]),r=t[2].replace(this.rules.other.tableAlignChars,\"\").split(\"|\"),i=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,\"\").split(`\n`):[],s={type:\"table\",raw:t[0],header:[],align:[],rows:[]};if(n.length===r.length){for(let a of r)this.rules.other.tableAlignRight.test(a)?s.align.push(\"right\"):this.rules.other.tableAlignCenter.test(a)?s.align.push(\"center\"):this.rules.other.tableAlignLeft.test(a)?s.align.push(\"left\"):s.align.push(null);for(let a=0;a({text:o,tokens:this.lexer.inline(o),header:!1,align:s.align[l]})));return s}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t)return{type:\"heading\",raw:t[0],depth:t[2].charAt(0)===\"=\"?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let n=t[1].charAt(t[1].length-1)===`\n`?t[1].slice(0,-1):t[1];return{type:\"paragraph\",raw:t[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return{type:\"text\",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return{type:\"escape\",raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:\"html\",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let n=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let s=z(n.slice(0,-1),\"\\\\\");if((n.length-s.length)%2===0)return}else{let s=de(t[2],\"()\");if(s===-2)return;if(s>-1){let o=(t[0].indexOf(\"!\")===0?5:4)+t[1].length+s;t[2]=t[2].substring(0,s),t[0]=t[0].substring(0,o).trim(),t[3]=\"\"}}let r=t[2],i=\"\";if(this.options.pedantic){let s=this.rules.other.pedanticHrefTitle.exec(r);s&&(r=s[1],i=s[3])}else i=t[3]?t[3].slice(1,-1):\"\";return r=r.trim(),this.rules.other.startAngleBracket.test(r)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?r=r.slice(1):r=r.slice(1,-1)),ge(t,{href:r&&r.replace(this.rules.inline.anyPunctuation,\"$1\"),title:i&&i.replace(this.rules.inline.anyPunctuation,\"$1\")},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let r=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal,\" \"),i=t[r.toLowerCase()];if(!i){let s=n[0].charAt(0);return{type:\"text\",raw:s,text:s}}return ge(n,i,n[0],this.lexer,this.rules)}}emStrong(e,t,n=\"\"){let r=this.rules.inline.emStrongLDelim.exec(e);if(!r||r[3]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(r[1]||r[2]||\"\")||!n||this.rules.inline.punctuation.exec(n)){let s=[...r[0]].length-1,a,o,l=s,p=0,c=r[0][0]===\"*\"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,t=t.slice(-1*e.length+s);(r=c.exec(t))!=null;){if(a=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!a)continue;if(o=[...a].length,r[3]||r[4]){l+=o;continue}else if((r[5]||r[6])&&s%3&&!((s+o)%3)){p+=o;continue}if(l-=o,l>0)continue;o=Math.min(o,o+l+p);let g=[...r[0]][0].length,h=e.slice(0,s+r.index+g+o);if(Math.min(s,o)%2){let f=h.slice(1,-1);return{type:\"em\",raw:h,text:f,tokens:this.lexer.inlineTokens(f)}}let R=h.slice(2,-2);return{type:\"strong\",raw:h,text:R,tokens:this.lexer.inlineTokens(R)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let n=t[2].replace(this.rules.other.newLineCharGlobal,\" \"),r=this.rules.other.nonSpaceChar.test(n),i=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return r&&i&&(n=n.substring(1,n.length-1)),{type:\"codespan\",raw:t[0],text:n}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return{type:\"br\",raw:t[0]}}del(e){let t=this.rules.inline.del.exec(e);if(t)return{type:\"del\",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let n,r;return t[2]===\"@\"?(n=t[1],r=\"mailto:\"+n):(n=t[1],r=n),{type:\"link\",raw:t[0],text:n,href:r,tokens:[{type:\"text\",raw:n,text:n}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let n,r;if(t[2]===\"@\")n=t[0],r=\"mailto:\"+n;else{let i;do i=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??\"\";while(i!==t[0]);n=t[0],t[1]===\"www.\"?r=\"http://\"+t[0]:r=t[0]}return{type:\"link\",raw:t[0],text:n,href:r,tokens:[{type:\"text\",raw:n,text:n}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let n=this.lexer.state.inRawBlock;return{type:\"text\",raw:t[0],text:t[0],escaped:n}}}};var x=class u{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||T,this.options.tokenizer=this.options.tokenizer||new y,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:m,block:E.normal,inline:M.normal};this.options.pedantic?(t.block=E.pedantic,t.inline=M.pedantic):this.options.gfm&&(t.block=E.gfm,this.options.breaks?t.inline=M.breaks:t.inline=M.gfm),this.tokenizer.rules=t}static get rules(){return{block:E,inline:M}}static lex(e,t){return new u(t).lex(e)}static lexInline(e,t){return new u(t).inlineTokens(e)}lex(e){e=e.replace(m.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let t=0;t(r=s.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);let s=t.at(-1);r.raw.length===1&&s!==void 0?s.raw+=`\n`:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"paragraph\"||s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"paragraph\"||s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.raw,this.inlineQueue.at(-1).src=s.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title},t.push(r));continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let s=1/0,a=e.slice(1),o;this.options.extensions.startBlock.forEach(l=>{o=l.call({lexer:this},a),typeof o==\"number\"&&o>=0&&(s=Math.min(s,o))}),s<1/0&&s>=0&&(i=e.substring(0,s+1))}if(this.state.top&&(r=this.tokenizer.paragraph(i))){let s=t.at(-1);n&&s?.type===\"paragraph\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r),n=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(e){let s=\"Infinite loop on byte: \"+e.charCodeAt(0);if(this.options.silent){console.error(s);break}else throw new Error(s)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n=e,r=null;if(this.tokens.links){let o=Object.keys(this.tokens.links);if(o.length>0)for(;(r=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)o.includes(r[0].slice(r[0].lastIndexOf(\"[\")+1,-1))&&(n=n.slice(0,r.index)+\"[\"+\"a\".repeat(r[0].length-2)+\"]\"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(r=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,r.index)+\"++\"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let i;for(;(r=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)i=r[2]?r[2].length:0,n=n.slice(0,r.index+i)+\"[\"+\"a\".repeat(r[0].length-i-2)+\"]\"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let s=!1,a=\"\";for(;e;){s||(a=\"\"),s=!1;let o;if(this.options.extensions?.inline?.some(p=>(o=p.call({lexer:this},e,t))?(e=e.substring(o.raw.length),t.push(o),!0):!1))continue;if(o=this.tokenizer.escape(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.tag(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.link(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(o.raw.length);let p=t.at(-1);o.type===\"text\"&&p?.type===\"text\"?(p.raw+=o.raw,p.text+=o.text):t.push(o);continue}if(o=this.tokenizer.emStrong(e,n,a)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.codespan(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.br(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.del(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.autolink(e)){e=e.substring(o.raw.length),t.push(o);continue}if(!this.state.inLink&&(o=this.tokenizer.url(e))){e=e.substring(o.raw.length),t.push(o);continue}let l=e;if(this.options.extensions?.startInline){let p=1/0,c=e.slice(1),g;this.options.extensions.startInline.forEach(h=>{g=h.call({lexer:this},c),typeof g==\"number\"&&g>=0&&(p=Math.min(p,g))}),p<1/0&&p>=0&&(l=e.substring(0,p+1))}if(o=this.tokenizer.inlineText(l)){e=e.substring(o.raw.length),o.raw.slice(-1)!==\"_\"&&(a=o.raw.slice(-1)),s=!0;let p=t.at(-1);p?.type===\"text\"?(p.raw+=o.raw,p.text+=o.text):t.push(o);continue}if(e){let p=\"Infinite loop on byte: \"+e.charCodeAt(0);if(this.options.silent){console.error(p);break}else throw new Error(p)}}return t}};var P=class{options;parser;constructor(e){this.options=e||T}space(e){return\"\"}code({text:e,lang:t,escaped:n}){let r=(t||\"\").match(m.notSpaceStart)?.[0],i=e.replace(m.endingNewline,\"\")+`\n`;return r?'
    '+(n?i:w(i,!0))+`
    \n`:\"
    \"+(n?i:w(i,!0))+`
    \n`}blockquote({tokens:e}){return`
    \n${this.parser.parse(e)}
    \n`}html({text:e}){return e}def(e){return\"\"}heading({tokens:e,depth:t}){return`${this.parser.parseInline(e)}\n`}hr(e){return`
    \n`}list(e){let t=e.ordered,n=e.start,r=\"\";for(let a=0;a\n`+r+\"\n`}listitem(e){return`
  • ${this.parser.parse(e.tokens)}
  • \n`}checkbox({checked:e}){return\" '}paragraph({tokens:e}){return`

    ${this.parser.parseInline(e)}

    \n`}table(e){let t=\"\",n=\"\";for(let i=0;i${r}`),`\n\n`+t+`\n`+r+`
    \n`}tablerow({text:e}){return`\n${e}\n`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?\"th\":\"td\";return(e.align?`<${n} align=\"${e.align}\">`:`<${n}>`)+t+`\n`}strong({tokens:e}){return`${this.parser.parseInline(e)}`}em({tokens:e}){return`${this.parser.parseInline(e)}`}codespan({text:e}){return`${w(e,!0)}`}br(e){return\"
    \"}del({tokens:e}){return`${this.parser.parseInline(e)}`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=X(e);if(i===null)return r;e=i;let s='
    \"+r+\"\",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=X(e);if(i===null)return w(n);e=i;let s=`\"${n}\"`;return\",s}text(e){return\"tokens\"in e&&e.tokens?this.parser.parseInline(e.tokens):\"escaped\"in e&&e.escaped?e.text:w(e.text)}};var $=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return\"\"+e}image({text:e}){return\"\"+e}br(){return\"\"}checkbox({raw:e}){return e}};var b=class u{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new P,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $}static parse(e,t){return new u(t).parse(e)}static parseInline(e,t){return new u(t).parseInline(e)}parse(e){let t=\"\";for(let n=0;n{let a=i[s].flat(1/0);n=n.concat(this.walkTokens(a,t))}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||!1,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error(\"extension name required\");if(\"renderer\"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...a){let o=i.renderer.apply(this,a);return o===!1&&(o=s.apply(this,a)),o}:t.renderers[i.name]=i.renderer}if(\"tokenizer\"in i){if(!i.level||i.level!==\"block\"&&i.level!==\"inline\")throw new Error(\"extension level must be 'block' or 'inline'\");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level===\"block\"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level===\"inline\"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]))}\"childTokens\"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens)}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new P(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if([\"options\",\"parser\"].includes(s))continue;let a=s,o=n.renderer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===!1&&(c=l.apply(i,p)),c||\"\"}}r.renderer=i}if(n.tokenizer){let i=this.defaults.tokenizer||new y(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if([\"options\",\"rules\",\"lexer\"].includes(s))continue;let a=s,o=n.tokenizer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===!1&&(c=l.apply(i,p)),c}}r.tokenizer=i}if(n.hooks){let i=this.defaults.hooks||new S;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if([\"options\",\"block\"].includes(s))continue;let a=s,o=n.hooks[a],l=i[a];S.passThroughHooks.has(s)?i[a]=p=>{if(this.defaults.async&&S.passThroughHooksRespectAsync.has(s))return(async()=>{let g=await o.call(i,p);return l.call(i,g)})();let c=o.call(i,p);return l.call(i,c)}:i[a]=(...p)=>{if(this.defaults.async)return(async()=>{let g=await o.apply(i,p);return g===!1&&(g=await l.apply(i,p)),g})();let c=o.apply(i,p);return c===!1&&(c=l.apply(i,p)),c}}r.hooks=i}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(a){let o=[];return o.push(s.call(this,a)),i&&(o=o.concat(i.call(this,a))),o}}this.defaults={...this.defaults,...r}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return(n,r)=>{let i={...r},s={...this.defaults,...i},a=this.onError(!!s.silent,!!s.async);if(this.defaults.async===!0&&i.async===!1)return a(new Error(\"marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.\"));if(typeof n>\"u\"||n===null)return a(new Error(\"marked(): input parameter is undefined or null\"));if(typeof n!=\"string\")return a(new Error(\"marked(): input parameter is of type \"+Object.prototype.toString.call(n)+\", string expected\"));if(s.hooks&&(s.hooks.options=s,s.hooks.block=e),s.async)return(async()=>{let o=s.hooks?await s.hooks.preprocess(n):n,p=await(s.hooks?await s.hooks.provideLexer():e?x.lex:x.lexInline)(o,s),c=s.hooks?await s.hooks.processAllTokens(p):p;s.walkTokens&&await Promise.all(this.walkTokens(c,s.walkTokens));let h=await(s.hooks?await s.hooks.provideParser():e?b.parse:b.parseInline)(c,s);return s.hooks?await s.hooks.postprocess(h):h})().catch(a);try{s.hooks&&(n=s.hooks.preprocess(n));let l=(s.hooks?s.hooks.provideLexer():e?x.lex:x.lexInline)(n,s);s.hooks&&(l=s.hooks.processAllTokens(l)),s.walkTokens&&this.walkTokens(l,s.walkTokens);let c=(s.hooks?s.hooks.provideParser():e?b.parse:b.parseInline)(l,s);return s.hooks&&(c=s.hooks.postprocess(c)),c}catch(o){return a(o)}}}onError(e,t){return n=>{if(n.message+=`\nPlease report this to https://github.com/markedjs/marked.`,e){let r=\"

    An error occurred:

    \"+w(n.message+\"\",!0)+\"
    \";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}};var _=new B;function d(u,e){return _.parse(u,e)}d.options=d.setOptions=function(u){return _.setOptions(u),d.defaults=_.defaults,Z(d.defaults),d};d.getDefaults=L;d.defaults=T;d.use=function(...u){return _.use(...u),d.defaults=_.defaults,Z(d.defaults),d};d.walkTokens=function(u,e){return _.walkTokens(u,e)};d.parseInline=_.parseInline;d.Parser=b;d.parser=b.parse;d.Renderer=P;d.TextRenderer=$;d.Lexer=x;d.lexer=x.lex;d.Tokenizer=y;d.Hooks=S;d.parse=d;var Dt=d.options,Ht=d.setOptions,Zt=d.use,Gt=d.walkTokens,Nt=d.parseInline,Qt=d,Ft=b.parse,jt=x.lex;export{S as Hooks,x as Lexer,B as Marked,b as Parser,P as Renderer,$ as TextRenderer,y as Tokenizer,T as defaults,L as getDefaults,jt as lexer,d as marked,Dt as options,Qt as parse,Nt as parseInline,Ft as parser,Ht as setOptions,Zt as use,Gt as walkTokens};\n//# sourceMappingURL=marked.esm.js.map\n", + "import { MeasureMode } from \"../yoga.js\"\nimport { type RenderableOptions, Renderable } from \"../Renderable.js\"\nimport type { OptimizedBuffer } from \"../buffer.js\"\nimport { type BorderStyle, BorderCharArrays, parseBorderStyle } from \"../lib/border.js\"\nimport { convertGlobalToLocalSelection, type Selection, type LocalSelectionBounds } from \"../lib/selection.js\"\nimport { StyledText, stringToStyledText } from \"../lib/styled-text.js\"\nimport { RGBA, parseColor, type ColorInput } from \"../lib/RGBA.js\"\nimport { SyntaxStyle } from \"../syntax-style.js\"\nimport { type TextChunk, TextBuffer } from \"../text-buffer.js\"\nimport { TextBufferView } from \"../text-buffer-view.js\"\nimport type { RenderContext } from \"../types.js\"\n\n// Large sentinel height for text measurement. The Zig measure path currently\n// ignores height, but we pass an effectively unbounded value so if height-aware\n// measuring is introduced later, table sizing remains stable.\nconst MEASURE_HEIGHT = 10_000\n\nexport type TextTableCellContent = TextChunk[] | null | undefined\nexport type TextTableContent = TextTableCellContent[][]\nexport type TextTableColumnWidthMode = \"content\" | \"full\"\nexport type TextTableColumnFitter = \"proportional\" | \"balanced\"\n\ninterface ResolvedTableBorderLayout {\n left: boolean\n right: boolean\n top: boolean\n bottom: boolean\n innerVertical: boolean\n innerHorizontal: boolean\n}\n\ninterface TextTableCellState {\n textBuffer: TextBuffer\n textBufferView: TextBufferView\n syntaxStyle: SyntaxStyle\n}\n\ninterface TextTableLayout {\n columnWidths: number[]\n rowHeights: number[]\n columnOffsets: number[]\n rowOffsets: number[]\n columnOffsetsI32: Int32Array\n rowOffsetsI32: Int32Array\n tableWidth: number\n tableHeight: number\n}\n\ninterface CellPosition {\n rowIdx: number\n colIdx: number\n}\n\ninterface RowRange {\n firstRow: number\n lastRow: number\n}\n\ntype TableSelectionMode = \"single-cell\" | \"column-locked\" | \"grid\"\n\ninterface SelectionResolution {\n mode: TableSelectionMode\n anchorCell: CellPosition | null\n anchorColumn: number | null\n}\n\ninterface CellSelectionCoords {\n anchorX: number\n anchorY: number\n focusX: number\n focusY: number\n}\n\nexport interface TextTableOptions extends RenderableOptions {\n content?: TextTableContent\n wrapMode?: \"none\" | \"char\" | \"word\"\n columnWidthMode?: TextTableColumnWidthMode\n columnFitter?: TextTableColumnFitter\n cellPadding?: number\n cellPaddingX?: number\n cellPaddingY?: number\n columnGap?: number\n showBorders?: boolean\n border?: boolean\n outerBorder?: boolean\n selectable?: boolean\n selectionBg?: ColorInput\n selectionFg?: ColorInput\n borderStyle?: BorderStyle\n borderColor?: ColorInput\n borderBackgroundColor?: ColorInput\n backgroundColor?: ColorInput\n fg?: ColorInput\n bg?: ColorInput\n attributes?: number\n}\n\nexport class TextTableRenderable extends Renderable {\n private _content: TextTableContent\n private _wrapMode: \"none\" | \"char\" | \"word\"\n private _columnWidthMode: TextTableColumnWidthMode\n private _columnFitter: TextTableColumnFitter\n private _cellPaddingX: number\n private _cellPaddingY: number\n private _columnGap: number\n private _showBorders: boolean\n private _border: boolean\n private _outerBorder: boolean\n private _hasExplicitOuterBorder: boolean\n private _borderStyle: BorderStyle\n private _borderColor: RGBA\n private _borderBackgroundColor: RGBA\n private _backgroundColor: RGBA\n private _defaultFg: RGBA\n private _defaultBg: RGBA\n private _defaultAttributes: number\n private _selectionBg: RGBA | undefined\n private _selectionFg: RGBA | undefined\n private _lastLocalSelection: LocalSelectionBounds | null = null\n private _lastSelectionMode: TableSelectionMode | null = null\n\n private _cells: TextTableCellState[][] = []\n private _prevCellContent: TextTableCellContent[][] = []\n private _rowCount: number = 0\n private _columnCount: number = 0\n\n private _layout: TextTableLayout = this.createEmptyLayout()\n private _layoutDirty: boolean = true\n private _rasterDirty: boolean = true\n\n private _cachedMeasureLayout: TextTableLayout | null = null\n private _cachedMeasureWidth: number | undefined = undefined\n\n private readonly _defaultOptions = {\n content: [] as TextTableContent,\n wrapMode: \"word\" as \"none\" | \"char\" | \"word\",\n columnWidthMode: \"full\" as TextTableColumnWidthMode,\n columnFitter: \"proportional\" as TextTableColumnFitter,\n cellPadding: 0,\n cellPaddingX: undefined as number | undefined,\n cellPaddingY: undefined as number | undefined,\n columnGap: 0,\n showBorders: true,\n border: true,\n outerBorder: true,\n selectable: true,\n selectionBg: undefined as ColorInput | undefined,\n selectionFg: undefined as ColorInput | undefined,\n borderStyle: \"single\" as BorderStyle,\n borderColor: \"#FFFFFF\",\n borderBackgroundColor: \"transparent\",\n backgroundColor: \"transparent\",\n fg: \"#FFFFFF\",\n bg: \"transparent\",\n attributes: 0,\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: TextTableOptions = {}) {\n super(ctx, { ...options, flexShrink: options.flexShrink ?? 0, buffered: true })\n\n this._content = options.content ?? this._defaultOptions.content\n this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode\n this._columnWidthMode = options.columnWidthMode ?? this._defaultOptions.columnWidthMode\n this._columnFitter = this.resolveColumnFitter(options.columnFitter)\n this._cellPaddingX = this.resolveCellPadding(options.cellPaddingX ?? options.cellPadding)\n this._cellPaddingY = this.resolveCellPadding(options.cellPaddingY ?? options.cellPadding)\n this._columnGap = this.resolveColumnGap(options.columnGap)\n this._showBorders = options.showBorders ?? this._defaultOptions.showBorders\n this._border = options.border ?? this._defaultOptions.border\n this._hasExplicitOuterBorder = options.outerBorder !== undefined\n this._outerBorder = options.outerBorder ?? this._border\n this.selectable = options.selectable ?? this._defaultOptions.selectable\n this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : undefined\n this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : undefined\n this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle)\n this._borderColor = parseColor(options.borderColor ?? this._defaultOptions.borderColor)\n this._borderBackgroundColor = parseColor(\n options.borderBackgroundColor ?? this._defaultOptions.borderBackgroundColor,\n )\n this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor)\n this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg)\n this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg)\n this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes\n\n this.setupMeasureFunc()\n this.rebuildCells()\n }\n\n public get content(): TextTableContent {\n return this._content\n }\n\n public set content(value: TextTableContent) {\n this._content = value ?? []\n this.rebuildCells()\n }\n\n public get wrapMode(): \"none\" | \"char\" | \"word\" {\n return this._wrapMode\n }\n\n public set wrapMode(value: \"none\" | \"char\" | \"word\") {\n if (this._wrapMode === value) return\n this._wrapMode = value\n for (const row of this._cells) {\n for (const cell of row) {\n cell.textBufferView.setWrapMode(value)\n }\n }\n this.invalidateLayoutAndRaster()\n }\n\n public get columnWidthMode(): TextTableColumnWidthMode {\n return this._columnWidthMode\n }\n\n public set columnWidthMode(value: TextTableColumnWidthMode) {\n if (this._columnWidthMode === value) return\n this._columnWidthMode = value\n this.invalidateLayoutAndRaster()\n }\n\n public get columnFitter(): TextTableColumnFitter {\n return this._columnFitter\n }\n\n public set columnFitter(value: TextTableColumnFitter) {\n const next = this.resolveColumnFitter(value)\n if (this._columnFitter === next) return\n this._columnFitter = next\n this.invalidateLayoutAndRaster()\n }\n\n public get cellPadding(): number {\n return this._cellPaddingX === this._cellPaddingY ? this._cellPaddingX : 0\n }\n\n public set cellPadding(value: number) {\n const next = this.resolveCellPadding(value)\n if (this._cellPaddingX === next && this._cellPaddingY === next) return\n this._cellPaddingX = next\n this._cellPaddingY = next\n this.invalidateLayoutAndRaster()\n }\n\n public get cellPaddingX(): number {\n return this._cellPaddingX\n }\n\n public set cellPaddingX(value: number) {\n const next = this.resolveCellPadding(value)\n if (this._cellPaddingX === next) return\n this._cellPaddingX = next\n this.invalidateLayoutAndRaster()\n }\n\n public get cellPaddingY(): number {\n return this._cellPaddingY\n }\n\n public set cellPaddingY(value: number) {\n const next = this.resolveCellPadding(value)\n if (this._cellPaddingY === next) return\n this._cellPaddingY = next\n this.invalidateLayoutAndRaster()\n }\n\n public get columnGap(): number {\n return this._columnGap\n }\n\n public set columnGap(value: number) {\n const next = this.resolveColumnGap(value)\n if (this._columnGap === next) return\n this._columnGap = next\n this.invalidateLayoutAndRaster()\n }\n\n public get showBorders(): boolean {\n return this._showBorders\n }\n\n public set showBorders(value: boolean) {\n if (this._showBorders === value) return\n this._showBorders = value\n this.invalidateRasterOnly()\n }\n\n public get outerBorder(): boolean {\n return this._outerBorder\n }\n\n public set outerBorder(value: boolean) {\n if (this._outerBorder === value) return\n\n this._hasExplicitOuterBorder = true\n this._outerBorder = value\n this.invalidateLayoutAndRaster()\n }\n\n public get border(): boolean {\n return this._border\n }\n\n public set border(value: boolean) {\n if (this._border === value) return\n\n this._border = value\n\n if (!this._hasExplicitOuterBorder) {\n this._outerBorder = value\n }\n\n this.invalidateLayoutAndRaster()\n }\n\n public get borderStyle(): BorderStyle {\n return this._borderStyle\n }\n\n public set borderStyle(value: BorderStyle) {\n const next = parseBorderStyle(value, this._defaultOptions.borderStyle)\n if (this._borderStyle === next) return\n this._borderStyle = next\n this.invalidateRasterOnly()\n }\n\n public get borderColor(): RGBA {\n return this._borderColor\n }\n\n public set borderColor(value: ColorInput) {\n const next = parseColor(value)\n if (this._borderColor === next) return\n this._borderColor = next\n this.invalidateRasterOnly()\n }\n\n public shouldStartSelection(x: number, y: number): boolean {\n if (!this.selectable) return false\n\n this.ensureLayoutReady()\n\n const localX = x - this.x\n const localY = y - this.y\n return this.getCellAtLocalPosition(localX, localY) !== null\n }\n\n public onSelectionChanged(selection: Selection | null): boolean {\n this.ensureLayoutReady()\n\n const previousLocalSelection = this._lastLocalSelection\n const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y)\n this._lastLocalSelection = localSelection\n const dirtyRows = this.getDirtySelectionRowRange(previousLocalSelection, localSelection)\n\n if (!localSelection?.isActive) {\n this.resetCellSelections()\n this._lastSelectionMode = null\n } else {\n this.applySelectionToCells(localSelection, selection?.isStart ?? false)\n }\n\n if (dirtyRows !== null) {\n this.redrawSelectionRows(dirtyRows.firstRow, dirtyRows.lastRow)\n }\n\n return this.hasSelection()\n }\n\n public hasSelection(): boolean {\n for (const row of this._cells) {\n for (const cell of row) {\n if (cell.textBufferView.hasSelection()) {\n return true\n }\n }\n }\n\n return false\n }\n\n public getSelection(): { start: number; end: number } | null {\n for (const row of this._cells) {\n for (const cell of row) {\n const selection = cell.textBufferView.getSelection()\n if (selection) {\n return selection\n }\n }\n }\n\n return null\n }\n\n public getSelectedText(): string {\n const selectedRows: string[] = []\n\n for (let rowIdx = 0; rowIdx < this._rowCount; rowIdx++) {\n const rowSelections: string[] = []\n\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const cell = this._cells[rowIdx]?.[colIdx]\n if (!cell || !cell.textBufferView.hasSelection()) continue\n\n const selectedText = cell.textBufferView.getSelectedText()\n if (selectedText.length > 0) {\n rowSelections.push(selectedText)\n }\n }\n\n if (rowSelections.length > 0) {\n selectedRows.push(rowSelections.join(\"\\t\"))\n }\n }\n\n return selectedRows.join(\"\\n\")\n }\n\n protected onResize(width: number, height: number): void {\n this.invalidateLayoutAndRaster(false)\n super.onResize(width, height)\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n if (!this.visible || this.isDestroyed) return\n\n if (this._layoutDirty) {\n this.rebuildLayoutForCurrentWidth()\n }\n\n if (!this._rasterDirty) return\n\n buffer.clear(this._backgroundColor)\n\n if (this._rowCount === 0 || this._columnCount === 0) {\n this._rasterDirty = false\n return\n }\n\n this.drawBorders(buffer)\n this.drawCells(buffer)\n\n this._rasterDirty = false\n }\n\n protected destroySelf(): void {\n this.destroyCells()\n super.destroySelf()\n }\n\n private setupMeasureFunc(): void {\n const measureFunc = (\n width: number,\n widthMode: MeasureMode,\n _height: number,\n _heightMode: MeasureMode,\n ): { width: number; height: number } => {\n const hasWidthConstraint = widthMode !== MeasureMode.Undefined && Number.isFinite(width)\n const rawWidthConstraint = hasWidthConstraint ? Math.max(1, Math.floor(width)) : undefined\n const widthConstraint = this.resolveLayoutWidthConstraint(rawWidthConstraint)\n const measuredLayout = this.computeLayout(widthConstraint)\n this._cachedMeasureLayout = measuredLayout\n this._cachedMeasureWidth = widthConstraint\n\n let measuredWidth = measuredLayout.tableWidth > 0 ? measuredLayout.tableWidth : 1\n let measuredHeight = measuredLayout.tableHeight > 0 ? measuredLayout.tableHeight : 1\n\n if (widthMode === MeasureMode.AtMost && rawWidthConstraint !== undefined && this._positionType !== \"absolute\") {\n measuredWidth = Math.min(rawWidthConstraint, measuredWidth)\n }\n\n // Keep intrinsic height even under AtMost constraints. Clamping here can under-report\n // content height during Yoga measure passes and leave parent scroll extents stale.\n return {\n width: measuredWidth,\n height: measuredHeight,\n }\n }\n\n this.yogaNode.setMeasureFunc(measureFunc)\n }\n\n private rebuildCells(): void {\n const newRowCount = this._content.length\n const newColumnCount = this._content.reduce((max, row) => Math.max(max, row.length), 0)\n\n if (this._cells.length === 0) {\n this._rowCount = newRowCount\n this._columnCount = newColumnCount\n this._cells = []\n this._prevCellContent = []\n\n for (let rowIdx = 0; rowIdx < newRowCount; rowIdx++) {\n const row = this._content[rowIdx] ?? []\n const rowCells: TextTableCellState[] = []\n const rowRefs: TextTableCellContent[] = []\n\n for (let colIdx = 0; colIdx < newColumnCount; colIdx++) {\n const cellContent = row[colIdx]\n rowCells.push(this.createCell(cellContent))\n rowRefs.push(cellContent)\n }\n\n this._cells.push(rowCells)\n this._prevCellContent.push(rowRefs)\n }\n\n this.invalidateLayoutAndRaster()\n return\n }\n\n this.updateCellsDiff(newRowCount, newColumnCount)\n this.invalidateLayoutAndRaster()\n }\n\n private updateCellsDiff(newRowCount: number, newColumnCount: number): void {\n const oldRowCount = this._rowCount\n const oldColumnCount = this._columnCount\n const keepRows = Math.min(oldRowCount, newRowCount)\n const keepCols = Math.min(oldColumnCount, newColumnCount)\n\n for (let rowIdx = 0; rowIdx < keepRows; rowIdx++) {\n const newRow = this._content[rowIdx] ?? []\n const cellRow = this._cells[rowIdx]\n const refRow = this._prevCellContent[rowIdx]\n\n for (let colIdx = 0; colIdx < keepCols; colIdx++) {\n const cellContent = newRow[colIdx]\n if (cellContent === refRow[colIdx]) continue\n\n const oldCell = cellRow[colIdx]\n oldCell.textBufferView.destroy()\n oldCell.textBuffer.destroy()\n oldCell.syntaxStyle.destroy()\n\n cellRow[colIdx] = this.createCell(cellContent)\n refRow[colIdx] = cellContent\n }\n\n if (newColumnCount > oldColumnCount) {\n for (let colIdx = oldColumnCount; colIdx < newColumnCount; colIdx++) {\n const cellContent = newRow[colIdx]\n cellRow.push(this.createCell(cellContent))\n refRow.push(cellContent)\n }\n } else if (newColumnCount < oldColumnCount) {\n for (let colIdx = newColumnCount; colIdx < oldColumnCount; colIdx++) {\n const cell = cellRow[colIdx]\n cell.textBufferView.destroy()\n cell.textBuffer.destroy()\n cell.syntaxStyle.destroy()\n }\n cellRow.length = newColumnCount\n refRow.length = newColumnCount\n }\n }\n\n if (newRowCount > oldRowCount) {\n for (let rowIdx = oldRowCount; rowIdx < newRowCount; rowIdx++) {\n const newRow = this._content[rowIdx] ?? []\n const rowCells: TextTableCellState[] = []\n const rowRefs: TextTableCellContent[] = []\n\n for (let colIdx = 0; colIdx < newColumnCount; colIdx++) {\n const cellContent = newRow[colIdx]\n rowCells.push(this.createCell(cellContent))\n rowRefs.push(cellContent)\n }\n\n this._cells.push(rowCells)\n this._prevCellContent.push(rowRefs)\n }\n } else if (newRowCount < oldRowCount) {\n for (let rowIdx = newRowCount; rowIdx < oldRowCount; rowIdx++) {\n const row = this._cells[rowIdx]\n for (const cell of row) {\n cell.textBufferView.destroy()\n cell.textBuffer.destroy()\n cell.syntaxStyle.destroy()\n }\n }\n this._cells.length = newRowCount\n this._prevCellContent.length = newRowCount\n }\n\n this._rowCount = newRowCount\n this._columnCount = newColumnCount\n }\n\n private createCell(content: TextTableCellContent): TextTableCellState {\n const styledText = this.toStyledText(content)\n const textBuffer = TextBuffer.create(this._ctx.widthMethod)\n const syntaxStyle = SyntaxStyle.create()\n\n textBuffer.setDefaultFg(this._defaultFg)\n textBuffer.setDefaultBg(this._defaultBg)\n textBuffer.setDefaultAttributes(this._defaultAttributes)\n textBuffer.setSyntaxStyle(syntaxStyle)\n textBuffer.setStyledText(styledText)\n\n const textBufferView = TextBufferView.create(textBuffer)\n textBufferView.setWrapMode(this._wrapMode)\n\n return { textBuffer, textBufferView, syntaxStyle }\n }\n\n private toStyledText(content: TextTableCellContent): StyledText {\n if (Array.isArray(content)) {\n return new StyledText(content)\n }\n\n if (content === null || content === undefined) {\n return stringToStyledText(\"\")\n }\n\n return stringToStyledText(String(content))\n }\n\n private destroyCells(): void {\n for (const row of this._cells) {\n for (const cell of row) {\n cell.textBufferView.destroy()\n cell.textBuffer.destroy()\n cell.syntaxStyle.destroy()\n }\n }\n\n this._cells = []\n this._prevCellContent = []\n this._rowCount = 0\n this._columnCount = 0\n this._layout = this.createEmptyLayout()\n }\n\n private rebuildLayoutForCurrentWidth(): void {\n const maxTableWidth = this.resolveLayoutWidthConstraint(this.width)\n\n let layout: TextTableLayout\n if (this._cachedMeasureLayout !== null && this._cachedMeasureWidth === maxTableWidth) {\n layout = this._cachedMeasureLayout\n } else {\n layout = this.computeLayout(maxTableWidth)\n }\n this._cachedMeasureLayout = null\n this._cachedMeasureWidth = undefined\n\n this._layout = layout\n this.applyLayoutToViews(layout)\n this._layoutDirty = false\n\n if (this._lastLocalSelection?.isActive) {\n this.applySelectionToCells(this._lastLocalSelection, true)\n }\n }\n\n private computeLayout(maxTableWidth?: number): TextTableLayout {\n if (this._rowCount === 0 || this._columnCount === 0) {\n return this.createEmptyLayout()\n }\n\n const borderLayout = this.resolveBorderLayout()\n const columnWidths = this.computeColumnWidths(maxTableWidth, borderLayout)\n const rowHeights = this.computeRowHeights(columnWidths)\n const columnOffsets = this.computeOffsets(\n columnWidths,\n borderLayout.left,\n borderLayout.right,\n borderLayout.innerVertical,\n this.getInterColumnGap(borderLayout),\n )\n const rowOffsets = this.computeOffsets(\n rowHeights,\n borderLayout.top,\n borderLayout.bottom,\n borderLayout.innerHorizontal,\n )\n return {\n columnWidths,\n rowHeights,\n columnOffsets,\n rowOffsets,\n columnOffsetsI32: new Int32Array(columnOffsets),\n rowOffsetsI32: new Int32Array(rowOffsets),\n tableWidth: (columnOffsets[columnOffsets.length - 1] ?? 0) + 1,\n tableHeight: (rowOffsets[rowOffsets.length - 1] ?? 0) + 1,\n }\n }\n\n private isFullWidthMode(): boolean {\n return this._columnWidthMode === \"full\"\n }\n\n private computeColumnWidths(maxTableWidth: number | undefined, borderLayout: ResolvedTableBorderLayout): number[] {\n const horizontalPadding = this.getHorizontalCellPadding()\n const intrinsicWidths = new Array(this._columnCount).fill(1 + horizontalPadding)\n\n for (let rowIdx = 0; rowIdx < this._rowCount; rowIdx++) {\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const cell = this._cells[rowIdx]?.[colIdx]\n if (!cell) continue\n\n const measure = cell.textBufferView.measureForDimensions(0, MEASURE_HEIGHT)\n const measuredWidth = Math.max(1, measure?.widthColsMax ?? 0) + horizontalPadding\n intrinsicWidths[colIdx] = Math.max(intrinsicWidths[colIdx], measuredWidth)\n }\n }\n\n if (maxTableWidth === undefined || !Number.isFinite(maxTableWidth) || maxTableWidth <= 0) {\n return intrinsicWidths\n }\n\n const maxContentWidth = Math.max(\n 1,\n Math.floor(maxTableWidth) - this.getVerticalBorderCount(borderLayout) - this.getTotalInterColumnGap(borderLayout),\n )\n const currentWidth = intrinsicWidths.reduce((sum, width) => sum + width, 0)\n\n if (currentWidth === maxContentWidth) {\n return intrinsicWidths\n }\n\n if (currentWidth < maxContentWidth) {\n if (this.isFullWidthMode()) {\n return this.expandColumnWidths(intrinsicWidths, maxContentWidth)\n }\n\n return intrinsicWidths\n }\n\n if (this._wrapMode === \"none\") {\n return intrinsicWidths\n }\n\n return this.fitColumnWidths(intrinsicWidths, maxContentWidth)\n }\n\n private expandColumnWidths(widths: number[], targetContentWidth: number): number[] {\n const baseWidths = widths.map((width) => Math.max(1, Math.floor(width)))\n const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0)\n\n if (totalBaseWidth >= targetContentWidth) {\n return baseWidths\n }\n\n const expanded = [...baseWidths]\n const columns = expanded.length\n const extraWidth = targetContentWidth - totalBaseWidth\n const sharedWidth = Math.floor(extraWidth / columns)\n const remainder = extraWidth % columns\n\n for (let idx = 0; idx < columns; idx++) {\n expanded[idx] += sharedWidth\n if (idx < remainder) {\n expanded[idx] += 1\n }\n }\n\n return expanded\n }\n\n private fitColumnWidths(widths: number[], targetContentWidth: number): number[] {\n if (this._columnFitter === \"balanced\") {\n return this.fitColumnWidthsBalanced(widths, targetContentWidth)\n }\n\n return this.fitColumnWidthsProportional(widths, targetContentWidth)\n }\n\n private fitColumnWidthsProportional(widths: number[], targetContentWidth: number): number[] {\n const minWidth = 1 + this.getHorizontalCellPadding()\n const hardMinWidths = new Array(widths.length).fill(minWidth)\n const baseWidths = widths.map((width) => Math.max(1, Math.floor(width)))\n\n const preferredMinWidths = baseWidths.map((width) => Math.min(width, minWidth + 1))\n const preferredMinTotal = preferredMinWidths.reduce((sum, width) => sum + width, 0)\n\n const floorWidths = preferredMinTotal <= targetContentWidth ? preferredMinWidths : hardMinWidths\n const floorTotal = floorWidths.reduce((sum, width) => sum + width, 0)\n const clampedTarget = Math.max(floorTotal, targetContentWidth)\n\n const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0)\n\n if (totalBaseWidth <= clampedTarget) {\n return baseWidths\n }\n\n const shrinkable = baseWidths.map((width, idx) => width - floorWidths[idx])\n const totalShrinkable = shrinkable.reduce((sum, value) => sum + value, 0)\n if (totalShrinkable <= 0) {\n return [...floorWidths]\n }\n\n const targetShrink = totalBaseWidth - clampedTarget\n const integerShrink = new Array(baseWidths.length).fill(0)\n const fractions = new Array(baseWidths.length).fill(0)\n let usedShrink = 0\n\n for (let idx = 0; idx < baseWidths.length; idx++) {\n if (shrinkable[idx] <= 0) continue\n\n const exact = (shrinkable[idx] / totalShrinkable) * targetShrink\n const whole = Math.min(shrinkable[idx], Math.floor(exact))\n integerShrink[idx] = whole\n fractions[idx] = exact - whole\n usedShrink += whole\n }\n\n let remainingShrink = targetShrink - usedShrink\n\n while (remainingShrink > 0) {\n let bestIdx = -1\n let bestFraction = -1\n\n for (let idx = 0; idx < baseWidths.length; idx++) {\n if (shrinkable[idx] - integerShrink[idx] <= 0) continue\n if (fractions[idx] > bestFraction) {\n bestFraction = fractions[idx]\n bestIdx = idx\n }\n }\n\n if (bestIdx === -1) break\n\n integerShrink[bestIdx] += 1\n fractions[bestIdx] = 0\n remainingShrink -= 1\n }\n\n return baseWidths.map((width, idx) => Math.max(floorWidths[idx], width - integerShrink[idx]))\n }\n\n private fitColumnWidthsBalanced(widths: number[], targetContentWidth: number): number[] {\n const minWidth = 1 + this.getHorizontalCellPadding()\n const hardMinWidths = new Array(widths.length).fill(minWidth)\n const baseWidths = widths.map((width) => Math.max(1, Math.floor(width)))\n const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0)\n const columns = baseWidths.length\n\n if (columns === 0 || totalBaseWidth <= targetContentWidth) {\n return baseWidths\n }\n\n const evenShare = Math.max(minWidth, Math.floor(targetContentWidth / columns))\n const preferredMinWidths = baseWidths.map((width) => Math.min(width, evenShare))\n const preferredMinTotal = preferredMinWidths.reduce((sum, width) => sum + width, 0)\n const floorWidths = preferredMinTotal <= targetContentWidth ? preferredMinWidths : hardMinWidths\n const floorTotal = floorWidths.reduce((sum, width) => sum + width, 0)\n const clampedTarget = Math.max(floorTotal, targetContentWidth)\n\n if (totalBaseWidth <= clampedTarget) {\n return baseWidths\n }\n\n const shrinkable = baseWidths.map((width, idx) => width - floorWidths[idx])\n const totalShrinkable = shrinkable.reduce((sum, value) => sum + value, 0)\n if (totalShrinkable <= 0) {\n return [...floorWidths]\n }\n\n const targetShrink = totalBaseWidth - clampedTarget\n const shrink = this.allocateShrinkByWeight(shrinkable, targetShrink, \"sqrt\")\n\n return baseWidths.map((width, idx) => Math.max(floorWidths[idx], width - shrink[idx]))\n }\n\n private allocateShrinkByWeight(shrinkable: number[], targetShrink: number, mode: \"linear\" | \"sqrt\"): number[] {\n const shrink = new Array(shrinkable.length).fill(0)\n\n if (targetShrink <= 0) {\n return shrink\n }\n\n const weights = shrinkable.map((value) => {\n if (value <= 0) {\n return 0\n }\n\n return mode === \"sqrt\" ? Math.sqrt(value) : value\n })\n const totalWeight = weights.reduce((sum, value) => sum + value, 0)\n\n if (totalWeight <= 0) {\n return shrink\n }\n\n const fractions = new Array(shrinkable.length).fill(0)\n let usedShrink = 0\n\n for (let idx = 0; idx < shrinkable.length; idx++) {\n if (shrinkable[idx] <= 0 || weights[idx] <= 0) continue\n\n const exact = (weights[idx] / totalWeight) * targetShrink\n const whole = Math.min(shrinkable[idx], Math.floor(exact))\n shrink[idx] = whole\n fractions[idx] = exact - whole\n usedShrink += whole\n }\n\n let remainingShrink = targetShrink - usedShrink\n\n while (remainingShrink > 0) {\n let bestIdx = -1\n let bestFraction = -1\n\n for (let idx = 0; idx < shrinkable.length; idx++) {\n if (shrinkable[idx] - shrink[idx] <= 0) continue\n\n if (\n bestIdx === -1 ||\n fractions[idx] > bestFraction ||\n (fractions[idx] === bestFraction && shrinkable[idx] > shrinkable[bestIdx])\n ) {\n bestIdx = idx\n bestFraction = fractions[idx]\n }\n }\n\n if (bestIdx === -1) {\n break\n }\n\n shrink[bestIdx] += 1\n fractions[bestIdx] = 0\n remainingShrink -= 1\n }\n\n return shrink\n }\n\n private computeRowHeights(columnWidths: number[]): number[] {\n const horizontalPadding = this.getHorizontalCellPadding()\n const verticalPadding = this.getVerticalCellPadding()\n const rowHeights = new Array(this._rowCount).fill(1 + verticalPadding)\n\n for (let rowIdx = 0; rowIdx < this._rowCount; rowIdx++) {\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const cell = this._cells[rowIdx]?.[colIdx]\n if (!cell) continue\n\n const width = Math.max(1, (columnWidths[colIdx] ?? 1) - horizontalPadding)\n const measure = cell.textBufferView.measureForDimensions(width, MEASURE_HEIGHT)\n const lineCount = Math.max(1, measure?.lineCount ?? 1)\n rowHeights[rowIdx] = Math.max(rowHeights[rowIdx], lineCount + verticalPadding)\n }\n }\n\n return rowHeights\n }\n\n private computeOffsets(\n parts: number[],\n startBoundary: boolean,\n endBoundary: boolean,\n includeInnerBoundaries: boolean,\n innerGap: number = 0,\n ): number[] {\n const offsets: number[] = [startBoundary ? 0 : -1]\n let cursor = offsets[0] ?? 0\n\n for (let idx = 0; idx < parts.length; idx++) {\n const size = parts[idx] ?? 1\n const separatorAfter = idx < parts.length - 1 ? (includeInnerBoundaries ? 1 : innerGap) : endBoundary ? 1 : 0\n cursor += size + separatorAfter\n offsets.push(cursor)\n }\n\n return offsets\n }\n\n private getInterColumnGap(borderLayout: ResolvedTableBorderLayout): number {\n if (borderLayout.innerVertical) {\n return 0\n }\n\n return this._columnGap\n }\n\n private getTotalInterColumnGap(borderLayout: ResolvedTableBorderLayout): number {\n return Math.max(0, this._columnCount - 1) * this.getInterColumnGap(borderLayout)\n }\n\n private applyLayoutToViews(layout: TextTableLayout): void {\n const horizontalPadding = this.getHorizontalCellPadding()\n const verticalPadding = this.getVerticalCellPadding()\n\n for (let rowIdx = 0; rowIdx < this._rowCount; rowIdx++) {\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const cell = this._cells[rowIdx]?.[colIdx]\n if (!cell) continue\n\n const colWidth = layout.columnWidths[colIdx] ?? 1\n const rowHeight = layout.rowHeights[rowIdx] ?? 1\n const contentWidth = Math.max(1, colWidth - horizontalPadding)\n const contentHeight = Math.max(1, rowHeight - verticalPadding)\n\n if (this._wrapMode === \"none\") {\n cell.textBufferView.setWrapWidth(null)\n } else {\n cell.textBufferView.setWrapWidth(contentWidth)\n }\n\n cell.textBufferView.setViewport(0, 0, contentWidth, contentHeight)\n }\n }\n }\n\n private resolveBorderLayout(): ResolvedTableBorderLayout {\n return {\n left: this._outerBorder,\n right: this._outerBorder,\n top: this._outerBorder,\n bottom: this._outerBorder,\n innerVertical: this._border && this._columnCount > 1,\n innerHorizontal: this._border && this._rowCount > 1,\n }\n }\n\n private getVerticalBorderCount(borderLayout: ResolvedTableBorderLayout): number {\n return (\n (borderLayout.left ? 1 : 0) +\n (borderLayout.right ? 1 : 0) +\n (borderLayout.innerVertical ? Math.max(0, this._columnCount - 1) : 0)\n )\n }\n\n private getHorizontalBorderCount(borderLayout: ResolvedTableBorderLayout): number {\n return (\n (borderLayout.top ? 1 : 0) +\n (borderLayout.bottom ? 1 : 0) +\n (borderLayout.innerHorizontal ? Math.max(0, this._rowCount - 1) : 0)\n )\n }\n\n private drawBorders(buffer: OptimizedBuffer): void {\n if (!this._showBorders) {\n return\n }\n\n const borderLayout = this.resolveBorderLayout()\n\n if (this.getVerticalBorderCount(borderLayout) === 0 && this.getHorizontalBorderCount(borderLayout) === 0) {\n return\n }\n\n buffer.drawGrid({\n borderChars: BorderCharArrays[this._borderStyle],\n borderFg: this._borderColor,\n borderBg: this._borderBackgroundColor,\n columnOffsets: this._layout.columnOffsetsI32,\n rowOffsets: this._layout.rowOffsetsI32,\n drawInner: this._border,\n drawOuter: this._outerBorder,\n })\n }\n\n private drawCells(buffer: OptimizedBuffer): void {\n this.drawCellRange(buffer, 0, this._rowCount - 1)\n }\n\n private drawCellRange(buffer: OptimizedBuffer, firstRow: number, lastRow: number): void {\n const colOffsets = this._layout.columnOffsets\n const rowOffsets = this._layout.rowOffsets\n const cellPaddingX = this._cellPaddingX\n const cellPaddingY = this._cellPaddingY\n\n for (let rowIdx = firstRow; rowIdx <= lastRow; rowIdx++) {\n const cellY = (rowOffsets[rowIdx] ?? 0) + 1 + cellPaddingY\n\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const cell = this._cells[rowIdx]?.[colIdx]\n if (!cell) continue\n buffer.drawTextBuffer(cell.textBufferView, (colOffsets[colIdx] ?? 0) + 1 + cellPaddingX, cellY)\n }\n }\n }\n\n private redrawSelectionRows(firstRow: number, lastRow: number): void {\n if (firstRow > lastRow) return\n\n if (this._backgroundColor.a < 1) {\n this.invalidateRasterOnly()\n return\n }\n\n const buffer = this.frameBuffer\n if (!buffer) return\n\n this.clearCellRange(buffer, firstRow, lastRow)\n this.drawCellRange(buffer, firstRow, lastRow)\n this.requestRender()\n }\n\n private clearCellRange(buffer: OptimizedBuffer, firstRow: number, lastRow: number): void {\n const colWidths = this._layout.columnWidths\n const rowHeights = this._layout.rowHeights\n const colOffsets = this._layout.columnOffsets\n const rowOffsets = this._layout.rowOffsets\n\n for (let rowIdx = firstRow; rowIdx <= lastRow; rowIdx++) {\n const cellY = (rowOffsets[rowIdx] ?? 0) + 1\n const rowHeight = rowHeights[rowIdx] ?? 1\n\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const cellX = (colOffsets[colIdx] ?? 0) + 1\n const colWidth = colWidths[colIdx] ?? 1\n if (this._backgroundColor.a < 1) {\n for (let y = cellY; y < cellY + rowHeight; y++) {\n for (let x = cellX; x < cellX + colWidth; x++) {\n buffer.setCell(x, y, \" \", this._defaultFg, this._backgroundColor, this._defaultAttributes)\n }\n }\n } else {\n buffer.fillRect(cellX, cellY, colWidth, rowHeight, this._backgroundColor)\n }\n }\n }\n }\n\n private ensureLayoutReady(): void {\n if (!this._layoutDirty) return\n this.rebuildLayoutForCurrentWidth()\n }\n\n private getCellAtLocalPosition(localX: number, localY: number): CellPosition | null {\n if (this._rowCount === 0 || this._columnCount === 0) return null\n if (localX < 0 || localY < 0 || localX >= this._layout.tableWidth || localY >= this._layout.tableHeight) {\n return null\n }\n\n let rowIdx = -1\n for (let idx = 0; idx < this._rowCount; idx++) {\n const top = (this._layout.rowOffsets[idx] ?? 0) + 1\n const bottom = top + (this._layout.rowHeights[idx] ?? 1) - 1\n if (localY >= top && localY <= bottom) {\n rowIdx = idx\n break\n }\n }\n\n if (rowIdx < 0) return null\n\n let colIdx = -1\n for (let idx = 0; idx < this._columnCount; idx++) {\n const left = (this._layout.columnOffsets[idx] ?? 0) + 1\n const right = left + (this._layout.columnWidths[idx] ?? 1) - 1\n if (localX >= left && localX <= right) {\n colIdx = idx\n break\n }\n }\n\n if (colIdx < 0) return null\n\n return { rowIdx, colIdx }\n }\n\n private applySelectionToCells(localSelection: LocalSelectionBounds, isStart: boolean): void {\n if (localSelection.anchorX === localSelection.focusX && localSelection.anchorY === localSelection.focusY) {\n this.resetCellSelections()\n this._lastSelectionMode = null\n return\n }\n\n const minSelY = Math.min(localSelection.anchorY, localSelection.focusY)\n const maxSelY = Math.max(localSelection.anchorY, localSelection.focusY)\n\n const firstRow = this.findRowForLocalY(minSelY)\n const lastRow = this.findRowForLocalY(maxSelY)\n const selection = this.resolveSelectionResolution(localSelection)\n const modeChanged = this._lastSelectionMode !== selection.mode\n this._lastSelectionMode = selection.mode\n const lockToAnchorColumn = selection.mode === \"column-locked\" && selection.anchorColumn !== null\n\n for (let rowIdx = 0; rowIdx < this._rowCount; rowIdx++) {\n if (rowIdx < firstRow || rowIdx > lastRow) {\n this.resetRowSelection(rowIdx)\n continue\n }\n\n const cellTop = (this._layout.rowOffsets[rowIdx] ?? 0) + 1 + this._cellPaddingY\n\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const cell = this._cells[rowIdx]?.[colIdx]\n if (!cell) continue\n\n if (lockToAnchorColumn && colIdx !== selection.anchorColumn) {\n cell.textBufferView.resetLocalSelection()\n continue\n }\n\n const cellLeft = (this._layout.columnOffsets[colIdx] ?? 0) + 1 + this._cellPaddingX\n let coords: CellSelectionCoords = {\n anchorX: localSelection.anchorX - cellLeft,\n anchorY: localSelection.anchorY - cellTop,\n focusX: localSelection.focusX - cellLeft,\n focusY: localSelection.focusY - cellTop,\n }\n\n const isAnchorCell =\n selection.anchorCell !== null &&\n selection.anchorCell.rowIdx === rowIdx &&\n selection.anchorCell.colIdx === colIdx\n\n if (selection.mode === \"single-cell\" && !isAnchorCell) {\n cell.textBufferView.resetLocalSelection()\n continue\n }\n\n const forceSet = isAnchorCell && selection.mode !== \"single-cell\"\n\n if (forceSet) {\n coords = this.getFullCellSelectionCoords(rowIdx, colIdx)\n }\n\n const shouldUseSet = isStart || modeChanged || forceSet\n\n if (shouldUseSet) {\n cell.textBufferView.setLocalSelection(\n coords.anchorX,\n coords.anchorY,\n coords.focusX,\n coords.focusY,\n this._selectionBg,\n this._selectionFg,\n )\n } else {\n cell.textBufferView.updateLocalSelection(\n coords.anchorX,\n coords.anchorY,\n coords.focusX,\n coords.focusY,\n this._selectionBg,\n this._selectionFg,\n )\n }\n }\n }\n }\n\n private resolveSelectionResolution(localSelection: LocalSelectionBounds): SelectionResolution {\n const anchorCell = this.getCellAtLocalPosition(localSelection.anchorX, localSelection.anchorY)\n const focusCell = this.getCellAtLocalPosition(localSelection.focusX, localSelection.focusY)\n const anchorColumn = anchorCell?.colIdx ?? this.getColumnAtLocalX(localSelection.anchorX)\n\n if (\n anchorCell !== null &&\n focusCell !== null &&\n anchorCell.rowIdx === focusCell.rowIdx &&\n anchorCell.colIdx === focusCell.colIdx\n ) {\n return {\n mode: \"single-cell\",\n anchorCell,\n anchorColumn,\n }\n }\n\n const focusColumn = this.getColumnAtLocalX(localSelection.focusX)\n if (anchorColumn !== null && focusColumn === anchorColumn) {\n return {\n mode: \"column-locked\",\n anchorCell,\n anchorColumn,\n }\n }\n\n return {\n mode: \"grid\",\n anchorCell,\n anchorColumn,\n }\n }\n\n private getColumnAtLocalX(localX: number): number | null {\n if (this._columnCount === 0) return null\n if (localX < 0 || localX >= this._layout.tableWidth) return null\n\n for (let colIdx = 0; colIdx < this._columnCount; colIdx++) {\n const colStart = (this._layout.columnOffsets[colIdx] ?? 0) + 1\n const colEnd = colStart + (this._layout.columnWidths[colIdx] ?? 1) - 1\n if (localX >= colStart && localX <= colEnd) {\n return colIdx\n }\n }\n\n return null\n }\n\n private getFullCellSelectionCoords(rowIdx: number, colIdx: number): CellSelectionCoords {\n const colWidth = this._layout.columnWidths[colIdx] ?? 1\n const rowHeight = this._layout.rowHeights[rowIdx] ?? 1\n const contentWidth = Math.max(1, colWidth - this.getHorizontalCellPadding())\n const contentHeight = Math.max(1, rowHeight - this.getVerticalCellPadding())\n\n return {\n anchorX: -1,\n anchorY: 0,\n focusX: contentWidth,\n focusY: contentHeight,\n }\n }\n\n private findRowForLocalY(localY: number): number {\n if (this._rowCount === 0) return 0\n if (localY < 0) return 0\n\n for (let rowIdx = 0; rowIdx < this._rowCount; rowIdx++) {\n const rowStart = (this._layout.rowOffsets[rowIdx] ?? 0) + 1\n const rowEnd = rowStart + (this._layout.rowHeights[rowIdx] ?? 1) - 1\n if (localY <= rowEnd) return rowIdx\n }\n\n return this._rowCount - 1\n }\n\n private getSelectionRowRange(selection: LocalSelectionBounds | null): RowRange | null {\n if (!selection?.isActive || this._rowCount === 0) return null\n\n const minSelY = Math.min(selection.anchorY, selection.focusY)\n const maxSelY = Math.max(selection.anchorY, selection.focusY)\n\n return {\n firstRow: this.findRowForLocalY(minSelY),\n lastRow: this.findRowForLocalY(maxSelY),\n }\n }\n\n private getDirtySelectionRowRange(\n previousSelection: LocalSelectionBounds | null,\n currentSelection: LocalSelectionBounds | null,\n ): RowRange | null {\n const previousRange = this.getSelectionRowRange(previousSelection)\n const currentRange = this.getSelectionRowRange(currentSelection)\n\n if (previousRange === null) return currentRange\n if (currentRange === null) return previousRange\n\n return {\n firstRow: Math.min(previousRange.firstRow, currentRange.firstRow),\n lastRow: Math.max(previousRange.lastRow, currentRange.lastRow),\n }\n }\n\n private resetRowSelection(rowIdx: number): void {\n const row = this._cells[rowIdx]\n if (!row) return\n\n for (const cell of row) {\n cell.textBufferView.resetLocalSelection()\n }\n }\n\n private resetCellSelections(): void {\n for (let rowIdx = 0; rowIdx < this._rowCount; rowIdx++) {\n this.resetRowSelection(rowIdx)\n }\n }\n\n private createEmptyLayout(): TextTableLayout {\n return {\n columnWidths: [],\n rowHeights: [],\n columnOffsets: [0],\n rowOffsets: [0],\n columnOffsetsI32: new Int32Array([0]),\n rowOffsetsI32: new Int32Array([0]),\n tableWidth: 0,\n tableHeight: 0,\n }\n }\n\n private resolveLayoutWidthConstraint(width: number | undefined): number | undefined {\n if (width === undefined || !Number.isFinite(width) || width <= 0) {\n return undefined\n }\n\n if (this._wrapMode !== \"none\" || this.isFullWidthMode()) {\n return Math.max(1, Math.floor(width))\n }\n\n return undefined\n }\n\n private getHorizontalCellPadding(): number {\n return this._cellPaddingX * 2\n }\n\n private getVerticalCellPadding(): number {\n return this._cellPaddingY * 2\n }\n\n private resolveColumnFitter(value: TextTableColumnFitter | undefined): TextTableColumnFitter {\n if (value === undefined) {\n return this._defaultOptions.columnFitter\n }\n\n return value === \"balanced\" ? \"balanced\" : \"proportional\"\n }\n\n private resolveCellPadding(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value)) {\n return this._defaultOptions.cellPadding\n }\n\n return Math.max(0, Math.floor(value))\n }\n\n private resolveColumnGap(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value)) {\n return this._defaultOptions.columnGap\n }\n\n return Math.max(0, Math.floor(value))\n }\n\n private invalidateLayoutAndRaster(markYogaDirty: boolean = true): void {\n this._layoutDirty = true\n this._rasterDirty = true\n this._cachedMeasureLayout = null\n this._cachedMeasureWidth = undefined\n\n if (markYogaDirty) {\n this.yogaNode.markDirty()\n }\n\n this.requestRender()\n }\n\n private invalidateRasterOnly(): void {\n this._rasterDirty = true\n this.requestRender()\n }\n}\n", + "import { Lexer, type MarkedToken } from \"marked\"\n\nexport interface ParseState {\n content: string\n tokens: MarkedToken[]\n stableTokenCount?: number\n}\n\n/**\n * Incrementally parse markdown, reusing unchanged tokens from previous parse.\n * Compares token.raw at each offset - matching tokens keep same object reference.\n */\nexport function parseMarkdownIncremental(\n newContent: string,\n prevState: ParseState | null,\n trailingUnstable: number = 2,\n): ParseState {\n if (!prevState || prevState.tokens.length === 0) {\n try {\n const tokens = Lexer.lex(newContent, { gfm: true }) as MarkedToken[]\n return {\n content: newContent,\n tokens,\n stableTokenCount: Math.max(0, tokens.length - trailingUnstable),\n }\n } catch {\n return { content: newContent, tokens: [], stableTokenCount: 0 }\n }\n }\n\n // Find how many tokens from start are unchanged\n let offset = 0\n let reuseCount = 0\n\n for (const token of prevState.tokens) {\n const tokenLength = token.raw.length\n if (offset + tokenLength <= newContent.length && newContent.startsWith(token.raw, offset)) {\n reuseCount++\n offset += tokenLength\n } else {\n break\n }\n }\n\n // Keep last N tokens unstable (e.g. \"# Hello\" might become \"# Hello World\")\n reuseCount = Math.max(0, reuseCount - trailingUnstable)\n\n offset = 0\n for (let i = 0; i < reuseCount; i++) {\n offset += prevState.tokens[i].raw.length\n }\n\n const stableTokens = prevState.tokens.slice(0, reuseCount)\n const remainingContent = newContent.slice(offset)\n\n if (!remainingContent) {\n return {\n content: newContent,\n tokens: stableTokens,\n stableTokenCount: stableTokens.length,\n }\n }\n\n try {\n const newTokens = Lexer.lex(remainingContent, { gfm: true }) as MarkedToken[]\n return {\n content: newContent,\n tokens: [...stableTokens, ...newTokens],\n stableTokenCount: trailingUnstable === 0 ? stableTokens.length + newTokens.length : stableTokens.length,\n }\n } catch {\n try {\n const fullTokens = Lexer.lex(newContent, { gfm: true }) as MarkedToken[]\n return { content: newContent, tokens: fullTokens, stableTokenCount: 0 }\n } catch {\n return { content: newContent, tokens: [], stableTokenCount: 0 }\n }\n }\n}\n", + "import { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport { type RenderContext } from \"../types.js\"\nimport { SyntaxStyle, type StyleDefinition } from \"../syntax-style.js\"\nimport type { TextChunk } from \"../text-buffer.js\"\nimport { createTextAttributes } from \"../utils.js\"\nimport type { BorderStyle } from \"../lib/border.js\"\nimport { RGBA, parseColor, type ColorInput } from \"../lib/RGBA.js\"\nimport { Lexer, type MarkedToken, type Token, type Tokens } from \"marked\"\nimport { CodeRenderable, type OnChunksCallback } from \"./Code.js\"\nimport { BoxRenderable } from \"./Box.js\"\nimport { StyledText } from \"../lib/styled-text.js\"\nimport { TextRenderable } from \"./Text.js\"\nimport {\n TextTableRenderable,\n type TextTableCellContent,\n type TextTableColumnFitter,\n type TextTableColumnWidthMode,\n type TextTableContent,\n} from \"./TextTable.js\"\nimport type { TreeSitterClient } from \"../lib/tree-sitter/index.js\"\nimport { infoStringToFiletype } from \"../lib/tree-sitter/resolve-ft.js\"\nimport { parseMarkdownIncremental, type ParseState } from \"./markdown-parser.js\"\nimport type { OptimizedBuffer } from \"../buffer.js\"\nimport { detectLinks } from \"../lib/detect-links.js\"\n\nexport type MarkdownTableStyle = \"grid\" | \"columns\"\n\nexport interface MarkdownTableOptions {\n /**\n * Visual style preset for markdown tables.\n * - \"grid\": boxed table with visible borders.\n * - \"columns\": borderless columns optimized for separated block output.\n *\n * Defaults to \"columns\" in `internalBlockMode: \"top-level\"`, otherwise \"grid\".\n */\n style?: MarkdownTableStyle\n /**\n * Strategy for sizing table columns.\n * - \"content\": columns fit to intrinsic content width.\n * - \"full\": columns expand to fill available width.\n */\n widthMode?: TextTableColumnWidthMode\n /**\n * Column fitting method when shrinking constrained tables.\n */\n columnFitter?: TextTableColumnFitter\n /**\n * Wrapping strategy for table cell content.\n */\n wrapMode?: \"none\" | \"char\" | \"word\"\n /**\n * Padding applied on all sides of each table cell.\n */\n cellPadding?: number\n /**\n * Horizontal padding applied on the left and right of each table cell.\n */\n cellPaddingX?: number\n /**\n * Vertical padding applied above and below each table cell.\n */\n cellPaddingY?: number\n /**\n * Enables/disables table border rendering.\n */\n borders?: boolean\n /**\n * Overrides outer border visibility. Defaults to `borders`.\n */\n outerBorder?: boolean\n /**\n * Border style for markdown tables.\n */\n borderStyle?: BorderStyle\n /**\n * Border color for markdown tables. Defaults to conceal style color.\n */\n borderColor?: ColorInput\n /**\n * Enables/disables selection support on markdown tables.\n */\n selectable?: boolean\n}\n\nexport interface MarkdownOptions extends RenderableOptions {\n content?: string\n syntaxStyle: SyntaxStyle\n fg?: ColorInput\n bg?: ColorInput\n /** Controls concealment for markdown syntax markers in markdown text blocks. */\n conceal?: boolean\n /** Controls concealment inside fenced code blocks rendered by CodeRenderable. */\n concealCode?: boolean\n treeSitterClient?: TreeSitterClient\n /**\n * Enable streaming mode for incremental content updates.\n *\n * Semantics:\n * - The trailing markdown block stays unstable while streaming is enabled.\n * - Tables render all rows produced by the markdown parser (including trailing rows).\n * - Incomplete table rows are normalized by the parser and rendered with empty cells\n * where data is missing.\n *\n * Expectations:\n * - Keep this true while chunks are still being appended.\n * - Set this to false once streaming is complete to finalize trailing token parsing.\n */\n streaming?: boolean\n /**\n * Options for internally rendered markdown tables.\n */\n tableOptions?: MarkdownTableOptions\n /**\n * Custom node renderer. Return a Renderable to override default rendering,\n * or undefined/null to use default rendering.\n */\n renderNode?: (token: Token, context: RenderNodeContext) => Renderable | undefined | null\n /**\n * Internal only.\n * - \"coalesced\": combine ordinary markdown into larger render blocks.\n * - \"top-level\": preserve top-level markdown blocks as separate render blocks.\n */\n internalBlockMode?: \"coalesced\" | \"top-level\"\n}\n\nexport interface RenderNodeContext {\n syntaxStyle: SyntaxStyle\n conceal: boolean\n concealCode: boolean\n treeSitterClient?: TreeSitterClient\n /** Creates default renderable for this token */\n defaultRender: () => Renderable | null\n}\n\nexport type MarkdownCodeBlockRenderer = (\n token: Tokens.Code,\n context: RenderNodeContext,\n) => Renderable | undefined | null\n\nexport type MarkdownCodeBlockRendererMap =\n | ReadonlyMap\n | Readonly>\n\ntype MarkdownRenderNode = NonNullable & {\n codeBlockOnly?: boolean\n}\n\nfunction normalizeMarkdownCodeBlockRenderers(\n renderers: MarkdownCodeBlockRendererMap,\n): ReadonlyMap {\n const rendererMap = new Map()\n const maybeMap = renderers as Partial>\n\n if (typeof maybeMap.forEach === \"function\") {\n maybeMap.forEach((renderer, language) => {\n rendererMap.set(language, renderer)\n })\n return rendererMap\n }\n\n const rendererRecord = renderers as Readonly>\n for (const [language, renderer] of Object.entries(rendererRecord)) {\n rendererMap.set(language, renderer)\n }\n\n return rendererMap\n}\n\nexport function createMarkdownCodeBlockRenderer(\n renderers: MarkdownCodeBlockRendererMap,\n): MarkdownOptions[\"renderNode\"] {\n const rendererMap = normalizeMarkdownCodeBlockRenderers(renderers)\n\n const renderNode: MarkdownRenderNode = (token, context) => {\n if (token.type !== \"code\") {\n return undefined\n }\n\n const language = infoStringToFiletype(token.lang ?? \"\")\n if (!language) return undefined\n\n return rendererMap.get(language)?.(token as Tokens.Code, context)\n }\n\n renderNode.codeBlockOnly = true\n return renderNode\n}\n\ninterface TableContentCache {\n content: TextTableContent\n cellKeys: Uint32Array[]\n}\n\ninterface CustomRenderableResult {\n renderable?: Renderable\n tableContentCache?: TableContentCache\n tracksInterBlockMargin: boolean\n canUpdateInPlace: boolean\n}\n\ninterface CustomRenderDefaultResult {\n renderable: Renderable | null | undefined\n tableContentCache?: TableContentCache\n}\n\ninterface RenderNodeResult {\n renderable?: Renderable\n defaultResult?: CustomRenderDefaultResult\n}\n\ninterface ResolvedTableRenderableOptions {\n columnWidthMode: TextTableColumnWidthMode\n columnFitter: TextTableColumnFitter\n wrapMode: \"none\" | \"char\" | \"word\"\n cellPadding: number\n cellPaddingX: number\n cellPaddingY: number\n columnGap: number\n border: boolean\n outerBorder: boolean\n showBorders: boolean\n borderStyle: BorderStyle\n borderColor: ColorInput\n selectable: boolean\n}\n\nconst TRAILING_MARKDOWN_BLOCK_BREAKS_RE = /(?:\\r?\\n){2,}$/\nconst TRAILING_MARKDOWN_BLOCK_NEWLINES_RE = /(?:\\r?\\n)+$/\n\nfunction colorsEqual(left?: RGBA, right?: RGBA): boolean {\n if (!left || !right) return left === right\n return left.equals(right)\n}\n\nexport interface BlockState {\n token: MarkedToken\n tokenRaw: string // Cache raw for comparison\n marginTop?: number\n renderable: Renderable\n tableContentCache?: TableContentCache\n tracksInterBlockMargin?: boolean\n /** Whether built-in reconciliation can update this renderable without replacing it. */\n canUpdateInPlace: boolean\n}\n\nexport type { ParseState }\n\ninterface MarkdownRenderBlock {\n token: MarkedToken\n sourceTokenEnd: number\n marginTop: number\n}\n\ninterface ListItemRenderInput {\n item: Tokens.ListItem\n marker: string\n markerWidth: number\n id: string\n}\n\nexport class MarkdownRenderable extends Renderable {\n private _content: string = \"\"\n private _syntaxStyle: SyntaxStyle\n private _fg?: RGBA\n private _bg?: RGBA\n private _conceal: boolean\n private _concealCode: boolean\n private _treeSitterClient?: TreeSitterClient\n private _tableOptions?: MarkdownTableOptions\n private _renderNode?: MarkdownOptions[\"renderNode\"]\n private _internalBlockMode: \"coalesced\" | \"top-level\"\n\n _parseState: ParseState | null = null\n private _streaming: boolean = false\n _blockStates: BlockState[] = []\n _stableBlockCount = 0\n private _styleDirty: boolean = false\n private _linkifyMarkdownChunks: OnChunksCallback = (chunks, context) =>\n detectLinks(chunks, {\n content: context.content,\n highlights: context.highlights,\n })\n\n protected _contentDefaultOptions = {\n content: \"\",\n conceal: true,\n concealCode: false,\n streaming: false,\n internalBlockMode: \"coalesced\",\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: MarkdownOptions) {\n super(ctx, {\n ...options,\n flexDirection: \"column\",\n flexShrink: options.flexShrink ?? 0,\n })\n\n this._syntaxStyle = options.syntaxStyle\n this._fg = options.fg ? parseColor(options.fg) : undefined\n this._bg = options.bg ? parseColor(options.bg) : undefined\n this._conceal = options.conceal ?? this._contentDefaultOptions.conceal\n this._concealCode = options.concealCode ?? this._contentDefaultOptions.concealCode\n this._content = options.content ?? this._contentDefaultOptions.content\n this._treeSitterClient = options.treeSitterClient\n this._tableOptions = options.tableOptions\n this._renderNode = options.renderNode\n this._streaming = options.streaming ?? this._contentDefaultOptions.streaming\n this._internalBlockMode = options.internalBlockMode ?? this._contentDefaultOptions.internalBlockMode\n\n this.updateBlocks()\n }\n\n get content(): string {\n return this._content\n }\n\n set content(value: string) {\n if (this.isDestroyed) return\n if (this._content !== value) {\n this._content = value\n this.updateBlocks()\n this.requestRender()\n }\n }\n\n get syntaxStyle(): SyntaxStyle {\n return this._syntaxStyle\n }\n\n set syntaxStyle(value: SyntaxStyle) {\n if (this._syntaxStyle !== value) {\n this._syntaxStyle = value\n // Mark dirty - actual re-render happens in renderSelf\n this._styleDirty = true\n }\n }\n\n get fg(): RGBA | undefined {\n return this._fg\n }\n\n set fg(value: ColorInput | undefined) {\n const next = value ? parseColor(value) : undefined\n if (!colorsEqual(this._fg, next)) {\n this._fg = next\n this._styleDirty = true\n }\n }\n\n get bg(): RGBA | undefined {\n return this._bg\n }\n\n set bg(value: ColorInput | undefined) {\n const next = value ? parseColor(value) : undefined\n if (!colorsEqual(this._bg, next)) {\n this._bg = next\n this._styleDirty = true\n }\n }\n\n get conceal(): boolean {\n return this._conceal\n }\n\n set conceal(value: boolean) {\n if (this._conceal !== value) {\n this._conceal = value\n // Mark dirty - actual re-render happens in renderSelf\n this._styleDirty = true\n }\n }\n\n get concealCode(): boolean {\n return this._concealCode\n }\n\n set concealCode(value: boolean) {\n if (this._concealCode !== value) {\n this._concealCode = value\n // Mark dirty - actual re-render happens in renderSelf\n this._styleDirty = true\n }\n }\n\n get streaming(): boolean {\n return this._streaming\n }\n\n set streaming(value: boolean) {\n if (this.isDestroyed) return\n if (this._streaming !== value) {\n this._streaming = value\n this.updateBlocks(true)\n }\n }\n\n get tableOptions(): MarkdownTableOptions | undefined {\n return this._tableOptions\n }\n\n set tableOptions(value: MarkdownTableOptions | undefined) {\n this._tableOptions = value\n this.applyTableOptionsToBlocks()\n }\n\n get renderNode(): MarkdownOptions[\"renderNode\"] | undefined {\n return this._renderNode\n }\n\n set renderNode(value: MarkdownOptions[\"renderNode\"] | undefined) {\n if (this._renderNode === value) return\n this._renderNode = value\n this.clearBlockStates()\n this._parseState = null\n this.updateBlocks(true)\n this.requestRender()\n }\n\n get internalBlockMode(): \"coalesced\" | \"top-level\" {\n return this._internalBlockMode\n }\n\n set internalBlockMode(value: \"coalesced\" | \"top-level\") {\n if (this._internalBlockMode === value) return\n this._internalBlockMode = value\n this.updateBlocks(true)\n this.requestRender()\n }\n\n private getStyle(group: string): StyleDefinition | undefined {\n // The solid reconciler applies props via setters in JSX declaration order.\n // If `content` is set before `syntaxStyle`, updateBlocks() runs before\n // _syntaxStyle is initialized.\n if (!this._syntaxStyle) return undefined\n let style = this._syntaxStyle.getStyle(group)\n if (!style && group.includes(\".\")) {\n const baseName = group.split(\".\")[0]\n style = this._syntaxStyle.getStyle(baseName)\n }\n return style\n }\n\n private createChunk(text: string, group: string, link?: { url: string }): TextChunk {\n const style = this.getStyle(group) || this.getStyle(\"default\")\n return {\n __isChunk: true,\n text,\n fg: style?.fg,\n bg: style?.bg,\n attributes: style\n ? createTextAttributes({\n bold: style.bold,\n italic: style.italic,\n underline: style.underline,\n dim: style.dim,\n })\n : 0,\n link,\n }\n }\n\n private createDefaultChunk(text: string): TextChunk {\n return this.createChunk(text, \"default\")\n }\n\n private createInitialStyledText(token: MarkedToken): StyledText | undefined {\n if (!this._streaming) return undefined\n\n const chunks: TextChunk[] = []\n if (\"tokens\" in token && Array.isArray(token.tokens)) {\n this.renderInlineContent(token.tokens, chunks)\n }\n\n if (chunks.length === 0 && \"text\" in token && typeof token.text === \"string\") {\n this.renderInlineContent(Lexer.lexInline(token.text), chunks)\n }\n\n return chunks.length > 0 ? new StyledText(chunks) : undefined\n }\n\n private renderInlineContent(tokens: Token[], chunks: TextChunk[]): void {\n for (const token of tokens) {\n this.renderInlineToken(token as MarkedToken, chunks)\n }\n }\n\n private renderInlineToken(token: MarkedToken, chunks: TextChunk[]): void {\n switch (token.type) {\n case \"text\":\n chunks.push(this.createDefaultChunk(token.text))\n break\n\n case \"escape\":\n chunks.push(this.createDefaultChunk(token.text))\n break\n\n case \"codespan\":\n if (this._conceal) {\n chunks.push(this.createChunk(token.text, \"markup.raw\"))\n } else {\n chunks.push(this.createChunk(\"`\", \"markup.raw\"))\n chunks.push(this.createChunk(token.text, \"markup.raw\"))\n chunks.push(this.createChunk(\"`\", \"markup.raw\"))\n }\n break\n\n case \"strong\":\n if (!this._conceal) {\n chunks.push(this.createChunk(\"**\", \"markup.strong\"))\n }\n for (const child of token.tokens) {\n this.renderInlineTokenWithStyle(child as MarkedToken, chunks, \"markup.strong\")\n }\n if (!this._conceal) {\n chunks.push(this.createChunk(\"**\", \"markup.strong\"))\n }\n break\n\n case \"em\":\n if (!this._conceal) {\n chunks.push(this.createChunk(\"*\", \"markup.italic\"))\n }\n for (const child of token.tokens) {\n this.renderInlineTokenWithStyle(child as MarkedToken, chunks, \"markup.italic\")\n }\n if (!this._conceal) {\n chunks.push(this.createChunk(\"*\", \"markup.italic\"))\n }\n break\n\n case \"del\":\n if (!this._conceal) {\n chunks.push(this.createChunk(\"~~\", \"markup.strikethrough\"))\n }\n for (const child of token.tokens) {\n this.renderInlineTokenWithStyle(child as MarkedToken, chunks, \"markup.strikethrough\")\n }\n if (!this._conceal) {\n chunks.push(this.createChunk(\"~~\", \"markup.strikethrough\"))\n }\n break\n\n case \"link\": {\n const linkHref = { url: token.href }\n if (this._conceal) {\n for (const child of token.tokens) {\n this.renderInlineTokenWithStyle(child as MarkedToken, chunks, \"markup.link.label\", linkHref)\n }\n chunks.push(this.createChunk(\" (\", \"markup.link\", linkHref))\n chunks.push(this.createChunk(token.href, \"markup.link.url\", linkHref))\n chunks.push(this.createChunk(\")\", \"markup.link\", linkHref))\n } else {\n chunks.push(this.createChunk(\"[\", \"markup.link\", linkHref))\n for (const child of token.tokens) {\n this.renderInlineTokenWithStyle(child as MarkedToken, chunks, \"markup.link.label\", linkHref)\n }\n chunks.push(this.createChunk(\"](\", \"markup.link\", linkHref))\n chunks.push(this.createChunk(token.href, \"markup.link.url\", linkHref))\n chunks.push(this.createChunk(\")\", \"markup.link\", linkHref))\n }\n break\n }\n\n case \"image\": {\n const imageHref = { url: token.href }\n if (this._conceal) {\n chunks.push(this.createChunk(token.text || \"image\", \"markup.link.label\", imageHref))\n } else {\n chunks.push(this.createChunk(\"![\", \"markup.link\", imageHref))\n chunks.push(this.createChunk(token.text || \"\", \"markup.link.label\", imageHref))\n chunks.push(this.createChunk(\"](\", \"markup.link\", imageHref))\n chunks.push(this.createChunk(token.href, \"markup.link.url\", imageHref))\n chunks.push(this.createChunk(\")\", \"markup.link\", imageHref))\n }\n break\n }\n\n case \"br\":\n chunks.push(this.createDefaultChunk(\"\\n\"))\n break\n\n default:\n if (\"tokens\" in token && Array.isArray(token.tokens)) {\n this.renderInlineContent(token.tokens, chunks)\n } else if (\"text\" in token && typeof token.text === \"string\") {\n chunks.push(this.createDefaultChunk(token.text))\n }\n break\n }\n }\n\n private renderInlineTokenWithStyle(\n token: MarkedToken,\n chunks: TextChunk[],\n styleGroup: string,\n link?: { url: string },\n ): void {\n switch (token.type) {\n case \"text\":\n chunks.push(this.createChunk(token.text, styleGroup, link))\n break\n\n case \"escape\":\n chunks.push(this.createChunk(token.text, styleGroup, link))\n break\n\n case \"codespan\":\n if (this._conceal) {\n chunks.push(this.createChunk(token.text, \"markup.raw\", link))\n } else {\n chunks.push(this.createChunk(\"`\", \"markup.raw\", link))\n chunks.push(this.createChunk(token.text, \"markup.raw\", link))\n chunks.push(this.createChunk(\"`\", \"markup.raw\", link))\n }\n break\n\n default:\n this.renderInlineToken(token, chunks)\n break\n }\n }\n\n private applyMargins(renderable: Renderable, marginTop: number, marginBottom: number): void {\n renderable.marginTop = marginTop\n renderable.marginBottom = marginBottom\n }\n\n private createMarkdownCodeRenderable(\n content: string,\n id: string,\n marginBottom: number = 0,\n onChunks: OnChunksCallback = this._linkifyMarkdownChunks,\n baseHighlight?: string,\n initialStyledText?: StyledText,\n ): CodeRenderable {\n return new CodeRenderable(this.ctx, {\n id,\n content,\n filetype: \"markdown\",\n syntaxStyle: this._syntaxStyle,\n fg: this._fg,\n bg: this._bg,\n conceal: this._conceal,\n drawUnstyledText: initialStyledText !== undefined,\n streaming: true,\n initialStyledText,\n baseHighlight,\n onChunks,\n treeSitterClient: this._treeSitterClient,\n width: \"100%\",\n marginBottom,\n })\n }\n\n private getBlockquoteContent(token: MarkedToken): string {\n return \"text\" in token && typeof token.text === \"string\" && token.text ? token.text : \" \"\n }\n\n private getBlockquoteBorderColor(): ColorInput {\n return this.getStyle(\"conceal\")?.fg ?? this.getStyle(\"default\")?.fg ?? this._fg ?? \"#FFFFFF\"\n }\n\n private createBlockquoteRenderable(token: MarkedToken, id: string, marginBottom: number = 0): BoxRenderable {\n const renderable = new BoxRenderable(this.ctx, {\n id,\n width: \"100%\",\n border: [\"left\"],\n borderColor: this.getBlockquoteBorderColor(),\n paddingLeft: 1,\n flexShrink: 0,\n marginBottom,\n })\n\n renderable.add(\n this.createMarkdownCodeRenderable(\n this.getBlockquoteContent(token),\n `${id}-content`,\n 0,\n this._linkifyMarkdownChunks,\n \"markup.quote\",\n ),\n )\n\n return renderable\n }\n\n private createListRenderable(token: Tokens.List, id: string, marginBottom: number = 0): BoxRenderable {\n const list = new BoxRenderable(this.ctx, {\n id,\n width: \"100%\",\n flexDirection: \"column\",\n flexShrink: 0,\n marginBottom,\n })\n\n for (const item of this.getListItemInputs(token, id)) {\n list.add(this.createListItemRenderable(item))\n }\n\n return list\n }\n\n private getListItemInputs(token: Tokens.List, id: string): ListItemRenderInput[] {\n const items = token.items ?? []\n const start = token.start === \"\" || token.start === undefined || token.start === null ? 1 : Number(token.start)\n const markerWidth = Math.max(1, ...items.map((_, index) => (token.ordered ? `${start + index}.` : \"-\").length))\n\n return items.map((item, index) => ({\n item,\n marker: token.ordered ? `${start + index}.` : \"-\",\n markerWidth,\n id: `${id}-item-${index}`,\n }))\n }\n\n private applyListRenderable(\n renderable: Renderable,\n token: Tokens.List,\n previousToken: Tokens.List | undefined,\n id: string,\n marginBottom: number = 0,\n ): boolean {\n if (!(renderable instanceof BoxRenderable)) return false\n\n renderable.marginBottom = marginBottom\n\n const inputs = this.getListItemInputs(token, id)\n const previousItems = previousToken?.items ?? []\n const rows = renderable.getChildren()\n\n for (let index = 0; index < inputs.length; index += 1) {\n const input = inputs[index]\n const existing = rows[index]\n\n if (existing instanceof BoxRenderable && this.applyListItemRenderable(existing, input, previousItems[index])) {\n continue\n }\n\n existing?.destroyRecursively()\n renderable.add(this.createListItemRenderable(input), index)\n }\n\n for (let index = rows.length - 1; index >= inputs.length; index -= 1) {\n rows[index]?.destroyRecursively()\n }\n\n return true\n }\n\n private createListItemRenderable(input: ListItemRenderInput): BoxRenderable {\n const row = new BoxRenderable(this.ctx, {\n id: input.id,\n width: \"100%\",\n flexDirection: \"row\",\n flexShrink: 0,\n marginBottom: /\\n[ \\t]*\\n$/.test(input.item.raw) ? 1 : 0,\n })\n row.add(\n new TextRenderable(this.ctx, {\n id: `${input.id}-marker`,\n content: new StyledText([this.createChunk(input.marker.padStart(input.markerWidth) + \" \", \"markup.list\")]),\n width: input.markerWidth + 1,\n flexShrink: 0,\n }),\n )\n\n const content = new BoxRenderable(this.ctx, {\n id: `${input.id}-content`,\n flexDirection: \"column\",\n flexGrow: 1,\n flexShrink: 1,\n })\n row.add(content)\n\n let pendingMarginTop = 0\n for (let index = 0; index < input.item.tokens.length; index += 1) {\n const child = input.item.tokens[index] as MarkedToken | undefined\n if (!child) continue\n if (child.type === \"checkbox\") continue\n if (child.type === \"space\") {\n pendingMarginTop = Math.max(pendingMarginTop, 1)\n continue\n }\n const renderable = this.createListChildRenderable(child, `${input.id}-child-${index}`)\n if (!renderable) continue\n renderable.marginTop = child.type === \"list\" ? 0 : pendingMarginTop\n pendingMarginTop = 0\n content.add(renderable)\n }\n\n return row\n }\n\n private applyListItemRenderable(\n row: BoxRenderable,\n input: ListItemRenderInput,\n previousItem: Tokens.ListItem | undefined,\n ): boolean {\n this.applyListItemMarker(row, input)\n\n const content = row.getChildren()[1]\n if (!(content instanceof BoxRenderable)) return false\n\n if (previousItem && previousItem.raw === input.item.raw) {\n return true\n }\n\n return this.applyListItemChildren(content, input.item, previousItem, input.id)\n }\n\n private applyListItemChildren(\n content: BoxRenderable,\n item: Tokens.ListItem,\n previousItem: Tokens.ListItem | undefined,\n id: string,\n ): boolean {\n const previousTokens = previousItem ? this.getRenderableListItemTokens(previousItem) : []\n const children = content.getChildren()\n let childIndex = 0\n let pendingMarginTop = 0\n\n for (let tokenIndex = 0; tokenIndex < item.tokens.length; tokenIndex += 1) {\n const token = item.tokens[tokenIndex] as MarkedToken | undefined\n if (!token) continue\n if (token.type === \"checkbox\") continue\n if (token.type === \"space\") {\n pendingMarginTop = Math.max(pendingMarginTop, 1)\n continue\n }\n\n const existing = children[childIndex]\n const childId = `${id}-child-${tokenIndex}`\n\n const marginTop = token.type === \"list\" ? 0 : pendingMarginTop\n pendingMarginTop = 0\n\n if (!existing) {\n const renderable = this.createListChildRenderable(token, childId)\n if (!renderable) return false\n renderable.marginTop = marginTop\n content.add(renderable, childIndex)\n childIndex += 1\n continue\n }\n\n if (!this.applyListChildRenderable(existing, token, previousTokens[childIndex], childId)) {\n return false\n }\n existing.marginTop = marginTop\n childIndex += 1\n }\n\n this.destroyListItemChildrenAfter(content, childIndex)\n return true\n }\n\n private getRenderableListItemTokens(item: Tokens.ListItem): MarkedToken[] {\n const tokens: MarkedToken[] = []\n\n for (const token of item.tokens as MarkedToken[]) {\n if (token.type === \"checkbox\" || token.type === \"space\") continue\n tokens.push(token)\n }\n\n return tokens\n }\n\n private applyListChildRenderable(\n renderable: Renderable,\n token: MarkedToken,\n previousToken: MarkedToken | undefined,\n id: string,\n ): boolean {\n if ((token.type === \"text\" || token.type === \"paragraph\") && renderable instanceof CodeRenderable) {\n this.applyMarkdownCodeRenderable(renderable, this.normalizeScrollbackMarkdownBlockRaw(token.raw), 0)\n return true\n }\n\n if (token.type === \"list\" && renderable instanceof BoxRenderable) {\n return this.applyListRenderable(renderable, token as Tokens.List, previousToken as Tokens.List | undefined, id)\n }\n\n if (token.type === \"code\" && renderable instanceof CodeRenderable) {\n this.applyCodeBlockRenderable(renderable, token as Tokens.Code, 0)\n return true\n }\n\n return previousToken?.raw === token.raw\n }\n\n private destroyListItemChildrenAfter(content: BoxRenderable, index: number): void {\n const children = content.getChildren()\n for (let i = children.length - 1; i >= index; i -= 1) {\n children[i]?.destroyRecursively()\n }\n }\n\n private applyListItemMarker(row: BoxRenderable, input: ListItemRenderInput): void {\n const marker = row.getChildren()[0]\n if (!(marker instanceof TextRenderable)) return\n const marginBottom = /\\n[ \\t]*\\n$/.test(input.item.raw) ? 1 : 0\n const markerWidth = input.markerWidth + 1\n const markerText = input.marker.padStart(input.markerWidth) + \" \"\n\n if (row.marginBottom !== marginBottom) row.marginBottom = marginBottom\n if (marker.width !== markerWidth) marker.width = markerWidth\n if (marker.chunks[0]?.text !== markerText) {\n marker.content = new StyledText([this.createChunk(markerText, \"markup.list\")])\n }\n }\n\n private createListChildRenderable(token: MarkedToken, id: string): Renderable | null {\n if (token.type === \"text\" || token.type === \"paragraph\") {\n return this.createMarkdownCodeRenderable(\n this.normalizeScrollbackMarkdownBlockRaw(token.raw),\n id,\n 0,\n this._linkifyMarkdownChunks,\n undefined,\n this.createInitialStyledText(token),\n )\n }\n if (token.type === \"list\") return this.createListRenderable(token as Tokens.List, id)\n if (token.type === \"code\") return this.createCodeRenderable(token as Tokens.Code, id)\n if (token.type === \"blockquote\") return this.createBlockquoteRenderable(token, id)\n if (token.type === \"hr\") return this.createHorizontalRuleRenderable(id)\n if (token.type === \"table\") return this.createTableBlock(token as Tokens.Table, id).renderable\n return token.raw\n ? this.createMarkdownCodeRenderable(\n token.raw,\n id,\n 0,\n this._linkifyMarkdownChunks,\n undefined,\n this.createInitialStyledText(token),\n )\n : null\n }\n\n private createHorizontalRuleRenderable(id: string, marginBottom: number = 0): BoxRenderable {\n return new BoxRenderable(this.ctx, {\n id,\n width: \"100%\",\n height: 1,\n border: [\"top\"],\n borderColor: this.getStyle(\"conceal\")?.fg ?? this._fg ?? \"#888888\",\n flexShrink: 0,\n marginBottom,\n })\n }\n\n private createCodeRenderable(token: Tokens.Code, id: string, marginBottom: number = 0): Renderable {\n return new CodeRenderable(this.ctx, {\n id,\n content: token.text,\n filetype: infoStringToFiletype(token.lang ?? \"\"),\n syntaxStyle: this._syntaxStyle,\n fg: this._fg,\n bg: this._bg,\n conceal: this._concealCode,\n drawUnstyledText: !this._streaming,\n streaming: this._streaming,\n treeSitterClient: this._treeSitterClient,\n width: \"100%\",\n marginBottom,\n })\n }\n\n private applyMarkdownCodeRenderable(\n renderable: CodeRenderable,\n content: string,\n marginBottom: number,\n baseHighlight?: string,\n initialStyledText?: StyledText,\n ): void {\n renderable.initialStyledText = initialStyledText\n renderable.filetype = \"markdown\"\n renderable.syntaxStyle = this._syntaxStyle\n renderable.fg = this._fg\n renderable.bg = this._bg\n renderable.conceal = this._conceal\n renderable.drawUnstyledText = initialStyledText !== undefined\n renderable.streaming = true\n renderable.baseHighlight = baseHighlight\n renderable.content = content\n renderable.marginBottom = marginBottom\n }\n\n private applyBlockquoteRenderable(renderable: Renderable, token: MarkedToken, marginBottom: number): void {\n if (!(renderable instanceof BoxRenderable)) return\n\n renderable.borderColor = this.getBlockquoteBorderColor()\n renderable.marginBottom = marginBottom\n\n const child = renderable.getChildren()[0]\n if (child instanceof CodeRenderable) {\n this.applyMarkdownCodeRenderable(child, this.getBlockquoteContent(token), 0, \"markup.quote\")\n return\n }\n\n for (const existing of renderable.getChildren()) {\n existing.destroyRecursively()\n }\n renderable.add(\n this.createMarkdownCodeRenderable(\n this.getBlockquoteContent(token),\n `${renderable.id}-content`,\n 0,\n this._linkifyMarkdownChunks,\n \"markup.quote\",\n ),\n )\n }\n\n private applyCodeBlockRenderable(renderable: Renderable, token: Tokens.Code, marginBottom: number): void {\n if (!(renderable instanceof CodeRenderable)) return\n\n renderable.filetype = infoStringToFiletype(token.lang ?? \"\")\n renderable.syntaxStyle = this._syntaxStyle\n renderable.fg = this._fg\n renderable.bg = this._bg\n renderable.conceal = this._concealCode\n renderable.drawUnstyledText = !this._streaming\n renderable.streaming = this._streaming\n renderable.content = token.text\n renderable.marginBottom = marginBottom\n }\n\n private shouldRenderSeparately(token: MarkedToken): boolean {\n return token.type === \"code\" || token.type === \"table\" || token.type === \"blockquote\" || token.type === \"hr\"\n }\n\n private getInterBlockMargin(token: MarkedToken, nextToken: MarkedToken | undefined): number {\n if (!nextToken) return 0\n if (this.shouldRenderSeparately(token)) return 1\n if (!this.shouldRenderSeparately(nextToken)) return 0\n return TRAILING_MARKDOWN_BLOCK_NEWLINES_RE.test(token.raw) ? 0 : 1\n }\n\n private applyInterBlockMargin(state: BlockState, token: MarkedToken, nextToken: MarkedToken | undefined): void {\n if (state.tracksInterBlockMargin === false) return\n state.renderable.marginBottom = this.getInterBlockMargin(token, nextToken)\n }\n\n private createMarkdownBlockToken(raw: string): MarkedToken {\n return {\n type: \"paragraph\",\n raw,\n text: raw,\n tokens: [],\n } as MarkedToken\n }\n\n private normalizeMarkdownBlockRaw(raw: string): string {\n return raw.replace(TRAILING_MARKDOWN_BLOCK_BREAKS_RE, \"\\n\")\n }\n\n private normalizeScrollbackMarkdownBlockRaw(raw: string): string {\n return raw.replace(TRAILING_MARKDOWN_BLOCK_NEWLINES_RE, \"\")\n }\n\n private isCodeBlockOnlyRenderer(): boolean {\n return (this._renderNode as MarkdownRenderNode | undefined)?.codeBlockOnly === true\n }\n\n private buildRenderableTokens(tokens: MarkedToken[]): MarkedToken[] {\n if (this._renderNode && !this.isCodeBlockOnlyRenderer()) {\n return tokens.filter((token) => token.type !== \"space\")\n }\n\n const renderTokens: MarkedToken[] = []\n let markdownRaw = \"\"\n\n const flushMarkdownRaw = (): void => {\n if (markdownRaw.length === 0) return\n const normalizedRaw = this.normalizeMarkdownBlockRaw(markdownRaw)\n if (normalizedRaw.length > 0) {\n renderTokens.push(this.createMarkdownBlockToken(normalizedRaw))\n }\n markdownRaw = \"\"\n }\n\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i]\n\n if (token.type === \"space\") {\n if (markdownRaw.length === 0) {\n continue\n }\n\n let nextIndex = i + 1\n while (nextIndex < tokens.length && tokens[nextIndex].type === \"space\") {\n nextIndex += 1\n }\n\n const nextToken = tokens[nextIndex]\n if (nextToken && !this.shouldRenderSeparately(nextToken)) {\n markdownRaw += token.raw\n }\n continue\n }\n\n if (this.shouldRenderSeparately(token)) {\n flushMarkdownRaw()\n renderTokens.push(token)\n continue\n }\n\n markdownRaw += token.raw\n }\n\n flushMarkdownRaw()\n\n return renderTokens\n }\n\n private buildTopLevelRenderBlocks(tokens: MarkedToken[]): MarkdownRenderBlock[] {\n const blocks: MarkdownRenderBlock[] = []\n let gapBefore = \"\"\n\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i]\n if (token.type === \"space\") {\n gapBefore += token.raw\n continue\n }\n\n const prev = blocks[blocks.length - 1]\n const marginTop = prev && this.shouldAddTopLevelMargin(prev.token, token, gapBefore) ? 1 : 0\n\n blocks.push({\n token,\n sourceTokenEnd: i + 1,\n marginTop,\n })\n gapBefore = \"\"\n }\n\n return blocks\n }\n\n private shouldAddTopLevelMargin(prev: MarkedToken, current: MarkedToken, gapBefore: string): boolean {\n if (this.isSeparatedTopLevelBlock(prev) || this.isSeparatedTopLevelBlock(current)) return true\n if (prev.type !== \"paragraph\" || current.type !== \"paragraph\") return false\n return TRAILING_MARKDOWN_BLOCK_BREAKS_RE.test(prev.raw + gapBefore)\n }\n\n private isSeparatedTopLevelBlock(token: MarkedToken): boolean {\n return token.type === \"heading\" || token.type === \"list\" || this.shouldRenderSeparately(token)\n }\n\n private getTableRowsToRender(table: Tokens.Table): Tokens.TableCell[][] {\n return table.rows\n }\n\n private hashString(value: string, seed: number): number {\n let hash = seed >>> 0\n for (let i = 0; i < value.length; i += 1) {\n hash ^= value.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return hash >>> 0\n }\n\n private hashTableToken(token: MarkedToken, seed: number, depth: number = 0): number {\n let hash = this.hashString(token.type, seed)\n\n if (\"raw\" in token && typeof token.raw === \"string\") {\n return this.hashString(token.raw, hash)\n }\n\n if (\"text\" in token && typeof token.text === \"string\") {\n hash = this.hashString(token.text, hash)\n }\n\n if (depth < 2 && \"tokens\" in token && Array.isArray(token.tokens)) {\n for (const child of token.tokens) {\n hash = this.hashTableToken(child as MarkedToken, hash, depth + 1)\n }\n }\n\n return hash >>> 0\n }\n\n private getTableCellKey(cell: Tokens.TableCell | undefined, isHeader: boolean): number {\n const seed = isHeader ? 2902232141 : 1371922141\n if (!cell) {\n return seed\n }\n\n if (typeof cell.text === \"string\") {\n return this.hashString(cell.text, seed)\n }\n\n if (Array.isArray(cell.tokens) && cell.tokens.length > 0) {\n let hash = seed ^ cell.tokens.length\n for (const token of cell.tokens) {\n hash = this.hashTableToken(token as MarkedToken, hash)\n }\n return hash >>> 0\n }\n\n return (seed ^ 2654435769) >>> 0\n }\n\n private createTableDataCellChunks(cell: Tokens.TableCell | undefined): TextChunk[] {\n const chunks: TextChunk[] = []\n if (cell) {\n this.renderInlineContent(cell.tokens, chunks)\n }\n return chunks.length > 0 ? chunks : [this.createDefaultChunk(\" \")]\n }\n\n private createTableHeaderCellChunks(cell: Tokens.TableCell): TextChunk[] {\n const chunks: TextChunk[] = []\n this.renderInlineContent(cell.tokens, chunks)\n\n const baseChunks = chunks.length > 0 ? chunks : [this.createDefaultChunk(\" \")]\n const headingStyle = this.getStyle(\"markup.heading\") || this.getStyle(\"default\")\n if (!headingStyle) {\n return baseChunks\n }\n\n const headingAttributes = createTextAttributes({\n bold: headingStyle.bold,\n italic: headingStyle.italic,\n underline: headingStyle.underline,\n dim: headingStyle.dim,\n })\n\n return baseChunks.map((chunk) => ({\n ...chunk,\n fg: headingStyle.fg ?? chunk.fg,\n bg: headingStyle.bg ?? chunk.bg,\n attributes: headingAttributes,\n }))\n }\n\n private buildTableContentCache(\n table: Tokens.Table,\n previous?: TableContentCache,\n forceRegenerate: boolean = false,\n ): { cache: TableContentCache | null; changed: boolean } {\n const colCount = table.header.length\n const rowsToRender = this.getTableRowsToRender(table)\n if (colCount === 0 || rowsToRender.length === 0) {\n return { cache: null, changed: previous !== undefined }\n }\n\n const content: TextTableContent = []\n const cellKeys: Uint32Array[] = []\n const totalRows = rowsToRender.length + 1\n\n let changed = forceRegenerate || !previous\n\n for (let rowIndex = 0; rowIndex < totalRows; rowIndex += 1) {\n const rowContent: TextTableCellContent[] = []\n const rowKeys = new Uint32Array(colCount)\n\n for (let colIndex = 0; colIndex < colCount; colIndex += 1) {\n const isHeader = rowIndex === 0\n const cell = isHeader ? table.header[colIndex] : rowsToRender[rowIndex - 1]?.[colIndex]\n const cellKey = this.getTableCellKey(cell, isHeader)\n rowKeys[colIndex] = cellKey\n\n const previousCellKey = previous?.cellKeys[rowIndex]?.[colIndex]\n const previousCellContent = previous?.content[rowIndex]?.[colIndex]\n\n if (!forceRegenerate && previousCellKey === cellKey && Array.isArray(previousCellContent)) {\n rowContent.push(previousCellContent)\n continue\n }\n\n changed = true\n rowContent.push(\n isHeader ? this.createTableHeaderCellChunks(table.header[colIndex]) : this.createTableDataCellChunks(cell),\n )\n }\n\n content.push(rowContent)\n cellKeys.push(rowKeys)\n }\n\n if (previous && !changed) {\n if (previous.content.length !== content.length) {\n changed = true\n } else {\n for (let rowIndex = 0; rowIndex < content.length; rowIndex += 1) {\n if ((previous.content[rowIndex]?.length ?? 0) !== content[rowIndex].length) {\n changed = true\n break\n }\n }\n }\n }\n\n return {\n cache: {\n content,\n cellKeys,\n },\n changed,\n }\n }\n\n private resolveTableStyle(options: MarkdownTableOptions | undefined = this._tableOptions): MarkdownTableStyle {\n if (options?.style === \"columns\") {\n return \"columns\"\n }\n\n if (options?.style === \"grid\") {\n return \"grid\"\n }\n\n return this._internalBlockMode === \"top-level\" ? \"columns\" : \"grid\"\n }\n\n private usesBorderlessColumnSpacing(options: MarkdownTableOptions | undefined = this._tableOptions): boolean {\n const style = this.resolveTableStyle(options)\n const borders = options?.borders ?? style === \"grid\"\n\n return style === \"columns\" && !borders\n }\n\n private resolveTableRenderableOptions(): ResolvedTableRenderableOptions {\n const style = this.resolveTableStyle()\n const borders = this._tableOptions?.borders ?? style === \"grid\"\n\n return {\n columnWidthMode: this._tableOptions?.widthMode ?? (style === \"columns\" ? \"content\" : \"full\"),\n columnFitter: this._tableOptions?.columnFitter ?? \"proportional\",\n wrapMode: this._tableOptions?.wrapMode ?? \"word\",\n cellPadding: this._tableOptions?.cellPadding ?? 0,\n cellPaddingX: this._tableOptions?.cellPaddingX ?? this._tableOptions?.cellPadding ?? 0,\n cellPaddingY: this._tableOptions?.cellPaddingY ?? this._tableOptions?.cellPadding ?? 0,\n columnGap: this.usesBorderlessColumnSpacing() ? 2 : 0,\n border: borders,\n outerBorder: this._tableOptions?.outerBorder ?? borders,\n showBorders: borders,\n borderStyle: this._tableOptions?.borderStyle ?? \"single\",\n borderColor: this._tableOptions?.borderColor ?? this.getStyle(\"conceal\")?.fg ?? \"#888888\",\n selectable: this._tableOptions?.selectable ?? true,\n }\n }\n\n private applyTableRenderableOptions(\n tableRenderable: TextTableRenderable,\n options: ResolvedTableRenderableOptions,\n ): void {\n tableRenderable.columnWidthMode = options.columnWidthMode\n tableRenderable.columnFitter = options.columnFitter\n tableRenderable.wrapMode = options.wrapMode\n tableRenderable.cellPaddingX = options.cellPaddingX\n tableRenderable.cellPaddingY = options.cellPaddingY\n tableRenderable.columnGap = options.columnGap\n tableRenderable.border = options.border\n tableRenderable.outerBorder = options.outerBorder\n tableRenderable.showBorders = options.showBorders\n tableRenderable.borderStyle = options.borderStyle\n tableRenderable.borderColor = options.borderColor\n tableRenderable.selectable = options.selectable\n }\n\n private applyTableOptionsToBlocks(): void {\n const options = this.resolveTableRenderableOptions()\n let updated = false\n\n for (const state of this._blockStates) {\n if (state.renderable instanceof TextTableRenderable) {\n this.applyTableRenderableOptions(state.renderable, options)\n updated = true\n }\n }\n\n if (updated) {\n this.requestRender()\n }\n }\n\n private createTextTableRenderable(\n content: TextTableContent,\n id: string,\n marginBottom: number = 0,\n ): TextTableRenderable {\n const options = this.resolveTableRenderableOptions()\n return new TextTableRenderable(this.ctx, {\n id,\n content,\n width: \"100%\",\n marginBottom,\n columnWidthMode: options.columnWidthMode,\n columnFitter: options.columnFitter,\n wrapMode: options.wrapMode,\n cellPadding: options.cellPadding,\n cellPaddingX: options.cellPaddingX,\n cellPaddingY: options.cellPaddingY,\n columnGap: options.columnGap,\n border: options.border,\n outerBorder: options.outerBorder,\n showBorders: options.showBorders,\n borderStyle: options.borderStyle,\n borderColor: options.borderColor,\n selectable: options.selectable,\n })\n }\n\n private createTableBlock(\n table: Tokens.Table,\n id: string,\n marginBottom: number = 0,\n previousCache?: TableContentCache,\n forceRegenerate: boolean = false,\n ): { renderable: Renderable; tableContentCache?: TableContentCache } {\n const { cache } = this.buildTableContentCache(table, previousCache, forceRegenerate)\n\n if (!cache) {\n return {\n renderable: this.createMarkdownCodeRenderable(table.raw, id, marginBottom),\n }\n }\n\n return {\n renderable: this.createTextTableRenderable(cache.content, id, marginBottom),\n tableContentCache: cache,\n }\n }\n\n private getStableBlockCount(blocks: MarkdownRenderBlock[], stableTokenCount: number): number {\n if (this._internalBlockMode !== \"top-level\") {\n return 0\n }\n\n let stableBlockCount = 0\n for (const block of blocks) {\n if (block.sourceTokenEnd <= stableTokenCount) {\n stableBlockCount += 1\n continue\n }\n\n break\n }\n\n return stableBlockCount\n }\n\n private syncTopLevelBlockState(\n state: BlockState,\n block: MarkdownRenderBlock,\n tableContentCache: TableContentCache | undefined = state.tableContentCache,\n ): void {\n state.token = block.token\n state.tokenRaw = block.token.raw\n state.marginTop = block.marginTop\n state.tableContentCache = tableContentCache\n }\n\n private getTopLevelBlockRaw(token: MarkedToken): string | undefined {\n if (!token.raw) {\n return undefined\n }\n\n return this.shouldRenderSeparately(token) ? token.raw : this.normalizeScrollbackMarkdownBlockRaw(token.raw)\n }\n\n private createTopLevelDefaultRenderable(\n block: MarkdownRenderBlock,\n index: number,\n ): { renderable: Renderable | undefined; tableContentCache?: TableContentCache; canUpdateInPlace: boolean } {\n const { token, marginTop } = block\n const id = `${this.id}-block-${index}`\n\n if (token.type === \"code\") {\n const renderable = this.createCodeRenderable(token, id)\n renderable.marginTop = marginTop\n return { renderable, canUpdateInPlace: true }\n }\n\n if (token.type === \"table\") {\n const next = this.createTableBlock(token, id)\n next.renderable.marginTop = marginTop\n return { ...next, canUpdateInPlace: true }\n }\n\n if (token.type === \"blockquote\") {\n const renderable = this.createBlockquoteRenderable(token, id)\n renderable.marginTop = marginTop\n return { renderable, canUpdateInPlace: true }\n }\n\n if (token.type === \"list\") {\n const renderable = this.createListRenderable(token, id)\n renderable.marginTop = marginTop\n return { renderable, canUpdateInPlace: true }\n }\n\n if (token.type === \"hr\") {\n const renderable = this.createHorizontalRuleRenderable(id)\n renderable.marginTop = marginTop\n return { renderable, canUpdateInPlace: true }\n }\n\n const markdownRaw = this.getTopLevelBlockRaw(token)\n if (!markdownRaw) {\n return { renderable: undefined, canUpdateInPlace: true }\n }\n\n const renderable = this.createMarkdownCodeRenderable(\n markdownRaw,\n id,\n 0,\n this._linkifyMarkdownChunks,\n undefined,\n this.createInitialStyledText(token),\n )\n renderable.marginTop = marginTop\n return { renderable, canUpdateInPlace: true }\n }\n\n private createTopLevelRenderable(\n block: MarkdownRenderBlock,\n index: number,\n ): { renderable: Renderable | undefined; tableContentCache?: TableContentCache; canUpdateInPlace: boolean } {\n if (!this._renderNode) {\n return this.createTopLevelDefaultRenderable(block, index)\n }\n\n const custom = this.createTopLevelCustomRenderable(block, index)\n if (!custom.renderable) return this.createTopLevelDefaultRenderable(block, index)\n\n const marginTop =\n typeof custom.renderable.marginTop === \"number\"\n ? Math.max(custom.renderable.marginTop, block.marginTop)\n : block.marginTop\n this.applyMargins(custom.renderable, marginTop, 0)\n\n return {\n renderable: custom.renderable,\n tableContentCache: custom.tableContentCache,\n canUpdateInPlace: custom.canUpdateInPlace,\n }\n }\n\n private createDefaultRenderable(token: MarkedToken, index: number, nextToken?: MarkedToken): Renderable | null {\n const id = `${this.id}-block-${index}`\n const marginBottom = this.getInterBlockMargin(token, nextToken)\n\n if (token.type === \"code\") {\n return this.createCodeRenderable(token, id, marginBottom)\n }\n\n if (token.type === \"blockquote\") {\n return this.createBlockquoteRenderable(token, id, marginBottom)\n }\n\n if (token.type === \"list\") {\n return this.createListRenderable(token as Tokens.List, id, marginBottom)\n }\n\n if (token.type === \"hr\") {\n return this.createHorizontalRuleRenderable(id, marginBottom)\n }\n\n if (token.type === \"table\") {\n return this.createTableBlock(token, id, marginBottom).renderable\n }\n\n if (token.type === \"space\") {\n return null\n }\n\n if (!token.raw) {\n return null\n }\n\n return this.createMarkdownCodeRenderable(\n token.raw,\n id,\n marginBottom,\n this._linkifyMarkdownChunks,\n undefined,\n this.createInitialStyledText(token),\n )\n }\n\n private createCustomRenderable(\n token: MarkedToken,\n index: number,\n nextToken: MarkedToken | undefined,\n ): CustomRenderableResult {\n const custom = this.renderCustomNode(token, () => {\n return { renderable: this.createDefaultRenderable(token, index, nextToken) }\n })\n if (!custom.renderable) {\n return { tracksInterBlockMargin: true, canUpdateInPlace: true }\n }\n\n const canUpdateInPlace = custom.renderable === custom.defaultResult?.renderable\n\n return {\n renderable: custom.renderable,\n tracksInterBlockMargin: canUpdateInPlace,\n canUpdateInPlace,\n }\n }\n\n private createTopLevelCustomRenderable(block: MarkdownRenderBlock, index: number): CustomRenderableResult {\n const custom = this.renderCustomNode(block.token, () => {\n return this.createTopLevelDefaultRenderable(block, index)\n })\n if (!custom.renderable) {\n return { tracksInterBlockMargin: true, canUpdateInPlace: true }\n }\n\n const canUpdateInPlace = custom.renderable === custom.defaultResult?.renderable\n\n return {\n renderable: custom.renderable,\n tableContentCache: canUpdateInPlace ? custom.defaultResult?.tableContentCache : undefined,\n tracksInterBlockMargin: canUpdateInPlace,\n canUpdateInPlace,\n }\n }\n\n private renderCustomNode(token: MarkedToken, createDefault: () => CustomRenderDefaultResult): RenderNodeResult {\n if (!this._renderNode) return {}\n\n let defaultResult: CustomRenderDefaultResult | undefined\n const custom = this._renderNode(token, {\n syntaxStyle: this._syntaxStyle,\n conceal: this._conceal,\n concealCode: this._concealCode,\n treeSitterClient: this._treeSitterClient,\n defaultRender: () => {\n defaultResult = createDefault()\n return defaultResult.renderable ?? null\n },\n })\n\n this.destroyUnusedDefaultRenderable(defaultResult?.renderable, custom ?? undefined)\n\n return custom ? { renderable: custom, defaultResult } : {}\n }\n\n private destroyUnusedDefaultRenderable(renderable: Renderable | null | undefined, usedRenderable?: Renderable): void {\n if (!renderable || renderable === usedRenderable || renderable.parent) return\n renderable.destroyRecursively()\n }\n\n private updateBlockRenderable(\n state: BlockState,\n token: MarkedToken,\n index: number,\n nextToken: MarkedToken | undefined,\n forceListRefresh: boolean = false,\n ): void {\n const marginBottom = this.getInterBlockMargin(token, nextToken)\n\n if (token.type === \"code\") {\n this.applyCodeBlockRenderable(state.renderable, token as Tokens.Code, marginBottom)\n return\n }\n\n if (token.type === \"blockquote\") {\n this.applyBlockquoteRenderable(state.renderable, token, marginBottom)\n return\n }\n\n if (token.type === \"list\") {\n if (\n !this.applyListRenderable(\n state.renderable,\n token as Tokens.List,\n forceListRefresh ? undefined : (state.token as Tokens.List),\n `${this.id}-block-${index}`,\n marginBottom,\n )\n ) {\n state.renderable.destroyRecursively()\n state.renderable = this.createListRenderable(token as Tokens.List, `${this.id}-block-${index}`, marginBottom)\n this.add(state.renderable, index)\n }\n return\n }\n\n if (token.type === \"hr\") {\n state.renderable.marginBottom = marginBottom\n return\n }\n\n if (token.type === \"table\") {\n const tableToken = token as Tokens.Table\n const { cache, changed } = this.buildTableContentCache(tableToken, state.tableContentCache)\n\n if (!cache) {\n if (state.renderable instanceof CodeRenderable) {\n this.applyMarkdownCodeRenderable(state.renderable, tableToken.raw, marginBottom)\n state.tableContentCache = undefined\n return\n }\n\n state.renderable.destroyRecursively()\n const fallbackRenderable = this.createMarkdownCodeRenderable(\n tableToken.raw,\n `${this.id}-block-${index}`,\n marginBottom,\n )\n this.add(fallbackRenderable, index)\n state.renderable = fallbackRenderable\n state.tableContentCache = undefined\n return\n }\n\n if (state.renderable instanceof TextTableRenderable) {\n if (changed) {\n state.renderable.content = cache.content\n }\n this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions())\n state.renderable.marginBottom = marginBottom\n state.tableContentCache = cache\n return\n }\n\n state.renderable.destroyRecursively()\n const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${index}`, marginBottom)\n this.add(tableRenderable, index)\n state.renderable = tableRenderable\n state.tableContentCache = cache\n return\n }\n\n if (state.renderable instanceof CodeRenderable) {\n this.applyMarkdownCodeRenderable(\n state.renderable,\n this.getTopLevelBlockRaw(token) ?? token.raw,\n marginBottom,\n undefined,\n this.createInitialStyledText(token),\n )\n return\n }\n\n state.renderable.destroyRecursively()\n const markdownRenderable = this.createMarkdownCodeRenderable(\n this.getTopLevelBlockRaw(token) ?? token.raw,\n `${this.id}-block-${index}`,\n marginBottom,\n this._linkifyMarkdownChunks,\n undefined,\n this.createInitialStyledText(token),\n )\n this.add(markdownRenderable, index)\n state.renderable = markdownRenderable\n }\n\n private updateTopLevelBlocks(tokens: MarkedToken[], forceTableRefresh: boolean): void {\n const blocks = this.buildTopLevelRenderBlocks(tokens)\n this._stableBlockCount = this.getStableBlockCount(blocks, this._parseState?.stableTokenCount ?? 0)\n\n let blockIndex = 0\n for (let i = 0; i < blocks.length; i += 1) {\n const block = blocks[i]\n const existing = this._blockStates[blockIndex]\n\n if (existing && existing.token === block.token && !forceTableRefresh) {\n if (existing.marginTop !== block.marginTop) {\n this.applyMargins(existing.renderable, block.marginTop, 0)\n }\n this.syncTopLevelBlockState(existing, block)\n blockIndex++\n continue\n }\n\n if (\n existing &&\n existing.tokenRaw === block.token.raw &&\n existing.token.type === block.token.type &&\n !forceTableRefresh\n ) {\n if (existing.marginTop !== block.marginTop) {\n this.applyMargins(existing.renderable, block.marginTop, 0)\n }\n this.syncTopLevelBlockState(existing, block)\n blockIndex++\n continue\n }\n\n if (\n existing &&\n !forceTableRefresh &&\n existing.canUpdateInPlace &&\n existing.token.type === block.token.type &&\n this.canUpdateBlockRenderable(existing.renderable, block.token)\n ) {\n if (this._renderNode) {\n const custom = this.createTopLevelCustomRenderable(block, blockIndex)\n if (custom.renderable && !custom.canUpdateInPlace) {\n const marginTop =\n typeof custom.renderable.marginTop === \"number\"\n ? Math.max(custom.renderable.marginTop, block.marginTop)\n : block.marginTop\n this.applyMargins(custom.renderable, marginTop, 0)\n if (custom.renderable !== existing.renderable) {\n existing.renderable.destroyRecursively()\n this.add(custom.renderable, blockIndex)\n }\n this._blockStates[blockIndex] = {\n token: block.token,\n tokenRaw: block.token.raw,\n marginTop: block.marginTop,\n renderable: custom.renderable,\n tableContentCache: custom.tableContentCache,\n canUpdateInPlace: custom.canUpdateInPlace,\n }\n blockIndex++\n continue\n }\n this.destroyUnusedDefaultRenderable(custom.renderable)\n }\n\n this.updateBlockRenderable(existing, block.token, blockIndex, blocks[i + 1]?.token)\n existing.renderable.marginBottom = 0\n if (existing.marginTop !== block.marginTop) {\n this.applyMargins(existing.renderable, block.marginTop, 0)\n }\n this.syncTopLevelBlockState(existing, block)\n blockIndex++\n continue\n }\n\n if (existing) {\n existing.renderable.destroyRecursively()\n }\n\n const next = this.createTopLevelRenderable(block, blockIndex)\n if (next.renderable) {\n this.add(next.renderable, blockIndex)\n this._blockStates[blockIndex] = {\n token: block.token,\n tokenRaw: block.token.raw,\n marginTop: block.marginTop,\n renderable: next.renderable,\n tableContentCache: next.tableContentCache,\n canUpdateInPlace: next.canUpdateInPlace,\n }\n }\n blockIndex++\n }\n\n while (this._blockStates.length > blockIndex) {\n const removed = this._blockStates.pop()!\n removed.renderable.destroyRecursively()\n }\n }\n\n private canUpdateBlockRenderable(renderable: Renderable, token: MarkedToken): boolean {\n if (token.type === \"code\") return renderable instanceof CodeRenderable\n\n if (token.type === \"table\") return renderable instanceof TextTableRenderable\n if (token.type === \"blockquote\") return renderable instanceof BoxRenderable\n if (token.type === \"list\") return renderable instanceof BoxRenderable\n if (token.type === \"hr\") return renderable instanceof BoxRenderable\n return renderable instanceof CodeRenderable\n }\n\n private updateBlocks(forceTableRefresh: boolean = false): void {\n if (this.isDestroyed) return\n if (!this._content) {\n this.clearBlockStates()\n this._parseState = null\n this._stableBlockCount = 0\n return\n }\n\n const trailingUnstable = this._streaming ? 2 : 0\n this._parseState = parseMarkdownIncremental(this._content, this._parseState, trailingUnstable)\n\n const tokens = this._parseState.tokens\n\n if (tokens.length === 0 && this._content.length > 0) {\n this.clearBlockStates()\n this._stableBlockCount = 0\n const fallback = this.createMarkdownCodeRenderable(this._content, `${this.id}-fallback`)\n this.add(fallback)\n this._blockStates = [\n {\n token: { type: \"text\", raw: this._content, text: this._content } as MarkedToken,\n tokenRaw: this._content,\n marginTop: 0,\n renderable: fallback,\n tracksInterBlockMargin: true,\n canUpdateInPlace: true,\n },\n ]\n return\n }\n\n if (this._internalBlockMode === \"top-level\") {\n this.updateTopLevelBlocks(tokens, forceTableRefresh)\n return\n }\n\n this._stableBlockCount = 0\n const blockTokens = this.buildRenderableTokens(tokens)\n let blockIndex = 0\n for (let i = 0; i < blockTokens.length; i++) {\n const token = blockTokens[i]\n const nextToken = blockTokens[i + 1]\n const existing = this._blockStates[blockIndex]\n\n const shouldForceRefresh = forceTableRefresh\n\n if (existing && existing.token === token) {\n if (shouldForceRefresh) {\n this.updateBlockRenderable(existing, token, blockIndex, nextToken)\n existing.tokenRaw = token.raw\n } else {\n this.applyInterBlockMargin(existing, token, nextToken)\n }\n blockIndex++\n continue\n }\n\n if (existing && existing.tokenRaw === token.raw && existing.token.type === token.type) {\n existing.token = token\n if (shouldForceRefresh) {\n this.updateBlockRenderable(existing, token, blockIndex, nextToken)\n existing.tokenRaw = token.raw\n } else {\n this.applyInterBlockMargin(existing, token, nextToken)\n }\n blockIndex++\n continue\n }\n\n if (existing && existing.canUpdateInPlace && existing.token.type === token.type) {\n const custom = this.createCustomRenderable(token, blockIndex, nextToken)\n if (custom.renderable && !custom.canUpdateInPlace) {\n if (custom.renderable !== existing.renderable) {\n existing.renderable.destroyRecursively()\n this.add(custom.renderable, blockIndex)\n }\n this._blockStates[blockIndex] = {\n token,\n tokenRaw: token.raw,\n renderable: custom.renderable,\n tracksInterBlockMargin: custom.tracksInterBlockMargin,\n canUpdateInPlace: custom.canUpdateInPlace,\n }\n blockIndex++\n continue\n }\n this.destroyUnusedDefaultRenderable(custom.renderable)\n\n this.updateBlockRenderable(existing, token, blockIndex, nextToken)\n existing.token = token\n existing.tokenRaw = token.raw\n existing.tracksInterBlockMargin = true\n blockIndex++\n continue\n }\n\n if (existing) {\n existing.renderable.destroyRecursively()\n }\n\n let renderable: Renderable | undefined\n let tableContentCache: TableContentCache | undefined\n let tracksInterBlockMargin = true\n let canUpdateInPlace = true\n\n const custom = this.createCustomRenderable(token, blockIndex, nextToken)\n if (custom.renderable) {\n renderable = custom.renderable\n tracksInterBlockMargin = custom.tracksInterBlockMargin\n canUpdateInPlace = custom.canUpdateInPlace\n }\n\n if (!renderable) {\n if (token.type === \"table\") {\n const tableBlock = this.createTableBlock(\n token,\n `${this.id}-block-${blockIndex}`,\n this.getInterBlockMargin(token, nextToken),\n )\n renderable = tableBlock.renderable\n tableContentCache = tableBlock.tableContentCache\n } else {\n renderable = this.createDefaultRenderable(token, blockIndex, nextToken) ?? undefined\n }\n }\n\n if (token.type === \"table\" && !tableContentCache && renderable instanceof TextTableRenderable) {\n const { cache } = this.buildTableContentCache(token as Tokens.Table)\n tableContentCache = cache ?? undefined\n }\n\n if (renderable) {\n this.add(renderable, blockIndex)\n this._blockStates[blockIndex] = {\n token,\n tokenRaw: token.raw,\n renderable,\n tableContentCache,\n tracksInterBlockMargin,\n canUpdateInPlace,\n }\n }\n blockIndex++\n }\n\n while (this._blockStates.length > blockIndex) {\n const removed = this._blockStates.pop()!\n removed.renderable.destroyRecursively()\n }\n }\n\n private clearBlockStates(): void {\n for (const state of this._blockStates) {\n state.renderable.destroyRecursively()\n }\n this._blockStates = []\n this._stableBlockCount = 0\n }\n\n /**\n * Re-render existing blocks without rebuilding the parse state or block structure.\n * Used when only style/conceal changes - much faster than full rebuild.\n */\n private rerenderBlocks(): void {\n if (this._internalBlockMode === \"top-level\") {\n this.updateBlocks(true)\n return\n }\n\n for (let i = 0; i < this._blockStates.length; i++) {\n const state = this._blockStates[i]\n const marginBottom = this.getInterBlockMargin(state.token, this._blockStates[i + 1]?.token)\n\n if (state.token.type === \"code\") {\n this.applyCodeBlockRenderable(state.renderable, state.token as Tokens.Code, marginBottom)\n continue\n }\n\n if (state.token.type === \"blockquote\") {\n this.applyBlockquoteRenderable(state.renderable, state.token, marginBottom)\n continue\n }\n\n if (state.token.type === \"list\") {\n this.updateBlockRenderable(state, state.token, i, this._blockStates[i + 1]?.token, true)\n continue\n }\n\n if (state.token.type === \"hr\") {\n state.renderable.marginBottom = marginBottom\n continue\n }\n\n if (state.token.type === \"table\") {\n const tableToken = state.token as Tokens.Table\n const { cache } = this.buildTableContentCache(tableToken, state.tableContentCache, true)\n\n if (!cache) {\n if (state.renderable instanceof CodeRenderable) {\n this.applyMarkdownCodeRenderable(state.renderable, tableToken.raw, marginBottom)\n } else {\n state.renderable.destroyRecursively()\n const fallbackRenderable = this.createMarkdownCodeRenderable(\n tableToken.raw,\n `${this.id}-block-${i}`,\n marginBottom,\n )\n this.add(fallbackRenderable, i)\n state.renderable = fallbackRenderable\n }\n state.tableContentCache = undefined\n continue\n }\n\n if (state.renderable instanceof TextTableRenderable) {\n state.renderable.content = cache.content\n this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions())\n state.renderable.marginBottom = marginBottom\n state.tableContentCache = cache\n continue\n }\n\n state.renderable.destroyRecursively()\n const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${i}`, marginBottom)\n this.add(tableRenderable, i)\n state.renderable = tableRenderable\n state.tableContentCache = cache\n continue\n }\n\n if (state.renderable instanceof CodeRenderable) {\n this.applyMarkdownCodeRenderable(\n state.renderable,\n this.getTopLevelBlockRaw(state.token) ?? state.token.raw,\n marginBottom,\n undefined,\n this.createInitialStyledText(state.token),\n )\n continue\n }\n\n state.renderable.destroyRecursively()\n const markdownRenderable = this.createMarkdownCodeRenderable(\n this.getTopLevelBlockRaw(state.token) ?? state.token.raw,\n `${this.id}-block-${i}`,\n marginBottom,\n this._linkifyMarkdownChunks,\n undefined,\n this.createInitialStyledText(state.token),\n )\n this.add(markdownRenderable, i)\n state.renderable = markdownRenderable\n }\n }\n\n public clearCache(): void {\n this._parseState = null\n this.clearBlockStates()\n this.updateBlocks()\n this.requestRender()\n }\n\n public refreshStyles(): void {\n this._styleDirty = false\n this.rerenderBlocks()\n this.requestRender()\n }\n\n protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void {\n // Check if style/conceal changed - re-render blocks before rendering\n if (this._styleDirty) {\n this._styleDirty = false\n this.rerenderBlocks()\n }\n super.renderSelf(buffer, deltaTime)\n }\n}\n", + "import { type RenderableOptions, Renderable } from \"../Renderable.js\"\nimport { type RenderContext } from \"../types.js\"\nimport { type ColorInput, RGBA, parseColor } from \"../lib/RGBA.js\"\nimport { OptimizedBuffer } from \"../buffer.js\"\n\nconst defaultThumbBackgroundColor = RGBA.fromHex(\"#9a9ea3\")\nconst defaultTrackBackgroundColor = RGBA.fromHex(\"#252527\")\n\nexport interface SliderOptions extends RenderableOptions {\n orientation: \"vertical\" | \"horizontal\"\n value?: number\n min?: number\n max?: number\n viewPortSize?: number\n backgroundColor?: ColorInput\n foregroundColor?: ColorInput\n onChange?: (value: number) => void\n}\n\nexport class SliderRenderable extends Renderable {\n public readonly orientation: \"vertical\" | \"horizontal\"\n private _value: number\n private _min: number\n private _max: number\n private _viewPortSize: number\n private _backgroundColor: RGBA\n private _foregroundColor: RGBA\n private _onChange?: (value: number) => void\n\n constructor(ctx: RenderContext, options: SliderOptions) {\n super(ctx, { flexShrink: 0, ...options })\n this.orientation = options.orientation\n this._min = options.min ?? 0\n this._max = options.max ?? 100\n this._value = options.value ?? this._min\n this._viewPortSize = options.viewPortSize ?? Math.max(1, (this._max - this._min) * 0.1)\n this._onChange = options.onChange\n this._backgroundColor = options.backgroundColor ? parseColor(options.backgroundColor) : defaultTrackBackgroundColor\n this._foregroundColor = options.foregroundColor ? parseColor(options.foregroundColor) : defaultThumbBackgroundColor\n\n this.setupMouseHandling()\n }\n\n get value(): number {\n return this._value\n }\n\n set value(newValue: number) {\n const clamped = Math.max(this._min, Math.min(this._max, newValue))\n if (clamped !== this._value) {\n this._value = clamped\n this._onChange?.(clamped)\n this.emit(\"change\", { value: clamped })\n this.requestRender()\n }\n }\n\n get min(): number {\n return this._min\n }\n\n set min(newMin: number) {\n if (newMin !== this._min) {\n this._min = newMin\n if (this._value < newMin) {\n this.value = newMin\n }\n this.requestRender()\n }\n }\n\n get max(): number {\n return this._max\n }\n\n set max(newMax: number) {\n if (newMax !== this._max) {\n this._max = newMax\n if (this._value > newMax) {\n this.value = newMax\n }\n this.requestRender()\n }\n }\n\n set viewPortSize(size: number) {\n const clampedSize = Math.max(0.01, Math.min(size, this._max - this._min))\n if (clampedSize !== this._viewPortSize) {\n this._viewPortSize = clampedSize\n this.requestRender()\n }\n }\n\n get viewPortSize(): number {\n return this._viewPortSize\n }\n\n get backgroundColor(): RGBA {\n return this._backgroundColor\n }\n\n set backgroundColor(value: ColorInput) {\n this._backgroundColor = parseColor(value)\n this.requestRender()\n }\n\n get foregroundColor(): RGBA {\n return this._foregroundColor\n }\n\n set foregroundColor(value: ColorInput) {\n this._foregroundColor = parseColor(value)\n this.requestRender()\n }\n\n private calculateDragOffsetVirtual(event: any): number {\n const trackStart = this.orientation === \"vertical\" ? this.y : this.x\n const mousePos = (this.orientation === \"vertical\" ? event.y : event.x) - trackStart\n const virtualMousePos = Math.max(\n 0,\n Math.min((this.orientation === \"vertical\" ? this.height : this.width) * 2, mousePos * 2),\n )\n const virtualThumbStart = this.getVirtualThumbStart()\n const virtualThumbSize = this.getVirtualThumbSize()\n\n return Math.max(0, Math.min(virtualThumbSize, virtualMousePos - virtualThumbStart))\n }\n\n private setupMouseHandling(): void {\n let isDragging = false\n let dragOffsetVirtual = 0\n\n this.onMouseDown = (event) => {\n event.stopPropagation()\n event.preventDefault()\n\n const thumb = this.getThumbRect()\n const inThumb =\n event.x >= thumb.x && event.x < thumb.x + thumb.width && event.y >= thumb.y && event.y < thumb.y + thumb.height\n\n if (inThumb) {\n isDragging = true\n\n dragOffsetVirtual = this.calculateDragOffsetVirtual(event)\n } else {\n this.updateValueFromMouseDirect(event)\n isDragging = true\n\n dragOffsetVirtual = this.calculateDragOffsetVirtual(event)\n }\n }\n\n this.onMouseDrag = (event) => {\n if (!isDragging) return\n event.stopPropagation()\n this.updateValueFromMouseWithOffset(event, dragOffsetVirtual)\n }\n\n this.onMouseUp = (event) => {\n if (isDragging) {\n this.updateValueFromMouseWithOffset(event, dragOffsetVirtual)\n }\n isDragging = false\n }\n }\n\n private updateValueFromMouseDirect(event: any): void {\n const trackStart = this.orientation === \"vertical\" ? this.y : this.x\n const trackSize = this.orientation === \"vertical\" ? this.height : this.width\n const mousePos = this.orientation === \"vertical\" ? event.y : event.x\n\n const relativeMousePos = mousePos - trackStart\n const clampedMousePos = Math.max(0, Math.min(trackSize, relativeMousePos))\n const ratio = trackSize === 0 ? 0 : clampedMousePos / trackSize\n const range = this._max - this._min\n const newValue = this._min + ratio * range\n\n this.value = newValue\n }\n\n private updateValueFromMouseWithOffset(event: any, offsetVirtual: number): void {\n const trackStart = this.orientation === \"vertical\" ? this.y : this.x\n const trackSize = this.orientation === \"vertical\" ? this.height : this.width\n const mousePos = this.orientation === \"vertical\" ? event.y : event.x\n\n const virtualTrackSize = trackSize * 2\n const relativeMousePos = mousePos - trackStart\n const clampedMousePos = Math.max(0, Math.min(trackSize, relativeMousePos))\n const virtualMousePos = clampedMousePos * 2\n\n const virtualThumbSize = this.getVirtualThumbSize()\n const maxThumbStart = Math.max(0, virtualTrackSize - virtualThumbSize)\n\n let desiredThumbStart = virtualMousePos - offsetVirtual\n desiredThumbStart = Math.max(0, Math.min(maxThumbStart, desiredThumbStart))\n\n const ratio = maxThumbStart === 0 ? 0 : desiredThumbStart / maxThumbStart\n const range = this._max - this._min\n const newValue = this._min + ratio * range\n\n this.value = newValue\n }\n\n private getThumbRect(): { x: number; y: number; width: number; height: number } {\n const virtualThumbSize = this.getVirtualThumbSize()\n const virtualThumbStart = this.getVirtualThumbStart()\n\n const realThumbStart = Math.floor(virtualThumbStart / 2)\n const realThumbSize = Math.ceil((virtualThumbStart + virtualThumbSize) / 2) - realThumbStart\n\n if (this.orientation === \"vertical\") {\n return {\n x: this.x,\n y: this.y + realThumbStart,\n width: this.width,\n height: Math.max(1, realThumbSize),\n }\n } else {\n return {\n x: this.x + realThumbStart,\n y: this.y,\n width: Math.max(1, realThumbSize),\n height: this.height,\n }\n }\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n if (this.orientation === \"horizontal\") {\n this.renderHorizontal(buffer)\n } else {\n this.renderVertical(buffer)\n }\n }\n\n private renderHorizontal(buffer: OptimizedBuffer): void {\n const virtualThumbSize = this.getVirtualThumbSize()\n const virtualThumbStart = this.getVirtualThumbStart()\n const virtualThumbEnd = virtualThumbStart + virtualThumbSize\n\n buffer.fillRect(this.x, this.y, this.width, this.height, this._backgroundColor)\n\n const realStartCell = Math.floor(virtualThumbStart / 2)\n const realEndCell = Math.ceil(virtualThumbEnd / 2) - 1\n const startX = Math.max(0, realStartCell)\n const endX = Math.min(this.width - 1, realEndCell)\n\n for (let realX = startX; realX <= endX; realX++) {\n const virtualCellStart = realX * 2\n const virtualCellEnd = virtualCellStart + 2\n\n const thumbStartInCell = Math.max(virtualThumbStart, virtualCellStart)\n const thumbEndInCell = Math.min(virtualThumbEnd, virtualCellEnd)\n const coverage = thumbEndInCell - thumbStartInCell\n\n let char = \" \"\n\n if (coverage >= 2) {\n char = \"█\"\n } else {\n const isLeftHalf = thumbStartInCell === virtualCellStart\n if (isLeftHalf) {\n char = \"▌\"\n } else {\n char = \"▐\"\n }\n }\n\n for (let y = 0; y < this.height; y++) {\n buffer.setCellWithAlphaBlending(this.x + realX, this.y + y, char, this._foregroundColor, this._backgroundColor)\n }\n }\n }\n\n private renderVertical(buffer: OptimizedBuffer): void {\n const virtualThumbSize = this.getVirtualThumbSize()\n const virtualThumbStart = this.getVirtualThumbStart()\n const virtualThumbEnd = virtualThumbStart + virtualThumbSize\n\n buffer.fillRect(this.x, this.y, this.width, this.height, this._backgroundColor)\n\n const realStartCell = Math.floor(virtualThumbStart / 2)\n const realEndCell = Math.ceil(virtualThumbEnd / 2) - 1\n const startY = Math.max(0, realStartCell)\n const endY = Math.min(this.height - 1, realEndCell)\n\n for (let realY = startY; realY <= endY; realY++) {\n const virtualCellStart = realY * 2\n const virtualCellEnd = virtualCellStart + 2\n\n const thumbStartInCell = Math.max(virtualThumbStart, virtualCellStart)\n const thumbEndInCell = Math.min(virtualThumbEnd, virtualCellEnd)\n const coverage = thumbEndInCell - thumbStartInCell\n\n let char = \" \"\n\n if (coverage >= 2) {\n char = \"█\"\n } else if (coverage > 0) {\n const virtualPositionInCell = thumbStartInCell - virtualCellStart\n if (virtualPositionInCell === 0) {\n char = \"▀\"\n } else {\n char = \"▄\"\n }\n }\n\n for (let x = 0; x < this.width; x++) {\n buffer.setCellWithAlphaBlending(this.x + x, this.y + realY, char, this._foregroundColor, this._backgroundColor)\n }\n }\n }\n\n private getVirtualThumbSize(): number {\n const virtualTrackSize = this.orientation === \"vertical\" ? this.height * 2 : this.width * 2\n const range = this._max - this._min\n\n if (range === 0) return virtualTrackSize\n\n const viewportSize = Math.max(1, this._viewPortSize)\n const contentSize = range + viewportSize\n\n if (contentSize <= viewportSize) return virtualTrackSize\n\n const thumbRatio = viewportSize / contentSize\n const calculatedSize = Math.floor(virtualTrackSize * thumbRatio)\n\n return Math.max(1, Math.min(calculatedSize, virtualTrackSize))\n }\n\n private getVirtualThumbStart(): number {\n const virtualTrackSize = this.orientation === \"vertical\" ? this.height * 2 : this.width * 2\n const range = this._max - this._min\n\n if (range === 0) return 0\n\n const valueRatio = (this._value - this._min) / range\n const virtualThumbSize = this.getVirtualThumbSize()\n\n return Math.round(valueRatio * (virtualTrackSize - virtualThumbSize))\n }\n}\n", + "import type { OptimizedBuffer } from \"../buffer.js\"\nimport { parseColor, RGBA, type ColorInput } from \"../lib/index.js\"\nimport type { KeyEvent } from \"../lib/KeyHandler.js\"\nimport { stringWidth } from \"../platform/runtime.js\"\nimport { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport type { RenderContext, Timeout } from \"../types.js\"\nimport { type BoxOptions } from \"./Box.js\"\nimport { SliderRenderable, type SliderOptions } from \"./Slider.js\"\n\nexport interface ScrollBarOptions extends RenderableOptions {\n orientation: \"vertical\" | \"horizontal\"\n showArrows?: boolean\n arrowOptions?: Omit\n trackOptions?: Partial\n onChange?: (position: number) => void\n}\n\nexport type ScrollUnit = \"absolute\" | \"viewport\" | \"content\" | \"step\"\n\nexport class ScrollBarRenderable extends Renderable {\n public readonly slider: SliderRenderable\n public readonly startArrow: ArrowRenderable\n public readonly endArrow: ArrowRenderable\n public readonly orientation: \"vertical\" | \"horizontal\"\n\n protected _focusable: boolean = true\n\n private _scrollSize = 0\n private _scrollPosition = 0\n private _viewportSize = 0\n private _showArrows = false\n private _manualVisibility = false\n\n private _onChange: ((position: number) => void) | undefined\n\n scrollStep: number | undefined | null = null\n\n get visible(): boolean {\n return super.visible\n }\n\n set visible(value: boolean) {\n this._manualVisibility = true\n super.visible = value\n }\n\n public resetVisibilityControl(): void {\n this._manualVisibility = false\n this.recalculateVisibility()\n }\n\n get scrollSize(): number {\n return this._scrollSize\n }\n\n get scrollPosition(): number {\n return this._scrollPosition\n }\n\n get viewportSize(): number {\n return this._viewportSize\n }\n\n set scrollSize(value: number) {\n if (value === this.scrollSize) return\n this._scrollSize = value\n this.recalculateVisibility()\n this.updateSliderFromScrollState()\n this.scrollPosition = this.scrollPosition\n }\n\n set scrollPosition(value: number) {\n const newPosition = Math.round(Math.min(Math.max(0, value), this.scrollSize - this.viewportSize))\n if (newPosition !== this._scrollPosition) {\n this._scrollPosition = newPosition\n this.updateSliderFromScrollState()\n // Events are triggered by the slider change event\n // this._onChange?.(newPosition)\n // this.emit(\"change\", { position: newPosition })\n }\n }\n\n set viewportSize(value: number) {\n if (value === this.viewportSize) return\n this._viewportSize = value\n this.slider.viewPortSize = Math.max(1, this._viewportSize)\n this.recalculateVisibility()\n this.updateSliderFromScrollState()\n this.scrollPosition = this.scrollPosition\n }\n\n get showArrows(): boolean {\n return this._showArrows\n }\n\n set showArrows(value: boolean) {\n if (value === this._showArrows) return\n this._showArrows = value\n this.startArrow.visible = value\n this.endArrow.visible = value\n }\n\n constructor(\n ctx: RenderContext,\n { trackOptions, arrowOptions, orientation, showArrows = false, ...options }: ScrollBarOptions,\n ) {\n super(ctx, {\n flexDirection: orientation === \"vertical\" ? \"column\" : \"row\",\n alignSelf: \"stretch\",\n alignItems: \"stretch\",\n ...(options as BoxOptions),\n })\n\n this._onChange = options.onChange\n\n this.orientation = orientation\n this._showArrows = showArrows\n\n const scrollRange = Math.max(0, this._scrollSize - this._viewportSize)\n\n const defaultStepSize = Math.max(1, this._viewportSize)\n const stepSize = trackOptions?.viewPortSize ?? defaultStepSize\n\n this.slider = new SliderRenderable(ctx, {\n orientation,\n min: 0,\n max: scrollRange,\n value: this._scrollPosition,\n viewPortSize: stepSize,\n onChange: (value) => {\n this._scrollPosition = Math.round(value)\n this._onChange?.(this._scrollPosition)\n this.emit(\"change\", { position: this._scrollPosition })\n },\n ...(orientation === \"vertical\"\n ? {\n width: Math.max(1, Math.min(2, this.width)),\n height: \"100%\",\n marginLeft: \"auto\",\n }\n : {\n width: \"100%\",\n height: 1,\n marginTop: \"auto\",\n }),\n flexGrow: 1,\n flexShrink: 1,\n ...trackOptions,\n })\n\n this.updateSliderFromScrollState()\n\n const arrowOpts = arrowOptions\n ? {\n foregroundColor: arrowOptions.backgroundColor,\n backgroundColor: arrowOptions.backgroundColor,\n attributes: arrowOptions.attributes,\n ...arrowOptions,\n }\n : {}\n\n this.startArrow = new ArrowRenderable(ctx, {\n alignSelf: \"center\",\n visible: this.showArrows,\n direction: this.orientation === \"vertical\" ? \"up\" : \"left\",\n height: this.orientation === \"vertical\" ? 1 : 1,\n ...arrowOpts,\n })\n\n this.endArrow = new ArrowRenderable(ctx, {\n alignSelf: \"center\",\n visible: this.showArrows,\n direction: this.orientation === \"vertical\" ? \"down\" : \"right\",\n height: this.orientation === \"vertical\" ? 1 : 1,\n ...arrowOpts,\n })\n\n this.add(this.startArrow)\n this.add(this.slider)\n this.add(this.endArrow)\n\n let startArrowMouseTimeout = undefined as Timeout\n let endArrowMouseTimeout = undefined as Timeout\n\n this.startArrow.onMouseDown = (event) => {\n event.stopPropagation()\n event.preventDefault()\n\n this.scrollBy(-0.5, \"viewport\")\n\n startArrowMouseTimeout = setTimeout(() => {\n this.scrollBy(-0.5, \"viewport\")\n\n startArrowMouseTimeout = setInterval(() => {\n this.scrollBy(-0.2, \"viewport\")\n }, 200)\n }, 500)\n }\n\n this.startArrow.onMouseUp = (event) => {\n event.stopPropagation()\n clearInterval(startArrowMouseTimeout!)\n }\n\n this.endArrow.onMouseDown = (event) => {\n event.stopPropagation()\n event.preventDefault()\n\n this.scrollBy(0.5, \"viewport\")\n\n endArrowMouseTimeout = setTimeout(() => {\n this.scrollBy(0.5, \"viewport\")\n\n endArrowMouseTimeout = setInterval(() => {\n this.scrollBy(0.2, \"viewport\")\n }, 200)\n }, 500)\n }\n\n this.endArrow.onMouseUp = (event) => {\n event.stopPropagation()\n clearInterval(endArrowMouseTimeout!)\n }\n }\n\n public set arrowOptions(options: ScrollBarOptions[\"arrowOptions\"]) {\n Object.assign(this.startArrow, options)\n Object.assign(this.endArrow, options)\n this.requestRender()\n }\n\n public set trackOptions(options: ScrollBarOptions[\"trackOptions\"]) {\n Object.assign(this.slider, options)\n this.requestRender()\n }\n\n private updateSliderFromScrollState(): void {\n const scrollRange = Math.max(0, this._scrollSize - this._viewportSize)\n\n this.slider.min = 0\n this.slider.max = scrollRange\n\n this.slider.value = Math.min(this._scrollPosition, scrollRange)\n }\n\n public scrollBy(delta: number, unit: ScrollUnit = \"absolute\"): void {\n const multiplier =\n unit === \"viewport\"\n ? this.viewportSize\n : unit === \"content\"\n ? this.scrollSize\n : unit === \"step\"\n ? (this.scrollStep ?? 1)\n : 1\n\n const resolvedDelta = multiplier * delta\n this.scrollPosition += resolvedDelta\n }\n\n private recalculateVisibility(): void {\n if (!this._manualVisibility) {\n const sizeRatio = this.scrollSize <= this.viewportSize ? 1 : this.viewportSize / this.scrollSize\n super.visible = sizeRatio < 1\n }\n }\n\n public handleKeyPress(key: KeyEvent): boolean {\n switch (key.name) {\n case \"left\":\n case \"h\":\n if (this.orientation !== \"horizontal\") return false\n this.scrollBy(-1 / 5, \"viewport\")\n return true\n case \"right\":\n case \"l\":\n if (this.orientation !== \"horizontal\") return false\n this.scrollBy(1 / 5, \"viewport\")\n return true\n case \"up\":\n case \"k\":\n if (this.orientation !== \"vertical\") return false\n this.scrollBy(-1 / 5, \"viewport\")\n return true\n case \"down\":\n case \"j\":\n if (this.orientation !== \"vertical\") return false\n this.scrollBy(1 / 5, \"viewport\")\n return true\n case \"pageup\":\n this.scrollBy(-1 / 2, \"viewport\")\n return true\n case \"pagedown\":\n this.scrollBy(1 / 2, \"viewport\")\n return true\n case \"home\":\n this.scrollBy(-1, \"content\")\n return true\n case \"end\":\n this.scrollBy(1, \"content\")\n return true\n }\n\n return false\n }\n}\n\nexport interface ArrowOptions extends RenderableOptions {\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n foregroundColor?: ColorInput\n backgroundColor?: ColorInput\n attributes?: number\n arrowChars?: {\n up?: string\n down?: string\n left?: string\n right?: string\n }\n}\n\nexport class ArrowRenderable extends Renderable {\n private _direction: \"up\" | \"down\" | \"left\" | \"right\"\n private _foregroundColor: RGBA\n private _backgroundColor: RGBA\n private _attributes: number\n private _arrowChars: {\n up: string\n down: string\n left: string\n right: string\n }\n\n constructor(ctx: RenderContext, options: ArrowOptions) {\n super(ctx, options)\n this._direction = options.direction\n this._foregroundColor = options.foregroundColor ? parseColor(options.foregroundColor) : RGBA.fromValues(1, 1, 1, 1)\n this._backgroundColor = options.backgroundColor ? parseColor(options.backgroundColor) : RGBA.fromValues(0, 0, 0, 0)\n this._attributes = options.attributes ?? 0\n\n this._arrowChars = {\n up: \"▲\",\n down: \"▼\",\n left: \"◀\",\n right: \"▶\",\n ...options.arrowChars,\n }\n\n if (!options.width) {\n this.width = stringWidth(this.getArrowChar())\n }\n }\n\n get direction(): \"up\" | \"down\" | \"left\" | \"right\" {\n return this._direction\n }\n\n set direction(value: \"up\" | \"down\" | \"left\" | \"right\") {\n if (this._direction !== value) {\n this._direction = value\n this.requestRender()\n }\n }\n\n get foregroundColor(): RGBA {\n return this._foregroundColor\n }\n\n set foregroundColor(value: ColorInput) {\n if (this._foregroundColor !== value) {\n this._foregroundColor = parseColor(value)\n this.requestRender()\n }\n }\n\n get backgroundColor(): RGBA {\n return this._backgroundColor\n }\n\n set backgroundColor(value: ColorInput) {\n if (this._backgroundColor !== value) {\n this._backgroundColor = parseColor(value)\n this.requestRender()\n }\n }\n\n get attributes(): number {\n return this._attributes\n }\n\n set attributes(value: number) {\n if (this._attributes !== value) {\n this._attributes = value\n this.requestRender()\n }\n }\n\n set arrowChars(value: ArrowOptions[\"arrowChars\"]) {\n this._arrowChars = {\n ...this._arrowChars,\n ...value,\n }\n this.requestRender()\n }\n\n protected renderSelf(buffer: OptimizedBuffer): void {\n const char = this.getArrowChar()\n buffer.drawText(char, this.x, this.y, this._foregroundColor, this._backgroundColor, this._attributes)\n }\n\n private getArrowChar(): string {\n switch (this._direction) {\n case \"up\":\n return this._arrowChars.up\n case \"down\":\n return this._arrowChars.down\n case \"left\":\n return this._arrowChars.left\n case \"right\":\n return this._arrowChars.right\n default:\n return \"?\"\n }\n }\n}\n", + "import { type KeyEvent } from \"../lib/index.js\"\nimport { getObjectsInViewport } from \"../lib/objects-in-viewport.js\"\nimport { LinearScrollAccel, MacOSScrollAccel, type ScrollAcceleration } from \"../lib/scroll-acceleration.js\"\nimport type { Renderable, RenderableOptions } from \"../Renderable.js\"\nimport type { MouseEvent } from \"../renderer.js\"\nimport type { RenderContext } from \"../types.js\"\nimport { BoxRenderable, type BoxOptions } from \"./Box.js\"\nimport type { VNode } from \"./composition/vnode.js\"\nimport { ScrollBarRenderable, type ScrollBarOptions, type ScrollUnit } from \"./ScrollBar.js\"\n\nclass ContentRenderable extends BoxRenderable {\n private viewport: BoxRenderable\n private _viewportCulling: boolean\n\n constructor(\n ctx: RenderContext,\n viewport: BoxRenderable,\n viewportCulling: boolean,\n options: RenderableOptions,\n ) {\n super(ctx, options)\n this.viewport = viewport\n this._viewportCulling = viewportCulling\n }\n\n get viewportCulling(): boolean {\n return this._viewportCulling\n }\n\n set viewportCulling(value: boolean) {\n this._viewportCulling = value\n }\n\n protected _hasVisibleChildFilter(): boolean {\n return this._viewportCulling\n }\n\n protected _getVisibleChildren(): number[] {\n if (this._viewportCulling) {\n // The viewport is in terminal coordinates, so culling has to compare it\n // against each child's absolute screen position rather than local x/y.\n return getObjectsInViewport(\n {\n x: this.viewport.screenX,\n y: this.viewport.screenY,\n width: this.viewport.width,\n height: this.viewport.height,\n },\n this.getChildrenSortedByPrimaryAxis(),\n this.primaryAxis,\n 0,\n ).map((child) => child.num)\n }\n return super._getVisibleChildren()\n }\n}\n\nexport interface ScrollBoxOptions extends BoxOptions {\n rootOptions?: BoxOptions\n wrapperOptions?: BoxOptions\n viewportOptions?: BoxOptions\n contentOptions?: BoxOptions\n scrollbarOptions?: Omit\n verticalScrollbarOptions?: Omit\n horizontalScrollbarOptions?: Omit\n stickyScroll?: boolean\n stickyStart?: \"bottom\" | \"top\" | \"left\" | \"right\"\n scrollX?: boolean\n scrollY?: boolean\n scrollAcceleration?: ScrollAcceleration\n viewportCulling?: boolean\n}\n\nconst SCROLLBOX_PADDING_KEYS = [\n \"padding\",\n \"paddingX\",\n \"paddingY\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n] as const\n\ntype ScrollBoxPaddingKey = (typeof SCROLLBOX_PADDING_KEYS)[number]\ntype ScrollBoxPaddingOptions = Pick\n\nfunction pickScrollBoxPadding(options: Partial | undefined): Partial {\n if (!options) return {}\n\n const picked: Partial = {}\n for (const key of SCROLLBOX_PADDING_KEYS) {\n const value = options[key]\n if (value !== undefined) {\n picked[key] = value\n }\n }\n\n return picked\n}\n\nfunction stripScrollBoxPadding(options: T): Omit {\n const sanitized = { ...options }\n for (const key of SCROLLBOX_PADDING_KEYS) {\n delete (sanitized as Partial>)[key]\n }\n return sanitized as Omit\n}\n\nexport class ScrollBoxRenderable extends BoxRenderable {\n static idCounter = 0\n private internalId = 0\n public readonly wrapper: BoxRenderable\n public readonly viewport: BoxRenderable\n public readonly content: ContentRenderable\n public readonly horizontalScrollBar: ScrollBarRenderable\n public readonly verticalScrollBar: ScrollBarRenderable\n\n protected _focusable: boolean = true\n private selectionListener?: () => void\n\n private autoScrollMouseX: number = 0\n private autoScrollMouseY: number = 0\n private readonly autoScrollThresholdVertical = 3\n private readonly autoScrollThresholdHorizontal = 3\n private readonly autoScrollSpeedSlow = 6\n private readonly autoScrollSpeedMedium = 36\n private readonly autoScrollSpeedFast = 72\n private isAutoScrolling: boolean = false\n private cachedAutoScrollSpeed: number = 3\n private autoScrollAccumulatorX: number = 0\n private autoScrollAccumulatorY: number = 0\n\n private scrollAccumulatorX: number = 0\n private scrollAccumulatorY: number = 0\n\n private _stickyScroll: boolean\n private _stickyScrollTop: boolean = false\n private _stickyScrollBottom: boolean = false\n private _stickyScrollLeft: boolean = false\n private _stickyScrollRight: boolean = false\n private _stickyStart?: \"bottom\" | \"top\" | \"left\" | \"right\"\n private _hasManualScroll: boolean = false\n private _isApplyingStickyScroll: boolean = false\n private scrollAccel: ScrollAcceleration\n\n get stickyScroll(): boolean {\n return this._stickyScroll\n }\n\n set stickyScroll(value: boolean) {\n this._stickyScroll = value\n this.updateStickyState()\n }\n\n get stickyStart(): \"bottom\" | \"top\" | \"left\" | \"right\" | undefined {\n return this._stickyStart\n }\n\n set stickyStart(value: \"bottom\" | \"top\" | \"left\" | \"right\" | undefined) {\n this._stickyStart = value\n this.updateStickyState()\n }\n\n get scrollTop(): number {\n return this.verticalScrollBar.scrollPosition\n }\n\n set scrollTop(value: number) {\n this.verticalScrollBar.scrollPosition = value\n this.updateStickyState()\n }\n\n get scrollLeft(): number {\n return this.horizontalScrollBar.scrollPosition\n }\n\n set scrollLeft(value: number) {\n this.horizontalScrollBar.scrollPosition = value\n this.updateStickyState()\n }\n\n get scrollWidth(): number {\n return this.horizontalScrollBar.scrollSize\n }\n\n get scrollHeight(): number {\n return this.verticalScrollBar.scrollSize\n }\n\n private updateStickyState(): void {\n if (!this._stickyScroll) {\n this.syncManualScrollState()\n return\n }\n\n const maxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height)\n const maxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width)\n\n if (this.scrollTop <= 0) {\n this._stickyScrollTop = true\n this._stickyScrollBottom = false\n } else if (this.scrollTop >= maxScrollTop) {\n this._stickyScrollTop = false\n this._stickyScrollBottom = true\n } else {\n this._stickyScrollTop = false\n this._stickyScrollBottom = false\n }\n\n if (this.scrollLeft <= 0) {\n this._stickyScrollLeft = true\n this._stickyScrollRight = false\n } else if (this.scrollLeft >= maxScrollLeft) {\n this._stickyScrollLeft = false\n this._stickyScrollRight = true\n } else {\n this._stickyScrollLeft = false\n this._stickyScrollRight = false\n }\n\n this.syncManualScrollState()\n }\n\n private syncManualScrollState(): void {\n if (!this._stickyScroll) {\n this._hasManualScroll = false\n return\n }\n\n const maxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height)\n const maxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width)\n const hasScrollableContent = maxScrollTop > 1 || maxScrollLeft > 1\n\n if (this._isApplyingStickyScroll) {\n if (this._hasManualScroll && hasScrollableContent && this.isAtStickyPosition()) {\n this._hasManualScroll = false\n }\n return\n }\n\n this._hasManualScroll = hasScrollableContent && !this.isAtStickyPosition()\n }\n\n private applyStickyStart(stickyStart: \"bottom\" | \"top\" | \"left\" | \"right\"): void {\n const wasApplyingStickyScroll = this._isApplyingStickyScroll\n this._isApplyingStickyScroll = true\n try {\n switch (stickyStart) {\n case \"top\":\n this._stickyScrollTop = true\n this._stickyScrollBottom = false\n this.verticalScrollBar.scrollPosition = 0\n break\n case \"bottom\":\n this._stickyScrollTop = false\n this._stickyScrollBottom = true\n this.verticalScrollBar.scrollPosition = Math.max(0, this.scrollHeight - this.viewport.height)\n break\n case \"left\":\n this._stickyScrollLeft = true\n this._stickyScrollRight = false\n this.horizontalScrollBar.scrollPosition = 0\n break\n case \"right\":\n this._stickyScrollLeft = false\n this._stickyScrollRight = true\n this.horizontalScrollBar.scrollPosition = Math.max(0, this.scrollWidth - this.viewport.width)\n break\n }\n } finally {\n this._isApplyingStickyScroll = wasApplyingStickyScroll\n }\n }\n\n constructor(ctx: RenderContext, options: ScrollBoxOptions) {\n const {\n wrapperOptions,\n viewportOptions,\n contentOptions,\n rootOptions,\n scrollbarOptions,\n verticalScrollbarOptions,\n horizontalScrollbarOptions,\n stickyScroll = false,\n stickyStart,\n scrollX = false,\n scrollY = true,\n scrollAcceleration,\n viewportCulling = true,\n ...rootBoxOptions\n } = options\n\n const forwardedContentPadding = {\n ...pickScrollBoxPadding(rootBoxOptions),\n ...pickScrollBoxPadding(rootOptions),\n }\n\n const sanitizedRootBoxOptions = stripScrollBoxPadding(rootBoxOptions)\n const sanitizedRootOptions = rootOptions ? stripScrollBoxPadding(rootOptions) : undefined\n const mergedContentOptions = {\n ...forwardedContentPadding,\n ...contentOptions,\n }\n\n // Root\n super(ctx, {\n flexDirection: \"row\",\n alignItems: \"stretch\",\n ...(sanitizedRootBoxOptions as BoxOptions),\n ...(sanitizedRootOptions as BoxOptions),\n })\n\n this.internalId = ScrollBoxRenderable.idCounter++\n this._stickyScroll = stickyScroll\n this._stickyStart = stickyStart\n this.scrollAccel = scrollAcceleration ?? new LinearScrollAccel()\n\n this.wrapper = new BoxRenderable(ctx, {\n flexDirection: \"column\",\n flexGrow: 1,\n ...wrapperOptions,\n id: `scroll-box-wrapper-${this.internalId}`,\n })\n super.add(this.wrapper)\n\n this.viewport = new BoxRenderable(ctx, {\n flexDirection: \"column\",\n flexGrow: 1,\n // NOTE: Overflow scroll makes the content size behave weird\n // when the scrollbox is in a container with max-width/height\n overflow: \"hidden\",\n onSizeChange: () => {\n this.recalculateBarProps()\n },\n ...viewportOptions,\n id: `scroll-box-viewport-${this.internalId}`,\n })\n this.wrapper.add(this.viewport)\n\n this.content = new ContentRenderable(ctx, this.viewport, viewportCulling, {\n alignSelf: \"flex-start\",\n flexShrink: 0,\n ...(scrollX ? { minWidth: \"100%\" } : { minWidth: \"100%\", maxWidth: \"100%\" }),\n ...(scrollY ? { minHeight: \"100%\" } : { minHeight: \"100%\", maxHeight: \"100%\" }),\n onSizeChange: () => {\n this.recalculateBarProps()\n },\n ...mergedContentOptions,\n id: `scroll-box-content-${this.internalId}`,\n })\n this.viewport.add(this.content)\n\n this.verticalScrollBar = new ScrollBarRenderable(ctx, {\n ...scrollbarOptions,\n ...verticalScrollbarOptions,\n arrowOptions: {\n ...scrollbarOptions?.arrowOptions,\n ...verticalScrollbarOptions?.arrowOptions,\n },\n id: `scroll-box-vertical-scrollbar-${this.internalId}`,\n orientation: \"vertical\",\n onChange: (position) => {\n this.content.translateY = -position\n this.updateStickyState()\n },\n })\n super.add(this.verticalScrollBar)\n\n this.horizontalScrollBar = new ScrollBarRenderable(ctx, {\n ...scrollbarOptions,\n ...horizontalScrollbarOptions,\n arrowOptions: {\n ...scrollbarOptions?.arrowOptions,\n ...horizontalScrollbarOptions?.arrowOptions,\n },\n id: `scroll-box-horizontal-scrollbar-${this.internalId}`,\n orientation: \"horizontal\",\n onChange: (position) => {\n this.content.translateX = -position\n this.updateStickyState()\n },\n })\n this.wrapper.add(this.horizontalScrollBar)\n\n this.recalculateBarProps()\n\n if (stickyStart && stickyScroll) {\n this.applyStickyStart(stickyStart)\n }\n\n this.selectionListener = () => {\n const selection = this._ctx.getSelection()\n if (!selection || !selection.isDragging) {\n this.stopAutoScroll()\n }\n }\n this._ctx.on(\"selection\", this.selectionListener)\n }\n\n protected onUpdate(deltaTime: number): void {\n this.handleAutoScroll(deltaTime)\n }\n\n public scrollBy(delta: number | { x: number; y: number }, unit: ScrollUnit = \"absolute\"): void {\n if (typeof delta === \"number\") {\n this.verticalScrollBar.scrollBy(delta, unit)\n } else {\n this.verticalScrollBar.scrollBy(delta.y, unit)\n this.horizontalScrollBar.scrollBy(delta.x, unit)\n }\n // Note: scrollBy doesn't need to set _hasManualScroll here because the scrollbar\n // change will trigger the scrollTop setter which handles it\n }\n\n public scrollChildIntoView(childId: string): void {\n const child = this.content.findDescendantById(childId)\n if (!child) return\n\n const getNearestDelta = (\n elementStart: number,\n elementEnd: number,\n viewportStart: number,\n viewportEnd: number,\n ): number => {\n const elementSize = elementEnd - elementStart\n const viewportSize = viewportEnd - viewportStart\n const elementStartOutside = elementStart < viewportStart\n const elementEndOutside = elementEnd > viewportEnd\n\n if (elementStartOutside && elementEndOutside) {\n return 0\n }\n\n if ((elementStartOutside && elementSize < viewportSize) || (elementEndOutside && elementSize > viewportSize)) {\n return elementStart - viewportStart\n }\n\n if ((elementStartOutside && elementSize > viewportSize) || (elementEndOutside && elementSize < viewportSize)) {\n return elementEnd - viewportEnd\n }\n\n return 0\n }\n\n const childTop = child.y\n const childBottom = child.y + child.height\n const viewportTop = this.viewport.y\n const viewportBottom = this.viewport.y + this.viewport.height\n\n const dy = getNearestDelta(childTop, childBottom, viewportTop, viewportBottom)\n\n const childLeft = child.x\n const childRight = child.x + child.width\n const viewportLeft = this.viewport.x\n const viewportRight = this.viewport.x + this.viewport.width\n\n const dx = getNearestDelta(childLeft, childRight, viewportLeft, viewportRight)\n\n if (dx !== 0 || dy !== 0) {\n this.scrollBy({ x: dx, y: dy })\n }\n }\n\n public scrollTo(position: number | { x: number; y: number }): void {\n if (typeof position === \"number\") {\n this.scrollTop = position\n } else {\n this.scrollTop = position.y\n this.scrollLeft = position.x\n }\n // Note: scrollTo doesn't need to set _hasManualScroll here because\n // the scrollTop/scrollLeft setters handle it\n }\n\n private isAtStickyPosition(): boolean {\n if (!this._stickyScroll || !this._stickyStart) {\n return false\n }\n\n const maxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height)\n const maxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width)\n\n switch (this._stickyStart) {\n case \"top\":\n return this.scrollTop === 0\n case \"bottom\":\n return this.scrollTop >= maxScrollTop\n case \"left\":\n return this.scrollLeft === 0\n case \"right\":\n return this.scrollLeft >= maxScrollLeft\n default:\n return false\n }\n }\n\n private isAtStickyReengagePoint(\n stickyStart: \"bottom\" | \"top\" | \"left\" | \"right\",\n maxScrollTop: number,\n maxScrollLeft: number,\n ): boolean {\n switch (stickyStart) {\n case \"top\":\n return maxScrollTop > 0 && this.scrollTop <= 0\n case \"bottom\":\n return maxScrollTop > 0 && this.scrollTop >= maxScrollTop - 1\n case \"left\":\n return maxScrollLeft > 0 && this.scrollLeft <= 0\n case \"right\":\n return maxScrollLeft > 0 && this.scrollLeft >= maxScrollLeft - 1\n }\n }\n\n public add(obj: Renderable | VNode, index?: number): number {\n return this.content.add(obj, index)\n }\n\n public insertBefore(obj: Renderable | VNode | unknown, anchor?: Renderable | unknown): number {\n return this.content.insertBefore(obj, anchor)\n }\n\n public remove(id: string): void {\n this.content.remove(id)\n }\n\n public getChildren(): Renderable[] {\n return this.content.getChildren()\n }\n\n protected onMouseEvent(event: MouseEvent): void {\n if (event.type === \"scroll\") {\n let dir = event.scroll?.direction\n if (event.modifiers.shift)\n dir = dir === \"up\" ? \"left\" : dir === \"down\" ? \"right\" : dir === \"right\" ? \"down\" : \"up\"\n\n const baseDelta = event.scroll?.delta ?? 0\n const now = Date.now()\n const multiplier = this.scrollAccel.tick(now)\n const scrollAmount = baseDelta * multiplier\n\n if (dir === \"up\") {\n this.scrollAccumulatorY -= scrollAmount\n const integerScroll = Math.trunc(this.scrollAccumulatorY)\n if (integerScroll !== 0) {\n this.scrollTop += integerScroll\n this.scrollAccumulatorY -= integerScroll\n }\n } else if (dir === \"down\") {\n this.scrollAccumulatorY += scrollAmount\n const integerScroll = Math.trunc(this.scrollAccumulatorY)\n if (integerScroll !== 0) {\n this.scrollTop += integerScroll\n this.scrollAccumulatorY -= integerScroll\n }\n } else if (dir === \"left\") {\n this.scrollAccumulatorX -= scrollAmount\n const integerScroll = Math.trunc(this.scrollAccumulatorX)\n if (integerScroll !== 0) {\n this.scrollLeft += integerScroll\n this.scrollAccumulatorX -= integerScroll\n }\n } else if (dir === \"right\") {\n this.scrollAccumulatorX += scrollAmount\n const integerScroll = Math.trunc(this.scrollAccumulatorX)\n if (integerScroll !== 0) {\n this.scrollLeft += integerScroll\n this.scrollAccumulatorX -= integerScroll\n }\n }\n\n this.syncManualScrollState()\n }\n\n if (event.type === \"drag\" && event.isDragging) {\n this.updateAutoScroll(event.x, event.y)\n } else if (event.type === \"up\") {\n this.stopAutoScroll()\n }\n }\n\n public handleKeyPress(key: KeyEvent): boolean {\n // Let scrollbars handle their own acceleration\n if (this.verticalScrollBar.handleKeyPress(key)) {\n this.scrollAccel.reset()\n this.resetScrollAccumulators()\n this.syncManualScrollState()\n return true\n }\n if (this.horizontalScrollBar.handleKeyPress(key)) {\n this.scrollAccel.reset()\n this.resetScrollAccumulators()\n this.syncManualScrollState()\n return true\n }\n return false\n }\n\n private resetScrollAccumulators(): void {\n this.scrollAccumulatorX = 0\n this.scrollAccumulatorY = 0\n }\n\n public startAutoScroll(mouseX: number, mouseY: number): void {\n this.stopAutoScroll()\n this.autoScrollMouseX = mouseX\n this.autoScrollMouseY = mouseY\n this.cachedAutoScrollSpeed = this.getAutoScrollSpeed(mouseX, mouseY)\n this.isAutoScrolling = true\n\n if (!this.live) {\n this.live = true\n }\n }\n\n public updateAutoScroll(mouseX: number, mouseY: number): void {\n this.autoScrollMouseX = mouseX\n this.autoScrollMouseY = mouseY\n\n // Cache the speed based on current mouse position\n this.cachedAutoScrollSpeed = this.getAutoScrollSpeed(mouseX, mouseY)\n\n const scrollX = this.getAutoScrollDirectionX(mouseX)\n const scrollY = this.getAutoScrollDirectionY(mouseY)\n\n if (scrollX === 0 && scrollY === 0) {\n this.stopAutoScroll()\n } else if (!this.isAutoScrolling) {\n this.startAutoScroll(mouseX, mouseY)\n }\n }\n\n public stopAutoScroll(): void {\n const wasAutoScrolling = this.isAutoScrolling\n this.isAutoScrolling = false\n this.autoScrollAccumulatorX = 0\n this.autoScrollAccumulatorY = 0\n\n // Only turn off live if no other features need it\n // For now, auto-scroll is the only feature using live, but this could be extended\n if (wasAutoScrolling && !this.hasOtherLiveReasons()) {\n this.live = false\n }\n }\n\n private hasOtherLiveReasons(): boolean {\n // Placeholder for future features that might need live mode\n // For now, always return false since auto-scroll is the only user\n return false\n }\n\n private handleAutoScroll(deltaTime: number): void {\n if (!this.isAutoScrolling) return\n\n const scrollX = this.getAutoScrollDirectionX(this.autoScrollMouseX)\n const scrollY = this.getAutoScrollDirectionY(this.autoScrollMouseY)\n const scrollAmount = this.cachedAutoScrollSpeed * (deltaTime / 1000)\n\n let scrolled = false\n\n if (scrollX !== 0) {\n this.autoScrollAccumulatorX += scrollX * scrollAmount\n const integerScrollX = Math.trunc(this.autoScrollAccumulatorX)\n if (integerScrollX !== 0) {\n this.scrollLeft += integerScrollX\n this.autoScrollAccumulatorX -= integerScrollX\n scrolled = true\n }\n }\n\n if (scrollY !== 0) {\n this.autoScrollAccumulatorY += scrollY * scrollAmount\n const integerScrollY = Math.trunc(this.autoScrollAccumulatorY)\n if (integerScrollY !== 0) {\n this.scrollTop += integerScrollY\n this.autoScrollAccumulatorY -= integerScrollY\n scrolled = true\n }\n }\n\n if (scrolled) {\n this._ctx.requestSelectionUpdate()\n }\n\n if (scrollX === 0 && scrollY === 0) {\n this.stopAutoScroll()\n }\n }\n\n private getAutoScrollDirectionX(mouseX: number): number {\n const relativeX = mouseX - this.x\n const distToLeft = relativeX\n const distToRight = this.width - relativeX\n\n if (distToLeft <= this.autoScrollThresholdHorizontal) {\n return this.scrollLeft > 0 ? -1 : 0\n } else if (distToRight <= this.autoScrollThresholdHorizontal) {\n const maxScrollLeft = this.scrollWidth - this.viewport.width\n return this.scrollLeft < maxScrollLeft ? 1 : 0\n }\n return 0\n }\n\n private getAutoScrollDirectionY(mouseY: number): number {\n const relativeY = mouseY - this.y\n const distToTop = relativeY\n const distToBottom = this.height - relativeY\n\n if (distToTop <= this.autoScrollThresholdVertical) {\n return this.scrollTop > 0 ? -1 : 0\n } else if (distToBottom <= this.autoScrollThresholdVertical) {\n const maxScrollTop = this.scrollHeight - this.viewport.height\n return this.scrollTop < maxScrollTop ? 1 : 0\n }\n return 0\n }\n\n private getAutoScrollSpeed(mouseX: number, mouseY: number): number {\n const relativeX = mouseX - this.x\n const relativeY = mouseY - this.y\n\n const distToLeft = relativeX\n const distToRight = this.width - relativeX\n const distToTop = relativeY\n const distToBottom = this.height - relativeY\n\n const minDistance = Math.min(distToLeft, distToRight, distToTop, distToBottom)\n\n if (minDistance <= 1) {\n return this.autoScrollSpeedFast\n } else if (minDistance <= 2) {\n return this.autoScrollSpeedMedium\n } else {\n return this.autoScrollSpeedSlow\n }\n }\n\n private recalculateBarProps(): void {\n // Wrap entire method to prevent scroll changes from being treated as manual\n const wasApplyingStickyScroll = this._isApplyingStickyScroll\n this._isApplyingStickyScroll = true\n\n try {\n this.verticalScrollBar.scrollSize = this.content.height\n this.verticalScrollBar.viewportSize = this.viewport.height\n this.horizontalScrollBar.scrollSize = this.content.width\n this.horizontalScrollBar.viewportSize = this.viewport.width\n\n if (this._stickyScroll) {\n const newMaxScrollTop = Math.max(0, this.scrollHeight - this.viewport.height)\n const newMaxScrollLeft = Math.max(0, this.scrollWidth - this.viewport.width)\n const stickyStart = this._stickyStart\n\n if (stickyStart && !this._hasManualScroll) {\n this.applyStickyStart(stickyStart)\n } else if (\n stickyStart &&\n this._hasManualScroll &&\n this.isAtStickyReengagePoint(stickyStart, newMaxScrollTop, newMaxScrollLeft)\n ) {\n // User scrolled back to the sticky edge during streaming; re-engage sticky.\n this._hasManualScroll = false\n this.applyStickyStart(stickyStart)\n } else if (!this._hasManualScroll) {\n if (this._stickyScrollTop) {\n this.scrollTop = 0\n } else if (this._stickyScrollBottom && newMaxScrollTop > 0) {\n this.scrollTop = newMaxScrollTop\n }\n\n if (this._stickyScrollLeft) {\n this.scrollLeft = 0\n } else if (this._stickyScrollRight && newMaxScrollLeft > 0) {\n this.scrollLeft = newMaxScrollLeft\n }\n }\n }\n } finally {\n this._isApplyingStickyScroll = wasApplyingStickyScroll\n }\n\n // NOTE: This is obviously a workaround for something,\n // which is that the bar props are recalculated when the viewport is resized,\n // which intially happens onUpdate but is the viewport does not have the correct dimensions yet,\n // then when it does, no update is triggered and when we do we are in the middle of a render,\n // which just ignores the request. ¯\\_(ツ)_/¯\n // TODO: Fix this properly. How? Move yoga to native, get all changes for elements in one go\n // and update all renderables in one go before rendering.\n // OR: Move this logic to the viewport. IMHO the wrapper and viewport are overkill and not necessary.\n // The Scrollbox can be the viewport, we are using translations on the content anyway.\n process.nextTick(() => {\n this.requestRender()\n })\n }\n\n // Setters for reactive properties\n public set padding(value: number | `${number}%` | null | undefined) {\n this.content.padding = value\n this.requestRender()\n }\n\n public set paddingX(value: number | `${number}%` | null | undefined) {\n this.content.paddingX = value\n this.requestRender()\n }\n\n public set paddingY(value: number | `${number}%` | null | undefined) {\n this.content.paddingY = value\n this.requestRender()\n }\n\n public set paddingTop(value: number | `${number}%` | null | undefined) {\n this.content.paddingTop = value\n this.requestRender()\n }\n\n public set paddingRight(value: number | `${number}%` | null | undefined) {\n this.content.paddingRight = value\n this.requestRender()\n }\n\n public set paddingBottom(value: number | `${number}%` | null | undefined) {\n this.content.paddingBottom = value\n this.requestRender()\n }\n\n public set paddingLeft(value: number | `${number}%` | null | undefined) {\n this.content.paddingLeft = value\n this.requestRender()\n }\n\n public set rootOptions(options: ScrollBoxOptions[\"rootOptions\"]) {\n Object.assign(this, options)\n this.requestRender()\n }\n\n public set wrapperOptions(options: ScrollBoxOptions[\"wrapperOptions\"]) {\n Object.assign(this.wrapper, options)\n this.requestRender()\n }\n\n public set viewportOptions(options: ScrollBoxOptions[\"viewportOptions\"]) {\n Object.assign(this.viewport, options)\n this.requestRender()\n }\n\n public set contentOptions(options: ScrollBoxOptions[\"contentOptions\"]) {\n Object.assign(this.content, options)\n this.requestRender()\n }\n\n public set scrollbarOptions(options: ScrollBoxOptions[\"scrollbarOptions\"]) {\n Object.assign(this.verticalScrollBar, options)\n Object.assign(this.horizontalScrollBar, options)\n this.requestRender()\n }\n\n public set verticalScrollbarOptions(options: ScrollBoxOptions[\"verticalScrollbarOptions\"]) {\n Object.assign(this.verticalScrollBar, options)\n this.requestRender()\n }\n\n public set horizontalScrollbarOptions(options: ScrollBoxOptions[\"horizontalScrollbarOptions\"]) {\n Object.assign(this.horizontalScrollBar, options)\n this.requestRender()\n }\n\n public get scrollAcceleration(): ScrollAcceleration {\n return this.scrollAccel\n }\n\n public set scrollAcceleration(value: ScrollAcceleration) {\n this.scrollAccel = value\n }\n\n get viewportCulling(): boolean {\n return this.content.viewportCulling\n }\n\n set viewportCulling(value: boolean) {\n this.content.viewportCulling = value\n this.requestRender()\n }\n\n protected destroySelf(): void {\n if (this.selectionListener) {\n this._ctx.off(\"selection\", this.selectionListener)\n this.selectionListener = undefined\n }\n super.destroySelf()\n }\n}\n", + "import { OptimizedBuffer } from \"../buffer.js\"\nimport { fonts, measureText, renderFontToFrameBuffer } from \"../lib/ascii.font.js\"\nimport type { KeyEvent } from \"../lib/KeyHandler.js\"\nimport { RGBA, parseColor, type ColorInput } from \"../lib/RGBA.js\"\nimport { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport type { RenderContext } from \"../types.js\"\nimport {\n type KeyBinding as BaseKeyBinding,\n mergeKeyBindings,\n buildKeyBindingsMap,\n getKeyBindingAction,\n defaultKeyAliases,\n mergeKeyAliases,\n} from \"../lib/keybinding.internal.js\"\n\ntype KeyAliasMap = Record\n\nexport interface SelectOption {\n name: string\n description: string\n value?: any\n}\n\nexport type SelectAction = \"move-up\" | \"move-down\" | \"move-up-fast\" | \"move-down-fast\" | \"select-current\"\n\nexport type SelectKeyBinding = BaseKeyBinding\n\nconst defaultSelectKeybindings: SelectKeyBinding[] = [\n { name: \"up\", action: \"move-up\" },\n { name: \"k\", action: \"move-up\" },\n { name: \"down\", action: \"move-down\" },\n { name: \"j\", action: \"move-down\" },\n { name: \"up\", shift: true, action: \"move-up-fast\" },\n { name: \"down\", shift: true, action: \"move-down-fast\" },\n { name: \"return\", action: \"select-current\" },\n { name: \"linefeed\", action: \"select-current\" },\n]\n\nexport interface SelectRenderableOptions extends RenderableOptions {\n backgroundColor?: ColorInput\n textColor?: ColorInput\n focusedBackgroundColor?: ColorInput\n focusedTextColor?: ColorInput\n options?: SelectOption[]\n selectedIndex?: number\n selectedBackgroundColor?: ColorInput\n selectedTextColor?: ColorInput\n descriptionColor?: ColorInput\n selectedDescriptionColor?: ColorInput\n showScrollIndicator?: boolean\n wrapSelection?: boolean\n showDescription?: boolean\n font?: keyof typeof fonts\n itemSpacing?: number\n fastScrollStep?: number\n keyBindings?: SelectKeyBinding[]\n keyAliasMap?: KeyAliasMap\n}\n\nexport enum SelectRenderableEvents {\n SELECTION_CHANGED = \"selectionChanged\",\n ITEM_SELECTED = \"itemSelected\",\n}\n\nexport class SelectRenderable extends Renderable {\n protected _focusable: boolean = true\n\n private _options: SelectOption[] = []\n private _selectedIndex: number = 0\n private scrollOffset: number = 0\n private maxVisibleItems: number\n\n private _backgroundColor: RGBA\n private _textColor: RGBA\n private _focusedBackgroundColor: RGBA\n private _focusedTextColor: RGBA\n private _selectedBackgroundColor: RGBA\n private _selectedTextColor: RGBA\n private _descriptionColor: RGBA\n private _selectedDescriptionColor: RGBA\n private _showScrollIndicator: boolean\n private _wrapSelection: boolean\n private _showDescription: boolean\n private _font?: keyof typeof fonts\n private _itemSpacing: number\n private linesPerItem: number\n private fontHeight: number\n private _fastScrollStep: number\n private _keyBindingsMap: Map\n private _keyAliasMap: KeyAliasMap\n private _keyBindings: SelectKeyBinding[]\n\n protected _defaultOptions = {\n backgroundColor: \"transparent\",\n textColor: \"#FFFFFF\",\n focusedBackgroundColor: \"#1a1a1a\",\n focusedTextColor: \"#FFFFFF\",\n selectedBackgroundColor: \"#334455\",\n selectedTextColor: \"#FFFF00\",\n selectedIndex: 0,\n descriptionColor: \"#888888\",\n selectedDescriptionColor: \"#CCCCCC\",\n showScrollIndicator: false,\n wrapSelection: false,\n showDescription: true,\n itemSpacing: 0,\n fastScrollStep: 5,\n } satisfies Partial\n\n constructor(ctx: RenderContext, options: SelectRenderableOptions) {\n super(ctx, { ...options, buffered: true })\n this._options = options.options || []\n const requestedIndex = options.selectedIndex ?? this._defaultOptions.selectedIndex\n this._selectedIndex = this._options.length > 0 ? Math.min(requestedIndex, this._options.length - 1) : 0\n this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor)\n this._textColor = parseColor(options.textColor || this._defaultOptions.textColor)\n this._focusedBackgroundColor = parseColor(\n options.focusedBackgroundColor || this._defaultOptions.focusedBackgroundColor,\n )\n this._focusedTextColor = parseColor(options.focusedTextColor || this._defaultOptions.focusedTextColor)\n\n this._showScrollIndicator = options.showScrollIndicator ?? this._defaultOptions.showScrollIndicator\n this._wrapSelection = options.wrapSelection ?? this._defaultOptions.wrapSelection\n this._showDescription = options.showDescription ?? this._defaultOptions.showDescription\n this._font = options.font\n this._itemSpacing = options.itemSpacing || this._defaultOptions.itemSpacing\n\n this.fontHeight = this._font ? measureText({ text: \"A\", font: this._font }).height : 1\n this.linesPerItem = this._showDescription\n ? this._font\n ? this.fontHeight + 1\n : 2\n : this._font\n ? this.fontHeight\n : 1\n this.linesPerItem += this._itemSpacing\n\n this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem))\n\n this._selectedBackgroundColor = parseColor(\n options.selectedBackgroundColor || this._defaultOptions.selectedBackgroundColor,\n )\n this._selectedTextColor = parseColor(options.selectedTextColor || this._defaultOptions.selectedTextColor)\n this._descriptionColor = parseColor(options.descriptionColor || this._defaultOptions.descriptionColor)\n this._selectedDescriptionColor = parseColor(\n options.selectedDescriptionColor || this._defaultOptions.selectedDescriptionColor,\n )\n this._fastScrollStep = options.fastScrollStep || this._defaultOptions.fastScrollStep\n\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {})\n this._keyBindings = options.keyBindings || []\n const mergedBindings = mergeKeyBindings(defaultSelectKeybindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n\n this.requestRender() // Initial render needed\n }\n\n protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void {\n if (!this.visible || !this.frameBuffer) return\n\n if (this.isDirty) {\n this.refreshFrameBuffer()\n }\n }\n\n private refreshFrameBuffer(): void {\n if (!this.frameBuffer) return\n\n const bgColor = this._focused ? this._focusedBackgroundColor : this._backgroundColor\n this.frameBuffer.clear(bgColor)\n if (this._options.length === 0) return\n\n const contentX = 0\n const contentY = 0\n const contentWidth = this.width\n const contentHeight = this.height\n\n const visibleOptions = this._options.slice(this.scrollOffset, this.scrollOffset + this.maxVisibleItems)\n\n for (let i = 0; i < visibleOptions.length; i++) {\n const actualIndex = this.scrollOffset + i\n const option = visibleOptions[i]\n const isSelected = actualIndex === this._selectedIndex\n const itemY = contentY + i * this.linesPerItem\n\n if (itemY + this.linesPerItem - 1 >= contentY + contentHeight) break\n\n if (isSelected) {\n const contentHeight = this.linesPerItem - this._itemSpacing\n this.frameBuffer.fillRect(contentX, itemY, contentWidth, contentHeight, this._selectedBackgroundColor)\n }\n\n const nameContent = `${isSelected ? \"▶ \" : \" \"}${option.name}`\n const baseTextColor = this._focused ? this._focusedTextColor : this._textColor\n const nameColor = isSelected ? this._selectedTextColor : baseTextColor\n let descX = contentX + 3\n\n if (this._font) {\n const indicator = isSelected ? \"▶ \" : \" \"\n this.frameBuffer.drawText(indicator, contentX + 1, itemY, nameColor)\n\n const indicatorWidth = 2\n renderFontToFrameBuffer(this.frameBuffer, {\n text: option.name,\n x: contentX + 1 + indicatorWidth,\n y: itemY,\n color: nameColor,\n backgroundColor: isSelected ? this._selectedBackgroundColor : bgColor,\n font: this._font,\n })\n descX = contentX + 1 + indicatorWidth\n } else {\n this.frameBuffer.drawText(nameContent, contentX + 1, itemY, nameColor)\n }\n\n if (this._showDescription && itemY + this.fontHeight < contentY + contentHeight) {\n const descColor = isSelected ? this._selectedDescriptionColor : this._descriptionColor\n this.frameBuffer.drawText(option.description, descX, itemY + this.fontHeight, descColor)\n }\n }\n\n if (this._showScrollIndicator && this._options.length > this.maxVisibleItems) {\n this.renderScrollIndicatorToFrameBuffer(contentX, contentY, contentWidth, contentHeight)\n }\n }\n\n private renderScrollIndicatorToFrameBuffer(\n contentX: number,\n contentY: number,\n contentWidth: number,\n contentHeight: number,\n ): void {\n if (!this.frameBuffer) return\n\n const scrollPercent = this._selectedIndex / Math.max(1, this._options.length - 1)\n const indicatorHeight = Math.max(1, contentHeight - 2)\n const indicatorY = contentY + 1 + Math.floor(scrollPercent * indicatorHeight)\n const indicatorX = contentX + contentWidth - 1\n\n this.frameBuffer.drawText(\"█\", indicatorX, indicatorY, parseColor(\"#666666\"))\n }\n\n public get options(): SelectOption[] {\n return this._options\n }\n\n public set options(options: SelectOption[]) {\n this._options = options\n this._selectedIndex = Math.min(this._selectedIndex, Math.max(0, options.length - 1))\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public getSelectedOption(): SelectOption | null {\n return this._options[this._selectedIndex] || null\n }\n\n public getSelectedIndex(): number {\n return this._selectedIndex\n }\n\n public moveUp(steps: number = 1): void {\n const newIndex = this._selectedIndex - steps\n\n if (newIndex >= 0) {\n this._selectedIndex = newIndex\n } else if (this._wrapSelection && this._options.length > 0) {\n this._selectedIndex = this._options.length - 1\n } else {\n this._selectedIndex = 0\n }\n\n this.updateScrollOffset()\n this.requestRender()\n this.emit(SelectRenderableEvents.SELECTION_CHANGED, this._selectedIndex, this.getSelectedOption())\n }\n\n public moveDown(steps: number = 1): void {\n const newIndex = this._selectedIndex + steps\n\n if (newIndex < this._options.length) {\n this._selectedIndex = newIndex\n } else if (this._wrapSelection && this._options.length > 0) {\n this._selectedIndex = 0\n } else {\n this._selectedIndex = this._options.length - 1\n }\n\n this.updateScrollOffset()\n this.requestRender()\n this.emit(SelectRenderableEvents.SELECTION_CHANGED, this._selectedIndex, this.getSelectedOption())\n }\n\n public selectCurrent(): void {\n const selected = this.getSelectedOption()\n if (selected) {\n this.emit(SelectRenderableEvents.ITEM_SELECTED, this._selectedIndex, selected)\n }\n }\n\n public setSelectedIndex(index: number): void {\n if (index >= 0 && index < this._options.length) {\n this._selectedIndex = index\n this.updateScrollOffset()\n this.requestRender()\n this.emit(SelectRenderableEvents.SELECTION_CHANGED, this._selectedIndex, this.getSelectedOption())\n }\n }\n\n private updateScrollOffset(): void {\n if (!this._options) return\n\n const halfVisible = Math.floor(this.maxVisibleItems / 2)\n const newScrollOffset = Math.max(\n 0,\n Math.min(this._selectedIndex - halfVisible, this._options.length - this.maxVisibleItems),\n )\n\n if (newScrollOffset !== this.scrollOffset) {\n this.scrollOffset = newScrollOffset\n this.requestRender()\n }\n }\n\n protected onResize(width: number, height: number): void {\n this.maxVisibleItems = Math.max(1, Math.floor(height / this.linesPerItem))\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public handleKeyPress(key: KeyEvent): boolean {\n const action = getKeyBindingAction(this._keyBindingsMap, key)\n\n if (action) {\n switch (action) {\n case \"move-up\":\n this.moveUp(1)\n return true\n case \"move-down\":\n this.moveDown(1)\n return true\n case \"move-up-fast\":\n this.moveUp(this._fastScrollStep)\n return true\n case \"move-down-fast\":\n this.moveDown(this._fastScrollStep)\n return true\n case \"select-current\":\n this.selectCurrent()\n return true\n }\n }\n\n return false\n }\n\n public get showScrollIndicator(): boolean {\n return this._showScrollIndicator\n }\n\n public set showScrollIndicator(show: boolean) {\n this._showScrollIndicator = show\n this.requestRender()\n }\n\n public get showDescription(): boolean {\n return this._showDescription\n }\n\n public set showDescription(show: boolean) {\n if (this._showDescription !== show) {\n this._showDescription = show\n this.linesPerItem = this._showDescription\n ? this._font\n ? this.fontHeight + 1\n : 2\n : this._font\n ? this.fontHeight\n : 1\n this.linesPerItem += this._itemSpacing\n\n this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem))\n this.updateScrollOffset()\n this.requestRender()\n }\n }\n\n public get wrapSelection(): boolean {\n return this._wrapSelection\n }\n\n public set wrapSelection(wrap: boolean) {\n this._wrapSelection = wrap\n }\n\n public set backgroundColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.backgroundColor)\n if (this._backgroundColor !== newColor) {\n this._backgroundColor = newColor\n this.requestRender()\n }\n }\n\n public set textColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.textColor)\n if (this._textColor !== newColor) {\n this._textColor = newColor\n this.requestRender()\n }\n }\n\n public set focusedBackgroundColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.focusedBackgroundColor)\n if (this._focusedBackgroundColor !== newColor) {\n this._focusedBackgroundColor = newColor\n this.requestRender()\n }\n }\n\n public set focusedTextColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.focusedTextColor)\n if (this._focusedTextColor !== newColor) {\n this._focusedTextColor = newColor\n this.requestRender()\n }\n }\n\n public set selectedBackgroundColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.selectedBackgroundColor)\n if (this._selectedBackgroundColor !== newColor) {\n this._selectedBackgroundColor = newColor\n this.requestRender()\n }\n }\n\n public set selectedTextColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.selectedTextColor)\n if (this._selectedTextColor !== newColor) {\n this._selectedTextColor = newColor\n this.requestRender()\n }\n }\n\n public set descriptionColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.descriptionColor)\n if (this._descriptionColor !== newColor) {\n this._descriptionColor = newColor\n this.requestRender()\n }\n }\n\n public set selectedDescriptionColor(value: ColorInput) {\n const newColor = parseColor(value ?? this._defaultOptions.selectedDescriptionColor)\n if (this._selectedDescriptionColor !== newColor) {\n this._selectedDescriptionColor = newColor\n this.requestRender()\n }\n }\n\n public set font(font: keyof typeof fonts) {\n this._font = font\n this.fontHeight = measureText({ text: \"A\", font: this._font }).height\n this.linesPerItem = this._showDescription\n ? this._font\n ? this.fontHeight + 1\n : 2\n : this._font\n ? this.fontHeight\n : 1\n this.linesPerItem += this._itemSpacing\n this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem))\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public set itemSpacing(spacing: number) {\n this._itemSpacing = spacing\n this.linesPerItem = this._showDescription\n ? this._font\n ? this.fontHeight + 1\n : 2\n : this._font\n ? this.fontHeight\n : 1\n this.linesPerItem += this._itemSpacing\n this.maxVisibleItems = Math.max(1, Math.floor(this.height / this.linesPerItem))\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public set fastScrollStep(step: number) {\n this._fastScrollStep = step\n }\n\n public set keyBindings(bindings: SelectKeyBinding[]) {\n this._keyBindings = bindings\n const mergedBindings = mergeKeyBindings(defaultSelectKeybindings, bindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n }\n\n public set keyAliasMap(aliases: KeyAliasMap) {\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases)\n const mergedBindings = mergeKeyBindings(defaultSelectKeybindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n }\n\n public set selectedIndex(value: number) {\n const newIndex = value ?? this._defaultOptions.selectedIndex\n const clampedIndex = this._options.length > 0 ? Math.min(Math.max(0, newIndex), this._options.length - 1) : 0\n if (this._selectedIndex !== clampedIndex) {\n this._selectedIndex = clampedIndex\n this.updateScrollOffset()\n this.requestRender()\n }\n }\n}\n", + "import { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport { OptimizedBuffer } from \"../buffer.js\"\nimport { RGBA, parseColor, type ColorInput } from \"../lib/RGBA.js\"\nimport type { KeyEvent } from \"../lib/KeyHandler.js\"\nimport type { RenderContext } from \"../types.js\"\nimport {\n type KeyBinding as BaseKeyBinding,\n mergeKeyBindings,\n buildKeyBindingsMap,\n getKeyBindingAction,\n defaultKeyAliases,\n mergeKeyAliases,\n} from \"../lib/keybinding.internal.js\"\n\ntype KeyAliasMap = Record\n\nexport interface TabSelectOption {\n name: string\n description: string\n value?: any\n}\n\nexport type TabSelectAction = \"move-left\" | \"move-right\" | \"select-current\"\n\nexport type TabSelectKeyBinding = BaseKeyBinding\n\nconst defaultTabSelectKeybindings: TabSelectKeyBinding[] = [\n { name: \"left\", action: \"move-left\" },\n { name: \"[\", action: \"move-left\" },\n { name: \"right\", action: \"move-right\" },\n { name: \"]\", action: \"move-right\" },\n { name: \"return\", action: \"select-current\" },\n { name: \"linefeed\", action: \"select-current\" },\n]\n\nexport interface TabSelectRenderableOptions extends Omit, \"height\"> {\n height?: number\n options?: TabSelectOption[]\n tabWidth?: number\n backgroundColor?: ColorInput\n textColor?: ColorInput\n focusedBackgroundColor?: ColorInput\n focusedTextColor?: ColorInput\n selectedBackgroundColor?: ColorInput\n selectedTextColor?: ColorInput\n selectedDescriptionColor?: ColorInput\n showScrollArrows?: boolean\n showDescription?: boolean\n showUnderline?: boolean\n wrapSelection?: boolean\n keyBindings?: TabSelectKeyBinding[]\n keyAliasMap?: KeyAliasMap\n}\n\nexport enum TabSelectRenderableEvents {\n SELECTION_CHANGED = \"selectionChanged\",\n ITEM_SELECTED = \"itemSelected\",\n}\n\nfunction calculateDynamicHeight(showUnderline: boolean, showDescription: boolean): number {\n let height = 1\n\n if (showUnderline) {\n height += 1\n }\n\n if (showDescription) {\n height += 1\n }\n\n return height\n}\n\nexport class TabSelectRenderable extends Renderable {\n protected _focusable: boolean = true\n\n private _options: TabSelectOption[] = []\n private selectedIndex: number = 0\n private scrollOffset: number = 0\n private _tabWidth: number\n private maxVisibleTabs: number\n\n private _backgroundColor: RGBA\n private _textColor: RGBA\n private _focusedBackgroundColor: RGBA\n private _focusedTextColor: RGBA\n private _selectedBackgroundColor: RGBA\n private _selectedTextColor: RGBA\n private _selectedDescriptionColor: RGBA\n private _showScrollArrows: boolean\n private _showDescription: boolean\n private _showUnderline: boolean\n private _wrapSelection: boolean\n private _keyBindingsMap: Map\n private _keyAliasMap: KeyAliasMap\n private _keyBindings: TabSelectKeyBinding[]\n\n constructor(ctx: RenderContext, options: TabSelectRenderableOptions) {\n const calculatedHeight = calculateDynamicHeight(options.showUnderline ?? true, options.showDescription ?? true)\n\n super(ctx, { ...options, height: calculatedHeight, buffered: true })\n\n this._backgroundColor = parseColor(options.backgroundColor || \"transparent\")\n this._textColor = parseColor(options.textColor || \"#FFFFFF\")\n this._focusedBackgroundColor = parseColor(options.focusedBackgroundColor || options.backgroundColor || \"#1a1a1a\")\n this._focusedTextColor = parseColor(options.focusedTextColor || options.textColor || \"#FFFFFF\")\n this._options = options.options || []\n this._tabWidth = options.tabWidth || 20\n this._showDescription = options.showDescription ?? true\n this._showUnderline = options.showUnderline ?? true\n this._showScrollArrows = options.showScrollArrows ?? true\n this._wrapSelection = options.wrapSelection ?? false\n\n this.maxVisibleTabs = Math.max(1, Math.floor(this.width / this._tabWidth))\n\n this._selectedBackgroundColor = parseColor(options.selectedBackgroundColor || \"#334455\")\n this._selectedTextColor = parseColor(options.selectedTextColor || \"#FFFF00\")\n this._selectedDescriptionColor = parseColor(options.selectedDescriptionColor || \"#CCCCCC\")\n\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {})\n this._keyBindings = options.keyBindings || []\n const mergedBindings = mergeKeyBindings(defaultTabSelectKeybindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n }\n\n private calculateDynamicHeight(): number {\n return calculateDynamicHeight(this._showUnderline, this._showDescription)\n }\n\n protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void {\n if (!this.visible || !this.frameBuffer) return\n\n if (this.isDirty) {\n this.refreshFrameBuffer()\n }\n }\n\n private refreshFrameBuffer(): void {\n if (!this.frameBuffer) return\n // Use focused colors if focused\n const bgColor = this._focused ? this._focusedBackgroundColor : this._backgroundColor\n this.frameBuffer.clear(bgColor)\n if (this._options.length === 0) return\n\n const contentX = 0\n const contentY = 0\n const contentWidth = this.width\n const contentHeight = this.height\n\n const visibleOptions = this._options.slice(this.scrollOffset, this.scrollOffset + this.maxVisibleTabs)\n\n // Render tab names\n for (let i = 0; i < visibleOptions.length; i++) {\n const actualIndex = this.scrollOffset + i\n const option = visibleOptions[i]\n const isSelected = actualIndex === this.selectedIndex\n const tabX = contentX + i * this._tabWidth\n\n if (tabX >= contentX + contentWidth) break\n\n const actualTabWidth = Math.min(this._tabWidth, contentWidth - i * this._tabWidth)\n\n if (isSelected) {\n this.frameBuffer.fillRect(tabX, contentY, actualTabWidth, 1, this._selectedBackgroundColor)\n }\n\n const baseTextColor = this._focused ? this._focusedTextColor : this._textColor\n const nameColor = isSelected ? this._selectedTextColor : baseTextColor\n const nameContent = this.truncateText(option.name, actualTabWidth - 2)\n this.frameBuffer.drawText(nameContent, tabX + 1, contentY, nameColor)\n\n if (isSelected && this._showUnderline && contentHeight >= 2) {\n const underlineY = contentY + 1\n const underlineBg = isSelected ? this._selectedBackgroundColor : bgColor\n this.frameBuffer.drawText(\"▬\".repeat(actualTabWidth), tabX, underlineY, nameColor, underlineBg)\n }\n }\n\n if (this._showDescription && contentHeight >= (this._showUnderline ? 3 : 2)) {\n const selectedOption = this.getSelectedOption()\n if (selectedOption) {\n const descriptionY = contentY + (this._showUnderline ? 2 : 1)\n const descColor = this._selectedDescriptionColor\n const descContent = this.truncateText(selectedOption.description, contentWidth - 2)\n this.frameBuffer.drawText(descContent, contentX + 1, descriptionY, descColor)\n }\n }\n\n if (this._showScrollArrows && this._options.length > this.maxVisibleTabs) {\n this.renderScrollArrowsToFrameBuffer(contentX, contentY, contentWidth, contentHeight)\n }\n }\n\n private truncateText(text: string, maxWidth: number): string {\n if (text.length <= maxWidth) return text\n return text.substring(0, Math.max(0, maxWidth - 1)) + \"…\"\n }\n\n private renderScrollArrowsToFrameBuffer(\n contentX: number,\n contentY: number,\n contentWidth: number,\n contentHeight: number,\n ): void {\n if (!this.frameBuffer) return\n\n const hasMoreLeft = this.scrollOffset > 0\n const hasMoreRight = this.scrollOffset + this.maxVisibleTabs < this._options.length\n\n if (hasMoreLeft) {\n this.frameBuffer.drawText(\"‹\", contentX, contentY, parseColor(\"#AAAAAA\"))\n }\n\n if (hasMoreRight) {\n this.frameBuffer.drawText(\"›\", contentX + contentWidth - 1, contentY, parseColor(\"#AAAAAA\"))\n }\n }\n\n public setOptions(options: TabSelectOption[]): void {\n this._options = options\n this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, options.length - 1))\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public getSelectedOption(): TabSelectOption | null {\n return this._options[this.selectedIndex] || null\n }\n\n public getSelectedIndex(): number {\n return this.selectedIndex\n }\n\n public moveLeft(): void {\n if (this.selectedIndex > 0) {\n this.selectedIndex--\n } else if (this._wrapSelection && this._options.length > 0) {\n this.selectedIndex = this._options.length - 1\n } else {\n return\n }\n\n this.updateScrollOffset()\n this.requestRender()\n this.emit(TabSelectRenderableEvents.SELECTION_CHANGED, this.selectedIndex, this.getSelectedOption())\n }\n\n public moveRight(): void {\n if (this.selectedIndex < this._options.length - 1) {\n this.selectedIndex++\n } else if (this._wrapSelection && this._options.length > 0) {\n this.selectedIndex = 0\n } else {\n return\n }\n\n this.updateScrollOffset()\n this.requestRender()\n this.emit(TabSelectRenderableEvents.SELECTION_CHANGED, this.selectedIndex, this.getSelectedOption())\n }\n\n public selectCurrent(): void {\n const selected = this.getSelectedOption()\n if (selected) {\n this.emit(TabSelectRenderableEvents.ITEM_SELECTED, this.selectedIndex, selected)\n }\n }\n\n public setSelectedIndex(index: number): void {\n if (index >= 0 && index < this._options.length) {\n this.selectedIndex = index\n this.updateScrollOffset()\n this.requestRender()\n this.emit(TabSelectRenderableEvents.SELECTION_CHANGED, this.selectedIndex, this.getSelectedOption())\n }\n }\n\n private updateScrollOffset(): void {\n const halfVisible = Math.floor(this.maxVisibleTabs / 2)\n const newScrollOffset = Math.max(\n 0,\n Math.min(this.selectedIndex - halfVisible, this._options.length - this.maxVisibleTabs),\n )\n\n if (newScrollOffset !== this.scrollOffset) {\n this.scrollOffset = newScrollOffset\n this.requestRender()\n }\n }\n\n protected onResize(width: number, height: number): void {\n this.maxVisibleTabs = Math.max(1, Math.floor(width / this._tabWidth))\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public setTabWidth(tabWidth: number): void {\n if (this._tabWidth === tabWidth) return\n\n this._tabWidth = tabWidth\n this.maxVisibleTabs = Math.max(1, Math.floor(this.width / this._tabWidth))\n\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public getTabWidth(): number {\n return this._tabWidth\n }\n\n public handleKeyPress(key: KeyEvent): boolean {\n const action = getKeyBindingAction(this._keyBindingsMap, key)\n\n if (action) {\n switch (action) {\n case \"move-left\":\n this.moveLeft()\n return true\n case \"move-right\":\n this.moveRight()\n return true\n case \"select-current\":\n this.selectCurrent()\n return true\n }\n }\n\n return false\n }\n\n public get options(): TabSelectOption[] {\n return this._options\n }\n\n public set options(options: TabSelectOption[]) {\n this._options = options\n this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, options.length - 1))\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public set backgroundColor(color: ColorInput) {\n this._backgroundColor = parseColor(color)\n this.requestRender()\n }\n\n public set textColor(color: ColorInput) {\n this._textColor = parseColor(color)\n this.requestRender()\n }\n\n public set focusedBackgroundColor(color: ColorInput) {\n this._focusedBackgroundColor = parseColor(color)\n this.requestRender()\n }\n\n public set focusedTextColor(color: ColorInput) {\n this._focusedTextColor = parseColor(color)\n this.requestRender()\n }\n\n public set selectedBackgroundColor(color: ColorInput) {\n this._selectedBackgroundColor = parseColor(color)\n this.requestRender()\n }\n\n public set selectedTextColor(color: ColorInput) {\n this._selectedTextColor = parseColor(color)\n this.requestRender()\n }\n\n public set selectedDescriptionColor(color: ColorInput) {\n this._selectedDescriptionColor = parseColor(color)\n this.requestRender()\n }\n\n public get showDescription(): boolean {\n return this._showDescription\n }\n\n public set showDescription(show: boolean) {\n if (this._showDescription !== show) {\n this._showDescription = show\n const newHeight = this.calculateDynamicHeight()\n this.height = newHeight\n this.requestRender()\n }\n }\n\n public get showUnderline(): boolean {\n return this._showUnderline\n }\n\n public set showUnderline(show: boolean) {\n if (this._showUnderline !== show) {\n this._showUnderline = show\n const newHeight = this.calculateDynamicHeight()\n this.height = newHeight\n this.requestRender()\n }\n }\n\n public get showScrollArrows(): boolean {\n return this._showScrollArrows\n }\n\n public set showScrollArrows(show: boolean) {\n if (this._showScrollArrows !== show) {\n this._showScrollArrows = show\n this.requestRender()\n }\n }\n\n public get wrapSelection(): boolean {\n return this._wrapSelection\n }\n\n public set wrapSelection(wrap: boolean) {\n this._wrapSelection = wrap\n }\n\n public get tabWidth(): number {\n return this._tabWidth\n }\n\n public set tabWidth(tabWidth: number) {\n if (this._tabWidth === tabWidth) return\n\n this._tabWidth = tabWidth\n this.maxVisibleTabs = Math.max(1, Math.floor(this.width / this._tabWidth))\n\n this.updateScrollOffset()\n this.requestRender()\n }\n\n public set keyBindings(bindings: TabSelectKeyBinding[]) {\n this._keyBindings = bindings\n const mergedBindings = mergeKeyBindings(defaultTabSelectKeybindings, bindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n }\n\n public set keyAliasMap(aliases: KeyAliasMap) {\n this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases)\n const mergedBindings = mergeKeyBindings(defaultTabSelectKeybindings, this._keyBindings)\n this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap)\n }\n}\n", + "import type { OptimizedBuffer } from \"../buffer.js\"\nimport { parseColor, RGBA, type ColorInput } from \"../lib/RGBA.js\"\nimport { Renderable, type RenderableOptions } from \"../Renderable.js\"\nimport type { RenderContext } from \"../types.js\"\n\nexport interface TimeToFirstDrawOptions extends RenderableOptions {\n fg?: ColorInput\n label?: string\n precision?: number\n}\n\nexport class TimeToFirstDrawRenderable extends Renderable {\n private _runtimeMs: number | null = null\n private textColor: RGBA\n private label: string\n private precision: number\n\n constructor(ctx: RenderContext, options: TimeToFirstDrawOptions = {}) {\n super(ctx, {\n width: \"100%\",\n height: 1,\n flexShrink: 0,\n alignSelf: \"center\",\n ...options,\n })\n\n this.textColor = parseColor(options.fg ?? \"#AAAAAA\")\n this.label = options.label ?? \"Time to first draw\"\n this.precision = this.normalizePrecision(options.precision ?? 2)\n }\n\n public get runtimeMs(): number | null {\n return this._runtimeMs\n }\n\n public set fg(value: ColorInput) {\n this.textColor = parseColor(value)\n this.requestRender()\n }\n\n public set color(value: ColorInput) {\n this.fg = value\n }\n\n public set textLabel(value: string) {\n if (value === this.label) {\n return\n }\n\n this.label = value\n this.requestRender()\n }\n\n public set decimals(value: number) {\n const nextPrecision = this.normalizePrecision(value)\n if (nextPrecision === this.precision) {\n return\n }\n\n this.precision = nextPrecision\n this.requestRender()\n }\n\n public reset(): void {\n this._runtimeMs = null\n this.requestRender()\n }\n\n protected override renderSelf(buffer: OptimizedBuffer): void {\n if (this._runtimeMs === null) {\n this._runtimeMs = performance.now()\n }\n\n const content = `${this.label}: ${this._runtimeMs.toFixed(this.precision)}ms`\n const maxWidth = Math.max(this.width, 1)\n const visibleContent = content.length > maxWidth ? content.slice(0, maxWidth) : content\n const centeredX = this.x + Math.max(0, Math.floor((maxWidth - visibleContent.length) / 2))\n\n buffer.drawText(visibleContent, centeredX, this.y, this.textColor)\n }\n\n private normalizePrecision(value: number): number {\n if (!Number.isFinite(value)) {\n return 2\n }\n\n return Math.max(0, Math.floor(value))\n }\n}\n" + ], + "mappings": "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", + "debugId": "0C019ED1790BA7F464756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/.patches/@opentui/core/lib/KeyHandler.d.ts b/.patches/@opentui/core/lib/KeyHandler.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/KeyHandler.d.ts @@ -0,0 +1,61 @@ +import { EventEmitter } from "events"; +import { type KeyEventType, type ParsedKey } from "./parse.keypress.js"; +import type { PasteMetadata } from "./paste.js"; +export declare class KeyEvent implements ParsedKey { + name: string; + ctrl: boolean; + meta: boolean; + shift: boolean; + option: boolean; + sequence: string; + number: boolean; + raw: string; + eventType: KeyEventType; + source: "raw" | "kitty"; + code?: string; + super?: boolean; + hyper?: boolean; + capsLock?: boolean; + numLock?: boolean; + baseCode?: number; + repeated?: boolean; + private _defaultPrevented; + private _propagationStopped; + constructor(key: ParsedKey); + get defaultPrevented(): boolean; + get propagationStopped(): boolean; + preventDefault(): void; + stopPropagation(): void; +} +export declare class PasteEvent { + type: "paste"; + bytes: Uint8Array; + metadata?: PasteMetadata; + private _defaultPrevented; + private _propagationStopped; + constructor(bytes: Uint8Array, metadata?: PasteMetadata); + get defaultPrevented(): boolean; + get propagationStopped(): boolean; + preventDefault(): void; + stopPropagation(): void; +} +export type KeyHandlerEventMap = { + keypress: [KeyEvent]; + keyrelease: [KeyEvent]; + paste: [PasteEvent]; +}; +export declare class KeyHandler extends EventEmitter { + processParsedKey(parsedKey: ParsedKey): boolean; + processPaste(bytes: Uint8Array, metadata?: PasteMetadata): void; +} +/** + * This class is used internally by the renderer to ensure global handlers + * can preventDefault before renderable handlers process events. + */ +export declare class InternalKeyHandler extends KeyHandler { + private renderableHandlers; + emit(event: K, ...args: KeyHandlerEventMap[K]): boolean; + private emitWithPriority; + onInternal(event: K, handler: (...args: KeyHandlerEventMap[K]) => void): void; + offInternal(event: K, handler: (...args: KeyHandlerEventMap[K]) => void): void; +} diff --git a/.patches/@opentui/core/lib/RGBA.d.ts b/.patches/@opentui/core/lib/RGBA.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/RGBA.d.ts @@ -0,0 +1,42 @@ +export type RGBTriplet = readonly [number, number, number]; +export type ColorIntent = "rgb" | "indexed" | "default"; +export type ColorInput = string | RGBA; +export declare const DEFAULT_FOREGROUND_RGB: RGBTriplet; +export declare const DEFAULT_BACKGROUND_RGB: RGBTriplet; +export interface NormalizedColorValue { + rgba: RGBA; +} +export declare function normalizeIndexedColorIndex(index: number): number; +export declare function ansi256IndexToRgb(index: number): RGBTriplet; +export declare class RGBA { + buffer: Uint16Array; + constructor(buffer: Uint16Array); + static fromArray(array: Uint16Array): RGBA; + static fromValues(r: number, g: number, b: number, a?: number): RGBA; + static clone(rgba: RGBA): RGBA; + static fromInts(r: number, g: number, b: number, a?: number): RGBA; + static fromHex(hex: string): RGBA; + static fromIndex(index: number, snapshot?: ColorInput): RGBA; + static defaultForeground(snapshot?: ColorInput): RGBA; + static defaultBackground(snapshot?: ColorInput): RGBA; + toInts(): [number, number, number, number]; + get r(): number; + set r(value: number); + get g(): number; + set g(value: number); + get b(): number; + set b(value: number); + get a(): number; + set a(value: number); + get meta(): number; + get intent(): ColorIntent; + get slot(): number; + map(fn: (value: number) => R): [R, R, R, R]; + toString(): string; + equals(other?: RGBA): boolean; +} +export declare function normalizeColorValue(value: ColorInput | null | undefined): NormalizedColorValue | null; +export declare function hexToRgb(hex: string): RGBA; +export declare function rgbToHex(rgb: RGBA): string; +export declare function hsvToRgb(h: number, s: number, v: number): RGBA; +export declare function parseColor(color: ColorInput): RGBA; diff --git a/.patches/@opentui/core/lib/ascii.font.d.ts b/.patches/@opentui/core/lib/ascii.font.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/ascii.font.d.ts @@ -0,0 +1,508 @@ +import { OptimizedBuffer } from "../buffer.js"; +import { type ColorInput } from "./RGBA.js"; +export type ASCIIFontName = "tiny" | "block" | "shade" | "slick" | "huge" | "grid" | "pallet"; +export declare const fonts: { + tiny: { + name: string; + version: string; + homepage: string; + colors: number; + lines: number; + buffer: string[]; + letterspace: string[]; + letterspace_size: number; + chars: { + A: string[]; + B: string[]; + C: string[]; + D: string[]; + E: string[]; + F: string[]; + G: string[]; + H: string[]; + I: string[]; + J: string[]; + K: string[]; + L: string[]; + M: string[]; + N: string[]; + O: string[]; + P: string[]; + Q: string[]; + R: string[]; + S: string[]; + T: string[]; + U: string[]; + V: string[]; + W: string[]; + X: string[]; + Y: string[]; + Z: string[]; + "0": string[]; + "1": string[]; + "2": string[]; + "3": string[]; + "4": string[]; + "5": string[]; + "6": string[]; + "7": string[]; + "8": string[]; + "9": string[]; + "!": string[]; + "?": string[]; + ".": string[]; + "+": string[]; + "-": string[]; + _: string[]; + "=": string[]; + "@": string[]; + "#": string[]; + $: string[]; + "%": string[]; + "&": string[]; + "(": string[]; + ")": string[]; + "/": string[]; + ":": string[]; + ";": string[]; + ",": string[]; + "'": string[]; + "\"": string[]; + " ": string[]; + }; + }; + block: { + name: string; + version: string; + homepage: string; + colors: number; + lines: number; + buffer: string[]; + letterspace: string[]; + letterspace_size: number; + chars: { + A: string[]; + B: string[]; + C: string[]; + D: string[]; + E: string[]; + F: string[]; + G: string[]; + H: string[]; + I: string[]; + J: string[]; + K: string[]; + L: string[]; + M: string[]; + N: string[]; + O: string[]; + P: string[]; + Q: string[]; + R: string[]; + S: string[]; + T: string[]; + U: string[]; + V: string[]; + W: string[]; + X: string[]; + Y: string[]; + Z: string[]; + "0": string[]; + "1": string[]; + "2": string[]; + "3": string[]; + "4": string[]; + "5": string[]; + "6": string[]; + "7": string[]; + "8": string[]; + "9": string[]; + "!": string[]; + "?": string[]; + ".": string[]; + "+": string[]; + "-": string[]; + _: string[]; + "=": string[]; + "@": string[]; + "#": string[]; + $: string[]; + "%": string[]; + "&": string[]; + "(": string[]; + ")": string[]; + "/": string[]; + ":": string[]; + ";": string[]; + ",": string[]; + "'": string[]; + "\"": string[]; + " ": string[]; + }; + }; + shade: { + name: string; + version: string; + homepage: string; + colors: number; + lines: number; + buffer: string[]; + letterspace: string[]; + letterspace_size: number; + chars: { + A: string[]; + B: string[]; + C: string[]; + D: string[]; + E: string[]; + F: string[]; + G: string[]; + H: string[]; + I: string[]; + J: string[]; + K: string[]; + L: string[]; + M: string[]; + N: string[]; + O: string[]; + P: string[]; + Q: string[]; + R: string[]; + S: string[]; + T: string[]; + U: string[]; + V: string[]; + W: string[]; + X: string[]; + Y: string[]; + Z: string[]; + "0": string[]; + "1": string[]; + "2": string[]; + "3": string[]; + "4": string[]; + "5": string[]; + "6": string[]; + "7": string[]; + "8": string[]; + "9": string[]; + "!": string[]; + "?": string[]; + ".": string[]; + "+": string[]; + "-": string[]; + _: string[]; + "=": string[]; + "@": string[]; + "#": string[]; + $: string[]; + "%": string[]; + "&": string[]; + "(": string[]; + ")": string[]; + "/": string[]; + ":": string[]; + ";": string[]; + ",": string[]; + "'": string[]; + "\"": string[]; + " ": string[]; + }; + }; + slick: { + name: string; + version: string; + homepage: string; + colors: number; + lines: number; + buffer: string[]; + letterspace: string[]; + letterspace_size: number; + chars: { + A: string[]; + B: string[]; + C: string[]; + D: string[]; + E: string[]; + F: string[]; + G: string[]; + H: string[]; + I: string[]; + J: string[]; + K: string[]; + L: string[]; + M: string[]; + N: string[]; + O: string[]; + P: string[]; + Q: string[]; + R: string[]; + S: string[]; + T: string[]; + U: string[]; + V: string[]; + W: string[]; + X: string[]; + Y: string[]; + Z: string[]; + "0": string[]; + "1": string[]; + "2": string[]; + "3": string[]; + "4": string[]; + "5": string[]; + "6": string[]; + "7": string[]; + "8": string[]; + "9": string[]; + "!": string[]; + "?": string[]; + ".": string[]; + "+": string[]; + "-": string[]; + _: string[]; + "=": string[]; + "@": string[]; + "#": string[]; + $: string[]; + "%": string[]; + "&": string[]; + "(": string[]; + ")": string[]; + "/": string[]; + ":": string[]; + ";": string[]; + ",": string[]; + "'": string[]; + "\"": string[]; + " ": string[]; + }; + }; + huge: { + name: string; + version: string; + homepage: string; + colors: number; + lines: number; + buffer: string[]; + letterspace: string[]; + letterspace_size: number; + chars: { + A: string[]; + B: string[]; + C: string[]; + D: string[]; + E: string[]; + F: string[]; + G: string[]; + H: string[]; + I: string[]; + J: string[]; + K: string[]; + L: string[]; + M: string[]; + N: string[]; + O: string[]; + P: string[]; + Q: string[]; + R: string[]; + S: string[]; + T: string[]; + U: string[]; + V: string[]; + W: string[]; + X: string[]; + Y: string[]; + Z: string[]; + "0": string[]; + "1": string[]; + "2": string[]; + "3": string[]; + "4": string[]; + "5": string[]; + "6": string[]; + "7": string[]; + "8": string[]; + "9": string[]; + "!": string[]; + "?": string[]; + ".": string[]; + "+": string[]; + "-": string[]; + _: string[]; + "=": string[]; + "@": string[]; + "#": string[]; + $: string[]; + "%": string[]; + "&": string[]; + "(": string[]; + ")": string[]; + "/": string[]; + ":": string[]; + ";": string[]; + ",": string[]; + "'": string[]; + "\"": string[]; + " ": string[]; + }; + }; + grid: { + name: string; + version: string; + homepage: string; + colors: number; + lines: number; + buffer: string[]; + letterspace: string[]; + letterspace_size: number; + chars: { + A: string[]; + B: string[]; + C: string[]; + D: string[]; + E: string[]; + F: string[]; + G: string[]; + H: string[]; + I: string[]; + J: string[]; + K: string[]; + L: string[]; + M: string[]; + N: string[]; + O: string[]; + P: string[]; + Q: string[]; + R: string[]; + S: string[]; + T: string[]; + U: string[]; + V: string[]; + W: string[]; + X: string[]; + Y: string[]; + Z: string[]; + "0": string[]; + "1": string[]; + "2": string[]; + "3": string[]; + "4": string[]; + "5": string[]; + "6": string[]; + "7": string[]; + "8": string[]; + "9": string[]; + "!": string[]; + "?": string[]; + ".": string[]; + "+": string[]; + "-": string[]; + _: string[]; + "=": string[]; + "@": string[]; + "#": string[]; + $: string[]; + "%": string[]; + "&": string[]; + "(": string[]; + ")": string[]; + "/": string[]; + ":": string[]; + ";": string[]; + ",": string[]; + "'": string[]; + "\"": string[]; + " ": string[]; + }; + }; + pallet: { + name: string; + version: string; + homepage: string; + colors: number; + lines: number; + buffer: string[]; + letterspace: string[]; + letterspace_size: number; + chars: { + A: string[]; + B: string[]; + C: string[]; + D: string[]; + E: string[]; + F: string[]; + G: string[]; + H: string[]; + I: string[]; + J: string[]; + K: string[]; + L: string[]; + M: string[]; + N: string[]; + O: string[]; + P: string[]; + Q: string[]; + R: string[]; + S: string[]; + T: string[]; + U: string[]; + V: string[]; + W: string[]; + X: string[]; + Y: string[]; + Z: string[]; + "0": string[]; + "1": string[]; + "2": string[]; + "3": string[]; + "4": string[]; + "5": string[]; + "6": string[]; + "7": string[]; + "8": string[]; + "9": string[]; + "!": string[]; + "?": string[]; + ".": string[]; + "+": string[]; + "-": string[]; + _: string[]; + "=": string[]; + "@": string[]; + "#": string[]; + $: string[]; + "%": string[]; + "&": string[]; + "(": string[]; + ")": string[]; + "/": string[]; + ":": string[]; + ";": string[]; + ",": string[]; + "'": string[]; + "\"": string[]; + " ": string[]; + }; + }; +}; +export declare function measureText({ text, font }: { + text: string; + font?: keyof typeof fonts; +}): { + width: number; + height: number; +}; +export declare function getCharacterPositions(text: string, font?: keyof typeof fonts): number[]; +export declare function coordinateToCharacterIndex(x: number, text: string, font?: keyof typeof fonts): number; +export declare function renderFontToFrameBuffer(buffer: OptimizedBuffer, { text, x, y, color, backgroundColor, font, }: { + text: string; + x?: number; + y?: number; + color?: ColorInput | ColorInput[]; + backgroundColor?: ColorInput; + font?: keyof typeof fonts; +}): { + width: number; + height: number; +}; diff --git a/.patches/@opentui/core/lib/border.d.ts b/.patches/@opentui/core/lib/border.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/border.d.ts @@ -0,0 +1,51 @@ +import type { ColorInput } from "./RGBA.js"; +export interface BorderCharacters { + topLeft: string; + topRight: string; + bottomLeft: string; + bottomRight: string; + horizontal: string; + vertical: string; + topT: string; + bottomT: string; + leftT: string; + rightT: string; + cross: string; +} +export type BorderStyle = "single" | "double" | "rounded" | "heavy"; +export type BorderSides = "top" | "right" | "bottom" | "left"; +export declare function isValidBorderStyle(value: unknown): value is BorderStyle; +export declare function parseBorderStyle(value: unknown, fallback?: BorderStyle): BorderStyle; +export declare const BorderChars: Record; +export interface BorderConfig { + borderStyle: BorderStyle; + border: boolean | BorderSides[]; + borderColor?: ColorInput; + customBorderChars?: BorderCharacters; +} +export interface BoxDrawOptions { + x: number; + y: number; + width: number; + height: number; + borderStyle: BorderStyle; + border: boolean | BorderSides[]; + borderColor: ColorInput; + customBorderChars?: BorderCharacters; + backgroundColor: ColorInput; + shouldFill?: boolean; + title?: string; + titleAlignment?: "left" | "center" | "right"; + bottomTitle?: string; + bottomTitleAlignment?: "left" | "center" | "right"; +} +export interface BorderSidesConfig { + top: boolean; + right: boolean; + bottom: boolean; + left: boolean; +} +export declare function getBorderFromSides(sides: BorderSidesConfig): boolean | BorderSides[]; +export declare function getBorderSides(border: boolean | BorderSides[]): BorderSidesConfig; +export declare function borderCharsToArray(chars: BorderCharacters): Uint32Array; +export declare const BorderCharArrays: Record; diff --git a/.patches/@opentui/core/lib/bunfs.d.ts b/.patches/@opentui/core/lib/bunfs.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/bunfs.d.ts @@ -0,0 +1,7 @@ +export declare function isBunfsPath(path: string): boolean; +export declare function getBunfsRootPath(): string; +/** + * Normalizes a path to the embedded root. + * Flattens directory structure to ensure file exists at root. + */ +export declare function normalizeBunfsPath(fileName: string): string; diff --git a/.patches/@opentui/core/lib/clipboard.d.ts b/.patches/@opentui/core/lib/clipboard.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/clipboard.d.ts @@ -0,0 +1,16 @@ +import type { RendererHandle, RenderLib } from "../zig.js"; +export declare enum ClipboardTarget { + Clipboard = 0, + Primary = 1, + Secondary = 2, + Query = 3 +} +export declare function encodeOsc52Payload(text: string, encoder?: TextEncoder): Uint8Array; +export declare class Clipboard { + private lib; + private rendererPtr; + constructor(lib: RenderLib, rendererPtr: RendererHandle); + copyToClipboardOSC52(text: string, target?: ClipboardTarget): boolean; + clearClipboardOSC52(target?: ClipboardTarget): boolean; + isOsc52Supported(): boolean; +} diff --git a/.patches/@opentui/core/lib/clock.d.ts b/.patches/@opentui/core/lib/clock.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/clock.d.ts @@ -0,0 +1,15 @@ +export type TimerHandle = ReturnType | number; +export interface Clock { + now(): number; + setTimeout(fn: () => void, delayMs: number): TimerHandle; + clearTimeout(handle: TimerHandle): void; + setInterval(fn: () => void, delayMs: number): TimerHandle; + clearInterval(handle: TimerHandle): void; +} +export declare class SystemClock implements Clock { + now(): number; + setTimeout(fn: () => void, delayMs: number): TimerHandle; + clearTimeout(handle: TimerHandle): void; + setInterval(fn: () => void, delayMs: number): TimerHandle; + clearInterval(handle: TimerHandle): void; +} diff --git a/.patches/@opentui/core/lib/data-paths.d.ts b/.patches/@opentui/core/lib/data-paths.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/data-paths.d.ts @@ -0,0 +1,26 @@ +import { EventEmitter } from "events"; +export interface DataPaths { + globalConfigPath: string; + globalConfigFile: string; + localConfigFile: string; + globalDataPath: string; +} +export interface DataPathsEvents { + "paths:changed": [paths: DataPaths]; +} +export declare class DataPathsManager extends EventEmitter { + private _appName; + private _globalConfigPath?; + private _globalConfigFile?; + private _localConfigFile?; + private _globalDataPath?; + constructor(); + get appName(): string; + set appName(value: string); + get globalConfigPath(): string; + get globalConfigFile(): string; + get localConfigFile(): string; + get globalDataPath(): string; + toObject(): DataPaths; +} +export declare function getDataPaths(): DataPathsManager; diff --git a/.patches/@opentui/core/lib/debounce.d.ts b/.patches/@opentui/core/lib/debounce.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/debounce.d.ts @@ -0,0 +1,42 @@ +/** + * Debounce controller that manages debounce instances for a specific scope + */ +export declare class DebounceController { + private scopeId; + constructor(scopeId: string | number); + /** + * Debounces the provided function with the given ID + * + * @param id Unique identifier within this scope + * @param ms Milliseconds to wait before executing + * @param fn Function to execute + */ + debounce(id: string | number, ms: number, fn: () => Promise): Promise; + /** + * Clear a specific debounce timer in this scope + * + * @param id The debounce ID to clear + */ + clearDebounce(id: string | number): void; + /** + * Clear all debounce timers in this scope + */ + clear(): void; +} +/** + * Creates a new debounce controller for a specific scope + * + * @param scopeId Unique identifier for this debounce scope + * @returns A DebounceController for the specified scope + */ +export declare function createDebounce(scopeId: string | number): DebounceController; +/** + * Clears all debounce timers for a specific scope + * + * @param scopeId The scope identifier + */ +export declare function clearDebounceScope(scopeId: string | number): void; +/** + * Clears all active debounce timers across all scopes + */ +export declare function clearAllDebounces(): void; diff --git a/.patches/@opentui/core/lib/detect-links.d.ts b/.patches/@opentui/core/lib/detect-links.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/detect-links.d.ts @@ -0,0 +1,6 @@ +import type { TextChunk } from "../text-buffer.js"; +import type { SimpleHighlight } from "./tree-sitter/types.js"; +export declare function detectLinks(chunks: TextChunk[], context: { + content: string; + highlights: SimpleHighlight[]; +}): TextChunk[]; diff --git a/.patches/@opentui/core/lib/env.d.ts b/.patches/@opentui/core/lib/env.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/env.d.ts @@ -0,0 +1,42 @@ +/** + * Environment variable registry + * + * Usage: + * ```ts + * import { registerEnvVar, env } from "./lib/env.ts"; + * + * // Register environment variables + * registerEnvVar({ + * name: "DEBUG", + * description: "Enable debug logging", + * type: "boolean", + * default: false + * }); + * + * registerEnvVar({ + * name: "PORT", + * description: "Server port number", + * type: "number", + * default: 3000 + * }); + * + * // Access environment variables + * if (env.DEBUG) { + * console.log("Debug mode enabled"); + * } + * + * const port = env.PORT; // number + * ``` + */ +export interface EnvVarConfig { + name: string; + description: string; + default?: string | boolean | number; + type?: "string" | "boolean" | "number"; +} +export declare const envRegistry: Record; +export declare function registerEnvVar(config: EnvVarConfig): void; +export declare function clearEnvCache(): void; +export declare function generateEnvMarkdown(): string; +export declare function generateEnvColored(): string; +export declare const env: Record; diff --git a/.patches/@opentui/core/lib/extmarks-history.d.ts b/.patches/@opentui/core/lib/extmarks-history.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/extmarks-history.d.ts @@ -0,0 +1,17 @@ +import type { Extmark } from "./extmarks.js"; +export interface ExtmarksSnapshot { + extmarks: Map; + nextId: number; +} +export declare class ExtmarksHistory { + private undoStack; + private redoStack; + saveSnapshot(extmarks: Map, nextId: number): void; + undo(): ExtmarksSnapshot | null; + redo(): ExtmarksSnapshot | null; + pushRedo(snapshot: ExtmarksSnapshot): void; + pushUndo(snapshot: ExtmarksSnapshot): void; + clear(): void; + canUndo(): boolean; + canRedo(): boolean; +} diff --git a/.patches/@opentui/core/lib/extmarks.d.ts b/.patches/@opentui/core/lib/extmarks.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/extmarks.d.ts @@ -0,0 +1,90 @@ +import type { EditBuffer } from "../edit-buffer.js"; +import type { EditorView } from "../editor-view.js"; +export interface Extmark { + id: number; + start: number; + end: number; + virtual: boolean; + styleId?: number; + priority?: number; + data?: any; + typeId: number; +} +export interface ExtmarkOptions { + start: number; + end: number; + virtual?: boolean; + styleId?: number; + priority?: number; + data?: any; + typeId?: number; + metadata?: any; +} +/** + * WARNING: This is simulating extmarks in the edit buffer + * and will move to a real native implementation in the future. + * Use with caution. + */ +export declare class ExtmarksController { + private editBuffer; + private editorView; + private extmarks; + private extmarksByTypeId; + private metadata; + private nextId; + private destroyed; + private history; + private typeNameToId; + private typeIdToName; + private nextTypeId; + private originalMoveCursorLeft; + private originalMoveCursorRight; + private originalSetCursorByOffset; + private originalMoveUpVisual; + private originalMoveDownVisual; + private originalDeleteCharBackward; + private originalDeleteChar; + private originalInsertText; + private originalInsertChar; + private originalDeleteRange; + private originalSetText; + private originalReplaceText; + private originalClear; + private originalNewLine; + private originalDeleteLine; + private originalEditorViewDeleteSelectedText; + private originalUndo; + private originalRedo; + constructor(editBuffer: EditBuffer, editorView: EditorView); + private wrapCursorMovement; + private wrapDeletion; + private wrapInsertion; + private wrapEditorViewDeleteSelectedText; + private setupContentChangeListener; + private deleteExtmarkById; + private findVirtualExtmarkContaining; + private adjustExtmarksAfterInsertion; + adjustExtmarksAfterDeletion(deleteOffset: number, length: number): void; + private offsetToPosition; + private positionToOffset; + private getNextCursorOffset; + private updateHighlights; + private offsetExcludingNewlines; + create(options: ExtmarkOptions): number; + delete(id: number): boolean; + get(id: number): Extmark | null; + getAll(): Extmark[]; + getVirtual(): Extmark[]; + getAtOffset(offset: number): Extmark[]; + getAllForTypeId(typeId: number): Extmark[]; + clear(): void; + private saveSnapshot; + private restoreSnapshot; + private wrapUndoRedo; + registerType(typeName: string): number; + getTypeId(typeName: string): number | null; + getTypeName(typeId: number): string | null; + getMetadataFor(extmarkId: number): any; + destroy(): void; +} +export declare function createExtmarksController(editBuffer: EditBuffer, editorView: EditorView): ExtmarksController; diff --git a/.patches/@opentui/core/lib/hast-styled-text.d.ts b/.patches/@opentui/core/lib/hast-styled-text.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/hast-styled-text.d.ts @@ -0,0 +1,17 @@ +import { StyledText } from "./styled-text.js"; +import { SyntaxStyle } from "../syntax-style.js"; +export interface HASTText { + type: "text"; + value: string; +} +export interface HASTElement { + type: "element"; + tagName: string; + properties?: { + className?: string; + }; + children: HASTNode[]; +} +export type HASTNode = HASTText | HASTElement; +export type { StyleDefinition } from "../syntax-style.js"; +export declare function hastToStyledText(hast: HASTNode, syntaxStyle: SyntaxStyle): StyledText; diff --git a/.patches/@opentui/core/lib/index.d.ts b/.patches/@opentui/core/lib/index.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/index.d.ts @@ -0,0 +1,21 @@ +export * from "./border.js"; +export * from "./KeyHandler.js"; +export * from "./ascii.font.js"; +export * from "./hast-styled-text.js"; +export * from "./RGBA.js"; +export * from "./clock.js"; +export * from "./parse.keypress.js"; +export * from "./scroll-acceleration.js"; +export * from "./styled-text.js"; +export * from "./yoga.options.js"; +export * from "./parse.mouse.js"; +export * from "./selection.js"; +export * from "./env.js"; +export * from "./stdin-parser.js"; +export * from "./tree-sitter-styled-text.js"; +export * from "./tree-sitter/index.js"; +export * from "./data-paths.js"; +export * from "./extmarks.js"; +export * from "./terminal-palette.js"; +export * from "./paste.js"; +export { detectLinks } from "./detect-links.js"; diff --git a/.patches/@opentui/core/lib/keybinding.internal.d.ts b/.patches/@opentui/core/lib/keybinding.internal.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/keybinding.internal.d.ts @@ -0,0 +1,33 @@ +export interface KeyBindingLike { + name: string; + ctrl?: boolean; + shift?: boolean; + meta?: boolean; + super?: boolean; +} +export interface KeyBinding extends KeyBindingLike { + action: Action; +} +export interface KeyBindingLookup extends KeyBindingLike { + baseCode?: number; +} +export type KeyAliasMap = Record; +export declare const defaultKeyAliases: KeyAliasMap; +export declare function mergeKeyAliases(defaults: KeyAliasMap, custom: KeyAliasMap): KeyAliasMap; +export declare function mergeKeyBindings(defaults: KeyBinding[], custom: KeyBinding[]): KeyBinding[]; +export declare function getKeyBindingKey(binding: KeyBindingLike): string; +export declare function getKeyBindingKeys(binding: KeyBindingLookup): string[]; +export declare function getKeyBindingAction(map: Map, binding: KeyBindingLookup): Action | undefined; +export declare function matchesKeyBinding(binding: KeyBindingLookup, match: KeyBindingLike): boolean; +export declare function buildKeyBindingsMap(bindings: KeyBinding[], aliasMap?: KeyAliasMap): Map; +/** + * Converts a key binding to a human-readable string representation + * @param binding The key binding to stringify + * @returns A string like "ctrl+shift+y" or just "escape" + * @example + * keyBindingToString({ name: "y", ctrl: true, shift: true }) // "ctrl+shift+y" + * keyBindingToString({ name: "escape" }) // "escape" + * keyBindingToString({ name: "c", ctrl: true }) // "ctrl+c" + * keyBindingToString({ name: "s", super: true }) // "super+s" + */ +export declare function keyBindingToString(binding: KeyBinding): string; diff --git a/.patches/@opentui/core/lib/objects-in-viewport.d.ts b/.patches/@opentui/core/lib/objects-in-viewport.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/objects-in-viewport.d.ts @@ -0,0 +1,24 @@ +import type { ViewportBounds } from "../types.js"; +interface ViewportObject { + screenX: number; + screenY: number; + width: number; + height: number; + zIndex: number; +} +/** + * Returns objects that overlap with the viewport bounds. + * + * @param viewport - The viewport bounds to check against + * @param objects - Array of objects MUST be sorted by screen position (screenY for column, screenX for row direction) + * @param direction - Primary scroll direction: "column" (vertical) or "row" (horizontal) + * @param padding - Extra padding around viewport to include nearby objects + * @param minTriggerSize - Minimum array size to use binary search optimization + * @returns Array of visible objects sorted by zIndex + * + * @remarks + * Objects must be pre-sorted by their start screen position (screenY for column direction, screenX for row direction). + * Unsorted input will produce incorrect results. + */ +export declare function getObjectsInViewport(viewport: ViewportBounds, objects: T[], direction?: "row" | "column", padding?: number, minTriggerSize?: number): T[]; +export {}; diff --git a/.patches/@opentui/core/lib/output.capture.d.ts b/.patches/@opentui/core/lib/output.capture.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/output.capture.d.ts @@ -0,0 +1,24 @@ +import { Writable } from "stream"; +import { EventEmitter } from "events"; +export type CapturedOutput = { + stream: "stdout" | "stderr"; + output: string; +}; +export declare class Capture extends EventEmitter { + private output; + constructor(); + get size(): number; + write(stream: "stdout" | "stderr", data: string): void; + claimOutput(): string; + private clear; +} +export declare class CapturedWritableStream extends Writable { + private stream; + private capture; + isTTY: boolean; + columns: number; + rows: number; + constructor(stream: "stdout" | "stderr", capture: Capture); + _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void; + getColorDepth(): number; +} diff --git a/.patches/@opentui/core/lib/parse.keypress-kitty.d.ts b/.patches/@opentui/core/lib/parse.keypress-kitty.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/parse.keypress-kitty.d.ts @@ -0,0 +1,3 @@ +import type { ParsedKey } from "./parse.keypress.js"; +export declare const kittyNamedSingleStrokeKeys: string[]; +export declare function parseKittyKeyboard(sequence: string): ParsedKey | null; diff --git a/.patches/@opentui/core/lib/parse.keypress.d.ts b/.patches/@opentui/core/lib/parse.keypress.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/parse.keypress.d.ts @@ -0,0 +1,27 @@ +import { Buffer } from "node:buffer"; +export declare const nonAlphanumericKeys: string[]; +export declare const terminalNamedSingleStrokeKeys: string[]; +export type KeyEventType = "press" | "repeat" | "release"; +export interface ParsedKey { + name: string; + ctrl: boolean; + meta: boolean; + shift: boolean; + option: boolean; + sequence: string; + number: boolean; + raw: string; + eventType: KeyEventType; + source: "raw" | "kitty"; + code?: string; + super?: boolean; + hyper?: boolean; + capsLock?: boolean; + numLock?: boolean; + baseCode?: number; + repeated?: boolean; +} +export type ParseKeypressOptions = { + useKittyKeyboard?: boolean; +}; +export declare const parseKeypress: (s?: Buffer | string, options?: ParseKeypressOptions) => ParsedKey | null; diff --git a/.patches/@opentui/core/lib/parse.mouse.d.ts b/.patches/@opentui/core/lib/parse.mouse.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/parse.mouse.d.ts @@ -0,0 +1,30 @@ +export type MouseEventType = "down" | "up" | "move" | "drag" | "drag-end" | "drop" | "over" | "out" | "scroll"; +export interface ScrollInfo { + direction: "up" | "down" | "left" | "right"; + delta: number; +} +export type RawMouseEvent = { + type: MouseEventType; + button: number; + x: number; + y: number; + modifiers: { + shift: boolean; + alt: boolean; + ctrl: boolean; + }; + scroll?: ScrollInfo; +}; +export declare class MouseParser { + private mouseButtonsPressed; + private static readonly SCROLL_DIRECTIONS; + reset(): void; + private decodeInput; + parseMouseEvent(data: Buffer | Uint8Array): RawMouseEvent | null; + parseAllMouseEvents(data: Buffer | Uint8Array): RawMouseEvent[]; + private parseMouseSequenceAt; + private parseSgrSequence; + private parseBasicSequence; + private decodeSgrEvent; + private decodeBasicEvent; +} diff --git a/.patches/@opentui/core/lib/paste.d.ts b/.patches/@opentui/core/lib/paste.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/paste.d.ts @@ -0,0 +1,7 @@ +export type PasteKind = "text" | "binary" | "unknown"; +export interface PasteMetadata { + mimeType?: string; + kind?: PasteKind; +} +export declare function decodePasteBytes(bytes: Uint8Array): string; +export declare function stripAnsiSequences(text: string): string; diff --git a/.patches/@opentui/core/lib/queue.d.ts b/.patches/@opentui/core/lib/queue.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/queue.d.ts @@ -0,0 +1,15 @@ +/** + * Generic processing queue that handles asynchronous job processing + */ +export declare class ProcessQueue { + private processor; + private queue; + private processing; + private autoProcess; + constructor(processor: (item: T) => Promise | void, autoProcess?: boolean); + enqueue(item: T): void; + private processQueue; + clear(): void; + isProcessing(): boolean; + size(): number; +} diff --git a/.patches/@opentui/core/lib/render-geometry.d.ts b/.patches/@opentui/core/lib/render-geometry.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/render-geometry.d.ts @@ -0,0 +1,8 @@ +export type RenderGeometryScreenMode = "alternate-screen" | "main-screen" | "split-footer"; +export interface RenderGeometry { + effectiveFooterHeight: number; + renderOffset: number; + renderWidth: number; + renderHeight: number; +} +export declare function calculateRenderGeometry(screenMode: RenderGeometryScreenMode, terminalWidth: number, terminalHeight: number, footerHeight: number): RenderGeometry; diff --git a/.patches/@opentui/core/lib/renderable.validations.d.ts b/.patches/@opentui/core/lib/renderable.validations.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/renderable.validations.d.ts @@ -0,0 +1,12 @@ +import type { RenderableOptions, Renderable } from "../Renderable.js"; +import type { PositionTypeString, OverflowString } from "./yoga.options.js"; +export declare function validateOptions(id: string, options: RenderableOptions): void; +export declare function isValidPercentage(value: any): value is `${number}%`; +export declare function isMarginType(value: any): value is number | "auto" | `${number}%`; +export declare function isPaddingType(value: any): value is number | `${number}%`; +export declare function isPositionType(value: any): value is number | "auto" | `${number}%`; +export declare function isPositionTypeType(value: any): value is PositionTypeString; +export declare function isOverflowType(value: any): value is OverflowString; +export declare function isDimensionType(value: any): value is number | "auto" | `${number}%`; +export declare function isFlexBasisType(value: any): value is number | "auto" | undefined; +export declare function isSizeType(value: any): value is number | `${number}%` | undefined; diff --git a/.patches/@opentui/core/lib/scroll-acceleration.d.ts b/.patches/@opentui/core/lib/scroll-acceleration.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/scroll-acceleration.d.ts @@ -0,0 +1,43 @@ +export interface ScrollAcceleration { + tick(now?: number): number; + reset(): void; +} +export declare class LinearScrollAccel implements ScrollAcceleration { + tick(_now?: number): number; + reset(): void; +} +/** + * macOS-inspired scroll acceleration. + * + * The class measures the time between consecutive scroll events and keeps a short + * moving window of the latest intervals. The average interval determines which + * multiplier to apply so that quick bursts accelerate and slower gestures stay precise. + * + * For intuition, treat the streak as a continuous timeline and compare it with the + * exponential distance curve from the pointer-acceleration research post: + * d(t) = v₀ * ( t + A * (exp(t/τ) - 1 - t/τ) ). + * Small t stays near the base multiplier, medium streaks settle on multiplier1, and + * sustained bursts reach multiplier2, mirroring how the exponential curve bends up. + * + * Options: + * - threshold1: upper bound (ms) of the "medium" band. Raise to delay the ramp. + * - threshold2: upper bound (ms) of the "fast" band. Lower to demand tighter bursts. + * - multiplier1: scale for medium speed streaks. + * - multiplier2: scale for sustained fast streaks. + * - baseMultiplier: scale for relaxed scrolling; set to 1 for linear behaviour. + */ +export declare class MacOSScrollAccel implements ScrollAcceleration { + private opts; + private lastTickTime; + private velocityHistory; + private readonly historySize; + private readonly streakTimeout; + private readonly minTickInterval; + constructor(opts?: { + A?: number; + tau?: number; + maxMultiplier?: number; + }); + tick(now?: number): number; + reset(): void; +} diff --git a/.patches/@opentui/core/lib/selection.d.ts b/.patches/@opentui/core/lib/selection.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/selection.d.ts @@ -0,0 +1,64 @@ +import { Renderable } from "../Renderable.js"; +import type { ViewportBounds } from "../types.js"; +import { fonts } from "./ascii.font.js"; +export declare class Selection { + private _anchor; + private _focus; + private _selectedRenderables; + private _touchedRenderables; + private _isActive; + private _isDragging; + private _isStart; + constructor(anchorRenderable: Renderable, anchor: { + x: number; + y: number; + }, focus: { + x: number; + y: number; + }); + get isStart(): boolean; + set isStart(value: boolean); + get anchor(): { + x: number; + y: number; + }; + get focus(): { + x: number; + y: number; + }; + set focus(value: { + x: number; + y: number; + }); + get isActive(): boolean; + set isActive(value: boolean); + get isDragging(): boolean; + set isDragging(value: boolean); + get bounds(): ViewportBounds; + updateSelectedRenderables(selectedRenderables: Renderable[]): void; + get selectedRenderables(): Renderable[]; + updateTouchedRenderables(touchedRenderables: Renderable[]): void; + get touchedRenderables(): Renderable[]; + getSelectedText(): string; +} +export interface LocalSelectionBounds { + anchorX: number; + anchorY: number; + focusX: number; + focusY: number; + isActive: boolean; +} +export declare function convertGlobalToLocalSelection(globalSelection: Selection | null, localX: number, localY: number): LocalSelectionBounds | null; +export declare class ASCIIFontSelectionHelper { + private getText; + private getFont; + private localSelection; + constructor(getText: () => string, getFont: () => keyof typeof fonts); + hasSelection(): boolean; + getSelection(): { + start: number; + end: number; + } | null; + shouldStartSelection(localX: number, localY: number, width: number, height: number): boolean; + onLocalSelectionChanged(localSelection: LocalSelectionBounds | null, width: number, height: number): boolean; +} diff --git a/.patches/@opentui/core/lib/singleton.d.ts b/.patches/@opentui/core/lib/singleton.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/singleton.d.ts @@ -0,0 +1,8 @@ +/** + * Ensures a value is initialized once per process, + * persists across Bun hot reloads, and is type-safe. + */ +export declare function singleton(key: string, factory: () => T): T; +export declare function getSingleton(key: string): T | undefined; +export declare function destroySingleton(key: string): void; +export declare function hasSingleton(key: string): boolean; diff --git a/.patches/@opentui/core/lib/stdin-parser.d.ts b/.patches/@opentui/core/lib/stdin-parser.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/stdin-parser.d.ts @@ -0,0 +1,90 @@ +import { type Clock } from "./clock.js"; +import { type ParsedKey } from "./parse.keypress.js"; +import { type RawMouseEvent } from "./parse.mouse.js"; +import type { PasteMetadata } from "./paste.js"; +export { SystemClock, type Clock, type TimerHandle } from "./clock.js"; +export type StdinResponseProtocol = "csi" | "cpr" | "osc" | "dcs" | "apc" | "unknown"; +export type StdinEvent = { + type: "key"; + raw: string; + key: ParsedKey; +} | { + type: "mouse"; + raw: string; + encoding: "sgr" | "x10"; + event: RawMouseEvent; +} | { + type: "paste"; + bytes: Uint8Array; + metadata?: PasteMetadata; +} | { + type: "response"; + protocol: StdinResponseProtocol; + sequence: string; +}; +export interface StdinParserProtocolContext { + kittyKeyboardEnabled: boolean; + privateCapabilityRepliesActive: boolean; + pixelResolutionQueryActive: boolean; + explicitWidthCprActive: boolean; + startupCursorCprActive: boolean; +} +export interface StdinParserOptions { + timeoutMs?: number; + maxPendingBytes?: number; + armTimeouts?: boolean; + onTimeoutFlush?: () => void; + useKittyKeyboard?: boolean; + protocolContext?: Partial; + clock?: Clock; +} +export declare class StdinParser { + private readonly pending; + private readonly events; + private readonly timeoutMs; + private readonly maxPendingBytes; + private readonly armTimeouts; + private readonly onTimeoutFlush; + private readonly useKittyKeyboard; + private readonly mouseParser; + private readonly clock; + private protocolContext; + private timeoutId; + private destroyed; + private pendingSinceMs; + private forceFlush; + private justFlushedEsc; + private state; + private cursor; + private unitStart; + private paste; + constructor(options?: StdinParserOptions); + get bufferCapacity(): number; + updateProtocolContext(patch: Partial): void; + private getAbortableStartupCursorCprState; + abortPendingStartupCursorCpr(): void; + push(data: Uint8Array): void; + read(): StdinEvent | null; + drain(onEvent: (event: StdinEvent) => void): void; + flushTimeout(nowMsValue?: number): void; + private tryForceFlush; + reset(): void; + resetMouseState(): void; + destroy(): void; + private ensureAlive; + private scanPending; + private emitKeyOrResponse; + private emitMouse; + private emitLegacyHighByte; + private emitOpaqueResponse; + private consumePrefix; + private takePendingBytes; + private flushPendingOverflow; + private markPending; + private consumePasteBytes; + private pushPasteBytes; + private reconcileDeferredStateWithProtocolContext; + private reconcileTimeoutState; + private clearTimeout; + private resetState; +} diff --git a/.patches/@opentui/core/lib/styled-text.d.ts b/.patches/@opentui/core/lib/styled-text.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/styled-text.d.ts @@ -0,0 +1,63 @@ +import type { TextChunk } from "../text-buffer.js"; +import { type ColorInput } from "./RGBA.js"; +declare const BrandedStyledText: unique symbol; +export type Color = ColorInput; +export interface StyleAttrs { + fg?: Color; + bg?: Color; + bold?: boolean; + italic?: boolean; + underline?: boolean; + strikethrough?: boolean; + dim?: boolean; + reverse?: boolean; + blink?: boolean; +} +export declare function isStyledText(obj: any): obj is StyledText; +export declare class StyledText { + [BrandedStyledText]: boolean; + chunks: TextChunk[]; + constructor(chunks: TextChunk[]); +} +export declare function stringToStyledText(content: string): StyledText; +export type StylableInput = string | number | boolean | TextChunk; +export declare const black: (input: StylableInput) => TextChunk; +export declare const red: (input: StylableInput) => TextChunk; +export declare const green: (input: StylableInput) => TextChunk; +export declare const yellow: (input: StylableInput) => TextChunk; +export declare const blue: (input: StylableInput) => TextChunk; +export declare const magenta: (input: StylableInput) => TextChunk; +export declare const cyan: (input: StylableInput) => TextChunk; +export declare const white: (input: StylableInput) => TextChunk; +export declare const brightBlack: (input: StylableInput) => TextChunk; +export declare const brightRed: (input: StylableInput) => TextChunk; +export declare const brightGreen: (input: StylableInput) => TextChunk; +export declare const brightYellow: (input: StylableInput) => TextChunk; +export declare const brightBlue: (input: StylableInput) => TextChunk; +export declare const brightMagenta: (input: StylableInput) => TextChunk; +export declare const brightCyan: (input: StylableInput) => TextChunk; +export declare const brightWhite: (input: StylableInput) => TextChunk; +export declare const bgBlack: (input: StylableInput) => TextChunk; +export declare const bgRed: (input: StylableInput) => TextChunk; +export declare const bgGreen: (input: StylableInput) => TextChunk; +export declare const bgYellow: (input: StylableInput) => TextChunk; +export declare const bgBlue: (input: StylableInput) => TextChunk; +export declare const bgMagenta: (input: StylableInput) => TextChunk; +export declare const bgCyan: (input: StylableInput) => TextChunk; +export declare const bgWhite: (input: StylableInput) => TextChunk; +export declare const bold: (input: StylableInput) => TextChunk; +export declare const italic: (input: StylableInput) => TextChunk; +export declare const underline: (input: StylableInput) => TextChunk; +export declare const strikethrough: (input: StylableInput) => TextChunk; +export declare const dim: (input: StylableInput) => TextChunk; +export declare const reverse: (input: StylableInput) => TextChunk; +export declare const blink: (input: StylableInput) => TextChunk; +export declare const fg: (color: Color) => (input: StylableInput) => TextChunk; +export declare const bg: (color: Color) => (input: StylableInput) => TextChunk; +export declare const link: (url: string) => (input: StylableInput) => TextChunk; +/** + * Template literal handler for styled text (non-cached version). + * Returns a StyledText object containing chunks of text with optional styles. + */ +export declare function t(strings: TemplateStringsArray, ...values: StylableInput[]): StyledText; +export {}; diff --git a/.patches/@opentui/core/lib/terminal-capability-detection.d.ts b/.patches/@opentui/core/lib/terminal-capability-detection.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/terminal-capability-detection.d.ts @@ -0,0 +1,32 @@ +/** + * Terminal capability response detection utilities. + * + * Detects various terminal capability response sequences: + * - DECRPM (DEC Request Mode): ESC[?...;N$y where N is 0,1,2,3,4 + * - CPR (Cursor Position Report): ESC[row;colR (used for width detection) + * - XTVersion: ESC P >| ... ESC \ + * - Kitty Graphics: ESC _ G ... ESC \ + * - Kitty Keyboard Query: ESC[?Nu where N is 0,1,2,etc + * - DA1 (Device Attributes): ESC[?...c + * - Pixel Resolution: ESC[4;height;widtht + * - OSC 99 notification capability query response + * - iTerm2 OSC 1337 feature-reporting response + */ +/** + * Check if a sequence is a terminal capability response. + * Returns true if the sequence matches any known capability response pattern. + */ +export declare function isCapabilityResponse(sequence: string): boolean; +/** + * Check if a sequence is a pixel resolution response. + * Format: ESC[4;height;widtht + */ +export declare function isPixelResolutionResponse(sequence: string): boolean; +/** + * Parse pixel resolution from response sequence. + * Returns { width, height } or null if not a valid resolution response. + */ +export declare function parsePixelResolution(sequence: string): { + width: number; + height: number; +} | null; diff --git a/.patches/@opentui/core/lib/terminal-palette.d.ts b/.patches/@opentui/core/lib/terminal-palette.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/terminal-palette.d.ts @@ -0,0 +1,65 @@ +import { RGBA } from "./RGBA.js"; +import { type Clock } from "./clock.js"; +type Hex = string | null; +export type WriteFunction = (data: string | Buffer) => boolean; +export interface TerminalColors { + palette: Hex[]; + defaultForeground: Hex; + defaultBackground: Hex; + cursorColor: Hex; + mouseForeground: Hex; + mouseBackground: Hex; + tekForeground: Hex; + tekBackground: Hex; + highlightBackground: Hex; + highlightForeground: Hex; +} +export interface GetPaletteOptions { + timeout?: number; + size?: number; +} +export interface TerminalPaletteDetector { + detect(options?: GetPaletteOptions): Promise; + detectOSCSupport(timeoutMs?: number): Promise; + cleanup(): void; +} +export interface NormalizedTerminalPalette { + palette: RGBA[]; + defaultForeground: RGBA; + defaultBackground: RGBA; +} +export type OscSubscriptionSource = { + subscribeOsc(handler: (sequence: string) => void): () => void; +}; +export interface TerminalPaletteOptions { + stdin: NodeJS.ReadStream; + stdout: NodeJS.WriteStream; + writeFn?: WriteFunction; + isLegacyTmux?: boolean; + isTmux?: boolean; + oscSource?: OscSubscriptionSource; + clock?: Clock; +} +export declare class TerminalPalette implements TerminalPaletteDetector { + private stdin; + private stdout; + private writeFn; + private activeQuerySessions; + private inLegacyTmux; + private inTmux; + private oscSource?; + private readonly clock; + constructor(options: TerminalPaletteOptions); + private writeOsc; + cleanup(): void; + private subscribeInput; + private createQuerySession; + detectOSCSupport(timeoutMs?: number): Promise; + private queryPalette; + private querySpecialColors; + detect(options?: GetPaletteOptions): Promise; +} +export declare function createTerminalPalette(options: TerminalPaletteOptions): TerminalPaletteDetector; +export declare function normalizeTerminalPalette(colors?: TerminalColors | null): NormalizedTerminalPalette; +export declare function buildTerminalPaletteSignature(colors?: TerminalColors | null): string; +export {}; diff --git a/.patches/@opentui/core/lib/tree-sitter-styled-text.d.ts b/.patches/@opentui/core/lib/tree-sitter-styled-text.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter-styled-text.d.ts @@ -0,0 +1,16 @@ +import type { TextChunk } from "../text-buffer.js"; +import { StyledText } from "./styled-text.js"; +import { SyntaxStyle } from "../syntax-style.js"; +import { TreeSitterClient } from "./tree-sitter/client.js"; +import type { SimpleHighlight } from "./tree-sitter/types.js"; +interface TextChunkOptions { + enabled?: boolean; + baseHighlight?: string; +} +export declare function treeSitterToTextChunks(content: string, highlights: SimpleHighlight[], syntaxStyle: SyntaxStyle, options?: TextChunkOptions): TextChunk[]; +export interface TreeSitterToStyledTextOptions { + conceal?: Pick; + baseHighlight?: string; +} +export declare function treeSitterToStyledText(content: string, filetype: string, syntaxStyle: SyntaxStyle, client: TreeSitterClient, options?: TreeSitterToStyledTextOptions): Promise; +export {}; diff --git a/.patches/@opentui/core/lib/tree-sitter/assets/update.d.ts b/.patches/@opentui/core/lib/tree-sitter/assets/update.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/assets/update.d.ts @@ -0,0 +1,12 @@ +#!/usr/bin/env bun +export interface UpdateOptions { + /** Path to parsers-config.json */ + configPath: string; + /** Directory where .wasm and .scm files will be downloaded */ + assetsDir: string; + /** Path where the generated TypeScript file will be written */ + outputPath: string; +} +declare function main(options?: Partial): Promise; +export declare function runUpdateAssetsCli(): Promise; +export { main as updateAssets }; diff --git a/.patches/@opentui/core/lib/tree-sitter/client.d.ts b/.patches/@opentui/core/lib/tree-sitter/client.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/client.d.ts @@ -0,0 +1,65 @@ +import { EventEmitter } from "events"; +import type { TreeSitterClientOptions, TreeSitterClientEvents, BufferState, FiletypeParserOptions, Edit, PerformanceStats, SimpleHighlight } from "./types.js"; +declare global { + const OTUI_TREE_SITTER_WORKER_PATH: string; +} +interface TreeSitterClientInternalOptions { + autoStartWorker?: boolean; +} +export declare function addDefaultParsers(parsers: FiletypeParserOptions[]): void; +export declare class TreeSitterClient extends EventEmitter { + private initialized; + private worker; + private buffers; + private initializePromise; + private initializeResolvers; + private messageCallbacks; + private messageIdCounter; + private editQueues; + private debouncer; + private options; + private destroyCallbacks; + private lifecycleGeneration; + private rejectInitialization; + private destroyPromise; + private workerTerminationFailed; + constructor(options: TreeSitterClientOptions, internalOptions?: TreeSitterClientInternalOptions); + onDestroy(callback: () => void): () => void; + private emitError; + private emitWarning; + private startWorker; + private sendWorkerMessage; + private rejectPendingRequests; + private rejectActiveInitialization; + private handleWorkerFailure; + private resolveWorkerPath; + private stopWorker; + private handleReset; + initialize(): Promise; + private assertCurrentInitialization; + private initializeClient; + private registerDefaultParsers; + private resolvePath; + addFiletypeParser(filetypeParser: FiletypeParserOptions): void; + private resolveFiletypeParser; + getPerformance(): Promise; + highlightOnce(content: string, filetype: string): Promise<{ + highlights?: SimpleHighlight[]; + warning?: string; + error?: string; + }>; + private handleWorkerMessage; + preloadParser(filetype: string): Promise; + createBuffer(id: number, content: string, filetype: string, version?: number, autoInitialize?: boolean): Promise; + updateBuffer(id: number, edits: Edit[], newContent: string, version: number): Promise; + private processEdit; + removeBuffer(bufferId: number): Promise; + destroy(): Promise; + resetBuffer(bufferId: number, version: number, content: string): Promise; + getBuffer(bufferId: number): BufferState | undefined; + getAllBuffers(): BufferState[]; + isInitialized(): boolean; + setDataPath(dataPath: string): Promise; + clearCache(): Promise; +} +export {}; diff --git a/.patches/@opentui/core/lib/tree-sitter/default-parsers.d.ts b/.patches/@opentui/core/lib/tree-sitter/default-parsers.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/default-parsers.d.ts @@ -0,0 +1,2 @@ +import type { FiletypeParserOptions } from "./types.js"; +export declare function getParsers(): Promise; diff --git a/.patches/@opentui/core/lib/tree-sitter/download-utils.d.ts b/.patches/@opentui/core/lib/tree-sitter/download-utils.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/download-utils.d.ts @@ -0,0 +1,21 @@ +export interface DownloadResult { + content?: Buffer; + filePath?: string; + error?: string; +} +export declare class DownloadUtils { + private static hashUrl; + /** + * Download a file from URL or load from local path, with caching support + */ + static downloadOrLoad(source: string, cacheDir: string, cacheSubdir: string, fileExtension: string, useHashForCache?: boolean, filetype?: string): Promise; + /** + * Download and save a file to a specific target path + */ + static downloadToPath(source: string, targetPath: string): Promise; + /** + * Fetch multiple highlight queries and concatenate them + */ + static fetchHighlightQueries(sources: string[], cacheDir: string, filetype: string): Promise; + private static fetchHighlightQuery; +} diff --git a/.patches/@opentui/core/lib/tree-sitter/index.d.ts b/.patches/@opentui/core/lib/tree-sitter/index.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/index.d.ts @@ -0,0 +1,7 @@ +import { TreeSitterClient } from "./client.js"; +export * from "./client.js"; +export * from "../tree-sitter-styled-text.js"; +export * from "./types.js"; +export * from "./resolve-ft.js"; +export declare function getTreeSitterClient(): TreeSitterClient; +export declare function destroyTreeSitterClient(): Promise; diff --git a/.patches/@opentui/core/lib/tree-sitter/parser.worker.d.ts b/.patches/@opentui/core/lib/tree-sitter/parser.worker.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/parser.worker.d.ts @@ -0,0 +1,1 @@ +export {}; diff --git a/.patches/@opentui/core/lib/tree-sitter/parsers-config.d.ts b/.patches/@opentui/core/lib/tree-sitter/parsers-config.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/parsers-config.d.ts @@ -0,0 +1,53 @@ +/** + * This file contains the configuration for the defaulttree-sitter parsers. + * It is used by ./assets/update.ts to generate the default-parsers.ts file. + * For changes here to be reflected in the default-parsers.ts file, you need to run `bun run ./assets/update.ts` + */ +declare const _default: { + parsers: ({ + filetype: string; + aliases: string[]; + wasm: string; + queries: { + highlights: string[]; + injections?: undefined; + }; + injectionMapping?: undefined; + } | { + filetype: string; + wasm: string; + queries: { + highlights: string[]; + injections: string[]; + }; + injectionMapping: { + nodeTypes: { + inline: string; + pipe_table_cell: string; + }; + infoStringMap: { + javascript: string; + js: string; + jsx: string; + javascriptreact: string; + typescript: string; + ts: string; + tsx: string; + typescriptreact: string; + markdown: string; + md: string; + }; + }; + aliases?: undefined; + } | { + filetype: string; + wasm: string; + queries: { + highlights: string[]; + injections?: undefined; + }; + aliases?: undefined; + injectionMapping?: undefined; + })[]; +}; +export default _default; diff --git a/.patches/@opentui/core/lib/tree-sitter/resolve-ft.d.ts b/.patches/@opentui/core/lib/tree-sitter/resolve-ft.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/resolve-ft.d.ts @@ -0,0 +1,5 @@ +export declare const extensionToFiletype: Map; +export declare const basenameToFiletype: Map; +export declare function extToFiletype(extension: string): string | undefined; +export declare function pathToFiletype(path: string): string | undefined; +export declare function infoStringToFiletype(infoString: string): string | undefined; diff --git a/.patches/@opentui/core/lib/tree-sitter/types.d.ts b/.patches/@opentui/core/lib/tree-sitter/types.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/types.d.ts @@ -0,0 +1,185 @@ +export interface HighlightRange { + startCol: number; + endCol: number; + group: string; +} +export interface HighlightResponse { + line: number; + highlights: HighlightRange[]; + droppedHighlights: HighlightRange[]; +} +export interface HighlightMeta { + isInjection?: boolean; + injectionLang?: string; + containsInjection?: boolean; + conceal?: string | null; + concealLines?: string | null; +} +export type SimpleHighlight = [number, number, string, HighlightMeta?]; +export interface InjectionMapping { + nodeTypes?: { + [nodeType: string]: string; + }; + infoStringMap?: { + [infoString: string]: string; + }; +} +export interface FiletypeParserOptions { + filetype: string; + aliases?: string[]; + queries: { + highlights: string[]; + injections?: string[]; + }; + wasm: string; + injectionMapping?: InjectionMapping; +} +export interface BufferState { + id: number; + version: number; + content: string; + filetype: string; + hasParser: boolean; +} +export interface ParsedBuffer extends BufferState { + hasParser: true; +} +export type TreeSitterWorkerLogType = "log" | "error" | "warn"; +export type TreeSitterWorkerRequest = { + type: "INIT"; + dataPath: string; +} | { + type: "ADD_FILETYPE_PARSER"; + filetypeParser: FiletypeParserOptions; +} | { + type: "PRELOAD_PARSER"; + filetype: string; + messageId: string; +} | { + type: "INITIALIZE_PARSER"; + bufferId: number; + version: number; + content: string; + filetype: string; + messageId: string; +} | { + type: "HANDLE_EDITS"; + bufferId: number; + version: number; + content: string; + edits: Edit[]; +} | { + type: "GET_PERFORMANCE"; + messageId: string; +} | { + type: "RESET_BUFFER"; + bufferId: number; + version: number; + content: string; + edits: Edit[]; +} | { + type: "DISPOSE_BUFFER"; + bufferId: number; +} | { + type: "ONESHOT_HIGHLIGHT"; + content: string; + filetype: string; + messageId: string; +} | { + type: "UPDATE_DATA_PATH"; + dataPath: string; + messageId: string; +} | { + type: "CLEAR_CACHE"; + messageId: string; +}; +export type TreeSitterWorkerResponse = { + type: "INIT_RESPONSE"; + error?: string; +} | { + type: "PARSER_INIT_RESPONSE"; + bufferId: number; + messageId: string; + hasParser: boolean; + warning?: string; + error?: string; +} | { + type: "HIGHLIGHT_RESPONSE"; + bufferId: number; + version: number; + highlights: HighlightResponse[]; +} | { + type: "PRELOAD_PARSER_RESPONSE"; + messageId: string; + hasParser: boolean; +} | { + type: "BUFFER_DISPOSED"; + bufferId: number; +} | { + type: "PERFORMANCE_RESPONSE"; + performance: PerformanceStats; + messageId: string; +} | { + type: "ONESHOT_HIGHLIGHT_RESPONSE"; + messageId: string; + hasParser: boolean; + highlights?: SimpleHighlight[]; + warning?: string; + error?: string; +} | { + type: "UPDATE_DATA_PATH_RESPONSE"; + messageId: string; + error?: string; +} | { + type: "CLEAR_CACHE_RESPONSE"; + messageId: string; + error?: string; +} | { + type: "WARNING"; + bufferId?: number; + warning: string; +} | { + type: "ERROR"; + bufferId?: number; + error: string; +} | { + type: "WORKER_LOG"; + logType: TreeSitterWorkerLogType; + data: unknown[]; +}; +export interface TreeSitterClientEvents { + "highlights:response": [bufferId: number, version: number, highlights: HighlightResponse[]]; + "buffer:initialized": [bufferId: number, hasParser: boolean]; + "buffer:disposed": [bufferId: number]; + "worker:log": [logType: TreeSitterWorkerLogType, message: string]; + error: [error: string, bufferId?: number]; + warning: [warning: string, bufferId?: number]; +} +export interface TreeSitterClientOptions { + dataPath: string; + workerPath?: string | URL; + initTimeout?: number; +} +export interface Edit { + startIndex: number; + oldEndIndex: number; + newEndIndex: number; + startPosition: { + row: number; + column: number; + }; + oldEndPosition: { + row: number; + column: number; + }; + newEndPosition: { + row: number; + column: number; + }; +} +export interface PerformanceStats { + averageParseTime: number; + parseTimes: number[]; + averageQueryTime: number; + queryTimes: number[]; +} diff --git a/.patches/@opentui/core/lib/tree-sitter/update-assets.d.ts b/.patches/@opentui/core/lib/tree-sitter/update-assets.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/update-assets.d.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env bun +export { runUpdateAssetsCli, updateAssets } from "./assets/update.js"; +export type { UpdateOptions } from "./assets/update.js"; diff --git a/.patches/@opentui/core/lib/tree-sitter/update-assets.js b/.patches/@opentui/core/lib/tree-sitter/update-assets.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/update-assets.js @@ -0,0 +1,379 @@ +#!/usr/bin/env bun +// @bun + +// src/lib/tree-sitter/assets/update.ts +import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises"; +import * as path2 from "path"; + +// src/lib/tree-sitter/download-utils.ts +import { mkdir, readFile, writeFile } from "fs/promises"; +import * as path from "path"; + +class DownloadUtils { + static hashUrl(url) { + let hash = 0; + for (let i = 0;i < url.length; i++) { + const char = url.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash = hash & hash; + } + return Math.abs(hash).toString(16); + } + static async downloadOrLoad(source, cacheDir, cacheSubdir, fileExtension, useHashForCache = true, filetype) { + const isUrl = source.startsWith("http://") || source.startsWith("https://"); + if (isUrl) { + let cacheFileName; + if (useHashForCache) { + const hash = this.hashUrl(source); + cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`; + } else { + cacheFileName = path.basename(source); + } + const cacheFile = path.join(cacheDir, cacheSubdir, cacheFileName); + await mkdir(path.dirname(cacheFile), { recursive: true }); + try { + const cachedContent = await readFile(cacheFile); + if (cachedContent.byteLength > 0) { + console.log(`Loaded from cache: ${cacheFile} (${source})`); + return { content: cachedContent, filePath: cacheFile }; + } + } catch (error) {} + try { + console.log(`Downloading from URL: ${source}`); + const response = await fetch(source); + if (!response.ok) { + return { error: `Failed to fetch from ${source}: ${response.statusText}` }; + } + const content = Buffer.from(await response.arrayBuffer()); + try { + await writeFile(cacheFile, Buffer.from(content)); + console.log(`Cached: ${source}`); + } catch (cacheError) { + console.warn(`Failed to cache: ${cacheError}`); + } + return { content, filePath: cacheFile }; + } catch (error) { + return { error: `Error downloading from ${source}: ${error}` }; + } + } else { + try { + console.log(`Loading from local path: ${source}`); + const content = await readFile(source); + return { content, filePath: source }; + } catch (error) { + return { error: `Error loading from local path ${source}: ${error}` }; + } + } + } + static async downloadToPath(source, targetPath) { + const isUrl = source.startsWith("http://") || source.startsWith("https://"); + await mkdir(path.dirname(targetPath), { recursive: true }); + if (isUrl) { + try { + console.log(`Downloading from URL: ${source}`); + const response = await fetch(source); + if (!response.ok) { + return { error: `Failed to fetch from ${source}: ${response.statusText}` }; + } + const content = Buffer.from(await response.arrayBuffer()); + await writeFile(targetPath, Buffer.from(content)); + console.log(`Downloaded: ${source} -> ${targetPath}`); + return { content, filePath: targetPath }; + } catch (error) { + return { error: `Error downloading from ${source}: ${error}` }; + } + } else { + try { + console.log(`Copying from local path: ${source}`); + const content = await readFile(source); + await writeFile(targetPath, Buffer.from(content)); + return { content, filePath: targetPath }; + } catch (error) { + return { error: `Error copying from local path ${source}: ${error}` }; + } + } + } + static async fetchHighlightQueries(sources, cacheDir, filetype) { + const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype)); + const queryResults = await Promise.all(queryPromises); + const validQueries = queryResults.filter((query) => query.trim().length > 0); + return validQueries.join(` +`); + } + static async fetchHighlightQuery(source, cacheDir, filetype) { + const result = await this.downloadOrLoad(source, cacheDir, "queries", ".scm", true, filetype); + if (result.error) { + console.error(`Error fetching highlight query from ${source}:`, result.error); + return ""; + } + if (result.content) { + return new TextDecoder().decode(result.content); + } + return ""; + } +} + +// src/lib/tree-sitter/assets/update.ts +import { parseArgs } from "util"; +import { readdir } from "fs/promises"; +import { fileURLToPath } from "url"; +var __filename2 = fileURLToPath(import.meta.url); +var __dirname2 = path2.dirname(__filename2); +function getDefaultOptions() { + return { + configPath: path2.resolve(__dirname2, "../parsers-config"), + assetsDir: path2.resolve(__dirname2), + outputPath: path2.resolve(__dirname2, "../default-parsers.ts") + }; +} +async function loadConfig(configPath) { + let ext = path2.extname(configPath); + let resolvedConfigPath = configPath; + if (ext === "") { + const files = await readdir(path2.dirname(configPath)); + const file = files.find((file2) => file2.startsWith(path2.basename(configPath)) && (file2.endsWith(".json") || file2.endsWith(".ts") || file2.endsWith(".js"))); + if (!file) { + throw new Error(`No config file found for ${configPath}`); + } + resolvedConfigPath = path2.join(path2.dirname(configPath), file); + ext = path2.extname(resolvedConfigPath); + } + if (ext === ".json") { + const configContent = await readFile2(resolvedConfigPath, "utf-8"); + return JSON.parse(configContent); + } else if (ext === ".ts" || ext === ".js") { + const { default: configContent } = await import(resolvedConfigPath); + return configContent; + } + throw new Error(`Unsupported config file extension: ${ext}`); +} +async function downloadLanguage(filetype, languageUrl, assetsDir, outputPath) { + const languageDir = path2.join(assetsDir, filetype); + const languageFilename = path2.basename(languageUrl); + const languagePath = path2.join(languageDir, languageFilename); + const result = await DownloadUtils.downloadToPath(languageUrl, languagePath); + if (result.error) { + throw new Error(`Failed to download language for ${filetype}: ${result.error}`); + } + return "./" + path2.relative(path2.dirname(outputPath), languagePath); +} +async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputPath, queryType, configPath) { + const queriesDir = path2.join(assetsDir, filetype); + const queryPath = path2.join(queriesDir, `${queryType}.scm`); + const queryContents = []; + for (let i = 0;i < queryUrls.length; i++) { + const queryUrl = queryUrls[i]; + if (queryUrl.startsWith("./")) { + console.log(` Using local query ${i + 1}/${queryUrls.length}: ${queryUrl}`); + try { + const localPath = path2.resolve(path2.dirname(configPath), queryUrl); + const content = await readFile2(localPath, "utf-8"); + if (content.trim()) { + queryContents.push(content); + console.log(` \u2713 Loaded ${content.split(` +`).length} lines from local file`); + } + } catch (error) { + console.warn(`Failed to read local query from ${queryUrl}: ${error}`); + continue; + } + } else { + console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`); + try { + const response = await fetch(queryUrl); + if (!response.ok) { + console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`); + continue; + } + const content = await response.text(); + if (content.trim()) { + queryContents.push(`; Query from: ${queryUrl} +${content}`); + console.log(` \u2713 Downloaded ${content.split(` +`).length} lines`); + } + } catch (error) { + console.warn(`Failed to download query from ${queryUrl}: ${error}`); + continue; + } + } + } + const combinedContent = queryContents.join(` + +`); + await writeFile2(queryPath, combinedContent, "utf-8"); + console.log(` Combined ${queryContents.length} queries into ${queryPath}`); + return "./" + path2.relative(path2.dirname(outputPath), queryPath); +} +async function generateDefaultParsersFile(parsers, outputPath) { + const assetPaths = parsers.map((parser) => { + const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_"); + const lines = [ + `const ${safeFiletype}_highlights = await resolveBundledFilePath(`, + ` () => import("${parser.highlightsPath}" as string, { with: { type: "file" } }),`, + ` "${parser.highlightsPath}",`, + ` import.meta.url,`, + `)`, + `const ${safeFiletype}_language = await resolveBundledFilePath(`, + ` () => import("${parser.languagePath}" as string, { with: { type: "file" } }),`, + ` "${parser.languagePath}",`, + ` import.meta.url,`, + `)` + ]; + if (parser.injectionsPath) { + lines.push(`const ${safeFiletype}_injections = await resolveBundledFilePath(`, ` () => import("${parser.injectionsPath}" as string, { with: { type: "file" } }),`, ` "${parser.injectionsPath}",`, ` import.meta.url,`, `)`); + } + return lines.join(` +`); + }).join(` +`); + const parserDefinitions = parsers.map((parser) => { + const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_"); + const queriesLines = [` highlights: [${safeFiletype}_highlights],`]; + if (parser.injectionsPath) { + queriesLines.push(` injections: [${safeFiletype}_injections],`); + } + const injectionMappingLine = parser.injectionMapping ? ` injectionMapping: ${JSON.stringify(parser.injectionMapping, null, 10)},` : ""; + const aliasesLine = parser.aliases?.length ? ` aliases: ${JSON.stringify(parser.aliases)},` : ""; + return ` { + filetype: "${parser.filetype}", +${aliasesLine ? aliasesLine + ` +` : ""} queries: { +${queriesLines.join(` +`)} + }, + wasm: ${safeFiletype}_language,${injectionMappingLine ? ` +` + injectionMappingLine : ""} + }`; + }).join(`, +`); + const fileContent = `// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY +// Run 'bun assets/update.ts' to regenerate this file +// Last generated: ${new Date().toISOString()} + +import type { FiletypeParserOptions } from "./types.js" +import { resolveBundledFilePath } from "../../platform/runtime.js" + +// Cached parsers to avoid re-resolving paths on every call +let _cachedParsers: Promise | undefined + +export function getParsers(): Promise { + if (!_cachedParsers) { + _cachedParsers = loadParsers() + } + return _cachedParsers +} + +async function loadParsers(): Promise { +${assetPaths} + + return [ +${parserDefinitions}, + ] +} +`; + await mkdir2(path2.dirname(outputPath), { recursive: true }); + await writeFile2(outputPath, fileContent, "utf-8"); + console.log(`Generated ${path2.basename(outputPath)} with ${parsers.length} parsers`); +} +async function main(options) { + const opts = { ...getDefaultOptions(), ...options }; + try { + console.log("Loading parsers configuration..."); + console.log(` Config: ${opts.configPath}`); + console.log(` Assets Dir: ${opts.assetsDir}`); + console.log(` Output: ${opts.outputPath}`); + const config = await loadConfig(opts.configPath); + console.log(`Found ${config.parsers.length} parsers to process`); + const generatedParsers = []; + for (const parser of config.parsers) { + console.log(`Processing ${parser.filetype}...`); + console.log(` Downloading language...`); + const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath); + console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`); + const highlightsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.highlights, opts.assetsDir, opts.outputPath, "highlights", opts.configPath); + let injectionsPath; + if (parser.queries.injections && parser.queries.injections.length > 0) { + console.log(` Downloading ${parser.queries.injections.length} injection queries...`); + injectionsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.injections, opts.assetsDir, opts.outputPath, "injections", opts.configPath); + } + generatedParsers.push({ + filetype: parser.filetype, + aliases: parser.aliases, + languagePath, + highlightsPath, + injectionsPath, + injectionMapping: parser.injectionMapping + }); + console.log(` \u2713 Completed ${parser.filetype}`); + } + console.log("Generating output file..."); + await generateDefaultParsersFile(generatedParsers, opts.outputPath); + console.log("\u2705 Update completed successfully!"); + } catch (error) { + console.error("\u274C Update failed:", error); + process.exit(1); + } +} +function parseCLIArgs() { + try { + const { values } = parseArgs({ + args: process.argv.slice(2), + options: { + config: { type: "string" }, + assets: { type: "string" }, + output: { type: "string" }, + help: { type: "boolean" } + }, + strict: true + }); + if (values.help) { + const command = path2.basename(Bun.argv[1] ?? "update-assets.js"); + console.log(`Usage: bun ${command} [options] + +Options: + --config Path to parsers-config.json + --assets Directory where .wasm and .scm files will be downloaded + --output Path where the generated TypeScript file will be written + --help Show this help message + +Examples: + # Use default paths (for OpenTUI core development) + bun ${command} + + # Use custom paths (for application integration) + bun ${command} --config ./my-parsers.json --assets ./src/parsers --output ./src/parsers.ts +`); + process.exit(0); + } + const options = {}; + if (values.config) + options.configPath = path2.resolve(values.config); + if (values.assets) + options.assetsDir = path2.resolve(values.assets); + if (values.output) + options.outputPath = path2.resolve(values.output); + return Object.keys(options).length > 0 ? options : null; + } catch (error) { + console.error(`Error parsing arguments: ${error}`); + console.log("Run with --help for usage information"); + process.exit(1); + } +} +function runUpdateAssetsCli() { + const cliOptions = parseCLIArgs(); + return main(cliOptions || undefined); +} +if (false) {} + +// src/lib/tree-sitter/update-assets.ts +if (import.meta.main) { + await runUpdateAssetsCli(); +} +export { + main as updateAssets, + runUpdateAssetsCli +}; + +//# debugId=1A2D716CBBE1018664756E2164756E21 +//# sourceMappingURL=update-assets.js.map diff --git a/.patches/@opentui/core/lib/tree-sitter/update-assets.js.map b/.patches/@opentui/core/lib/tree-sitter/update-assets.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/tree-sitter/update-assets.js.map @@ -0,0 +1,12 @@ +{ + "version": 3, + "sources": ["../../../src/lib/tree-sitter/assets/update.ts", "../../../src/lib/tree-sitter/download-utils.ts", "../../../src/lib/tree-sitter/update-assets.ts"], + "sourcesContent": [ + "#!/usr/bin/env bun\n\nimport { readFile, writeFile, mkdir } from \"fs/promises\"\nimport * as path from \"path\"\nimport { DownloadUtils } from \"../download-utils.js\"\nimport { parseArgs } from \"util\"\nimport type { FiletypeParserOptions } from \"../types.js\"\nimport { readdir } from \"fs/promises\"\nimport { fileURLToPath } from \"node:url\"\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\ninterface ParsersConfig {\n parsers: FiletypeParserOptions[]\n}\n\ninterface GeneratedParser {\n filetype: string\n aliases?: string[]\n languagePath: string\n highlightsPath: string\n injectionsPath?: string\n injectionMapping?: any\n}\n\nexport interface UpdateOptions {\n /** Path to parsers-config.json */\n configPath: string\n /** Directory where .wasm and .scm files will be downloaded */\n assetsDir: string\n /** Path where the generated TypeScript file will be written */\n outputPath: string\n}\n\nfunction getDefaultOptions(): UpdateOptions {\n return {\n configPath: path.resolve(__dirname, \"../parsers-config\"),\n assetsDir: path.resolve(__dirname),\n outputPath: path.resolve(__dirname, \"../default-parsers.ts\"),\n }\n}\n\nasync function loadConfig(configPath: string): Promise {\n let ext = path.extname(configPath)\n let resolvedConfigPath = configPath\n\n if (ext === \"\") {\n const files = await readdir(path.dirname(configPath))\n const file = files.find(\n (file) =>\n file.startsWith(path.basename(configPath)) &&\n (file.endsWith(\".json\") || file.endsWith(\".ts\") || file.endsWith(\".js\")),\n )\n if (!file) {\n throw new Error(`No config file found for ${configPath}`)\n }\n resolvedConfigPath = path.join(path.dirname(configPath), file)\n ext = path.extname(resolvedConfigPath)\n }\n\n if (ext === \".json\") {\n const configContent = await readFile(resolvedConfigPath, \"utf-8\")\n return JSON.parse(configContent)\n } else if (ext === \".ts\" || ext === \".js\") {\n const { default: configContent } = await import(resolvedConfigPath)\n return configContent\n }\n throw new Error(`Unsupported config file extension: ${ext}`)\n}\n\nasync function downloadLanguage(\n filetype: string,\n languageUrl: string,\n assetsDir: string,\n outputPath: string,\n): Promise {\n const languageDir = path.join(assetsDir, filetype)\n const languageFilename = path.basename(languageUrl)\n const languagePath = path.join(languageDir, languageFilename)\n\n const result = await DownloadUtils.downloadToPath(languageUrl, languagePath)\n\n if (result.error) {\n throw new Error(`Failed to download language for ${filetype}: ${result.error}`)\n }\n\n return \"./\" + path.relative(path.dirname(outputPath), languagePath)\n}\n\nasync function downloadAndCombineQueries(\n filetype: string,\n queryUrls: string[],\n assetsDir: string,\n outputPath: string,\n queryType: \"highlights\" | \"injections\",\n configPath: string,\n): Promise {\n const queriesDir = path.join(assetsDir, filetype)\n const queryPath = path.join(queriesDir, `${queryType}.scm`)\n\n const queryContents: string[] = []\n\n for (let i = 0; i < queryUrls.length; i++) {\n const queryUrl = queryUrls[i]\n\n if (queryUrl.startsWith(\"./\")) {\n console.log(` Using local query ${i + 1}/${queryUrls.length}: ${queryUrl}`)\n\n try {\n const localPath = path.resolve(path.dirname(configPath), queryUrl)\n const content = await readFile(localPath, \"utf-8\")\n\n if (content.trim()) {\n queryContents.push(content)\n console.log(` ✓ Loaded ${content.split(\"\\n\").length} lines from local file`)\n }\n } catch (error) {\n console.warn(`Failed to read local query from ${queryUrl}: ${error}`)\n continue\n }\n } else {\n console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`)\n\n try {\n const response = await fetch(queryUrl)\n if (!response.ok) {\n console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`)\n continue\n }\n\n const content = await response.text()\n if (content.trim()) {\n queryContents.push(`; Query from: ${queryUrl}\\n${content}`)\n console.log(` ✓ Downloaded ${content.split(\"\\n\").length} lines`)\n }\n } catch (error) {\n console.warn(`Failed to download query from ${queryUrl}: ${error}`)\n continue\n }\n }\n }\n\n const combinedContent = queryContents.join(\"\\n\\n\")\n await writeFile(queryPath, combinedContent, \"utf-8\")\n\n console.log(` Combined ${queryContents.length} queries into ${queryPath}`)\n\n return \"./\" + path.relative(path.dirname(outputPath), queryPath)\n}\n\nasync function generateDefaultParsersFile(parsers: GeneratedParser[], outputPath: string): Promise {\n const assetPaths = parsers\n .map((parser) => {\n const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, \"_\")\n const lines = [\n `const ${safeFiletype}_highlights = await resolveBundledFilePath(`,\n ` () => import(\"${parser.highlightsPath}\" as string, { with: { type: \"file\" } }),`,\n ` \"${parser.highlightsPath}\",`,\n ` import.meta.url,`,\n `)`,\n `const ${safeFiletype}_language = await resolveBundledFilePath(`,\n ` () => import(\"${parser.languagePath}\" as string, { with: { type: \"file\" } }),`,\n ` \"${parser.languagePath}\",`,\n ` import.meta.url,`,\n `)`,\n ]\n\n if (parser.injectionsPath) {\n lines.push(\n `const ${safeFiletype}_injections = await resolveBundledFilePath(`,\n ` () => import(\"${parser.injectionsPath}\" as string, { with: { type: \"file\" } }),`,\n ` \"${parser.injectionsPath}\",`,\n ` import.meta.url,`,\n `)`,\n )\n }\n\n return lines.join(\"\\n\")\n })\n .join(\"\\n\")\n\n const parserDefinitions = parsers\n .map((parser) => {\n const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, \"_\")\n const queriesLines = [` highlights: [${safeFiletype}_highlights],`]\n\n if (parser.injectionsPath) {\n queriesLines.push(` injections: [${safeFiletype}_injections],`)\n }\n\n const injectionMappingLine = parser.injectionMapping\n ? ` injectionMapping: ${JSON.stringify(parser.injectionMapping, null, 10)},`\n : \"\"\n const aliasesLine = parser.aliases?.length ? ` aliases: ${JSON.stringify(parser.aliases)},` : \"\"\n\n return ` {\n filetype: \"${parser.filetype}\",\n${aliasesLine ? aliasesLine + \"\\n\" : \"\"} queries: {\n${queriesLines.join(\"\\n\")}\n },\n wasm: ${safeFiletype}_language,${injectionMappingLine ? \"\\n\" + injectionMappingLine : \"\"}\n }`\n })\n .join(\",\\n\")\n\n const fileContent = `// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY\n// Run 'bun assets/update.ts' to regenerate this file\n// Last generated: ${new Date().toISOString()}\n\nimport type { FiletypeParserOptions } from \"./types.js\"\nimport { resolveBundledFilePath } from \"../../platform/runtime.js\"\n\n// Cached parsers to avoid re-resolving paths on every call\nlet _cachedParsers: Promise | undefined\n\nexport function getParsers(): Promise {\n if (!_cachedParsers) {\n _cachedParsers = loadParsers()\n }\n return _cachedParsers\n}\n\nasync function loadParsers(): Promise {\n${assetPaths}\n\n return [\n${parserDefinitions},\n ]\n}\n`\n\n await mkdir(path.dirname(outputPath), { recursive: true })\n await writeFile(outputPath, fileContent, \"utf-8\")\n console.log(`Generated ${path.basename(outputPath)} with ${parsers.length} parsers`)\n}\n\nasync function main(options?: Partial): Promise {\n const opts = { ...getDefaultOptions(), ...options }\n\n try {\n console.log(\"Loading parsers configuration...\")\n console.log(` Config: ${opts.configPath}`)\n console.log(` Assets Dir: ${opts.assetsDir}`)\n console.log(` Output: ${opts.outputPath}`)\n\n const config = await loadConfig(opts.configPath)\n\n console.log(`Found ${config.parsers.length} parsers to process`)\n\n const generatedParsers: GeneratedParser[] = []\n\n for (const parser of config.parsers) {\n console.log(`Processing ${parser.filetype}...`)\n\n console.log(` Downloading language...`)\n const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath)\n\n console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`)\n const highlightsPath = await downloadAndCombineQueries(\n parser.filetype,\n parser.queries.highlights,\n opts.assetsDir,\n opts.outputPath,\n \"highlights\",\n opts.configPath,\n )\n\n let injectionsPath: string | undefined\n if (parser.queries.injections && parser.queries.injections.length > 0) {\n console.log(` Downloading ${parser.queries.injections.length} injection queries...`)\n injectionsPath = await downloadAndCombineQueries(\n parser.filetype,\n parser.queries.injections,\n opts.assetsDir,\n opts.outputPath,\n \"injections\",\n opts.configPath,\n )\n }\n\n generatedParsers.push({\n filetype: parser.filetype,\n aliases: parser.aliases,\n languagePath,\n highlightsPath,\n injectionsPath,\n injectionMapping: parser.injectionMapping,\n })\n\n console.log(` ✓ Completed ${parser.filetype}`)\n }\n\n console.log(\"Generating output file...\")\n await generateDefaultParsersFile(generatedParsers, opts.outputPath)\n\n console.log(\"✅ Update completed successfully!\")\n } catch (error) {\n console.error(\"❌ Update failed:\", error)\n process.exit(1)\n }\n}\n\nfunction parseCLIArgs(): Partial | null {\n try {\n const { values } = parseArgs({\n args: process.argv.slice(2),\n options: {\n config: { type: \"string\" },\n assets: { type: \"string\" },\n output: { type: \"string\" },\n help: { type: \"boolean\" },\n },\n strict: true,\n })\n\n if (values.help) {\n const command = path.basename(Bun.argv[1] ?? \"update-assets.js\")\n\n console.log(`Usage: bun ${command} [options]\n\nOptions:\n --config Path to parsers-config.json\n --assets Directory where .wasm and .scm files will be downloaded\n --output Path where the generated TypeScript file will be written\n --help Show this help message\n\nExamples:\n # Use default paths (for OpenTUI core development)\n bun ${command}\n\n # Use custom paths (for application integration)\n bun ${command} --config ./my-parsers.json --assets ./src/parsers --output ./src/parsers.ts\n`)\n process.exit(0)\n }\n\n const options: Partial = {}\n if (values.config) options.configPath = path.resolve(values.config)\n if (values.assets) options.assetsDir = path.resolve(values.assets)\n if (values.output) options.outputPath = path.resolve(values.output)\n\n return Object.keys(options).length > 0 ? options : null\n } catch (error) {\n console.error(`Error parsing arguments: ${error}`)\n console.log(\"Run with --help for usage information\")\n process.exit(1)\n }\n}\n\nexport function runUpdateAssetsCli(): Promise {\n const cliOptions = parseCLIArgs()\n return main(cliOptions || undefined)\n}\n\nif (import.meta.main) {\n await runUpdateAssetsCli()\n}\n\nexport { main as updateAssets }\n", + "import { mkdir, readFile, writeFile } from \"fs/promises\"\nimport * as path from \"path\"\n\nexport interface DownloadResult {\n content?: Buffer\n filePath?: string\n error?: string\n}\n\nexport class DownloadUtils {\n private static hashUrl(url: string): string {\n let hash = 0\n for (let i = 0; i < url.length; i++) {\n const char = url.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash\n }\n return Math.abs(hash).toString(16)\n }\n\n /**\n * Download a file from URL or load from local path, with caching support\n */\n static async downloadOrLoad(\n source: string,\n cacheDir: string,\n cacheSubdir: string,\n fileExtension: string,\n useHashForCache: boolean = true,\n filetype?: string,\n ): Promise {\n const isUrl = source.startsWith(\"http://\") || source.startsWith(\"https://\")\n\n if (isUrl) {\n let cacheFileName: string\n if (useHashForCache) {\n const hash = this.hashUrl(source)\n cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`\n } else {\n cacheFileName = path.basename(source)\n }\n const cacheFile = path.join(cacheDir, cacheSubdir, cacheFileName)\n\n // Ensure cache directory exists\n await mkdir(path.dirname(cacheFile), { recursive: true })\n\n try {\n const cachedContent = await readFile(cacheFile)\n if (cachedContent.byteLength > 0) {\n console.log(`Loaded from cache: ${cacheFile} (${source})`)\n return { content: cachedContent, filePath: cacheFile }\n }\n } catch (error) {\n // Cache miss, continue to fetch\n }\n\n try {\n console.log(`Downloading from URL: ${source}`)\n const response = await fetch(source)\n if (!response.ok) {\n return { error: `Failed to fetch from ${source}: ${response.statusText}` }\n }\n const content = Buffer.from(await response.arrayBuffer())\n\n try {\n await writeFile(cacheFile, Buffer.from(content))\n console.log(`Cached: ${source}`)\n } catch (cacheError) {\n console.warn(`Failed to cache: ${cacheError}`)\n }\n\n return { content, filePath: cacheFile }\n } catch (error) {\n return { error: `Error downloading from ${source}: ${error}` }\n }\n } else {\n try {\n console.log(`Loading from local path: ${source}`)\n const content = await readFile(source)\n return { content, filePath: source }\n } catch (error) {\n return { error: `Error loading from local path ${source}: ${error}` }\n }\n }\n }\n\n /**\n * Download and save a file to a specific target path\n */\n static async downloadToPath(source: string, targetPath: string): Promise {\n const isUrl = source.startsWith(\"http://\") || source.startsWith(\"https://\")\n\n await mkdir(path.dirname(targetPath), { recursive: true })\n\n if (isUrl) {\n try {\n console.log(`Downloading from URL: ${source}`)\n const response = await fetch(source)\n if (!response.ok) {\n return { error: `Failed to fetch from ${source}: ${response.statusText}` }\n }\n const content = Buffer.from(await response.arrayBuffer())\n\n await writeFile(targetPath, Buffer.from(content))\n console.log(`Downloaded: ${source} -> ${targetPath}`)\n\n return { content, filePath: targetPath }\n } catch (error) {\n return { error: `Error downloading from ${source}: ${error}` }\n }\n } else {\n try {\n console.log(`Copying from local path: ${source}`)\n const content = await readFile(source)\n await writeFile(targetPath, Buffer.from(content))\n return { content, filePath: targetPath }\n } catch (error) {\n return { error: `Error copying from local path ${source}: ${error}` }\n }\n }\n }\n\n /**\n * Fetch multiple highlight queries and concatenate them\n */\n static async fetchHighlightQueries(sources: string[], cacheDir: string, filetype: string): Promise {\n const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype))\n const queryResults = await Promise.all(queryPromises)\n\n const validQueries = queryResults.filter((query) => query.trim().length > 0)\n return validQueries.join(\"\\n\")\n }\n\n private static async fetchHighlightQuery(source: string, cacheDir: string, filetype: string): Promise {\n const result = await this.downloadOrLoad(source, cacheDir, \"queries\", \".scm\", true, filetype)\n\n if (result.error) {\n console.error(`Error fetching highlight query from ${source}:`, result.error)\n return \"\"\n }\n\n if (result.content) {\n return new TextDecoder().decode(result.content)\n }\n\n return \"\"\n }\n}\n", + "#!/usr/bin/env bun\n\nimport { runUpdateAssetsCli } from \"./assets/update.js\"\n\nexport { runUpdateAssetsCli, updateAssets } from \"./assets/update.js\"\nexport type { UpdateOptions } from \"./assets/update.js\"\n\nif (import.meta.main) {\n await runUpdateAssetsCli()\n}\n" + ], + "mappings": "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", + "debugId": "1A2D716CBBE1018664756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/.patches/@opentui/core/lib/validate-dir-name.d.ts b/.patches/@opentui/core/lib/validate-dir-name.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/validate-dir-name.d.ts @@ -0,0 +1,1 @@ +export declare function isValidDirectoryName(name: string): boolean; diff --git a/.patches/@opentui/core/lib/yoga.options.d.ts b/.patches/@opentui/core/lib/yoga.options.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/lib/yoga.options.d.ts @@ -0,0 +1,32 @@ +import { BoxSizing, Align, Dimension, Direction, Display, Edge, FlexDirection, Gutter, Justify, LogLevel, MeasureMode, Overflow, PositionType, Unit, Wrap } from "../yoga.js"; +export type AlignString = "auto" | "flex-start" | "center" | "flex-end" | "stretch" | "baseline" | "space-between" | "space-around" | "space-evenly"; +export type BoxSizingString = "border-box" | "content-box"; +export type DimensionString = "width" | "height"; +export type DirectionString = "inherit" | "ltr" | "rtl"; +export type DisplayString = "flex" | "none" | "contents"; +export type EdgeString = "left" | "top" | "right" | "bottom" | "start" | "end" | "horizontal" | "vertical" | "all"; +export type FlexDirectionString = "column" | "column-reverse" | "row" | "row-reverse"; +export type GutterString = "column" | "row" | "all"; +export type JustifyString = "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | "space-evenly"; +export type LogLevelString = "error" | "warn" | "info" | "debug" | "verbose" | "fatal"; +export type MeasureModeString = "undefined" | "exactly" | "at-most"; +export type OverflowString = "visible" | "hidden" | "scroll"; +export type PositionTypeString = "static" | "relative" | "absolute"; +export type UnitString = "undefined" | "point" | "percent" | "auto"; +export type WrapString = "no-wrap" | "wrap" | "wrap-reverse"; +export declare function parseAlign(value: string | null | undefined): Align; +export declare function parseAlignItems(value: string | null | undefined): Align; +export declare function parseBoxSizing(value: string): BoxSizing; +export declare function parseDimension(value: string): Dimension; +export declare function parseDirection(value: string): Direction; +export declare function parseDisplay(value: string): Display; +export declare function parseEdge(value: string): Edge; +export declare function parseFlexDirection(value: string | null | undefined): FlexDirection; +export declare function parseGutter(value: string): Gutter; +export declare function parseJustify(value: string | null | undefined): Justify; +export declare function parseLogLevel(value: string): LogLevel; +export declare function parseMeasureMode(value: string): MeasureMode; +export declare function parseOverflow(value: string | null | undefined): Overflow; +export declare function parsePositionType(value: string | null | undefined): PositionType; +export declare function parseUnit(value: string): Unit; +export declare function parseWrap(value: string | null | undefined): Wrap; diff --git a/.patches/@opentui/core/native-event-worker-repro.worker.d.ts b/.patches/@opentui/core/native-event-worker-repro.worker.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/native-event-worker-repro.worker.d.ts @@ -0,0 +1,1 @@ +export {}; diff --git a/.patches/@opentui/core/package.json b/.patches/@opentui/core/package.json new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/package.json @@ -0,0 +1,77 @@ +{ + "name": "@opentui/core", + "module": "index.js", + "main": "index.js", + "types": "index.d.ts", + "type": "module", + "version": "0.4.1", + "description": "OpenTUI is a TypeScript library on a native Zig core for building terminal user interfaces (TUIs)", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/anomalyco/opentui", + "directory": "packages/core" + }, + "exports": { + ".": { + "import": "./index.js", + "types": "./index.d.ts" + }, + "./testing": { + "import": "./testing.js", + "types": "./testing.d.ts" + }, + "./runtime-plugin": { + "types": "./runtime-plugin.d.ts", + "bun": "./runtime-plugin.js", + "node": "./runtime-plugin.node.js", + "default": "./runtime-plugin.node.js" + }, + "./runtime-plugin-support": { + "types": "./runtime-plugin-support.d.ts", + "bun": "./runtime-plugin-support.js", + "node": "./runtime-plugin-support.node.js", + "default": "./runtime-plugin-support.node.js" + }, + "./runtime-plugin-support/configure": { + "types": "./runtime-plugin-support-configure.d.ts", + "bun": "./runtime-plugin-support-configure.js", + "node": "./runtime-plugin-support-configure.node.js", + "default": "./runtime-plugin-support-configure.node.js" + }, + "./yoga": { + "types": "./yoga.d.ts", + "import": "./yoga.js" + }, + "./tree-sitter/update-assets": { + "types": "./lib/tree-sitter/update-assets.d.ts", + "bun": "./lib/tree-sitter/update-assets.js", + "import": "./lib/tree-sitter/update-assets.js" + }, + "./parser.worker": { + "import": "./parser.worker.js", + "require": "./parser.worker.js", + "types": "./lib/tree-sitter/parser.worker.d.ts" + } + }, + "dependencies": { + "bun-ffi-structs": "0.2.3", + "diff": "9.0.0", + "marked": "17.0.1", + "string-width": "7.2.0", + "strip-ansi": "7.1.2" + }, + "peerDependencies": { + "web-tree-sitter": "0.25.10" + }, + "optionalDependencies": { + "@opentui/core-darwin-x64": "0.4.1", + "@opentui/core-darwin-arm64": "0.4.1", + "@opentui/core-linux-x64": "0.4.1", + "@opentui/core-linux-arm64": "0.4.1", + "@opentui/core-win32-x64": "0.4.1", + "@opentui/core-win32-arm64": "0.4.1", + "@opentui/core-linux-x64-musl": "0.4.1", + "@opentui/core-linux-arm64-musl": "0.4.1" + } +} \ No newline at end of file diff --git a/.patches/@opentui/core/parser.worker.js b/.patches/@opentui/core/parser.worker.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/parser.worker.js @@ -0,0 +1,1399 @@ +import { createRequire } from "node:module"; +var __create = Object.create; +var __getProtoOf = Object.getPrototypeOf; +var __defProp = Object.defineProperty; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +function __accessProp(key) { + return this[key]; +} +var __toESMCache_node; +var __toESMCache_esm; +var __toESM = (mod, isNodeMode, target) => { + var canCache = mod != null && typeof mod === "object"; + if (canCache) { + var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap; + var cached = cache.get(mod); + if (cached) + return cached; + } + target = mod != null ? __create(__getProtoOf(mod)) : {}; + const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target; + for (let key of __getOwnPropNames(mod)) + if (!__hasOwnProp.call(to, key)) + __defProp(to, key, { + get: __accessProp.bind(mod, key), + enumerable: true + }); + if (canCache) + cache.set(mod, to); + return to; +}; +var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); +var __require = /* @__PURE__ */ createRequire(import.meta.url); + +// ../../node_modules/.bun/emoji-regex@10.6.0/node_modules/emoji-regex/index.js +var require_emoji_regex = __commonJS((exports, module) => { + module.exports = () => { + return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g; + }; +}); + +// src/lib/tree-sitter/parser.worker.ts +import { Parser, Query, Language } from "web-tree-sitter"; +import { mkdir as mkdir3 } from "fs/promises"; +import * as path2 from "path"; + +// src/lib/tree-sitter/download-utils.ts +import { mkdir, readFile, writeFile } from "fs/promises"; +import * as path from "path"; + +class DownloadUtils { + static hashUrl(url) { + let hash = 0; + for (let i = 0;i < url.length; i++) { + const char = url.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash = hash & hash; + } + return Math.abs(hash).toString(16); + } + static async downloadOrLoad(source, cacheDir, cacheSubdir, fileExtension, useHashForCache = true, filetype) { + const isUrl = source.startsWith("http://") || source.startsWith("https://"); + if (isUrl) { + let cacheFileName; + if (useHashForCache) { + const hash = this.hashUrl(source); + cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`; + } else { + cacheFileName = path.basename(source); + } + const cacheFile = path.join(cacheDir, cacheSubdir, cacheFileName); + await mkdir(path.dirname(cacheFile), { recursive: true }); + try { + const cachedContent = await readFile(cacheFile); + if (cachedContent.byteLength > 0) { + console.log(`Loaded from cache: ${cacheFile} (${source})`); + return { content: cachedContent, filePath: cacheFile }; + } + } catch (error) {} + try { + console.log(`Downloading from URL: ${source}`); + const response = await fetch(source); + if (!response.ok) { + return { error: `Failed to fetch from ${source}: ${response.statusText}` }; + } + const content = Buffer.from(await response.arrayBuffer()); + try { + await writeFile(cacheFile, Buffer.from(content)); + console.log(`Cached: ${source}`); + } catch (cacheError) { + console.warn(`Failed to cache: ${cacheError}`); + } + return { content, filePath: cacheFile }; + } catch (error) { + return { error: `Error downloading from ${source}: ${error}` }; + } + } else { + try { + console.log(`Loading from local path: ${source}`); + const content = await readFile(source); + return { content, filePath: source }; + } catch (error) { + return { error: `Error loading from local path ${source}: ${error}` }; + } + } + } + static async downloadToPath(source, targetPath) { + const isUrl = source.startsWith("http://") || source.startsWith("https://"); + await mkdir(path.dirname(targetPath), { recursive: true }); + if (isUrl) { + try { + console.log(`Downloading from URL: ${source}`); + const response = await fetch(source); + if (!response.ok) { + return { error: `Failed to fetch from ${source}: ${response.statusText}` }; + } + const content = Buffer.from(await response.arrayBuffer()); + await writeFile(targetPath, Buffer.from(content)); + console.log(`Downloaded: ${source} -> ${targetPath}`); + return { content, filePath: targetPath }; + } catch (error) { + return { error: `Error downloading from ${source}: ${error}` }; + } + } else { + try { + console.log(`Copying from local path: ${source}`); + const content = await readFile(source); + await writeFile(targetPath, Buffer.from(content)); + return { content, filePath: targetPath }; + } catch (error) { + return { error: `Error copying from local path ${source}: ${error}` }; + } + } + } + static async fetchHighlightQueries(sources, cacheDir, filetype) { + const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype)); + const queryResults = await Promise.all(queryPromises); + const validQueries = queryResults.filter((query) => query.trim().length > 0); + return validQueries.join(` +`); + } + static async fetchHighlightQuery(source, cacheDir, filetype) { + const result = await this.downloadOrLoad(source, cacheDir, "queries", ".scm", true, filetype); + if (result.error) { + console.error(`Error fetching highlight query from ${source}:`, result.error); + return ""; + } + if (result.content) { + return new TextDecoder().decode(result.content); + } + return ""; + } +} + +// src/lib/bunfs.ts +import { basename as basename2, join as join2 } from "node:path"; +function isBunfsPath(path2) { + return path2.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path2); +} +function getBunfsRootPath() { + return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root"; +} +function normalizeBunfsPath(fileName) { + return join2(getBunfsRootPath(), basename2(fileName)); +} + +// src/platform/runtime.ts +import { existsSync } from "node:fs"; +import { mkdir as mkdir2, writeFile as writeFileNode } from "node:fs/promises"; +import { dirname as dirname2, isAbsolute, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +// ../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js +function ansiRegex({ onlyFirst = false } = {}) { + const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)"; + const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`; + const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]"; + const pattern = `${osc}|${csi}`; + return new RegExp(pattern, onlyFirst ? undefined : "g"); +} + +// ../../node_modules/.bun/strip-ansi@7.1.2/node_modules/strip-ansi/index.js +var regex = ansiRegex(); +function stripAnsi(string) { + if (typeof string !== "string") { + throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); + } + return string.replace(regex, ""); +} + +// ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js +function isAmbiguous(x) { + return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109; +} +function isFullWidth(x) { + return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510; +} +function isWide(x) { + return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141; +} + +// ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js +function validate(codePoint) { + if (!Number.isSafeInteger(codePoint)) { + throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`); + } +} +function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) { + validate(codePoint); + if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) { + return 2; + } + return 1; +} + +// ../../node_modules/.bun/string-width@7.2.0/node_modules/string-width/index.js +var import_emoji_regex = __toESM(require_emoji_regex(), 1); +var segmenter = new Intl.Segmenter; +var defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u; +function stringWidth(string, options = {}) { + if (typeof string !== "string" || string.length === 0) { + return 0; + } + const { + ambiguousIsNarrow = true, + countAnsiEscapeCodes = false + } = options; + if (!countAnsiEscapeCodes) { + string = stripAnsi(string); + } + if (string.length === 0) { + return 0; + } + let width = 0; + const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow }; + for (const { segment: character } of segmenter.segment(string)) { + const codePoint = character.codePointAt(0); + if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) { + continue; + } + if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) { + continue; + } + if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) { + continue; + } + if (codePoint >= 55296 && codePoint <= 57343) { + continue; + } + if (codePoint >= 65024 && codePoint <= 65039) { + continue; + } + if (defaultIgnorableCodePointRegex.test(character)) { + continue; + } + if (import_emoji_regex.default().test(character)) { + width += 2; + continue; + } + width += eastAsianWidth(codePoint, eastAsianWidthOptions); + } + return width; +} + +// src/platform/runtime.ts +var TEXT_ENCODER = new TextEncoder; +var bun = globalThis.Bun; +var sleep = bun?.sleep ?? standardSleep; +var stringWidth2 = bun?.stringWidth ?? stringWidth; +var stripANSI = bun?.stripANSI ?? stripAnsi; +var writeFile2 = bun?.write ?? writeFilePortable; +async function resolveBundledFilePath(loadBundledFile, fallbackPath, metaUrl) { + if (!bun) { + const path2 = resolveFallbackFilePath(fallbackPath, metaUrl); + if (existsSync(path2)) { + return path2; + } + return await loadBundledFilePath(loadBundledFile, metaUrl) ?? path2; + } + return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl); +} +function resolveFallbackFilePath(fallbackPath, metaUrl) { + const path2 = typeof fallbackPath === "function" ? fallbackPath() : fallbackPath; + return fileURLToPath(path2 instanceof URL ? path2 : new URL(path2, metaUrl)); +} +function normalizeLoadedFilePath(loadedPath, baseUrl) { + if (loadedPath.startsWith("file:")) { + return fileURLToPath(loadedPath); + } + if (isAbsolute(loadedPath)) { + return loadedPath; + } + return resolve(dirname2(fileURLToPath(baseUrl)), loadedPath); +} +async function loadBundledFilePath(loadBundledFile, metaUrl) { + const specifier = extractBundledImportSpecifier(loadBundledFile); + if (!specifier) { + return; + } + try { + const moduleUrl = new URL(specifier, metaUrl); + const loaded = await import(moduleUrl.href); + return normalizeLoadedFilePath(loaded.default, moduleUrl.href); + } catch { + return; + } +} +function extractBundledImportSpecifier(loadBundledFile) { + const match = String(loadBundledFile).match(/\bimport\(\s*(["'`])([^"'`]+)\1/); + return match?.[2]; +} +function standardSleep(msOrDate) { + const ms = msOrDate instanceof Date ? msOrDate.getTime() - Date.now() : msOrDate; + return new Promise((resolve2) => setTimeout(resolve2, ms)); +} +async function writeFilePortable(destination, data, options) { + const destinationPath = destination instanceof URL ? fileURLToPath(destination) : destination; + if (options?.createPath) { + await mkdir2(dirname2(destinationPath), { recursive: true }); + } + const bytes = typeof data === "string" ? TEXT_ENCODER.encode(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength); + await writeFileNode(destinationPath, bytes, { mode: options?.mode }); + return bytes.byteLength; +} + +// src/platform/worker.ts +var WORKER_UNAVAILABLE = "OpenTUI tree-sitter workers are not available for this runtime yet."; +var globalWithWorker = globalThis; +var nodeWorkerThreads = getBuiltinModule("node:worker_threads"); +var runtimeBridge = loadWorkerRuntime(nodeWorkerThreads); + +class UnsupportedWorker { + onmessage = null; + onerror = null; + constructor() { + throw new Error(WORKER_UNAVAILABLE); + } + postMessage() { + throw new Error(WORKER_UNAVAILABLE); + } + terminate() { + throw new Error(WORKER_UNAVAILABLE); + } + addEventListener() { + throw new Error(WORKER_UNAVAILABLE); + } + removeEventListener() { + throw new Error(WORKER_UNAVAILABLE); + } +} +var Worker = loadWorkerConstructor(); +var isWorkerRuntime = runtimeBridge !== undefined; +function postWorkerMessage(value) { + if (!runtimeBridge) { + throw new Error(WORKER_UNAVAILABLE); + } + runtimeBridge.postMessage(value); +} +function setWorkerMessageHandler(handler) { + if (!runtimeBridge) { + throw new Error(WORKER_UNAVAILABLE); + } + return runtimeBridge.setMessageHandler(handler); +} +function getBuiltinModule(id) { + if (typeof process === "undefined") { + return; + } + const loader = process.getBuiltinModule; + if (typeof loader !== "function") { + return; + } + try { + return loader(id); + } catch { + return; + } +} +function loadWorkerConstructor() { + if (typeof globalWithWorker.Worker === "function") { + return globalWithWorker.Worker; + } + if (nodeWorkerThreads) { + return createNodeWorkerConstructor(nodeWorkerThreads); + } + return UnsupportedWorker; +} +function createNodeWorkerConstructor(node) { + return class NodeWorkerShim { + onmessage = null; + onerror = null; + errorListeners = new Set; + messageListeners = new Set; + worker; + terminationPromise; + constructor(specifier, options = {}) { + const resolvedSpecifier = resolveWorkerImportSpecifier(specifier); + this.worker = new node.Worker(createWorkerBootstrapSource(resolvedSpecifier), { + eval: true, + type: "module", + name: options.name + }); + this.worker.on("message", this.handleMessage); + this.worker.on("error", this.handleError); + } + postMessage(value) { + this.worker.postMessage(value); + } + terminate() { + if (this.terminationPromise) { + return this.terminationPromise; + } + this.worker.off("message", this.handleMessage); + this.worker.off("error", this.handleError); + const termination = this.worker.terminate().catch((error) => { + this.terminationPromise = undefined; + this.worker.on("message", this.handleMessage); + this.worker.on("error", this.handleError); + throw error; + }); + this.terminationPromise = termination; + return termination; + } + addEventListener(type, listener) { + if (type === "message") { + this.messageListeners.add(listener); + return; + } + this.errorListeners.add(listener); + } + removeEventListener(type, listener) { + if (type === "message") { + this.messageListeners.delete(listener); + return; + } + this.errorListeners.delete(listener); + } + handleMessage = (data) => { + const event = { data }; + this.onmessage?.(event); + for (const listener of this.messageListeners) { + listener(event); + } + }; + handleError = (error) => { + const event = { + error, + message: error.message + }; + this.onerror?.(event); + for (const listener of this.errorListeners) { + listener(event); + } + }; + }; +} +function createWorkerBootstrapSource(specifier) { + return ` + import { parentPort } from "node:worker_threads" + + const pendingMessages = [] + let messageHandler = null + + globalThis.self ??= globalThis + globalThis.postMessage ??= (value) => parentPort?.postMessage(value) + globalThis.__opentuiWorkerMessageBridge = true + Object.defineProperty(globalThis, "onmessage", { + configurable: true, + get: () => messageHandler, + set: (handler) => { + messageHandler = typeof handler === "function" ? handler : null + if (!messageHandler) return + + const messages = pendingMessages.splice(0) + for (const data of messages) { + messageHandler({ data }) + } + }, + }) + parentPort?.on("message", (data) => { + if (messageHandler) { + messageHandler({ data }) + } else { + pendingMessages.push(data) + } + }) + + await import(${JSON.stringify(specifier)}) + `; +} +function resolveWorkerImportSpecifier(specifier) { + if (specifier instanceof URL) { + return specifier.href; + } + if (isRuntimeSpecifier(specifier)) { + return specifier; + } + const nodePath = getBuiltinModule("node:path"); + const nodeUrl = getBuiltinModule("node:url"); + if (!nodePath || !nodeUrl) { + throw new Error(WORKER_UNAVAILABLE); + } + const absolutePath = nodePath.isAbsolute(specifier) ? specifier : nodePath.resolve(specifier); + return nodeUrl.pathToFileURL(absolutePath).href; +} +function isRuntimeSpecifier(specifier) { + return specifier.startsWith("file:") || specifier.startsWith("data:") || specifier.startsWith("node:") || specifier.startsWith("http:") || specifier.startsWith("https:"); +} +function loadWorkerRuntime(node) { + if (node?.parentPort && node.isMainThread === false) { + if (globalWithWorker.__opentuiWorkerMessageBridge) { + return createGlobalWorkerRuntimeBridge(); + } + return { + postMessage(value) { + node.parentPort?.postMessage(value); + }, + setMessageHandler(handler) { + const listener = (data) => { + handler({ data }); + }; + node.parentPort?.on("message", listener); + return () => { + node.parentPort?.off("message", listener); + }; + } + }; + } + if (!isGlobalWorkerRuntime()) { + return; + } + return createGlobalWorkerRuntimeBridge(); +} +function createGlobalWorkerRuntimeBridge() { + let currentRegistration; + return { + postMessage(value) { + globalWithWorker.postMessage?.(value); + }, + setMessageHandler(handler) { + const previousHandler = getGlobalWorkerMessageHandler(); + if (currentRegistration && previousHandler !== currentRegistration.listener) { + currentRegistration = undefined; + } + const listener = (event) => { + const normalizedEvent = normalizeWorkerMessageEvent(event); + handler(normalizedEvent); + }; + const registration = { + active: true, + fallbackHandler: currentRegistration ? currentRegistration.fallbackHandler : previousHandler, + listener, + previous: currentRegistration + }; + currentRegistration = registration; + setGlobalWorkerMessageHandler(listener); + return () => { + registration.active = false; + if (currentRegistration !== registration || getGlobalWorkerMessageHandler() !== listener) { + return; + } + let previous = registration.previous; + while (previous && !previous.active) { + previous = previous.previous; + } + currentRegistration = previous; + setGlobalWorkerMessageHandler(previous?.listener ?? registration.fallbackHandler); + }; + } + }; +} +function isGlobalWorkerRuntime() { + if (typeof globalWithWorker.postMessage !== "function") { + return false; + } + return typeof document === "undefined" && typeof globalWithWorker.close === "function" && "onmessage" in globalThis; +} +function normalizeWorkerMessageEvent(event) { + if (event && typeof event === "object" && "data" in event) { + return event; + } + return { data: event }; +} +function getGlobalWorkerMessageHandler() { + return globalThis.onmessage ?? null; +} +function setGlobalWorkerMessageHandler(handler) { + globalThis.onmessage = handler; +} + +// src/lib/tree-sitter/parser.worker.ts +class ParserWorker { + bufferParsers = new Map; + filetypeParserOptions = new Map; + filetypeAliases = new Map; + filetypeParsers = new Map; + filetypeParserPromises = new Map; + reusableParsers = new Map; + reusableParserPromises = new Map; + initializePromise; + performance; + dataPath; + tsDataPath; + initialized = false; + constructor() { + this.performance = { + averageParseTime: 0, + parseTimes: [], + averageQueryTime: 0, + queryTimes: [] + }; + } + async fetchQueries(sources, filetype) { + if (!this.tsDataPath) { + return ""; + } + return DownloadUtils.fetchHighlightQueries(sources, this.tsDataPath, filetype); + } + async initialize({ dataPath }) { + if (this.initializePromise) { + return this.initializePromise; + } + this.initializePromise = (async () => { + this.dataPath = dataPath; + this.tsDataPath = path2.join(dataPath, "tree-sitter"); + await mkdir3(path2.join(this.tsDataPath, "languages"), { recursive: true }); + await mkdir3(path2.join(this.tsDataPath, "queries"), { recursive: true }); + let treeWasm = await resolveBundledFilePath(() => import("web-tree-sitter/tree-sitter.wasm", { with: { type: "wasm" } }), () => import.meta.resolve("web-tree-sitter/tree-sitter.wasm"), import.meta.url); + if (isBunfsPath(treeWasm)) { + treeWasm = normalizeBunfsPath(path2.parse(treeWasm).base); + } + await Parser.init({ + locateFile() { + return treeWasm; + } + }); + this.initialized = true; + })(); + return this.initializePromise; + } + addFiletypeParser(filetypeParser) { + const previousAliases = this.filetypeParserOptions.get(filetypeParser.filetype)?.aliases ?? []; + for (const alias of previousAliases) { + if (this.filetypeAliases.get(alias) === filetypeParser.filetype) { + this.filetypeAliases.delete(alias); + } + } + const aliases = [...new Set((filetypeParser.aliases ?? []).filter((alias) => alias !== filetypeParser.filetype))]; + this.filetypeAliases.delete(filetypeParser.filetype); + this.filetypeParserOptions.set(filetypeParser.filetype, { + ...filetypeParser, + aliases + }); + for (const alias of aliases) { + this.filetypeAliases.set(alias, filetypeParser.filetype); + } + this.invalidateParserCaches(filetypeParser.filetype); + } + resolveCanonicalFiletype(filetype) { + if (this.filetypeParserOptions.has(filetype)) { + return filetype; + } + return this.filetypeAliases.get(filetype) ?? filetype; + } + invalidateParserCaches(filetype) { + this.filetypeParsers.delete(filetype); + this.filetypeParserPromises.delete(filetype); + const reusableParser = this.reusableParsers.get(filetype); + if (reusableParser) { + reusableParser.parser.delete(); + this.reusableParsers.delete(filetype); + } + this.reusableParserPromises.delete(filetype); + } + async createQueries(filetypeParser, language) { + try { + const highlightQueryContent = await this.fetchQueries(filetypeParser.queries.highlights, filetypeParser.filetype); + if (!highlightQueryContent) { + console.error("Failed to fetch highlight queries for:", filetypeParser.filetype); + return; + } + const highlightsQuery = new Query(language, highlightQueryContent); + const result = { + highlights: highlightsQuery + }; + if (filetypeParser.queries.injections && filetypeParser.queries.injections.length > 0) { + const injectionQueryContent = await this.fetchQueries(filetypeParser.queries.injections, filetypeParser.filetype); + if (injectionQueryContent) { + result.injections = new Query(language, injectionQueryContent); + } + } + return result; + } catch (error) { + console.error("Error creating queries for", filetypeParser.filetype, filetypeParser.queries); + console.error(error); + return; + } + } + async loadLanguage(languageSource) { + if (!this.initialized || !this.tsDataPath) { + return; + } + const result = await DownloadUtils.downloadOrLoad(languageSource, this.tsDataPath, "languages", ".wasm", false); + if (result.error) { + console.error(`Error loading language ${languageSource}:`, result.error); + return; + } + if (!result.filePath) { + return; + } + const normalizedPath = result.filePath.replaceAll("\\", "/"); + try { + const language = await Language.load(normalizedPath); + return language; + } catch (error) { + console.error(`Error loading language from ${normalizedPath}:`, error); + return; + } + } + async resolveFiletypeParser(filetype) { + const canonicalFiletype = this.resolveCanonicalFiletype(filetype); + if (this.filetypeParsers.has(canonicalFiletype)) { + return this.filetypeParsers.get(canonicalFiletype); + } + if (this.filetypeParserPromises.has(canonicalFiletype)) { + return this.filetypeParserPromises.get(canonicalFiletype); + } + const loadingPromise = this.loadFiletypeParser(canonicalFiletype); + this.filetypeParserPromises.set(canonicalFiletype, loadingPromise); + try { + const result = await loadingPromise; + if (result) { + this.filetypeParsers.set(canonicalFiletype, result); + } + return result; + } finally { + this.filetypeParserPromises.delete(canonicalFiletype); + } + } + async loadFiletypeParser(filetype) { + const filetypeParserOptions = this.filetypeParserOptions.get(filetype); + if (!filetypeParserOptions) { + return; + } + const language = await this.loadLanguage(filetypeParserOptions.wasm); + if (!language) { + return; + } + const queries = await this.createQueries(filetypeParserOptions, language); + if (!queries) { + console.error("Failed to create queries for:", filetype); + return; + } + const filetypeParser = { + ...filetypeParserOptions, + queries, + language + }; + return filetypeParser; + } + async preloadParser(filetype) { + return this.resolveFiletypeParser(filetype); + } + async getReusableParser(filetype) { + const canonicalFiletype = this.resolveCanonicalFiletype(filetype); + if (this.reusableParsers.has(canonicalFiletype)) { + return this.reusableParsers.get(canonicalFiletype); + } + if (this.reusableParserPromises.has(canonicalFiletype)) { + return this.reusableParserPromises.get(canonicalFiletype); + } + const creationPromise = this.createReusableParser(canonicalFiletype); + this.reusableParserPromises.set(canonicalFiletype, creationPromise); + try { + const result = await creationPromise; + if (result) { + this.reusableParsers.set(canonicalFiletype, result); + } + return result; + } finally { + this.reusableParserPromises.delete(canonicalFiletype); + } + } + async createReusableParser(filetype) { + const filetypeParser = await this.resolveFiletypeParser(filetype); + if (!filetypeParser) { + return; + } + const parser = new Parser; + parser.setLanguage(filetypeParser.language); + const reusableState = { + parser, + filetypeParser, + queries: filetypeParser.queries + }; + return reusableState; + } + async handleInitializeParser(bufferId, version, content, filetype, messageId) { + const filetypeParser = await this.resolveFiletypeParser(filetype); + if (!filetypeParser) { + postWorkerMessage({ + type: "PARSER_INIT_RESPONSE", + bufferId, + messageId, + hasParser: false, + warning: `No parser available for filetype ${filetype}` + }); + return; + } + const parser = new Parser; + parser.setLanguage(filetypeParser.language); + const tree = parser.parse(content); + if (!tree) { + postWorkerMessage({ + type: "PARSER_INIT_RESPONSE", + bufferId, + messageId, + hasParser: false, + error: "Failed to parse buffer" + }); + return; + } + const parserState = { + parser, + tree, + queries: filetypeParser.queries, + filetype, + content, + injectionMapping: filetypeParser.injectionMapping + }; + this.bufferParsers.set(bufferId, parserState); + postWorkerMessage({ + type: "PARSER_INIT_RESPONSE", + bufferId, + messageId, + hasParser: true + }); + const highlights = await this.initialQuery(parserState); + postWorkerMessage({ + type: "HIGHLIGHT_RESPONSE", + bufferId, + version, + ...highlights + }); + } + async initialQuery(parserState) { + const query = parserState.queries.highlights; + const matches = query.captures(parserState.tree.rootNode); + let injectionRanges = new Map; + if (parserState.queries.injections) { + const injectionResult = await this.processInjections(parserState); + matches.push(...injectionResult.captures); + injectionRanges = injectionResult.injectionRanges; + } + return this.getHighlights(parserState, matches, injectionRanges); + } + getNodeText(node, content) { + return content.substring(node.startIndex, node.endIndex); + } + async processInjections(parserState) { + const injectionMatches = []; + const injectionRanges = new Map; + if (!parserState.queries.injections) { + return { captures: injectionMatches, injectionRanges }; + } + const content = parserState.content; + const injectionCaptures = parserState.queries.injections.captures(parserState.tree.rootNode); + const languageGroups = new Map; + const injectionMapping = parserState.injectionMapping; + for (const capture of injectionCaptures) { + const captureName = capture.name; + if (captureName === "injection.content" || captureName.includes("injection")) { + const nodeType = capture.node.type; + let targetLanguage; + if (injectionMapping?.nodeTypes && injectionMapping.nodeTypes[nodeType]) { + targetLanguage = injectionMapping.nodeTypes[nodeType]; + } else if (nodeType === "code_fence_content") { + const parent = capture.node.parent; + if (parent) { + const infoString = parent.children.find((child) => child.type === "info_string"); + if (infoString) { + const languageNode = infoString.children.find((child) => child.type === "language"); + if (languageNode) { + const languageName = this.getNodeText(languageNode, content); + if (injectionMapping?.infoStringMap && injectionMapping.infoStringMap[languageName]) { + targetLanguage = injectionMapping.infoStringMap[languageName]; + } else { + targetLanguage = languageName; + } + } + } + } + } + if (targetLanguage) { + if (!languageGroups.has(targetLanguage)) { + languageGroups.set(targetLanguage, []); + } + languageGroups.get(targetLanguage).push({ node: capture.node, name: capture.name }); + } + } + } + for (const [language, captures] of languageGroups.entries()) { + const injectedParser = await this.getReusableParser(language); + if (!injectedParser) { + console.warn(`No parser found for injection language: ${language}`); + continue; + } + if (!injectionRanges.has(language)) { + injectionRanges.set(language, []); + } + const parser = injectedParser.parser; + for (const { node: injectionNode } of captures) { + try { + injectionRanges.get(language).push({ + start: injectionNode.startIndex, + end: injectionNode.endIndex + }); + const injectionContent = this.getNodeText(injectionNode, content); + const tree = parser.parse(injectionContent); + if (tree) { + const matches = injectedParser.queries.highlights.captures(tree.rootNode); + for (const match of matches) { + const offsetCapture = { + name: match.name, + patternIndex: match.patternIndex, + _injectedQuery: injectedParser.queries.highlights, + node: { + ...match.node, + startPosition: { + row: match.node.startPosition.row + injectionNode.startPosition.row, + column: match.node.startPosition.row === 0 ? match.node.startPosition.column + injectionNode.startPosition.column : match.node.startPosition.column + }, + endPosition: { + row: match.node.endPosition.row + injectionNode.startPosition.row, + column: match.node.endPosition.row === 0 ? match.node.endPosition.column + injectionNode.startPosition.column : match.node.endPosition.column + }, + startIndex: match.node.startIndex + injectionNode.startIndex, + endIndex: match.node.endIndex + injectionNode.startIndex + } + }; + injectionMatches.push(offsetCapture); + } + tree.delete(); + } + } catch (error) { + console.error(`Error processing injection for language ${language}:`, error); + } + } + } + return { captures: injectionMatches, injectionRanges }; + } + editToRange(edit) { + return { + startPosition: { + column: edit.startPosition.column, + row: edit.startPosition.row + }, + endPosition: { + column: edit.newEndPosition.column, + row: edit.newEndPosition.row + }, + startIndex: edit.startIndex, + endIndex: edit.newEndIndex + }; + } + async handleEdits(bufferId, content, edits) { + const parserState = this.bufferParsers.get(bufferId); + if (!parserState) { + return { warning: "No parser state found for buffer" }; + } + parserState.content = content; + for (const edit of edits) { + parserState.tree.edit(edit); + } + const startParse = performance.now(); + const newTree = parserState.parser.parse(content, parserState.tree); + const endParse = performance.now(); + const parseTime = endParse - startParse; + this.performance.parseTimes.push(parseTime); + if (this.performance.parseTimes.length > 10) { + this.performance.parseTimes.shift(); + } + this.performance.averageParseTime = this.performance.parseTimes.reduce((acc, time) => acc + time, 0) / this.performance.parseTimes.length; + if (!newTree) { + return { error: "Failed to parse buffer" }; + } + const changedRanges = parserState.tree.getChangedRanges(newTree); + parserState.tree = newTree; + const startQuery = performance.now(); + const matches = []; + if (changedRanges.length === 0) { + edits.forEach((edit) => { + const range = this.editToRange(edit); + changedRanges.push(range); + }); + } + for (const range of changedRanges) { + let node = parserState.tree.rootNode.descendantForPosition(range.startPosition, range.endPosition); + if (!node) { + continue; + } + if (node.equals(parserState.tree.rootNode)) { + const rangeCaptures = parserState.queries.highlights.captures(node, { + startIndex: range.startIndex - 100, + endIndex: range.endIndex + 1000 + }); + matches.push(...rangeCaptures); + continue; + } + while (node && !this.nodeContainsRange(node, range)) { + node = node.parent; + } + if (!node) { + node = parserState.tree.rootNode; + } + const nodeCaptures = parserState.queries.highlights.captures(node); + matches.push(...nodeCaptures); + } + let injectionRanges = new Map; + if (parserState.queries.injections) { + const injectionResult = await this.processInjections(parserState); + matches.push(...injectionResult.captures); + injectionRanges = injectionResult.injectionRanges; + } + const endQuery = performance.now(); + const queryTime = endQuery - startQuery; + this.performance.queryTimes.push(queryTime); + if (this.performance.queryTimes.length > 10) { + this.performance.queryTimes.shift(); + } + this.performance.averageQueryTime = this.performance.queryTimes.reduce((acc, time) => acc + time, 0) / this.performance.queryTimes.length; + return this.getHighlights(parserState, matches, injectionRanges); + } + nodeContainsRange(node, range) { + return node.startPosition.row <= range.startPosition.row && node.endPosition.row >= range.endPosition.row && (node.startPosition.row < range.startPosition.row || node.startPosition.column <= range.startPosition.column) && (node.endPosition.row > range.endPosition.row || node.endPosition.column >= range.endPosition.column); + } + getHighlights(parserState, matches, injectionRanges) { + const lineHighlights = new Map; + const droppedHighlights = new Map; + for (const match of matches) { + const node = match.node; + const startLine = node.startPosition.row; + const endLine = node.endPosition.row; + const highlight = { + startCol: node.startPosition.column, + endCol: node.endPosition.column, + group: match.name + }; + if (!lineHighlights.has(startLine)) { + lineHighlights.set(startLine, new Map); + droppedHighlights.set(startLine, new Map); + } + if (lineHighlights.get(startLine)?.has(node.id)) { + droppedHighlights.get(startLine)?.set(node.id, lineHighlights.get(startLine)?.get(node.id)); + } + lineHighlights.get(startLine)?.set(node.id, highlight); + if (startLine !== endLine) { + for (let line = startLine + 1;line <= endLine; line++) { + if (!lineHighlights.has(line)) { + lineHighlights.set(line, new Map); + } + const hl = { + startCol: 0, + endCol: node.endPosition.column, + group: match.name + }; + lineHighlights.get(line)?.set(node.id, hl); + } + } + } + return { + highlights: Array.from(lineHighlights.entries()).map(([line, lineHighlights2]) => ({ + line, + highlights: Array.from(lineHighlights2.values()), + droppedHighlights: droppedHighlights.get(line) ? Array.from(droppedHighlights.get(line).values()) : [] + })) + }; + } + getSimpleHighlights(matches, injectionRanges) { + const highlights = []; + const flatInjectionRanges = []; + for (const [lang, ranges] of injectionRanges.entries()) { + for (const range of ranges) { + flatInjectionRanges.push({ ...range, lang }); + } + } + for (const match of matches) { + const node = match.node; + let isInjection = false; + let injectionLang; + let containsInjection = false; + for (const injRange of flatInjectionRanges) { + if (node.startIndex >= injRange.start && node.endIndex <= injRange.end) { + isInjection = true; + injectionLang = injRange.lang; + break; + } else if (node.startIndex <= injRange.start && node.endIndex >= injRange.end) { + containsInjection = true; + break; + } + } + const matchQuery = match._injectedQuery; + const patternProperties = matchQuery?.setProperties?.[match.patternIndex]; + const concealValue = patternProperties?.conceal ?? match.setProperties?.conceal; + const concealLines = patternProperties?.conceal_lines ?? match.setProperties?.conceal_lines; + const meta = {}; + if (isInjection && injectionLang) { + meta.isInjection = true; + meta.injectionLang = injectionLang; + } + if (containsInjection) { + meta.containsInjection = true; + } + if (concealValue !== undefined) { + meta.conceal = concealValue; + } + if (concealLines !== undefined) { + meta.concealLines = concealLines; + } + if (Object.keys(meta).length > 0) { + highlights.push([node.startIndex, node.endIndex, match.name, meta]); + } else { + highlights.push([node.startIndex, node.endIndex, match.name]); + } + } + highlights.sort((a, b) => a[0] - b[0]); + return highlights; + } + async handleResetBuffer(bufferId, version, content) { + const parserState = this.bufferParsers.get(bufferId); + if (!parserState) { + return { warning: "No parser state found for buffer" }; + } + parserState.content = content; + const newTree = parserState.parser.parse(content); + if (!newTree) { + return { error: "Failed to parse buffer during reset" }; + } + parserState.tree = newTree; + const matches = parserState.queries.highlights.captures(parserState.tree.rootNode); + let injectionRanges = new Map; + if (parserState.queries.injections) { + const injectionResult = await this.processInjections(parserState); + matches.push(...injectionResult.captures); + injectionRanges = injectionResult.injectionRanges; + } + return this.getHighlights(parserState, matches, injectionRanges); + } + disposeBuffer(bufferId) { + const parserState = this.bufferParsers.get(bufferId); + if (!parserState) { + return; + } + parserState.tree.delete(); + parserState.parser.delete(); + this.bufferParsers.delete(bufferId); + } + async handleOneShotHighlight(content, filetype, messageId) { + const reusableState = await this.getReusableParser(filetype); + if (!reusableState) { + postWorkerMessage({ + type: "ONESHOT_HIGHLIGHT_RESPONSE", + messageId, + hasParser: false, + warning: `No parser available for filetype ${filetype}` + }); + return; + } + const parseContent = filetype === "markdown" && content.endsWith("```") ? content + ` +` : content; + const tree = reusableState.parser.parse(parseContent); + if (!tree) { + postWorkerMessage({ + type: "ONESHOT_HIGHLIGHT_RESPONSE", + messageId, + hasParser: false, + error: "Failed to parse content" + }); + return; + } + try { + const matches = reusableState.filetypeParser.queries.highlights.captures(tree.rootNode); + let injectionRanges = new Map; + if (reusableState.filetypeParser.queries.injections) { + const parserState = { + parser: reusableState.parser, + tree, + queries: reusableState.filetypeParser.queries, + filetype, + content, + injectionMapping: reusableState.filetypeParser.injectionMapping + }; + const injectionResult = await this.processInjections(parserState); + matches.push(...injectionResult.captures); + injectionRanges = injectionResult.injectionRanges; + } + const highlights = this.getSimpleHighlights(matches, injectionRanges); + postWorkerMessage({ + type: "ONESHOT_HIGHLIGHT_RESPONSE", + messageId, + hasParser: true, + highlights + }); + } finally { + tree.delete(); + } + } + async updateDataPath(dataPath) { + this.dataPath = dataPath; + this.tsDataPath = path2.join(dataPath, "tree-sitter"); + try { + await mkdir3(path2.join(this.tsDataPath, "languages"), { recursive: true }); + await mkdir3(path2.join(this.tsDataPath, "queries"), { recursive: true }); + } catch (error) { + throw new Error(`Failed to update data path: ${error}`); + } + } + async clearCache() { + if (!this.dataPath || !this.tsDataPath) { + throw new Error("No data path configured"); + } + const { rm } = await import("fs/promises"); + try { + const treeSitterPath = path2.join(this.dataPath, "tree-sitter"); + await rm(treeSitterPath, { recursive: true, force: true }); + await mkdir3(path2.join(treeSitterPath, "languages"), { recursive: true }); + await mkdir3(path2.join(treeSitterPath, "queries"), { recursive: true }); + this.filetypeParsers.clear(); + this.filetypeParserPromises.clear(); + this.reusableParsers.clear(); + this.reusableParserPromises.clear(); + } catch (error) { + throw new Error(`Failed to clear cache: ${error}`); + } + } +} +function logMessage(type, ...args) { + postWorkerMessage({ + type: "WORKER_LOG", + logType: type, + data: args + }); +} +function postWorkerError(bufferId, error) { + postWorkerMessage({ + type: "ERROR", + bufferId, + error: error instanceof Error ? error.stack || error.message : String(error) + }); +} +if (isWorkerRuntime) { + const worker = new ParserWorker; + console.log = (...args) => logMessage("log", ...args); + console.error = (...args) => logMessage("error", ...args); + console.warn = (...args) => logMessage("warn", ...args); + setWorkerMessageHandler(async (event) => { + const message = event.data; + const messageType = String(event.data.type ?? "unknown"); + try { + switch (message.type) { + case "INIT": + try { + await worker.initialize({ dataPath: message.dataPath }); + postWorkerMessage({ type: "INIT_RESPONSE" }); + } catch (error) { + postWorkerMessage({ + type: "INIT_RESPONSE", + error: error instanceof Error ? error.stack || error.message : String(error) + }); + } + break; + case "ADD_FILETYPE_PARSER": + worker.addFiletypeParser(message.filetypeParser); + break; + case "PRELOAD_PARSER": { + const maybeParser = await worker.preloadParser(message.filetype); + postWorkerMessage({ + type: "PRELOAD_PARSER_RESPONSE", + messageId: message.messageId, + hasParser: !!maybeParser + }); + break; + } + case "INITIALIZE_PARSER": + await worker.handleInitializeParser(message.bufferId, message.version, message.content, message.filetype, message.messageId); + break; + case "HANDLE_EDITS": { + const response = await worker.handleEdits(message.bufferId, message.content, message.edits); + if (response.highlights && response.highlights.length > 0) { + postWorkerMessage({ + type: "HIGHLIGHT_RESPONSE", + bufferId: message.bufferId, + version: message.version, + highlights: response.highlights + }); + } else if (response.warning) { + postWorkerMessage({ + type: "WARNING", + bufferId: message.bufferId, + warning: response.warning + }); + } else if (response.error) { + postWorkerMessage({ + type: "ERROR", + bufferId: message.bufferId, + error: response.error + }); + } + break; + } + case "GET_PERFORMANCE": + postWorkerMessage({ + type: "PERFORMANCE_RESPONSE", + performance: worker.performance, + messageId: message.messageId + }); + break; + case "RESET_BUFFER": { + const resetResponse = await worker.handleResetBuffer(message.bufferId, message.version, message.content); + if (resetResponse.highlights && resetResponse.highlights.length > 0) { + postWorkerMessage({ + type: "HIGHLIGHT_RESPONSE", + bufferId: message.bufferId, + version: message.version, + highlights: resetResponse.highlights + }); + } else if (resetResponse.warning) { + postWorkerMessage({ + type: "WARNING", + bufferId: message.bufferId, + warning: resetResponse.warning + }); + } else if (resetResponse.error) { + postWorkerMessage({ + type: "ERROR", + bufferId: message.bufferId, + error: resetResponse.error + }); + } + break; + } + case "DISPOSE_BUFFER": + worker.disposeBuffer(message.bufferId); + postWorkerMessage({ + type: "BUFFER_DISPOSED", + bufferId: message.bufferId + }); + break; + case "ONESHOT_HIGHLIGHT": + await worker.handleOneShotHighlight(message.content, message.filetype, message.messageId); + break; + case "UPDATE_DATA_PATH": + try { + await worker.updateDataPath(message.dataPath); + postWorkerMessage({ + type: "UPDATE_DATA_PATH_RESPONSE", + messageId: message.messageId + }); + } catch (error) { + postWorkerMessage({ + type: "UPDATE_DATA_PATH_RESPONSE", + messageId: message.messageId, + error: error instanceof Error ? error.message : String(error) + }); + } + break; + case "CLEAR_CACHE": + try { + await worker.clearCache(); + postWorkerMessage({ + type: "CLEAR_CACHE_RESPONSE", + messageId: message.messageId + }); + } catch (error) { + postWorkerMessage({ + type: "CLEAR_CACHE_RESPONSE", + messageId: message.messageId, + error: error instanceof Error ? error.message : String(error) + }); + } + break; + default: + postWorkerMessage({ + type: "ERROR", + error: `Unknown message type: ${messageType}` + }); + } + } catch (error) { + if ("bufferId" in message) { + postWorkerError(message.bufferId, error); + } else { + postWorkerError(undefined, error); + } + } + }); +} + +//# debugId=0D88AD8518CAE38D64756E2164756E21 +//# sourceMappingURL=parser.worker.js.map diff --git a/.patches/@opentui/core/parser.worker.js.map b/.patches/@opentui/core/parser.worker.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/parser.worker.js.map @@ -0,0 +1,20 @@ +{ + "version": 3, + "sources": ["../../../node_modules/.bun/emoji-regex@10.6.0/node_modules/emoji-regex/index.js", "../src/lib/tree-sitter/parser.worker.ts", "../src/lib/tree-sitter/download-utils.ts", "../src/lib/bunfs.ts", "../src/platform/runtime.ts", "../../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js", "../../../node_modules/.bun/strip-ansi@7.1.2/node_modules/strip-ansi/index.js", "../../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js", "../../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js", "../../../node_modules/.bun/string-width@7.2.0/node_modules/string-width/index.js", "../src/platform/worker.ts"], + "sourcesContent": [ + "module.exports = () => {\n\t// https://mths.be/emoji\n\treturn /[#*0-9]\\uFE0F?\\u20E3|[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23ED-\\u23EF\\u23F1\\u23F2\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB\\u25FC\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692\\u2694-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A7\\u26AA\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C8\\u26CF\\u26D1\\u26E9\\u26F0-\\u26F5\\u26F7\\u26F8\\u26FA\\u2702\\u2708\\u2709\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u27A1\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B55\\u3030\\u303D\\u3297\\u3299]\\uFE0F?|[\\u261D\\u270C\\u270D](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\u270A\\u270B](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u2693\\u26A1\\u26AB\\u26C5\\u26CE\\u26D4\\u26EA\\u26FD\\u2705\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2795-\\u2797\\u27B0\\u27BF\\u2B50]|\\u26D3\\uFE0F?(?:\\u200D\\uD83D\\uDCA5)?|\\u26F9(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|\\u2764\\uFE0F?(?:\\u200D(?:\\uD83D\\uDD25|\\uD83E\\uDE79))?|\\uD83C(?:[\\uDC04\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDE02\\uDE37\\uDF21\\uDF24-\\uDF2C\\uDF36\\uDF7D\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E\\uDF9F\\uDFCD\\uDFCE\\uDFD4-\\uDFDF\\uDFF5\\uDFF7]\\uFE0F?|[\\uDF85\\uDFC2\\uDFC7](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDFC4\\uDFCA](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDFCB\\uDFCC](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDE01\\uDE1A\\uDE2F\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF43\\uDF45-\\uDF4A\\uDF4C-\\uDF7C\\uDF7E-\\uDF84\\uDF86-\\uDF93\\uDFA0-\\uDFC1\\uDFC5\\uDFC6\\uDFC8\\uDFC9\\uDFCF-\\uDFD3\\uDFE0-\\uDFF0\\uDFF8-\\uDFFF]|\\uDDE6\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF]|\\uDDE7\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF]|\\uDDE8\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF7\\uDDFA-\\uDDFF]|\\uDDE9\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF]|\\uDDEA\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA]|\\uDDEB\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7]|\\uDDEC\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE]|\\uDDED\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA]|\\uDDEE\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9]|\\uDDEF\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5]|\\uDDF0\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF]|\\uDDF1\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE]|\\uDDF2\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF]|\\uDDF3\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF]|\\uDDF4\\uD83C\\uDDF2|\\uDDF5\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE]|\\uDDF6\\uD83C\\uDDE6|\\uDDF7\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC]|\\uDDF8\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF]|\\uDDF9\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF]|\\uDDFA\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF]|\\uDDFB\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uDDF3\\uDDFA]|\\uDDFC\\uD83C[\\uDDEB\\uDDF8]|\\uDDFD\\uD83C\\uDDF0|\\uDDFE\\uD83C[\\uDDEA\\uDDF9]|\\uDDFF\\uD83C[\\uDDE6\\uDDF2\\uDDFC]|\\uDF44(?:\\u200D\\uD83D\\uDFEB)?|\\uDF4B(?:\\u200D\\uD83D\\uDFE9)?|\\uDFC3(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDFF3\\uFE0F?(?:\\u200D(?:\\u26A7\\uFE0F?|\\uD83C\\uDF08))?|\\uDFF4(?:\\u200D\\u2620\\uFE0F?|\\uDB40\\uDC67\\uDB40\\uDC62\\uDB40(?:\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67|\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73)\\uDB40\\uDC7F)?)|\\uD83D(?:[\\uDC3F\\uDCFD\\uDD49\\uDD4A\\uDD6F\\uDD70\\uDD73\\uDD76-\\uDD79\\uDD87\\uDD8A-\\uDD8D\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA\\uDECB\\uDECD-\\uDECF\\uDEE0-\\uDEE5\\uDEE9\\uDEF0\\uDEF3]\\uFE0F?|[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC6B-\\uDC6D\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDC8F\\uDC91\\uDCAA\\uDD7A\\uDD95\\uDD96\\uDE4C\\uDE4F\\uDEC0\\uDECC](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDC6E-\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4\\uDEB5](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD74\\uDD90](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\uDC00-\\uDC07\\uDC09-\\uDC14\\uDC16-\\uDC25\\uDC27-\\uDC3A\\uDC3C-\\uDC3E\\uDC40\\uDC44\\uDC45\\uDC51-\\uDC65\\uDC6A\\uDC79-\\uDC7B\\uDC7D-\\uDC80\\uDC84\\uDC88-\\uDC8E\\uDC90\\uDC92-\\uDCA9\\uDCAB-\\uDCFC\\uDCFF-\\uDD3D\\uDD4B-\\uDD4E\\uDD50-\\uDD67\\uDDA4\\uDDFB-\\uDE2D\\uDE2F-\\uDE34\\uDE37-\\uDE41\\uDE43\\uDE44\\uDE48-\\uDE4A\\uDE80-\\uDEA2\\uDEA4-\\uDEB3\\uDEB7-\\uDEBF\\uDEC1-\\uDEC5\\uDED0-\\uDED2\\uDED5-\\uDED8\\uDEDC-\\uDEDF\\uDEEB\\uDEEC\\uDEF4-\\uDEFC\\uDFE0-\\uDFEB\\uDFF0]|\\uDC08(?:\\u200D\\u2B1B)?|\\uDC15(?:\\u200D\\uD83E\\uDDBA)?|\\uDC26(?:\\u200D(?:\\u2B1B|\\uD83D\\uDD25))?|\\uDC3B(?:\\u200D\\u2744\\uFE0F?)?|\\uDC41\\uFE0F?(?:\\u200D\\uD83D\\uDDE8\\uFE0F?)?|\\uDC68(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDC68\\uDC69]\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?)|[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?)|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?))?|\\uDC69(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?[\\uDC68\\uDC69]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?|\\uDC69\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?))|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFC-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFE]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDD75(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|\\uDE2E(?:\\u200D\\uD83D\\uDCA8)?|\\uDE35(?:\\u200D\\uD83D\\uDCAB)?|\\uDE36(?:\\u200D\\uD83C\\uDF2B\\uFE0F?)?|\\uDE42(?:\\u200D[\\u2194\\u2195]\\uFE0F?)?|\\uDEB6(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?)|\\uD83E(?:[\\uDD0C\\uDD0F\\uDD18-\\uDD1F\\uDD30-\\uDD34\\uDD36\\uDD77\\uDDB5\\uDDB6\\uDDBB\\uDDD2\\uDDD3\\uDDD5\\uDEC3-\\uDEC5\\uDEF0\\uDEF2-\\uDEF8](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDB8\\uDDB9\\uDDCD\\uDDCF\\uDDD4\\uDDD6-\\uDDDD](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDDDE\\uDDDF](?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD0D\\uDD0E\\uDD10-\\uDD17\\uDD20-\\uDD25\\uDD27-\\uDD2F\\uDD3A\\uDD3F-\\uDD45\\uDD47-\\uDD76\\uDD78-\\uDDB4\\uDDB7\\uDDBA\\uDDBC-\\uDDCC\\uDDD0\\uDDE0-\\uDDFF\\uDE70-\\uDE7C\\uDE80-\\uDE8A\\uDE8E-\\uDEC2\\uDEC6\\uDEC8\\uDECD-\\uDEDC\\uDEDF-\\uDEEA\\uDEEF]|\\uDDCE(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDDD1(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1|\\uDDD1\\u200D\\uD83E\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?|\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDEF1(?:\\uD83C(?:\\uDFFB(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFC-\\uDFFF])?|\\uDFFC(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])?|\\uDFFD(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])?|\\uDFFE(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])?|\\uDFFF(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFE])?))?)/g;\n};\n", + "import { Parser, Query, Tree, Language } from \"web-tree-sitter\"\nimport type { Edit, QueryCapture, Range } from \"web-tree-sitter\"\nimport { mkdir } from \"fs/promises\"\nimport * as path from \"path\"\nimport type {\n HighlightRange,\n HighlightResponse,\n SimpleHighlight,\n FiletypeParserOptions,\n PerformanceStats,\n InjectionMapping,\n TreeSitterWorkerLogType,\n TreeSitterWorkerRequest,\n TreeSitterWorkerResponse,\n} from \"./types.js\"\nimport { DownloadUtils } from \"./download-utils.js\"\nimport { isBunfsPath, normalizeBunfsPath } from \"../bunfs.js\"\nimport { resolveBundledFilePath } from \"../../platform/runtime.js\"\nimport {\n isWorkerRuntime,\n postWorkerMessage,\n setWorkerMessageHandler,\n type WorkerMessageEvent,\n} from \"../../platform/worker.js\"\n\ntype ParserState = {\n parser: Parser\n tree: Tree\n queries: {\n highlights: Query\n injections?: Query\n }\n filetype: string\n content: string\n injectionMapping?: InjectionMapping\n}\n\ninterface FiletypeParser {\n filetype: string\n queries: {\n highlights: Query\n injections?: Query\n }\n language: Language\n injectionMapping?: InjectionMapping\n}\n\ninterface ReusableParserState {\n parser: Parser\n filetypeParser: FiletypeParser\n queries: {\n highlights: Query\n injections?: Query\n }\n}\n\nclass ParserWorker {\n private bufferParsers: Map = new Map()\n private filetypeParserOptions: Map = new Map()\n private filetypeAliases: Map = new Map()\n private filetypeParsers: Map = new Map()\n private filetypeParserPromises: Map> = new Map()\n private reusableParsers: Map = new Map()\n private reusableParserPromises: Map> = new Map()\n private initializePromise: Promise | undefined\n public performance: PerformanceStats\n private dataPath: string | undefined\n private tsDataPath: string | undefined\n private initialized: boolean = false\n\n constructor() {\n this.performance = {\n averageParseTime: 0,\n parseTimes: [],\n averageQueryTime: 0,\n queryTimes: [],\n }\n }\n\n private async fetchQueries(sources: string[], filetype: string): Promise {\n if (!this.tsDataPath) {\n return \"\"\n }\n return DownloadUtils.fetchHighlightQueries(sources, this.tsDataPath, filetype)\n }\n\n async initialize({ dataPath }: { dataPath: string }) {\n if (this.initializePromise) {\n return this.initializePromise\n }\n this.initializePromise = (async () => {\n this.dataPath = dataPath\n this.tsDataPath = path.join(dataPath, \"tree-sitter\")\n\n await mkdir(path.join(this.tsDataPath, \"languages\"), { recursive: true })\n await mkdir(path.join(this.tsDataPath, \"queries\"), { recursive: true })\n\n let treeWasm = await resolveBundledFilePath(\n () => import(\"web-tree-sitter/tree-sitter.wasm\" as string, { with: { type: \"wasm\" } }),\n () => import.meta.resolve(\"web-tree-sitter/tree-sitter.wasm\"),\n import.meta.url,\n )\n\n if (isBunfsPath(treeWasm)) {\n treeWasm = normalizeBunfsPath(path.parse(treeWasm).base)\n }\n\n await Parser.init({\n locateFile() {\n return treeWasm\n },\n })\n\n this.initialized = true\n })()\n return this.initializePromise\n }\n\n public addFiletypeParser(filetypeParser: FiletypeParserOptions) {\n const previousAliases = this.filetypeParserOptions.get(filetypeParser.filetype)?.aliases ?? []\n for (const alias of previousAliases) {\n if (this.filetypeAliases.get(alias) === filetypeParser.filetype) {\n this.filetypeAliases.delete(alias)\n }\n }\n\n const aliases = [...new Set((filetypeParser.aliases ?? []).filter((alias) => alias !== filetypeParser.filetype))]\n\n this.filetypeAliases.delete(filetypeParser.filetype)\n this.filetypeParserOptions.set(filetypeParser.filetype, {\n ...filetypeParser,\n aliases,\n })\n\n for (const alias of aliases) {\n this.filetypeAliases.set(alias, filetypeParser.filetype)\n }\n\n this.invalidateParserCaches(filetypeParser.filetype)\n }\n\n private resolveCanonicalFiletype(filetype: string): string {\n if (this.filetypeParserOptions.has(filetype)) {\n return filetype\n }\n\n return this.filetypeAliases.get(filetype) ?? filetype\n }\n\n private invalidateParserCaches(filetype: string): void {\n this.filetypeParsers.delete(filetype)\n this.filetypeParserPromises.delete(filetype)\n\n const reusableParser = this.reusableParsers.get(filetype)\n if (reusableParser) {\n reusableParser.parser.delete()\n this.reusableParsers.delete(filetype)\n }\n\n this.reusableParserPromises.delete(filetype)\n }\n\n private async createQueries(\n filetypeParser: FiletypeParserOptions,\n language: Language,\n ): Promise<\n | {\n highlights: Query\n injections?: Query\n }\n | undefined\n > {\n try {\n const highlightQueryContent = await this.fetchQueries(filetypeParser.queries.highlights, filetypeParser.filetype)\n if (!highlightQueryContent) {\n console.error(\"Failed to fetch highlight queries for:\", filetypeParser.filetype)\n return undefined\n }\n\n const highlightsQuery = new Query(language, highlightQueryContent)\n const result: { highlights: Query; injections?: Query } = {\n highlights: highlightsQuery,\n }\n\n if (filetypeParser.queries.injections && filetypeParser.queries.injections.length > 0) {\n const injectionQueryContent = await this.fetchQueries(\n filetypeParser.queries.injections,\n filetypeParser.filetype,\n )\n if (injectionQueryContent) {\n result.injections = new Query(language, injectionQueryContent)\n }\n }\n\n return result\n } catch (error) {\n console.error(\"Error creating queries for\", filetypeParser.filetype, filetypeParser.queries)\n console.error(error)\n return undefined\n }\n }\n\n private async loadLanguage(languageSource: string): Promise {\n if (!this.initialized || !this.tsDataPath) {\n return undefined\n }\n\n const result = await DownloadUtils.downloadOrLoad(languageSource, this.tsDataPath, \"languages\", \".wasm\", false)\n\n if (result.error) {\n console.error(`Error loading language ${languageSource}:`, result.error)\n return undefined\n }\n\n if (!result.filePath) {\n return undefined\n }\n\n // Normalize path for Windows compatibility - tree-sitter expects forward slashes\n const normalizedPath = result.filePath.replaceAll(\"\\\\\", \"/\")\n\n try {\n const language = await Language.load(normalizedPath)\n return language\n } catch (error) {\n console.error(`Error loading language from ${normalizedPath}:`, error)\n return undefined\n }\n }\n\n private async resolveFiletypeParser(filetype: string): Promise {\n const canonicalFiletype = this.resolveCanonicalFiletype(filetype)\n\n if (this.filetypeParsers.has(canonicalFiletype)) {\n return this.filetypeParsers.get(canonicalFiletype)\n }\n\n if (this.filetypeParserPromises.has(canonicalFiletype)) {\n return this.filetypeParserPromises.get(canonicalFiletype)\n }\n\n const loadingPromise = this.loadFiletypeParser(canonicalFiletype)\n this.filetypeParserPromises.set(canonicalFiletype, loadingPromise)\n\n try {\n const result = await loadingPromise\n if (result) {\n this.filetypeParsers.set(canonicalFiletype, result)\n }\n return result\n } finally {\n this.filetypeParserPromises.delete(canonicalFiletype)\n }\n }\n\n private async loadFiletypeParser(filetype: string): Promise {\n const filetypeParserOptions = this.filetypeParserOptions.get(filetype)\n if (!filetypeParserOptions) {\n return undefined\n }\n const language = await this.loadLanguage(filetypeParserOptions.wasm)\n if (!language) {\n return undefined\n }\n const queries = await this.createQueries(filetypeParserOptions, language)\n if (!queries) {\n console.error(\"Failed to create queries for:\", filetype)\n return undefined\n }\n const filetypeParser: FiletypeParser = {\n ...filetypeParserOptions,\n queries,\n language,\n }\n return filetypeParser\n }\n\n public async preloadParser(filetype: string) {\n return this.resolveFiletypeParser(filetype)\n }\n\n private async getReusableParser(filetype: string): Promise {\n const canonicalFiletype = this.resolveCanonicalFiletype(filetype)\n\n if (this.reusableParsers.has(canonicalFiletype)) {\n return this.reusableParsers.get(canonicalFiletype)\n }\n\n if (this.reusableParserPromises.has(canonicalFiletype)) {\n return this.reusableParserPromises.get(canonicalFiletype)\n }\n\n const creationPromise = this.createReusableParser(canonicalFiletype)\n this.reusableParserPromises.set(canonicalFiletype, creationPromise)\n\n try {\n const result = await creationPromise\n if (result) {\n this.reusableParsers.set(canonicalFiletype, result)\n }\n return result\n } finally {\n this.reusableParserPromises.delete(canonicalFiletype)\n }\n }\n\n private async createReusableParser(filetype: string): Promise {\n const filetypeParser = await this.resolveFiletypeParser(filetype)\n if (!filetypeParser) {\n return undefined\n }\n\n const parser = new Parser()\n parser.setLanguage(filetypeParser.language)\n\n const reusableState: ReusableParserState = {\n parser,\n filetypeParser,\n queries: filetypeParser.queries,\n }\n\n return reusableState\n }\n\n async handleInitializeParser(\n bufferId: number,\n version: number,\n content: string,\n filetype: string,\n messageId: string,\n ) {\n const filetypeParser = await this.resolveFiletypeParser(filetype)\n\n if (!filetypeParser) {\n postWorkerMessage({\n type: \"PARSER_INIT_RESPONSE\",\n bufferId,\n messageId,\n hasParser: false,\n warning: `No parser available for filetype ${filetype}`,\n })\n return\n }\n\n const parser = new Parser()\n parser.setLanguage(filetypeParser.language)\n const tree = parser.parse(content)\n if (!tree) {\n postWorkerMessage({\n type: \"PARSER_INIT_RESPONSE\",\n bufferId,\n messageId,\n hasParser: false,\n error: \"Failed to parse buffer\",\n })\n return\n }\n\n const parserState: ParserState = {\n parser,\n tree,\n queries: filetypeParser.queries,\n filetype,\n content,\n injectionMapping: filetypeParser.injectionMapping,\n }\n this.bufferParsers.set(bufferId, parserState)\n\n postWorkerMessage({\n type: \"PARSER_INIT_RESPONSE\",\n bufferId,\n messageId,\n hasParser: true,\n })\n const highlights = await this.initialQuery(parserState)\n postWorkerMessage({\n type: \"HIGHLIGHT_RESPONSE\",\n bufferId,\n version,\n ...highlights,\n })\n }\n\n private async initialQuery(parserState: ParserState) {\n const query = parserState.queries.highlights\n const matches: QueryCapture[] = query.captures(parserState.tree.rootNode)\n let injectionRanges = new Map>()\n\n if (parserState.queries.injections) {\n const injectionResult = await this.processInjections(parserState)\n matches.push(...injectionResult.captures)\n injectionRanges = injectionResult.injectionRanges\n }\n\n return this.getHighlights(parserState, matches, injectionRanges)\n }\n\n private getNodeText(node: any, content: string): string {\n return content.substring(node.startIndex, node.endIndex)\n }\n\n private async processInjections(\n parserState: ParserState,\n ): Promise<{ captures: QueryCapture[]; injectionRanges: Map> }> {\n const injectionMatches: QueryCapture[] = []\n const injectionRanges = new Map>()\n\n if (!parserState.queries.injections) {\n return { captures: injectionMatches, injectionRanges }\n }\n\n const content = parserState.content\n const injectionCaptures = parserState.queries.injections.captures(parserState.tree.rootNode)\n const languageGroups = new Map>()\n\n // Use the injection mapping stored in the parser state\n const injectionMapping = parserState.injectionMapping\n\n for (const capture of injectionCaptures) {\n const captureName = capture.name\n\n if (captureName === \"injection.content\" || captureName.includes(\"injection\")) {\n const nodeType = capture.node.type\n let targetLanguage: string | undefined\n\n // First, check if there's a direct node type mapping\n if (injectionMapping?.nodeTypes && injectionMapping.nodeTypes[nodeType]) {\n targetLanguage = injectionMapping.nodeTypes[nodeType]\n } else if (nodeType === \"code_fence_content\") {\n // For code fence content, try to extract language from info_string\n const parent = capture.node.parent\n if (parent) {\n const infoString = parent.children.find((child: any) => child.type === \"info_string\")\n if (infoString) {\n const languageNode = infoString.children.find((child: any) => child.type === \"language\")\n if (languageNode) {\n const languageName = this.getNodeText(languageNode, content)\n\n if (injectionMapping?.infoStringMap && injectionMapping.infoStringMap[languageName]) {\n targetLanguage = injectionMapping.infoStringMap[languageName]\n } else {\n targetLanguage = languageName\n }\n }\n }\n }\n }\n\n if (targetLanguage) {\n if (!languageGroups.has(targetLanguage)) {\n languageGroups.set(targetLanguage, [])\n }\n languageGroups.get(targetLanguage)!.push({ node: capture.node, name: capture.name })\n }\n }\n }\n\n // Process each language group\n for (const [language, captures] of languageGroups.entries()) {\n const injectedParser = await this.getReusableParser(language)\n\n if (!injectedParser) {\n console.warn(`No parser found for injection language: ${language}`)\n continue\n }\n\n // Track injection ranges for this language\n if (!injectionRanges.has(language)) {\n injectionRanges.set(language, [])\n }\n\n const parser = injectedParser.parser\n for (const { node: injectionNode } of captures) {\n try {\n // Record the injection range\n injectionRanges.get(language)!.push({\n start: injectionNode.startIndex,\n end: injectionNode.endIndex,\n })\n\n const injectionContent = this.getNodeText(injectionNode, content)\n const tree = parser.parse(injectionContent)\n\n if (tree) {\n const matches = injectedParser.queries.highlights.captures(tree.rootNode)\n\n // Create new QueryCapture objects with offset positions\n for (const match of matches) {\n // Calculate offset positions by creating a new capture with adjusted node properties\n // Store the injected query reference so we can look up properties correctly\n const offsetCapture: QueryCapture & { _injectedQuery?: Query } = {\n name: match.name,\n patternIndex: match.patternIndex,\n _injectedQuery: injectedParser.queries.highlights, // Store the correct query reference\n node: {\n ...match.node,\n startPosition: {\n row: match.node.startPosition.row + injectionNode.startPosition.row,\n column:\n match.node.startPosition.row === 0\n ? match.node.startPosition.column + injectionNode.startPosition.column\n : match.node.startPosition.column,\n },\n endPosition: {\n row: match.node.endPosition.row + injectionNode.startPosition.row,\n column:\n match.node.endPosition.row === 0\n ? match.node.endPosition.column + injectionNode.startPosition.column\n : match.node.endPosition.column,\n },\n startIndex: match.node.startIndex + injectionNode.startIndex,\n endIndex: match.node.endIndex + injectionNode.startIndex,\n } as any, // Cast to any since we're creating a pseudo-node\n }\n\n injectionMatches.push(offsetCapture)\n }\n\n tree.delete()\n }\n } catch (error) {\n console.error(`Error processing injection for language ${language}:`, error)\n }\n }\n\n // NOTE: Do NOT call parser.delete() here - this is a reusable parser!\n }\n\n return { captures: injectionMatches, injectionRanges }\n }\n\n private editToRange(edit: Edit): Range {\n return {\n startPosition: {\n column: edit.startPosition.column,\n row: edit.startPosition.row,\n },\n endPosition: {\n column: edit.newEndPosition.column,\n row: edit.newEndPosition.row,\n },\n startIndex: edit.startIndex,\n endIndex: edit.newEndIndex,\n }\n }\n\n async handleEdits(\n bufferId: number,\n content: string,\n edits: Edit[],\n ): Promise<{ highlights?: HighlightResponse[]; warning?: string; error?: string }> {\n const parserState = this.bufferParsers.get(bufferId)\n if (!parserState) {\n return { warning: \"No parser state found for buffer\" }\n }\n\n parserState.content = content\n\n for (const edit of edits) {\n parserState.tree.edit(edit)\n }\n\n const startParse = performance.now()\n\n const newTree = parserState.parser.parse(content, parserState.tree)\n\n const endParse = performance.now()\n const parseTime = endParse - startParse\n this.performance.parseTimes.push(parseTime)\n if (this.performance.parseTimes.length > 10) {\n this.performance.parseTimes.shift()\n }\n this.performance.averageParseTime =\n this.performance.parseTimes.reduce((acc, time) => acc + time, 0) / this.performance.parseTimes.length\n\n if (!newTree) {\n return { error: \"Failed to parse buffer\" }\n }\n\n const changedRanges = parserState.tree.getChangedRanges(newTree)\n parserState.tree = newTree\n\n const startQuery = performance.now()\n const matches: QueryCapture[] = []\n\n if (changedRanges.length === 0) {\n edits.forEach((edit) => {\n const range = this.editToRange(edit)\n changedRanges.push(range)\n })\n }\n\n for (const range of changedRanges) {\n let node = parserState.tree.rootNode.descendantForPosition(range.startPosition, range.endPosition)\n\n if (!node) {\n continue\n }\n\n // If we got the root node, query with range to limit scope\n if (node.equals(parserState.tree.rootNode)) {\n // WHY ARE RANGES NOT WORKING!?\n // The changed ranges are not returning anything in some cases\n // Even this shit somehow returns many lines before the actual range,\n // and even though expanded by 1000 bytes it does not capture much beyond the actual range.\n // So freaking weird.\n const rangeCaptures = parserState.queries.highlights.captures(\n node,\n // WTF!?\n {\n startIndex: range.startIndex - 100,\n endIndex: range.endIndex + 1000,\n },\n )\n matches.push(...rangeCaptures)\n continue\n }\n\n while (node && !this.nodeContainsRange(node, range)) {\n node = node.parent\n }\n\n if (!node) {\n node = parserState.tree.rootNode\n }\n\n const nodeCaptures = parserState.queries.highlights.captures(node)\n matches.push(...nodeCaptures)\n }\n\n let injectionRanges = new Map>()\n if (parserState.queries.injections) {\n const injectionResult = await this.processInjections(parserState)\n // Only add injection matches that are in the changed ranges\n // This is a simplification - ideally we'd only process injections in changed ranges\n matches.push(...injectionResult.captures)\n injectionRanges = injectionResult.injectionRanges\n }\n\n const endQuery = performance.now()\n const queryTime = endQuery - startQuery\n this.performance.queryTimes.push(queryTime)\n if (this.performance.queryTimes.length > 10) {\n this.performance.queryTimes.shift()\n }\n this.performance.averageQueryTime =\n this.performance.queryTimes.reduce((acc, time) => acc + time, 0) / this.performance.queryTimes.length\n\n return this.getHighlights(parserState, matches, injectionRanges)\n }\n\n private nodeContainsRange(node: any, range: any): boolean {\n return (\n node.startPosition.row <= range.startPosition.row &&\n node.endPosition.row >= range.endPosition.row &&\n (node.startPosition.row < range.startPosition.row || node.startPosition.column <= range.startPosition.column) &&\n (node.endPosition.row > range.endPosition.row || node.endPosition.column >= range.endPosition.column)\n )\n }\n\n private getHighlights(\n parserState: ParserState,\n matches: QueryCapture[],\n injectionRanges?: Map>,\n ): { highlights: HighlightResponse[] } {\n const lineHighlights: Map> = new Map()\n const droppedHighlights: Map> = new Map()\n\n for (const match of matches) {\n const node = match.node\n const startLine = node.startPosition.row\n const endLine = node.endPosition.row\n\n const highlight = {\n startCol: node.startPosition.column,\n endCol: node.endPosition.column,\n group: match.name,\n }\n\n if (!lineHighlights.has(startLine)) {\n lineHighlights.set(startLine, new Map())\n droppedHighlights.set(startLine, new Map())\n }\n if (lineHighlights.get(startLine)?.has(node.id)) {\n droppedHighlights.get(startLine)?.set(node.id, lineHighlights.get(startLine)?.get(node.id)!)\n }\n lineHighlights.get(startLine)?.set(node.id, highlight)\n\n if (startLine !== endLine) {\n for (let line = startLine + 1; line <= endLine; line++) {\n if (!lineHighlights.has(line)) {\n lineHighlights.set(line, new Map())\n }\n const hl: HighlightRange = {\n startCol: 0,\n endCol: node.endPosition.column,\n group: match.name,\n }\n lineHighlights.get(line)?.set(node.id, hl)\n }\n }\n }\n\n return {\n highlights: Array.from(lineHighlights.entries()).map(([line, lineHighlights]) => ({\n line,\n highlights: Array.from(lineHighlights.values()),\n droppedHighlights: droppedHighlights.get(line) ? Array.from(droppedHighlights.get(line)!.values()) : [],\n })),\n }\n }\n\n private getSimpleHighlights(\n matches: QueryCapture[],\n injectionRanges: Map>,\n ): SimpleHighlight[] {\n const highlights: SimpleHighlight[] = []\n\n const flatInjectionRanges: Array<{ start: number; end: number; lang: string }> = []\n for (const [lang, ranges] of injectionRanges.entries()) {\n for (const range of ranges) {\n flatInjectionRanges.push({ ...range, lang })\n }\n }\n\n for (const match of matches) {\n const node = match.node\n\n let isInjection = false\n let injectionLang: string | undefined\n let containsInjection = false\n for (const injRange of flatInjectionRanges) {\n if (node.startIndex >= injRange.start && node.endIndex <= injRange.end) {\n isInjection = true\n injectionLang = injRange.lang\n break\n } else if (node.startIndex <= injRange.start && node.endIndex >= injRange.end) {\n containsInjection = true\n break\n }\n }\n\n const matchQuery = (match as any)._injectedQuery\n const patternProperties = matchQuery?.setProperties?.[match.patternIndex]\n\n const concealValue = patternProperties?.conceal ?? match.setProperties?.conceal\n const concealLines = patternProperties?.conceal_lines ?? match.setProperties?.conceal_lines\n\n const meta: any = {}\n if (isInjection && injectionLang) {\n meta.isInjection = true\n meta.injectionLang = injectionLang\n }\n if (containsInjection) {\n meta.containsInjection = true\n }\n if (concealValue !== undefined) {\n meta.conceal = concealValue\n }\n if (concealLines !== undefined) {\n meta.concealLines = concealLines\n }\n\n if (Object.keys(meta).length > 0) {\n highlights.push([node.startIndex, node.endIndex, match.name, meta])\n } else {\n highlights.push([node.startIndex, node.endIndex, match.name])\n }\n }\n\n highlights.sort((a, b) => a[0] - b[0])\n\n return highlights\n }\n\n async handleResetBuffer(\n bufferId: number,\n version: number,\n content: string,\n ): Promise<{ highlights?: HighlightResponse[]; warning?: string; error?: string }> {\n const parserState = this.bufferParsers.get(bufferId)\n if (!parserState) {\n return { warning: \"No parser state found for buffer\" }\n }\n\n parserState.content = content\n\n const newTree = parserState.parser.parse(content)\n\n if (!newTree) {\n return { error: \"Failed to parse buffer during reset\" }\n }\n\n parserState.tree = newTree\n const matches = parserState.queries.highlights.captures(parserState.tree.rootNode)\n\n let injectionRanges = new Map>()\n if (parserState.queries.injections) {\n const injectionResult = await this.processInjections(parserState)\n matches.push(...injectionResult.captures)\n injectionRanges = injectionResult.injectionRanges\n }\n\n return this.getHighlights(parserState, matches, injectionRanges)\n }\n\n disposeBuffer(bufferId: number): void {\n const parserState = this.bufferParsers.get(bufferId)\n if (!parserState) {\n return\n }\n\n parserState.tree.delete()\n parserState.parser.delete()\n\n this.bufferParsers.delete(bufferId)\n }\n\n async handleOneShotHighlight(content: string, filetype: string, messageId: string): Promise {\n const reusableState = await this.getReusableParser(filetype)\n\n if (!reusableState) {\n postWorkerMessage({\n type: \"ONESHOT_HIGHLIGHT_RESPONSE\",\n messageId,\n hasParser: false,\n warning: `No parser available for filetype ${filetype}`,\n })\n return\n }\n\n // Markdown Parser BUG: For markdown, ensure content ends with newline so closing delimiters are parsed correctly\n // The tree-sitter markdown parser only creates closing delimiter nodes when followed by newline\n const parseContent = filetype === \"markdown\" && content.endsWith(\"```\") ? content + \"\\n\" : content\n\n const tree = reusableState.parser.parse(parseContent)\n\n if (!tree) {\n postWorkerMessage({\n type: \"ONESHOT_HIGHLIGHT_RESPONSE\",\n messageId,\n hasParser: false,\n error: \"Failed to parse content\",\n })\n return\n }\n\n try {\n const matches = reusableState.filetypeParser.queries.highlights.captures(tree.rootNode)\n\n let injectionRanges = new Map>()\n if (reusableState.filetypeParser.queries.injections) {\n const parserState: ParserState = {\n parser: reusableState.parser,\n tree,\n queries: reusableState.filetypeParser.queries,\n filetype,\n content,\n injectionMapping: reusableState.filetypeParser.injectionMapping,\n }\n const injectionResult = await this.processInjections(parserState)\n\n matches.push(...injectionResult.captures)\n injectionRanges = injectionResult.injectionRanges\n }\n\n const highlights = this.getSimpleHighlights(matches, injectionRanges)\n\n postWorkerMessage({\n type: \"ONESHOT_HIGHLIGHT_RESPONSE\",\n messageId,\n hasParser: true,\n highlights,\n })\n } finally {\n tree.delete()\n }\n }\n\n async updateDataPath(dataPath: string): Promise {\n this.dataPath = dataPath\n this.tsDataPath = path.join(dataPath, \"tree-sitter\")\n\n try {\n await mkdir(path.join(this.tsDataPath, \"languages\"), { recursive: true })\n await mkdir(path.join(this.tsDataPath, \"queries\"), { recursive: true })\n } catch (error) {\n throw new Error(`Failed to update data path: ${error}`)\n }\n }\n\n async clearCache(): Promise {\n if (!this.dataPath || !this.tsDataPath) {\n throw new Error(\"No data path configured\")\n }\n\n const { rm } = await import(\"fs/promises\")\n\n try {\n const treeSitterPath = path.join(this.dataPath, \"tree-sitter\")\n\n await rm(treeSitterPath, { recursive: true, force: true })\n\n await mkdir(path.join(treeSitterPath, \"languages\"), { recursive: true })\n await mkdir(path.join(treeSitterPath, \"queries\"), { recursive: true })\n\n this.filetypeParsers.clear()\n this.filetypeParserPromises.clear()\n this.reusableParsers.clear()\n this.reusableParserPromises.clear()\n } catch (error) {\n throw new Error(`Failed to clear cache: ${error}`)\n }\n }\n}\n\nfunction logMessage(type: TreeSitterWorkerLogType, ...args: unknown[]): void {\n postWorkerMessage({\n type: \"WORKER_LOG\",\n logType: type,\n data: args,\n } satisfies TreeSitterWorkerResponse)\n}\n\nfunction postWorkerError(bufferId: number | undefined, error: unknown): void {\n postWorkerMessage({\n type: \"ERROR\",\n bufferId,\n error: error instanceof Error ? error.stack || error.message : String(error),\n } satisfies TreeSitterWorkerResponse)\n}\n\nif (isWorkerRuntime) {\n const worker = new ParserWorker()\n\n console.log = (...args) => logMessage(\"log\", ...args)\n console.error = (...args) => logMessage(\"error\", ...args)\n console.warn = (...args) => logMessage(\"warn\", ...args)\n\n setWorkerMessageHandler(async (event: WorkerMessageEvent) => {\n const message = event.data\n const messageType = String((event.data as { type?: unknown }).type ?? \"unknown\")\n\n try {\n switch (message.type) {\n case \"INIT\":\n try {\n await worker.initialize({ dataPath: message.dataPath })\n postWorkerMessage({ type: \"INIT_RESPONSE\" } satisfies TreeSitterWorkerResponse)\n } catch (error) {\n postWorkerMessage({\n type: \"INIT_RESPONSE\",\n error: error instanceof Error ? error.stack || error.message : String(error),\n } satisfies TreeSitterWorkerResponse)\n }\n break\n\n case \"ADD_FILETYPE_PARSER\":\n worker.addFiletypeParser(message.filetypeParser)\n break\n\n case \"PRELOAD_PARSER\": {\n const maybeParser = await worker.preloadParser(message.filetype)\n postWorkerMessage({\n type: \"PRELOAD_PARSER_RESPONSE\",\n messageId: message.messageId,\n hasParser: !!maybeParser,\n } satisfies TreeSitterWorkerResponse)\n break\n }\n\n case \"INITIALIZE_PARSER\":\n await worker.handleInitializeParser(\n message.bufferId,\n message.version,\n message.content,\n message.filetype,\n message.messageId,\n )\n break\n\n case \"HANDLE_EDITS\": {\n const response = await worker.handleEdits(message.bufferId, message.content, message.edits)\n if (response.highlights && response.highlights.length > 0) {\n postWorkerMessage({\n type: \"HIGHLIGHT_RESPONSE\",\n bufferId: message.bufferId,\n version: message.version,\n highlights: response.highlights,\n } satisfies TreeSitterWorkerResponse)\n } else if (response.warning) {\n postWorkerMessage({\n type: \"WARNING\",\n bufferId: message.bufferId,\n warning: response.warning,\n } satisfies TreeSitterWorkerResponse)\n } else if (response.error) {\n postWorkerMessage({\n type: \"ERROR\",\n bufferId: message.bufferId,\n error: response.error,\n } satisfies TreeSitterWorkerResponse)\n }\n break\n }\n\n case \"GET_PERFORMANCE\":\n postWorkerMessage({\n type: \"PERFORMANCE_RESPONSE\",\n performance: worker.performance,\n messageId: message.messageId,\n } satisfies TreeSitterWorkerResponse)\n break\n\n case \"RESET_BUFFER\": {\n const resetResponse = await worker.handleResetBuffer(message.bufferId, message.version, message.content)\n if (resetResponse.highlights && resetResponse.highlights.length > 0) {\n postWorkerMessage({\n type: \"HIGHLIGHT_RESPONSE\",\n bufferId: message.bufferId,\n version: message.version,\n highlights: resetResponse.highlights,\n } satisfies TreeSitterWorkerResponse)\n } else if (resetResponse.warning) {\n postWorkerMessage({\n type: \"WARNING\",\n bufferId: message.bufferId,\n warning: resetResponse.warning,\n } satisfies TreeSitterWorkerResponse)\n } else if (resetResponse.error) {\n postWorkerMessage({\n type: \"ERROR\",\n bufferId: message.bufferId,\n error: resetResponse.error,\n } satisfies TreeSitterWorkerResponse)\n }\n break\n }\n\n case \"DISPOSE_BUFFER\":\n worker.disposeBuffer(message.bufferId)\n postWorkerMessage({\n type: \"BUFFER_DISPOSED\",\n bufferId: message.bufferId,\n } satisfies TreeSitterWorkerResponse)\n break\n\n case \"ONESHOT_HIGHLIGHT\":\n await worker.handleOneShotHighlight(message.content, message.filetype, message.messageId)\n break\n\n case \"UPDATE_DATA_PATH\":\n try {\n await worker.updateDataPath(message.dataPath)\n postWorkerMessage({\n type: \"UPDATE_DATA_PATH_RESPONSE\",\n messageId: message.messageId,\n } satisfies TreeSitterWorkerResponse)\n } catch (error) {\n postWorkerMessage({\n type: \"UPDATE_DATA_PATH_RESPONSE\",\n messageId: message.messageId,\n error: error instanceof Error ? error.message : String(error),\n } satisfies TreeSitterWorkerResponse)\n }\n break\n\n case \"CLEAR_CACHE\":\n try {\n await worker.clearCache()\n postWorkerMessage({\n type: \"CLEAR_CACHE_RESPONSE\",\n messageId: message.messageId,\n } satisfies TreeSitterWorkerResponse)\n } catch (error) {\n postWorkerMessage({\n type: \"CLEAR_CACHE_RESPONSE\",\n messageId: message.messageId,\n error: error instanceof Error ? error.message : String(error),\n } satisfies TreeSitterWorkerResponse)\n }\n break\n\n default:\n postWorkerMessage({\n type: \"ERROR\",\n error: `Unknown message type: ${messageType}`,\n } satisfies TreeSitterWorkerResponse)\n }\n } catch (error) {\n if (\"bufferId\" in message) {\n postWorkerError(message.bufferId, error)\n } else {\n postWorkerError(undefined, error)\n }\n }\n })\n}\n", + "import { mkdir, readFile, writeFile } from \"fs/promises\"\nimport * as path from \"path\"\n\nexport interface DownloadResult {\n content?: Buffer\n filePath?: string\n error?: string\n}\n\nexport class DownloadUtils {\n private static hashUrl(url: string): string {\n let hash = 0\n for (let i = 0; i < url.length; i++) {\n const char = url.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash\n }\n return Math.abs(hash).toString(16)\n }\n\n /**\n * Download a file from URL or load from local path, with caching support\n */\n static async downloadOrLoad(\n source: string,\n cacheDir: string,\n cacheSubdir: string,\n fileExtension: string,\n useHashForCache: boolean = true,\n filetype?: string,\n ): Promise {\n const isUrl = source.startsWith(\"http://\") || source.startsWith(\"https://\")\n\n if (isUrl) {\n let cacheFileName: string\n if (useHashForCache) {\n const hash = this.hashUrl(source)\n cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`\n } else {\n cacheFileName = path.basename(source)\n }\n const cacheFile = path.join(cacheDir, cacheSubdir, cacheFileName)\n\n // Ensure cache directory exists\n await mkdir(path.dirname(cacheFile), { recursive: true })\n\n try {\n const cachedContent = await readFile(cacheFile)\n if (cachedContent.byteLength > 0) {\n console.log(`Loaded from cache: ${cacheFile} (${source})`)\n return { content: cachedContent, filePath: cacheFile }\n }\n } catch (error) {\n // Cache miss, continue to fetch\n }\n\n try {\n console.log(`Downloading from URL: ${source}`)\n const response = await fetch(source)\n if (!response.ok) {\n return { error: `Failed to fetch from ${source}: ${response.statusText}` }\n }\n const content = Buffer.from(await response.arrayBuffer())\n\n try {\n await writeFile(cacheFile, Buffer.from(content))\n console.log(`Cached: ${source}`)\n } catch (cacheError) {\n console.warn(`Failed to cache: ${cacheError}`)\n }\n\n return { content, filePath: cacheFile }\n } catch (error) {\n return { error: `Error downloading from ${source}: ${error}` }\n }\n } else {\n try {\n console.log(`Loading from local path: ${source}`)\n const content = await readFile(source)\n return { content, filePath: source }\n } catch (error) {\n return { error: `Error loading from local path ${source}: ${error}` }\n }\n }\n }\n\n /**\n * Download and save a file to a specific target path\n */\n static async downloadToPath(source: string, targetPath: string): Promise {\n const isUrl = source.startsWith(\"http://\") || source.startsWith(\"https://\")\n\n await mkdir(path.dirname(targetPath), { recursive: true })\n\n if (isUrl) {\n try {\n console.log(`Downloading from URL: ${source}`)\n const response = await fetch(source)\n if (!response.ok) {\n return { error: `Failed to fetch from ${source}: ${response.statusText}` }\n }\n const content = Buffer.from(await response.arrayBuffer())\n\n await writeFile(targetPath, Buffer.from(content))\n console.log(`Downloaded: ${source} -> ${targetPath}`)\n\n return { content, filePath: targetPath }\n } catch (error) {\n return { error: `Error downloading from ${source}: ${error}` }\n }\n } else {\n try {\n console.log(`Copying from local path: ${source}`)\n const content = await readFile(source)\n await writeFile(targetPath, Buffer.from(content))\n return { content, filePath: targetPath }\n } catch (error) {\n return { error: `Error copying from local path ${source}: ${error}` }\n }\n }\n }\n\n /**\n * Fetch multiple highlight queries and concatenate them\n */\n static async fetchHighlightQueries(sources: string[], cacheDir: string, filetype: string): Promise {\n const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype))\n const queryResults = await Promise.all(queryPromises)\n\n const validQueries = queryResults.filter((query) => query.trim().length > 0)\n return validQueries.join(\"\\n\")\n }\n\n private static async fetchHighlightQuery(source: string, cacheDir: string, filetype: string): Promise {\n const result = await this.downloadOrLoad(source, cacheDir, \"queries\", \".scm\", true, filetype)\n\n if (result.error) {\n console.error(`Error fetching highlight query from ${source}:`, result.error)\n return \"\"\n }\n\n if (result.content) {\n return new TextDecoder().decode(result.content)\n }\n\n return \"\"\n }\n}\n", + "import { basename, join } from \"node:path\"\n\nexport function isBunfsPath(path: string): boolean {\n // Removed ambiguous '//' check\n return path.includes(\"$bunfs\") || /^B:[\\\\/]~BUN/i.test(path)\n}\n\nexport function getBunfsRootPath(): string {\n return process.platform === \"win32\" ? \"B:\\\\~BUN\\\\root\" : \"/$bunfs/root\"\n}\n\n/**\n * Normalizes a path to the embedded root.\n * Flattens directory structure to ensure file exists at root.\n */\nexport function normalizeBunfsPath(fileName: string): string {\n return join(getBunfsRootPath(), basename(fileName))\n}\n", + "import { existsSync } from \"node:fs\"\nimport { mkdir, writeFile as writeFileNode } from \"node:fs/promises\"\nimport { dirname, isAbsolute, resolve } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\n\nimport stringWidthLib from \"string-width\"\nimport stripAnsiLib from \"strip-ansi\"\n\nexport interface WriteFileOptions {\n createPath?: boolean\n mode?: number\n}\n\ninterface BunLike {\n sleep(msOrDate: number | Date): Promise\n stringWidth(text: string): number\n stripANSI(text: string): string\n write(destination: string | URL, data: string | ArrayBufferView, options?: WriteFileOptions): Promise\n}\n\ninterface FileImportModule {\n default: string\n}\n\ntype FilePathFallback = string | URL | (() => string | URL)\n\ntype GlobalWithBun = typeof globalThis & { Bun?: BunLike }\n\nconst TEXT_ENCODER = new TextEncoder()\nconst bun = (globalThis as GlobalWithBun).Bun\n\nexport const sleep: (msOrDate: number | Date) => Promise = bun?.sleep ?? standardSleep\nexport const stringWidth: (text: string) => number = bun?.stringWidth ?? stringWidthLib\nexport const stripANSI: (text: string) => string = bun?.stripANSI ?? stripAnsiLib\nexport const writeFile: (\n destination: string | URL,\n data: string | ArrayBufferView,\n options?: WriteFileOptions,\n) => Promise = bun?.write ?? writeFilePortable\n\n// Bun only discovers bundled file-like assets from the literal import expression at the call site.\nexport async function resolveBundledFilePath(\n loadBundledFile: () => Promise,\n fallbackPath: FilePathFallback,\n metaUrl: string,\n): Promise {\n if (!bun) {\n const path = resolveFallbackFilePath(fallbackPath, metaUrl)\n if (existsSync(path)) {\n return path\n }\n\n return (await loadBundledFilePath(loadBundledFile, metaUrl)) ?? path\n }\n\n return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl)\n}\n\nfunction resolveFallbackFilePath(fallbackPath: FilePathFallback, metaUrl: string): string {\n const path = typeof fallbackPath === \"function\" ? fallbackPath() : fallbackPath\n return fileURLToPath(path instanceof URL ? path : new URL(path, metaUrl))\n}\n\nfunction normalizeLoadedFilePath(loadedPath: string, baseUrl: string): string {\n if (loadedPath.startsWith(\"file:\")) {\n return fileURLToPath(loadedPath)\n }\n\n if (isAbsolute(loadedPath)) {\n return loadedPath\n }\n\n return resolve(dirname(fileURLToPath(baseUrl)), loadedPath)\n}\n\nasync function loadBundledFilePath(\n loadBundledFile: () => Promise,\n metaUrl: string,\n): Promise {\n const specifier = extractBundledImportSpecifier(loadBundledFile)\n if (!specifier) {\n return undefined\n }\n\n try {\n const moduleUrl = new URL(specifier, metaUrl)\n const loaded = (await import(moduleUrl.href)) as FileImportModule\n return normalizeLoadedFilePath(loaded.default, moduleUrl.href)\n } catch {\n return undefined\n }\n}\n\nfunction extractBundledImportSpecifier(loadBundledFile: () => Promise): string | undefined {\n const match = String(loadBundledFile).match(/\\bimport\\(\\s*([\"'`])([^\"'`]+)\\1/)\n return match?.[2]\n}\n\nfunction standardSleep(msOrDate: number | Date): Promise {\n const ms = msOrDate instanceof Date ? msOrDate.getTime() - Date.now() : msOrDate\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nasync function writeFilePortable(\n destination: string | URL,\n data: string | ArrayBufferView,\n options?: WriteFileOptions,\n): Promise {\n const destinationPath = destination instanceof URL ? fileURLToPath(destination) : destination\n\n if (options?.createPath) {\n await mkdir(dirname(destinationPath), { recursive: true })\n }\n\n const bytes =\n typeof data === \"string\" ? TEXT_ENCODER.encode(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength)\n\n await writeFileNode(destinationPath, bytes, { mode: options?.mode })\n\n return bytes.byteLength\n}\n", + "export default function ansiRegex({onlyFirst = false} = {}) {\n\t// Valid string terminator sequences are BEL, ESC\\, and 0x9c\n\tconst ST = '(?:\\\\u0007|\\\\u001B\\\\u005C|\\\\u009C)';\n\n\t// OSC sequences only: ESC ] ... ST (non-greedy until the first ST)\n\tconst osc = `(?:\\\\u001B\\\\][\\\\s\\\\S]*?${ST})`;\n\n\t// CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte\n\tconst csi = '[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:\\\\d{1,4}(?:[;:]\\\\d{0,4})*)?[\\\\dA-PR-TZcf-nq-uy=><~]';\n\n\tconst pattern = `${osc}|${csi}`;\n\n\treturn new RegExp(pattern, onlyFirst ? undefined : 'g');\n}\n", + "import ansiRegex from 'ansi-regex';\n\nconst regex = ansiRegex();\n\nexport default function stripAnsi(string) {\n\tif (typeof string !== 'string') {\n\t\tthrow new TypeError(`Expected a \\`string\\`, got \\`${typeof string}\\``);\n\t}\n\n\t// Even though the regex is global, we don't need to reset the `.lastIndex`\n\t// because unlike `.exec()` and `.test()`, `.replace()` does it automatically\n\t// and doing it manually has a performance penalty.\n\treturn string.replace(regex, '');\n}\n", + "// Generated code.\n\nfunction isAmbiguous(x) {\n\treturn x === 0xA1\n\t\t|| x === 0xA4\n\t\t|| x === 0xA7\n\t\t|| x === 0xA8\n\t\t|| x === 0xAA\n\t\t|| x === 0xAD\n\t\t|| x === 0xAE\n\t\t|| x >= 0xB0 && x <= 0xB4\n\t\t|| x >= 0xB6 && x <= 0xBA\n\t\t|| x >= 0xBC && x <= 0xBF\n\t\t|| x === 0xC6\n\t\t|| x === 0xD0\n\t\t|| x === 0xD7\n\t\t|| x === 0xD8\n\t\t|| x >= 0xDE && x <= 0xE1\n\t\t|| x === 0xE6\n\t\t|| x >= 0xE8 && x <= 0xEA\n\t\t|| x === 0xEC\n\t\t|| x === 0xED\n\t\t|| x === 0xF0\n\t\t|| x === 0xF2\n\t\t|| x === 0xF3\n\t\t|| x >= 0xF7 && x <= 0xFA\n\t\t|| x === 0xFC\n\t\t|| x === 0xFE\n\t\t|| x === 0x101\n\t\t|| x === 0x111\n\t\t|| x === 0x113\n\t\t|| x === 0x11B\n\t\t|| x === 0x126\n\t\t|| x === 0x127\n\t\t|| x === 0x12B\n\t\t|| x >= 0x131 && x <= 0x133\n\t\t|| x === 0x138\n\t\t|| x >= 0x13F && x <= 0x142\n\t\t|| x === 0x144\n\t\t|| x >= 0x148 && x <= 0x14B\n\t\t|| x === 0x14D\n\t\t|| x === 0x152\n\t\t|| x === 0x153\n\t\t|| x === 0x166\n\t\t|| x === 0x167\n\t\t|| x === 0x16B\n\t\t|| x === 0x1CE\n\t\t|| x === 0x1D0\n\t\t|| x === 0x1D2\n\t\t|| x === 0x1D4\n\t\t|| x === 0x1D6\n\t\t|| x === 0x1D8\n\t\t|| x === 0x1DA\n\t\t|| x === 0x1DC\n\t\t|| x === 0x251\n\t\t|| x === 0x261\n\t\t|| x === 0x2C4\n\t\t|| x === 0x2C7\n\t\t|| x >= 0x2C9 && x <= 0x2CB\n\t\t|| x === 0x2CD\n\t\t|| x === 0x2D0\n\t\t|| x >= 0x2D8 && x <= 0x2DB\n\t\t|| x === 0x2DD\n\t\t|| x === 0x2DF\n\t\t|| x >= 0x300 && x <= 0x36F\n\t\t|| x >= 0x391 && x <= 0x3A1\n\t\t|| x >= 0x3A3 && x <= 0x3A9\n\t\t|| x >= 0x3B1 && x <= 0x3C1\n\t\t|| x >= 0x3C3 && x <= 0x3C9\n\t\t|| x === 0x401\n\t\t|| x >= 0x410 && x <= 0x44F\n\t\t|| x === 0x451\n\t\t|| x === 0x2010\n\t\t|| x >= 0x2013 && x <= 0x2016\n\t\t|| x === 0x2018\n\t\t|| x === 0x2019\n\t\t|| x === 0x201C\n\t\t|| x === 0x201D\n\t\t|| x >= 0x2020 && x <= 0x2022\n\t\t|| x >= 0x2024 && x <= 0x2027\n\t\t|| x === 0x2030\n\t\t|| x === 0x2032\n\t\t|| x === 0x2033\n\t\t|| x === 0x2035\n\t\t|| x === 0x203B\n\t\t|| x === 0x203E\n\t\t|| x === 0x2074\n\t\t|| x === 0x207F\n\t\t|| x >= 0x2081 && x <= 0x2084\n\t\t|| x === 0x20AC\n\t\t|| x === 0x2103\n\t\t|| x === 0x2105\n\t\t|| x === 0x2109\n\t\t|| x === 0x2113\n\t\t|| x === 0x2116\n\t\t|| x === 0x2121\n\t\t|| x === 0x2122\n\t\t|| x === 0x2126\n\t\t|| x === 0x212B\n\t\t|| x === 0x2153\n\t\t|| x === 0x2154\n\t\t|| x >= 0x215B && x <= 0x215E\n\t\t|| x >= 0x2160 && x <= 0x216B\n\t\t|| x >= 0x2170 && x <= 0x2179\n\t\t|| x === 0x2189\n\t\t|| x >= 0x2190 && x <= 0x2199\n\t\t|| x === 0x21B8\n\t\t|| x === 0x21B9\n\t\t|| x === 0x21D2\n\t\t|| x === 0x21D4\n\t\t|| x === 0x21E7\n\t\t|| x === 0x2200\n\t\t|| x === 0x2202\n\t\t|| x === 0x2203\n\t\t|| x === 0x2207\n\t\t|| x === 0x2208\n\t\t|| x === 0x220B\n\t\t|| x === 0x220F\n\t\t|| x === 0x2211\n\t\t|| x === 0x2215\n\t\t|| x === 0x221A\n\t\t|| x >= 0x221D && x <= 0x2220\n\t\t|| x === 0x2223\n\t\t|| x === 0x2225\n\t\t|| x >= 0x2227 && x <= 0x222C\n\t\t|| x === 0x222E\n\t\t|| x >= 0x2234 && x <= 0x2237\n\t\t|| x === 0x223C\n\t\t|| x === 0x223D\n\t\t|| x === 0x2248\n\t\t|| x === 0x224C\n\t\t|| x === 0x2252\n\t\t|| x === 0x2260\n\t\t|| x === 0x2261\n\t\t|| x >= 0x2264 && x <= 0x2267\n\t\t|| x === 0x226A\n\t\t|| x === 0x226B\n\t\t|| x === 0x226E\n\t\t|| x === 0x226F\n\t\t|| x === 0x2282\n\t\t|| x === 0x2283\n\t\t|| x === 0x2286\n\t\t|| x === 0x2287\n\t\t|| x === 0x2295\n\t\t|| x === 0x2299\n\t\t|| x === 0x22A5\n\t\t|| x === 0x22BF\n\t\t|| x === 0x2312\n\t\t|| x >= 0x2460 && x <= 0x24E9\n\t\t|| x >= 0x24EB && x <= 0x254B\n\t\t|| x >= 0x2550 && x <= 0x2573\n\t\t|| x >= 0x2580 && x <= 0x258F\n\t\t|| x >= 0x2592 && x <= 0x2595\n\t\t|| x === 0x25A0\n\t\t|| x === 0x25A1\n\t\t|| x >= 0x25A3 && x <= 0x25A9\n\t\t|| x === 0x25B2\n\t\t|| x === 0x25B3\n\t\t|| x === 0x25B6\n\t\t|| x === 0x25B7\n\t\t|| x === 0x25BC\n\t\t|| x === 0x25BD\n\t\t|| x === 0x25C0\n\t\t|| x === 0x25C1\n\t\t|| x >= 0x25C6 && x <= 0x25C8\n\t\t|| x === 0x25CB\n\t\t|| x >= 0x25CE && x <= 0x25D1\n\t\t|| x >= 0x25E2 && x <= 0x25E5\n\t\t|| x === 0x25EF\n\t\t|| x === 0x2605\n\t\t|| x === 0x2606\n\t\t|| x === 0x2609\n\t\t|| x === 0x260E\n\t\t|| x === 0x260F\n\t\t|| x === 0x261C\n\t\t|| x === 0x261E\n\t\t|| x === 0x2640\n\t\t|| x === 0x2642\n\t\t|| x === 0x2660\n\t\t|| x === 0x2661\n\t\t|| x >= 0x2663 && x <= 0x2665\n\t\t|| x >= 0x2667 && x <= 0x266A\n\t\t|| x === 0x266C\n\t\t|| x === 0x266D\n\t\t|| x === 0x266F\n\t\t|| x === 0x269E\n\t\t|| x === 0x269F\n\t\t|| x === 0x26BF\n\t\t|| x >= 0x26C6 && x <= 0x26CD\n\t\t|| x >= 0x26CF && x <= 0x26D3\n\t\t|| x >= 0x26D5 && x <= 0x26E1\n\t\t|| x === 0x26E3\n\t\t|| x === 0x26E8\n\t\t|| x === 0x26E9\n\t\t|| x >= 0x26EB && x <= 0x26F1\n\t\t|| x === 0x26F4\n\t\t|| x >= 0x26F6 && x <= 0x26F9\n\t\t|| x === 0x26FB\n\t\t|| x === 0x26FC\n\t\t|| x === 0x26FE\n\t\t|| x === 0x26FF\n\t\t|| x === 0x273D\n\t\t|| x >= 0x2776 && x <= 0x277F\n\t\t|| x >= 0x2B56 && x <= 0x2B59\n\t\t|| x >= 0x3248 && x <= 0x324F\n\t\t|| x >= 0xE000 && x <= 0xF8FF\n\t\t|| x >= 0xFE00 && x <= 0xFE0F\n\t\t|| x === 0xFFFD\n\t\t|| x >= 0x1F100 && x <= 0x1F10A\n\t\t|| x >= 0x1F110 && x <= 0x1F12D\n\t\t|| x >= 0x1F130 && x <= 0x1F169\n\t\t|| x >= 0x1F170 && x <= 0x1F18D\n\t\t|| x === 0x1F18F\n\t\t|| x === 0x1F190\n\t\t|| x >= 0x1F19B && x <= 0x1F1AC\n\t\t|| x >= 0xE0100 && x <= 0xE01EF\n\t\t|| x >= 0xF0000 && x <= 0xFFFFD\n\t\t|| x >= 0x100000 && x <= 0x10FFFD;\n}\n\nfunction isFullWidth(x) {\n\treturn x === 0x3000\n\t\t|| x >= 0xFF01 && x <= 0xFF60\n\t\t|| x >= 0xFFE0 && x <= 0xFFE6;\n}\n\nfunction isWide(x) {\n\treturn x >= 0x1100 && x <= 0x115F\n\t\t|| x === 0x231A\n\t\t|| x === 0x231B\n\t\t|| x === 0x2329\n\t\t|| x === 0x232A\n\t\t|| x >= 0x23E9 && x <= 0x23EC\n\t\t|| x === 0x23F0\n\t\t|| x === 0x23F3\n\t\t|| x === 0x25FD\n\t\t|| x === 0x25FE\n\t\t|| x === 0x2614\n\t\t|| x === 0x2615\n\t\t|| x >= 0x2630 && x <= 0x2637\n\t\t|| x >= 0x2648 && x <= 0x2653\n\t\t|| x === 0x267F\n\t\t|| x >= 0x268A && x <= 0x268F\n\t\t|| x === 0x2693\n\t\t|| x === 0x26A1\n\t\t|| x === 0x26AA\n\t\t|| x === 0x26AB\n\t\t|| x === 0x26BD\n\t\t|| x === 0x26BE\n\t\t|| x === 0x26C4\n\t\t|| x === 0x26C5\n\t\t|| x === 0x26CE\n\t\t|| x === 0x26D4\n\t\t|| x === 0x26EA\n\t\t|| x === 0x26F2\n\t\t|| x === 0x26F3\n\t\t|| x === 0x26F5\n\t\t|| x === 0x26FA\n\t\t|| x === 0x26FD\n\t\t|| x === 0x2705\n\t\t|| x === 0x270A\n\t\t|| x === 0x270B\n\t\t|| x === 0x2728\n\t\t|| x === 0x274C\n\t\t|| x === 0x274E\n\t\t|| x >= 0x2753 && x <= 0x2755\n\t\t|| x === 0x2757\n\t\t|| x >= 0x2795 && x <= 0x2797\n\t\t|| x === 0x27B0\n\t\t|| x === 0x27BF\n\t\t|| x === 0x2B1B\n\t\t|| x === 0x2B1C\n\t\t|| x === 0x2B50\n\t\t|| x === 0x2B55\n\t\t|| x >= 0x2E80 && x <= 0x2E99\n\t\t|| x >= 0x2E9B && x <= 0x2EF3\n\t\t|| x >= 0x2F00 && x <= 0x2FD5\n\t\t|| x >= 0x2FF0 && x <= 0x2FFF\n\t\t|| x >= 0x3001 && x <= 0x303E\n\t\t|| x >= 0x3041 && x <= 0x3096\n\t\t|| x >= 0x3099 && x <= 0x30FF\n\t\t|| x >= 0x3105 && x <= 0x312F\n\t\t|| x >= 0x3131 && x <= 0x318E\n\t\t|| x >= 0x3190 && x <= 0x31E5\n\t\t|| x >= 0x31EF && x <= 0x321E\n\t\t|| x >= 0x3220 && x <= 0x3247\n\t\t|| x >= 0x3250 && x <= 0xA48C\n\t\t|| x >= 0xA490 && x <= 0xA4C6\n\t\t|| x >= 0xA960 && x <= 0xA97C\n\t\t|| x >= 0xAC00 && x <= 0xD7A3\n\t\t|| x >= 0xF900 && x <= 0xFAFF\n\t\t|| x >= 0xFE10 && x <= 0xFE19\n\t\t|| x >= 0xFE30 && x <= 0xFE52\n\t\t|| x >= 0xFE54 && x <= 0xFE66\n\t\t|| x >= 0xFE68 && x <= 0xFE6B\n\t\t|| x >= 0x16FE0 && x <= 0x16FE4\n\t\t|| x >= 0x16FF0 && x <= 0x16FF6\n\t\t|| x >= 0x17000 && x <= 0x18CD5\n\t\t|| x >= 0x18CFF && x <= 0x18D1E\n\t\t|| x >= 0x18D80 && x <= 0x18DF2\n\t\t|| x >= 0x1AFF0 && x <= 0x1AFF3\n\t\t|| x >= 0x1AFF5 && x <= 0x1AFFB\n\t\t|| x === 0x1AFFD\n\t\t|| x === 0x1AFFE\n\t\t|| x >= 0x1B000 && x <= 0x1B122\n\t\t|| x === 0x1B132\n\t\t|| x >= 0x1B150 && x <= 0x1B152\n\t\t|| x === 0x1B155\n\t\t|| x >= 0x1B164 && x <= 0x1B167\n\t\t|| x >= 0x1B170 && x <= 0x1B2FB\n\t\t|| x >= 0x1D300 && x <= 0x1D356\n\t\t|| x >= 0x1D360 && x <= 0x1D376\n\t\t|| x === 0x1F004\n\t\t|| x === 0x1F0CF\n\t\t|| x === 0x1F18E\n\t\t|| x >= 0x1F191 && x <= 0x1F19A\n\t\t|| x >= 0x1F200 && x <= 0x1F202\n\t\t|| x >= 0x1F210 && x <= 0x1F23B\n\t\t|| x >= 0x1F240 && x <= 0x1F248\n\t\t|| x === 0x1F250\n\t\t|| x === 0x1F251\n\t\t|| x >= 0x1F260 && x <= 0x1F265\n\t\t|| x >= 0x1F300 && x <= 0x1F320\n\t\t|| x >= 0x1F32D && x <= 0x1F335\n\t\t|| x >= 0x1F337 && x <= 0x1F37C\n\t\t|| x >= 0x1F37E && x <= 0x1F393\n\t\t|| x >= 0x1F3A0 && x <= 0x1F3CA\n\t\t|| x >= 0x1F3CF && x <= 0x1F3D3\n\t\t|| x >= 0x1F3E0 && x <= 0x1F3F0\n\t\t|| x === 0x1F3F4\n\t\t|| x >= 0x1F3F8 && x <= 0x1F43E\n\t\t|| x === 0x1F440\n\t\t|| x >= 0x1F442 && x <= 0x1F4FC\n\t\t|| x >= 0x1F4FF && x <= 0x1F53D\n\t\t|| x >= 0x1F54B && x <= 0x1F54E\n\t\t|| x >= 0x1F550 && x <= 0x1F567\n\t\t|| x === 0x1F57A\n\t\t|| x === 0x1F595\n\t\t|| x === 0x1F596\n\t\t|| x === 0x1F5A4\n\t\t|| x >= 0x1F5FB && x <= 0x1F64F\n\t\t|| x >= 0x1F680 && x <= 0x1F6C5\n\t\t|| x === 0x1F6CC\n\t\t|| x >= 0x1F6D0 && x <= 0x1F6D2\n\t\t|| x >= 0x1F6D5 && x <= 0x1F6D8\n\t\t|| x >= 0x1F6DC && x <= 0x1F6DF\n\t\t|| x === 0x1F6EB\n\t\t|| x === 0x1F6EC\n\t\t|| x >= 0x1F6F4 && x <= 0x1F6FC\n\t\t|| x >= 0x1F7E0 && x <= 0x1F7EB\n\t\t|| x === 0x1F7F0\n\t\t|| x >= 0x1F90C && x <= 0x1F93A\n\t\t|| x >= 0x1F93C && x <= 0x1F945\n\t\t|| x >= 0x1F947 && x <= 0x1F9FF\n\t\t|| x >= 0x1FA70 && x <= 0x1FA7C\n\t\t|| x >= 0x1FA80 && x <= 0x1FA8A\n\t\t|| x >= 0x1FA8E && x <= 0x1FAC6\n\t\t|| x === 0x1FAC8\n\t\t|| x >= 0x1FACD && x <= 0x1FADC\n\t\t|| x >= 0x1FADF && x <= 0x1FAEA\n\t\t|| x >= 0x1FAEF && x <= 0x1FAF8\n\t\t|| x >= 0x20000 && x <= 0x2FFFD\n\t\t|| x >= 0x30000 && x <= 0x3FFFD;\n}\n\nfunction getCategory(x) {\n\tif (isAmbiguous(x)) return 'ambiguous';\n\n\tif (isFullWidth(x)) return 'fullwidth';\n\n\tif (\n\t\tx === 0x20A9\n\t\t|| x >= 0xFF61 && x <= 0xFFBE\n\t\t|| x >= 0xFFC2 && x <= 0xFFC7\n\t\t|| x >= 0xFFCA && x <= 0xFFCF\n\t\t|| x >= 0xFFD2 && x <= 0xFFD7\n\t\t|| x >= 0xFFDA && x <= 0xFFDC\n\t\t|| x >= 0xFFE8 && x <= 0xFFEE\n\t) {\n\t\treturn 'halfwidth';\n\t}\n\n\tif (\n\t\tx >= 0x20 && x <= 0x7E\n\t\t|| x === 0xA2\n\t\t|| x === 0xA3\n\t\t|| x === 0xA5\n\t\t|| x === 0xA6\n\t\t|| x === 0xAC\n\t\t|| x === 0xAF\n\t\t|| x >= 0x27E6 && x <= 0x27ED\n\t\t|| x === 0x2985\n\t\t|| x === 0x2986\n\t) {\n\t\treturn 'narrow';\n\t}\n\n\tif (isWide(x)) return 'wide';\n\n\treturn 'neutral';\n}\n\nexport {isAmbiguous, isFullWidth, isWide, getCategory};\n", + "import {getCategory, isAmbiguous, isFullWidth, isWide} from './lookup.js';\n\nfunction validate(codePoint) {\n\tif (!Number.isSafeInteger(codePoint)) {\n\t\tthrow new TypeError(`Expected a code point, got \\`${typeof codePoint}\\`.`);\n\t}\n}\n\nexport function eastAsianWidthType(codePoint) {\n\tvalidate(codePoint);\n\n\treturn getCategory(codePoint);\n}\n\nexport function eastAsianWidth(codePoint, {ambiguousAsWide = false} = {}) {\n\tvalidate(codePoint);\n\n\tif (\n\t\tisFullWidth(codePoint)\n\t\t|| isWide(codePoint)\n\t\t|| (ambiguousAsWide && isAmbiguous(codePoint))\n\t) {\n\t\treturn 2;\n\t}\n\n\treturn 1;\n}\n\n// Private exports for https://github.com/sindresorhus/is-fullwidth-code-point\nexport {isFullWidth as _isFullWidth, isWide as _isWide} from './lookup.js';\n", + "import stripAnsi from 'strip-ansi';\nimport {eastAsianWidth} from 'get-east-asian-width';\nimport emojiRegex from 'emoji-regex';\n\nconst segmenter = new Intl.Segmenter();\n\nconst defaultIgnorableCodePointRegex = /^\\p{Default_Ignorable_Code_Point}$/u;\n\nexport default function stringWidth(string, options = {}) {\n\tif (typeof string !== 'string' || string.length === 0) {\n\t\treturn 0;\n\t}\n\n\tconst {\n\t\tambiguousIsNarrow = true,\n\t\tcountAnsiEscapeCodes = false,\n\t} = options;\n\n\tif (!countAnsiEscapeCodes) {\n\t\tstring = stripAnsi(string);\n\t}\n\n\tif (string.length === 0) {\n\t\treturn 0;\n\t}\n\n\tlet width = 0;\n\tconst eastAsianWidthOptions = {ambiguousAsWide: !ambiguousIsNarrow};\n\n\tfor (const {segment: character} of segmenter.segment(string)) {\n\t\tconst codePoint = character.codePointAt(0);\n\n\t\t// Ignore control characters\n\t\tif (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore zero-width characters\n\t\tif (\n\t\t\t(codePoint >= 0x20_0B && codePoint <= 0x20_0F) // Zero-width space, non-joiner, joiner, left-to-right mark, right-to-left mark\n\t\t\t|| codePoint === 0xFE_FF // Zero-width no-break space\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore combining characters\n\t\tif (\n\t\t\t(codePoint >= 0x3_00 && codePoint <= 0x3_6F) // Combining diacritical marks\n\t\t\t|| (codePoint >= 0x1A_B0 && codePoint <= 0x1A_FF) // Combining diacritical marks extended\n\t\t\t|| (codePoint >= 0x1D_C0 && codePoint <= 0x1D_FF) // Combining diacritical marks supplement\n\t\t\t|| (codePoint >= 0x20_D0 && codePoint <= 0x20_FF) // Combining diacritical marks for symbols\n\t\t\t|| (codePoint >= 0xFE_20 && codePoint <= 0xFE_2F) // Combining half marks\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore surrogate pairs\n\t\tif (codePoint >= 0xD8_00 && codePoint <= 0xDF_FF) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore variation selectors\n\t\tif (codePoint >= 0xFE_00 && codePoint <= 0xFE_0F) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// This covers some of the above cases, but we still keep them for performance reasons.\n\t\tif (defaultIgnorableCodePointRegex.test(character)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// TODO: Use `/\\p{RGI_Emoji}/v` when targeting Node.js 20.\n\t\tif (emojiRegex().test(character)) {\n\t\t\twidth += 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\twidth += eastAsianWidth(codePoint, eastAsianWidthOptions);\n\t}\n\n\treturn width;\n}\n", + "export const WORKER_UNAVAILABLE = \"OpenTUI tree-sitter workers are not available for this runtime yet.\"\n\nexport interface WorkerMessageEvent {\n readonly data: T\n}\n\nexport interface WorkerErrorEvent {\n readonly error?: unknown\n readonly message: string\n}\n\nexport type WorkerMessageHandler = (event: WorkerMessageEvent) => void | Promise\nexport type WorkerErrorHandler = (event: WorkerErrorEvent) => void\n\ntype AnyWorkerMessageHandler = WorkerMessageHandler\n\nexport interface PlatformWorkerOptions {\n name?: string\n}\n\nexport interface PlatformWorkerHandle {\n onmessage: WorkerMessageHandler | null\n onerror: WorkerErrorHandler | null\n postMessage(value: unknown): void\n terminate(): void | Promise\n addEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void\n removeEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void\n}\n\nexport type PlatformWorkerConstructor = new (\n specifier: string | URL,\n options?: PlatformWorkerOptions,\n) => PlatformWorkerHandle\n\ninterface NodeMessagePort {\n postMessage(value: unknown): void\n on(event: \"message\", listener: (value: unknown) => void): void\n off(event: \"message\", listener: (value: unknown) => void): void\n}\n\ninterface NodeWorkerThread {\n postMessage(value: unknown): void\n on(event: \"message\", listener: (value: unknown) => void): void\n on(event: \"error\", listener: (error: Error) => void): void\n off(event: \"message\", listener: (value: unknown) => void): void\n off(event: \"error\", listener: (error: Error) => void): void\n terminate(): Promise\n}\n\ninterface NodeWorkerThreadsModule {\n Worker: new (\n filename: string,\n options: {\n eval: true\n type: \"module\"\n name?: string\n },\n ) => NodeWorkerThread\n readonly parentPort: NodeMessagePort | null\n readonly isMainThread: boolean\n}\n\ninterface WorkerRuntimeBridge {\n postMessage(value: unknown): void\n setMessageHandler(handler: WorkerMessageHandler): () => void\n}\n\ntype GlobalWithWorker = typeof globalThis & {\n Worker?: PlatformWorkerConstructor\n __opentuiWorkerMessageBridge?: true\n close?: () => void\n postMessage?: (value: unknown) => void\n}\n\ninterface NodePathModule {\n isAbsolute(path: string): boolean\n resolve(...paths: string[]): string\n}\n\ninterface NodeUrlModule {\n pathToFileURL(path: string): URL\n}\n\ninterface ProcessWithBuiltinModule {\n readonly getBuiltinModule?: (id: string) => unknown\n}\n\nconst globalWithWorker = globalThis as GlobalWithWorker\nconst nodeWorkerThreads = getBuiltinModule(\"node:worker_threads\")\nconst runtimeBridge = loadWorkerRuntime(nodeWorkerThreads)\n\nclass UnsupportedWorker implements PlatformWorkerHandle {\n public onmessage: WorkerMessageHandler | null = null\n public onerror: WorkerErrorHandler | null = null\n\n constructor() {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n postMessage(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n terminate(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n addEventListener(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n removeEventListener(): void {\n throw new Error(WORKER_UNAVAILABLE)\n }\n}\n\nexport const Worker: PlatformWorkerConstructor = loadWorkerConstructor()\nexport const isWorkerRuntime = runtimeBridge !== undefined\n\nexport function postWorkerMessage(value: unknown): void {\n if (!runtimeBridge) {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n runtimeBridge.postMessage(value)\n}\n\nexport function setWorkerMessageHandler(handler: WorkerMessageHandler): () => void {\n if (!runtimeBridge) {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n return runtimeBridge.setMessageHandler(handler)\n}\n\nfunction getBuiltinModule(id: string): T | undefined {\n if (typeof process === \"undefined\") {\n return undefined\n }\n\n const loader = (process as typeof process & ProcessWithBuiltinModule).getBuiltinModule\n if (typeof loader !== \"function\") {\n return undefined\n }\n\n try {\n return loader(id) as T\n } catch {\n return undefined\n }\n}\n\nfunction loadWorkerConstructor(): PlatformWorkerConstructor {\n if (typeof globalWithWorker.Worker === \"function\") {\n return globalWithWorker.Worker\n }\n\n if (nodeWorkerThreads) {\n return createNodeWorkerConstructor(nodeWorkerThreads)\n }\n\n return UnsupportedWorker\n}\n\nfunction createNodeWorkerConstructor(node: NodeWorkerThreadsModule): PlatformWorkerConstructor {\n return class NodeWorkerShim implements PlatformWorkerHandle {\n public onmessage: WorkerMessageHandler | null = null\n public onerror: WorkerErrorHandler | null = null\n\n private readonly errorListeners = new Set()\n private readonly messageListeners = new Set()\n private readonly worker: NodeWorkerThread\n private terminationPromise: Promise | undefined\n\n constructor(specifier: string | URL, options: PlatformWorkerOptions = {}) {\n const resolvedSpecifier = resolveWorkerImportSpecifier(specifier)\n\n this.worker = new node.Worker(createWorkerBootstrapSource(resolvedSpecifier), {\n eval: true,\n type: \"module\",\n name: options.name,\n })\n\n this.worker.on(\"message\", this.handleMessage)\n this.worker.on(\"error\", this.handleError)\n }\n\n postMessage(value: unknown): void {\n this.worker.postMessage(value)\n }\n\n terminate(): Promise {\n if (this.terminationPromise) {\n return this.terminationPromise\n }\n\n this.worker.off(\"message\", this.handleMessage)\n this.worker.off(\"error\", this.handleError)\n const termination = this.worker.terminate().catch((error: unknown) => {\n this.terminationPromise = undefined\n this.worker.on(\"message\", this.handleMessage)\n this.worker.on(\"error\", this.handleError)\n throw error\n })\n this.terminationPromise = termination\n return termination\n }\n\n addEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void {\n if (type === \"message\") {\n this.messageListeners.add(listener as WorkerMessageHandler)\n return\n }\n\n this.errorListeners.add(listener as WorkerErrorHandler)\n }\n\n removeEventListener(type: \"message\" | \"error\", listener: WorkerMessageHandler | WorkerErrorHandler): void {\n if (type === \"message\") {\n this.messageListeners.delete(listener as WorkerMessageHandler)\n return\n }\n\n this.errorListeners.delete(listener as WorkerErrorHandler)\n }\n\n private readonly handleMessage = (data: unknown): void => {\n const event: WorkerMessageEvent = { data }\n\n this.onmessage?.(event)\n\n for (const listener of this.messageListeners) {\n listener(event)\n }\n }\n\n private readonly handleError = (error: Error): void => {\n const event: WorkerErrorEvent = {\n error,\n message: error.message,\n }\n\n this.onerror?.(event)\n\n for (const listener of this.errorListeners) {\n listener(event)\n }\n }\n }\n}\n\nfunction createWorkerBootstrapSource(specifier: string): string {\n return `\n import { parentPort } from \"node:worker_threads\"\n\n const pendingMessages = []\n let messageHandler = null\n\n globalThis.self ??= globalThis\n globalThis.postMessage ??= (value) => parentPort?.postMessage(value)\n globalThis.__opentuiWorkerMessageBridge = true\n Object.defineProperty(globalThis, \"onmessage\", {\n configurable: true,\n get: () => messageHandler,\n set: (handler) => {\n messageHandler = typeof handler === \"function\" ? handler : null\n if (!messageHandler) return\n\n const messages = pendingMessages.splice(0)\n for (const data of messages) {\n messageHandler({ data })\n }\n },\n })\n parentPort?.on(\"message\", (data) => {\n if (messageHandler) {\n messageHandler({ data })\n } else {\n pendingMessages.push(data)\n }\n })\n\n await import(${JSON.stringify(specifier)})\n `\n}\n\nfunction resolveWorkerImportSpecifier(specifier: string | URL): string {\n if (specifier instanceof URL) {\n return specifier.href\n }\n\n if (isRuntimeSpecifier(specifier)) {\n return specifier\n }\n\n // The Node shim cannot infer the caller module URL for plain strings, so\n // relative override strings resolve from the current working directory.\n // Callers that need module-relative behavior should pass a URL instead.\n const nodePath = getBuiltinModule(\"node:path\")\n const nodeUrl = getBuiltinModule(\"node:url\")\n if (!nodePath || !nodeUrl) {\n throw new Error(WORKER_UNAVAILABLE)\n }\n\n const absolutePath = nodePath.isAbsolute(specifier) ? specifier : nodePath.resolve(specifier)\n\n return nodeUrl.pathToFileURL(absolutePath).href\n}\n\nfunction isRuntimeSpecifier(specifier: string): boolean {\n return (\n specifier.startsWith(\"file:\") ||\n specifier.startsWith(\"data:\") ||\n specifier.startsWith(\"node:\") ||\n specifier.startsWith(\"http:\") ||\n specifier.startsWith(\"https:\")\n )\n}\n\nfunction loadWorkerRuntime(node: NodeWorkerThreadsModule | undefined): WorkerRuntimeBridge | undefined {\n if (node?.parentPort && node.isMainThread === false) {\n if (globalWithWorker.__opentuiWorkerMessageBridge) {\n return createGlobalWorkerRuntimeBridge()\n }\n\n return {\n postMessage(value: unknown): void {\n node.parentPort?.postMessage(value)\n },\n setMessageHandler(handler: WorkerMessageHandler): () => void {\n const listener = (data: unknown): void => {\n void handler({ data: data as T })\n }\n\n node.parentPort?.on(\"message\", listener)\n\n return () => {\n node.parentPort?.off(\"message\", listener)\n }\n },\n }\n }\n\n if (!isGlobalWorkerRuntime()) {\n return undefined\n }\n\n return createGlobalWorkerRuntimeBridge()\n}\n\nfunction createGlobalWorkerRuntimeBridge(): WorkerRuntimeBridge {\n interface HandlerRegistration {\n active: boolean\n fallbackHandler: AnyWorkerMessageHandler | null\n listener: AnyWorkerMessageHandler\n previous?: HandlerRegistration\n }\n\n let currentRegistration: HandlerRegistration | undefined\n\n return {\n postMessage(value: unknown): void {\n globalWithWorker.postMessage?.(value)\n },\n setMessageHandler(handler: WorkerMessageHandler): () => void {\n const previousHandler = getGlobalWorkerMessageHandler()\n if (currentRegistration && previousHandler !== currentRegistration.listener) {\n currentRegistration = undefined\n }\n\n const listener: WorkerMessageHandler = (event): void => {\n const normalizedEvent = normalizeWorkerMessageEvent(event)\n void handler(normalizedEvent)\n }\n const registration: HandlerRegistration = {\n active: true,\n fallbackHandler: currentRegistration ? currentRegistration.fallbackHandler : previousHandler,\n listener,\n previous: currentRegistration,\n }\n\n currentRegistration = registration\n setGlobalWorkerMessageHandler(listener)\n\n return () => {\n registration.active = false\n if (currentRegistration !== registration || getGlobalWorkerMessageHandler() !== listener) {\n return\n }\n\n let previous = registration.previous\n while (previous && !previous.active) {\n previous = previous.previous\n }\n\n currentRegistration = previous\n setGlobalWorkerMessageHandler(previous?.listener ?? registration.fallbackHandler)\n }\n },\n }\n}\n\nfunction isGlobalWorkerRuntime(): boolean {\n if (typeof globalWithWorker.postMessage !== \"function\") {\n return false\n }\n\n return typeof document === \"undefined\" && typeof globalWithWorker.close === \"function\" && \"onmessage\" in globalThis\n}\n\nfunction normalizeWorkerMessageEvent(event: unknown): WorkerMessageEvent {\n if (event && typeof event === \"object\" && \"data\" in event) {\n return event as WorkerMessageEvent\n }\n\n return { data: event as T }\n}\n\nfunction getGlobalWorkerMessageHandler(): AnyWorkerMessageHandler | null {\n return ((globalThis as { onmessage?: unknown }).onmessage as AnyWorkerMessageHandler | null | undefined) ?? null\n}\n\nfunction setGlobalWorkerMessageHandler(handler: AnyWorkerMessageHandler | null): void {\n ;(globalThis as { onmessage?: unknown }).onmessage = handler\n}\n" + ], + "mappings": "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AAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,KAAK,QAAU,KAAK,QACpB,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,KAAK,QAAU,KAAK,QACpB,KAAK,QAAU,KAAK,QACpB,KAAK,QAAU,KAAK,QACpB,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,KAAK,QAAU,KAAK,QACpB,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,KAAK,QAAU,KAAK,QACpB,KA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", + "debugId": "0D88AD8518CAE38D64756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/.patches/@opentui/core/platform/ffi.d.ts b/.patches/@opentui/core/platform/ffi.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/platform/ffi.d.ts @@ -0,0 +1,129 @@ +declare const pointerBrand: unique symbol; +export type PointerInput = number | bigint; +export type Pointer = PointerInput & { + readonly [pointerBrand]: "Pointer"; +}; +type PointerSource = ArrayBufferLike | ArrayBufferView; +type BunPointer = number; +export declare const FFIType: { + readonly char: "char"; + readonly int8_t: "int8_t"; + readonly i8: "i8"; + readonly uint8_t: "uint8_t"; + readonly u8: "u8"; + readonly int16_t: "int16_t"; + readonly i16: "i16"; + readonly uint16_t: "uint16_t"; + readonly u16: "u16"; + readonly int32_t: "int32_t"; + readonly i32: "i32"; + readonly int: "int"; + readonly uint32_t: "uint32_t"; + readonly u32: "u32"; + readonly int64_t: "int64_t"; + readonly i64: "i64"; + readonly uint64_t: "uint64_t"; + readonly u64: "u64"; + readonly double: "double"; + readonly f64: "f64"; + readonly float: "float"; + readonly f32: "f32"; + readonly bool: "bool"; + readonly ptr: "ptr"; + readonly pointer: "pointer"; + readonly void: "void"; + readonly cstring: "cstring"; + readonly function: "function"; + readonly usize: "usize"; + readonly callback: "callback"; + readonly napi_env: "napi_env"; + readonly napi_value: "napi_value"; + readonly buffer: "buffer"; +}; +export type FFIType = (typeof FFIType)[keyof typeof FFIType]; +export type FFITypeOrString = FFIType; +export interface FFIFunction { + readonly args?: readonly FFITypeOrString[]; + readonly returns?: FFITypeOrString; + readonly ptr?: Pointer; + readonly threadsafe?: boolean; +} +export interface FFICallbackInstance { + readonly ptr: Pointer | null; + readonly threadsafe: boolean; + close(): void; +} +export interface Library> { + symbols: { + [K in keyof Fns]: (...args: any[]) => any; + }; + createCallback(callback: (...args: any[]) => any, definition: FFIFunction): FFICallbackInstance; + close(): void; +} +interface FfiBackend { + dlopen>(path: string | URL, symbols: Fns): Library; + ptr(value: PointerSource): Pointer; + suffix: string; + toArrayBuffer(pointer: Pointer, offset: number | undefined, length: number): ArrayBuffer; +} +interface BunFFIFunction { + readonly args?: readonly FFITypeOrString[]; + readonly returns?: FFITypeOrString; + readonly ptr?: BunPointer; + readonly threadsafe?: boolean; +} +interface BunFfiLibrary> { + symbols: { + [K in keyof Fns]: (...args: any[]) => any; + }; + close(): void; +} +interface BunFfiBackend { + JSCallback: new (callback: (...args: any[]) => any, definition: BunFFIFunction) => FFICallbackInstance; + dlopen>(path: string | URL, symbols: Fns): BunFfiLibrary; + ptr(value: PointerSource): Pointer; + suffix: string; + toArrayBuffer(pointer: BunPointer, offset: number | undefined, length: number): ArrayBuffer; +} +interface NodeFFIFunction { + readonly arguments: readonly string[]; + readonly return: string; +} +interface NodeDynamicLibrary { + close(): void; + registerCallback(signature: NodeFFIFunction, callback: (...args: any[]) => any): bigint; + unregisterCallback(pointer: bigint): void; +} +interface NodeFfiLibrary { + readonly lib: NodeDynamicLibrary; + readonly functions: Record any>; +} +interface NodeFfiBackend { + dlopen(path: string | null, symbols: Record): NodeFfiLibrary; + getRawPointer(source: ArrayBuffer): bigint; + suffix: string; + toArrayBuffer(pointer: bigint, length: number, copy?: boolean): ArrayBuffer; +} +export declare const FFI_UNAVAILABLE = "OpenTUI native FFI is not available for this runtime yet"; +export declare const BUN_DLOPEN_NULL = "Bun FFI backend does not support dlopen(null)"; +export declare const LIBRARY_CLOSED = "Cannot create FFI callback after library.close() has been called"; +export declare const NODE_CALLBACK_THREADSAFE = "Node FFI callbacks are same-thread only and do not support threadsafe callbacks"; +export declare const NODE_NAPI_UNSUPPORTED = "Node FFI backend does not support Bun N-API FFI types"; +export declare const NODE_POINTER_OVERRIDE = "Node FFI backend does not support FFIFunction.ptr overrides"; +export declare const NODE_POINTER_ARGUMENT = "Node FFI pointer arguments must be a Pointer, ArrayBuffer, or ArrayBufferView"; +export declare const NODE_PTR_VALUE = "node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values backed by ArrayBuffer"; +export declare const NODE_STRING_RETURN = "Node FFI backend does not normalize string return values (yet)"; +export declare const NODE_USIZE_UNSUPPORTED = "Node FFI backend does not support usize yet"; +export declare const POINTER_NEGATIVE = "Pointer must be non-negative"; +export declare const POINTER_OFFSET_NEGATIVE = "Pointer offset must be non-negative"; +export declare const POINTER_OFFSET_UNSAFE = "Pointer offset must be a safe integer"; +export declare const POINTER_UNSAFE = "Pointer exceeds safe integer range"; +export declare function toPointer(value: PointerInput): Pointer; +export declare function ffiBool(value: boolean): 0 | 1; +export declare function createBunBackend(bun: BunFfiBackend): FfiBackend; +export declare function createNodeBackend(nodeFfi: NodeFfiBackend): FfiBackend; +export declare const dlopen: >(path: string | URL, symbols: Fns) => Library; +export declare const ptr: (value: PointerSource) => Pointer; +export declare const suffix: string; +export declare const toArrayBuffer: (pointer: Pointer, offset: number | undefined, length: number) => ArrayBuffer; +export {}; diff --git a/.patches/@opentui/core/platform/runtime.d.ts b/.patches/@opentui/core/platform/runtime.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/platform/runtime.d.ts @@ -0,0 +1,14 @@ +export interface WriteFileOptions { + createPath?: boolean; + mode?: number; +} +interface FileImportModule { + default: string; +} +type FilePathFallback = string | URL | (() => string | URL); +export declare const sleep: (msOrDate: number | Date) => Promise; +export declare const stringWidth: (text: string) => number; +export declare const stripANSI: (text: string) => string; +export declare const writeFile: (destination: string | URL, data: string | ArrayBufferView, options?: WriteFileOptions) => Promise; +export declare function resolveBundledFilePath(loadBundledFile: () => Promise, fallbackPath: FilePathFallback, metaUrl: string): Promise; +export {}; diff --git a/.patches/@opentui/core/platform/test.d.ts b/.patches/@opentui/core/platform/test.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/platform/test.d.ts @@ -0,0 +1,12 @@ +import { after, afterEach, before, beforeEach, describe, it, test } from "node:test"; +type ThrowMatcher = RegExp | string | Error | ((value: unknown) => boolean) | (new (...args: any[]) => Error); +declare class Expectation { + private readonly received; + constructor(received: T); + toBe(expected: T): void; + toBeNull(): void; + toEqual(expected: unknown): void; + toThrow(expected?: ThrowMatcher): void; +} +export declare function expect(received: T): Expectation; +export { after, afterEach, before, beforeEach, describe, it, test }; diff --git a/.patches/@opentui/core/platform/worker.d.ts b/.patches/@opentui/core/platform/worker.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/platform/worker.d.ts @@ -0,0 +1,26 @@ +export declare const WORKER_UNAVAILABLE = "OpenTUI tree-sitter workers are not available for this runtime yet."; +export interface WorkerMessageEvent { + readonly data: T; +} +export interface WorkerErrorEvent { + readonly error?: unknown; + readonly message: string; +} +export type WorkerMessageHandler = (event: WorkerMessageEvent) => void | Promise; +export type WorkerErrorHandler = (event: WorkerErrorEvent) => void; +export interface PlatformWorkerOptions { + name?: string; +} +export interface PlatformWorkerHandle { + onmessage: WorkerMessageHandler | null; + onerror: WorkerErrorHandler | null; + postMessage(value: unknown): void; + terminate(): void | Promise; + addEventListener(type: "message" | "error", listener: WorkerMessageHandler | WorkerErrorHandler): void; + removeEventListener(type: "message" | "error", listener: WorkerMessageHandler | WorkerErrorHandler): void; +} +export type PlatformWorkerConstructor = new (specifier: string | URL, options?: PlatformWorkerOptions) => PlatformWorkerHandle; +export declare const Worker: PlatformWorkerConstructor; +export declare const isWorkerRuntime: boolean; +export declare function postWorkerMessage(value: unknown): void; +export declare function setWorkerMessageHandler(handler: WorkerMessageHandler): () => void; diff --git a/.patches/@opentui/core/platform/worker.node-test.d.ts b/.patches/@opentui/core/platform/worker.node-test.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/platform/worker.node-test.d.ts @@ -0,0 +1,1 @@ +export {}; diff --git a/.patches/@opentui/core/plugins/core-slot.d.ts b/.patches/@opentui/core/plugins/core-slot.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/plugins/core-slot.d.ts @@ -0,0 +1,72 @@ +import { BaseRenderable, Renderable, type RenderableOptions } from "../Renderable.js"; +import type { CliRenderer } from "../renderer.js"; +import type { RenderContext } from "../types.js"; +import { SlotRegistry, type SlotRegistryOptions } from "./registry.js"; +import type { PluginContext, PluginErrorEvent, SlotMode } from "./types.js"; +export type CoreSlotMode = SlotMode; +type CoreSlotProps = { + [K in TSlotName]: TData; +}; +export type CoreSlotRegistry> = SlotRegistry, TContext>; +export type CoreSlotRenderer> = (ctx: Readonly, data: TData) => BaseRenderable; +export interface CoreManagedSlot> { + render: CoreSlotRenderer; + onActivate?: (ctx: Readonly) => void; + onDeactivate?: (ctx: Readonly) => void; + onDispose?: (ctx: Readonly) => void; +} +export type CoreSlotContribution> = CoreSlotRenderer | CoreManagedSlot; +export interface CorePlugin> { + id: string; + order?: number; + setup?: (ctx: Readonly, renderer: CliRenderer) => void; + dispose?: () => void; + slots: Partial>>; +} +export interface CoreResolvedSlotRenderer> { + id: string; + renderer: CoreSlotRenderer; +} +type FallbackNodes = BaseRenderable | BaseRenderable[] | undefined; +export type CoreSlotFailurePlaceholder = (failure: PluginErrorEvent, ctx: Readonly) => FallbackNodes; +export declare function createCoreSlotRegistry>(renderer: CliRenderer, context: TContext, options?: SlotRegistryOptions): CoreSlotRegistry; +export declare function registerCorePlugin>(registry: CoreSlotRegistry, plugin: CorePlugin): () => void; +export declare function resolveCoreSlot>(registry: CoreSlotRegistry, slot: K): Array>; +export interface SlotRenderableOptions> extends RenderableOptions { + registry: CoreSlotRegistry; + name: K; + data?: TData; + mode?: CoreSlotMode; + fallback?: FallbackNodes | (() => FallbackNodes); + pluginFailurePlaceholder?: CoreSlotFailurePlaceholder; +} +export declare class SlotRenderable> extends Renderable { + private _mode; + private _slotRegistry; + private _slotName; + private _data; + private _fallbackOption; + private _pluginFailurePlaceholder?; + private _disposed; + private _mountedNodes; + private _pluginNodes; + private _activePluginIds; + private _fallbackNodes; + private _unsubscribe; + constructor(ctx: RenderContext, options: SlotRenderableOptions); + get mode(): CoreSlotMode; + set mode(value: CoreSlotMode); + get data(): TData; + set data(value: TData); + refresh(): void; + protected destroySelf(): void; + private _cleanupAll; + private _ensureFallbackNodes; + private _callManagedHook; + private _detachNodeFromMount; + private _cleanupInactivePluginNodes; + private _cleanupReplacedPluginNodes; + private _resolvePluginFailurePlaceholder; + private _reconcileMountedNodes; +} +export {}; diff --git a/.patches/@opentui/core/plugins/registry.d.ts b/.patches/@opentui/core/plugins/registry.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/plugins/registry.d.ts @@ -0,0 +1,42 @@ +import type { CliRenderer } from "../renderer.js"; +import type { Plugin, PluginContext, PluginErrorEvent, PluginErrorReport, ResolvedSlotRenderer, SlotRenderer } from "./types.js"; +export interface SlotRegistryOptions { + onPluginError?: (event: PluginErrorEvent) => void; + debugPluginErrors?: boolean; + maxPluginErrors?: number; +} +export declare class SlotRegistry { + private plugins; + private sortedPluginsCache; + private listeners; + private errorListeners; + private pluginErrors; + private registrationOrder; + private batchDepth; + private batchedNotify; + private rendererInstance; + private hostContext; + private options; + constructor(renderer: CliRenderer, context: TContext, options?: SlotRegistryOptions); + get renderer(): CliRenderer; + get context(): Readonly; + configure(options: SlotRegistryOptions): void; + register(plugin: Plugin): () => void; + unregister(id: string): boolean; + updateOrder(id: string, order: number): boolean; + clear(): void; + subscribe(listener: () => void): () => void; + onPluginError(listener: (event: PluginErrorEvent) => void): () => void; + batch(run: () => T): T; + getPluginErrors(): readonly PluginErrorEvent[]; + clearPluginErrors(): void; + reportPluginError(report: PluginErrorReport): PluginErrorEvent; + resolve(slot: K): Array>; + resolveEntries(slot: K): Array>; + private getSortedPlugins; + private syncPluginSortMetadata; + private invalidateSortedPluginsCache; + private notifyListeners; + private flushListeners; +} +export declare function createSlotRegistry(renderer: CliRenderer, key: string, context: TContext, options?: SlotRegistryOptions): SlotRegistry; diff --git a/.patches/@opentui/core/plugins/types.d.ts b/.patches/@opentui/core/plugins/types.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/plugins/types.d.ts @@ -0,0 +1,34 @@ +import type { CliRenderer } from "../renderer.js"; +export type PluginContext = object; +export type SlotMode = "append" | "replace" | "single_winner"; +export type PluginErrorPhase = "setup" | "render" | "dispose" | "error_placeholder"; +export type PluginErrorSource = "registry" | "core" | (string & {}); +export interface PluginErrorEvent { + pluginId: string; + slot?: string; + phase: PluginErrorPhase; + source: PluginErrorSource; + error: Error; + timestamp: number; +} +export interface PluginErrorReport { + pluginId: string; + slot?: string; + phase: PluginErrorPhase; + source?: PluginErrorSource; + error: unknown; +} +export type SlotRenderer = (ctx: Readonly, props: TProps) => TNode; +export interface Plugin { + id: string; + order?: number; + setup?: (ctx: Readonly, renderer: CliRenderer) => void; + dispose?: () => void; + slots: { + [K in keyof TSlots]?: SlotRenderer; + }; +} +export interface ResolvedSlotRenderer { + id: string; + renderer: SlotRenderer; +} diff --git a/.patches/@opentui/core/post/effects.d.ts b/.patches/@opentui/core/post/effects.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/post/effects.d.ts @@ -0,0 +1,147 @@ +import type { OptimizedBuffer } from "../buffer.js"; +export declare class DistortionEffect { + glitchChancePerSecond: number; + maxGlitchLines: number; + minGlitchDuration: number; + maxGlitchDuration: number; + maxShiftAmount: number; + shiftFlipRatio: number; + colorGlitchChance: number; + private lastGlitchTime; + private glitchDuration; + private activeGlitches; + constructor(options?: Partial); + /** + * Applies the animated distortion/glitch effect to the buffer. + */ + apply(buffer: OptimizedBuffer, deltaTime: number): void; +} +/** + * Applies a vignette effect by darkening the corners, optimized with precomputation. + * Uses native colorMatrix with a zero matrix for attenuation. + */ +export declare class VignetteEffect { + private _strength; + private precomputedAttenuationCellMask; + private cachedWidth; + private cachedHeight; + private static zeroMatrix; + constructor(strength?: number); + set strength(newStrength: number); + get strength(): number; + private _computeFactors; + /** + * Applies the vignette effect using native colorMatrix with a zero matrix. + * The zero matrix maps all colors to black, and the attenuation cell masks + * control how much of the effect is applied (strength-based blending). + */ + apply(buffer: OptimizedBuffer): void; +} +/** + * Applies animated cloud shadows using Perlin noise. + * Darkens the background buffer based on procedural cloud density. + */ +export declare class CloudsEffect { + private noise; + private _scale; + private _speed; + private _density; + private _darkness; + private time; + constructor(scale?: number, speed?: number, density?: number, darkness?: number); + set scale(newScale: number); + get scale(): number; + set speed(newSpeed: number); + get speed(): number; + set density(newDensity: number); + get density(): number; + set darkness(newDarkness: number); + get darkness(): number; + /** + * Applies cloud shadow effect using Perlin noise mask with native colorMatrix. + * Uses FBM (Fractal Brownian Motion) for detailed clouds, offloaded to native code. + */ + apply(buffer: OptimizedBuffer, deltaTime: number): void; +} +/** + * Applies animated flames rising from the bottom using Perlin noise. + * Creates warm fire effect that fades as it rises. + */ +export declare class FlamesEffect { + private noise; + private _scale; + private _speed; + private _intensity; + private time; + constructor(scale?: number, speed?: number, intensity?: number); + set scale(newScale: number); + get scale(): number; + set speed(newSpeed: number); + get speed(): number; + set intensity(newIntensity: number); + get intensity(): number; + /** + * Applies flame effect rising from bottom using Perlin noise. + * Flames get cooler (redder) and fade as they rise. + */ + apply(buffer: OptimizedBuffer, deltaTime: number): void; +} +/** + * Applies a CRT rolling bar effect - a horizontal bar that slowly scans down the screen. + * Simulates the classic CRT monitor rolling bar artifact. + */ +export declare class CRTRollingBarEffect { + private _speed; + private _height; + private _intensity; + private _fadeDistance; + private position; + constructor(speed?: number, height?: number, intensity?: number, fadeDistance?: number); + set speed(newSpeed: number); + get speed(): number; + set height(newHeight: number); + get height(): number; + set intensity(newIntensity: number); + get intensity(): number; + set fadeDistance(newFadeDistance: number); + get fadeDistance(): number; + /** + * Applies the rolling bar effect to the buffer. + * Creates a smooth horizontal bar that scans down the screen with a bell-curve gradient. + * The bar has a bright center that smoothly fades to the edges. + */ + apply(buffer: OptimizedBuffer, deltaTime: number): void; +} +/** + * Applies animated rainbow colors to cells with white foreground. + * Cycles through HSV hue spectrum over time. + */ +export declare class RainbowTextEffect { + private _speed; + private _saturation; + private _value; + private _repeats; + private time; + constructor(speed?: number, saturation?: number, value?: number, repeats?: number); + set speed(newSpeed: number); + get speed(): number; + set saturation(newSaturation: number); + get saturation(): number; + set value(newValue: number); + get value(): number; + set repeats(newRepeats: number); + get repeats(): number; + /** + * Converts HSV color to RGB + * @param h - Hue [0, 1] + * @param s - Saturation [0, 1] + * @param v - Value [0, 1] + * @returns [r, g, b] each in [0, 1] + */ + private hsvToRgb; + /** + * Applies rainbow colors to cells with white foreground. + * White is defined as R, G, B all >= 0.9 + */ + apply(buffer: OptimizedBuffer, deltaTime: number): void; +} diff --git a/.patches/@opentui/core/post/filters.d.ts b/.patches/@opentui/core/post/filters.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/post/filters.d.ts @@ -0,0 +1,65 @@ +import type { OptimizedBuffer } from "../buffer.js"; +/** + * Applies a scanline effect by darkening every nth row using native color matrix. + * Only affects the background buffer to maintain text readability. + */ +export declare function applyScanlines(buffer: OptimizedBuffer, strength?: number, step?: number): void; +/** + * Inverts the colors in the buffer using native color matrix. + * Uses negative matrix with alpha offset: output = 1.0 - input for each RGB channel. + */ +export declare function applyInvert(buffer: OptimizedBuffer, strength?: number): void; +/** + * Adds random noise to the buffer colors using colorMatrix with brightness matrix. + * Uses per-pixel random strength values to dim/brighten each cell. + */ +export declare function applyNoise(buffer: OptimizedBuffer, strength?: number): void; +/** + * Applies a simplified chromatic aberration effect. + */ +export declare function applyChromaticAberration(buffer: OptimizedBuffer, strength?: number): void; +/** + * Converts the buffer to ASCII art based on background brightness. + * Uses native colorMatrix for efficient color corrections. + */ +export declare function applyAsciiArt(buffer: OptimizedBuffer, ramp?: string, fgColor?: { + r: number; + g: number; + b: number; +}, bgColor?: { + r: number; + g: number; + b: number; +}): void; +/** + * Adjusts the brightness of the buffer using color matrix transformation. + * Brightness adds the brightness value to all RGB channels (additive brightness). + * If not provided, applies uniform brightness to entire buffer. + */ +export declare function applyBrightness(buffer: OptimizedBuffer, brightness?: number, cellMask?: Float32Array): void; +/** + * Adjusts the gain of the buffer using color matrix transformation. + * Gain multiplies all RGB channels by the gain factor (no clamping). + * If not provided, applies uniform gain to entire buffer. + */ +export declare function applyGain(buffer: OptimizedBuffer, gain?: number, cellMask?: Float32Array): void; +/** + * Applies a saturation adjustment to the buffer. + */ +export declare function applySaturation(buffer: OptimizedBuffer, cellMask?: Float32Array, strength?: number): void; +/** + * Applies a bloom effect based on bright areas (Simplified). + */ +export declare class BloomEffect { + private _threshold; + private _strength; + private _radius; + constructor(threshold?: number, strength?: number, radius?: number); + set threshold(newThreshold: number); + get threshold(): number; + set strength(newStrength: number); + get strength(): number; + set radius(newRadius: number); + get radius(): number; + apply(buffer: OptimizedBuffer): void; +} diff --git a/.patches/@opentui/core/post/matrices.d.ts b/.patches/@opentui/core/post/matrices.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/post/matrices.d.ts @@ -0,0 +1,20 @@ +export declare const SEPIA_MATRIX: Float32Array; +/** + * Colorblindness simulation and compensation filters using color matrix transformations. + */ +export declare const PROTANOPIA_SIM_MATRIX: Float32Array; +export declare const DEUTERANOPIA_SIM_MATRIX: Float32Array; +export declare const TRITANOPIA_SIM_MATRIX: Float32Array; +export declare const ACHROMATOPSIA_MATRIX: Float32Array; +export declare const PROTANOPIA_COMP_MATRIX: Float32Array; +export declare const DEUTERANOPIA_COMP_MATRIX: Float32Array; +export declare const TRITANOPIA_COMP_MATRIX: Float32Array; +/** + * Creative color effect matrices. + */ +export declare const TECHNICOLOR_MATRIX: Float32Array; +export declare const SOLARIZATION_MATRIX: Float32Array; +export declare const SYNTHWAVE_MATRIX: Float32Array; +export declare const GREENSCALE_MATRIX: Float32Array; +export declare const GRAYSCALE_MATRIX: Float32Array; +export declare const INVERT_MATRIX: Float32Array; diff --git a/.patches/@opentui/core/renderables/ASCIIFont.d.ts b/.patches/@opentui/core/renderables/ASCIIFont.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/ASCIIFont.d.ts @@ -0,0 +1,52 @@ +import { type ASCIIFontName, type fonts } from "../lib/ascii.font.js"; +import { type ColorInput } from "../lib/RGBA.js"; +import { Selection, type LocalSelectionBounds } from "../lib/selection.js"; +import type { RenderableOptions } from "../Renderable.js"; +import type { RenderContext } from "../types.js"; +import { FrameBufferRenderable } from "./FrameBuffer.js"; +export interface ASCIIFontOptions extends Omit, "width" | "height"> { + text?: string; + font?: ASCIIFontName; + color?: ColorInput | ColorInput[]; + backgroundColor?: ColorInput; + selectionBg?: ColorInput; + selectionFg?: ColorInput; + selectable?: boolean; +} +export declare class ASCIIFontRenderable extends FrameBufferRenderable { + selectable: boolean; + protected static readonly _defaultOptions: { + text: string; + font: "tiny"; + color: string; + backgroundColor: string; + selectionBg: undefined; + selectionFg: undefined; + selectable: true; + }; + protected _text: string; + protected _font: keyof typeof fonts; + protected _color: ColorInput | ColorInput[]; + protected _backgroundColor: ColorInput; + protected _selectionBg: ColorInput | undefined; + protected _selectionFg: ColorInput | undefined; + protected lastLocalSelection: LocalSelectionBounds | null; + private selectionHelper; + constructor(ctx: RenderContext, options: ASCIIFontOptions); + get text(): string; + set text(value: string); + get font(): keyof typeof fonts; + set font(value: keyof typeof fonts); + get color(): ColorInput | ColorInput[]; + set color(value: ColorInput | ColorInput[]); + get backgroundColor(): ColorInput; + set backgroundColor(value: ColorInput); + private updateDimensions; + shouldStartSelection(x: number, y: number): boolean; + onSelectionChanged(selection: Selection | null): boolean; + getSelectedText(): string; + hasSelection(): boolean; + protected onResize(width: number, height: number): void; + private renderFontToBuffer; + private renderSelectionHighlight; +} diff --git a/.patches/@opentui/core/renderables/Box.d.ts b/.patches/@opentui/core/renderables/Box.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Box.d.ts @@ -0,0 +1,85 @@ +import { type RenderableOptions, Renderable } from "../Renderable.js"; +import type { OptimizedBuffer } from "../buffer.js"; +import { type BorderCharacters, type BorderSides, type BorderSidesConfig, type BorderStyle } from "../lib/index.js"; +import { type ColorInput, RGBA } from "../lib/RGBA.js"; +import type { RenderContext } from "../types.js"; +export interface BoxOptions extends RenderableOptions { + backgroundColor?: string | RGBA; + borderStyle?: BorderStyle; + border?: boolean | BorderSides[]; + borderColor?: string | RGBA; + customBorderChars?: BorderCharacters; + shouldFill?: boolean; + title?: string; + titleColor?: string | RGBA; + titleAlignment?: "left" | "center" | "right"; + bottomTitle?: string; + bottomTitleAlignment?: "left" | "center" | "right"; + focusedBorderColor?: ColorInput; + focusable?: boolean; + gap?: number | `${number}%`; + rowGap?: number | `${number}%`; + columnGap?: number | `${number}%`; +} +export declare class BoxRenderable extends Renderable { + protected _backgroundColor: RGBA; + protected _border: boolean | BorderSides[]; + protected _borderStyle: BorderStyle; + protected _borderColor: RGBA; + protected _focusedBorderColor: RGBA; + private _customBorderCharsObj; + protected _customBorderChars?: Uint32Array; + protected borderSides: BorderSidesConfig; + shouldFill: boolean; + protected _title?: string; + protected _titleColor?: RGBA; + protected _titleAlignment: "left" | "center" | "right"; + protected _bottomTitle?: string; + protected _bottomTitleAlignment: "left" | "center" | "right"; + protected _defaultOptions: { + backgroundColor: string; + borderStyle: "single"; + border: false; + borderColor: string; + shouldFill: true; + titleAlignment: "left"; + bottomTitleAlignment: "left"; + focusedBorderColor: string; + }; + constructor(ctx: RenderContext, options: BoxOptions); + private initializeBorder; + get customBorderChars(): BorderCharacters | undefined; + set customBorderChars(value: BorderCharacters | undefined); + get backgroundColor(): RGBA; + set backgroundColor(value: RGBA | string | undefined); + get border(): boolean | BorderSides[]; + set border(value: boolean | BorderSides[]); + get borderStyle(): BorderStyle; + set borderStyle(value: BorderStyle); + get borderColor(): RGBA; + set borderColor(value: RGBA | string); + get focusedBorderColor(): RGBA; + set focusedBorderColor(value: RGBA | string); + get title(): string | undefined; + set title(value: string | undefined); + get titleColor(): RGBA | undefined; + set titleColor(value: string | RGBA | undefined); + get titleAlignment(): "left" | "center" | "right"; + set titleAlignment(value: "left" | "center" | "right"); + get bottomTitle(): string | undefined; + set bottomTitle(value: string | undefined); + get bottomTitleAlignment(): "left" | "center" | "right"; + set bottomTitleAlignment(value: "left" | "center" | "right"); + protected renderSelf(buffer: OptimizedBuffer): void; + protected getScissorRect(): { + x: number; + y: number; + width: number; + height: number; + }; + private applyYogaBorders; + private applyYogaGap; + set gap(gap: number | `${number}%` | undefined); + set rowGap(rowGap: number | `${number}%` | undefined); + set columnGap(columnGap: number | `${number}%` | undefined); +} diff --git a/.patches/@opentui/core/renderables/Code.d.ts b/.patches/@opentui/core/renderables/Code.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Code.d.ts @@ -0,0 +1,97 @@ +import { type LineInfo, type RenderContext } from "../types.js"; +import { StyledText } from "../lib/styled-text.js"; +import { SyntaxStyle } from "../syntax-style.js"; +import { TreeSitterClient } from "../lib/tree-sitter/index.js"; +import { TextBufferRenderable, type TextBufferOptions } from "./TextBufferRenderable.js"; +import type { OptimizedBuffer } from "../buffer.js"; +import type { SimpleHighlight } from "../lib/tree-sitter/types.js"; +import type { TextChunk } from "../text-buffer.js"; +export interface HighlightContext { + content: string; + filetype: string; + syntaxStyle: SyntaxStyle; +} +export type OnHighlightCallback = (highlights: SimpleHighlight[], context: HighlightContext) => SimpleHighlight[] | undefined | Promise; +export interface ChunkRenderContext extends HighlightContext { + highlights: SimpleHighlight[]; +} +export type OnChunksCallback = (chunks: TextChunk[], context: ChunkRenderContext) => TextChunk[] | undefined | Promise; +export interface CodeOptions extends TextBufferOptions { + content?: string; + filetype?: string; + syntaxStyle: SyntaxStyle; + treeSitterClient?: TreeSitterClient; + conceal?: boolean; + drawUnstyledText?: boolean; + streaming?: boolean; + initialStyledText?: StyledText; + baseHighlight?: string; + onHighlight?: OnHighlightCallback; + onChunks?: OnChunksCallback; +} +export declare class CodeRenderable extends TextBufferRenderable { + private _content; + private _filetype?; + private _syntaxStyle; + private _isHighlighting; + private _treeSitterClient; + private _highlightsDirty; + private _highlightSnapshotId; + private _conceal; + private _drawUnstyledText; + private _shouldRenderTextBuffer; + private _streaming; + private _initialStyledText?; + private _hadInitialContent; + private _lastHighlights; + private _baseHighlight?; + private _onHighlight?; + private _onChunks?; + private _highlightingPromise; + private _renderedLineSources?; + private _mappedLineInfo?; + protected _contentDefaultOptions: { + content: string; + conceal: true; + drawUnstyledText: true; + streaming: false; + }; + constructor(ctx: RenderContext, options: CodeOptions); + get content(): string; + set content(value: string); + get lineInfo(): LineInfo; + get wrapMode(): "none" | "char" | "word"; + set wrapMode(value: "none" | "char" | "word"); + protected onResize(width: number, height: number): void; + protected updateTextInfo(): void; + get filetype(): string | undefined; + set filetype(value: string | undefined); + get syntaxStyle(): SyntaxStyle; + set syntaxStyle(value: SyntaxStyle); + get conceal(): boolean; + set conceal(value: boolean); + get drawUnstyledText(): boolean; + set drawUnstyledText(value: boolean); + get streaming(): boolean; + set initialStyledText(value: StyledText | undefined); + set streaming(value: boolean); + get treeSitterClient(): TreeSitterClient; + set treeSitterClient(value: TreeSitterClient); + get onHighlight(): OnHighlightCallback | undefined; + get baseHighlight(): string | undefined; + set baseHighlight(value: string | undefined); + set onHighlight(value: OnHighlightCallback | undefined); + get onChunks(): OnChunksCallback | undefined; + set onChunks(value: OnChunksCallback | undefined); + get isHighlighting(): boolean; + get highlightingDone(): Promise; + protected transformChunks(chunks: TextChunk[], context: ChunkRenderContext): Promise; + private ensureVisibleTextBeforeHighlight; + private startHighlight; + private setRenderedLineSources; + private static isIdentityLineSources; + private static getMergedConcealLineRanges; + private getConcealLinesSourceMap; + getLineHighlights(lineIdx: number): import("../types.js").Highlight[]; + protected renderSelf(buffer: OptimizedBuffer): void; +} diff --git a/.patches/@opentui/core/renderables/Diff.d.ts b/.patches/@opentui/core/renderables/Diff.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Diff.d.ts @@ -0,0 +1,147 @@ +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import type { RenderContext } from "../types.js"; +import { type LineColorConfig } from "./LineNumberRenderable.js"; +import { RGBA } from "../lib/RGBA.js"; +import { SyntaxStyle } from "../syntax-style.js"; +import type { TreeSitterClient } from "../lib/tree-sitter/index.js"; +import type { MouseEvent } from "../renderer.js"; +export interface DiffRenderableOptions extends RenderableOptions { + diff?: string; + syncScroll?: boolean; + view?: "unified" | "split"; + fg?: string | RGBA; + filetype?: string; + syntaxStyle?: SyntaxStyle; + wrapMode?: "word" | "char" | "none"; + conceal?: boolean; + selectionBg?: string | RGBA; + selectionFg?: string | RGBA; + treeSitterClient?: TreeSitterClient; + showLineNumbers?: boolean; + lineNumberFg?: string | RGBA; + lineNumberBg?: string | RGBA; + addedBg?: string | RGBA; + removedBg?: string | RGBA; + contextBg?: string | RGBA; + addedContentBg?: string | RGBA; + removedContentBg?: string | RGBA; + contextContentBg?: string | RGBA; + addedSignColor?: string | RGBA; + removedSignColor?: string | RGBA; + addedLineNumberBg?: string | RGBA; + removedLineNumberBg?: string | RGBA; +} +export declare class DiffRenderable extends Renderable { + private _diff; + private _syncScroll; + private _view; + private _parsedDiff; + private _parseError; + private _hunkStartLines; + private _hunkRowOffsets; + private _fg?; + private _filetype?; + private _syntaxStyle?; + private _wrapMode?; + private _conceal; + private _selectionBg?; + private _selectionFg?; + private _treeSitterClient?; + private _showLineNumbers; + private _lineNumberFg; + private _lineNumberBg; + private _addedBg; + private _removedBg; + private _contextBg; + private _addedContentBg; + private _removedContentBg; + private _contextContentBg; + private _addedSignColor; + private _removedSignColor; + private _addedLineNumberBg; + private _removedLineNumberBg; + private leftSide; + private rightSide; + private leftSideAdded; + private rightSideAdded; + private leftCodeRenderable; + private rightCodeRenderable; + private pendingRebuild; + private _lastWidth; + private errorTextRenderable; + private errorCodeRenderable; + private _waitingForHighlight; + private _lineInfoChangeHandler; + constructor(ctx: RenderContext, options: DiffRenderableOptions); + private parseDiff; + private buildView; + protected onMouseEvent(event: MouseEvent): void; + private isInsideSide; + protected onResize(width: number, height: number): void; + private requestRebuild; + private invalidateHunkRowOffsets; + private rebuildView; + private handleLineInfoChange; + private attachLineInfoListeners; + private detachLineInfoListeners; + destroyRecursively(): void; + private buildErrorView; + private createOrUpdateCodeRenderable; + private createOrUpdateSide; + private buildUnifiedView; + private buildSplitView; + get diff(): string; + set diff(value: string); + get syncScroll(): boolean; + set syncScroll(value: boolean); + get view(): "unified" | "split"; + set view(value: "unified" | "split"); + get filetype(): string | undefined; + set filetype(value: string | undefined); + get syntaxStyle(): SyntaxStyle | undefined; + set syntaxStyle(value: SyntaxStyle | undefined); + get wrapMode(): "word" | "char" | "none" | undefined; + set wrapMode(value: "word" | "char" | "none" | undefined); + get showLineNumbers(): boolean; + set showLineNumbers(value: boolean); + get addedBg(): RGBA; + set addedBg(value: string | RGBA); + get removedBg(): RGBA; + set removedBg(value: string | RGBA); + get contextBg(): RGBA; + set contextBg(value: string | RGBA); + get addedSignColor(): RGBA; + set addedSignColor(value: string | RGBA); + get removedSignColor(): RGBA; + set removedSignColor(value: string | RGBA); + get addedLineNumberBg(): RGBA; + set addedLineNumberBg(value: string | RGBA); + get removedLineNumberBg(): RGBA; + set removedLineNumberBg(value: string | RGBA); + get lineNumberFg(): RGBA; + set lineNumberFg(value: string | RGBA); + get lineNumberBg(): RGBA; + set lineNumberBg(value: string | RGBA); + get addedContentBg(): RGBA | null; + set addedContentBg(value: string | RGBA | null); + get removedContentBg(): RGBA | null; + set removedContentBg(value: string | RGBA | null); + get contextContentBg(): RGBA | null; + set contextContentBg(value: string | RGBA | null); + get selectionBg(): RGBA | undefined; + set selectionBg(value: string | RGBA | undefined); + get selectionFg(): RGBA | undefined; + set selectionFg(value: string | RGBA | undefined); + get conceal(): boolean; + set conceal(value: boolean); + get fg(): RGBA | undefined; + set fg(value: string | RGBA | undefined); + setLineColor(line: number, color: string | RGBA | LineColorConfig): void; + clearLineColor(line: number): void; + setLineColors(lineColors: Map): void; + clearAllLineColors(): void; + highlightLines(startLine: number, endLine: number, color: string | RGBA | LineColorConfig): void; + clearHighlightLines(startLine: number, endLine: number): void; + getHunkRowOffsets(): number[]; + private computeHunkRowOffsets; +} diff --git a/.patches/@opentui/core/renderables/EditBufferRenderable.d.ts b/.patches/@opentui/core/renderables/EditBufferRenderable.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/EditBufferRenderable.d.ts @@ -0,0 +1,237 @@ +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import { Selection, type LocalSelectionBounds } from "../lib/selection.js"; +import { EditBuffer, type LogicalCursor } from "../edit-buffer.js"; +import { EditorView, type VisualCursor } from "../editor-view.js"; +import { RGBA } from "../lib/RGBA.js"; +import type { RenderContext, Highlight, CursorStyleOptions, LineInfoProvider, LineInfo } from "../types.js"; +import type { OptimizedBuffer } from "../buffer.js"; +import type { SyntaxStyle } from "../syntax-style.js"; +declare const BrandedEditBufferRenderable: unique symbol; +export type EditorCapture = "escape" | "navigate" | "submit" | "tab"; +export interface EditorTraits { + capture?: readonly EditorCapture[]; + suspend?: boolean; + status?: string; +} +export declare enum EditBufferRenderableEvents { + TRAITS_CHANGED = "traits-changed" +} +export declare function isEditBufferRenderable(obj: unknown): obj is EditBufferRenderable; +export interface CursorChangeEvent { + line: number; + visualColumn: number; +} +export interface ContentChangeEvent { +} +export interface EditBufferOptions extends RenderableOptions { + textColor?: string | RGBA; + backgroundColor?: string | RGBA; + selectionBg?: string | RGBA; + selectionFg?: string | RGBA; + selectable?: boolean; + attributes?: number; + wrapMode?: "none" | "char" | "word"; + scrollMargin?: number; + scrollSpeed?: number; + showCursor?: boolean; + cursorColor?: string | RGBA; + cursorStyle?: CursorStyleOptions; + syntaxStyle?: SyntaxStyle; + tabIndicator?: string | number; + tabIndicatorColor?: string | RGBA; + onCursorChange?: (event: CursorChangeEvent) => void; + onContentChange?: (event: ContentChangeEvent) => void; +} +export declare abstract class EditBufferRenderable extends Renderable implements LineInfoProvider { + [BrandedEditBufferRenderable]: boolean; + protected _focusable: boolean; + selectable: boolean; + private _traits; + protected _textColor: RGBA; + protected _backgroundColor: RGBA; + protected _defaultAttributes: number; + protected _selectionBg: RGBA | undefined; + protected _selectionFg: RGBA | undefined; + protected _wrapMode: "none" | "char" | "word"; + protected _scrollMargin: number; + protected _showCursor: boolean; + protected _cursorColor: RGBA; + protected _cursorStyle: CursorStyleOptions; + protected lastLocalSelection: LocalSelectionBounds | null; + protected _tabIndicator?: string | number; + protected _tabIndicatorColor?: RGBA; + private _cursorChangeListener; + private _contentChangeListener; + private _autoScrollVelocity; + private _autoScrollAccumulator; + private _scrollSpeed; + private _keyboardSelectionActive; + readonly editBuffer: EditBuffer; + readonly editorView: EditorView; + protected _defaultOptions: { + textColor: RGBA; + backgroundColor: string; + selectionBg: undefined; + selectionFg: undefined; + selectable: true; + attributes: number; + wrapMode: "none" | "char" | "word"; + scrollMargin: number; + scrollSpeed: number; + showCursor: true; + cursorColor: RGBA; + cursorStyle: { + style: "block"; + blinking: true; + }; + tabIndicator: undefined; + tabIndicatorColor: undefined; + }; + constructor(ctx: RenderContext, options: EditBufferOptions); + get lineInfo(): LineInfo; + private setupEventListeners; + get lineCount(): number; + get virtualLineCount(): number; + get scrollY(): number; + get plainText(): string; + get logicalCursor(): LogicalCursor; + get visualCursor(): VisualCursor; + get cursorOffset(): number; + set cursorOffset(offset: number); + get cursorCharacterOffset(): number | undefined; + get textColor(): RGBA; + set textColor(value: RGBA | string | undefined); + get selectionBg(): RGBA | undefined; + get traits(): EditorTraits; + set traits(value: EditorTraits); + set selectionBg(value: RGBA | string | undefined); + get selectionFg(): RGBA | undefined; + set selectionFg(value: RGBA | string | undefined); + get backgroundColor(): RGBA; + set backgroundColor(value: RGBA | string | undefined); + get attributes(): number; + set attributes(value: number); + get wrapMode(): "none" | "char" | "word"; + set wrapMode(value: "none" | "char" | "word"); + get showCursor(): boolean; + set showCursor(value: boolean); + get cursorColor(): RGBA; + set cursorColor(value: RGBA | string); + get cursorStyle(): CursorStyleOptions; + set cursorStyle(style: CursorStyleOptions); + get tabIndicator(): string | number | undefined; + set tabIndicator(value: string | number | undefined); + get tabIndicatorColor(): RGBA | undefined; + set tabIndicatorColor(value: RGBA | string | undefined); + get scrollSpeed(): number; + set scrollSpeed(value: number); + protected onMouseEvent(event: any): void; + protected handleScroll(event: any): void; + protected onResize(width: number, height: number): void; + protected refreshLocalSelection(): boolean; + private updateLocalSelection; + shouldStartSelection(x: number, y: number): boolean; + onSelectionChanged(selection: Selection | null): boolean; + protected onUpdate(deltaTime: number): void; + getSelectedText(): string; + hasSelection(): boolean; + getSelection(): { + start: number; + end: number; + } | null; + private refreshSelectionStyle; + private deleteSelectedText; + setSelection(start: number, end: number): void; + setSelectionInclusive(start: number, end: number): void; + clearSelection(): boolean; + deleteSelection(): boolean; + setCursor(row: number, col: number): void; + insertChar(char: string): void; + insertText(text: string): void; + deleteChar(): boolean; + deleteCharBackward(): boolean; + newLine(): boolean; + deleteLine(): boolean; + moveCursorLeft(options?: { + select?: boolean; + }): boolean; + moveCursorRight(options?: { + select?: boolean; + }): boolean; + moveCursorUp(options?: { + select?: boolean; + }): boolean; + moveCursorDown(options?: { + select?: boolean; + }): boolean; + gotoLine(line: number): void; + gotoLineStart(): void; + gotoLineTextEnd(): void; + gotoLineHome(options?: { + select?: boolean; + }): boolean; + gotoLineEnd(options?: { + select?: boolean; + }): boolean; + gotoVisualLineHome(options?: { + select?: boolean; + }): boolean; + gotoVisualLineEnd(options?: { + select?: boolean; + }): boolean; + gotoBufferHome(options?: { + select?: boolean; + }): boolean; + gotoBufferEnd(options?: { + select?: boolean; + }): boolean; + selectAll(): boolean; + deleteToLineEnd(): boolean; + deleteToLineStart(): boolean; + undo(): boolean; + redo(): boolean; + moveWordForward(options?: { + select?: boolean; + }): boolean; + moveWordBackward(options?: { + select?: boolean; + }): boolean; + deleteWordForward(): boolean; + deleteWordBackward(): boolean; + private setupMeasureFunc; + render(buffer: OptimizedBuffer, deltaTime: number): void; + protected renderSelf(buffer: OptimizedBuffer): void; + protected renderCursor(buffer: OptimizedBuffer): void; + focus(): void; + blur(): void; + protected onRemove(): void; + destroy(): void; + set onCursorChange(handler: ((event: CursorChangeEvent) => void) | undefined); + get onCursorChange(): ((event: CursorChangeEvent) => void) | undefined; + set onContentChange(handler: ((event: ContentChangeEvent) => void) | undefined); + get onContentChange(): ((event: ContentChangeEvent) => void) | undefined; + get syntaxStyle(): SyntaxStyle | null; + set syntaxStyle(style: SyntaxStyle | null); + addHighlight(lineIdx: number, highlight: Highlight): void; + addHighlightByCharRange(highlight: Highlight): void; + removeHighlightsByRef(hlRef: number): void; + clearLineHighlights(lineIdx: number): void; + clearAllHighlights(): void; + getLineHighlights(lineIdx: number): Array; + /** + * Set text and completely reset the buffer state (clears history, resets add_buffer). + * Use this for initial text setting or when you want a clean slate. + */ + setText(text: string): void; + /** + * Replace text while preserving undo history (creates an undo point). + * Use this when you want the setText operation to be undoable. + */ + replaceText(text: string): void; + clear(): void; + deleteRange(startLine: number, startCol: number, endLine: number, endCol: number): void; + getTextRange(startOffset: number, endOffset: number): string; + getTextRangeByCoords(startRow: number, startCol: number, endRow: number, endCol: number): string; + protected updateSelectionForMovement(shiftPressed: boolean, isBeforeMovement: boolean): void; +} +export {}; diff --git a/.patches/@opentui/core/renderables/FrameBuffer.d.ts b/.patches/@opentui/core/renderables/FrameBuffer.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/FrameBuffer.d.ts @@ -0,0 +1,16 @@ +import { type RenderableOptions, Renderable } from "../Renderable.js"; +import { OptimizedBuffer } from "../buffer.js"; +import type { RenderContext } from "../types.js"; +export interface FrameBufferOptions extends RenderableOptions { + width: number; + height: number; + respectAlpha?: boolean; +} +export declare class FrameBufferRenderable extends Renderable { + frameBuffer: OptimizedBuffer; + protected respectAlpha: boolean; + constructor(ctx: RenderContext, options: FrameBufferOptions); + protected onResize(width: number, height: number): void; + protected renderSelf(buffer: OptimizedBuffer): void; + protected destroySelf(): void; +} diff --git a/.patches/@opentui/core/renderables/Input.d.ts b/.patches/@opentui/core/renderables/Input.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Input.d.ts @@ -0,0 +1,72 @@ +import type { PasteEvent } from "../lib/KeyHandler.js"; +import type { RenderContext } from "../types.js"; +import { TextareaRenderable, type TextareaOptions, type TextareaAction, type KeyBinding as TextareaKeyBinding } from "./Textarea.js"; +export type InputAction = TextareaAction; +export type InputKeyBinding = TextareaKeyBinding; +export interface InputRenderableOptions extends Omit { + /** Initial text value (newlines are stripped) */ + value?: string; + /** Minimum number of characters allowed */ + minLength?: number; + /** Maximum number of characters allowed */ + maxLength?: number; + /** Placeholder text (Input only supports string, not StyledText) */ + placeholder?: string; +} +export declare enum InputRenderableEvents { + INPUT = "input", + CHANGE = "change", + ENTER = "enter" +} +/** + * InputRenderable - A single-line text input component. + * + * Extends TextareaRenderable with single-line constraints: + * - Height is always 1 + * - No text wrapping + * - Newlines are stripped from input + * - Enter key submits instead of inserting newline + * + * Inherits all keybindings from TextareaRenderable. + */ +export declare class InputRenderable extends TextareaRenderable { + private _maxLength; + private _minLength; + private _lastCommittedValue; + private static readonly defaultOptions; + constructor(ctx: RenderContext, options: InputRenderableOptions); + /** + * Prevent newlines in single-line input + */ + newLine(): boolean; + /** + * Handle paste - strip newlines and enforce maxLength + */ + handlePaste(event: PasteEvent): void; + /** + * Insert text - strip newlines and enforce maxLength + */ + insertText(text: string): void; + get value(): string; + set value(value: string); + focus(): void; + blur(): void; + submit(): boolean; + deleteCharBackward(): boolean; + deleteChar(): boolean; + deleteLine(): boolean; + deleteWordBackward(): boolean; + deleteWordForward(): boolean; + deleteToLineStart(): boolean; + deleteToLineEnd(): boolean; + undo(): boolean; + redo(): boolean; + deleteCharacter(direction: "backward" | "forward"): void; + set maxLength(maxLength: number); + get maxLength(): number; + set minLength(minLength: number); + get minLength(): number; + set placeholder(placeholder: string); + get placeholder(): string; + set initialValue(value: string); +} diff --git a/.patches/@opentui/core/renderables/LineNumberRenderable.d.ts b/.patches/@opentui/core/renderables/LineNumberRenderable.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/LineNumberRenderable.d.ts @@ -0,0 +1,78 @@ +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import { OptimizedBuffer } from "../buffer.js"; +import type { RenderContext, LineInfoProvider } from "../types.js"; +import { RGBA } from "../lib/RGBA.js"; +export interface LineSign { + before?: string; + beforeColor?: string | RGBA; + after?: string; + afterColor?: string | RGBA; +} +export interface LineColorConfig { + gutter?: string | RGBA; + content?: string | RGBA; +} +export interface LineNumberOptions extends RenderableOptions { + target?: Renderable & LineInfoProvider; + fg?: string | RGBA; + bg?: string | RGBA; + minWidth?: number; + paddingRight?: number; + lineColors?: Map; + lineSigns?: Map; + lineNumberOffset?: number; + hideLineNumbers?: Set; + lineNumbers?: Map; + showLineNumbers?: boolean; +} +export declare class LineNumberRenderable extends Renderable { + private gutter; + private target; + private _lineColorsGutter; + private _lineColorsContent; + private _lineSigns; + private _fg; + private _bg; + private _minWidth; + private _paddingRight; + private _lineNumberOffset; + private _hideLineNumbers; + private _lineNumbers; + private _isDestroying; + private handleLineInfoChange; + private parseLineColor; + constructor(ctx: RenderContext, options: LineNumberOptions); + private setTarget; + add(child: Renderable): number; + remove(id: string): void; + destroyRecursively(): void; + clearTarget(): void; + protected renderSelf(buffer: OptimizedBuffer): void; + set showLineNumbers(value: boolean); + get showLineNumbers(): boolean; + get fg(): RGBA; + set fg(value: string | RGBA | undefined); + get bg(): RGBA; + set bg(value: string | RGBA | undefined); + setLineColor(line: number, color: string | RGBA | LineColorConfig): void; + clearLineColor(line: number): void; + clearAllLineColors(): void; + setLineColors(lineColors: Map): void; + getLineColors(): { + gutter: Map; + content: Map; + }; + setLineSign(line: number, sign: LineSign): void; + clearLineSign(line: number): void; + clearAllLineSigns(): void; + setLineSigns(lineSigns: Map): void; + getLineSigns(): Map; + set lineNumberOffset(value: number); + get lineNumberOffset(): number; + setHideLineNumbers(hideLineNumbers: Set): void; + getHideLineNumbers(): Set; + setLineNumbers(lineNumbers: Map): void; + getLineNumbers(): Map; + highlightLines(startLine: number, endLine: number, color: string | RGBA | LineColorConfig): void; + clearHighlightLines(startLine: number, endLine: number): void; +} diff --git a/.patches/@opentui/core/renderables/Markdown.d.ts b/.patches/@opentui/core/renderables/Markdown.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Markdown.d.ts @@ -0,0 +1,255 @@ +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import { type RenderContext } from "../types.js"; +import { SyntaxStyle } from "../syntax-style.js"; +import type { BorderStyle } from "../lib/border.js"; +import { RGBA, type ColorInput } from "../lib/RGBA.js"; +import { type MarkedToken, type Token, type Tokens } from "marked"; +import { type TextTableColumnFitter, type TextTableColumnWidthMode, type TextTableContent } from "./TextTable.js"; +import type { TreeSitterClient } from "../lib/tree-sitter/index.js"; +import { type ParseState } from "./markdown-parser.js"; +import type { OptimizedBuffer } from "../buffer.js"; +export type MarkdownTableStyle = "grid" | "columns"; +export interface MarkdownTableOptions { + /** + * Visual style preset for markdown tables. + * - "grid": boxed table with visible borders. + * - "columns": borderless columns optimized for separated block output. + * + * Defaults to "columns" in `internalBlockMode: "top-level"`, otherwise "grid". + */ + style?: MarkdownTableStyle; + /** + * Strategy for sizing table columns. + * - "content": columns fit to intrinsic content width. + * - "full": columns expand to fill available width. + */ + widthMode?: TextTableColumnWidthMode; + /** + * Column fitting method when shrinking constrained tables. + */ + columnFitter?: TextTableColumnFitter; + /** + * Wrapping strategy for table cell content. + */ + wrapMode?: "none" | "char" | "word"; + /** + * Padding applied on all sides of each table cell. + */ + cellPadding?: number; + /** + * Horizontal padding applied on the left and right of each table cell. + */ + cellPaddingX?: number; + /** + * Vertical padding applied above and below each table cell. + */ + cellPaddingY?: number; + /** + * Enables/disables table border rendering. + */ + borders?: boolean; + /** + * Overrides outer border visibility. Defaults to `borders`. + */ + outerBorder?: boolean; + /** + * Border style for markdown tables. + */ + borderStyle?: BorderStyle; + /** + * Border color for markdown tables. Defaults to conceal style color. + */ + borderColor?: ColorInput; + /** + * Enables/disables selection support on markdown tables. + */ + selectable?: boolean; +} +export interface MarkdownOptions extends RenderableOptions { + content?: string; + syntaxStyle: SyntaxStyle; + fg?: ColorInput; + bg?: ColorInput; + /** Controls concealment for markdown syntax markers in markdown text blocks. */ + conceal?: boolean; + /** Controls concealment inside fenced code blocks rendered by CodeRenderable. */ + concealCode?: boolean; + treeSitterClient?: TreeSitterClient; + /** + * Enable streaming mode for incremental content updates. + * + * Semantics: + * - The trailing markdown block stays unstable while streaming is enabled. + * - Tables render all rows produced by the markdown parser (including trailing rows). + * - Incomplete table rows are normalized by the parser and rendered with empty cells + * where data is missing. + * + * Expectations: + * - Keep this true while chunks are still being appended. + * - Set this to false once streaming is complete to finalize trailing token parsing. + */ + streaming?: boolean; + /** + * Options for internally rendered markdown tables. + */ + tableOptions?: MarkdownTableOptions; + /** + * Custom node renderer. Return a Renderable to override default rendering, + * or undefined/null to use default rendering. + */ + renderNode?: (token: Token, context: RenderNodeContext) => Renderable | undefined | null; + /** + * Internal only. + * - "coalesced": combine ordinary markdown into larger render blocks. + * - "top-level": preserve top-level markdown blocks as separate render blocks. + */ + internalBlockMode?: "coalesced" | "top-level"; +} +export interface RenderNodeContext { + syntaxStyle: SyntaxStyle; + conceal: boolean; + concealCode: boolean; + treeSitterClient?: TreeSitterClient; + /** Creates default renderable for this token */ + defaultRender: () => Renderable | null; +} +export type MarkdownCodeBlockRenderer = (token: Tokens.Code, context: RenderNodeContext) => Renderable | undefined | null; +export type MarkdownCodeBlockRendererMap = ReadonlyMap | Readonly>; +export declare function createMarkdownCodeBlockRenderer(renderers: MarkdownCodeBlockRendererMap): MarkdownOptions["renderNode"]; +interface TableContentCache { + content: TextTableContent; + cellKeys: Uint32Array[]; +} +export interface BlockState { + token: MarkedToken; + tokenRaw: string; + marginTop?: number; + renderable: Renderable; + tableContentCache?: TableContentCache; + tracksInterBlockMargin?: boolean; + /** Whether built-in reconciliation can update this renderable without replacing it. */ + canUpdateInPlace: boolean; +} +export type { ParseState }; +export declare class MarkdownRenderable extends Renderable { + private _content; + private _syntaxStyle; + private _fg?; + private _bg?; + private _conceal; + private _concealCode; + private _treeSitterClient?; + private _tableOptions?; + private _renderNode?; + private _internalBlockMode; + _parseState: ParseState | null; + private _streaming; + _blockStates: BlockState[]; + _stableBlockCount: number; + private _styleDirty; + private _linkifyMarkdownChunks; + protected _contentDefaultOptions: { + content: string; + conceal: true; + concealCode: false; + streaming: false; + internalBlockMode: "coalesced"; + }; + constructor(ctx: RenderContext, options: MarkdownOptions); + get content(): string; + set content(value: string); + get syntaxStyle(): SyntaxStyle; + set syntaxStyle(value: SyntaxStyle); + get fg(): RGBA | undefined; + set fg(value: ColorInput | undefined); + get bg(): RGBA | undefined; + set bg(value: ColorInput | undefined); + get conceal(): boolean; + set conceal(value: boolean); + get concealCode(): boolean; + set concealCode(value: boolean); + get streaming(): boolean; + set streaming(value: boolean); + get tableOptions(): MarkdownTableOptions | undefined; + set tableOptions(value: MarkdownTableOptions | undefined); + get renderNode(): MarkdownOptions["renderNode"] | undefined; + set renderNode(value: MarkdownOptions["renderNode"] | undefined); + get internalBlockMode(): "coalesced" | "top-level"; + set internalBlockMode(value: "coalesced" | "top-level"); + private getStyle; + private createChunk; + private createDefaultChunk; + private createInitialStyledText; + private renderInlineContent; + private renderInlineToken; + private renderInlineTokenWithStyle; + private applyMargins; + private createMarkdownCodeRenderable; + private getBlockquoteContent; + private getBlockquoteBorderColor; + private createBlockquoteRenderable; + private createListRenderable; + private getListItemInputs; + private applyListRenderable; + private createListItemRenderable; + private applyListItemRenderable; + private applyListItemChildren; + private getRenderableListItemTokens; + private applyListChildRenderable; + private destroyListItemChildrenAfter; + private applyListItemMarker; + private createListChildRenderable; + private createHorizontalRuleRenderable; + private createCodeRenderable; + private applyMarkdownCodeRenderable; + private applyBlockquoteRenderable; + private applyCodeBlockRenderable; + private shouldRenderSeparately; + private getInterBlockMargin; + private applyInterBlockMargin; + private createMarkdownBlockToken; + private normalizeMarkdownBlockRaw; + private normalizeScrollbackMarkdownBlockRaw; + private isCodeBlockOnlyRenderer; + private buildRenderableTokens; + private buildTopLevelRenderBlocks; + private shouldAddTopLevelMargin; + private isSeparatedTopLevelBlock; + private getTableRowsToRender; + private hashString; + private hashTableToken; + private getTableCellKey; + private createTableDataCellChunks; + private createTableHeaderCellChunks; + private buildTableContentCache; + private resolveTableStyle; + private usesBorderlessColumnSpacing; + private resolveTableRenderableOptions; + private applyTableRenderableOptions; + private applyTableOptionsToBlocks; + private createTextTableRenderable; + private createTableBlock; + private getStableBlockCount; + private syncTopLevelBlockState; + private getTopLevelBlockRaw; + private createTopLevelDefaultRenderable; + private createTopLevelRenderable; + private createDefaultRenderable; + private createCustomRenderable; + private createTopLevelCustomRenderable; + private renderCustomNode; + private destroyUnusedDefaultRenderable; + private updateBlockRenderable; + private updateTopLevelBlocks; + private canUpdateBlockRenderable; + private updateBlocks; + private clearBlockStates; + /** + * Re-render existing blocks without rebuilding the parse state or block structure. + * Used when only style/conceal changes - much faster than full rebuild. + */ + private rerenderBlocks; + clearCache(): void; + refreshStyles(): void; + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void; +} diff --git a/.patches/@opentui/core/renderables/ScrollBar.d.ts b/.patches/@opentui/core/renderables/ScrollBar.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/ScrollBar.d.ts @@ -0,0 +1,77 @@ +import type { OptimizedBuffer } from "../buffer.js"; +import { RGBA, type ColorInput } from "../lib/index.js"; +import type { KeyEvent } from "../lib/KeyHandler.js"; +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import type { RenderContext } from "../types.js"; +import { SliderRenderable, type SliderOptions } from "./Slider.js"; +export interface ScrollBarOptions extends RenderableOptions { + orientation: "vertical" | "horizontal"; + showArrows?: boolean; + arrowOptions?: Omit; + trackOptions?: Partial; + onChange?: (position: number) => void; +} +export type ScrollUnit = "absolute" | "viewport" | "content" | "step"; +export declare class ScrollBarRenderable extends Renderable { + readonly slider: SliderRenderable; + readonly startArrow: ArrowRenderable; + readonly endArrow: ArrowRenderable; + readonly orientation: "vertical" | "horizontal"; + protected _focusable: boolean; + private _scrollSize; + private _scrollPosition; + private _viewportSize; + private _showArrows; + private _manualVisibility; + private _onChange; + scrollStep: number | undefined | null; + get visible(): boolean; + set visible(value: boolean); + resetVisibilityControl(): void; + get scrollSize(): number; + get scrollPosition(): number; + get viewportSize(): number; + set scrollSize(value: number); + set scrollPosition(value: number); + set viewportSize(value: number); + get showArrows(): boolean; + set showArrows(value: boolean); + constructor(ctx: RenderContext, { trackOptions, arrowOptions, orientation, showArrows, ...options }: ScrollBarOptions); + set arrowOptions(options: ScrollBarOptions["arrowOptions"]); + set trackOptions(options: ScrollBarOptions["trackOptions"]); + private updateSliderFromScrollState; + scrollBy(delta: number, unit?: ScrollUnit): void; + private recalculateVisibility; + handleKeyPress(key: KeyEvent): boolean; +} +export interface ArrowOptions extends RenderableOptions { + direction: "up" | "down" | "left" | "right"; + foregroundColor?: ColorInput; + backgroundColor?: ColorInput; + attributes?: number; + arrowChars?: { + up?: string; + down?: string; + left?: string; + right?: string; + }; +} +export declare class ArrowRenderable extends Renderable { + private _direction; + private _foregroundColor; + private _backgroundColor; + private _attributes; + private _arrowChars; + constructor(ctx: RenderContext, options: ArrowOptions); + get direction(): "up" | "down" | "left" | "right"; + set direction(value: "up" | "down" | "left" | "right"); + get foregroundColor(): RGBA; + set foregroundColor(value: ColorInput); + get backgroundColor(): RGBA; + set backgroundColor(value: ColorInput); + get attributes(): number; + set attributes(value: number); + set arrowChars(value: ArrowOptions["arrowChars"]); + protected renderSelf(buffer: OptimizedBuffer): void; + private getArrowChar; +} diff --git a/.patches/@opentui/core/renderables/ScrollBox.d.ts b/.patches/@opentui/core/renderables/ScrollBox.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/ScrollBox.d.ts @@ -0,0 +1,127 @@ +import { type KeyEvent } from "../lib/index.js"; +import { type ScrollAcceleration } from "../lib/scroll-acceleration.js"; +import type { Renderable, RenderableOptions } from "../Renderable.js"; +import type { MouseEvent } from "../renderer.js"; +import type { RenderContext } from "../types.js"; +import { BoxRenderable, type BoxOptions } from "./Box.js"; +import type { VNode } from "./composition/vnode.js"; +import { ScrollBarRenderable, type ScrollBarOptions, type ScrollUnit } from "./ScrollBar.js"; +declare class ContentRenderable extends BoxRenderable { + private viewport; + private _viewportCulling; + constructor(ctx: RenderContext, viewport: BoxRenderable, viewportCulling: boolean, options: RenderableOptions); + get viewportCulling(): boolean; + set viewportCulling(value: boolean); + protected _hasVisibleChildFilter(): boolean; + protected _getVisibleChildren(): number[]; +} +export interface ScrollBoxOptions extends BoxOptions { + rootOptions?: BoxOptions; + wrapperOptions?: BoxOptions; + viewportOptions?: BoxOptions; + contentOptions?: BoxOptions; + scrollbarOptions?: Omit; + verticalScrollbarOptions?: Omit; + horizontalScrollbarOptions?: Omit; + stickyScroll?: boolean; + stickyStart?: "bottom" | "top" | "left" | "right"; + scrollX?: boolean; + scrollY?: boolean; + scrollAcceleration?: ScrollAcceleration; + viewportCulling?: boolean; +} +export declare class ScrollBoxRenderable extends BoxRenderable { + static idCounter: number; + private internalId; + readonly wrapper: BoxRenderable; + readonly viewport: BoxRenderable; + readonly content: ContentRenderable; + readonly horizontalScrollBar: ScrollBarRenderable; + readonly verticalScrollBar: ScrollBarRenderable; + protected _focusable: boolean; + private selectionListener?; + private autoScrollMouseX; + private autoScrollMouseY; + private readonly autoScrollThresholdVertical; + private readonly autoScrollThresholdHorizontal; + private readonly autoScrollSpeedSlow; + private readonly autoScrollSpeedMedium; + private readonly autoScrollSpeedFast; + private isAutoScrolling; + private cachedAutoScrollSpeed; + private autoScrollAccumulatorX; + private autoScrollAccumulatorY; + private scrollAccumulatorX; + private scrollAccumulatorY; + private _stickyScroll; + private _stickyScrollTop; + private _stickyScrollBottom; + private _stickyScrollLeft; + private _stickyScrollRight; + private _stickyStart?; + private _hasManualScroll; + private _isApplyingStickyScroll; + private scrollAccel; + get stickyScroll(): boolean; + set stickyScroll(value: boolean); + get stickyStart(): "bottom" | "top" | "left" | "right" | undefined; + set stickyStart(value: "bottom" | "top" | "left" | "right" | undefined); + get scrollTop(): number; + set scrollTop(value: number); + get scrollLeft(): number; + set scrollLeft(value: number); + get scrollWidth(): number; + get scrollHeight(): number; + private updateStickyState; + private syncManualScrollState; + private applyStickyStart; + constructor(ctx: RenderContext, options: ScrollBoxOptions); + protected onUpdate(deltaTime: number): void; + scrollBy(delta: number | { + x: number; + y: number; + }, unit?: ScrollUnit): void; + scrollChildIntoView(childId: string): void; + scrollTo(position: number | { + x: number; + y: number; + }): void; + private isAtStickyPosition; + private isAtStickyReengagePoint; + add(obj: Renderable | VNode, index?: number): number; + insertBefore(obj: Renderable | VNode | unknown, anchor?: Renderable | unknown): number; + remove(id: string): void; + getChildren(): Renderable[]; + protected onMouseEvent(event: MouseEvent): void; + handleKeyPress(key: KeyEvent): boolean; + private resetScrollAccumulators; + startAutoScroll(mouseX: number, mouseY: number): void; + updateAutoScroll(mouseX: number, mouseY: number): void; + stopAutoScroll(): void; + private hasOtherLiveReasons; + private handleAutoScroll; + private getAutoScrollDirectionX; + private getAutoScrollDirectionY; + private getAutoScrollSpeed; + private recalculateBarProps; + set padding(value: number | `${number}%` | null | undefined); + set paddingX(value: number | `${number}%` | null | undefined); + set paddingY(value: number | `${number}%` | null | undefined); + set paddingTop(value: number | `${number}%` | null | undefined); + set paddingRight(value: number | `${number}%` | null | undefined); + set paddingBottom(value: number | `${number}%` | null | undefined); + set paddingLeft(value: number | `${number}%` | null | undefined); + set rootOptions(options: ScrollBoxOptions["rootOptions"]); + set wrapperOptions(options: ScrollBoxOptions["wrapperOptions"]); + set viewportOptions(options: ScrollBoxOptions["viewportOptions"]); + set contentOptions(options: ScrollBoxOptions["contentOptions"]); + set scrollbarOptions(options: ScrollBoxOptions["scrollbarOptions"]); + set verticalScrollbarOptions(options: ScrollBoxOptions["verticalScrollbarOptions"]); + set horizontalScrollbarOptions(options: ScrollBoxOptions["horizontalScrollbarOptions"]); + get scrollAcceleration(): ScrollAcceleration; + set scrollAcceleration(value: ScrollAcceleration); + get viewportCulling(): boolean; + set viewportCulling(value: boolean); + protected destroySelf(): void; +} +export {}; diff --git a/.patches/@opentui/core/renderables/Select.d.ts b/.patches/@opentui/core/renderables/Select.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Select.d.ts @@ -0,0 +1,117 @@ +import { OptimizedBuffer } from "../buffer.js"; +import { fonts } from "../lib/ascii.font.js"; +import type { KeyEvent } from "../lib/KeyHandler.js"; +import { type ColorInput } from "../lib/RGBA.js"; +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import type { RenderContext } from "../types.js"; +import { type KeyBinding as BaseKeyBinding } from "../lib/keybinding.internal.js"; +type KeyAliasMap = Record; +export interface SelectOption { + name: string; + description: string; + value?: any; +} +export type SelectAction = "move-up" | "move-down" | "move-up-fast" | "move-down-fast" | "select-current"; +export type SelectKeyBinding = BaseKeyBinding; +export interface SelectRenderableOptions extends RenderableOptions { + backgroundColor?: ColorInput; + textColor?: ColorInput; + focusedBackgroundColor?: ColorInput; + focusedTextColor?: ColorInput; + options?: SelectOption[]; + selectedIndex?: number; + selectedBackgroundColor?: ColorInput; + selectedTextColor?: ColorInput; + descriptionColor?: ColorInput; + selectedDescriptionColor?: ColorInput; + showScrollIndicator?: boolean; + wrapSelection?: boolean; + showDescription?: boolean; + font?: keyof typeof fonts; + itemSpacing?: number; + fastScrollStep?: number; + keyBindings?: SelectKeyBinding[]; + keyAliasMap?: KeyAliasMap; +} +export declare enum SelectRenderableEvents { + SELECTION_CHANGED = "selectionChanged", + ITEM_SELECTED = "itemSelected" +} +export declare class SelectRenderable extends Renderable { + protected _focusable: boolean; + private _options; + private _selectedIndex; + private scrollOffset; + private maxVisibleItems; + private _backgroundColor; + private _textColor; + private _focusedBackgroundColor; + private _focusedTextColor; + private _selectedBackgroundColor; + private _selectedTextColor; + private _descriptionColor; + private _selectedDescriptionColor; + private _showScrollIndicator; + private _wrapSelection; + private _showDescription; + private _font?; + private _itemSpacing; + private linesPerItem; + private fontHeight; + private _fastScrollStep; + private _keyBindingsMap; + private _keyAliasMap; + private _keyBindings; + protected _defaultOptions: { + backgroundColor: string; + textColor: string; + focusedBackgroundColor: string; + focusedTextColor: string; + selectedBackgroundColor: string; + selectedTextColor: string; + selectedIndex: number; + descriptionColor: string; + selectedDescriptionColor: string; + showScrollIndicator: false; + wrapSelection: false; + showDescription: true; + itemSpacing: number; + fastScrollStep: number; + }; + constructor(ctx: RenderContext, options: SelectRenderableOptions); + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void; + private refreshFrameBuffer; + private renderScrollIndicatorToFrameBuffer; + get options(): SelectOption[]; + set options(options: SelectOption[]); + getSelectedOption(): SelectOption | null; + getSelectedIndex(): number; + moveUp(steps?: number): void; + moveDown(steps?: number): void; + selectCurrent(): void; + setSelectedIndex(index: number): void; + private updateScrollOffset; + protected onResize(width: number, height: number): void; + handleKeyPress(key: KeyEvent): boolean; + get showScrollIndicator(): boolean; + set showScrollIndicator(show: boolean); + get showDescription(): boolean; + set showDescription(show: boolean); + get wrapSelection(): boolean; + set wrapSelection(wrap: boolean); + set backgroundColor(value: ColorInput); + set textColor(value: ColorInput); + set focusedBackgroundColor(value: ColorInput); + set focusedTextColor(value: ColorInput); + set selectedBackgroundColor(value: ColorInput); + set selectedTextColor(value: ColorInput); + set descriptionColor(value: ColorInput); + set selectedDescriptionColor(value: ColorInput); + set font(font: keyof typeof fonts); + set itemSpacing(spacing: number); + set fastScrollStep(step: number); + set keyBindings(bindings: SelectKeyBinding[]); + set keyAliasMap(aliases: KeyAliasMap); + set selectedIndex(value: number); +} +export {}; diff --git a/.patches/@opentui/core/renderables/Slider.d.ts b/.patches/@opentui/core/renderables/Slider.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Slider.d.ts @@ -0,0 +1,47 @@ +import { type RenderableOptions, Renderable } from "../Renderable.js"; +import { type RenderContext } from "../types.js"; +import { type ColorInput, RGBA } from "../lib/RGBA.js"; +import { OptimizedBuffer } from "../buffer.js"; +export interface SliderOptions extends RenderableOptions { + orientation: "vertical" | "horizontal"; + value?: number; + min?: number; + max?: number; + viewPortSize?: number; + backgroundColor?: ColorInput; + foregroundColor?: ColorInput; + onChange?: (value: number) => void; +} +export declare class SliderRenderable extends Renderable { + readonly orientation: "vertical" | "horizontal"; + private _value; + private _min; + private _max; + private _viewPortSize; + private _backgroundColor; + private _foregroundColor; + private _onChange?; + constructor(ctx: RenderContext, options: SliderOptions); + get value(): number; + set value(newValue: number); + get min(): number; + set min(newMin: number); + get max(): number; + set max(newMax: number); + set viewPortSize(size: number); + get viewPortSize(): number; + get backgroundColor(): RGBA; + set backgroundColor(value: ColorInput); + get foregroundColor(): RGBA; + set foregroundColor(value: ColorInput); + private calculateDragOffsetVirtual; + private setupMouseHandling; + private updateValueFromMouseDirect; + private updateValueFromMouseWithOffset; + private getThumbRect; + protected renderSelf(buffer: OptimizedBuffer): void; + private renderHorizontal; + private renderVertical; + private getVirtualThumbSize; + private getVirtualThumbStart; +} diff --git a/.patches/@opentui/core/renderables/TabSelect.d.ts b/.patches/@opentui/core/renderables/TabSelect.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/TabSelect.d.ts @@ -0,0 +1,98 @@ +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import { OptimizedBuffer } from "../buffer.js"; +import { type ColorInput } from "../lib/RGBA.js"; +import type { KeyEvent } from "../lib/KeyHandler.js"; +import type { RenderContext } from "../types.js"; +import { type KeyBinding as BaseKeyBinding } from "../lib/keybinding.internal.js"; +type KeyAliasMap = Record; +export interface TabSelectOption { + name: string; + description: string; + value?: any; +} +export type TabSelectAction = "move-left" | "move-right" | "select-current"; +export type TabSelectKeyBinding = BaseKeyBinding; +export interface TabSelectRenderableOptions extends Omit, "height"> { + height?: number; + options?: TabSelectOption[]; + tabWidth?: number; + backgroundColor?: ColorInput; + textColor?: ColorInput; + focusedBackgroundColor?: ColorInput; + focusedTextColor?: ColorInput; + selectedBackgroundColor?: ColorInput; + selectedTextColor?: ColorInput; + selectedDescriptionColor?: ColorInput; + showScrollArrows?: boolean; + showDescription?: boolean; + showUnderline?: boolean; + wrapSelection?: boolean; + keyBindings?: TabSelectKeyBinding[]; + keyAliasMap?: KeyAliasMap; +} +export declare enum TabSelectRenderableEvents { + SELECTION_CHANGED = "selectionChanged", + ITEM_SELECTED = "itemSelected" +} +export declare class TabSelectRenderable extends Renderable { + protected _focusable: boolean; + private _options; + private selectedIndex; + private scrollOffset; + private _tabWidth; + private maxVisibleTabs; + private _backgroundColor; + private _textColor; + private _focusedBackgroundColor; + private _focusedTextColor; + private _selectedBackgroundColor; + private _selectedTextColor; + private _selectedDescriptionColor; + private _showScrollArrows; + private _showDescription; + private _showUnderline; + private _wrapSelection; + private _keyBindingsMap; + private _keyAliasMap; + private _keyBindings; + constructor(ctx: RenderContext, options: TabSelectRenderableOptions); + private calculateDynamicHeight; + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void; + private refreshFrameBuffer; + private truncateText; + private renderScrollArrowsToFrameBuffer; + setOptions(options: TabSelectOption[]): void; + getSelectedOption(): TabSelectOption | null; + getSelectedIndex(): number; + moveLeft(): void; + moveRight(): void; + selectCurrent(): void; + setSelectedIndex(index: number): void; + private updateScrollOffset; + protected onResize(width: number, height: number): void; + setTabWidth(tabWidth: number): void; + getTabWidth(): number; + handleKeyPress(key: KeyEvent): boolean; + get options(): TabSelectOption[]; + set options(options: TabSelectOption[]); + set backgroundColor(color: ColorInput); + set textColor(color: ColorInput); + set focusedBackgroundColor(color: ColorInput); + set focusedTextColor(color: ColorInput); + set selectedBackgroundColor(color: ColorInput); + set selectedTextColor(color: ColorInput); + set selectedDescriptionColor(color: ColorInput); + get showDescription(): boolean; + set showDescription(show: boolean); + get showUnderline(): boolean; + set showUnderline(show: boolean); + get showScrollArrows(): boolean; + set showScrollArrows(show: boolean); + get wrapSelection(): boolean; + set wrapSelection(wrap: boolean); + get tabWidth(): number; + set tabWidth(tabWidth: number); + set keyBindings(bindings: TabSelectKeyBinding[]); + set keyAliasMap(aliases: KeyAliasMap); +} +export {}; diff --git a/.patches/@opentui/core/renderables/Text.d.ts b/.patches/@opentui/core/renderables/Text.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Text.d.ts @@ -0,0 +1,36 @@ +import { BaseRenderable } from "../Renderable.js"; +import { StyledText } from "../lib/styled-text.js"; +import { type TextChunk } from "../text-buffer.js"; +import { RGBA } from "../lib/RGBA.js"; +import { type RenderContext } from "../types.js"; +import { RootTextNodeRenderable, TextNodeRenderable } from "./TextNode.js"; +import { TextBufferRenderable, type TextBufferOptions } from "./TextBufferRenderable.js"; +export interface TextOptions extends TextBufferOptions { + content?: StyledText | string; +} +export declare class TextRenderable extends TextBufferRenderable { + private _text; + private _hasManualStyledText; + protected rootTextNode: RootTextNodeRenderable; + protected _contentDefaultOptions: { + content: string; + }; + constructor(ctx: RenderContext, options: TextOptions); + private updateTextBuffer; + private clearChunks; + get content(): StyledText; + get chunks(): TextChunk[]; + get textNode(): RootTextNodeRenderable; + set content(value: StyledText | string); + private updateTextFromNodes; + add(obj: TextNodeRenderable | StyledText | string, index?: number): number; + remove(id: string): void; + insertBefore(obj: BaseRenderable | any, anchor?: TextNodeRenderable): number; + getTextChildren(): BaseRenderable[]; + clear(): void; + onLifecyclePass: () => void; + protected onFgChanged(newColor: RGBA): void; + protected onBgChanged(newColor: RGBA): void; + protected onAttributesChanged(newAttributes: number): void; + destroy(): void; +} diff --git a/.patches/@opentui/core/renderables/TextBufferRenderable.d.ts b/.patches/@opentui/core/renderables/TextBufferRenderable.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/TextBufferRenderable.d.ts @@ -0,0 +1,106 @@ +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import { Selection, type LocalSelectionBounds } from "../lib/selection.js"; +import { TextBuffer } from "../text-buffer.js"; +import { TextBufferView } from "../text-buffer-view.js"; +import { RGBA } from "../lib/RGBA.js"; +import { type RenderContext, type LineInfoProvider } from "../types.js"; +import type { OptimizedBuffer } from "../buffer.js"; +import type { LineInfo } from "../zig.js"; +import { SyntaxStyle } from "../syntax-style.js"; +export interface TextBufferOptions extends RenderableOptions { + fg?: string | RGBA; + bg?: string | RGBA; + selectionBg?: string | RGBA; + selectionFg?: string | RGBA; + selectable?: boolean; + attributes?: number; + wrapMode?: "none" | "char" | "word"; + tabIndicator?: string | number; + tabIndicatorColor?: string | RGBA; + truncate?: boolean; +} +export declare abstract class TextBufferRenderable extends Renderable implements LineInfoProvider { + selectable: boolean; + protected _defaultFg: RGBA; + protected _defaultBg: RGBA; + protected _defaultAttributes: number; + protected _selectionBg: RGBA | undefined; + protected _selectionFg: RGBA | undefined; + protected _wrapMode: "none" | "char" | "word"; + protected lastLocalSelection: LocalSelectionBounds | null; + protected _tabIndicator?: string | number; + protected _tabIndicatorColor?: RGBA; + protected _scrollX: number; + protected _scrollY: number; + protected _truncate: boolean; + protected _firstLineOffset: number; + protected textBuffer: TextBuffer; + protected textBufferView: TextBufferView; + protected _textBufferSyntaxStyle: SyntaxStyle; + protected _defaultOptions: { + fg: RGBA; + bg: RGBA; + selectionBg: undefined; + selectionFg: undefined; + selectable: true; + attributes: number; + wrapMode: "none" | "char" | "word"; + tabIndicator: undefined; + tabIndicatorColor: undefined; + truncate: false; + }; + constructor(ctx: RenderContext, options: TextBufferOptions); + protected onMouseEvent(event: any): void; + protected handleScroll(event: any): void; + get lineInfo(): LineInfo; + get lineCount(): number; + get virtualLineCount(): number; + get scrollY(): number; + set scrollY(value: number); + get scrollX(): number; + set scrollX(value: number); + get scrollWidth(): number; + get scrollHeight(): number; + get maxScrollY(): number; + get maxScrollX(): number; + protected updateViewportOffset(): void; + get plainText(): string; + get textLength(): number; + get fg(): RGBA; + set fg(value: RGBA | string | undefined); + get selectionBg(): RGBA | undefined; + set selectionBg(value: RGBA | string | undefined); + get selectionFg(): RGBA | undefined; + set selectionFg(value: RGBA | string | undefined); + get bg(): RGBA; + set bg(value: RGBA | string | undefined); + get attributes(): number; + set attributes(value: number); + get wrapMode(): "none" | "char" | "word"; + set wrapMode(value: "none" | "char" | "word"); + get tabIndicator(): string | number | undefined; + set tabIndicator(value: string | number | undefined); + get tabIndicatorColor(): RGBA | undefined; + set tabIndicatorColor(value: RGBA | string | undefined); + get truncate(): boolean; + set truncate(value: boolean); + protected onResize(width: number, height: number): void; + protected refreshLocalSelection(): boolean; + private updateLocalSelection; + protected updateTextInfo(): void; + private setupMeasureFunc; + shouldStartSelection(x: number, y: number): boolean; + onSelectionChanged(selection: Selection | null): boolean; + getSelectedText(): string; + hasSelection(): boolean; + getSelection(): { + start: number; + end: number; + } | null; + render(buffer: OptimizedBuffer, deltaTime: number): void; + protected renderSelf(buffer: OptimizedBuffer): void; + destroy(): void; + protected onFgChanged(newColor: RGBA): void; + protected onBgChanged(newColor: RGBA): void; + protected onAttributesChanged(newAttributes: number): void; +} diff --git a/.patches/@opentui/core/renderables/TextNode.d.ts b/.patches/@opentui/core/renderables/TextNode.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/TextNode.d.ts @@ -0,0 +1,91 @@ +import type { TextRenderable } from "./Text.js"; +import { BaseRenderable, type BaseRenderableOptions } from "../Renderable.js"; +import { RGBA } from "../lib/RGBA.js"; +import { StyledText } from "../lib/styled-text.js"; +import { type TextChunk } from "../text-buffer.js"; +import type { RenderContext } from "../types.js"; +export interface TextNodeOptions extends BaseRenderableOptions { + fg?: string | RGBA; + bg?: string | RGBA; + attributes?: number; + link?: { + url: string; + }; +} +declare const BrandedTextNodeRenderable: unique symbol; +export declare function isTextNodeRenderable(obj: any): obj is TextNodeRenderable; +export declare class TextNodeRenderable extends BaseRenderable { + [BrandedTextNodeRenderable]: boolean; + private _fg?; + private _bg?; + private _attributes; + private _link?; + private _children; + parent: TextNodeRenderable | null; + constructor(options: TextNodeOptions); + get children(): (string | TextNodeRenderable)[]; + set children(children: (string | TextNodeRenderable)[]); + requestRender(): void; + add(obj: TextNodeRenderable | StyledText | string, index?: number): number; + replace(obj: TextNodeRenderable | string, index: number): void; + insertBefore(child: string | TextNodeRenderable | StyledText, anchorNode: TextNodeRenderable | string | unknown): this; + remove(id: string): this; + clear(): void; + mergeStyles(parentStyle: { + fg?: RGBA; + bg?: RGBA; + attributes: number; + link?: { + url: string; + }; + }): { + fg?: RGBA; + bg?: RGBA; + attributes: number; + link?: { + url: string; + }; + }; + gatherWithInheritedStyle(parentStyle?: { + fg?: RGBA; + bg?: RGBA; + attributes: number; + link?: { + url: string; + }; + }): TextChunk[]; + static fromString(text: string, options?: Partial): TextNodeRenderable; + static fromNodes(nodes: TextNodeRenderable[], options?: Partial): TextNodeRenderable; + toChunks(parentStyle?: { + fg?: RGBA; + bg?: RGBA; + attributes: number; + link?: { + url: string; + }; + }): TextChunk[]; + getChildren(): BaseRenderable[]; + getChildrenCount(): number; + getRenderable(id: string): BaseRenderable | undefined; + getRenderableIndex(id: string): number; + get fg(): RGBA | undefined; + set fg(fg: RGBA | string | undefined); + set bg(bg: RGBA | string | undefined); + get bg(): RGBA | undefined; + set attributes(attributes: number); + get attributes(): number; + set link(link: { + url: string; + } | undefined); + get link(): { + url: string; + } | undefined; + findDescendantById(id: string): BaseRenderable | undefined; +} +export declare class RootTextNodeRenderable extends TextNodeRenderable { + private readonly ctx; + textParent: TextRenderable; + constructor(ctx: RenderContext, options: TextNodeOptions, textParent: TextRenderable); + requestRender(): void; +} +export {}; diff --git a/.patches/@opentui/core/renderables/TextTable.d.ts b/.patches/@opentui/core/renderables/TextTable.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/TextTable.d.ts @@ -0,0 +1,154 @@ +import { type RenderableOptions, Renderable } from "../Renderable.js"; +import type { OptimizedBuffer } from "../buffer.js"; +import { type BorderStyle } from "../lib/border.js"; +import { type Selection } from "../lib/selection.js"; +import { RGBA, type ColorInput } from "../lib/RGBA.js"; +import { type TextChunk } from "../text-buffer.js"; +import type { RenderContext } from "../types.js"; +export type TextTableCellContent = TextChunk[] | null | undefined; +export type TextTableContent = TextTableCellContent[][]; +export type TextTableColumnWidthMode = "content" | "full"; +export type TextTableColumnFitter = "proportional" | "balanced"; +export interface TextTableOptions extends RenderableOptions { + content?: TextTableContent; + wrapMode?: "none" | "char" | "word"; + columnWidthMode?: TextTableColumnWidthMode; + columnFitter?: TextTableColumnFitter; + cellPadding?: number; + cellPaddingX?: number; + cellPaddingY?: number; + columnGap?: number; + showBorders?: boolean; + border?: boolean; + outerBorder?: boolean; + selectable?: boolean; + selectionBg?: ColorInput; + selectionFg?: ColorInput; + borderStyle?: BorderStyle; + borderColor?: ColorInput; + borderBackgroundColor?: ColorInput; + backgroundColor?: ColorInput; + fg?: ColorInput; + bg?: ColorInput; + attributes?: number; +} +export declare class TextTableRenderable extends Renderable { + private _content; + private _wrapMode; + private _columnWidthMode; + private _columnFitter; + private _cellPaddingX; + private _cellPaddingY; + private _columnGap; + private _showBorders; + private _border; + private _outerBorder; + private _hasExplicitOuterBorder; + private _borderStyle; + private _borderColor; + private _borderBackgroundColor; + private _backgroundColor; + private _defaultFg; + private _defaultBg; + private _defaultAttributes; + private _selectionBg; + private _selectionFg; + private _lastLocalSelection; + private _lastSelectionMode; + private _cells; + private _prevCellContent; + private _rowCount; + private _columnCount; + private _layout; + private _layoutDirty; + private _rasterDirty; + private _cachedMeasureLayout; + private _cachedMeasureWidth; + private readonly _defaultOptions; + constructor(ctx: RenderContext, options?: TextTableOptions); + get content(): TextTableContent; + set content(value: TextTableContent); + get wrapMode(): "none" | "char" | "word"; + set wrapMode(value: "none" | "char" | "word"); + get columnWidthMode(): TextTableColumnWidthMode; + set columnWidthMode(value: TextTableColumnWidthMode); + get columnFitter(): TextTableColumnFitter; + set columnFitter(value: TextTableColumnFitter); + get cellPadding(): number; + set cellPadding(value: number); + get cellPaddingX(): number; + set cellPaddingX(value: number); + get cellPaddingY(): number; + set cellPaddingY(value: number); + get columnGap(): number; + set columnGap(value: number); + get showBorders(): boolean; + set showBorders(value: boolean); + get outerBorder(): boolean; + set outerBorder(value: boolean); + get border(): boolean; + set border(value: boolean); + get borderStyle(): BorderStyle; + set borderStyle(value: BorderStyle); + get borderColor(): RGBA; + set borderColor(value: ColorInput); + shouldStartSelection(x: number, y: number): boolean; + onSelectionChanged(selection: Selection | null): boolean; + hasSelection(): boolean; + getSelection(): { + start: number; + end: number; + } | null; + getSelectedText(): string; + protected onResize(width: number, height: number): void; + protected renderSelf(buffer: OptimizedBuffer): void; + protected destroySelf(): void; + private setupMeasureFunc; + private rebuildCells; + private updateCellsDiff; + private createCell; + private toStyledText; + private destroyCells; + private rebuildLayoutForCurrentWidth; + private computeLayout; + private isFullWidthMode; + private computeColumnWidths; + private expandColumnWidths; + private fitColumnWidths; + private fitColumnWidthsProportional; + private fitColumnWidthsBalanced; + private allocateShrinkByWeight; + private computeRowHeights; + private computeOffsets; + private getInterColumnGap; + private getTotalInterColumnGap; + private applyLayoutToViews; + private resolveBorderLayout; + private getVerticalBorderCount; + private getHorizontalBorderCount; + private drawBorders; + private drawCells; + private drawCellRange; + private redrawSelectionRows; + private clearCellRange; + private ensureLayoutReady; + private getCellAtLocalPosition; + private applySelectionToCells; + private resolveSelectionResolution; + private getColumnAtLocalX; + private getFullCellSelectionCoords; + private findRowForLocalY; + private getSelectionRowRange; + private getDirtySelectionRowRange; + private resetRowSelection; + private resetCellSelections; + private createEmptyLayout; + private resolveLayoutWidthConstraint; + private getHorizontalCellPadding; + private getVerticalCellPadding; + private resolveColumnFitter; + private resolveCellPadding; + private resolveColumnGap; + private invalidateLayoutAndRaster; + private invalidateRasterOnly; +} diff --git a/.patches/@opentui/core/renderables/Textarea.d.ts b/.patches/@opentui/core/renderables/Textarea.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/Textarea.d.ts @@ -0,0 +1,65 @@ +import type { KeyEvent, PasteEvent } from "../lib/KeyHandler.js"; +import { RGBA, type ColorInput } from "../lib/RGBA.js"; +import { type RenderContext } from "../types.js"; +import { EditBufferRenderable, type EditBufferOptions } from "./EditBufferRenderable.js"; +import { type KeyBinding as BaseKeyBinding } from "../lib/keybinding.internal.js"; +import { type StyledText } from "../lib/styled-text.js"; +import type { ExtmarksController } from "../lib/extmarks.js"; +export type TextareaAction = "move-left" | "move-right" | "move-up" | "move-down" | "select-left" | "select-right" | "select-up" | "select-down" | "line-home" | "line-end" | "select-line-home" | "select-line-end" | "visual-line-home" | "visual-line-end" | "select-visual-line-home" | "select-visual-line-end" | "buffer-home" | "buffer-end" | "select-buffer-home" | "select-buffer-end" | "delete-line" | "delete-to-line-end" | "delete-to-line-start" | "backspace" | "delete" | "newline" | "undo" | "redo" | "word-forward" | "word-backward" | "select-word-forward" | "select-word-backward" | "delete-word-forward" | "delete-word-backward" | "select-all" | "submit"; +export type KeyBinding = BaseKeyBinding; +export type TextareaKeyAliasMap = Record; +export declare const defaultTextareaKeyBindings: KeyBinding[]; +export interface SubmitEvent { +} +export interface TextareaOptions extends EditBufferOptions { + initialValue?: string; + backgroundColor?: ColorInput; + textColor?: ColorInput; + focusedBackgroundColor?: ColorInput; + focusedTextColor?: ColorInput; + placeholder?: StyledText | string | null; + placeholderColor?: ColorInput; + keyBindings?: KeyBinding[]; + keyAliasMap?: TextareaKeyAliasMap; + onSubmit?: (event: SubmitEvent) => void; +} +export declare class TextareaRenderable extends EditBufferRenderable { + private _placeholder; + private _placeholderColor; + private _unfocusedBackgroundColor; + private _unfocusedTextColor; + private _focusedBackgroundColor; + private _focusedTextColor; + private _keyBindingsMap; + private _keyAliasMap; + private _keyBindings; + private _actionHandlers; + private _initialValueSet; + private _submitListener; + private static readonly defaults; + constructor(ctx: RenderContext, options: TextareaOptions); + private applyPlaceholder; + private buildActionHandlers; + handlePaste(event: PasteEvent): void; + handleKeyPress(key: KeyEvent): boolean; + private updateColors; + focus(): void; + blur(): void; + get placeholder(): StyledText | string | null; + set placeholder(value: StyledText | string | null | undefined); + get placeholderColor(): RGBA; + set placeholderColor(value: ColorInput); + get backgroundColor(): RGBA; + set backgroundColor(value: RGBA | string | undefined); + get textColor(): RGBA; + set textColor(value: RGBA | string | undefined); + set focusedBackgroundColor(value: ColorInput); + set focusedTextColor(value: ColorInput); + set initialValue(value: string); + submit(): boolean; + set onSubmit(handler: ((event: SubmitEvent) => void) | undefined); + get onSubmit(): ((event: SubmitEvent) => void) | undefined; + set keyBindings(bindings: KeyBinding[]); + set keyAliasMap(aliases: TextareaKeyAliasMap); + get extmarks(): ExtmarksController; +} diff --git a/.patches/@opentui/core/renderables/TimeToFirstDraw.d.ts b/.patches/@opentui/core/renderables/TimeToFirstDraw.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/TimeToFirstDraw.d.ts @@ -0,0 +1,24 @@ +import type { OptimizedBuffer } from "../buffer.js"; +import { type ColorInput } from "../lib/RGBA.js"; +import { Renderable, type RenderableOptions } from "../Renderable.js"; +import type { RenderContext } from "../types.js"; +export interface TimeToFirstDrawOptions extends RenderableOptions { + fg?: ColorInput; + label?: string; + precision?: number; +} +export declare class TimeToFirstDrawRenderable extends Renderable { + private _runtimeMs; + private textColor; + private label; + private precision; + constructor(ctx: RenderContext, options?: TimeToFirstDrawOptions); + get runtimeMs(): number | null; + set fg(value: ColorInput); + set color(value: ColorInput); + set textLabel(value: string); + set decimals(value: number); + reset(): void; + protected renderSelf(buffer: OptimizedBuffer): void; + private normalizePrecision; +} diff --git a/.patches/@opentui/core/renderables/__tests__/renderable-test-utils.d.ts b/.patches/@opentui/core/renderables/__tests__/renderable-test-utils.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/__tests__/renderable-test-utils.d.ts @@ -0,0 +1,12 @@ +import { TextareaRenderable } from "../Textarea.js"; +import { type TestRenderer } from "../../testing/test-renderer.js"; +import { type TextareaOptions } from "../Textarea.js"; +import type { DiffRenderable } from "../Diff.js"; +import type { MockTreeSitterClient } from "../../testing/mock-tree-sitter-client.js"; +import type { ManualClock } from "../../testing/manual-clock.js"; +export declare function createTextareaRenderable(renderer: TestRenderer, renderOnce: () => Promise, options: TextareaOptions): Promise<{ + textarea: TextareaRenderable; + root: any; +}>; +export declare function settleDiffHighlighting(diff: DiffRenderable, client: MockTreeSitterClient, render: () => Promise): Promise; +export declare function simulateFrames(clock: ManualClock, renderOnce: () => Promise, ms: number, frameInterval?: number): Promise; diff --git a/.patches/@opentui/core/renderables/composition/VRenderable.d.ts b/.patches/@opentui/core/renderables/composition/VRenderable.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/composition/VRenderable.d.ts @@ -0,0 +1,16 @@ +import { Renderable, type RenderableOptions } from "../../Renderable.js"; +import type { OptimizedBuffer } from "../../buffer.js"; +import type { RenderContext } from "../../types.js"; +export interface VRenderableOptions extends RenderableOptions { + render?: (this: VRenderable | VRenderableOptions, buffer: OptimizedBuffer, deltaTime: number, renderable: VRenderable) => void; +} +/** + * A generic renderable that accepts a custom render function as a prop. + * This allows functional constructs to specify custom rendering behavior + * without needing to subclass Renderable. + */ +export declare class VRenderable extends Renderable { + private options; + constructor(ctx: RenderContext, options: VRenderableOptions); + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void; +} diff --git a/.patches/@opentui/core/renderables/composition/constructs.d.ts b/.patches/@opentui/core/renderables/composition/constructs.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/composition/constructs.d.ts @@ -0,0 +1,35 @@ +import { ASCIIFontRenderable, BoxRenderable, CodeRenderable, InputRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextRenderable, VRenderable, FrameBufferRenderable, type ASCIIFontOptions, type BoxOptions, type CodeOptions, type TextOptions, type VRenderableOptions, type InputRenderableOptions, type ScrollBoxOptions, type SelectRenderableOptions, type TabSelectRenderableOptions, type FrameBufferOptions } from "..//index.js"; +import { TextNodeRenderable } from "../TextNode.js"; +import { type VChild } from "./vnode.js"; +import type { RGBA } from "../../lib/RGBA.js"; +export declare function Generic(props?: VRenderableOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function Box(props?: BoxOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function Text(props?: TextOptions & { + content?: any; +}, ...children: VChild[] | TextNodeRenderable[]): import("./vnode.js").ProxiedVNode; +export declare function ASCIIFont(props?: ASCIIFontOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function Input(props?: InputRenderableOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function Select(props?: SelectRenderableOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function TabSelect(props?: TabSelectRenderableOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function FrameBuffer(props: FrameBufferOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function Code(props: CodeOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare function ScrollBox(props?: ScrollBoxOptions, ...children: VChild[]): import("./vnode.js").ProxiedVNode; +export declare const vstyles: { + bold: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + italic: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + underline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + dim: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + blink: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + inverse: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + hidden: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + strikethrough: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + boldItalic: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + boldUnderline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + italicUnderline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + boldItalicUnderline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + color: (color: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + bgColor: (bgColor: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + fg: (color: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + bg: (bgColor: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; + styled: (attributes?: number, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable; +}; diff --git a/.patches/@opentui/core/renderables/composition/vnode.d.ts b/.patches/@opentui/core/renderables/composition/vnode.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/composition/vnode.d.ts @@ -0,0 +1,46 @@ +import { Renderable, type RenderableOptions } from "../../Renderable.js"; +import type { RenderContext } from "../../types.js"; +export type VChild = VNode | Renderable | VChild[] | null | undefined | false; +export interface PendingCall { + method: string; + args: any[]; + isProperty?: boolean; +} +declare const BrandedVNode: unique symbol; +export interface VNode

    { + [BrandedVNode]: true; + type: Construct

    ; + props?: P; + children?: C; + __delegateMap?: Record; + __pendingCalls?: PendingCall[]; +} +export type ProxiedVNode> = VNode ? P : any> & { + [K in keyof InstanceType]: InstanceType[K] extends (...args: infer Args) => any ? (...args: Args) => ProxiedVNode : InstanceType[K]; +}; +export interface RenderableConstructor

    = RenderableOptions> { + new (ctx: RenderContext, options: P): Renderable; +} +export type FunctionalConstruct

    = (props: P, children?: VChild[]) => VNode; +export type Construct

    = RenderableConstructor

    ? P : never> | FunctionalConstruct

    ; +export declare function h>(type: TCtor, props?: TCtor extends RenderableConstructor ? P : never, ...children: VChild[]): ProxiedVNode; +export declare function h

    (type: FunctionalConstruct

    , props?: P, ...children: VChild[]): VNode

    ; +export declare function h

    (type: Construct

    , props?: P, ...children: VChild[]): VNode

    | ProxiedVNode; +export declare function isVNode(node: any): node is VNode; +export declare function maybeMakeRenderable(ctx: RenderContext, node: Renderable | VNode | unknown): Renderable | null; +export declare function wrapWithDelegates>(instance: T, delegateMap: Record | undefined): T; +export type InstantiateFn = Renderable & { + __node?: NodeType; +}; +export declare function instantiate(ctx: RenderContext, node: NodeType): InstantiateFn; +export type DelegateMap = Partial>; +export type ValidateShape = { + [K in keyof Given]: K extends keyof AllowedKeys ? NonNullable : never; +}; +type InferNode = T extends InstantiateFn ? U : never; +export declare function delegate, InnerNode extends InferNode, TargetMap extends Record, const Mapping extends Partial>(mapping: ValidateShape, vnode: Factory): Renderable; +export declare function delegate, TargetMap extends Record, string>, const Mapping extends Partial>(mapping: ValidateShape, vnode: ProxiedVNode): ProxiedVNode; +export declare function delegate, const Mapping extends DelegateMap>>(mapping: ValidateShape, vnode: VNode & { + type: ConstructorType; +}): VNode; +export {}; diff --git a/.patches/@opentui/core/renderables/index.d.ts b/.patches/@opentui/core/renderables/index.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/index.d.ts @@ -0,0 +1,23 @@ +export * from "./ASCIIFont.js"; +export * from "./Box.js"; +export * from "./Code.js"; +export * from "./composition/constructs.js"; +export * from "./composition/VRenderable.js"; +export * from "./composition/vnode.js"; +export * from "./Diff.js"; +export * from "./EditBufferRenderable.js"; +export * from "./FrameBuffer.js"; +export * from "./Input.js"; +export * from "./LineNumberRenderable.js"; +export * from "./Markdown.js"; +export * from "./ScrollBar.js"; +export * from "./ScrollBox.js"; +export * from "./Select.js"; +export * from "./Slider.js"; +export * from "./TextTable.js"; +export * from "./TabSelect.js"; +export * from "./Text.js"; +export * from "./TimeToFirstDraw.js"; +export * from "./TextBufferRenderable.js"; +export * from "./TextNode.js"; +export * from "./Textarea.js"; diff --git a/.patches/@opentui/core/renderables/markdown-parser.d.ts b/.patches/@opentui/core/renderables/markdown-parser.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderables/markdown-parser.d.ts @@ -0,0 +1,11 @@ +import { type MarkedToken } from "marked"; +export interface ParseState { + content: string; + tokens: MarkedToken[]; + stableTokenCount?: number; +} +/** + * Incrementally parse markdown, reusing unchanged tokens from previous parse. + * Compares token.raw at each offset - matching tokens keep same object reference. + */ +export declare function parseMarkdownIncremental(newContent: string, prevState: ParseState | null, trailingUnstable?: number): ParseState; diff --git a/.patches/@opentui/core/renderer-theme-mode.d.ts b/.patches/@opentui/core/renderer-theme-mode.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderer-theme-mode.d.ts @@ -0,0 +1,29 @@ +import { type Clock } from "./lib/clock.js"; +import type { ThemeMode } from "./types.js"; +export interface RendererThemeModeHost { + queryThemeColors(): void; +} +export declare class RendererThemeMode { + private readonly host; + private readonly clock; + private static readonly QUERY_TIMEOUT_MS; + private _themeMode; + private themeQueryPending; + private themeOscForeground; + private themeOscBackground; + private themeRefreshTimeoutId; + private waiters; + constructor(host: RendererThemeModeHost, clock: Clock); + get themeMode(): ThemeMode | null; + waitForThemeMode(timeoutMs: number, isDestroyed: boolean): Promise; + cancelRefresh(): void; + dispose(): void; + handleSequence(sequence: string): { + handled: boolean; + changedMode: ThemeMode | null; + }; + private clearThemeRefreshTimeout; + private completeThemeQuery; + private requestThemeOscColors; + private applyThemeMode; +} diff --git a/.patches/@opentui/core/renderer.d.ts b/.patches/@opentui/core/renderer.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/renderer.d.ts @@ -0,0 +1,601 @@ +import { Renderable, RootRenderable } from "./Renderable.js"; +import { DebugOverlayCorner, type CursorStyleOptions, type MousePointerStyle, type RenderContext, type TerminalCapabilities, type ThemeMode, type WidthMethod } from "./types.js"; +import { RGBA, type ColorInput } from "./lib/RGBA.js"; +import { OptimizedBuffer } from "./buffer.js"; +import { type NativeBufferedOutput, type NativeRenderStats, type RendererHandle } from "./zig.js"; +import { TerminalConsole, type ConsoleOptions } from "./console.js"; +import { type MouseEventType, type RawMouseEvent, type ScrollInfo } from "./lib/parse.mouse.js"; +import { Selection } from "./lib/selection.js"; +import { type ClipboardTarget } from "./lib/clipboard.js"; +import { EventEmitter } from "events"; +import { KeyHandler, InternalKeyHandler } from "./lib/KeyHandler.js"; +import { type EditBufferRenderable } from "./renderables/EditBufferRenderable.js"; +import { type TerminalColors, type GetPaletteOptions } from "./lib/terminal-palette.js"; +import { type Clock } from "./lib/clock.js"; +export interface CliRendererConfig { + stdin?: NodeJS.ReadStream; + stdout?: NodeJS.WriteStream; + width?: number; + height?: number; + remote?: boolean; + bufferedOutput?: NativeBufferedOutput; + exitOnCtrlC?: boolean; + exitSignals?: NodeJS.Signals[]; + clearOnShutdown?: boolean; + forwardEnvKeys?: string[]; + debounceDelay?: number; + targetFps?: number; + maxFps?: number; + memorySnapshotInterval?: number; + useThread?: boolean; + gatherStats?: boolean; + maxStatSamples?: number; + consoleOptions?: Omit; + postProcessFns?: ((buffer: OptimizedBuffer, deltaTime: number) => void)[]; + enableMouseMovement?: boolean; + useMouse?: boolean; + autoFocus?: boolean; + screenMode?: ScreenMode; + footerHeight?: number; + externalOutputMode?: ExternalOutputMode; + consoleMode?: ConsoleMode; + useKittyKeyboard?: KittyKeyboardOptions | null; + backgroundColor?: ColorInput; + openConsoleOnError?: boolean; + prependInputHandlers?: ((sequence: string) => boolean)[]; + stdinParserMaxBufferBytes?: number; + clock?: Clock; + onDestroy?: () => void; +} +export type ScreenMode = "alternate-screen" | "main-screen" | "split-footer"; +export type ExternalOutputMode = "capture-stdout" | "passthrough"; +export interface CliRendererExternalOutputEvent { + snapshot: OptimizedBuffer; + rowColumns: number; + startOnNewLine: boolean; + trailingNewline: boolean; +} +export type ConsoleMode = "console-overlay" | "disabled"; +export type PixelResolution = { + width: number; + height: number; +}; +export interface CliRendererStats extends NativeRenderStats { + fps: number; + frameCount: number; + frameTimes: number[]; + averageFrameTime: number; + minFrameTime: number; + maxFrameTime: number; + frameCallbackTime: number; +} +export interface CliRendererFrameEvent { + frameId: number; +} +export interface RendererSchedulerState { + isRunning: boolean; + isRendering: boolean; + hasScheduledRender: boolean; +} +export interface ScrollbackRenderContext { + width: number; + widthMethod: WidthMethod; + tailColumn: number; + renderContext: RenderContext; +} +export interface ScrollbackSnapshot { + root: Renderable; + width?: number; + height?: number; + rowColumns?: number; + startOnNewLine?: boolean; + trailingNewline?: boolean; + teardown?: () => void; +} +export type ScrollbackWriter = (ctx: ScrollbackRenderContext) => ScrollbackSnapshot; +export interface ScrollbackSurfaceOptions { + startOnNewLine?: boolean; +} +export interface ScrollbackSurfaceCommitOptions { + rowColumns?: number; + trailingNewline?: boolean; +} +export interface ScrollbackSurface { + readonly renderContext: RenderContext; + readonly root: Renderable; + readonly width: number; + readonly height: number; + readonly isDestroyed: boolean; + render(): void; + settle(timeoutMs?: number): Promise; + commitRows(startRow: number, endRowExclusive: number, options?: ScrollbackSurfaceCommitOptions): void; + destroy(): void; +} +export interface SplitFooterReplayResetOptions { + clearSavedLines?: boolean; +} +/** + * Kitty Keyboard Protocol configuration options + * See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement + */ +export interface KittyKeyboardOptions { + /** Disambiguate escape codes (fixes ESC timing, alt+key ambiguity, ctrl+c as event). Default: true */ + disambiguate?: boolean; + /** Report alternate keys (numpad, shifted, base layout) for cross-keyboard shortcuts. Default: true */ + alternateKeys?: boolean; + /** Report event types (press/repeat/release). Default: false */ + events?: boolean; + /** Report all keys as escape codes. Default: false */ + allKeysAsEscapes?: boolean; + /** Report text associated with key events. Default: false */ + reportText?: boolean; +} +/** + * Build kitty keyboard protocol flags based on configuration + * @param config Kitty keyboard configuration object (null/undefined = disabled) + * @returns The combined flags value (0 = disabled, >0 = enabled) + * @internal Exported for testing + */ +export declare function buildKittyKeyboardFlags(config: KittyKeyboardOptions | null | undefined): number; +export declare class MouseEvent { + readonly type: MouseEventType; + readonly button: number; + readonly x: number; + readonly y: number; + readonly source?: Renderable; + readonly modifiers: { + shift: boolean; + alt: boolean; + ctrl: boolean; + }; + readonly scroll?: ScrollInfo; + readonly target: Renderable | null; + readonly isDragging?: boolean; + private _propagationStopped; + private _defaultPrevented; + get propagationStopped(): boolean; + get defaultPrevented(): boolean; + constructor(target: Renderable | null, attributes: RawMouseEvent & { + source?: Renderable; + isDragging?: boolean; + }); + stopPropagation(): void; + preventDefault(): void; +} +export declare enum MouseButton { + LEFT = 0, + MIDDLE = 1, + RIGHT = 2, + WHEEL_UP = 4, + WHEEL_DOWN = 5 +} +/** + * Create a CLI renderer and run its async terminal setup. The constructor + * owns all stream and backend decisions; this factory only layers on the + * `--delay-start` flag and the `await setupTerminal()` convenience. + */ +export declare function createCliRenderer(config?: CliRendererConfig): Promise; +export declare enum CliRenderEvents { + RESIZE = "resize", + FRAME = "frame", + EXTERNAL_OUTPUT = "external_output", + FOCUS = "focus", + BLUR = "blur", + FOCUSED_RENDERABLE = "focused_renderable", + FOCUSED_EDITOR = "focused_editor", + THEME_MODE = "theme_mode", + PALETTE = "palette", + CAPABILITIES = "capabilities", + SELECTION = "selection", + DEBUG_OVERLAY_TOGGLE = "debugOverlay:toggle", + DESTROY = "destroy", + MEMORY_SNAPSHOT = "memory:snapshot" +} +export declare enum RendererControlState { + IDLE = "idle", + AUTO_STARTED = "auto_started", + EXPLICIT_STARTED = "explicit_started", + EXPLICIT_PAUSED = "explicit_paused", + EXPLICIT_SUSPENDED = "explicit_suspended", + EXPLICIT_STOPPED = "explicit_stopped" +} +export declare class CliRenderer extends EventEmitter implements RenderContext { + private static animationFrameId; + private lib; + rendererPtr: RendererHandle; + stdin: NodeJS.ReadStream; + private stdout; + private exitOnCtrlC; + private exitSignals; + private _exitListenersAdded; + private _isDestroyed; + private _destroyPending; + private _destroyFinalized; + private _destroyCleanupPrepared; + private _streamLeaseAcquired; + nextRenderBuffer: OptimizedBuffer; + currentRenderBuffer: OptimizedBuffer; + private _isRunning; + private _targetFps; + private _maxFps; + private automaticMemorySnapshot; + private memorySnapshotInterval; + private memorySnapshotTimer; + private lastMemorySnapshot; + readonly root: RootRenderable; + width: number; + height: number; + private _useThread; + private gatherStats; + private frameTimes; + private maxStatSamples; + private postProcessFns; + private backgroundColor; + private waitingForPixelResolution; + private readonly clock; + private rendering; + private renderingNative; + private renderTimeout; + private lastTime; + private frameCount; + private _frameId; + private lastFpsTime; + private currentFps; + private targetFrameTime; + private minTargetFrameTime; + private immediateRerenderRequested; + private updateScheduled; + private liveRequestCounter; + private _controlState; + private frameCallbacks; + private renderStats; + debugOverlay: { + enabled: any; + corner: DebugOverlayCorner; + }; + private _console; + private _resolution; + private _keyHandler; + private stdinParser; + private readonly oscSubscribers; + private hasLoggedStdinParserError; + private animationRequest; + private resizeTimeoutId; + private capabilityTimeoutId; + private xtVersionWaiters; + private splitStartupSeedTimeoutId; + private pendingSplitStartupCursorSeed; + private resizeDebounceDelay; + private enableMouseMovement; + private _useMouse; + private autoFocus; + private _screenMode; + private _footerHeight; + private _externalOutputMode; + private clearOnShutdown; + private _suspendedMouseEnabled; + private _previousControlState; + private pendingSuspendedTerminalSetup; + private suspendedNonAltSurfacePreserved; + private capturedRenderable?; + private lastOverRenderableNum; + private lastOverRenderable?; + private currentSelection; + private selectionContainers; + private clipboard; + private _splitHeight; + private renderOffset; + private splitTailColumn; + private pendingSplitFooterTransition; + private forceFullRepaintRequested; + private readonly maxSplitCommitsPerFrame; + private _terminalWidth; + private _terminalHeight; + private _terminalIsSetup; + private externalOutputQueue; + private pendingExternalOutputMode; + private realStdoutWrite; + private _useConsole; + private sigwinchHandler; + private _capabilities; + private _latestPointer; + private _hasPointer; + private _lastPointerModifiers; + private _currentMousePointerStyle; + private _currentFocusedRenderable; + private lifecyclePasses; + private _openConsoleOnError; + private _paletteDetector; + private _paletteCache; + private _paletteDetectionPromise; + private _paletteDetectionSize; + private _paletteEpoch; + private _nativePaletteSignature; + private _emittedPaletteSignature; + private _palettePublishGeneration; + private _onDestroy?; + private themeModeState; + private _terminalFocusState; + private sequenceHandlers; + private prependedInputHandlers; + private shouldRestoreModesOnNextFocus; + private themeModeHandler; + private idleResolvers; + private _debugInputs; + private _debugModeEnabled; + private handleError; + private dumpOutputCache; + private exitHandler; + private warningHandler; + private readonly _usesProcessStdout; + private _feed; + private _detachFeed; + private _detachFeedError; + private feedIdleRenderScheduled; + private ordinaryFrameWaitingForFeed; + private ordinaryFrameWaitControlState; + get controlState(): RendererControlState; + /** + * Construct a renderer over the given streams. + * + * If `stdout` is not `process.stdout`, a `NativeSpanFeed` is allocated + * internally and rendered bytes are piped through it to `stdout` unless + * `bufferedOutput: "memory"` is set. Prefer `createCliRenderer` for the async + * `setupTerminal` convenience. + * + * Construction side effects (observable before the constructor returns): + * - Acquires exclusive ownership of the given stdin/stdout streams + * - Allocates a `NativeSpanFeed` (for non-process stdout unless bufferedOutput is "memory") + * - Calls `lib.createRenderer` → native Zig allocation + * - Registers in the process-wide `rendererTracker` + * - Adds `process.on(...)` listeners for SIGWINCH (process.stdout only), + * "warning", "uncaughtException", "unhandledRejection", "beforeExit", + * plus the configured `exitSignals` + * - Replaces `global.requestAnimationFrame` with the renderer's impl + * - When `setupTerminal()` is called, it will put `stdin` in raw mode and + * call `stdin.resume()` + * + * Some late constructor side effects are not rolled back if construction + * throws partway; production callers should use `createCliRenderer`, which + * wraps `setupTerminal()` in a try/catch that calls `destroy()` on failure. + */ + constructor(stdin: NodeJS.ReadStream, stdout: NodeJS.WriteStream, width: number, height: number, config?: CliRendererConfig); + private addExitListeners; + private removeExitListeners; + get isDestroyed(): boolean; + registerLifecyclePass(renderable: Renderable): void; + unregisterLifecyclePass(renderable: Renderable): void; + getLifecyclePasses(): Set; + get currentFocusedRenderable(): Renderable | null; + get currentFocusedEditor(): EditBufferRenderable | null; + private normalizeClockTime; + private getElapsedMs; + focusRenderable(renderable: Renderable): void; + blurRenderable(renderable: Renderable): void; + private setCapturedRenderable; + addToHitGrid(x: number, y: number, width: number, height: number, id: number): void; + pushHitGridScissorRect(x: number, y: number, width: number, height: number): void; + popHitGridScissorRect(): void; + clearHitGridScissorRects(): void; + get widthMethod(): WidthMethod; + get frameId(): number; + private writeOut; + private scheduleRenderAfterFeedIdle; + private handleNativeRenderRejection; + private reportNativeRenderFailure; + private scheduleRenderTimer; + private scheduleRenderAfterBackpressure; + requestRender(): void; + private activateFrame; + get consoleMode(): ConsoleMode; + set consoleMode(mode: ConsoleMode); + get isRunning(): boolean; + private isIdleNow; + private resolveIdleIfNeeded; + idle(): Promise; + getSchedulerState(): RendererSchedulerState; + get resolution(): PixelResolution | null; + get console(): TerminalConsole; + get keyInput(): KeyHandler; + get _internalKeyInput(): InternalKeyHandler; + get terminalWidth(): number; + get terminalHeight(): number; + get useThread(): boolean; + get targetFps(): number; + set targetFps(targetFps: number); + get maxFps(): number; + set maxFps(maxFps: number); + get useMouse(): boolean; + set useMouse(useMouse: boolean); + get screenMode(): ScreenMode; + set screenMode(mode: ScreenMode); + get footerHeight(): number; + set footerHeight(footerHeight: number); + get externalOutputMode(): ExternalOutputMode; + set externalOutputMode(mode: ExternalOutputMode); + private applyExternalOutputMode; + private afterExternalOutputModeChanged; + private applyPendingExternalOutputModeIfReady; + private flushPendingSplitOutputBeforeLeavingSplitFooter; + get liveRequestCount(): number; + get currentControlState(): string; + get capabilities(): TerminalCapabilities | null; + triggerNotification(message: string, title?: string): boolean; + get themeMode(): ThemeMode | null; + waitForThemeMode(timeoutMs?: number): Promise; + getDebugInputs(): Array<{ + timestamp: string; + sequence: string; + }>; + get useKittyKeyboard(): boolean; + set useKittyKeyboard(use: boolean); + createScrollbackSurface(options?: ScrollbackSurfaceOptions): ScrollbackSurface; + writeToScrollback(write: ScrollbackWriter): void; + resetSplitFooterForReplay(options?: SplitFooterReplayResetOptions): void; + private getSnapshotWidth; + private getSnapshotHeight; + private getSnapshotRowWidths; + private advanceSplitTailColumn; + private getSplitTailColumnAfterCommit; + private recordSplitCommit; + private getPendingSplitTailColumn; + private enqueueRenderedScrollbackCommit; + private enqueueSplitCommit; + private createStdoutSnapshotCommit; + private splitStdoutRows; + private createStdoutSnapshotCommits; + private flushPendingSplitCommits; + private interceptStdoutWrite; + private getSplitPinnedRenderOffset; + private getSplitCursorSeedRows; + private isSplitCursorSeedFrameBlocked; + private canFlushSplitOutputBeforeTransition; + private clearSplitStartupCursorSeed; + private abortSplitStartupCursorSeed; + private flushPendingSplitOutputBeforeTransition; + private resetSplitScrollback; + private syncSplitScrollback; + private getSplitOutputOffset; + private clearPendingSplitFooterTransition; + private setPendingSplitFooterTransition; + private syncSplitFooterState; + private clearStaleSplitSurfaceRows; + private applyScreenMode; + private flushStdoutCache; + private enableMouse; + private disableMouse; + enableKittyKeyboard(flags?: number): void; + disableKittyKeyboard(): void; + set useThread(useThread: boolean); + setupTerminal(): Promise; + private stdinListener; + addInputHandler(handler: (sequence: string) => boolean): void; + prependInputHandler(handler: (sequence: string) => boolean): void; + removeInputHandler(handler: (sequence: string) => boolean): void; + private updateStdinParserProtocolContext; + subscribeOsc(handler: (sequence: string) => void): () => void; + private processCapabilitySequence; + private capabilityHandler; + private focusHandler; + private dispatchSequenceHandlers; + private drainStdinParser; + private handleStdinEvent; + private handleStdinParserFailure; + private setupInput; + private dispatchMouseEvent; + private processSingleMouseEvent; + /** + * Recheck hover state after hit grid changes. + * Called after render when native code detects the hit grid changed. + * Fires out/over events if the element under the cursor changed. + */ + private recheckHoverState; + setMousePointer(style: MousePointerStyle): void; + hitTest(x: number, y: number): number; + private takeMemorySnapshot; + private startMemorySnapshotTimer; + private stopMemorySnapshotTimer; + setMemorySnapshotInterval(interval: number): void; + private handleResize; + private queryPixelResolution; + private processResize; + /** + * Programmatically resize the renderer to new dimensions. + * + * Use this for externally-driven resize events — for example, an SSH + * `window-change` signal or a test harness simulating a terminal resize. + * When the renderer is attached to `process.stdout`, `SIGWINCH` is handled + * automatically and callers do not need this method. + */ + resize(width: number, height: number): void; + setBackgroundColor(color: ColorInput): void; + toggleDebugOverlay(): void; + configureDebugOverlay(options: { + enabled?: boolean; + corner?: DebugOverlayCorner; + }): void; + setTerminalTitle(title: string): void; + /** + * Reset the terminal background color to its default via OSC 111. + * Called automatically by destroy() and suspend(), but exposed for + * consumers that need explicit control (e.g. before SIGTSTP). + */ + resetTerminalBgColor(): void; + copyToClipboardOSC52(text: string, target?: ClipboardTarget): boolean; + clearClipboardOSC52(target?: ClipboardTarget): boolean; + isOsc52Supported(): boolean; + dumpHitGrid(): void; + dumpBuffers(timestamp?: number): void; + dumpOutputBuffer(timestamp?: number): void; + static setCursorPosition(renderer: CliRenderer, x: number, y: number, visible?: boolean): void; + static setCursorStyle(renderer: CliRenderer, options: CursorStyleOptions): void; + static setCursorColor(renderer: CliRenderer, color: RGBA): void; + setCursorPosition(x: number, y: number, visible?: boolean): void; + setCursorStyle(options: CursorStyleOptions): void; + setCursorColor(color: RGBA): void; + getCursorState(): import("./zig.js").CursorState; + addPostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void; + removePostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void; + clearPostProcessFns(): void; + setFrameCallback(callback: (deltaTime: number) => Promise): void; + removeFrameCallback(callback: (deltaTime: number) => Promise): void; + clearFrameCallbacks(): void; + requestLive(): void; + dropLive(): void; + start(): void; + auto(): void; + private internalStart; + pause(): void; + suspend(): void; + resume(): void; + private internalPause; + stop(): void; + private internalStop; + destroy(): void; + private cleanupBeforeDestroy; + private prepareDestroyDuringRender; + private finalizeDestroy; + private startRenderLoop; + private loop; + intermediateRender(): void; + private renderNative; + private collectStatSample; + getNativeStats(): NativeRenderStats; + getStats(): CliRendererStats; + resetStats(): void; + setGatherStats(enabled: boolean): void; + getSelection(): Selection | null; + get hasSelection(): boolean; + getSelectionContainer(): Renderable | null; + clearSelection(): void; + /** + * Start a new selection at the given coordinates. + * Used by both mouse and keyboard selection. + */ + startSelection(renderable: Renderable, x: number, y: number): void; + updateSelection(currentRenderable: Renderable | undefined, x: number, y: number, options?: { + finishDragging?: boolean; + }): void; + requestSelectionUpdate(): void; + private isWithinContainer; + private finishSelection; + private notifySelectablesOfSelectionChange; + private walkSelectableRenderables; + get paletteDetectionStatus(): "idle" | "detecting" | "cached"; + private getCachedPaletteBySize; + private ensurePaletteDetector; + private syncNativePaletteState; + private emitPaletteChange; + private resolveXtVersionWaiters; + private waitForXtVersion; + private shouldSyncNativePaletteState; + private refreshPalette; + clearPaletteCache(): void; + /** + * Detects the terminal's color palette + * + * @returns Promise resolving to TerminalColors object containing palette and special colors + * @throws Error if renderer is suspended + */ + getPalette(options?: GetPaletteOptions): Promise; +} diff --git a/.patches/@opentui/core/runtime-plugin-support-configure.d.ts b/.patches/@opentui/core/runtime-plugin-support-configure.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support-configure.d.ts @@ -0,0 +1,4 @@ +import { type CreateRuntimePluginOptions } from "./runtime-plugin.js"; +export declare function ensureRuntimePluginSupport(options?: CreateRuntimePluginOptions): boolean; +export { createRuntimePlugin, runtimeModuleIdForSpecifier } from "./runtime-plugin.js"; +export type { CreateRuntimePluginOptions, RuntimeModuleEntry, RuntimeModuleExports, RuntimeModuleLoader, } from "./runtime-plugin.js"; diff --git a/.patches/@opentui/core/runtime-plugin-support-configure.js b/.patches/@opentui/core/runtime-plugin-support-configure.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support-configure.js @@ -0,0 +1,36 @@ +import { plugin as registerBunPlugin } from "bun"; +import { createRuntimePlugin } from "./runtime-plugin.js"; +const runtimePluginSupportInstalledKey = "__opentuiCoreRuntimePluginSupportInstalled__"; +function normalizeRewriteKey(rewrite) { + return `${rewrite?.nodeModulesRuntimeSpecifiers ?? true}:${rewrite?.nodeModulesBareSpecifiers ?? false}`; +} +function assertCompatibleInstall(install, options) { + for (const specifier of Object.keys(options.additional ?? {})) { + if (!install.additionalSpecifiers.has(specifier)) { + throw new Error(`OpenTUI Core runtime plugin support is already installed without ${specifier}. Call ensureRuntimePluginSupport({ additional }) from @opentui/core/runtime-plugin-support/configure before importing @opentui/core/runtime-plugin-support.`); + } + } + if (options.core && options.core !== install.core) { + throw new Error("OpenTUI Core runtime plugin support is already installed with a different core runtime module."); + } + if (options.rewrite && normalizeRewriteKey(options.rewrite) !== install.rewriteKey) { + throw new Error("OpenTUI Core runtime plugin support is already installed with different rewrite options."); + } +} +export function ensureRuntimePluginSupport(options = {}) { + const state = globalThis; + const install = state[runtimePluginSupportInstalledKey]; + if (install) { + assertCompatibleInstall(install, options); + return false; + } + registerBunPlugin(createRuntimePlugin(options)); + state[runtimePluginSupportInstalledKey] = { + additionalSpecifiers: new Set(Object.keys(options.additional ?? {})), + core: options.core, + rewriteKey: normalizeRewriteKey(options.rewrite), + }; + return true; +} +export { createRuntimePlugin, runtimeModuleIdForSpecifier } from "./runtime-plugin.js"; +//# sourceMappingURL=runtime-plugin-support-configure.js.map \ No newline at end of file diff --git a/.patches/@opentui/core/runtime-plugin-support-configure.js.map b/.patches/@opentui/core/runtime-plugin-support-configure.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support-configure.js.map @@ -0,0 +1,1 @@ +{"version":3,"file":"runtime-plugin-support-configure.js","sourceRoot":"","sources":["runtime-plugin-support-configure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,iBAAiB,EAAE,MAAM,KAAK,CAAA;AACjD,OAAO,EAAE,mBAAmB,EAA4D,MAAM,qBAAqB,CAAA;AAEnH,MAAM,gCAAgC,GAAG,8CAA8C,CAAA;AAYvF,SAAS,mBAAmB,CAAC,OAA0D;IACrF,OAAO,GAAG,OAAO,EAAE,4BAA4B,IAAI,IAAI,IAAI,OAAO,EAAE,yBAAyB,IAAI,KAAK,EAAE,CAAA;AAC1G,CAAC;AAED,SAAS,uBAAuB,CAAC,OAAoC,EAAE,OAAmC;IACxG,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CACb,oEAAoE,SAAS,8JAA8J,CAC5O,CAAA;QACH,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gGAAgG,CAAC,CAAA;IACnH,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,IAAI,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAA;IAC7G,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,UAAsC,EAAE;IACjF,MAAM,KAAK,GAAG,UAAuC,CAAA;IACrD,MAAM,OAAO,GAAG,KAAK,CAAC,gCAAgC,CAAC,CAAA;IAEvD,IAAI,OAAO,EAAE,CAAC;QACZ,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACzC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,iBAAiB,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAA;IAE/C,KAAK,CAAC,gCAAgC,CAAC,GAAG;QACxC,oBAAoB,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,UAAU,EAAE,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC;KACjD,CAAA;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA"} \ No newline at end of file diff --git a/.patches/@opentui/core/runtime-plugin-support-configure.node.js b/.patches/@opentui/core/runtime-plugin-support-configure.node.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support-configure.node.js @@ -0,0 +1,15 @@ +const errorMessage = "@opentui/core/runtime-plugin-support/configure is Bun-only and is not available in Node.js. Use Bun to import this entrypoint." + +export function ensureRuntimePluginSupport() { + throw new Error("@opentui/core/runtime-plugin-support/configure is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +export function createRuntimePlugin() { + throw new Error("@opentui/core/runtime-plugin-support/configure is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +export function runtimeModuleIdForSpecifier() { + throw new Error("@opentui/core/runtime-plugin-support/configure is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +throw new Error(errorMessage) diff --git a/.patches/@opentui/core/runtime-plugin-support.d.ts b/.patches/@opentui/core/runtime-plugin-support.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support.d.ts @@ -0,0 +1,3 @@ +import { ensureRuntimePluginSupport } from "./runtime-plugin-support-configure.js"; +export { ensureRuntimePluginSupport }; +export { createRuntimePlugin, runtimeModuleIdForSpecifier, type CreateRuntimePluginOptions, type RuntimeModuleEntry, type RuntimeModuleExports, type RuntimeModuleLoader, } from "./runtime-plugin-support-configure.js"; diff --git a/.patches/@opentui/core/runtime-plugin-support.js b/.patches/@opentui/core/runtime-plugin-support.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support.js @@ -0,0 +1,5 @@ +import { ensureRuntimePluginSupport } from "./runtime-plugin-support-configure.js"; +export { ensureRuntimePluginSupport }; +export { createRuntimePlugin, runtimeModuleIdForSpecifier, } from "./runtime-plugin-support-configure.js"; +ensureRuntimePluginSupport(); +//# sourceMappingURL=runtime-plugin-support.js.map \ No newline at end of file diff --git a/.patches/@opentui/core/runtime-plugin-support.js.map b/.patches/@opentui/core/runtime-plugin-support.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support.js.map @@ -0,0 +1,1 @@ +{"version":3,"file":"runtime-plugin-support.js","sourceRoot":"","sources":["runtime-plugin-support.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAA;AAElF,OAAO,EAAE,0BAA0B,EAAE,CAAA;AACrC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAK5B,MAAM,uCAAuC,CAAA;AAE9C,0BAA0B,EAAE,CAAA"} \ No newline at end of file diff --git a/.patches/@opentui/core/runtime-plugin-support.node.js b/.patches/@opentui/core/runtime-plugin-support.node.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin-support.node.js @@ -0,0 +1,15 @@ +const errorMessage = "@opentui/core/runtime-plugin-support is Bun-only and is not available in Node.js. Use Bun to import this entrypoint." + +export function ensureRuntimePluginSupport() { + throw new Error("@opentui/core/runtime-plugin-support is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +export function createRuntimePlugin() { + throw new Error("@opentui/core/runtime-plugin-support is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +export function runtimeModuleIdForSpecifier() { + throw new Error("@opentui/core/runtime-plugin-support is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +throw new Error(errorMessage) diff --git a/.patches/@opentui/core/runtime-plugin.d.ts b/.patches/@opentui/core/runtime-plugin.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin.d.ts @@ -0,0 +1,16 @@ +import { type BunPlugin } from "bun"; +export type RuntimeModuleExports = Record; +export type RuntimeModuleLoader = () => RuntimeModuleExports | Promise; +export type RuntimeModuleEntry = RuntimeModuleExports | RuntimeModuleLoader; +export interface RuntimePluginRewriteOptions { + nodeModulesRuntimeSpecifiers?: boolean; + nodeModulesBareSpecifiers?: boolean; +} +export interface CreateRuntimePluginOptions { + core?: RuntimeModuleEntry; + additional?: Record; + rewrite?: RuntimePluginRewriteOptions; +} +export declare const isCoreRuntimeModuleSpecifier: (specifier: string) => boolean; +export declare const runtimeModuleIdForSpecifier: (specifier: string) => string; +export declare function createRuntimePlugin(input?: CreateRuntimePluginOptions): BunPlugin; diff --git a/.patches/@opentui/core/runtime-plugin.js b/.patches/@opentui/core/runtime-plugin.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin.js @@ -0,0 +1,473 @@ +/* + * Exposes runtime-only modules (for example `@opentui/core`, `@opentui/solid`, + * `solid-js`) to externally loaded plugins by rewriting matching imports to + * virtual `opentui:runtime-module:*` ids. + * + * Why this is exact-path + prescan instead of one broad `onLoad`: + * - Bun can break CJS/UMD interop if a file is routed through plugin `onLoad` + * (real repro: `jsonc-parser` resolving to `lib/umd/main.js`; + * https://github.com/oven-sh/bun/issues/19279, + * https://github.com/oven-sh/bun/issues/21369), so arbitrary `node_modules` + * JS cannot be blanket-rewritten. + * - runtime `onResolve` is sync-only, so package/type/source discovery here is + * synchronous and cached. + * - a matched `onLoad` cannot safely fall through, so loaders must be narrow. + * - Bun may canonicalize paths before `onLoad`, so loaders are registered for + * both the resolved path spelling and its realpath, then canonical-checked. + * - Bun may native-load `node_modules` ESM without firing `onResolve` for + * nested package imports, so `node_modules` ESM is recursively prescanned and + * only files that actually need runtime rewriting get exact-path loaders. + * + * Behavior: + * - non-`node_modules` source files get a dedicated rewrite loader immediately. + * - `node_modules` files are rewritten only if they are ESM (`.mjs`, `.mts`, + * `.ts`, `.tsx`, `.jsx`, or `.js` under `package.json#type="module"`) and + * directly or transitively need runtime-module rewriting; unrelated CJS stays + * untouched. + * - optional bare-specifier rewriting is preserved for sibling files in + * packages already marked for runtime rewriting. + * + * Notes: + * - import scanning is regex-based, not a full parser. + * - CJS helper libraries that themselves import runtime modules are still not + * supported. + * - `package.json#type` caching is per plugin setup, not module-global, so a + * later plugin instance in the same process can observe filesystem changes. + */ +import { existsSync, readFileSync, realpathSync } from "node:fs"; +import { basename, dirname, isAbsolute, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import * as coreRuntime from "./index.js"; +const CORE_RUNTIME_SPECIFIER = "@opentui/core"; +const CORE_TESTING_RUNTIME_SPECIFIER = "@opentui/core/testing"; +const RUNTIME_MODULE_PREFIX = "opentui:runtime-module:"; +const MAX_RUNTIME_RESOLVE_PARENTS = 64; +const DEFAULT_RUNTIME_PLUGIN_REWRITE_OPTIONS = { + nodeModulesRuntimeSpecifiers: true, + nodeModulesBareSpecifiers: false, +}; +const DEFAULT_CORE_RUNTIME_MODULE_SPECIFIERS = [CORE_RUNTIME_SPECIFIER, CORE_TESTING_RUNTIME_SPECIFIER]; +const DEFAULT_CORE_RUNTIME_MODULE_SPECIFIER_SET = new Set(DEFAULT_CORE_RUNTIME_MODULE_SPECIFIERS); +export const isCoreRuntimeModuleSpecifier = (specifier) => { + return DEFAULT_CORE_RUNTIME_MODULE_SPECIFIER_SET.has(specifier); +}; +const loadCoreTestingRuntimeModule = async () => { + return (await import("./testing.js")); +}; +const escapeRegExp = (value) => { + return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +}; +const exactSpecifierFilter = (specifier) => { + return new RegExp(`^${escapeRegExp(specifier)}$`); +}; +const exactPathFilter = (paths) => { + const candidates = [...new Set(paths.map(sourcePath))]; + return new RegExp(`^(?:${candidates.map(escapeRegExp).join("|")})(?:[?#].*)?$`); +}; +export const runtimeModuleIdForSpecifier = (specifier) => { + return `${RUNTIME_MODULE_PREFIX}${encodeURIComponent(specifier)}`; +}; +const resolveRuntimeModuleExports = async (moduleEntry) => { + if (typeof moduleEntry === "function") { + return await moduleEntry(); + } + return moduleEntry; +}; +const sourcePath = (path) => { + const searchIndex = path.indexOf("?"); + const hashIndex = path.indexOf("#"); + const end = [searchIndex, hashIndex].filter((index) => index >= 0).sort((a, b) => a - b)[0]; + return end === undefined ? path : path.slice(0, end); +}; +const normalizedSourcePathByPath = new Map(); +const normalizeSourcePath = (path) => { + const cleanPath = sourcePath(path); + const cachedPath = normalizedSourcePathByPath.get(cleanPath); + if (cachedPath !== undefined) { + return cachedPath; + } + let normalizedPath = cleanPath; + try { + normalizedPath = realpathSync(cleanPath); + } + catch { + normalizedPath = cleanPath; + } + normalizedSourcePathByPath.set(cleanPath, normalizedPath); + return normalizedPath; +}; +const isNodeModulesPath = (path) => { + return /(?:^|[/\\])node_modules(?:[/\\])/.test(path); +}; +const packageTypeForPath = (path, packageTypeByPackageJsonPath) => { + let currentDir = dirname(path); + while (true) { + const packageJsonPath = join(currentDir, "package.json"); + if (existsSync(packageJsonPath)) { + const cachedPackageType = packageTypeByPackageJsonPath.get(packageJsonPath); + if (cachedPackageType) { + return cachedPackageType; + } + let packageType = "commonjs"; + try { + const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")); + if (packageJson.type === "module") { + packageType = "module"; + } + } + catch { + packageType = "commonjs"; + } + packageTypeByPackageJsonPath.set(packageJsonPath, packageType); + return packageType; + } + const parentDir = dirname(currentDir); + if (parentDir === currentDir) { + return "commonjs"; + } + currentDir = parentDir; + } +}; +const isNodeModulesEsmPath = (path, packageTypeByPackageJsonPath) => { + const normalizedPath = normalizeSourcePath(path); + if (!isNodeModulesPath(normalizedPath)) { + return false; + } + if (normalizedPath.endsWith(".mjs") || + normalizedPath.endsWith(".mts") || + normalizedPath.endsWith(".ts") || + normalizedPath.endsWith(".tsx") || + normalizedPath.endsWith(".jsx")) { + return true; + } + if (normalizedPath.endsWith(".cjs") || normalizedPath.endsWith(".cts") || !normalizedPath.endsWith(".js")) { + return false; + } + return packageTypeForPath(normalizedPath, packageTypeByPackageJsonPath) === "module"; +}; +const nodeModulesPackageRootForPath = (path) => { + let currentDir = dirname(path); + while (true) { + const parentDir = dirname(currentDir); + if (parentDir === currentDir) { + return null; + } + if (basename(parentDir) === "node_modules") { + return currentDir; + } + if (basename(dirname(parentDir)) === "node_modules" && basename(parentDir).startsWith("@")) { + return currentDir; + } + currentDir = parentDir; + } +}; +const resolveRuntimePluginRewriteOptions = (options) => { + return { + nodeModulesRuntimeSpecifiers: options?.nodeModulesRuntimeSpecifiers ?? DEFAULT_RUNTIME_PLUGIN_REWRITE_OPTIONS.nodeModulesRuntimeSpecifiers, + nodeModulesBareSpecifiers: options?.nodeModulesBareSpecifiers ?? DEFAULT_RUNTIME_PLUGIN_REWRITE_OPTIONS.nodeModulesBareSpecifiers, + }; +}; +const runtimeLoaderForPath = (path) => { + const cleanPath = sourcePath(path); + if (cleanPath.endsWith(".tsx")) { + return "tsx"; + } + if (cleanPath.endsWith(".jsx")) { + return "jsx"; + } + if (cleanPath.endsWith(".ts") || cleanPath.endsWith(".mts") || cleanPath.endsWith(".cts")) { + return "ts"; + } + if (cleanPath.endsWith(".js") || cleanPath.endsWith(".mjs") || cleanPath.endsWith(".cjs")) { + return "js"; + } + return null; +}; +const resolveImportSpecifierPatterns = [ + /(from\s+["'])([^"']+)(["'])/g, + /(import\s+["'])([^"']+)(["'])/g, + /(import\s*\(\s*["'])([^"']+)(["']\s*\))/g, + /(require\s*\(\s*["'])([^"']+)(["']\s*\))/g, +]; +const isBareSpecifier = (specifier) => { + if (specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("\\")) { + return false; + } + if (specifier.startsWith("node:") || + specifier.startsWith("bun:") || + specifier.startsWith("http:") || + specifier.startsWith("https:") || + specifier.startsWith("file:") || + specifier.startsWith("data:")) { + return false; + } + if (specifier.startsWith(RUNTIME_MODULE_PREFIX)) { + return false; + } + return true; +}; +const registerResolveParent = (resolveParentsByRecency, resolveParent) => { + const existingIndex = resolveParentsByRecency.indexOf(resolveParent); + if (existingIndex >= 0) { + resolveParentsByRecency.splice(existingIndex, 1); + } + resolveParentsByRecency.push(resolveParent); + if (resolveParentsByRecency.length > MAX_RUNTIME_RESOLVE_PARENTS) { + resolveParentsByRecency.shift(); + } +}; +const rewriteImportSpecifiers = (code, resolveReplacement) => { + let transformedCode = code; + for (const pattern of resolveImportSpecifierPatterns) { + transformedCode = transformedCode.replace(pattern, (fullMatch, prefix, specifier, suffix) => { + const replacement = resolveReplacement(specifier); + if (!replacement || replacement === specifier) { + return fullMatch; + } + return `${prefix}${replacement}${suffix}`; + }); + } + return transformedCode; +}; +const collectImportSpecifiers = (code) => { + const specifiers = new Set(); + for (const pattern of resolveImportSpecifierPatterns) { + code.replace(pattern, (_fullMatch, _prefix, specifier) => { + specifiers.add(specifier); + return _fullMatch; + }); + } + return [...specifiers]; +}; +const resolveFromParent = (specifier, parent) => { + try { + const resolvedSpecifier = import.meta.resolve(specifier, parent); + if (resolvedSpecifier === specifier || + resolvedSpecifier.startsWith("node:") || + resolvedSpecifier.startsWith("bun:")) { + return null; + } + return resolvedSpecifier; + } + catch { + return null; + } +}; +const resolveSourcePathFromSpecifier = (specifier, importer) => { + if (specifier.startsWith("node:") || + specifier.startsWith("bun:") || + specifier.startsWith("http:") || + specifier.startsWith("https:") || + specifier.startsWith("data:") || + specifier.startsWith(RUNTIME_MODULE_PREFIX)) { + return null; + } + if (specifier.startsWith("file:")) { + return sourcePath(fileURLToPath(specifier)); + } + if (isAbsolute(specifier)) { + return sourcePath(specifier); + } + const resolvedSpecifier = resolveFromParent(specifier, importer); + if (!resolvedSpecifier) { + return null; + } + if (resolvedSpecifier.startsWith("file:")) { + return sourcePath(fileURLToPath(resolvedSpecifier)); + } + if (isAbsolute(resolvedSpecifier)) { + return sourcePath(resolvedSpecifier); + } + return null; +}; +const rewriteImportsFromResolveParents = (code, resolveParentsByRecency) => { + if (resolveParentsByRecency.length === 0) { + return code; + } + const resolveFromParents = (specifier) => { + if (!isBareSpecifier(specifier)) { + return null; + } + for (let index = resolveParentsByRecency.length - 1; index >= 0; index -= 1) { + const resolveParent = resolveParentsByRecency[index]; + const resolvedSpecifier = resolveFromParent(specifier, resolveParent); + if (resolvedSpecifier) { + return resolvedSpecifier; + } + } + return null; + }; + return rewriteImportSpecifiers(code, resolveFromParents); +}; +const rewriteRuntimeSpecifiers = (code, runtimeModuleIdsBySpecifier) => { + return rewriteImportSpecifiers(code, (specifier) => { + const runtimeModuleId = runtimeModuleIdsBySpecifier.get(specifier); + return runtimeModuleId ?? null; + }); +}; +export function createRuntimePlugin(input = {}) { + const runtimeModules = new Map(); + runtimeModules.set(CORE_RUNTIME_SPECIFIER, input.core ?? coreRuntime); + runtimeModules.set(CORE_TESTING_RUNTIME_SPECIFIER, loadCoreTestingRuntimeModule); + const rewriteOptions = resolveRuntimePluginRewriteOptions(input.rewrite); + for (const [specifier, moduleEntry] of Object.entries(input.additional ?? {})) { + runtimeModules.set(specifier, moduleEntry); + } + const runtimeModuleIdsBySpecifier = new Map(); + for (const specifier of runtimeModules.keys()) { + runtimeModuleIdsBySpecifier.set(specifier, runtimeModuleIdForSpecifier(specifier)); + } + return { + name: "bun-plugin-opentui-runtime-modules", + setup: (build) => { + const resolveParentsByRecency = []; + const installedRewriteLoaders = new Set(); + const nodeModulesBareRewritePackageRoots = new Set(); + const packageTypeByPackageJsonPath = new Map(); + const sourceAnalysisByPath = new Map(); + const nodeModulesRuntimeRewritePathsByPath = new Map(); + const installRewriteLoader = (path) => { + const resolvedTargetPath = sourcePath(path); + const canonicalTargetPath = normalizeSourcePath(resolvedTargetPath); + if (installedRewriteLoaders.has(canonicalTargetPath)) { + return; + } + installedRewriteLoaders.add(canonicalTargetPath); + // Register both the resolved path spelling and its canonical realpath so Bun + // can reach the loader even if it reports the same file through a different alias. + build.onLoad({ filter: exactPathFilter([resolvedTargetPath, canonicalTargetPath]) }, async (args) => { + const loadedPath = normalizeSourcePath(args.path); + if (loadedPath !== canonicalTargetPath) { + return undefined; + } + const nodeModulesPath = isNodeModulesPath(loadedPath); + const shouldRewriteRuntimeSpecifiers = !nodeModulesPath || rewriteOptions.nodeModulesRuntimeSpecifiers; + const shouldRewriteBareSpecifiers = !nodeModulesPath || rewriteOptions.nodeModulesBareSpecifiers; + const loader = runtimeLoaderForPath(args.path); + if (!loader) { + throw new Error(`Unable to determine runtime loader for path: ${args.path}`); + } + const contents = await Bun.file(loadedPath).text(); + const runtimeRewrittenContents = shouldRewriteRuntimeSpecifiers + ? rewriteRuntimeSpecifiers(contents, runtimeModuleIdsBySpecifier) + : contents; + if (runtimeRewrittenContents !== contents && shouldRewriteBareSpecifiers) { + registerResolveParent(resolveParentsByRecency, loadedPath); + } + const transformedContents = shouldRewriteBareSpecifiers + ? rewriteImportsFromResolveParents(runtimeRewrittenContents, resolveParentsByRecency) + : runtimeRewrittenContents; + return { + contents: transformedContents, + loader, + }; + }); + }; + const analyzeSourcePath = (path) => { + const normalizedPath = normalizeSourcePath(path); + const cachedAnalysis = sourceAnalysisByPath.get(normalizedPath); + if (cachedAnalysis) { + return cachedAnalysis; + } + let contents; + try { + contents = readFileSync(normalizedPath, "utf8"); + } + catch (error) { + if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") { + const analysis = { importSpecifiers: [], needsRuntimeSpecifierRewrite: false }; + sourceAnalysisByPath.set(normalizedPath, analysis); + return analysis; + } + throw error; + } + const importSpecifiers = collectImportSpecifiers(contents); + const analysis = { + importSpecifiers, + needsRuntimeSpecifierRewrite: importSpecifiers.some((specifier) => runtimeModuleIdsBySpecifier.has(specifier)), + }; + sourceAnalysisByPath.set(normalizedPath, analysis); + return analysis; + }; + const collectNodeModulesRuntimeRewritePaths = (path, visiting = new Set()) => { + const normalizedPath = normalizeSourcePath(path); + if (!isNodeModulesEsmPath(normalizedPath, packageTypeByPackageJsonPath)) { + return []; + } + const cachedPaths = nodeModulesRuntimeRewritePathsByPath.get(normalizedPath); + if (cachedPaths) { + return cachedPaths; + } + if (visiting.has(normalizedPath)) { + return []; + } + visiting.add(normalizedPath); + const rewritePaths = new Set(); + const analysis = analyzeSourcePath(normalizedPath); + if (analysis.needsRuntimeSpecifierRewrite) { + rewritePaths.add(normalizedPath); + } + for (const specifier of analysis.importSpecifiers) { + const resolvedPath = resolveSourcePathFromSpecifier(specifier, normalizedPath); + if (!resolvedPath || !isNodeModulesEsmPath(resolvedPath, packageTypeByPackageJsonPath)) { + continue; + } + for (const nestedPath of collectNodeModulesRuntimeRewritePaths(resolvedPath, visiting)) { + rewritePaths.add(nestedPath); + } + } + visiting.delete(normalizedPath); + const resolvedRewritePaths = [...rewritePaths]; + nodeModulesRuntimeRewritePathsByPath.set(normalizedPath, resolvedRewritePaths); + return resolvedRewritePaths; + }; + for (const [specifier, moduleEntry] of runtimeModules.entries()) { + const moduleId = runtimeModuleIdsBySpecifier.get(specifier); + if (!moduleId) { + continue; + } + build.module(moduleId, async () => ({ + exports: await resolveRuntimeModuleExports(moduleEntry), + loader: "object", + })); + build.onResolve({ filter: exactSpecifierFilter(specifier) }, () => ({ path: moduleId })); + } + build.onResolve({ filter: /.*/ }, (args) => { + if (runtimeModuleIdsBySpecifier.has(args.path) || args.path.startsWith(RUNTIME_MODULE_PREFIX)) { + return undefined; + } + const path = resolveSourcePathFromSpecifier(args.path, args.importer); + if (!path || !runtimeLoaderForPath(path)) { + return undefined; + } + const nodeModulesPath = isNodeModulesPath(path); + if (!nodeModulesPath) { + installRewriteLoader(path); + return undefined; + } + if (!rewriteOptions.nodeModulesRuntimeSpecifiers && !rewriteOptions.nodeModulesBareSpecifiers) { + return undefined; + } + for (const rewritePath of collectNodeModulesRuntimeRewritePaths(path)) { + installRewriteLoader(rewritePath); + } + const packageRoot = nodeModulesPackageRootForPath(path); + if (rewriteOptions.nodeModulesBareSpecifiers && + packageRoot && + nodeModulesBareRewritePackageRoots.has(packageRoot)) { + installRewriteLoader(path); + return undefined; + } + if (!rewriteOptions.nodeModulesRuntimeSpecifiers || !analyzeSourcePath(path).needsRuntimeSpecifierRewrite) { + return undefined; + } + if (rewriteOptions.nodeModulesBareSpecifiers && packageRoot) { + nodeModulesBareRewritePackageRoots.add(packageRoot); + } + installRewriteLoader(path); + return undefined; + }); + }, + }; +} +//# sourceMappingURL=runtime-plugin.js.map \ No newline at end of file diff --git a/.patches/@opentui/core/runtime-plugin.js.map b/.patches/@opentui/core/runtime-plugin.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin.js.map @@ -0,0 +1,1 @@ +{"version":3,"file":"runtime-plugin.js","sourceRoot":"","sources":["runtime-plugin.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.patches/@opentui/core/runtime-plugin.node.js b/.patches/@opentui/core/runtime-plugin.node.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/runtime-plugin.node.js @@ -0,0 +1,15 @@ +const errorMessage = "@opentui/core/runtime-plugin is Bun-only and is not available in Node.js. Use Bun to import this entrypoint." + +export function createRuntimePlugin() { + throw new Error("@opentui/core/runtime-plugin is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +export function isCoreRuntimeModuleSpecifier() { + throw new Error("@opentui/core/runtime-plugin is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +export function runtimeModuleIdForSpecifier() { + throw new Error("@opentui/core/runtime-plugin is Bun-only and is not available in Node.js. Use Bun to import this entrypoint.") +} + +throw new Error(errorMessage) diff --git a/.patches/@opentui/core/syntax-style.d.ts b/.patches/@opentui/core/syntax-style.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/syntax-style.d.ts @@ -0,0 +1,61 @@ +import { RGBA, type ColorInput } from "./lib/RGBA.js"; +import { type RenderLib, type SyntaxStyleHandle } from "./zig.js"; +export interface StyleDefinition { + fg?: RGBA; + bg?: RGBA; + bold?: boolean; + italic?: boolean; + underline?: boolean; + dim?: boolean; +} +export interface StyleDefinitionInput { + fg?: ColorInput; + bg?: ColorInput; + bold?: boolean; + italic?: boolean; + underline?: boolean; + dim?: boolean; +} +export interface MergedStyle { + fg?: RGBA; + bg?: RGBA; + attributes: number; +} +export interface ThemeTokenStyle { + scope: string[]; + style: { + foreground?: ColorInput; + background?: ColorInput; + bold?: boolean; + italic?: boolean; + underline?: boolean; + dim?: boolean; + }; +} +export declare function convertThemeToStyles(theme: ThemeTokenStyle[]): Record; +export declare class SyntaxStyle { + private lib; + private stylePtr; + private _destroyed; + private nameCache; + private styleDefs; + private mergedCache; + constructor(lib: RenderLib, ptr: SyntaxStyleHandle); + static create(): SyntaxStyle; + static fromTheme(theme: ThemeTokenStyle[]): SyntaxStyle; + static fromStyles(styles: Record): SyntaxStyle; + private guard; + registerStyle(name: string, style: StyleDefinitionInput): number; + resolveStyleId(name: string): number | null; + getStyleId(name: string): number | null; + get ptr(): SyntaxStyleHandle; + getStyleCount(): number; + clearNameCache(): void; + getStyle(name: string): StyleDefinition | undefined; + mergeStyles(...styleNames: string[]): MergedStyle; + clearCache(): void; + getCacheSize(): number; + getAllStyles(): Map; + getRegisteredNames(): string[]; + destroy(): void; +} diff --git a/.patches/@opentui/core/testing.d.ts b/.patches/@opentui/core/testing.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing.d.ts @@ -0,0 +1,8 @@ +export * from "./testing/test-renderer.js"; +export * from "./testing/mock-keys.js"; +export * from "./testing/mock-mouse.js"; +export * from "./testing/mock-tree-sitter-client.js"; +export * from "./testing/terminal-capabilities.js"; +export * from "./testing/spy.js"; +export { ManualClock } from "./testing/manual-clock.js"; +export { TestRecorder, type RecordedFrame } from "./testing/test-recorder.js"; diff --git a/.patches/@opentui/core/testing.js b/.patches/@opentui/core/testing.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing.js @@ -0,0 +1,1003 @@ +import { + ANSI, + CliRenderer +} from "./index-07zpr2dg.js"; +import { + SystemClock, + TreeSitterClient +} from "./index-pcvh9d34.js"; + +// src/testing/mock-keys.ts +import { Buffer as Buffer2 } from "node:buffer"; +function pasteBytes(text) { + return Uint8Array.from(Buffer2.from(text)); +} +var KeyCodes = { + RETURN: "\r", + LINEFEED: ` +`, + TAB: "\t", + BACKSPACE: "\b", + DELETE: "\x1B[3~", + HOME: "\x1B[H", + END: "\x1B[F", + ESCAPE: "\x1B", + ARROW_UP: "\x1B[A", + ARROW_DOWN: "\x1B[B", + ARROW_RIGHT: "\x1B[C", + ARROW_LEFT: "\x1B[D", + F1: "\x1BOP", + F2: "\x1BOQ", + F3: "\x1BOR", + F4: "\x1BOS", + F5: "\x1B[15~", + F6: "\x1B[17~", + F7: "\x1B[18~", + F8: "\x1B[19~", + F9: "\x1B[20~", + F10: "\x1B[21~", + F11: "\x1B[23~", + F12: "\x1B[24~" +}; +var kittyKeyCodeMap = { + escape: 27, + tab: 9, + return: 13, + backspace: 127, + insert: 57348, + delete: 57349, + left: 57350, + right: 57351, + up: 57352, + down: 57353, + pageup: 57354, + pagedown: 57355, + home: 57356, + end: 57357, + f1: 57364, + f2: 57365, + f3: 57366, + f4: 57367, + f5: 57368, + f6: 57369, + f7: 57370, + f8: 57371, + f9: 57372, + f10: 57373, + f11: 57374, + f12: 57375 +}; +function encodeKittySequence(codepoint, modifiers) { + let modMask = 0; + if (modifiers?.shift) + modMask |= 1; + if (modifiers?.meta) + modMask |= 2; + if (modifiers?.ctrl) + modMask |= 4; + if (modifiers?.super) + modMask |= 8; + if (modifiers?.hyper) + modMask |= 16; + if (modMask === 0) { + return `\x1B[${codepoint}u`; + } else { + return `\x1B[${codepoint};${modMask + 1}u`; + } +} +function encodeModifyOtherKeysSequence(charCode, modifiers) { + let modMask = 0; + if (modifiers?.shift) + modMask |= 1; + if (modifiers?.meta) + modMask |= 2; + if (modifiers?.ctrl) + modMask |= 4; + if (modifiers?.super) + modMask |= 8; + if (modifiers?.hyper) + modMask |= 16; + if (modMask === 0) { + return String.fromCharCode(charCode); + } + return `\x1B[27;${modMask + 1};${charCode}~`; +} +function resolveKeyInput(key) { + let keyValue; + let keyName; + if (typeof key === "string") { + if (key in KeyCodes) { + keyValue = KeyCodes[key]; + keyName = key.toLowerCase(); + } else { + keyValue = key; + keyName = undefined; + } + } else { + keyValue = KeyCodes[key]; + if (!keyValue) { + throw new Error(`Unknown key: ${key}`); + } + keyName = String(key).toLowerCase(); + } + return { keyValue, keyName }; +} +function createMockKeys(renderer, options) { + const useKittyKeyboard = options?.kittyKeyboard ?? false; + const useOtherModifiersMode = options?.otherModifiersMode ?? false; + const effectiveOtherModifiersMode = useOtherModifiersMode && !useKittyKeyboard; + const pressKeys = async (keys, delayMs = 0) => { + for (const key of keys) { + const { keyValue: keyCode } = resolveKeyInput(key); + renderer.stdin.emit("data", Buffer2.from(keyCode)); + if (delayMs > 0) { + await new Promise((resolve) => setTimeout(resolve, delayMs)); + } + } + }; + const pressKey = (key, modifiers) => { + if (useKittyKeyboard) { + let { keyValue, keyName } = resolveKeyInput(key); + const valueToKeyNameMap = { + "\b": "backspace", + "\r": "return", + "\n": "return", + "\t": "tab", + "\x1B": "escape", + "\x1B[A": "up", + "\x1B[B": "down", + "\x1B[C": "right", + "\x1B[D": "left", + "\x1B[H": "home", + "\x1B[F": "end", + "\x1B[3~": "delete" + }; + if (keyValue && valueToKeyNameMap[keyValue]) { + keyName = valueToKeyNameMap[keyValue]; + } + if (keyName && keyName.startsWith("arrow_")) { + keyName = keyName.substring(6); + } + if (keyName && kittyKeyCodeMap[keyName]) { + const kittyCode = kittyKeyCodeMap[keyName]; + const sequence = encodeKittySequence(kittyCode, modifiers); + renderer.stdin.emit("data", Buffer2.from(sequence)); + return; + } + if (keyValue && keyValue.length === 1 && !keyValue.startsWith("\x1B")) { + const codepoint = keyValue.codePointAt(0); + if (codepoint) { + const sequence = encodeKittySequence(codepoint, modifiers); + renderer.stdin.emit("data", Buffer2.from(sequence)); + return; + } + } + } + if (effectiveOtherModifiersMode && modifiers) { + let { keyValue, keyName } = resolveKeyInput(key); + const valueToCharCodeMap = { + "\b": 127, + "\r": 13, + "\n": 13, + "\t": 9, + "\x1B": 27, + " ": 32 + }; + let charCode; + if (keyValue && valueToCharCodeMap[keyValue] !== undefined) { + charCode = valueToCharCodeMap[keyValue]; + } else if (keyValue && keyValue.length === 1 && !keyValue.startsWith("\x1B")) { + charCode = keyValue.charCodeAt(0); + } + if (charCode !== undefined) { + const sequence = encodeModifyOtherKeysSequence(charCode, modifiers); + renderer.stdin.emit("data", Buffer2.from(sequence)); + return; + } + } + let keyCode = resolveKeyInput(key).keyValue; + if (modifiers) { + if (keyCode.startsWith("\x1B[") && keyCode.length > 2) { + const modifier = 1 + (modifiers.shift ? 1 : 0) + (modifiers.meta ? 2 : 0) + (modifiers.ctrl ? 4 : 0) + (modifiers.super ? 8 : 0) + (modifiers.hyper ? 16 : 0); + if (modifier > 1) { + const tildeMatch = keyCode.match(/^\x1b\[(\d+)~$/); + if (tildeMatch) { + keyCode = `\x1B[${tildeMatch[1]};${modifier}~`; + } else { + const ending = keyCode.slice(-1); + keyCode = `\x1B[1;${modifier}${ending}`; + } + } + } else if (keyCode.length === 1) { + let char = keyCode; + if (char === "\t" && modifiers.shift) { + keyCode = modifiers.meta ? "\x1B\x1B[Z" : "\x1B[Z"; + renderer.stdin.emit("data", Buffer2.from(keyCode)); + return; + } + if (char === "\b" && (modifiers.ctrl || modifiers.super || modifiers.hyper)) { + const modifier = 1 + (modifiers.shift ? 1 : 0) + (modifiers.meta ? 2 : 0) + (modifiers.ctrl ? 4 : 0) + (modifiers.super ? 8 : 0) + (modifiers.hyper ? 16 : 0); + keyCode = `\x1B[27;${modifier};127~`; + } else if (modifiers.ctrl) { + if (char >= "a" && char <= "z") { + keyCode = String.fromCharCode(char.charCodeAt(0) - 96); + } else if (char >= "A" && char <= "Z") { + keyCode = String.fromCharCode(char.charCodeAt(0) - 64); + } else { + const specialCtrlMap = { + "[": "\x1B", + "\\": "\x1C", + "]": "\x1D", + "^": "\x1E", + _: "\x1F", + "?": "", + "/": "\x1F", + "-": "\x1F", + ".": "\x1E", + ",": "\x1C", + "@": "\x00", + " ": "\x00" + }; + if (char in specialCtrlMap) { + keyCode = specialCtrlMap[char]; + } + } + if (modifiers.meta) { + keyCode = `\x1B${keyCode}`; + } + } else { + if (modifiers.shift && char >= "a" && char <= "z") { + char = char.toUpperCase(); + } + if (modifiers.meta) { + keyCode = `\x1B${char}`; + } else { + keyCode = char; + } + } + } else if (modifiers.meta && !keyCode.startsWith("\x1B")) { + keyCode = `\x1B${keyCode}`; + } + } + renderer.stdin.emit("data", Buffer2.from(keyCode)); + }; + const typeText = async (text, delayMs = 0) => { + const keys = text.split(""); + await pressKeys(keys, delayMs); + }; + const pressReturn = (modifiers) => { + pressKey(KeyCodes.RETURN, modifiers); + }; + const pressEscape = (modifiers) => { + pressKey(KeyCodes.ESCAPE, modifiers); + }; + const pressTab = (modifiers) => { + pressKey(KeyCodes.TAB, modifiers); + }; + const pressBackspace = (modifiers) => { + pressKey(KeyCodes.BACKSPACE, modifiers); + }; + const pressArrow = (direction, modifiers) => { + const keyMap = { + up: KeyCodes.ARROW_UP, + down: KeyCodes.ARROW_DOWN, + left: KeyCodes.ARROW_LEFT, + right: KeyCodes.ARROW_RIGHT + }; + pressKey(keyMap[direction], modifiers); + }; + const pressCtrlC = () => { + pressKey("c", { ctrl: true }); + }; + const pasteBracketedText = (text) => { + return pressKeys([ANSI.bracketedPasteStart, text, ANSI.bracketedPasteEnd]); + }; + return { + pressKeys, + pressKey, + typeText, + pressEnter: pressReturn, + pressEscape, + pressTab, + pressBackspace, + pressArrow, + pressCtrlC, + pasteBracketedText + }; +} + +// src/testing/mock-mouse.ts +var MouseButtons = { + LEFT: 0, + MIDDLE: 1, + RIGHT: 2, + WHEEL_UP: 64, + WHEEL_DOWN: 65, + WHEEL_LEFT: 66, + WHEEL_RIGHT: 67 +}; +function createMockMouse(renderer) { + let currentPosition = { x: 0, y: 0 }; + let buttonsPressed = new Set; + const generateMouseEvent = (type, x, y, button = MouseButtons.LEFT, modifiers = {}) => { + let buttonCode = button; + if (modifiers.shift) + buttonCode |= 4; + if (modifiers.alt) + buttonCode |= 8; + if (modifiers.ctrl) + buttonCode |= 16; + switch (type) { + case "move": + buttonCode = 32 | 3; + if (modifiers.shift) + buttonCode |= 4; + if (modifiers.alt) + buttonCode |= 8; + if (modifiers.ctrl) + buttonCode |= 16; + break; + case "drag": + buttonCode = (buttonsPressed.size > 0 ? Array.from(buttonsPressed)[0] : button) | 32; + if (modifiers.shift) + buttonCode |= 4; + if (modifiers.alt) + buttonCode |= 8; + if (modifiers.ctrl) + buttonCode |= 16; + break; + case "scroll": + break; + } + const ansiX = x + 1; + const ansiY = y + 1; + let pressRelease = "M"; + if (type === "up" || type === "move" || type === "drag") { + pressRelease = "m"; + } + return `\x1B[<${buttonCode};${ansiX};${ansiY}${pressRelease}`; + }; + const emitMouseEvent = async (type, x, y, button = MouseButtons.LEFT, options = {}) => { + const { modifiers = {}, delayMs = 0 } = options; + const eventSequence = generateMouseEvent(type, x, y, button, modifiers); + renderer.stdin.emit("data", Buffer.from(eventSequence)); + currentPosition = { x, y }; + if (type === "down" && button < 64) { + buttonsPressed.add(button); + } else if (type === "up") { + buttonsPressed.delete(button); + } + if (delayMs > 0) { + await new Promise((resolve) => setTimeout(resolve, delayMs)); + } + }; + const moveTo = async (x, y, options = {}) => { + const { button = MouseButtons.LEFT, delayMs = 0, modifiers = {} } = options; + if (buttonsPressed.size > 0) { + await emitMouseEvent("drag", x, y, Array.from(buttonsPressed)[0], { modifiers, delayMs }); + } else { + await emitMouseEvent("move", x, y, button, { modifiers, delayMs }); + } + currentPosition = { x, y }; + }; + const click = async (x, y, button = MouseButtons.LEFT, options = {}) => { + const { delayMs = 10, modifiers = {} } = options; + await emitMouseEvent("down", x, y, button, { modifiers, delayMs }); + await new Promise((resolve) => setTimeout(resolve, delayMs)); + await emitMouseEvent("up", x, y, button, { modifiers, delayMs }); + }; + const doubleClick = async (x, y, button = MouseButtons.LEFT, options = {}) => { + const { delayMs = 10, modifiers = {} } = options; + await click(x, y, button, { modifiers, delayMs }); + await new Promise((resolve) => setTimeout(resolve, delayMs)); + await click(x, y, button, { modifiers, delayMs }); + }; + const pressDown = async (x, y, button = MouseButtons.LEFT, options = {}) => { + const { modifiers = {}, delayMs = 0 } = options; + await emitMouseEvent("down", x, y, button, { modifiers, delayMs }); + }; + const release = async (x, y, button = MouseButtons.LEFT, options = {}) => { + const { modifiers = {}, delayMs = 0 } = options; + await emitMouseEvent("up", x, y, button, { modifiers, delayMs }); + }; + const drag = async (startX, startY, endX, endY, button = MouseButtons.LEFT, options = {}) => { + const { delayMs = 10, modifiers = {} } = options; + await pressDown(startX, startY, button, { modifiers }); + const steps = 5; + const dx = (endX - startX) / steps; + const dy = (endY - startY) / steps; + for (let i = 1;i <= steps; i++) { + const currentX = Math.round(startX + dx * i); + const currentY = Math.round(startY + dy * i); + await emitMouseEvent("drag", currentX, currentY, button, { modifiers, delayMs }); + } + await release(endX, endY, button, { modifiers }); + }; + const scroll = async (x, y, direction, options = {}) => { + const { modifiers = {}, delayMs = 0 } = options; + let button; + switch (direction) { + case "up": + button = MouseButtons.WHEEL_UP; + break; + case "down": + button = MouseButtons.WHEEL_DOWN; + break; + case "left": + button = MouseButtons.WHEEL_LEFT; + break; + case "right": + button = MouseButtons.WHEEL_RIGHT; + break; + } + await emitMouseEvent("scroll", x, y, button, { modifiers, delayMs }); + }; + const getCurrentPosition = () => { + return { ...currentPosition }; + }; + const getPressedButtons = () => { + return Array.from(buttonsPressed); + }; + return { + moveTo, + click, + doubleClick, + pressDown, + release, + drag, + scroll, + getCurrentPosition, + getPressedButtons, + emitMouseEvent + }; +} + +// src/testing/test-streams.ts +import { Readable, Writable } from "stream"; + +class TestWriteStream extends Writable { + isTTY = true; + columns; + rows; + constructor(columns = 80, rows = 24) { + super(); + this.columns = columns; + this.rows = rows; + } + _write(_chunk, _encoding, callback) { + callback(); + } + getColorDepth() { + return 24; + } +} +function createTestStdin() { + return new Readable({ read() {} }); +} +function createTestStdout(columns = 80, rows = 24) { + return new TestWriteStream(columns, rows); +} + +// src/testing/test-renderer.ts +var decoder = new TextDecoder; +var DEFAULT_MAX_PASSES = 20; +var DEFAULT_MAX_VISUAL_IDLE_FRAMES = 20; +var DEFAULT_QUIET_FRAMES = 1; +async function drainImmediateWork() { + await Promise.resolve(); + await new Promise((resolve) => process.nextTick(resolve)); + await Promise.resolve(); +} +function normalizePositiveInteger(value, fallback) { + if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) { + return fallback; + } + return Math.floor(value); +} +function createWaitError(renderer, message, frame) { + const stats = renderer.getStats(); + const scheduler = renderer.getSchedulerState(); + const details = [ + message, + `frameId: ${renderer.frameId}`, + `nativeFrameCount: ${stats.nativeFrameCount}`, + `cellsUpdated: ${stats.cellsUpdated}`, + `isRunning: ${scheduler.isRunning}`, + `isRendering: ${scheduler.isRendering}`, + `hasScheduledRender: ${scheduler.hasScheduledRender}` + ]; + if (frame !== undefined) { + details.push(`lastFrame: +${frame}`); + } + return new Error(details.join(` +`)); +} + +class TestExternalOutputRecorder { + commits = []; + constructor(renderer) { + renderer.on("external_output" /* EXTERNAL_OUTPUT */, this.record); + renderer.once("destroy" /* DESTROY */, () => { + renderer.off("external_output" /* EXTERNAL_OUTPUT */, this.record); + }); + } + record = (event) => { + const raw = decoder.decode(event.snapshot.getRealCharBytes(false)); + const rows = Array.from({ length: event.snapshot.height }, (_, index) => raw.slice(index * event.snapshot.width, (index + 1) * event.snapshot.width).trimEnd()); + this.commits.push({ + text: rows.join(` +`), + rows, + width: event.snapshot.width, + height: event.snapshot.height, + rowColumns: event.rowColumns, + startOnNewLine: event.startOnNewLine, + trailingNewline: event.trailingNewline + }); + }; + take() { + const commits = this.commits; + this.commits = []; + return commits; + } + takeText() { + return this.take().flatMap((commit) => commit.rows).join(` +`); + } + clear() { + this.commits = []; + } +} +function waitForNextFrameOrIdle(renderer) { + const scheduler = renderer.getSchedulerState(); + if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) { + return Promise.resolve(null); + } + return new Promise((resolve) => { + let settled = false; + const cleanup = () => { + renderer.off("frame" /* FRAME */, onFrame); + renderer.off("destroy" /* DESTROY */, onDestroy); + }; + const finish = (event) => { + if (settled) + return; + settled = true; + cleanup(); + resolve(event); + }; + const onFrame = (event) => { + finish(event); + }; + const onDestroy = () => { + finish(null); + }; + renderer.on("frame" /* FRAME */, onFrame); + renderer.once("destroy" /* DESTROY */, onDestroy); + if (!scheduler.isRunning) { + renderer.idle().then(() => finish(null)); + } + }); +} +async function createTestRenderer(options) { + const useKittyKeyboard = options.kittyKeyboard ? { events: true } : options.useKittyKeyboard; + const renderer = await setupTestRenderer({ + ...options, + useKittyKeyboard, + screenMode: options.screenMode ?? "main-screen", + footerHeight: options.footerHeight ?? 12, + consoleMode: options.consoleMode ?? "disabled", + externalOutputMode: options.externalOutputMode ?? "passthrough" + }); + const externalOutput = new TestExternalOutputRecorder(renderer); + const mockInput = createMockKeys(renderer, { + kittyKeyboard: options.kittyKeyboard, + otherModifiersMode: options.otherModifiersMode + }); + const mockMouse = createMockMouse(renderer); + const renderOnce = async () => { + const feed = renderer._feed; + if (feed?.isBackpressured()) { + await feed.idle(); + } + await renderer.loop(); + }; + const captureCharFrame = () => { + const currentBuffer = renderer.currentRenderBuffer; + const frameBytes = currentBuffer.getRealCharBytes(true); + return decoder.decode(frameBytes); + }; + const waitForVisualIdle = async (waitOptions = {}) => { + const maxFrames = normalizePositiveInteger(waitOptions.maxFrames, DEFAULT_MAX_VISUAL_IDLE_FRAMES); + const quietFrames = normalizePositiveInteger(waitOptions.quietFrames, DEFAULT_QUIET_FRAMES); + let consecutiveQuietFrames = 0; + for (let frame = 0;frame < maxFrames; frame++) { + await drainImmediateWork(); + const scheduler2 = renderer.getSchedulerState(); + if (!scheduler2.isRunning && !scheduler2.isRendering && !scheduler2.hasScheduledRender) { + return; + } + const event = await waitForNextFrameOrIdle(renderer); + if (!event) { + return; + } + if (renderer.getNativeStats().cellsUpdated === 0) { + consecutiveQuietFrames++; + if (consecutiveQuietFrames >= quietFrames) { + return; + } + } else { + consecutiveQuietFrames = 0; + } + } + await drainImmediateWork(); + const scheduler = renderer.getSchedulerState(); + if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) { + return; + } + throw createWaitError(renderer, `Timed out waiting for visual idle after ${maxFrames} frames`); + }; + const flush = async (flushOptions = {}) => { + await waitForVisualIdle({ maxFrames: normalizePositiveInteger(flushOptions.maxPasses, DEFAULT_MAX_PASSES) }); + }; + const waitFor = async (predicate, waitOptions = {}) => { + const maxPasses = normalizePositiveInteger(waitOptions.maxPasses, DEFAULT_MAX_PASSES); + for (let pass = 0;pass <= maxPasses; pass++) { + await drainImmediateWork(); + if (await predicate()) { + return; + } + if (pass === maxPasses) { + break; + } + const scheduler = renderer.getSchedulerState(); + if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) { + break; + } + await waitForNextFrameOrIdle(renderer); + } + throw createWaitError(renderer, `Timed out waiting for predicate after ${maxPasses} passes`); + }; + const waitForFrame = async (predicate, waitOptions = {}) => { + const maxPasses = normalizePositiveInteger(waitOptions.maxPasses, DEFAULT_MAX_PASSES); + let frame = captureCharFrame(); + for (let pass = 0;pass <= maxPasses; pass++) { + await drainImmediateWork(); + frame = captureCharFrame(); + if (await predicate(frame)) { + return frame; + } + if (pass === maxPasses) { + break; + } + const scheduler = renderer.getSchedulerState(); + if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) { + break; + } + await waitForNextFrameOrIdle(renderer); + } + frame = captureCharFrame(); + throw createWaitError(renderer, `Timed out waiting for frame predicate after ${maxPasses} passes`, frame); + }; + return { + renderer, + mockInput, + mockMouse, + renderOnce, + flush, + waitFor, + waitForFrame, + waitForVisualIdle, + externalOutput, + getNativeStats: () => renderer.getNativeStats(), + captureCharFrame, + captureSpans: () => { + const currentBuffer = renderer.currentRenderBuffer; + const lines = currentBuffer.getSpanLines(); + const cursorState = renderer.getCursorState(); + return { + cols: currentBuffer.width, + rows: currentBuffer.height, + cursor: [cursorState.x, cursorState.y], + lines + }; + }, + resize: (width, height) => { + renderer.processResize(width, height); + } + }; +} +async function setupTestRenderer(config) { + const stdin = config.stdin || createTestStdin(); + const width = config.width || config.stdout?.columns || process.stdout.columns || 80; + const height = config.height || config.stdout?.rows || process.stdout.rows || 24; + const stdout = config.stdout || createTestStdout(width, height); + return new CliRenderer(stdin, stdout, width, height, { + ...config, + bufferedOutput: config.bufferedOutput ?? "memory" + }); +} +// src/testing/mock-tree-sitter-client.ts +class MockTreeSitterClient extends TreeSitterClient { + _highlightPromises = []; + _mockResult = { highlights: [] }; + _autoResolveTimeout; + _clock; + constructor(options) { + super({ dataPath: "/tmp/mock" }, { autoStartWorker: false }); + this._autoResolveTimeout = options?.autoResolveTimeout; + this._clock = options?.clock ?? new SystemClock; + } + async destroy() { + this.resolveAllHighlightOnce(); + await super.destroy(); + } + async highlightOnce(content, filetype) { + const { promise, resolve } = Promise.withResolvers(); + let timeout; + if (this._autoResolveTimeout !== undefined) { + timeout = this._clock.setTimeout(() => { + const index = this._highlightPromises.findIndex((p) => p.promise === promise); + if (index !== -1) { + resolve(this._mockResult); + this._highlightPromises.splice(index, 1); + } + }, this._autoResolveTimeout); + } + this._highlightPromises.push({ promise, resolve, timeout }); + return promise; + } + setMockResult(result) { + this._mockResult = result; + } + resolveHighlightOnce(index = 0) { + if (index >= 0 && index < this._highlightPromises.length) { + const item = this._highlightPromises[index]; + if (item.timeout) { + this._clock.clearTimeout(item.timeout); + } + item.resolve(this._mockResult); + this._highlightPromises.splice(index, 1); + } + } + resolveAllHighlightOnce() { + for (const { resolve, timeout } of this._highlightPromises) { + if (timeout) { + this._clock.clearTimeout(timeout); + } + resolve(this._mockResult); + } + this._highlightPromises = []; + } + isHighlighting() { + return this._highlightPromises.length > 0; + } +} +// src/testing/terminal-capabilities.ts +function createTerminalCapabilities(overrides = {}) { + return { + kitty_keyboard: false, + kitty_graphics: false, + rgb: false, + ansi256: false, + unicode: "unicode", + sgr_pixels: false, + color_scheme_updates: false, + explicit_width: false, + scaled_text: false, + sixel: false, + focus_tracking: false, + sync: false, + bracketed_paste: false, + hyperlinks: false, + osc52: false, + notifications: false, + explicit_cursor_positioning: false, + remote: false, + multiplexer: "none", + ...overrides, + terminal: { + name: "", + version: "", + from_xtversion: false, + ...overrides.terminal + } + }; +} +function setRendererCapabilities(renderer, overrides = {}) { + const capabilities = createTerminalCapabilities(overrides); + renderer._capabilities = capabilities; + return capabilities; +} +// src/testing/spy.ts +function createSpy() { + const calls = []; + const spy = (...args) => { + calls.push(args); + }; + spy.calls = calls; + spy.callCount = () => calls.length; + spy.calledWith = (...expected) => { + return calls.some((call) => JSON.stringify(call) === JSON.stringify(expected)); + }; + spy.reset = () => calls.length = 0; + return spy; +} +// src/testing/manual-clock.ts +function compareTimers(left, right) { + if (left.fireAt !== right.fireAt) { + return left.fireAt - right.fireAt; + } + return left.order - right.order; +} + +class ManualClock { + time = 0; + nextId = 1; + nextOrder = 0; + timers = new Map; + now() { + return this.time; + } + setTime(time) { + const targetTime = Math.floor(time); + if (targetTime >= this.time) { + this.advance(targetTime - this.time); + return; + } + this.time = targetTime; + } + setTimeout(fn, delayMs) { + return this.schedule(fn, delayMs, false); + } + clearTimeout(handle) { + this.timers.delete(Number(handle)); + } + setInterval(fn, delayMs) { + return this.schedule(fn, delayMs, true); + } + clearInterval(handle) { + this.clearTimeout(handle); + } + advance(delayMs) { + const targetTime = this.time + Math.max(0, Math.floor(delayMs)); + while (true) { + const nextTimer = this.peekNextTimer(); + if (!nextTimer || nextTimer.fireAt > targetTime) { + break; + } + this.timers.delete(nextTimer.id); + this.time = nextTimer.fireAt; + nextTimer.fn(); + if (nextTimer.repeat && !this.timers.has(nextTimer.id)) { + this.timers.set(nextTimer.id, { + ...nextTimer, + fireAt: this.time + nextTimer.delayMs, + order: this.nextOrder++ + }); + } + } + this.time = targetTime; + } + runAll() { + while (true) { + const nextTimer = this.peekNextTimer(); + if (!nextTimer) { + return; + } + this.advance(nextTimer.fireAt - this.time); + } + } + schedule(fn, delayMs, repeat) { + const id = this.nextId++; + const normalizedDelay = Math.max(0, Math.floor(delayMs)); + this.timers.set(id, { + id, + fireAt: this.time + normalizedDelay, + order: this.nextOrder++, + delayMs: normalizedDelay, + repeat, + fn + }); + return id; + } + peekNextTimer() { + let nextTimer = null; + for (const timer of this.timers.values()) { + if (!nextTimer || compareTimers(timer, nextTimer) < 0) { + nextTimer = timer; + } + } + return nextTimer; + } +} +// src/testing/test-recorder.ts +class TestRecorder { + renderer; + frames = []; + recording = false; + frameNumber = 0; + startTime = 0; + decoder = new TextDecoder; + recordBuffers; + now; + onFrame = () => { + if (!this.recording) + return; + this.captureFrame(); + }; + constructor(renderer, options) { + this.renderer = renderer; + this.recordBuffers = options?.recordBuffers || {}; + this.now = options?.now ?? (() => performance.now()); + } + rec() { + if (this.recording) { + return; + } + this.recording = true; + this.frames = []; + this.frameNumber = 0; + this.startTime = this.now(); + this.renderer.on("frame" /* FRAME */, this.onFrame); + } + stop() { + if (!this.recording) { + return; + } + this.recording = false; + this.renderer.off("frame" /* FRAME */, this.onFrame); + } + get recordedFrames() { + return [...this.frames]; + } + clear() { + this.frames = []; + this.frameNumber = 0; + } + get isRecording() { + return this.recording; + } + captureFrame() { + const currentBuffer = this.renderer.currentRenderBuffer; + const frameBytes = currentBuffer.getRealCharBytes(true); + const frame = this.decoder.decode(frameBytes); + const recordedFrame = { + frame, + timestamp: this.now() - this.startTime, + frameNumber: this.frameNumber++ + }; + if (this.recordBuffers.fg || this.recordBuffers.bg || this.recordBuffers.attributes) { + const buffers = currentBuffer.buffers; + recordedFrame.buffers = {}; + if (this.recordBuffers.fg) { + recordedFrame.buffers.fg = new Uint16Array(buffers.fg); + } + if (this.recordBuffers.bg) { + recordedFrame.buffers.bg = new Uint16Array(buffers.bg); + } + if (this.recordBuffers.attributes) { + recordedFrame.buffers.attributes = new Uint8Array(buffers.attributes); + } + } + this.frames.push(recordedFrame); + } +} +export { + setRendererCapabilities, + pasteBytes, + createTestRenderer, + createTerminalCapabilities, + createSpy, + createMockMouse, + createMockKeys, + TestRecorder, + MouseButtons, + MockTreeSitterClient, + ManualClock, + KeyCodes +}; + +//# debugId=884B8CD1F6ACF7CC64756E2164756E21 +//# sourceMappingURL=testing.js.map diff --git a/.patches/@opentui/core/testing.js.map b/.patches/@opentui/core/testing.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing.js.map @@ -0,0 +1,18 @@ +{ + "version": 3, + "sources": ["../src/testing/mock-keys.ts", "../src/testing/mock-mouse.ts", "../src/testing/test-streams.ts", "../src/testing/test-renderer.ts", "../src/testing/mock-tree-sitter-client.ts", "../src/testing/terminal-capabilities.ts", "../src/testing/spy.ts", "../src/testing/manual-clock.ts", "../src/testing/test-recorder.ts"], + "sourcesContent": [ + "import { Buffer } from \"node:buffer\"\nimport type { CliRenderer } from \"../renderer.js\"\nimport { ANSI } from \"../ansi.js\"\n\nexport function pasteBytes(text: string): Uint8Array {\n return Uint8Array.from(Buffer.from(text))\n}\n\nexport const KeyCodes = {\n // Control keys\n RETURN: \"\\r\",\n LINEFEED: \"\\n\",\n TAB: \"\\t\",\n BACKSPACE: \"\\b\",\n // NOTE: This may depend on the platform and terminals\n DELETE: \"\\x1b[3~\",\n HOME: \"\\x1b[H\",\n END: \"\\x1b[F\",\n ESCAPE: \"\\x1b\",\n\n // Arrow keys\n ARROW_UP: \"\\x1b[A\",\n ARROW_DOWN: \"\\x1b[B\",\n ARROW_RIGHT: \"\\x1b[C\",\n ARROW_LEFT: \"\\x1b[D\",\n\n // Function keys\n F1: \"\\x1bOP\",\n F2: \"\\x1bOQ\",\n F3: \"\\x1bOR\",\n F4: \"\\x1bOS\",\n F5: \"\\x1b[15~\",\n F6: \"\\x1b[17~\",\n F7: \"\\x1b[18~\",\n F8: \"\\x1b[19~\",\n F9: \"\\x1b[20~\",\n F10: \"\\x1b[21~\",\n F11: \"\\x1b[23~\",\n F12: \"\\x1b[24~\",\n} as const\n\nexport type KeyInput = string | keyof typeof KeyCodes\n\nexport interface MockKeysOptions {\n kittyKeyboard?: boolean\n otherModifiersMode?: boolean\n}\n\n// Kitty keyboard protocol key mappings\nconst kittyKeyCodeMap: Record = {\n escape: 27,\n tab: 9,\n return: 13,\n backspace: 127,\n insert: 57348,\n delete: 57349,\n left: 57350,\n right: 57351,\n up: 57352,\n down: 57353,\n pageup: 57354,\n pagedown: 57355,\n home: 57356,\n end: 57357,\n f1: 57364,\n f2: 57365,\n f3: 57366,\n f4: 57367,\n f5: 57368,\n f6: 57369,\n f7: 57370,\n f8: 57371,\n f9: 57372,\n f10: 57373,\n f11: 57374,\n f12: 57375,\n}\n\nfunction encodeKittySequence(\n codepoint: number,\n modifiers?: { shift?: boolean; ctrl?: boolean; meta?: boolean; super?: boolean; hyper?: boolean },\n): string {\n // Kitty keyboard protocol: CSI unicode-key-code ; modifiers u\n // Modifier encoding: shift=1, alt=2, ctrl=4, super=8, hyper=16, meta=32, caps=64, num=128\n let modMask = 0\n if (modifiers?.shift) modMask |= 1\n if (modifiers?.meta) modMask |= 2 // alt/meta\n if (modifiers?.ctrl) modMask |= 4\n if (modifiers?.super) modMask |= 8\n if (modifiers?.hyper) modMask |= 16\n\n if (modMask === 0) {\n // No modifiers\n return `\\x1b[${codepoint}u`\n } else {\n // With modifiers (kitty uses 1-based, so add 1)\n return `\\x1b[${codepoint};${modMask + 1}u`\n }\n}\n\nfunction encodeModifyOtherKeysSequence(\n charCode: number,\n modifiers?: { shift?: boolean; ctrl?: boolean; meta?: boolean; super?: boolean; hyper?: boolean },\n): string {\n // modifyOtherKeys protocol: CSI 27 ; modifier ; code ~\n // This is the format used by xterm, iTerm2, Ghostty with modifyOtherKeys enabled\n // Modifier encoding: shift=1, alt/option=2, ctrl=4, super=8, hyper=16 (1-based, so add 1)\n let modMask = 0\n if (modifiers?.shift) modMask |= 1\n if (modifiers?.meta) modMask |= 2 // alt/option/meta\n if (modifiers?.ctrl) modMask |= 4\n if (modifiers?.super) modMask |= 8\n if (modifiers?.hyper) modMask |= 16\n\n // modifyOtherKeys is only used when modifiers are present\n // Without modifiers, use the standard key sequence\n if (modMask === 0) {\n return String.fromCharCode(charCode)\n }\n\n // With modifiers, use CSI 27 ; modifier ; code ~\n return `\\x1b[27;${modMask + 1};${charCode}~`\n}\n\ninterface ResolvedKey {\n keyValue: string\n keyName: string | undefined\n}\n\nfunction resolveKeyInput(key: KeyInput): ResolvedKey {\n let keyValue: string\n let keyName: string | undefined\n\n if (typeof key === \"string\") {\n if (key in KeyCodes) {\n // It's a KeyCode name like \"BACKSPACE\", \"ARROW_UP\", etc.\n keyValue = KeyCodes[key as keyof typeof KeyCodes]\n keyName = key.toLowerCase()\n } else {\n // It's a regular character\n keyValue = key\n keyName = undefined\n }\n } else {\n // It's already a keycode enum value\n keyValue = KeyCodes[key]\n if (!keyValue) {\n throw new Error(`Unknown key: ${key}`)\n }\n keyName = String(key).toLowerCase()\n }\n\n return { keyValue, keyName }\n}\n\nexport function createMockKeys(renderer: CliRenderer, options?: MockKeysOptions) {\n const useKittyKeyboard = options?.kittyKeyboard ?? false\n const useOtherModifiersMode = options?.otherModifiersMode ?? false\n\n // Kitty keyboard takes precedence over otherModifiersMode\n const effectiveOtherModifiersMode = useOtherModifiersMode && !useKittyKeyboard\n\n const pressKeys = async (keys: KeyInput[], delayMs: number = 0): Promise => {\n for (const key of keys) {\n const { keyValue: keyCode } = resolveKeyInput(key)\n\n renderer.stdin.emit(\"data\", Buffer.from(keyCode))\n\n if (delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, delayMs))\n }\n }\n }\n\n const pressKey = (\n key: KeyInput,\n modifiers?: { shift?: boolean; ctrl?: boolean; meta?: boolean; super?: boolean; hyper?: boolean },\n ): void => {\n // Handle Kitty keyboard protocol mode\n if (useKittyKeyboard) {\n // Resolve the key to its string representation or keycode value\n let { keyValue, keyName } = resolveKeyInput(key)\n\n // Map control characters and escape sequences to their kitty key names\n const valueToKeyNameMap: Record = {\n \"\\b\": \"backspace\",\n \"\\r\": \"return\",\n \"\\n\": \"return\",\n \"\\t\": \"tab\",\n \"\\x1b\": \"escape\",\n \"\\x1b[A\": \"up\",\n \"\\x1b[B\": \"down\",\n \"\\x1b[C\": \"right\",\n \"\\x1b[D\": \"left\",\n \"\\x1b[H\": \"home\",\n \"\\x1b[F\": \"end\",\n \"\\x1b[3~\": \"delete\",\n }\n\n // Check value mapping\n if (keyValue && valueToKeyNameMap[keyValue]) {\n keyName = valueToKeyNameMap[keyValue]\n }\n\n // Also check for ARROW_ prefix\n if (keyName && keyName.startsWith(\"arrow_\")) {\n keyName = keyName.substring(6) // Remove \"arrow_\" prefix\n }\n\n // Check if we have a direct kitty code mapping\n if (keyName && kittyKeyCodeMap[keyName]) {\n const kittyCode = kittyKeyCodeMap[keyName]\n const sequence = encodeKittySequence(kittyCode, modifiers)\n renderer.stdin.emit(\"data\", Buffer.from(sequence))\n return\n }\n\n // For regular characters, get the codepoint\n if (keyValue && keyValue.length === 1 && !keyValue.startsWith(\"\\x1b\")) {\n const codepoint = keyValue.codePointAt(0)\n if (codepoint) {\n const sequence = encodeKittySequence(codepoint, modifiers)\n renderer.stdin.emit(\"data\", Buffer.from(sequence))\n return\n }\n }\n\n // Fall through to regular mode for unknown keys\n }\n\n // Handle modifyOtherKeys mode (CSI u protocol variant)\n // Used by xterm, iTerm2, Ghostty with modifyOtherKeys enabled\n if (effectiveOtherModifiersMode && modifiers) {\n // Resolve the key to its string representation or keycode value\n let { keyValue, keyName } = resolveKeyInput(key)\n\n // Map control characters and escape sequences to their char codes\n const valueToCharCodeMap: Record = {\n \"\\b\": 127, // backspace (or 8, but 127 is more common)\n \"\\r\": 13, // return\n \"\\n\": 13, // linefeed -> return\n \"\\t\": 9, // tab\n \"\\x1b\": 27, // escape\n \" \": 32, // space\n }\n\n // Check if we have a control character that needs modifyOtherKeys encoding\n let charCode: number | undefined\n\n if (keyValue && valueToCharCodeMap[keyValue] !== undefined) {\n charCode = valueToCharCodeMap[keyValue]\n } else if (keyValue && keyValue.length === 1 && !keyValue.startsWith(\"\\x1b\")) {\n // For regular single characters\n charCode = keyValue.charCodeAt(0)\n }\n\n // If we have a char code and modifiers, use modifyOtherKeys format\n if (charCode !== undefined) {\n const sequence = encodeModifyOtherKeysSequence(charCode, modifiers)\n renderer.stdin.emit(\"data\", Buffer.from(sequence))\n return\n }\n\n // For other keys (like arrow keys with modifiers), fall through to regular mode\n }\n\n // Regular (non-Kitty, non-modifyOtherKeys) mode\n let keyCode = resolveKeyInput(key).keyValue\n\n // Apply modifiers if present\n if (modifiers) {\n // For arrow keys and special keys, modify the escape sequence\n if (keyCode.startsWith(\"\\x1b[\") && keyCode.length > 2) {\n // Arrow keys: \\x1b[A, \\x1b[B, \\x1b[C, \\x1b[D\n // With shift modifier: \\x1b[1;2A, \\x1b[1;2B, \\x1b[1;2C, \\x1b[1;2D\n // Special keys like delete: \\x1b[3~ becomes \\x1b[3;2~ with meta\n const modifier =\n 1 +\n (modifiers.shift ? 1 : 0) +\n (modifiers.meta ? 2 : 0) +\n (modifiers.ctrl ? 4 : 0) +\n (modifiers.super ? 8 : 0) +\n (modifiers.hyper ? 16 : 0)\n if (modifier > 1) {\n // Check if it's a sequence like \\x1b[3~ (delete, insert, pageup, etc.)\n const tildeMatch = keyCode.match(/^\\x1b\\[(\\d+)~$/)\n if (tildeMatch) {\n // Format: \\x1b[number;modifier~\n keyCode = `\\x1b[${tildeMatch[1]};${modifier}~`\n } else {\n // Arrow keys and other single-letter endings\n // Insert modifier into sequence\n const ending = keyCode.slice(-1)\n keyCode = `\\x1b[1;${modifier}${ending}`\n }\n }\n } else if (keyCode.length === 1) {\n // For regular characters and single-char control codes with modifiers\n let char = keyCode\n\n // Shift+Tab produces the back-tab escape sequence \\x1b[Z in standard ANSI terminals\n if (char === \"\\t\" && modifiers.shift) {\n // Build the base as \\x1b[Z, then apply meta prefix if also pressed\n keyCode = modifiers.meta ? \"\\x1b\\x1b[Z\" : \"\\x1b[Z\"\n renderer.stdin.emit(\"data\", Buffer.from(keyCode))\n return\n }\n\n // Special handling for backspace with modifiers - use modifyOtherKeys format\n // Terminals send Ctrl+Backspace as CSI 27;5;127~ (or CSI 27;5;8~)\n // Only use modifyOtherKeys for ctrl, super, or hyper (not shift or meta alone)\n if (char === \"\\b\" && (modifiers.ctrl || modifiers.super || modifiers.hyper)) {\n const modifier =\n 1 +\n (modifiers.shift ? 1 : 0) +\n (modifiers.meta ? 2 : 0) +\n (modifiers.ctrl ? 4 : 0) +\n (modifiers.super ? 8 : 0) +\n (modifiers.hyper ? 16 : 0)\n // Use charcode 127 for backspace (DEL)\n keyCode = `\\x1b[27;${modifier};127~`\n } else if (modifiers.ctrl) {\n // Handle ctrl modifier for characters\n // Ctrl+letter produces control codes (0x01-0x1a for a-z)\n if (char >= \"a\" && char <= \"z\") {\n keyCode = String.fromCharCode(char.charCodeAt(0) - 96)\n } else if (char >= \"A\" && char <= \"Z\") {\n keyCode = String.fromCharCode(char.charCodeAt(0) - 64)\n } else {\n // Handle special characters with ctrl modifier\n // These produce ASCII control codes\n const specialCtrlMap: Record = {\n \"[\": \"\\x1b\", // Ctrl+[ = ESC (ASCII 27)\n \"\\\\\": \"\\x1c\", // Ctrl+\\ = FS (ASCII 28)\n \"]\": \"\\x1d\", // Ctrl+] = GS (ASCII 29)\n \"^\": \"\\x1e\", // Ctrl+^ = RS (ASCII 30)\n _: \"\\x1f\", // Ctrl+_ = US (ASCII 31)\n \"?\": \"\\x7f\", // Ctrl+? = DEL (ASCII 127)\n // Common aliases\n \"/\": \"\\x1f\", // Ctrl+/ = US (ASCII 31, same as Ctrl+_)\n \"-\": \"\\x1f\", // Ctrl+- = US (ASCII 31, same as Ctrl+_)\n \".\": \"\\x1e\", // Ctrl+. = RS (ASCII 30, same as Ctrl+^)\n \",\": \"\\x1c\", // Ctrl+, = FS (ASCII 28, same as Ctrl+\\)\n \"@\": \"\\x00\", // Ctrl+@ = NUL (ASCII 0)\n \" \": \"\\x00\", // Ctrl+Space = NUL (ASCII 0)\n }\n\n if (char in specialCtrlMap) {\n keyCode = specialCtrlMap[char]\n }\n // If no mapping found, keep the original character\n }\n // If meta is also pressed, prefix with escape\n if (modifiers.meta) {\n keyCode = `\\x1b${keyCode}`\n }\n } else {\n // Handle shift+meta or just meta\n if (modifiers.shift && char >= \"a\" && char <= \"z\") {\n char = char.toUpperCase()\n }\n if (modifiers.meta) {\n // For meta+character (including control codes), prefix with escape\n keyCode = `\\x1b${char}`\n } else {\n keyCode = char\n }\n }\n } else if (modifiers.meta && !keyCode.startsWith(\"\\x1b\")) {\n // For multi-char sequences that aren't escape sequences (like simple control codes)\n // just prefix with escape for meta\n keyCode = `\\x1b${keyCode}`\n }\n }\n\n renderer.stdin.emit(\"data\", Buffer.from(keyCode))\n }\n\n const typeText = async (text: string, delayMs: number = 0): Promise => {\n const keys = text.split(\"\")\n await pressKeys(keys, delayMs)\n }\n\n const pressReturn = (modifiers?: {\n shift?: boolean\n ctrl?: boolean\n meta?: boolean\n super?: boolean\n hyper?: boolean\n }): void => {\n pressKey(KeyCodes.RETURN, modifiers)\n }\n\n const pressEscape = (modifiers?: {\n shift?: boolean\n ctrl?: boolean\n meta?: boolean\n super?: boolean\n hyper?: boolean\n }): void => {\n pressKey(KeyCodes.ESCAPE, modifiers)\n }\n\n const pressTab = (modifiers?: {\n shift?: boolean\n ctrl?: boolean\n meta?: boolean\n super?: boolean\n hyper?: boolean\n }): void => {\n pressKey(KeyCodes.TAB, modifiers)\n }\n\n const pressBackspace = (modifiers?: {\n shift?: boolean\n ctrl?: boolean\n meta?: boolean\n super?: boolean\n hyper?: boolean\n }): void => {\n pressKey(KeyCodes.BACKSPACE, modifiers)\n }\n\n const pressArrow = (\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n modifiers?: { shift?: boolean; ctrl?: boolean; meta?: boolean; super?: boolean; hyper?: boolean },\n ): void => {\n const keyMap = {\n up: KeyCodes.ARROW_UP,\n down: KeyCodes.ARROW_DOWN,\n left: KeyCodes.ARROW_LEFT,\n right: KeyCodes.ARROW_RIGHT,\n }\n pressKey(keyMap[direction], modifiers)\n }\n\n const pressCtrlC = (): void => {\n pressKey(\"c\", { ctrl: true })\n }\n\n const pasteBracketedText = (text: string): Promise => {\n return pressKeys([ANSI.bracketedPasteStart, text, ANSI.bracketedPasteEnd])\n }\n\n return {\n pressKeys,\n pressKey,\n typeText,\n pressEnter: pressReturn,\n pressEscape,\n pressTab,\n pressBackspace,\n pressArrow,\n pressCtrlC,\n pasteBracketedText,\n }\n}\n", + "import type { CliRenderer } from \"../renderer.js\"\n\nexport const MouseButtons = {\n LEFT: 0,\n MIDDLE: 1,\n RIGHT: 2,\n\n WHEEL_UP: 64, // 64 = scroll flag + 0\n WHEEL_DOWN: 65, // 64 + 1\n WHEEL_LEFT: 66, // 64 + 2\n WHEEL_RIGHT: 67, // 64 + 3\n} as const\n\nexport type MouseButton = (typeof MouseButtons)[keyof typeof MouseButtons]\n\nexport interface MousePosition {\n x: number\n y: number\n}\n\nexport interface MouseModifiers {\n shift?: boolean\n alt?: boolean\n ctrl?: boolean\n}\n\nexport type MouseEventType = \"down\" | \"up\" | \"move\" | \"drag\" | \"scroll\"\n\nexport interface MouseEventOptions {\n button?: MouseButton\n modifiers?: MouseModifiers\n delayMs?: number\n}\n\nexport function createMockMouse(renderer: CliRenderer) {\n let currentPosition: MousePosition = { x: 0, y: 0 }\n let buttonsPressed = new Set()\n\n // Generate SGR mouse event sequence\n const generateMouseEvent = (\n type: MouseEventType,\n x: number,\n y: number,\n button: MouseButton = MouseButtons.LEFT,\n modifiers: MouseModifiers = {},\n ): string => {\n // SGR format: \\x1b[ 0 ? Array.from(buttonsPressed)[0] : button) | 32\n if (modifiers.shift) buttonCode |= 4\n if (modifiers.alt) buttonCode |= 8\n if (modifiers.ctrl) buttonCode |= 16\n break\n case \"scroll\":\n // Scroll events already have the scroll flag set in the button code\n break\n }\n\n // Convert to 1-based coordinates for ANSI\n const ansiX = x + 1\n const ansiY = y + 1\n\n let pressRelease = \"M\" // Default to press\n if (type === \"up\" || type === \"move\" || type === \"drag\") {\n pressRelease = \"m\"\n }\n\n return `\\x1b[<${buttonCode};${ansiX};${ansiY}${pressRelease}`\n }\n\n const emitMouseEvent = async (\n type: MouseEventType,\n x: number,\n y: number,\n button: MouseButton = MouseButtons.LEFT,\n options: Omit = {},\n ): Promise => {\n const { modifiers = {}, delayMs = 0 } = options\n\n const eventSequence = generateMouseEvent(type, x, y, button, modifiers)\n renderer.stdin.emit(\"data\", Buffer.from(eventSequence))\n\n currentPosition = { x, y }\n\n if (type === \"down\" && button < 64) {\n buttonsPressed.add(button)\n } else if (type === \"up\") {\n buttonsPressed.delete(button)\n }\n\n if (delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, delayMs))\n }\n }\n\n const moveTo = async (x: number, y: number, options: MouseEventOptions = {}): Promise => {\n const { button = MouseButtons.LEFT, delayMs = 0, modifiers = {} } = options\n\n if (buttonsPressed.size > 0) {\n await emitMouseEvent(\"drag\", x, y, Array.from(buttonsPressed)[0], { modifiers, delayMs })\n } else {\n await emitMouseEvent(\"move\", x, y, button, { modifiers, delayMs })\n }\n\n currentPosition = { x, y }\n }\n\n const click = async (\n x: number,\n y: number,\n button: MouseButton = MouseButtons.LEFT,\n options: MouseEventOptions = {},\n ): Promise => {\n const { delayMs = 10, modifiers = {} } = options\n\n await emitMouseEvent(\"down\", x, y, button, { modifiers, delayMs })\n await new Promise((resolve) => setTimeout(resolve, delayMs))\n await emitMouseEvent(\"up\", x, y, button, { modifiers, delayMs })\n }\n\n const doubleClick = async (\n x: number,\n y: number,\n button: MouseButton = MouseButtons.LEFT,\n options: MouseEventOptions = {},\n ): Promise => {\n const { delayMs = 10, modifiers = {} } = options\n\n await click(x, y, button, { modifiers, delayMs })\n await new Promise((resolve) => setTimeout(resolve, delayMs))\n await click(x, y, button, { modifiers, delayMs })\n }\n\n const pressDown = async (\n x: number,\n y: number,\n button: MouseButton = MouseButtons.LEFT,\n options: MouseEventOptions = {},\n ): Promise => {\n const { modifiers = {}, delayMs = 0 } = options\n await emitMouseEvent(\"down\", x, y, button, { modifiers, delayMs })\n }\n\n const release = async (\n x: number,\n y: number,\n button: MouseButton = MouseButtons.LEFT,\n options: MouseEventOptions = {},\n ): Promise => {\n const { modifiers = {}, delayMs = 0 } = options\n await emitMouseEvent(\"up\", x, y, button, { modifiers, delayMs })\n }\n\n const drag = async (\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n button: MouseButton = MouseButtons.LEFT,\n options: MouseEventOptions = {},\n ): Promise => {\n const { delayMs = 10, modifiers = {} } = options\n\n await pressDown(startX, startY, button, { modifiers })\n\n const steps = 5\n const dx = (endX - startX) / steps\n const dy = (endY - startY) / steps\n\n for (let i = 1; i <= steps; i++) {\n const currentX = Math.round(startX + dx * i)\n const currentY = Math.round(startY + dy * i)\n await emitMouseEvent(\"drag\", currentX, currentY, button, { modifiers, delayMs })\n }\n\n await release(endX, endY, button, { modifiers })\n }\n\n const scroll = async (\n x: number,\n y: number,\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n options: MouseEventOptions = {},\n ): Promise => {\n const { modifiers = {}, delayMs = 0 } = options\n\n let button: MouseButton\n switch (direction) {\n case \"up\":\n button = MouseButtons.WHEEL_UP\n break\n case \"down\":\n button = MouseButtons.WHEEL_DOWN\n break\n case \"left\":\n button = MouseButtons.WHEEL_LEFT\n break\n case \"right\":\n button = MouseButtons.WHEEL_RIGHT\n break\n }\n\n await emitMouseEvent(\"scroll\", x, y, button, { modifiers, delayMs })\n }\n\n const getCurrentPosition = (): MousePosition => {\n return { ...currentPosition }\n }\n\n const getPressedButtons = (): MouseButton[] => {\n return Array.from(buttonsPressed)\n }\n\n return {\n // Core interaction methods\n moveTo,\n click,\n doubleClick,\n pressDown,\n release,\n drag,\n scroll,\n\n // State getters\n getCurrentPosition,\n getPressedButtons,\n\n // Low-level event emission (for advanced use cases)\n emitMouseEvent,\n }\n}\n", + "import { Readable, Writable } from \"stream\"\n\nexport class TestWriteStream extends Writable {\n public readonly isTTY = true\n public readonly columns: number\n public readonly rows: number\n\n constructor(columns = 80, rows = 24) {\n super()\n this.columns = columns\n this.rows = rows\n }\n\n override _write(_chunk: any, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void {\n callback()\n }\n\n getColorDepth(): number {\n return 24\n }\n}\n\nexport type TestStdout = TestWriteStream & NodeJS.WriteStream\n\nexport function createTestStdin(): NodeJS.ReadStream {\n return new Readable({ read() {} }) as NodeJS.ReadStream\n}\n\nexport function createTestStdout(columns = 80, rows = 24): NodeJS.WriteStream {\n return new TestWriteStream(columns, rows) as TestStdout\n}\n", + "import {\n CliRenderer,\n CliRenderEvents,\n type CliRendererConfig,\n type CliRendererExternalOutputEvent,\n type CliRendererFrameEvent,\n} from \"../renderer.js\"\nimport type { NativeSpanFeed } from \"../NativeSpanFeed.js\"\nimport type { NativeRenderStats } from \"../zig.js\"\nimport { createMockKeys } from \"./mock-keys.js\"\nimport { createMockMouse } from \"./mock-mouse.js\"\nimport { createTestStdin, createTestStdout } from \"./test-streams.js\"\nimport type { CapturedFrame } from \"../types.js\"\n\nexport interface TestRendererOptions extends CliRendererConfig {\n width?: number\n height?: number\n kittyKeyboard?: boolean\n otherModifiersMode?: boolean\n}\nexport type TestRenderer = CliRenderer\nexport type MockInput = ReturnType\nexport type MockMouse = ReturnType\n\ntype RendererFeedAccess = {\n _feed?: NativeSpanFeed | null\n}\n\nexport interface TestFlushOptions {\n maxPasses?: number\n}\n\nexport interface TestVisualIdleOptions {\n quietFrames?: number\n maxFrames?: number\n}\n\nexport interface TestWaitForOptions {\n maxPasses?: number\n}\n\nexport interface TestExternalOutputCommit {\n text: string\n rows: string[]\n width: number\n height: number\n rowColumns: number\n startOnNewLine: boolean\n trailingNewline: boolean\n}\n\nexport interface TestExternalOutput {\n take(): TestExternalOutputCommit[]\n takeText(): string\n clear(): void\n}\n\nexport interface TestRendererSetup {\n renderer: TestRenderer\n mockInput: MockInput\n mockMouse: MockMouse\n renderOnce: () => Promise\n flush: (options?: TestFlushOptions) => Promise\n waitFor: (predicate: () => boolean | Promise, options?: TestWaitForOptions) => Promise\n waitForFrame: (\n predicate: (frame: string) => boolean | Promise,\n options?: TestWaitForOptions,\n ) => Promise\n waitForVisualIdle: (options?: TestVisualIdleOptions) => Promise\n externalOutput: TestExternalOutput\n getNativeStats: () => NativeRenderStats\n captureCharFrame: () => string\n captureSpans: () => CapturedFrame\n resize: (width: number, height: number) => void\n}\n\nconst decoder = new TextDecoder()\nconst DEFAULT_MAX_PASSES = 20\nconst DEFAULT_MAX_VISUAL_IDLE_FRAMES = 20\nconst DEFAULT_QUIET_FRAMES = 1\n\nasync function drainImmediateWork(): Promise {\n await Promise.resolve()\n await new Promise((resolve) => process.nextTick(resolve))\n await Promise.resolve()\n}\n\nfunction normalizePositiveInteger(value: number | undefined, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return fallback\n }\n\n return Math.floor(value)\n}\n\nfunction createWaitError(renderer: TestRenderer, message: string, frame?: string): Error {\n const stats = renderer.getStats()\n const scheduler = renderer.getSchedulerState()\n const details = [\n message,\n `frameId: ${renderer.frameId}`,\n `nativeFrameCount: ${stats.nativeFrameCount}`,\n `cellsUpdated: ${stats.cellsUpdated}`,\n `isRunning: ${scheduler.isRunning}`,\n `isRendering: ${scheduler.isRendering}`,\n `hasScheduledRender: ${scheduler.hasScheduledRender}`,\n ]\n\n if (frame !== undefined) {\n details.push(`lastFrame:\\n${frame}`)\n }\n\n return new Error(details.join(\"\\n\"))\n}\n\nclass TestExternalOutputRecorder implements TestExternalOutput {\n private commits: TestExternalOutputCommit[] = []\n\n constructor(renderer: TestRenderer) {\n renderer.on(CliRenderEvents.EXTERNAL_OUTPUT, this.record)\n renderer.once(CliRenderEvents.DESTROY, () => {\n renderer.off(CliRenderEvents.EXTERNAL_OUTPUT, this.record)\n })\n }\n\n private record = (event: CliRendererExternalOutputEvent): void => {\n const raw = decoder.decode(event.snapshot.getRealCharBytes(false))\n const rows = Array.from({ length: event.snapshot.height }, (_, index) =>\n raw.slice(index * event.snapshot.width, (index + 1) * event.snapshot.width).trimEnd(),\n )\n\n this.commits.push({\n text: rows.join(\"\\n\"),\n rows,\n width: event.snapshot.width,\n height: event.snapshot.height,\n rowColumns: event.rowColumns,\n startOnNewLine: event.startOnNewLine,\n trailingNewline: event.trailingNewline,\n })\n }\n\n public take(): TestExternalOutputCommit[] {\n const commits = this.commits\n this.commits = []\n return commits\n }\n\n public takeText(): string {\n return this.take()\n .flatMap((commit) => commit.rows)\n .join(\"\\n\")\n }\n\n public clear(): void {\n this.commits = []\n }\n}\n\nfunction waitForNextFrameOrIdle(renderer: TestRenderer): Promise {\n const scheduler = renderer.getSchedulerState()\n if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {\n return Promise.resolve(null)\n }\n\n return new Promise((resolve) => {\n let settled = false\n\n const cleanup = () => {\n renderer.off(CliRenderEvents.FRAME, onFrame)\n renderer.off(CliRenderEvents.DESTROY, onDestroy)\n }\n\n const finish = (event: CliRendererFrameEvent | null) => {\n if (settled) return\n settled = true\n cleanup()\n resolve(event)\n }\n\n const onFrame = (event: CliRendererFrameEvent) => {\n finish(event)\n }\n\n const onDestroy = () => {\n finish(null)\n }\n\n renderer.on(CliRenderEvents.FRAME, onFrame)\n renderer.once(CliRenderEvents.DESTROY, onDestroy)\n\n if (!scheduler.isRunning) {\n renderer.idle().then(() => finish(null))\n }\n })\n}\n\nexport async function createTestRenderer(options: TestRendererOptions): Promise {\n // Convert legacy kittyKeyboard boolean to new format\n const useKittyKeyboard = options.kittyKeyboard ? { events: true } : options.useKittyKeyboard\n\n const renderer = await setupTestRenderer({\n ...options,\n useKittyKeyboard,\n screenMode: options.screenMode ?? \"main-screen\",\n footerHeight: options.footerHeight ?? 12,\n consoleMode: options.consoleMode ?? \"disabled\",\n externalOutputMode: options.externalOutputMode ?? \"passthrough\",\n })\n const externalOutput = new TestExternalOutputRecorder(renderer)\n\n const mockInput = createMockKeys(renderer, {\n kittyKeyboard: options.kittyKeyboard,\n otherModifiersMode: options.otherModifiersMode,\n })\n const mockMouse = createMockMouse(renderer)\n\n const renderOnce = async () => {\n const feed = (renderer as unknown as RendererFeedAccess)._feed\n if (feed?.isBackpressured()) {\n await feed.idle()\n }\n //@ts-expect-error - this is a test renderer\n await renderer.loop()\n }\n\n const captureCharFrame = () => {\n const currentBuffer = renderer.currentRenderBuffer\n const frameBytes = currentBuffer.getRealCharBytes(true)\n return decoder.decode(frameBytes)\n }\n\n const waitForVisualIdle = async (waitOptions: TestVisualIdleOptions = {}): Promise => {\n const maxFrames = normalizePositiveInteger(waitOptions.maxFrames, DEFAULT_MAX_VISUAL_IDLE_FRAMES)\n const quietFrames = normalizePositiveInteger(waitOptions.quietFrames, DEFAULT_QUIET_FRAMES)\n let consecutiveQuietFrames = 0\n\n for (let frame = 0; frame < maxFrames; frame++) {\n await drainImmediateWork()\n\n const scheduler = renderer.getSchedulerState()\n if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {\n return\n }\n\n const event = await waitForNextFrameOrIdle(renderer)\n if (!event) {\n return\n }\n\n if (renderer.getNativeStats().cellsUpdated === 0) {\n consecutiveQuietFrames++\n if (consecutiveQuietFrames >= quietFrames) {\n return\n }\n } else {\n consecutiveQuietFrames = 0\n }\n }\n\n await drainImmediateWork()\n const scheduler = renderer.getSchedulerState()\n if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {\n return\n }\n\n throw createWaitError(renderer, `Timed out waiting for visual idle after ${maxFrames} frames`)\n }\n\n const flush = async (flushOptions: TestFlushOptions = {}): Promise => {\n await waitForVisualIdle({ maxFrames: normalizePositiveInteger(flushOptions.maxPasses, DEFAULT_MAX_PASSES) })\n }\n\n const waitFor = async (\n predicate: () => boolean | Promise,\n waitOptions: TestWaitForOptions = {},\n ): Promise => {\n const maxPasses = normalizePositiveInteger(waitOptions.maxPasses, DEFAULT_MAX_PASSES)\n\n for (let pass = 0; pass <= maxPasses; pass++) {\n await drainImmediateWork()\n if (await predicate()) {\n return\n }\n\n if (pass === maxPasses) {\n break\n }\n\n const scheduler = renderer.getSchedulerState()\n if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {\n break\n }\n\n await waitForNextFrameOrIdle(renderer)\n }\n\n throw createWaitError(renderer, `Timed out waiting for predicate after ${maxPasses} passes`)\n }\n\n const waitForFrame = async (\n predicate: (frame: string) => boolean | Promise,\n waitOptions: TestWaitForOptions = {},\n ): Promise => {\n const maxPasses = normalizePositiveInteger(waitOptions.maxPasses, DEFAULT_MAX_PASSES)\n let frame = captureCharFrame()\n\n for (let pass = 0; pass <= maxPasses; pass++) {\n await drainImmediateWork()\n frame = captureCharFrame()\n if (await predicate(frame)) {\n return frame\n }\n\n if (pass === maxPasses) {\n break\n }\n\n const scheduler = renderer.getSchedulerState()\n if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {\n break\n }\n\n await waitForNextFrameOrIdle(renderer)\n }\n\n frame = captureCharFrame()\n throw createWaitError(renderer, `Timed out waiting for frame predicate after ${maxPasses} passes`, frame)\n }\n\n return {\n renderer,\n mockInput,\n mockMouse,\n renderOnce,\n flush,\n waitFor,\n waitForFrame,\n waitForVisualIdle,\n externalOutput,\n getNativeStats: () => renderer.getNativeStats(),\n captureCharFrame,\n captureSpans: () => {\n const currentBuffer = renderer.currentRenderBuffer\n const lines = currentBuffer.getSpanLines()\n const cursorState = renderer.getCursorState()\n return {\n cols: currentBuffer.width,\n rows: currentBuffer.height,\n cursor: [cursorState.x, cursorState.y] as [number, number],\n lines,\n }\n },\n resize: (width: number, height: number) => {\n //@ts-expect-error - this is a test renderer\n renderer.processResize(width, height)\n },\n }\n}\n\nasync function setupTestRenderer(config: TestRendererOptions) {\n const stdin = config.stdin || createTestStdin()\n const width = config.width || config.stdout?.columns || process.stdout.columns || 80\n const height = config.height || config.stdout?.rows || process.stdout.rows || 24\n const stdout = config.stdout || createTestStdout(width, height)\n\n // Direct construction skips setupTerminal(); native bytes are routed to an\n // explicit memory destination so tests do not depend on process stdout or feed\n // backpressure behavior. CliRenderer still owns native renderer creation and\n // applies the same useThread defaults as production construction.\n return new CliRenderer(stdin, stdout, width, height, {\n ...config,\n bufferedOutput: config.bufferedOutput ?? \"memory\",\n })\n}\n", + "import { TreeSitterClient } from \"../lib/tree-sitter/index.js\"\nimport { SystemClock, type Clock, type TimerHandle } from \"../lib/clock.js\"\nimport type { SimpleHighlight } from \"../lib/tree-sitter/types.js\"\n\nexport class MockTreeSitterClient extends TreeSitterClient {\n private _highlightPromises: Array<{\n promise: Promise<{ highlights?: SimpleHighlight[]; warning?: string; error?: string }>\n resolve: (result: { highlights?: SimpleHighlight[]; warning?: string; error?: string }) => void\n timeout?: TimerHandle\n }> = []\n private _mockResult: { highlights?: SimpleHighlight[]; warning?: string; error?: string } = { highlights: [] }\n private _autoResolveTimeout?: number\n private readonly _clock: Clock\n\n constructor(options?: { autoResolveTimeout?: number; clock?: Clock }) {\n super({ dataPath: \"/tmp/mock\" }, { autoStartWorker: false })\n this._autoResolveTimeout = options?.autoResolveTimeout\n this._clock = options?.clock ?? new SystemClock()\n }\n\n override async destroy(): Promise {\n this.resolveAllHighlightOnce()\n await super.destroy()\n }\n\n async highlightOnce(\n content: string,\n filetype: string,\n ): Promise<{ highlights?: SimpleHighlight[]; warning?: string; error?: string }> {\n const { promise, resolve } = Promise.withResolvers<{\n highlights?: SimpleHighlight[]\n warning?: string\n error?: string\n }>()\n\n let timeout: TimerHandle | undefined\n\n if (this._autoResolveTimeout !== undefined) {\n timeout = this._clock.setTimeout(() => {\n const index = this._highlightPromises.findIndex((p) => p.promise === promise)\n if (index !== -1) {\n resolve(this._mockResult)\n this._highlightPromises.splice(index, 1)\n }\n }, this._autoResolveTimeout)\n }\n\n this._highlightPromises.push({ promise, resolve, timeout })\n\n return promise\n }\n\n setMockResult(result: { highlights?: SimpleHighlight[]; warning?: string; error?: string }) {\n this._mockResult = result\n }\n\n resolveHighlightOnce(index: number = 0) {\n if (index >= 0 && index < this._highlightPromises.length) {\n const item = this._highlightPromises[index]\n if (item.timeout) {\n this._clock.clearTimeout(item.timeout)\n }\n item.resolve(this._mockResult)\n this._highlightPromises.splice(index, 1)\n }\n }\n\n resolveAllHighlightOnce() {\n for (const { resolve, timeout } of this._highlightPromises) {\n if (timeout) {\n this._clock.clearTimeout(timeout)\n }\n resolve(this._mockResult)\n }\n this._highlightPromises = []\n }\n\n isHighlighting(): boolean {\n return this._highlightPromises.length > 0\n }\n}\n", + "import type { CliRenderer } from \"../renderer.js\"\nimport type { TerminalCapabilities, TerminalInfo } from \"../types.js\"\n\nexport interface TerminalCapabilitiesOverrides extends Partial> {\n terminal?: Partial\n}\n\nexport function createTerminalCapabilities(overrides: TerminalCapabilitiesOverrides = {}): TerminalCapabilities {\n return {\n kitty_keyboard: false,\n kitty_graphics: false,\n rgb: false,\n ansi256: false,\n unicode: \"unicode\",\n sgr_pixels: false,\n color_scheme_updates: false,\n explicit_width: false,\n scaled_text: false,\n sixel: false,\n focus_tracking: false,\n sync: false,\n bracketed_paste: false,\n hyperlinks: false,\n osc52: false,\n notifications: false,\n explicit_cursor_positioning: false,\n remote: false,\n multiplexer: \"none\",\n ...overrides,\n terminal: {\n name: \"\",\n version: \"\",\n from_xtversion: false,\n ...overrides.terminal,\n },\n }\n}\n\nexport function setRendererCapabilities(\n renderer: CliRenderer,\n overrides: TerminalCapabilitiesOverrides = {},\n): TerminalCapabilities {\n const capabilities = createTerminalCapabilities(overrides)\n ;(renderer as unknown as { _capabilities: TerminalCapabilities })._capabilities = capabilities\n return capabilities\n}\n", + "export function createSpy() {\n const calls: any[][] = []\n const spy = (...args: any[]) => {\n calls.push(args)\n }\n spy.calls = calls\n spy.callCount = () => calls.length\n spy.calledWith = (...expected: any[]) => {\n return calls.some((call) => JSON.stringify(call) === JSON.stringify(expected))\n }\n spy.reset = () => (calls.length = 0)\n return spy\n}\n", + "import type { Clock, TimerHandle } from \"../lib/clock.js\"\n\ninterface ScheduledTimer {\n id: number\n fireAt: number\n order: number\n delayMs: number\n repeat: boolean\n fn: () => void\n}\n\nfunction compareTimers(left: ScheduledTimer, right: ScheduledTimer): number {\n if (left.fireAt !== right.fireAt) {\n return left.fireAt - right.fireAt\n }\n\n return left.order - right.order\n}\n\nexport class ManualClock implements Clock {\n private time = 0\n private nextId = 1\n private nextOrder = 0\n private readonly timers = new Map()\n\n public now(): number {\n return this.time\n }\n\n public setTime(time: number): void {\n const targetTime = Math.floor(time)\n\n if (targetTime >= this.time) {\n this.advance(targetTime - this.time)\n return\n }\n\n this.time = targetTime\n }\n\n public setTimeout(fn: () => void, delayMs: number): TimerHandle {\n return this.schedule(fn, delayMs, false)\n }\n\n public clearTimeout(handle: TimerHandle): void {\n this.timers.delete(Number(handle))\n }\n\n public setInterval(fn: () => void, delayMs: number): TimerHandle {\n return this.schedule(fn, delayMs, true)\n }\n\n public clearInterval(handle: TimerHandle): void {\n this.clearTimeout(handle)\n }\n\n public advance(delayMs: number): void {\n const targetTime = this.time + Math.max(0, Math.floor(delayMs))\n\n while (true) {\n const nextTimer = this.peekNextTimer()\n if (!nextTimer || nextTimer.fireAt > targetTime) {\n break\n }\n\n this.timers.delete(nextTimer.id)\n this.time = nextTimer.fireAt\n nextTimer.fn()\n\n if (nextTimer.repeat && !this.timers.has(nextTimer.id)) {\n this.timers.set(nextTimer.id, {\n ...nextTimer,\n fireAt: this.time + nextTimer.delayMs,\n order: this.nextOrder++,\n })\n }\n }\n\n this.time = targetTime\n }\n\n public runAll(): void {\n while (true) {\n const nextTimer = this.peekNextTimer()\n if (!nextTimer) {\n return\n }\n\n this.advance(nextTimer.fireAt - this.time)\n }\n }\n\n private schedule(fn: () => void, delayMs: number, repeat: boolean): number {\n const id = this.nextId++\n const normalizedDelay = Math.max(0, Math.floor(delayMs))\n this.timers.set(id, {\n id,\n fireAt: this.time + normalizedDelay,\n order: this.nextOrder++,\n delayMs: normalizedDelay,\n repeat,\n fn,\n })\n return id\n }\n\n private peekNextTimer(): ScheduledTimer | null {\n let nextTimer: ScheduledTimer | null = null\n for (const timer of this.timers.values()) {\n if (!nextTimer || compareTimers(timer, nextTimer) < 0) {\n nextTimer = timer\n }\n }\n\n return nextTimer\n }\n}\n", + "import type { TestRenderer } from \"./test-renderer.js\"\nimport { CliRenderEvents } from \"../renderer.js\"\n\nexport interface RecordBuffersOptions {\n fg?: boolean\n bg?: boolean\n attributes?: boolean\n}\n\nexport interface RecordedBuffers {\n fg?: Uint16Array\n bg?: Uint16Array\n attributes?: Uint8Array\n}\n\nexport interface RecordedFrame {\n frame: string\n timestamp: number\n frameNumber: number\n buffers?: RecordedBuffers\n}\n\nexport interface TestRecorderOptions {\n recordBuffers?: RecordBuffersOptions\n now?: () => number\n}\n\n/**\n * TestRecorder records frames from a TestRenderer by listening to rendered frame events.\n * It captures the character frame after each native render pass.\n */\nexport class TestRecorder {\n private renderer: TestRenderer\n private frames: RecordedFrame[] = []\n private recording: boolean = false\n private frameNumber: number = 0\n private startTime: number = 0\n private decoder = new TextDecoder()\n private recordBuffers: RecordBuffersOptions\n private now: () => number\n private readonly onFrame = () => {\n if (!this.recording) return\n this.captureFrame()\n }\n\n constructor(renderer: TestRenderer, options?: TestRecorderOptions) {\n this.renderer = renderer\n this.recordBuffers = options?.recordBuffers || {}\n this.now = options?.now ?? (() => performance.now())\n }\n\n /**\n * Start recording frames.\n */\n public rec(): void {\n if (this.recording) {\n return\n }\n\n this.recording = true\n this.frames = []\n this.frameNumber = 0\n this.startTime = this.now()\n this.renderer.on(CliRenderEvents.FRAME, this.onFrame)\n }\n\n /**\n * Stop recording frames.\n */\n public stop(): void {\n if (!this.recording) {\n return\n }\n\n this.recording = false\n this.renderer.off(CliRenderEvents.FRAME, this.onFrame)\n }\n\n /**\n * Get the recorded frames.\n */\n public get recordedFrames(): RecordedFrame[] {\n return [...this.frames]\n }\n\n /**\n * Clear all recorded frames.\n */\n public clear(): void {\n this.frames = []\n this.frameNumber = 0\n }\n\n /**\n * Check if currently recording.\n */\n public get isRecording(): boolean {\n return this.recording\n }\n\n /**\n * Capture the current frame from the renderer's buffer.\n */\n private captureFrame(): void {\n const currentBuffer = this.renderer.currentRenderBuffer\n const frameBytes = currentBuffer.getRealCharBytes(true)\n const frame = this.decoder.decode(frameBytes)\n\n const recordedFrame: RecordedFrame = {\n frame,\n timestamp: this.now() - this.startTime,\n frameNumber: this.frameNumber++,\n }\n\n // Optionally record buffer data from currentRenderBuffer\n if (this.recordBuffers.fg || this.recordBuffers.bg || this.recordBuffers.attributes) {\n const buffers = currentBuffer.buffers\n recordedFrame.buffers = {}\n\n if (this.recordBuffers.fg) {\n recordedFrame.buffers.fg = new Uint16Array(buffers.fg)\n }\n if (this.recordBuffers.bg) {\n recordedFrame.buffers.bg = new Uint16Array(buffers.bg)\n }\n if (this.recordBuffers.attributes) {\n recordedFrame.buffers.attributes = new Uint8Array(buffers.attributes)\n }\n }\n\n this.frames.push(recordedFrame)\n }\n}\n" + ], + "mappings": "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", + "debugId": "884B8CD1F6ACF7CC64756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/.patches/@opentui/core/testing/bun-test-node.d.ts b/.patches/@opentui/core/testing/bun-test-node.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/bun-test-node.d.ts @@ -0,0 +1,87 @@ +import { after, afterEach, before, beforeEach, describe as nodeDescribe, test as nodeTest } from "node:test"; +type AnyFunction = (...args: any[]) => any; +type ThrowMatcher = RegExp | string | Error | ((value: unknown) => boolean) | (new (...args: any[]) => Error); +declare const asymmetricMatcher: unique symbol; +interface AsymmetricMatcher { + readonly [asymmetricMatcher]: true; + matches(received: unknown): boolean; +} +interface MockedFunction { + (...args: Parameters): ReturnType; + mock: { + calls: unknown[][]; + }; + mockImplementation(implementation: Fn): MockedFunction; + mockRestore(): void; + mockClear(): void; +} +declare function createEach(base: AnyFunction): (cases: readonly unknown[]) => (name: string, optionsOrFn?: unknown, maybeFn?: unknown) => void; +declare class AsyncExpectation { + private readonly received; + private readonly mode; + private readonly inverted; + constructor(received: PromiseLike | T, mode: "resolves" | "rejects", inverted?: boolean); + get not(): AsyncExpectation; + toBe(expected: unknown): Promise; + toEqual(expected: unknown): Promise; + toBeNull(): Promise; + toBeUndefined(): Promise; + toContain(expected: unknown): Promise; + toMatchSnapshot(snapshotName?: string): Promise; + toMatchInlineSnapshot(snapshot: string): Promise; + toThrow(expected?: ThrowMatcher): Promise; + toHaveBeenCalled(): Promise; + toHaveBeenCalledTimes(expected: number): Promise; + toHaveBeenCalledWith(...expectedArgs: unknown[]): Promise; + private unwrap; +} +declare class Expectation { + private readonly received; + private readonly inverted; + constructor(received: T, inverted?: boolean); + get not(): Expectation; + get resolves(): AsyncExpectation; + get rejects(): AsyncExpectation; + toBe(expected: unknown): void; + toEqual(expected: unknown): void; + toBeNull(): void; + toBeUndefined(): void; + toBeDefined(): void; + toContain(expected: unknown): void; + toHaveLength(expected: number): void; + toBeInstanceOf(expected: new (...args: any[]) => unknown): void; + toMatchObject(expected: object): void; + toBeTruthy(): void; + toBeFalsy(): void; + toBeGreaterThan(expected: number | bigint): void; + toBeGreaterThanOrEqual(expected: number | bigint): void; + toBeLessThan(expected: number | bigint): void; + toBeLessThanOrEqual(expected: number | bigint): void; + toBeCloseTo(expected: number, precision?: number): void; + toMatch(expected: RegExp | string): void; + toMatchSnapshot(snapshotName?: string): void; + toMatchInlineSnapshot(snapshot: string): void; + toThrow(expected?: ThrowMatcher): void; + toHaveBeenCalled(): void; + toHaveBeenCalledTimes(expected: number): void; + toHaveBeenCalledWith(...expectedArgs: unknown[]): void; + toHaveProperty(property: PropertyKey, expectedValue?: unknown): void; + private assertMatch; +} +interface ExpectApi { + (received: T): Expectation; + any(expectedType: unknown): AsymmetricMatcher; +} +export declare const expect: ExpectApi; +export declare function mock undefined>(implementation?: Fn): MockedFunction; +export declare function spyOn(object: object, key: string | symbol): MockedFunction; +export declare const beforeAll: typeof before; +export declare const afterAll: typeof after; +export declare const test: typeof nodeTest & { + each: ReturnType; +}; +export declare const it: typeof nodeTest & { + each: ReturnType; +}; +export declare const describe: typeof nodeDescribe; +export { afterEach, beforeEach }; diff --git a/.patches/@opentui/core/testing/manual-clock.d.ts b/.patches/@opentui/core/testing/manual-clock.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/manual-clock.d.ts @@ -0,0 +1,17 @@ +import type { Clock, TimerHandle } from "../lib/clock.js"; +export declare class ManualClock implements Clock { + private time; + private nextId; + private nextOrder; + private readonly timers; + now(): number; + setTime(time: number): void; + setTimeout(fn: () => void, delayMs: number): TimerHandle; + clearTimeout(handle: TimerHandle): void; + setInterval(fn: () => void, delayMs: number): TimerHandle; + clearInterval(handle: TimerHandle): void; + advance(delayMs: number): void; + runAll(): void; + private schedule; + private peekNextTimer; +} diff --git a/.patches/@opentui/core/testing/mock-keys.d.ts b/.patches/@opentui/core/testing/mock-keys.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/mock-keys.d.ts @@ -0,0 +1,81 @@ +import type { CliRenderer } from "../renderer.js"; +export declare function pasteBytes(text: string): Uint8Array; +export declare const KeyCodes: { + readonly RETURN: "\r"; + readonly LINEFEED: "\n"; + readonly TAB: "\t"; + readonly BACKSPACE: "\b"; + readonly DELETE: "\u001B[3~"; + readonly HOME: "\u001B[H"; + readonly END: "\u001B[F"; + readonly ESCAPE: "\u001B"; + readonly ARROW_UP: "\u001B[A"; + readonly ARROW_DOWN: "\u001B[B"; + readonly ARROW_RIGHT: "\u001B[C"; + readonly ARROW_LEFT: "\u001B[D"; + readonly F1: "\u001BOP"; + readonly F2: "\u001BOQ"; + readonly F3: "\u001BOR"; + readonly F4: "\u001BOS"; + readonly F5: "\u001B[15~"; + readonly F6: "\u001B[17~"; + readonly F7: "\u001B[18~"; + readonly F8: "\u001B[19~"; + readonly F9: "\u001B[20~"; + readonly F10: "\u001B[21~"; + readonly F11: "\u001B[23~"; + readonly F12: "\u001B[24~"; +}; +export type KeyInput = string | keyof typeof KeyCodes; +export interface MockKeysOptions { + kittyKeyboard?: boolean; + otherModifiersMode?: boolean; +} +export declare function createMockKeys(renderer: CliRenderer, options?: MockKeysOptions): { + pressKeys: (keys: KeyInput[], delayMs?: number) => Promise; + pressKey: (key: KeyInput, modifiers?: { + shift?: boolean; + ctrl?: boolean; + meta?: boolean; + super?: boolean; + hyper?: boolean; + }) => void; + typeText: (text: string, delayMs?: number) => Promise; + pressEnter: (modifiers?: { + shift?: boolean; + ctrl?: boolean; + meta?: boolean; + super?: boolean; + hyper?: boolean; + }) => void; + pressEscape: (modifiers?: { + shift?: boolean; + ctrl?: boolean; + meta?: boolean; + super?: boolean; + hyper?: boolean; + }) => void; + pressTab: (modifiers?: { + shift?: boolean; + ctrl?: boolean; + meta?: boolean; + super?: boolean; + hyper?: boolean; + }) => void; + pressBackspace: (modifiers?: { + shift?: boolean; + ctrl?: boolean; + meta?: boolean; + super?: boolean; + hyper?: boolean; + }) => void; + pressArrow: (direction: "up" | "down" | "left" | "right", modifiers?: { + shift?: boolean; + ctrl?: boolean; + meta?: boolean; + super?: boolean; + hyper?: boolean; + }) => void; + pressCtrlC: () => void; + pasteBracketedText: (text: string) => Promise; +}; diff --git a/.patches/@opentui/core/testing/mock-mouse.d.ts b/.patches/@opentui/core/testing/mock-mouse.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/mock-mouse.d.ts @@ -0,0 +1,38 @@ +import type { CliRenderer } from "../renderer.js"; +export declare const MouseButtons: { + readonly LEFT: 0; + readonly MIDDLE: 1; + readonly RIGHT: 2; + readonly WHEEL_UP: 64; + readonly WHEEL_DOWN: 65; + readonly WHEEL_LEFT: 66; + readonly WHEEL_RIGHT: 67; +}; +export type MouseButton = (typeof MouseButtons)[keyof typeof MouseButtons]; +export interface MousePosition { + x: number; + y: number; +} +export interface MouseModifiers { + shift?: boolean; + alt?: boolean; + ctrl?: boolean; +} +export type MouseEventType = "down" | "up" | "move" | "drag" | "scroll"; +export interface MouseEventOptions { + button?: MouseButton; + modifiers?: MouseModifiers; + delayMs?: number; +} +export declare function createMockMouse(renderer: CliRenderer): { + moveTo: (x: number, y: number, options?: MouseEventOptions) => Promise; + click: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise; + doubleClick: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise; + pressDown: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise; + release: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise; + drag: (startX: number, startY: number, endX: number, endY: number, button?: MouseButton, options?: MouseEventOptions) => Promise; + scroll: (x: number, y: number, direction: "up" | "down" | "left" | "right", options?: MouseEventOptions) => Promise; + getCurrentPosition: () => MousePosition; + getPressedButtons: () => MouseButton[]; + emitMouseEvent: (type: MouseEventType, x: number, y: number, button?: MouseButton, options?: Omit) => Promise; +}; diff --git a/.patches/@opentui/core/testing/mock-tree-sitter-client.d.ts b/.patches/@opentui/core/testing/mock-tree-sitter-client.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/mock-tree-sitter-client.d.ts @@ -0,0 +1,27 @@ +import { TreeSitterClient } from "../lib/tree-sitter/index.js"; +import { type Clock } from "../lib/clock.js"; +import type { SimpleHighlight } from "../lib/tree-sitter/types.js"; +export declare class MockTreeSitterClient extends TreeSitterClient { + private _highlightPromises; + private _mockResult; + private _autoResolveTimeout?; + private readonly _clock; + constructor(options?: { + autoResolveTimeout?: number; + clock?: Clock; + }); + destroy(): Promise; + highlightOnce(content: string, filetype: string): Promise<{ + highlights?: SimpleHighlight[]; + warning?: string; + error?: string; + }>; + setMockResult(result: { + highlights?: SimpleHighlight[]; + warning?: string; + error?: string; + }): void; + resolveHighlightOnce(index?: number): void; + resolveAllHighlightOnce(): void; + isHighlighting(): boolean; +} diff --git a/.patches/@opentui/core/testing/spy.d.ts b/.patches/@opentui/core/testing/spy.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/spy.d.ts @@ -0,0 +1,7 @@ +export declare function createSpy(): { + (...args: any[]): void; + calls: any[][]; + callCount(): number; + calledWith(...expected: any[]): boolean; + reset(): number; +}; diff --git a/.patches/@opentui/core/testing/terminal-capabilities.d.ts b/.patches/@opentui/core/testing/terminal-capabilities.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/terminal-capabilities.d.ts @@ -0,0 +1,7 @@ +import type { CliRenderer } from "../renderer.js"; +import type { TerminalCapabilities, TerminalInfo } from "../types.js"; +export interface TerminalCapabilitiesOverrides extends Partial> { + terminal?: Partial; +} +export declare function createTerminalCapabilities(overrides?: TerminalCapabilitiesOverrides): TerminalCapabilities; +export declare function setRendererCapabilities(renderer: CliRenderer, overrides?: TerminalCapabilitiesOverrides): TerminalCapabilities; diff --git a/.patches/@opentui/core/testing/test-recorder.d.ts b/.patches/@opentui/core/testing/test-recorder.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/test-recorder.d.ts @@ -0,0 +1,61 @@ +import type { TestRenderer } from "./test-renderer.js"; +export interface RecordBuffersOptions { + fg?: boolean; + bg?: boolean; + attributes?: boolean; +} +export interface RecordedBuffers { + fg?: Uint16Array; + bg?: Uint16Array; + attributes?: Uint8Array; +} +export interface RecordedFrame { + frame: string; + timestamp: number; + frameNumber: number; + buffers?: RecordedBuffers; +} +export interface TestRecorderOptions { + recordBuffers?: RecordBuffersOptions; + now?: () => number; +} +/** + * TestRecorder records frames from a TestRenderer by listening to rendered frame events. + * It captures the character frame after each native render pass. + */ +export declare class TestRecorder { + private renderer; + private frames; + private recording; + private frameNumber; + private startTime; + private decoder; + private recordBuffers; + private now; + private readonly onFrame; + constructor(renderer: TestRenderer, options?: TestRecorderOptions); + /** + * Start recording frames. + */ + rec(): void; + /** + * Stop recording frames. + */ + stop(): void; + /** + * Get the recorded frames. + */ + get recordedFrames(): RecordedFrame[]; + /** + * Clear all recorded frames. + */ + clear(): void; + /** + * Check if currently recording. + */ + get isRecording(): boolean; + /** + * Capture the current frame from the renderer's buffer. + */ + private captureFrame; +} diff --git a/.patches/@opentui/core/testing/test-renderer.d.ts b/.patches/@opentui/core/testing/test-renderer.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/test-renderer.d.ts @@ -0,0 +1,54 @@ +import { CliRenderer, type CliRendererConfig } from "../renderer.js"; +import type { NativeRenderStats } from "../zig.js"; +import { createMockKeys } from "./mock-keys.js"; +import { createMockMouse } from "./mock-mouse.js"; +import type { CapturedFrame } from "../types.js"; +export interface TestRendererOptions extends CliRendererConfig { + width?: number; + height?: number; + kittyKeyboard?: boolean; + otherModifiersMode?: boolean; +} +export type TestRenderer = CliRenderer; +export type MockInput = ReturnType; +export type MockMouse = ReturnType; +export interface TestFlushOptions { + maxPasses?: number; +} +export interface TestVisualIdleOptions { + quietFrames?: number; + maxFrames?: number; +} +export interface TestWaitForOptions { + maxPasses?: number; +} +export interface TestExternalOutputCommit { + text: string; + rows: string[]; + width: number; + height: number; + rowColumns: number; + startOnNewLine: boolean; + trailingNewline: boolean; +} +export interface TestExternalOutput { + take(): TestExternalOutputCommit[]; + takeText(): string; + clear(): void; +} +export interface TestRendererSetup { + renderer: TestRenderer; + mockInput: MockInput; + mockMouse: MockMouse; + renderOnce: () => Promise; + flush: (options?: TestFlushOptions) => Promise; + waitFor: (predicate: () => boolean | Promise, options?: TestWaitForOptions) => Promise; + waitForFrame: (predicate: (frame: string) => boolean | Promise, options?: TestWaitForOptions) => Promise; + waitForVisualIdle: (options?: TestVisualIdleOptions) => Promise; + externalOutput: TestExternalOutput; + getNativeStats: () => NativeRenderStats; + captureCharFrame: () => string; + captureSpans: () => CapturedFrame; + resize: (width: number, height: number) => void; +} +export declare function createTestRenderer(options: TestRendererOptions): Promise; diff --git a/.patches/@opentui/core/testing/test-streams.d.ts b/.patches/@opentui/core/testing/test-streams.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/testing/test-streams.d.ts @@ -0,0 +1,12 @@ +import { Writable } from "stream"; +export declare class TestWriteStream extends Writable { + readonly isTTY = true; + readonly columns: number; + readonly rows: number; + constructor(columns?: number, rows?: number); + _write(_chunk: any, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void; + getColorDepth(): number; +} +export type TestStdout = TestWriteStream & NodeJS.WriteStream; +export declare function createTestStdin(): NodeJS.ReadStream; +export declare function createTestStdout(columns?: number, rows?: number): NodeJS.WriteStream; diff --git a/.patches/@opentui/core/tests/yoga-upstream/tools/MeasureCounter.d.ts b/.patches/@opentui/core/tests/yoga-upstream/tools/MeasureCounter.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/tests/yoga-upstream/tools/MeasureCounter.d.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ +import type { MeasureFunction } from "../../../yoga.js"; +export type MeasureCounter = { + inc: MeasureFunction; + get: () => number; +}; +export declare function getMeasureCounter(cb?: MeasureFunction | null, staticWidth?: number, staticHeight?: number): MeasureCounter; +export declare function getMeasureCounterMax(): MeasureCounter; +export declare function getMeasureCounterMin(): MeasureCounter; diff --git a/.patches/@opentui/core/tests/yoga-upstream/tools/utils.d.ts b/.patches/@opentui/core/tests/yoga-upstream/tools/utils.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/tests/yoga-upstream/tools/utils.d.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import { MeasureMode } from "../../../yoga.js"; +export declare function instrinsicSizeMeasureFunc(this: string, width: number, widthMode: MeasureMode, height: number, heightMode: MeasureMode): { + width: number; + height: number; +}; diff --git a/.patches/@opentui/core/text-buffer-view.d.ts b/.patches/@opentui/core/text-buffer-view.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/text-buffer-view.d.ts @@ -0,0 +1,42 @@ +import { RGBA } from "./lib/RGBA.js"; +import { type LineInfo, type RenderLib, type TextBufferViewHandle } from "./zig.js"; +import type { TextBuffer } from "./text-buffer.js"; +export declare class TextBufferView { + private lib; + private viewPtr; + private textBuffer; + private _destroyed; + constructor(lib: RenderLib, ptr: TextBufferViewHandle, textBuffer: TextBuffer); + static create(textBuffer: TextBuffer): TextBufferView; + private guard; + get ptr(): TextBufferViewHandle; + setSelection(start: number, end: number, bgColor?: RGBA, fgColor?: RGBA): void; + updateSelection(end: number, bgColor?: RGBA, fgColor?: RGBA): void; + resetSelection(): void; + getSelection(): { + start: number; + end: number; + } | null; + hasSelection(): boolean; + setLocalSelection(anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor?: RGBA, fgColor?: RGBA): boolean; + updateLocalSelection(anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor?: RGBA, fgColor?: RGBA): boolean; + resetLocalSelection(): void; + setWrapWidth(width: number | null): void; + setWrapMode(mode: "none" | "char" | "word"): void; + setFirstLineOffset(offset: number): void; + setViewportSize(width: number, height: number): void; + setViewport(x: number, y: number, width: number, height: number): void; + get lineInfo(): LineInfo; + get logicalLineInfo(): LineInfo; + getSelectedText(): string; + getPlainText(): string; + setTabIndicator(indicator: string | number): void; + setTabIndicatorColor(color: RGBA): void; + setTruncate(truncate: boolean): void; + measureForDimensions(width: number, height: number): { + lineCount: number; + widthColsMax: number; + } | null; + getVirtualLineCount(): number; + destroy(): void; +} diff --git a/.patches/@opentui/core/text-buffer.d.ts b/.patches/@opentui/core/text-buffer.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/text-buffer.d.ts @@ -0,0 +1,66 @@ +import type { StyledText } from "./lib/styled-text.js"; +import { RGBA } from "./lib/RGBA.js"; +import { type RenderLib, type TextBufferHandle } from "./zig.js"; +import { type WidthMethod, type Highlight } from "./types.js"; +import type { SyntaxStyle } from "./syntax-style.js"; +export interface TextChunk { + __isChunk: true; + text: string; + fg?: RGBA; + bg?: RGBA; + attributes?: number; + link?: { + url: string; + }; +} +export declare class TextBuffer { + private lib; + private bufferPtr; + private _length; + private _byteSize; + private _lineInfo?; + private _destroyed; + private _syntaxStyle?; + private _textBytes?; + private _memId?; + private _appendedChunks; + constructor(lib: RenderLib, ptr: TextBufferHandle); + static create(widthMethod: WidthMethod): TextBuffer; + private guard; + setText(text: string): void; + append(text: string): void; + loadFile(path: string): void; + setStyledText(text: StyledText): void; + setDefaultFg(fg: RGBA | null): void; + setDefaultBg(bg: RGBA | null): void; + setDefaultAttributes(attributes: number | null): void; + resetDefaults(): void; + getLineCount(): number; + get length(): number; + get byteSize(): number; + get ptr(): TextBufferHandle; + getPlainText(): string; + getTextRange(startOffset: number, endOffset: number): string; + /** + * Add a highlight using character offsets into the full text. + * start/end in highlight represent absolute character positions. + */ + addHighlightByCharRange(highlight: Highlight): void; + /** + * Add a highlight to a specific line by column positions. + * start/end in highlight represent column offsets. + */ + addHighlight(lineIdx: number, highlight: Highlight): void; + removeHighlightsByRef(hlRef: number): void; + clearLineHighlights(lineIdx: number): void; + clearAllHighlights(): void; + getLineHighlights(lineIdx: number): Array; + getHighlightCount(): number; + setSyntaxStyle(style: SyntaxStyle | null): void; + getSyntaxStyle(): SyntaxStyle | null; + setTabWidth(width: number): void; + getTabWidth(): number; + clear(): void; + reset(): void; + destroy(): void; +} diff --git a/.patches/@opentui/core/types.d.ts b/.patches/@opentui/core/types.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/types.d.ts @@ -0,0 +1,173 @@ +import type { RGBA } from "./lib/RGBA.js"; +import type { EventEmitter } from "events"; +import type { Selection } from "./lib/selection.js"; +import type { Renderable } from "./Renderable.js"; +import type { InternalKeyHandler, KeyHandler } from "./lib/KeyHandler.js"; +import type { EditBufferRenderable } from "./renderables/EditBufferRenderable.js"; +export declare const TextAttributes: { + NONE: number; + BOLD: number; + DIM: number; + ITALIC: number; + UNDERLINE: number; + BLINK: number; + INVERSE: number; + HIDDEN: number; + STRIKETHROUGH: number; +}; +export declare const ATTRIBUTE_BASE_BITS = 8; +export declare const ATTRIBUTE_BASE_MASK = 255; +/** + * Extract the base 8 bits of attributes from a u32 attribute value. + * Currently we only use the first 8 bits for standard text attributes. + */ +export declare function getBaseAttributes(attr: number): number; +export type ThemeMode = "dark" | "light"; +export type CursorStyle = "block" | "line" | "underline" | "default"; +export type MousePointerStyle = "default" | "pointer" | "text" | "crosshair" | "move" | "not-allowed"; +export interface CursorStyleOptions { + style?: CursorStyle; + blinking?: boolean; + color?: RGBA; + cursor?: MousePointerStyle; +} +export declare enum DebugOverlayCorner { + topLeft = 0, + topRight = 1, + bottomLeft = 2, + bottomRight = 3 +} +export declare enum TargetChannel { + FG = 1, + BG = 2, + Both = 3 +} +export type WidthMethod = "wcwidth" | "unicode"; +export type TerminalMultiplexer = "none" | "tmux" | "zellij" | "screen" | "unknown"; +export interface TerminalInfo { + name: string; + version: string; + from_xtversion: boolean; +} +export interface TerminalCapabilities { + kitty_keyboard: boolean; + kitty_graphics: boolean; + rgb: boolean; + ansi256: boolean; + unicode: WidthMethod; + sgr_pixels: boolean; + color_scheme_updates: boolean; + explicit_width: boolean; + scaled_text: boolean; + sixel: boolean; + focus_tracking: boolean; + sync: boolean; + bracketed_paste: boolean; + hyperlinks: boolean; + osc52: boolean; + notifications: boolean; + explicit_cursor_positioning: boolean; + remote: boolean; + multiplexer: TerminalMultiplexer; + terminal: TerminalInfo; +} +export interface RendererEvents { + resize: (width: number, height: number) => void; + key: (data: Buffer) => void; + "memory:snapshot": (snapshot: { + heapUsed: number; + heapTotal: number; + arrayBuffers: number; + }) => void; + capabilities: (capabilities: TerminalCapabilities) => void; + selection: (selection: Selection) => void; + focused_renderable: (current: Renderable | null, previous: Renderable | null) => void; + focused_editor: (current: EditBufferRenderable | null, previous: EditBufferRenderable | null) => void; + "debugOverlay:toggle": (enabled: boolean) => void; + theme_mode: (mode: ThemeMode) => void; +} +export interface RenderContext extends EventEmitter { + addToHitGrid: (x: number, y: number, width: number, height: number, id: number) => void; + pushHitGridScissorRect: (x: number, y: number, width: number, height: number) => void; + popHitGridScissorRect: () => void; + clearHitGridScissorRects: () => void; + width: number; + height: number; + /** Monotonic, bumped once per `loop()` iteration. Lets renderables dedupe per-frame work. */ + frameId: number; + requestRender: () => void; + setCursorPosition: (x: number, y: number, visible: boolean) => void; + setCursorStyle: (options: CursorStyleOptions) => void; + setCursorColor: (color: RGBA) => void; + setMousePointer: (shape: MousePointerStyle) => void; + widthMethod: WidthMethod; + capabilities: TerminalCapabilities | null; + requestLive: () => void; + dropLive: () => void; + hasSelection: boolean; + getSelection: () => Selection | null; + requestSelectionUpdate: () => void; + currentFocusedRenderable: Renderable | null; + currentFocusedEditor: EditBufferRenderable | null; + focusRenderable: (renderable: Renderable) => void; + blurRenderable: (renderable: Renderable) => void; + claimFirstLineOffset?: (renderable?: Renderable) => number; + registerLifecyclePass: (renderable: Renderable) => void; + unregisterLifecyclePass: (renderable: Renderable) => void; + getLifecyclePasses: () => Set; + keyInput: KeyHandler; + _internalKeyInput: InternalKeyHandler; + clearSelection: () => void; + startSelection: (renderable: Renderable, x: number, y: number) => void; + updateSelection: (currentRenderable: Renderable | undefined, x: number, y: number, options?: { + finishDragging?: boolean; + }) => void; +} +export type Timeout = ReturnType | undefined; +export interface ViewportBounds { + x: number; + y: number; + width: number; + height: number; +} +export interface Highlight { + start: number; + end: number; + styleId: number; + priority?: number | null; + hlRef?: number | null; +} +export interface LineInfo { + /** Display-column offset for each visual line start. */ + lineStartCols: number[]; + /** Display-column width for each visual line. */ + lineWidthCols: number[]; + /** Maximum display-column width across the reported lines. */ + lineWidthColsMax: number; + /** Source logical line index for each visual line. */ + lineSources: number[]; + /** Wrap index within each source logical line. */ + lineWraps: number[]; +} +export interface LineInfoProvider { + get lineInfo(): LineInfo; + get lineCount(): number; + get virtualLineCount(): number; + get scrollY(): number; +} +export interface CapturedSpan { + text: string; + fg: RGBA; + bg: RGBA; + attributes: number; + width: number; +} +export interface CapturedLine { + spans: CapturedSpan[]; +} +export interface CapturedFrame { + cols: number; + rows: number; + cursor: [number, number]; + lines: CapturedLine[]; +} diff --git a/.patches/@opentui/core/utils.d.ts b/.patches/@opentui/core/utils.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/utils.d.ts @@ -0,0 +1,14 @@ +import { Renderable } from "./Renderable.js"; +export declare function createTextAttributes({ bold, italic, underline, dim, blink, inverse, hidden, strikethrough, }?: { + bold?: boolean; + italic?: boolean; + underline?: boolean; + dim?: boolean; + blink?: boolean; + inverse?: boolean; + hidden?: boolean; + strikethrough?: boolean; +}): number; +export declare function attributesWithLink(baseAttributes: number, linkId: number): number; +export declare function getLinkId(attributes: number): number; +export declare function visualizeRenderableTree(renderable: Renderable, maxDepth?: number): void; diff --git a/.patches/@opentui/core/yoga.d.ts b/.patches/@opentui/core/yoga.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/yoga.d.ts @@ -0,0 +1,440 @@ +import type { Pointer } from "./platform/ffi.js"; +export declare enum Align { + Auto = 0, + FlexStart = 1, + Center = 2, + FlexEnd = 3, + Stretch = 4, + Baseline = 5, + SpaceBetween = 6, + SpaceAround = 7, + SpaceEvenly = 8 +} +export declare enum BoxSizing { + BorderBox = 0, + ContentBox = 1 +} +export declare enum Dimension { + Width = 0, + Height = 1 +} +export declare enum Direction { + Inherit = 0, + LTR = 1, + RTL = 2 +} +export declare enum Display { + Flex = 0, + None = 1, + Contents = 2 +} +export declare enum Edge { + Left = 0, + Top = 1, + Right = 2, + Bottom = 3, + Start = 4, + End = 5, + Horizontal = 6, + Vertical = 7, + All = 8 +} +export declare enum Errata { + None = 0, + StretchFlexBasis = 1, + AbsolutePositionWithoutInsetsExcludesPadding = 2, + AbsolutePercentAgainstInnerSize = 4, + All = 2147483647, + Classic = 2147483646 +} +export declare enum ExperimentalFeature { + WebFlexBasis = 0 +} +export declare enum FlexDirection { + Column = 0, + ColumnReverse = 1, + Row = 2, + RowReverse = 3 +} +export declare enum Gutter { + Column = 0, + Row = 1, + All = 2 +} +export declare enum Justify { + FlexStart = 0, + Center = 1, + FlexEnd = 2, + SpaceBetween = 3, + SpaceAround = 4, + SpaceEvenly = 5 +} +export declare enum LogLevel { + Error = 0, + Warn = 1, + Info = 2, + Debug = 3, + Verbose = 4, + Fatal = 5 +} +export declare enum MeasureMode { + Undefined = 0, + Exactly = 1, + AtMost = 2 +} +export declare enum NodeType { + Default = 0, + Text = 1 +} +export declare enum Overflow { + Visible = 0, + Hidden = 1, + Scroll = 2 +} +export declare enum PositionType { + Static = 0, + Relative = 1, + Absolute = 2 +} +export declare enum Unit { + Undefined = 0, + Point = 1, + Percent = 2, + Auto = 3 +} +export declare enum Wrap { + NoWrap = 0, + Wrap = 1, + WrapReverse = 2 +} +export declare const ALIGN_AUTO = Align.Auto; +export declare const ALIGN_FLEX_START = Align.FlexStart; +export declare const ALIGN_CENTER = Align.Center; +export declare const ALIGN_FLEX_END = Align.FlexEnd; +export declare const ALIGN_STRETCH = Align.Stretch; +export declare const ALIGN_BASELINE = Align.Baseline; +export declare const ALIGN_SPACE_BETWEEN = Align.SpaceBetween; +export declare const ALIGN_SPACE_AROUND = Align.SpaceAround; +export declare const ALIGN_SPACE_EVENLY = Align.SpaceEvenly; +export declare const BOX_SIZING_BORDER_BOX = BoxSizing.BorderBox; +export declare const BOX_SIZING_CONTENT_BOX = BoxSizing.ContentBox; +export declare const DIMENSION_WIDTH = Dimension.Width; +export declare const DIMENSION_HEIGHT = Dimension.Height; +export declare const DIRECTION_INHERIT = Direction.Inherit; +export declare const DIRECTION_LTR = Direction.LTR; +export declare const DIRECTION_RTL = Direction.RTL; +export declare const DISPLAY_FLEX = Display.Flex; +export declare const DISPLAY_NONE = Display.None; +export declare const DISPLAY_CONTENTS = Display.Contents; +export declare const EDGE_LEFT = Edge.Left; +export declare const EDGE_TOP = Edge.Top; +export declare const EDGE_RIGHT = Edge.Right; +export declare const EDGE_BOTTOM = Edge.Bottom; +export declare const EDGE_START = Edge.Start; +export declare const EDGE_END = Edge.End; +export declare const EDGE_HORIZONTAL = Edge.Horizontal; +export declare const EDGE_VERTICAL = Edge.Vertical; +export declare const EDGE_ALL = Edge.All; +export declare const ERRATA_NONE = Errata.None; +export declare const ERRATA_STRETCH_FLEX_BASIS = Errata.StretchFlexBasis; +export declare const ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING = Errata.AbsolutePositionWithoutInsetsExcludesPadding; +export declare const ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE = Errata.AbsolutePercentAgainstInnerSize; +export declare const ERRATA_ALL = Errata.All; +export declare const ERRATA_CLASSIC = Errata.Classic; +export declare const EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS = ExperimentalFeature.WebFlexBasis; +export declare const FLEX_DIRECTION_COLUMN = FlexDirection.Column; +export declare const FLEX_DIRECTION_COLUMN_REVERSE = FlexDirection.ColumnReverse; +export declare const FLEX_DIRECTION_ROW = FlexDirection.Row; +export declare const FLEX_DIRECTION_ROW_REVERSE = FlexDirection.RowReverse; +export declare const GUTTER_COLUMN = Gutter.Column; +export declare const GUTTER_ROW = Gutter.Row; +export declare const GUTTER_ALL = Gutter.All; +export declare const JUSTIFY_FLEX_START = Justify.FlexStart; +export declare const JUSTIFY_CENTER = Justify.Center; +export declare const JUSTIFY_FLEX_END = Justify.FlexEnd; +export declare const JUSTIFY_SPACE_BETWEEN = Justify.SpaceBetween; +export declare const JUSTIFY_SPACE_AROUND = Justify.SpaceAround; +export declare const JUSTIFY_SPACE_EVENLY = Justify.SpaceEvenly; +export declare const LOG_LEVEL_ERROR = LogLevel.Error; +export declare const LOG_LEVEL_WARN = LogLevel.Warn; +export declare const LOG_LEVEL_INFO = LogLevel.Info; +export declare const LOG_LEVEL_DEBUG = LogLevel.Debug; +export declare const LOG_LEVEL_VERBOSE = LogLevel.Verbose; +export declare const LOG_LEVEL_FATAL = LogLevel.Fatal; +export declare const MEASURE_MODE_UNDEFINED = MeasureMode.Undefined; +export declare const MEASURE_MODE_EXACTLY = MeasureMode.Exactly; +export declare const MEASURE_MODE_AT_MOST = MeasureMode.AtMost; +export declare const NODE_TYPE_DEFAULT = NodeType.Default; +export declare const NODE_TYPE_TEXT = NodeType.Text; +export declare const OVERFLOW_VISIBLE = Overflow.Visible; +export declare const OVERFLOW_HIDDEN = Overflow.Hidden; +export declare const OVERFLOW_SCROLL = Overflow.Scroll; +export declare const POSITION_TYPE_STATIC = PositionType.Static; +export declare const POSITION_TYPE_RELATIVE = PositionType.Relative; +export declare const POSITION_TYPE_ABSOLUTE = PositionType.Absolute; +export declare const UNIT_UNDEFINED = Unit.Undefined; +export declare const UNIT_POINT = Unit.Point; +export declare const UNIT_PERCENT = Unit.Percent; +export declare const UNIT_AUTO = Unit.Auto; +export declare const WRAP_NO_WRAP = Wrap.NoWrap; +export declare const WRAP_WRAP = Wrap.Wrap; +export declare const WRAP_WRAP_REVERSE = Wrap.WrapReverse; +export interface Layout { + left: number; + right: number; + top: number; + bottom: number; + width: number; + height: number; +} +export interface Size { + width: number; + height: number; +} +export interface Value { + unit: Unit; + value: number; +} +export type MeasureFunction = (width: number, widthMode: MeasureMode, height: number, heightMode: MeasureMode) => Size; +export type DirtiedFunction = (node: Node) => void; +type ValueInput = number | "auto" | `${number}%` | Value | undefined; +type ValueInputNoAuto = number | `${number}%` | Value | undefined; +export declare class Config { + readonly ptr: Pointer; + private freed; + private constructor(); + static create(): Config; + static destroy(config: Config): void; + free(): void; + setUseWebDefaults(useWebDefaults: boolean): void; + useWebDefaults(): boolean; + setPointScaleFactor(pointScaleFactor: number): void; + getPointScaleFactor(): number; + setErrata(errata: Errata): void; + getErrata(): Errata; + setExperimentalFeatureEnabled(feature: ExperimentalFeature, enabled: boolean): void; + isExperimentalFeatureEnabled(feature: ExperimentalFeature): boolean; +} +export declare class Node { + readonly ptr: Pointer; + private freed; + private measureCallback; + private dirtiedCallback; + private constructor(); + static create(config?: Config): Node; + static createForOpenTUI(): Node; + static createDefault(): Node; + static createWithConfig(config: Config): Node; + static destroy(node: Node): void; + private static fromPointer; + isFreed(): boolean; + free(): void; + freeRecursive(): void; + reset(): void; + copyStyle(node: Node): void; + insertChild(child: Node, index: number): void; + removeChild(child: Node): void; + removeAllChildren(): void; + getChild(index: number): Node | null; + getChildCount(): number; + getParent(): Node | null; + calculateLayout(width?: number | "auto", height?: number | "auto", direction?: Direction): void; + hasNewLayout(): boolean; + markLayoutSeen(): void; + markDirty(): void; + isDirty(): boolean; + getComputedLayout(): Layout; + getComputedLeft(): number; + getComputedTop(): number; + getComputedRight(): number; + getComputedBottom(): number; + getComputedWidth(): number; + getComputedHeight(): number; + getComputedMargin(edge: Edge): number; + getComputedPadding(edge: Edge): number; + getComputedBorder(edge: Edge): number; + setDirection(direction: Direction): void; + getDirection(): Direction; + setFlexDirection(flexDirection: FlexDirection): void; + getFlexDirection(): FlexDirection; + setJustifyContent(justifyContent: Justify): void; + getJustifyContent(): Justify; + setAlignContent(alignContent: Align): void; + getAlignContent(): Align; + setAlignItems(alignItems: Align): void; + getAlignItems(): Align; + setAlignSelf(alignSelf: Align): void; + getAlignSelf(): Align; + setPositionType(positionType: PositionType): void; + getPositionType(): PositionType; + setFlexWrap(flexWrap: Wrap): void; + getFlexWrap(): Wrap; + setOverflow(overflow: Overflow): void; + getOverflow(): Overflow; + setDisplay(display: Display): void; + getDisplay(): Display; + setBoxSizing(boxSizing: BoxSizing): void; + getBoxSizing(): BoxSizing; + setFlex(flex: number | undefined): void; + getFlex(): number; + setFlexGrow(flexGrow: number | undefined): void; + getFlexGrow(): number; + setFlexShrink(flexShrink: number | undefined): void; + getFlexShrink(): number; + setAspectRatio(aspectRatio: number | undefined): void; + getAspectRatio(): number; + setFlexBasis(flexBasis: ValueInput): void; + setFlexBasisPercent(flexBasis: number | undefined): void; + setFlexBasisAuto(): void; + getFlexBasis(): Value; + setWidth(width: ValueInput): void; + setWidthPercent(width: number | undefined): void; + setWidthAuto(): void; + getWidth(): Value; + setHeight(height: ValueInput): void; + setHeightPercent(height: number | undefined): void; + setHeightAuto(): void; + getHeight(): Value; + setMinWidth(minWidth: ValueInputNoAuto): void; + setMinWidthPercent(minWidth: number | undefined): void; + getMinWidth(): Value; + setMinHeight(minHeight: ValueInputNoAuto): void; + setMinHeightPercent(minHeight: number | undefined): void; + getMinHeight(): Value; + setMaxWidth(maxWidth: ValueInputNoAuto): void; + setMaxWidthPercent(maxWidth: number | undefined): void; + getMaxWidth(): Value; + setMaxHeight(maxHeight: ValueInputNoAuto): void; + setMaxHeightPercent(maxHeight: number | undefined): void; + getMaxHeight(): Value; + setMargin(edge: Edge, margin: ValueInput): void; + setMarginPercent(edge: Edge, margin: number | undefined): void; + setMarginAuto(edge: Edge): void; + getMargin(edge: Edge): Value; + setPadding(edge: Edge, padding: ValueInputNoAuto): void; + setPaddingPercent(edge: Edge, padding: number | undefined): void; + getPadding(edge: Edge): Value; + setPosition(edge: Edge, position: ValueInput): void; + setPositionPercent(edge: Edge, position: number | undefined): void; + setPositionAuto(edge: Edge): void; + getPosition(edge: Edge): Value; + setGap(gutter: Gutter, gap: ValueInputNoAuto): void; + setGapPercent(gutter: Gutter, gap: number | undefined): void; + getGap(gutter: Gutter): Value; + setBorder(edge: Edge, border: number | undefined): void; + getBorder(edge: Edge): number; + setIsReferenceBaseline(isReferenceBaseline: boolean): void; + isReferenceBaseline(): boolean; + setAlwaysFormsContainingBlock(alwaysFormsContainingBlock: boolean): void; + getAlwaysFormsContainingBlock(): boolean; + setMeasureFunc(measureFunc: MeasureFunction | null): void; + unsetMeasureFunc(): void; + hasMeasureFunc(): boolean; + setDirtiedFunc(dirtiedFunc: DirtiedFunction | null): void; + unsetDirtiedFunc(): void; + private setEnum; + private getEnum; + private setFloat; + private getFloat; + private setValue; + private getValue; + private collectSubtree; + private closeMeasureCallback; + private closeDirtiedCallback; + private markFreed; +} +declare const Yoga: { + Config: typeof Config; + Node: typeof Node; + Align: typeof Align; + BoxSizing: typeof BoxSizing; + Dimension: typeof Dimension; + Direction: typeof Direction; + Display: typeof Display; + Edge: typeof Edge; + Errata: typeof Errata; + ExperimentalFeature: typeof ExperimentalFeature; + FlexDirection: typeof FlexDirection; + Gutter: typeof Gutter; + Justify: typeof Justify; + LogLevel: typeof LogLevel; + MeasureMode: typeof MeasureMode; + NodeType: typeof NodeType; + Overflow: typeof Overflow; + PositionType: typeof PositionType; + Unit: typeof Unit; + Wrap: typeof Wrap; + ALIGN_AUTO: Align; + ALIGN_FLEX_START: Align; + ALIGN_CENTER: Align; + ALIGN_FLEX_END: Align; + ALIGN_STRETCH: Align; + ALIGN_BASELINE: Align; + ALIGN_SPACE_BETWEEN: Align; + ALIGN_SPACE_AROUND: Align; + ALIGN_SPACE_EVENLY: Align; + BOX_SIZING_BORDER_BOX: BoxSizing; + BOX_SIZING_CONTENT_BOX: BoxSizing; + DIMENSION_WIDTH: Dimension; + DIMENSION_HEIGHT: Dimension; + DIRECTION_INHERIT: Direction; + DIRECTION_LTR: Direction; + DIRECTION_RTL: Direction; + DISPLAY_FLEX: Display; + DISPLAY_NONE: Display; + DISPLAY_CONTENTS: Display; + EDGE_LEFT: Edge; + EDGE_TOP: Edge; + EDGE_RIGHT: Edge; + EDGE_BOTTOM: Edge; + EDGE_START: Edge; + EDGE_END: Edge; + EDGE_HORIZONTAL: Edge; + EDGE_VERTICAL: Edge; + EDGE_ALL: Edge; + ERRATA_NONE: Errata; + ERRATA_STRETCH_FLEX_BASIS: Errata; + ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING: Errata; + ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE: Errata; + ERRATA_ALL: Errata; + ERRATA_CLASSIC: Errata; + EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS: ExperimentalFeature; + FLEX_DIRECTION_COLUMN: FlexDirection; + FLEX_DIRECTION_COLUMN_REVERSE: FlexDirection; + FLEX_DIRECTION_ROW: FlexDirection; + FLEX_DIRECTION_ROW_REVERSE: FlexDirection; + GUTTER_COLUMN: Gutter; + GUTTER_ROW: Gutter; + GUTTER_ALL: Gutter; + JUSTIFY_FLEX_START: Justify; + JUSTIFY_CENTER: Justify; + JUSTIFY_FLEX_END: Justify; + JUSTIFY_SPACE_BETWEEN: Justify; + JUSTIFY_SPACE_AROUND: Justify; + JUSTIFY_SPACE_EVENLY: Justify; + LOG_LEVEL_ERROR: LogLevel; + LOG_LEVEL_WARN: LogLevel; + LOG_LEVEL_INFO: LogLevel; + LOG_LEVEL_DEBUG: LogLevel; + LOG_LEVEL_VERBOSE: LogLevel; + LOG_LEVEL_FATAL: LogLevel; + MEASURE_MODE_UNDEFINED: MeasureMode; + MEASURE_MODE_EXACTLY: MeasureMode; + MEASURE_MODE_AT_MOST: MeasureMode; + NODE_TYPE_DEFAULT: NodeType; + NODE_TYPE_TEXT: NodeType; + OVERFLOW_VISIBLE: Overflow; + OVERFLOW_HIDDEN: Overflow; + OVERFLOW_SCROLL: Overflow; + POSITION_TYPE_STATIC: PositionType; + POSITION_TYPE_RELATIVE: PositionType; + POSITION_TYPE_ABSOLUTE: PositionType; + UNIT_UNDEFINED: Unit; + UNIT_POINT: Unit; + UNIT_PERCENT: Unit; + UNIT_AUTO: Unit; + WRAP_NO_WRAP: Wrap; + WRAP_WRAP: Wrap; + WRAP_WRAP_REVERSE: Wrap; +}; +export default Yoga; diff --git a/.patches/@opentui/core/yoga.js b/.patches/@opentui/core/yoga.js new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/yoga.js @@ -0,0 +1,193 @@ +import { + ALIGN_AUTO, + ALIGN_BASELINE, + ALIGN_CENTER, + ALIGN_FLEX_END, + ALIGN_FLEX_START, + ALIGN_SPACE_AROUND, + ALIGN_SPACE_BETWEEN, + ALIGN_SPACE_EVENLY, + ALIGN_STRETCH, + Align, + BOX_SIZING_BORDER_BOX, + BOX_SIZING_CONTENT_BOX, + BoxSizing, + Config, + DIMENSION_HEIGHT, + DIMENSION_WIDTH, + DIRECTION_INHERIT, + DIRECTION_LTR, + DIRECTION_RTL, + DISPLAY_CONTENTS, + DISPLAY_FLEX, + DISPLAY_NONE, + Dimension, + Direction, + Display, + EDGE_ALL, + EDGE_BOTTOM, + EDGE_END, + EDGE_HORIZONTAL, + EDGE_LEFT, + EDGE_RIGHT, + EDGE_START, + EDGE_TOP, + EDGE_VERTICAL, + ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, + ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, + ERRATA_ALL, + ERRATA_CLASSIC, + ERRATA_NONE, + ERRATA_STRETCH_FLEX_BASIS, + EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, + Edge, + Errata, + ExperimentalFeature, + FLEX_DIRECTION_COLUMN, + FLEX_DIRECTION_COLUMN_REVERSE, + FLEX_DIRECTION_ROW, + FLEX_DIRECTION_ROW_REVERSE, + FlexDirection, + GUTTER_ALL, + GUTTER_COLUMN, + GUTTER_ROW, + Gutter, + JUSTIFY_CENTER, + JUSTIFY_FLEX_END, + JUSTIFY_FLEX_START, + JUSTIFY_SPACE_AROUND, + JUSTIFY_SPACE_BETWEEN, + JUSTIFY_SPACE_EVENLY, + Justify, + LOG_LEVEL_DEBUG, + LOG_LEVEL_ERROR, + LOG_LEVEL_FATAL, + LOG_LEVEL_INFO, + LOG_LEVEL_VERBOSE, + LOG_LEVEL_WARN, + LogLevel1 as LogLevel, + MEASURE_MODE_AT_MOST, + MEASURE_MODE_EXACTLY, + MEASURE_MODE_UNDEFINED, + MeasureMode, + NODE_TYPE_DEFAULT, + NODE_TYPE_TEXT, + Node, + NodeType, + OVERFLOW_HIDDEN, + OVERFLOW_SCROLL, + OVERFLOW_VISIBLE, + Overflow, + POSITION_TYPE_ABSOLUTE, + POSITION_TYPE_RELATIVE, + POSITION_TYPE_STATIC, + PositionType, + UNIT_AUTO, + UNIT_PERCENT, + UNIT_POINT, + UNIT_UNDEFINED, + Unit, + WRAP_NO_WRAP, + WRAP_WRAP, + WRAP_WRAP_REVERSE, + Wrap, + yoga_default +} from "./index-pcvh9d34.js"; +export { + yoga_default as default, + Wrap, + WRAP_WRAP_REVERSE, + WRAP_WRAP, + WRAP_NO_WRAP, + Unit, + UNIT_UNDEFINED, + UNIT_POINT, + UNIT_PERCENT, + UNIT_AUTO, + PositionType, + POSITION_TYPE_STATIC, + POSITION_TYPE_RELATIVE, + POSITION_TYPE_ABSOLUTE, + Overflow, + OVERFLOW_VISIBLE, + OVERFLOW_SCROLL, + OVERFLOW_HIDDEN, + NodeType, + Node, + NODE_TYPE_TEXT, + NODE_TYPE_DEFAULT, + MeasureMode, + MEASURE_MODE_UNDEFINED, + MEASURE_MODE_EXACTLY, + MEASURE_MODE_AT_MOST, + LogLevel, + LOG_LEVEL_WARN, + LOG_LEVEL_VERBOSE, + LOG_LEVEL_INFO, + LOG_LEVEL_FATAL, + LOG_LEVEL_ERROR, + LOG_LEVEL_DEBUG, + Justify, + JUSTIFY_SPACE_EVENLY, + JUSTIFY_SPACE_BETWEEN, + JUSTIFY_SPACE_AROUND, + JUSTIFY_FLEX_START, + JUSTIFY_FLEX_END, + JUSTIFY_CENTER, + Gutter, + GUTTER_ROW, + GUTTER_COLUMN, + GUTTER_ALL, + FlexDirection, + FLEX_DIRECTION_ROW_REVERSE, + FLEX_DIRECTION_ROW, + FLEX_DIRECTION_COLUMN_REVERSE, + FLEX_DIRECTION_COLUMN, + ExperimentalFeature, + Errata, + Edge, + EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, + ERRATA_STRETCH_FLEX_BASIS, + ERRATA_NONE, + ERRATA_CLASSIC, + ERRATA_ALL, + ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, + ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, + EDGE_VERTICAL, + EDGE_TOP, + EDGE_START, + EDGE_RIGHT, + EDGE_LEFT, + EDGE_HORIZONTAL, + EDGE_END, + EDGE_BOTTOM, + EDGE_ALL, + Display, + Direction, + Dimension, + DISPLAY_NONE, + DISPLAY_FLEX, + DISPLAY_CONTENTS, + DIRECTION_RTL, + DIRECTION_LTR, + DIRECTION_INHERIT, + DIMENSION_WIDTH, + DIMENSION_HEIGHT, + Config, + BoxSizing, + BOX_SIZING_CONTENT_BOX, + BOX_SIZING_BORDER_BOX, + Align, + ALIGN_STRETCH, + ALIGN_SPACE_EVENLY, + ALIGN_SPACE_BETWEEN, + ALIGN_SPACE_AROUND, + ALIGN_FLEX_START, + ALIGN_FLEX_END, + ALIGN_CENTER, + ALIGN_BASELINE, + ALIGN_AUTO +}; + +//# debugId=3DEE98A3AAE9E41E64756E2164756E21 +//# sourceMappingURL=yoga.js.map diff --git a/.patches/@opentui/core/yoga.js.map b/.patches/@opentui/core/yoga.js.map new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/yoga.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sourcesContent": [ + ], + "mappings": "", + "debugId": "3DEE98A3AAE9E41E64756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/.patches/@opentui/core/zig-structs.d.ts b/.patches/@opentui/core/zig-structs.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/zig-structs.d.ts @@ -0,0 +1,252 @@ +import { type Pointer } from "./platform/ffi.js"; +import { RGBA } from "./lib/RGBA.js"; +type StyledChunkInput = { + text: string; + fg?: RGBA | null; + bg?: RGBA | null; + attributes?: number | null; + link?: { + url: string; + } | string | null; +}; +export declare const StyledChunkStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["text", "char*"], readonly ["text_len", "u64", { + readonly lengthOf: "text"; +}], readonly ["fg", "pointer", { + readonly optional: true; + readonly packTransform: (rgba?: RGBA) => Pointer | null; + readonly unpackTransform: (ptr?: Pointer) => RGBA | undefined; +}], readonly ["bg", "pointer", { + readonly optional: true; + readonly packTransform: (rgba?: RGBA) => Pointer | null; + readonly unpackTransform: (ptr?: Pointer) => RGBA | undefined; +}], readonly ["attributes", "u32", { + readonly default: 0; +}], readonly ["link", "char*", { + readonly default: ""; +}], readonly ["link_len", "u64", { + readonly lengthOf: "link"; +}]], { + readonly mapValue: (chunk: StyledChunkInput) => StyledChunkInput; +}>; +export declare const HighlightStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["start", "u32"], readonly ["end", "u32"], readonly ["styleId", "u32"], readonly ["priority", "u8", { + readonly default: 0; +}], readonly ["hlRef", "u16", { + readonly default: 0; +}]], {}>; +export declare const LogicalCursorStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["row", "u32"], readonly ["col", "u32"], readonly ["offset", "u32"]], {}>; +export declare const VisualCursorStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["visualRow", "u32"], readonly ["visualCol", "u32"], readonly ["logicalRow", "u32"], readonly ["logicalCol", "u32"], readonly ["offset", "u32"]], {}>; +export declare const TerminalCapabilitiesStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["kitty_keyboard", "bool_u8"], readonly ["kitty_graphics", "bool_u8"], readonly ["rgb", "bool_u8"], readonly ["ansi256", "bool_u8"], readonly ["unicode", import("bun-ffi-structs").EnumDef<{ + wcwidth: number; + unicode: number; +}>], readonly ["sgr_pixels", "bool_u8"], readonly ["color_scheme_updates", "bool_u8"], readonly ["explicit_width", "bool_u8"], readonly ["scaled_text", "bool_u8"], readonly ["sixel", "bool_u8"], readonly ["focus_tracking", "bool_u8"], readonly ["sync", "bool_u8"], readonly ["bracketed_paste", "bool_u8"], readonly ["hyperlinks", "bool_u8"], readonly ["osc52", "bool_u8"], readonly ["notifications", "bool_u8"], readonly ["explicit_cursor_positioning", "bool_u8"], readonly ["remote", "bool_u8"], readonly ["multiplexer", import("bun-ffi-structs").EnumDef<{ + none: number; + tmux: number; + zellij: number; + screen: number; + unknown: number; +}>], readonly ["term_name", "char*"], readonly ["term_name_len", "u64", { + readonly lengthOf: "term_name"; +}], readonly ["term_version", "char*"], readonly ["term_version_len", "u64", { + readonly lengthOf: "term_version"; +}], readonly ["term_from_xtversion", "bool_u8"]], {}>; +export declare const EncodedCharStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["width", "u8"], readonly ["char", "u32"]], {}>; +export declare const LineInfoStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["startCols", readonly ["u32"]], readonly ["startColsLen", "u32", { + readonly lengthOf: "startCols"; +}], readonly ["widthCols", readonly ["u32"]], readonly ["widthColsLen", "u32", { + readonly lengthOf: "widthCols"; +}], readonly ["sources", readonly ["u32"]], readonly ["sourcesLen", "u32", { + readonly lengthOf: "sources"; +}], readonly ["wraps", readonly ["u32"]], readonly ["wrapsLen", "u32", { + readonly lengthOf: "wraps"; +}], readonly ["widthColsMax", "u32"]], {}>; +export declare const MeasureResultStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["lineCount", "u32"], readonly ["widthColsMax", "u32"]], {}>; +export declare const CursorStateStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["x", "u32"], readonly ["y", "u32"], readonly ["visible", "bool_u8"], readonly ["style", "u8"], readonly ["blinking", "bool_u8"], readonly ["r", "f32"], readonly ["g", "f32"], readonly ["b", "f32"], readonly ["a", "f32"]], {}>; +export declare const CursorStyleOptionsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["style", "u8", { + readonly default: 255; +}], readonly ["blinking", "u8", { + readonly default: 255; +}], readonly ["color", "pointer", { + readonly optional: true; + readonly packTransform: (rgba?: RGBA) => Pointer | null; + readonly unpackTransform: (ptr?: Pointer) => RGBA | undefined; +}], readonly ["cursor", "u8", { + readonly default: 255; +}]], {}>; +export declare const GridDrawOptionsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["drawInner", "bool_u8", { + readonly default: true; +}], readonly ["drawOuter", "bool_u8", { + readonly default: true; +}]], {}>; +export type BuildOptions = { + gpaSafeStats: boolean; + gpaMemoryLimitTracking: boolean; +}; +export declare const BuildOptionsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["gpaSafeStats", "bool_u8"], readonly ["gpaMemoryLimitTracking", "bool_u8"]], {}>; +export type AllocatorStats = { + totalRequestedBytes: number; + activeAllocations: number; + smallAllocations: number; + largeAllocations: number; + requestedBytesValid: boolean; +}; +export declare const AllocatorStatsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["totalRequestedBytes", "u64"], readonly ["activeAllocations", "u64"], readonly ["smallAllocations", "u64"], readonly ["largeAllocations", "u64"], readonly ["requestedBytesValid", "bool_u8"]], {}>; +export type NativeRenderStats = { + nativeLastFrameTime: number; + nativeAverageFrameTime: number; + nativeFrameCount: number; + cellsUpdated: number; + averageCellsUpdated: number; + nativeRenderTime?: number; + nativeStdoutWriteTime?: number; +}; +export declare const NativeRenderStatsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["lastFrameTime", "f64"], readonly ["averageFrameTime", "f64"], readonly ["renderTime", "f64"], readonly ["stdoutWriteTime", "f64"], readonly ["frameCount", "u64"], readonly ["cellsUpdated", "u32"], readonly ["averageCellsUpdated", "u32"], readonly ["renderTimeValid", "bool_u8"], readonly ["stdoutWriteTimeValid", "bool_u8"]], {}>; +export type GrowthPolicy = "grow" | "block"; +export type NativeSpanFeedOptions = { + chunkSize?: number; + initialChunks?: number; + maxBytes?: bigint; + growthPolicy?: GrowthPolicy; + autoCommitOnFull?: boolean; + spanQueueCapacity?: number; +}; +export type NativeSpanFeedStats = { + bytesWritten: bigint; + spansCommitted: bigint; + chunks: number; + pendingSpans: number; +}; +export type SpanInfo = { + chunkPtr: Pointer; + offset: number; + len: number; + chunkIndex: number; +}; +export type ReserveInfo = { + ptr: Pointer; + len: number; +}; +export declare const NativeSpanFeedOptionsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["chunkSize", "u32", { + readonly default: number; +}], readonly ["initialChunks", "u32", { + readonly default: 2; +}], readonly ["maxBytes", "u64", { + readonly default: 0n; +}], readonly ["growthPolicy", import("bun-ffi-structs").EnumDef<{ + grow: number; + block: number; +}>, { + readonly default: "grow"; +}], readonly ["autoCommitOnFull", "bool_u8", { + readonly default: true; +}], readonly ["spanQueueCapacity", "u32", { + readonly default: 0; +}]], {}>; +export declare const NativeSpanFeedStatsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["bytesWritten", "u64"], readonly ["spansCommitted", "u64"], readonly ["chunks", "u32"], readonly ["pendingSpans", "u32"]], {}>; +export declare const SpanInfoStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["chunkPtr", "pointer"], readonly ["offset", "u32"], readonly ["len", "u32"], readonly ["chunkIndex", "u32"], readonly ["reserved", "u32", { + readonly default: 0; +}]], { + readonly reduceValue: (value: { + chunkPtr: Pointer; + offset: number; + len: number; + chunkIndex: number; + }) => { + chunkPtr: Pointer; + offset: number; + len: number; + chunkIndex: number; + }; +}>; +export declare const ReserveInfoStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["ptr", "pointer"], readonly ["len", "u32"], readonly ["reserved", "u32", { + readonly default: 0; +}]], { + readonly reduceValue: (value: { + ptr: Pointer; + len: number; + }) => { + ptr: Pointer; + len: number; + }; +}>; +export type AudioCreateOptions = { + sampleRate?: number; + playbackChannels?: number; +}; +export type AudioStartOptions = { + periodSizeInFrames?: number; + periodSizeInMilliseconds?: number; + periods?: number; + performanceProfile?: number; + shareMode?: number; + noPreSilencedOutputBuffer?: boolean; + noClip?: boolean; + noDisableDenormals?: boolean; + noFixedSizedCallback?: boolean; + wasapiNoAutoConvertSrc?: boolean; + wasapiNoDefaultQualitySrc?: boolean; + alsaNoMMap?: boolean; + alsaNoAutoFormat?: boolean; + alsaNoAutoChannels?: boolean; + alsaNoAutoResample?: boolean; +}; +export type AudioVoiceOptions = { + volume?: number; + pan?: number; + loop?: boolean; + groupId?: number; +}; +export type AudioStats = { + soundsLoaded: number; + voicesActive: number; + framesMixed: bigint; + lockMisses: number; + lastPeak: number; + lastRms: number; +}; +export declare const AudioCreateOptionsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["sampleRate", "u32", { + readonly default: 48000; +}], readonly ["playbackChannels", "u32", { + readonly default: 2; +}]], {}>; +export declare const AudioStartOptionsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["periodSizeInFrames", "u32", { + readonly default: 0; +}], readonly ["periodSizeInMilliseconds", "u32", { + readonly default: 0; +}], readonly ["periods", "u32", { + readonly default: 0; +}], readonly ["performanceProfile", "u8", { + readonly default: 0; +}], readonly ["shareMode", "u8", { + readonly default: 0; +}], readonly ["noPreSilencedOutputBuffer", "bool_u8", { + readonly default: false; +}], readonly ["noClip", "bool_u8", { + readonly default: false; +}], readonly ["noDisableDenormals", "bool_u8", { + readonly default: false; +}], readonly ["noFixedSizedCallback", "bool_u8", { + readonly default: false; +}], readonly ["wasapiNoAutoConvertSrc", "bool_u8", { + readonly default: false; +}], readonly ["wasapiNoDefaultQualitySrc", "bool_u8", { + readonly default: false; +}], readonly ["alsaNoMMap", "bool_u8", { + readonly default: false; +}], readonly ["alsaNoAutoFormat", "bool_u8", { + readonly default: false; +}], readonly ["alsaNoAutoChannels", "bool_u8", { + readonly default: false; +}], readonly ["alsaNoAutoResample", "bool_u8", { + readonly default: false; +}]], {}>; +export declare const AudioVoiceOptionsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["volume", "f32", { + readonly default: 1; +}], readonly ["pan", "f32", { + readonly default: 0; +}], readonly ["loop", "bool_u8", { + readonly default: false; +}], readonly ["groupId", "u32", { + readonly default: 0; +}]], {}>; +export declare const AudioStatsStruct: import("bun-ffi-structs").DefineStructReturnType<[readonly ["soundsLoaded", "u32"], readonly ["voicesActive", "u32"], readonly ["framesMixed", "u64"], readonly ["lockMisses", "u32"], readonly ["lastPeak", "f32"], readonly ["lastRms", "f32"]], {}>; +export {}; diff --git a/.patches/@opentui/core/zig.d.ts b/.patches/@opentui/core/zig.d.ts new file mode 100644 --- /dev/null +++ b/.patches/@opentui/core/zig.d.ts @@ -0,0 +1,482 @@ +import { type FFICallbackInstance, type Pointer } from "./platform/ffi.js"; +import { type CursorStyle, type CursorStyleOptions, type TargetChannel, type DebugOverlayCorner, type WidthMethod, type TerminalCapabilities, type Highlight, type LineInfo } from "./types.js"; +export type { LineInfo, AllocatorStats, BuildOptions, NativeRenderStats }; +import { RGBA } from "./lib/RGBA.js"; +import { OptimizedBuffer } from "./buffer.js"; +import { TextBuffer } from "./text-buffer.js"; +import type { NativeSpanFeedOptions, NativeSpanFeedStats, ReserveInfo, AudioCreateOptions, AudioStartOptions, AudioVoiceOptions, AudioStats, BuildOptions, AllocatorStats, NativeRenderStats } from "./zig-structs.js"; +export type NativeHandle = Pointer & { + readonly __nativeHandle: T; +}; +export type RendererHandle = NativeHandle<"renderer">; +export type OptimizedBufferHandle = NativeHandle<"optimized_buffer">; +export type TextBufferHandle = NativeHandle<"text_buffer">; +export type TextBufferViewHandle = NativeHandle<"text_buffer_view">; +export type EditBufferHandle = NativeHandle<"edit_buffer">; +export type EditorViewHandle = NativeHandle<"editor_view">; +export type SyntaxStyleHandle = NativeHandle<"syntax_style">; +export type EventSinkHandle = NativeHandle<"event_sink">; +export type AudioEngineHandle = NativeHandle<"audio_engine">; +export declare enum LogLevel { + Error = 0, + Warn = 1, + Info = 2, + Debug = 3 +} +/** + * VisualCursor represents a cursor position with both visual and logical coordinates. + * Visual coordinates (visualRow, visualCol) are VIEWPORT-RELATIVE. + * This means visualRow=0 is the first visible line in the viewport, not the first line in the document. + * Logical coordinates (logicalRow, logicalCol) are document-absolute. + */ +export interface VisualCursor { + visualRow: number; + visualCol: number; + logicalRow: number; + logicalCol: number; + offset: number; +} +export interface LogicalCursor { + row: number; + col: number; + offset: number; +} +export interface CursorState { + x: number; + y: number; + visible: boolean; + style: CursorStyle; + blinking: boolean; + color: RGBA; +} +export type NativeSpanFeedEventHandler = (eventId: number, arg0: Pointer, arg1: number | bigint) => void; +export type NativeBufferedOutput = "stdout" | "memory"; +export interface NativeRendererCreateOptions { + remote?: boolean; + feedPtr?: Pointer | null; + bufferedOutput?: NativeBufferedOutput; +} +export interface NativeRenderOperationResult { + renderOffset: number; + status: number; +} +export interface NativeYogaLayout { + left: number; + top: number; + right: number; + bottom: number; + width: number; + height: number; +} +export type NativeYogaMeasureCallback = (node: Pointer | null, width: number, widthMode: number, height: number, heightMode: number) => void; +export type NativeYogaDirtiedCallback = () => void; +export interface AudioEngineLib { + createAudioEngine: (options?: AudioCreateOptions | null) => AudioEngineHandle | null; + destroyAudioEngine: (engine: AudioEngineHandle) => void; + audioRefreshPlaybackDevices: (engine: AudioEngineHandle) => number; + audioGetPlaybackDeviceCount: (engine: AudioEngineHandle) => number; + audioGetPlaybackDeviceName: (engine: AudioEngineHandle, index: number) => string; + audioIsPlaybackDeviceDefault: (engine: AudioEngineHandle, index: number) => boolean; + audioSelectPlaybackDevice: (engine: AudioEngineHandle, index: number) => number; + audioClearPlaybackDeviceSelection: (engine: AudioEngineHandle) => void; + audioStart: (engine: AudioEngineHandle, options?: AudioStartOptions | null) => number; + audioStartMixer: (engine: AudioEngineHandle) => number; + audioStop: (engine: AudioEngineHandle) => number; + audioLoad: (engine: AudioEngineHandle, data: Uint8Array) => { + status: number; + soundId: number | null; + }; + audioUnload: (engine: AudioEngineHandle, soundId: number) => number; + audioPlay: (engine: AudioEngineHandle, soundId: number, options?: AudioVoiceOptions) => { + status: number; + voiceId: number | null; + }; + audioStopVoice: (engine: AudioEngineHandle, voiceId: number) => number; + audioSetVoiceGroup: (engine: AudioEngineHandle, voiceId: number, groupId: number) => number; + audioCreateGroup: (engine: AudioEngineHandle, name: string) => { + status: number; + groupId: number | null; + }; + audioSetGroupVolume: (engine: AudioEngineHandle, groupId: number, volume: number) => number; + audioSetMasterVolume: (engine: AudioEngineHandle, volume: number) => number; + audioMixToBuffer: (engine: AudioEngineHandle, outBuffer: Float32Array, frameCount: number, channels: number) => number; + audioEnableTap: (engine: AudioEngineHandle, enabled: boolean, capacityFrames: number) => number; + audioReadTap: (engine: AudioEngineHandle, outBuffer: Float32Array, frameCount: number, channels: number) => { + status: number; + framesRead: number; + }; + audioGetStats: (engine: AudioEngineHandle) => AudioStats | null; +} +export interface RenderLib extends AudioEngineLib { + createRenderer: (width: number, height: number, options?: NativeRendererCreateOptions) => RendererHandle | null; + setTerminalEnvVar: (renderer: RendererHandle, key: string, value: string) => boolean; + destroyRenderer: (renderer: RendererHandle) => void; + setUseThread: (renderer: RendererHandle, useThread: boolean) => void; + setClearOnShutdown: (renderer: RendererHandle, clear: boolean) => void; + setBackgroundColor: (renderer: RendererHandle, color: RGBA) => void; + setRenderOffset: (renderer: RendererHandle, offset: number) => void; + resetSplitScrollback: (renderer: RendererHandle, seedRows: number, pinnedRenderOffset: number) => number; + syncSplitScrollback: (renderer: RendererHandle, pinnedRenderOffset: number) => number; + getSplitOutputOffset: (renderer: RendererHandle, surfaceOffset: number) => number; + setPendingSplitFooterTransition: (renderer: RendererHandle, mode: number, sourceTopLine: number, sourceHeight: number, targetTopLine: number, targetHeight: number, scrollLines: number) => void; + clearPendingSplitFooterTransition: (renderer: RendererHandle) => void; + updateStats: (renderer: RendererHandle, time: number, fps: number, frameCallbackTime: number) => void; + updateMemoryStats: (renderer: RendererHandle, heapUsed: number, heapTotal: number, arrayBuffers: number) => void; + getRenderStats: (renderer: RendererHandle) => NativeRenderStats; + render: (renderer: RendererHandle, force: boolean) => number; + repaintSplitFooter: (renderer: RendererHandle, pinnedRenderOffset: number, force: boolean) => NativeRenderOperationResult; + commitSplitFooterSnapshot: (renderer: RendererHandle, snapshot: OptimizedBuffer, rowColumns: number, startOnNewLine: boolean, trailingNewline: boolean, pinnedRenderOffset: number, force: boolean, beginFrame?: boolean, finalizeFrame?: boolean) => NativeRenderOperationResult; + getNextBuffer: (renderer: RendererHandle) => OptimizedBuffer; + getCurrentBuffer: (renderer: RendererHandle) => OptimizedBuffer; + rendererSetPaletteState: (renderer: RendererHandle, palette: readonly RGBA[], defaultForeground: RGBA, defaultBackground: RGBA, paletteEpoch: number) => void; + createOptimizedBuffer: (width: number, height: number, widthMethod: WidthMethod, respectAlpha?: boolean, id?: string) => OptimizedBuffer; + destroyOptimizedBuffer: (bufferPtr: OptimizedBufferHandle) => void; + drawFrameBuffer: (targetBufferPtr: OptimizedBufferHandle, destX: number, destY: number, bufferPtr: OptimizedBufferHandle, sourceX?: number, sourceY?: number, sourceWidth?: number, sourceHeight?: number) => void; + getBufferWidth: (buffer: OptimizedBufferHandle) => number; + getBufferHeight: (buffer: OptimizedBufferHandle) => number; + bufferClear: (buffer: OptimizedBufferHandle, color: RGBA) => void; + bufferGetCharPtr: (buffer: OptimizedBufferHandle) => Pointer; + bufferGetFgPtr: (buffer: OptimizedBufferHandle) => Pointer; + bufferGetBgPtr: (buffer: OptimizedBufferHandle) => Pointer; + bufferGetAttributesPtr: (buffer: OptimizedBufferHandle) => Pointer; + bufferGetRespectAlpha: (buffer: OptimizedBufferHandle) => boolean; + bufferSetRespectAlpha: (buffer: OptimizedBufferHandle, respectAlpha: boolean) => void; + bufferGetId: (buffer: OptimizedBufferHandle) => string; + bufferGetRealCharSize: (buffer: OptimizedBufferHandle) => number; + bufferWriteResolvedChars: (buffer: OptimizedBufferHandle, outputBuffer: Uint8Array, addLineBreaks: boolean) => number; + bufferDrawText: (buffer: OptimizedBufferHandle, text: string, x: number, y: number, color: RGBA, bgColor?: RGBA, attributes?: number) => void; + bufferSetCellWithAlphaBlending: (buffer: OptimizedBufferHandle, x: number, y: number, char: string, color: RGBA, bgColor: RGBA, attributes?: number) => void; + bufferSetCell: (buffer: OptimizedBufferHandle, x: number, y: number, char: string, color: RGBA, bgColor: RGBA, attributes?: number) => void; + bufferFillRect: (buffer: OptimizedBufferHandle, x: number, y: number, width: number, height: number, color: RGBA) => void; + bufferColorMatrix: (buffer: OptimizedBufferHandle, matrixPtr: Pointer, cellMaskPtr: Pointer, cellMaskCount: number, strength: number, target: TargetChannel) => void; + bufferColorMatrixUniform: (buffer: OptimizedBufferHandle, matrixPtr: Pointer, strength: number, target: TargetChannel) => void; + bufferDrawSuperSampleBuffer: (buffer: OptimizedBufferHandle, x: number, y: number, pixelDataPtr: Pointer, pixelDataLength: number, format: "bgra8unorm" | "rgba8unorm", alignedBytesPerRow: number) => void; + bufferDrawPackedBuffer: (buffer: OptimizedBufferHandle, dataPtr: Pointer, dataLen: number, posX: number, posY: number, terminalWidthCells: number, terminalHeightCells: number) => void; + bufferDrawGrayscaleBuffer: (buffer: OptimizedBufferHandle, posX: number, posY: number, intensitiesPtr: Pointer, srcWidth: number, srcHeight: number, fg: RGBA | null, bg: RGBA | null) => void; + bufferDrawGrayscaleBufferSupersampled: (buffer: OptimizedBufferHandle, posX: number, posY: number, intensitiesPtr: Pointer, srcWidth: number, srcHeight: number, fg: RGBA | null, bg: RGBA | null) => void; + bufferDrawGrid: (buffer: OptimizedBufferHandle, borderChars: Uint32Array, borderFg: RGBA, borderBg: RGBA, columnOffsets: Int32Array, columnCount: number, rowOffsets: Int32Array, rowCount: number, options: { + drawInner: boolean; + drawOuter: boolean; + }) => void; + bufferDrawBox: (buffer: OptimizedBufferHandle, x: number, y: number, width: number, height: number, borderChars: Uint32Array, packedOptions: number, borderColor: RGBA, backgroundColor: RGBA, titleColor: RGBA, title: string | null, bottomTitle: string | null) => void; + bufferResize: (buffer: OptimizedBufferHandle, width: number, height: number) => void; + resizeRenderer: (renderer: RendererHandle, width: number, height: number) => void; + setCursorPosition: (renderer: RendererHandle, x: number, y: number, visible: boolean) => void; + setCursorColor: (renderer: RendererHandle, color: RGBA) => void; + getCursorState: (renderer: RendererHandle) => CursorState; + setCursorStyleOptions: (renderer: RendererHandle, options: CursorStyleOptions) => void; + setDebugOverlay: (renderer: RendererHandle, enabled: boolean, corner: DebugOverlayCorner) => void; + clearTerminal: (renderer: RendererHandle) => void; + setTerminalTitle: (renderer: RendererHandle, title: string) => void; + copyToClipboardOSC52: (renderer: RendererHandle, target: number, payload: Uint8Array) => boolean; + clearClipboardOSC52: (renderer: RendererHandle, target: number) => boolean; + triggerNotification: (renderer: RendererHandle, message: string, title?: string) => boolean; + addToHitGrid: (renderer: RendererHandle, x: number, y: number, width: number, height: number, id: number) => void; + clearCurrentHitGrid: (renderer: RendererHandle) => void; + hitGridPushScissorRect: (renderer: RendererHandle, x: number, y: number, width: number, height: number) => void; + hitGridPopScissorRect: (renderer: RendererHandle) => void; + hitGridClearScissorRects: (renderer: RendererHandle) => void; + addToCurrentHitGridClipped: (renderer: RendererHandle, x: number, y: number, width: number, height: number, id: number) => void; + checkHit: (renderer: RendererHandle, x: number, y: number) => number; + getHitGridDirty: (renderer: RendererHandle) => boolean; + dumpHitGrid: (renderer: RendererHandle) => void; + dumpBuffers: (renderer: RendererHandle, timestamp?: number) => void; + dumpOutputBuffer: (renderer: RendererHandle, timestamp?: number) => void; + restoreTerminalModes: (renderer: RendererHandle) => void; + enableMouse: (renderer: RendererHandle, enableMovement: boolean) => void; + disableMouse: (renderer: RendererHandle) => void; + enableKittyKeyboard: (renderer: RendererHandle, flags: number) => void; + disableKittyKeyboard: (renderer: RendererHandle) => void; + setKittyKeyboardFlags: (renderer: RendererHandle, flags: number) => void; + getKittyKeyboardFlags: (renderer: RendererHandle) => number; + setupTerminal: (renderer: RendererHandle, useAlternateScreen: boolean) => void; + suspendRenderer: (renderer: RendererHandle) => void; + resumeRenderer: (renderer: RendererHandle) => void; + queryPixelResolution: (renderer: RendererHandle) => void; + queryThemeColors: (renderer: RendererHandle) => void; + writeOut: (renderer: RendererHandle, data: string | Uint8Array) => void; + yogaConfigCreate: () => Pointer; + yogaConfigFree: (config: Pointer) => void; + yogaConfigSetUseWebDefaults: (config: Pointer, enabled: boolean) => void; + yogaConfigGetUseWebDefaults: (config: Pointer) => boolean; + yogaConfigSetPointScaleFactor: (config: Pointer, pointScaleFactor: number) => void; + yogaConfigGetPointScaleFactor: (config: Pointer) => number; + yogaConfigSetErrata: (config: Pointer, errata: number) => void; + yogaConfigGetErrata: (config: Pointer) => number; + yogaConfigSetExperimentalFeatureEnabled: (config: Pointer, feature: number, enabled: boolean) => void; + yogaConfigIsExperimentalFeatureEnabled: (config: Pointer, feature: number) => boolean; + yogaNodeCreate: () => Pointer; + yogaNodeCreateForOpenTUI: () => Pointer; + yogaNodeCreateWithConfig: (config: Pointer) => Pointer; + yogaNodeFree: (node: Pointer) => void; + yogaNodeFreeRecursive: (node: Pointer) => void; + yogaNodeReset: (node: Pointer) => void; + yogaNodeCopyStyle: (dstNode: Pointer, srcNode: Pointer) => void; + yogaNodeInsertChild: (node: Pointer, child: Pointer, index: number) => void; + yogaNodeRemoveChild: (node: Pointer, child: Pointer) => void; + yogaNodeRemoveAllChildren: (node: Pointer) => void; + yogaNodeGetChild: (node: Pointer, index: number) => Pointer | null; + yogaNodeGetChildCount: (node: Pointer) => number; + yogaNodeGetParent: (node: Pointer) => Pointer | null; + yogaNodeCalculateLayout: (node: Pointer, width: number, height: number, direction: number) => void; + yogaNodeIsDirty: (node: Pointer) => boolean; + yogaNodeMarkDirty: (node: Pointer) => void; + yogaNodeGetHasNewLayout: (node: Pointer) => boolean; + yogaNodeSetHasNewLayout: (node: Pointer, hasNewLayout: boolean) => void; + yogaNodeSetIsReferenceBaseline: (node: Pointer, isReferenceBaseline: boolean) => void; + yogaNodeIsReferenceBaseline: (node: Pointer) => boolean; + yogaNodeSetAlwaysFormsContainingBlock: (node: Pointer, alwaysFormsContainingBlock: boolean) => void; + yogaNodeGetAlwaysFormsContainingBlock: (node: Pointer) => boolean; + yogaNodeGetComputedLayout: (node: Pointer) => NativeYogaLayout; + yogaNodeLayoutGetEdge: (node: Pointer, kind: number, edge: number) => number; + yogaNodeStyleSetEnum: (node: Pointer, kind: number, value: number) => void; + yogaNodeStyleGetEnum: (node: Pointer, kind: number) => number; + yogaNodeStyleSetFloat: (node: Pointer, kind: number, value: number) => void; + yogaNodeStyleGetFloat: (node: Pointer, kind: number) => number; + yogaNodeStyleSetBorder: (node: Pointer, edge: number, border: number) => void; + yogaNodeStyleGetBorder: (node: Pointer, edge: number) => number; + yogaNodeStyleSetValue: (node: Pointer, kind: number, edgeOrGutter: number, unit: number, value: number) => void; + yogaNodeStyleGetValue: (node: Pointer, kind: number, edgeOrGutter: number) => number | bigint; + yogaNodeSetMeasureFunc: (node: Pointer, callback: Pointer | null) => void; + yogaNodeUnsetMeasureFunc: (node: Pointer) => void; + yogaNodeHasMeasureFunc: (node: Pointer) => boolean; + yogaNodeSetDirtiedFunc: (node: Pointer, callback: Pointer | null) => void; + yogaNodeUnsetDirtiedFunc: (node: Pointer) => void; + yogaStoreMeasureResult: (width: number, height: number) => void; + createYogaMeasureCallback: (callback: NativeYogaMeasureCallback) => FFICallbackInstance; + createYogaDirtiedCallback: (callback: NativeYogaDirtiedCallback) => FFICallbackInstance; + createTextBuffer: (widthMethod: WidthMethod) => TextBuffer; + destroyTextBuffer: (buffer: TextBufferHandle) => void; + textBufferGetLength: (buffer: TextBufferHandle) => number; + textBufferGetByteSize: (buffer: TextBufferHandle) => number; + textBufferReset: (buffer: TextBufferHandle) => void; + textBufferClear: (buffer: TextBufferHandle) => void; + textBufferRegisterMemBuffer: (buffer: TextBufferHandle, bytes: Uint8Array, owned?: boolean) => number; + textBufferReplaceMemBuffer: (buffer: TextBufferHandle, memId: number, bytes: Uint8Array, owned?: boolean) => boolean; + textBufferClearMemRegistry: (buffer: TextBufferHandle) => void; + textBufferSetTextFromMem: (buffer: TextBufferHandle, memId: number) => void; + textBufferAppend: (buffer: TextBufferHandle, bytes: Uint8Array) => void; + textBufferAppendFromMemId: (buffer: TextBufferHandle, memId: number) => void; + textBufferLoadFile: (buffer: TextBufferHandle, path: string) => boolean; + textBufferSetStyledText: (buffer: TextBufferHandle, chunks: Array<{ + text: string; + fg?: RGBA | null; + bg?: RGBA | null; + attributes?: number; + link?: { + url: string; + }; + }>) => void; + textBufferSetDefaultFg: (buffer: TextBufferHandle, fg: RGBA | null) => void; + textBufferSetDefaultBg: (buffer: TextBufferHandle, bg: RGBA | null) => void; + textBufferSetDefaultAttributes: (buffer: TextBufferHandle, attributes: number | null) => void; + textBufferResetDefaults: (buffer: TextBufferHandle) => void; + textBufferGetTabWidth: (buffer: TextBufferHandle) => number; + textBufferSetTabWidth: (buffer: TextBufferHandle, width: number) => void; + textBufferGetLineCount: (buffer: TextBufferHandle) => number; + getPlainTextBytes: (buffer: TextBufferHandle, maxLength: number) => Uint8Array | null; + textBufferGetTextRange: (buffer: TextBufferHandle, startOffset: number, endOffset: number, maxLength: number) => Uint8Array | null; + textBufferGetTextRangeByCoords: (buffer: TextBufferHandle, startRow: number, startCol: number, endRow: number, endCol: number, maxLength: number) => Uint8Array | null; + createTextBufferView: (textBuffer: TextBufferHandle) => TextBufferViewHandle; + destroyTextBufferView: (view: TextBufferViewHandle) => void; + textBufferViewSetSelection: (view: TextBufferViewHandle, start: number, end: number, bgColor: RGBA | null, fgColor: RGBA | null) => void; + textBufferViewResetSelection: (view: TextBufferViewHandle) => void; + textBufferViewGetSelection: (view: TextBufferViewHandle) => { + start: number; + end: number; + } | null; + textBufferViewSetLocalSelection: (view: TextBufferViewHandle, anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor: RGBA | null, fgColor: RGBA | null) => boolean; + textBufferViewUpdateSelection: (view: TextBufferViewHandle, end: number, bgColor: RGBA | null, fgColor: RGBA | null) => void; + textBufferViewUpdateLocalSelection: (view: TextBufferViewHandle, anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor: RGBA | null, fgColor: RGBA | null) => boolean; + textBufferViewResetLocalSelection: (view: TextBufferViewHandle) => void; + textBufferViewSetWrapWidth: (view: TextBufferViewHandle, width: number) => void; + textBufferViewSetWrapMode: (view: TextBufferViewHandle, mode: "none" | "char" | "word") => void; + textBufferViewSetFirstLineOffset: (view: TextBufferViewHandle, offset: number) => void; + textBufferViewSetViewportSize: (view: TextBufferViewHandle, width: number, height: number) => void; + textBufferViewSetViewport: (view: TextBufferViewHandle, x: number, y: number, width: number, height: number) => void; + textBufferViewGetLineInfo: (view: TextBufferViewHandle) => LineInfo; + textBufferViewGetLogicalLineInfo: (view: TextBufferViewHandle) => LineInfo; + textBufferViewGetSelectedTextBytes: (view: TextBufferViewHandle, maxLength: number) => Uint8Array | null; + textBufferViewGetPlainTextBytes: (view: TextBufferViewHandle, maxLength: number) => Uint8Array | null; + textBufferViewSetTabIndicator: (view: TextBufferViewHandle, indicator: number) => void; + textBufferViewSetTabIndicatorColor: (view: TextBufferViewHandle, color: RGBA) => void; + textBufferViewSetTruncate: (view: TextBufferViewHandle, truncate: boolean) => void; + textBufferViewMeasureForDimensions: (view: TextBufferViewHandle, width: number, height: number) => { + lineCount: number; + widthColsMax: number; + } | null; + textBufferViewGetVirtualLineCount: (view: TextBufferViewHandle) => number; + readonly encoder: TextEncoder; + readonly decoder: TextDecoder; + bufferDrawTextBufferView: (buffer: OptimizedBufferHandle, view: TextBufferViewHandle, x: number, y: number) => void; + bufferDrawEditorView: (buffer: OptimizedBufferHandle, view: EditorViewHandle, x: number, y: number) => void; + createEditBuffer: (widthMethod: WidthMethod) => EditBufferHandle; + destroyEditBuffer: (buffer: EditBufferHandle) => void; + editBufferSetText: (buffer: EditBufferHandle, textBytes: Uint8Array) => void; + editBufferSetTextFromMem: (buffer: EditBufferHandle, memId: number) => void; + editBufferReplaceText: (buffer: EditBufferHandle, textBytes: Uint8Array) => void; + editBufferReplaceTextFromMem: (buffer: EditBufferHandle, memId: number) => void; + editBufferGetText: (buffer: EditBufferHandle, maxLength: number) => Uint8Array | null; + editBufferInsertChar: (buffer: EditBufferHandle, char: string) => void; + editBufferInsertText: (buffer: EditBufferHandle, text: string) => void; + editBufferDeleteChar: (buffer: EditBufferHandle) => void; + editBufferDeleteCharBackward: (buffer: EditBufferHandle) => void; + editBufferDeleteRange: (buffer: EditBufferHandle, startLine: number, startCol: number, endLine: number, endCol: number) => void; + editBufferNewLine: (buffer: EditBufferHandle) => void; + editBufferDeleteLine: (buffer: EditBufferHandle) => void; + editBufferMoveCursorLeft: (buffer: EditBufferHandle) => void; + editBufferMoveCursorRight: (buffer: EditBufferHandle) => void; + editBufferMoveCursorUp: (buffer: EditBufferHandle) => void; + editBufferMoveCursorDown: (buffer: EditBufferHandle) => void; + editBufferGotoLine: (buffer: EditBufferHandle, line: number) => void; + editBufferSetCursor: (buffer: EditBufferHandle, line: number, col: number) => void; + editBufferSetCursorToLineCol: (buffer: EditBufferHandle, line: number, col: number) => void; + editBufferSetCursorByOffset: (buffer: EditBufferHandle, offset: number) => void; + editBufferGetCursorPosition: (buffer: EditBufferHandle) => LogicalCursor; + editBufferGetId: (buffer: EditBufferHandle) => number; + editBufferGetTextBuffer: (buffer: EditBufferHandle) => TextBufferHandle; + editBufferDebugLogRope: (buffer: EditBufferHandle) => void; + editBufferUndo: (buffer: EditBufferHandle, maxLength: number) => Uint8Array | null; + editBufferRedo: (buffer: EditBufferHandle, maxLength: number) => Uint8Array | null; + editBufferCanUndo: (buffer: EditBufferHandle) => boolean; + editBufferCanRedo: (buffer: EditBufferHandle) => boolean; + editBufferClearHistory: (buffer: EditBufferHandle) => void; + editBufferClear: (buffer: EditBufferHandle) => void; + editBufferGetNextWordBoundary: (buffer: EditBufferHandle) => { + row: number; + col: number; + offset: number; + }; + editBufferGetPrevWordBoundary: (buffer: EditBufferHandle) => { + row: number; + col: number; + offset: number; + }; + editBufferGetEOL: (buffer: EditBufferHandle) => { + row: number; + col: number; + offset: number; + }; + editBufferOffsetToPosition: (buffer: EditBufferHandle, offset: number) => { + row: number; + col: number; + offset: number; + } | null; + editBufferPositionToOffset: (buffer: EditBufferHandle, row: number, col: number) => number; + editBufferGetLineStartOffset: (buffer: EditBufferHandle, row: number) => number; + editBufferGetTextRange: (buffer: EditBufferHandle, startOffset: number, endOffset: number, maxLength: number) => Uint8Array | null; + editBufferGetTextRangeByCoords: (buffer: EditBufferHandle, startRow: number, startCol: number, endRow: number, endCol: number, maxLength: number) => Uint8Array | null; + createEditorView: (editBufferPtr: EditBufferHandle, viewportWidth: number, viewportHeight: number) => EditorViewHandle; + destroyEditorView: (view: EditorViewHandle) => void; + editorViewSetViewportSize: (view: EditorViewHandle, width: number, height: number) => void; + editorViewSetViewport: (view: EditorViewHandle, x: number, y: number, width: number, height: number, moveCursor: boolean) => void; + editorViewGetViewport: (view: EditorViewHandle) => { + offsetY: number; + offsetX: number; + height: number; + width: number; + }; + editorViewSetScrollMargin: (view: EditorViewHandle, margin: number) => void; + editorViewSetWrapMode: (view: EditorViewHandle, mode: "none" | "char" | "word") => void; + editorViewGetVirtualLineCount: (view: EditorViewHandle) => number; + editorViewGetTotalVirtualLineCount: (view: EditorViewHandle) => number; + editorViewGetTextBufferView: (view: EditorViewHandle) => TextBufferViewHandle; + editorViewSetSelection: (view: EditorViewHandle, start: number, end: number, bgColor: RGBA | null, fgColor: RGBA | null) => void; + editorViewResetSelection: (view: EditorViewHandle) => void; + editorViewGetSelection: (view: EditorViewHandle) => { + start: number; + end: number; + } | null; + editorViewSetLocalSelection: (view: EditorViewHandle, anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor: RGBA | null, fgColor: RGBA | null, updateCursor: boolean, followCursor: boolean) => boolean; + editorViewUpdateSelection: (view: EditorViewHandle, end: number, bgColor: RGBA | null, fgColor: RGBA | null) => void; + editorViewUpdateLocalSelection: (view: EditorViewHandle, anchorX: number, anchorY: number, focusX: number, focusY: number, bgColor: RGBA | null, fgColor: RGBA | null, updateCursor: boolean, followCursor: boolean) => boolean; + editorViewResetLocalSelection: (view: EditorViewHandle) => void; + editorViewGetSelectedTextBytes: (view: EditorViewHandle, maxLength: number) => Uint8Array | null; + editorViewGetCursor: (view: EditorViewHandle) => { + row: number; + col: number; + }; + editorViewGetText: (view: EditorViewHandle, maxLength: number) => Uint8Array | null; + editorViewGetVisualCursor: (view: EditorViewHandle) => VisualCursor; + editorViewMoveUpVisual: (view: EditorViewHandle) => void; + editorViewMoveDownVisual: (view: EditorViewHandle) => void; + editorViewDeleteSelectedText: (view: EditorViewHandle) => void; + editorViewSetCursorByOffset: (view: EditorViewHandle, offset: number) => void; + editorViewGetNextWordBoundary: (view: EditorViewHandle) => VisualCursor; + editorViewGetPrevWordBoundary: (view: EditorViewHandle) => VisualCursor; + editorViewGetEOL: (view: EditorViewHandle) => VisualCursor; + editorViewGetVisualSOL: (view: EditorViewHandle) => VisualCursor; + editorViewGetVisualEOL: (view: EditorViewHandle) => VisualCursor; + editorViewGetLineInfo: (view: EditorViewHandle) => LineInfo; + editorViewGetLogicalLineInfo: (view: EditorViewHandle) => LineInfo; + editorViewSetPlaceholderStyledText: (view: EditorViewHandle, chunks: Array<{ + text: string; + fg?: RGBA | null; + bg?: RGBA | null; + attributes?: number; + }>) => void; + editorViewSetTabIndicator: (view: EditorViewHandle, indicator: number) => void; + editorViewSetTabIndicatorColor: (view: EditorViewHandle, color: RGBA) => void; + bufferPushScissorRect: (buffer: OptimizedBufferHandle, x: number, y: number, width: number, height: number) => void; + bufferPopScissorRect: (buffer: OptimizedBufferHandle) => void; + bufferClearScissorRects: (buffer: OptimizedBufferHandle) => void; + bufferPushOpacity: (buffer: OptimizedBufferHandle, opacity: number) => void; + bufferPopOpacity: (buffer: OptimizedBufferHandle) => void; + bufferGetCurrentOpacity: (buffer: OptimizedBufferHandle) => number; + bufferClearOpacity: (buffer: OptimizedBufferHandle) => void; + textBufferAddHighlightByCharRange: (buffer: TextBufferHandle, highlight: Highlight) => void; + textBufferAddHighlight: (buffer: TextBufferHandle, lineIdx: number, highlight: Highlight) => void; + textBufferRemoveHighlightsByRef: (buffer: TextBufferHandle, hlRef: number) => void; + textBufferClearLineHighlights: (buffer: TextBufferHandle, lineIdx: number) => void; + textBufferClearAllHighlights: (buffer: TextBufferHandle) => void; + textBufferSetSyntaxStyle: (buffer: TextBufferHandle, style: SyntaxStyleHandle | null) => boolean; + textBufferGetLineHighlights: (buffer: TextBufferHandle, lineIdx: number) => Array; + textBufferGetHighlightCount: (buffer: TextBufferHandle) => number; + getArenaAllocatedBytes: () => number; + getBuildOptions: () => BuildOptions; + getAllocatorStats: () => AllocatorStats; + createSyntaxStyle: () => SyntaxStyleHandle; + destroySyntaxStyle: (style: SyntaxStyleHandle) => void; + syntaxStyleRegister: (style: SyntaxStyleHandle, name: string, fg: RGBA | null, bg: RGBA | null, attributes: number) => number; + syntaxStyleResolveByName: (style: SyntaxStyleHandle, name: string) => number | null; + syntaxStyleGetStyleCount: (style: SyntaxStyleHandle) => number; + getTerminalCapabilities: (renderer: RendererHandle) => TerminalCapabilities; + processCapabilityResponse: (renderer: RendererHandle, response: string) => void; + encodeUnicode: (text: string, widthMethod: WidthMethod) => { + ptr: Pointer; + data: Array<{ + width: number; + char: number; + }>; + } | null; + freeUnicode: (encoded: { + ptr: Pointer; + data: Array<{ + width: number; + char: number; + }>; + }) => void; + bufferDrawChar: (buffer: OptimizedBufferHandle, char: number, x: number, y: number, fg: RGBA, bg: RGBA, attributes?: number) => void; + registerNativeSpanFeedStream: (stream: Pointer, handler: NativeSpanFeedEventHandler) => void; + unregisterNativeSpanFeedStream: (stream: Pointer) => void; + createNativeSpanFeed: (options?: NativeSpanFeedOptions | null) => Pointer; + attachNativeSpanFeed: (stream: Pointer) => number; + destroyNativeSpanFeed: (stream: Pointer) => void; + streamWrite: (stream: Pointer, data: Uint8Array | string) => number; + streamCommit: (stream: Pointer) => number; + streamDrainSpans: (stream: Pointer, outBuffer: Uint8Array, maxSpans: number) => number; + streamClose: (stream: Pointer) => number; + streamSetOptions: (stream: Pointer, options: NativeSpanFeedOptions) => number; + streamGetStats: (stream: Pointer) => NativeSpanFeedStats | null; + streamReserve: (stream: Pointer, minLen: number) => { + status: number; + info: ReserveInfo | null; + }; + streamCommitReserved: (stream: Pointer, length: number) => number; + onNativeEvent: (name: string, handler: (data: ArrayBuffer) => void) => void; + onceNativeEvent: (name: string, handler: (data: ArrayBuffer) => void) => void; + offNativeEvent: (name: string, handler: (data: ArrayBuffer) => void) => void; + onAnyNativeEvent: (handler: (name: string, data: ArrayBuffer) => void) => void; +} +export declare function setRenderLibPath(libPath: string): void; +export declare function resolveRenderLib(): RenderLib; diff --git a/deno.json b/deno.json --- a/deno.json +++ b/deno.json @@ -27,5 +27,6 @@ "deny": ["npm:ssh2@1.17.0"] }, "lint": { "exclude": ["**"] - } + }, + "links": [".patches/@opentui/core"] } diff --git a/deno.lock b/deno.lock --- a/deno.lock +++ b/deno.lock @@ -1027,7 +1027,6 @@ "os": ["win32"], "cpu": ["x64"] }, "@opentui/core@0.4.1_web-tree-sitter@0.25.10_typescript@6.0.3": { - "integrity": "sha512-ejlunoFCGLcghYGdfamI/DlWHsgCTLbuoL2JeOmFuLsN+DM5phje3CQbGR4tpl24cadCgHJQFomjoQ9Htvin+Q==", "dependencies": [ "bun-ffi-structs", "diff", @@ -5139,6 +5138,30 @@ "npm:vite-plugin-solid@^2.11.8", "npm:vite@^8.0.1" ] } + } + }, + "links": { + "npm:@opentui/core@0.4.1": { + "dependencies": [ + "npm:bun-ffi-structs@0.2.3", + "npm:diff@9.0.0", + "npm:marked@17.0.1", + "npm:string-width@7.2.0", + "npm:strip-ansi@7.1.2" + ], + "optionalDependencies": [ + "npm:@opentui/core-darwin-arm64@0.4.1", + "npm:@opentui/core-darwin-x64@0.4.1", + "npm:@opentui/core-linux-arm64-musl@0.4.1", + "npm:@opentui/core-linux-arm64@0.4.1", + "npm:@opentui/core-linux-x64-musl@0.4.1", + "npm:@opentui/core-linux-x64@0.4.1", + "npm:@opentui/core-win32-arm64@0.4.1", + "npm:@opentui/core-win32-x64@0.4.1" + ], + "peerDependencies": [ + "npm:web-tree-sitter@0.25.10" + ] } } } diff --git a/instance/src/systems/terminalUI.ts b/instance/src/systems/terminalUI.ts --- a/instance/src/systems/terminalUI.ts +++ b/instance/src/systems/terminalUI.ts @@ -1,7 +1,6 @@ +import { createCliRenderer, Text } from "@opentui/core"; import type { Instance } from "../index.ts"; import System from "../system.ts"; -import { createCliRenderer, Text } from "@opentui/core"; -import ffi from "node:ffi"; export default class TerminalUISystem extends System { constructor(instance: Instance) {