@opentui/core 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1,4 +1,32 @@
1
1
  // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __require = import.meta.require;
29
+
2
30
  // src/Renderable.ts
3
31
  import { EventEmitter as EventEmitter3 } from "events";
4
32
 
@@ -2014,6 +2042,74 @@ function parseAlign(value) {
2014
2042
  return Align.Auto;
2015
2043
  }
2016
2044
  }
2045
+ function parseBoxSizing(value) {
2046
+ switch (value.toLowerCase()) {
2047
+ case "border-box":
2048
+ return BoxSizing.BorderBox;
2049
+ case "content-box":
2050
+ return BoxSizing.ContentBox;
2051
+ default:
2052
+ return BoxSizing.BorderBox;
2053
+ }
2054
+ }
2055
+ function parseDimension(value) {
2056
+ switch (value.toLowerCase()) {
2057
+ case "width":
2058
+ return Dimension.Width;
2059
+ case "height":
2060
+ return Dimension.Height;
2061
+ default:
2062
+ return Dimension.Width;
2063
+ }
2064
+ }
2065
+ function parseDirection(value) {
2066
+ switch (value.toLowerCase()) {
2067
+ case "inherit":
2068
+ return Direction.Inherit;
2069
+ case "ltr":
2070
+ return Direction.LTR;
2071
+ case "rtl":
2072
+ return Direction.RTL;
2073
+ default:
2074
+ return Direction.LTR;
2075
+ }
2076
+ }
2077
+ function parseDisplay(value) {
2078
+ switch (value.toLowerCase()) {
2079
+ case "flex":
2080
+ return Display.Flex;
2081
+ case "none":
2082
+ return Display.None;
2083
+ case "contents":
2084
+ return Display.Contents;
2085
+ default:
2086
+ return Display.Flex;
2087
+ }
2088
+ }
2089
+ function parseEdge(value) {
2090
+ switch (value.toLowerCase()) {
2091
+ case "left":
2092
+ return Edge.Left;
2093
+ case "top":
2094
+ return Edge.Top;
2095
+ case "right":
2096
+ return Edge.Right;
2097
+ case "bottom":
2098
+ return Edge.Bottom;
2099
+ case "start":
2100
+ return Edge.Start;
2101
+ case "end":
2102
+ return Edge.End;
2103
+ case "horizontal":
2104
+ return Edge.Horizontal;
2105
+ case "vertical":
2106
+ return Edge.Vertical;
2107
+ case "all":
2108
+ return Edge.All;
2109
+ default:
2110
+ return Edge.All;
2111
+ }
2112
+ }
2017
2113
  function parseFlexDirection(value) {
2018
2114
  switch (value.toLowerCase()) {
2019
2115
  case "column":
@@ -2028,6 +2124,18 @@ function parseFlexDirection(value) {
2028
2124
  return FlexDirection.Column;
2029
2125
  }
2030
2126
  }
2127
+ function parseGutter(value) {
2128
+ switch (value.toLowerCase()) {
2129
+ case "column":
2130
+ return Gutter.Column;
2131
+ case "row":
2132
+ return Gutter.Row;
2133
+ case "all":
2134
+ return Gutter.All;
2135
+ default:
2136
+ return Gutter.All;
2137
+ }
2138
+ }
2031
2139
  function parseJustify(value) {
2032
2140
  switch (value.toLowerCase()) {
2033
2141
  case "flex-start":
@@ -2046,6 +2154,48 @@ function parseJustify(value) {
2046
2154
  return Justify.FlexStart;
2047
2155
  }
2048
2156
  }
2157
+ function parseLogLevel(value) {
2158
+ switch (value.toLowerCase()) {
2159
+ case "error":
2160
+ return LogLevel.Error;
2161
+ case "warn":
2162
+ return LogLevel.Warn;
2163
+ case "info":
2164
+ return LogLevel.Info;
2165
+ case "debug":
2166
+ return LogLevel.Debug;
2167
+ case "verbose":
2168
+ return LogLevel.Verbose;
2169
+ case "fatal":
2170
+ return LogLevel.Fatal;
2171
+ default:
2172
+ return LogLevel.Info;
2173
+ }
2174
+ }
2175
+ function parseMeasureMode(value) {
2176
+ switch (value.toLowerCase()) {
2177
+ case "undefined":
2178
+ return MeasureMode.Undefined;
2179
+ case "exactly":
2180
+ return MeasureMode.Exactly;
2181
+ case "at-most":
2182
+ return MeasureMode.AtMost;
2183
+ default:
2184
+ return MeasureMode.Undefined;
2185
+ }
2186
+ }
2187
+ function parseOverflow(value) {
2188
+ switch (value.toLowerCase()) {
2189
+ case "visible":
2190
+ return Overflow.Visible;
2191
+ case "hidden":
2192
+ return Overflow.Hidden;
2193
+ case "scroll":
2194
+ return Overflow.Scroll;
2195
+ default:
2196
+ return Overflow.Visible;
2197
+ }
2198
+ }
2049
2199
  function parsePositionType(value) {
2050
2200
  switch (value.toLowerCase()) {
2051
2201
  case "static":
@@ -2058,6 +2208,32 @@ function parsePositionType(value) {
2058
2208
  return PositionType.Static;
2059
2209
  }
2060
2210
  }
2211
+ function parseUnit(value) {
2212
+ switch (value.toLowerCase()) {
2213
+ case "undefined":
2214
+ return Unit.Undefined;
2215
+ case "point":
2216
+ return Unit.Point;
2217
+ case "percent":
2218
+ return Unit.Percent;
2219
+ case "auto":
2220
+ return Unit.Auto;
2221
+ default:
2222
+ return Unit.Point;
2223
+ }
2224
+ }
2225
+ function parseWrap(value) {
2226
+ switch (value.toLowerCase()) {
2227
+ case "no-wrap":
2228
+ return Wrap.NoWrap;
2229
+ case "wrap":
2230
+ return Wrap.Wrap;
2231
+ case "wrap-reverse":
2232
+ return Wrap.WrapReverse;
2233
+ default:
2234
+ return Wrap.NoWrap;
2235
+ }
2236
+ }
2061
2237
 
2062
2238
  // src/Renderable.ts
2063
2239
  var LayoutEvents;
@@ -2117,6 +2293,9 @@ function isPositionType(value) {
2117
2293
  }
2118
2294
  return isValidPercentage(value);
2119
2295
  }
2296
+ function isPostionTypeType(value) {
2297
+ return value === "relative" || value === "absolute";
2298
+ }
2120
2299
  function isDimensionType(value) {
2121
2300
  return isPositionType(value);
2122
2301
  }
@@ -2160,6 +2339,10 @@ class Renderable extends EventEmitter3 {
2160
2339
  _focused = false;
2161
2340
  keyHandler = getKeyHandler();
2162
2341
  keypressHandler = null;
2342
+ _live = false;
2343
+ _liveCount = 0;
2344
+ _mouseListeners = {};
2345
+ _keyListeners = {};
2163
2346
  layoutNode;
2164
2347
  _positionType = "relative";
2165
2348
  _position = {};
@@ -2185,9 +2368,12 @@ class Renderable extends EventEmitter3 {
2185
2368
  this._zIndex = options.zIndex ?? 0;
2186
2369
  this._visible = options.visible !== false;
2187
2370
  this.buffered = options.buffered ?? false;
2371
+ this._live = options.live ?? false;
2372
+ this._liveCount = this._live && this._visible ? 1 : 0;
2188
2373
  this.layoutNode = createTrackedNode({ renderable: this });
2189
2374
  this.layoutNode.yogaNode.setDisplay(this._visible ? Display.Flex : Display.None);
2190
2375
  this.setupYogaProperties(options);
2376
+ this.applyEventOptions(options);
2191
2377
  if (this.buffered) {
2192
2378
  this.createFrameBuffer();
2193
2379
  }
@@ -2196,8 +2382,18 @@ class Renderable extends EventEmitter3 {
2196
2382
  return this._visible;
2197
2383
  }
2198
2384
  set visible(value) {
2385
+ if (this._visible === value)
2386
+ return;
2387
+ const wasVisible = this._visible;
2199
2388
  this._visible = value;
2200
2389
  this.layoutNode.yogaNode.setDisplay(value ? Display.Flex : Display.None);
2390
+ if (this._live) {
2391
+ if (!wasVisible && value) {
2392
+ this.propagateLiveCount(1);
2393
+ } else if (wasVisible && !value) {
2394
+ this.propagateLiveCount(-1);
2395
+ }
2396
+ }
2201
2397
  if (this._focused) {
2202
2398
  this.blur();
2203
2399
  }
@@ -2221,6 +2417,7 @@ class Renderable extends EventEmitter3 {
2221
2417
  this._focused = true;
2222
2418
  this.needsUpdate();
2223
2419
  this.keypressHandler = (key) => {
2420
+ this._keyListeners["down"]?.(key);
2224
2421
  if (this.handleKeyPress) {
2225
2422
  this.handleKeyPress(key);
2226
2423
  }
@@ -2242,6 +2439,25 @@ class Renderable extends EventEmitter3 {
2242
2439
  get focused() {
2243
2440
  return this._focused;
2244
2441
  }
2442
+ get live() {
2443
+ return this._live;
2444
+ }
2445
+ get liveCount() {
2446
+ return this._liveCount;
2447
+ }
2448
+ set live(value) {
2449
+ if (this._live === value)
2450
+ return;
2451
+ this._live = value;
2452
+ if (this._visible) {
2453
+ const delta = value ? 1 : -1;
2454
+ this.propagateLiveCount(delta);
2455
+ }
2456
+ }
2457
+ propagateLiveCount(delta) {
2458
+ this._liveCount += delta;
2459
+ this.parent?.propagateLiveCount(delta);
2460
+ }
2245
2461
  get isDirty() {
2246
2462
  return this._dirty;
2247
2463
  }
@@ -2379,7 +2595,7 @@ class Renderable extends EventEmitter3 {
2379
2595
  this._height = options.height;
2380
2596
  this.layoutNode.setHeight(options.height);
2381
2597
  }
2382
- this._positionType = options.position ?? "relative";
2598
+ this._positionType = options.position === "absolute" ? "absolute" : "relative";
2383
2599
  if (this._positionType !== "relative") {
2384
2600
  node.setPositionType(parsePositionType(this._positionType));
2385
2601
  }
@@ -2441,7 +2657,7 @@ class Renderable extends EventEmitter3 {
2441
2657
  }
2442
2658
  }
2443
2659
  set position(positionType) {
2444
- if (this._positionType === positionType)
2660
+ if (!isPostionTypeType(positionType) || this._positionType === positionType)
2445
2661
  return;
2446
2662
  this._positionType = positionType;
2447
2663
  this.layoutNode.yogaNode.setPositionType(parsePositionType(positionType));
@@ -2704,6 +2920,9 @@ class Renderable extends EventEmitter3 {
2704
2920
  }
2705
2921
  this.needsZIndexSort = true;
2706
2922
  this.renderableMap.set(obj.id, obj);
2923
+ if (obj._liveCount > 0) {
2924
+ this.propagateLiveCount(obj._liveCount);
2925
+ }
2707
2926
  this.requestLayout();
2708
2927
  this.emit("child:added", obj);
2709
2928
  return insertedIndex;
@@ -2737,6 +2956,9 @@ class Renderable extends EventEmitter3 {
2737
2956
  if (this.renderableMap.has(id)) {
2738
2957
  const obj = this.renderableMap.get(id);
2739
2958
  if (obj) {
2959
+ if (obj._liveCount > 0) {
2960
+ this.propagateLiveCount(-obj._liveCount);
2961
+ }
2740
2962
  const childLayoutNode = obj.getLayoutNode();
2741
2963
  this.layoutNode.removeChild(childLayoutNode);
2742
2964
  this.requestLayout();
@@ -2801,19 +3023,107 @@ class Renderable extends EventEmitter3 {
2801
3023
  }
2802
3024
  destroySelf() {}
2803
3025
  processMouseEvent(event) {
3026
+ this._mouseListeners[event.type]?.(event);
2804
3027
  this.onMouseEvent(event);
2805
3028
  if (this.parent && !event.defaultPrevented) {
2806
3029
  this.parent.processMouseEvent(event);
2807
3030
  }
2808
3031
  }
2809
3032
  onMouseEvent(event) {}
3033
+ set onMouseDown(handler) {
3034
+ if (handler)
3035
+ this._mouseListeners["down"] = handler;
3036
+ else
3037
+ delete this._mouseListeners["down"];
3038
+ }
3039
+ set onMouseUp(handler) {
3040
+ if (handler)
3041
+ this._mouseListeners["up"] = handler;
3042
+ else
3043
+ delete this._mouseListeners["up"];
3044
+ }
3045
+ set onMouseMove(handler) {
3046
+ if (handler)
3047
+ this._mouseListeners["move"] = handler;
3048
+ else
3049
+ delete this._mouseListeners["move"];
3050
+ }
3051
+ set onMouseDrag(handler) {
3052
+ if (handler)
3053
+ this._mouseListeners["drag"] = handler;
3054
+ else
3055
+ delete this._mouseListeners["drag"];
3056
+ }
3057
+ set onMouseDragEnd(handler) {
3058
+ if (handler)
3059
+ this._mouseListeners["drag-end"] = handler;
3060
+ else
3061
+ delete this._mouseListeners["drag-end"];
3062
+ }
3063
+ set onMouseDrop(handler) {
3064
+ if (handler)
3065
+ this._mouseListeners["drop"] = handler;
3066
+ else
3067
+ delete this._mouseListeners["drop"];
3068
+ }
3069
+ set onMouseOver(handler) {
3070
+ if (handler)
3071
+ this._mouseListeners["over"] = handler;
3072
+ else
3073
+ delete this._mouseListeners["over"];
3074
+ }
3075
+ set onMouseOut(handler) {
3076
+ if (handler)
3077
+ this._mouseListeners["out"] = handler;
3078
+ else
3079
+ delete this._mouseListeners["out"];
3080
+ }
3081
+ set onMouseScroll(handler) {
3082
+ if (handler)
3083
+ this._mouseListeners["scroll"] = handler;
3084
+ else
3085
+ delete this._mouseListeners["scroll"];
3086
+ }
3087
+ set onKeyDown(handler) {
3088
+ if (handler)
3089
+ this._keyListeners["down"] = handler;
3090
+ else
3091
+ delete this._keyListeners["down"];
3092
+ }
3093
+ get onKeyDown() {
3094
+ return this._keyListeners["down"];
3095
+ }
3096
+ applyEventOptions(options) {
3097
+ if (options.onMouseDown)
3098
+ this.onMouseDown = options.onMouseDown;
3099
+ if (options.onMouseUp)
3100
+ this.onMouseUp = options.onMouseUp;
3101
+ if (options.onMouseMove)
3102
+ this.onMouseMove = options.onMouseMove;
3103
+ if (options.onMouseDrag)
3104
+ this.onMouseDrag = options.onMouseDrag;
3105
+ if (options.onMouseDragEnd)
3106
+ this.onMouseDragEnd = options.onMouseDragEnd;
3107
+ if (options.onMouseDrop)
3108
+ this.onMouseDrop = options.onMouseDrop;
3109
+ if (options.onMouseOver)
3110
+ this.onMouseOver = options.onMouseOver;
3111
+ if (options.onMouseOut)
3112
+ this.onMouseOut = options.onMouseOut;
3113
+ if (options.onMouseScroll)
3114
+ this.onMouseScroll = options.onMouseScroll;
3115
+ if (options.onKeyDown)
3116
+ this.onKeyDown = options.onKeyDown;
3117
+ }
2810
3118
  }
2811
3119
 
2812
3120
  class RootRenderable extends Renderable {
2813
3121
  yogaConfig;
2814
- constructor(width, height, ctx) {
3122
+ rootContext;
3123
+ constructor(width, height, ctx, rootContext) {
2815
3124
  super("__root__", { zIndex: 0, visible: true, width, height, enableLayout: true });
2816
3125
  this.ctx = ctx;
3126
+ this.rootContext = rootContext;
2817
3127
  this.yogaConfig = src_default.Config.create();
2818
3128
  this.yogaConfig.setUseWebDefaults(false);
2819
3129
  this.yogaConfig.setPointScaleFactor(1);
@@ -2829,13 +3139,22 @@ class RootRenderable extends Renderable {
2829
3139
  requestLayout() {
2830
3140
  this.needsUpdate();
2831
3141
  }
3142
+ propagateLiveCount(delta) {
3143
+ const oldCount = this._liveCount;
3144
+ this._liveCount += delta;
3145
+ if (oldCount === 0 && this._liveCount > 0) {
3146
+ this.rootContext.requestLive();
3147
+ } else if (oldCount > 0 && this._liveCount === 0) {
3148
+ this.rootContext.dropLive();
3149
+ }
3150
+ }
2832
3151
  calculateLayout() {
2833
3152
  this.layoutNode.yogaNode.calculateLayout(this.width, this.height, Direction.LTR);
2834
3153
  this.emit("layout-changed" /* LAYOUT_CHANGED */);
2835
3154
  }
2836
3155
  resize(width, height) {
2837
- this.layoutNode.setWidth(width);
2838
- this.layoutNode.setHeight(height);
3156
+ this.width = width;
3157
+ this.height = height;
2839
3158
  this.emit("resized" /* RESIZED */, { width, height });
2840
3159
  }
2841
3160
  beforeRender() {
@@ -2853,111 +3172,26 @@ class RootRenderable extends Renderable {
2853
3172
  super.destroySelf();
2854
3173
  }
2855
3174
  }
2856
- // src/utils.ts
2857
- function hexToRgb(hex) {
2858
- hex = hex.replace(/^#/, "");
2859
- if (hex.length === 3) {
2860
- hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
2861
- }
2862
- if (!/^[0-9A-Fa-f]{6}$/.test(hex)) {
2863
- console.warn(`Invalid hex color: ${hex}, defaulting to magenta`);
2864
- return RGBA.fromValues(1, 0, 1, 1);
2865
- }
2866
- const r = parseInt(hex.substring(0, 2), 16) / 255;
2867
- const g = parseInt(hex.substring(2, 4), 16) / 255;
2868
- const b = parseInt(hex.substring(4, 6), 16) / 255;
2869
- return RGBA.fromValues(r, g, b, 1);
2870
- }
2871
- function rgbToHex(rgb) {
2872
- return "#" + [rgb.r, rgb.g, rgb.b].map((x) => {
2873
- const hex = Math.floor(Math.max(0, Math.min(1, x) * 255)).toString(16);
2874
- return hex.length === 1 ? "0" + hex : hex;
2875
- }).join("");
2876
- }
2877
- function hsvToRgb(h, s, v) {
2878
- let r = 0, g = 0, b = 0;
2879
- const i = Math.floor(h / 60) % 6;
2880
- const f = h / 60 - Math.floor(h / 60);
2881
- const p = v * (1 - s);
2882
- const q = v * (1 - f * s);
2883
- const t = v * (1 - (1 - f) * s);
2884
- switch (i) {
2885
- case 0:
2886
- r = v;
2887
- g = t;
2888
- b = p;
2889
- break;
2890
- case 1:
2891
- r = q;
2892
- g = v;
2893
- b = p;
2894
- break;
2895
- case 2:
2896
- r = p;
2897
- g = v;
2898
- b = t;
2899
- break;
2900
- case 3:
2901
- r = p;
2902
- g = q;
2903
- b = v;
2904
- break;
2905
- case 4:
2906
- r = t;
2907
- g = p;
2908
- b = v;
2909
- break;
2910
- case 5:
2911
- r = v;
2912
- g = p;
2913
- b = q;
2914
- break;
2915
- }
2916
- return RGBA.fromValues(r, g, b, 1);
2917
- }
2918
- var CSS_COLOR_NAMES = {
2919
- black: "#000000",
2920
- white: "#FFFFFF",
2921
- red: "#FF0000",
2922
- green: "#008000",
2923
- blue: "#0000FF",
2924
- yellow: "#FFFF00",
2925
- cyan: "#00FFFF",
2926
- magenta: "#FF00FF",
2927
- silver: "#C0C0C0",
2928
- gray: "#808080",
2929
- grey: "#808080",
2930
- maroon: "#800000",
2931
- olive: "#808000",
2932
- lime: "#00FF00",
2933
- aqua: "#00FFFF",
2934
- teal: "#008080",
2935
- navy: "#000080",
2936
- fuchsia: "#FF00FF",
2937
- purple: "#800080",
2938
- orange: "#FFA500",
2939
- brightblack: "#666666",
2940
- brightred: "#FF6666",
2941
- brightgreen: "#66FF66",
2942
- brightblue: "#6666FF",
2943
- brightyellow: "#FFFF66",
2944
- brightcyan: "#66FFFF",
2945
- brightmagenta: "#FF66FF",
2946
- brightwhite: "#FFFFFF"
3175
+ // src/types.ts
3176
+ var TextAttributes = {
3177
+ NONE: 0,
3178
+ BOLD: 1 << 0,
3179
+ DIM: 1 << 1,
3180
+ ITALIC: 1 << 2,
3181
+ UNDERLINE: 1 << 3,
3182
+ BLINK: 1 << 4,
3183
+ INVERSE: 1 << 5,
3184
+ HIDDEN: 1 << 6,
3185
+ STRIKETHROUGH: 1 << 7
2947
3186
  };
2948
- function parseColor(color) {
2949
- if (typeof color === "string") {
2950
- const lowerColor = color.toLowerCase();
2951
- if (lowerColor === "transparent") {
2952
- return RGBA.fromValues(0, 0, 0, 0);
2953
- }
2954
- if (CSS_COLOR_NAMES[lowerColor]) {
2955
- return hexToRgb(CSS_COLOR_NAMES[lowerColor]);
2956
- }
2957
- return hexToRgb(color);
2958
- }
2959
- return color;
2960
- }
3187
+ var DebugOverlayCorner;
3188
+ ((DebugOverlayCorner2) => {
3189
+ DebugOverlayCorner2[DebugOverlayCorner2["topLeft"] = 0] = "topLeft";
3190
+ DebugOverlayCorner2[DebugOverlayCorner2["topRight"] = 1] = "topRight";
3191
+ DebugOverlayCorner2[DebugOverlayCorner2["bottomLeft"] = 2] = "bottomLeft";
3192
+ DebugOverlayCorner2[DebugOverlayCorner2["bottomRight"] = 3] = "bottomRight";
3193
+ })(DebugOverlayCorner ||= {});
3194
+ // src/utils.ts
2961
3195
  function createTextAttributes({
2962
3196
  bold = false,
2963
3197
  italic = false,
@@ -2987,15 +3221,110 @@ function createTextAttributes({
2987
3221
  attributes |= TextAttributes.STRIKETHROUGH;
2988
3222
  return attributes;
2989
3223
  }
2990
-
2991
- // src/types.ts
2992
- class RGBA {
2993
- buffer;
2994
- constructor(buffer) {
2995
- this.buffer = buffer;
3224
+ // src/lib/border.ts
3225
+ var BorderChars = {
3226
+ single: {
3227
+ topLeft: "\u250C",
3228
+ topRight: "\u2510",
3229
+ bottomLeft: "\u2514",
3230
+ bottomRight: "\u2518",
3231
+ horizontal: "\u2500",
3232
+ vertical: "\u2502",
3233
+ topT: "\u252C",
3234
+ bottomT: "\u2534",
3235
+ leftT: "\u251C",
3236
+ rightT: "\u2524",
3237
+ cross: "\u253C"
3238
+ },
3239
+ double: {
3240
+ topLeft: "\u2554",
3241
+ topRight: "\u2557",
3242
+ bottomLeft: "\u255A",
3243
+ bottomRight: "\u255D",
3244
+ horizontal: "\u2550",
3245
+ vertical: "\u2551",
3246
+ topT: "\u2566",
3247
+ bottomT: "\u2569",
3248
+ leftT: "\u2560",
3249
+ rightT: "\u2563",
3250
+ cross: "\u256C"
3251
+ },
3252
+ rounded: {
3253
+ topLeft: "\u256D",
3254
+ topRight: "\u256E",
3255
+ bottomLeft: "\u2570",
3256
+ bottomRight: "\u256F",
3257
+ horizontal: "\u2500",
3258
+ vertical: "\u2502",
3259
+ topT: "\u252C",
3260
+ bottomT: "\u2534",
3261
+ leftT: "\u251C",
3262
+ rightT: "\u2524",
3263
+ cross: "\u253C"
3264
+ },
3265
+ heavy: {
3266
+ topLeft: "\u250F",
3267
+ topRight: "\u2513",
3268
+ bottomLeft: "\u2517",
3269
+ bottomRight: "\u251B",
3270
+ horizontal: "\u2501",
3271
+ vertical: "\u2503",
3272
+ topT: "\u2533",
3273
+ bottomT: "\u253B",
3274
+ leftT: "\u2523",
3275
+ rightT: "\u252B",
3276
+ cross: "\u254B"
2996
3277
  }
2997
- static fromArray(array) {
2998
- return new RGBA(array);
3278
+ };
3279
+ function getBorderFromSides(sides) {
3280
+ const result = [];
3281
+ if (sides.top)
3282
+ result.push("top");
3283
+ if (sides.right)
3284
+ result.push("right");
3285
+ if (sides.bottom)
3286
+ result.push("bottom");
3287
+ if (sides.left)
3288
+ result.push("left");
3289
+ return result.length > 0 ? result : false;
3290
+ }
3291
+ function getBorderSides(border) {
3292
+ return border === true ? { top: true, right: true, bottom: true, left: true } : Array.isArray(border) ? {
3293
+ top: border.includes("top"),
3294
+ right: border.includes("right"),
3295
+ bottom: border.includes("bottom"),
3296
+ left: border.includes("left")
3297
+ } : { top: false, right: false, bottom: false, left: false };
3298
+ }
3299
+ function borderCharsToArray(chars) {
3300
+ const array = new Uint32Array(11);
3301
+ array[0] = chars.topLeft.codePointAt(0);
3302
+ array[1] = chars.topRight.codePointAt(0);
3303
+ array[2] = chars.bottomLeft.codePointAt(0);
3304
+ array[3] = chars.bottomRight.codePointAt(0);
3305
+ array[4] = chars.horizontal.codePointAt(0);
3306
+ array[5] = chars.vertical.codePointAt(0);
3307
+ array[6] = chars.topT.codePointAt(0);
3308
+ array[7] = chars.bottomT.codePointAt(0);
3309
+ array[8] = chars.leftT.codePointAt(0);
3310
+ array[9] = chars.rightT.codePointAt(0);
3311
+ array[10] = chars.cross.codePointAt(0);
3312
+ return array;
3313
+ }
3314
+ var BorderCharArrays = {
3315
+ single: borderCharsToArray(BorderChars.single),
3316
+ double: borderCharsToArray(BorderChars.double),
3317
+ rounded: borderCharsToArray(BorderChars.rounded),
3318
+ heavy: borderCharsToArray(BorderChars.heavy)
3319
+ };
3320
+ // src/lib/RGBA.ts
3321
+ class RGBA {
3322
+ buffer;
3323
+ constructor(buffer) {
3324
+ this.buffer = buffer;
3325
+ }
3326
+ static fromArray(array) {
3327
+ return new RGBA(array);
2999
3328
  }
3000
3329
  static fromValues(r, g, b, a = 1) {
3001
3330
  return new RGBA(new Float32Array([r, g, b, a]));
@@ -3040,863 +3369,110 @@ class RGBA {
3040
3369
  return `rgba(${this.r.toFixed(2)}, ${this.g.toFixed(2)}, ${this.b.toFixed(2)}, ${this.a.toFixed(2)})`;
3041
3370
  }
3042
3371
  }
3043
- var TextAttributes = {
3044
- NONE: 0,
3045
- BOLD: 1 << 0,
3046
- DIM: 1 << 1,
3047
- ITALIC: 1 << 2,
3048
- UNDERLINE: 1 << 3,
3049
- BLINK: 1 << 4,
3050
- INVERSE: 1 << 5,
3051
- HIDDEN: 1 << 6,
3052
- STRIKETHROUGH: 1 << 7
3053
- };
3054
- var DebugOverlayCorner;
3055
- ((DebugOverlayCorner2) => {
3056
- DebugOverlayCorner2[DebugOverlayCorner2["topLeft"] = 0] = "topLeft";
3057
- DebugOverlayCorner2[DebugOverlayCorner2["topRight"] = 1] = "topRight";
3058
- DebugOverlayCorner2[DebugOverlayCorner2["bottomLeft"] = 2] = "bottomLeft";
3059
- DebugOverlayCorner2[DebugOverlayCorner2["bottomRight"] = 3] = "bottomRight";
3060
- })(DebugOverlayCorner ||= {});
3061
- // src/zig.ts
3062
- import { dlopen, toArrayBuffer } from "bun:ffi";
3063
- import { existsSync } from "fs";
3064
-
3065
- // src/text-buffer.ts
3066
- class TextBuffer {
3067
- lib;
3068
- bufferPtr;
3069
- buffer;
3070
- _length = 0;
3071
- _capacity;
3072
- _lineInfo;
3073
- constructor(lib, ptr, buffer, capacity) {
3074
- this.lib = lib;
3075
- this.bufferPtr = ptr;
3076
- this.buffer = buffer;
3077
- this._capacity = capacity;
3078
- }
3079
- static create(capacity = 256) {
3080
- const lib = resolveRenderLib();
3081
- return lib.createTextBuffer(capacity);
3082
- }
3083
- syncBuffersAfterResize() {
3084
- const capacity = this.lib.textBufferGetCapacity(this.bufferPtr);
3085
- this.buffer = this.lib.getTextBufferArrays(this.bufferPtr, capacity);
3086
- this._capacity = capacity;
3087
- }
3088
- setStyledText(text) {
3089
- this.lib.textBufferReset(this.bufferPtr);
3090
- this._length = 0;
3091
- this._lineInfo = undefined;
3092
- for (const chunk of text.chunks) {
3093
- const result = this.lib.textBufferWriteChunk(this.bufferPtr, chunk.text, chunk.fg || null, chunk.bg || null, chunk.attributes ?? null);
3094
- if (result & 1) {
3095
- this.syncBuffersAfterResize();
3096
- }
3097
- }
3098
- this.lib.textBufferFinalizeLineInfo(this.bufferPtr);
3099
- this._length = this.lib.textBufferGetLength(this.bufferPtr);
3100
- }
3101
- setDefaultFg(fg) {
3102
- this.lib.textBufferSetDefaultFg(this.bufferPtr, fg);
3103
- }
3104
- setDefaultBg(bg) {
3105
- this.lib.textBufferSetDefaultBg(this.bufferPtr, bg);
3106
- }
3107
- setDefaultAttributes(attributes) {
3108
- this.lib.textBufferSetDefaultAttributes(this.bufferPtr, attributes);
3109
- }
3110
- resetDefaults() {
3111
- this.lib.textBufferResetDefaults(this.bufferPtr);
3112
- }
3113
- get length() {
3114
- return this._length;
3372
+ function hexToRgb(hex) {
3373
+ hex = hex.replace(/^#/, "");
3374
+ if (hex.length === 3) {
3375
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
3115
3376
  }
3116
- get capacity() {
3117
- return this._capacity;
3377
+ if (!/^[0-9A-Fa-f]{6}$/.test(hex)) {
3378
+ console.warn(`Invalid hex color: ${hex}, defaulting to magenta`);
3379
+ return RGBA.fromValues(1, 0, 1, 1);
3118
3380
  }
3119
- get ptr() {
3120
- return this.bufferPtr;
3381
+ const r = parseInt(hex.substring(0, 2), 16) / 255;
3382
+ const g = parseInt(hex.substring(2, 4), 16) / 255;
3383
+ const b = parseInt(hex.substring(4, 6), 16) / 255;
3384
+ return RGBA.fromValues(r, g, b, 1);
3385
+ }
3386
+ function rgbToHex(rgb) {
3387
+ return "#" + [rgb.r, rgb.g, rgb.b].map((x) => {
3388
+ const hex = Math.floor(Math.max(0, Math.min(1, x) * 255)).toString(16);
3389
+ return hex.length === 1 ? "0" + hex : hex;
3390
+ }).join("");
3391
+ }
3392
+ function hsvToRgb(h, s, v) {
3393
+ let r = 0, g = 0, b = 0;
3394
+ const i = Math.floor(h / 60) % 6;
3395
+ const f = h / 60 - Math.floor(h / 60);
3396
+ const p = v * (1 - s);
3397
+ const q = v * (1 - f * s);
3398
+ const t = v * (1 - (1 - f) * s);
3399
+ switch (i) {
3400
+ case 0:
3401
+ r = v;
3402
+ g = t;
3403
+ b = p;
3404
+ break;
3405
+ case 1:
3406
+ r = q;
3407
+ g = v;
3408
+ b = p;
3409
+ break;
3410
+ case 2:
3411
+ r = p;
3412
+ g = v;
3413
+ b = t;
3414
+ break;
3415
+ case 3:
3416
+ r = p;
3417
+ g = q;
3418
+ b = v;
3419
+ break;
3420
+ case 4:
3421
+ r = t;
3422
+ g = p;
3423
+ b = v;
3424
+ break;
3425
+ case 5:
3426
+ r = v;
3427
+ g = p;
3428
+ b = q;
3429
+ break;
3121
3430
  }
3122
- get lineInfo() {
3123
- if (!this._lineInfo) {
3124
- this._lineInfo = this.lib.textBufferGetLineInfo(this.bufferPtr);
3431
+ return RGBA.fromValues(r, g, b, 1);
3432
+ }
3433
+ var CSS_COLOR_NAMES = {
3434
+ black: "#000000",
3435
+ white: "#FFFFFF",
3436
+ red: "#FF0000",
3437
+ green: "#008000",
3438
+ blue: "#0000FF",
3439
+ yellow: "#FFFF00",
3440
+ cyan: "#00FFFF",
3441
+ magenta: "#FF00FF",
3442
+ silver: "#C0C0C0",
3443
+ gray: "#808080",
3444
+ grey: "#808080",
3445
+ maroon: "#800000",
3446
+ olive: "#808000",
3447
+ lime: "#00FF00",
3448
+ aqua: "#00FFFF",
3449
+ teal: "#008080",
3450
+ navy: "#000080",
3451
+ fuchsia: "#FF00FF",
3452
+ purple: "#800080",
3453
+ orange: "#FFA500",
3454
+ brightblack: "#666666",
3455
+ brightred: "#FF6666",
3456
+ brightgreen: "#66FF66",
3457
+ brightblue: "#6666FF",
3458
+ brightyellow: "#FFFF66",
3459
+ brightcyan: "#66FFFF",
3460
+ brightmagenta: "#FF66FF",
3461
+ brightwhite: "#FFFFFF"
3462
+ };
3463
+ function parseColor(color) {
3464
+ if (typeof color === "string") {
3465
+ const lowerColor = color.toLowerCase();
3466
+ if (lowerColor === "transparent") {
3467
+ return RGBA.fromValues(0, 0, 0, 0);
3125
3468
  }
3126
- return this._lineInfo;
3127
- }
3128
- toString() {
3129
- const chars = [];
3130
- for (let i = 0;i < this._length; i++) {
3131
- chars.push(String.fromCharCode(this.buffer.char[i]));
3469
+ if (CSS_COLOR_NAMES[lowerColor]) {
3470
+ return hexToRgb(CSS_COLOR_NAMES[lowerColor]);
3132
3471
  }
3133
- return chars.join("");
3134
- }
3135
- concat(other) {
3136
- return this.lib.textBufferConcat(this.bufferPtr, other.bufferPtr);
3137
- }
3138
- setSelection(start, end, bgColor, fgColor) {
3139
- this.lib.textBufferSetSelection(this.bufferPtr, start, end, bgColor || null, fgColor || null);
3140
- }
3141
- resetSelection() {
3142
- this.lib.textBufferResetSelection(this.bufferPtr);
3143
- }
3144
- destroy() {
3145
- this.lib.destroyTextBuffer(this.bufferPtr);
3472
+ return hexToRgb(color);
3146
3473
  }
3474
+ return color;
3147
3475
  }
3148
-
3149
- // src/zig.ts
3150
- var module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`);
3151
- var targetLibPath = module.default;
3152
- if (!existsSync(targetLibPath)) {
3153
- throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
3154
- }
3155
- function getOpenTUILib(libPath) {
3156
- const resolvedLibPath = libPath || targetLibPath;
3157
- return dlopen(resolvedLibPath, {
3158
- createRenderer: {
3159
- args: ["u32", "u32"],
3160
- returns: "ptr"
3161
- },
3162
- destroyRenderer: {
3163
- args: ["ptr", "bool", "u32"],
3164
- returns: "void"
3165
- },
3166
- setUseThread: {
3167
- args: ["ptr", "bool"],
3168
- returns: "void"
3169
- },
3170
- setBackgroundColor: {
3171
- args: ["ptr", "ptr"],
3172
- returns: "void"
3173
- },
3174
- setRenderOffset: {
3175
- args: ["ptr", "u32"],
3176
- returns: "void"
3177
- },
3178
- updateStats: {
3179
- args: ["ptr", "f64", "u32", "f64"],
3180
- returns: "void"
3181
- },
3182
- updateMemoryStats: {
3183
- args: ["ptr", "u32", "u32", "u32"],
3184
- returns: "void"
3185
- },
3186
- render: {
3187
- args: ["ptr", "bool"],
3188
- returns: "void"
3189
- },
3190
- getNextBuffer: {
3191
- args: ["ptr"],
3192
- returns: "ptr"
3193
- },
3194
- getCurrentBuffer: {
3195
- args: ["ptr"],
3196
- returns: "ptr"
3197
- },
3198
- createOptimizedBuffer: {
3199
- args: ["u32", "u32", "bool"],
3200
- returns: "ptr"
3201
- },
3202
- destroyOptimizedBuffer: {
3203
- args: ["ptr"],
3204
- returns: "void"
3205
- },
3206
- drawFrameBuffer: {
3207
- args: ["ptr", "i32", "i32", "ptr", "u32", "u32", "u32", "u32"],
3208
- returns: "void"
3209
- },
3210
- getBufferWidth: {
3211
- args: ["ptr"],
3212
- returns: "u32"
3213
- },
3214
- getBufferHeight: {
3215
- args: ["ptr"],
3216
- returns: "u32"
3217
- },
3218
- bufferClear: {
3219
- args: ["ptr", "ptr"],
3220
- returns: "void"
3221
- },
3222
- bufferGetCharPtr: {
3223
- args: ["ptr"],
3224
- returns: "ptr"
3225
- },
3226
- bufferGetFgPtr: {
3227
- args: ["ptr"],
3228
- returns: "ptr"
3229
- },
3230
- bufferGetBgPtr: {
3231
- args: ["ptr"],
3232
- returns: "ptr"
3233
- },
3234
- bufferGetAttributesPtr: {
3235
- args: ["ptr"],
3236
- returns: "ptr"
3237
- },
3238
- bufferGetRespectAlpha: {
3239
- args: ["ptr"],
3240
- returns: "bool"
3241
- },
3242
- bufferSetRespectAlpha: {
3243
- args: ["ptr", "bool"],
3244
- returns: "void"
3245
- },
3246
- bufferDrawText: {
3247
- args: ["ptr", "ptr", "u32", "u32", "u32", "ptr", "ptr", "u8"],
3248
- returns: "void"
3249
- },
3250
- bufferSetCellWithAlphaBlending: {
3251
- args: ["ptr", "u32", "u32", "u32", "ptr", "ptr", "u8"],
3252
- returns: "void"
3253
- },
3254
- bufferFillRect: {
3255
- args: ["ptr", "u32", "u32", "u32", "u32", "ptr"],
3256
- returns: "void"
3257
- },
3258
- bufferResize: {
3259
- args: ["ptr", "u32", "u32"],
3260
- returns: "void"
3261
- },
3262
- resizeRenderer: {
3263
- args: ["ptr", "u32", "u32"],
3264
- returns: "void"
3265
- },
3266
- setCursorPosition: {
3267
- args: ["i32", "i32", "bool"],
3268
- returns: "void"
3269
- },
3270
- setCursorStyle: {
3271
- args: ["ptr", "u32", "bool"],
3272
- returns: "void"
3273
- },
3274
- setCursorColor: {
3275
- args: ["ptr"],
3276
- returns: "void"
3277
- },
3278
- setDebugOverlay: {
3279
- args: ["ptr", "bool", "u8"],
3280
- returns: "void"
3281
- },
3282
- clearTerminal: {
3283
- args: ["ptr"],
3284
- returns: "void"
3285
- },
3286
- bufferDrawSuperSampleBuffer: {
3287
- args: ["ptr", "u32", "u32", "ptr", "usize", "u8", "u32"],
3288
- returns: "void"
3289
- },
3290
- bufferDrawPackedBuffer: {
3291
- args: ["ptr", "ptr", "usize", "u32", "u32", "u32", "u32"],
3292
- returns: "void"
3293
- },
3294
- bufferDrawBox: {
3295
- args: ["ptr", "i32", "i32", "u32", "u32", "ptr", "u32", "ptr", "ptr", "ptr", "u32"],
3296
- returns: "void"
3297
- },
3298
- addToHitGrid: {
3299
- args: ["ptr", "i32", "i32", "u32", "u32", "u32"],
3300
- returns: "void"
3301
- },
3302
- checkHit: {
3303
- args: ["ptr", "u32", "u32"],
3304
- returns: "u32"
3305
- },
3306
- dumpHitGrid: {
3307
- args: ["ptr"],
3308
- returns: "void"
3309
- },
3310
- dumpBuffers: {
3311
- args: ["ptr", "i64"],
3312
- returns: "void"
3313
- },
3314
- dumpStdoutBuffer: {
3315
- args: ["ptr", "i64"],
3316
- returns: "void"
3317
- },
3318
- enableMouse: {
3319
- args: ["ptr", "bool"],
3320
- returns: "void"
3321
- },
3322
- disableMouse: {
3323
- args: ["ptr"],
3324
- returns: "void"
3325
- },
3326
- createTextBuffer: {
3327
- args: ["u32"],
3328
- returns: "ptr"
3329
- },
3330
- destroyTextBuffer: {
3331
- args: ["ptr"],
3332
- returns: "void"
3333
- },
3334
- textBufferGetCharPtr: {
3335
- args: ["ptr"],
3336
- returns: "ptr"
3337
- },
3338
- textBufferGetFgPtr: {
3339
- args: ["ptr"],
3340
- returns: "ptr"
3341
- },
3342
- textBufferGetBgPtr: {
3343
- args: ["ptr"],
3344
- returns: "ptr"
3345
- },
3346
- textBufferGetAttributesPtr: {
3347
- args: ["ptr"],
3348
- returns: "ptr"
3349
- },
3350
- textBufferGetLength: {
3351
- args: ["ptr"],
3352
- returns: "u32"
3353
- },
3354
- textBufferSetCell: {
3355
- args: ["ptr", "u32", "u32", "ptr", "ptr", "u16"],
3356
- returns: "void"
3357
- },
3358
- textBufferConcat: {
3359
- args: ["ptr", "ptr"],
3360
- returns: "ptr"
3361
- },
3362
- textBufferResize: {
3363
- args: ["ptr", "u32"],
3364
- returns: "void"
3365
- },
3366
- textBufferReset: {
3367
- args: ["ptr"],
3368
- returns: "void"
3369
- },
3370
- textBufferSetSelection: {
3371
- args: ["ptr", "u32", "u32", "ptr", "ptr"],
3372
- returns: "void"
3373
- },
3374
- textBufferResetSelection: {
3375
- args: ["ptr"],
3376
- returns: "void"
3377
- },
3378
- textBufferSetDefaultFg: {
3379
- args: ["ptr", "ptr"],
3380
- returns: "void"
3381
- },
3382
- textBufferSetDefaultBg: {
3383
- args: ["ptr", "ptr"],
3384
- returns: "void"
3385
- },
3386
- textBufferSetDefaultAttributes: {
3387
- args: ["ptr", "ptr"],
3388
- returns: "void"
3389
- },
3390
- textBufferResetDefaults: {
3391
- args: ["ptr"],
3392
- returns: "void"
3393
- },
3394
- textBufferWriteChunk: {
3395
- args: ["ptr", "ptr", "u32", "ptr", "ptr", "ptr"],
3396
- returns: "u32"
3397
- },
3398
- textBufferGetCapacity: {
3399
- args: ["ptr"],
3400
- returns: "u32"
3401
- },
3402
- textBufferFinalizeLineInfo: {
3403
- args: ["ptr"],
3404
- returns: "void"
3405
- },
3406
- textBufferGetLineStartsPtr: {
3407
- args: ["ptr"],
3408
- returns: "ptr"
3409
- },
3410
- textBufferGetLineWidthsPtr: {
3411
- args: ["ptr"],
3412
- returns: "ptr"
3413
- },
3414
- textBufferGetLineCount: {
3415
- args: ["ptr"],
3416
- returns: "u32"
3417
- },
3418
- bufferDrawTextBuffer: {
3419
- args: ["ptr", "ptr", "i32", "i32", "i32", "i32", "u32", "u32", "bool"],
3420
- returns: "void"
3421
- }
3422
- });
3423
- }
3424
-
3425
- class FFIRenderLib {
3426
- opentui;
3427
- encoder = new TextEncoder;
3428
- constructor(libPath) {
3429
- this.opentui = getOpenTUILib(libPath);
3430
- }
3431
- createRenderer(width, height) {
3432
- return this.opentui.symbols.createRenderer(width, height);
3433
- }
3434
- destroyRenderer(renderer, useAlternateScreen, splitHeight) {
3435
- this.opentui.symbols.destroyRenderer(renderer, useAlternateScreen, splitHeight);
3436
- }
3437
- setUseThread(renderer, useThread) {
3438
- this.opentui.symbols.setUseThread(renderer, useThread);
3439
- }
3440
- setBackgroundColor(renderer, color) {
3441
- this.opentui.symbols.setBackgroundColor(renderer, color.buffer);
3442
- }
3443
- setRenderOffset(renderer, offset) {
3444
- this.opentui.symbols.setRenderOffset(renderer, offset);
3445
- }
3446
- updateStats(renderer, time, fps, frameCallbackTime) {
3447
- this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime);
3448
- }
3449
- updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers) {
3450
- this.opentui.symbols.updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers);
3451
- }
3452
- getNextBuffer(renderer) {
3453
- const bufferPtr = this.opentui.symbols.getNextBuffer(renderer);
3454
- if (!bufferPtr) {
3455
- throw new Error("Failed to get next buffer");
3456
- }
3457
- const width = this.opentui.symbols.getBufferWidth(bufferPtr);
3458
- const height = this.opentui.symbols.getBufferHeight(bufferPtr);
3459
- const size = width * height;
3460
- const buffers = this.getBuffer(bufferPtr, size);
3461
- return new OptimizedBuffer(this, bufferPtr, buffers, width, height, {});
3462
- }
3463
- getCurrentBuffer(renderer) {
3464
- const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer);
3465
- if (!bufferPtr) {
3466
- throw new Error("Failed to get current buffer");
3467
- }
3468
- const width = this.opentui.symbols.getBufferWidth(bufferPtr);
3469
- const height = this.opentui.symbols.getBufferHeight(bufferPtr);
3470
- const size = width * height;
3471
- const buffers = this.getBuffer(bufferPtr, size);
3472
- return new OptimizedBuffer(this, bufferPtr, buffers, width, height, {});
3473
- }
3474
- getBuffer(bufferPtr, size) {
3475
- const charPtr = this.opentui.symbols.bufferGetCharPtr(bufferPtr);
3476
- const fgPtr = this.opentui.symbols.bufferGetFgPtr(bufferPtr);
3477
- const bgPtr = this.opentui.symbols.bufferGetBgPtr(bufferPtr);
3478
- const attributesPtr = this.opentui.symbols.bufferGetAttributesPtr(bufferPtr);
3479
- if (!charPtr || !fgPtr || !bgPtr || !attributesPtr) {
3480
- throw new Error("Failed to get buffer pointers");
3481
- }
3482
- const buffers = {
3483
- char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
3484
- fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
3485
- bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
3486
- attributes: new Uint8Array(toArrayBuffer(attributesPtr, 0, size))
3487
- };
3488
- return buffers;
3489
- }
3490
- getTextBuffer(bufferPtr, size) {
3491
- const charPtr = this.opentui.symbols.textBufferGetCharPtr(bufferPtr);
3492
- const fgPtr = this.opentui.symbols.textBufferGetFgPtr(bufferPtr);
3493
- const bgPtr = this.opentui.symbols.textBufferGetBgPtr(bufferPtr);
3494
- const attributesPtr = this.opentui.symbols.textBufferGetAttributesPtr(bufferPtr);
3495
- if (!charPtr || !fgPtr || !bgPtr || !attributesPtr) {
3496
- throw new Error("Failed to get text buffer pointers");
3497
- }
3498
- const buffers = {
3499
- char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
3500
- fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
3501
- bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
3502
- attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, size * 2))
3503
- };
3504
- return buffers;
3505
- }
3506
- bufferGetCharPtr(buffer) {
3507
- const ptr = this.opentui.symbols.bufferGetCharPtr(buffer);
3508
- if (!ptr) {
3509
- throw new Error("Failed to get char pointer");
3510
- }
3511
- return ptr;
3512
- }
3513
- bufferGetFgPtr(buffer) {
3514
- const ptr = this.opentui.symbols.bufferGetFgPtr(buffer);
3515
- if (!ptr) {
3516
- throw new Error("Failed to get fg pointer");
3517
- }
3518
- return ptr;
3519
- }
3520
- bufferGetBgPtr(buffer) {
3521
- const ptr = this.opentui.symbols.bufferGetBgPtr(buffer);
3522
- if (!ptr) {
3523
- throw new Error("Failed to get bg pointer");
3524
- }
3525
- return ptr;
3526
- }
3527
- bufferGetAttributesPtr(buffer) {
3528
- const ptr = this.opentui.symbols.bufferGetAttributesPtr(buffer);
3529
- if (!ptr) {
3530
- throw new Error("Failed to get attributes pointer");
3531
- }
3532
- return ptr;
3533
- }
3534
- bufferGetRespectAlpha(buffer) {
3535
- return this.opentui.symbols.bufferGetRespectAlpha(buffer);
3536
- }
3537
- bufferSetRespectAlpha(buffer, respectAlpha) {
3538
- this.opentui.symbols.bufferSetRespectAlpha(buffer, respectAlpha);
3539
- }
3540
- getBufferWidth(buffer) {
3541
- return this.opentui.symbols.getBufferWidth(buffer);
3542
- }
3543
- getBufferHeight(buffer) {
3544
- return this.opentui.symbols.getBufferHeight(buffer);
3545
- }
3546
- bufferClear(buffer, color) {
3547
- this.opentui.symbols.bufferClear(buffer, color.buffer);
3548
- }
3549
- bufferDrawText(buffer, text, x, y, color, bgColor, attributes) {
3550
- const textBytes = this.encoder.encode(text);
3551
- const textLength = textBytes.byteLength;
3552
- const bg = bgColor ? bgColor.buffer : null;
3553
- const fg = color.buffer;
3554
- this.opentui.symbols.bufferDrawText(buffer, textBytes, textLength, x, y, fg, bg, attributes ?? 0);
3555
- }
3556
- bufferSetCellWithAlphaBlending(buffer, x, y, char, color, bgColor, attributes) {
3557
- const charPtr = char.codePointAt(0) ?? " ".codePointAt(0);
3558
- const bg = bgColor.buffer;
3559
- const fg = color.buffer;
3560
- this.opentui.symbols.bufferSetCellWithAlphaBlending(buffer, x, y, charPtr, fg, bg, attributes ?? 0);
3561
- }
3562
- bufferFillRect(buffer, x, y, width, height, color) {
3563
- const bg = color.buffer;
3564
- this.opentui.symbols.bufferFillRect(buffer, x, y, width, height, bg);
3565
- }
3566
- bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow) {
3567
- const formatId = format === "bgra8unorm" ? 0 : 1;
3568
- this.opentui.symbols.bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, formatId, alignedBytesPerRow);
3569
- }
3570
- bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
3571
- this.opentui.symbols.bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
3572
- }
3573
- bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, title) {
3574
- const titleBytes = title ? this.encoder.encode(title) : null;
3575
- const titleLen = title ? titleBytes.length : 0;
3576
- const titlePtr = title ? titleBytes : null;
3577
- this.opentui.symbols.bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor.buffer, backgroundColor.buffer, titlePtr, titleLen);
3578
- }
3579
- bufferResize(buffer, width, height) {
3580
- this.opentui.symbols.bufferResize(buffer, width, height);
3581
- const buffers = this.getBuffer(buffer, width * height);
3582
- return buffers;
3583
- }
3584
- resizeRenderer(renderer, width, height) {
3585
- this.opentui.symbols.resizeRenderer(renderer, width, height);
3586
- }
3587
- setCursorPosition(x, y, visible) {
3588
- this.opentui.symbols.setCursorPosition(x, y, visible);
3589
- }
3590
- setCursorStyle(style, blinking) {
3591
- const stylePtr = this.encoder.encode(style);
3592
- this.opentui.symbols.setCursorStyle(stylePtr, style.length, blinking);
3593
- }
3594
- setCursorColor(color) {
3595
- this.opentui.symbols.setCursorColor(color.buffer);
3596
- }
3597
- render(renderer, force) {
3598
- this.opentui.symbols.render(renderer, force);
3599
- }
3600
- createOptimizedBuffer(width, height, respectAlpha = false) {
3601
- if (Number.isNaN(width) || Number.isNaN(height)) {
3602
- console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
3603
- }
3604
- const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, respectAlpha);
3605
- if (!bufferPtr) {
3606
- throw new Error(`Failed to create optimized buffer: ${width}x${height}`);
3607
- }
3608
- const size = width * height;
3609
- const buffers = this.getBuffer(bufferPtr, size);
3610
- return new OptimizedBuffer(this, bufferPtr, buffers, width, height, { respectAlpha });
3611
- }
3612
- destroyOptimizedBuffer(bufferPtr) {
3613
- this.opentui.symbols.destroyOptimizedBuffer(bufferPtr);
3614
- }
3615
- drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, sourceX, sourceY, sourceWidth, sourceHeight) {
3616
- const srcX = sourceX ?? 0;
3617
- const srcY = sourceY ?? 0;
3618
- const srcWidth = sourceWidth ?? 0;
3619
- const srcHeight = sourceHeight ?? 0;
3620
- this.opentui.symbols.drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, srcX, srcY, srcWidth, srcHeight);
3621
- }
3622
- setDebugOverlay(renderer, enabled, corner) {
3623
- this.opentui.symbols.setDebugOverlay(renderer, enabled, corner);
3624
- }
3625
- clearTerminal(renderer) {
3626
- this.opentui.symbols.clearTerminal(renderer);
3627
- }
3628
- addToHitGrid(renderer, x, y, width, height, id) {
3629
- this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id);
3630
- }
3631
- checkHit(renderer, x, y) {
3632
- return this.opentui.symbols.checkHit(renderer, x, y);
3633
- }
3634
- dumpHitGrid(renderer) {
3635
- this.opentui.symbols.dumpHitGrid(renderer);
3636
- }
3637
- dumpBuffers(renderer, timestamp) {
3638
- const ts = timestamp ?? Date.now();
3639
- this.opentui.symbols.dumpBuffers(renderer, ts);
3640
- }
3641
- dumpStdoutBuffer(renderer, timestamp) {
3642
- const ts = timestamp ?? Date.now();
3643
- this.opentui.symbols.dumpStdoutBuffer(renderer, ts);
3644
- }
3645
- enableMouse(renderer, enableMovement) {
3646
- this.opentui.symbols.enableMouse(renderer, enableMovement);
3647
- }
3648
- disableMouse(renderer) {
3649
- this.opentui.symbols.disableMouse(renderer);
3650
- }
3651
- createTextBuffer(capacity) {
3652
- const bufferPtr = this.opentui.symbols.createTextBuffer(capacity);
3653
- if (!bufferPtr) {
3654
- throw new Error(`Failed to create TextBuffer with capacity ${capacity}`);
3655
- }
3656
- const charPtr = this.textBufferGetCharPtr(bufferPtr);
3657
- const fgPtr = this.textBufferGetFgPtr(bufferPtr);
3658
- const bgPtr = this.textBufferGetBgPtr(bufferPtr);
3659
- const attributesPtr = this.textBufferGetAttributesPtr(bufferPtr);
3660
- const buffer = {
3661
- char: new Uint32Array(toArrayBuffer(charPtr, 0, capacity * 4)),
3662
- fg: new Float32Array(toArrayBuffer(fgPtr, 0, capacity * 4 * 4)),
3663
- bg: new Float32Array(toArrayBuffer(bgPtr, 0, capacity * 4 * 4)),
3664
- attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, capacity * 2))
3665
- };
3666
- return new TextBuffer(this, bufferPtr, buffer, capacity);
3667
- }
3668
- destroyTextBuffer(buffer) {
3669
- this.opentui.symbols.destroyTextBuffer(buffer);
3670
- }
3671
- textBufferGetCharPtr(buffer) {
3672
- const ptr = this.opentui.symbols.textBufferGetCharPtr(buffer);
3673
- if (!ptr) {
3674
- throw new Error("Failed to get TextBuffer char pointer");
3675
- }
3676
- return ptr;
3677
- }
3678
- textBufferGetFgPtr(buffer) {
3679
- const ptr = this.opentui.symbols.textBufferGetFgPtr(buffer);
3680
- if (!ptr) {
3681
- throw new Error("Failed to get TextBuffer fg pointer");
3682
- }
3683
- return ptr;
3684
- }
3685
- textBufferGetBgPtr(buffer) {
3686
- const ptr = this.opentui.symbols.textBufferGetBgPtr(buffer);
3687
- if (!ptr) {
3688
- throw new Error("Failed to get TextBuffer bg pointer");
3689
- }
3690
- return ptr;
3691
- }
3692
- textBufferGetAttributesPtr(buffer) {
3693
- const ptr = this.opentui.symbols.textBufferGetAttributesPtr(buffer);
3694
- if (!ptr) {
3695
- throw new Error("Failed to get TextBuffer attributes pointer");
3696
- }
3697
- return ptr;
3698
- }
3699
- textBufferGetLength(buffer) {
3700
- return this.opentui.symbols.textBufferGetLength(buffer);
3701
- }
3702
- textBufferSetCell(buffer, index, char, fg, bg, attr) {
3703
- this.opentui.symbols.textBufferSetCell(buffer, index, char, fg, bg, attr);
3704
- }
3705
- textBufferConcat(buffer1, buffer2) {
3706
- const resultPtr = this.opentui.symbols.textBufferConcat(buffer1, buffer2);
3707
- if (!resultPtr) {
3708
- throw new Error("Failed to concatenate TextBuffers");
3709
- }
3710
- const length = this.textBufferGetLength(resultPtr);
3711
- const charPtr = this.textBufferGetCharPtr(resultPtr);
3712
- const fgPtr = this.textBufferGetFgPtr(resultPtr);
3713
- const bgPtr = this.textBufferGetBgPtr(resultPtr);
3714
- const attributesPtr = this.textBufferGetAttributesPtr(resultPtr);
3715
- const buffer = {
3716
- char: new Uint32Array(toArrayBuffer(charPtr, 0, length * 4)),
3717
- fg: new Float32Array(toArrayBuffer(fgPtr, 0, length * 4 * 4)),
3718
- bg: new Float32Array(toArrayBuffer(bgPtr, 0, length * 4 * 4)),
3719
- attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, length * 2))
3720
- };
3721
- return new TextBuffer(this, resultPtr, buffer, length);
3722
- }
3723
- textBufferResize(buffer, newLength) {
3724
- this.opentui.symbols.textBufferResize(buffer, newLength);
3725
- const buffers = this.getTextBuffer(buffer, newLength);
3726
- return buffers;
3727
- }
3728
- textBufferReset(buffer) {
3729
- this.opentui.symbols.textBufferReset(buffer);
3730
- }
3731
- textBufferSetSelection(buffer, start, end, bgColor, fgColor) {
3732
- const bg = bgColor ? bgColor.buffer : null;
3733
- const fg = fgColor ? fgColor.buffer : null;
3734
- this.opentui.symbols.textBufferSetSelection(buffer, start, end, bg, fg);
3735
- }
3736
- textBufferResetSelection(buffer) {
3737
- this.opentui.symbols.textBufferResetSelection(buffer);
3738
- }
3739
- textBufferSetDefaultFg(buffer, fg) {
3740
- const fgPtr = fg ? fg.buffer : null;
3741
- this.opentui.symbols.textBufferSetDefaultFg(buffer, fgPtr);
3742
- }
3743
- textBufferSetDefaultBg(buffer, bg) {
3744
- const bgPtr = bg ? bg.buffer : null;
3745
- this.opentui.symbols.textBufferSetDefaultBg(buffer, bgPtr);
3746
- }
3747
- textBufferSetDefaultAttributes(buffer, attributes) {
3748
- const attrValue = attributes === null ? null : new Uint8Array([attributes]);
3749
- this.opentui.symbols.textBufferSetDefaultAttributes(buffer, attrValue);
3750
- }
3751
- textBufferResetDefaults(buffer) {
3752
- this.opentui.symbols.textBufferResetDefaults(buffer);
3753
- }
3754
- textBufferWriteChunk(buffer, textBytes, fg, bg, attributes) {
3755
- const attrValue = attributes === null ? null : new Uint8Array([attributes]);
3756
- return this.opentui.symbols.textBufferWriteChunk(buffer, textBytes, textBytes.length, fg ? fg.buffer : null, bg ? bg.buffer : null, attrValue);
3757
- }
3758
- textBufferGetCapacity(buffer) {
3759
- return this.opentui.symbols.textBufferGetCapacity(buffer);
3760
- }
3761
- textBufferFinalizeLineInfo(buffer) {
3762
- this.opentui.symbols.textBufferFinalizeLineInfo(buffer);
3763
- }
3764
- textBufferGetLineInfo(buffer) {
3765
- const lineCount = this.opentui.symbols.textBufferGetLineCount(buffer);
3766
- if (lineCount === 0) {
3767
- return { lineStarts: [], lineWidths: [] };
3768
- }
3769
- const lineStartsPtr = this.opentui.symbols.textBufferGetLineStartsPtr(buffer);
3770
- const lineWidthsPtr = this.opentui.symbols.textBufferGetLineWidthsPtr(buffer);
3771
- if (!lineStartsPtr || !lineWidthsPtr) {
3772
- return { lineStarts: [], lineWidths: [] };
3773
- }
3774
- const lineStartsArray = new Uint32Array(toArrayBuffer(lineStartsPtr, 0, lineCount * 4));
3775
- const lineWidthsArray = new Uint32Array(toArrayBuffer(lineWidthsPtr, 0, lineCount * 4));
3776
- const lineStarts = Array.from(lineStartsArray);
3777
- const lineWidths = Array.from(lineWidthsArray);
3778
- return { lineStarts, lineWidths };
3779
- }
3780
- getTextBufferArrays(buffer, size) {
3781
- return this.getTextBuffer(buffer, size);
3782
- }
3783
- bufferDrawTextBuffer(buffer, textBuffer, x, y, clipRect) {
3784
- const hasClipRect = clipRect !== undefined && clipRect !== null;
3785
- const clipX = clipRect?.x ?? 0;
3786
- const clipY = clipRect?.y ?? 0;
3787
- const clipWidth = clipRect?.width ?? 0;
3788
- const clipHeight = clipRect?.height ?? 0;
3789
- this.opentui.symbols.bufferDrawTextBuffer(buffer, textBuffer, x, y, clipX, clipY, clipWidth, clipHeight, hasClipRect);
3790
- }
3791
- }
3792
- var opentuiLibPath;
3793
- var opentuiLib;
3794
- function setRenderLibPath(libPath) {
3795
- opentuiLibPath = libPath;
3796
- }
3797
- function resolveRenderLib() {
3798
- if (!opentuiLib) {
3799
- opentuiLib = new FFIRenderLib(opentuiLibPath);
3800
- }
3801
- return opentuiLib;
3802
- }
3803
-
3804
- // src/lib/border.ts
3805
- var BorderChars = {
3806
- single: {
3807
- topLeft: "\u250C",
3808
- topRight: "\u2510",
3809
- bottomLeft: "\u2514",
3810
- bottomRight: "\u2518",
3811
- horizontal: "\u2500",
3812
- vertical: "\u2502",
3813
- topT: "\u252C",
3814
- bottomT: "\u2534",
3815
- leftT: "\u251C",
3816
- rightT: "\u2524",
3817
- cross: "\u253C"
3818
- },
3819
- double: {
3820
- topLeft: "\u2554",
3821
- topRight: "\u2557",
3822
- bottomLeft: "\u255A",
3823
- bottomRight: "\u255D",
3824
- horizontal: "\u2550",
3825
- vertical: "\u2551",
3826
- topT: "\u2566",
3827
- bottomT: "\u2569",
3828
- leftT: "\u2560",
3829
- rightT: "\u2563",
3830
- cross: "\u256C"
3831
- },
3832
- rounded: {
3833
- topLeft: "\u256D",
3834
- topRight: "\u256E",
3835
- bottomLeft: "\u2570",
3836
- bottomRight: "\u256F",
3837
- horizontal: "\u2500",
3838
- vertical: "\u2502",
3839
- topT: "\u252C",
3840
- bottomT: "\u2534",
3841
- leftT: "\u251C",
3842
- rightT: "\u2524",
3843
- cross: "\u253C"
3844
- },
3845
- heavy: {
3846
- topLeft: "\u250F",
3847
- topRight: "\u2513",
3848
- bottomLeft: "\u2517",
3849
- bottomRight: "\u251B",
3850
- horizontal: "\u2501",
3851
- vertical: "\u2503",
3852
- topT: "\u2533",
3853
- bottomT: "\u253B",
3854
- leftT: "\u2523",
3855
- rightT: "\u252B",
3856
- cross: "\u254B"
3857
- }
3858
- };
3859
- function getBorderFromSides(sides) {
3860
- const result = [];
3861
- if (sides.top)
3862
- result.push("top");
3863
- if (sides.right)
3864
- result.push("right");
3865
- if (sides.bottom)
3866
- result.push("bottom");
3867
- if (sides.left)
3868
- result.push("left");
3869
- return result.length > 0 ? result : false;
3870
- }
3871
- function getBorderSides(border) {
3872
- return border === true ? { top: true, right: true, bottom: true, left: true } : Array.isArray(border) ? {
3873
- top: border.includes("top"),
3874
- right: border.includes("right"),
3875
- bottom: border.includes("bottom"),
3876
- left: border.includes("left")
3877
- } : { top: false, right: false, bottom: false, left: false };
3878
- }
3879
- function borderCharsToArray(chars) {
3880
- const array = new Uint32Array(11);
3881
- array[0] = chars.topLeft.codePointAt(0);
3882
- array[1] = chars.topRight.codePointAt(0);
3883
- array[2] = chars.bottomLeft.codePointAt(0);
3884
- array[3] = chars.bottomRight.codePointAt(0);
3885
- array[4] = chars.horizontal.codePointAt(0);
3886
- array[5] = chars.vertical.codePointAt(0);
3887
- array[6] = chars.topT.codePointAt(0);
3888
- array[7] = chars.bottomT.codePointAt(0);
3889
- array[8] = chars.leftT.codePointAt(0);
3890
- array[9] = chars.rightT.codePointAt(0);
3891
- array[10] = chars.cross.codePointAt(0);
3892
- return array;
3893
- }
3894
- var BorderCharArrays = {
3895
- single: borderCharsToArray(BorderChars.single),
3896
- double: borderCharsToArray(BorderChars.double),
3897
- rounded: borderCharsToArray(BorderChars.rounded),
3898
- heavy: borderCharsToArray(BorderChars.heavy)
3899
- };
3900
3476
  // src/lib/fonts/tiny.json
3901
3477
  var tiny_default = {
3902
3478
  name: "tiny",
@@ -5286,526 +4862,1633 @@ var slick_default = {
5286
4862
  '"': ["<c1>\u256D\u256E\u256D\u256E</c1>", "<c1>\u2570\u256F\u2570\u256F</c1>", "<c2>\u2571\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571\u2571</c2>"],
5287
4863
  " ": ["<c2>\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571</c2>", "<c2>\u2571\u2571\u2571</c2>"]
5288
4864
  }
5289
- };
4865
+ };
4866
+
4867
+ // src/lib/ascii.font.ts
4868
+ var fonts = {
4869
+ tiny: tiny_default,
4870
+ block: block_default,
4871
+ shade: shade_default,
4872
+ slick: slick_default
4873
+ };
4874
+ var parsedFonts = {};
4875
+ function parseColorTags(text) {
4876
+ const segments = [];
4877
+ let currentIndex = 0;
4878
+ const colorTagRegex = /<c(\d+)>(.*?)<\/c\d+>/g;
4879
+ let lastIndex = 0;
4880
+ let match;
4881
+ while ((match = colorTagRegex.exec(text)) !== null) {
4882
+ if (match.index > lastIndex) {
4883
+ const plainText = text.slice(lastIndex, match.index);
4884
+ if (plainText) {
4885
+ segments.push({ text: plainText, colorIndex: 0 });
4886
+ }
4887
+ }
4888
+ const colorIndex = parseInt(match[1]) - 1;
4889
+ const taggedText = match[2];
4890
+ segments.push({ text: taggedText, colorIndex: Math.max(0, colorIndex) });
4891
+ lastIndex = match.index + match[0].length;
4892
+ }
4893
+ if (lastIndex < text.length) {
4894
+ const remainingText = text.slice(lastIndex);
4895
+ if (remainingText) {
4896
+ segments.push({ text: remainingText, colorIndex: 0 });
4897
+ }
4898
+ }
4899
+ return segments;
4900
+ }
4901
+ function getParsedFont(fontKey) {
4902
+ if (!parsedFonts[fontKey]) {
4903
+ const fontDef = fonts[fontKey];
4904
+ const parsedChars = {};
4905
+ for (const [char, lines] of Object.entries(fontDef.chars)) {
4906
+ parsedChars[char] = lines.map((line) => parseColorTags(line));
4907
+ }
4908
+ parsedFonts[fontKey] = {
4909
+ ...fontDef,
4910
+ colors: fontDef.colors || 1,
4911
+ chars: parsedChars
4912
+ };
4913
+ }
4914
+ return parsedFonts[fontKey];
4915
+ }
4916
+ function measureText({ text, font = "tiny" }) {
4917
+ const fontDef = getParsedFont(font);
4918
+ if (!fontDef) {
4919
+ console.warn(`Font '${font}' not found`);
4920
+ return { width: 0, height: 0 };
4921
+ }
4922
+ let currentX = 0;
4923
+ for (let i = 0;i < text.length; i++) {
4924
+ const char = text[i].toUpperCase();
4925
+ const charDef = fontDef.chars[char];
4926
+ if (!charDef) {
4927
+ const spaceChar = fontDef.chars[" "];
4928
+ if (spaceChar && spaceChar[0]) {
4929
+ let spaceWidth = 0;
4930
+ for (const segment of spaceChar[0]) {
4931
+ spaceWidth += segment.text.length;
4932
+ }
4933
+ currentX += spaceWidth;
4934
+ } else {
4935
+ currentX += 1;
4936
+ }
4937
+ continue;
4938
+ }
4939
+ let charWidth = 0;
4940
+ if (charDef[0]) {
4941
+ for (const segment of charDef[0]) {
4942
+ charWidth += segment.text.length;
4943
+ }
4944
+ }
4945
+ currentX += charWidth;
4946
+ if (i < text.length - 1) {
4947
+ currentX += fontDef.letterspace_size;
4948
+ }
4949
+ }
4950
+ return {
4951
+ width: currentX,
4952
+ height: fontDef.lines
4953
+ };
4954
+ }
4955
+ function getCharacterPositions(text, font = "tiny") {
4956
+ const fontDef = getParsedFont(font);
4957
+ if (!fontDef) {
4958
+ return [0];
4959
+ }
4960
+ const positions = [0];
4961
+ let currentX = 0;
4962
+ for (let i = 0;i < text.length; i++) {
4963
+ const char = text[i].toUpperCase();
4964
+ const charDef = fontDef.chars[char];
4965
+ let charWidth = 0;
4966
+ if (!charDef) {
4967
+ const spaceChar = fontDef.chars[" "];
4968
+ if (spaceChar && spaceChar[0]) {
4969
+ for (const segment of spaceChar[0]) {
4970
+ charWidth += segment.text.length;
4971
+ }
4972
+ } else {
4973
+ charWidth = 1;
4974
+ }
4975
+ } else if (charDef[0]) {
4976
+ for (const segment of charDef[0]) {
4977
+ charWidth += segment.text.length;
4978
+ }
4979
+ }
4980
+ currentX += charWidth;
4981
+ if (i < text.length - 1) {
4982
+ currentX += fontDef.letterspace_size;
4983
+ }
4984
+ positions.push(currentX);
4985
+ }
4986
+ return positions;
4987
+ }
4988
+ function coordinateToCharacterIndex(x, text, font = "tiny") {
4989
+ const positions = getCharacterPositions(text, font);
4990
+ if (x < 0) {
4991
+ return 0;
4992
+ }
4993
+ for (let i = 0;i < positions.length - 1; i++) {
4994
+ const currentPos = positions[i];
4995
+ const nextPos = positions[i + 1];
4996
+ if (x >= currentPos && x < nextPos) {
4997
+ const charMidpoint = currentPos + (nextPos - currentPos) / 2;
4998
+ return x < charMidpoint ? i : i + 1;
4999
+ }
5000
+ }
5001
+ if (positions.length > 0 && x >= positions[positions.length - 1]) {
5002
+ return text.length;
5003
+ }
5004
+ return 0;
5005
+ }
5006
+ function renderFontToFrameBuffer(buffer, {
5007
+ text,
5008
+ x = 0,
5009
+ y = 0,
5010
+ fg = [RGBA.fromInts(255, 255, 255, 255)],
5011
+ bg = RGBA.fromInts(0, 0, 0, 255),
5012
+ font = "tiny"
5013
+ }) {
5014
+ const width = buffer.getWidth();
5015
+ const height = buffer.getHeight();
5016
+ const fontDef = getParsedFont(font);
5017
+ if (!fontDef) {
5018
+ console.warn(`Font '${font}' not found`);
5019
+ return { width: 0, height: 0 };
5020
+ }
5021
+ const colors = Array.isArray(fg) ? fg : [fg];
5022
+ if (y < 0 || y + fontDef.lines > height) {
5023
+ return { width: 0, height: fontDef.lines };
5024
+ }
5025
+ let currentX = x;
5026
+ const startX = x;
5027
+ for (let i = 0;i < text.length; i++) {
5028
+ const char = text[i].toUpperCase();
5029
+ const charDef = fontDef.chars[char];
5030
+ if (!charDef) {
5031
+ const spaceChar = fontDef.chars[" "];
5032
+ if (spaceChar && spaceChar[0]) {
5033
+ let spaceWidth = 0;
5034
+ for (const segment of spaceChar[0]) {
5035
+ spaceWidth += segment.text.length;
5036
+ }
5037
+ currentX += spaceWidth;
5038
+ } else {
5039
+ currentX += 1;
5040
+ }
5041
+ continue;
5042
+ }
5043
+ let charWidth = 0;
5044
+ if (charDef[0]) {
5045
+ for (const segment of charDef[0]) {
5046
+ charWidth += segment.text.length;
5047
+ }
5048
+ }
5049
+ if (currentX >= width)
5050
+ break;
5051
+ if (currentX + charWidth < 0) {
5052
+ currentX += charWidth + fontDef.letterspace_size;
5053
+ continue;
5054
+ }
5055
+ for (let lineIdx = 0;lineIdx < fontDef.lines && lineIdx < charDef.length; lineIdx++) {
5056
+ const segments = charDef[lineIdx];
5057
+ const renderY = y + lineIdx;
5058
+ if (renderY >= 0 && renderY < height) {
5059
+ let segmentX = currentX;
5060
+ for (const segment of segments) {
5061
+ const segmentColor = colors[segment.colorIndex] || colors[0];
5062
+ for (let charIdx = 0;charIdx < segment.text.length; charIdx++) {
5063
+ const renderX = segmentX + charIdx;
5064
+ if (renderX >= 0 && renderX < width) {
5065
+ const fontChar = segment.text[charIdx];
5066
+ if (fontChar !== " ") {
5067
+ buffer.setCell(renderX, renderY, fontChar, segmentColor, bg);
5068
+ }
5069
+ }
5070
+ }
5071
+ segmentX += segment.text.length;
5072
+ }
5073
+ }
5074
+ }
5075
+ currentX += charWidth;
5076
+ if (i < text.length - 1) {
5077
+ currentX += fontDef.letterspace_size;
5078
+ }
5079
+ }
5080
+ return {
5081
+ width: currentX - startX,
5082
+ height: fontDef.lines
5083
+ };
5084
+ }
5085
+ // src/lib/styled-text.ts
5086
+ var textEncoder = new TextEncoder;
5087
+
5088
+ class StyledText {
5089
+ chunks;
5090
+ _plainText = "";
5091
+ constructor(chunks) {
5092
+ this.chunks = chunks;
5093
+ for (let i = 0;i < chunks.length; i++) {
5094
+ this._plainText += chunks[i].plainText;
5095
+ }
5096
+ }
5097
+ toString() {
5098
+ return this._plainText;
5099
+ }
5100
+ static _createInstance(chunks, plainText) {
5101
+ const newInstance = Object.create(StyledText.prototype);
5102
+ newInstance.chunks = chunks;
5103
+ newInstance._plainText = plainText;
5104
+ return newInstance;
5105
+ }
5106
+ static _chunksToPlainText(chunks) {
5107
+ let plainText = "";
5108
+ for (const chunk of chunks) {
5109
+ plainText += chunk.plainText;
5110
+ }
5111
+ return plainText;
5112
+ }
5113
+ insert(chunk, index) {
5114
+ const originalLength = this.chunks.length;
5115
+ let newChunks;
5116
+ let newPlainText;
5117
+ if (index === undefined) {
5118
+ newChunks = [...this.chunks, chunk];
5119
+ newPlainText = this._plainText + chunk.plainText;
5120
+ } else if (index === originalLength) {
5121
+ newChunks = [...this.chunks, chunk];
5122
+ newPlainText = this._plainText + chunk.plainText;
5123
+ } else {
5124
+ newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index)];
5125
+ newPlainText = StyledText._chunksToPlainText(newChunks);
5126
+ }
5127
+ return StyledText._createInstance(newChunks, newPlainText);
5128
+ }
5129
+ remove(chunk) {
5130
+ const originalLength = this.chunks.length;
5131
+ const index = this.chunks.indexOf(chunk);
5132
+ if (index === -1)
5133
+ return this;
5134
+ let newChunks;
5135
+ let newPlainText;
5136
+ if (index === originalLength - 1) {
5137
+ newChunks = this.chunks.slice(0, -1);
5138
+ newPlainText = this._plainText.slice(0, this._plainText.length - chunk.plainText.length);
5139
+ } else {
5140
+ newChunks = [...this.chunks.slice(0, index), ...this.chunks.slice(index + 1)];
5141
+ newPlainText = StyledText._chunksToPlainText(newChunks);
5142
+ }
5143
+ return StyledText._createInstance(newChunks, newPlainText);
5144
+ }
5145
+ replace(chunk, oldChunk) {
5146
+ const index = this.chunks.indexOf(oldChunk);
5147
+ if (index === -1)
5148
+ return this;
5149
+ let newChunks;
5150
+ let newPlainText;
5151
+ if (index === this.chunks.length - 1) {
5152
+ newChunks = [...this.chunks.slice(0, -1), chunk];
5153
+ newPlainText = this._plainText.slice(0, this._plainText.length - oldChunk.plainText.length) + chunk.plainText;
5154
+ } else {
5155
+ newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index + 1)];
5156
+ newPlainText = StyledText._chunksToPlainText(newChunks);
5157
+ }
5158
+ return StyledText._createInstance(newChunks, newPlainText);
5159
+ }
5160
+ }
5161
+ function stringToStyledText(content) {
5162
+ const textEncoder2 = new TextEncoder;
5163
+ const chunk = {
5164
+ __isChunk: true,
5165
+ text: textEncoder2.encode(content),
5166
+ plainText: content
5167
+ };
5168
+ return new StyledText([chunk]);
5169
+ }
5170
+ var templateCache = new WeakMap;
5171
+ function applyStyle(input, style) {
5172
+ if (typeof input === "object" && "__isChunk" in input) {
5173
+ const existingChunk = input;
5174
+ const fg = style.fg ? parseColor(style.fg) : existingChunk.fg;
5175
+ const bg = style.bg ? parseColor(style.bg) : existingChunk.bg;
5176
+ const newAttrs = createTextAttributes(style);
5177
+ const mergedAttrs = existingChunk.attributes ? existingChunk.attributes | newAttrs : newAttrs;
5178
+ return {
5179
+ __isChunk: true,
5180
+ text: existingChunk.text,
5181
+ plainText: existingChunk.plainText,
5182
+ fg,
5183
+ bg,
5184
+ attributes: mergedAttrs
5185
+ };
5186
+ } else {
5187
+ const plainTextStr = String(input);
5188
+ const text = textEncoder.encode(plainTextStr);
5189
+ const fg = style.fg ? parseColor(style.fg) : undefined;
5190
+ const bg = style.bg ? parseColor(style.bg) : undefined;
5191
+ const attributes = createTextAttributes(style);
5192
+ return {
5193
+ __isChunk: true,
5194
+ text,
5195
+ plainText: plainTextStr,
5196
+ fg,
5197
+ bg,
5198
+ attributes
5199
+ };
5200
+ }
5201
+ }
5202
+ var black = (input) => applyStyle(input, { fg: "black" });
5203
+ var red = (input) => applyStyle(input, { fg: "red" });
5204
+ var green = (input) => applyStyle(input, { fg: "green" });
5205
+ var yellow = (input) => applyStyle(input, { fg: "yellow" });
5206
+ var blue = (input) => applyStyle(input, { fg: "blue" });
5207
+ var magenta = (input) => applyStyle(input, { fg: "magenta" });
5208
+ var cyan = (input) => applyStyle(input, { fg: "cyan" });
5209
+ var white = (input) => applyStyle(input, { fg: "white" });
5210
+ var brightBlack = (input) => applyStyle(input, { fg: "brightBlack" });
5211
+ var brightRed = (input) => applyStyle(input, { fg: "brightRed" });
5212
+ var brightGreen = (input) => applyStyle(input, { fg: "brightGreen" });
5213
+ var brightYellow = (input) => applyStyle(input, { fg: "brightYellow" });
5214
+ var brightBlue = (input) => applyStyle(input, { fg: "brightBlue" });
5215
+ var brightMagenta = (input) => applyStyle(input, { fg: "brightMagenta" });
5216
+ var brightCyan = (input) => applyStyle(input, { fg: "brightCyan" });
5217
+ var brightWhite = (input) => applyStyle(input, { fg: "brightWhite" });
5218
+ var bgBlack = (input) => applyStyle(input, { bg: "black" });
5219
+ var bgRed = (input) => applyStyle(input, { bg: "red" });
5220
+ var bgGreen = (input) => applyStyle(input, { bg: "green" });
5221
+ var bgYellow = (input) => applyStyle(input, { bg: "yellow" });
5222
+ var bgBlue = (input) => applyStyle(input, { bg: "blue" });
5223
+ var bgMagenta = (input) => applyStyle(input, { bg: "magenta" });
5224
+ var bgCyan = (input) => applyStyle(input, { bg: "cyan" });
5225
+ var bgWhite = (input) => applyStyle(input, { bg: "white" });
5226
+ var bold = (input) => applyStyle(input, { bold: true });
5227
+ var italic = (input) => applyStyle(input, { italic: true });
5228
+ var underline = (input) => applyStyle(input, { underline: true });
5229
+ var strikethrough = (input) => applyStyle(input, { strikethrough: true });
5230
+ var dim = (input) => applyStyle(input, { dim: true });
5231
+ var reverse = (input) => applyStyle(input, { reverse: true });
5232
+ var blink = (input) => applyStyle(input, { blink: true });
5233
+ var fg = (color) => (input) => applyStyle(input, { fg: color });
5234
+ var bg = (color) => (input) => applyStyle(input, { bg: color });
5235
+ function tn(strings, ...values) {
5236
+ const chunks = [];
5237
+ let length = 0;
5238
+ let plainText = "";
5239
+ for (let i = 0;i < strings.length; i++) {
5240
+ const raw = strings[i];
5241
+ if (raw) {
5242
+ chunks.push({
5243
+ __isChunk: true,
5244
+ text: textEncoder.encode(raw),
5245
+ plainText: raw,
5246
+ attributes: 0
5247
+ });
5248
+ length += raw.length;
5249
+ plainText += raw;
5250
+ }
5251
+ const val = values[i];
5252
+ if (typeof val === "object" && "__isChunk" in val) {
5253
+ chunks.push(val);
5254
+ length += val.plainText.length;
5255
+ plainText += val.plainText;
5256
+ } else if (val !== undefined) {
5257
+ const plainTextStr = String(val);
5258
+ chunks.push({
5259
+ __isChunk: true,
5260
+ text: textEncoder.encode(plainTextStr),
5261
+ plainText: plainTextStr,
5262
+ attributes: 0
5263
+ });
5264
+ length += plainTextStr.length;
5265
+ plainText += plainTextStr;
5266
+ }
5267
+ }
5268
+ return new StyledText(chunks);
5269
+ }
5270
+ function t(strings, ...values) {
5271
+ let cachedStringChunks = templateCache.get(strings);
5272
+ let length = 0;
5273
+ let plainText = "";
5274
+ if (!cachedStringChunks) {
5275
+ cachedStringChunks = [];
5276
+ for (let i = 0;i < strings.length; i++) {
5277
+ const raw = strings[i];
5278
+ if (raw) {
5279
+ cachedStringChunks.push({
5280
+ __isChunk: true,
5281
+ text: textEncoder.encode(raw),
5282
+ plainText: raw,
5283
+ attributes: 0
5284
+ });
5285
+ } else {
5286
+ cachedStringChunks.push(null);
5287
+ }
5288
+ }
5289
+ templateCache.set(strings, cachedStringChunks);
5290
+ }
5291
+ const chunks = [];
5292
+ for (let i = 0;i < strings.length; i++) {
5293
+ const stringChunk = cachedStringChunks[i];
5294
+ if (stringChunk) {
5295
+ chunks.push(stringChunk);
5296
+ length += stringChunk.plainText.length;
5297
+ plainText += stringChunk.plainText;
5298
+ }
5299
+ const val = values[i];
5300
+ if (typeof val === "object" && "__isChunk" in val) {
5301
+ chunks.push(val);
5302
+ length += val.plainText.length;
5303
+ plainText += val.plainText;
5304
+ } else if (val !== undefined) {
5305
+ const plainTextStr = String(val);
5306
+ chunks.push({
5307
+ __isChunk: true,
5308
+ text: textEncoder.encode(plainTextStr),
5309
+ plainText: plainTextStr,
5310
+ attributes: 0
5311
+ });
5312
+ length += plainTextStr.length;
5313
+ plainText += plainTextStr;
5314
+ }
5315
+ }
5316
+ return new StyledText(chunks);
5317
+ }
5318
+
5319
+ // src/lib/hast-styled-text.ts
5320
+ class SyntaxStyle {
5321
+ styles;
5322
+ mergedStyleCache;
5323
+ constructor(styles) {
5324
+ this.styles = styles;
5325
+ this.mergedStyleCache = new Map;
5326
+ }
5327
+ mergeStyles(...styleNames) {
5328
+ const cacheKey = styleNames.join(":");
5329
+ const cached = this.mergedStyleCache.get(cacheKey);
5330
+ if (cached)
5331
+ return cached;
5332
+ const styleDefinition = {};
5333
+ for (const name of styleNames) {
5334
+ const style = this.styles[name];
5335
+ if (!style)
5336
+ continue;
5337
+ if (style.fg)
5338
+ styleDefinition.fg = style.fg;
5339
+ if (style.bg)
5340
+ styleDefinition.bg = style.bg;
5341
+ if (style.bold !== undefined)
5342
+ styleDefinition.bold = style.bold;
5343
+ if (style.italic !== undefined)
5344
+ styleDefinition.italic = style.italic;
5345
+ if (style.underline !== undefined)
5346
+ styleDefinition.underline = style.underline;
5347
+ if (style.dim !== undefined)
5348
+ styleDefinition.dim = style.dim;
5349
+ }
5350
+ const attributes = createTextAttributes({
5351
+ bold: styleDefinition.bold,
5352
+ italic: styleDefinition.italic,
5353
+ underline: styleDefinition.underline,
5354
+ dim: styleDefinition.dim
5355
+ });
5356
+ const merged = {
5357
+ fg: styleDefinition.fg,
5358
+ bg: styleDefinition.bg,
5359
+ attributes
5360
+ };
5361
+ this.mergedStyleCache.set(cacheKey, merged);
5362
+ return merged;
5363
+ }
5364
+ clearCache() {
5365
+ this.mergedStyleCache.clear();
5366
+ }
5367
+ getCacheSize() {
5368
+ return this.mergedStyleCache.size;
5369
+ }
5370
+ }
5371
+ var textEncoder2 = new TextEncoder;
5372
+ function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
5373
+ const chunks = [];
5374
+ if (node.type === "text") {
5375
+ const stylesToMerge = parentStyles.length > 0 ? parentStyles : ["default"];
5376
+ const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge);
5377
+ chunks.push({
5378
+ __isChunk: true,
5379
+ text: textEncoder2.encode(node.value),
5380
+ plainText: node.value,
5381
+ fg: mergedStyle.fg,
5382
+ bg: mergedStyle.bg,
5383
+ attributes: mergedStyle.attributes
5384
+ });
5385
+ } else if (node.type === "element") {
5386
+ let currentStyles = [...parentStyles];
5387
+ if (node.properties?.className) {
5388
+ const classes = node.properties.className.split(" ");
5389
+ for (const cls of classes) {
5390
+ currentStyles.push(cls);
5391
+ }
5392
+ }
5393
+ for (const child of node.children) {
5394
+ chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles));
5395
+ }
5396
+ }
5397
+ return chunks;
5398
+ }
5399
+ function hastToStyledText(hast, syntaxStyle) {
5400
+ const chunks = hastToTextChunks(hast, syntaxStyle);
5401
+ return new StyledText(chunks);
5402
+ }
5403
+ // src/lib/parse.mouse.ts
5404
+ class MouseParser {
5405
+ mouseButtonsPressed = new Set;
5406
+ static SCROLL_DIRECTIONS = {
5407
+ 64: "up",
5408
+ 65: "down",
5409
+ 66: "left",
5410
+ 67: "right"
5411
+ };
5412
+ reset() {
5413
+ this.mouseButtonsPressed.clear();
5414
+ }
5415
+ parseMouseEvent(data) {
5416
+ const str = data.toString();
5417
+ const sgrMatch = str.match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);
5418
+ if (sgrMatch) {
5419
+ const [, buttonCode, x, y, pressRelease] = sgrMatch;
5420
+ const rawButtonCode = parseInt(buttonCode);
5421
+ const scrollDirection = MouseParser.SCROLL_DIRECTIONS[rawButtonCode];
5422
+ const isScroll = scrollDirection !== undefined;
5423
+ const button = rawButtonCode & 3;
5424
+ const isMotion = (rawButtonCode & 32) !== 0;
5425
+ const modifiers = {
5426
+ shift: (rawButtonCode & 4) !== 0,
5427
+ alt: (rawButtonCode & 8) !== 0,
5428
+ ctrl: (rawButtonCode & 16) !== 0
5429
+ };
5430
+ let type;
5431
+ let scrollInfo;
5432
+ if (isScroll && pressRelease === "M") {
5433
+ type = "scroll";
5434
+ scrollInfo = {
5435
+ direction: scrollDirection,
5436
+ delta: 1
5437
+ };
5438
+ } else if (isMotion) {
5439
+ const isDragging = this.mouseButtonsPressed.size > 0;
5440
+ if (button === 3) {
5441
+ type = "move";
5442
+ } else if (isDragging) {
5443
+ type = "drag";
5444
+ } else {
5445
+ type = "move";
5446
+ }
5447
+ } else {
5448
+ type = pressRelease === "M" ? "down" : "up";
5449
+ if (type === "down" && button !== 3) {
5450
+ this.mouseButtonsPressed.add(button);
5451
+ } else if (type === "up") {
5452
+ this.mouseButtonsPressed.clear();
5453
+ }
5454
+ }
5455
+ return {
5456
+ type,
5457
+ button: button === 3 ? 0 : button,
5458
+ x: parseInt(x) - 1,
5459
+ y: parseInt(y) - 1,
5460
+ modifiers,
5461
+ scroll: scrollInfo
5462
+ };
5463
+ }
5464
+ if (str.startsWith("\x1B[M") && str.length >= 6) {
5465
+ const buttonByte = str.charCodeAt(3) - 32;
5466
+ const x = str.charCodeAt(4) - 33;
5467
+ const y = str.charCodeAt(5) - 33;
5468
+ const scrollDirection = MouseParser.SCROLL_DIRECTIONS[buttonByte];
5469
+ const isScroll = scrollDirection !== undefined;
5470
+ const button = buttonByte & 3;
5471
+ const modifiers = {
5472
+ shift: (buttonByte & 4) !== 0,
5473
+ alt: (buttonByte & 8) !== 0,
5474
+ ctrl: (buttonByte & 16) !== 0
5475
+ };
5476
+ let type;
5477
+ let actualButton;
5478
+ let scrollInfo;
5479
+ if (isScroll) {
5480
+ type = "scroll";
5481
+ actualButton = 0;
5482
+ scrollInfo = {
5483
+ direction: scrollDirection,
5484
+ delta: 1
5485
+ };
5486
+ } else {
5487
+ type = button === 3 ? "up" : "down";
5488
+ actualButton = button === 3 ? 0 : button;
5489
+ }
5490
+ return {
5491
+ type,
5492
+ button: actualButton,
5493
+ x,
5494
+ y,
5495
+ modifiers,
5496
+ scroll: scrollInfo
5497
+ };
5498
+ }
5499
+ return null;
5500
+ }
5501
+ }
5502
+ // src/lib/selection.ts
5503
+ class Selection {
5504
+ _anchor;
5505
+ _focus;
5506
+ _selectedRenderables = [];
5507
+ constructor(anchor, focus) {
5508
+ this._anchor = { ...anchor };
5509
+ this._focus = { ...focus };
5510
+ }
5511
+ get anchor() {
5512
+ return { ...this._anchor };
5513
+ }
5514
+ get focus() {
5515
+ return { ...this._focus };
5516
+ }
5517
+ get bounds() {
5518
+ return {
5519
+ startX: Math.min(this._anchor.x, this._focus.x),
5520
+ startY: Math.min(this._anchor.y, this._focus.y),
5521
+ endX: Math.max(this._anchor.x, this._focus.x),
5522
+ endY: Math.max(this._anchor.y, this._focus.y)
5523
+ };
5524
+ }
5525
+ updateSelectedRenderables(selectedRenderables) {
5526
+ this._selectedRenderables = selectedRenderables;
5527
+ }
5528
+ getSelectedText() {
5529
+ const selectedTexts = this._selectedRenderables.sort((a, b) => {
5530
+ const aY = a.y;
5531
+ const bY = b.y;
5532
+ if (aY !== bY) {
5533
+ return aY - bY;
5534
+ }
5535
+ return a.x - b.x;
5536
+ }).map((renderable) => renderable.getSelectedText()).filter((text) => text);
5537
+ return selectedTexts.join(`
5538
+ `);
5539
+ }
5540
+ }
5541
+
5542
+ class TextSelectionHelper {
5543
+ getX;
5544
+ getY;
5545
+ getTextLength;
5546
+ getLineInfo;
5547
+ localSelection = null;
5548
+ cachedGlobalSelection = null;
5549
+ constructor(getX, getY, getTextLength, getLineInfo) {
5550
+ this.getX = getX;
5551
+ this.getY = getY;
5552
+ this.getTextLength = getTextLength;
5553
+ this.getLineInfo = getLineInfo;
5554
+ }
5555
+ hasSelection() {
5556
+ return this.localSelection !== null;
5557
+ }
5558
+ getSelection() {
5559
+ return this.localSelection;
5560
+ }
5561
+ reevaluateSelection(width, height = 1) {
5562
+ if (!this.cachedGlobalSelection) {
5563
+ return false;
5564
+ }
5565
+ return this.onSelectionChanged(this.cachedGlobalSelection, width, height);
5566
+ }
5567
+ shouldStartSelection(x, y, width, height) {
5568
+ const localX = x - this.getX();
5569
+ const localY = y - this.getY();
5570
+ return localX >= 0 && localX < width && localY >= 0 && localY < height;
5571
+ }
5572
+ onSelectionChanged(selection, width, height = 1) {
5573
+ this.cachedGlobalSelection = selection;
5574
+ const previousSelection = this.localSelection;
5575
+ if (!selection?.isActive) {
5576
+ this.localSelection = null;
5577
+ return previousSelection !== null;
5578
+ }
5579
+ const myY = this.getY();
5580
+ const myEndY = myY + height - 1;
5581
+ if (myEndY < selection.anchor.y || myY > selection.focus.y) {
5582
+ this.localSelection = null;
5583
+ return previousSelection !== null;
5584
+ }
5585
+ if (height === 1) {
5586
+ this.localSelection = this.calculateSingleLineSelection(myY, selection.anchor.y, selection.focus.y, selection.anchor.x, selection.focus.x, width);
5587
+ } else {
5588
+ this.localSelection = this.calculateMultiLineSelection(myY, selection.anchor.y, selection.focus.y, selection.anchor.x, selection.focus.x);
5589
+ }
5590
+ return this.localSelection !== null !== (previousSelection !== null) || this.localSelection?.start !== previousSelection?.start || this.localSelection?.end !== previousSelection?.end;
5591
+ }
5592
+ calculateSingleLineSelection(lineY, anchorY, focusY, anchorX, focusX, width) {
5593
+ const textLength = this.getTextLength();
5594
+ const myX = this.getX();
5595
+ if (lineY > anchorY && lineY < focusY) {
5596
+ return { start: 0, end: textLength };
5597
+ }
5598
+ if (lineY === anchorY && lineY === focusY) {
5599
+ const start = Math.max(0, Math.min(anchorX - myX, textLength));
5600
+ const end = Math.max(0, Math.min(focusX - myX, textLength));
5601
+ return start < end ? { start, end } : null;
5602
+ }
5603
+ if (lineY === anchorY) {
5604
+ const start = Math.max(0, Math.min(anchorX - myX, textLength));
5605
+ return start < textLength ? { start, end: textLength } : null;
5606
+ }
5607
+ if (lineY === focusY) {
5608
+ const end = Math.max(0, Math.min(focusX - myX, textLength));
5609
+ return end > 0 ? { start: 0, end } : null;
5610
+ }
5611
+ return null;
5612
+ }
5613
+ calculateMultiLineSelection(startY, anchorY, focusY, anchorX, focusX) {
5614
+ const lineInfo = this.getLineInfo?.();
5615
+ if (!lineInfo) {
5616
+ return { start: 0, end: this.getTextLength() };
5617
+ }
5618
+ const myX = this.getX();
5619
+ let selectionStart = null;
5620
+ let selectionEnd = null;
5621
+ for (let i = 0;i < lineInfo.lineStarts.length; i++) {
5622
+ const lineY = startY + i;
5623
+ if (lineY < anchorY || lineY > focusY)
5624
+ continue;
5625
+ const lineStart = lineInfo.lineStarts[i];
5626
+ const lineEnd = i < lineInfo.lineStarts.length - 1 ? lineInfo.lineStarts[i + 1] - 1 : this.getTextLength();
5627
+ const lineWidth = lineInfo.lineWidths[i];
5628
+ if (lineY > anchorY && lineY < focusY) {
5629
+ if (selectionStart === null)
5630
+ selectionStart = lineStart;
5631
+ selectionEnd = lineEnd;
5632
+ } else if (lineY === anchorY && lineY === focusY) {
5633
+ const localStartX = Math.max(0, Math.min(anchorX - myX, lineWidth));
5634
+ const localEndX = Math.max(0, Math.min(focusX - myX, lineWidth));
5635
+ if (localStartX < localEndX) {
5636
+ selectionStart = lineStart + localStartX;
5637
+ selectionEnd = lineStart + localEndX;
5638
+ }
5639
+ } else if (lineY === anchorY) {
5640
+ const localStartX = Math.max(0, Math.min(anchorX - myX, lineWidth));
5641
+ if (localStartX < lineWidth) {
5642
+ selectionStart = lineStart + localStartX;
5643
+ selectionEnd = lineEnd;
5644
+ }
5645
+ } else if (lineY === focusY) {
5646
+ const localEndX = Math.max(0, Math.min(focusX - myX, lineWidth));
5647
+ if (localEndX > 0) {
5648
+ if (selectionStart === null)
5649
+ selectionStart = lineStart;
5650
+ selectionEnd = lineStart + localEndX;
5651
+ }
5652
+ }
5653
+ }
5654
+ return selectionStart !== null && selectionEnd !== null && selectionStart < selectionEnd ? { start: selectionStart, end: selectionEnd } : null;
5655
+ }
5656
+ }
5657
+
5658
+ class ASCIIFontSelectionHelper {
5659
+ getX;
5660
+ getY;
5661
+ getText;
5662
+ getFont;
5663
+ localSelection = null;
5664
+ cachedGlobalSelection = null;
5665
+ constructor(getX, getY, getText, getFont) {
5666
+ this.getX = getX;
5667
+ this.getY = getY;
5668
+ this.getText = getText;
5669
+ this.getFont = getFont;
5670
+ }
5671
+ hasSelection() {
5672
+ return this.localSelection !== null;
5673
+ }
5674
+ getSelection() {
5675
+ return this.localSelection;
5676
+ }
5677
+ shouldStartSelection(x, y, width, height) {
5678
+ const localX = x - this.getX();
5679
+ const localY = y - this.getY();
5680
+ if (localX < 0 || localX >= width || localY < 0 || localY >= height) {
5681
+ return false;
5682
+ }
5683
+ const text = this.getText();
5684
+ const font = this.getFont();
5685
+ const charIndex = coordinateToCharacterIndex(localX, text, font);
5686
+ return charIndex >= 0 && charIndex <= text.length;
5687
+ }
5688
+ onSelectionChanged(selection, width, height) {
5689
+ this.cachedGlobalSelection = selection;
5690
+ const previousSelection = this.localSelection;
5691
+ if (!selection?.isActive) {
5692
+ this.localSelection = null;
5693
+ return previousSelection !== null;
5694
+ }
5695
+ const myX = this.getX();
5696
+ const myY = this.getY();
5697
+ const myEndY = myY + height - 1;
5698
+ const text = this.getText();
5699
+ const font = this.getFont();
5700
+ let selStart;
5701
+ let selEnd;
5702
+ if (selection.anchor.y < selection.focus.y || selection.anchor.y === selection.focus.y && selection.anchor.x <= selection.focus.x) {
5703
+ selStart = selection.anchor;
5704
+ selEnd = selection.focus;
5705
+ } else {
5706
+ selStart = selection.focus;
5707
+ selEnd = selection.anchor;
5708
+ }
5709
+ if (myEndY < selStart.y || myY > selEnd.y) {
5710
+ this.localSelection = null;
5711
+ return previousSelection !== null;
5712
+ }
5713
+ let startCharIndex = 0;
5714
+ let endCharIndex = text.length;
5715
+ if (selStart.y > myEndY) {
5716
+ this.localSelection = null;
5717
+ return previousSelection !== null;
5718
+ } else if (selStart.y >= myY && selStart.y <= myEndY) {
5719
+ const localX = selStart.x - myX;
5720
+ if (localX > 0) {
5721
+ startCharIndex = coordinateToCharacterIndex(localX, text, font);
5722
+ }
5723
+ }
5724
+ if (selEnd.y < myY) {
5725
+ this.localSelection = null;
5726
+ return previousSelection !== null;
5727
+ } else if (selEnd.y >= myY && selEnd.y <= myEndY) {
5728
+ const localX = selEnd.x - myX;
5729
+ if (localX >= 0) {
5730
+ endCharIndex = coordinateToCharacterIndex(localX, text, font);
5731
+ } else {
5732
+ endCharIndex = 0;
5733
+ }
5734
+ }
5735
+ if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) {
5736
+ this.localSelection = { start: startCharIndex, end: endCharIndex };
5737
+ } else {
5738
+ this.localSelection = null;
5739
+ }
5740
+ return this.localSelection !== null !== (previousSelection !== null) || this.localSelection?.start !== previousSelection?.start || this.localSelection?.end !== previousSelection?.end;
5741
+ }
5742
+ reevaluateSelection(width, height) {
5743
+ if (!this.cachedGlobalSelection) {
5744
+ return false;
5745
+ }
5746
+ return this.onSelectionChanged(this.cachedGlobalSelection, width, height);
5747
+ }
5748
+ }
5749
+ // src/zig.ts
5750
+ import { dlopen, toArrayBuffer } from "bun:ffi";
5751
+ import { existsSync } from "fs";
5752
+
5753
+ // src/text-buffer.ts
5754
+ class TextBuffer {
5755
+ lib;
5756
+ bufferPtr;
5757
+ buffer;
5758
+ _length = 0;
5759
+ _capacity;
5760
+ _lineInfo;
5761
+ constructor(lib, ptr, buffer, capacity) {
5762
+ this.lib = lib;
5763
+ this.bufferPtr = ptr;
5764
+ this.buffer = buffer;
5765
+ this._capacity = capacity;
5766
+ }
5767
+ static create(capacity = 256) {
5768
+ const lib = resolveRenderLib();
5769
+ return lib.createTextBuffer(capacity);
5770
+ }
5771
+ syncBuffersAfterResize() {
5772
+ const capacity = this.lib.textBufferGetCapacity(this.bufferPtr);
5773
+ this.buffer = this.lib.getTextBufferArrays(this.bufferPtr, capacity);
5774
+ this._capacity = capacity;
5775
+ }
5776
+ setStyledText(text) {
5777
+ this.lib.textBufferReset(this.bufferPtr);
5778
+ this._length = 0;
5779
+ this._lineInfo = undefined;
5780
+ for (const chunk of text.chunks) {
5781
+ const result = this.lib.textBufferWriteChunk(this.bufferPtr, chunk.text, chunk.fg || null, chunk.bg || null, chunk.attributes ?? null);
5782
+ if (result & 1) {
5783
+ this.syncBuffersAfterResize();
5784
+ }
5785
+ }
5786
+ this.lib.textBufferFinalizeLineInfo(this.bufferPtr);
5787
+ this._length = this.lib.textBufferGetLength(this.bufferPtr);
5788
+ }
5789
+ setDefaultFg(fg2) {
5790
+ this.lib.textBufferSetDefaultFg(this.bufferPtr, fg2);
5791
+ }
5792
+ setDefaultBg(bg2) {
5793
+ this.lib.textBufferSetDefaultBg(this.bufferPtr, bg2);
5794
+ }
5795
+ setDefaultAttributes(attributes) {
5796
+ this.lib.textBufferSetDefaultAttributes(this.bufferPtr, attributes);
5797
+ }
5798
+ resetDefaults() {
5799
+ this.lib.textBufferResetDefaults(this.bufferPtr);
5800
+ }
5801
+ get length() {
5802
+ return this._length;
5803
+ }
5804
+ get capacity() {
5805
+ return this._capacity;
5806
+ }
5807
+ get ptr() {
5808
+ return this.bufferPtr;
5809
+ }
5810
+ get lineInfo() {
5811
+ if (!this._lineInfo) {
5812
+ this._lineInfo = this.lib.textBufferGetLineInfo(this.bufferPtr);
5813
+ }
5814
+ return this._lineInfo;
5815
+ }
5816
+ toString() {
5817
+ const chars = [];
5818
+ for (let i = 0;i < this._length; i++) {
5819
+ chars.push(String.fromCharCode(this.buffer.char[i]));
5820
+ }
5821
+ return chars.join("");
5822
+ }
5823
+ concat(other) {
5824
+ return this.lib.textBufferConcat(this.bufferPtr, other.bufferPtr);
5825
+ }
5826
+ setSelection(start, end, bgColor, fgColor) {
5827
+ this.lib.textBufferSetSelection(this.bufferPtr, start, end, bgColor || null, fgColor || null);
5828
+ }
5829
+ resetSelection() {
5830
+ this.lib.textBufferResetSelection(this.bufferPtr);
5831
+ }
5832
+ destroy() {
5833
+ this.lib.destroyTextBuffer(this.bufferPtr);
5834
+ }
5835
+ }
5836
+
5837
+ // src/zig.ts
5838
+ var module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`);
5839
+ var targetLibPath = module.default;
5840
+ if (!existsSync(targetLibPath)) {
5841
+ throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
5842
+ }
5843
+ function getOpenTUILib(libPath) {
5844
+ const resolvedLibPath = libPath || targetLibPath;
5845
+ return dlopen(resolvedLibPath, {
5846
+ createRenderer: {
5847
+ args: ["u32", "u32"],
5848
+ returns: "ptr"
5849
+ },
5850
+ destroyRenderer: {
5851
+ args: ["ptr", "bool", "u32"],
5852
+ returns: "void"
5853
+ },
5854
+ setUseThread: {
5855
+ args: ["ptr", "bool"],
5856
+ returns: "void"
5857
+ },
5858
+ setBackgroundColor: {
5859
+ args: ["ptr", "ptr"],
5860
+ returns: "void"
5861
+ },
5862
+ setRenderOffset: {
5863
+ args: ["ptr", "u32"],
5864
+ returns: "void"
5865
+ },
5866
+ updateStats: {
5867
+ args: ["ptr", "f64", "u32", "f64"],
5868
+ returns: "void"
5869
+ },
5870
+ updateMemoryStats: {
5871
+ args: ["ptr", "u32", "u32", "u32"],
5872
+ returns: "void"
5873
+ },
5874
+ render: {
5875
+ args: ["ptr", "bool"],
5876
+ returns: "void"
5877
+ },
5878
+ getNextBuffer: {
5879
+ args: ["ptr"],
5880
+ returns: "ptr"
5881
+ },
5882
+ getCurrentBuffer: {
5883
+ args: ["ptr"],
5884
+ returns: "ptr"
5885
+ },
5886
+ createOptimizedBuffer: {
5887
+ args: ["u32", "u32", "bool"],
5888
+ returns: "ptr"
5889
+ },
5890
+ destroyOptimizedBuffer: {
5891
+ args: ["ptr"],
5892
+ returns: "void"
5893
+ },
5894
+ drawFrameBuffer: {
5895
+ args: ["ptr", "i32", "i32", "ptr", "u32", "u32", "u32", "u32"],
5896
+ returns: "void"
5897
+ },
5898
+ getBufferWidth: {
5899
+ args: ["ptr"],
5900
+ returns: "u32"
5901
+ },
5902
+ getBufferHeight: {
5903
+ args: ["ptr"],
5904
+ returns: "u32"
5905
+ },
5906
+ bufferClear: {
5907
+ args: ["ptr", "ptr"],
5908
+ returns: "void"
5909
+ },
5910
+ bufferGetCharPtr: {
5911
+ args: ["ptr"],
5912
+ returns: "ptr"
5913
+ },
5914
+ bufferGetFgPtr: {
5915
+ args: ["ptr"],
5916
+ returns: "ptr"
5917
+ },
5918
+ bufferGetBgPtr: {
5919
+ args: ["ptr"],
5920
+ returns: "ptr"
5921
+ },
5922
+ bufferGetAttributesPtr: {
5923
+ args: ["ptr"],
5924
+ returns: "ptr"
5925
+ },
5926
+ bufferGetRespectAlpha: {
5927
+ args: ["ptr"],
5928
+ returns: "bool"
5929
+ },
5930
+ bufferSetRespectAlpha: {
5931
+ args: ["ptr", "bool"],
5932
+ returns: "void"
5933
+ },
5934
+ bufferDrawText: {
5935
+ args: ["ptr", "ptr", "u32", "u32", "u32", "ptr", "ptr", "u8"],
5936
+ returns: "void"
5937
+ },
5938
+ bufferSetCellWithAlphaBlending: {
5939
+ args: ["ptr", "u32", "u32", "u32", "ptr", "ptr", "u8"],
5940
+ returns: "void"
5941
+ },
5942
+ bufferFillRect: {
5943
+ args: ["ptr", "u32", "u32", "u32", "u32", "ptr"],
5944
+ returns: "void"
5945
+ },
5946
+ bufferResize: {
5947
+ args: ["ptr", "u32", "u32"],
5948
+ returns: "void"
5949
+ },
5950
+ resizeRenderer: {
5951
+ args: ["ptr", "u32", "u32"],
5952
+ returns: "void"
5953
+ },
5954
+ setCursorPosition: {
5955
+ args: ["i32", "i32", "bool"],
5956
+ returns: "void"
5957
+ },
5958
+ setCursorStyle: {
5959
+ args: ["ptr", "u32", "bool"],
5960
+ returns: "void"
5961
+ },
5962
+ setCursorColor: {
5963
+ args: ["ptr"],
5964
+ returns: "void"
5965
+ },
5966
+ setDebugOverlay: {
5967
+ args: ["ptr", "bool", "u8"],
5968
+ returns: "void"
5969
+ },
5970
+ clearTerminal: {
5971
+ args: ["ptr"],
5972
+ returns: "void"
5973
+ },
5974
+ bufferDrawSuperSampleBuffer: {
5975
+ args: ["ptr", "u32", "u32", "ptr", "usize", "u8", "u32"],
5976
+ returns: "void"
5977
+ },
5978
+ bufferDrawPackedBuffer: {
5979
+ args: ["ptr", "ptr", "usize", "u32", "u32", "u32", "u32"],
5980
+ returns: "void"
5981
+ },
5982
+ bufferDrawBox: {
5983
+ args: ["ptr", "i32", "i32", "u32", "u32", "ptr", "u32", "ptr", "ptr", "ptr", "u32"],
5984
+ returns: "void"
5985
+ },
5986
+ addToHitGrid: {
5987
+ args: ["ptr", "i32", "i32", "u32", "u32", "u32"],
5988
+ returns: "void"
5989
+ },
5990
+ checkHit: {
5991
+ args: ["ptr", "u32", "u32"],
5992
+ returns: "u32"
5993
+ },
5994
+ dumpHitGrid: {
5995
+ args: ["ptr"],
5996
+ returns: "void"
5997
+ },
5998
+ dumpBuffers: {
5999
+ args: ["ptr", "i64"],
6000
+ returns: "void"
6001
+ },
6002
+ dumpStdoutBuffer: {
6003
+ args: ["ptr", "i64"],
6004
+ returns: "void"
6005
+ },
6006
+ enableMouse: {
6007
+ args: ["ptr", "bool"],
6008
+ returns: "void"
6009
+ },
6010
+ disableMouse: {
6011
+ args: ["ptr"],
6012
+ returns: "void"
6013
+ },
6014
+ createTextBuffer: {
6015
+ args: ["u32"],
6016
+ returns: "ptr"
6017
+ },
6018
+ destroyTextBuffer: {
6019
+ args: ["ptr"],
6020
+ returns: "void"
6021
+ },
6022
+ textBufferGetCharPtr: {
6023
+ args: ["ptr"],
6024
+ returns: "ptr"
6025
+ },
6026
+ textBufferGetFgPtr: {
6027
+ args: ["ptr"],
6028
+ returns: "ptr"
6029
+ },
6030
+ textBufferGetBgPtr: {
6031
+ args: ["ptr"],
6032
+ returns: "ptr"
6033
+ },
6034
+ textBufferGetAttributesPtr: {
6035
+ args: ["ptr"],
6036
+ returns: "ptr"
6037
+ },
6038
+ textBufferGetLength: {
6039
+ args: ["ptr"],
6040
+ returns: "u32"
6041
+ },
6042
+ textBufferSetCell: {
6043
+ args: ["ptr", "u32", "u32", "ptr", "ptr", "u16"],
6044
+ returns: "void"
6045
+ },
6046
+ textBufferConcat: {
6047
+ args: ["ptr", "ptr"],
6048
+ returns: "ptr"
6049
+ },
6050
+ textBufferResize: {
6051
+ args: ["ptr", "u32"],
6052
+ returns: "void"
6053
+ },
6054
+ textBufferReset: {
6055
+ args: ["ptr"],
6056
+ returns: "void"
6057
+ },
6058
+ textBufferSetSelection: {
6059
+ args: ["ptr", "u32", "u32", "ptr", "ptr"],
6060
+ returns: "void"
6061
+ },
6062
+ textBufferResetSelection: {
6063
+ args: ["ptr"],
6064
+ returns: "void"
6065
+ },
6066
+ textBufferSetDefaultFg: {
6067
+ args: ["ptr", "ptr"],
6068
+ returns: "void"
6069
+ },
6070
+ textBufferSetDefaultBg: {
6071
+ args: ["ptr", "ptr"],
6072
+ returns: "void"
6073
+ },
6074
+ textBufferSetDefaultAttributes: {
6075
+ args: ["ptr", "ptr"],
6076
+ returns: "void"
6077
+ },
6078
+ textBufferResetDefaults: {
6079
+ args: ["ptr"],
6080
+ returns: "void"
6081
+ },
6082
+ textBufferWriteChunk: {
6083
+ args: ["ptr", "ptr", "u32", "ptr", "ptr", "ptr"],
6084
+ returns: "u32"
6085
+ },
6086
+ textBufferGetCapacity: {
6087
+ args: ["ptr"],
6088
+ returns: "u32"
6089
+ },
6090
+ textBufferFinalizeLineInfo: {
6091
+ args: ["ptr"],
6092
+ returns: "void"
6093
+ },
6094
+ textBufferGetLineStartsPtr: {
6095
+ args: ["ptr"],
6096
+ returns: "ptr"
6097
+ },
6098
+ textBufferGetLineWidthsPtr: {
6099
+ args: ["ptr"],
6100
+ returns: "ptr"
6101
+ },
6102
+ textBufferGetLineCount: {
6103
+ args: ["ptr"],
6104
+ returns: "u32"
6105
+ },
6106
+ bufferDrawTextBuffer: {
6107
+ args: ["ptr", "ptr", "i32", "i32", "i32", "i32", "u32", "u32", "bool"],
6108
+ returns: "void"
6109
+ }
6110
+ });
6111
+ }
5290
6112
 
5291
- // src/lib/ascii.font.ts
5292
- var fonts = {
5293
- tiny: tiny_default,
5294
- block: block_default,
5295
- shade: shade_default,
5296
- slick: slick_default
5297
- };
5298
- var parsedFonts = {};
5299
- function parseColorTags(text) {
5300
- const segments = [];
5301
- let currentIndex = 0;
5302
- const colorTagRegex = /<c(\d+)>(.*?)<\/c\d+>/g;
5303
- let lastIndex = 0;
5304
- let match;
5305
- while ((match = colorTagRegex.exec(text)) !== null) {
5306
- if (match.index > lastIndex) {
5307
- const plainText = text.slice(lastIndex, match.index);
5308
- if (plainText) {
5309
- segments.push({ text: plainText, colorIndex: 0 });
5310
- }
6113
+ class FFIRenderLib {
6114
+ opentui;
6115
+ encoder = new TextEncoder;
6116
+ constructor(libPath) {
6117
+ this.opentui = getOpenTUILib(libPath);
6118
+ }
6119
+ createRenderer(width, height) {
6120
+ return this.opentui.symbols.createRenderer(width, height);
6121
+ }
6122
+ destroyRenderer(renderer, useAlternateScreen, splitHeight) {
6123
+ this.opentui.symbols.destroyRenderer(renderer, useAlternateScreen, splitHeight);
6124
+ }
6125
+ setUseThread(renderer, useThread) {
6126
+ this.opentui.symbols.setUseThread(renderer, useThread);
6127
+ }
6128
+ setBackgroundColor(renderer, color) {
6129
+ this.opentui.symbols.setBackgroundColor(renderer, color.buffer);
6130
+ }
6131
+ setRenderOffset(renderer, offset) {
6132
+ this.opentui.symbols.setRenderOffset(renderer, offset);
6133
+ }
6134
+ updateStats(renderer, time, fps, frameCallbackTime) {
6135
+ this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime);
6136
+ }
6137
+ updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers) {
6138
+ this.opentui.symbols.updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers);
6139
+ }
6140
+ getNextBuffer(renderer) {
6141
+ const bufferPtr = this.opentui.symbols.getNextBuffer(renderer);
6142
+ if (!bufferPtr) {
6143
+ throw new Error("Failed to get next buffer");
5311
6144
  }
5312
- const colorIndex = parseInt(match[1]) - 1;
5313
- const taggedText = match[2];
5314
- segments.push({ text: taggedText, colorIndex: Math.max(0, colorIndex) });
5315
- lastIndex = match.index + match[0].length;
6145
+ const width = this.opentui.symbols.getBufferWidth(bufferPtr);
6146
+ const height = this.opentui.symbols.getBufferHeight(bufferPtr);
6147
+ const size = width * height;
6148
+ const buffers = this.getBuffer(bufferPtr, size);
6149
+ return new OptimizedBuffer(this, bufferPtr, buffers, width, height, {});
5316
6150
  }
5317
- if (lastIndex < text.length) {
5318
- const remainingText = text.slice(lastIndex);
5319
- if (remainingText) {
5320
- segments.push({ text: remainingText, colorIndex: 0 });
6151
+ getCurrentBuffer(renderer) {
6152
+ const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer);
6153
+ if (!bufferPtr) {
6154
+ throw new Error("Failed to get current buffer");
5321
6155
  }
6156
+ const width = this.opentui.symbols.getBufferWidth(bufferPtr);
6157
+ const height = this.opentui.symbols.getBufferHeight(bufferPtr);
6158
+ const size = width * height;
6159
+ const buffers = this.getBuffer(bufferPtr, size);
6160
+ return new OptimizedBuffer(this, bufferPtr, buffers, width, height, {});
5322
6161
  }
5323
- return segments;
5324
- }
5325
- function getParsedFont(fontKey) {
5326
- if (!parsedFonts[fontKey]) {
5327
- const fontDef = fonts[fontKey];
5328
- const parsedChars = {};
5329
- for (const [char, lines] of Object.entries(fontDef.chars)) {
5330
- parsedChars[char] = lines.map((line) => parseColorTags(line));
6162
+ getBuffer(bufferPtr, size) {
6163
+ const charPtr = this.opentui.symbols.bufferGetCharPtr(bufferPtr);
6164
+ const fgPtr = this.opentui.symbols.bufferGetFgPtr(bufferPtr);
6165
+ const bgPtr = this.opentui.symbols.bufferGetBgPtr(bufferPtr);
6166
+ const attributesPtr = this.opentui.symbols.bufferGetAttributesPtr(bufferPtr);
6167
+ if (!charPtr || !fgPtr || !bgPtr || !attributesPtr) {
6168
+ throw new Error("Failed to get buffer pointers");
5331
6169
  }
5332
- parsedFonts[fontKey] = {
5333
- ...fontDef,
5334
- colors: fontDef.colors || 1,
5335
- chars: parsedChars
6170
+ const buffers = {
6171
+ char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
6172
+ fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
6173
+ bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
6174
+ attributes: new Uint8Array(toArrayBuffer(attributesPtr, 0, size))
5336
6175
  };
6176
+ return buffers;
5337
6177
  }
5338
- return parsedFonts[fontKey];
5339
- }
5340
- function measureText({ text, font = "tiny" }) {
5341
- const fontDef = getParsedFont(font);
5342
- if (!fontDef) {
5343
- console.warn(`Font '${font}' not found`);
5344
- return { width: 0, height: 0 };
6178
+ getTextBuffer(bufferPtr, size) {
6179
+ const charPtr = this.opentui.symbols.textBufferGetCharPtr(bufferPtr);
6180
+ const fgPtr = this.opentui.symbols.textBufferGetFgPtr(bufferPtr);
6181
+ const bgPtr = this.opentui.symbols.textBufferGetBgPtr(bufferPtr);
6182
+ const attributesPtr = this.opentui.symbols.textBufferGetAttributesPtr(bufferPtr);
6183
+ if (!charPtr || !fgPtr || !bgPtr || !attributesPtr) {
6184
+ throw new Error("Failed to get text buffer pointers");
6185
+ }
6186
+ const buffers = {
6187
+ char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
6188
+ fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
6189
+ bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
6190
+ attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, size * 2))
6191
+ };
6192
+ return buffers;
5345
6193
  }
5346
- let currentX = 0;
5347
- for (let i = 0;i < text.length; i++) {
5348
- const char = text[i].toUpperCase();
5349
- const charDef = fontDef.chars[char];
5350
- if (!charDef) {
5351
- const spaceChar = fontDef.chars[" "];
5352
- if (spaceChar && spaceChar[0]) {
5353
- let spaceWidth = 0;
5354
- for (const segment of spaceChar[0]) {
5355
- spaceWidth += segment.text.length;
5356
- }
5357
- currentX += spaceWidth;
5358
- } else {
5359
- currentX += 1;
5360
- }
5361
- continue;
6194
+ bufferGetCharPtr(buffer) {
6195
+ const ptr = this.opentui.symbols.bufferGetCharPtr(buffer);
6196
+ if (!ptr) {
6197
+ throw new Error("Failed to get char pointer");
5362
6198
  }
5363
- let charWidth = 0;
5364
- if (charDef[0]) {
5365
- for (const segment of charDef[0]) {
5366
- charWidth += segment.text.length;
5367
- }
6199
+ return ptr;
6200
+ }
6201
+ bufferGetFgPtr(buffer) {
6202
+ const ptr = this.opentui.symbols.bufferGetFgPtr(buffer);
6203
+ if (!ptr) {
6204
+ throw new Error("Failed to get fg pointer");
5368
6205
  }
5369
- currentX += charWidth;
5370
- if (i < text.length - 1) {
5371
- currentX += fontDef.letterspace_size;
6206
+ return ptr;
6207
+ }
6208
+ bufferGetBgPtr(buffer) {
6209
+ const ptr = this.opentui.symbols.bufferGetBgPtr(buffer);
6210
+ if (!ptr) {
6211
+ throw new Error("Failed to get bg pointer");
6212
+ }
6213
+ return ptr;
6214
+ }
6215
+ bufferGetAttributesPtr(buffer) {
6216
+ const ptr = this.opentui.symbols.bufferGetAttributesPtr(buffer);
6217
+ if (!ptr) {
6218
+ throw new Error("Failed to get attributes pointer");
5372
6219
  }
6220
+ return ptr;
5373
6221
  }
5374
- return {
5375
- width: currentX,
5376
- height: fontDef.lines
5377
- };
5378
- }
5379
- function getCharacterPositions(text, font = "tiny") {
5380
- const fontDef = getParsedFont(font);
5381
- if (!fontDef) {
5382
- return [0];
6222
+ bufferGetRespectAlpha(buffer) {
6223
+ return this.opentui.symbols.bufferGetRespectAlpha(buffer);
6224
+ }
6225
+ bufferSetRespectAlpha(buffer, respectAlpha) {
6226
+ this.opentui.symbols.bufferSetRespectAlpha(buffer, respectAlpha);
6227
+ }
6228
+ getBufferWidth(buffer) {
6229
+ return this.opentui.symbols.getBufferWidth(buffer);
6230
+ }
6231
+ getBufferHeight(buffer) {
6232
+ return this.opentui.symbols.getBufferHeight(buffer);
6233
+ }
6234
+ bufferClear(buffer, color) {
6235
+ this.opentui.symbols.bufferClear(buffer, color.buffer);
6236
+ }
6237
+ bufferDrawText(buffer, text, x, y, color, bgColor, attributes) {
6238
+ const textBytes = this.encoder.encode(text);
6239
+ const textLength = textBytes.byteLength;
6240
+ const bg2 = bgColor ? bgColor.buffer : null;
6241
+ const fg2 = color.buffer;
6242
+ this.opentui.symbols.bufferDrawText(buffer, textBytes, textLength, x, y, fg2, bg2, attributes ?? 0);
6243
+ }
6244
+ bufferSetCellWithAlphaBlending(buffer, x, y, char, color, bgColor, attributes) {
6245
+ const charPtr = char.codePointAt(0) ?? " ".codePointAt(0);
6246
+ const bg2 = bgColor.buffer;
6247
+ const fg2 = color.buffer;
6248
+ this.opentui.symbols.bufferSetCellWithAlphaBlending(buffer, x, y, charPtr, fg2, bg2, attributes ?? 0);
6249
+ }
6250
+ bufferFillRect(buffer, x, y, width, height, color) {
6251
+ const bg2 = color.buffer;
6252
+ this.opentui.symbols.bufferFillRect(buffer, x, y, width, height, bg2);
6253
+ }
6254
+ bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow) {
6255
+ const formatId = format === "bgra8unorm" ? 0 : 1;
6256
+ this.opentui.symbols.bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, formatId, alignedBytesPerRow);
6257
+ }
6258
+ bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
6259
+ this.opentui.symbols.bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
6260
+ }
6261
+ bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, title) {
6262
+ const titleBytes = title ? this.encoder.encode(title) : null;
6263
+ const titleLen = title ? titleBytes.length : 0;
6264
+ const titlePtr = title ? titleBytes : null;
6265
+ this.opentui.symbols.bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor.buffer, backgroundColor.buffer, titlePtr, titleLen);
5383
6266
  }
5384
- const positions = [0];
5385
- let currentX = 0;
5386
- for (let i = 0;i < text.length; i++) {
5387
- const char = text[i].toUpperCase();
5388
- const charDef = fontDef.chars[char];
5389
- let charWidth = 0;
5390
- if (!charDef) {
5391
- const spaceChar = fontDef.chars[" "];
5392
- if (spaceChar && spaceChar[0]) {
5393
- for (const segment of spaceChar[0]) {
5394
- charWidth += segment.text.length;
5395
- }
5396
- } else {
5397
- charWidth = 1;
5398
- }
5399
- } else if (charDef[0]) {
5400
- for (const segment of charDef[0]) {
5401
- charWidth += segment.text.length;
5402
- }
5403
- }
5404
- currentX += charWidth;
5405
- if (i < text.length - 1) {
5406
- currentX += fontDef.letterspace_size;
5407
- }
5408
- positions.push(currentX);
6267
+ bufferResize(buffer, width, height) {
6268
+ this.opentui.symbols.bufferResize(buffer, width, height);
6269
+ const buffers = this.getBuffer(buffer, width * height);
6270
+ return buffers;
5409
6271
  }
5410
- return positions;
5411
- }
5412
- function coordinateToCharacterIndex(x, text, font = "tiny") {
5413
- const positions = getCharacterPositions(text, font);
5414
- if (x < 0) {
5415
- return 0;
6272
+ resizeRenderer(renderer, width, height) {
6273
+ this.opentui.symbols.resizeRenderer(renderer, width, height);
5416
6274
  }
5417
- for (let i = 0;i < positions.length - 1; i++) {
5418
- const currentPos = positions[i];
5419
- const nextPos = positions[i + 1];
5420
- if (x >= currentPos && x < nextPos) {
5421
- const charMidpoint = currentPos + (nextPos - currentPos) / 2;
5422
- return x < charMidpoint ? i : i + 1;
5423
- }
6275
+ setCursorPosition(x, y, visible) {
6276
+ this.opentui.symbols.setCursorPosition(x, y, visible);
5424
6277
  }
5425
- if (positions.length > 0 && x >= positions[positions.length - 1]) {
5426
- return text.length;
6278
+ setCursorStyle(style, blinking) {
6279
+ const stylePtr = this.encoder.encode(style);
6280
+ this.opentui.symbols.setCursorStyle(stylePtr, style.length, blinking);
5427
6281
  }
5428
- return 0;
5429
- }
5430
- function renderFontToFrameBuffer(buffer, {
5431
- text,
5432
- x = 0,
5433
- y = 0,
5434
- fg = [RGBA.fromInts(255, 255, 255, 255)],
5435
- bg = RGBA.fromInts(0, 0, 0, 255),
5436
- font = "tiny"
5437
- }) {
5438
- const width = buffer.getWidth();
5439
- const height = buffer.getHeight();
5440
- const fontDef = getParsedFont(font);
5441
- if (!fontDef) {
5442
- console.warn(`Font '${font}' not found`);
5443
- return { width: 0, height: 0 };
6282
+ setCursorColor(color) {
6283
+ this.opentui.symbols.setCursorColor(color.buffer);
5444
6284
  }
5445
- const colors = Array.isArray(fg) ? fg : [fg];
5446
- if (y < 0 || y + fontDef.lines > height) {
5447
- return { width: 0, height: fontDef.lines };
6285
+ render(renderer, force) {
6286
+ this.opentui.symbols.render(renderer, force);
5448
6287
  }
5449
- let currentX = x;
5450
- const startX = x;
5451
- for (let i = 0;i < text.length; i++) {
5452
- const char = text[i].toUpperCase();
5453
- const charDef = fontDef.chars[char];
5454
- if (!charDef) {
5455
- const spaceChar = fontDef.chars[" "];
5456
- if (spaceChar && spaceChar[0]) {
5457
- let spaceWidth = 0;
5458
- for (const segment of spaceChar[0]) {
5459
- spaceWidth += segment.text.length;
5460
- }
5461
- currentX += spaceWidth;
5462
- } else {
5463
- currentX += 1;
5464
- }
5465
- continue;
5466
- }
5467
- let charWidth = 0;
5468
- if (charDef[0]) {
5469
- for (const segment of charDef[0]) {
5470
- charWidth += segment.text.length;
5471
- }
5472
- }
5473
- if (currentX >= width)
5474
- break;
5475
- if (currentX + charWidth < 0) {
5476
- currentX += charWidth + fontDef.letterspace_size;
5477
- continue;
5478
- }
5479
- for (let lineIdx = 0;lineIdx < fontDef.lines && lineIdx < charDef.length; lineIdx++) {
5480
- const segments = charDef[lineIdx];
5481
- const renderY = y + lineIdx;
5482
- if (renderY >= 0 && renderY < height) {
5483
- let segmentX = currentX;
5484
- for (const segment of segments) {
5485
- const segmentColor = colors[segment.colorIndex] || colors[0];
5486
- for (let charIdx = 0;charIdx < segment.text.length; charIdx++) {
5487
- const renderX = segmentX + charIdx;
5488
- if (renderX >= 0 && renderX < width) {
5489
- const fontChar = segment.text[charIdx];
5490
- if (fontChar !== " ") {
5491
- buffer.setCell(renderX, renderY, fontChar, segmentColor, bg);
5492
- }
5493
- }
5494
- }
5495
- segmentX += segment.text.length;
5496
- }
5497
- }
6288
+ createOptimizedBuffer(width, height, respectAlpha = false) {
6289
+ if (Number.isNaN(width) || Number.isNaN(height)) {
6290
+ console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
5498
6291
  }
5499
- currentX += charWidth;
5500
- if (i < text.length - 1) {
5501
- currentX += fontDef.letterspace_size;
6292
+ const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, respectAlpha);
6293
+ if (!bufferPtr) {
6294
+ throw new Error(`Failed to create optimized buffer: ${width}x${height}`);
5502
6295
  }
6296
+ const size = width * height;
6297
+ const buffers = this.getBuffer(bufferPtr, size);
6298
+ return new OptimizedBuffer(this, bufferPtr, buffers, width, height, { respectAlpha });
5503
6299
  }
5504
- return {
5505
- width: currentX - startX,
5506
- height: fontDef.lines
5507
- };
5508
- }
5509
- // src/lib/styled-text.ts
5510
- var textEncoder = new TextEncoder;
5511
-
5512
- class StyledText {
5513
- chunks;
5514
- _plainText = "";
5515
- constructor(chunks) {
5516
- this.chunks = chunks;
5517
- for (let i = 0;i < chunks.length; i++) {
5518
- this._plainText += chunks[i].plainText;
5519
- }
6300
+ destroyOptimizedBuffer(bufferPtr) {
6301
+ this.opentui.symbols.destroyOptimizedBuffer(bufferPtr);
5520
6302
  }
5521
- toString() {
5522
- return this._plainText;
6303
+ drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, sourceX, sourceY, sourceWidth, sourceHeight) {
6304
+ const srcX = sourceX ?? 0;
6305
+ const srcY = sourceY ?? 0;
6306
+ const srcWidth = sourceWidth ?? 0;
6307
+ const srcHeight = sourceHeight ?? 0;
6308
+ this.opentui.symbols.drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, srcX, srcY, srcWidth, srcHeight);
5523
6309
  }
5524
- _chunksToPlainText() {
5525
- this._plainText = "";
5526
- for (const chunk of this.chunks) {
5527
- this._plainText += chunk.plainText;
5528
- }
6310
+ setDebugOverlay(renderer, enabled, corner) {
6311
+ this.opentui.symbols.setDebugOverlay(renderer, enabled, corner);
5529
6312
  }
5530
- insert(chunk, index) {
5531
- const originalLength = this.chunks.length;
5532
- if (index === undefined) {
5533
- this.chunks.push(chunk);
5534
- } else {
5535
- this.chunks.splice(index, 0, chunk);
5536
- }
5537
- if (index === undefined || index === originalLength) {
5538
- this._plainText += chunk.plainText;
5539
- } else {
5540
- this._chunksToPlainText();
5541
- }
6313
+ clearTerminal(renderer) {
6314
+ this.opentui.symbols.clearTerminal(renderer);
5542
6315
  }
5543
- remove(chunk) {
5544
- const originalLength = this.chunks.length;
5545
- const index = this.chunks.indexOf(chunk);
5546
- if (index === -1)
5547
- return;
5548
- this.chunks.splice(index, 1);
5549
- if (index === originalLength - 1) {
5550
- this._plainText = this._plainText.slice(0, this._plainText.length - chunk.plainText.length);
5551
- } else {
5552
- this._chunksToPlainText();
5553
- }
6316
+ addToHitGrid(renderer, x, y, width, height, id) {
6317
+ this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id);
5554
6318
  }
5555
- replace(chunk, oldChunk) {
5556
- const index = this.chunks.indexOf(oldChunk);
5557
- if (index === -1)
5558
- return;
5559
- this.chunks.splice(index, 1, chunk);
5560
- if (index === this.chunks.length - 1) {
5561
- this._plainText = this._plainText.slice(0, this._plainText.length - oldChunk.plainText.length) + chunk.plainText;
5562
- } else {
5563
- this._chunksToPlainText();
5564
- }
6319
+ checkHit(renderer, x, y) {
6320
+ return this.opentui.symbols.checkHit(renderer, x, y);
5565
6321
  }
5566
- }
5567
- function stringToStyledText(content) {
5568
- const textEncoder2 = new TextEncoder;
5569
- const chunk = {
5570
- __isChunk: true,
5571
- text: textEncoder2.encode(content),
5572
- plainText: content
5573
- };
5574
- return new StyledText([chunk]);
5575
- }
5576
- var templateCache = new WeakMap;
5577
- function applyStyle(input, style) {
5578
- if (typeof input === "object" && "__isChunk" in input) {
5579
- const existingChunk = input;
5580
- const fg = style.fg ? parseColor(style.fg) : existingChunk.fg;
5581
- const bg = style.bg ? parseColor(style.bg) : existingChunk.bg;
5582
- const newAttrs = createTextAttributes(style);
5583
- const mergedAttrs = existingChunk.attributes ? existingChunk.attributes | newAttrs : newAttrs;
5584
- return {
5585
- __isChunk: true,
5586
- text: existingChunk.text,
5587
- plainText: existingChunk.plainText,
5588
- fg,
5589
- bg,
5590
- attributes: mergedAttrs
5591
- };
5592
- } else {
5593
- const plainTextStr = String(input);
5594
- const text = textEncoder.encode(plainTextStr);
5595
- const fg = style.fg ? parseColor(style.fg) : undefined;
5596
- const bg = style.bg ? parseColor(style.bg) : undefined;
5597
- const attributes = createTextAttributes(style);
5598
- return {
5599
- __isChunk: true,
5600
- text,
5601
- plainText: plainTextStr,
5602
- fg,
5603
- bg,
5604
- attributes
6322
+ dumpHitGrid(renderer) {
6323
+ this.opentui.symbols.dumpHitGrid(renderer);
6324
+ }
6325
+ dumpBuffers(renderer, timestamp) {
6326
+ const ts = timestamp ?? Date.now();
6327
+ this.opentui.symbols.dumpBuffers(renderer, ts);
6328
+ }
6329
+ dumpStdoutBuffer(renderer, timestamp) {
6330
+ const ts = timestamp ?? Date.now();
6331
+ this.opentui.symbols.dumpStdoutBuffer(renderer, ts);
6332
+ }
6333
+ enableMouse(renderer, enableMovement) {
6334
+ this.opentui.symbols.enableMouse(renderer, enableMovement);
6335
+ }
6336
+ disableMouse(renderer) {
6337
+ this.opentui.symbols.disableMouse(renderer);
6338
+ }
6339
+ createTextBuffer(capacity) {
6340
+ const bufferPtr = this.opentui.symbols.createTextBuffer(capacity);
6341
+ if (!bufferPtr) {
6342
+ throw new Error(`Failed to create TextBuffer with capacity ${capacity}`);
6343
+ }
6344
+ const charPtr = this.textBufferGetCharPtr(bufferPtr);
6345
+ const fgPtr = this.textBufferGetFgPtr(bufferPtr);
6346
+ const bgPtr = this.textBufferGetBgPtr(bufferPtr);
6347
+ const attributesPtr = this.textBufferGetAttributesPtr(bufferPtr);
6348
+ const buffer = {
6349
+ char: new Uint32Array(toArrayBuffer(charPtr, 0, capacity * 4)),
6350
+ fg: new Float32Array(toArrayBuffer(fgPtr, 0, capacity * 4 * 4)),
6351
+ bg: new Float32Array(toArrayBuffer(bgPtr, 0, capacity * 4 * 4)),
6352
+ attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, capacity * 2))
5605
6353
  };
6354
+ return new TextBuffer(this, bufferPtr, buffer, capacity);
5606
6355
  }
5607
- }
5608
- var black = (input) => applyStyle(input, { fg: "black" });
5609
- var red = (input) => applyStyle(input, { fg: "red" });
5610
- var green = (input) => applyStyle(input, { fg: "green" });
5611
- var yellow = (input) => applyStyle(input, { fg: "yellow" });
5612
- var blue = (input) => applyStyle(input, { fg: "blue" });
5613
- var magenta = (input) => applyStyle(input, { fg: "magenta" });
5614
- var cyan = (input) => applyStyle(input, { fg: "cyan" });
5615
- var white = (input) => applyStyle(input, { fg: "white" });
5616
- var brightBlack = (input) => applyStyle(input, { fg: "brightBlack" });
5617
- var brightRed = (input) => applyStyle(input, { fg: "brightRed" });
5618
- var brightGreen = (input) => applyStyle(input, { fg: "brightGreen" });
5619
- var brightYellow = (input) => applyStyle(input, { fg: "brightYellow" });
5620
- var brightBlue = (input) => applyStyle(input, { fg: "brightBlue" });
5621
- var brightMagenta = (input) => applyStyle(input, { fg: "brightMagenta" });
5622
- var brightCyan = (input) => applyStyle(input, { fg: "brightCyan" });
5623
- var brightWhite = (input) => applyStyle(input, { fg: "brightWhite" });
5624
- var bgBlack = (input) => applyStyle(input, { bg: "black" });
5625
- var bgRed = (input) => applyStyle(input, { bg: "red" });
5626
- var bgGreen = (input) => applyStyle(input, { bg: "green" });
5627
- var bgYellow = (input) => applyStyle(input, { bg: "yellow" });
5628
- var bgBlue = (input) => applyStyle(input, { bg: "blue" });
5629
- var bgMagenta = (input) => applyStyle(input, { bg: "magenta" });
5630
- var bgCyan = (input) => applyStyle(input, { bg: "cyan" });
5631
- var bgWhite = (input) => applyStyle(input, { bg: "white" });
5632
- var bold = (input) => applyStyle(input, { bold: true });
5633
- var italic = (input) => applyStyle(input, { italic: true });
5634
- var underline = (input) => applyStyle(input, { underline: true });
5635
- var strikethrough = (input) => applyStyle(input, { strikethrough: true });
5636
- var dim = (input) => applyStyle(input, { dim: true });
5637
- var reverse = (input) => applyStyle(input, { reverse: true });
5638
- var blink = (input) => applyStyle(input, { blink: true });
5639
- var fg = (color) => (input) => applyStyle(input, { fg: color });
5640
- var bg = (color) => (input) => applyStyle(input, { bg: color });
5641
- function tn(strings, ...values) {
5642
- const chunks = [];
5643
- let length = 0;
5644
- let plainText = "";
5645
- for (let i = 0;i < strings.length; i++) {
5646
- const raw = strings[i];
5647
- if (raw) {
5648
- chunks.push({
5649
- __isChunk: true,
5650
- text: textEncoder.encode(raw),
5651
- plainText: raw,
5652
- attributes: 0
5653
- });
5654
- length += raw.length;
5655
- plainText += raw;
5656
- }
5657
- const val = values[i];
5658
- if (typeof val === "object" && "__isChunk" in val) {
5659
- chunks.push(val);
5660
- length += val.plainText.length;
5661
- plainText += val.plainText;
5662
- } else if (val !== undefined) {
5663
- const plainTextStr = String(val);
5664
- chunks.push({
5665
- __isChunk: true,
5666
- text: textEncoder.encode(plainTextStr),
5667
- plainText: plainTextStr,
5668
- attributes: 0
5669
- });
5670
- length += plainTextStr.length;
5671
- plainText += plainTextStr;
6356
+ destroyTextBuffer(buffer) {
6357
+ this.opentui.symbols.destroyTextBuffer(buffer);
6358
+ }
6359
+ textBufferGetCharPtr(buffer) {
6360
+ const ptr = this.opentui.symbols.textBufferGetCharPtr(buffer);
6361
+ if (!ptr) {
6362
+ throw new Error("Failed to get TextBuffer char pointer");
5672
6363
  }
6364
+ return ptr;
5673
6365
  }
5674
- return new StyledText(chunks);
5675
- }
5676
- function t(strings, ...values) {
5677
- let cachedStringChunks = templateCache.get(strings);
5678
- let length = 0;
5679
- let plainText = "";
5680
- if (!cachedStringChunks) {
5681
- cachedStringChunks = [];
5682
- for (let i = 0;i < strings.length; i++) {
5683
- const raw = strings[i];
5684
- if (raw) {
5685
- cachedStringChunks.push({
5686
- __isChunk: true,
5687
- text: textEncoder.encode(raw),
5688
- plainText: raw,
5689
- attributes: 0
5690
- });
5691
- } else {
5692
- cachedStringChunks.push(null);
5693
- }
6366
+ textBufferGetFgPtr(buffer) {
6367
+ const ptr = this.opentui.symbols.textBufferGetFgPtr(buffer);
6368
+ if (!ptr) {
6369
+ throw new Error("Failed to get TextBuffer fg pointer");
5694
6370
  }
5695
- templateCache.set(strings, cachedStringChunks);
6371
+ return ptr;
5696
6372
  }
5697
- const chunks = [];
5698
- for (let i = 0;i < strings.length; i++) {
5699
- const stringChunk = cachedStringChunks[i];
5700
- if (stringChunk) {
5701
- chunks.push(stringChunk);
5702
- length += stringChunk.plainText.length;
5703
- plainText += stringChunk.plainText;
6373
+ textBufferGetBgPtr(buffer) {
6374
+ const ptr = this.opentui.symbols.textBufferGetBgPtr(buffer);
6375
+ if (!ptr) {
6376
+ throw new Error("Failed to get TextBuffer bg pointer");
5704
6377
  }
5705
- const val = values[i];
5706
- if (typeof val === "object" && "__isChunk" in val) {
5707
- chunks.push(val);
5708
- length += val.plainText.length;
5709
- plainText += val.plainText;
5710
- } else if (val !== undefined) {
5711
- const plainTextStr = String(val);
5712
- chunks.push({
5713
- __isChunk: true,
5714
- text: textEncoder.encode(plainTextStr),
5715
- plainText: plainTextStr,
5716
- attributes: 0
5717
- });
5718
- length += plainTextStr.length;
5719
- plainText += plainTextStr;
6378
+ return ptr;
6379
+ }
6380
+ textBufferGetAttributesPtr(buffer) {
6381
+ const ptr = this.opentui.symbols.textBufferGetAttributesPtr(buffer);
6382
+ if (!ptr) {
6383
+ throw new Error("Failed to get TextBuffer attributes pointer");
5720
6384
  }
6385
+ return ptr;
5721
6386
  }
5722
- return new StyledText(chunks);
5723
- }
5724
-
5725
- // src/lib/hast-styled-text.ts
5726
- class SyntaxStyle {
5727
- styles;
5728
- mergedStyleCache;
5729
- constructor(styles) {
5730
- this.styles = styles;
5731
- this.mergedStyleCache = new Map;
6387
+ textBufferGetLength(buffer) {
6388
+ return this.opentui.symbols.textBufferGetLength(buffer);
5732
6389
  }
5733
- mergeStyles(...styleNames) {
5734
- const cacheKey = styleNames.join(":");
5735
- const cached = this.mergedStyleCache.get(cacheKey);
5736
- if (cached)
5737
- return cached;
5738
- const styleDefinition = {};
5739
- for (const name of styleNames) {
5740
- const style = this.styles[name];
5741
- if (!style)
5742
- continue;
5743
- if (style.fg)
5744
- styleDefinition.fg = style.fg;
5745
- if (style.bg)
5746
- styleDefinition.bg = style.bg;
5747
- if (style.bold !== undefined)
5748
- styleDefinition.bold = style.bold;
5749
- if (style.italic !== undefined)
5750
- styleDefinition.italic = style.italic;
5751
- if (style.underline !== undefined)
5752
- styleDefinition.underline = style.underline;
5753
- if (style.dim !== undefined)
5754
- styleDefinition.dim = style.dim;
6390
+ textBufferSetCell(buffer, index, char, fg2, bg2, attr) {
6391
+ this.opentui.symbols.textBufferSetCell(buffer, index, char, fg2, bg2, attr);
6392
+ }
6393
+ textBufferConcat(buffer1, buffer2) {
6394
+ const resultPtr = this.opentui.symbols.textBufferConcat(buffer1, buffer2);
6395
+ if (!resultPtr) {
6396
+ throw new Error("Failed to concatenate TextBuffers");
5755
6397
  }
5756
- const attributes = createTextAttributes({
5757
- bold: styleDefinition.bold,
5758
- italic: styleDefinition.italic,
5759
- underline: styleDefinition.underline,
5760
- dim: styleDefinition.dim
5761
- });
5762
- const merged = {
5763
- fg: styleDefinition.fg,
5764
- bg: styleDefinition.bg,
5765
- attributes
6398
+ const length = this.textBufferGetLength(resultPtr);
6399
+ const charPtr = this.textBufferGetCharPtr(resultPtr);
6400
+ const fgPtr = this.textBufferGetFgPtr(resultPtr);
6401
+ const bgPtr = this.textBufferGetBgPtr(resultPtr);
6402
+ const attributesPtr = this.textBufferGetAttributesPtr(resultPtr);
6403
+ const buffer = {
6404
+ char: new Uint32Array(toArrayBuffer(charPtr, 0, length * 4)),
6405
+ fg: new Float32Array(toArrayBuffer(fgPtr, 0, length * 4 * 4)),
6406
+ bg: new Float32Array(toArrayBuffer(bgPtr, 0, length * 4 * 4)),
6407
+ attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, length * 2))
5766
6408
  };
5767
- this.mergedStyleCache.set(cacheKey, merged);
5768
- return merged;
6409
+ return new TextBuffer(this, resultPtr, buffer, length);
5769
6410
  }
5770
- clearCache() {
5771
- this.mergedStyleCache.clear();
6411
+ textBufferResize(buffer, newLength) {
6412
+ this.opentui.symbols.textBufferResize(buffer, newLength);
6413
+ const buffers = this.getTextBuffer(buffer, newLength);
6414
+ return buffers;
5772
6415
  }
5773
- getCacheSize() {
5774
- return this.mergedStyleCache.size;
6416
+ textBufferReset(buffer) {
6417
+ this.opentui.symbols.textBufferReset(buffer);
5775
6418
  }
5776
- }
5777
- var textEncoder2 = new TextEncoder;
5778
- function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
5779
- const chunks = [];
5780
- if (node.type === "text") {
5781
- const stylesToMerge = parentStyles.length > 0 ? parentStyles : ["default"];
5782
- const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge);
5783
- chunks.push({
5784
- __isChunk: true,
5785
- text: textEncoder2.encode(node.value),
5786
- plainText: node.value,
5787
- fg: mergedStyle.fg,
5788
- bg: mergedStyle.bg,
5789
- attributes: mergedStyle.attributes
5790
- });
5791
- } else if (node.type === "element") {
5792
- let currentStyles = [...parentStyles];
5793
- if (node.properties?.className) {
5794
- const classes = node.properties.className.split(" ");
5795
- for (const cls of classes) {
5796
- currentStyles.push(cls);
5797
- }
6419
+ textBufferSetSelection(buffer, start, end, bgColor, fgColor) {
6420
+ const bg2 = bgColor ? bgColor.buffer : null;
6421
+ const fg2 = fgColor ? fgColor.buffer : null;
6422
+ this.opentui.symbols.textBufferSetSelection(buffer, start, end, bg2, fg2);
6423
+ }
6424
+ textBufferResetSelection(buffer) {
6425
+ this.opentui.symbols.textBufferResetSelection(buffer);
6426
+ }
6427
+ textBufferSetDefaultFg(buffer, fg2) {
6428
+ const fgPtr = fg2 ? fg2.buffer : null;
6429
+ this.opentui.symbols.textBufferSetDefaultFg(buffer, fgPtr);
6430
+ }
6431
+ textBufferSetDefaultBg(buffer, bg2) {
6432
+ const bgPtr = bg2 ? bg2.buffer : null;
6433
+ this.opentui.symbols.textBufferSetDefaultBg(buffer, bgPtr);
6434
+ }
6435
+ textBufferSetDefaultAttributes(buffer, attributes) {
6436
+ const attrValue = attributes === null ? null : new Uint8Array([attributes]);
6437
+ this.opentui.symbols.textBufferSetDefaultAttributes(buffer, attrValue);
6438
+ }
6439
+ textBufferResetDefaults(buffer) {
6440
+ this.opentui.symbols.textBufferResetDefaults(buffer);
6441
+ }
6442
+ textBufferWriteChunk(buffer, textBytes, fg2, bg2, attributes) {
6443
+ const attrValue = attributes === null ? null : new Uint8Array([attributes]);
6444
+ return this.opentui.symbols.textBufferWriteChunk(buffer, textBytes, textBytes.length, fg2 ? fg2.buffer : null, bg2 ? bg2.buffer : null, attrValue);
6445
+ }
6446
+ textBufferGetCapacity(buffer) {
6447
+ return this.opentui.symbols.textBufferGetCapacity(buffer);
6448
+ }
6449
+ textBufferFinalizeLineInfo(buffer) {
6450
+ this.opentui.symbols.textBufferFinalizeLineInfo(buffer);
6451
+ }
6452
+ textBufferGetLineInfo(buffer) {
6453
+ const lineCount = this.opentui.symbols.textBufferGetLineCount(buffer);
6454
+ if (lineCount === 0) {
6455
+ return { lineStarts: [], lineWidths: [] };
5798
6456
  }
5799
- for (const child of node.children) {
5800
- chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles));
6457
+ const lineStartsPtr = this.opentui.symbols.textBufferGetLineStartsPtr(buffer);
6458
+ const lineWidthsPtr = this.opentui.symbols.textBufferGetLineWidthsPtr(buffer);
6459
+ if (!lineStartsPtr || !lineWidthsPtr) {
6460
+ return { lineStarts: [], lineWidths: [] };
5801
6461
  }
6462
+ const lineStartsArray = new Uint32Array(toArrayBuffer(lineStartsPtr, 0, lineCount * 4));
6463
+ const lineWidthsArray = new Uint32Array(toArrayBuffer(lineWidthsPtr, 0, lineCount * 4));
6464
+ const lineStarts = Array.from(lineStartsArray);
6465
+ const lineWidths = Array.from(lineWidthsArray);
6466
+ return { lineStarts, lineWidths };
6467
+ }
6468
+ getTextBufferArrays(buffer, size) {
6469
+ return this.getTextBuffer(buffer, size);
6470
+ }
6471
+ bufferDrawTextBuffer(buffer, textBuffer, x, y, clipRect) {
6472
+ const hasClipRect = clipRect !== undefined && clipRect !== null;
6473
+ const clipX = clipRect?.x ?? 0;
6474
+ const clipY = clipRect?.y ?? 0;
6475
+ const clipWidth = clipRect?.width ?? 0;
6476
+ const clipHeight = clipRect?.height ?? 0;
6477
+ this.opentui.symbols.bufferDrawTextBuffer(buffer, textBuffer, x, y, clipX, clipY, clipWidth, clipHeight, hasClipRect);
5802
6478
  }
5803
- return chunks;
5804
6479
  }
5805
- function hastToStyledText(hast, syntaxStyle) {
5806
- const chunks = hastToTextChunks(hast, syntaxStyle);
5807
- return new StyledText(chunks);
6480
+ var opentuiLibPath;
6481
+ var opentuiLib;
6482
+ function setRenderLibPath(libPath) {
6483
+ opentuiLibPath = libPath;
6484
+ }
6485
+ function resolveRenderLib() {
6486
+ if (!opentuiLib) {
6487
+ opentuiLib = new FFIRenderLib(opentuiLibPath);
6488
+ }
6489
+ return opentuiLib;
5808
6490
  }
6491
+
5809
6492
  // src/buffer.ts
5810
6493
  var fbIdCounter = 0;
5811
6494
  function isRGBAWithAlpha(color) {
@@ -5982,17 +6665,17 @@ class OptimizedBuffer {
5982
6665
  }
5983
6666
  this.setCell(x, y, char, fg2, bg2, attributes);
5984
6667
  }
5985
- drawText(text, x, y, fg2, bg2, attributes = 0, selection) {
5986
- if (!selection) {
6668
+ drawText(text, x, y, fg2, bg2, attributes = 0, selection2) {
6669
+ if (!selection2) {
5987
6670
  this.drawTextFFI.call(this, text, x, y, fg2, bg2, attributes);
5988
6671
  return;
5989
6672
  }
5990
- const { start, end } = selection;
6673
+ const { start, end } = selection2;
5991
6674
  let selectionBg;
5992
6675
  let selectionFg;
5993
- if (selection.bgColor) {
5994
- selectionBg = selection.bgColor;
5995
- selectionFg = selection.fgColor || fg2;
6676
+ if (selection2.bgColor) {
6677
+ selectionBg = selection2.bgColor;
6678
+ selectionFg = selection2.fgColor || fg2;
5996
6679
  } else {
5997
6680
  const defaultBg = bg2 || RGBA.fromValues(0, 0, 0, 0);
5998
6681
  selectionFg = defaultBg.a > 0 ? defaultBg : RGBA.fromValues(0, 0, 0, 1);
@@ -7124,312 +7807,65 @@ class Timeline {
7124
7807
  evaluateTimelineSync(subTimeline, this.currentTime + deltaTime, deltaTime);
7125
7808
  }
7126
7809
  if (!this.isPlaying)
7127
- return;
7128
- this.currentTime += deltaTime;
7129
- for (const item of this.items) {
7130
- evaluateItem(item, this.currentTime, deltaTime);
7131
- }
7132
- for (let i = this.items.length - 1;i >= 0; i--) {
7133
- const item = this.items[i];
7134
- if (item.type === "animation" && item.once && item.completed) {
7135
- this.items.splice(i, 1);
7136
- }
7137
- }
7138
- if (this.loop && this.currentTime >= this.duration) {
7139
- const overshoot = this.currentTime % this.duration;
7140
- this.resetItems();
7141
- this.currentTime = 0;
7142
- if (overshoot > 0) {
7143
- this.update(overshoot);
7144
- }
7145
- } else if (!this.loop && this.currentTime >= this.duration) {
7146
- this.currentTime = this.duration;
7147
- this.isPlaying = false;
7148
- this.isComplete = true;
7149
- if (this.onComplete) {
7150
- this.onComplete();
7151
- }
7152
- }
7153
- }
7154
- }
7155
-
7156
- class TimelineEngine {
7157
- timelines = new Set;
7158
- defaults = {
7159
- frameRate: 60
7160
- };
7161
- register(timeline) {
7162
- this.timelines.add(timeline);
7163
- }
7164
- unregister(timeline) {
7165
- this.timelines.delete(timeline);
7166
- }
7167
- clear() {
7168
- this.timelines.clear();
7169
- }
7170
- update(deltaTime) {
7171
- for (const timeline of this.timelines) {
7172
- if (!timeline.synced) {
7173
- timeline.update(deltaTime);
7174
- }
7175
- }
7176
- }
7177
- }
7178
- var engine = new TimelineEngine;
7179
- function createTimeline(options = {}) {
7180
- const timeline = new Timeline(options);
7181
- if (options.autoplay !== false) {
7182
- timeline.play();
7183
- }
7184
- engine.register(timeline);
7185
- return timeline;
7186
- }
7187
- // src/lib/selection.ts
7188
- class Selection {
7189
- _anchor;
7190
- _focus;
7191
- _selectedRenderables = [];
7192
- constructor(anchor, focus) {
7193
- this._anchor = { ...anchor };
7194
- this._focus = { ...focus };
7195
- }
7196
- get anchor() {
7197
- return { ...this._anchor };
7198
- }
7199
- get focus() {
7200
- return { ...this._focus };
7201
- }
7202
- get bounds() {
7203
- return {
7204
- startX: Math.min(this._anchor.x, this._focus.x),
7205
- startY: Math.min(this._anchor.y, this._focus.y),
7206
- endX: Math.max(this._anchor.x, this._focus.x),
7207
- endY: Math.max(this._anchor.y, this._focus.y)
7208
- };
7209
- }
7210
- updateSelectedRenderables(selectedRenderables) {
7211
- this._selectedRenderables = selectedRenderables;
7212
- }
7213
- getSelectedText() {
7214
- const selectedTexts = this._selectedRenderables.sort((a, b) => {
7215
- const aY = a.y;
7216
- const bY = b.y;
7217
- if (aY !== bY) {
7218
- return aY - bY;
7219
- }
7220
- return a.x - b.x;
7221
- }).map((renderable) => renderable.getSelectedText()).filter((text) => text);
7222
- return selectedTexts.join(`
7223
- `);
7224
- }
7225
- }
7226
-
7227
- class TextSelectionHelper {
7228
- getX;
7229
- getY;
7230
- getTextLength;
7231
- getLineInfo;
7232
- localSelection = null;
7233
- cachedGlobalSelection = null;
7234
- constructor(getX, getY, getTextLength, getLineInfo) {
7235
- this.getX = getX;
7236
- this.getY = getY;
7237
- this.getTextLength = getTextLength;
7238
- this.getLineInfo = getLineInfo;
7239
- }
7240
- hasSelection() {
7241
- return this.localSelection !== null;
7242
- }
7243
- getSelection() {
7244
- return this.localSelection;
7245
- }
7246
- reevaluateSelection(width, height = 1) {
7247
- if (!this.cachedGlobalSelection) {
7248
- return false;
7249
- }
7250
- return this.onSelectionChanged(this.cachedGlobalSelection, width, height);
7251
- }
7252
- shouldStartSelection(x, y, width, height) {
7253
- const localX = x - this.getX();
7254
- const localY = y - this.getY();
7255
- return localX >= 0 && localX < width && localY >= 0 && localY < height;
7256
- }
7257
- onSelectionChanged(selection, width, height = 1) {
7258
- this.cachedGlobalSelection = selection;
7259
- const previousSelection = this.localSelection;
7260
- if (!selection?.isActive) {
7261
- this.localSelection = null;
7262
- return previousSelection !== null;
7263
- }
7264
- const myY = this.getY();
7265
- const myEndY = myY + height - 1;
7266
- if (myEndY < selection.anchor.y || myY > selection.focus.y) {
7267
- this.localSelection = null;
7268
- return previousSelection !== null;
7269
- }
7270
- if (height === 1) {
7271
- this.localSelection = this.calculateSingleLineSelection(myY, selection.anchor.y, selection.focus.y, selection.anchor.x, selection.focus.x, width);
7272
- } else {
7273
- this.localSelection = this.calculateMultiLineSelection(myY, selection.anchor.y, selection.focus.y, selection.anchor.x, selection.focus.x);
7274
- }
7275
- return this.localSelection !== null !== (previousSelection !== null) || this.localSelection?.start !== previousSelection?.start || this.localSelection?.end !== previousSelection?.end;
7276
- }
7277
- calculateSingleLineSelection(lineY, anchorY, focusY, anchorX, focusX, width) {
7278
- const textLength = this.getTextLength();
7279
- const myX = this.getX();
7280
- if (lineY > anchorY && lineY < focusY) {
7281
- return { start: 0, end: textLength };
7282
- }
7283
- if (lineY === anchorY && lineY === focusY) {
7284
- const start = Math.max(0, Math.min(anchorX - myX, textLength));
7285
- const end = Math.max(0, Math.min(focusX - myX, textLength));
7286
- return start < end ? { start, end } : null;
7287
- }
7288
- if (lineY === anchorY) {
7289
- const start = Math.max(0, Math.min(anchorX - myX, textLength));
7290
- return start < textLength ? { start, end: textLength } : null;
7291
- }
7292
- if (lineY === focusY) {
7293
- const end = Math.max(0, Math.min(focusX - myX, textLength));
7294
- return end > 0 ? { start: 0, end } : null;
7295
- }
7296
- return null;
7297
- }
7298
- calculateMultiLineSelection(startY, anchorY, focusY, anchorX, focusX) {
7299
- const lineInfo = this.getLineInfo?.();
7300
- if (!lineInfo) {
7301
- return { start: 0, end: this.getTextLength() };
7302
- }
7303
- const myX = this.getX();
7304
- let selectionStart = null;
7305
- let selectionEnd = null;
7306
- for (let i = 0;i < lineInfo.lineStarts.length; i++) {
7307
- const lineY = startY + i;
7308
- if (lineY < anchorY || lineY > focusY)
7309
- continue;
7310
- const lineStart = lineInfo.lineStarts[i];
7311
- const lineEnd = i < lineInfo.lineStarts.length - 1 ? lineInfo.lineStarts[i + 1] - 1 : this.getTextLength();
7312
- const lineWidth = lineInfo.lineWidths[i];
7313
- if (lineY > anchorY && lineY < focusY) {
7314
- if (selectionStart === null)
7315
- selectionStart = lineStart;
7316
- selectionEnd = lineEnd;
7317
- } else if (lineY === anchorY && lineY === focusY) {
7318
- const localStartX = Math.max(0, Math.min(anchorX - myX, lineWidth));
7319
- const localEndX = Math.max(0, Math.min(focusX - myX, lineWidth));
7320
- if (localStartX < localEndX) {
7321
- selectionStart = lineStart + localStartX;
7322
- selectionEnd = lineStart + localEndX;
7323
- }
7324
- } else if (lineY === anchorY) {
7325
- const localStartX = Math.max(0, Math.min(anchorX - myX, lineWidth));
7326
- if (localStartX < lineWidth) {
7327
- selectionStart = lineStart + localStartX;
7328
- selectionEnd = lineEnd;
7329
- }
7330
- } else if (lineY === focusY) {
7331
- const localEndX = Math.max(0, Math.min(focusX - myX, lineWidth));
7332
- if (localEndX > 0) {
7333
- if (selectionStart === null)
7334
- selectionStart = lineStart;
7335
- selectionEnd = lineStart + localEndX;
7336
- }
7810
+ return;
7811
+ this.currentTime += deltaTime;
7812
+ for (const item of this.items) {
7813
+ evaluateItem(item, this.currentTime, deltaTime);
7814
+ }
7815
+ for (let i = this.items.length - 1;i >= 0; i--) {
7816
+ const item = this.items[i];
7817
+ if (item.type === "animation" && item.once && item.completed) {
7818
+ this.items.splice(i, 1);
7819
+ }
7820
+ }
7821
+ if (this.loop && this.currentTime >= this.duration) {
7822
+ const overshoot = this.currentTime % this.duration;
7823
+ this.resetItems();
7824
+ this.currentTime = 0;
7825
+ if (overshoot > 0) {
7826
+ this.update(overshoot);
7827
+ }
7828
+ } else if (!this.loop && this.currentTime >= this.duration) {
7829
+ this.currentTime = this.duration;
7830
+ this.isPlaying = false;
7831
+ this.isComplete = true;
7832
+ if (this.onComplete) {
7833
+ this.onComplete();
7337
7834
  }
7338
7835
  }
7339
- return selectionStart !== null && selectionEnd !== null && selectionStart < selectionEnd ? { start: selectionStart, end: selectionEnd } : null;
7340
7836
  }
7341
7837
  }
7342
7838
 
7343
- class ASCIIFontSelectionHelper {
7344
- getX;
7345
- getY;
7346
- getText;
7347
- getFont;
7348
- localSelection = null;
7349
- cachedGlobalSelection = null;
7350
- constructor(getX, getY, getText, getFont) {
7351
- this.getX = getX;
7352
- this.getY = getY;
7353
- this.getText = getText;
7354
- this.getFont = getFont;
7355
- }
7356
- hasSelection() {
7357
- return this.localSelection !== null;
7839
+ class TimelineEngine {
7840
+ timelines = new Set;
7841
+ defaults = {
7842
+ frameRate: 60
7843
+ };
7844
+ register(timeline) {
7845
+ this.timelines.add(timeline);
7358
7846
  }
7359
- getSelection() {
7360
- return this.localSelection;
7847
+ unregister(timeline) {
7848
+ this.timelines.delete(timeline);
7361
7849
  }
7362
- shouldStartSelection(x, y, width, height) {
7363
- const localX = x - this.getX();
7364
- const localY = y - this.getY();
7365
- if (localX < 0 || localX >= width || localY < 0 || localY >= height) {
7366
- return false;
7367
- }
7368
- const text = this.getText();
7369
- const font = this.getFont();
7370
- const charIndex = coordinateToCharacterIndex(localX, text, font);
7371
- return charIndex >= 0 && charIndex <= text.length;
7850
+ clear() {
7851
+ this.timelines.clear();
7372
7852
  }
7373
- onSelectionChanged(selection, width, height) {
7374
- this.cachedGlobalSelection = selection;
7375
- const previousSelection = this.localSelection;
7376
- if (!selection?.isActive) {
7377
- this.localSelection = null;
7378
- return previousSelection !== null;
7379
- }
7380
- const myX = this.getX();
7381
- const myY = this.getY();
7382
- const myEndY = myY + height - 1;
7383
- const text = this.getText();
7384
- const font = this.getFont();
7385
- let selStart;
7386
- let selEnd;
7387
- if (selection.anchor.y < selection.focus.y || selection.anchor.y === selection.focus.y && selection.anchor.x <= selection.focus.x) {
7388
- selStart = selection.anchor;
7389
- selEnd = selection.focus;
7390
- } else {
7391
- selStart = selection.focus;
7392
- selEnd = selection.anchor;
7393
- }
7394
- if (myEndY < selStart.y || myY > selEnd.y) {
7395
- this.localSelection = null;
7396
- return previousSelection !== null;
7397
- }
7398
- let startCharIndex = 0;
7399
- let endCharIndex = text.length;
7400
- if (selStart.y > myEndY) {
7401
- this.localSelection = null;
7402
- return previousSelection !== null;
7403
- } else if (selStart.y >= myY && selStart.y <= myEndY) {
7404
- const localX = selStart.x - myX;
7405
- if (localX > 0) {
7406
- startCharIndex = coordinateToCharacterIndex(localX, text, font);
7407
- }
7408
- }
7409
- if (selEnd.y < myY) {
7410
- this.localSelection = null;
7411
- return previousSelection !== null;
7412
- } else if (selEnd.y >= myY && selEnd.y <= myEndY) {
7413
- const localX = selEnd.x - myX;
7414
- if (localX >= 0) {
7415
- endCharIndex = coordinateToCharacterIndex(localX, text, font);
7416
- } else {
7417
- endCharIndex = 0;
7853
+ update(deltaTime) {
7854
+ for (const timeline of this.timelines) {
7855
+ if (!timeline.synced) {
7856
+ timeline.update(deltaTime);
7418
7857
  }
7419
7858
  }
7420
- if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) {
7421
- this.localSelection = { start: startCharIndex, end: endCharIndex };
7422
- } else {
7423
- this.localSelection = null;
7424
- }
7425
- return this.localSelection !== null !== (previousSelection !== null) || this.localSelection?.start !== previousSelection?.start || this.localSelection?.end !== previousSelection?.end;
7426
7859
  }
7427
- reevaluateSelection(width, height) {
7428
- if (!this.cachedGlobalSelection) {
7429
- return false;
7430
- }
7431
- return this.onSelectionChanged(this.cachedGlobalSelection, width, height);
7860
+ }
7861
+ var engine = new TimelineEngine;
7862
+ function createTimeline(options = {}) {
7863
+ const timeline = new Timeline(options);
7864
+ if (options.autoplay !== false) {
7865
+ timeline.play();
7432
7866
  }
7867
+ engine.register(timeline);
7868
+ return timeline;
7433
7869
  }
7434
7870
  // src/ansi.ts
7435
7871
  var ANSI = {
@@ -8119,106 +8555,6 @@ class TerminalConsole extends EventEmitter5 {
8119
8555
  }
8120
8556
  }
8121
8557
 
8122
- // src/lib/parse.mouse.ts
8123
- class MouseParser {
8124
- mouseButtonsPressed = new Set;
8125
- static SCROLL_DIRECTIONS = {
8126
- 64: "up",
8127
- 65: "down",
8128
- 66: "left",
8129
- 67: "right"
8130
- };
8131
- reset() {
8132
- this.mouseButtonsPressed.clear();
8133
- }
8134
- parseMouseEvent(data) {
8135
- const str = data.toString();
8136
- const sgrMatch = str.match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);
8137
- if (sgrMatch) {
8138
- const [, buttonCode, x, y, pressRelease] = sgrMatch;
8139
- const rawButtonCode = parseInt(buttonCode);
8140
- const scrollDirection = MouseParser.SCROLL_DIRECTIONS[rawButtonCode];
8141
- const isScroll = scrollDirection !== undefined;
8142
- const button = rawButtonCode & 3;
8143
- const isMotion = (rawButtonCode & 32) !== 0;
8144
- const modifiers = {
8145
- shift: (rawButtonCode & 4) !== 0,
8146
- alt: (rawButtonCode & 8) !== 0,
8147
- ctrl: (rawButtonCode & 16) !== 0
8148
- };
8149
- let type;
8150
- let scrollInfo;
8151
- if (isScroll && pressRelease === "M") {
8152
- type = "scroll";
8153
- scrollInfo = {
8154
- direction: scrollDirection,
8155
- delta: 1
8156
- };
8157
- } else if (isMotion) {
8158
- const isDragging = this.mouseButtonsPressed.size > 0;
8159
- if (button === 3) {
8160
- type = "move";
8161
- } else if (isDragging) {
8162
- type = "drag";
8163
- } else {
8164
- type = "move";
8165
- }
8166
- } else {
8167
- type = pressRelease === "M" ? "down" : "up";
8168
- if (type === "down" && button !== 3) {
8169
- this.mouseButtonsPressed.add(button);
8170
- } else if (type === "up") {
8171
- this.mouseButtonsPressed.clear();
8172
- }
8173
- }
8174
- return {
8175
- type,
8176
- button: button === 3 ? 0 : button,
8177
- x: parseInt(x) - 1,
8178
- y: parseInt(y) - 1,
8179
- modifiers,
8180
- scroll: scrollInfo
8181
- };
8182
- }
8183
- if (str.startsWith("\x1B[M") && str.length >= 6) {
8184
- const buttonByte = str.charCodeAt(3) - 32;
8185
- const x = str.charCodeAt(4) - 33;
8186
- const y = str.charCodeAt(5) - 33;
8187
- const scrollDirection = MouseParser.SCROLL_DIRECTIONS[buttonByte];
8188
- const isScroll = scrollDirection !== undefined;
8189
- const button = buttonByte & 3;
8190
- const modifiers = {
8191
- shift: (buttonByte & 4) !== 0,
8192
- alt: (buttonByte & 8) !== 0,
8193
- ctrl: (buttonByte & 16) !== 0
8194
- };
8195
- let type;
8196
- let actualButton;
8197
- let scrollInfo;
8198
- if (isScroll) {
8199
- type = "scroll";
8200
- actualButton = 0;
8201
- scrollInfo = {
8202
- direction: scrollDirection,
8203
- delta: 1
8204
- };
8205
- } else {
8206
- type = button === 3 ? "up" : "down";
8207
- actualButton = button === 3 ? 0 : button;
8208
- }
8209
- return {
8210
- type,
8211
- button: actualButton,
8212
- x,
8213
- y,
8214
- modifiers,
8215
- scroll: scrollInfo
8216
- };
8217
- }
8218
- return null;
8219
- }
8220
- }
8221
-
8222
8558
  // src/renderer.ts
8223
8559
  import { EventEmitter as EventEmitter6 } from "events";
8224
8560
 
@@ -8319,7 +8655,6 @@ class CliRenderer extends EventEmitter6 {
8319
8655
  postProcessFns = [];
8320
8656
  backgroundColor = RGBA.fromHex("#000000");
8321
8657
  waitingForPixelResolution = false;
8322
- shutdownRequested = null;
8323
8658
  rendering = false;
8324
8659
  renderingNative = false;
8325
8660
  renderTimeout = null;
@@ -8330,6 +8665,8 @@ class CliRenderer extends EventEmitter6 {
8330
8665
  targetFrameTime = 0;
8331
8666
  immediateRerenderRequested = false;
8332
8667
  updateScheduled = false;
8668
+ liveRequestCounter = 0;
8669
+ controlState = "idle" /* IDLE */;
8333
8670
  frameCallbacks = [];
8334
8671
  renderStats = {
8335
8672
  frameCount: 0,
@@ -8415,7 +8752,15 @@ class CliRenderer extends EventEmitter6 {
8415
8752
  this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
8416
8753
  this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
8417
8754
  this.postProcessFns = config.postProcessFns || [];
8418
- this.root = new RootRenderable(this.width, this.height, this.renderContext);
8755
+ const rootContext = {
8756
+ requestLive: () => {
8757
+ this.requestLive();
8758
+ },
8759
+ dropLive: () => {
8760
+ this.dropLive();
8761
+ }
8762
+ };
8763
+ this.root = new RootRenderable(this.width, this.height, this.renderContext, rootContext);
8419
8764
  this.setupTerminal();
8420
8765
  this.takeMemorySnapshot();
8421
8766
  if (this.memorySnapshotInterval > 0) {
@@ -8548,6 +8893,12 @@ Error details:
8548
8893
  get experimental_splitHeight() {
8549
8894
  return this._splitHeight;
8550
8895
  }
8896
+ get liveRequestCount() {
8897
+ return this.liveRequestCounter;
8898
+ }
8899
+ get currentControlState() {
8900
+ return this.controlState;
8901
+ }
8551
8902
  set experimental_splitHeight(splitHeight) {
8552
8903
  if (splitHeight < 0)
8553
8904
  splitHeight = 0;
@@ -8736,6 +9087,7 @@ Error details:
8736
9087
  if (this.capturedRenderable && mouseEvent.type === "up") {
8737
9088
  const event = new MouseEvent(this.capturedRenderable, { ...mouseEvent, type: "drag-end" });
8738
9089
  this.capturedRenderable.processMouseEvent(event);
9090
+ this.capturedRenderable.processMouseEvent(new MouseEvent(this.capturedRenderable, mouseEvent));
8739
9091
  if (maybeRenderable) {
8740
9092
  const event2 = new MouseEvent(maybeRenderable, {
8741
9093
  ...mouseEvent,
@@ -8749,7 +9101,7 @@ Error details:
8749
9101
  this.capturedRenderable = undefined;
8750
9102
  }
8751
9103
  if (maybeRenderable) {
8752
- if (mouseEvent.type === "down" && mouseEvent.button === 0 /* LEFT */) {
9104
+ if (mouseEvent.type === "drag" && mouseEvent.button === 0 /* LEFT */) {
8753
9105
  this.capturedRenderable = maybeRenderable;
8754
9106
  } else {
8755
9107
  this.capturedRenderable = undefined;
@@ -8916,7 +9268,25 @@ Error details:
8916
9268
  clearFrameCallbacks() {
8917
9269
  this.frameCallbacks = [];
8918
9270
  }
9271
+ requestLive() {
9272
+ this.liveRequestCounter++;
9273
+ if (this.controlState === "idle" /* IDLE */ && this.liveRequestCounter > 0) {
9274
+ this.controlState = "auto_started" /* AUTO_STARTED */;
9275
+ this.internalStart();
9276
+ }
9277
+ }
9278
+ dropLive() {
9279
+ this.liveRequestCounter = Math.max(0, this.liveRequestCounter - 1);
9280
+ if (this.controlState === "auto_started" /* AUTO_STARTED */ && this.liveRequestCounter === 0) {
9281
+ this.controlState = "idle" /* IDLE */;
9282
+ this.internalPause();
9283
+ }
9284
+ }
8919
9285
  start() {
9286
+ this.controlState = "explicit_started" /* EXPLICIT_STARTED */;
9287
+ this.internalStart();
9288
+ }
9289
+ internalStart() {
8920
9290
  if (!this._isRunning && !this.isDestroyed) {
8921
9291
  this._isRunning = true;
8922
9292
  if (this.memorySnapshotInterval > 0) {
@@ -8926,9 +9296,17 @@ Error details:
8926
9296
  }
8927
9297
  }
8928
9298
  pause() {
9299
+ this.controlState = "explicit_paused" /* EXPLICIT_PAUSED */;
9300
+ this.internalPause();
9301
+ }
9302
+ internalPause() {
8929
9303
  this._isRunning = false;
8930
9304
  }
8931
9305
  stop() {
9306
+ this.controlState = "explicit_stopped" /* EXPLICIT_STOPPED */;
9307
+ this.internalStop();
9308
+ }
9309
+ internalStop() {
8932
9310
  if (this.isRunning && !this.isDestroyed) {
8933
9311
  this._isRunning = false;
8934
9312
  if (this.memorySnapshotTimer) {
@@ -9349,9 +9727,8 @@ class TextRenderable extends Renderable {
9349
9727
  constructor(id, options) {
9350
9728
  super(id, options);
9351
9729
  this.selectionHelper = new TextSelectionHelper(() => this.x, () => this.y, () => this._plainText.length, () => this._lineInfo);
9352
- if (options.content) {
9353
- this._text = typeof options.content === "string" ? stringToStyledText(options.content) : options.content;
9354
- }
9730
+ const content = options.content ?? "";
9731
+ this._text = typeof content === "string" ? stringToStyledText(content) : content;
9355
9732
  this._defaultFg = options.fg ? parseColor(options.fg) : RGBA.fromValues(1, 1, 1, 1);
9356
9733
  this._defaultBg = options.bg ? parseColor(options.bg) : RGBA.fromValues(0, 0, 0, 0);
9357
9734
  this._defaultAttributes = options.attributes ?? 0;
@@ -9362,8 +9739,8 @@ class TextRenderable extends Renderable {
9362
9739
  this.textBuffer.setDefaultFg(this._defaultFg);
9363
9740
  this.textBuffer.setDefaultBg(this._defaultBg);
9364
9741
  this.textBuffer.setDefaultAttributes(this._defaultAttributes);
9365
- this.updateTextInfo();
9366
9742
  this.setupMeasureFunc();
9743
+ this.updateTextInfo();
9367
9744
  }
9368
9745
  get content() {
9369
9746
  return this._text;
@@ -9408,9 +9785,9 @@ class TextRenderable extends Renderable {
9408
9785
  }
9409
9786
  }
9410
9787
  syncSelectionToTextBuffer() {
9411
- const selection = this.selectionHelper.getSelection();
9412
- if (selection) {
9413
- this.textBuffer.setSelection(selection.start, selection.end, this._selectionBg, this._selectionFg);
9788
+ const selection2 = this.selectionHelper.getSelection();
9789
+ if (selection2) {
9790
+ this.textBuffer.setSelection(selection2.start, selection2.end, this._selectionBg, this._selectionFg);
9414
9791
  } else {
9415
9792
  this.textBuffer.resetSelection();
9416
9793
  }
@@ -9422,12 +9799,14 @@ class TextRenderable extends Renderable {
9422
9799
  this._lineInfo.lineStarts = lineInfo.lineStarts;
9423
9800
  this._lineInfo.lineWidths = lineInfo.lineWidths;
9424
9801
  const numLines = this._lineInfo.lineStarts.length;
9425
- if (this._height === "auto") {
9426
- this.height = numLines;
9802
+ if (this._positionType === "absolute" && this._height === "auto") {
9803
+ this._heightValue = numLines;
9804
+ this.layoutNode.yogaNode.markDirty();
9427
9805
  }
9428
9806
  const maxLineWidth = Math.max(...this._lineInfo.lineWidths);
9429
9807
  if (this._positionType === "absolute" && this._width === "auto") {
9430
- this.width = maxLineWidth;
9808
+ this._widthValue = maxLineWidth;
9809
+ this.layoutNode.yogaNode.markDirty();
9431
9810
  }
9432
9811
  const changed = this.selectionHelper.reevaluateSelection(this.width, this.height);
9433
9812
  if (changed) {
@@ -9436,35 +9815,33 @@ class TextRenderable extends Renderable {
9436
9815
  this.needsUpdate();
9437
9816
  }
9438
9817
  setupMeasureFunc() {
9439
- if (this._positionType === "relative" && this._width === "auto") {
9440
- const measureFunc = (width, widthMode, height, heightMode) => {
9441
- const maxLineWidth = Math.max(...this._lineInfo.lineWidths, 0);
9442
- const numLines = this._lineInfo.lineStarts.length || 1;
9443
- let measuredWidth = maxLineWidth;
9444
- let measuredHeight = numLines;
9445
- if (widthMode === MeasureMode.Exactly) {
9446
- measuredWidth = width;
9447
- } else if (widthMode === MeasureMode.AtMost) {
9448
- measuredWidth = Math.min(maxLineWidth, width);
9449
- }
9450
- if (heightMode === MeasureMode.Exactly) {
9451
- measuredHeight = height;
9452
- } else if (heightMode === MeasureMode.AtMost) {
9453
- measuredHeight = Math.min(numLines, height);
9454
- }
9455
- return {
9456
- width: Math.max(1, measuredWidth),
9457
- height: Math.max(1, measuredHeight)
9458
- };
9818
+ const measureFunc = (width, widthMode, height, heightMode) => {
9819
+ const maxLineWidth = Math.max(...this._lineInfo.lineWidths, 0);
9820
+ const numLines = this._lineInfo.lineStarts.length || 1;
9821
+ let measuredWidth = maxLineWidth;
9822
+ let measuredHeight = numLines;
9823
+ if (widthMode === MeasureMode.Exactly) {
9824
+ measuredWidth = width;
9825
+ } else if (widthMode === MeasureMode.AtMost) {
9826
+ measuredWidth = Math.min(maxLineWidth, width);
9827
+ }
9828
+ if (heightMode === MeasureMode.Exactly) {
9829
+ measuredHeight = height;
9830
+ } else if (heightMode === MeasureMode.AtMost) {
9831
+ measuredHeight = Math.min(numLines, height);
9832
+ }
9833
+ return {
9834
+ width: Math.max(1, measuredWidth),
9835
+ height: Math.max(1, measuredHeight)
9459
9836
  };
9460
- this.layoutNode.yogaNode.setMeasureFunc(measureFunc);
9461
- }
9837
+ };
9838
+ this.layoutNode.yogaNode.setMeasureFunc(measureFunc);
9462
9839
  }
9463
9840
  shouldStartSelection(x, y) {
9464
9841
  return this.selectionHelper.shouldStartSelection(x, y, this.width, this.height);
9465
9842
  }
9466
- onSelectionChanged(selection) {
9467
- const changed = this.selectionHelper.onSelectionChanged(selection, this.width, this.height);
9843
+ onSelectionChanged(selection2) {
9844
+ const changed = this.selectionHelper.onSelectionChanged(selection2, this.width, this.height);
9468
9845
  if (changed) {
9469
9846
  this.syncSelectionToTextBuffer();
9470
9847
  this.needsUpdate();
@@ -9472,10 +9849,10 @@ class TextRenderable extends Renderable {
9472
9849
  return this.selectionHelper.hasSelection();
9473
9850
  }
9474
9851
  getSelectedText() {
9475
- const selection = this.selectionHelper.getSelection();
9476
- if (!selection)
9852
+ const selection2 = this.selectionHelper.getSelection();
9853
+ if (!selection2)
9477
9854
  return "";
9478
- return this._plainText.slice(selection.start, selection.end);
9855
+ return this._plainText.slice(selection2.start, selection2.end);
9479
9856
  }
9480
9857
  hasSelection() {
9481
9858
  return this.selectionHelper.hasSelection();
@@ -9577,8 +9954,8 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
9577
9954
  shouldStartSelection(x, y) {
9578
9955
  return this.selectionHelper.shouldStartSelection(x, y, this.width, this.height);
9579
9956
  }
9580
- onSelectionChanged(selection) {
9581
- const changed = this.selectionHelper.onSelectionChanged(selection, this.width, this.height);
9957
+ onSelectionChanged(selection2) {
9958
+ const changed = this.selectionHelper.onSelectionChanged(selection2, this.width, this.height);
9582
9959
  if (changed) {
9583
9960
  this.renderFontToBuffer();
9584
9961
  this.needsUpdate();
@@ -9586,10 +9963,10 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
9586
9963
  return this.selectionHelper.hasSelection();
9587
9964
  }
9588
9965
  getSelectedText() {
9589
- const selection = this.selectionHelper.getSelection();
9590
- if (!selection)
9966
+ const selection2 = this.selectionHelper.getSelection();
9967
+ if (!selection2)
9591
9968
  return "";
9592
- return this._text.slice(selection.start, selection.end);
9969
+ return this._text.slice(selection2.start, selection2.end);
9593
9970
  }
9594
9971
  hasSelection() {
9595
9972
  return this.selectionHelper.hasSelection();
@@ -9608,20 +9985,20 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
9608
9985
  bg: this._bg,
9609
9986
  font: this._font
9610
9987
  });
9611
- const selection = this.selectionHelper.getSelection();
9612
- if (selection && (this._selectionBg || this._selectionFg)) {
9613
- this.renderSelectionHighlight(selection);
9988
+ const selection2 = this.selectionHelper.getSelection();
9989
+ if (selection2 && (this._selectionBg || this._selectionFg)) {
9990
+ this.renderSelectionHighlight(selection2);
9614
9991
  }
9615
9992
  }
9616
- renderSelectionHighlight(selection) {
9993
+ renderSelectionHighlight(selection2) {
9617
9994
  if (!this._selectionBg && !this._selectionFg)
9618
9995
  return;
9619
- const selectedText = this._text.slice(selection.start, selection.end);
9996
+ const selectedText = this._text.slice(selection2.start, selection2.end);
9620
9997
  if (!selectedText)
9621
9998
  return;
9622
9999
  const positions = getCharacterPositions(this._text, this._font);
9623
- const startX = positions[selection.start] || 0;
9624
- const endX = selection.end < positions.length ? positions[selection.end] : measureText({ text: this._text, font: this._font }).width;
10000
+ const startX = positions[selection2.start] || 0;
10001
+ const endX = selection2.end < positions.length ? positions[selection2.end] : measureText({ text: this._text, font: this._font }).width;
9625
10002
  if (this._selectionBg) {
9626
10003
  this.frameBuffer.fillRect(startX, 0, endX - startX, this.height, this._selectionBg);
9627
10004
  }
@@ -10424,13 +10801,29 @@ export {
10424
10801
  resolveRenderLib,
10425
10802
  renderFontToFrameBuffer,
10426
10803
  red,
10804
+ parseWrap,
10805
+ parseUnit,
10806
+ parsePositionType,
10807
+ parseOverflow,
10808
+ parseMeasureMode,
10809
+ parseLogLevel,
10427
10810
  parseKeypress,
10811
+ parseJustify,
10812
+ parseGutter,
10813
+ parseFlexDirection,
10814
+ parseEdge,
10815
+ parseDisplay,
10816
+ parseDirection,
10817
+ parseDimension,
10428
10818
  parseColor,
10819
+ parseBoxSizing,
10820
+ parseAlign,
10429
10821
  nonAlphanumericKeys,
10430
10822
  measureText,
10431
10823
  magenta,
10432
10824
  italic,
10433
10825
  isSizeType,
10826
+ isPostionTypeType,
10434
10827
  isPositionType,
10435
10828
  isPaddingType,
10436
10829
  isMarginType,
@@ -10504,6 +10897,7 @@ export {
10504
10897
  Renderable,
10505
10898
  RGBA,
10506
10899
  OptimizedBuffer,
10900
+ MouseParser,
10507
10901
  MouseEvent,
10508
10902
  MouseButton,
10509
10903
  LayoutEvents,
@@ -10526,3 +10920,6 @@ export {
10526
10920
  ASCIIFontSelectionHelper,
10527
10921
  ASCIIFontRenderable
10528
10922
  };
10923
+ export { __toESM, __commonJS, __export, __require };
10924
+ //# debugId=D2D08A0277CDE28864756E2164756E21
10925
+ //# sourceMappingURL=index.js.map