@opentui/core 0.1.6 → 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/3d/WGPURenderer.d.ts +2 -2
- package/3d.js +225 -6494
- package/3d.js.map +154 -0
- package/README.md +2 -0
- package/Renderable.d.ts +41 -3
- package/ansi.d.ts +2 -0
- package/buffer.d.ts +1 -1
- package/index.d.ts +0 -3
- package/index.js +2457 -2057
- package/index.js.map +44 -0
- package/lib/RGBA.d.ts +24 -0
- package/lib/ascii.font.d.ts +1 -1
- package/lib/border.d.ts +1 -1
- package/lib/hast-styled-text.d.ts +1 -1
- package/lib/index.d.ts +6 -0
- package/lib/styled-text.d.ts +6 -5
- package/package.json +9 -10
- package/renderables/ASCIIFont.d.ts +2 -1
- package/renderables/Box.d.ts +1 -2
- package/renderables/Input.d.ts +1 -1
- package/renderables/Select.d.ts +1 -1
- package/renderables/TabSelect.d.ts +1 -1
- package/renderables/Text.d.ts +2 -1
- package/renderer.d.ts +11 -3
- package/text-buffer.d.ts +1 -1
- package/types.d.ts +0 -20
- package/utils.d.ts +0 -5
- package/zig.d.ts +4 -2
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
|
|
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
|
-
|
|
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.
|
|
2838
|
-
this.
|
|
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/
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
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
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
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
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
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
|
-
|
|
2998
|
-
|
|
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,849 +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
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
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
|
-
|
|
3117
|
-
|
|
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
|
-
|
|
3120
|
-
|
|
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
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
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
|
-
|
|
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
|
|
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"],
|
|
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
|
-
createTextBuffer: {
|
|
3319
|
-
args: ["u32"],
|
|
3320
|
-
returns: "ptr"
|
|
3321
|
-
},
|
|
3322
|
-
destroyTextBuffer: {
|
|
3323
|
-
args: ["ptr"],
|
|
3324
|
-
returns: "void"
|
|
3325
|
-
},
|
|
3326
|
-
textBufferGetCharPtr: {
|
|
3327
|
-
args: ["ptr"],
|
|
3328
|
-
returns: "ptr"
|
|
3329
|
-
},
|
|
3330
|
-
textBufferGetFgPtr: {
|
|
3331
|
-
args: ["ptr"],
|
|
3332
|
-
returns: "ptr"
|
|
3333
|
-
},
|
|
3334
|
-
textBufferGetBgPtr: {
|
|
3335
|
-
args: ["ptr"],
|
|
3336
|
-
returns: "ptr"
|
|
3337
|
-
},
|
|
3338
|
-
textBufferGetAttributesPtr: {
|
|
3339
|
-
args: ["ptr"],
|
|
3340
|
-
returns: "ptr"
|
|
3341
|
-
},
|
|
3342
|
-
textBufferGetLength: {
|
|
3343
|
-
args: ["ptr"],
|
|
3344
|
-
returns: "u32"
|
|
3345
|
-
},
|
|
3346
|
-
textBufferSetCell: {
|
|
3347
|
-
args: ["ptr", "u32", "u32", "ptr", "ptr", "u16"],
|
|
3348
|
-
returns: "void"
|
|
3349
|
-
},
|
|
3350
|
-
textBufferConcat: {
|
|
3351
|
-
args: ["ptr", "ptr"],
|
|
3352
|
-
returns: "ptr"
|
|
3353
|
-
},
|
|
3354
|
-
textBufferResize: {
|
|
3355
|
-
args: ["ptr", "u32"],
|
|
3356
|
-
returns: "void"
|
|
3357
|
-
},
|
|
3358
|
-
textBufferReset: {
|
|
3359
|
-
args: ["ptr"],
|
|
3360
|
-
returns: "void"
|
|
3361
|
-
},
|
|
3362
|
-
textBufferSetSelection: {
|
|
3363
|
-
args: ["ptr", "u32", "u32", "ptr", "ptr"],
|
|
3364
|
-
returns: "void"
|
|
3365
|
-
},
|
|
3366
|
-
textBufferResetSelection: {
|
|
3367
|
-
args: ["ptr"],
|
|
3368
|
-
returns: "void"
|
|
3369
|
-
},
|
|
3370
|
-
textBufferSetDefaultFg: {
|
|
3371
|
-
args: ["ptr", "ptr"],
|
|
3372
|
-
returns: "void"
|
|
3373
|
-
},
|
|
3374
|
-
textBufferSetDefaultBg: {
|
|
3375
|
-
args: ["ptr", "ptr"],
|
|
3376
|
-
returns: "void"
|
|
3377
|
-
},
|
|
3378
|
-
textBufferSetDefaultAttributes: {
|
|
3379
|
-
args: ["ptr", "ptr"],
|
|
3380
|
-
returns: "void"
|
|
3381
|
-
},
|
|
3382
|
-
textBufferResetDefaults: {
|
|
3383
|
-
args: ["ptr"],
|
|
3384
|
-
returns: "void"
|
|
3385
|
-
},
|
|
3386
|
-
textBufferWriteChunk: {
|
|
3387
|
-
args: ["ptr", "ptr", "u32", "ptr", "ptr", "ptr"],
|
|
3388
|
-
returns: "u32"
|
|
3389
|
-
},
|
|
3390
|
-
textBufferGetCapacity: {
|
|
3391
|
-
args: ["ptr"],
|
|
3392
|
-
returns: "u32"
|
|
3393
|
-
},
|
|
3394
|
-
textBufferFinalizeLineInfo: {
|
|
3395
|
-
args: ["ptr"],
|
|
3396
|
-
returns: "void"
|
|
3397
|
-
},
|
|
3398
|
-
textBufferGetLineStartsPtr: {
|
|
3399
|
-
args: ["ptr"],
|
|
3400
|
-
returns: "ptr"
|
|
3401
|
-
},
|
|
3402
|
-
textBufferGetLineWidthsPtr: {
|
|
3403
|
-
args: ["ptr"],
|
|
3404
|
-
returns: "ptr"
|
|
3405
|
-
},
|
|
3406
|
-
textBufferGetLineCount: {
|
|
3407
|
-
args: ["ptr"],
|
|
3408
|
-
returns: "u32"
|
|
3409
|
-
},
|
|
3410
|
-
bufferDrawTextBuffer: {
|
|
3411
|
-
args: ["ptr", "ptr", "i32", "i32", "i32", "i32", "u32", "u32", "bool"],
|
|
3412
|
-
returns: "void"
|
|
3413
|
-
}
|
|
3414
|
-
});
|
|
3415
|
-
}
|
|
3416
|
-
|
|
3417
|
-
class FFIRenderLib {
|
|
3418
|
-
opentui;
|
|
3419
|
-
encoder = new TextEncoder;
|
|
3420
|
-
constructor(libPath) {
|
|
3421
|
-
this.opentui = getOpenTUILib(libPath);
|
|
3422
|
-
}
|
|
3423
|
-
createRenderer(width, height) {
|
|
3424
|
-
return this.opentui.symbols.createRenderer(width, height);
|
|
3425
|
-
}
|
|
3426
|
-
destroyRenderer(renderer) {
|
|
3427
|
-
this.opentui.symbols.destroyRenderer(renderer);
|
|
3428
|
-
}
|
|
3429
|
-
setUseThread(renderer, useThread) {
|
|
3430
|
-
this.opentui.symbols.setUseThread(renderer, useThread);
|
|
3431
|
-
}
|
|
3432
|
-
setBackgroundColor(renderer, color) {
|
|
3433
|
-
this.opentui.symbols.setBackgroundColor(renderer, color.buffer);
|
|
3434
|
-
}
|
|
3435
|
-
setRenderOffset(renderer, offset) {
|
|
3436
|
-
this.opentui.symbols.setRenderOffset(renderer, offset);
|
|
3437
|
-
}
|
|
3438
|
-
updateStats(renderer, time, fps, frameCallbackTime) {
|
|
3439
|
-
this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime);
|
|
3440
|
-
}
|
|
3441
|
-
updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers) {
|
|
3442
|
-
this.opentui.symbols.updateMemoryStats(renderer, heapUsed, heapTotal, arrayBuffers);
|
|
3443
|
-
}
|
|
3444
|
-
getNextBuffer(renderer) {
|
|
3445
|
-
const bufferPtr = this.opentui.symbols.getNextBuffer(renderer);
|
|
3446
|
-
if (!bufferPtr) {
|
|
3447
|
-
throw new Error("Failed to get next buffer");
|
|
3448
|
-
}
|
|
3449
|
-
const width = this.opentui.symbols.getBufferWidth(bufferPtr);
|
|
3450
|
-
const height = this.opentui.symbols.getBufferHeight(bufferPtr);
|
|
3451
|
-
const size = width * height;
|
|
3452
|
-
const buffers = this.getBuffer(bufferPtr, size);
|
|
3453
|
-
return new OptimizedBuffer(this, bufferPtr, buffers, width, height, {});
|
|
3454
|
-
}
|
|
3455
|
-
getCurrentBuffer(renderer) {
|
|
3456
|
-
const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer);
|
|
3457
|
-
if (!bufferPtr) {
|
|
3458
|
-
throw new Error("Failed to get current buffer");
|
|
3459
|
-
}
|
|
3460
|
-
const width = this.opentui.symbols.getBufferWidth(bufferPtr);
|
|
3461
|
-
const height = this.opentui.symbols.getBufferHeight(bufferPtr);
|
|
3462
|
-
const size = width * height;
|
|
3463
|
-
const buffers = this.getBuffer(bufferPtr, size);
|
|
3464
|
-
return new OptimizedBuffer(this, bufferPtr, buffers, width, height, {});
|
|
3465
|
-
}
|
|
3466
|
-
getBuffer(bufferPtr, size) {
|
|
3467
|
-
const charPtr = this.opentui.symbols.bufferGetCharPtr(bufferPtr);
|
|
3468
|
-
const fgPtr = this.opentui.symbols.bufferGetFgPtr(bufferPtr);
|
|
3469
|
-
const bgPtr = this.opentui.symbols.bufferGetBgPtr(bufferPtr);
|
|
3470
|
-
const attributesPtr = this.opentui.symbols.bufferGetAttributesPtr(bufferPtr);
|
|
3471
|
-
if (!charPtr || !fgPtr || !bgPtr || !attributesPtr) {
|
|
3472
|
-
throw new Error("Failed to get buffer pointers");
|
|
3473
|
-
}
|
|
3474
|
-
const buffers = {
|
|
3475
|
-
char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
|
|
3476
|
-
fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
|
|
3477
|
-
bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
|
|
3478
|
-
attributes: new Uint8Array(toArrayBuffer(attributesPtr, 0, size))
|
|
3479
|
-
};
|
|
3480
|
-
return buffers;
|
|
3481
|
-
}
|
|
3482
|
-
getTextBuffer(bufferPtr, size) {
|
|
3483
|
-
const charPtr = this.opentui.symbols.textBufferGetCharPtr(bufferPtr);
|
|
3484
|
-
const fgPtr = this.opentui.symbols.textBufferGetFgPtr(bufferPtr);
|
|
3485
|
-
const bgPtr = this.opentui.symbols.textBufferGetBgPtr(bufferPtr);
|
|
3486
|
-
const attributesPtr = this.opentui.symbols.textBufferGetAttributesPtr(bufferPtr);
|
|
3487
|
-
if (!charPtr || !fgPtr || !bgPtr || !attributesPtr) {
|
|
3488
|
-
throw new Error("Failed to get text buffer pointers");
|
|
3489
|
-
}
|
|
3490
|
-
const buffers = {
|
|
3491
|
-
char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
|
|
3492
|
-
fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
|
|
3493
|
-
bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
|
|
3494
|
-
attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, size * 2))
|
|
3495
|
-
};
|
|
3496
|
-
return buffers;
|
|
3497
|
-
}
|
|
3498
|
-
bufferGetCharPtr(buffer) {
|
|
3499
|
-
const ptr = this.opentui.symbols.bufferGetCharPtr(buffer);
|
|
3500
|
-
if (!ptr) {
|
|
3501
|
-
throw new Error("Failed to get char pointer");
|
|
3502
|
-
}
|
|
3503
|
-
return ptr;
|
|
3504
|
-
}
|
|
3505
|
-
bufferGetFgPtr(buffer) {
|
|
3506
|
-
const ptr = this.opentui.symbols.bufferGetFgPtr(buffer);
|
|
3507
|
-
if (!ptr) {
|
|
3508
|
-
throw new Error("Failed to get fg pointer");
|
|
3509
|
-
}
|
|
3510
|
-
return ptr;
|
|
3511
|
-
}
|
|
3512
|
-
bufferGetBgPtr(buffer) {
|
|
3513
|
-
const ptr = this.opentui.symbols.bufferGetBgPtr(buffer);
|
|
3514
|
-
if (!ptr) {
|
|
3515
|
-
throw new Error("Failed to get bg pointer");
|
|
3516
|
-
}
|
|
3517
|
-
return ptr;
|
|
3518
|
-
}
|
|
3519
|
-
bufferGetAttributesPtr(buffer) {
|
|
3520
|
-
const ptr = this.opentui.symbols.bufferGetAttributesPtr(buffer);
|
|
3521
|
-
if (!ptr) {
|
|
3522
|
-
throw new Error("Failed to get attributes pointer");
|
|
3523
|
-
}
|
|
3524
|
-
return ptr;
|
|
3525
|
-
}
|
|
3526
|
-
bufferGetRespectAlpha(buffer) {
|
|
3527
|
-
return this.opentui.symbols.bufferGetRespectAlpha(buffer);
|
|
3528
|
-
}
|
|
3529
|
-
bufferSetRespectAlpha(buffer, respectAlpha) {
|
|
3530
|
-
this.opentui.symbols.bufferSetRespectAlpha(buffer, respectAlpha);
|
|
3531
|
-
}
|
|
3532
|
-
getBufferWidth(buffer) {
|
|
3533
|
-
return this.opentui.symbols.getBufferWidth(buffer);
|
|
3534
|
-
}
|
|
3535
|
-
getBufferHeight(buffer) {
|
|
3536
|
-
return this.opentui.symbols.getBufferHeight(buffer);
|
|
3537
|
-
}
|
|
3538
|
-
bufferClear(buffer, color) {
|
|
3539
|
-
this.opentui.symbols.bufferClear(buffer, color.buffer);
|
|
3540
|
-
}
|
|
3541
|
-
bufferDrawText(buffer, text, x, y, color, bgColor, attributes) {
|
|
3542
|
-
const textBytes = this.encoder.encode(text);
|
|
3543
|
-
const textLength = textBytes.byteLength;
|
|
3544
|
-
const bg = bgColor ? bgColor.buffer : null;
|
|
3545
|
-
const fg = color.buffer;
|
|
3546
|
-
this.opentui.symbols.bufferDrawText(buffer, textBytes, textLength, x, y, fg, bg, attributes ?? 0);
|
|
3547
|
-
}
|
|
3548
|
-
bufferSetCellWithAlphaBlending(buffer, x, y, char, color, bgColor, attributes) {
|
|
3549
|
-
const charPtr = char.codePointAt(0) ?? " ".codePointAt(0);
|
|
3550
|
-
const bg = bgColor.buffer;
|
|
3551
|
-
const fg = color.buffer;
|
|
3552
|
-
this.opentui.symbols.bufferSetCellWithAlphaBlending(buffer, x, y, charPtr, fg, bg, attributes ?? 0);
|
|
3553
|
-
}
|
|
3554
|
-
bufferFillRect(buffer, x, y, width, height, color) {
|
|
3555
|
-
const bg = color.buffer;
|
|
3556
|
-
this.opentui.symbols.bufferFillRect(buffer, x, y, width, height, bg);
|
|
3557
|
-
}
|
|
3558
|
-
bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow) {
|
|
3559
|
-
const formatId = format === "bgra8unorm" ? 0 : 1;
|
|
3560
|
-
this.opentui.symbols.bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, formatId, alignedBytesPerRow);
|
|
3561
|
-
}
|
|
3562
|
-
bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
|
|
3563
|
-
this.opentui.symbols.bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
|
|
3564
|
-
}
|
|
3565
|
-
bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, title) {
|
|
3566
|
-
const titleBytes = title ? this.encoder.encode(title) : null;
|
|
3567
|
-
const titleLen = title ? titleBytes.length : 0;
|
|
3568
|
-
const titlePtr = title ? titleBytes : null;
|
|
3569
|
-
this.opentui.symbols.bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor.buffer, backgroundColor.buffer, titlePtr, titleLen);
|
|
3570
|
-
}
|
|
3571
|
-
bufferResize(buffer, width, height) {
|
|
3572
|
-
this.opentui.symbols.bufferResize(buffer, width, height);
|
|
3573
|
-
const buffers = this.getBuffer(buffer, width * height);
|
|
3574
|
-
return buffers;
|
|
3575
|
-
}
|
|
3576
|
-
resizeRenderer(renderer, width, height) {
|
|
3577
|
-
this.opentui.symbols.resizeRenderer(renderer, width, height);
|
|
3578
|
-
}
|
|
3579
|
-
setCursorPosition(x, y, visible) {
|
|
3580
|
-
this.opentui.symbols.setCursorPosition(x, y, visible);
|
|
3581
|
-
}
|
|
3582
|
-
setCursorStyle(style, blinking) {
|
|
3583
|
-
const stylePtr = this.encoder.encode(style);
|
|
3584
|
-
this.opentui.symbols.setCursorStyle(stylePtr, style.length, blinking);
|
|
3585
|
-
}
|
|
3586
|
-
setCursorColor(color) {
|
|
3587
|
-
this.opentui.symbols.setCursorColor(color.buffer);
|
|
3588
|
-
}
|
|
3589
|
-
render(renderer, force) {
|
|
3590
|
-
this.opentui.symbols.render(renderer, force);
|
|
3591
|
-
}
|
|
3592
|
-
createOptimizedBuffer(width, height, respectAlpha = false) {
|
|
3593
|
-
if (Number.isNaN(width) || Number.isNaN(height)) {
|
|
3594
|
-
console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
|
|
3595
|
-
}
|
|
3596
|
-
const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, respectAlpha);
|
|
3597
|
-
if (!bufferPtr) {
|
|
3598
|
-
throw new Error(`Failed to create optimized buffer: ${width}x${height}`);
|
|
3599
|
-
}
|
|
3600
|
-
const size = width * height;
|
|
3601
|
-
const buffers = this.getBuffer(bufferPtr, size);
|
|
3602
|
-
return new OptimizedBuffer(this, bufferPtr, buffers, width, height, { respectAlpha });
|
|
3603
|
-
}
|
|
3604
|
-
destroyOptimizedBuffer(bufferPtr) {
|
|
3605
|
-
this.opentui.symbols.destroyOptimizedBuffer(bufferPtr);
|
|
3606
|
-
}
|
|
3607
|
-
drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, sourceX, sourceY, sourceWidth, sourceHeight) {
|
|
3608
|
-
const srcX = sourceX ?? 0;
|
|
3609
|
-
const srcY = sourceY ?? 0;
|
|
3610
|
-
const srcWidth = sourceWidth ?? 0;
|
|
3611
|
-
const srcHeight = sourceHeight ?? 0;
|
|
3612
|
-
this.opentui.symbols.drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, srcX, srcY, srcWidth, srcHeight);
|
|
3613
|
-
}
|
|
3614
|
-
setDebugOverlay(renderer, enabled, corner) {
|
|
3615
|
-
this.opentui.symbols.setDebugOverlay(renderer, enabled, corner);
|
|
3616
|
-
}
|
|
3617
|
-
clearTerminal(renderer) {
|
|
3618
|
-
this.opentui.symbols.clearTerminal(renderer);
|
|
3619
|
-
}
|
|
3620
|
-
addToHitGrid(renderer, x, y, width, height, id) {
|
|
3621
|
-
this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id);
|
|
3622
|
-
}
|
|
3623
|
-
checkHit(renderer, x, y) {
|
|
3624
|
-
return this.opentui.symbols.checkHit(renderer, x, y);
|
|
3625
|
-
}
|
|
3626
|
-
dumpHitGrid(renderer) {
|
|
3627
|
-
this.opentui.symbols.dumpHitGrid(renderer);
|
|
3628
|
-
}
|
|
3629
|
-
dumpBuffers(renderer, timestamp) {
|
|
3630
|
-
const ts = timestamp ?? Date.now();
|
|
3631
|
-
this.opentui.symbols.dumpBuffers(renderer, ts);
|
|
3632
|
-
}
|
|
3633
|
-
dumpStdoutBuffer(renderer, timestamp) {
|
|
3634
|
-
const ts = timestamp ?? Date.now();
|
|
3635
|
-
this.opentui.symbols.dumpStdoutBuffer(renderer, ts);
|
|
3636
|
-
}
|
|
3637
|
-
createTextBuffer(capacity) {
|
|
3638
|
-
const bufferPtr = this.opentui.symbols.createTextBuffer(capacity);
|
|
3639
|
-
if (!bufferPtr) {
|
|
3640
|
-
throw new Error(`Failed to create TextBuffer with capacity ${capacity}`);
|
|
3641
|
-
}
|
|
3642
|
-
const charPtr = this.textBufferGetCharPtr(bufferPtr);
|
|
3643
|
-
const fgPtr = this.textBufferGetFgPtr(bufferPtr);
|
|
3644
|
-
const bgPtr = this.textBufferGetBgPtr(bufferPtr);
|
|
3645
|
-
const attributesPtr = this.textBufferGetAttributesPtr(bufferPtr);
|
|
3646
|
-
const buffer = {
|
|
3647
|
-
char: new Uint32Array(toArrayBuffer(charPtr, 0, capacity * 4)),
|
|
3648
|
-
fg: new Float32Array(toArrayBuffer(fgPtr, 0, capacity * 4 * 4)),
|
|
3649
|
-
bg: new Float32Array(toArrayBuffer(bgPtr, 0, capacity * 4 * 4)),
|
|
3650
|
-
attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, capacity * 2))
|
|
3651
|
-
};
|
|
3652
|
-
return new TextBuffer(this, bufferPtr, buffer, capacity);
|
|
3653
|
-
}
|
|
3654
|
-
destroyTextBuffer(buffer) {
|
|
3655
|
-
this.opentui.symbols.destroyTextBuffer(buffer);
|
|
3656
|
-
}
|
|
3657
|
-
textBufferGetCharPtr(buffer) {
|
|
3658
|
-
const ptr = this.opentui.symbols.textBufferGetCharPtr(buffer);
|
|
3659
|
-
if (!ptr) {
|
|
3660
|
-
throw new Error("Failed to get TextBuffer char pointer");
|
|
3661
|
-
}
|
|
3662
|
-
return ptr;
|
|
3663
|
-
}
|
|
3664
|
-
textBufferGetFgPtr(buffer) {
|
|
3665
|
-
const ptr = this.opentui.symbols.textBufferGetFgPtr(buffer);
|
|
3666
|
-
if (!ptr) {
|
|
3667
|
-
throw new Error("Failed to get TextBuffer fg pointer");
|
|
3668
|
-
}
|
|
3669
|
-
return ptr;
|
|
3670
|
-
}
|
|
3671
|
-
textBufferGetBgPtr(buffer) {
|
|
3672
|
-
const ptr = this.opentui.symbols.textBufferGetBgPtr(buffer);
|
|
3673
|
-
if (!ptr) {
|
|
3674
|
-
throw new Error("Failed to get TextBuffer bg pointer");
|
|
3675
|
-
}
|
|
3676
|
-
return ptr;
|
|
3677
|
-
}
|
|
3678
|
-
textBufferGetAttributesPtr(buffer) {
|
|
3679
|
-
const ptr = this.opentui.symbols.textBufferGetAttributesPtr(buffer);
|
|
3680
|
-
if (!ptr) {
|
|
3681
|
-
throw new Error("Failed to get TextBuffer attributes pointer");
|
|
3682
|
-
}
|
|
3683
|
-
return ptr;
|
|
3684
|
-
}
|
|
3685
|
-
textBufferGetLength(buffer) {
|
|
3686
|
-
return this.opentui.symbols.textBufferGetLength(buffer);
|
|
3687
|
-
}
|
|
3688
|
-
textBufferSetCell(buffer, index, char, fg, bg, attr) {
|
|
3689
|
-
this.opentui.symbols.textBufferSetCell(buffer, index, char, fg, bg, attr);
|
|
3690
|
-
}
|
|
3691
|
-
textBufferConcat(buffer1, buffer2) {
|
|
3692
|
-
const resultPtr = this.opentui.symbols.textBufferConcat(buffer1, buffer2);
|
|
3693
|
-
if (!resultPtr) {
|
|
3694
|
-
throw new Error("Failed to concatenate TextBuffers");
|
|
3695
|
-
}
|
|
3696
|
-
const length = this.textBufferGetLength(resultPtr);
|
|
3697
|
-
const charPtr = this.textBufferGetCharPtr(resultPtr);
|
|
3698
|
-
const fgPtr = this.textBufferGetFgPtr(resultPtr);
|
|
3699
|
-
const bgPtr = this.textBufferGetBgPtr(resultPtr);
|
|
3700
|
-
const attributesPtr = this.textBufferGetAttributesPtr(resultPtr);
|
|
3701
|
-
const buffer = {
|
|
3702
|
-
char: new Uint32Array(toArrayBuffer(charPtr, 0, length * 4)),
|
|
3703
|
-
fg: new Float32Array(toArrayBuffer(fgPtr, 0, length * 4 * 4)),
|
|
3704
|
-
bg: new Float32Array(toArrayBuffer(bgPtr, 0, length * 4 * 4)),
|
|
3705
|
-
attributes: new Uint16Array(toArrayBuffer(attributesPtr, 0, length * 2))
|
|
3706
|
-
};
|
|
3707
|
-
return new TextBuffer(this, resultPtr, buffer, length);
|
|
3708
|
-
}
|
|
3709
|
-
textBufferResize(buffer, newLength) {
|
|
3710
|
-
this.opentui.symbols.textBufferResize(buffer, newLength);
|
|
3711
|
-
const buffers = this.getTextBuffer(buffer, newLength);
|
|
3712
|
-
return buffers;
|
|
3713
|
-
}
|
|
3714
|
-
textBufferReset(buffer) {
|
|
3715
|
-
this.opentui.symbols.textBufferReset(buffer);
|
|
3716
|
-
}
|
|
3717
|
-
textBufferSetSelection(buffer, start, end, bgColor, fgColor) {
|
|
3718
|
-
const bg = bgColor ? bgColor.buffer : null;
|
|
3719
|
-
const fg = fgColor ? fgColor.buffer : null;
|
|
3720
|
-
this.opentui.symbols.textBufferSetSelection(buffer, start, end, bg, fg);
|
|
3721
|
-
}
|
|
3722
|
-
textBufferResetSelection(buffer) {
|
|
3723
|
-
this.opentui.symbols.textBufferResetSelection(buffer);
|
|
3724
|
-
}
|
|
3725
|
-
textBufferSetDefaultFg(buffer, fg) {
|
|
3726
|
-
const fgPtr = fg ? fg.buffer : null;
|
|
3727
|
-
this.opentui.symbols.textBufferSetDefaultFg(buffer, fgPtr);
|
|
3728
|
-
}
|
|
3729
|
-
textBufferSetDefaultBg(buffer, bg) {
|
|
3730
|
-
const bgPtr = bg ? bg.buffer : null;
|
|
3731
|
-
this.opentui.symbols.textBufferSetDefaultBg(buffer, bgPtr);
|
|
3732
|
-
}
|
|
3733
|
-
textBufferSetDefaultAttributes(buffer, attributes) {
|
|
3734
|
-
const attrValue = attributes === null ? null : new Uint8Array([attributes]);
|
|
3735
|
-
this.opentui.symbols.textBufferSetDefaultAttributes(buffer, attrValue);
|
|
3736
|
-
}
|
|
3737
|
-
textBufferResetDefaults(buffer) {
|
|
3738
|
-
this.opentui.symbols.textBufferResetDefaults(buffer);
|
|
3739
|
-
}
|
|
3740
|
-
textBufferWriteChunk(buffer, textBytes, fg, bg, attributes) {
|
|
3741
|
-
const attrValue = attributes === null ? null : new Uint8Array([attributes]);
|
|
3742
|
-
return this.opentui.symbols.textBufferWriteChunk(buffer, textBytes, textBytes.length, fg ? fg.buffer : null, bg ? bg.buffer : null, attrValue);
|
|
3743
|
-
}
|
|
3744
|
-
textBufferGetCapacity(buffer) {
|
|
3745
|
-
return this.opentui.symbols.textBufferGetCapacity(buffer);
|
|
3746
|
-
}
|
|
3747
|
-
textBufferFinalizeLineInfo(buffer) {
|
|
3748
|
-
this.opentui.symbols.textBufferFinalizeLineInfo(buffer);
|
|
3749
|
-
}
|
|
3750
|
-
textBufferGetLineInfo(buffer) {
|
|
3751
|
-
const lineCount = this.opentui.symbols.textBufferGetLineCount(buffer);
|
|
3752
|
-
if (lineCount === 0) {
|
|
3753
|
-
return { lineStarts: [], lineWidths: [] };
|
|
3754
|
-
}
|
|
3755
|
-
const lineStartsPtr = this.opentui.symbols.textBufferGetLineStartsPtr(buffer);
|
|
3756
|
-
const lineWidthsPtr = this.opentui.symbols.textBufferGetLineWidthsPtr(buffer);
|
|
3757
|
-
if (!lineStartsPtr || !lineWidthsPtr) {
|
|
3758
|
-
return { lineStarts: [], lineWidths: [] };
|
|
3759
|
-
}
|
|
3760
|
-
const lineStartsArray = new Uint32Array(toArrayBuffer(lineStartsPtr, 0, lineCount * 4));
|
|
3761
|
-
const lineWidthsArray = new Uint32Array(toArrayBuffer(lineWidthsPtr, 0, lineCount * 4));
|
|
3762
|
-
const lineStarts = Array.from(lineStartsArray);
|
|
3763
|
-
const lineWidths = Array.from(lineWidthsArray);
|
|
3764
|
-
return { lineStarts, lineWidths };
|
|
3765
|
-
}
|
|
3766
|
-
getTextBufferArrays(buffer, size) {
|
|
3767
|
-
return this.getTextBuffer(buffer, size);
|
|
3768
|
-
}
|
|
3769
|
-
bufferDrawTextBuffer(buffer, textBuffer, x, y, clipRect) {
|
|
3770
|
-
const hasClipRect = clipRect !== undefined && clipRect !== null;
|
|
3771
|
-
const clipX = clipRect?.x ?? 0;
|
|
3772
|
-
const clipY = clipRect?.y ?? 0;
|
|
3773
|
-
const clipWidth = clipRect?.width ?? 0;
|
|
3774
|
-
const clipHeight = clipRect?.height ?? 0;
|
|
3775
|
-
this.opentui.symbols.bufferDrawTextBuffer(buffer, textBuffer, x, y, clipX, clipY, clipWidth, clipHeight, hasClipRect);
|
|
3776
|
-
}
|
|
3777
|
-
}
|
|
3778
|
-
var opentuiLibPath;
|
|
3779
|
-
var opentuiLib;
|
|
3780
|
-
function setRenderLibPath(libPath) {
|
|
3781
|
-
opentuiLibPath = libPath;
|
|
3782
|
-
}
|
|
3783
|
-
function resolveRenderLib() {
|
|
3784
|
-
if (!opentuiLib) {
|
|
3785
|
-
opentuiLib = new FFIRenderLib(opentuiLibPath);
|
|
3786
|
-
}
|
|
3787
|
-
return opentuiLib;
|
|
3788
|
-
}
|
|
3789
|
-
|
|
3790
|
-
// src/lib/border.ts
|
|
3791
|
-
var BorderChars = {
|
|
3792
|
-
single: {
|
|
3793
|
-
topLeft: "\u250C",
|
|
3794
|
-
topRight: "\u2510",
|
|
3795
|
-
bottomLeft: "\u2514",
|
|
3796
|
-
bottomRight: "\u2518",
|
|
3797
|
-
horizontal: "\u2500",
|
|
3798
|
-
vertical: "\u2502",
|
|
3799
|
-
topT: "\u252C",
|
|
3800
|
-
bottomT: "\u2534",
|
|
3801
|
-
leftT: "\u251C",
|
|
3802
|
-
rightT: "\u2524",
|
|
3803
|
-
cross: "\u253C"
|
|
3804
|
-
},
|
|
3805
|
-
double: {
|
|
3806
|
-
topLeft: "\u2554",
|
|
3807
|
-
topRight: "\u2557",
|
|
3808
|
-
bottomLeft: "\u255A",
|
|
3809
|
-
bottomRight: "\u255D",
|
|
3810
|
-
horizontal: "\u2550",
|
|
3811
|
-
vertical: "\u2551",
|
|
3812
|
-
topT: "\u2566",
|
|
3813
|
-
bottomT: "\u2569",
|
|
3814
|
-
leftT: "\u2560",
|
|
3815
|
-
rightT: "\u2563",
|
|
3816
|
-
cross: "\u256C"
|
|
3817
|
-
},
|
|
3818
|
-
rounded: {
|
|
3819
|
-
topLeft: "\u256D",
|
|
3820
|
-
topRight: "\u256E",
|
|
3821
|
-
bottomLeft: "\u2570",
|
|
3822
|
-
bottomRight: "\u256F",
|
|
3823
|
-
horizontal: "\u2500",
|
|
3824
|
-
vertical: "\u2502",
|
|
3825
|
-
topT: "\u252C",
|
|
3826
|
-
bottomT: "\u2534",
|
|
3827
|
-
leftT: "\u251C",
|
|
3828
|
-
rightT: "\u2524",
|
|
3829
|
-
cross: "\u253C"
|
|
3830
|
-
},
|
|
3831
|
-
heavy: {
|
|
3832
|
-
topLeft: "\u250F",
|
|
3833
|
-
topRight: "\u2513",
|
|
3834
|
-
bottomLeft: "\u2517",
|
|
3835
|
-
bottomRight: "\u251B",
|
|
3836
|
-
horizontal: "\u2501",
|
|
3837
|
-
vertical: "\u2503",
|
|
3838
|
-
topT: "\u2533",
|
|
3839
|
-
bottomT: "\u253B",
|
|
3840
|
-
leftT: "\u2523",
|
|
3841
|
-
rightT: "\u252B",
|
|
3842
|
-
cross: "\u254B"
|
|
3843
|
-
}
|
|
3844
|
-
};
|
|
3845
|
-
function getBorderFromSides(sides) {
|
|
3846
|
-
const result = [];
|
|
3847
|
-
if (sides.top)
|
|
3848
|
-
result.push("top");
|
|
3849
|
-
if (sides.right)
|
|
3850
|
-
result.push("right");
|
|
3851
|
-
if (sides.bottom)
|
|
3852
|
-
result.push("bottom");
|
|
3853
|
-
if (sides.left)
|
|
3854
|
-
result.push("left");
|
|
3855
|
-
return result.length > 0 ? result : false;
|
|
3856
|
-
}
|
|
3857
|
-
function getBorderSides(border) {
|
|
3858
|
-
return border === true ? { top: true, right: true, bottom: true, left: true } : Array.isArray(border) ? {
|
|
3859
|
-
top: border.includes("top"),
|
|
3860
|
-
right: border.includes("right"),
|
|
3861
|
-
bottom: border.includes("bottom"),
|
|
3862
|
-
left: border.includes("left")
|
|
3863
|
-
} : { top: false, right: false, bottom: false, left: false };
|
|
3864
|
-
}
|
|
3865
|
-
function borderCharsToArray(chars) {
|
|
3866
|
-
const array = new Uint32Array(11);
|
|
3867
|
-
array[0] = chars.topLeft.codePointAt(0);
|
|
3868
|
-
array[1] = chars.topRight.codePointAt(0);
|
|
3869
|
-
array[2] = chars.bottomLeft.codePointAt(0);
|
|
3870
|
-
array[3] = chars.bottomRight.codePointAt(0);
|
|
3871
|
-
array[4] = chars.horizontal.codePointAt(0);
|
|
3872
|
-
array[5] = chars.vertical.codePointAt(0);
|
|
3873
|
-
array[6] = chars.topT.codePointAt(0);
|
|
3874
|
-
array[7] = chars.bottomT.codePointAt(0);
|
|
3875
|
-
array[8] = chars.leftT.codePointAt(0);
|
|
3876
|
-
array[9] = chars.rightT.codePointAt(0);
|
|
3877
|
-
array[10] = chars.cross.codePointAt(0);
|
|
3878
|
-
return array;
|
|
3879
|
-
}
|
|
3880
|
-
var BorderCharArrays = {
|
|
3881
|
-
single: borderCharsToArray(BorderChars.single),
|
|
3882
|
-
double: borderCharsToArray(BorderChars.double),
|
|
3883
|
-
rounded: borderCharsToArray(BorderChars.rounded),
|
|
3884
|
-
heavy: borderCharsToArray(BorderChars.heavy)
|
|
3885
|
-
};
|
|
3886
3476
|
// src/lib/fonts/tiny.json
|
|
3887
3477
|
var tiny_default = {
|
|
3888
3478
|
name: "tiny",
|
|
@@ -5272,526 +4862,1633 @@ var slick_default = {
|
|
|
5272
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>"],
|
|
5273
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>"]
|
|
5274
4864
|
}
|
|
5275
|
-
};
|
|
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
|
+
}
|
|
5276
6112
|
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
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");
|
|
5297
6144
|
}
|
|
5298
|
-
const
|
|
5299
|
-
const
|
|
5300
|
-
|
|
5301
|
-
|
|
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, {});
|
|
5302
6150
|
}
|
|
5303
|
-
|
|
5304
|
-
const
|
|
5305
|
-
if (
|
|
5306
|
-
|
|
6151
|
+
getCurrentBuffer(renderer) {
|
|
6152
|
+
const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer);
|
|
6153
|
+
if (!bufferPtr) {
|
|
6154
|
+
throw new Error("Failed to get current buffer");
|
|
5307
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, {});
|
|
5308
6161
|
}
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
const
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
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");
|
|
5317
6169
|
}
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
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))
|
|
5322
6175
|
};
|
|
6176
|
+
return buffers;
|
|
5323
6177
|
}
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
}
|
|
5332
|
-
let currentX = 0;
|
|
5333
|
-
for (let i = 0;i < text.length; i++) {
|
|
5334
|
-
const char = text[i].toUpperCase();
|
|
5335
|
-
const charDef = fontDef.chars[char];
|
|
5336
|
-
if (!charDef) {
|
|
5337
|
-
const spaceChar = fontDef.chars[" "];
|
|
5338
|
-
if (spaceChar && spaceChar[0]) {
|
|
5339
|
-
let spaceWidth = 0;
|
|
5340
|
-
for (const segment of spaceChar[0]) {
|
|
5341
|
-
spaceWidth += segment.text.length;
|
|
5342
|
-
}
|
|
5343
|
-
currentX += spaceWidth;
|
|
5344
|
-
} else {
|
|
5345
|
-
currentX += 1;
|
|
5346
|
-
}
|
|
5347
|
-
continue;
|
|
5348
|
-
}
|
|
5349
|
-
let charWidth = 0;
|
|
5350
|
-
if (charDef[0]) {
|
|
5351
|
-
for (const segment of charDef[0]) {
|
|
5352
|
-
charWidth += segment.text.length;
|
|
5353
|
-
}
|
|
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");
|
|
5354
6185
|
}
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
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;
|
|
6193
|
+
}
|
|
6194
|
+
bufferGetCharPtr(buffer) {
|
|
6195
|
+
const ptr = this.opentui.symbols.bufferGetCharPtr(buffer);
|
|
6196
|
+
if (!ptr) {
|
|
6197
|
+
throw new Error("Failed to get char pointer");
|
|
5358
6198
|
}
|
|
6199
|
+
return ptr;
|
|
5359
6200
|
}
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
}
|
|
5365
|
-
|
|
5366
|
-
const fontDef = getParsedFont(font);
|
|
5367
|
-
if (!fontDef) {
|
|
5368
|
-
return [0];
|
|
6201
|
+
bufferGetFgPtr(buffer) {
|
|
6202
|
+
const ptr = this.opentui.symbols.bufferGetFgPtr(buffer);
|
|
6203
|
+
if (!ptr) {
|
|
6204
|
+
throw new Error("Failed to get fg pointer");
|
|
6205
|
+
}
|
|
6206
|
+
return ptr;
|
|
5369
6207
|
}
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
const charDef = fontDef.chars[char];
|
|
5375
|
-
let charWidth = 0;
|
|
5376
|
-
if (!charDef) {
|
|
5377
|
-
const spaceChar = fontDef.chars[" "];
|
|
5378
|
-
if (spaceChar && spaceChar[0]) {
|
|
5379
|
-
for (const segment of spaceChar[0]) {
|
|
5380
|
-
charWidth += segment.text.length;
|
|
5381
|
-
}
|
|
5382
|
-
} else {
|
|
5383
|
-
charWidth = 1;
|
|
5384
|
-
}
|
|
5385
|
-
} else if (charDef[0]) {
|
|
5386
|
-
for (const segment of charDef[0]) {
|
|
5387
|
-
charWidth += segment.text.length;
|
|
5388
|
-
}
|
|
6208
|
+
bufferGetBgPtr(buffer) {
|
|
6209
|
+
const ptr = this.opentui.symbols.bufferGetBgPtr(buffer);
|
|
6210
|
+
if (!ptr) {
|
|
6211
|
+
throw new Error("Failed to get bg pointer");
|
|
5389
6212
|
}
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
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");
|
|
5393
6219
|
}
|
|
5394
|
-
|
|
6220
|
+
return ptr;
|
|
5395
6221
|
}
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
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);
|
|
6266
|
+
}
|
|
6267
|
+
bufferResize(buffer, width, height) {
|
|
6268
|
+
this.opentui.symbols.bufferResize(buffer, width, height);
|
|
6269
|
+
const buffers = this.getBuffer(buffer, width * height);
|
|
6270
|
+
return buffers;
|
|
6271
|
+
}
|
|
6272
|
+
resizeRenderer(renderer, width, height) {
|
|
6273
|
+
this.opentui.symbols.resizeRenderer(renderer, width, height);
|
|
5402
6274
|
}
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
const nextPos = positions[i + 1];
|
|
5406
|
-
if (x >= currentPos && x < nextPos) {
|
|
5407
|
-
const charMidpoint = currentPos + (nextPos - currentPos) / 2;
|
|
5408
|
-
return x < charMidpoint ? i : i + 1;
|
|
5409
|
-
}
|
|
6275
|
+
setCursorPosition(x, y, visible) {
|
|
6276
|
+
this.opentui.symbols.setCursorPosition(x, y, visible);
|
|
5410
6277
|
}
|
|
5411
|
-
|
|
5412
|
-
|
|
6278
|
+
setCursorStyle(style, blinking) {
|
|
6279
|
+
const stylePtr = this.encoder.encode(style);
|
|
6280
|
+
this.opentui.symbols.setCursorStyle(stylePtr, style.length, blinking);
|
|
5413
6281
|
}
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
function renderFontToFrameBuffer(buffer, {
|
|
5417
|
-
text,
|
|
5418
|
-
x = 0,
|
|
5419
|
-
y = 0,
|
|
5420
|
-
fg = [RGBA.fromInts(255, 255, 255, 255)],
|
|
5421
|
-
bg = RGBA.fromInts(0, 0, 0, 255),
|
|
5422
|
-
font = "tiny"
|
|
5423
|
-
}) {
|
|
5424
|
-
const width = buffer.getWidth();
|
|
5425
|
-
const height = buffer.getHeight();
|
|
5426
|
-
const fontDef = getParsedFont(font);
|
|
5427
|
-
if (!fontDef) {
|
|
5428
|
-
console.warn(`Font '${font}' not found`);
|
|
5429
|
-
return { width: 0, height: 0 };
|
|
6282
|
+
setCursorColor(color) {
|
|
6283
|
+
this.opentui.symbols.setCursorColor(color.buffer);
|
|
5430
6284
|
}
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
return { width: 0, height: fontDef.lines };
|
|
6285
|
+
render(renderer, force) {
|
|
6286
|
+
this.opentui.symbols.render(renderer, force);
|
|
5434
6287
|
}
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
const char = text[i].toUpperCase();
|
|
5439
|
-
const charDef = fontDef.chars[char];
|
|
5440
|
-
if (!charDef) {
|
|
5441
|
-
const spaceChar = fontDef.chars[" "];
|
|
5442
|
-
if (spaceChar && spaceChar[0]) {
|
|
5443
|
-
let spaceWidth = 0;
|
|
5444
|
-
for (const segment of spaceChar[0]) {
|
|
5445
|
-
spaceWidth += segment.text.length;
|
|
5446
|
-
}
|
|
5447
|
-
currentX += spaceWidth;
|
|
5448
|
-
} else {
|
|
5449
|
-
currentX += 1;
|
|
5450
|
-
}
|
|
5451
|
-
continue;
|
|
5452
|
-
}
|
|
5453
|
-
let charWidth = 0;
|
|
5454
|
-
if (charDef[0]) {
|
|
5455
|
-
for (const segment of charDef[0]) {
|
|
5456
|
-
charWidth += segment.text.length;
|
|
5457
|
-
}
|
|
5458
|
-
}
|
|
5459
|
-
if (currentX >= width)
|
|
5460
|
-
break;
|
|
5461
|
-
if (currentX + charWidth < 0) {
|
|
5462
|
-
currentX += charWidth + fontDef.letterspace_size;
|
|
5463
|
-
continue;
|
|
5464
|
-
}
|
|
5465
|
-
for (let lineIdx = 0;lineIdx < fontDef.lines && lineIdx < charDef.length; lineIdx++) {
|
|
5466
|
-
const segments = charDef[lineIdx];
|
|
5467
|
-
const renderY = y + lineIdx;
|
|
5468
|
-
if (renderY >= 0 && renderY < height) {
|
|
5469
|
-
let segmentX = currentX;
|
|
5470
|
-
for (const segment of segments) {
|
|
5471
|
-
const segmentColor = colors[segment.colorIndex] || colors[0];
|
|
5472
|
-
for (let charIdx = 0;charIdx < segment.text.length; charIdx++) {
|
|
5473
|
-
const renderX = segmentX + charIdx;
|
|
5474
|
-
if (renderX >= 0 && renderX < width) {
|
|
5475
|
-
const fontChar = segment.text[charIdx];
|
|
5476
|
-
if (fontChar !== " ") {
|
|
5477
|
-
buffer.setCell(renderX, renderY, fontChar, segmentColor, bg);
|
|
5478
|
-
}
|
|
5479
|
-
}
|
|
5480
|
-
}
|
|
5481
|
-
segmentX += segment.text.length;
|
|
5482
|
-
}
|
|
5483
|
-
}
|
|
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);
|
|
5484
6291
|
}
|
|
5485
|
-
|
|
5486
|
-
if (
|
|
5487
|
-
|
|
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}`);
|
|
5488
6295
|
}
|
|
6296
|
+
const size = width * height;
|
|
6297
|
+
const buffers = this.getBuffer(bufferPtr, size);
|
|
6298
|
+
return new OptimizedBuffer(this, bufferPtr, buffers, width, height, { respectAlpha });
|
|
5489
6299
|
}
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
height: fontDef.lines
|
|
5493
|
-
};
|
|
5494
|
-
}
|
|
5495
|
-
// src/lib/styled-text.ts
|
|
5496
|
-
var textEncoder = new TextEncoder;
|
|
5497
|
-
|
|
5498
|
-
class StyledText {
|
|
5499
|
-
chunks;
|
|
5500
|
-
_plainText = "";
|
|
5501
|
-
constructor(chunks) {
|
|
5502
|
-
this.chunks = chunks;
|
|
5503
|
-
for (let i = 0;i < chunks.length; i++) {
|
|
5504
|
-
this._plainText += chunks[i].plainText;
|
|
5505
|
-
}
|
|
6300
|
+
destroyOptimizedBuffer(bufferPtr) {
|
|
6301
|
+
this.opentui.symbols.destroyOptimizedBuffer(bufferPtr);
|
|
5506
6302
|
}
|
|
5507
|
-
|
|
5508
|
-
|
|
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);
|
|
5509
6309
|
}
|
|
5510
|
-
|
|
5511
|
-
this.
|
|
5512
|
-
for (const chunk of this.chunks) {
|
|
5513
|
-
this._plainText += chunk.plainText;
|
|
5514
|
-
}
|
|
6310
|
+
setDebugOverlay(renderer, enabled, corner) {
|
|
6311
|
+
this.opentui.symbols.setDebugOverlay(renderer, enabled, corner);
|
|
5515
6312
|
}
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
if (index === undefined) {
|
|
5519
|
-
this.chunks.push(chunk);
|
|
5520
|
-
} else {
|
|
5521
|
-
this.chunks.splice(index, 0, chunk);
|
|
5522
|
-
}
|
|
5523
|
-
if (index === undefined || index === originalLength) {
|
|
5524
|
-
this._plainText += chunk.plainText;
|
|
5525
|
-
} else {
|
|
5526
|
-
this._chunksToPlainText();
|
|
5527
|
-
}
|
|
6313
|
+
clearTerminal(renderer) {
|
|
6314
|
+
this.opentui.symbols.clearTerminal(renderer);
|
|
5528
6315
|
}
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
const index = this.chunks.indexOf(chunk);
|
|
5532
|
-
if (index === -1)
|
|
5533
|
-
return;
|
|
5534
|
-
this.chunks.splice(index, 1);
|
|
5535
|
-
if (index === originalLength - 1) {
|
|
5536
|
-
this._plainText = this._plainText.slice(0, this._plainText.length - chunk.plainText.length);
|
|
5537
|
-
} else {
|
|
5538
|
-
this._chunksToPlainText();
|
|
5539
|
-
}
|
|
6316
|
+
addToHitGrid(renderer, x, y, width, height, id) {
|
|
6317
|
+
this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id);
|
|
5540
6318
|
}
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
if (index === -1)
|
|
5544
|
-
return;
|
|
5545
|
-
this.chunks.splice(index, 1, chunk);
|
|
5546
|
-
if (index === this.chunks.length - 1) {
|
|
5547
|
-
this._plainText = this._plainText.slice(0, this._plainText.length - oldChunk.plainText.length) + chunk.plainText;
|
|
5548
|
-
} else {
|
|
5549
|
-
this._chunksToPlainText();
|
|
5550
|
-
}
|
|
6319
|
+
checkHit(renderer, x, y) {
|
|
6320
|
+
return this.opentui.symbols.checkHit(renderer, x, y);
|
|
5551
6321
|
}
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
const textEncoder2 = new TextEncoder;
|
|
5555
|
-
const chunk = {
|
|
5556
|
-
__isChunk: true,
|
|
5557
|
-
text: textEncoder2.encode(content),
|
|
5558
|
-
plainText: content
|
|
5559
|
-
};
|
|
5560
|
-
return new StyledText([chunk]);
|
|
5561
|
-
}
|
|
5562
|
-
var templateCache = new WeakMap;
|
|
5563
|
-
function applyStyle(input, style) {
|
|
5564
|
-
if (typeof input === "object" && "__isChunk" in input) {
|
|
5565
|
-
const existingChunk = input;
|
|
5566
|
-
const fg = style.fg ? parseColor(style.fg) : existingChunk.fg;
|
|
5567
|
-
const bg = style.bg ? parseColor(style.bg) : existingChunk.bg;
|
|
5568
|
-
const newAttrs = createTextAttributes(style);
|
|
5569
|
-
const mergedAttrs = existingChunk.attributes ? existingChunk.attributes | newAttrs : newAttrs;
|
|
5570
|
-
return {
|
|
5571
|
-
__isChunk: true,
|
|
5572
|
-
text: existingChunk.text,
|
|
5573
|
-
plainText: existingChunk.plainText,
|
|
5574
|
-
fg,
|
|
5575
|
-
bg,
|
|
5576
|
-
attributes: mergedAttrs
|
|
5577
|
-
};
|
|
5578
|
-
} else {
|
|
5579
|
-
const plainTextStr = String(input);
|
|
5580
|
-
const text = textEncoder.encode(plainTextStr);
|
|
5581
|
-
const fg = style.fg ? parseColor(style.fg) : undefined;
|
|
5582
|
-
const bg = style.bg ? parseColor(style.bg) : undefined;
|
|
5583
|
-
const attributes = createTextAttributes(style);
|
|
5584
|
-
return {
|
|
5585
|
-
__isChunk: true,
|
|
5586
|
-
text,
|
|
5587
|
-
plainText: plainTextStr,
|
|
5588
|
-
fg,
|
|
5589
|
-
bg,
|
|
5590
|
-
attributes
|
|
5591
|
-
};
|
|
6322
|
+
dumpHitGrid(renderer) {
|
|
6323
|
+
this.opentui.symbols.dumpHitGrid(renderer);
|
|
5592
6324
|
}
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
var bgRed = (input) => applyStyle(input, { bg: "red" });
|
|
5612
|
-
var bgGreen = (input) => applyStyle(input, { bg: "green" });
|
|
5613
|
-
var bgYellow = (input) => applyStyle(input, { bg: "yellow" });
|
|
5614
|
-
var bgBlue = (input) => applyStyle(input, { bg: "blue" });
|
|
5615
|
-
var bgMagenta = (input) => applyStyle(input, { bg: "magenta" });
|
|
5616
|
-
var bgCyan = (input) => applyStyle(input, { bg: "cyan" });
|
|
5617
|
-
var bgWhite = (input) => applyStyle(input, { bg: "white" });
|
|
5618
|
-
var bold = (input) => applyStyle(input, { bold: true });
|
|
5619
|
-
var italic = (input) => applyStyle(input, { italic: true });
|
|
5620
|
-
var underline = (input) => applyStyle(input, { underline: true });
|
|
5621
|
-
var strikethrough = (input) => applyStyle(input, { strikethrough: true });
|
|
5622
|
-
var dim = (input) => applyStyle(input, { dim: true });
|
|
5623
|
-
var reverse = (input) => applyStyle(input, { reverse: true });
|
|
5624
|
-
var blink = (input) => applyStyle(input, { blink: true });
|
|
5625
|
-
var fg = (color) => (input) => applyStyle(input, { fg: color });
|
|
5626
|
-
var bg = (color) => (input) => applyStyle(input, { bg: color });
|
|
5627
|
-
function tn(strings, ...values) {
|
|
5628
|
-
const chunks = [];
|
|
5629
|
-
let length = 0;
|
|
5630
|
-
let plainText = "";
|
|
5631
|
-
for (let i = 0;i < strings.length; i++) {
|
|
5632
|
-
const raw = strings[i];
|
|
5633
|
-
if (raw) {
|
|
5634
|
-
chunks.push({
|
|
5635
|
-
__isChunk: true,
|
|
5636
|
-
text: textEncoder.encode(raw),
|
|
5637
|
-
plainText: raw,
|
|
5638
|
-
attributes: 0
|
|
5639
|
-
});
|
|
5640
|
-
length += raw.length;
|
|
5641
|
-
plainText += raw;
|
|
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}`);
|
|
5642
6343
|
}
|
|
5643
|
-
const
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
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))
|
|
6353
|
+
};
|
|
6354
|
+
return new TextBuffer(this, bufferPtr, buffer, capacity);
|
|
6355
|
+
}
|
|
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");
|
|
5658
6363
|
}
|
|
6364
|
+
return ptr;
|
|
5659
6365
|
}
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
let length = 0;
|
|
5665
|
-
let plainText = "";
|
|
5666
|
-
if (!cachedStringChunks) {
|
|
5667
|
-
cachedStringChunks = [];
|
|
5668
|
-
for (let i = 0;i < strings.length; i++) {
|
|
5669
|
-
const raw = strings[i];
|
|
5670
|
-
if (raw) {
|
|
5671
|
-
cachedStringChunks.push({
|
|
5672
|
-
__isChunk: true,
|
|
5673
|
-
text: textEncoder.encode(raw),
|
|
5674
|
-
plainText: raw,
|
|
5675
|
-
attributes: 0
|
|
5676
|
-
});
|
|
5677
|
-
} else {
|
|
5678
|
-
cachedStringChunks.push(null);
|
|
5679
|
-
}
|
|
6366
|
+
textBufferGetFgPtr(buffer) {
|
|
6367
|
+
const ptr = this.opentui.symbols.textBufferGetFgPtr(buffer);
|
|
6368
|
+
if (!ptr) {
|
|
6369
|
+
throw new Error("Failed to get TextBuffer fg pointer");
|
|
5680
6370
|
}
|
|
5681
|
-
|
|
6371
|
+
return ptr;
|
|
5682
6372
|
}
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
chunks.push(stringChunk);
|
|
5688
|
-
length += stringChunk.plainText.length;
|
|
5689
|
-
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");
|
|
5690
6377
|
}
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
const plainTextStr = String(val);
|
|
5698
|
-
chunks.push({
|
|
5699
|
-
__isChunk: true,
|
|
5700
|
-
text: textEncoder.encode(plainTextStr),
|
|
5701
|
-
plainText: plainTextStr,
|
|
5702
|
-
attributes: 0
|
|
5703
|
-
});
|
|
5704
|
-
length += plainTextStr.length;
|
|
5705
|
-
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");
|
|
5706
6384
|
}
|
|
6385
|
+
return ptr;
|
|
5707
6386
|
}
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
// src/lib/hast-styled-text.ts
|
|
5712
|
-
class SyntaxStyle {
|
|
5713
|
-
styles;
|
|
5714
|
-
mergedStyleCache;
|
|
5715
|
-
constructor(styles) {
|
|
5716
|
-
this.styles = styles;
|
|
5717
|
-
this.mergedStyleCache = new Map;
|
|
6387
|
+
textBufferGetLength(buffer) {
|
|
6388
|
+
return this.opentui.symbols.textBufferGetLength(buffer);
|
|
5718
6389
|
}
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
const style = this.styles[name];
|
|
5727
|
-
if (!style)
|
|
5728
|
-
continue;
|
|
5729
|
-
if (style.fg)
|
|
5730
|
-
styleDefinition.fg = style.fg;
|
|
5731
|
-
if (style.bg)
|
|
5732
|
-
styleDefinition.bg = style.bg;
|
|
5733
|
-
if (style.bold !== undefined)
|
|
5734
|
-
styleDefinition.bold = style.bold;
|
|
5735
|
-
if (style.italic !== undefined)
|
|
5736
|
-
styleDefinition.italic = style.italic;
|
|
5737
|
-
if (style.underline !== undefined)
|
|
5738
|
-
styleDefinition.underline = style.underline;
|
|
5739
|
-
if (style.dim !== undefined)
|
|
5740
|
-
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");
|
|
5741
6397
|
}
|
|
5742
|
-
const
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
fg:
|
|
5750
|
-
bg:
|
|
5751
|
-
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))
|
|
5752
6408
|
};
|
|
5753
|
-
this
|
|
5754
|
-
return merged;
|
|
6409
|
+
return new TextBuffer(this, resultPtr, buffer, length);
|
|
5755
6410
|
}
|
|
5756
|
-
|
|
5757
|
-
this.
|
|
6411
|
+
textBufferResize(buffer, newLength) {
|
|
6412
|
+
this.opentui.symbols.textBufferResize(buffer, newLength);
|
|
6413
|
+
const buffers = this.getTextBuffer(buffer, newLength);
|
|
6414
|
+
return buffers;
|
|
5758
6415
|
}
|
|
5759
|
-
|
|
5760
|
-
|
|
6416
|
+
textBufferReset(buffer) {
|
|
6417
|
+
this.opentui.symbols.textBufferReset(buffer);
|
|
5761
6418
|
}
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
}
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
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: [] };
|
|
5784
6456
|
}
|
|
5785
|
-
|
|
5786
|
-
|
|
6457
|
+
const lineStartsPtr = this.opentui.symbols.textBufferGetLineStartsPtr(buffer);
|
|
6458
|
+
const lineWidthsPtr = this.opentui.symbols.textBufferGetLineWidthsPtr(buffer);
|
|
6459
|
+
if (!lineStartsPtr || !lineWidthsPtr) {
|
|
6460
|
+
return { lineStarts: [], lineWidths: [] };
|
|
5787
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);
|
|
5788
6478
|
}
|
|
5789
|
-
return chunks;
|
|
5790
6479
|
}
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
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;
|
|
5794
6490
|
}
|
|
6491
|
+
|
|
5795
6492
|
// src/buffer.ts
|
|
5796
6493
|
var fbIdCounter = 0;
|
|
5797
6494
|
function isRGBAWithAlpha(color) {
|
|
@@ -5968,17 +6665,17 @@ class OptimizedBuffer {
|
|
|
5968
6665
|
}
|
|
5969
6666
|
this.setCell(x, y, char, fg2, bg2, attributes);
|
|
5970
6667
|
}
|
|
5971
|
-
drawText(text, x, y, fg2, bg2, attributes = 0,
|
|
5972
|
-
if (!
|
|
6668
|
+
drawText(text, x, y, fg2, bg2, attributes = 0, selection2) {
|
|
6669
|
+
if (!selection2) {
|
|
5973
6670
|
this.drawTextFFI.call(this, text, x, y, fg2, bg2, attributes);
|
|
5974
6671
|
return;
|
|
5975
6672
|
}
|
|
5976
|
-
const { start, end } =
|
|
6673
|
+
const { start, end } = selection2;
|
|
5977
6674
|
let selectionBg;
|
|
5978
6675
|
let selectionFg;
|
|
5979
|
-
if (
|
|
5980
|
-
selectionBg =
|
|
5981
|
-
selectionFg =
|
|
6676
|
+
if (selection2.bgColor) {
|
|
6677
|
+
selectionBg = selection2.bgColor;
|
|
6678
|
+
selectionFg = selection2.fgColor || fg2;
|
|
5982
6679
|
} else {
|
|
5983
6680
|
const defaultBg = bg2 || RGBA.fromValues(0, 0, 0, 0);
|
|
5984
6681
|
selectionFg = defaultBg.a > 0 ? defaultBg : RGBA.fromValues(0, 0, 0, 1);
|
|
@@ -6972,451 +7669,204 @@ function evaluateTimelineSync(item, timelineTime, deltaTime = 0) {
|
|
|
6972
7669
|
}
|
|
6973
7670
|
function evaluateItem(item, timelineTime, deltaTime = 0) {
|
|
6974
7671
|
if (item.type === "animation") {
|
|
6975
|
-
evaluateAnimation(item, timelineTime, deltaTime);
|
|
6976
|
-
} else if (item.type === "callback") {
|
|
6977
|
-
evaluateCallback(item, timelineTime);
|
|
6978
|
-
}
|
|
6979
|
-
}
|
|
6980
|
-
|
|
6981
|
-
class Timeline {
|
|
6982
|
-
items = [];
|
|
6983
|
-
subTimelines = [];
|
|
6984
|
-
currentTime = 0;
|
|
6985
|
-
isPlaying = false;
|
|
6986
|
-
isComplete = false;
|
|
6987
|
-
duration;
|
|
6988
|
-
loop;
|
|
6989
|
-
synced = false;
|
|
6990
|
-
autoplay;
|
|
6991
|
-
onComplete;
|
|
6992
|
-
onPause;
|
|
6993
|
-
constructor(options = {}) {
|
|
6994
|
-
this.duration = options.duration || 1000;
|
|
6995
|
-
this.loop = options.loop === true;
|
|
6996
|
-
this.autoplay = options.autoplay !== false;
|
|
6997
|
-
this.onComplete = options.onComplete;
|
|
6998
|
-
this.onPause = options.onPause;
|
|
6999
|
-
}
|
|
7000
|
-
add(target, properties, startTime = 0) {
|
|
7001
|
-
const resolvedStartTime = typeof startTime === "string" ? 0 : startTime;
|
|
7002
|
-
const animationProperties = {};
|
|
7003
|
-
for (const key in properties) {
|
|
7004
|
-
if (!["duration", "ease", "onUpdate", "onComplete", "onStart", "onLoop", "loop", "loopDelay", "alternate"].includes(key)) {
|
|
7005
|
-
if (typeof properties[key] === "number") {
|
|
7006
|
-
animationProperties[key] = properties[key];
|
|
7007
|
-
}
|
|
7008
|
-
}
|
|
7009
|
-
}
|
|
7010
|
-
this.items.push({
|
|
7011
|
-
type: "animation",
|
|
7012
|
-
startTime: resolvedStartTime,
|
|
7013
|
-
target: Array.isArray(target) ? target : [target],
|
|
7014
|
-
properties: animationProperties,
|
|
7015
|
-
initialValues: [],
|
|
7016
|
-
duration: properties.duration !== undefined ? properties.duration : 1000,
|
|
7017
|
-
ease: properties.ease || "linear",
|
|
7018
|
-
loop: properties.loop,
|
|
7019
|
-
loopDelay: properties.loopDelay || 0,
|
|
7020
|
-
alternate: properties.alternate || false,
|
|
7021
|
-
onUpdate: properties.onUpdate,
|
|
7022
|
-
onComplete: properties.onComplete,
|
|
7023
|
-
onStart: properties.onStart,
|
|
7024
|
-
onLoop: properties.onLoop,
|
|
7025
|
-
completed: false,
|
|
7026
|
-
started: false,
|
|
7027
|
-
currentLoop: 0,
|
|
7028
|
-
once: properties.once ?? false
|
|
7029
|
-
});
|
|
7030
|
-
return this;
|
|
7031
|
-
}
|
|
7032
|
-
once(target, properties) {
|
|
7033
|
-
this.add(target, {
|
|
7034
|
-
...properties,
|
|
7035
|
-
once: true
|
|
7036
|
-
}, this.currentTime);
|
|
7037
|
-
return this;
|
|
7038
|
-
}
|
|
7039
|
-
call(callback, startTime = 0) {
|
|
7040
|
-
const resolvedStartTime = typeof startTime === "string" ? 0 : startTime;
|
|
7041
|
-
this.items.push({
|
|
7042
|
-
type: "callback",
|
|
7043
|
-
startTime: resolvedStartTime,
|
|
7044
|
-
callback,
|
|
7045
|
-
executed: false
|
|
7046
|
-
});
|
|
7047
|
-
return this;
|
|
7048
|
-
}
|
|
7049
|
-
sync(timeline, startTime = 0) {
|
|
7050
|
-
if (timeline.synced) {
|
|
7051
|
-
throw new Error("Timeline already synced");
|
|
7052
|
-
}
|
|
7053
|
-
this.subTimelines.push({
|
|
7054
|
-
type: "timeline",
|
|
7055
|
-
startTime,
|
|
7056
|
-
timeline
|
|
7057
|
-
});
|
|
7058
|
-
timeline.synced = true;
|
|
7059
|
-
return this;
|
|
7060
|
-
}
|
|
7061
|
-
play() {
|
|
7062
|
-
if (this.isComplete) {
|
|
7063
|
-
return this.restart();
|
|
7064
|
-
}
|
|
7065
|
-
this.subTimelines.forEach((subTimeline) => {
|
|
7066
|
-
if (subTimeline.timelineStarted) {
|
|
7067
|
-
subTimeline.timeline.play();
|
|
7068
|
-
}
|
|
7069
|
-
});
|
|
7070
|
-
this.isPlaying = true;
|
|
7071
|
-
return this;
|
|
7072
|
-
}
|
|
7073
|
-
pause() {
|
|
7074
|
-
this.subTimelines.forEach((subTimeline) => {
|
|
7075
|
-
subTimeline.timeline.pause();
|
|
7076
|
-
});
|
|
7077
|
-
this.isPlaying = false;
|
|
7078
|
-
if (this.onPause) {
|
|
7079
|
-
this.onPause();
|
|
7080
|
-
}
|
|
7081
|
-
return this;
|
|
7082
|
-
}
|
|
7083
|
-
resetItems() {
|
|
7084
|
-
this.items.forEach((item) => {
|
|
7085
|
-
if (item.type === "callback") {
|
|
7086
|
-
item.executed = false;
|
|
7087
|
-
} else if (item.type === "animation") {
|
|
7088
|
-
item.completed = false;
|
|
7089
|
-
item.started = false;
|
|
7090
|
-
item.currentLoop = 0;
|
|
7091
|
-
}
|
|
7092
|
-
});
|
|
7093
|
-
this.subTimelines.forEach((subTimeline) => {
|
|
7094
|
-
subTimeline.timelineStarted = false;
|
|
7095
|
-
if (subTimeline.timeline) {
|
|
7096
|
-
subTimeline.timeline.restart();
|
|
7097
|
-
subTimeline.timeline.pause();
|
|
7098
|
-
}
|
|
7099
|
-
});
|
|
7100
|
-
}
|
|
7101
|
-
restart() {
|
|
7102
|
-
this.isComplete = false;
|
|
7103
|
-
this.currentTime = 0;
|
|
7104
|
-
this.isPlaying = true;
|
|
7105
|
-
this.resetItems();
|
|
7106
|
-
return this;
|
|
7107
|
-
}
|
|
7108
|
-
update(deltaTime) {
|
|
7109
|
-
for (const subTimeline of this.subTimelines) {
|
|
7110
|
-
evaluateTimelineSync(subTimeline, this.currentTime + deltaTime, deltaTime);
|
|
7111
|
-
}
|
|
7112
|
-
if (!this.isPlaying)
|
|
7113
|
-
return;
|
|
7114
|
-
this.currentTime += deltaTime;
|
|
7115
|
-
for (const item of this.items) {
|
|
7116
|
-
evaluateItem(item, this.currentTime, deltaTime);
|
|
7117
|
-
}
|
|
7118
|
-
for (let i = this.items.length - 1;i >= 0; i--) {
|
|
7119
|
-
const item = this.items[i];
|
|
7120
|
-
if (item.type === "animation" && item.once && item.completed) {
|
|
7121
|
-
this.items.splice(i, 1);
|
|
7122
|
-
}
|
|
7123
|
-
}
|
|
7124
|
-
if (this.loop && this.currentTime >= this.duration) {
|
|
7125
|
-
const overshoot = this.currentTime % this.duration;
|
|
7126
|
-
this.resetItems();
|
|
7127
|
-
this.currentTime = 0;
|
|
7128
|
-
if (overshoot > 0) {
|
|
7129
|
-
this.update(overshoot);
|
|
7130
|
-
}
|
|
7131
|
-
} else if (!this.loop && this.currentTime >= this.duration) {
|
|
7132
|
-
this.currentTime = this.duration;
|
|
7133
|
-
this.isPlaying = false;
|
|
7134
|
-
this.isComplete = true;
|
|
7135
|
-
if (this.onComplete) {
|
|
7136
|
-
this.onComplete();
|
|
7137
|
-
}
|
|
7138
|
-
}
|
|
7139
|
-
}
|
|
7140
|
-
}
|
|
7141
|
-
|
|
7142
|
-
class TimelineEngine {
|
|
7143
|
-
timelines = new Set;
|
|
7144
|
-
defaults = {
|
|
7145
|
-
frameRate: 60
|
|
7146
|
-
};
|
|
7147
|
-
register(timeline) {
|
|
7148
|
-
this.timelines.add(timeline);
|
|
7149
|
-
}
|
|
7150
|
-
unregister(timeline) {
|
|
7151
|
-
this.timelines.delete(timeline);
|
|
7152
|
-
}
|
|
7153
|
-
clear() {
|
|
7154
|
-
this.timelines.clear();
|
|
7155
|
-
}
|
|
7156
|
-
update(deltaTime) {
|
|
7157
|
-
for (const timeline of this.timelines) {
|
|
7158
|
-
if (!timeline.synced) {
|
|
7159
|
-
timeline.update(deltaTime);
|
|
7160
|
-
}
|
|
7161
|
-
}
|
|
7162
|
-
}
|
|
7163
|
-
}
|
|
7164
|
-
var engine = new TimelineEngine;
|
|
7165
|
-
function createTimeline(options = {}) {
|
|
7166
|
-
const timeline = new Timeline(options);
|
|
7167
|
-
if (options.autoplay !== false) {
|
|
7168
|
-
timeline.play();
|
|
7169
|
-
}
|
|
7170
|
-
engine.register(timeline);
|
|
7171
|
-
return timeline;
|
|
7172
|
-
}
|
|
7173
|
-
// src/lib/selection.ts
|
|
7174
|
-
class Selection {
|
|
7175
|
-
_anchor;
|
|
7176
|
-
_focus;
|
|
7177
|
-
_selectedRenderables = [];
|
|
7178
|
-
constructor(anchor, focus) {
|
|
7179
|
-
this._anchor = { ...anchor };
|
|
7180
|
-
this._focus = { ...focus };
|
|
7181
|
-
}
|
|
7182
|
-
get anchor() {
|
|
7183
|
-
return { ...this._anchor };
|
|
7184
|
-
}
|
|
7185
|
-
get focus() {
|
|
7186
|
-
return { ...this._focus };
|
|
7187
|
-
}
|
|
7188
|
-
get bounds() {
|
|
7189
|
-
return {
|
|
7190
|
-
startX: Math.min(this._anchor.x, this._focus.x),
|
|
7191
|
-
startY: Math.min(this._anchor.y, this._focus.y),
|
|
7192
|
-
endX: Math.max(this._anchor.x, this._focus.x),
|
|
7193
|
-
endY: Math.max(this._anchor.y, this._focus.y)
|
|
7194
|
-
};
|
|
7195
|
-
}
|
|
7196
|
-
updateSelectedRenderables(selectedRenderables) {
|
|
7197
|
-
this._selectedRenderables = selectedRenderables;
|
|
7198
|
-
}
|
|
7199
|
-
getSelectedText() {
|
|
7200
|
-
const selectedTexts = this._selectedRenderables.sort((a, b) => {
|
|
7201
|
-
const aY = a.y;
|
|
7202
|
-
const bY = b.y;
|
|
7203
|
-
if (aY !== bY) {
|
|
7204
|
-
return aY - bY;
|
|
7205
|
-
}
|
|
7206
|
-
return a.x - b.x;
|
|
7207
|
-
}).map((renderable) => renderable.getSelectedText()).filter((text) => text);
|
|
7208
|
-
return selectedTexts.join(`
|
|
7209
|
-
`);
|
|
7210
|
-
}
|
|
7211
|
-
}
|
|
7212
|
-
|
|
7213
|
-
class TextSelectionHelper {
|
|
7214
|
-
getX;
|
|
7215
|
-
getY;
|
|
7216
|
-
getTextLength;
|
|
7217
|
-
getLineInfo;
|
|
7218
|
-
localSelection = null;
|
|
7219
|
-
cachedGlobalSelection = null;
|
|
7220
|
-
constructor(getX, getY, getTextLength, getLineInfo) {
|
|
7221
|
-
this.getX = getX;
|
|
7222
|
-
this.getY = getY;
|
|
7223
|
-
this.getTextLength = getTextLength;
|
|
7224
|
-
this.getLineInfo = getLineInfo;
|
|
7225
|
-
}
|
|
7226
|
-
hasSelection() {
|
|
7227
|
-
return this.localSelection !== null;
|
|
7672
|
+
evaluateAnimation(item, timelineTime, deltaTime);
|
|
7673
|
+
} else if (item.type === "callback") {
|
|
7674
|
+
evaluateCallback(item, timelineTime);
|
|
7228
7675
|
}
|
|
7229
|
-
|
|
7230
|
-
|
|
7676
|
+
}
|
|
7677
|
+
|
|
7678
|
+
class Timeline {
|
|
7679
|
+
items = [];
|
|
7680
|
+
subTimelines = [];
|
|
7681
|
+
currentTime = 0;
|
|
7682
|
+
isPlaying = false;
|
|
7683
|
+
isComplete = false;
|
|
7684
|
+
duration;
|
|
7685
|
+
loop;
|
|
7686
|
+
synced = false;
|
|
7687
|
+
autoplay;
|
|
7688
|
+
onComplete;
|
|
7689
|
+
onPause;
|
|
7690
|
+
constructor(options = {}) {
|
|
7691
|
+
this.duration = options.duration || 1000;
|
|
7692
|
+
this.loop = options.loop === true;
|
|
7693
|
+
this.autoplay = options.autoplay !== false;
|
|
7694
|
+
this.onComplete = options.onComplete;
|
|
7695
|
+
this.onPause = options.onPause;
|
|
7231
7696
|
}
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7697
|
+
add(target, properties, startTime = 0) {
|
|
7698
|
+
const resolvedStartTime = typeof startTime === "string" ? 0 : startTime;
|
|
7699
|
+
const animationProperties = {};
|
|
7700
|
+
for (const key in properties) {
|
|
7701
|
+
if (!["duration", "ease", "onUpdate", "onComplete", "onStart", "onLoop", "loop", "loopDelay", "alternate"].includes(key)) {
|
|
7702
|
+
if (typeof properties[key] === "number") {
|
|
7703
|
+
animationProperties[key] = properties[key];
|
|
7704
|
+
}
|
|
7705
|
+
}
|
|
7235
7706
|
}
|
|
7236
|
-
|
|
7707
|
+
this.items.push({
|
|
7708
|
+
type: "animation",
|
|
7709
|
+
startTime: resolvedStartTime,
|
|
7710
|
+
target: Array.isArray(target) ? target : [target],
|
|
7711
|
+
properties: animationProperties,
|
|
7712
|
+
initialValues: [],
|
|
7713
|
+
duration: properties.duration !== undefined ? properties.duration : 1000,
|
|
7714
|
+
ease: properties.ease || "linear",
|
|
7715
|
+
loop: properties.loop,
|
|
7716
|
+
loopDelay: properties.loopDelay || 0,
|
|
7717
|
+
alternate: properties.alternate || false,
|
|
7718
|
+
onUpdate: properties.onUpdate,
|
|
7719
|
+
onComplete: properties.onComplete,
|
|
7720
|
+
onStart: properties.onStart,
|
|
7721
|
+
onLoop: properties.onLoop,
|
|
7722
|
+
completed: false,
|
|
7723
|
+
started: false,
|
|
7724
|
+
currentLoop: 0,
|
|
7725
|
+
once: properties.once ?? false
|
|
7726
|
+
});
|
|
7727
|
+
return this;
|
|
7237
7728
|
}
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7729
|
+
once(target, properties) {
|
|
7730
|
+
this.add(target, {
|
|
7731
|
+
...properties,
|
|
7732
|
+
once: true
|
|
7733
|
+
}, this.currentTime);
|
|
7734
|
+
return this;
|
|
7242
7735
|
}
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
if (myEndY < selection.anchor.y || myY > selection.focus.y) {
|
|
7253
|
-
this.localSelection = null;
|
|
7254
|
-
return previousSelection !== null;
|
|
7255
|
-
}
|
|
7256
|
-
if (height === 1) {
|
|
7257
|
-
this.localSelection = this.calculateSingleLineSelection(myY, selection.anchor.y, selection.focus.y, selection.anchor.x, selection.focus.x, width);
|
|
7258
|
-
} else {
|
|
7259
|
-
this.localSelection = this.calculateMultiLineSelection(myY, selection.anchor.y, selection.focus.y, selection.anchor.x, selection.focus.x);
|
|
7260
|
-
}
|
|
7261
|
-
return this.localSelection !== null !== (previousSelection !== null) || this.localSelection?.start !== previousSelection?.start || this.localSelection?.end !== previousSelection?.end;
|
|
7736
|
+
call(callback, startTime = 0) {
|
|
7737
|
+
const resolvedStartTime = typeof startTime === "string" ? 0 : startTime;
|
|
7738
|
+
this.items.push({
|
|
7739
|
+
type: "callback",
|
|
7740
|
+
startTime: resolvedStartTime,
|
|
7741
|
+
callback,
|
|
7742
|
+
executed: false
|
|
7743
|
+
});
|
|
7744
|
+
return this;
|
|
7262
7745
|
}
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
if (lineY > anchorY && lineY < focusY) {
|
|
7267
|
-
return { start: 0, end: textLength };
|
|
7268
|
-
}
|
|
7269
|
-
if (lineY === anchorY && lineY === focusY) {
|
|
7270
|
-
const start = Math.max(0, Math.min(anchorX - myX, textLength));
|
|
7271
|
-
const end = Math.max(0, Math.min(focusX - myX, textLength));
|
|
7272
|
-
return start < end ? { start, end } : null;
|
|
7273
|
-
}
|
|
7274
|
-
if (lineY === anchorY) {
|
|
7275
|
-
const start = Math.max(0, Math.min(anchorX - myX, textLength));
|
|
7276
|
-
return start < textLength ? { start, end: textLength } : null;
|
|
7277
|
-
}
|
|
7278
|
-
if (lineY === focusY) {
|
|
7279
|
-
const end = Math.max(0, Math.min(focusX - myX, textLength));
|
|
7280
|
-
return end > 0 ? { start: 0, end } : null;
|
|
7746
|
+
sync(timeline, startTime = 0) {
|
|
7747
|
+
if (timeline.synced) {
|
|
7748
|
+
throw new Error("Timeline already synced");
|
|
7281
7749
|
}
|
|
7282
|
-
|
|
7750
|
+
this.subTimelines.push({
|
|
7751
|
+
type: "timeline",
|
|
7752
|
+
startTime,
|
|
7753
|
+
timeline
|
|
7754
|
+
});
|
|
7755
|
+
timeline.synced = true;
|
|
7756
|
+
return this;
|
|
7283
7757
|
}
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
return { start: 0, end: this.getTextLength() };
|
|
7758
|
+
play() {
|
|
7759
|
+
if (this.isComplete) {
|
|
7760
|
+
return this.restart();
|
|
7288
7761
|
}
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
for (let i = 0;i < lineInfo.lineStarts.length; i++) {
|
|
7293
|
-
const lineY = startY + i;
|
|
7294
|
-
if (lineY < anchorY || lineY > focusY)
|
|
7295
|
-
continue;
|
|
7296
|
-
const lineStart = lineInfo.lineStarts[i];
|
|
7297
|
-
const lineEnd = i < lineInfo.lineStarts.length - 1 ? lineInfo.lineStarts[i + 1] - 1 : this.getTextLength();
|
|
7298
|
-
const lineWidth = lineInfo.lineWidths[i];
|
|
7299
|
-
if (lineY > anchorY && lineY < focusY) {
|
|
7300
|
-
if (selectionStart === null)
|
|
7301
|
-
selectionStart = lineStart;
|
|
7302
|
-
selectionEnd = lineEnd;
|
|
7303
|
-
} else if (lineY === anchorY && lineY === focusY) {
|
|
7304
|
-
const localStartX = Math.max(0, Math.min(anchorX - myX, lineWidth));
|
|
7305
|
-
const localEndX = Math.max(0, Math.min(focusX - myX, lineWidth));
|
|
7306
|
-
if (localStartX < localEndX) {
|
|
7307
|
-
selectionStart = lineStart + localStartX;
|
|
7308
|
-
selectionEnd = lineStart + localEndX;
|
|
7309
|
-
}
|
|
7310
|
-
} else if (lineY === anchorY) {
|
|
7311
|
-
const localStartX = Math.max(0, Math.min(anchorX - myX, lineWidth));
|
|
7312
|
-
if (localStartX < lineWidth) {
|
|
7313
|
-
selectionStart = lineStart + localStartX;
|
|
7314
|
-
selectionEnd = lineEnd;
|
|
7315
|
-
}
|
|
7316
|
-
} else if (lineY === focusY) {
|
|
7317
|
-
const localEndX = Math.max(0, Math.min(focusX - myX, lineWidth));
|
|
7318
|
-
if (localEndX > 0) {
|
|
7319
|
-
if (selectionStart === null)
|
|
7320
|
-
selectionStart = lineStart;
|
|
7321
|
-
selectionEnd = lineStart + localEndX;
|
|
7322
|
-
}
|
|
7762
|
+
this.subTimelines.forEach((subTimeline) => {
|
|
7763
|
+
if (subTimeline.timelineStarted) {
|
|
7764
|
+
subTimeline.timeline.play();
|
|
7323
7765
|
}
|
|
7324
|
-
}
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
}
|
|
7328
|
-
|
|
7329
|
-
class ASCIIFontSelectionHelper {
|
|
7330
|
-
getX;
|
|
7331
|
-
getY;
|
|
7332
|
-
getText;
|
|
7333
|
-
getFont;
|
|
7334
|
-
localSelection = null;
|
|
7335
|
-
cachedGlobalSelection = null;
|
|
7336
|
-
constructor(getX, getY, getText, getFont) {
|
|
7337
|
-
this.getX = getX;
|
|
7338
|
-
this.getY = getY;
|
|
7339
|
-
this.getText = getText;
|
|
7340
|
-
this.getFont = getFont;
|
|
7766
|
+
});
|
|
7767
|
+
this.isPlaying = true;
|
|
7768
|
+
return this;
|
|
7341
7769
|
}
|
|
7342
|
-
|
|
7343
|
-
|
|
7770
|
+
pause() {
|
|
7771
|
+
this.subTimelines.forEach((subTimeline) => {
|
|
7772
|
+
subTimeline.timeline.pause();
|
|
7773
|
+
});
|
|
7774
|
+
this.isPlaying = false;
|
|
7775
|
+
if (this.onPause) {
|
|
7776
|
+
this.onPause();
|
|
7777
|
+
}
|
|
7778
|
+
return this;
|
|
7344
7779
|
}
|
|
7345
|
-
|
|
7346
|
-
|
|
7780
|
+
resetItems() {
|
|
7781
|
+
this.items.forEach((item) => {
|
|
7782
|
+
if (item.type === "callback") {
|
|
7783
|
+
item.executed = false;
|
|
7784
|
+
} else if (item.type === "animation") {
|
|
7785
|
+
item.completed = false;
|
|
7786
|
+
item.started = false;
|
|
7787
|
+
item.currentLoop = 0;
|
|
7788
|
+
}
|
|
7789
|
+
});
|
|
7790
|
+
this.subTimelines.forEach((subTimeline) => {
|
|
7791
|
+
subTimeline.timelineStarted = false;
|
|
7792
|
+
if (subTimeline.timeline) {
|
|
7793
|
+
subTimeline.timeline.restart();
|
|
7794
|
+
subTimeline.timeline.pause();
|
|
7795
|
+
}
|
|
7796
|
+
});
|
|
7347
7797
|
}
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
const text = this.getText();
|
|
7355
|
-
const font = this.getFont();
|
|
7356
|
-
const charIndex = coordinateToCharacterIndex(localX, text, font);
|
|
7357
|
-
return charIndex >= 0 && charIndex <= text.length;
|
|
7798
|
+
restart() {
|
|
7799
|
+
this.isComplete = false;
|
|
7800
|
+
this.currentTime = 0;
|
|
7801
|
+
this.isPlaying = true;
|
|
7802
|
+
this.resetItems();
|
|
7803
|
+
return this;
|
|
7358
7804
|
}
|
|
7359
|
-
|
|
7360
|
-
this.
|
|
7361
|
-
|
|
7362
|
-
if (!selection?.isActive) {
|
|
7363
|
-
this.localSelection = null;
|
|
7364
|
-
return previousSelection !== null;
|
|
7365
|
-
}
|
|
7366
|
-
const myX = this.getX();
|
|
7367
|
-
const myY = this.getY();
|
|
7368
|
-
const myEndY = myY + height - 1;
|
|
7369
|
-
const text = this.getText();
|
|
7370
|
-
const font = this.getFont();
|
|
7371
|
-
let selStart;
|
|
7372
|
-
let selEnd;
|
|
7373
|
-
if (selection.anchor.y < selection.focus.y || selection.anchor.y === selection.focus.y && selection.anchor.x <= selection.focus.x) {
|
|
7374
|
-
selStart = selection.anchor;
|
|
7375
|
-
selEnd = selection.focus;
|
|
7376
|
-
} else {
|
|
7377
|
-
selStart = selection.focus;
|
|
7378
|
-
selEnd = selection.anchor;
|
|
7805
|
+
update(deltaTime) {
|
|
7806
|
+
for (const subTimeline of this.subTimelines) {
|
|
7807
|
+
evaluateTimelineSync(subTimeline, this.currentTime + deltaTime, deltaTime);
|
|
7379
7808
|
}
|
|
7380
|
-
if (
|
|
7381
|
-
|
|
7382
|
-
|
|
7809
|
+
if (!this.isPlaying)
|
|
7810
|
+
return;
|
|
7811
|
+
this.currentTime += deltaTime;
|
|
7812
|
+
for (const item of this.items) {
|
|
7813
|
+
evaluateItem(item, this.currentTime, deltaTime);
|
|
7383
7814
|
}
|
|
7384
|
-
let
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
return previousSelection !== null;
|
|
7389
|
-
} else if (selStart.y >= myY && selStart.y <= myEndY) {
|
|
7390
|
-
const localX = selStart.x - myX;
|
|
7391
|
-
if (localX > 0) {
|
|
7392
|
-
startCharIndex = coordinateToCharacterIndex(localX, text, font);
|
|
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);
|
|
7393
7819
|
}
|
|
7394
7820
|
}
|
|
7395
|
-
if (
|
|
7396
|
-
this.
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
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();
|
|
7404
7834
|
}
|
|
7405
7835
|
}
|
|
7406
|
-
if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) {
|
|
7407
|
-
this.localSelection = { start: startCharIndex, end: endCharIndex };
|
|
7408
|
-
} else {
|
|
7409
|
-
this.localSelection = null;
|
|
7410
|
-
}
|
|
7411
|
-
return this.localSelection !== null !== (previousSelection !== null) || this.localSelection?.start !== previousSelection?.start || this.localSelection?.end !== previousSelection?.end;
|
|
7412
7836
|
}
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7837
|
+
}
|
|
7838
|
+
|
|
7839
|
+
class TimelineEngine {
|
|
7840
|
+
timelines = new Set;
|
|
7841
|
+
defaults = {
|
|
7842
|
+
frameRate: 60
|
|
7843
|
+
};
|
|
7844
|
+
register(timeline) {
|
|
7845
|
+
this.timelines.add(timeline);
|
|
7846
|
+
}
|
|
7847
|
+
unregister(timeline) {
|
|
7848
|
+
this.timelines.delete(timeline);
|
|
7849
|
+
}
|
|
7850
|
+
clear() {
|
|
7851
|
+
this.timelines.clear();
|
|
7852
|
+
}
|
|
7853
|
+
update(deltaTime) {
|
|
7854
|
+
for (const timeline of this.timelines) {
|
|
7855
|
+
if (!timeline.synced) {
|
|
7856
|
+
timeline.update(deltaTime);
|
|
7857
|
+
}
|
|
7416
7858
|
}
|
|
7417
|
-
return this.onSelectionChanged(this.cachedGlobalSelection, width, height);
|
|
7418
7859
|
}
|
|
7419
7860
|
}
|
|
7861
|
+
var engine = new TimelineEngine;
|
|
7862
|
+
function createTimeline(options = {}) {
|
|
7863
|
+
const timeline = new Timeline(options);
|
|
7864
|
+
if (options.autoplay !== false) {
|
|
7865
|
+
timeline.play();
|
|
7866
|
+
}
|
|
7867
|
+
engine.register(timeline);
|
|
7868
|
+
return timeline;
|
|
7869
|
+
}
|
|
7420
7870
|
// src/ansi.ts
|
|
7421
7871
|
var ANSI = {
|
|
7422
7872
|
switchToAlternateScreen: "\x1B[?1049h",
|
|
@@ -7442,7 +7892,10 @@ var ANSI = {
|
|
|
7442
7892
|
enableAnyEventTracking: "\x1B[?1003h",
|
|
7443
7893
|
disableAnyEventTracking: "\x1B[?1003l",
|
|
7444
7894
|
enableSGRMouseMode: "\x1B[?1006h",
|
|
7445
|
-
disableSGRMouseMode: "\x1B[?1006l"
|
|
7895
|
+
disableSGRMouseMode: "\x1B[?1006l",
|
|
7896
|
+
makeRoomForRenderer: (height) => `
|
|
7897
|
+
`.repeat(height) + `\x1B[${height}A`,
|
|
7898
|
+
clearRendererSpace: (height) => `\x1B[${height}A\x1B[1G\x1B[J`
|
|
7446
7899
|
};
|
|
7447
7900
|
|
|
7448
7901
|
// src/console.ts
|
|
@@ -8102,106 +8555,6 @@ class TerminalConsole extends EventEmitter5 {
|
|
|
8102
8555
|
}
|
|
8103
8556
|
}
|
|
8104
8557
|
|
|
8105
|
-
// src/lib/parse.mouse.ts
|
|
8106
|
-
class MouseParser {
|
|
8107
|
-
mouseButtonsPressed = new Set;
|
|
8108
|
-
static SCROLL_DIRECTIONS = {
|
|
8109
|
-
64: "up",
|
|
8110
|
-
65: "down",
|
|
8111
|
-
66: "left",
|
|
8112
|
-
67: "right"
|
|
8113
|
-
};
|
|
8114
|
-
reset() {
|
|
8115
|
-
this.mouseButtonsPressed.clear();
|
|
8116
|
-
}
|
|
8117
|
-
parseMouseEvent(data) {
|
|
8118
|
-
const str = data.toString();
|
|
8119
|
-
const sgrMatch = str.match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);
|
|
8120
|
-
if (sgrMatch) {
|
|
8121
|
-
const [, buttonCode, x, y, pressRelease] = sgrMatch;
|
|
8122
|
-
const rawButtonCode = parseInt(buttonCode);
|
|
8123
|
-
const scrollDirection = MouseParser.SCROLL_DIRECTIONS[rawButtonCode];
|
|
8124
|
-
const isScroll = scrollDirection !== undefined;
|
|
8125
|
-
const button = rawButtonCode & 3;
|
|
8126
|
-
const isMotion = (rawButtonCode & 32) !== 0;
|
|
8127
|
-
const modifiers = {
|
|
8128
|
-
shift: (rawButtonCode & 4) !== 0,
|
|
8129
|
-
alt: (rawButtonCode & 8) !== 0,
|
|
8130
|
-
ctrl: (rawButtonCode & 16) !== 0
|
|
8131
|
-
};
|
|
8132
|
-
let type;
|
|
8133
|
-
let scrollInfo;
|
|
8134
|
-
if (isScroll && pressRelease === "M") {
|
|
8135
|
-
type = "scroll";
|
|
8136
|
-
scrollInfo = {
|
|
8137
|
-
direction: scrollDirection,
|
|
8138
|
-
delta: 1
|
|
8139
|
-
};
|
|
8140
|
-
} else if (isMotion) {
|
|
8141
|
-
const isDragging = this.mouseButtonsPressed.size > 0;
|
|
8142
|
-
if (button === 3) {
|
|
8143
|
-
type = "move";
|
|
8144
|
-
} else if (isDragging) {
|
|
8145
|
-
type = "drag";
|
|
8146
|
-
} else {
|
|
8147
|
-
type = "move";
|
|
8148
|
-
}
|
|
8149
|
-
} else {
|
|
8150
|
-
type = pressRelease === "M" ? "down" : "up";
|
|
8151
|
-
if (type === "down" && button !== 3) {
|
|
8152
|
-
this.mouseButtonsPressed.add(button);
|
|
8153
|
-
} else if (type === "up") {
|
|
8154
|
-
this.mouseButtonsPressed.clear();
|
|
8155
|
-
}
|
|
8156
|
-
}
|
|
8157
|
-
return {
|
|
8158
|
-
type,
|
|
8159
|
-
button: button === 3 ? 0 : button,
|
|
8160
|
-
x: parseInt(x) - 1,
|
|
8161
|
-
y: parseInt(y) - 1,
|
|
8162
|
-
modifiers,
|
|
8163
|
-
scroll: scrollInfo
|
|
8164
|
-
};
|
|
8165
|
-
}
|
|
8166
|
-
if (str.startsWith("\x1B[M") && str.length >= 6) {
|
|
8167
|
-
const buttonByte = str.charCodeAt(3) - 32;
|
|
8168
|
-
const x = str.charCodeAt(4) - 33;
|
|
8169
|
-
const y = str.charCodeAt(5) - 33;
|
|
8170
|
-
const scrollDirection = MouseParser.SCROLL_DIRECTIONS[buttonByte];
|
|
8171
|
-
const isScroll = scrollDirection !== undefined;
|
|
8172
|
-
const button = buttonByte & 3;
|
|
8173
|
-
const modifiers = {
|
|
8174
|
-
shift: (buttonByte & 4) !== 0,
|
|
8175
|
-
alt: (buttonByte & 8) !== 0,
|
|
8176
|
-
ctrl: (buttonByte & 16) !== 0
|
|
8177
|
-
};
|
|
8178
|
-
let type;
|
|
8179
|
-
let actualButton;
|
|
8180
|
-
let scrollInfo;
|
|
8181
|
-
if (isScroll) {
|
|
8182
|
-
type = "scroll";
|
|
8183
|
-
actualButton = 0;
|
|
8184
|
-
scrollInfo = {
|
|
8185
|
-
direction: scrollDirection,
|
|
8186
|
-
delta: 1
|
|
8187
|
-
};
|
|
8188
|
-
} else {
|
|
8189
|
-
type = button === 3 ? "up" : "down";
|
|
8190
|
-
actualButton = button === 3 ? 0 : button;
|
|
8191
|
-
}
|
|
8192
|
-
return {
|
|
8193
|
-
type,
|
|
8194
|
-
button: actualButton,
|
|
8195
|
-
x,
|
|
8196
|
-
y,
|
|
8197
|
-
modifiers,
|
|
8198
|
-
scroll: scrollInfo
|
|
8199
|
-
};
|
|
8200
|
-
}
|
|
8201
|
-
return null;
|
|
8202
|
-
}
|
|
8203
|
-
}
|
|
8204
|
-
|
|
8205
8558
|
// src/renderer.ts
|
|
8206
8559
|
import { EventEmitter as EventEmitter6 } from "events";
|
|
8207
8560
|
|
|
@@ -8240,6 +8593,11 @@ var MouseButton;
|
|
|
8240
8593
|
MouseButton2[MouseButton2["WHEEL_UP"] = 4] = "WHEEL_UP";
|
|
8241
8594
|
MouseButton2[MouseButton2["WHEEL_DOWN"] = 5] = "WHEEL_DOWN";
|
|
8242
8595
|
})(MouseButton ||= {});
|
|
8596
|
+
["SIGINT", "SIGTERM", "SIGQUIT", "SIGABRT"].forEach((signal) => {
|
|
8597
|
+
process.on(signal, () => {
|
|
8598
|
+
process.exit();
|
|
8599
|
+
});
|
|
8600
|
+
});
|
|
8243
8601
|
async function createCliRenderer(config = {}) {
|
|
8244
8602
|
if (process.argv.includes("--delay-start")) {
|
|
8245
8603
|
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
@@ -8276,7 +8634,6 @@ class CliRenderer extends EventEmitter6 {
|
|
|
8276
8634
|
stdout;
|
|
8277
8635
|
exitOnCtrlC;
|
|
8278
8636
|
isDestroyed = false;
|
|
8279
|
-
isShuttingDown = false;
|
|
8280
8637
|
nextRenderBuffer;
|
|
8281
8638
|
currentRenderBuffer;
|
|
8282
8639
|
_isRunning = false;
|
|
@@ -8308,6 +8665,8 @@ class CliRenderer extends EventEmitter6 {
|
|
|
8308
8665
|
targetFrameTime = 0;
|
|
8309
8666
|
immediateRerenderRequested = false;
|
|
8310
8667
|
updateScheduled = false;
|
|
8668
|
+
liveRequestCounter = 0;
|
|
8669
|
+
controlState = "idle" /* IDLE */;
|
|
8311
8670
|
frameCallbacks = [];
|
|
8312
8671
|
renderStats = {
|
|
8313
8672
|
frameCount: 0,
|
|
@@ -8393,7 +8752,15 @@ class CliRenderer extends EventEmitter6 {
|
|
|
8393
8752
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
8394
8753
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
8395
8754
|
this.postProcessFns = config.postProcessFns || [];
|
|
8396
|
-
|
|
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);
|
|
8397
8764
|
this.setupTerminal();
|
|
8398
8765
|
this.takeMemorySnapshot();
|
|
8399
8766
|
if (this.memorySnapshotInterval > 0) {
|
|
@@ -8401,8 +8768,6 @@ class CliRenderer extends EventEmitter6 {
|
|
|
8401
8768
|
}
|
|
8402
8769
|
this.stdout.write = this.interceptStdoutWrite.bind(this);
|
|
8403
8770
|
this.sigwinchHandler = () => {
|
|
8404
|
-
if (this.isShuttingDown)
|
|
8405
|
-
return;
|
|
8406
8771
|
const width2 = this.stdout.columns || 80;
|
|
8407
8772
|
const height2 = this.stdout.rows || 24;
|
|
8408
8773
|
this.handleResize(width2, height2);
|
|
@@ -8410,6 +8775,7 @@ class CliRenderer extends EventEmitter6 {
|
|
|
8410
8775
|
process.on("SIGWINCH", this.sigwinchHandler);
|
|
8411
8776
|
const handleError = (error) => {
|
|
8412
8777
|
this.stop();
|
|
8778
|
+
this.destroy();
|
|
8413
8779
|
new Promise((resolve) => {
|
|
8414
8780
|
setTimeout(() => {
|
|
8415
8781
|
resolve(true);
|
|
@@ -8443,8 +8809,7 @@ Error details:
|
|
|
8443
8809
|
};
|
|
8444
8810
|
process.on("uncaughtException", handleError);
|
|
8445
8811
|
process.on("unhandledRejection", handleError);
|
|
8446
|
-
process.on("exit", (
|
|
8447
|
-
this.stop();
|
|
8812
|
+
process.on("exit", () => {
|
|
8448
8813
|
this.destroy();
|
|
8449
8814
|
});
|
|
8450
8815
|
this._console = new TerminalConsole(this, config.consoleOptions);
|
|
@@ -8463,6 +8828,13 @@ Error details:
|
|
|
8463
8828
|
}
|
|
8464
8829
|
global.window.requestAnimationFrame = requestAnimationFrame;
|
|
8465
8830
|
this.queryPixelResolution();
|
|
8831
|
+
if (process.env.OTUI_NO_NATIVE_RENDER === "true") {
|
|
8832
|
+
this.renderNative = () => {
|
|
8833
|
+
if (this._splitHeight > 0) {
|
|
8834
|
+
this.flushStdoutCache(this._splitHeight);
|
|
8835
|
+
}
|
|
8836
|
+
};
|
|
8837
|
+
}
|
|
8466
8838
|
}
|
|
8467
8839
|
writeOut(chunk, encoding, callback) {
|
|
8468
8840
|
return this.realStdoutWrite.call(this.stdout, chunk, encoding, callback);
|
|
@@ -8521,6 +8893,12 @@ Error details:
|
|
|
8521
8893
|
get experimental_splitHeight() {
|
|
8522
8894
|
return this._splitHeight;
|
|
8523
8895
|
}
|
|
8896
|
+
get liveRequestCount() {
|
|
8897
|
+
return this.liveRequestCounter;
|
|
8898
|
+
}
|
|
8899
|
+
get currentControlState() {
|
|
8900
|
+
return this.controlState;
|
|
8901
|
+
}
|
|
8524
8902
|
set experimental_splitHeight(splitHeight) {
|
|
8525
8903
|
if (splitHeight < 0)
|
|
8526
8904
|
splitHeight = 0;
|
|
@@ -8594,30 +8972,17 @@ Error details:
|
|
|
8594
8972
|
return true;
|
|
8595
8973
|
}
|
|
8596
8974
|
enableMouse() {
|
|
8597
|
-
this.
|
|
8598
|
-
this.writeOut(ANSI.enableMouseTracking);
|
|
8599
|
-
this.writeOut(ANSI.enableButtonEventTracking);
|
|
8600
|
-
if (this.enableMouseMovement) {
|
|
8601
|
-
this.writeOut(ANSI.enableAnyEventTracking);
|
|
8602
|
-
}
|
|
8975
|
+
this.lib.enableMouse(this.rendererPtr, this.enableMouseMovement);
|
|
8603
8976
|
}
|
|
8604
8977
|
disableMouse() {
|
|
8605
|
-
if (this.enableMouseMovement) {
|
|
8606
|
-
this.writeOut(ANSI.disableAnyEventTracking);
|
|
8607
|
-
}
|
|
8608
|
-
this.writeOut(ANSI.disableButtonEventTracking);
|
|
8609
|
-
this.writeOut(ANSI.disableMouseTracking);
|
|
8610
|
-
this.writeOut(ANSI.disableSGRMouseMode);
|
|
8611
8978
|
this.capturedRenderable = undefined;
|
|
8612
8979
|
this.mouseParser.reset();
|
|
8980
|
+
this.lib.disableMouse(this.rendererPtr);
|
|
8613
8981
|
}
|
|
8614
8982
|
set useThread(useThread) {
|
|
8615
8983
|
this._useThread = useThread;
|
|
8616
8984
|
this.lib.setUseThread(this.rendererPtr, useThread);
|
|
8617
8985
|
}
|
|
8618
|
-
setTerminalSize(width, height) {
|
|
8619
|
-
this.handleResize(width, height);
|
|
8620
|
-
}
|
|
8621
8986
|
setupTerminal() {
|
|
8622
8987
|
this.writeOut(ANSI.saveCursorState);
|
|
8623
8988
|
if (this.stdin.setRawMode) {
|
|
@@ -8644,7 +9009,7 @@ Error details:
|
|
|
8644
9009
|
}
|
|
8645
9010
|
if (this.exitOnCtrlC && str === "\x03") {
|
|
8646
9011
|
process.nextTick(() => {
|
|
8647
|
-
process.exit(
|
|
9012
|
+
process.exit();
|
|
8648
9013
|
});
|
|
8649
9014
|
return;
|
|
8650
9015
|
}
|
|
@@ -8655,6 +9020,8 @@ Error details:
|
|
|
8655
9020
|
});
|
|
8656
9021
|
if (this._useAlternateScreen) {
|
|
8657
9022
|
this.writeOut(ANSI.switchToAlternateScreen);
|
|
9023
|
+
} else {
|
|
9024
|
+
this.writeOut(ANSI.makeRoomForRenderer(this.height - 1));
|
|
8658
9025
|
}
|
|
8659
9026
|
this.setCursorPosition(0, 0, false);
|
|
8660
9027
|
}
|
|
@@ -8720,6 +9087,7 @@ Error details:
|
|
|
8720
9087
|
if (this.capturedRenderable && mouseEvent.type === "up") {
|
|
8721
9088
|
const event = new MouseEvent(this.capturedRenderable, { ...mouseEvent, type: "drag-end" });
|
|
8722
9089
|
this.capturedRenderable.processMouseEvent(event);
|
|
9090
|
+
this.capturedRenderable.processMouseEvent(new MouseEvent(this.capturedRenderable, mouseEvent));
|
|
8723
9091
|
if (maybeRenderable) {
|
|
8724
9092
|
const event2 = new MouseEvent(maybeRenderable, {
|
|
8725
9093
|
...mouseEvent,
|
|
@@ -8733,7 +9101,7 @@ Error details:
|
|
|
8733
9101
|
this.capturedRenderable = undefined;
|
|
8734
9102
|
}
|
|
8735
9103
|
if (maybeRenderable) {
|
|
8736
|
-
if (mouseEvent.type === "
|
|
9104
|
+
if (mouseEvent.type === "drag" && mouseEvent.button === 0 /* LEFT */) {
|
|
8737
9105
|
this.capturedRenderable = maybeRenderable;
|
|
8738
9106
|
} else {
|
|
8739
9107
|
this.capturedRenderable = undefined;
|
|
@@ -8776,7 +9144,7 @@ Error details:
|
|
|
8776
9144
|
}
|
|
8777
9145
|
}
|
|
8778
9146
|
handleResize(width, height) {
|
|
8779
|
-
if (this.
|
|
9147
|
+
if (this.isDestroyed)
|
|
8780
9148
|
return;
|
|
8781
9149
|
if (this._splitHeight > 0) {
|
|
8782
9150
|
this.processResize(width, height);
|
|
@@ -8900,7 +9268,25 @@ Error details:
|
|
|
8900
9268
|
clearFrameCallbacks() {
|
|
8901
9269
|
this.frameCallbacks = [];
|
|
8902
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
|
+
}
|
|
8903
9285
|
start() {
|
|
9286
|
+
this.controlState = "explicit_started" /* EXPLICIT_STARTED */;
|
|
9287
|
+
this.internalStart();
|
|
9288
|
+
}
|
|
9289
|
+
internalStart() {
|
|
8904
9290
|
if (!this._isRunning && !this.isDestroyed) {
|
|
8905
9291
|
this._isRunning = true;
|
|
8906
9292
|
if (this.memorySnapshotInterval > 0) {
|
|
@@ -8910,47 +9296,42 @@ Error details:
|
|
|
8910
9296
|
}
|
|
8911
9297
|
}
|
|
8912
9298
|
pause() {
|
|
9299
|
+
this.controlState = "explicit_paused" /* EXPLICIT_PAUSED */;
|
|
9300
|
+
this.internalPause();
|
|
9301
|
+
}
|
|
9302
|
+
internalPause() {
|
|
8913
9303
|
this._isRunning = false;
|
|
8914
9304
|
}
|
|
8915
9305
|
stop() {
|
|
8916
|
-
|
|
9306
|
+
this.controlState = "explicit_stopped" /* EXPLICIT_STOPPED */;
|
|
9307
|
+
this.internalStop();
|
|
9308
|
+
}
|
|
9309
|
+
internalStop() {
|
|
9310
|
+
if (this.isRunning && !this.isDestroyed) {
|
|
9311
|
+
this._isRunning = false;
|
|
9312
|
+
if (this.memorySnapshotTimer) {
|
|
9313
|
+
clearInterval(this.memorySnapshotTimer);
|
|
9314
|
+
this.memorySnapshotTimer = null;
|
|
9315
|
+
}
|
|
9316
|
+
if (this.renderTimeout) {
|
|
9317
|
+
clearTimeout(this.renderTimeout);
|
|
9318
|
+
this.renderTimeout = null;
|
|
9319
|
+
}
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9322
|
+
destroy() {
|
|
9323
|
+
if (this.isDestroyed)
|
|
8917
9324
|
return;
|
|
8918
|
-
this.
|
|
8919
|
-
this.isShuttingDown = true;
|
|
9325
|
+
this.isDestroyed = true;
|
|
8920
9326
|
this.waitingForPixelResolution = false;
|
|
9327
|
+
this.capturedRenderable = undefined;
|
|
8921
9328
|
if (this.sigwinchHandler) {
|
|
8922
9329
|
process.removeListener("SIGWINCH", this.sigwinchHandler);
|
|
8923
9330
|
this.sigwinchHandler = null;
|
|
8924
9331
|
}
|
|
8925
9332
|
this._console.deactivate();
|
|
9333
|
+
this.lib.destroyRenderer(this.rendererPtr, this._useAlternateScreen, this._splitHeight);
|
|
8926
9334
|
this.disableStdoutInterception();
|
|
8927
|
-
if (this.renderTimeout) {
|
|
8928
|
-
clearTimeout(this.renderTimeout);
|
|
8929
|
-
this.renderTimeout = null;
|
|
8930
|
-
}
|
|
8931
|
-
if (this.memorySnapshotTimer) {
|
|
8932
|
-
clearInterval(this.memorySnapshotTimer);
|
|
8933
|
-
this.memorySnapshotTimer = null;
|
|
8934
|
-
}
|
|
8935
|
-
if (this._splitHeight > 0) {
|
|
8936
|
-
const consoleEndLine = this._terminalHeight - this._splitHeight;
|
|
8937
|
-
this.writeOut(ANSI.moveCursor(consoleEndLine, 1));
|
|
8938
|
-
}
|
|
8939
|
-
this.capturedRenderable = undefined;
|
|
8940
|
-
if (this._useMouse) {
|
|
8941
|
-
this.disableMouse();
|
|
8942
|
-
}
|
|
8943
|
-
this.writeOut(ANSI.resetCursorColor);
|
|
8944
|
-
this.writeOut(ANSI.showCursor);
|
|
8945
|
-
if (this._useAlternateScreen) {
|
|
8946
|
-
this.writeOut(ANSI.switchToMainScreen);
|
|
8947
|
-
}
|
|
8948
|
-
}
|
|
8949
|
-
destroy() {
|
|
8950
|
-
if (this.isDestroyed)
|
|
8951
|
-
return;
|
|
8952
|
-
this.lib.destroyRenderer(this.rendererPtr);
|
|
8953
|
-
this.isDestroyed = true;
|
|
8954
9335
|
}
|
|
8955
9336
|
startRenderLoop() {
|
|
8956
9337
|
if (!this._isRunning)
|
|
@@ -8963,7 +9344,7 @@ Error details:
|
|
|
8963
9344
|
this.loop();
|
|
8964
9345
|
}
|
|
8965
9346
|
async loop() {
|
|
8966
|
-
if (this.rendering)
|
|
9347
|
+
if (this.rendering || this.isDestroyed)
|
|
8967
9348
|
return;
|
|
8968
9349
|
this.rendering = true;
|
|
8969
9350
|
if (this.renderTimeout) {
|
|
@@ -9346,9 +9727,8 @@ class TextRenderable extends Renderable {
|
|
|
9346
9727
|
constructor(id, options) {
|
|
9347
9728
|
super(id, options);
|
|
9348
9729
|
this.selectionHelper = new TextSelectionHelper(() => this.x, () => this.y, () => this._plainText.length, () => this._lineInfo);
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
}
|
|
9730
|
+
const content = options.content ?? "";
|
|
9731
|
+
this._text = typeof content === "string" ? stringToStyledText(content) : content;
|
|
9352
9732
|
this._defaultFg = options.fg ? parseColor(options.fg) : RGBA.fromValues(1, 1, 1, 1);
|
|
9353
9733
|
this._defaultBg = options.bg ? parseColor(options.bg) : RGBA.fromValues(0, 0, 0, 0);
|
|
9354
9734
|
this._defaultAttributes = options.attributes ?? 0;
|
|
@@ -9359,8 +9739,8 @@ class TextRenderable extends Renderable {
|
|
|
9359
9739
|
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
9360
9740
|
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
9361
9741
|
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
9362
|
-
this.updateTextInfo();
|
|
9363
9742
|
this.setupMeasureFunc();
|
|
9743
|
+
this.updateTextInfo();
|
|
9364
9744
|
}
|
|
9365
9745
|
get content() {
|
|
9366
9746
|
return this._text;
|
|
@@ -9405,9 +9785,9 @@ class TextRenderable extends Renderable {
|
|
|
9405
9785
|
}
|
|
9406
9786
|
}
|
|
9407
9787
|
syncSelectionToTextBuffer() {
|
|
9408
|
-
const
|
|
9409
|
-
if (
|
|
9410
|
-
this.textBuffer.setSelection(
|
|
9788
|
+
const selection2 = this.selectionHelper.getSelection();
|
|
9789
|
+
if (selection2) {
|
|
9790
|
+
this.textBuffer.setSelection(selection2.start, selection2.end, this._selectionBg, this._selectionFg);
|
|
9411
9791
|
} else {
|
|
9412
9792
|
this.textBuffer.resetSelection();
|
|
9413
9793
|
}
|
|
@@ -9419,49 +9799,49 @@ class TextRenderable extends Renderable {
|
|
|
9419
9799
|
this._lineInfo.lineStarts = lineInfo.lineStarts;
|
|
9420
9800
|
this._lineInfo.lineWidths = lineInfo.lineWidths;
|
|
9421
9801
|
const numLines = this._lineInfo.lineStarts.length;
|
|
9422
|
-
if (this._height === "auto") {
|
|
9423
|
-
this.
|
|
9802
|
+
if (this._positionType === "absolute" && this._height === "auto") {
|
|
9803
|
+
this._heightValue = numLines;
|
|
9804
|
+
this.layoutNode.yogaNode.markDirty();
|
|
9424
9805
|
}
|
|
9425
9806
|
const maxLineWidth = Math.max(...this._lineInfo.lineWidths);
|
|
9426
9807
|
if (this._positionType === "absolute" && this._width === "auto") {
|
|
9427
|
-
this.
|
|
9808
|
+
this._widthValue = maxLineWidth;
|
|
9809
|
+
this.layoutNode.yogaNode.markDirty();
|
|
9428
9810
|
}
|
|
9429
9811
|
const changed = this.selectionHelper.reevaluateSelection(this.width, this.height);
|
|
9430
9812
|
if (changed) {
|
|
9431
9813
|
this.syncSelectionToTextBuffer();
|
|
9432
|
-
this.needsUpdate();
|
|
9433
9814
|
}
|
|
9815
|
+
this.needsUpdate();
|
|
9434
9816
|
}
|
|
9435
9817
|
setupMeasureFunc() {
|
|
9436
|
-
|
|
9437
|
-
const
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
height: Math.max(1, measuredHeight)
|
|
9455
|
-
};
|
|
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)
|
|
9456
9836
|
};
|
|
9457
|
-
|
|
9458
|
-
|
|
9837
|
+
};
|
|
9838
|
+
this.layoutNode.yogaNode.setMeasureFunc(measureFunc);
|
|
9459
9839
|
}
|
|
9460
9840
|
shouldStartSelection(x, y) {
|
|
9461
9841
|
return this.selectionHelper.shouldStartSelection(x, y, this.width, this.height);
|
|
9462
9842
|
}
|
|
9463
|
-
onSelectionChanged(
|
|
9464
|
-
const changed = this.selectionHelper.onSelectionChanged(
|
|
9843
|
+
onSelectionChanged(selection2) {
|
|
9844
|
+
const changed = this.selectionHelper.onSelectionChanged(selection2, this.width, this.height);
|
|
9465
9845
|
if (changed) {
|
|
9466
9846
|
this.syncSelectionToTextBuffer();
|
|
9467
9847
|
this.needsUpdate();
|
|
@@ -9469,10 +9849,10 @@ class TextRenderable extends Renderable {
|
|
|
9469
9849
|
return this.selectionHelper.hasSelection();
|
|
9470
9850
|
}
|
|
9471
9851
|
getSelectedText() {
|
|
9472
|
-
const
|
|
9473
|
-
if (!
|
|
9852
|
+
const selection2 = this.selectionHelper.getSelection();
|
|
9853
|
+
if (!selection2)
|
|
9474
9854
|
return "";
|
|
9475
|
-
return this._plainText.slice(
|
|
9855
|
+
return this._plainText.slice(selection2.start, selection2.end);
|
|
9476
9856
|
}
|
|
9477
9857
|
hasSelection() {
|
|
9478
9858
|
return this.selectionHelper.hasSelection();
|
|
@@ -9574,8 +9954,8 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
|
|
|
9574
9954
|
shouldStartSelection(x, y) {
|
|
9575
9955
|
return this.selectionHelper.shouldStartSelection(x, y, this.width, this.height);
|
|
9576
9956
|
}
|
|
9577
|
-
onSelectionChanged(
|
|
9578
|
-
const changed = this.selectionHelper.onSelectionChanged(
|
|
9957
|
+
onSelectionChanged(selection2) {
|
|
9958
|
+
const changed = this.selectionHelper.onSelectionChanged(selection2, this.width, this.height);
|
|
9579
9959
|
if (changed) {
|
|
9580
9960
|
this.renderFontToBuffer();
|
|
9581
9961
|
this.needsUpdate();
|
|
@@ -9583,10 +9963,10 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
|
|
|
9583
9963
|
return this.selectionHelper.hasSelection();
|
|
9584
9964
|
}
|
|
9585
9965
|
getSelectedText() {
|
|
9586
|
-
const
|
|
9587
|
-
if (!
|
|
9966
|
+
const selection2 = this.selectionHelper.getSelection();
|
|
9967
|
+
if (!selection2)
|
|
9588
9968
|
return "";
|
|
9589
|
-
return this._text.slice(
|
|
9969
|
+
return this._text.slice(selection2.start, selection2.end);
|
|
9590
9970
|
}
|
|
9591
9971
|
hasSelection() {
|
|
9592
9972
|
return this.selectionHelper.hasSelection();
|
|
@@ -9605,20 +9985,20 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
|
|
|
9605
9985
|
bg: this._bg,
|
|
9606
9986
|
font: this._font
|
|
9607
9987
|
});
|
|
9608
|
-
const
|
|
9609
|
-
if (
|
|
9610
|
-
this.renderSelectionHighlight(
|
|
9988
|
+
const selection2 = this.selectionHelper.getSelection();
|
|
9989
|
+
if (selection2 && (this._selectionBg || this._selectionFg)) {
|
|
9990
|
+
this.renderSelectionHighlight(selection2);
|
|
9611
9991
|
}
|
|
9612
9992
|
}
|
|
9613
|
-
renderSelectionHighlight(
|
|
9993
|
+
renderSelectionHighlight(selection2) {
|
|
9614
9994
|
if (!this._selectionBg && !this._selectionFg)
|
|
9615
9995
|
return;
|
|
9616
|
-
const selectedText = this._text.slice(
|
|
9996
|
+
const selectedText = this._text.slice(selection2.start, selection2.end);
|
|
9617
9997
|
if (!selectedText)
|
|
9618
9998
|
return;
|
|
9619
9999
|
const positions = getCharacterPositions(this._text, this._font);
|
|
9620
|
-
const startX = positions[
|
|
9621
|
-
const endX =
|
|
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;
|
|
9622
10002
|
if (this._selectionBg) {
|
|
9623
10003
|
this.frameBuffer.fillRect(startX, 0, endX - startX, this.height, this._selectionBg);
|
|
9624
10004
|
}
|
|
@@ -10421,13 +10801,29 @@ export {
|
|
|
10421
10801
|
resolveRenderLib,
|
|
10422
10802
|
renderFontToFrameBuffer,
|
|
10423
10803
|
red,
|
|
10804
|
+
parseWrap,
|
|
10805
|
+
parseUnit,
|
|
10806
|
+
parsePositionType,
|
|
10807
|
+
parseOverflow,
|
|
10808
|
+
parseMeasureMode,
|
|
10809
|
+
parseLogLevel,
|
|
10424
10810
|
parseKeypress,
|
|
10811
|
+
parseJustify,
|
|
10812
|
+
parseGutter,
|
|
10813
|
+
parseFlexDirection,
|
|
10814
|
+
parseEdge,
|
|
10815
|
+
parseDisplay,
|
|
10816
|
+
parseDirection,
|
|
10817
|
+
parseDimension,
|
|
10425
10818
|
parseColor,
|
|
10819
|
+
parseBoxSizing,
|
|
10820
|
+
parseAlign,
|
|
10426
10821
|
nonAlphanumericKeys,
|
|
10427
10822
|
measureText,
|
|
10428
10823
|
magenta,
|
|
10429
10824
|
italic,
|
|
10430
10825
|
isSizeType,
|
|
10826
|
+
isPostionTypeType,
|
|
10431
10827
|
isPositionType,
|
|
10432
10828
|
isPaddingType,
|
|
10433
10829
|
isMarginType,
|
|
@@ -10501,6 +10897,7 @@ export {
|
|
|
10501
10897
|
Renderable,
|
|
10502
10898
|
RGBA,
|
|
10503
10899
|
OptimizedBuffer,
|
|
10900
|
+
MouseParser,
|
|
10504
10901
|
MouseEvent,
|
|
10505
10902
|
MouseButton,
|
|
10506
10903
|
LayoutEvents,
|
|
@@ -10523,3 +10920,6 @@ export {
|
|
|
10523
10920
|
ASCIIFontSelectionHelper,
|
|
10524
10921
|
ASCIIFontRenderable
|
|
10525
10922
|
};
|
|
10923
|
+
export { __toESM, __commonJS, __export, __require };
|
|
10924
|
+
//# debugId=D2D08A0277CDE28864756E2164756E21
|
|
10925
|
+
//# sourceMappingURL=index.js.map
|