@amaretto-software-labs/borealis-cli 0.1.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/LICENSE +201 -0
- package/README.md +112 -0
- package/dist/api-client.d.ts +36 -0
- package/dist/api-client.js +673 -0
- package/dist/api-client.js.map +1 -0
- package/dist/app.d.ts +6 -0
- package/dist/app.js +344 -0
- package/dist/app.js.map +1 -0
- package/dist/auth.d.ts +16 -0
- package/dist/auth.js +506 -0
- package/dist/auth.js.map +1 -0
- package/dist/catalog.d.ts +6 -0
- package/dist/catalog.js +15 -0
- package/dist/catalog.js.map +1 -0
- package/dist/command-grammar.d.ts +3 -0
- package/dist/command-grammar.js +274 -0
- package/dist/command-grammar.js.map +1 -0
- package/dist/completion.d.ts +1 -0
- package/dist/completion.js +18 -0
- package/dist/completion.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.js +55 -0
- package/dist/config.js.map +1 -0
- package/dist/credential-file.d.ts +1 -0
- package/dist/credential-file.js +41 -0
- package/dist/credential-file.js.map +1 -0
- package/dist/http-timeout.d.ts +5 -0
- package/dist/http-timeout.js +10 -0
- package/dist/http-timeout.js.map +1 -0
- package/dist/interactive.d.ts +4 -0
- package/dist/interactive.js +158 -0
- package/dist/interactive.js.map +1 -0
- package/dist/invocation.d.ts +13 -0
- package/dist/invocation.js +526 -0
- package/dist/invocation.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +14 -0
- package/dist/main.js.map +1 -0
- package/dist/operations.json +1127 -0
- package/dist/output.d.ts +1 -0
- package/dist/output.js +32 -0
- package/dist/output.js.map +1 -0
- package/dist/secret-file.d.ts +1 -0
- package/dist/secret-file.js +19 -0
- package/dist/secret-file.js.map +1 -0
- package/dist/session-store.d.ts +54 -0
- package/dist/session-store.js +470 -0
- package/dist/session-store.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.js +28 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function writeResult(result: unknown, json: boolean): void;
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function writeResult(result, json) {
|
|
2
|
+
if (result instanceof Uint8Array) {
|
|
3
|
+
process.stdout.write(Buffer.from(result));
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
if (json) {
|
|
7
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(result)) {
|
|
11
|
+
for (const item of result)
|
|
12
|
+
process.stdout.write(`${formatItem(item)}\n`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (result &&
|
|
16
|
+
typeof result === "object" &&
|
|
17
|
+
Array.isArray(result.items)) {
|
|
18
|
+
for (const item of result.items)
|
|
19
|
+
process.stdout.write(`${formatItem(item)}\n`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
process.stdout.write(`${typeof result === "string" ? result : JSON.stringify(result, null, 2)}\n`);
|
|
23
|
+
}
|
|
24
|
+
function formatItem(value) {
|
|
25
|
+
if (!value || typeof value !== "object")
|
|
26
|
+
return String(value);
|
|
27
|
+
return Object.values(value)
|
|
28
|
+
.filter((item) => typeof item !== "object")
|
|
29
|
+
.slice(0, 5)
|
|
30
|
+
.join("\t");
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,MAAe,EAAE,IAAa;IACxD,IAAI,MAAM,YAAY,UAAU,EAAE,CAAC;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,MAAM;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IACD,IACE,MAAM;QACN,OAAO,MAAM,KAAK,QAAQ;QAC1B,KAAK,CAAC,OAAO,CAAE,MAAgC,CAAC,KAAK,CAAC,EACtD,CAAC;QACD,KAAK,MAAM,IAAI,IAAK,MAA+B,CAAC,KAAK;YACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC7E,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC;SACnD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;SAC1C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function readOwnerOnlySecretFile(path: string): Promise<string>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { lstat, readFile } from "node:fs/promises";
|
|
2
|
+
export async function readOwnerOnlySecretFile(path) {
|
|
3
|
+
const metadata = await lstat(path);
|
|
4
|
+
if (!metadata.isFile() || metadata.isSymbolicLink())
|
|
5
|
+
throw new Error(`Secret file '${path}' must be a regular file, not a symlink.`);
|
|
6
|
+
if (metadata.size > 65_536)
|
|
7
|
+
throw new Error(`Secret file '${path}' exceeds 64 KiB.`);
|
|
8
|
+
if (process.platform !== "win32") {
|
|
9
|
+
if ((metadata.mode & 0o077) !== 0)
|
|
10
|
+
throw new Error(`Secret file '${path}' must not be readable or writable by group or other users.`);
|
|
11
|
+
if (process.getuid && metadata.uid !== process.getuid())
|
|
12
|
+
throw new Error(`Secret file '${path}' must be owned by the current user.`);
|
|
13
|
+
}
|
|
14
|
+
const value = (await readFile(path, "utf8")).trim();
|
|
15
|
+
if (!value)
|
|
16
|
+
throw new Error(`Secret file '${path}' is empty.`);
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=secret-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-file.js","sourceRoot":"","sources":["../src/secret-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAAY;IACxD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,QAAQ,CAAC,cAAc,EAAE;QACjD,MAAM,IAAI,KAAK,CACb,gBAAgB,IAAI,0CAA0C,CAC/D,CAAC;IACJ,IAAI,QAAQ,CAAC,IAAI,GAAG,MAAM;QACxB,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,mBAAmB,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,gBAAgB,IAAI,6DAA6D,CAClF,CAAC;QACJ,IAAI,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE;YACrD,MAAM,IAAI,KAAK,CACb,gBAAgB,IAAI,sCAAsC,CAC3D,CAAC;IACN,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,aAAa,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type Session } from "./types.js";
|
|
2
|
+
export interface NativeCommandOptions {
|
|
3
|
+
env?: NodeJS.ProcessEnv;
|
|
4
|
+
input?: string;
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export type NativeCommandExecutor = (file: string, arguments_: readonly string[], options?: NativeCommandOptions) => Promise<{
|
|
9
|
+
stdout: string;
|
|
10
|
+
stderr: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const executeBoundedNativeCommand: NativeCommandExecutor;
|
|
13
|
+
export type CredentialFileDescriptorExecutor = (file: string, arguments_: readonly string[], program: string, secret: string, signal?: AbortSignal) => Promise<{
|
|
14
|
+
stdout: string;
|
|
15
|
+
stderr: string;
|
|
16
|
+
}>;
|
|
17
|
+
export interface SessionSecretStore {
|
|
18
|
+
read(signal?: AbortSignal): Promise<string | undefined>;
|
|
19
|
+
write(value: string, signal?: AbortSignal): Promise<void>;
|
|
20
|
+
clear(signal?: AbortSignal): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export declare class NativeSessionSecretStore implements SessionSecretStore {
|
|
23
|
+
private readonly account;
|
|
24
|
+
private readonly platform;
|
|
25
|
+
private readonly encryptedPath;
|
|
26
|
+
private readonly execute;
|
|
27
|
+
constructor(account: string, platform?: NodeJS.Platform, encryptedPath?: string, execute?: NativeCommandExecutor);
|
|
28
|
+
read(signal?: AbortSignal): Promise<string | undefined>;
|
|
29
|
+
write(value: string, signal?: AbortSignal): Promise<void>;
|
|
30
|
+
clear(signal?: AbortSignal): Promise<void>;
|
|
31
|
+
private powerShell;
|
|
32
|
+
}
|
|
33
|
+
export declare class FileSessionSecretStore implements SessionSecretStore {
|
|
34
|
+
private readonly path;
|
|
35
|
+
constructor(path: string);
|
|
36
|
+
read(signal?: AbortSignal): Promise<string | undefined>;
|
|
37
|
+
write(value: string, signal?: AbortSignal): Promise<void>;
|
|
38
|
+
clear(signal?: AbortSignal): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare class SecureFallbackSessionSecretStore implements SessionSecretStore {
|
|
41
|
+
private readonly secure;
|
|
42
|
+
private readonly insecure;
|
|
43
|
+
private readonly allowInsecure;
|
|
44
|
+
constructor(secure: SessionSecretStore, insecure: SessionSecretStore, allowInsecure?: () => boolean);
|
|
45
|
+
read(signal?: AbortSignal): Promise<string | undefined>;
|
|
46
|
+
write(value: string, signal?: AbortSignal): Promise<void>;
|
|
47
|
+
clear(signal?: AbortSignal): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
export declare function loadSession(profile: string, signal?: AbortSignal): Promise<Session | undefined>;
|
|
50
|
+
export declare function saveSession(profile: string, session: Session, signal?: AbortSignal): Promise<void>;
|
|
51
|
+
export declare function deleteSession(profile: string, signal?: AbortSignal): Promise<void>;
|
|
52
|
+
export declare function writeMacOSKeychainCredential(serviceName: string, account: string, secret: string, execute?: CredentialFileDescriptorExecutor, signal?: AbortSignal): Promise<void>;
|
|
53
|
+
export declare function readMacOSKeychainCredential(serviceName: string, account: string, execute?: CredentialFileDescriptorExecutor, signal?: AbortSignal): Promise<string | null>;
|
|
54
|
+
export declare function deleteMacOSKeychainCredential(serviceName: string, account: string, execute?: CredentialFileDescriptorExecutor, signal?: AbortSignal): Promise<void>;
|
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { configDirectory } from "./config.js";
|
|
5
|
+
import { sessionSchema } from "./types.js";
|
|
6
|
+
const service = "com.amarettosoftwarelabs.borealis-cli";
|
|
7
|
+
const profilePattern = /^[A-Za-z0-9._-]{1,64}$/;
|
|
8
|
+
const insecureFileOptIn = "BOREALIS_CLI_ALLOW_INSECURE_FILE_SESSION";
|
|
9
|
+
function terminateProcessTree(child, platform = process.platform) {
|
|
10
|
+
if (!child.pid) {
|
|
11
|
+
child.kill("SIGKILL");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (platform === "win32") {
|
|
15
|
+
const killer = spawn("taskkill.exe", ["/pid", String(child.pid), "/t", "/f"], { stdio: "ignore", windowsHide: true });
|
|
16
|
+
killer.once("error", () => child.kill("SIGKILL"));
|
|
17
|
+
killer.unref();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
process.kill(-child.pid, "SIGKILL");
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
child.kill("SIGKILL");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export const executeBoundedNativeCommand = async (file, arguments_, options = {}) => {
|
|
28
|
+
options.signal?.throwIfAborted();
|
|
29
|
+
return await new Promise((resolvePromise, reject) => {
|
|
30
|
+
const child = spawn(file, arguments_, {
|
|
31
|
+
detached: true,
|
|
32
|
+
env: options.env,
|
|
33
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
34
|
+
windowsHide: true,
|
|
35
|
+
});
|
|
36
|
+
let settled = false;
|
|
37
|
+
let outputBytes = 0;
|
|
38
|
+
const stdout = [];
|
|
39
|
+
const stderr = [];
|
|
40
|
+
const cleanup = () => {
|
|
41
|
+
clearTimeout(timeout);
|
|
42
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
43
|
+
};
|
|
44
|
+
const finish = (error, terminate = true) => {
|
|
45
|
+
if (settled)
|
|
46
|
+
return;
|
|
47
|
+
settled = true;
|
|
48
|
+
cleanup();
|
|
49
|
+
if (error) {
|
|
50
|
+
if (terminate)
|
|
51
|
+
terminateProcessTree(child);
|
|
52
|
+
reject(error);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
resolvePromise({
|
|
56
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
57
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const onAbort = () => finish(options.signal?.reason instanceof Error
|
|
62
|
+
? options.signal.reason
|
|
63
|
+
: new DOMException("Aborted", "AbortError"));
|
|
64
|
+
const timeout = setTimeout(() => finish(new DOMException(`'${file}' timed out.`, "TimeoutError")), options.timeoutMs ?? 15_000);
|
|
65
|
+
timeout.unref();
|
|
66
|
+
const trackOutput = (target) => (chunk) => {
|
|
67
|
+
outputBytes += chunk.length;
|
|
68
|
+
if (outputBytes > 1024 * 1024)
|
|
69
|
+
finish(new Error(`'${file}' produced too much output.`));
|
|
70
|
+
else
|
|
71
|
+
target.push(chunk);
|
|
72
|
+
};
|
|
73
|
+
child.stdout?.on("data", trackOutput(stdout));
|
|
74
|
+
child.stderr?.on("data", trackOutput(stderr));
|
|
75
|
+
child.stdin?.once("error", (error) => finish(error));
|
|
76
|
+
child.once("error", (error) => finish(error, false));
|
|
77
|
+
child.once("close", (code) => {
|
|
78
|
+
if (code === 0) {
|
|
79
|
+
finish();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const error = new Error(`'${file}' exited with status ${code ?? -1}.`);
|
|
83
|
+
error.code = code ?? -1;
|
|
84
|
+
error.stderr = Buffer.concat(stderr).toString("utf8");
|
|
85
|
+
finish(error, false);
|
|
86
|
+
});
|
|
87
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
88
|
+
if (options.signal?.aborted) {
|
|
89
|
+
onAbort();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
child.stdin?.end(options.input ?? "");
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const macOSCredentialProgram = String.raw `ObjC.import("Foundation");
|
|
96
|
+
ObjC.import("Security");
|
|
97
|
+
|
|
98
|
+
function run(argv) {
|
|
99
|
+
if (argv.length !== 3) throw new Error("Expected operation, service, and account.");
|
|
100
|
+
const operation = argv[0];
|
|
101
|
+
const value = (item) => $.NSString.stringWithString(item);
|
|
102
|
+
const constant = (item) => ObjC.castRefToObject(item);
|
|
103
|
+
const query = $.NSMutableDictionary.alloc.init;
|
|
104
|
+
query.setObjectForKey(constant($.kSecClassGenericPassword), constant($.kSecClass));
|
|
105
|
+
query.setObjectForKey(value(argv[1]), constant($.kSecAttrService));
|
|
106
|
+
query.setObjectForKey(value(argv[2]), constant($.kSecAttrAccount));
|
|
107
|
+
|
|
108
|
+
if (operation === "get") {
|
|
109
|
+
query.setObjectForKey($.NSNumber.numberWithBool(true), constant($.kSecReturnData));
|
|
110
|
+
query.setObjectForKey(constant($.kSecMatchLimitOne), constant($.kSecMatchLimit));
|
|
111
|
+
const result = Ref();
|
|
112
|
+
const status = Number($.SecItemCopyMatching(query, result));
|
|
113
|
+
if (status === Number($.errSecItemNotFound)) return "missing";
|
|
114
|
+
if (status !== Number($.errSecSuccess))
|
|
115
|
+
throw new Error("Keychain read failed with status " + status + ".");
|
|
116
|
+
const secretData = ObjC.castRefToObject(result[0]);
|
|
117
|
+
return "value:" + ObjC.unwrap(secretData.base64EncodedStringWithOptions(0));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (operation === "delete") {
|
|
121
|
+
const status = Number($.SecItemDelete(query));
|
|
122
|
+
if (status !== Number($.errSecSuccess) && status !== Number($.errSecItemNotFound))
|
|
123
|
+
throw new Error("Keychain deletion failed with status " + status + ".");
|
|
124
|
+
return "deleted";
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (operation !== "set") throw new Error("Unsupported Keychain operation.");
|
|
128
|
+
const secretHandle = $.NSFileHandle.alloc.initWithFileDescriptorCloseOnDealloc(3, false);
|
|
129
|
+
const secretData = secretHandle.readDataToEndOfFile;
|
|
130
|
+
if (Number(secretData.length) === 0) throw new Error("Credential data is empty.");
|
|
131
|
+
const attributes = $.NSMutableDictionary.alloc.init;
|
|
132
|
+
attributes.setObjectForKey(secretData, constant($.kSecValueData));
|
|
133
|
+
let status = Number($.SecItemUpdate(query, attributes));
|
|
134
|
+
if (status === Number($.errSecItemNotFound)) {
|
|
135
|
+
query.setObjectForKey(secretData, constant($.kSecValueData));
|
|
136
|
+
status = Number($.SecItemAdd(query, null));
|
|
137
|
+
}
|
|
138
|
+
if (status !== Number($.errSecSuccess))
|
|
139
|
+
throw new Error("Keychain write failed with status " + status + ".");
|
|
140
|
+
return "stored";
|
|
141
|
+
}
|
|
142
|
+
`;
|
|
143
|
+
const executeCredentialFileDescriptorCommand = async (file, arguments_, program, secret, signal) => {
|
|
144
|
+
signal?.throwIfAborted();
|
|
145
|
+
return await new Promise((resolvePromise, reject) => {
|
|
146
|
+
const child = spawn(file, arguments_, {
|
|
147
|
+
detached: true,
|
|
148
|
+
stdio: ["pipe", "pipe", "pipe", "pipe"],
|
|
149
|
+
});
|
|
150
|
+
let settled = false;
|
|
151
|
+
let outputBytes = 0;
|
|
152
|
+
const stdout = [];
|
|
153
|
+
const stderr = [];
|
|
154
|
+
const finish = (error) => {
|
|
155
|
+
if (settled)
|
|
156
|
+
return;
|
|
157
|
+
settled = true;
|
|
158
|
+
clearTimeout(timeout);
|
|
159
|
+
signal?.removeEventListener("abort", onAbort);
|
|
160
|
+
if (error) {
|
|
161
|
+
try {
|
|
162
|
+
if (child.pid)
|
|
163
|
+
process.kill(-child.pid, "SIGKILL");
|
|
164
|
+
else
|
|
165
|
+
child.kill("SIGKILL");
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
child.kill("SIGKILL");
|
|
169
|
+
}
|
|
170
|
+
reject(error);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
resolvePromise({
|
|
174
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
175
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const timeout = setTimeout(() => finish(new Error(`'${file}' timed out.`)), 15_000);
|
|
180
|
+
timeout.unref();
|
|
181
|
+
const onAbort = () => finish(signal?.reason instanceof Error
|
|
182
|
+
? signal.reason
|
|
183
|
+
: new DOMException("Aborted", "AbortError"));
|
|
184
|
+
const trackOutput = (target) => (chunk) => {
|
|
185
|
+
outputBytes += chunk.length;
|
|
186
|
+
if (outputBytes > 64 * 1024)
|
|
187
|
+
finish(new Error(`'${file}' produced too much output.`));
|
|
188
|
+
else
|
|
189
|
+
target.push(chunk);
|
|
190
|
+
};
|
|
191
|
+
child.stdout?.on("data", trackOutput(stdout));
|
|
192
|
+
child.stderr?.on("data", trackOutput(stderr));
|
|
193
|
+
child.once("error", finish);
|
|
194
|
+
child.once("close", (code) => code === 0
|
|
195
|
+
? finish()
|
|
196
|
+
: finish(new Error(`'${file}' exited with status ${code ?? -1}.`)));
|
|
197
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
198
|
+
if (signal?.aborted) {
|
|
199
|
+
onAbort();
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const secretPipe = child.stdio[3];
|
|
203
|
+
if (!child.stdin || !secretPipe) {
|
|
204
|
+
finish(new Error("Unable to open credential process pipes."));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
child.stdin.once("error", finish);
|
|
208
|
+
secretPipe.once("error", finish);
|
|
209
|
+
child.stdin.end(program);
|
|
210
|
+
secretPipe.end(secret);
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
export class NativeSessionSecretStore {
|
|
214
|
+
account;
|
|
215
|
+
platform;
|
|
216
|
+
encryptedPath;
|
|
217
|
+
execute;
|
|
218
|
+
constructor(account, platform = process.platform, encryptedPath = join(configDirectory, `${account.replace(/[^A-Za-z0-9._-]/g, "_")}.session.dpapi`), execute = executeBoundedNativeCommand) {
|
|
219
|
+
this.account = account;
|
|
220
|
+
this.platform = platform;
|
|
221
|
+
this.encryptedPath = encryptedPath;
|
|
222
|
+
this.execute = execute;
|
|
223
|
+
}
|
|
224
|
+
async read(signal) {
|
|
225
|
+
signal?.throwIfAborted();
|
|
226
|
+
try {
|
|
227
|
+
if (this.platform === "darwin") {
|
|
228
|
+
return ((await readMacOSKeychainCredential(service, this.account, executeCredentialFileDescriptorCommand, signal)) ?? undefined);
|
|
229
|
+
}
|
|
230
|
+
if (this.platform === "linux") {
|
|
231
|
+
const { stdout } = await this.execute("secret-tool", ["lookup", "service", service, "account", this.account], { ...(signal ? { signal } : {}) });
|
|
232
|
+
return stdout.replace(/\r?\n$/, "") || undefined;
|
|
233
|
+
}
|
|
234
|
+
if (this.platform === "win32") {
|
|
235
|
+
const { stdout } = await this.powerShell(`
|
|
236
|
+
Add-Type -AssemblyName System.Security
|
|
237
|
+
if (-not [IO.File]::Exists($env:BOREALIS_CLI_SECRET_PATH)) { exit 44 }
|
|
238
|
+
$raw = [IO.File]::ReadAllText($env:BOREALIS_CLI_SECRET_PATH)
|
|
239
|
+
$protected = [Convert]::FromBase64String($raw)
|
|
240
|
+
$bytes = [Security.Cryptography.ProtectedData]::Unprotect($protected, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)
|
|
241
|
+
[Console]::Out.Write([Text.Encoding]::UTF8.GetString($bytes))
|
|
242
|
+
`, {}, signal);
|
|
243
|
+
return stdout || undefined;
|
|
244
|
+
}
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
if (signal?.aborted)
|
|
249
|
+
throw signal.reason;
|
|
250
|
+
if (this.platform === "linux" && isMissingLinuxSecret(error))
|
|
251
|
+
return undefined;
|
|
252
|
+
if (this.platform === "win32" && isMissingWindowsSecret(error))
|
|
253
|
+
return undefined;
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async write(value, signal) {
|
|
258
|
+
signal?.throwIfAborted();
|
|
259
|
+
try {
|
|
260
|
+
if (this.platform === "darwin") {
|
|
261
|
+
await writeMacOSKeychainCredential(service, this.account, value, executeCredentialFileDescriptorCommand, signal);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (this.platform === "linux") {
|
|
265
|
+
await this.execute("secret-tool", [
|
|
266
|
+
"store",
|
|
267
|
+
"--label",
|
|
268
|
+
"Borealis CLI auth session",
|
|
269
|
+
"service",
|
|
270
|
+
service,
|
|
271
|
+
"account",
|
|
272
|
+
this.account,
|
|
273
|
+
], { input: value, ...(signal ? { signal } : {}) });
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (this.platform === "win32") {
|
|
277
|
+
await mkdir(configDirectory, { recursive: true });
|
|
278
|
+
await this.powerShell(`
|
|
279
|
+
Add-Type -AssemblyName System.Security
|
|
280
|
+
$bytes = [Text.Encoding]::UTF8.GetBytes($env:BOREALIS_CLI_SECRET_VALUE)
|
|
281
|
+
$protected = [Security.Cryptography.ProtectedData]::Protect($bytes, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)
|
|
282
|
+
[IO.File]::WriteAllText($env:BOREALIS_CLI_SECRET_PATH, [Convert]::ToBase64String($protected))
|
|
283
|
+
`, { BOREALIS_CLI_SECRET_VALUE: value }, signal);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
throw new Error(`Unsupported platform '${this.platform}'.`);
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
if (signal?.aborted)
|
|
290
|
+
throw signal.reason;
|
|
291
|
+
throw new Error(`Native Borealis CLI credential storage is unavailable.${error instanceof Error && error.message ? ` ${error.message}` : ""}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async clear(signal) {
|
|
295
|
+
signal?.throwIfAborted();
|
|
296
|
+
try {
|
|
297
|
+
if (this.platform === "darwin")
|
|
298
|
+
await deleteMacOSKeychainCredential(service, this.account, executeCredentialFileDescriptorCommand, signal);
|
|
299
|
+
else if (this.platform === "linux")
|
|
300
|
+
await this.execute("secret-tool", ["clear", "service", service, "account", this.account], { ...(signal ? { signal } : {}) });
|
|
301
|
+
else if (this.platform === "win32") {
|
|
302
|
+
await rm(this.encryptedPath, { force: true });
|
|
303
|
+
signal?.throwIfAborted();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
if (signal?.aborted)
|
|
308
|
+
throw signal.reason;
|
|
309
|
+
if (this.platform === "linux" && isMissingLinuxSecret(error))
|
|
310
|
+
return;
|
|
311
|
+
throw error;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
async powerShell(script, environment = {}, signal) {
|
|
315
|
+
return await this.execute("powershell.exe", [
|
|
316
|
+
"-NoProfile",
|
|
317
|
+
"-NonInteractive",
|
|
318
|
+
"-ExecutionPolicy",
|
|
319
|
+
"Bypass",
|
|
320
|
+
"-Command",
|
|
321
|
+
script,
|
|
322
|
+
], {
|
|
323
|
+
env: {
|
|
324
|
+
...process.env,
|
|
325
|
+
BOREALIS_CLI_SECRET_PATH: resolve(this.encryptedPath),
|
|
326
|
+
...environment,
|
|
327
|
+
},
|
|
328
|
+
...(signal ? { signal } : {}),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function isMissingLinuxSecret(error) {
|
|
333
|
+
const failure = error;
|
|
334
|
+
return failure.code === 1 && !failure.stderr?.trim();
|
|
335
|
+
}
|
|
336
|
+
function isMissingWindowsSecret(error) {
|
|
337
|
+
return error.code === 44;
|
|
338
|
+
}
|
|
339
|
+
export class FileSessionSecretStore {
|
|
340
|
+
path;
|
|
341
|
+
constructor(path) {
|
|
342
|
+
this.path = path;
|
|
343
|
+
}
|
|
344
|
+
async read(signal) {
|
|
345
|
+
signal?.throwIfAborted();
|
|
346
|
+
const value = await readFile(this.path, "utf8").catch(() => undefined);
|
|
347
|
+
signal?.throwIfAborted();
|
|
348
|
+
return value;
|
|
349
|
+
}
|
|
350
|
+
async write(value, signal) {
|
|
351
|
+
signal?.throwIfAborted();
|
|
352
|
+
await mkdir(configDirectory, { recursive: true, mode: 0o700 });
|
|
353
|
+
if (process.platform !== "win32")
|
|
354
|
+
await chmod(configDirectory, 0o700);
|
|
355
|
+
await writeFile(this.path, value, { mode: 0o600, flag: "w" });
|
|
356
|
+
if (process.platform !== "win32")
|
|
357
|
+
await chmod(this.path, 0o600);
|
|
358
|
+
signal?.throwIfAborted();
|
|
359
|
+
}
|
|
360
|
+
async clear(signal) {
|
|
361
|
+
signal?.throwIfAborted();
|
|
362
|
+
await rm(this.path, { force: true });
|
|
363
|
+
signal?.throwIfAborted();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
export class SecureFallbackSessionSecretStore {
|
|
367
|
+
secure;
|
|
368
|
+
insecure;
|
|
369
|
+
allowInsecure;
|
|
370
|
+
constructor(secure, insecure, allowInsecure = () => process.env[insecureFileOptIn] === "1") {
|
|
371
|
+
this.secure = secure;
|
|
372
|
+
this.insecure = insecure;
|
|
373
|
+
this.allowInsecure = allowInsecure;
|
|
374
|
+
}
|
|
375
|
+
async read(signal) {
|
|
376
|
+
try {
|
|
377
|
+
const value = await this.secure.read(signal);
|
|
378
|
+
if (value)
|
|
379
|
+
return value;
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
if (signal?.aborted)
|
|
383
|
+
throw error;
|
|
384
|
+
if (error instanceof DOMException && error.name === "TimeoutError")
|
|
385
|
+
throw error;
|
|
386
|
+
// A missing platform keychain is treated as no stored session.
|
|
387
|
+
}
|
|
388
|
+
return this.allowInsecure() ? await this.insecure.read(signal) : undefined;
|
|
389
|
+
}
|
|
390
|
+
async write(value, signal) {
|
|
391
|
+
try {
|
|
392
|
+
await this.secure.write(value, signal);
|
|
393
|
+
await this.insecure.clear(signal);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
if (signal?.aborted)
|
|
398
|
+
throw error;
|
|
399
|
+
if (!this.allowInsecure())
|
|
400
|
+
throw new Error(`Secure Borealis CLI credential storage is unavailable. Install platform keychain support, or explicitly set ${insecureFileOptIn}=1 to opt in to plaintext local session storage.`, { cause: error });
|
|
401
|
+
}
|
|
402
|
+
await this.insecure.write(value, signal);
|
|
403
|
+
}
|
|
404
|
+
async clear(signal) {
|
|
405
|
+
let secureFailure;
|
|
406
|
+
try {
|
|
407
|
+
await this.secure.clear(signal);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
if (signal?.aborted)
|
|
411
|
+
throw error;
|
|
412
|
+
secureFailure = error;
|
|
413
|
+
}
|
|
414
|
+
let insecureFailure;
|
|
415
|
+
try {
|
|
416
|
+
await this.insecure.clear(signal);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
if (signal?.aborted)
|
|
420
|
+
throw error;
|
|
421
|
+
insecureFailure = error;
|
|
422
|
+
}
|
|
423
|
+
if (secureFailure && insecureFailure)
|
|
424
|
+
throw new AggregateError([secureFailure, insecureFailure], "Secure and fallback session deletion both failed.");
|
|
425
|
+
if (secureFailure)
|
|
426
|
+
throw secureFailure;
|
|
427
|
+
if (insecureFailure)
|
|
428
|
+
throw insecureFailure;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function validateProfile(profile) {
|
|
432
|
+
if (!profilePattern.test(profile))
|
|
433
|
+
throw new Error("Profile names may contain only 1-64 letters, digits, dots, underscores, or hyphens.");
|
|
434
|
+
}
|
|
435
|
+
function sessionStore(profile) {
|
|
436
|
+
const account = `auth-session:${profile}`;
|
|
437
|
+
return new SecureFallbackSessionSecretStore(new NativeSessionSecretStore(account), new FileSessionSecretStore(join(configDirectory, `${profile}.json`)));
|
|
438
|
+
}
|
|
439
|
+
export async function loadSession(profile, signal) {
|
|
440
|
+
validateProfile(profile);
|
|
441
|
+
const stored = await sessionStore(profile).read(signal);
|
|
442
|
+
return stored ? sessionSchema.parse(JSON.parse(stored)) : undefined;
|
|
443
|
+
}
|
|
444
|
+
export async function saveSession(profile, session, signal) {
|
|
445
|
+
validateProfile(profile);
|
|
446
|
+
await sessionStore(profile).write(JSON.stringify(session), signal);
|
|
447
|
+
}
|
|
448
|
+
export async function deleteSession(profile, signal) {
|
|
449
|
+
validateProfile(profile);
|
|
450
|
+
await sessionStore(profile).clear(signal);
|
|
451
|
+
}
|
|
452
|
+
export async function writeMacOSKeychainCredential(serviceName, account, secret, execute = executeCredentialFileDescriptorCommand, signal) {
|
|
453
|
+
await executeMacOSKeychainCredential("set", serviceName, account, secret, execute, signal);
|
|
454
|
+
}
|
|
455
|
+
export async function readMacOSKeychainCredential(serviceName, account, execute = executeCredentialFileDescriptorCommand, signal) {
|
|
456
|
+
const value = await executeMacOSKeychainCredential("get", serviceName, account, "", execute, signal);
|
|
457
|
+
if (value === "missing")
|
|
458
|
+
return null;
|
|
459
|
+
if (!value.startsWith("value:"))
|
|
460
|
+
throw new Error("Keychain returned an invalid response.");
|
|
461
|
+
return Buffer.from(value.slice("value:".length), "base64").toString("utf8");
|
|
462
|
+
}
|
|
463
|
+
export async function deleteMacOSKeychainCredential(serviceName, account, execute = executeCredentialFileDescriptorCommand, signal) {
|
|
464
|
+
await executeMacOSKeychainCredential("delete", serviceName, account, "", execute, signal);
|
|
465
|
+
}
|
|
466
|
+
async function executeMacOSKeychainCredential(operation, serviceName, account, secret, execute, signal) {
|
|
467
|
+
const result = await execute("/usr/bin/osascript", ["-l", "JavaScript", "-", operation, serviceName, account], macOSCredentialProgram, secret, signal);
|
|
468
|
+
return result.stdout.replace(/\r?\n$/, "");
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=session-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAG,uCAAuC,CAAC;AACxD,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAChD,MAAM,iBAAiB,GAAG,0CAA0C,CAAC;AAerE,SAAS,oBAAoB,CAC3B,KAA+B,EAC/B,WAA4B,OAAO,CAAC,QAAQ;IAE5C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,OAAO;IACT,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,KAAK,CAClB,cAAc,EACd,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EACvC,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CACvC,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,2BAA2B,GAA0B,KAAK,EACrE,IAAI,EACJ,UAAU,EACV,OAAO,GAAG,EAAE,EACZ,EAAE;IACF,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IACjC,OAAO,MAAM,IAAI,OAAO,CACtB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE;YACpC,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,SAAS,GAAG,IAAI,EAAQ,EAAE;YACvD,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,EAAE,CAAC;YACV,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,SAAS;oBAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC;gBAC3C,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,cAAc,CAAC;oBACb,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;iBAC/C,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,GAAS,EAAE,CACzB,MAAM,CACJ,OAAO,CAAC,MAAM,EAAE,MAAM,YAAY,KAAK;YACrC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM;YACvB,CAAC,CAAC,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAC9C,CAAC;QACJ,MAAM,OAAO,GAAG,UAAU,CACxB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,IAAI,IAAI,cAAc,EAAE,cAAc,CAAC,CAAC,EACtE,OAAO,CAAC,SAAS,IAAI,MAAM,CAC5B,CAAC;QACF,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,WAAW,GAAG,CAAC,MAAgB,EAAE,EAAE,CAAC,CAAC,KAAa,EAAE,EAAE;YAC1D,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;YAC5B,IAAI,WAAW,GAAG,IAAI,GAAG,IAAI;gBAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,6BAA6B,CAAC,CAAC,CAAC;;gBACtD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC;QACF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,MAAM,EAAE,CAAC;gBACT,OAAO;YACT,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,IAAI,IAAI,wBAAwB,IAAI,IAAI,CAAC,CAAC,GAAG,CACS,CAAC;YACzD,KAAK,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC;YACxB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAUF,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CxC,CAAC;AAEF,MAAM,sCAAsC,GAC1C,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;IAClD,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,OAAO,MAAM,IAAI,OAAO,CACtB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE;YACpC,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SACxC,CAAC,CAAC;QACH,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC;oBACH,IAAI,KAAK,CAAC,GAAG;wBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;;wBAC9C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC7B,CAAC;gBAAC,MAAM,CAAC;oBACP,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,cAAc,CAAC;oBACb,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;iBAC/C,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,UAAU,CACxB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,cAAc,CAAC,CAAC,EAC/C,MAAM,CACP,CAAC;QACF,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,GAAS,EAAE,CACzB,MAAM,CACJ,MAAM,EAAE,MAAM,YAAY,KAAK;YAC7B,CAAC,CAAC,MAAM,CAAC,MAAM;YACf,CAAC,CAAC,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAC9C,CAAC;QACJ,MAAM,WAAW,GAAG,CAAC,MAAgB,EAAE,EAAE,CAAC,CAAC,KAAa,EAAE,EAAE;YAC1D,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;YAC5B,IAAI,WAAW,GAAG,EAAE,GAAG,IAAI;gBACzB,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,6BAA6B,CAAC,CAAC,CAAC;;gBACtD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC;QACF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3B,IAAI,KAAK,CAAC;YACR,CAAC,CAAC,MAAM,EAAE;YACV,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,wBAAwB,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CACrE,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAC+B,CAAC;QAChE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAClC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAQJ,MAAM,OAAO,wBAAwB;IAEhB;IACA;IACA;IAIA;IAPnB,YACmB,OAAe,EACf,WAAW,OAAO,CAAC,QAAQ,EAC3B,gBAAgB,IAAI,CACnC,eAAe,EACf,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,gBAAgB,CAC5D,EACgB,UAAiC,2BAA2B;QAN5D,YAAO,GAAP,OAAO,CAAQ;QACf,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,kBAAa,GAAb,aAAa,CAG7B;QACgB,YAAO,GAAP,OAAO,CAAqD;IAC5E,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,MAAoB;QAC7B,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/B,OAAO,CACL,CAAC,MAAM,2BAA2B,CAChC,OAAO,EACP,IAAI,CAAC,OAAO,EACZ,sCAAsC,EACtC,MAAM,CACP,CAAC,IAAI,SAAS,CAChB,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CACnC,aAAa,EACb,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EACvD,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAClC,CAAC;gBACF,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;YACnD,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CACtC;;;;;;;CAOT,EACS,EAAE,EACF,MAAM,CACP,CAAC;gBACF,OAAO,MAAM,IAAI,SAAS,CAAC;YAC7B,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,MAAM,CAAC,MAAM,CAAC;YACzC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,oBAAoB,CAAC,KAAK,CAAC;gBAC1D,OAAO,SAAS,CAAC;YACnB,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,sBAAsB,CAAC,KAAK,CAAC;gBAC5D,OAAO,SAAS,CAAC;YACnB,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,MAAoB;QAC7C,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,4BAA4B,CAChC,OAAO,EACP,IAAI,CAAC,OAAO,EACZ,KAAK,EACL,sCAAsC,EACtC,MAAM,CACP,CAAC;gBACF,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC9B,MAAM,IAAI,CAAC,OAAO,CAChB,aAAa,EACb;oBACE,OAAO;oBACP,SAAS;oBACT,2BAA2B;oBAC3B,SAAS;oBACT,OAAO;oBACP,SAAS;oBACT,IAAI,CAAC,OAAO;iBACb,EACD,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAChD,CAAC;gBACF,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,MAAM,IAAI,CAAC,UAAU,CACnB;;;;;WAKC,EACD,EAAE,yBAAyB,EAAE,KAAK,EAAE,EACpC,MAAM,CACP,CAAC;gBACF,OAAO;YACT,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,MAAM,CAAC,MAAM,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,yDAAyD,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9H,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAoB;QAC9B,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,6BAA6B,CACjC,OAAO,EACP,IAAI,CAAC,OAAO,EACZ,sCAAsC,EACtC,MAAM,CACP,CAAC;iBACC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO;gBAChC,MAAM,IAAI,CAAC,OAAO,CAChB,aAAa,EACb,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EACtD,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAClC,CAAC;iBACC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACnC,MAAM,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9C,MAAM,EAAE,cAAc,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,MAAM,CAAC,MAAM,CAAC;YACzC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,oBAAoB,CAAC,KAAK,CAAC;gBAAE,OAAO;YACrE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU,CACtB,MAAc,EACd,cAAsC,EAAE,EACxC,MAAoB;QAEpB,OAAO,MAAM,IAAI,CAAC,OAAO,CACvB,gBAAgB,EAChB;YACE,YAAY;YACZ,iBAAiB;YACjB,kBAAkB;YAClB,QAAQ;YACR,UAAU;YACV,MAAM;SACP,EACD;YACE,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,wBAAwB,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC;gBACrD,GAAG,WAAW;aACf;YACD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CACF,CAAC;IACJ,CAAC;CACF;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,MAAM,OAAO,GAAG,KAAoD,CAAC;IACrE,OAAO,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AACvD,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc;IAC5C,OAAQ,KAAoC,CAAC,IAAI,KAAK,EAAE,CAAC;AAC3D,CAAC;AAED,MAAM,OAAO,sBAAsB;IACJ;IAA7B,YAA6B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE7C,KAAK,CAAC,IAAI,CAAC,MAAoB;QAC7B,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACvE,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,MAAoB;QAC7C,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,MAAM,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACtE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,EAAE,cAAc,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAoB;QAC9B,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,MAAM,EAAE,cAAc,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,gCAAgC;IAExB;IACA;IACA;IAHnB,YACmB,MAA0B,EAC1B,QAA4B,EAC5B,gBAAgB,GAAG,EAAE,CACpC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,GAAG;QAHvB,WAAM,GAAN,MAAM,CAAoB;QAC1B,aAAQ,GAAR,QAAQ,CAAoB;QAC5B,kBAAa,GAAb,aAAa,CACU;IACvC,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,MAAoB;QAC7B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;YACjC,IAAI,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAChE,MAAM,KAAK,CAAC;YACd,+DAA+D;QACjE,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,MAAoB;QAC7C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;gBACvB,MAAM,IAAI,KAAK,CACb,+GAA+G,iBAAiB,kDAAkD,EAClL,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACN,CAAC;QACD,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAoB;QAC9B,IAAI,aAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;YACjC,aAAa,GAAG,KAAK,CAAC;QACxB,CAAC;QACD,IAAI,eAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;YACjC,eAAe,GAAG,KAAK,CAAC;QAC1B,CAAC;QACD,IAAI,aAAa,IAAI,eAAe;YAClC,MAAM,IAAI,cAAc,CACtB,CAAC,aAAa,EAAE,eAAe,CAAC,EAChC,mDAAmD,CACpD,CAAC;QACJ,IAAI,aAAa;YAAE,MAAM,aAAa,CAAC;QACvC,IAAI,eAAe;YAAE,MAAM,eAAe,CAAC;IAC7C,CAAC;CACF;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;AACN,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,OAAO,GAAG,gBAAgB,OAAO,EAAE,CAAC;IAC1C,OAAO,IAAI,gCAAgC,CACzC,IAAI,wBAAwB,CAAC,OAAO,CAAC,EACrC,IAAI,sBAAsB,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC,CACrE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAe,EACf,MAAoB;IAEpB,eAAe,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAe,EACf,OAAgB,EAChB,MAAoB;IAEpB,eAAe,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAe,EACf,MAAoB;IAEpB,eAAe,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,WAAmB,EACnB,OAAe,EACf,MAAc,EACd,UAA4C,sCAAsC,EAClF,MAAoB;IAEpB,MAAM,8BAA8B,CAClC,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,WAAmB,EACnB,OAAe,EACf,UAA4C,sCAAsC,EAClF,MAAoB;IAEpB,MAAM,KAAK,GAAG,MAAM,8BAA8B,CAChD,KAAK,EACL,WAAW,EACX,OAAO,EACP,EAAE,EACF,OAAO,EACP,MAAM,CACP,CAAC;IACF,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,WAAmB,EACnB,OAAe,EACf,UAA4C,sCAAsC,EAClF,MAAoB;IAEpB,MAAM,8BAA8B,CAClC,QAAQ,EACR,WAAW,EACX,OAAO,EACP,EAAE,EACF,OAAO,EACP,MAAM,CACP,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,8BAA8B,CAC3C,SAAmC,EACnC,WAAmB,EACnB,OAAe,EACf,MAAc,EACd,OAAyC,EACzC,MAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,oBAAoB,EACpB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,EAC1D,sBAAsB,EACtB,MAAM,EACN,MAAM,CACP,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|