@h-rig/cli 0.0.6-alpha.85 → 0.0.6-alpha.87
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/dist/bin/rig.js +79 -1027
- package/dist/src/app-opentui/bootstrap.js +79 -1027
- package/dist/src/app-opentui/command-palette.js +1 -0
- package/dist/src/app-opentui/drone.js +1 -0
- package/dist/src/app-opentui/index.js +61 -1024
- package/dist/src/app-opentui/list-search.d.ts +5 -1
- package/dist/src/app-opentui/list-search.js +2 -2
- package/dist/src/app-opentui/react/App.js +62 -970
- package/dist/src/app-opentui/react/Backdrop.js +3 -9
- package/dist/src/app-opentui/react/ChromeHost.js +6 -1038
- package/dist/src/app-opentui/react/SceneFrameView.js +55 -5
- package/dist/src/app-opentui/react/launch.js +62 -970
- package/dist/src/app-opentui/react/syntax.js +1 -0
- package/dist/src/app-opentui/registry.js +3 -5
- package/dist/src/app-opentui/render/constants.d.ts +0 -1
- package/dist/src/app-opentui/render/constants.js +0 -2
- package/dist/src/app-opentui/render/graphics.js +3 -9
- package/dist/src/app-opentui/render/hover.d.ts +11 -0
- package/dist/src/app-opentui/render/hover.js +34 -0
- package/dist/src/app-opentui/render/native-host.js +1 -0
- package/dist/src/app-opentui/render/panels.js +50 -3
- package/dist/src/app-opentui/render/preloader.js +1 -0
- package/dist/src/app-opentui/render/scene.js +1 -0
- package/dist/src/app-opentui/render/text.d.ts +13 -0
- package/dist/src/app-opentui/render/text.js +54 -5
- package/dist/src/app-opentui/render/type-bar.js +1 -0
- package/dist/src/app-opentui/runtime.js +62 -1025
- package/dist/src/app-opentui/scenes/command.js +1 -0
- package/dist/src/app-opentui/scenes/doctor.js +1 -0
- package/dist/src/app-opentui/scenes/error.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/agent.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/git.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/github.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/index.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/review.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.js +1 -0
- package/dist/src/app-opentui/scenes/family.js +1 -0
- package/dist/src/app-opentui/scenes/fleet.js +3 -5
- package/dist/src/app-opentui/scenes/handoff.js +1 -0
- package/dist/src/app-opentui/scenes/help.js +1 -0
- package/dist/src/app-opentui/scenes/inbox.js +1 -0
- package/dist/src/app-opentui/scenes/init.js +1 -0
- package/dist/src/app-opentui/scenes/inspect.js +1 -0
- package/dist/src/app-opentui/scenes/main.js +1 -0
- package/dist/src/app-opentui/scenes/pi.js +1 -0
- package/dist/src/app-opentui/scenes/plugin.js +1 -0
- package/dist/src/app-opentui/scenes/repo.js +1 -0
- package/dist/src/app-opentui/scenes/run-detail.js +1 -0
- package/dist/src/app-opentui/scenes/server.js +1 -0
- package/dist/src/app-opentui/scenes/tasks.js +3 -5
- package/dist/src/app-opentui/scenes/workspace.js +1 -0
- package/dist/src/app-opentui/selectable.js +1 -0
- package/dist/src/app-opentui/theme.d.ts +1 -0
- package/dist/src/app-opentui/theme.js +1 -0
- package/package.json +8 -8
- package/dist/src/app-opentui/render/image-visual-layer-worker.d.ts +0 -1
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +0 -1084
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +0 -109
- package/dist/src/app-opentui/render/image-visual-layer.js +0 -1068
- package/dist/src/app-opentui/terminal-capabilities.d.ts +0 -7
- package/dist/src/app-opentui/terminal-capabilities.js +0 -15
|
@@ -15585,6 +15585,7 @@ var init_theme2 = __esm(() => {
|
|
|
15585
15585
|
bg2: "#0b0c0e",
|
|
15586
15586
|
panel: "#101115",
|
|
15587
15587
|
panel2: "#14161b",
|
|
15588
|
+
hover: "#181b24",
|
|
15588
15589
|
glass: "#1e2230",
|
|
15589
15590
|
border: "#2a2e3a",
|
|
15590
15591
|
ink: "#f4f5f8",
|
|
@@ -17330,22 +17331,9 @@ function panelContentRect(layout, panel) {
|
|
|
17330
17331
|
const contentWidth = Math.max(1, width - paddingX * 2 - 1);
|
|
17331
17332
|
return { left, top, width, height, paddingX, paddingY, contentWidth };
|
|
17332
17333
|
}
|
|
17333
|
-
function panelPixelPlacement(layout, panel, size, minPixels = 8) {
|
|
17334
|
-
const cellW = size.width / layout.width;
|
|
17335
|
-
const cellH = size.height / layout.height;
|
|
17336
|
-
const leftCells = layout.centerLeft + (panel.left ?? 0);
|
|
17337
|
-
const topCells = layout.centerTop + panel.top;
|
|
17338
|
-
const widthCells = panel.width ?? layout.centerWidth;
|
|
17339
|
-
const heightCells = panel.height;
|
|
17340
|
-
const left = Math.round(leftCells * cellW);
|
|
17341
|
-
const top = Math.round(topCells * cellH);
|
|
17342
|
-
const width = Math.round(widthCells * cellW);
|
|
17343
|
-
const height = Math.round(heightCells * cellH);
|
|
17344
|
-
return width > minPixels && height > minPixels ? { left, top, width, height, leftCells, topCells, widthCells, heightCells } : null;
|
|
17345
|
-
}
|
|
17346
17334
|
|
|
17347
17335
|
// packages/cli/src/app-opentui/render/constants.ts
|
|
17348
|
-
var LCG_MULTIPLIER = 1664525, LCG_INCREMENT = 1013904223, LCG_DIVISOR = 4294967295, PACKET_CYAN_PROBABILITY = 0.22, LANE_INTERP_STEPS = 32, LANE_LEN_BASE = 0.32, LANE_LEN_SPREAD = 0.42, LANE_CURVE_RANGE = 0.7, PACKET_SPEED_BASE = 0.003, PACKET_SPEED_SPREAD = 0.009, DISPATCH_LANES_COMPACT = 7, DISPATCH_LANES_WIDE = 12, DISPATCH_PACKETS_COMPACT = 70, DISPATCH_PACKETS_WIDE = 150, CARRIER_NODES_COMPACT = 5, CARRIER_NODES_WIDE = 7, LOOP_GATES_COMPACT = 4, LOOP_GATES_WIDE = 5, DISPATCH_DRONES_COMPACT = 4, DISPATCH_DRONES_WIDE = 8, CORE_DISPATCH_X = 0.3, CORE_DISPATCH_Y = 0.45, CORE_CARRIER_X = 0.5, CORE_CARRIER_Y = 0.54, CORE_LOOP_X = 0.09, CORE_LOOP_Y = 0.56, RAIL_YS_LOOP, RAIL_YS_CARRIER, RAIL_YS_DISPATCH, GLOW_FALLOFF_EXP_ASCII = 2.2
|
|
17336
|
+
var LCG_MULTIPLIER = 1664525, LCG_INCREMENT = 1013904223, LCG_DIVISOR = 4294967295, PACKET_CYAN_PROBABILITY = 0.22, LANE_INTERP_STEPS = 32, LANE_LEN_BASE = 0.32, LANE_LEN_SPREAD = 0.42, LANE_CURVE_RANGE = 0.7, PACKET_SPEED_BASE = 0.003, PACKET_SPEED_SPREAD = 0.009, DISPATCH_LANES_COMPACT = 7, DISPATCH_LANES_WIDE = 12, DISPATCH_PACKETS_COMPACT = 70, DISPATCH_PACKETS_WIDE = 150, CARRIER_NODES_COMPACT = 5, CARRIER_NODES_WIDE = 7, LOOP_GATES_COMPACT = 4, LOOP_GATES_WIDE = 5, DISPATCH_DRONES_COMPACT = 4, DISPATCH_DRONES_WIDE = 8, CORE_DISPATCH_X = 0.3, CORE_DISPATCH_Y = 0.45, CORE_CARRIER_X = 0.5, CORE_CARRIER_Y = 0.54, CORE_LOOP_X = 0.09, CORE_LOOP_Y = 0.56, RAIL_YS_LOOP, RAIL_YS_CARRIER, RAIL_YS_DISPATCH, GLOW_FALLOFF_EXP_ASCII = 2.2;
|
|
17349
17337
|
var init_constants = __esm(() => {
|
|
17350
17338
|
RAIL_YS_LOOP = [0.18, 0.5, 0.82];
|
|
17351
17339
|
RAIL_YS_CARRIER = [0.24, 0.54, 0.82];
|
|
@@ -17764,27 +17752,20 @@ function writeCell(layer, x, y, char, fg2, bg) {
|
|
|
17764
17752
|
function drawFullCell(layer, x, y, bg) {
|
|
17765
17753
|
writeCell(layer, x, y, " ", TRANSPARENT, bg);
|
|
17766
17754
|
}
|
|
17767
|
-
function
|
|
17768
|
-
writeCell(layer, x, y, char, fg2, BACKDROP);
|
|
17769
|
-
}
|
|
17770
|
-
function drawRoundedFill(layer, left, top, right, bottom, dividerY) {
|
|
17755
|
+
function drawPanelFill(layer, left, top, right, bottom, dividerY) {
|
|
17771
17756
|
const bgForY = (y) => y < dividerY ? PANEL_HEADER_BG : PANEL_BG;
|
|
17772
17757
|
for (let y = top;y <= bottom; y += 1) {
|
|
17773
17758
|
const bg = bgForY(y);
|
|
17774
17759
|
for (let x = left;x <= right; x += 1)
|
|
17775
17760
|
drawFullCell(layer, x, y, bg);
|
|
17776
17761
|
}
|
|
17777
|
-
drawCornerCut(layer, left, top, "\u2597", PANEL_HEADER_BG);
|
|
17778
|
-
drawCornerCut(layer, right, top, "\u2596", PANEL_HEADER_BG);
|
|
17779
|
-
drawCornerCut(layer, left, bottom, "\u259D", PANEL_BG);
|
|
17780
|
-
drawCornerCut(layer, right, bottom, "\u2598", PANEL_BG);
|
|
17781
17762
|
}
|
|
17782
17763
|
function drawAdTerminalPanel(layer, layout, panel) {
|
|
17783
17764
|
const rect = panelCellRect(layout, panel);
|
|
17784
17765
|
if (!rect)
|
|
17785
17766
|
return;
|
|
17786
17767
|
const { left, top, width, right, bottom, headerHeight, dividerY } = rect;
|
|
17787
|
-
|
|
17768
|
+
drawPanelFill(layer, left, top, right, bottom, dividerY);
|
|
17788
17769
|
if (dividerY > top && dividerY < bottom) {
|
|
17789
17770
|
for (let x = left + 2;x < right - 1; x += 1) {
|
|
17790
17771
|
writeCell(layer, x, dividerY, "\u2500", PANEL_LINE_DIM, PANEL_BG);
|
|
@@ -17892,973 +17873,69 @@ var init_graphics = __esm(() => {
|
|
|
17892
17873
|
];
|
|
17893
17874
|
});
|
|
17894
17875
|
|
|
17895
|
-
// packages/cli/src/app-opentui/
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
const imageProtocol = getCapabilities().images;
|
|
17899
|
-
const supportsKittyImages = imageProtocol === "kitty";
|
|
17900
|
-
return {
|
|
17901
|
-
imageProtocol,
|
|
17902
|
-
supportsKittyImages,
|
|
17903
|
-
visualMode: supportsKittyImages ? "kitty-images" : "framebuffer-fallback"
|
|
17904
|
-
};
|
|
17876
|
+
// packages/cli/src/app-opentui/render/hover.ts
|
|
17877
|
+
function getHoveredSelectableId() {
|
|
17878
|
+
return hoveredId;
|
|
17905
17879
|
}
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
// packages/cli/src/app-opentui/render/image-visual-layer.ts
|
|
17909
|
-
import { Worker } from "worker_threads";
|
|
17910
|
-
import { deflateSync } from "zlib";
|
|
17911
|
-
import { allocateImageId, deleteKittyImage } from "@earendil-works/pi-tui";
|
|
17912
|
-
function loadBucket(load) {
|
|
17913
|
-
if (!Number.isFinite(load ?? NaN))
|
|
17914
|
-
return 0;
|
|
17915
|
-
return Math.max(0, Math.min(LOAD_BUCKETS, Math.round((load ?? 0) * LOAD_BUCKETS)));
|
|
17916
|
-
}
|
|
17917
|
-
function imageTransport() {
|
|
17918
|
-
const forced = process.env.RIG_OPENTUI_IMAGE_TRANSPORT;
|
|
17919
|
-
if (forced === "rgba-zlib")
|
|
17920
|
-
return "rgba-zlib";
|
|
17921
|
-
return "png";
|
|
17922
|
-
}
|
|
17923
|
-
function imageResolutionScale() {
|
|
17924
|
-
const raw = Number.parseFloat(process.env.RIG_OPENTUI_IMAGE_SCALE ?? "");
|
|
17925
|
-
if (Number.isFinite(raw) && raw > 0)
|
|
17926
|
-
return Math.max(0.25, Math.min(1, raw));
|
|
17927
|
-
return DEFAULT_IMAGE_RESOLUTION_SCALE;
|
|
17928
|
-
}
|
|
17929
|
-
function rgbaWord(color) {
|
|
17930
|
-
return (color[3] << 24 | color[2] << 16 | color[1] << 8 | color[0]) >>> 0;
|
|
17931
|
-
}
|
|
17932
|
-
function fillRgba(data, color, word = rgbaWord(color)) {
|
|
17933
|
-
if (data.byteOffset % 4 === 0 && data.byteLength % 4 === 0) {
|
|
17934
|
-
new Uint32Array(data.buffer, data.byteOffset, data.byteLength / 4).fill(word);
|
|
17935
|
-
return;
|
|
17936
|
-
}
|
|
17937
|
-
for (let i = 0;i < data.length; i += 4) {
|
|
17938
|
-
data[i] = color[0];
|
|
17939
|
-
data[i + 1] = color[1];
|
|
17940
|
-
data[i + 2] = color[2];
|
|
17941
|
-
data[i + 3] = color[3];
|
|
17942
|
-
}
|
|
17943
|
-
}
|
|
17944
|
-
function sceneStaticTick(scene) {
|
|
17945
|
-
let hash = 0;
|
|
17946
|
-
for (let index = 0;index < scene.length; index += 1)
|
|
17947
|
-
hash = hash * 33 + scene.charCodeAt(index) >>> 0;
|
|
17948
|
-
return 11 + hash % 97;
|
|
17880
|
+
function isHovered(id) {
|
|
17881
|
+
return id !== undefined && id === hoveredId;
|
|
17949
17882
|
}
|
|
17950
|
-
function
|
|
17951
|
-
if (
|
|
17952
|
-
return LIME;
|
|
17953
|
-
if (char === "%" || char === "!" || char === "/" || char === "\\" || char === "|")
|
|
17954
|
-
return CYAN;
|
|
17955
|
-
if (char === "." || char === "'" || char === "_" || row < 3 || row > totalRows - 4)
|
|
17956
|
-
return INK_DIM;
|
|
17957
|
-
if (char === "-" || char === "=" || char === "(" || char === ")")
|
|
17958
|
-
return LIME_DIM;
|
|
17959
|
-
return MAGENTA;
|
|
17960
|
-
}
|
|
17961
|
-
function fillRectAlpha(data, width, height, left, top, rectWidth, rectHeight, color, alpha) {
|
|
17962
|
-
const x0 = Math.max(0, Math.floor(left));
|
|
17963
|
-
const y0 = Math.max(0, Math.floor(top));
|
|
17964
|
-
const x1 = Math.min(width, Math.ceil(left + rectWidth));
|
|
17965
|
-
const y1 = Math.min(height, Math.ceil(top + rectHeight));
|
|
17966
|
-
for (let y = y0;y < y1; y += 1) {
|
|
17967
|
-
for (let x = x0;x < x1; x += 1)
|
|
17968
|
-
blendOver(data, (y * width + x) * 4, color, alpha);
|
|
17969
|
-
}
|
|
17970
|
-
}
|
|
17971
|
-
function drawAsciiGlyph(data, width, height, x, y, cellWidth, cellHeight, char, color, alpha) {
|
|
17972
|
-
const pattern = ASCII_GLYPHS[char] ?? ASCII_GLYPHS["*"];
|
|
17973
|
-
const glyphWidth = Math.max(1, cellWidth * 0.56);
|
|
17974
|
-
const glyphHeight = Math.max(1, cellHeight * 0.7);
|
|
17975
|
-
const originX = x + (cellWidth - glyphWidth) * 0.5;
|
|
17976
|
-
const originY = y + (cellHeight - glyphHeight) * 0.5;
|
|
17977
|
-
const pixelWidth = Math.max(1, glyphWidth / pattern[0].length);
|
|
17978
|
-
const pixelHeight = Math.max(1, glyphHeight / pattern.length);
|
|
17979
|
-
for (let row = 0;row < pattern.length; row += 1) {
|
|
17980
|
-
const bits = pattern[row];
|
|
17981
|
-
for (let col = 0;col < bits.length; col += 1) {
|
|
17982
|
-
if (bits[col] !== "1")
|
|
17983
|
-
continue;
|
|
17984
|
-
fillRectAlpha(data, width, height, originX + col * pixelWidth, originY + row * pixelHeight, pixelWidth * 0.72, pixelHeight * 0.72, color, alpha);
|
|
17985
|
-
}
|
|
17986
|
-
}
|
|
17987
|
-
}
|
|
17988
|
-
function drawStaticAsciiFleetBackground(data, width, height, scene, layout, load, activeRuns) {
|
|
17989
|
-
const rows = fleetRows(sceneStaticTick(scene), { animate: true });
|
|
17990
|
-
const cellWidth = width / Math.max(1, layout.width);
|
|
17991
|
-
const cellHeight = height / Math.max(1, layout.height);
|
|
17992
|
-
const sideBySide = layout.width >= FLEET_GRID_WIDTH * 1.9;
|
|
17993
|
-
const leftCells = sideBySide ? Math.max(1, Math.floor(layout.width * 0.3 - FLEET_GRID_WIDTH / 2)) : Math.floor((layout.width - FLEET_GRID_WIDTH) / 2);
|
|
17994
|
-
const topCells = Math.floor((layout.height - FLEET_GRID_HEIGHT) / 2);
|
|
17995
|
-
const fleetLeft = leftCells * cellWidth;
|
|
17996
|
-
const fleetTop = topCells * cellHeight;
|
|
17997
|
-
drawGlow2(data, width, height, width * 0.5, height * 0.5, Math.min(width, height) * 0.4, LIME, 0.022 + load * 0.03);
|
|
17998
|
-
drawGlow2(data, width, height, width * 0.18, height * 0.22, Math.min(width, height) * 0.28, CYAN, 0.018 + load * 0.012);
|
|
17999
|
-
drawGlow2(data, width, height, width * 0.82, height * 0.78, Math.min(width, height) * 0.22, MAGENTA, 0.012 + load * 0.008);
|
|
18000
|
-
let droneTotal = 0;
|
|
18001
|
-
for (const line2 of rows)
|
|
18002
|
-
for (const char of line2)
|
|
18003
|
-
if (char === "@" || char === "$" || char === "%")
|
|
18004
|
-
droneTotal += 1;
|
|
18005
|
-
const litTarget = Math.max(0, Math.min(droneTotal, activeRuns));
|
|
18006
|
-
let droneIndex = 0;
|
|
18007
|
-
for (let row = 0;row < rows.length; row += 1) {
|
|
18008
|
-
const line2 = rows[row];
|
|
18009
|
-
for (let col = 0;col < line2.length; col += 1) {
|
|
18010
|
-
const char = line2[col];
|
|
18011
|
-
if (char === " ")
|
|
18012
|
-
continue;
|
|
18013
|
-
const x = fleetLeft + col * cellWidth;
|
|
18014
|
-
const y = fleetTop + row * cellHeight;
|
|
18015
|
-
const color = charColor(char, row, rows.length);
|
|
18016
|
-
const isDrone = char === "@" || char === "$" || char === "%";
|
|
18017
|
-
const lit = isDrone && droneIndex < litTarget;
|
|
18018
|
-
drawAsciiGlyph(data, width, height, x + cellWidth * 0.07, y + cellHeight * 0.05, cellWidth, cellHeight, char, color, lit ? 0.72 : 0.46);
|
|
18019
|
-
if (isDrone) {
|
|
18020
|
-
droneIndex += 1;
|
|
18021
|
-
drawGlow2(data, width, height, x + cellWidth * 0.5, y + cellHeight * 0.5, Math.max(cellWidth, cellHeight) * 0.95, color, lit ? 0.044 : 0.014);
|
|
18022
|
-
}
|
|
18023
|
-
}
|
|
18024
|
-
}
|
|
18025
|
-
}
|
|
18026
|
-
function applyStaticAtmosphere(data, width, height, load) {
|
|
18027
|
-
const cx = width * 0.5;
|
|
18028
|
-
const cy = height * 0.42;
|
|
18029
|
-
const radius = Math.max(width, height) * 0.78;
|
|
18030
|
-
const minVignette = 0.1 - load * 0.02;
|
|
18031
|
-
for (let y = 0;y < height; y += 1) {
|
|
18032
|
-
for (let x = 0;x < width; x += 1) {
|
|
18033
|
-
const distance = Math.hypot(x - cx, y - cy) / radius;
|
|
18034
|
-
const alpha = Math.max(minVignette, Math.min(0.82, 0.12 + Math.pow(distance, 1.65) * 0.62));
|
|
18035
|
-
blendOver(data, (y * width + x) * 4, BG, alpha);
|
|
18036
|
-
}
|
|
18037
|
-
}
|
|
18038
|
-
drawGlow2(data, width, height, width * 0.82, height * 0.04, Math.min(width, height) * 0.2, LIME, 0.024 + load * 0.012);
|
|
18039
|
-
drawGlow2(data, width, height, width * 0.12, height * 0.18, Math.min(width, height) * 0.16, CYAN, 0.018 + load * 0.008);
|
|
18040
|
-
}
|
|
18041
|
-
function makeCrcTable() {
|
|
18042
|
-
const table = new Uint32Array(256);
|
|
18043
|
-
for (let n = 0;n < 256; n += 1) {
|
|
18044
|
-
let c = n;
|
|
18045
|
-
for (let k = 0;k < 8; k += 1)
|
|
18046
|
-
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
18047
|
-
table[n] = c >>> 0;
|
|
18048
|
-
}
|
|
18049
|
-
return table;
|
|
18050
|
-
}
|
|
18051
|
-
function crc32(bytes) {
|
|
18052
|
-
let c = 4294967295;
|
|
18053
|
-
for (let i = 0;i < bytes.length; i += 1)
|
|
18054
|
-
c = CRC_TABLE[(c ^ bytes[i]) & 255] ^ c >>> 8;
|
|
18055
|
-
return (c ^ 4294967295) >>> 0;
|
|
18056
|
-
}
|
|
18057
|
-
function chunk2(type, data) {
|
|
18058
|
-
const out = new Uint8Array(12 + data.length);
|
|
18059
|
-
const view = new DataView(out.buffer);
|
|
18060
|
-
view.setUint32(0, data.length);
|
|
18061
|
-
out[4] = type.charCodeAt(0);
|
|
18062
|
-
out[5] = type.charCodeAt(1);
|
|
18063
|
-
out[6] = type.charCodeAt(2);
|
|
18064
|
-
out[7] = type.charCodeAt(3);
|
|
18065
|
-
out.set(data, 8);
|
|
18066
|
-
view.setUint32(8 + data.length, crc32(out.subarray(4, 8 + data.length)));
|
|
18067
|
-
return out;
|
|
18068
|
-
}
|
|
18069
|
-
function encodePng(width, height, rgba) {
|
|
18070
|
-
const ihdr = new Uint8Array(13);
|
|
18071
|
-
const ihdrView = new DataView(ihdr.buffer);
|
|
18072
|
-
ihdrView.setUint32(0, width);
|
|
18073
|
-
ihdrView.setUint32(4, height);
|
|
18074
|
-
ihdr[8] = 8;
|
|
18075
|
-
ihdr[9] = 6;
|
|
18076
|
-
ihdr[10] = 0;
|
|
18077
|
-
ihdr[11] = 0;
|
|
18078
|
-
ihdr[12] = 0;
|
|
18079
|
-
const stride = width * 4;
|
|
18080
|
-
const raw = new Uint8Array((stride + 1) * height);
|
|
18081
|
-
for (let y = 0;y < height; y += 1) {
|
|
18082
|
-
const rawOffset = y * (stride + 1);
|
|
18083
|
-
raw[rawOffset] = 0;
|
|
18084
|
-
raw.set(rgba.subarray(y * stride, y * stride + stride), rawOffset + 1);
|
|
18085
|
-
}
|
|
18086
|
-
const compressed = deflateSync(raw, { level: ZLIB_LEVEL });
|
|
18087
|
-
return Buffer.concat([
|
|
18088
|
-
Buffer.from(PNG_SIGNATURE),
|
|
18089
|
-
Buffer.from(chunk2("IHDR", ihdr)),
|
|
18090
|
-
Buffer.from(chunk2("IDAT", compressed)),
|
|
18091
|
-
Buffer.from(chunk2("IEND", new Uint8Array(0)))
|
|
18092
|
-
]);
|
|
18093
|
-
}
|
|
18094
|
-
function kittyImageSequence(base64, options) {
|
|
18095
|
-
const params = [`a=T`, `f=${options.format}`, `q=2`, `C=1`, `c=${options.columns}`, `r=${options.rows}`, `i=${options.imageId}`, `z=${options.zIndex}`];
|
|
18096
|
-
if (options.format === 32) {
|
|
18097
|
-
params.push(`s=${options.pixelWidth ?? 1}`, `v=${options.pixelHeight ?? 1}`);
|
|
18098
|
-
if (options.compressed)
|
|
18099
|
-
params.push("o=z");
|
|
18100
|
-
}
|
|
18101
|
-
if (base64.length <= KITTY_CHUNK_SIZE)
|
|
18102
|
-
return `\x1B_G${params.join(",")};${base64}\x1B\\`;
|
|
18103
|
-
const chunks = [];
|
|
18104
|
-
for (let offset = 0;offset < base64.length; offset += KITTY_CHUNK_SIZE) {
|
|
18105
|
-
const part = base64.slice(offset, offset + KITTY_CHUNK_SIZE);
|
|
18106
|
-
const last = offset + KITTY_CHUNK_SIZE >= base64.length;
|
|
18107
|
-
chunks.push(`\x1B_G${offset === 0 ? `${params.join(",")},` : ""}m=${last ? 0 : 1};${part}\x1B\\`);
|
|
18108
|
-
}
|
|
18109
|
-
return chunks.join("");
|
|
18110
|
-
}
|
|
18111
|
-
function clampByte(value) {
|
|
18112
|
-
return Math.max(0, Math.min(255, Math.round(value)));
|
|
18113
|
-
}
|
|
18114
|
-
function blendOver(data, index, color, alphaScale = 1) {
|
|
18115
|
-
const alpha = color[3] / 255 * alphaScale;
|
|
18116
|
-
const inv = 1 - alpha;
|
|
18117
|
-
data[index] = clampByte(color[0] * alpha + data[index] * inv);
|
|
18118
|
-
data[index + 1] = clampByte(color[1] * alpha + data[index + 1] * inv);
|
|
18119
|
-
data[index + 2] = clampByte(color[2] * alpha + data[index + 2] * inv);
|
|
18120
|
-
data[index + 3] = 255;
|
|
18121
|
-
}
|
|
18122
|
-
function drawDisc(data, width, height, cx, cy, radius, color, alpha = 1) {
|
|
18123
|
-
const minX = Math.max(0, Math.floor(cx - radius));
|
|
18124
|
-
const maxX = Math.min(width - 1, Math.ceil(cx + radius));
|
|
18125
|
-
const minY = Math.max(0, Math.floor(cy - radius));
|
|
18126
|
-
const maxY = Math.min(height - 1, Math.ceil(cy + radius));
|
|
18127
|
-
for (let y = minY;y <= maxY; y += 1) {
|
|
18128
|
-
for (let x = minX;x <= maxX; x += 1) {
|
|
18129
|
-
const dx = x + 0.5 - cx;
|
|
18130
|
-
const dy = y + 0.5 - cy;
|
|
18131
|
-
const d = Math.sqrt(dx * dx + dy * dy);
|
|
18132
|
-
if (d > radius)
|
|
18133
|
-
continue;
|
|
18134
|
-
const edge = Math.max(0, Math.min(1, radius - d));
|
|
18135
|
-
blendOver(data, (y * width + x) * 4, color, alpha * Math.min(1, 0.35 + edge));
|
|
18136
|
-
}
|
|
18137
|
-
}
|
|
18138
|
-
}
|
|
18139
|
-
function drawGlow2(data, width, height, cx, cy, radius, color, alpha = 0.18) {
|
|
18140
|
-
const minX = Math.max(0, Math.floor(cx - radius));
|
|
18141
|
-
const maxX = Math.min(width - 1, Math.ceil(cx + radius));
|
|
18142
|
-
const minY = Math.max(0, Math.floor(cy - radius));
|
|
18143
|
-
const maxY = Math.min(height - 1, Math.ceil(cy + radius));
|
|
18144
|
-
for (let y = minY;y <= maxY; y += 1) {
|
|
18145
|
-
for (let x = minX;x <= maxX; x += 1) {
|
|
18146
|
-
const dx = x + 0.5 - cx;
|
|
18147
|
-
const dy = y + 0.5 - cy;
|
|
18148
|
-
const d = Math.sqrt(dx * dx + dy * dy);
|
|
18149
|
-
if (d > radius)
|
|
18150
|
-
continue;
|
|
18151
|
-
const falloff = Math.pow(1 - d / Math.max(1, radius), GLOW_FALLOFF_EXP_IMAGE);
|
|
18152
|
-
blendOver(data, (y * width + x) * 4, color, alpha * falloff);
|
|
18153
|
-
}
|
|
18154
|
-
}
|
|
18155
|
-
}
|
|
18156
|
-
function drawLine2(data, width, height, x0, y0, x1, y1, color, alpha = 0.5, thickness = 1.4) {
|
|
18157
|
-
const dx = x1 - x0;
|
|
18158
|
-
const dy = y1 - y0;
|
|
18159
|
-
const steps = Math.max(1, Math.ceil(Math.hypot(dx, dy) * 1.2));
|
|
18160
|
-
for (let i = 0;i <= steps; i += 1) {
|
|
18161
|
-
const t2 = i / steps;
|
|
18162
|
-
drawDisc(data, width, height, x0 + dx * t2, y0 + dy * t2, thickness, color, alpha);
|
|
18163
|
-
}
|
|
18164
|
-
}
|
|
18165
|
-
function roundRectAlpha(px, py, x, y, w, h, r) {
|
|
18166
|
-
const rx = Math.max(x + r, Math.min(px, x + w - r));
|
|
18167
|
-
const ry = Math.max(y + r, Math.min(py, y + h - r));
|
|
18168
|
-
const dx = px - rx;
|
|
18169
|
-
const dy = py - ry;
|
|
18170
|
-
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
18171
|
-
return Math.max(0, Math.min(1, r + 0.75 - dist));
|
|
18172
|
-
}
|
|
18173
|
-
function panelRect(layout, panel, size) {
|
|
18174
|
-
return panelPixelPlacement(layout, panel, size);
|
|
18175
|
-
}
|
|
18176
|
-
function downsampleRegion(data, canvasW, canvasH, rect, scale) {
|
|
18177
|
-
const w = Math.max(1, Math.ceil(rect.width / scale));
|
|
18178
|
-
const h = Math.max(1, Math.ceil(rect.height / scale));
|
|
18179
|
-
const out = new Uint8ClampedArray(w * h * 3);
|
|
18180
|
-
for (let y = 0;y < h; y += 1) {
|
|
18181
|
-
for (let x = 0;x < w; x += 1) {
|
|
18182
|
-
let r = 0, g = 0, b = 0, count = 0;
|
|
18183
|
-
const sx0 = rect.left + x * scale;
|
|
18184
|
-
const sy0 = rect.top + y * scale;
|
|
18185
|
-
for (let yy = 0;yy < scale; yy += 1) {
|
|
18186
|
-
const sy = sy0 + yy;
|
|
18187
|
-
if (sy < 0 || sy >= canvasH)
|
|
18188
|
-
continue;
|
|
18189
|
-
for (let xx = 0;xx < scale; xx += 1) {
|
|
18190
|
-
const sx = sx0 + xx;
|
|
18191
|
-
if (sx < 0 || sx >= canvasW)
|
|
18192
|
-
continue;
|
|
18193
|
-
const i = (sy * canvasW + sx) * 4;
|
|
18194
|
-
r += data[i];
|
|
18195
|
-
g += data[i + 1];
|
|
18196
|
-
b += data[i + 2];
|
|
18197
|
-
count += 1;
|
|
18198
|
-
}
|
|
18199
|
-
}
|
|
18200
|
-
const oi = (y * w + x) * 3;
|
|
18201
|
-
out[oi] = count ? r / count : BG[0];
|
|
18202
|
-
out[oi + 1] = count ? g / count : BG[1];
|
|
18203
|
-
out[oi + 2] = count ? b / count : BG[2];
|
|
18204
|
-
}
|
|
18205
|
-
}
|
|
18206
|
-
return { pixels: out, width: w, height: h };
|
|
18207
|
-
}
|
|
18208
|
-
function blurRgb(buffer, width, height, radius) {
|
|
18209
|
-
const tmp = new Uint8ClampedArray(buffer.length);
|
|
18210
|
-
const out = new Uint8ClampedArray(buffer.length);
|
|
18211
|
-
const window = radius * 2 + 1;
|
|
18212
|
-
for (let y = 0;y < height; y += 1) {
|
|
18213
|
-
let r = 0, g = 0, b = 0;
|
|
18214
|
-
for (let x = -radius;x <= radius; x += 1) {
|
|
18215
|
-
const sx = Math.max(0, Math.min(width - 1, x));
|
|
18216
|
-
const i = (y * width + sx) * 3;
|
|
18217
|
-
r += buffer[i];
|
|
18218
|
-
g += buffer[i + 1];
|
|
18219
|
-
b += buffer[i + 2];
|
|
18220
|
-
}
|
|
18221
|
-
for (let x = 0;x < width; x += 1) {
|
|
18222
|
-
const oi = (y * width + x) * 3;
|
|
18223
|
-
tmp[oi] = r / window;
|
|
18224
|
-
tmp[oi + 1] = g / window;
|
|
18225
|
-
tmp[oi + 2] = b / window;
|
|
18226
|
-
const removeX = Math.max(0, x - radius);
|
|
18227
|
-
const addX = Math.min(width - 1, x + radius + 1);
|
|
18228
|
-
const ri = (y * width + removeX) * 3;
|
|
18229
|
-
const ai = (y * width + addX) * 3;
|
|
18230
|
-
r += tmp.length ? buffer[ai] - buffer[ri] : 0;
|
|
18231
|
-
g += tmp.length ? buffer[ai + 1] - buffer[ri + 1] : 0;
|
|
18232
|
-
b += tmp.length ? buffer[ai + 2] - buffer[ri + 2] : 0;
|
|
18233
|
-
}
|
|
18234
|
-
}
|
|
18235
|
-
for (let x = 0;x < width; x += 1) {
|
|
18236
|
-
let r = 0, g = 0, b = 0;
|
|
18237
|
-
for (let y = -radius;y <= radius; y += 1) {
|
|
18238
|
-
const sy = Math.max(0, Math.min(height - 1, y));
|
|
18239
|
-
const i = (sy * width + x) * 3;
|
|
18240
|
-
r += tmp[i];
|
|
18241
|
-
g += tmp[i + 1];
|
|
18242
|
-
b += tmp[i + 2];
|
|
18243
|
-
}
|
|
18244
|
-
for (let y = 0;y < height; y += 1) {
|
|
18245
|
-
const oi = (y * width + x) * 3;
|
|
18246
|
-
out[oi] = r / window;
|
|
18247
|
-
out[oi + 1] = g / window;
|
|
18248
|
-
out[oi + 2] = b / window;
|
|
18249
|
-
const removeY = Math.max(0, y - radius);
|
|
18250
|
-
const addY = Math.min(height - 1, y + radius + 1);
|
|
18251
|
-
const ri = (removeY * width + x) * 3;
|
|
18252
|
-
const ai = (addY * width + x) * 3;
|
|
18253
|
-
r += tmp[ai] - tmp[ri];
|
|
18254
|
-
g += tmp[ai + 1] - tmp[ri + 1];
|
|
18255
|
-
b += tmp[ai + 2] - tmp[ri + 2];
|
|
18256
|
-
}
|
|
18257
|
-
}
|
|
18258
|
-
return out;
|
|
18259
|
-
}
|
|
18260
|
-
function panelMaskKey(width, height, rect, headerPx, blurScale) {
|
|
18261
|
-
return `${width}x${height}:${rect.left},${rect.top},${rect.width},${rect.height}:${Math.round(headerPx * 100) / 100}:${blurScale}`;
|
|
18262
|
-
}
|
|
18263
|
-
function getPanelMask(width, height, rect, headerPx, blurScale) {
|
|
18264
|
-
const key = panelMaskKey(width, height, rect, headerPx, blurScale);
|
|
18265
|
-
const cached = panelMaskCache.get(key);
|
|
18266
|
-
if (cached)
|
|
18267
|
-
return cached;
|
|
18268
|
-
const radius = Math.max(PANEL_MASK_RADIUS_MIN, Math.min(PANEL_MASK_RADIUS_MAX, Math.round(Math.min(rect.width, rect.height) * PANEL_MASK_RADIUS_FACTOR)));
|
|
18269
|
-
const sampledWidth = Math.max(1, Math.ceil(rect.width / blurScale));
|
|
18270
|
-
const sampledHeight = Math.max(1, Math.ceil(rect.height / blurScale));
|
|
18271
|
-
const x0 = Math.max(0, rect.left);
|
|
18272
|
-
const y0 = Math.max(0, rect.top);
|
|
18273
|
-
const x1 = Math.min(width - 1, rect.left + rect.width - 1);
|
|
18274
|
-
const y1 = Math.min(height - 1, rect.top + rect.height - 1);
|
|
18275
|
-
const indices = [];
|
|
18276
|
-
const sampleIndices = [];
|
|
18277
|
-
const panelAlpha = [];
|
|
18278
|
-
const edgeAlpha = [];
|
|
18279
|
-
const headerFlags = [];
|
|
18280
|
-
const dividerIndices = [];
|
|
18281
|
-
for (let y = y0;y <= y1; y += 1) {
|
|
18282
|
-
for (let x = x0;x <= x1; x += 1) {
|
|
18283
|
-
const a = roundRectAlpha(x + 0.5, y + 0.5, rect.left, rect.top, rect.width, rect.height, radius);
|
|
18284
|
-
if (a <= 0)
|
|
18285
|
-
continue;
|
|
18286
|
-
const edge = roundRectAlpha(x + 0.5, y + 0.5, rect.left + 1.2, rect.top + 1.2, rect.width - 2.4, rect.height - 2.4, Math.max(1, radius - 1.2));
|
|
18287
|
-
const sx = Math.max(0, Math.min(sampledWidth - 1, Math.floor((x - rect.left) / blurScale)));
|
|
18288
|
-
const sy = Math.max(0, Math.min(sampledHeight - 1, Math.floor((y - rect.top) / blurScale)));
|
|
18289
|
-
indices.push((y * width + x) * 4);
|
|
18290
|
-
sampleIndices.push((sy * sampledWidth + sx) * 3);
|
|
18291
|
-
panelAlpha.push(a);
|
|
18292
|
-
edgeAlpha.push(edge < 0.96 ? Math.min(1, (1 - edge) * 0.7) : 0);
|
|
18293
|
-
headerFlags.push(y < rect.top + headerPx ? 1 : 0);
|
|
18294
|
-
}
|
|
18295
|
-
}
|
|
18296
|
-
const dividerY = Math.round(rect.top + headerPx);
|
|
18297
|
-
if (dividerY > y0 && dividerY < y1) {
|
|
18298
|
-
for (let x = x0 + radius;x <= x1 - radius; x += 1) {
|
|
18299
|
-
dividerIndices.push((dividerY * width + x) * 4);
|
|
18300
|
-
}
|
|
18301
|
-
}
|
|
18302
|
-
const mask = {
|
|
18303
|
-
key,
|
|
18304
|
-
indices: Uint32Array.from(indices),
|
|
18305
|
-
sampleIndices: Uint32Array.from(sampleIndices),
|
|
18306
|
-
panelAlpha: Float32Array.from(panelAlpha),
|
|
18307
|
-
edgeAlpha: Float32Array.from(edgeAlpha),
|
|
18308
|
-
headerFlags: Uint8Array.from(headerFlags),
|
|
18309
|
-
dividerIndices: Uint32Array.from(dividerIndices)
|
|
18310
|
-
};
|
|
18311
|
-
panelMaskCache.set(key, mask);
|
|
18312
|
-
while (panelMaskCache.size > PANEL_MASK_CACHE_LIMIT) {
|
|
18313
|
-
const oldest = panelMaskCache.keys().next().value;
|
|
18314
|
-
if (!oldest)
|
|
18315
|
-
break;
|
|
18316
|
-
panelMaskCache.delete(oldest);
|
|
18317
|
-
}
|
|
18318
|
-
return mask;
|
|
18319
|
-
}
|
|
18320
|
-
function compositePanel(data, width, height, rect, headerPx) {
|
|
18321
|
-
const blurScale = PANEL_BLUR_SCALE;
|
|
18322
|
-
const sampled = downsampleRegion(data, width, height, rect, blurScale);
|
|
18323
|
-
const blurRadius = Math.max(PANEL_BLUR_RADIUS_MIN, Math.min(PANEL_BLUR_RADIUS_MAX, Math.round(Math.min(rect.width, rect.height) * PANEL_BLUR_RADIUS_FACTOR)));
|
|
18324
|
-
const blurred = blurRgb(sampled.pixels, sampled.width, sampled.height, blurRadius);
|
|
18325
|
-
const mask = getPanelMask(width, height, rect, headerPx, blurScale);
|
|
18326
|
-
for (let i = 0;i < mask.indices.length; i += 1) {
|
|
18327
|
-
const idx = mask.indices[i];
|
|
18328
|
-
const sampleIdx = mask.sampleIndices[i];
|
|
18329
|
-
data[idx] = blurred[sampleIdx];
|
|
18330
|
-
data[idx + 1] = blurred[sampleIdx + 1];
|
|
18331
|
-
data[idx + 2] = blurred[sampleIdx + 2];
|
|
18332
|
-
data[idx + 3] = 255;
|
|
18333
|
-
blendOver(data, idx, mask.headerFlags[i] ? PANEL_HEADER : PANEL, mask.panelAlpha[i]);
|
|
18334
|
-
const edge = mask.edgeAlpha[i];
|
|
18335
|
-
if (edge > 0)
|
|
18336
|
-
blendOver(data, idx, PANEL_LINE2, edge);
|
|
18337
|
-
}
|
|
18338
|
-
for (let i = 0;i < mask.dividerIndices.length; i += 1) {
|
|
18339
|
-
blendOver(data, mask.dividerIndices[i], PANEL_LINE2, 0.28);
|
|
18340
|
-
}
|
|
18341
|
-
}
|
|
18342
|
-
function drawBigRigWordmark(data, width, height, layout, load) {
|
|
18343
|
-
const sideBySide = layout.width >= FLEET_GRID_WIDTH * 1.9;
|
|
18344
|
-
if (!sideBySide)
|
|
17883
|
+
function setHoveredSelectableId(id) {
|
|
17884
|
+
if (hoveredId === id)
|
|
18345
17885
|
return;
|
|
18346
|
-
|
|
18347
|
-
const
|
|
18348
|
-
|
|
18349
|
-
const glyphW = width * 0.13;
|
|
18350
|
-
const gap = glyphW * 0.3;
|
|
18351
|
-
const totalW = letters.length * glyphW + (letters.length - 1) * gap;
|
|
18352
|
-
const centerX = width * 0.71;
|
|
18353
|
-
const startX = centerX - totalW / 2;
|
|
18354
|
-
const top = (height - glyphH) / 2;
|
|
18355
|
-
const stroke = Math.max(2, min * 0.013);
|
|
18356
|
-
drawGlow2(data, width, height, centerX, top + glyphH / 2, Math.max(glyphW, glyphH) * 0.9, LIME, 0.022 + load * 0.02);
|
|
18357
|
-
const strokeAlpha = 0.1 + load * 0.06;
|
|
18358
|
-
letters.split("").forEach((letter, index) => {
|
|
18359
|
-
const segments = RIG_GLYPH_STROKES[letter];
|
|
18360
|
-
if (!segments)
|
|
18361
|
-
return;
|
|
18362
|
-
const ox = startX + index * (glyphW + gap);
|
|
18363
|
-
for (const [x0, y0, x1, y1] of segments) {
|
|
18364
|
-
drawLine2(data, width, height, ox + x0 * glyphW, top + y0 * glyphH, ox + x1 * glyphW, top + y1 * glyphH, LIME_DIM, strokeAlpha, stroke);
|
|
18365
|
-
}
|
|
18366
|
-
});
|
|
17886
|
+
hoveredId = id;
|
|
17887
|
+
for (const listener of listeners)
|
|
17888
|
+
listener();
|
|
18367
17889
|
}
|
|
18368
|
-
function
|
|
18369
|
-
|
|
18370
|
-
|
|
18371
|
-
drawBigRigWordmark(data, width, height, layout, load);
|
|
18372
|
-
applyStaticAtmosphere(data, width, height, load);
|
|
18373
|
-
}
|
|
18374
|
-
function imageVisualFrameKey(input) {
|
|
18375
|
-
const width = Math.max(1, Math.floor(input.pixelSize.width));
|
|
18376
|
-
const height = Math.max(1, Math.floor(input.pixelSize.height));
|
|
18377
|
-
const layer = "layer" in input ? input.layer ?? "full" : "full";
|
|
18378
|
-
const load = loadBucket(input.load);
|
|
18379
|
-
return `${layer}:${width}x${height}:${input.layout.width}x${input.layout.height}:${input.scene}:${input.tick}:l${load}:${input.panels.map((panel) => `${panel.id}:${panel.top}:${panel.height}:${panel.width ?? ""}:${panel.left ?? ""}:${panel.headerHeight ?? ""}`).join("|")}`;
|
|
18380
|
-
}
|
|
18381
|
-
function encodeKittyFrame(width, height, data, input) {
|
|
18382
|
-
if (input.transport === "png") {
|
|
18383
|
-
const png = encodePng(width, height, data);
|
|
18384
|
-
return kittyImageSequence(png.toString("base64"), { columns: input.layout.width, rows: input.layout.height, imageId: input.imageId, zIndex: input.zIndex, format: 100 });
|
|
18385
|
-
}
|
|
18386
|
-
const compressed = deflateSync(data, { level: ZLIB_LEVEL });
|
|
18387
|
-
return kittyImageSequence(compressed.toString("base64"), {
|
|
18388
|
-
columns: input.layout.width,
|
|
18389
|
-
rows: input.layout.height,
|
|
18390
|
-
imageId: input.imageId,
|
|
18391
|
-
zIndex: input.zIndex,
|
|
18392
|
-
format: 32,
|
|
18393
|
-
pixelWidth: width,
|
|
18394
|
-
pixelHeight: height,
|
|
18395
|
-
compressed: true
|
|
18396
|
-
});
|
|
17890
|
+
function clearHoveredSelectableId(id) {
|
|
17891
|
+
if (id !== undefined && hoveredId === id)
|
|
17892
|
+
setHoveredSelectableId(undefined);
|
|
18397
17893
|
}
|
|
18398
|
-
function
|
|
18399
|
-
|
|
18400
|
-
|
|
18401
|
-
|
|
18402
|
-
out.set(data.subarray(sourceStart, sourceStart + rect.width * 4), y * rect.width * 4);
|
|
18403
|
-
}
|
|
18404
|
-
return out;
|
|
18405
|
-
}
|
|
18406
|
-
function encodePanelPatch(data, sourceWidth, placement, imageId, zIndex) {
|
|
18407
|
-
const patch = cropRgba(data, sourceWidth, placement);
|
|
18408
|
-
const png = encodePng(placement.width, placement.height, patch);
|
|
18409
|
-
const sequence = kittyImageSequence(png.toString("base64"), {
|
|
18410
|
-
columns: Math.max(1, Math.round(placement.widthCells)),
|
|
18411
|
-
rows: Math.max(1, Math.round(placement.heightCells)),
|
|
18412
|
-
imageId,
|
|
18413
|
-
zIndex,
|
|
18414
|
-
format: 100
|
|
18415
|
-
});
|
|
18416
|
-
return `\x1B[${Math.max(1, Math.round(placement.topCells) + 1)};${Math.max(1, Math.round(placement.leftCells) + 1)}H${sequence}`;
|
|
18417
|
-
}
|
|
18418
|
-
function renderImageVisualFrame(input) {
|
|
18419
|
-
const width = Math.max(1, Math.floor(input.pixelSize.width));
|
|
18420
|
-
const height = Math.max(1, Math.floor(input.pixelSize.height));
|
|
18421
|
-
const byteCount = width * height * 4;
|
|
18422
|
-
if (byteCount > MAX_IMAGE_BYTES)
|
|
18423
|
-
return null;
|
|
18424
|
-
const layer = input.layer ?? "full";
|
|
18425
|
-
const data = new Uint8ClampedArray(byteCount);
|
|
18426
|
-
const load = loadBucket(input.load) / LOAD_BUCKETS;
|
|
18427
|
-
const activeRuns = Math.max(0, Math.floor(input.activeRuns ?? 0));
|
|
18428
|
-
drawBackground(data, width, height, 0, input.scene, input.layout, load, activeRuns);
|
|
18429
|
-
if (layer === "split") {
|
|
18430
|
-
const sequences = [encodeKittyFrame(width, height, data, input)];
|
|
18431
|
-
let panelIndex = 0;
|
|
18432
|
-
for (const panel of input.panels) {
|
|
18433
|
-
if (panel.chrome !== "ad-terminal")
|
|
18434
|
-
continue;
|
|
18435
|
-
const placement = panelPixelPlacement(input.layout, panel, { width, height });
|
|
18436
|
-
if (!placement)
|
|
18437
|
-
continue;
|
|
18438
|
-
const cellH = height / input.layout.height;
|
|
18439
|
-
const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
|
|
18440
|
-
compositePanel(data, width, height, placement, headerPx);
|
|
18441
|
-
const imageId = input.imageIds?.[panelIndex] ?? (input.imageId + 1000 + panelIndex >>> 0 || panelIndex + 1);
|
|
18442
|
-
sequences.push(encodePanelPatch(data, width, placement, imageId, -12));
|
|
18443
|
-
panelIndex += 1;
|
|
18444
|
-
}
|
|
18445
|
-
return { key: imageVisualFrameKey(input), sequence: sequences.join("") };
|
|
18446
|
-
}
|
|
18447
|
-
if (layer === "panel-chrome")
|
|
18448
|
-
return { key: imageVisualFrameKey(input), sequence: "" };
|
|
18449
|
-
if (layer === "background") {
|
|
18450
|
-
return { key: imageVisualFrameKey(input), sequence: encodeKittyFrame(width, height, data, input) };
|
|
18451
|
-
}
|
|
18452
|
-
if (layer === "panel-patches") {
|
|
18453
|
-
const sequences = [];
|
|
18454
|
-
let panelIndex = 0;
|
|
18455
|
-
for (const panel of input.panels) {
|
|
18456
|
-
if (panel.chrome !== "ad-terminal")
|
|
18457
|
-
continue;
|
|
18458
|
-
const placement = panelPixelPlacement(input.layout, panel, { width, height });
|
|
18459
|
-
if (!placement)
|
|
18460
|
-
continue;
|
|
18461
|
-
const cellH = height / input.layout.height;
|
|
18462
|
-
const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
|
|
18463
|
-
compositePanel(data, width, height, placement, headerPx);
|
|
18464
|
-
const imageId = input.imageIds?.[panelIndex] ?? (input.imageId + 1000 + panelIndex >>> 0 || panelIndex + 1);
|
|
18465
|
-
sequences.push(encodePanelPatch(data, width, placement, imageId, input.zIndex));
|
|
18466
|
-
panelIndex += 1;
|
|
18467
|
-
}
|
|
18468
|
-
return { key: imageVisualFrameKey(input), sequence: sequences.join("") };
|
|
18469
|
-
}
|
|
18470
|
-
for (const panel of input.panels) {
|
|
18471
|
-
if (panel.chrome !== "ad-terminal")
|
|
18472
|
-
continue;
|
|
18473
|
-
const rect = panelRect(input.layout, panel, { width, height });
|
|
18474
|
-
if (!rect)
|
|
18475
|
-
continue;
|
|
18476
|
-
const cellH = height / input.layout.height;
|
|
18477
|
-
const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
|
|
18478
|
-
compositePanel(data, width, height, rect, headerPx);
|
|
18479
|
-
}
|
|
18480
|
-
return { key: imageVisualFrameKey(input), sequence: encodeKittyFrame(width, height, data, input) };
|
|
18481
|
-
}
|
|
18482
|
-
function shouldRenderImagesInline() {
|
|
18483
|
-
return process.env.RIG_OPENTUI_IMAGE_WORKER === "0" || import.meta.url.includes("$bunfs");
|
|
18484
|
-
}
|
|
18485
|
-
function createImageWorker() {
|
|
18486
|
-
if (shouldRenderImagesInline())
|
|
18487
|
-
return null;
|
|
18488
|
-
const isTypeScriptRuntime = import.meta.url.endsWith(".ts");
|
|
18489
|
-
const workerUrl = new URL(isTypeScriptRuntime ? "./image-visual-layer-worker.ts" : "./image-visual-layer-worker.js", import.meta.url);
|
|
18490
|
-
try {
|
|
18491
|
-
return new Worker(workerUrl);
|
|
18492
|
-
} catch {
|
|
18493
|
-
if (typeof process.versions.bun === "string") {
|
|
18494
|
-
try {
|
|
18495
|
-
return new Worker("./src/app-opentui/render/image-visual-layer-worker.ts");
|
|
18496
|
-
} catch {}
|
|
18497
|
-
}
|
|
18498
|
-
return null;
|
|
18499
|
-
}
|
|
18500
|
-
}
|
|
18501
|
-
function imageOutputBacklogBytes() {
|
|
18502
|
-
const raw = Number.parseInt(process.env.RIG_OPENTUI_IMAGE_BACKLOG_BYTES ?? "", 10);
|
|
18503
|
-
if (Number.isFinite(raw) && raw > 0)
|
|
18504
|
-
return Math.max(64 * 1024, Math.min(2 * 1024 * 1024, raw));
|
|
18505
|
-
return DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES;
|
|
18506
|
-
}
|
|
18507
|
-
function imageOutputBytesPerSecond() {
|
|
18508
|
-
const raw = Number.parseInt(process.env.RIG_OPENTUI_IMAGE_BYTES_PER_SECOND ?? "", 10);
|
|
18509
|
-
if (Number.isFinite(raw) && raw > 0)
|
|
18510
|
-
return Math.max(128 * 1024, Math.min(2 * 1024 * 1024, raw));
|
|
18511
|
-
return DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND;
|
|
18512
|
-
}
|
|
18513
|
-
function pendingLayerKey(key) {
|
|
18514
|
-
return key.split(":", 1)[0] || "full";
|
|
18515
|
-
}
|
|
18516
|
-
|
|
18517
|
-
class ImageVisualLayer {
|
|
18518
|
-
imageId = allocateImageId();
|
|
18519
|
-
panelImageIds = Array.from({ length: 8 }, () => allocateImageId());
|
|
18520
|
-
panelChromeImageIds = Array.from({ length: 8 }, () => allocateImageId());
|
|
18521
|
-
stdout;
|
|
18522
|
-
onFrameReady;
|
|
18523
|
-
protocol;
|
|
18524
|
-
transport = imageTransport();
|
|
18525
|
-
maxOutputBacklogBytes = imageOutputBacklogBytes();
|
|
18526
|
-
outputBytesPerSecond = imageOutputBytesPerSecond();
|
|
18527
|
-
outputBudgetBytes = imageOutputBytesPerSecond();
|
|
18528
|
-
lastBudgetAtMs = Date.now();
|
|
18529
|
-
motionSlot = this.createSlot();
|
|
18530
|
-
workersStarted = false;
|
|
18531
|
-
pendingFrames = new Map;
|
|
18532
|
-
recentWrittenKeys = [];
|
|
18533
|
-
imagesVisible = false;
|
|
18534
|
-
flushPaused = false;
|
|
18535
|
-
requestId = 0;
|
|
18536
|
-
lastBackgroundKey = "";
|
|
18537
|
-
fatalWorkerError = null;
|
|
18538
|
-
destroyed = false;
|
|
18539
|
-
constructor(stdout = process.stdout, onFrameReady) {
|
|
18540
|
-
this.stdout = stdout;
|
|
18541
|
-
this.onFrameReady = onFrameReady;
|
|
18542
|
-
this.protocol = getRigTerminalCapabilities().imageProtocol;
|
|
18543
|
-
}
|
|
18544
|
-
get enabled() {
|
|
18545
|
-
return this.protocol === "kitty";
|
|
18546
|
-
}
|
|
18547
|
-
clear() {
|
|
18548
|
-
if (this.enabled) {
|
|
18549
|
-
if (this.imagesVisible)
|
|
18550
|
-
this.stdout.write([this.imageId, ...this.panelImageIds, ...this.panelChromeImageIds].map((id) => deleteKittyImage(id)).join("") + "\x1B[?25h");
|
|
18551
|
-
this.imagesVisible = false;
|
|
18552
|
-
this.pendingFrames.clear();
|
|
18553
|
-
this.recentWrittenKeys.length = 0;
|
|
18554
|
-
this.resetSlot(this.motionSlot);
|
|
18555
|
-
this.lastBackgroundKey = "";
|
|
18556
|
-
this.outputBudgetBytes = this.outputBytesPerSecond;
|
|
18557
|
-
this.lastBudgetAtMs = Date.now();
|
|
18558
|
-
this.motionSlot.clearedThroughRequestId = this.requestId;
|
|
18559
|
-
}
|
|
18560
|
-
}
|
|
18561
|
-
destroy() {
|
|
18562
|
-
if (this.destroyed)
|
|
18563
|
-
return;
|
|
18564
|
-
this.clear();
|
|
18565
|
-
this.destroyed = true;
|
|
18566
|
-
const workers = [this.motionSlot.worker];
|
|
18567
|
-
this.motionSlot.worker = null;
|
|
18568
|
-
for (const worker of workers)
|
|
18569
|
-
if (worker)
|
|
18570
|
-
worker.terminate().catch(() => {
|
|
18571
|
-
return;
|
|
18572
|
-
});
|
|
18573
|
-
}
|
|
18574
|
-
setFlushPaused(paused) {
|
|
18575
|
-
this.flushPaused = paused;
|
|
18576
|
-
}
|
|
18577
|
-
isReady(input) {
|
|
18578
|
-
if (!this.enabled || this.destroyed)
|
|
18579
|
-
return true;
|
|
18580
|
-
this.throwIfFatal();
|
|
18581
|
-
const splitKey = imageVisualFrameKey({ ...input, tick: 0, layer: "split" });
|
|
18582
|
-
return this.recentWrittenKeys.includes(splitKey) || Array.from(this.pendingFrames.values()).some((frame) => frame.key === splitKey);
|
|
18583
|
-
}
|
|
18584
|
-
render(input) {
|
|
18585
|
-
if (!this.enabled || this.destroyed)
|
|
18586
|
-
return;
|
|
18587
|
-
this.throwIfFatal();
|
|
18588
|
-
if (this.transport !== "png")
|
|
18589
|
-
this.failWorker("renderer", new Error("OpenTUI image visuals require PNG transport for static-background rendering."));
|
|
18590
|
-
this.ensureWorkersStarted();
|
|
18591
|
-
const width = Math.max(1, Math.floor(input.pixelSize.width));
|
|
18592
|
-
const height = Math.max(1, Math.floor(input.pixelSize.height));
|
|
18593
|
-
if (width * height * 4 > MAX_IMAGE_BYTES)
|
|
18594
|
-
return;
|
|
18595
|
-
if (this.isOutputBackedUp())
|
|
18596
|
-
return;
|
|
18597
|
-
this.refillOutputBudget();
|
|
18598
|
-
const splitInput = { ...input, tick: 0, layer: "split" };
|
|
18599
|
-
const splitKey = imageVisualFrameKey(splitInput);
|
|
18600
|
-
if (input.force || splitKey !== this.lastBackgroundKey) {
|
|
18601
|
-
this.scheduleRender(this.motionSlot, splitInput, this.imageId, -30, input.force, this.panelImageIds);
|
|
18602
|
-
this.lastBackgroundKey = splitKey;
|
|
18603
|
-
}
|
|
18604
|
-
}
|
|
18605
|
-
flush() {
|
|
18606
|
-
this.throwIfFatal();
|
|
18607
|
-
if (this.flushPaused)
|
|
18608
|
-
return false;
|
|
18609
|
-
if (this.pendingFrames.size === 0)
|
|
18610
|
-
return false;
|
|
18611
|
-
this.refillOutputBudget();
|
|
18612
|
-
if (this.isOutputBackedUp()) {
|
|
18613
|
-
const retainedSplit = this.pendingFrames.get("split");
|
|
18614
|
-
this.pendingFrames.clear();
|
|
18615
|
-
if (retainedSplit)
|
|
18616
|
-
this.pendingFrames.set("split", retainedSplit);
|
|
18617
|
-
return false;
|
|
18618
|
-
}
|
|
18619
|
-
const framePriority = (frame) => {
|
|
18620
|
-
const layer = pendingLayerKey(frame.key);
|
|
18621
|
-
if (layer === "split")
|
|
18622
|
-
return 1;
|
|
18623
|
-
return 4;
|
|
18624
|
-
};
|
|
18625
|
-
const frames = Array.from(this.pendingFrames.values()).sort((a, b) => framePriority(a) - framePriority(b));
|
|
18626
|
-
const prefix = "\x1B[?25l\x1B7\x1B[s\x1B[H";
|
|
18627
|
-
const suffix = "\x1B[u\x1B8";
|
|
18628
|
-
const selected = [];
|
|
18629
|
-
const retained = new Map;
|
|
18630
|
-
let sequence = "";
|
|
18631
|
-
let byteLength = Buffer.byteLength(prefix + suffix);
|
|
18632
|
-
for (const frame of frames) {
|
|
18633
|
-
const candidate = sequence + frame.sequence;
|
|
18634
|
-
const candidateBytes = Buffer.byteLength(prefix + candidate + suffix);
|
|
18635
|
-
const layer = pendingLayerKey(frame.key);
|
|
18636
|
-
const allowOneStaticFrame = selected.length === 0 && layer === "split";
|
|
18637
|
-
if (candidateBytes <= this.outputBudgetBytes || allowOneStaticFrame) {
|
|
18638
|
-
selected.push(frame);
|
|
18639
|
-
sequence = candidate;
|
|
18640
|
-
byteLength = candidateBytes;
|
|
18641
|
-
} else if (layer === "split") {
|
|
18642
|
-
retained.set(layer, frame);
|
|
18643
|
-
}
|
|
18644
|
-
}
|
|
18645
|
-
this.pendingFrames.clear();
|
|
18646
|
-
for (const [layer, frame] of retained)
|
|
18647
|
-
this.pendingFrames.set(layer, frame);
|
|
18648
|
-
if (!sequence || selected.length === 0)
|
|
18649
|
-
return false;
|
|
18650
|
-
const payload = `${prefix}${sequence}${suffix}`;
|
|
18651
|
-
for (const frame of selected)
|
|
18652
|
-
this.markWritten(frame.key);
|
|
18653
|
-
this.outputBudgetBytes -= byteLength;
|
|
18654
|
-
this.stdout.cork?.();
|
|
18655
|
-
const accepted = this.stdout.write(payload);
|
|
18656
|
-
this.stdout.uncork?.();
|
|
18657
|
-
this.imagesVisible = true;
|
|
18658
|
-
return accepted;
|
|
18659
|
-
}
|
|
18660
|
-
createSlot() {
|
|
18661
|
-
return { worker: null, busy: false, queuedRequest: null, inFlightKey: "", queuedKey: "", clearedThroughRequestId: 0, latestRequestId: 0 };
|
|
18662
|
-
}
|
|
18663
|
-
resetSlot(slot) {
|
|
18664
|
-
slot.busy = false;
|
|
18665
|
-
slot.queuedRequest = null;
|
|
18666
|
-
slot.inFlightKey = "";
|
|
18667
|
-
slot.queuedKey = "";
|
|
18668
|
-
}
|
|
18669
|
-
markWritten(key) {
|
|
18670
|
-
this.recentWrittenKeys.push(key);
|
|
18671
|
-
while (this.recentWrittenKeys.length > RECENT_WRITTEN_LIMIT)
|
|
18672
|
-
this.recentWrittenKeys.shift();
|
|
18673
|
-
}
|
|
18674
|
-
refillOutputBudget() {
|
|
18675
|
-
const now = Date.now();
|
|
18676
|
-
const elapsedMs = Math.max(0, now - this.lastBudgetAtMs);
|
|
18677
|
-
this.lastBudgetAtMs = now;
|
|
18678
|
-
this.outputBudgetBytes = Math.min(this.outputBytesPerSecond, this.outputBudgetBytes + elapsedMs / 1000 * this.outputBytesPerSecond);
|
|
18679
|
-
}
|
|
18680
|
-
isOutputBackedUp() {
|
|
18681
|
-
return Boolean(this.stdout.writableNeedDrain) || this.stdout.writableLength > this.maxOutputBacklogBytes;
|
|
18682
|
-
}
|
|
18683
|
-
stageFrame(frame) {
|
|
18684
|
-
this.pendingFrames.set(pendingLayerKey(frame.key), frame);
|
|
18685
|
-
}
|
|
18686
|
-
isKnownKey(slot, key) {
|
|
18687
|
-
return this.recentWrittenKeys.includes(key) || Array.from(this.pendingFrames.values()).some((frame) => frame.key === key) || key === slot.inFlightKey || key === slot.queuedKey;
|
|
18688
|
-
}
|
|
18689
|
-
ensureWorkersStarted() {
|
|
18690
|
-
if (this.workersStarted)
|
|
18691
|
-
return;
|
|
18692
|
-
this.workersStarted = true;
|
|
18693
|
-
this.startWorker(this.motionSlot, "static-visuals");
|
|
18694
|
-
}
|
|
18695
|
-
failWorker(name, error) {
|
|
18696
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
18697
|
-
this.fatalWorkerError ??= new Error(`OpenTUI image worker ${name} failed: ${detail}`);
|
|
18698
|
-
throw this.fatalWorkerError;
|
|
18699
|
-
}
|
|
18700
|
-
throwIfFatal() {
|
|
18701
|
-
if (this.fatalWorkerError)
|
|
18702
|
-
throw this.fatalWorkerError;
|
|
18703
|
-
}
|
|
18704
|
-
scheduleRender(slot, input, imageId, zIndex, force, imageIds) {
|
|
18705
|
-
this.throwIfFatal();
|
|
18706
|
-
const key = imageVisualFrameKey(input);
|
|
18707
|
-
if (!force && this.isKnownKey(slot, key))
|
|
18708
|
-
return;
|
|
18709
|
-
const request = {
|
|
18710
|
-
...input,
|
|
18711
|
-
imageId,
|
|
18712
|
-
...imageIds ? { imageIds } : {},
|
|
18713
|
-
zIndex,
|
|
18714
|
-
transport: this.transport,
|
|
18715
|
-
requestId: ++this.requestId,
|
|
18716
|
-
key
|
|
18717
|
-
};
|
|
18718
|
-
slot.latestRequestId = request.requestId;
|
|
18719
|
-
if (!slot.worker) {
|
|
18720
|
-
this.renderInline(slot, request);
|
|
18721
|
-
return;
|
|
18722
|
-
}
|
|
18723
|
-
this.enqueueWorkerRender(slot, request);
|
|
18724
|
-
}
|
|
18725
|
-
startWorker(slot, name) {
|
|
18726
|
-
const worker = createImageWorker();
|
|
18727
|
-
if (!worker)
|
|
18728
|
-
return;
|
|
18729
|
-
slot.worker = worker;
|
|
18730
|
-
worker.on("message", (message2) => this.handleWorkerMessage(slot, message2));
|
|
18731
|
-
worker.once("error", (error) => {
|
|
18732
|
-
if (!this.destroyed)
|
|
18733
|
-
this.fatalWorkerError ??= new Error(`OpenTUI image worker ${name} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
18734
|
-
});
|
|
18735
|
-
worker.once("exit", (code) => {
|
|
18736
|
-
if (!this.destroyed)
|
|
18737
|
-
this.fatalWorkerError ??= new Error(`OpenTUI image worker ${name} exited unexpectedly with code ${code}.`);
|
|
18738
|
-
});
|
|
18739
|
-
}
|
|
18740
|
-
renderInline(slot, request) {
|
|
18741
|
-
try {
|
|
18742
|
-
const result = renderImageVisualFrame(request);
|
|
18743
|
-
if (result?.sequence && !this.isKnownKey(slot, result.key) && (!this.isOutputBackedUp() || pendingLayerKey(result.key) === "split")) {
|
|
18744
|
-
this.stageFrame({ key: result.key, sequence: result.sequence });
|
|
18745
|
-
this.onFrameReady?.();
|
|
18746
|
-
}
|
|
18747
|
-
} catch (error) {
|
|
18748
|
-
this.failWorker(String(request.layer ?? "visual"), error);
|
|
18749
|
-
}
|
|
18750
|
-
}
|
|
18751
|
-
enqueueWorkerRender(slot, request) {
|
|
18752
|
-
this.throwIfFatal();
|
|
18753
|
-
if (slot.busy) {
|
|
18754
|
-
slot.queuedRequest = request;
|
|
18755
|
-
slot.queuedKey = request.key;
|
|
18756
|
-
return;
|
|
18757
|
-
}
|
|
18758
|
-
this.dispatchWorkerRender(slot, request);
|
|
18759
|
-
}
|
|
18760
|
-
dispatchWorkerRender(slot, request) {
|
|
18761
|
-
this.throwIfFatal();
|
|
18762
|
-
if (!slot.worker)
|
|
18763
|
-
this.failWorker(String(request.layer ?? "visual"), new Error("worker is unavailable"));
|
|
18764
|
-
slot.busy = true;
|
|
18765
|
-
slot.inFlightKey = request.key;
|
|
18766
|
-
try {
|
|
18767
|
-
slot.worker.postMessage(request);
|
|
18768
|
-
} catch (error) {
|
|
18769
|
-
this.failWorker(String(request.layer ?? "visual"), error);
|
|
18770
|
-
}
|
|
18771
|
-
}
|
|
18772
|
-
handleWorkerMessage(slot, message2) {
|
|
18773
|
-
if (this.destroyed || !message2 || typeof message2 !== "object")
|
|
18774
|
-
return;
|
|
18775
|
-
const response = message2;
|
|
18776
|
-
slot.busy = false;
|
|
18777
|
-
slot.inFlightKey = "";
|
|
18778
|
-
const isStale = response.requestId <= slot.clearedThroughRequestId || response.requestId < slot.latestRequestId;
|
|
18779
|
-
if (!isStale) {
|
|
18780
|
-
if (response.error)
|
|
18781
|
-
this.failWorker(pendingLayerKey(response.key), new Error(response.error));
|
|
18782
|
-
if (response.sequence && !this.isKnownKey(slot, response.key) && (!this.isOutputBackedUp() || pendingLayerKey(response.key) === "split")) {
|
|
18783
|
-
this.stageFrame({ key: response.key, sequence: response.sequence });
|
|
18784
|
-
this.onFrameReady?.();
|
|
18785
|
-
}
|
|
18786
|
-
}
|
|
18787
|
-
const next = slot.queuedRequest;
|
|
18788
|
-
slot.queuedRequest = null;
|
|
18789
|
-
slot.queuedKey = "";
|
|
18790
|
-
if (next && !this.isKnownKey(slot, next.key))
|
|
18791
|
-
this.dispatchWorkerRender(slot, next);
|
|
18792
|
-
}
|
|
18793
|
-
}
|
|
18794
|
-
function pixelSizeForRenderer(renderer) {
|
|
18795
|
-
const resolution = renderer.resolution;
|
|
18796
|
-
const base = resolution?.width && resolution?.height ? resolution : { width: renderer.width * 12, height: renderer.height * 24 };
|
|
18797
|
-
const scale = imageResolutionScale();
|
|
18798
|
-
return {
|
|
18799
|
-
width: Math.max(renderer.width, Math.floor(base.width * scale)),
|
|
18800
|
-
height: Math.max(renderer.height, Math.floor(base.height * scale))
|
|
17894
|
+
function subscribeHover(listener) {
|
|
17895
|
+
listeners.add(listener);
|
|
17896
|
+
return () => {
|
|
17897
|
+
listeners.delete(listener);
|
|
18801
17898
|
};
|
|
18802
17899
|
}
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
var PANEL_MASK_RADIUS_MIN = 14, PANEL_MASK_RADIUS_MAX = 34, PANEL_MASK_RADIUS_FACTOR = 0.035, PANEL_BLUR_RADIUS_MIN = 8, PANEL_BLUR_RADIUS_MAX = 28, PANEL_BLUR_RADIUS_FACTOR = 0.018, BG, PANEL, PANEL_HEADER, PANEL_LINE2, LIME, LIME_DIM, CYAN, MAGENTA, INK_DIM, PNG_SIGNATURE, CRC_TABLE, MAX_IMAGE_BYTES, KITTY_CHUNK_SIZE = 4096, PANEL_BLUR_SCALE = 1, PANEL_MASK_CACHE_LIMIT = 16, ZLIB_LEVEL = 1, DEFAULT_IMAGE_RESOLUTION_SCALE = 1, LOAD_BUCKETS = 5, panelMaskCache, BG_WORD, ASCII_GLYPHS, RIG_GLYPH_STROKES, RECENT_WRITTEN_LIMIT = 24, DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES, DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND;
|
|
18807
|
-
var init_image_visual_layer = __esm(() => {
|
|
18808
|
-
init_terminal_capabilities();
|
|
18809
|
-
init_ascii_fleet();
|
|
18810
|
-
init_constants();
|
|
18811
|
-
BG = [7, 8, 9, 255];
|
|
18812
|
-
PANEL = [16, 17, 21, 184];
|
|
18813
|
-
PANEL_HEADER = [16, 17, 21, 190];
|
|
18814
|
-
PANEL_LINE2 = [255, 255, 255, 24];
|
|
18815
|
-
LIME = [204, 255, 77, 255];
|
|
18816
|
-
LIME_DIM = [169, 214, 63, 255];
|
|
18817
|
-
CYAN = [86, 216, 255, 255];
|
|
18818
|
-
MAGENTA = [255, 121, 176, 255];
|
|
18819
|
-
INK_DIM = [108, 110, 121, 255];
|
|
18820
|
-
PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
18821
|
-
CRC_TABLE = makeCrcTable();
|
|
18822
|
-
MAX_IMAGE_BYTES = 48 * 1024 * 1024;
|
|
18823
|
-
panelMaskCache = new Map;
|
|
18824
|
-
BG_WORD = rgbaWord(BG);
|
|
18825
|
-
ASCII_GLYPHS = {
|
|
18826
|
-
".": ["00000", "00000", "00000", "00000", "00000", "00100", "00100"],
|
|
18827
|
-
"'": ["00100", "00100", "00000", "00000", "00000", "00000", "00000"],
|
|
18828
|
-
"-": ["00000", "00000", "00000", "11111", "00000", "00000", "00000"],
|
|
18829
|
-
_: ["00000", "00000", "00000", "00000", "00000", "00000", "11111"],
|
|
18830
|
-
"=": ["00000", "11111", "00000", "00000", "11111", "00000", "00000"],
|
|
18831
|
-
"|": ["00100", "00100", "00100", "00100", "00100", "00100", "00100"],
|
|
18832
|
-
"/": ["00001", "00010", "00010", "00100", "01000", "01000", "10000"],
|
|
18833
|
-
"\\": ["10000", "01000", "01000", "00100", "00010", "00010", "00001"],
|
|
18834
|
-
"(": ["00010", "00100", "01000", "01000", "01000", "00100", "00010"],
|
|
18835
|
-
")": ["01000", "00100", "00010", "00010", "00010", "00100", "01000"],
|
|
18836
|
-
"!": ["00100", "00100", "00100", "00100", "00100", "00000", "00100"],
|
|
18837
|
-
"%": ["11001", "11010", "00100", "01000", "10110", "00110", "00000"],
|
|
18838
|
-
$: ["00100", "11110", "10100", "11110", "00101", "11110", "00100"],
|
|
18839
|
-
"@": ["01110", "10001", "10111", "10101", "10111", "10000", "01111"],
|
|
18840
|
-
o: ["00000", "01110", "10001", "10001", "10001", "01110", "00000"],
|
|
18841
|
-
"*": ["00100", "10101", "01110", "11111", "01110", "10101", "00100"]
|
|
18842
|
-
};
|
|
18843
|
-
RIG_GLYPH_STROKES = {
|
|
18844
|
-
R: [[0, 0, 0, 1], [0, 0, 0.82, 0], [0.82, 0, 0.82, 0.5], [0, 0.5, 0.82, 0.5], [0.36, 0.5, 0.92, 1]],
|
|
18845
|
-
I: [[0.5, 0, 0.5, 1], [0.18, 0, 0.82, 0], [0.18, 1, 0.82, 1]],
|
|
18846
|
-
G: [[0.92, 0.08, 0.12, 0], [0.12, 0, 0.12, 1], [0.12, 1, 0.92, 1], [0.92, 0.5, 0.92, 1], [0.5, 0.5, 0.92, 0.5]]
|
|
18847
|
-
};
|
|
18848
|
-
DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES = 256 * 1024;
|
|
18849
|
-
DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND = 850 * 1024;
|
|
17900
|
+
var hoveredId, listeners;
|
|
17901
|
+
var init_hover = __esm(() => {
|
|
17902
|
+
listeners = new Set;
|
|
18850
17903
|
});
|
|
18851
17904
|
|
|
18852
17905
|
// packages/cli/src/app-opentui/render/text.ts
|
|
18853
17906
|
import { RGBA as RGBA4, TextAttributes as TextAttributes4, TextRenderable } from "@opentui/core";
|
|
17907
|
+
function lineIsClickable(line2) {
|
|
17908
|
+
return line2?.selectable !== undefined || line2?.selectableIndex !== undefined;
|
|
17909
|
+
}
|
|
17910
|
+
function lineSelectableId(line2) {
|
|
17911
|
+
return line2?.selectable?.id ?? line2?.selectableId;
|
|
17912
|
+
}
|
|
17913
|
+
function lineBackground(line2) {
|
|
17914
|
+
if (line2?.bg)
|
|
17915
|
+
return RGBA4.fromHex(line2.bg);
|
|
17916
|
+
const id = lineSelectableId(line2);
|
|
17917
|
+
if (id !== undefined && isHovered(id))
|
|
17918
|
+
return HOVER_BG;
|
|
17919
|
+
return TRANSPARENT2;
|
|
17920
|
+
}
|
|
18854
17921
|
function selectableMouseHandler(currentLineRef, onLineMouseDown) {
|
|
18855
17922
|
return (event) => {
|
|
18856
17923
|
const currentLine = currentLineRef();
|
|
18857
|
-
if (currentLine
|
|
17924
|
+
if (!lineIsClickable(currentLine))
|
|
18858
17925
|
return;
|
|
18859
17926
|
onLineMouseDown?.(currentLine, event);
|
|
18860
17927
|
};
|
|
18861
17928
|
}
|
|
17929
|
+
function hoverHandlers(currentLineRef) {
|
|
17930
|
+
return {
|
|
17931
|
+
onMouseOver: () => {
|
|
17932
|
+
const id = lineSelectableId(currentLineRef());
|
|
17933
|
+
if (id !== undefined)
|
|
17934
|
+
setHoveredSelectableId(id);
|
|
17935
|
+
},
|
|
17936
|
+
onMouseOut: () => clearHoveredSelectableId(lineSelectableId(currentLineRef()))
|
|
17937
|
+
};
|
|
17938
|
+
}
|
|
18862
17939
|
function createTextLine(renderer, id, top, onLineMouseDown) {
|
|
18863
17940
|
let currentLine;
|
|
18864
17941
|
const renderable = new TextRenderable(renderer, {
|
|
@@ -18870,7 +17947,8 @@ function createTextLine(renderer, id, top, onLineMouseDown) {
|
|
|
18870
17947
|
width: 1,
|
|
18871
17948
|
fg: RIG_UI.ink2,
|
|
18872
17949
|
selectable: true,
|
|
18873
|
-
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown)
|
|
17950
|
+
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown),
|
|
17951
|
+
...hoverHandlers(() => currentLine)
|
|
18874
17952
|
});
|
|
18875
17953
|
renderable.setRigSceneLine = (line2) => {
|
|
18876
17954
|
currentLine = line2;
|
|
@@ -18887,7 +17965,8 @@ function createFlowTextLine(renderer, id, onLineMouseDown) {
|
|
|
18887
17965
|
flexShrink: 0,
|
|
18888
17966
|
fg: RIG_UI.ink2,
|
|
18889
17967
|
selectable: true,
|
|
18890
|
-
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown)
|
|
17968
|
+
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown),
|
|
17969
|
+
...hoverHandlers(() => currentLine)
|
|
18891
17970
|
});
|
|
18892
17971
|
renderable.setRigSceneLine = (line2) => {
|
|
18893
17972
|
currentLine = line2;
|
|
@@ -18901,7 +17980,7 @@ function applyTextLine(renderable, line2, top, left, width) {
|
|
|
18901
17980
|
renderable.width = width;
|
|
18902
17981
|
renderable.content = line2?.styledText ?? line2?.text ?? "";
|
|
18903
17982
|
renderable.fg = line2?.fg ?? RIG_UI.ink2;
|
|
18904
|
-
renderable.bg = line2
|
|
17983
|
+
renderable.bg = lineBackground(line2);
|
|
18905
17984
|
renderable.attributes = line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
|
|
18906
17985
|
}
|
|
18907
17986
|
function applyFlowTextLine(renderable, line2, width) {
|
|
@@ -18911,7 +17990,7 @@ function applyFlowTextLine(renderable, line2, width) {
|
|
|
18911
17990
|
renderable.width = Math.max(1, width);
|
|
18912
17991
|
renderable.content = line2?.styledText ?? line2?.text ?? "";
|
|
18913
17992
|
renderable.fg = line2?.fg ?? RIG_UI.ink2;
|
|
18914
|
-
renderable.bg = line2
|
|
17993
|
+
renderable.bg = lineBackground(line2);
|
|
18915
17994
|
renderable.attributes = line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
|
|
18916
17995
|
}
|
|
18917
17996
|
function clearTextLines(renderables, from = 0) {
|
|
@@ -18925,10 +18004,12 @@ function clearTextLines(renderables, from = 0) {
|
|
|
18925
18004
|
renderable.bg = TRANSPARENT2;
|
|
18926
18005
|
}
|
|
18927
18006
|
}
|
|
18928
|
-
var TRANSPARENT2;
|
|
18007
|
+
var TRANSPARENT2, HOVER_BG;
|
|
18929
18008
|
var init_text = __esm(() => {
|
|
18930
18009
|
init_theme2();
|
|
18010
|
+
init_hover();
|
|
18931
18011
|
TRANSPARENT2 = RGBA4.fromInts(0, 0, 0, 0);
|
|
18012
|
+
HOVER_BG = RGBA4.fromHex(RIG_UI.hover);
|
|
18932
18013
|
});
|
|
18933
18014
|
|
|
18934
18015
|
// packages/cli/src/app-opentui/render/panels.ts
|
|
@@ -20053,7 +19134,7 @@ function __renderSceneForTest(renderer, state, sceneRenderers) {
|
|
|
20053
19134
|
renderer.root.add(navText);
|
|
20054
19135
|
const registry = buildSceneRendererRegistry(sceneRenderers);
|
|
20055
19136
|
const transition = { scene: state.scene, startedAtMs: 0, minUntilMs: 0 };
|
|
20056
|
-
const selectables = renderNow(renderer, null, null,
|
|
19137
|
+
const selectables = renderNow(renderer, null, null, scrollPanels, null, null, navText, textLines, nativeHost, state, registry, transition);
|
|
20057
19138
|
return { selectables, nativeHost };
|
|
20058
19139
|
}
|
|
20059
19140
|
async function launchRigOpenTuiApp(options) {
|
|
@@ -20065,7 +19146,6 @@ async function launchRigOpenTuiApp(options) {
|
|
|
20065
19146
|
const events = createAppEventBus();
|
|
20066
19147
|
let renderer = null;
|
|
20067
19148
|
let graphics = null;
|
|
20068
|
-
let imageVisuals = null;
|
|
20069
19149
|
let preloaderBackdrop = null;
|
|
20070
19150
|
const scrollPanels = [];
|
|
20071
19151
|
let typeBar = null;
|
|
@@ -20093,7 +19173,7 @@ async function launchRigOpenTuiApp(options) {
|
|
|
20093
19173
|
if (!renderer || destroyed)
|
|
20094
19174
|
return;
|
|
20095
19175
|
const currentState = store.getState();
|
|
20096
|
-
renderedSelectableItems = renderNow(renderer, graphics,
|
|
19176
|
+
renderedSelectableItems = renderNow(renderer, graphics, preloaderBackdrop, scrollPanels, typeBar, brandText, navText, textLines, nativeHost, currentState, sceneRendererRegistry, preloaderTransition, scheduleAppRender);
|
|
20097
19177
|
focusManager.restoreTypeBarFocus(typeBar, { hidden: currentState.scene === "handoff" });
|
|
20098
19178
|
maybeRedirectFromUnresolvedScene(currentState);
|
|
20099
19179
|
};
|
|
@@ -20253,18 +19333,8 @@ async function launchRigOpenTuiApp(options) {
|
|
|
20253
19333
|
});
|
|
20254
19334
|
renderer.setTerminalTitle?.("Operator cockpit");
|
|
20255
19335
|
const layout = computeStageLayout(renderer.width, renderer.height);
|
|
20256
|
-
|
|
20257
|
-
|
|
20258
|
-
const flushImageVisuals = async () => {
|
|
20259
|
-
imageVisuals?.flush();
|
|
20260
|
-
};
|
|
20261
|
-
renderer.setFrameCallback(flushImageVisuals);
|
|
20262
|
-
resources.add(() => renderer?.removeFrameCallback(flushImageVisuals));
|
|
20263
|
-
}
|
|
20264
|
-
if (!imageVisuals?.enabled) {
|
|
20265
|
-
graphics = createGraphicsLayer(renderer, layout);
|
|
20266
|
-
renderer.root.add(graphics);
|
|
20267
|
-
}
|
|
19336
|
+
graphics = createGraphicsLayer(renderer, layout);
|
|
19337
|
+
renderer.root.add(graphics);
|
|
20268
19338
|
preloaderBackdrop = new BoxRenderable3(renderer, {
|
|
20269
19339
|
id: "rig-preloader-backdrop",
|
|
20270
19340
|
position: "absolute",
|
|
@@ -20287,8 +19357,7 @@ async function launchRigOpenTuiApp(options) {
|
|
|
20287
19357
|
} else if (!selectById(store, id, renderedSelectableItems)) {
|
|
20288
19358
|
return;
|
|
20289
19359
|
}
|
|
20290
|
-
|
|
20291
|
-
runAppAction("Activate selection", () => activateSelection(runtime, renderedSelectableItems));
|
|
19360
|
+
runAppAction("Activate selection", () => activateSelection(runtime, renderedSelectableItems));
|
|
20292
19361
|
};
|
|
20293
19362
|
for (let index = 0;index < MAX_SCENE_PANELS; index += 1) {
|
|
20294
19363
|
const panel = createScrollPanelLayer(renderer, `rig-scroll-panel-${index}`, onLineClick);
|
|
@@ -20355,6 +19424,7 @@ async function launchRigOpenTuiApp(options) {
|
|
|
20355
19424
|
};
|
|
20356
19425
|
renderer.keyInput.on("keypress", onKeyPress);
|
|
20357
19426
|
resources.add(() => renderer?.keyInput.off("keypress", onKeyPress));
|
|
19427
|
+
resources.add(subscribeHover(() => scheduleAppRender(0)));
|
|
20358
19428
|
const onPaste = (event) => {
|
|
20359
19429
|
const state = store.getState();
|
|
20360
19430
|
if (state.scene === "handoff") {
|
|
@@ -20390,7 +19460,6 @@ async function launchRigOpenTuiApp(options) {
|
|
|
20390
19460
|
stopActivePiHost("renderer destroyed");
|
|
20391
19461
|
stopActiveCommandHost("renderer destroyed");
|
|
20392
19462
|
destroyNativeHost(nativeHost);
|
|
20393
|
-
imageVisuals?.destroy();
|
|
20394
19463
|
if (renderTimer)
|
|
20395
19464
|
clearTimeout(renderTimer);
|
|
20396
19465
|
renderTimer = null;
|
|
@@ -20439,14 +19508,13 @@ async function launchRigOpenTuiApp(options) {
|
|
|
20439
19508
|
clearTimeout(renderTimer);
|
|
20440
19509
|
renderTimer = null;
|
|
20441
19510
|
resources.disposeAll();
|
|
20442
|
-
imageVisuals?.destroy();
|
|
20443
19511
|
stopActivePiHost("app shutdown");
|
|
20444
19512
|
stopActiveCommandHost("app shutdown");
|
|
20445
19513
|
if (renderer && !renderer.isDestroyed)
|
|
20446
19514
|
renderer.destroy();
|
|
20447
19515
|
}
|
|
20448
19516
|
}
|
|
20449
|
-
function renderNow(renderer, graphics,
|
|
19517
|
+
function renderNow(renderer, graphics, preloaderBackdrop, scrollPanels, typeBar, brandText, navText, textLines, nativeHost, state, sceneRendererRegistry, preloaderTransition, scheduleRenderAfter) {
|
|
20450
19518
|
const layout = computeStageLayout(renderer.width, renderer.height);
|
|
20451
19519
|
const hideNav = () => {
|
|
20452
19520
|
if (navText)
|
|
@@ -20455,7 +19523,6 @@ function renderNow(renderer, graphics, imageVisuals, preloaderBackdrop, scrollPa
|
|
|
20455
19523
|
if (layout.tooSmall) {
|
|
20456
19524
|
if (graphics)
|
|
20457
19525
|
clearGraphicsLayer(graphics);
|
|
20458
|
-
imageVisuals?.clear();
|
|
20459
19526
|
if (preloaderBackdrop)
|
|
20460
19527
|
preloaderBackdrop.visible = false;
|
|
20461
19528
|
if (brandText)
|
|
@@ -20489,8 +19556,7 @@ function renderNow(renderer, graphics, imageVisuals, preloaderBackdrop, scrollPa
|
|
|
20489
19556
|
preloaderTransition.minUntilMs = now;
|
|
20490
19557
|
const targetFrame = renderState.typeBar.mode === "command" ? commandPaletteFrame(renderState, layout) : rendererForScene(renderState.scene, sceneRendererRegistry)(renderState, layout);
|
|
20491
19558
|
const targetContentLayout = targetFrame.fullScreen ? { ...layout, centerWidth: layout.width, centerLeft: 0, centerTop: 0, centerHeight: Math.min(layout.height, MAX_SCENE_LINES) } : layout;
|
|
20492
|
-
const
|
|
20493
|
-
let targetVisualReady = true;
|
|
19559
|
+
const targetVisualReady = true;
|
|
20494
19560
|
const fleetStats = fleetStatsFromState(state);
|
|
20495
19561
|
const fleetLoad = fleetStats.load;
|
|
20496
19562
|
const fleetActive = fleetStats.active;
|
|
@@ -20500,23 +19566,7 @@ function renderNow(renderer, graphics, imageVisuals, preloaderBackdrop, scrollPa
|
|
|
20500
19566
|
if (renderState.scene === "command") {
|
|
20501
19567
|
getActiveCommandHost()?.resize(Math.max(40, targetContentLayout.centerWidth - 12), Math.max(10, targetContentLayout.centerHeight - 6));
|
|
20502
19568
|
}
|
|
20503
|
-
if (imageVisuals && targetFrame.terminalActive) {
|
|
20504
|
-
imageVisuals.clear();
|
|
20505
|
-
} else if (imageVisuals && !targetFrame.fullScreen && !sceneJustChanged) {
|
|
20506
|
-
const visualInput = {
|
|
20507
|
-
layout: targetContentLayout,
|
|
20508
|
-
pixelSize: pixelSizeForRenderer(renderer),
|
|
20509
|
-
panels: targetPanelsForImages,
|
|
20510
|
-
scene: state.scene,
|
|
20511
|
-
tick: state.tick,
|
|
20512
|
-
load: fleetLoad,
|
|
20513
|
-
activeRuns: fleetActive
|
|
20514
|
-
};
|
|
20515
|
-
imageVisuals.render(visualInput);
|
|
20516
|
-
targetVisualReady = imageVisuals.isReady(visualInput);
|
|
20517
|
-
}
|
|
20518
19569
|
const preloaderActive = sceneJustChanged && !cachedFastPath || isPreloaderActive(preloaderTransition, targetVisualReady, now);
|
|
20519
|
-
imageVisuals?.setFlushPaused(preloaderActive);
|
|
20520
19570
|
const frame = preloaderActive ? renderAsciiPreloaderFrame(renderState.scene, layout, state.tick) : targetFrame;
|
|
20521
19571
|
if (graphics) {
|
|
20522
19572
|
resizeGraphicsLayer(graphics, layout);
|
|
@@ -20615,8 +19665,8 @@ var init_runtime = __esm(() => {
|
|
|
20615
19665
|
init_theme2();
|
|
20616
19666
|
init_graphics();
|
|
20617
19667
|
init_fleet_stats();
|
|
20618
|
-
init_image_visual_layer();
|
|
20619
19668
|
init_text();
|
|
19669
|
+
init_hover();
|
|
20620
19670
|
init_panels();
|
|
20621
19671
|
init_type_bar();
|
|
20622
19672
|
init_scene();
|
|
@@ -20754,13 +19804,16 @@ function lineContent(line2) {
|
|
|
20754
19804
|
}
|
|
20755
19805
|
function LineView(props) {
|
|
20756
19806
|
const { line: line2, onLineClick } = props;
|
|
19807
|
+
const id = lineSelectableId(line2);
|
|
20757
19808
|
return /* @__PURE__ */ jsxDEV("text", {
|
|
20758
19809
|
style: { position: "absolute", left: props.left, top: props.top, width: props.width, zIndex: 5 },
|
|
20759
19810
|
fg: line2.fg ?? RIG_UI.ink2,
|
|
20760
|
-
bg: line2
|
|
19811
|
+
bg: lineBackground(line2),
|
|
20761
19812
|
attributes: lineAttributes(line2),
|
|
20762
19813
|
content: lineContent(line2),
|
|
20763
|
-
onMouseDown: onLineClick ? () => onLineClick(line2) : undefined
|
|
19814
|
+
onMouseDown: onLineClick ? () => onLineClick(line2) : undefined,
|
|
19815
|
+
onMouseOver: id !== undefined ? () => setHoveredSelectableId(id) : undefined,
|
|
19816
|
+
onMouseOut: id !== undefined ? () => clearHoveredSelectableId(id) : undefined
|
|
20764
19817
|
}, undefined, false, undefined, this);
|
|
20765
19818
|
}
|
|
20766
19819
|
function PanelHost(props) {
|
|
@@ -20847,6 +19900,7 @@ var init_SceneFrameView = __esm(() => {
|
|
|
20847
19900
|
init_theme2();
|
|
20848
19901
|
init_scene();
|
|
20849
19902
|
init_text();
|
|
19903
|
+
init_hover();
|
|
20850
19904
|
init_panels();
|
|
20851
19905
|
init_native_host();
|
|
20852
19906
|
init_scroll();
|
|
@@ -21000,7 +20054,7 @@ var init_nav = __esm(() => {
|
|
|
21000
20054
|
});
|
|
21001
20055
|
|
|
21002
20056
|
// packages/cli/src/app-opentui/react/App.tsx
|
|
21003
|
-
import { useMemo, useRef as useRef4 } from "react";
|
|
20057
|
+
import { useMemo, useRef as useRef4, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
21004
20058
|
import { useKeyboard, useRenderer as useRenderer4, useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
|
|
21005
20059
|
import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
|
|
21006
20060
|
function defaultFrame(state) {
|
|
@@ -21018,6 +20072,7 @@ function App(props) {
|
|
|
21018
20072
|
const runAppAction = useRunAppAction();
|
|
21019
20073
|
const store = useStore();
|
|
21020
20074
|
const renderer = useRenderer4();
|
|
20075
|
+
useSyncExternalStore2(subscribeHover, getHoveredSelectableId, getHoveredSelectableId);
|
|
21021
20076
|
const dims = useTerminalDimensions2();
|
|
21022
20077
|
const layout = computeStageLayout(dims.width, dims.height);
|
|
21023
20078
|
const registry = useMemo(() => ({ ...BUILTIN, ...props.sceneRenderers ?? {} }), [props.sceneRenderers]);
|
|
@@ -21052,8 +20107,7 @@ function App(props) {
|
|
|
21052
20107
|
} else {
|
|
21053
20108
|
return;
|
|
21054
20109
|
}
|
|
21055
|
-
|
|
21056
|
-
runAppAction("Activate selection", () => activateSelection(runtime, items));
|
|
20110
|
+
runAppAction("Activate selection", () => activateSelection(runtime, items));
|
|
21057
20111
|
};
|
|
21058
20112
|
return /* @__PURE__ */ jsxDEV3("box", {
|
|
21059
20113
|
style: { position: "absolute", left: 0, top: 0, width: "100%", height: "100%" },
|
|
@@ -21103,6 +20157,7 @@ var init_App = __esm(() => {
|
|
|
21103
20157
|
init_SceneFrameView();
|
|
21104
20158
|
init_ChromeHost();
|
|
21105
20159
|
init_scroll();
|
|
20160
|
+
init_hover();
|
|
21106
20161
|
init_context();
|
|
21107
20162
|
init_nav();
|
|
21108
20163
|
BUILTIN = {
|
|
@@ -24999,11 +24054,8 @@ init_scene();
|
|
|
24999
24054
|
init_selectable();
|
|
25000
24055
|
|
|
25001
24056
|
// packages/cli/src/app-opentui/list-search.ts
|
|
25002
|
-
function
|
|
25003
|
-
return
|
|
25004
|
-
}
|
|
25005
|
-
function listSearchQuery(state) {
|
|
25006
|
-
return isListSearchScene(state.scene) ? state.typeBar.value.trim() : "";
|
|
24057
|
+
function listSearchQuery(_state) {
|
|
24058
|
+
return "";
|
|
25007
24059
|
}
|
|
25008
24060
|
function valueText(value) {
|
|
25009
24061
|
if (value === undefined || value === null)
|