@opencomputer/cli 0.2.0 → 0.3.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/README.md +27 -0
- package/dist/api.d.ts +53 -22
- package/dist/api.js +38 -3
- package/dist/api.js.map +1 -1
- package/dist/commands.js +447 -31
- package/dist/commands.js.map +1 -1
- package/dist/index.js +22 -3
- package/dist/index.js.map +1 -1
- package/dist/local.d.ts +2 -1
- package/dist/local.js +120 -19
- package/dist/local.js.map +1 -1
- package/dist/project.js +225 -9
- package/dist/project.js.map +1 -1
- package/dist/project.test.js +29 -1
- package/dist/project.test.js.map +1 -1
- package/dist/slack.d.ts +24 -0
- package/dist/slack.js +257 -0
- package/dist/slack.js.map +1 -0
- package/dist/slack.test.d.ts +1 -0
- package/dist/slack.test.js +44 -0
- package/dist/slack.test.js.map +1 -0
- package/package.json +1 -1
package/dist/project.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.test.js","sourceRoot":"","sources":["../src/project.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,
|
|
1
|
+
{"version":3,"file":"project.test.js","sourceRoot":"","sources":["../src/project.test.ts"],"names":[],"mappings":"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"}
|
package/dist/slack.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface LocalSlackState {
|
|
2
|
+
version: 1;
|
|
3
|
+
appId: string;
|
|
4
|
+
teamId: string;
|
|
5
|
+
teamName?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RemoteSlackState {
|
|
8
|
+
version: 1;
|
|
9
|
+
connectionId: string;
|
|
10
|
+
agentId: string;
|
|
11
|
+
webhookUrl: string;
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function localSlackStatePath(root: string): string;
|
|
15
|
+
export declare function remoteSlackStatePath(root: string): string;
|
|
16
|
+
export declare function readLocalSlackState(root: string): Promise<LocalSlackState | undefined>;
|
|
17
|
+
export declare function readRemoteSlackState(root: string): Promise<RemoteSlackState | undefined>;
|
|
18
|
+
export declare function writeRemoteSlackState(root: string, state: RemoteSlackState): Promise<void>;
|
|
19
|
+
export declare function clearSlackState(root: string, mode: "local" | "remote"): Promise<void>;
|
|
20
|
+
export declare function ensureSlackHooks(root: string): Promise<void>;
|
|
21
|
+
export declare function requireSlackAgentRoot(): Promise<string>;
|
|
22
|
+
export declare function slackManifest(root: string, mode: "local" | "remote"): Promise<Record<string, unknown>>;
|
|
23
|
+
export declare function runSlackCli(root: string, args: string[], mode: "local" | "remote"): Promise<void>;
|
|
24
|
+
export declare function captureLocalSlackState(root: string): Promise<LocalSlackState>;
|
package/dist/slack.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, resolve } from "node:path";
|
|
4
|
+
import { findAgentRoot, readManifest } from "./project.js";
|
|
5
|
+
const OPENCOMPUTER_SLACK_HOOKS = {
|
|
6
|
+
"get-manifest": "node .opencomputer/slack-hook.mjs manifest",
|
|
7
|
+
start: "node .opencomputer/slack-hook.mjs start",
|
|
8
|
+
deploy: "node .opencomputer/slack-hook.mjs deploy",
|
|
9
|
+
};
|
|
10
|
+
const OPENCOMPUTER_SLACK_HOOK_BRIDGE = `#!/usr/bin/env node
|
|
11
|
+
import { spawn } from "node:child_process";
|
|
12
|
+
|
|
13
|
+
const [action, ...extraArgs] = process.argv.slice(2);
|
|
14
|
+
if (!["manifest", "start", "deploy"].includes(action)) {
|
|
15
|
+
process.stderr.write("Unsupported OpenComputer Slack hook\\n");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const cliEntry = process.env.OPENCOMPUTER_SLACK_CLI_ENTRY;
|
|
20
|
+
const command = cliEntry
|
|
21
|
+
? process.env.OPENCOMPUTER_SLACK_NODE_EXECUTABLE || process.execPath
|
|
22
|
+
: process.platform === "win32"
|
|
23
|
+
? "npx.cmd"
|
|
24
|
+
: "npx";
|
|
25
|
+
const args = cliEntry
|
|
26
|
+
? [cliEntry, "slack-hook", action, ...extraArgs]
|
|
27
|
+
: [
|
|
28
|
+
"-y",
|
|
29
|
+
"@opencomputer/cli@latest",
|
|
30
|
+
"slack-hook",
|
|
31
|
+
action,
|
|
32
|
+
...extraArgs,
|
|
33
|
+
];
|
|
34
|
+
const child = spawn(command, args, { stdio: "inherit", env: process.env });
|
|
35
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
36
|
+
process.once(signal, () => child.kill(signal));
|
|
37
|
+
}
|
|
38
|
+
child.once("error", (error) => {
|
|
39
|
+
process.stderr.write(\`opencomputer: \${error.message}\\n\`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
child.once("exit", (code) => process.exit(code ?? 1));
|
|
43
|
+
`;
|
|
44
|
+
async function exists(path) {
|
|
45
|
+
try {
|
|
46
|
+
await access(path);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function localSlackStatePath(root) {
|
|
54
|
+
return resolve(root, ".opencomputer", "channels", "slack.local.json");
|
|
55
|
+
}
|
|
56
|
+
export function remoteSlackStatePath(root) {
|
|
57
|
+
return resolve(root, ".opencomputer", "channels", "slack.remote.json");
|
|
58
|
+
}
|
|
59
|
+
export async function readLocalSlackState(root) {
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(await readFile(localSlackStatePath(root), "utf8"));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export async function readRemoteSlackState(root) {
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(await readFile(remoteSlackStatePath(root), "utf8"));
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export async function writeRemoteSlackState(root, state) {
|
|
76
|
+
const path = remoteSlackStatePath(root);
|
|
77
|
+
await mkdir(dirname(path), { recursive: true });
|
|
78
|
+
await writeFile(path, `${JSON.stringify(state, null, 2)}\n`, {
|
|
79
|
+
mode: 0o600,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export async function clearSlackState(root, mode) {
|
|
83
|
+
await rm(mode === "local"
|
|
84
|
+
? localSlackStatePath(root)
|
|
85
|
+
: remoteSlackStatePath(root), { force: true });
|
|
86
|
+
}
|
|
87
|
+
export async function ensureSlackHooks(root) {
|
|
88
|
+
const path = resolve(root, ".slack", "hooks.json");
|
|
89
|
+
await mkdir(dirname(path), { recursive: true });
|
|
90
|
+
let existing = {};
|
|
91
|
+
try {
|
|
92
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
93
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
94
|
+
existing = parsed;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// A new Slack project does not have hooks yet.
|
|
99
|
+
}
|
|
100
|
+
const hooks = existing.hooks &&
|
|
101
|
+
typeof existing.hooks === "object" &&
|
|
102
|
+
!Array.isArray(existing.hooks)
|
|
103
|
+
? existing.hooks
|
|
104
|
+
: {};
|
|
105
|
+
const startHook = hooks.start;
|
|
106
|
+
const managed = startHook === undefined ||
|
|
107
|
+
(typeof startHook === "string" &&
|
|
108
|
+
(startHook.includes("@opencomputer/cli") ||
|
|
109
|
+
startHook.includes(".opencomputer/slack-hook.mjs") ||
|
|
110
|
+
startHook.includes("@opencomputer/blue") ||
|
|
111
|
+
startHook.includes(".blue/slack-hook.mjs")));
|
|
112
|
+
if (!managed)
|
|
113
|
+
return;
|
|
114
|
+
const config = existing.config &&
|
|
115
|
+
typeof existing.config === "object" &&
|
|
116
|
+
!Array.isArray(existing.config)
|
|
117
|
+
? existing.config
|
|
118
|
+
: {};
|
|
119
|
+
await writeFile(path, `${JSON.stringify({
|
|
120
|
+
...existing,
|
|
121
|
+
hooks: { ...hooks, ...OPENCOMPUTER_SLACK_HOOKS },
|
|
122
|
+
config: { ...config, "sdk-managed-connection-enabled": true },
|
|
123
|
+
}, null, 2)}\n`);
|
|
124
|
+
const bridge = resolve(root, ".opencomputer", "slack-hook.mjs");
|
|
125
|
+
await mkdir(dirname(bridge), { recursive: true });
|
|
126
|
+
await writeFile(bridge, OPENCOMPUTER_SLACK_HOOK_BRIDGE, { mode: 0o755 });
|
|
127
|
+
}
|
|
128
|
+
export async function requireSlackAgentRoot() {
|
|
129
|
+
const root = await findAgentRoot();
|
|
130
|
+
if (!root || !(await exists(resolve(root, "channels", "slack.ts")))) {
|
|
131
|
+
throw new Error("Run `opencomputer channels add slack` inside an agent repository first.");
|
|
132
|
+
}
|
|
133
|
+
await ensureSlackHooks(root);
|
|
134
|
+
return root;
|
|
135
|
+
}
|
|
136
|
+
export async function slackManifest(root, mode) {
|
|
137
|
+
const manifest = await readManifest(root);
|
|
138
|
+
const remote = mode === "remote" ? await readRemoteSlackState(root) : undefined;
|
|
139
|
+
if (mode === "remote" && !remote?.webhookUrl) {
|
|
140
|
+
throw new Error("Run `opencomputer channels connect slack --remote` first.");
|
|
141
|
+
}
|
|
142
|
+
const subscriptions = {
|
|
143
|
+
bot_events: [
|
|
144
|
+
"app_mention",
|
|
145
|
+
"app_context_changed",
|
|
146
|
+
"app_home_opened",
|
|
147
|
+
"message.im",
|
|
148
|
+
],
|
|
149
|
+
};
|
|
150
|
+
if (remote)
|
|
151
|
+
subscriptions.request_url = remote.webhookUrl;
|
|
152
|
+
return {
|
|
153
|
+
_metadata: { major_version: 1, minor_version: 1 },
|
|
154
|
+
display_information: {
|
|
155
|
+
name: manifest.name || basename(root),
|
|
156
|
+
description: `Run the ${manifest.name} OpenComputer agent from Slack.`,
|
|
157
|
+
background_color: "#0B1220",
|
|
158
|
+
},
|
|
159
|
+
features: {
|
|
160
|
+
agent_view: {
|
|
161
|
+
agent_description: `Work with the ${manifest.name} agent.`,
|
|
162
|
+
suggested_prompts: [
|
|
163
|
+
{
|
|
164
|
+
title: "Get started",
|
|
165
|
+
message: "Tell me what you can help with.",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
bot_user: {
|
|
170
|
+
display_name: manifest.name,
|
|
171
|
+
always_online: true,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
oauth_config: {
|
|
175
|
+
scopes: {
|
|
176
|
+
bot: [
|
|
177
|
+
"app_mentions:read",
|
|
178
|
+
"assistant:write",
|
|
179
|
+
"chat:write",
|
|
180
|
+
"im:history",
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
settings: {
|
|
185
|
+
event_subscriptions: subscriptions,
|
|
186
|
+
org_deploy_enabled: false,
|
|
187
|
+
socket_mode_enabled: mode === "local",
|
|
188
|
+
token_rotation_enabled: false,
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
export async function runSlackCli(root, args, mode) {
|
|
193
|
+
const cliEntry = process.argv[1];
|
|
194
|
+
await new Promise((resolvePromise, reject) => {
|
|
195
|
+
const child = spawn("slack", args, {
|
|
196
|
+
cwd: root,
|
|
197
|
+
stdio: "inherit",
|
|
198
|
+
env: {
|
|
199
|
+
...process.env,
|
|
200
|
+
...(cliEntry
|
|
201
|
+
? {
|
|
202
|
+
OPENCOMPUTER_SLACK_CLI_ENTRY: cliEntry,
|
|
203
|
+
OPENCOMPUTER_SLACK_NODE_EXECUTABLE: process.execPath,
|
|
204
|
+
}
|
|
205
|
+
: {}),
|
|
206
|
+
OPENCOMPUTER_SLACK_MODE: mode,
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
child.once("error", (error) => {
|
|
210
|
+
reject(error instanceof Error && "code" in error && error.code === "ENOENT"
|
|
211
|
+
? new Error("Slack CLI is required. Install it from https://docs.slack.dev/tools/slack-cli/.")
|
|
212
|
+
: error);
|
|
213
|
+
});
|
|
214
|
+
child.once("exit", (code, signal) => {
|
|
215
|
+
if (code === 0)
|
|
216
|
+
resolvePromise();
|
|
217
|
+
else {
|
|
218
|
+
reject(new Error(`Slack CLI exited ${signal ? `with ${signal}` : `with code ${String(code)}`}`));
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
export async function captureLocalSlackState(root) {
|
|
224
|
+
const candidates = [
|
|
225
|
+
resolve(root, ".slack", "apps.dev.json"),
|
|
226
|
+
resolve(root, ".slack", "apps.json"),
|
|
227
|
+
];
|
|
228
|
+
for (const path of candidates) {
|
|
229
|
+
if (!(await exists(path)))
|
|
230
|
+
continue;
|
|
231
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
232
|
+
const entries = parsed.apps
|
|
233
|
+
? Object.values(parsed.apps)
|
|
234
|
+
: Object.values(parsed).filter((entry) => Boolean(entry &&
|
|
235
|
+
typeof entry === "object" &&
|
|
236
|
+
"app_id" in entry &&
|
|
237
|
+
"team_id" in entry));
|
|
238
|
+
const selected = entries.find((entry) => entry.team_domain === parsed.default) ??
|
|
239
|
+
entries[0];
|
|
240
|
+
if (selected?.app_id && selected.team_id) {
|
|
241
|
+
const state = {
|
|
242
|
+
version: 1,
|
|
243
|
+
appId: selected.app_id,
|
|
244
|
+
teamId: selected.team_id,
|
|
245
|
+
teamName: selected.team_domain,
|
|
246
|
+
};
|
|
247
|
+
const output = localSlackStatePath(root);
|
|
248
|
+
await mkdir(dirname(output), { recursive: true });
|
|
249
|
+
await writeFile(output, `${JSON.stringify(state, null, 2)}\n`, {
|
|
250
|
+
mode: 0o600,
|
|
251
|
+
});
|
|
252
|
+
return state;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
throw new Error("Slack CLI did not persist the local app installation.");
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, readFile, rm, stat } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import { addSlackChannel, initializeAgentProject, } from "./project.js";
|
|
7
|
+
import { ensureSlackHooks, slackManifest, writeRemoteSlackState, } from "./slack.js";
|
|
8
|
+
const template = {
|
|
9
|
+
id: "research",
|
|
10
|
+
name: "Research agent",
|
|
11
|
+
description: "Research a topic.",
|
|
12
|
+
category: "Insights",
|
|
13
|
+
integrations: [],
|
|
14
|
+
suggestedPrompts: ["Research this topic."],
|
|
15
|
+
};
|
|
16
|
+
test("Slack channel state renders local and remote manifests", async () => {
|
|
17
|
+
const parent = await mkdtemp(resolve(tmpdir(), "opencomputer-slack-"));
|
|
18
|
+
const root = resolve(parent, "research-agent");
|
|
19
|
+
try {
|
|
20
|
+
await initializeAgentProject(template, root);
|
|
21
|
+
await addSlackChannel(root);
|
|
22
|
+
await ensureSlackHooks(root);
|
|
23
|
+
const local = await slackManifest(root, "local");
|
|
24
|
+
assert.equal(local.settings.socket_mode_enabled, true);
|
|
25
|
+
assert.equal((await stat(resolve(root, ".opencomputer", "slack-hook.mjs"))).isFile(), true);
|
|
26
|
+
assert.match(await readFile(resolve(root, ".slack", "hooks.json"), "utf8"), /@opencomputer|opencomputer/);
|
|
27
|
+
await writeRemoteSlackState(root, {
|
|
28
|
+
version: 1,
|
|
29
|
+
connectionId: "channel-1",
|
|
30
|
+
agentId: "research-agent@production",
|
|
31
|
+
webhookUrl: "https://example.com/slack/events",
|
|
32
|
+
apiUrl: "https://example.com",
|
|
33
|
+
});
|
|
34
|
+
const remote = await slackManifest(root, "remote");
|
|
35
|
+
const settings = remote.settings;
|
|
36
|
+
const subscriptions = settings.event_subscriptions;
|
|
37
|
+
assert.equal(settings.socket_mode_enabled, false);
|
|
38
|
+
assert.equal(subscriptions.request_url, "https://example.com/slack/events");
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await rm(parent, { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=slack.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.test.js","sourceRoot":"","sources":["../src/slack.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EACL,eAAe,EACf,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,MAAM,QAAQ,GAAyB;IACrC,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,mBAAmB;IAChC,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,EAAE;IAChB,gBAAgB,EAAE,CAAC,sBAAsB,CAAC;CAC3C,CAAC;AAEF,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;IACxE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CACT,KAAK,CAAC,QAAoC,CAAC,mBAAmB,EAC/D,IAAI,CACL,CAAC;QACF,MAAM,CAAC,KAAK,CACV,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EACvE,IAAI,CACL,CAAC;QACF,MAAM,CAAC,KAAK,CACV,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,EAC7D,4BAA4B,CAC7B,CAAC;QAEF,MAAM,qBAAqB,CAAC,IAAI,EAAE;YAChC,OAAO,EAAE,CAAC;YACV,YAAY,EAAE,WAAW;YACzB,OAAO,EAAE,2BAA2B;YACpC,UAAU,EAAE,kCAAkC;YAC9C,MAAM,EAAE,qBAAqB;SAC9B,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAmC,CAAC;QAC5D,MAAM,aAAa,GAAG,QAAQ,CAAC,mBAG9B,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CACV,aAAa,CAAC,WAAW,EACzB,kCAAkC,CACnC,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC,CAAC,CAAC"}
|