@made-by-moonlight/athene-plugin-runtime-process 0.9.1
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/LICENSE +22 -0
- package/dist/__tests__/index.test.d.ts +2 -0
- package/dist/__tests__/index.test.d.ts.map +1 -0
- package/dist/__tests__/index.test.js +674 -0
- package/dist/__tests__/index.test.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +489 -0
- package/dist/index.js.map +1 -0
- package/dist/pty-client.d.ts +55 -0
- package/dist/pty-client.d.ts.map +1 -0
- package/dist/pty-client.js +248 -0
- package/dist/pty-client.js.map +1 -0
- package/dist/pty-host.d.ts +51 -0
- package/dist/pty-host.d.ts.map +1 -0
- package/dist/pty-host.js +354 -0
- package/dist/pty-host.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pty-client.ts
|
|
3
|
+
*
|
|
4
|
+
* Client library for connecting to a pty-host's Windows named pipe.
|
|
5
|
+
*
|
|
6
|
+
* Used by:
|
|
7
|
+
* - runtime-process/src/index.ts (sendMessage, getOutput, isAlive, destroy)
|
|
8
|
+
* - direct-terminal-ws.ts (raw socket relay via connectPtyHost)
|
|
9
|
+
*/
|
|
10
|
+
import { type Socket } from "node:net";
|
|
11
|
+
import { MSG_TERMINAL_INPUT, MSG_TERMINAL_DATA, MSG_RESIZE, encodeMessage, MessageParser } from "./pty-host.js";
|
|
12
|
+
export { MSG_TERMINAL_DATA, MSG_TERMINAL_INPUT, MSG_RESIZE, MessageParser, encodeMessage };
|
|
13
|
+
export interface PtyHostStatus {
|
|
14
|
+
alive: boolean;
|
|
15
|
+
pid: number;
|
|
16
|
+
exitCode?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns the Windows named pipe path for a given session ID.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getPipePath(sessionId: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Connect to the pty-host named pipe. Resolves with the socket on success,
|
|
24
|
+
* rejects on error or timeout.
|
|
25
|
+
*/
|
|
26
|
+
export declare function connectPtyHost(pipePath: string, timeoutMs?: number): Promise<Socket>;
|
|
27
|
+
/**
|
|
28
|
+
* Send a message (text command) to the PTY via a short-lived connection.
|
|
29
|
+
* Chunks large payloads to avoid ConPTY buffer truncation on Windows, then
|
|
30
|
+
* sends Enter as a separate frame after a short pause.
|
|
31
|
+
*
|
|
32
|
+
* Sliced by JS string length (UTF-16 code units), not bytes, so multi-byte
|
|
33
|
+
* codepoints aren't split mid-encoding. Surrogate pairs at chunk boundaries
|
|
34
|
+
* are still possible but extraordinarily rare in agent prompts; the cost of
|
|
35
|
+
* a defensive boundary check isn't worth it for our content.
|
|
36
|
+
*/
|
|
37
|
+
export declare function ptyHostSendMessage(pipePath: string, message: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Request the last N lines of PTY output from the host.
|
|
40
|
+
* Uses MessageParser to skip any MSG_TERMINAL_DATA frames that arrive before
|
|
41
|
+
* the MSG_GET_OUTPUT_RES response.
|
|
42
|
+
* Returns "" on timeout (3 s) or connection failure.
|
|
43
|
+
*/
|
|
44
|
+
export declare function ptyHostGetOutput(pipePath: string, lines?: number): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Check whether the pty-host process is still alive.
|
|
47
|
+
* Returns false if the pipe is unreachable (host has exited).
|
|
48
|
+
*/
|
|
49
|
+
export declare function ptyHostIsAlive(pipePath: string): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Send a kill request to the pty-host. Silently ignores errors — if the
|
|
52
|
+
* pipe is unreachable the process is already dead.
|
|
53
|
+
*/
|
|
54
|
+
export declare function ptyHostKill(pipePath: string): Promise<void>;
|
|
55
|
+
//# sourceMappingURL=pty-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-client.d.ts","sourceRoot":"","sources":["../src/pty-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EAMV,aAAa,EACb,aAAa,EACd,MAAM,eAAe,CAAC;AAMvB,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAM3F,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BlF;AA6BD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCzF;AAMD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCpF;AAMD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA4CvE;AAMD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjE"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pty-client.ts
|
|
3
|
+
*
|
|
4
|
+
* Client library for connecting to a pty-host's Windows named pipe.
|
|
5
|
+
*
|
|
6
|
+
* Used by:
|
|
7
|
+
* - runtime-process/src/index.ts (sendMessage, getOutput, isAlive, destroy)
|
|
8
|
+
* - direct-terminal-ws.ts (raw socket relay via connectPtyHost)
|
|
9
|
+
*/
|
|
10
|
+
import { connect } from "node:net";
|
|
11
|
+
import { MSG_TERMINAL_INPUT, MSG_TERMINAL_DATA, MSG_RESIZE, MSG_GET_OUTPUT_REQ, MSG_GET_OUTPUT_RES, MSG_STATUS_REQ, MSG_STATUS_RES, MSG_KILL_REQ, encodeMessage, MessageParser, } from "./pty-host.js";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Re-exports for direct-terminal-ws
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
export { MSG_TERMINAL_DATA, MSG_TERMINAL_INPUT, MSG_RESIZE, MessageParser, encodeMessage };
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Helpers
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Returns the Windows named pipe path for a given session ID.
|
|
21
|
+
*/
|
|
22
|
+
export function getPipePath(sessionId) {
|
|
23
|
+
return `\\\\.\\pipe\\ao-pty-${sessionId}`;
|
|
24
|
+
}
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// connectPtyHost
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
/**
|
|
29
|
+
* Connect to the pty-host named pipe. Resolves with the socket on success,
|
|
30
|
+
* rejects on error or timeout.
|
|
31
|
+
*/
|
|
32
|
+
export function connectPtyHost(pipePath, timeoutMs = 3000) {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
let settled = false;
|
|
35
|
+
const sock = connect(pipePath);
|
|
36
|
+
const timer = setTimeout(() => {
|
|
37
|
+
if (settled)
|
|
38
|
+
return;
|
|
39
|
+
settled = true;
|
|
40
|
+
sock.destroy();
|
|
41
|
+
reject(new Error(`Timed out connecting to pty-host at ${pipePath} (${timeoutMs}ms)`));
|
|
42
|
+
}, timeoutMs);
|
|
43
|
+
sock.once("connect", () => {
|
|
44
|
+
if (settled)
|
|
45
|
+
return;
|
|
46
|
+
settled = true;
|
|
47
|
+
clearTimeout(timer);
|
|
48
|
+
resolve(sock);
|
|
49
|
+
});
|
|
50
|
+
sock.once("error", (err) => {
|
|
51
|
+
if (settled)
|
|
52
|
+
return;
|
|
53
|
+
settled = true;
|
|
54
|
+
clearTimeout(timer);
|
|
55
|
+
reject(err);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// ptyHostSendMessage
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Windows ConPTY silently drops bytes when a single pty.write() exceeds its
|
|
63
|
+
// input buffer (observed truncation around 3–4 KB). Slicing the payload into
|
|
64
|
+
// small chunks with a brief delay between each lets the host's pty.write()
|
|
65
|
+
// drain into ConPTY before the next chunk arrives. Unix PTYs don't have this
|
|
66
|
+
// limitation, but chunking is harmless there — the small added latency
|
|
67
|
+
// (~15 ms × ceil(chars/512)) is imperceptible for typical prompts.
|
|
68
|
+
const PTY_INPUT_CHUNK_CHARS = 512;
|
|
69
|
+
const PTY_INPUT_CHUNK_DELAY_MS = 15;
|
|
70
|
+
const PTY_INPUT_ENTER_DELAY_MS = 300;
|
|
71
|
+
function writeFrame(sock, frame) {
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
sock.write(frame, (err) => {
|
|
74
|
+
if (err)
|
|
75
|
+
reject(err);
|
|
76
|
+
else
|
|
77
|
+
resolve();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function delay(ms) {
|
|
82
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Send a message (text command) to the PTY via a short-lived connection.
|
|
86
|
+
* Chunks large payloads to avoid ConPTY buffer truncation on Windows, then
|
|
87
|
+
* sends Enter as a separate frame after a short pause.
|
|
88
|
+
*
|
|
89
|
+
* Sliced by JS string length (UTF-16 code units), not bytes, so multi-byte
|
|
90
|
+
* codepoints aren't split mid-encoding. Surrogate pairs at chunk boundaries
|
|
91
|
+
* are still possible but extraordinarily rare in agent prompts; the cost of
|
|
92
|
+
* a defensive boundary check isn't worth it for our content.
|
|
93
|
+
*/
|
|
94
|
+
export async function ptyHostSendMessage(pipePath, message) {
|
|
95
|
+
const sock = await connectPtyHost(pipePath);
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
let settled = false;
|
|
98
|
+
const finish = (err) => {
|
|
99
|
+
if (settled)
|
|
100
|
+
return;
|
|
101
|
+
settled = true;
|
|
102
|
+
if (err) {
|
|
103
|
+
sock.destroy();
|
|
104
|
+
reject(err);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
sock.end();
|
|
108
|
+
resolve();
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
sock.once("error", finish);
|
|
112
|
+
void (async () => {
|
|
113
|
+
try {
|
|
114
|
+
for (let offset = 0; offset < message.length; offset += PTY_INPUT_CHUNK_CHARS) {
|
|
115
|
+
const slice = message.slice(offset, offset + PTY_INPUT_CHUNK_CHARS);
|
|
116
|
+
await writeFrame(sock, encodeMessage(MSG_TERMINAL_INPUT, slice));
|
|
117
|
+
if (offset + PTY_INPUT_CHUNK_CHARS < message.length) {
|
|
118
|
+
await delay(PTY_INPUT_CHUNK_DELAY_MS);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Brief pause before Enter so the terminal processes the pasted text
|
|
122
|
+
// as input rather than consuming \r as part of the paste itself.
|
|
123
|
+
await delay(PTY_INPUT_ENTER_DELAY_MS);
|
|
124
|
+
await writeFrame(sock, encodeMessage(MSG_TERMINAL_INPUT, "\r"));
|
|
125
|
+
finish();
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
finish(err);
|
|
129
|
+
}
|
|
130
|
+
})();
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// ptyHostGetOutput
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
/**
|
|
137
|
+
* Request the last N lines of PTY output from the host.
|
|
138
|
+
* Uses MessageParser to skip any MSG_TERMINAL_DATA frames that arrive before
|
|
139
|
+
* the MSG_GET_OUTPUT_RES response.
|
|
140
|
+
* Returns "" on timeout (3 s) or connection failure.
|
|
141
|
+
*/
|
|
142
|
+
export async function ptyHostGetOutput(pipePath, lines = 50) {
|
|
143
|
+
let sock;
|
|
144
|
+
try {
|
|
145
|
+
sock = await connectPtyHost(pipePath, 3000);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return "";
|
|
149
|
+
}
|
|
150
|
+
return new Promise((resolve) => {
|
|
151
|
+
let settled = false;
|
|
152
|
+
const finish = (result) => {
|
|
153
|
+
if (settled)
|
|
154
|
+
return;
|
|
155
|
+
settled = true;
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
sock.destroy();
|
|
158
|
+
resolve(result);
|
|
159
|
+
};
|
|
160
|
+
const timer = setTimeout(() => finish(""), 3000);
|
|
161
|
+
const parser = new MessageParser((type, payload) => {
|
|
162
|
+
if (type === MSG_GET_OUTPUT_RES) {
|
|
163
|
+
finish(payload.toString("utf-8"));
|
|
164
|
+
}
|
|
165
|
+
// MSG_TERMINAL_DATA and other types are silently ignored
|
|
166
|
+
});
|
|
167
|
+
sock.on("data", (chunk) => parser.feed(chunk));
|
|
168
|
+
sock.once("error", () => finish(""));
|
|
169
|
+
sock.once("close", () => finish(""));
|
|
170
|
+
const req = encodeMessage(MSG_GET_OUTPUT_REQ, JSON.stringify({ lines }));
|
|
171
|
+
sock.write(req);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// ptyHostIsAlive
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
/**
|
|
178
|
+
* Check whether the pty-host process is still alive.
|
|
179
|
+
* Returns false if the pipe is unreachable (host has exited).
|
|
180
|
+
*/
|
|
181
|
+
export async function ptyHostIsAlive(pipePath) {
|
|
182
|
+
let sock;
|
|
183
|
+
try {
|
|
184
|
+
sock = await connectPtyHost(pipePath, 2000);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
return new Promise((resolve) => {
|
|
190
|
+
let settled = false;
|
|
191
|
+
const finish = (result) => {
|
|
192
|
+
if (settled)
|
|
193
|
+
return;
|
|
194
|
+
settled = true;
|
|
195
|
+
clearTimeout(timer);
|
|
196
|
+
sock.destroy();
|
|
197
|
+
resolve(result);
|
|
198
|
+
};
|
|
199
|
+
const timer = setTimeout(() => finish(false), 2000);
|
|
200
|
+
const parser = new MessageParser((type, payload) => {
|
|
201
|
+
if (type === MSG_STATUS_RES) {
|
|
202
|
+
// The pty-host process is alive if we got ANY valid response.
|
|
203
|
+
// Whether the agent inside the PTY has exited (status.alive=false)
|
|
204
|
+
// is a separate concern handled by getActivityState, not isAlive.
|
|
205
|
+
// This mirrors tmux: `tmux has-session` returns true even after
|
|
206
|
+
// the command inside the pane has exited.
|
|
207
|
+
try {
|
|
208
|
+
JSON.parse(payload.toString("utf-8")); // validate it's real JSON
|
|
209
|
+
finish(true);
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
finish(false);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Skip MSG_TERMINAL_DATA and other types
|
|
216
|
+
});
|
|
217
|
+
sock.on("data", (chunk) => parser.feed(chunk));
|
|
218
|
+
sock.once("error", () => finish(false));
|
|
219
|
+
sock.once("close", () => finish(false));
|
|
220
|
+
sock.write(encodeMessage(MSG_STATUS_REQ, ""));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
// ptyHostKill
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
/**
|
|
227
|
+
* Send a kill request to the pty-host. Silently ignores errors — if the
|
|
228
|
+
* pipe is unreachable the process is already dead.
|
|
229
|
+
*/
|
|
230
|
+
export async function ptyHostKill(pipePath) {
|
|
231
|
+
let sock;
|
|
232
|
+
try {
|
|
233
|
+
sock = await connectPtyHost(pipePath, 2000);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
// Already dead — nothing to do
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
await new Promise((resolve) => {
|
|
240
|
+
sock.once("error", () => resolve());
|
|
241
|
+
const frame = encodeMessage(MSG_KILL_REQ, "");
|
|
242
|
+
sock.write(frame, () => {
|
|
243
|
+
sock.end();
|
|
244
|
+
resolve();
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=pty-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-client.js","sourceRoot":"","sources":["../src/pty-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pty-host.ts
|
|
3
|
+
*
|
|
4
|
+
* Dual-purpose file:
|
|
5
|
+
* 1. Module — exports protocol constants, encodeMessage(), and MessageParser
|
|
6
|
+
* (imported by pty-client.ts)
|
|
7
|
+
* 2. Standalone script — when run as `node pty-host.js <args>` it owns a
|
|
8
|
+
* ConPTY session and exposes it over a Windows named pipe so multiple
|
|
9
|
+
* clients can attach/detach (analogous to the tmux daemon).
|
|
10
|
+
*
|
|
11
|
+
* Usage (standalone):
|
|
12
|
+
* node pty-host.js <sessionId> <pipePath> <cwd> <shellCmd> <shellArg1> [shellArg2...]
|
|
13
|
+
*
|
|
14
|
+
* Binary protocol over named pipe:
|
|
15
|
+
* [1-byte type][4-byte big-endian length][payload]
|
|
16
|
+
*
|
|
17
|
+
* 0x01 terminal data host → client raw PTY output bytes
|
|
18
|
+
* 0x02 terminal input client → host raw keystrokes for PTY
|
|
19
|
+
* 0x03 resize client → host JSON { cols, rows }
|
|
20
|
+
* 0x04 get-output req client → host JSON { lines: number }
|
|
21
|
+
* 0x05 get-output res host → client UTF-8 text (last N lines joined)
|
|
22
|
+
* 0x06 status req client → host empty payload
|
|
23
|
+
* 0x07 status res host → client JSON { alive, pid, exitCode? }
|
|
24
|
+
* 0x08 kill req client → host empty payload
|
|
25
|
+
*/
|
|
26
|
+
export declare const MSG_TERMINAL_DATA = 1;
|
|
27
|
+
export declare const MSG_TERMINAL_INPUT = 2;
|
|
28
|
+
export declare const MSG_RESIZE = 3;
|
|
29
|
+
export declare const MSG_GET_OUTPUT_REQ = 4;
|
|
30
|
+
export declare const MSG_GET_OUTPUT_RES = 5;
|
|
31
|
+
export declare const MSG_STATUS_REQ = 6;
|
|
32
|
+
export declare const MSG_STATUS_RES = 7;
|
|
33
|
+
export declare const MSG_KILL_REQ = 8;
|
|
34
|
+
/**
|
|
35
|
+
* Encode a message into the binary framing format.
|
|
36
|
+
* @param type One of the MSG_* constants.
|
|
37
|
+
* @param payload String (UTF-8 encoded) or raw Buffer.
|
|
38
|
+
*/
|
|
39
|
+
export declare function encodeMessage(type: number, payload: Buffer | string): Buffer;
|
|
40
|
+
/**
|
|
41
|
+
* Streaming parser for the binary framing protocol.
|
|
42
|
+
* Feed arbitrary-sized chunks from a TCP/pipe stream and receive complete
|
|
43
|
+
* decoded messages via the onMessage callback.
|
|
44
|
+
*/
|
|
45
|
+
export declare class MessageParser {
|
|
46
|
+
private _buf;
|
|
47
|
+
private readonly _onMessage;
|
|
48
|
+
constructor(onMessage: (type: number, payload: Buffer) => void);
|
|
49
|
+
feed(chunk: Buffer): void;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=pty-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-host.d.ts","sourceRoot":"","sources":["../src/pty-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAQH,eAAO,MAAM,iBAAiB,IAAO,CAAC;AACtC,eAAO,MAAM,kBAAkB,IAAO,CAAC;AACvC,eAAO,MAAM,UAAU,IAAO,CAAC;AAC/B,eAAO,MAAM,kBAAkB,IAAO,CAAC;AACvC,eAAO,MAAM,kBAAkB,IAAO,CAAC;AACvC,eAAO,MAAM,cAAc,IAAO,CAAC;AACnC,eAAO,MAAM,cAAc,IAAO,CAAC;AACnC,eAAO,MAAM,YAAY,IAAO,CAAC;AAMjC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAO5E;AAMD;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;gBAEzD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI;IAI9D,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAe1B"}
|