@co0ontty/wand 4.36.0 → 4.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-info.json +3 -3
- package/dist/npm-update-utils.js +1 -1
- package/dist/process-manager.d.ts +10 -2
- package/dist/process-manager.js +144 -47
- package/dist/pty-shell-launch.d.ts +36 -0
- package/dist/pty-shell-launch.js +116 -0
- package/dist/pty-terminal-state.d.ts +39 -0
- package/dist/pty-terminal-state.js +93 -0
- package/dist/server.js +14 -3
- package/dist/session-transport.js +2 -0
- package/dist/types.d.ts +4 -0
- package/dist/web-ui/content/scripts.js +85 -64
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/content/vendor/xterm/xterm.bundle.js +80 -0
- package/dist/web-ui/content/vendor/xterm/xterm.css +285 -0
- package/dist/web-ui/embedded-assets.d.ts +5 -5
- package/dist/web-ui/embedded-assets.js +9 -9
- package/dist/web-ui/index.js +4 -4
- package/dist/web-ui/provider-identity.d.ts +2 -1
- package/dist/web-ui/provider-identity.js +5 -2
- package/dist/ws-broadcast.d.ts +15 -1
- package/dist/ws-broadcast.js +109 -13
- package/package.json +9 -5
- package/dist/web-ui/content/vendor/wterm/terminal.css +0 -162
- package/dist/web-ui/content/vendor/wterm/wterm.bundle.js +0 -1
package/dist/web-ui/index.js
CHANGED
|
@@ -12,9 +12,9 @@ export function vendorAssetUrl(relPath) {
|
|
|
12
12
|
export function renderApp(configPath) {
|
|
13
13
|
const cssStyles = getCSSStyles();
|
|
14
14
|
const scriptContent = getScriptContent(configPath);
|
|
15
|
-
const
|
|
15
|
+
const xtermSrc = vendorAssetUrl("/vendor/xterm/xterm.bundle.js");
|
|
16
16
|
const qrcodeSrc = vendorAssetUrl("/vendor/qrcode/qrcode.bundle.js");
|
|
17
|
-
const
|
|
17
|
+
const xtermCssHref = vendorAssetUrl("/vendor/xterm/xterm.css");
|
|
18
18
|
return `<!doctype html>
|
|
19
19
|
<html lang="zh-CN">
|
|
20
20
|
<head>
|
|
@@ -26,7 +26,7 @@ export function renderApp(configPath) {
|
|
|
26
26
|
<meta name="theme-color" content="#1f1b17" media="(prefers-color-scheme: dark)" />
|
|
27
27
|
<meta name="format-detection" content="telephone=no" />
|
|
28
28
|
<meta name="msapplication-tap-highlight" content="no" />
|
|
29
|
-
<link rel="stylesheet" href="${
|
|
29
|
+
<link rel="stylesheet" href="${xtermCssHref}" />
|
|
30
30
|
<style>
|
|
31
31
|
${cssStyles}
|
|
32
32
|
</style>
|
|
@@ -34,7 +34,7 @@ ${cssStyles}
|
|
|
34
34
|
<body>
|
|
35
35
|
<div id="app"></div>
|
|
36
36
|
<div id="overlay-root" data-wand-ui-root></div>
|
|
37
|
-
${scriptOpen} src="${
|
|
37
|
+
${scriptOpen} src="${xtermSrc}">${scriptClose}
|
|
38
38
|
${scriptOpen} src="${qrcodeSrc}">${scriptClose}
|
|
39
39
|
${scriptOpen}>
|
|
40
40
|
${scriptContent}
|
|
@@ -10,7 +10,8 @@ export declare function inferProviderIdFromCommand(value: unknown): ProviderId |
|
|
|
10
10
|
export declare function providerDisplayName(value: unknown): string;
|
|
11
11
|
export declare const CLAUDE_LOGO_PATH = "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z";
|
|
12
12
|
export declare const CODEX_LOGO_PATH = "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z";
|
|
13
|
-
export declare const PI_LOGO_PATH = "
|
|
13
|
+
export declare const PI_LOGO_PATH = "M165.29 165.29H517.36V400H400V517.36H282.65V634.72H165.29ZM282.65 282.65V400H400V282.65Z";
|
|
14
|
+
export declare const PI_LOGO_DOT_PATH = "M517.36 400H634.72V634.72H517.36Z";
|
|
14
15
|
export declare const GROK_LOGO_PATHS: readonly ["M13.2371 21.0407L24.3186 12.8506C24.8619 12.4491 25.6384 12.6057 25.8973 13.2294C27.2597 16.5185 26.651 20.4712 23.9403 23.1851C21.2297 25.8989 17.4581 26.4941 14.0108 25.1386L10.2449 26.8843C15.6463 30.5806 22.2053 29.6665 26.304 25.5601C29.5551 22.3051 30.562 17.8683 29.6205 13.8673L29.629 13.8758C28.2637 7.99809 29.9647 5.64871 33.449.844576C33.5314.730667 33.6139.616757 33.6964.5L29.1113 5.09055V5.07631L13.2343 21.0436Z", "M10.9503 23.0313C7.07343 19.3235 7.74185 13.5853 11.0498 10.2763C13.4959 7.82722 17.5036 6.82767 21.0021 8.2971L24.7595 6.55998C24.0826 6.07017 23.215 5.54334 22.2195 5.17313C17.7198 3.31926 12.3326 4.24192 8.67479 7.90126C5.15635 11.4239 4.0499 16.8403 5.94992 21.4622C7.36924 24.9165 5.04257 27.3598 2.69884 29.826C1.86829 30.7002 1.0349 31.5745.36364 32.5L10.9474 23.0341Z"];
|
|
15
16
|
/** Framework-free counterpart used by the legacy Shell rollback path. */
|
|
16
17
|
export declare function renderProviderLogoMarkup(value: unknown): string;
|
|
@@ -64,7 +64,10 @@ export function providerDisplayName(value) {
|
|
|
64
64
|
// CC0). Grok uses xAI's mark path already shipped by the Web new-session view.
|
|
65
65
|
export const CLAUDE_LOGO_PATH = "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z";
|
|
66
66
|
export const CODEX_LOGO_PATH = "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z";
|
|
67
|
-
|
|
67
|
+
// Official Pi mark from https://pi.dev/logo-auto.svg. Keep it local so provider
|
|
68
|
+
// logos remain available when Wand is offline.
|
|
69
|
+
export const PI_LOGO_PATH = "M165.29 165.29H517.36V400H400V517.36H282.65V634.72H165.29ZM282.65 282.65V400H400V282.65Z";
|
|
70
|
+
export const PI_LOGO_DOT_PATH = "M517.36 400H634.72V634.72H517.36Z";
|
|
68
71
|
export const GROK_LOGO_PATHS = [
|
|
69
72
|
"M13.2371 21.0407L24.3186 12.8506C24.8619 12.4491 25.6384 12.6057 25.8973 13.2294C27.2597 16.5185 26.651 20.4712 23.9403 23.1851C21.2297 25.8989 17.4581 26.4941 14.0108 25.1386L10.2449 26.8843C15.6463 30.5806 22.2053 29.6665 26.304 25.5601C29.5551 22.3051 30.562 17.8683 29.6205 13.8673L29.629 13.8758C28.2637 7.99809 29.9647 5.64871 33.449.844576C33.5314.730667 33.6139.616757 33.6964.5L29.1113 5.09055V5.07631L13.2343 21.0436Z",
|
|
70
73
|
"M10.9503 23.0313C7.07343 19.3235 7.74185 13.5853 11.0498 10.2763C13.4959 7.82722 17.5036 6.82767 21.0021 8.2971L24.7595 6.55998C24.0826 6.07017 23.215 5.54334 22.2195 5.17313C17.7198 3.31926 12.3326 4.24192 8.67479 7.90126C5.15635 11.4239 4.0499 16.8403 5.94992 21.4622C7.36924 24.9165 5.04257 27.3598 2.69884 29.826C1.86829 30.7002 1.0349 31.5745.36364 32.5L10.9474 23.0341Z",
|
|
@@ -84,7 +87,7 @@ export function renderProviderLogoMarkup(value) {
|
|
|
84
87
|
return `<svg ${common} viewBox="0 0 34 33" fill="currentColor">${GROK_LOGO_PATHS.map((path) => `<path d="${path}"/>`).join("")}</svg>`;
|
|
85
88
|
}
|
|
86
89
|
if (provider === "pi") {
|
|
87
|
-
return `<svg ${common} viewBox="0 0
|
|
90
|
+
return `<svg ${common} viewBox="0 0 800 800" fill="currentColor"><path d="${PI_LOGO_PATH}" fill-rule="evenodd"/><path d="${PI_LOGO_DOT_PATH}"/></svg>`;
|
|
88
91
|
}
|
|
89
92
|
if (provider === "claude" || provider === "codex") {
|
|
90
93
|
return `<svg ${common} viewBox="0 0 24 24" fill="currentColor"><path d="${provider === "claude" ? CLAUDE_LOGO_PATH : CODEX_LOGO_PATH}"/></svg>`;
|
package/dist/ws-broadcast.d.ts
CHANGED
|
@@ -5,13 +5,24 @@
|
|
|
5
5
|
import { WebSocketServer } from "ws";
|
|
6
6
|
import type { CardExpandDefaults, SessionSnapshot, ProcessEvent } from "./types.js";
|
|
7
7
|
import { type AuthService } from "./auth.js";
|
|
8
|
+
import type { PtyTerminalSnapshot } from "./pty-terminal-state.js";
|
|
8
9
|
export type { ProcessEvent } from "./types.js";
|
|
10
|
+
export interface WsSessionPort {
|
|
11
|
+
getSession(id: string): SessionSnapshot | null;
|
|
12
|
+
getTerminalState?(id: string): PtyTerminalSnapshot | null;
|
|
13
|
+
sendPtyInput?(id: string, input: string, shortcutKey?: string, userInput?: boolean): void;
|
|
14
|
+
resizePty?(id: string, cols: number, rows: number): void;
|
|
15
|
+
pausePtyOutput?(id: string): void;
|
|
16
|
+
resumePtyOutput?(id: string): void;
|
|
17
|
+
}
|
|
9
18
|
export declare class WsBroadcastManager {
|
|
10
19
|
private wss;
|
|
11
20
|
private clients;
|
|
12
21
|
private outputDebounceCache;
|
|
13
22
|
private heartbeatTimer?;
|
|
14
23
|
private disposed;
|
|
24
|
+
private port?;
|
|
25
|
+
private readonly ptyPauseRefs;
|
|
15
26
|
private getCardDefaults;
|
|
16
27
|
private useHttps;
|
|
17
28
|
private authService?;
|
|
@@ -21,7 +32,7 @@ export declare class WsBroadcastManager {
|
|
|
21
32
|
/** Stop timers, discard deferred output, and terminate every client. */
|
|
22
33
|
dispose(): void;
|
|
23
34
|
/** Set up connection handling. Should be called once during server startup. */
|
|
24
|
-
setup(
|
|
35
|
+
setup(portOrGetSession: WsSessionPort | ((id: string) => SessionSnapshot | null)): void;
|
|
25
36
|
/**
|
|
26
37
|
* 心跳 tick:对每个 client 执行 stale 判定 + 主动 ping。
|
|
27
38
|
* - 超过 HEARTBEAT_STALE_MS 没消息 → 视为半开 / 死连接,直接 terminate()。
|
|
@@ -55,5 +66,8 @@ export declare class WsBroadcastManager {
|
|
|
55
66
|
*/
|
|
56
67
|
private resumeAndQueueResyncNotices;
|
|
57
68
|
private discardClient;
|
|
69
|
+
private acquirePtyPause;
|
|
70
|
+
private releasePtyPause;
|
|
71
|
+
private sendPtyError;
|
|
58
72
|
private processWsQueue;
|
|
59
73
|
}
|
package/dist/ws-broadcast.js
CHANGED
|
@@ -24,6 +24,9 @@ const HEARTBEAT_INTERVAL_MS = 20_000;
|
|
|
24
24
|
* 半开连接并 terminate。45s = 两个心跳周期再加 5s 容忍,可以避开偶发抖动。
|
|
25
25
|
*/
|
|
26
26
|
const HEARTBEAT_STALE_MS = 45_000;
|
|
27
|
+
const PTY_UNACKED_HIGH_WATER = 512 * 1024;
|
|
28
|
+
const PTY_UNACKED_LOW_WATER = 128 * 1024;
|
|
29
|
+
const MAX_PTY_INPUT_CHARS = 128 * 1024;
|
|
27
30
|
// ── Manager ──
|
|
28
31
|
export class WsBroadcastManager {
|
|
29
32
|
wss;
|
|
@@ -31,6 +34,8 @@ export class WsBroadcastManager {
|
|
|
31
34
|
outputDebounceCache = new Map();
|
|
32
35
|
heartbeatTimer;
|
|
33
36
|
disposed = false;
|
|
37
|
+
port;
|
|
38
|
+
ptyPauseRefs = new Map();
|
|
34
39
|
getCardDefaults;
|
|
35
40
|
useHttps;
|
|
36
41
|
authService;
|
|
@@ -62,9 +67,12 @@ export class WsBroadcastManager {
|
|
|
62
67
|
this.disconnectAll();
|
|
63
68
|
}
|
|
64
69
|
/** Set up connection handling. Should be called once during server startup. */
|
|
65
|
-
setup(
|
|
70
|
+
setup(portOrGetSession) {
|
|
66
71
|
if (this.disposed)
|
|
67
72
|
return;
|
|
73
|
+
this.port = typeof portOrGetSession === "function"
|
|
74
|
+
? { getSession: portOrGetSession }
|
|
75
|
+
: portOrGetSession;
|
|
68
76
|
this.wss.on("connection", (ws, req) => {
|
|
69
77
|
if (this.disposed) {
|
|
70
78
|
ws.close(1012, "Server shutting down");
|
|
@@ -84,10 +92,14 @@ export class WsBroadcastManager {
|
|
|
84
92
|
outputSeqBySession: new Map(),
|
|
85
93
|
pendingResyncSessions: new Set(),
|
|
86
94
|
lastSeenAt: Date.now(),
|
|
95
|
+
subscribedSessionId: null,
|
|
96
|
+
supportsPtyAck: false,
|
|
97
|
+
unackedPtyBytes: 0,
|
|
98
|
+
ptyPausedSessionId: null,
|
|
87
99
|
};
|
|
88
100
|
this.clients.add(client);
|
|
89
101
|
ws.on("close", () => {
|
|
90
|
-
this.
|
|
102
|
+
this.discardClient(client, false);
|
|
91
103
|
});
|
|
92
104
|
ws.on("error", () => {
|
|
93
105
|
// Already closed, ignore
|
|
@@ -108,7 +120,13 @@ export class WsBroadcastManager {
|
|
|
108
120
|
if (Number.isSafeInteger(msg.blockBudget) && msg.blockBudget > 0) {
|
|
109
121
|
client.blockBudget = Math.min(msg.blockBudget, MAX_BLOCK_BUDGET);
|
|
110
122
|
}
|
|
111
|
-
|
|
123
|
+
this.releasePtyPause(client);
|
|
124
|
+
client.subscribedSessionId = null;
|
|
125
|
+
client.supportsPtyAck = msg.capabilities?.ptyAck === true;
|
|
126
|
+
this.flushOutput(msg.sessionId);
|
|
127
|
+
client.subscribedSessionId = msg.sessionId;
|
|
128
|
+
client.unackedPtyBytes = 0;
|
|
129
|
+
const snapshot = this.port?.getSession(msg.sessionId) ?? null;
|
|
112
130
|
if (snapshot) {
|
|
113
131
|
this.sendInit(client, msg.sessionId, snapshot, false);
|
|
114
132
|
}
|
|
@@ -121,10 +139,41 @@ export class WsBroadcastManager {
|
|
|
121
139
|
}
|
|
122
140
|
}
|
|
123
141
|
else if (msg.type === "resync" && msg.sessionId) {
|
|
124
|
-
|
|
142
|
+
this.flushOutput(msg.sessionId);
|
|
143
|
+
const snapshot = this.port?.getSession(msg.sessionId) ?? null;
|
|
125
144
|
if (snapshot)
|
|
126
145
|
this.sendInit(client, msg.sessionId, snapshot, true);
|
|
127
146
|
}
|
|
147
|
+
else if (msg.type === "pty_input" && msg.sessionId && typeof msg.data === "string") {
|
|
148
|
+
if (client.subscribedSessionId !== msg.sessionId || msg.data.length > MAX_PTY_INPUT_CHARS)
|
|
149
|
+
return;
|
|
150
|
+
try {
|
|
151
|
+
this.port?.sendPtyInput?.(msg.sessionId, msg.data, typeof msg.shortcutKey === "string" ? msg.shortcutKey : undefined, msg.userInput !== false);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
this.sendPtyError(client, msg.sessionId, error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (msg.type === "pty_resize" && msg.sessionId) {
|
|
158
|
+
if (client.subscribedSessionId !== msg.sessionId)
|
|
159
|
+
return;
|
|
160
|
+
if (!Number.isFinite(msg.cols) || !Number.isFinite(msg.rows))
|
|
161
|
+
return;
|
|
162
|
+
try {
|
|
163
|
+
this.port?.resizePty?.(msg.sessionId, Math.floor(msg.cols), Math.floor(msg.rows));
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
this.sendPtyError(client, msg.sessionId, error);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (msg.type === "pty_ack" && msg.sessionId && Number.isFinite(msg.bytes)) {
|
|
170
|
+
if (!client.supportsPtyAck || client.subscribedSessionId !== msg.sessionId)
|
|
171
|
+
return;
|
|
172
|
+
client.unackedPtyBytes = Math.max(0, client.unackedPtyBytes - Math.max(0, Math.floor(msg.bytes)));
|
|
173
|
+
if (client.ptyPausedSessionId && client.unackedPtyBytes <= PTY_UNACKED_LOW_WATER) {
|
|
174
|
+
this.releasePtyPause(client);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
128
177
|
else if (msg.type === "pong") {
|
|
129
178
|
// 应用层 pong(对我们下发的 {type:"ping"} 的响应)。lastSeenAt
|
|
130
179
|
// 已经在函数顶部刷新过了,这里不需要再做事;分支留着是为了
|
|
@@ -161,15 +210,11 @@ export class WsBroadcastManager {
|
|
|
161
210
|
if (client.ws.readyState !== WebSocket.OPEN) {
|
|
162
211
|
// 已经不是 OPEN 了,close handler 通常会清理;这里兜底防止集合里
|
|
163
212
|
// 留下僵尸 entry。
|
|
164
|
-
this.
|
|
213
|
+
this.discardClient(client, false);
|
|
165
214
|
continue;
|
|
166
215
|
}
|
|
167
216
|
if (now - client.lastSeenAt > HEARTBEAT_STALE_MS) {
|
|
168
|
-
|
|
169
|
-
client.ws.terminate();
|
|
170
|
-
}
|
|
171
|
-
catch { /* ignore */ }
|
|
172
|
-
this.clients.delete(client);
|
|
217
|
+
this.discardClient(client, true);
|
|
173
218
|
continue;
|
|
174
219
|
}
|
|
175
220
|
try {
|
|
@@ -238,7 +283,9 @@ export class WsBroadcastManager {
|
|
|
238
283
|
this.outputDebounceCache.set(event.sessionId, { event, timer });
|
|
239
284
|
return;
|
|
240
285
|
}
|
|
241
|
-
//
|
|
286
|
+
// Preserve PTY ordering: the final debounced bytes must arrive before an
|
|
287
|
+
// ended/status event for the same session.
|
|
288
|
+
this.flushOutput(event.sessionId);
|
|
242
289
|
this.broadcast(event);
|
|
243
290
|
}
|
|
244
291
|
/** Flush any pending debounced output for a session (e.g., before session close). */
|
|
@@ -268,7 +315,10 @@ export class WsBroadcastManager {
|
|
|
268
315
|
sessionId,
|
|
269
316
|
seq,
|
|
270
317
|
...(resync ? { resync: true } : {}),
|
|
271
|
-
data:
|
|
318
|
+
data: {
|
|
319
|
+
...toSessionDetailDTO(snapshot, { output: snapshot.output, ...windowed }),
|
|
320
|
+
terminalState: this.port?.getTerminalState?.(sessionId) ?? undefined,
|
|
321
|
+
},
|
|
272
322
|
}));
|
|
273
323
|
}
|
|
274
324
|
/**
|
|
@@ -304,6 +354,10 @@ export class WsBroadcastManager {
|
|
|
304
354
|
const boundedData = boundSessionEventData(event.data);
|
|
305
355
|
const boundedEvent = boundedData === event.data ? event : { ...event, data: boundedData };
|
|
306
356
|
const data = boundedData;
|
|
357
|
+
const isRawPtyOutput = event.type === "output"
|
|
358
|
+
&& data?.incremental === true
|
|
359
|
+
&& typeof data.chunk === "string";
|
|
360
|
+
const ptyBytes = isRawPtyOutput ? Buffer.byteLength(data.chunk) : 0;
|
|
307
361
|
const hasFullMessages = !!(data && !data.incremental && Array.isArray(data.messages));
|
|
308
362
|
const rawMessages = hasFullMessages
|
|
309
363
|
? data.messages
|
|
@@ -335,6 +389,8 @@ export class WsBroadcastManager {
|
|
|
335
389
|
for (const client of this.clients) {
|
|
336
390
|
if (client.ws.readyState !== WebSocket.OPEN)
|
|
337
391
|
continue;
|
|
392
|
+
if (isRawPtyOutput && client.subscribedSessionId !== event.sessionId)
|
|
393
|
+
continue;
|
|
338
394
|
const clientEvent = eventForClient(client);
|
|
339
395
|
// Stamp output events with a per-(client, session) sequence number so
|
|
340
396
|
// the client can detect a gap caused by backpressure drops.
|
|
@@ -344,10 +400,19 @@ export class WsBroadcastManager {
|
|
|
344
400
|
client.outputSeqBySession.set(event.sessionId, seq);
|
|
345
401
|
outgoing = { ...clientEvent, seq };
|
|
346
402
|
}
|
|
403
|
+
const usesPtyAckFlowControl = isRawPtyOutput && client.supportsPtyAck;
|
|
404
|
+
if (usesPtyAckFlowControl) {
|
|
405
|
+
outgoing = { ...outgoing, ptyBytes };
|
|
406
|
+
client.unackedPtyBytes += ptyBytes;
|
|
407
|
+
if (client.unackedPtyBytes >= PTY_UNACKED_HIGH_WATER) {
|
|
408
|
+
this.acquirePtyPause(client, event.sessionId);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
347
411
|
// Backpressure only gates new business messages. The send pump must
|
|
348
412
|
// keep draining messages that were already accepted; otherwise a queue
|
|
349
413
|
// at the high-water mark can never reach the low-water mark again.
|
|
350
|
-
if (
|
|
414
|
+
if (!usesPtyAckFlowControl
|
|
415
|
+
&& (client.backpressurePaused || client.sendQueue.length >= MAX_QUEUE_SIZE)) {
|
|
351
416
|
client.backpressurePaused = true;
|
|
352
417
|
if (event.type === "output")
|
|
353
418
|
client.pendingResyncSessions.add(event.sessionId);
|
|
@@ -386,6 +451,7 @@ export class WsBroadcastManager {
|
|
|
386
451
|
}
|
|
387
452
|
}
|
|
388
453
|
discardClient(client, terminate) {
|
|
454
|
+
this.releasePtyPause(client);
|
|
389
455
|
client.sendQueue.length = 0;
|
|
390
456
|
client.pendingResyncSessions.clear();
|
|
391
457
|
client.sendInProgress = false;
|
|
@@ -398,6 +464,36 @@ export class WsBroadcastManager {
|
|
|
398
464
|
catch { /* ignore */ }
|
|
399
465
|
}
|
|
400
466
|
}
|
|
467
|
+
acquirePtyPause(client, sessionId) {
|
|
468
|
+
if (client.ptyPausedSessionId === sessionId)
|
|
469
|
+
return;
|
|
470
|
+
this.releasePtyPause(client);
|
|
471
|
+
client.ptyPausedSessionId = sessionId;
|
|
472
|
+
const next = (this.ptyPauseRefs.get(sessionId) ?? 0) + 1;
|
|
473
|
+
this.ptyPauseRefs.set(sessionId, next);
|
|
474
|
+
if (next === 1)
|
|
475
|
+
this.port?.pausePtyOutput?.(sessionId);
|
|
476
|
+
}
|
|
477
|
+
releasePtyPause(client) {
|
|
478
|
+
const sessionId = client.ptyPausedSessionId;
|
|
479
|
+
if (!sessionId)
|
|
480
|
+
return;
|
|
481
|
+
client.ptyPausedSessionId = null;
|
|
482
|
+
const next = Math.max(0, (this.ptyPauseRefs.get(sessionId) ?? 1) - 1);
|
|
483
|
+
if (next === 0) {
|
|
484
|
+
this.ptyPauseRefs.delete(sessionId);
|
|
485
|
+
this.port?.resumePtyOutput?.(sessionId);
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
this.ptyPauseRefs.set(sessionId, next);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
sendPtyError(client, sessionId, error) {
|
|
492
|
+
if (client.ws.readyState !== WebSocket.OPEN)
|
|
493
|
+
return;
|
|
494
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
495
|
+
client.ws.send(JSON.stringify({ type: "pty_error", sessionId, error: message }));
|
|
496
|
+
}
|
|
401
497
|
processWsQueue(client) {
|
|
402
498
|
if (this.disposed)
|
|
403
499
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@co0ontty/wand",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.37.0",
|
|
4
4
|
"description": "A web console for Claude Code, Codex, OpenCode, and other local CLI tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"preferGlobal": true,
|
|
19
19
|
"scripts": {
|
|
20
20
|
"generate:web-assets": "node scripts/generate-web-assets.js",
|
|
21
|
-
"build": "rm -rf dist && node scripts/bundle-
|
|
21
|
+
"build": "rm -rf dist && node scripts/bundle-xterm.js && node scripts/bundle-qrcode.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc -p tsconfig.json && npm run build:copy-content && node scripts/stamp-build-info.js && node scripts/fix-dist-permissions.js",
|
|
22
22
|
"build:copy-content": "cp -r src/web-ui/content dist/web-ui/ && node scripts/minify-dist-content.js",
|
|
23
|
-
"dev": "node scripts/bundle-browser.js --development && npm run generate:web-assets && tsx src/cli.ts web",
|
|
24
|
-
"check": "node scripts/bundle-browser.js && npm run generate:web-assets && tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p tsconfig.react.json",
|
|
23
|
+
"dev": "node scripts/bundle-xterm.js && node scripts/bundle-browser.js --development && npm run generate:web-assets && tsx src/cli.ts web",
|
|
24
|
+
"check": "node scripts/bundle-xterm.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p tsconfig.react.json",
|
|
25
25
|
"test": "node --test --import tsx tests/*.test.ts",
|
|
26
26
|
"test:browser": "npm run build && playwright test",
|
|
27
27
|
"test:browser:current": "playwright test",
|
|
@@ -46,6 +46,11 @@
|
|
|
46
46
|
"@radix-ui/react-switch": "^1.3.3",
|
|
47
47
|
"@radix-ui/react-tabs": "^1.1.17",
|
|
48
48
|
"@radix-ui/react-toast": "^1.2.19",
|
|
49
|
+
"@xterm/addon-fit": "^0.11.0",
|
|
50
|
+
"@xterm/addon-serialize": "^0.14.0",
|
|
51
|
+
"@xterm/addon-unicode11": "^0.9.0",
|
|
52
|
+
"@xterm/headless": "^6.0.0",
|
|
53
|
+
"@xterm/xterm": "^6.0.0",
|
|
49
54
|
"compression": "^1.8.1",
|
|
50
55
|
"express": "^4.21.2",
|
|
51
56
|
"multer": "^2.1.1",
|
|
@@ -66,7 +71,6 @@
|
|
|
66
71
|
"@types/react": "^19.2.17",
|
|
67
72
|
"@types/react-dom": "^19.2.3",
|
|
68
73
|
"@types/ws": "^8.18.1",
|
|
69
|
-
"@wterm/dom": "^0.1.8",
|
|
70
74
|
"esbuild": "^0.28.0",
|
|
71
75
|
"qrcode": "^1.5.4",
|
|
72
76
|
"tsx": "^4.19.3",
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
.wterm {
|
|
2
|
-
--term-fg: #d4d4d4;
|
|
3
|
-
--term-bg: #1e1e1e;
|
|
4
|
-
--term-cursor: #aeafad;
|
|
5
|
-
|
|
6
|
-
--term-color-0: #1e1e1e;
|
|
7
|
-
--term-color-1: #f44747;
|
|
8
|
-
--term-color-2: #6a9955;
|
|
9
|
-
--term-color-3: #d7ba7d;
|
|
10
|
-
--term-color-4: #569cd6;
|
|
11
|
-
--term-color-5: #c586c0;
|
|
12
|
-
--term-color-6: #4ec9b0;
|
|
13
|
-
--term-color-7: #d4d4d4;
|
|
14
|
-
--term-color-8: #808080;
|
|
15
|
-
--term-color-9: #f44747;
|
|
16
|
-
--term-color-10: #6a9955;
|
|
17
|
-
--term-color-11: #d7ba7d;
|
|
18
|
-
--term-color-12: #569cd6;
|
|
19
|
-
--term-color-13: #c586c0;
|
|
20
|
-
--term-color-14: #4ec9b0;
|
|
21
|
-
--term-color-15: #ffffff;
|
|
22
|
-
|
|
23
|
-
--term-font-family: 'Menlo', 'Consolas', 'DejaVu Sans Mono', 'Courier New', monospace;
|
|
24
|
-
--term-font-size: 14px;
|
|
25
|
-
--term-line-height: 1.2;
|
|
26
|
-
--term-row-height: 17px;
|
|
27
|
-
|
|
28
|
-
position: relative;
|
|
29
|
-
background: var(--term-bg);
|
|
30
|
-
color: var(--term-fg);
|
|
31
|
-
font-family: var(--term-font-family);
|
|
32
|
-
font-size: var(--term-font-size);
|
|
33
|
-
line-height: var(--term-line-height);
|
|
34
|
-
padding: 12px;
|
|
35
|
-
border-radius: 8px;
|
|
36
|
-
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
|
37
|
-
outline: none;
|
|
38
|
-
overflow: hidden;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.wterm:focus,
|
|
42
|
-
.wterm:focus-visible {
|
|
43
|
-
outline: none;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.term-grid {
|
|
47
|
-
display: block;
|
|
48
|
-
white-space: pre;
|
|
49
|
-
contain: layout paint style;
|
|
50
|
-
will-change: contents;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.term-row {
|
|
54
|
-
display: block;
|
|
55
|
-
height: var(--term-row-height);
|
|
56
|
-
contain: content;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.term-block {
|
|
60
|
-
display: inline-block;
|
|
61
|
-
width: 1ch;
|
|
62
|
-
height: var(--term-row-height);
|
|
63
|
-
vertical-align: top;
|
|
64
|
-
overflow: hidden;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.term-cursor {
|
|
68
|
-
outline: 1px solid var(--term-cursor);
|
|
69
|
-
outline-offset: -1px;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.wterm.focused .term-cursor {
|
|
73
|
-
background: var(--term-cursor);
|
|
74
|
-
color: var(--term-bg);
|
|
75
|
-
outline: none;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.wterm.focused.cursor-blink .term-cursor {
|
|
79
|
-
animation: cursor-blink 1s step-end infinite;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
@keyframes cursor-blink {
|
|
83
|
-
0%, 100% { background: var(--term-cursor); color: var(--term-bg); }
|
|
84
|
-
50% { background: transparent; color: inherit; }
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
.wterm.has-scrollback {
|
|
88
|
-
overflow-y: auto;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.wterm ::selection {
|
|
92
|
-
background: rgba(86, 156, 214, 0.3);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/* Solarized Dark */
|
|
96
|
-
.wterm.theme-solarized-dark {
|
|
97
|
-
--term-fg: #839496;
|
|
98
|
-
--term-bg: #002b36;
|
|
99
|
-
--term-cursor: #93a1a1;
|
|
100
|
-
--term-color-0: #073642;
|
|
101
|
-
--term-color-1: #dc322f;
|
|
102
|
-
--term-color-2: #859900;
|
|
103
|
-
--term-color-3: #b58900;
|
|
104
|
-
--term-color-4: #268bd2;
|
|
105
|
-
--term-color-5: #d33682;
|
|
106
|
-
--term-color-6: #2aa198;
|
|
107
|
-
--term-color-7: #eee8d5;
|
|
108
|
-
--term-color-8: #586e75;
|
|
109
|
-
--term-color-9: #cb4b16;
|
|
110
|
-
--term-color-10: #586e75;
|
|
111
|
-
--term-color-11: #657b83;
|
|
112
|
-
--term-color-12: #839496;
|
|
113
|
-
--term-color-13: #6c71c4;
|
|
114
|
-
--term-color-14: #93a1a1;
|
|
115
|
-
--term-color-15: #fdf6e3;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/* Monokai */
|
|
119
|
-
.wterm.theme-monokai {
|
|
120
|
-
--term-fg: #f8f8f2;
|
|
121
|
-
--term-bg: #272822;
|
|
122
|
-
--term-cursor: #f8f8f0;
|
|
123
|
-
--term-color-0: #272822;
|
|
124
|
-
--term-color-1: #f92672;
|
|
125
|
-
--term-color-2: #a6e22e;
|
|
126
|
-
--term-color-3: #f4bf75;
|
|
127
|
-
--term-color-4: #66d9ef;
|
|
128
|
-
--term-color-5: #ae81ff;
|
|
129
|
-
--term-color-6: #a1efe4;
|
|
130
|
-
--term-color-7: #f8f8f2;
|
|
131
|
-
--term-color-8: #75715e;
|
|
132
|
-
--term-color-9: #f92672;
|
|
133
|
-
--term-color-10: #a6e22e;
|
|
134
|
-
--term-color-11: #f4bf75;
|
|
135
|
-
--term-color-12: #66d9ef;
|
|
136
|
-
--term-color-13: #ae81ff;
|
|
137
|
-
--term-color-14: #a1efe4;
|
|
138
|
-
--term-color-15: #f9f8f5;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/* Light */
|
|
142
|
-
.wterm.theme-light {
|
|
143
|
-
--term-fg: #383a42;
|
|
144
|
-
--term-bg: #fafafa;
|
|
145
|
-
--term-cursor: #526eff;
|
|
146
|
-
--term-color-0: #383a42;
|
|
147
|
-
--term-color-1: #e45649;
|
|
148
|
-
--term-color-2: #50a14f;
|
|
149
|
-
--term-color-3: #c18401;
|
|
150
|
-
--term-color-4: #4078f2;
|
|
151
|
-
--term-color-5: #a626a4;
|
|
152
|
-
--term-color-6: #0184bc;
|
|
153
|
-
--term-color-7: #fafafa;
|
|
154
|
-
--term-color-8: #a0a1a7;
|
|
155
|
-
--term-color-9: #e45649;
|
|
156
|
-
--term-color-10: #50a14f;
|
|
157
|
-
--term-color-11: #c18401;
|
|
158
|
-
--term-color-12: #4078f2;
|
|
159
|
-
--term-color-13: #a626a4;
|
|
160
|
-
--term-color-14: #0184bc;
|
|
161
|
-
--term-color-15: #ffffff;
|
|
162
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var WTermLib=(()=>{var f=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var v=(r,A)=>{for(var t in A)f(r,t,{get:A[t],enumerable:!0})},m=(r,A,t,e)=>{if(A&&typeof A=="object"||typeof A=="function")for(let s of x(A))!p.call(r,s)&&s!==t&&f(r,s,{get:()=>A[s],enumerable:!(e=F(A,s))||e.enumerable});return r};var k=r=>m(f({},"__esModule",{value:!0}),r);var O={};v(O,{InputHandler:()=>l,Renderer:()=>c,WTerm:()=>b,WasmBridge:()=>a,WebSocketTransport:()=>d});var G="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";function y(r){let A=atob(r),t=new Uint8Array(A.length);for(let e=0;e<A.length;e++)t[e]=A.charCodeAt(e);return t.buffer}var a=class r{constructor(A){this.gridPtr=0,this.dirtyPtr=0,this.writeBufferPtr=0,this.cellSize=12,this.maxCols=256,this.encoder=new TextEncoder,this.decoder=new TextDecoder,this.exports=A.exports,this.memory=this.exports.memory}static async load(A){let t;if(A){let s=await fetch(A);if(!s.ok)throw new Error(`[wterm] Failed to load WASM from ${A}: ${s.status} ${s.statusText}`);t=await s.arrayBuffer()}else t=y(G);let{instance:e}=await WebAssembly.instantiate(t);return new r(e)}init(A,t){this.exports.init(A,t),this._updatePointers()}_updatePointers(){this.gridPtr=this.exports.getGridPtr(),this.dirtyPtr=this.exports.getDirtyPtr(),this.writeBufferPtr=this.exports.getWriteBuffer(),this.cellSize=this.exports.getCellSize(),this.maxCols=this.exports.getMaxCols(),this._dv=new DataView(this.memory.buffer)}writeString(A){let t=this.encoder.encode(A);this.writeRaw(t)}writeRaw(A){let t=new Uint8Array(this.memory.buffer,this.writeBufferPtr,8192),e=0;for(;e<A.length;){let s=Math.min(A.length-e,8192);t.set(A.subarray(e,e+s)),this.exports.writeBytes(s),e+=s}}getCell(A,t){let e=this.gridPtr+(A*this.maxCols+t)*this.cellSize,s=this._dv;return{char:s.getUint32(e,!0),fg:s.getUint16(e+4,!0),bg:s.getUint16(e+6,!0),flags:s.getUint8(e+8)}}isDirtyRow(A){return new Uint8Array(this.memory.buffer,this.dirtyPtr,256)[A]!==0}clearDirty(){this.exports.clearDirty()}getCursor(){return{row:this.exports.getCursorRow(),col:this.exports.getCursorCol(),visible:this.exports.getCursorVisible()!==0}}getCols(){return this.exports.getCols()}getRows(){return this.exports.getRows()}cursorKeysApp(){return this.exports.getCursorKeysApp()!==0}bracketedPaste(){return this.exports.getBracketedPaste()!==0}usingAltScreen(){return this.exports.getUsingAltScreen()!==0}getTitle(){if(this.exports.getTitleChanged()===0)return null;let A=this.exports.getTitlePtr(),t=this.exports.getTitleLen(),e=new Uint8Array(this.memory.buffer,A,t);return this.decoder.decode(e)}getResponse(){let A=this.exports.getResponseLen();if(A===0)return null;let t=this.exports.getResponsePtr(),e=new Uint8Array(this.memory.buffer,t,A),s=this.decoder.decode(e);return this.exports.clearResponse(),s}getScrollbackCount(){return this.exports.getScrollbackCount()}getScrollbackCell(A,t){let s=this.exports.getScrollbackLine(A)+t*this.cellSize,i=this._dv;return{char:i.getUint32(s,!0),fg:i.getUint16(s+4,!0),bg:i.getUint16(s+6,!0),flags:i.getUint8(s+8)}}getScrollbackLineLen(A){return this.exports.getScrollbackLineLen(A)}resize(A,t){this.exports.resizeTerminal(A,t),this._updatePointers()}};var d=class{constructor(A={}){this._ws=null,this._reconnectTimer=null,this._reconnectDelay=1e3,this._closed=!1,this._buffer=[],this.url=A.url??null,this.reconnect=A.reconnect!==!1,this.maxReconnectDelay=A.maxReconnectDelay??3e4,this.onData=A.onData??null,this.onOpen=A.onOpen??null,this.onClose=A.onClose??null,this.onError=A.onError??null}connect(A){if(A&&(this.url=A),!this.url)throw new Error("No WebSocket URL provided");this._closed=!1,this._ws=new WebSocket(this.url),this._ws.binaryType="arraybuffer",this._ws.onopen=()=>{this._reconnectDelay=1e3,this._flushBuffer(),this.onOpen&&this.onOpen()},this._ws.onmessage=t=>{this.onData&&(t.data instanceof ArrayBuffer?this.onData(new Uint8Array(t.data)):this.onData(t.data))},this._ws.onclose=()=>{this.onClose&&this.onClose(),this.reconnect&&!this._closed&&this._scheduleReconnect()},this._ws.onerror=t=>{this.onError&&this.onError(t),this._ws?.close()}}send(A){this._ws&&this._ws.readyState===WebSocket.OPEN?typeof A=="string"?this._ws.send(new TextEncoder().encode(A)):this._ws.send(A):this._buffer.push(A)}close(){this._closed=!0,this._reconnectTimer&&clearTimeout(this._reconnectTimer),this._ws&&this._ws.close()}get connected(){return this._ws!==null&&this._ws.readyState===WebSocket.OPEN}_flushBuffer(){let A=this._buffer.splice(0);for(let t of A)this.send(t)}_scheduleReconnect(){this._reconnectTimer=setTimeout(()=>{this.connect()},this._reconnectDelay),this._reconnectDelay=Math.min(this._reconnectDelay*2,this.maxReconnectDelay)}};function u(r){if(r===256)return null;if(r<16)return`var(--term-color-${r})`;if(r<232){let t=r-16,e=Math.floor(t/36)*51,s=Math.floor(t/6)%6*51,i=t%6*51;return`rgb(${e},${s},${i})`}let A=(r-232)*10+8;return`rgb(${A},${A},${A})`}function S(r,A,t){let e=r,s=A;if(t&32){let Q=e;e=s,s=Q,e===256&&(e=0),s===256&&(s=7)}let i=u(e),o=u(s),B="";i&&(B+=`color:${i};`),o&&(B+=`background:${o};`),t&1&&(B+="font-weight:bold;"),t&2&&(B+="opacity:0.5;"),t&4&&(B+="font-style:italic;");let E=[];return t&128&&E.push("line-through"),E.length&&(B+=`text-decoration:${E.join(" ")};`),t&64&&(B+="visibility:hidden;"),B}function D(r,A,t){if(t){let e=document.createElement("span");e.style.cssText=t,e.textContent=A,r.appendChild(e)}else r.appendChild(document.createTextNode(A))}function R(r,A,t){let e=r,s=A;return t&32&&([e,s]=[s,e],e===256&&(e=0),s===256&&(s=7)),{fg:u(e)||"var(--term-fg)",bg:u(s)||"var(--term-bg)"}}function H(r,A,t){switch(r){case 9600:return`linear-gradient(${A} 50%,${t} 50%)`;case 9601:return`linear-gradient(${t} 87.5%,${A} 87.5%)`;case 9602:return`linear-gradient(${t} 75%,${A} 75%)`;case 9603:return`linear-gradient(${t} 62.5%,${A} 62.5%)`;case 9604:return`linear-gradient(${t} 50%,${A} 50%)`;case 9605:return`linear-gradient(${t} 37.5%,${A} 37.5%)`;case 9606:return`linear-gradient(${t} 25%,${A} 25%)`;case 9607:return`linear-gradient(${t} 12.5%,${A} 12.5%)`;case 9608:return A;case 9609:return`linear-gradient(to right,${A} 87.5%,${t} 87.5%)`;case 9610:return`linear-gradient(to right,${A} 75%,${t} 75%)`;case 9611:return`linear-gradient(to right,${A} 62.5%,${t} 62.5%)`;case 9612:return`linear-gradient(to right,${A} 50%,${t} 50%)`;case 9613:return`linear-gradient(to right,${A} 37.5%,${t} 37.5%)`;case 9614:return`linear-gradient(to right,${A} 25%,${t} 25%)`;case 9615:return`linear-gradient(to right,${A} 12.5%,${t} 12.5%)`;case 9616:return`linear-gradient(to right,${t} 50%,${A} 50%)`;case 9617:return`color-mix(in srgb,${A} 25%,${t})`;case 9618:return`color-mix(in srgb,${A} 50%,${t})`;case 9619:return`color-mix(in srgb,${A} 75%,${t})`;case 9620:return`linear-gradient(${A} 12.5%,${t} 12.5%)`;case 9621:return`linear-gradient(to right,${t} 87.5%,${A} 87.5%)`;default:{let s={9622:[!1,!1,!0,!1],9623:[!1,!1,!1,!0],9624:[!0,!1,!1,!1],9625:[!0,!1,!0,!0],9626:[!0,!1,!1,!0],9627:[!0,!0,!0,!1],9628:[!0,!0,!1,!0],9629:[!1,!0,!1,!1],9630:[!1,!0,!0,!1],9631:[!1,!0,!0,!0]}[r];if(!s)return A;let[i,o,B,E]=s;if(i&&o&&B&&E)return A;let Q=[],C=["0 0","100% 0","0 100%","100% 100%"];return s.forEach((n,I)=>{n&&Q.push(`linear-gradient(${A},${A}) ${C[I]}/50% 50% no-repeat`)}),Q.push(t),Q.join(",")}}}var c=class{constructor(A){this.rows=0,this.cols=0,this.rowEls=[],this.prevCursorRow=-1,this.prevCursorCol=-1,this._scrollbackRowEls=[],this._renderedScrollbackCount=0,this.container=A}setup(A,t){this.cols=A,this.rows=t,this.container.innerHTML="",this.rowEls=[],this._scrollbackRowEls=[],this._renderedScrollbackCount=0;let e=document.createDocumentFragment();for(let s=0;s<t;s++){let i=document.createElement("div");i.className="term-row",e.appendChild(i),this.rowEls.push(i)}this.container.appendChild(e),this.prevCursorRow=-1,this.prevCursorCol=-1}_buildRowContent(A,t,e,s){A.textContent="";let i="",o="",B=0,E=Q=>{if(o)if(s>=B&&s<Q){let C=s-B,n=o.slice(0,C),I=o[C],h=o.slice(C+1);n&&D(A,n,i);let g=document.createElement("span");g.className="term-cursor",i&&(g.style.cssText=i),g.textContent=I,A.appendChild(g),h&&D(A,h,i)}else D(A,o,i)};for(let Q=0;Q<this.cols;Q++){let C=t(Q),n=Q<e,I=n?C.char:0;if(n&&I>=9600&&I<=9631){E(Q);let h=R(C.fg,C.bg,C.flags),g=document.createElement("span");g.className=Q===s?"term-block term-cursor":"term-block",g.style.background=H(I,h.fg,h.bg),C.flags&2&&(g.style.opacity="0.5"),A.appendChild(g),i="",o="",B=Q+1}else{let h=n&&I>=32?String.fromCodePoint(I):" ",g=n?S(C.fg,C.bg,C.flags):"";g!==i?(E(Q),i=g,o=h,B=Q):o+=h}}E(this.cols)}_buildScrollbackRowEl(A,t){let e=document.createElement("div");e.className="term-row term-scrollback-row";let s=A.getScrollbackLineLen(t);return this._buildRowContent(e,i=>A.getScrollbackCell(t,i),s,-1),e}syncScrollback(A){let t=A.getScrollbackCount();if(t!==this._renderedScrollbackCount){if(t>this._renderedScrollbackCount){let e=t-this._renderedScrollbackCount,s=this.rowEls[0]??null,i=document.createDocumentFragment();for(let o=e-1;o>=0;o--){let B=this._buildScrollbackRowEl(A,o);i.appendChild(B),this._scrollbackRowEls.push(B)}this.container.insertBefore(i,s)}else{let e=this._renderedScrollbackCount-t;for(let s=0;s<e;s++){let i=this._scrollbackRowEls.shift();i&&i.remove()}}this._renderedScrollbackCount=t}}render(A){let t=A.getRows(),e=A.getCols(),s=!1;(t!==this.rows||e!==this.cols)&&(this.setup(e,t),s=!0),this.syncScrollback(A);let i=A.getCursor(),o=i.visible,B=i.row!==this.prevCursorRow||i.col!==this.prevCursorCol;for(let E=0;E<this.rows;E++){let Q=s||A.isDirtyRow(E),C=E===this.prevCursorRow&&B,n=E===i.row;if(Q||C||n&&B){let I=n&&o?i.col:-1;this._buildRowContent(this.rowEls[E],h=>A.getCell(E,h),this.cols,I)}}this.prevCursorRow=i.row,this.prevCursorCol=i.col,A.clearDirty()}};var U={ArrowUp:"\x1B[A",ArrowDown:"\x1B[B",ArrowRight:"\x1B[C",ArrowLeft:"\x1B[D",Home:"\x1B[H",End:"\x1B[F"},M={ArrowUp:"\x1BOA",ArrowDown:"\x1BOB",ArrowRight:"\x1BOC",ArrowLeft:"\x1BOD",Home:"\x1BOH",End:"\x1BOF"},_={Enter:"\r",Backspace:"\x7F",Tab:" ",Escape:"\x1B",Insert:"\x1B[2~",Delete:"\x1B[3~",PageUp:"\x1B[5~",PageDown:"\x1B[6~",F1:"\x1BOP",F2:"\x1BOQ",F3:"\x1BOR",F4:"\x1BOS",F5:"\x1B[15~",F6:"\x1B[17~",F7:"\x1B[18~",F8:"\x1B[19~",F9:"\x1B[20~",F10:"\x1B[21~",F11:"\x1B[23~",F12:"\x1B[24~"},l=class{constructor(A,t,e){this.composing=!1,this.element=A,this.onData=t,this.getBridge=e,this.textarea=document.createElement("textarea"),this.textarea.setAttribute("autocapitalize","off"),this.textarea.setAttribute("autocomplete","off"),this.textarea.setAttribute("autocorrect","off"),this.textarea.setAttribute("spellcheck","false"),this.textarea.setAttribute("enterkeyhint","send"),this.textarea.setAttribute("tabindex","0"),this.textarea.setAttribute("aria-label","terminal input");let s=this.textarea.style;s.position="absolute",s.left="-9999px",s.top="0",s.width="1px",s.height="1px",s.opacity="0",s.overflow="hidden",s.border="0",s.padding="0",s.margin="0",s.outline="none",s.resize="none",s.pointerEvents="none",s.caretColor="transparent",s.color="transparent",s.background="transparent",A.appendChild(this.textarea),this._onKeyDown=this.handleKeyDown.bind(this),this._onPaste=this.handlePaste.bind(this),this._onCompositionStart=this.handleCompositionStart.bind(this),this._onCompositionEnd=this.handleCompositionEnd.bind(this),this._onInput=this.handleInput.bind(this),this._onFocus=()=>this.element.classList.add("focused"),this._onBlur=()=>this.element.classList.remove("focused"),this.textarea.addEventListener("keydown",this._onKeyDown),this.textarea.addEventListener("paste",this._onPaste),this.textarea.addEventListener("compositionstart",this._onCompositionStart),this.textarea.addEventListener("compositionend",this._onCompositionEnd),this.textarea.addEventListener("input",this._onInput),this.textarea.addEventListener("focus",this._onFocus),this.textarea.addEventListener("blur",this._onBlur)}focus(){this.textarea.focus({preventScroll:!0})}destroy(){this.textarea.removeEventListener("keydown",this._onKeyDown),this.textarea.removeEventListener("paste",this._onPaste),this.textarea.removeEventListener("compositionstart",this._onCompositionStart),this.textarea.removeEventListener("compositionend",this._onCompositionEnd),this.textarea.removeEventListener("input",this._onInput),this.textarea.removeEventListener("focus",this._onFocus),this.textarea.removeEventListener("blur",this._onBlur),this.element.classList.remove("focused"),this.textarea.remove()}handleKeyDown(A){if(this.composing)return;if((A.metaKey||A.ctrlKey)&&A.key==="c"){let e=window.getSelection();if(e&&e.toString().length>0)return}if((A.metaKey||A.ctrlKey)&&A.key==="v"){this.textarea.focus();return}if(A.metaKey&&!A.ctrlKey){if(A.key==="Backspace")A.preventDefault(),this.onData("");else if(A.key==="a"){A.preventDefault();let e=window.getSelection();if(e){let s=document.createRange();s.selectNodeContents(this.element),e.removeAllRanges(),e.addRange(s)}}return}A.preventDefault();let t=this.keyToSequence(A);t&&this.onData(t)}handlePaste(A){A.preventDefault();let t=A.clipboardData?.getData("text");if(!t)return;let e=this.getBridge();e&&e.bracketedPaste()?this.onData("\x1B[200~"+t+"\x1B[201~"):this.onData(t)}handleCompositionStart(){this.composing=!0}handleCompositionEnd(A){this.composing=!1,A.data&&this.onData(A.data),this.textarea.value=""}handleInput(){if(this.composing)return;let A=this.textarea.value;A&&(this.onData(A),this.textarea.value="")}keyToSequence(A){if(A.ctrlKey&&!A.altKey&&!A.metaKey){if(A.key.length===1){let B=A.key.toLowerCase().charCodeAt(0);if(B>=97&&B<=122)return String.fromCharCode(B-96)}if(A.key==="[")return"\x1B";if(A.key==="\\")return"";if(A.key==="]")return"";if(A.key==="^")return"";if(A.key==="_")return""}if(A.key==="Enter"&&A.shiftKey)return"\x1B[13;2u";if(A.key==="Tab"&&A.shiftKey)return"\x1B[Z";let t=_[A.key];if(t)return A.altKey?"\x1B"+t:t;let e=this.getBridge(),o=(e&&e.cursorKeysApp()?M:U)[A.key];return o?A.altKey?"\x1B"+o:o:A.key.length===1&&!A.ctrlKey&&!A.metaKey?A.altKey?"\x1B"+A.key:A.key:null}};var w=class{constructor(A,t={}){this.bridge=null,this.renderer=null,this.input=null,this.rafId=null,this.resizeObserver=null,this._destroyed=!1,this._shouldScrollToBottom=!1,this.element=A,this.wasmUrl=t.wasmUrl,this.cols=t.cols||80,this.rows=t.rows||24,this.autoResize=t.autoResize!==!1,this.onData=t.onData||null,this.onTitle=t.onTitle||null,this.onResize=t.onResize||null,this._container=document.createElement("div"),this._container.className="term-grid",this.element.appendChild(this._container),this.element.classList.add("wterm"),t.cursorBlink&&this.element.classList.add("cursor-blink"),this._onClickFocus=()=>{let e=window.getSelection();(!e||e.isCollapsed)&&this.input?.focus()},this.element.addEventListener("click",this._onClickFocus)}async init(){try{if(this.bridge=await a.load(this.wasmUrl),this._destroyed)return this;this.bridge.init(this.cols,this.rows),this.renderer=new c(this._container),this.renderer.setup(this.cols,this.rows),this.input=new l(this.element,A=>{this.onData?this.onData(A):this.write(A)},()=>this.bridge),this.autoResize?this._setupResizeObserver():this._lockHeight(),this.input.focus(),this._initialRender()}catch(A){throw this.destroy(),new Error(`wterm: failed to initialize: ${A instanceof Error?A.message:A}`)}return this}_isScrolledToBottom(){let A=this.element;return A.scrollHeight-A.scrollTop-A.clientHeight<5}_scrollToBottom(){this.element.scrollTop=this.element.scrollHeight}write(A){this.bridge&&(this._shouldScrollToBottom=this._isScrolledToBottom(),typeof A=="string"?this.bridge.writeString(A):this.bridge.writeRaw(A),this._scheduleRender())}resize(A,t){this.bridge&&(this._shouldScrollToBottom=this._isScrolledToBottom(),this.cols=A,this.rows=t,this.bridge.resize(A,t),this.renderer?.setup(A,t),this._scheduleRender(),this.onResize&&this.onResize(A,t))}focus(){this.input?this.input.focus():this.element.focus()}_scheduleRender(){this.rafId==null&&(this.rafId=requestAnimationFrame(()=>{this.rafId=null,this._doRender()}))}_initialRender(){this._doRender()}_doRender(){if(!this.bridge||!this.renderer)return;this.renderer.render(this.bridge);let A=this.bridge.getScrollbackCount()>0;this.element.classList.toggle("has-scrollback",A),this._shouldScrollToBottom&&this._scrollToBottom();let t=this.bridge.getTitle();t!==null&&this.onTitle&&this.onTitle(t);let e=this.bridge.getResponse();e!==null&&this.onData&&this.onData(e)}_lockHeight(){let A=getComputedStyle(this.element),t=parseFloat(A.getPropertyValue("--term-row-height"))||17,e=this.rows*t,s=(parseFloat(A.paddingTop)||0)+(parseFloat(A.paddingBottom)||0);A.boxSizing==="border-box"&&(s+=(parseFloat(A.borderTopWidth)||0)+(parseFloat(A.borderBottomWidth)||0)),this.element.style.height=`${e+s}px`}_measureCharSize(){let A=document.createElement("span");A.className="term-cell",A.textContent="W",A.style.position="absolute",A.style.visibility="hidden",this._container.appendChild(A);let t=A.getBoundingClientRect(),e=t.width,s=t.height;return A.remove(),e===0||s===0?null:{width:e,height:s}}_setupResizeObserver(){let A=this._measureCharSize();if(!A)return;let t=A.width,e=A.height;this.resizeObserver=new ResizeObserver(s=>{let i=this._measureCharSize();i&&(t=i.width,e=i.height);for(let o of s){let{width:B,height:E}=o.contentRect,Q=Math.max(1,Math.floor(B/t)),C=Math.max(1,Math.floor(E/e));(Q!==this.cols||C!==this.rows)&&this.resize(Q,C)}}),this.resizeObserver.observe(this.element)}destroy(){this._destroyed=!0,this.rafId!=null&&cancelAnimationFrame(this.rafId),this.resizeObserver&&this.resizeObserver.disconnect(),this.input&&this.input.destroy(),this.element.removeEventListener("click",this._onClickFocus),this.element.innerHTML=""}};var J=/\x1b\[([0-9;]*)m/g,L=256;function N(r){if(!r)return null;let A=r.split(";"),t=[];for(let e=0;e<A.length;e++){let s=A[e];if((s==="38"||s==="48")&&A[e+1]==="5"){t.push(A[e],A[e+1],A[e+2]??""),e+=2;continue}if((s==="38"||s==="48")&&A[e+1]==="2"){t.push(A[e],A[e+1],A[e+2]??"",A[e+3]??"",A[e+4]??""),e+=4;continue}s==="4"||s==="24"||t.push(s)}return t.length?"\x1B["+t.join(";")+"m":""}var b=class extends w{resize(A,t){super.resize(Math.min(A,L),t)}write(A){typeof A=="string"&&(A=A.replace(J,(t,e)=>{let s=N(e);return s===null?t:s})),super.write(A)}reset(){!this.bridge||!this.renderer||(this.bridge.init(this.cols,this.rows),this.renderer.setup(this.cols,this.rows),this._scheduleRender())}async init(){return this._calibrateInitialSize(),await super.init(),this.autoResize&&!this.resizeObserver&&!this._destroyed&&this._scheduleObserverSetup(),this}_calibrateInitialSize(){if(!this.element||!this._container||!this.element.isConnected)return;this.element.offsetHeight;let A=document.createElement("span");A.className="term-cell",A.style.cssText="position:absolute;visibility:hidden;left:-9999px;top:0;",A.textContent="W",this._container.appendChild(A);let t=A.getBoundingClientRect(),e=t.width,s=t.height;if(A.remove(),e<=0||s<=0)return;let i=getComputedStyle(this.element),o=(parseFloat(i.paddingLeft)||0)+(parseFloat(i.paddingRight)||0),B=(parseFloat(i.paddingTop)||0)+(parseFloat(i.paddingBottom)||0),E=this.element.clientWidth-o,Q=this.element.clientHeight-B;if(E<=0||Q<=0)return;let C=Math.min(Math.max(1,Math.floor(E/e)),L),n=Math.max(1,Math.floor(Q/s));this.cols=C,this.rows=n}_scheduleObserverSetup(){if(this._observerSetupPending)return;this._observerSetupPending=!0;let A=0,t=120,e=()=>{if(this._destroyed||this.resizeObserver){this._observerSetupPending=!1;return}if(this.element.offsetHeight,this._measureCharSize()&&this.element.clientWidth>0&&this.element.clientHeight>0){this._setupResizeObserver(),this._observerSetupPending=!1;return}if(++A>=t){this._observerSetupPending=!1;return}A<=8?requestAnimationFrame(e):setTimeout(e,50)};requestAnimationFrame(e)}remeasure(){if(!this.bridge||!this.renderer)return;this.autoResize&&!this.resizeObserver&&!this._destroyed&&(this._measureCharSize()&&this.element.clientWidth>0&&this.element.clientHeight>0?this._setupResizeObserver():this._scheduleObserverSetup());let A=this._measureCharSize();if(!A)return;let t=getComputedStyle(this.element),e=this.element.clientWidth-(parseFloat(t.paddingLeft)||0)-(parseFloat(t.paddingRight)||0),s=this.element.clientHeight-(parseFloat(t.paddingTop)||0)-(parseFloat(t.paddingBottom)||0);if(e<=0||s<=0)return;let i=Math.min(Math.max(1,Math.floor(e/A.width)),L),o=Math.max(1,Math.floor(s/A.height));i!==this.cols||o!==this.rows?this.resize(i,o):this._scheduleRender()}};return k(O);})();
|