experimental-agent 0.0.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/README.md +243 -0
- package/dist/agent-workflow.d.mts +21 -0
- package/dist/agent-workflow.d.ts +21 -0
- package/dist/agent-workflow.js +2659 -0
- package/dist/agent-workflow.mjs +9 -0
- package/dist/chunk-2YI7MQGZ.mjs +261 -0
- package/dist/chunk-36X6L7SK.mjs +1 -0
- package/dist/chunk-DPPQO7DA.mjs +343 -0
- package/dist/chunk-JQPR6M7D.mjs +649 -0
- package/dist/chunk-MR4UWCJT.mjs +878 -0
- package/dist/client-FCFZYOOB.mjs +9 -0
- package/dist/client-RRX3GDQD.mjs +9 -0
- package/dist/index.d.mts +128 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.js +3078 -0
- package/dist/index.mjs +421 -0
- package/dist/lifecycle-workflow-steps-6BLGTYVB.mjs +20 -0
- package/dist/lifecycle-workflow.d.mts +17 -0
- package/dist/lifecycle-workflow.d.ts +17 -0
- package/dist/lifecycle-workflow.js +1690 -0
- package/dist/lifecycle-workflow.mjs +44 -0
- package/dist/local-J6QFWSWB.mjs +244 -0
- package/dist/process-manager-H2HF6G4G.mjs +153 -0
- package/dist/sandbox-Y3ENCNUA.mjs +10 -0
- package/dist/storage-QSTSE2ZB.mjs +27 -0
- package/dist/types-Lwut_0_u.d.mts +80 -0
- package/dist/types-ctZeJ3iQ.d.ts +80 -0
- package/dist/types-vRxN1Qz1.d.mts +805 -0
- package/dist/types-vRxN1Qz1.d.ts +805 -0
- package/dist/vercel-2CFDMEHB.mjs +18 -0
- package/package.json +59 -0
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SandboxError,
|
|
3
|
+
getStorage
|
|
4
|
+
} from "./chunk-DPPQO7DA.mjs";
|
|
5
|
+
|
|
6
|
+
// src/sandbox/bindings/local.ts
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import * as errore from "errore";
|
|
9
|
+
import { ulid } from "ulid";
|
|
10
|
+
|
|
11
|
+
// src/sandbox/write-files.ts
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
async function writeFiles(opts) {
|
|
14
|
+
const { sandbox, files, destPath } = opts;
|
|
15
|
+
if (files.length === 0) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const filePaths = files.map((file) => path.posix.join(destPath, file.path));
|
|
19
|
+
const parentDirs = [...new Set(filePaths.map((p) => path.posix.dirname(p)))];
|
|
20
|
+
const shellScripts = filePaths.filter((p) => p.endsWith(".sh"));
|
|
21
|
+
const mkdirResult = await sandbox.exec({
|
|
22
|
+
command: "mkdir",
|
|
23
|
+
args: ["-p", ...parentDirs]
|
|
24
|
+
});
|
|
25
|
+
if (mkdirResult instanceof Error) {
|
|
26
|
+
throw mkdirResult;
|
|
27
|
+
}
|
|
28
|
+
await mkdirResult.result;
|
|
29
|
+
const CHUNK_SIZE = 5e4;
|
|
30
|
+
for (let i = 0; i < files.length; i++) {
|
|
31
|
+
const file = files[i];
|
|
32
|
+
const fullPath = filePaths[i];
|
|
33
|
+
const base64Content = toBase64(file.content);
|
|
34
|
+
if (base64Content.length < CHUNK_SIZE) {
|
|
35
|
+
const marker = `EOF_${i}`;
|
|
36
|
+
const execResult = await sandbox.exec({
|
|
37
|
+
command: "bash",
|
|
38
|
+
args: [
|
|
39
|
+
"-c",
|
|
40
|
+
`base64 -d > ${quote(fullPath)} << '${marker}'
|
|
41
|
+
${base64Content}
|
|
42
|
+
${marker}`
|
|
43
|
+
]
|
|
44
|
+
});
|
|
45
|
+
if (execResult instanceof Error) {
|
|
46
|
+
throw execResult;
|
|
47
|
+
}
|
|
48
|
+
const { exitCode, stderr } = await execResult.result;
|
|
49
|
+
if (exitCode !== 0) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`writeFiles failed with exit code ${exitCode}: ${stderr}`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
const tempB64 = `/tmp/chunk-${Date.now()}-${i}.b64`;
|
|
56
|
+
const clearResult = await sandbox.exec({
|
|
57
|
+
command: "bash",
|
|
58
|
+
args: ["-c", `> ${quote(tempB64)}`]
|
|
59
|
+
});
|
|
60
|
+
if (clearResult instanceof Error) {
|
|
61
|
+
throw clearResult;
|
|
62
|
+
}
|
|
63
|
+
await clearResult.result;
|
|
64
|
+
for (let offset = 0; offset < base64Content.length; offset += CHUNK_SIZE) {
|
|
65
|
+
const chunk = base64Content.slice(offset, offset + CHUNK_SIZE);
|
|
66
|
+
const marker = `CHUNK_${offset}`;
|
|
67
|
+
const appendResult = await sandbox.exec({
|
|
68
|
+
command: "bash",
|
|
69
|
+
args: [
|
|
70
|
+
"-c",
|
|
71
|
+
`cat >> ${quote(tempB64)} << '${marker}'
|
|
72
|
+
${chunk}
|
|
73
|
+
${marker}`
|
|
74
|
+
]
|
|
75
|
+
});
|
|
76
|
+
if (appendResult instanceof Error) {
|
|
77
|
+
throw appendResult;
|
|
78
|
+
}
|
|
79
|
+
const { exitCode: exitCode2, stderr: stderr2 } = await appendResult.result;
|
|
80
|
+
if (exitCode2 !== 0) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`writeFiles chunk failed with exit code ${exitCode2}: ${stderr2}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const decodeResult = await sandbox.exec({
|
|
87
|
+
command: "bash",
|
|
88
|
+
args: [
|
|
89
|
+
"-c",
|
|
90
|
+
`base64 -d < ${quote(tempB64)} > ${quote(fullPath)} && rm -f ${quote(tempB64)}`
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
if (decodeResult instanceof Error) {
|
|
94
|
+
throw decodeResult;
|
|
95
|
+
}
|
|
96
|
+
const { exitCode, stderr } = await decodeResult.result;
|
|
97
|
+
if (exitCode !== 0) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`writeFiles decode failed with exit code ${exitCode}: ${stderr}`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (shellScripts.length > 0) {
|
|
105
|
+
const chmodResult = await sandbox.exec({
|
|
106
|
+
command: "chmod",
|
|
107
|
+
args: ["+x", ...shellScripts]
|
|
108
|
+
});
|
|
109
|
+
if (chmodResult instanceof Error) {
|
|
110
|
+
throw chmodResult;
|
|
111
|
+
}
|
|
112
|
+
await chmodResult.result;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function toBase64(content) {
|
|
116
|
+
if (typeof content === "string") {
|
|
117
|
+
return Buffer.from(content).toString("base64");
|
|
118
|
+
}
|
|
119
|
+
return content.toString("base64");
|
|
120
|
+
}
|
|
121
|
+
function quote(s) {
|
|
122
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/sandbox/bindings/local.ts
|
|
126
|
+
var localSandbox = ({
|
|
127
|
+
sandboxRecord
|
|
128
|
+
}) => {
|
|
129
|
+
const config = sandboxRecord.config;
|
|
130
|
+
const basePath = config.path ?? process.cwd();
|
|
131
|
+
const processes = /* @__PURE__ */ new Map();
|
|
132
|
+
const sandbox = {
|
|
133
|
+
id: sandboxRecord.id,
|
|
134
|
+
config: sandboxRecord.config,
|
|
135
|
+
exec: ({ command, args, signal }) => {
|
|
136
|
+
return errore.tryAsync({
|
|
137
|
+
try: () => {
|
|
138
|
+
const commandId = `command_${ulid()}`;
|
|
139
|
+
const child = spawn(command, args, {
|
|
140
|
+
cwd: basePath,
|
|
141
|
+
signal
|
|
142
|
+
});
|
|
143
|
+
processes.set(commandId, child);
|
|
144
|
+
let stdout = "";
|
|
145
|
+
let stderr = "";
|
|
146
|
+
const logQueue = [];
|
|
147
|
+
let logResolve = null;
|
|
148
|
+
let closed = false;
|
|
149
|
+
child.stdout.on("data", (data) => {
|
|
150
|
+
const str = String(data);
|
|
151
|
+
stdout += str;
|
|
152
|
+
logQueue.push({ stream: "stdout", data: str });
|
|
153
|
+
logResolve?.();
|
|
154
|
+
});
|
|
155
|
+
child.stderr.on("data", (data) => {
|
|
156
|
+
const str = String(data);
|
|
157
|
+
stderr += str;
|
|
158
|
+
logQueue.push({ stream: "stderr", data: str });
|
|
159
|
+
logResolve?.();
|
|
160
|
+
});
|
|
161
|
+
const result = new Promise((resolve, reject) => {
|
|
162
|
+
child.on("error", (err) => {
|
|
163
|
+
processes.delete(commandId);
|
|
164
|
+
closed = true;
|
|
165
|
+
logResolve?.();
|
|
166
|
+
reject(err);
|
|
167
|
+
});
|
|
168
|
+
child.on("close", (code) => {
|
|
169
|
+
processes.delete(commandId);
|
|
170
|
+
closed = true;
|
|
171
|
+
logResolve?.();
|
|
172
|
+
resolve({ stdout, stderr, exitCode: code ?? 0 });
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
async function* logs() {
|
|
176
|
+
while (!closed || logQueue.length > 0) {
|
|
177
|
+
const entry = logQueue.shift();
|
|
178
|
+
if (entry) {
|
|
179
|
+
yield entry;
|
|
180
|
+
} else if (!closed) {
|
|
181
|
+
await new Promise((resolve) => {
|
|
182
|
+
logResolve = resolve;
|
|
183
|
+
});
|
|
184
|
+
logResolve = null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return Promise.resolve({ commandId, logs, result });
|
|
189
|
+
},
|
|
190
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
getDomain: (port) => {
|
|
194
|
+
return Promise.resolve(`http://localhost:${port}`);
|
|
195
|
+
},
|
|
196
|
+
kill: async ({ commandId, storage }) => {
|
|
197
|
+
const child = processes.get(commandId);
|
|
198
|
+
if (!child) {
|
|
199
|
+
return new SandboxError({
|
|
200
|
+
reason: `Command ${commandId} not found or already finished`
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
child.kill("SIGTERM");
|
|
204
|
+
const cmd = await storage.command.get(commandId);
|
|
205
|
+
if (cmd instanceof Error) {
|
|
206
|
+
return new SandboxError({ reason: cmd.message, cause: cmd });
|
|
207
|
+
}
|
|
208
|
+
if (cmd && cmd.status === "running") {
|
|
209
|
+
const result = await storage.command.set({
|
|
210
|
+
...cmd,
|
|
211
|
+
status: "killed"
|
|
212
|
+
});
|
|
213
|
+
if (result instanceof Error) {
|
|
214
|
+
return new SandboxError({ reason: result.message, cause: result });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
writeFiles: (opts) => writeFiles({ sandbox, ...opts })
|
|
219
|
+
};
|
|
220
|
+
return sandbox;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// src/sandbox/bindings/vercel.ts
|
|
224
|
+
import * as errore2 from "errore";
|
|
225
|
+
import { Sandbox as VercelSandboxSDK } from "sandbox";
|
|
226
|
+
var VERCEL_MAX_TIMEOUT_MS = 5 * 60 * 60 * 1e3;
|
|
227
|
+
var LOCK_TIMEOUT_MS = 3e4;
|
|
228
|
+
var LOCK_POLL_INTERVAL_MS = 200;
|
|
229
|
+
var getTestCredentials = () => process.env.NODE_ENV === "test" ? {
|
|
230
|
+
token: process.env.TEST_VERCEL_TOKEN,
|
|
231
|
+
teamId: process.env.TEST_VERCEL_TEAM_ID,
|
|
232
|
+
projectId: process.env.TEST_VERCEL_PROJECT_ID
|
|
233
|
+
} : {};
|
|
234
|
+
var createPromises = /* @__PURE__ */ new Map();
|
|
235
|
+
var ACTIVITY_THROTTLE_MS = 1e4;
|
|
236
|
+
var lastActivitySent = /* @__PURE__ */ new Map();
|
|
237
|
+
var DEFAULT_VCPUS = 2;
|
|
238
|
+
var vercelSandbox = ({
|
|
239
|
+
sandboxRecord,
|
|
240
|
+
storageConfig,
|
|
241
|
+
enableLifecycleWorkflow = true,
|
|
242
|
+
storage: storageOverride
|
|
243
|
+
}) => {
|
|
244
|
+
const { id, config } = sandboxRecord;
|
|
245
|
+
const vcpus = config.resources?.vcpus ?? DEFAULT_VCPUS;
|
|
246
|
+
const ports = config.ports;
|
|
247
|
+
const storage = storageOverride ?? getStorage(storageConfig);
|
|
248
|
+
const initialVercel = sandboxRecord.providerMetadata?.provider === "vercel" ? sandboxRecord.providerMetadata : null;
|
|
249
|
+
let sandboxPromise = null;
|
|
250
|
+
async function pollForSandboxId() {
|
|
251
|
+
const deadline = Date.now() + LOCK_TIMEOUT_MS;
|
|
252
|
+
while (Date.now() < deadline) {
|
|
253
|
+
await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
|
|
254
|
+
const record = await storage.sandbox.get(id);
|
|
255
|
+
if (record instanceof Error) {
|
|
256
|
+
return new SandboxError({ reason: record.message, cause: record });
|
|
257
|
+
}
|
|
258
|
+
const vercelSandboxId = record?.providerMetadata?.provider === "vercel" ? record.providerMetadata.sandboxId : null;
|
|
259
|
+
if (vercelSandboxId) {
|
|
260
|
+
return vercelSandboxId;
|
|
261
|
+
}
|
|
262
|
+
if (!record?.acquiringLockAt) {
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return new SandboxError({
|
|
267
|
+
reason: "Timed out waiting for sandbox creation by another process"
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
async function createSandboxFromSnapshot(snapshotId) {
|
|
271
|
+
return await errore2.tryAsync({
|
|
272
|
+
try: async () => {
|
|
273
|
+
const sandbox2 = await VercelSandboxSDK.create({
|
|
274
|
+
source: { type: "snapshot", snapshotId },
|
|
275
|
+
resources: { vcpus },
|
|
276
|
+
timeout: VERCEL_MAX_TIMEOUT_MS,
|
|
277
|
+
ports,
|
|
278
|
+
...getTestCredentials()
|
|
279
|
+
});
|
|
280
|
+
const now = Date.now();
|
|
281
|
+
await storage.sandbox.set({
|
|
282
|
+
id,
|
|
283
|
+
config,
|
|
284
|
+
createdAt: now,
|
|
285
|
+
lastActivityAt: now,
|
|
286
|
+
acquiringLockId: null,
|
|
287
|
+
acquiringLockAt: null,
|
|
288
|
+
providerMetadata: {
|
|
289
|
+
provider: "vercel",
|
|
290
|
+
sandboxId: sandbox2.sandboxId,
|
|
291
|
+
snapshotId
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
return sandbox2.sandboxId;
|
|
295
|
+
},
|
|
296
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
async function createFreshSandbox() {
|
|
300
|
+
return await errore2.tryAsync({
|
|
301
|
+
try: async () => {
|
|
302
|
+
const sandbox2 = await VercelSandboxSDK.create({
|
|
303
|
+
resources: { vcpus },
|
|
304
|
+
timeout: VERCEL_MAX_TIMEOUT_MS,
|
|
305
|
+
ports,
|
|
306
|
+
...getTestCredentials()
|
|
307
|
+
});
|
|
308
|
+
const now = Date.now();
|
|
309
|
+
await storage.sandbox.set({
|
|
310
|
+
id,
|
|
311
|
+
config,
|
|
312
|
+
createdAt: now,
|
|
313
|
+
lastActivityAt: now,
|
|
314
|
+
acquiringLockId: null,
|
|
315
|
+
acquiringLockAt: null,
|
|
316
|
+
providerMetadata: {
|
|
317
|
+
provider: "vercel",
|
|
318
|
+
sandboxId: sandbox2.sandboxId,
|
|
319
|
+
snapshotId: null
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
return sandbox2.sandboxId;
|
|
323
|
+
},
|
|
324
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
async function doGetOrCreateSandboxId() {
|
|
328
|
+
if (initialVercel?.sandboxId) {
|
|
329
|
+
return initialVercel.sandboxId;
|
|
330
|
+
}
|
|
331
|
+
const existing = await storage.sandbox.get(id);
|
|
332
|
+
if (existing instanceof Error) {
|
|
333
|
+
return new SandboxError({ reason: existing.message, cause: existing });
|
|
334
|
+
}
|
|
335
|
+
const existingVercel = existing?.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
|
|
336
|
+
if (existingVercel?.sandboxId) {
|
|
337
|
+
return existingVercel.sandboxId;
|
|
338
|
+
}
|
|
339
|
+
const hasActiveLock = existing?.acquiringLockId && existing.acquiringLockAt && Date.now() - existing.acquiringLockAt < LOCK_TIMEOUT_MS;
|
|
340
|
+
if (hasActiveLock) {
|
|
341
|
+
return pollForSandboxId();
|
|
342
|
+
}
|
|
343
|
+
const lockId = crypto.randomUUID();
|
|
344
|
+
const now = Date.now();
|
|
345
|
+
await storage.sandbox.set({
|
|
346
|
+
id,
|
|
347
|
+
config,
|
|
348
|
+
createdAt: existing?.createdAt ?? sandboxRecord.createdAt,
|
|
349
|
+
lastActivityAt: existing?.lastActivityAt ?? sandboxRecord.lastActivityAt,
|
|
350
|
+
acquiringLockId: lockId,
|
|
351
|
+
acquiringLockAt: now,
|
|
352
|
+
providerMetadata: {
|
|
353
|
+
provider: "vercel",
|
|
354
|
+
sandboxId: null,
|
|
355
|
+
snapshotId: existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? null
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
const afterLock = await storage.sandbox.get(id);
|
|
359
|
+
if (afterLock instanceof Error) {
|
|
360
|
+
return new SandboxError({ reason: afterLock.message, cause: afterLock });
|
|
361
|
+
}
|
|
362
|
+
if (afterLock?.acquiringLockId !== lockId) {
|
|
363
|
+
return pollForSandboxId();
|
|
364
|
+
}
|
|
365
|
+
const snapshotId = existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? config.lifecycle?.snapshotId;
|
|
366
|
+
if (snapshotId) {
|
|
367
|
+
const result = await createSandboxFromSnapshot(snapshotId);
|
|
368
|
+
if (!(result instanceof Error)) {
|
|
369
|
+
return result;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return createFreshSandbox();
|
|
373
|
+
}
|
|
374
|
+
function getOrCreateSandboxId() {
|
|
375
|
+
const cached = createPromises.get(id);
|
|
376
|
+
if (cached) {
|
|
377
|
+
return cached;
|
|
378
|
+
}
|
|
379
|
+
const promise = doGetOrCreateSandboxId().finally(() => {
|
|
380
|
+
createPromises.delete(id);
|
|
381
|
+
});
|
|
382
|
+
createPromises.set(id, promise);
|
|
383
|
+
return promise;
|
|
384
|
+
}
|
|
385
|
+
async function doGetSandbox() {
|
|
386
|
+
const vercelSandboxId = await getOrCreateSandboxId();
|
|
387
|
+
if (vercelSandboxId instanceof Error) {
|
|
388
|
+
return vercelSandboxId;
|
|
389
|
+
}
|
|
390
|
+
return errore2.tryAsync({
|
|
391
|
+
try: () => VercelSandboxSDK.get({
|
|
392
|
+
sandboxId: vercelSandboxId,
|
|
393
|
+
...getTestCredentials()
|
|
394
|
+
}),
|
|
395
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
function getSandbox2() {
|
|
399
|
+
if (!sandboxPromise) {
|
|
400
|
+
sandboxPromise = doGetSandbox();
|
|
401
|
+
}
|
|
402
|
+
return sandboxPromise;
|
|
403
|
+
}
|
|
404
|
+
async function updateLastActivity() {
|
|
405
|
+
const now = Date.now();
|
|
406
|
+
const lastSent = lastActivitySent.get(id);
|
|
407
|
+
if (lastSent && now - lastSent < ACTIVITY_THROTTLE_MS) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
lastActivitySent.set(id, now);
|
|
411
|
+
const existing = await storage.sandbox.get(id);
|
|
412
|
+
if (existing instanceof Error || !existing) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
|
|
416
|
+
await storage.sandbox.set({
|
|
417
|
+
id: existing.id,
|
|
418
|
+
config: existing.config,
|
|
419
|
+
createdAt: existing.createdAt,
|
|
420
|
+
lastActivityAt: now,
|
|
421
|
+
acquiringLockId: null,
|
|
422
|
+
acquiringLockAt: null,
|
|
423
|
+
providerMetadata: existingVercel ?? {
|
|
424
|
+
provider: "vercel",
|
|
425
|
+
sandboxId: null,
|
|
426
|
+
snapshotId: null
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
if (enableLifecycleWorkflow) {
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
const lifecycle = {
|
|
433
|
+
start: async () => {
|
|
434
|
+
const sandbox2 = await getSandbox2();
|
|
435
|
+
if (sandbox2 instanceof Error) {
|
|
436
|
+
return sandbox2;
|
|
437
|
+
}
|
|
438
|
+
await updateLastActivity();
|
|
439
|
+
return sandbox2.status;
|
|
440
|
+
},
|
|
441
|
+
snapshot: async () => {
|
|
442
|
+
const sandbox2 = await getSandbox2();
|
|
443
|
+
if (sandbox2 instanceof Error) {
|
|
444
|
+
return sandbox2;
|
|
445
|
+
}
|
|
446
|
+
return errore2.tryAsync({
|
|
447
|
+
try: async () => {
|
|
448
|
+
const existing = await storage.sandbox.get(id);
|
|
449
|
+
const snapshot = await sandbox2.snapshot();
|
|
450
|
+
await storage.sandbox.set({
|
|
451
|
+
id,
|
|
452
|
+
config,
|
|
453
|
+
createdAt: existing instanceof Error ? null : existing?.createdAt ?? null,
|
|
454
|
+
lastActivityAt: existing instanceof Error ? null : existing?.lastActivityAt ?? null,
|
|
455
|
+
acquiringLockId: null,
|
|
456
|
+
acquiringLockAt: null,
|
|
457
|
+
providerMetadata: {
|
|
458
|
+
provider: "vercel",
|
|
459
|
+
sandboxId: null,
|
|
460
|
+
snapshotId: snapshot.snapshotId
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
return { snapshotId: snapshot.snapshotId };
|
|
464
|
+
},
|
|
465
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
466
|
+
});
|
|
467
|
+
},
|
|
468
|
+
stop: async () => {
|
|
469
|
+
const sandbox2 = await getSandbox2();
|
|
470
|
+
if (sandbox2 instanceof Error) {
|
|
471
|
+
return sandbox2;
|
|
472
|
+
}
|
|
473
|
+
return errore2.tryAsync({
|
|
474
|
+
try: async () => {
|
|
475
|
+
await sandbox2.stop();
|
|
476
|
+
const existing = await storage.sandbox.get(id);
|
|
477
|
+
if (existing instanceof Error || !existing) {
|
|
478
|
+
return void 0;
|
|
479
|
+
}
|
|
480
|
+
await storage.sandbox.set({
|
|
481
|
+
id: existing.id,
|
|
482
|
+
config: existing.config,
|
|
483
|
+
createdAt: existing.createdAt,
|
|
484
|
+
lastActivityAt: existing.lastActivityAt,
|
|
485
|
+
acquiringLockId: null,
|
|
486
|
+
acquiringLockAt: null,
|
|
487
|
+
providerMetadata: {
|
|
488
|
+
provider: "vercel",
|
|
489
|
+
sandboxId: null,
|
|
490
|
+
snapshotId: null
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
return void 0;
|
|
494
|
+
},
|
|
495
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
496
|
+
});
|
|
497
|
+
},
|
|
498
|
+
getStatus: async () => {
|
|
499
|
+
const sandbox2 = await getSandbox2();
|
|
500
|
+
if (sandbox2 instanceof Error) {
|
|
501
|
+
return sandbox2;
|
|
502
|
+
}
|
|
503
|
+
return sandbox2.status;
|
|
504
|
+
},
|
|
505
|
+
getCreatedAt: async () => {
|
|
506
|
+
const sandbox2 = await getSandbox2();
|
|
507
|
+
if (sandbox2 instanceof Error) {
|
|
508
|
+
return sandbox2;
|
|
509
|
+
}
|
|
510
|
+
return sandbox2.createdAt;
|
|
511
|
+
},
|
|
512
|
+
getRemainingTimeout: async () => {
|
|
513
|
+
const sandbox2 = await getSandbox2();
|
|
514
|
+
if (sandbox2 instanceof Error) {
|
|
515
|
+
return sandbox2;
|
|
516
|
+
}
|
|
517
|
+
return sandbox2.timeout;
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
const sandbox = {
|
|
521
|
+
id,
|
|
522
|
+
config,
|
|
523
|
+
exec: async ({ command, args, signal }) => {
|
|
524
|
+
const instance = await getSandbox2();
|
|
525
|
+
if (instance instanceof Error) {
|
|
526
|
+
return instance;
|
|
527
|
+
}
|
|
528
|
+
const updatePromise = updateLastActivity();
|
|
529
|
+
const execResult = await errore2.tryAsync({
|
|
530
|
+
try: async () => {
|
|
531
|
+
const output = await instance.runCommand(command, args, { signal });
|
|
532
|
+
let stdout = "";
|
|
533
|
+
let stderr = "";
|
|
534
|
+
const logBuffer = [];
|
|
535
|
+
const state = {
|
|
536
|
+
resolve: null,
|
|
537
|
+
consumed: false
|
|
538
|
+
};
|
|
539
|
+
const consumeLogs = (async () => {
|
|
540
|
+
for await (const log of output.logs()) {
|
|
541
|
+
const entry = log.stream === "stdout" ? { stream: "stdout", data: log.data } : { stream: "stderr", data: log.data };
|
|
542
|
+
if (log.stream === "stdout") {
|
|
543
|
+
stdout += log.data;
|
|
544
|
+
} else {
|
|
545
|
+
stderr += log.data;
|
|
546
|
+
}
|
|
547
|
+
logBuffer.push(entry);
|
|
548
|
+
state.resolve?.();
|
|
549
|
+
}
|
|
550
|
+
state.consumed = true;
|
|
551
|
+
state.resolve?.();
|
|
552
|
+
})();
|
|
553
|
+
async function* logs() {
|
|
554
|
+
let index = 0;
|
|
555
|
+
while (!state.consumed || index < logBuffer.length) {
|
|
556
|
+
if (index < logBuffer.length) {
|
|
557
|
+
yield logBuffer[index++];
|
|
558
|
+
} else {
|
|
559
|
+
await new Promise((resolve) => {
|
|
560
|
+
state.resolve = resolve;
|
|
561
|
+
});
|
|
562
|
+
state.resolve = null;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
const result = consumeLogs.then(() => ({
|
|
567
|
+
stdout,
|
|
568
|
+
stderr,
|
|
569
|
+
exitCode: output.exitCode
|
|
570
|
+
}));
|
|
571
|
+
return { commandId: output.cmdId, logs, result };
|
|
572
|
+
},
|
|
573
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
574
|
+
});
|
|
575
|
+
await updatePromise;
|
|
576
|
+
return execResult;
|
|
577
|
+
},
|
|
578
|
+
getDomain: async (port) => {
|
|
579
|
+
const sandbox2 = await getSandbox2();
|
|
580
|
+
if (sandbox2 instanceof Error) {
|
|
581
|
+
return sandbox2;
|
|
582
|
+
}
|
|
583
|
+
try {
|
|
584
|
+
return sandbox2.domain(port);
|
|
585
|
+
} catch (e) {
|
|
586
|
+
return new SandboxError({ reason: String(e), cause: e });
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
kill: async ({ commandId, storage: cmdStorage }) => {
|
|
590
|
+
const instance = await getSandbox2();
|
|
591
|
+
if (instance instanceof Error) {
|
|
592
|
+
return instance;
|
|
593
|
+
}
|
|
594
|
+
const cmd = await cmdStorage.command.get(commandId);
|
|
595
|
+
if (cmd instanceof Error) {
|
|
596
|
+
return new SandboxError({ reason: cmd.message, cause: cmd });
|
|
597
|
+
}
|
|
598
|
+
if (cmd && cmd.status === "running") {
|
|
599
|
+
const result = await cmdStorage.command.set({
|
|
600
|
+
...cmd,
|
|
601
|
+
status: "killed"
|
|
602
|
+
});
|
|
603
|
+
if (result instanceof Error) {
|
|
604
|
+
return new SandboxError({ reason: result.message, cause: result });
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return void 0;
|
|
608
|
+
},
|
|
609
|
+
writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
|
|
610
|
+
lifecycle
|
|
611
|
+
};
|
|
612
|
+
if (config.lifecycle?.autoStart !== false) {
|
|
613
|
+
sandboxPromise = doGetSandbox();
|
|
614
|
+
}
|
|
615
|
+
return sandbox;
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
// src/sandbox/client.ts
|
|
619
|
+
function getSandbox({
|
|
620
|
+
sandboxRecord,
|
|
621
|
+
storageConfig
|
|
622
|
+
}) {
|
|
623
|
+
const { config } = sandboxRecord;
|
|
624
|
+
switch (config.type) {
|
|
625
|
+
case "local":
|
|
626
|
+
return localSandbox({
|
|
627
|
+
sandboxRecord,
|
|
628
|
+
storageConfig
|
|
629
|
+
});
|
|
630
|
+
case "vercel":
|
|
631
|
+
return vercelSandbox({
|
|
632
|
+
sandboxRecord,
|
|
633
|
+
storageConfig
|
|
634
|
+
});
|
|
635
|
+
case "custom":
|
|
636
|
+
throw new Error("Custom sandboxes are not supported");
|
|
637
|
+
default:
|
|
638
|
+
config;
|
|
639
|
+
throw new Error(
|
|
640
|
+
`Unknown sandbox type: ${// biome-ignore lint/suspicious/noExplicitAny: .
|
|
641
|
+
config.type}`
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export {
|
|
647
|
+
getSandbox
|
|
648
|
+
};
|
|
649
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvbG9jYWwudHMiLCAiLi4vc3JjL3NhbmRib3gvd3JpdGUtZmlsZXMudHMiLCAiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvdmVyY2VsLnRzIiwgIi4uL3NyYy9zYW5kYm94L2NsaWVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCAqIGFzIGVycm9yZSBmcm9tIFwiZXJyb3JlXCI7XG5pbXBvcnQgeyB1bGlkIH0gZnJvbSBcInVsaWRcIjtcbmltcG9ydCB7IFNhbmRib3hFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgU2FuZGJveFJlY29yZCwgU3RvcmFnZUNvbmZpZyB9IGZyb20gXCIuLi8uLi9zdG9yYWdlL3R5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IExvZ0VudHJ5LCBTYW5kYm94IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyB3cml0ZUZpbGVzIH0gZnJvbSBcIi4uL3dyaXRlLWZpbGVzXCI7XG5cbmV4cG9ydCBjb25zdCBsb2NhbFNhbmRib3ggPSAoe1xuICBzYW5kYm94UmVjb3JkLFxufToge1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkICYgeyBjb25maWc6IHsgdHlwZTogXCJsb2NhbFwiIH0gfTtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbn0pOiBTYW5kYm94ID0+IHtcbiAgY29uc3QgY29uZmlnID0gc2FuZGJveFJlY29yZC5jb25maWc7XG4gIGNvbnN0IGJhc2VQYXRoID0gY29uZmlnLnBhdGggPz8gcHJvY2Vzcy5jd2QoKTtcbiAgY29uc3QgcHJvY2Vzc2VzID0gbmV3IE1hcDxzdHJpbmcsIENoaWxkUHJvY2Vzcz4oKTtcblxuICBjb25zdCBzYW5kYm94OiBTYW5kYm94ID0ge1xuICAgIGlkOiBzYW5kYm94UmVjb3JkLmlkLFxuICAgIGNvbmZpZzogc2FuZGJveFJlY29yZC5jb25maWcsXG4gICAgZXhlYzogKHsgY29tbWFuZCwgYXJncywgc2lnbmFsIH0pID0+IHtcbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kSWQgPSBgY29tbWFuZF8ke3VsaWQoKX1gO1xuXG4gICAgICAgICAgY29uc3QgY2hpbGQgPSBzcGF3bihjb21tYW5kLCBhcmdzLCB7XG4gICAgICAgICAgICBjd2Q6IGJhc2VQYXRoLFxuICAgICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcHJvY2Vzc2VzLnNldChjb21tYW5kSWQsIGNoaWxkKTtcblxuICAgICAgICAgIGxldCBzdGRvdXQgPSBcIlwiO1xuICAgICAgICAgIGxldCBzdGRlcnIgPSBcIlwiO1xuICAgICAgICAgIGNvbnN0IGxvZ1F1ZXVlOiBMb2dFbnRyeVtdID0gW107XG4gICAgICAgICAgbGV0IGxvZ1Jlc29sdmU6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICAgICAgICAgIGxldCBjbG9zZWQgPSBmYWxzZTtcblxuICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbihcImRhdGFcIiwgKGRhdGE6IHN0cmluZyB8IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGRhdGEpO1xuICAgICAgICAgICAgc3Rkb3V0ICs9IHN0cjtcbiAgICAgICAgICAgIGxvZ1F1ZXVlLnB1c2goeyBzdHJlYW06IFwic3Rkb3V0XCIsIGRhdGE6IHN0ciB9KTtcbiAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2hpbGQuc3RkZXJyLm9uKFwiZGF0YVwiLCAoZGF0YTogc3RyaW5nIHwgQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHIgPSBTdHJpbmcoZGF0YSk7XG4gICAgICAgICAgICBzdGRlcnIgKz0gc3RyO1xuICAgICAgICAgICAgbG9nUXVldWUucHVzaCh7IHN0cmVhbTogXCJzdGRlcnJcIiwgZGF0YTogc3RyIH0pO1xuICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgUHJvbWlzZTx7XG4gICAgICAgICAgICBzdGRvdXQ6IHN0cmluZztcbiAgICAgICAgICAgIHN0ZGVycjogc3RyaW5nO1xuICAgICAgICAgICAgZXhpdENvZGU6IG51bWJlcjtcbiAgICAgICAgICB9PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjaGlsZC5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VzLmRlbGV0ZShjb21tYW5kSWQpO1xuICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2hpbGQub24oXCJjbG9zZVwiLCAoY29kZTogbnVtYmVyIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgICBwcm9jZXNzZXMuZGVsZXRlKGNvbW1hbmRJZCk7XG4gICAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7XG4gICAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgICAgICByZXNvbHZlKHsgc3Rkb3V0LCBzdGRlcnIsIGV4aXRDb2RlOiBjb2RlID8/IDAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGFzeW5jIGZ1bmN0aW9uKiBsb2dzKCk6IEFzeW5jSXRlcmFibGU8TG9nRW50cnk+IHtcbiAgICAgICAgICAgIHdoaWxlICghY2xvc2VkIHx8IGxvZ1F1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgY29uc3QgZW50cnkgPSBsb2dRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBlbnRyeTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghY2xvc2VkKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgICAgICAgIGxvZ1Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGxvZ1Jlc29sdmUgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGNvbW1hbmRJZCwgbG9ncywgcmVzdWx0IH0pO1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGU6IHVua25vd24pID0+XG4gICAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXREb21haW46IChwb3J0KSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gKTtcbiAgICB9LFxuXG4gICAga2lsbDogYXN5bmMgKHsgY29tbWFuZElkLCBzdG9yYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IGNoaWxkID0gcHJvY2Vzc2VzLmdldChjb21tYW5kSWQpO1xuICAgICAgaWYgKCFjaGlsZCkge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgcmVhc29uOiBgQ29tbWFuZCAke2NvbW1hbmRJZH0gbm90IGZvdW5kIG9yIGFscmVhZHkgZmluaXNoZWRgLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG5cbiAgICAgIGNvbnN0IGNtZCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmIChjbWQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogY21kLm1lc3NhZ2UsIGNhdXNlOiBjbWQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY21kICYmIGNtZC5zdGF0dXMgPT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5zZXQoe1xuICAgICAgICAgIC4uLmNtZCxcbiAgICAgICAgICBzdGF0dXM6IFwia2lsbGVkXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogcmVzdWx0Lm1lc3NhZ2UsIGNhdXNlOiByZXN1bHQgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgd3JpdGVGaWxlczogKG9wdHMpID0+IHdyaXRlRmlsZXMoeyBzYW5kYm94LCAuLi5vcHRzIH0pLFxuICB9O1xuXG4gIHJldHVybiBzYW5kYm94O1xufTtcbiIsICJpbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB0eXBlIHsgVXBsb2FkYWJsZUZpbGUgfSBmcm9tIFwiLi4vc2tpbGxzL3R5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IFNhbmRib3ggfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIFdyaXRlcyBmaWxlcyB0byBhIHNhbmRib3ggYXQgdGhlIHNwZWNpZmllZCBkZXN0aW5hdGlvbiBwYXRoLlxuICogU2hlbGwgc2NyaXB0cyAoLnNoIGZpbGVzKSBhcmUgYXV0b21hdGljYWxseSBtYWRlIGV4ZWN1dGFibGUuXG4gKlxuICogRm9yIHNtYWxsIGZpbGVzICg8MTAwS0IgdG90YWwpLCB1c2VzIHNpbmdsZSBleGVjIHdpdGggaGVyZWRvYy5cbiAqIEZvciBsYXJnZSBmaWxlcywgd3JpdGVzIGJhc2U2NCBjaHVua3MgdGhlbiBkZWNvZGVzIHRvIGF2b2lkIEFSR19NQVggbGltaXRzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVGaWxlcyhvcHRzOiB7XG4gIHNhbmRib3g6IFBpY2s8U2FuZGJveCwgXCJleGVjXCI+O1xuICBmaWxlczogVXBsb2FkYWJsZUZpbGVbXTtcbiAgZGVzdFBhdGg6IHN0cmluZztcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBzYW5kYm94LCBmaWxlcywgZGVzdFBhdGggfSA9IG9wdHM7XG5cbiAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGZpbGVQYXRocyA9IGZpbGVzLm1hcCgoZmlsZSkgPT4gcGF0aC5wb3NpeC5qb2luKGRlc3RQYXRoLCBmaWxlLnBhdGgpKTtcbiAgY29uc3QgcGFyZW50RGlycyA9IFsuLi5uZXcgU2V0KGZpbGVQYXRocy5tYXAoKHApID0+IHBhdGgucG9zaXguZGlybmFtZShwKSkpXTtcbiAgY29uc3Qgc2hlbGxTY3JpcHRzID0gZmlsZVBhdGhzLmZpbHRlcigocCkgPT4gcC5lbmRzV2l0aChcIi5zaFwiKSk7XG5cbiAgY29uc3QgbWtkaXJSZXN1bHQgPSBhd2FpdCBzYW5kYm94LmV4ZWMoe1xuICAgIGNvbW1hbmQ6IFwibWtkaXJcIixcbiAgICBhcmdzOiBbXCItcFwiLCAuLi5wYXJlbnREaXJzXSxcbiAgfSk7XG4gIGlmIChta2RpclJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgdGhyb3cgbWtkaXJSZXN1bHQ7XG4gIH1cbiAgYXdhaXQgbWtkaXJSZXN1bHQucmVzdWx0O1xuXG4gIGNvbnN0IENIVU5LX1NJWkUgPSA1MF8wMDA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGZpbGUgPSBmaWxlc1tpXTtcbiAgICBjb25zdCBmdWxsUGF0aCA9IGZpbGVQYXRoc1tpXTtcbiAgICBjb25zdCBiYXNlNjRDb250ZW50ID0gdG9CYXNlNjQoZmlsZS5jb250ZW50KTtcblxuICAgIGlmIChiYXNlNjRDb250ZW50Lmxlbmd0aCA8IENIVU5LX1NJWkUpIHtcbiAgICAgIGNvbnN0IG1hcmtlciA9IGBFT0ZfJHtpfWA7XG4gICAgICBjb25zdCBleGVjUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgYGJhc2U2NCAtZCA+ICR7cXVvdGUoZnVsbFBhdGgpfSA8PCAnJHttYXJrZXJ9J1xuJHtiYXNlNjRDb250ZW50fVxuJHttYXJrZXJ9YCxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZXhlY1Jlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGV4ZWNSZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgZXhpdENvZGUsIHN0ZGVyciB9ID0gYXdhaXQgZXhlY1Jlc3VsdC5yZXN1bHQ7XG4gICAgICBpZiAoZXhpdENvZGUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGB3cml0ZUZpbGVzIGZhaWxlZCB3aXRoIGV4aXQgY29kZSAke2V4aXRDb2RlfTogJHtzdGRlcnJ9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0ZW1wQjY0ID0gYC90bXAvY2h1bmstJHtEYXRlLm5vdygpfS0ke2l9LmI2NGA7XG5cbiAgICAgIGNvbnN0IGNsZWFyUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgIGFyZ3M6IFtcIi1jXCIsIGA+ICR7cXVvdGUodGVtcEI2NCl9YF0sXG4gICAgICB9KTtcbiAgICAgIGlmIChjbGVhclJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGNsZWFyUmVzdWx0O1xuICAgICAgfVxuICAgICAgYXdhaXQgY2xlYXJSZXN1bHQucmVzdWx0O1xuXG4gICAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBiYXNlNjRDb250ZW50Lmxlbmd0aDsgb2Zmc2V0ICs9IENIVU5LX1NJWkUpIHtcbiAgICAgICAgY29uc3QgY2h1bmsgPSBiYXNlNjRDb250ZW50LnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgQ0hVTktfU0laRSk7XG4gICAgICAgIGNvbnN0IG1hcmtlciA9IGBDSFVOS18ke29mZnNldH1gO1xuICAgICAgICBjb25zdCBhcHBlbmRSZXN1bHQgPSBhd2FpdCBzYW5kYm94LmV4ZWMoe1xuICAgICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAgIFwiLWNcIixcbiAgICAgICAgICAgIGBjYXQgPj4gJHtxdW90ZSh0ZW1wQjY0KX0gPDwgJyR7bWFya2VyfSdcbiR7Y2h1bmt9XG4ke21hcmtlcn1gLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChhcHBlbmRSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHRocm93IGFwcGVuZFJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgZXhpdENvZGUsIHN0ZGVyciB9ID0gYXdhaXQgYXBwZW5kUmVzdWx0LnJlc3VsdDtcbiAgICAgICAgaWYgKGV4aXRDb2RlICE9PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYHdyaXRlRmlsZXMgY2h1bmsgZmFpbGVkIHdpdGggZXhpdCBjb2RlICR7ZXhpdENvZGV9OiAke3N0ZGVycn1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBkZWNvZGVSZXN1bHQgPSBhd2FpdCBzYW5kYm94LmV4ZWMoe1xuICAgICAgICBjb21tYW5kOiBcImJhc2hcIixcbiAgICAgICAgYXJnczogW1xuICAgICAgICAgIFwiLWNcIixcbiAgICAgICAgICBgYmFzZTY0IC1kIDwgJHtxdW90ZSh0ZW1wQjY0KX0gPiAke3F1b3RlKGZ1bGxQYXRoKX0gJiYgcm0gLWYgJHtxdW90ZSh0ZW1wQjY0KX1gLFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChkZWNvZGVSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBkZWNvZGVSZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgZXhpdENvZGUsIHN0ZGVyciB9ID0gYXdhaXQgZGVjb2RlUmVzdWx0LnJlc3VsdDtcbiAgICAgIGlmIChleGl0Q29kZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYHdyaXRlRmlsZXMgZGVjb2RlIGZhaWxlZCB3aXRoIGV4aXQgY29kZSAke2V4aXRDb2RlfTogJHtzdGRlcnJ9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChzaGVsbFNjcmlwdHMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGNobW9kUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgIGNvbW1hbmQ6IFwiY2htb2RcIixcbiAgICAgIGFyZ3M6IFtcIit4XCIsIC4uLnNoZWxsU2NyaXB0c10sXG4gICAgfSk7XG4gICAgaWYgKGNobW9kUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHRocm93IGNobW9kUmVzdWx0O1xuICAgIH1cbiAgICBhd2FpdCBjaG1vZFJlc3VsdC5yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gdG9CYXNlNjQoY29udGVudDogc3RyaW5nIHwgQnVmZmVyKTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiBjb250ZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNvbnRlbnQpLnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xuICB9XG4gIHJldHVybiBjb250ZW50LnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCcke3MucmVwbGFjZSgvJy9nLCBcIidcXFxcJydcIil9J2A7XG59XG4iLCAiaW1wb3J0ICogYXMgZXJyb3JlIGZyb20gXCJlcnJvcmVcIjtcbmltcG9ydCB7IFNhbmRib3ggYXMgVmVyY2VsU2FuZGJveFNESyB9IGZyb20gXCJzYW5kYm94XCI7XG5pbXBvcnQgeyBTYW5kYm94RXJyb3IgfSBmcm9tIFwiLi4vLi4vZXJyb3JzXCI7XG5pbXBvcnQge1xuICBnZXRTdG9yYWdlLFxuICB0eXBlIFNhbmRib3hSZWNvcmQsXG4gIHR5cGUgU3RvcmFnZSxcbiAgdHlwZSBTdG9yYWdlQ29uZmlnLFxufSBmcm9tIFwiLi4vLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHR5cGUge1xuICBMb2dFbnRyeSxcbiAgU2FuZGJveCxcbiAgU2FuZGJveExpZmVjeWNsZSxcbiAgU2FuZGJveFN0YXR1cyxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyB3cml0ZUZpbGVzIH0gZnJvbSBcIi4uL3dyaXRlLWZpbGVzXCI7XG5cbmV4cG9ydCB0eXBlIFZlcmNlbFNhbmRib3hDcmVhdGVPcHRpb25zID0gRXh0cmFjdDxcbiAgUGFyYW1ldGVyczx0eXBlb2YgVmVyY2VsU2FuZGJveFNESy5jcmVhdGU+WzBdLFxuICAvLyBiaW9tZS1pZ25vcmUgbGludC9jb21wbGV4aXR5L25vQmFubmVkVHlwZXM6IC5cbiAge31cbj47XG5cbmV4cG9ydCBjb25zdCBWRVJDRUxfTUFYX1RJTUVPVVRfTVMgPSA1ICogNjAgKiA2MCAqIDEwMDA7IC8vIDUgaG91cnNcbmNvbnN0IExPQ0tfVElNRU9VVF9NUyA9IDMwXzAwMDsgLy8gMzAgc2Vjb25kcyAtIGlmIGxvY2sgb2xkZXIgdGhhbiB0aGlzLCBjb25zaWRlciBpdCBzdGFsZVxuY29uc3QgTE9DS19QT0xMX0lOVEVSVkFMX01TID0gMjAwO1xuXG5jb25zdCBnZXRUZXN0Q3JlZGVudGlhbHMgPSAoKSA9PlxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJ0ZXN0XCJcbiAgICA/IHtcbiAgICAgICAgdG9rZW46IHByb2Nlc3MuZW52LlRFU1RfVkVSQ0VMX1RPS0VOLFxuICAgICAgICB0ZWFtSWQ6IHByb2Nlc3MuZW52LlRFU1RfVkVSQ0VMX1RFQU1fSUQsXG4gICAgICAgIHByb2plY3RJZDogcHJvY2Vzcy5lbnYuVEVTVF9WRVJDRUxfUFJPSkVDVF9JRCxcbiAgICAgIH1cbiAgICA6IHt9O1xuXG4vKipcbiAqIE1vZHVsZS1sZXZlbCBjYWNoZSBmb3IgaW4tZmxpZ2h0IHNhbmRib3ggY3JlYXRpb24gcHJvbWlzZXMuXG4gKiBQcmV2ZW50cyBwYXJhbGxlbCByZXF1ZXN0cyB3aXRoaW4gdGhlIHNhbWUgcHJvY2VzcyBmcm9tIGNyZWF0aW5nIGR1cGxpY2F0ZSBzYW5kYm94ZXMuXG4gKi9cbmNvbnN0IGNyZWF0ZVByb21pc2VzID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPj4oKTtcblxuY29uc3QgQUNUSVZJVFlfVEhST1RUTEVfTVMgPSAxMF8wMDA7XG5jb25zdCBsYXN0QWN0aXZpdHlTZW50ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuY29uc3QgREVGQVVMVF9WQ1BVUyA9IDI7XG5cbmV4cG9ydCBjb25zdCB2ZXJjZWxTYW5kYm94ID0gKHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3cgPSB0cnVlLFxuICBzdG9yYWdlOiBzdG9yYWdlT3ZlcnJpZGUsXG59OiB7XG4gIHNhbmRib3hSZWNvcmQ6IFNhbmRib3hSZWNvcmQgJiB7IGNvbmZpZzogeyB0eXBlOiBcInZlcmNlbFwiIH0gfTtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3c/OiBib29sZWFuO1xuICBzdG9yYWdlPzogU3RvcmFnZTtcbn0pOiBTYW5kYm94ID0+IHtcbiAgY29uc3QgeyBpZCwgY29uZmlnIH0gPSBzYW5kYm94UmVjb3JkO1xuICBjb25zdCB2Y3B1cyA9IGNvbmZpZy5yZXNvdXJjZXM/LnZjcHVzID8/IERFRkFVTFRfVkNQVVM7XG4gIGNvbnN0IHBvcnRzID0gY29uZmlnLnBvcnRzO1xuICBjb25zdCBzdG9yYWdlID0gc3RvcmFnZU92ZXJyaWRlID8/IGdldFN0b3JhZ2Uoc3RvcmFnZUNvbmZpZyk7XG4gIGNvbnN0IGluaXRpYWxWZXJjZWwgPVxuICAgIHNhbmRib3hSZWNvcmQucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgID8gc2FuZGJveFJlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICA6IG51bGw7XG5cbiAgdHlwZSBTYW5kYm94SW5zdGFuY2UgPSBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIFZlcmNlbFNhbmRib3hTREsuZ2V0Pj47XG4gIGxldCBzYW5kYm94UHJvbWlzZTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBTYW5kYm94SW5zdGFuY2U+IHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgZnVuY3Rpb24gcG9sbEZvclNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIExPQ0tfVElNRU9VVF9NUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBMT0NLX1BPTExfSU5URVJWQUxfTVMpKTtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgaWYgKHJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiByZWNvcmQubWVzc2FnZSwgY2F1c2U6IHJlY29yZCB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZlcmNlbFNhbmRib3hJZCA9XG4gICAgICAgIHJlY29yZD8ucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgICAgICA/IHJlY29yZC5wcm92aWRlck1ldGFkYXRhLnNhbmRib3hJZFxuICAgICAgICAgIDogbnVsbDtcbiAgICAgIGlmICh2ZXJjZWxTYW5kYm94SWQpIHtcbiAgICAgICAgcmV0dXJuIHZlcmNlbFNhbmRib3hJZDtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjb3JkPy5hY3F1aXJpbmdMb2NrQXQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHtcbiAgICAgIHJlYXNvbjogXCJUaW1lZCBvdXQgd2FpdGluZyBmb3Igc2FuZGJveCBjcmVhdGlvbiBieSBhbm90aGVyIHByb2Nlc3NcIixcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3QoXG4gICAgc25hcHNob3RJZDogc3RyaW5nXG4gICk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IFZlcmNlbFNhbmRib3hTREsuY3JlYXRlKHtcbiAgICAgICAgICBzb3VyY2U6IHsgdHlwZTogXCJzbmFwc2hvdFwiLCBzbmFwc2hvdElkIH0sXG4gICAgICAgICAgcmVzb3VyY2VzOiB7IHZjcHVzIH0sXG4gICAgICAgICAgdGltZW91dDogVkVSQ0VMX01BWF9USU1FT1VUX01TLFxuICAgICAgICAgIHBvcnRzLFxuICAgICAgICAgIC4uLmdldFRlc3RDcmVkZW50aWFscygpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGNyZWF0ZWRBdDogbm93LFxuICAgICAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICBwcm92aWRlcjogXCJ2ZXJjZWxcIixcbiAgICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveC5zYW5kYm94SWQsXG4gICAgICAgICAgICBzbmFwc2hvdElkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2FuZGJveC5zYW5kYm94SWQ7XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRnJlc2hTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IFZlcmNlbFNhbmRib3hTREsuY3JlYXRlKHtcbiAgICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgICAgcG9ydHMsXG4gICAgICAgICAgLi4uZ2V0VGVzdENyZWRlbnRpYWxzKCksXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LnNhbmRib3hJZCxcbiAgICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzYW5kYm94LnNhbmRib3hJZDtcbiAgICAgIH0sXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBkb0dldE9yQ3JlYXRlU2FuZGJveElkKCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgaWYgKGluaXRpYWxWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgcmV0dXJuIGluaXRpYWxWZXJjZWwuc2FuZGJveElkO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBleGlzdGluZy5tZXNzYWdlLCBjYXVzZTogZXhpc3RpbmcgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmdWZXJjZWwgPVxuICAgICAgZXhpc3Rpbmc/LnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG5cbiAgICBpZiAoZXhpc3RpbmdWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nVmVyY2VsLnNhbmRib3hJZDtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNBY3RpdmVMb2NrID1cbiAgICAgIGV4aXN0aW5nPy5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgIGV4aXN0aW5nLmFjcXVpcmluZ0xvY2tBdCAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGV4aXN0aW5nLmFjcXVpcmluZ0xvY2tBdCA8IExPQ0tfVElNRU9VVF9NUztcblxuICAgIGlmIChoYXNBY3RpdmVMb2NrKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGxvY2tJZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgIGlkLFxuICAgICAgY29uZmlnLFxuICAgICAgY3JlYXRlZEF0OiBleGlzdGluZz8uY3JlYXRlZEF0ID8/IHNhbmRib3hSZWNvcmQuY3JlYXRlZEF0LFxuICAgICAgbGFzdEFjdGl2aXR5QXQ6IGV4aXN0aW5nPy5sYXN0QWN0aXZpdHlBdCA/PyBzYW5kYm94UmVjb3JkLmxhc3RBY3Rpdml0eUF0LFxuICAgICAgYWNxdWlyaW5nTG9ja0lkOiBsb2NrSWQsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG5vdyxcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgc25hcHNob3RJZDpcbiAgICAgICAgICBleGlzdGluZ1ZlcmNlbD8uc25hcHNob3RJZCA/PyBpbml0aWFsVmVyY2VsPy5zbmFwc2hvdElkID8/IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgYWZ0ZXJMb2NrID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGFmdGVyTG9jayBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogYWZ0ZXJMb2NrLm1lc3NhZ2UsIGNhdXNlOiBhZnRlckxvY2sgfSk7XG4gICAgfVxuICAgIGlmIChhZnRlckxvY2s/LmFjcXVpcmluZ0xvY2tJZCAhPT0gbG9ja0lkKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHNuYXBzaG90SWQgPVxuICAgICAgZXhpc3RpbmdWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGluaXRpYWxWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGNvbmZpZy5saWZlY3ljbGU/LnNuYXBzaG90SWQ7XG4gICAgaWYgKHNuYXBzaG90SWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3Qoc25hcHNob3RJZCk7XG4gICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlRnJlc2hTYW5kYm94KCk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZVNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGNyZWF0ZVByb21pc2VzLmdldChpZCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlID0gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgY3JlYXRlUHJvbWlzZXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcbiAgICBjcmVhdGVQcm9taXNlcy5zZXQoaWQsIHByb21pc2UpO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZG9HZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgY29uc3QgdmVyY2VsU2FuZGJveElkID0gYXdhaXQgZ2V0T3JDcmVhdGVTYW5kYm94SWQoKTtcbiAgICBpZiAodmVyY2VsU2FuZGJveElkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiB2ZXJjZWxTYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6ICgpID0+XG4gICAgICAgIFZlcmNlbFNhbmRib3hTREsuZ2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHZlcmNlbFNhbmRib3hJZCxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSksXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgaWYgKCFzYW5kYm94UHJvbWlzZSkge1xuICAgICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcbiAgICB9XG4gICAgcmV0dXJuIHNhbmRib3hQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gdXBkYXRlTGFzdEFjdGl2aXR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgbGFzdFNlbnQgPSBsYXN0QWN0aXZpdHlTZW50LmdldChpZCk7XG4gICAgaWYgKGxhc3RTZW50ICYmIG5vdyAtIGxhc3RTZW50IDwgQUNUSVZJVFlfVEhST1RUTEVfTVMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdEFjdGl2aXR5U2VudC5zZXQoaWQsIG5vdyk7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBleGlzdGluZ1ZlcmNlbCA9XG4gICAgICBleGlzdGluZy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICA/IGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGFcbiAgICAgICAgOiBudWxsO1xuICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgaWQ6IGV4aXN0aW5nLmlkLFxuICAgICAgY29uZmlnOiBleGlzdGluZy5jb25maWcsXG4gICAgICBjcmVhdGVkQXQ6IGV4aXN0aW5nLmNyZWF0ZWRBdCxcbiAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICBwcm92aWRlck1ldGFkYXRhOiBleGlzdGluZ1ZlcmNlbCA/PyB7XG4gICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93KSB7XG4gICAgICAvLyB0b2RvIHJlLWVuYWJsZSBvbmNlIHdlIGZpZ3VyZSBvdXQgd2h5IHdvcmtmbG93IHRocm93cyBhIGJ1bmNoIG9mIGVycm9ycyBpbiBkZXZcbiAgICAgIC8vIGNvbnN0IGxpZmVjeWNsZUlucHV0OiBTYW5kYm94TGlmZWN5Y2xlSW5wdXQgPSB7XG4gICAgICAvLyAgIGlkLFxuICAgICAgLy8gICBzdG9yYWdlQ29uZmlnLFxuICAgICAgLy8gICBpbml0aWFsQ29uZmlnOiBjb25maWcsXG4gICAgICAvLyB9O1xuICAgICAgLy8gdHJ5IHtcbiAgICAgIC8vICAgYXdhaXQgc2FuZGJveEFjdGl2aXR5SG9vay5yZXN1bWUoaWQsIHtcbiAgICAgIC8vICAgICB0eXBlOiBcImFjdGl2aXR5XCIsXG4gICAgICAvLyAgICAgbmV3Q29uZmlnOiBjb25maWcsXG4gICAgICAvLyAgIH0pO1xuICAgICAgLy8gfSBjYXRjaCB7XG4gICAgICAvLyAgIGF3YWl0IHN0YXJ0KHNhbmRib3hMaWZlY3ljbGVXb3JrZmxvdywgW3sgaW5wdXQ6IGxpZmVjeWNsZUlucHV0IH1dKTtcbiAgICAgIC8vIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBsaWZlY3ljbGU6IFNhbmRib3hMaWZlY3ljbGUgPSB7XG4gICAgc3RhcnQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgYXdhaXQgdXBkYXRlTGFzdEFjdGl2aXR5KCk7XG4gICAgICByZXR1cm4gc2FuZGJveC5zdGF0dXMgYXMgU2FuZGJveFN0YXR1cztcbiAgICB9LFxuXG4gICAgc25hcHNob3Q6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHNhbmRib3guc25hcHNob3QoKTtcbiAgICAgICAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgY3JlYXRlZEF0OlxuICAgICAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yID8gbnVsbCA6IGV4aXN0aW5nPy5jcmVhdGVkQXQgPz8gbnVsbCxcbiAgICAgICAgICAgIGxhc3RBY3Rpdml0eUF0OlxuICAgICAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yXG4gICAgICAgICAgICAgICAgPyBudWxsXG4gICAgICAgICAgICAgICAgOiBleGlzdGluZz8ubGFzdEFjdGl2aXR5QXQgPz8gbnVsbCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgICAgICAgc25hcHNob3RJZDogc25hcHNob3Quc25hcHNob3RJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHsgc25hcHNob3RJZDogc25hcHNob3Quc25hcHNob3RJZCB9O1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgc3RvcDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBzYW5kYm94LnN0b3AoKTtcbiAgICAgICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgICBpZDogZXhpc3RpbmcuaWQsXG4gICAgICAgICAgICBjb25maWc6IGV4aXN0aW5nLmNvbmZpZyxcbiAgICAgICAgICAgIGNyZWF0ZWRBdDogZXhpc3RpbmcuY3JlYXRlZEF0LFxuICAgICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IGV4aXN0aW5nLmxhc3RBY3Rpdml0eUF0LFxuICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgICAgICBwcm92aWRlcjogXCJ2ZXJjZWxcIixcbiAgICAgICAgICAgICAgc2FuZGJveElkOiBudWxsLFxuICAgICAgICAgICAgICBzbmFwc2hvdElkOiBudWxsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgZ2V0U3RhdHVzOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW5kYm94LnN0YXR1cyBhcyBTYW5kYm94U3RhdHVzO1xuICAgIH0sXG5cbiAgICBnZXRDcmVhdGVkQXQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNhbmRib3guY3JlYXRlZEF0O1xuICAgIH0sXG5cbiAgICBnZXRSZW1haW5pbmdUaW1lb3V0OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW5kYm94LnRpbWVvdXQ7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBzYW5kYm94OiBTYW5kYm94ID0ge1xuICAgIGlkLFxuICAgIGNvbmZpZyxcbiAgICBleGVjOiBhc3luYyAoeyBjb21tYW5kLCBhcmdzLCBzaWduYWwgfSkgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVwZGF0ZVByb21pc2UgPSB1cGRhdGVMYXN0QWN0aXZpdHkoKTtcblxuICAgICAgY29uc3QgZXhlY1Jlc3VsdCA9IGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IG91dHB1dCA9IGF3YWl0IGluc3RhbmNlLnJ1bkNvbW1hbmQoY29tbWFuZCwgYXJncywgeyBzaWduYWwgfSk7XG5cbiAgICAgICAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICAgICAgICBsZXQgc3RkZXJyID0gXCJcIjtcbiAgICAgICAgICBjb25zdCBsb2dCdWZmZXI6IExvZ0VudHJ5W10gPSBbXTtcbiAgICAgICAgICBjb25zdCBzdGF0ZSA9IHtcbiAgICAgICAgICAgIHJlc29sdmU6IG51bGwgYXMgKCgpID0+IHZvaWQpIHwgbnVsbCxcbiAgICAgICAgICAgIGNvbnN1bWVkOiBmYWxzZSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgY29uc3VtZUxvZ3MgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBsb2cgb2Ygb3V0cHV0LmxvZ3MoKSkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPVxuICAgICAgICAgICAgICAgIGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCJcbiAgICAgICAgICAgICAgICAgID8geyBzdHJlYW06IFwic3Rkb3V0XCIsIGRhdGE6IGxvZy5kYXRhIH1cbiAgICAgICAgICAgICAgICAgIDogeyBzdHJlYW06IFwic3RkZXJyXCIsIGRhdGE6IGxvZy5kYXRhIH07XG5cbiAgICAgICAgICAgICAgaWYgKGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCIpIHtcbiAgICAgICAgICAgICAgICBzdGRvdXQgKz0gbG9nLmRhdGE7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RkZXJyICs9IGxvZy5kYXRhO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgbG9nQnVmZmVyLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICBzdGF0ZS5yZXNvbHZlPy4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0YXRlLmNvbnN1bWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHN0YXRlLnJlc29sdmU/LigpO1xuICAgICAgICAgIH0pKCk7XG5cbiAgICAgICAgICBhc3luYyBmdW5jdGlvbiogbG9ncygpOiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PiB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICAgICAgd2hpbGUgKCFzdGF0ZS5jb25zdW1lZCB8fCBpbmRleCA8IGxvZ0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgaWYgKGluZGV4IDwgbG9nQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHlpZWxkIGxvZ0J1ZmZlcltpbmRleCsrXTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgc3RhdGUucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc3RhdGUucmVzb2x2ZSA9IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb25zdW1lTG9ncy50aGVuKCgpID0+ICh7XG4gICAgICAgICAgICBzdGRvdXQsXG4gICAgICAgICAgICBzdGRlcnIsXG4gICAgICAgICAgICBleGl0Q29kZTogb3V0cHV0LmV4aXRDb2RlLFxuICAgICAgICAgIH0pKTtcblxuICAgICAgICAgIHJldHVybiB7IGNvbW1hbmRJZDogb3V0cHV0LmNtZElkLCBsb2dzLCByZXN1bHQgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHVwZGF0ZVByb21pc2U7XG4gICAgICByZXR1cm4gZXhlY1Jlc3VsdDtcbiAgICB9LFxuXG4gICAgZ2V0RG9tYWluOiBhc3luYyAocG9ydCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94LmRvbWFpbihwb3J0KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGtpbGw6IGFzeW5jICh7IGNvbW1hbmRJZCwgc3RvcmFnZTogY21kU3RvcmFnZSB9KSA9PiB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY21kID0gYXdhaXQgY21kU3RvcmFnZS5jb21tYW5kLmdldChjb21tYW5kSWQpO1xuICAgICAgaWYgKGNtZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBjbWQubWVzc2FnZSwgY2F1c2U6IGNtZCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjbWQgJiYgY21kLnN0YXR1cyA9PT0gXCJydW5uaW5nXCIpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY21kU3RvcmFnZS5jb21tYW5kLnNldCh7XG4gICAgICAgICAgLi4uY21kLFxuICAgICAgICAgIHN0YXR1czogXCJraWxsZWRcIixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiByZXN1bHQubWVzc2FnZSwgY2F1c2U6IHJlc3VsdCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9LFxuXG4gICAgd3JpdGVGaWxlczogKG9wdHMpID0+IHdyaXRlRmlsZXMoeyBzYW5kYm94LCAuLi5vcHRzIH0pLFxuXG4gICAgbGlmZWN5Y2xlLFxuICB9O1xuXG4gIGlmIChjb25maWcubGlmZWN5Y2xlPy5hdXRvU3RhcnQgIT09IGZhbHNlKSB7XG4gICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcbiAgfVxuXG4gIHJldHVybiBzYW5kYm94O1xufTtcbiIsICJpbXBvcnQgdHlwZSB7IFNhbmRib3hSZWNvcmQsIFN0b3JhZ2VDb25maWcgfSBmcm9tIFwiLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHsgbG9jYWxTYW5kYm94IH0gZnJvbSBcIi4vYmluZGluZ3MvbG9jYWxcIjtcbmltcG9ydCB7IHZlcmNlbFNhbmRib3ggfSBmcm9tIFwiLi9iaW5kaW5ncy92ZXJjZWxcIjtcbmltcG9ydCB0eXBlIHsgU2FuZGJveCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTYW5kYm94KHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbn06IHtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZDtcbn0pOiBTYW5kYm94IHtcbiAgY29uc3QgeyBjb25maWcgfSA9IHNhbmRib3hSZWNvcmQ7XG4gIHN3aXRjaCAoY29uZmlnLnR5cGUpIHtcbiAgICBjYXNlIFwibG9jYWxcIjpcbiAgICAgIHJldHVybiBsb2NhbFNhbmRib3goe1xuICAgICAgICBzYW5kYm94UmVjb3JkOiBzYW5kYm94UmVjb3JkIGFzIFNhbmRib3hSZWNvcmQgJiB7XG4gICAgICAgICAgY29uZmlnOiB7IHR5cGU6IFwibG9jYWxcIiB9O1xuICAgICAgICB9LFxuICAgICAgICBzdG9yYWdlQ29uZmlnLFxuICAgICAgfSk7XG4gICAgY2FzZSBcInZlcmNlbFwiOlxuICAgICAgcmV0dXJuIHZlcmNlbFNhbmRib3goe1xuICAgICAgICBzYW5kYm94UmVjb3JkOiBzYW5kYm94UmVjb3JkIGFzIFNhbmRib3hSZWNvcmQgJiB7XG4gICAgICAgICAgY29uZmlnOiB7IHR5cGU6IFwidmVyY2VsXCIgfTtcbiAgICAgICAgfSxcbiAgICAgICAgc3RvcmFnZUNvbmZpZyxcbiAgICAgIH0pO1xuICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkN1c3RvbSBzYW5kYm94ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgZGVmYXVsdDpcbiAgICAgIGNvbmZpZyBzYXRpc2ZpZXMgbmV2ZXI7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBVbmtub3duIHNhbmRib3ggdHlwZTogJHtcbiAgICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IC5cbiAgICAgICAgICAoY29uZmlnIGFzIGFueSkudHlwZVxuICAgICAgICB9YFxuICAgICAgKTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7O0FBQ0EsU0FBUyxhQUFhO0FBQ3RCLFlBQVksWUFBWTtBQUN4QixTQUFTLFlBQVk7OztBQ0hyQixZQUFZLFVBQVU7QUFXdEIsZUFBc0IsV0FBVyxNQUlmO0FBQ2hCLFFBQU0sRUFBRSxTQUFTLE9BQU8sU0FBUyxJQUFJO0FBRXJDLE1BQUksTUFBTSxXQUFXLEdBQUc7QUFDdEI7QUFBQSxFQUNGO0FBRUEsUUFBTSxZQUFZLE1BQU0sSUFBSSxDQUFDLFNBQWMsV0FBTSxLQUFLLFVBQVUsS0FBSyxJQUFJLENBQUM7QUFDMUUsUUFBTSxhQUFhLENBQUMsR0FBRyxJQUFJLElBQUksVUFBVSxJQUFJLENBQUMsTUFBVyxXQUFNLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzRSxRQUFNLGVBQWUsVUFBVSxPQUFPLENBQUMsTUFBTSxFQUFFLFNBQVMsS0FBSyxDQUFDO0FBRTlELFFBQU0sY0FBYyxNQUFNLFFBQVEsS0FBSztBQUFBLElBQ3JDLFNBQVM7QUFBQSxJQUNULE1BQU0sQ0FBQyxNQUFNLEdBQUcsVUFBVTtBQUFBLEVBQzVCLENBQUM7QUFDRCxNQUFJLHVCQUF1QixPQUFPO0FBQ2hDLFVBQU07QUFBQSxFQUNSO0FBQ0EsUUFBTSxZQUFZO0FBRWxCLFFBQU0sYUFBYTtBQUVuQixXQUFTLElBQUksR0FBRyxJQUFJLE1BQU0sUUFBUSxLQUFLO0FBQ3JDLFVBQU0sT0FBTyxNQUFNLENBQUM7QUFDcEIsVUFBTSxXQUFXLFVBQVUsQ0FBQztBQUM1QixVQUFNLGdCQUFnQixTQUFTLEtBQUssT0FBTztBQUUzQyxRQUFJLGNBQWMsU0FBUyxZQUFZO0FBQ3JDLFlBQU0sU0FBUyxPQUFPLENBQUM7QUFDdkIsWUFBTSxhQUFhLE1BQU0sUUFBUSxLQUFLO0FBQUEsUUFDcEMsU0FBUztBQUFBLFFBQ1QsTUFBTTtBQUFBLFVBQ0o7QUFBQSxVQUNBLGVBQWUsTUFBTSxRQUFRLENBQUMsUUFBUSxNQUFNO0FBQUEsRUFDcEQsYUFBYTtBQUFBLEVBQ2IsTUFBTTtBQUFBLFFBQ0E7QUFBQSxNQUNGLENBQUM7QUFFRCxVQUFJLHNCQUFzQixPQUFPO0FBQy9CLGNBQU07QUFBQSxNQUNSO0FBRUEsWUFBTSxFQUFFLFVBQVUsT0FBTyxJQUFJLE1BQU0sV0FBVztBQUM5QyxVQUFJLGFBQWEsR0FBRztBQUNsQixjQUFNLElBQUk7QUFBQSxVQUNSLG9DQUFvQyxRQUFRLEtBQUssTUFBTTtBQUFBLFFBQ3pEO0FBQUEsTUFDRjtBQUFBLElBQ0YsT0FBTztBQUNMLFlBQU0sVUFBVSxjQUFjLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQztBQUU3QyxZQUFNLGNBQWMsTUFBTSxRQUFRLEtBQUs7QUFBQSxRQUNyQyxTQUFTO0FBQUEsUUFDVCxNQUFNLENBQUMsTUFBTSxLQUFLLE1BQU0sT0FBTyxDQUFDLEVBQUU7QUFBQSxNQUNwQyxDQUFDO0FBQ0QsVUFBSSx1QkFBdUIsT0FBTztBQUNoQyxjQUFNO0FBQUEsTUFDUjtBQUNBLFlBQU0sWUFBWTtBQUVsQixlQUFTLFNBQVMsR0FBRyxTQUFTLGNBQWMsUUFBUSxVQUFVLFlBQVk7QUFDeEUsY0FBTSxRQUFRLGNBQWMsTUFBTSxRQUFRLFNBQVMsVUFBVTtBQUM3RCxjQUFNLFNBQVMsU0FBUyxNQUFNO0FBQzlCLGNBQU0sZUFBZSxNQUFNLFFBQVEsS0FBSztBQUFBLFVBQ3RDLFNBQVM7QUFBQSxVQUNULE1BQU07QUFBQSxZQUNKO0FBQUEsWUFDQSxVQUFVLE1BQU0sT0FBTyxDQUFDLFFBQVEsTUFBTTtBQUFBLEVBQ2hELEtBQUs7QUFBQSxFQUNMLE1BQU07QUFBQSxVQUNFO0FBQUEsUUFDRixDQUFDO0FBRUQsWUFBSSx3QkFBd0IsT0FBTztBQUNqQyxnQkFBTTtBQUFBLFFBQ1I7QUFFQSxjQUFNLEVBQUUsVUFBQUEsV0FBVSxRQUFBQyxRQUFPLElBQUksTUFBTSxhQUFhO0FBQ2hELFlBQUlELGNBQWEsR0FBRztBQUNsQixnQkFBTSxJQUFJO0FBQUEsWUFDUiwwQ0FBMENBLFNBQVEsS0FBS0MsT0FBTTtBQUFBLFVBQy9EO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFFQSxZQUFNLGVBQWUsTUFBTSxRQUFRLEtBQUs7QUFBQSxRQUN0QyxTQUFTO0FBQUEsUUFDVCxNQUFNO0FBQUEsVUFDSjtBQUFBLFVBQ0EsZUFBZSxNQUFNLE9BQU8sQ0FBQyxNQUFNLE1BQU0sUUFBUSxDQUFDLGFBQWEsTUFBTSxPQUFPLENBQUM7QUFBQSxRQUMvRTtBQUFBLE1BQ0YsQ0FBQztBQUVELFVBQUksd0JBQXdCLE9BQU87QUFDakMsY0FBTTtBQUFBLE1BQ1I7QUFFQSxZQUFNLEVBQUUsVUFBVSxPQUFPLElBQUksTUFBTSxhQUFhO0FBQ2hELFVBQUksYUFBYSxHQUFHO0FBQ2xCLGNBQU0sSUFBSTtBQUFBLFVBQ1IsMkNBQTJDLFFBQVEsS0FBSyxNQUFNO0FBQUEsUUFDaEU7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxNQUFJLGFBQWEsU0FBUyxHQUFHO0FBQzNCLFVBQU0sY0FBYyxNQUFNLFFBQVEsS0FBSztBQUFBLE1BQ3JDLFNBQVM7QUFBQSxNQUNULE1BQU0sQ0FBQyxNQUFNLEdBQUcsWUFBWTtBQUFBLElBQzlCLENBQUM7QUFDRCxRQUFJLHVCQUF1QixPQUFPO0FBQ2hDLFlBQU07QUFBQSxJQUNSO0FBQ0EsVUFBTSxZQUFZO0FBQUEsRUFDcEI7QUFDRjtBQUVBLFNBQVMsU0FBUyxTQUFrQztBQUNsRCxNQUFJLE9BQU8sWUFBWSxVQUFVO0FBQy9CLFdBQU8sT0FBTyxLQUFLLE9BQU8sRUFBRSxTQUFTLFFBQVE7QUFBQSxFQUMvQztBQUNBLFNBQU8sUUFBUSxTQUFTLFFBQVE7QUFDbEM7QUFFQSxTQUFTLE1BQU0sR0FBbUI7QUFDaEMsU0FBTyxJQUFJLEVBQUUsUUFBUSxNQUFNLE9BQU8sQ0FBQztBQUNyQzs7O0FEdElPLElBQU0sZUFBZSxDQUFDO0FBQUEsRUFDM0I7QUFDRixNQUdlO0FBQ2IsUUFBTSxTQUFTLGNBQWM7QUFDN0IsUUFBTSxXQUFXLE9BQU8sUUFBUSxRQUFRLElBQUk7QUFDNUMsUUFBTSxZQUFZLG9CQUFJLElBQTBCO0FBRWhELFFBQU0sVUFBbUI7QUFBQSxJQUN2QixJQUFJLGNBQWM7QUFBQSxJQUNsQixRQUFRLGNBQWM7QUFBQSxJQUN0QixNQUFNLENBQUMsRUFBRSxTQUFTLE1BQU0sT0FBTyxNQUFNO0FBQ25DLGFBQWMsZ0JBQVM7QUFBQSxRQUNyQixLQUFLLE1BQU07QUFDVCxnQkFBTSxZQUFZLFdBQVcsS0FBSyxDQUFDO0FBRW5DLGdCQUFNLFFBQVEsTUFBTSxTQUFTLE1BQU07QUFBQSxZQUNqQyxLQUFLO0FBQUEsWUFDTDtBQUFBLFVBQ0YsQ0FBQztBQUVELG9CQUFVLElBQUksV0FBVyxLQUFLO0FBRTlCLGNBQUksU0FBUztBQUNiLGNBQUksU0FBUztBQUNiLGdCQUFNLFdBQXVCLENBQUM7QUFDOUIsY0FBSSxhQUFrQztBQUN0QyxjQUFJLFNBQVM7QUFFYixnQkFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFNBQTBCO0FBQ2pELGtCQUFNLE1BQU0sT0FBTyxJQUFJO0FBQ3ZCLHNCQUFVO0FBQ1YscUJBQVMsS0FBSyxFQUFFLFFBQVEsVUFBVSxNQUFNLElBQUksQ0FBQztBQUM3Qyx5QkFBYTtBQUFBLFVBQ2YsQ0FBQztBQUVELGdCQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBMEI7QUFDakQsa0JBQU0sTUFBTSxPQUFPLElBQUk7QUFDdkIsc0JBQVU7QUFDVixxQkFBUyxLQUFLLEVBQUUsUUFBUSxVQUFVLE1BQU0sSUFBSSxDQUFDO0FBQzdDLHlCQUFhO0FBQUEsVUFDZixDQUFDO0FBRUQsZ0JBQU0sU0FBUyxJQUFJLFFBSWhCLENBQUMsU0FBUyxXQUFXO0FBQ3RCLGtCQUFNLEdBQUcsU0FBUyxDQUFDLFFBQVE7QUFDekIsd0JBQVUsT0FBTyxTQUFTO0FBQzFCLHVCQUFTO0FBQ1QsMkJBQWE7QUFDYixxQkFBTyxHQUFHO0FBQUEsWUFDWixDQUFDO0FBRUQsa0JBQU0sR0FBRyxTQUFTLENBQUMsU0FBd0I7QUFDekMsd0JBQVUsT0FBTyxTQUFTO0FBQzFCLHVCQUFTO0FBQ1QsMkJBQWE7QUFDYixzQkFBUSxFQUFFLFFBQVEsUUFBUSxVQUFVLFFBQVEsRUFBRSxDQUFDO0FBQUEsWUFDakQsQ0FBQztBQUFBLFVBQ0gsQ0FBQztBQUVELDBCQUFnQixPQUFnQztBQUM5QyxtQkFBTyxDQUFDLFVBQVUsU0FBUyxTQUFTLEdBQUc7QUFDckMsb0JBQU0sUUFBUSxTQUFTLE1BQU07QUFDN0Isa0JBQUksT0FBTztBQUNULHNCQUFNO0FBQUEsY0FDUixXQUFXLENBQUMsUUFBUTtBQUNsQixzQkFBTSxJQUFJLFFBQWMsQ0FBQyxZQUFZO0FBQ25DLCtCQUFhO0FBQUEsZ0JBQ2YsQ0FBQztBQUNELDZCQUFhO0FBQUEsY0FDZjtBQUFBLFlBQ0Y7QUFBQSxVQUNGO0FBRUEsaUJBQU8sUUFBUSxRQUFRLEVBQUUsV0FBVyxNQUFNLE9BQU8sQ0FBQztBQUFBLFFBQ3BEO0FBQUEsUUFDQSxPQUFPLENBQUMsTUFDTixJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsTUFDcEQsQ0FBQztBQUFBLElBQ0g7QUFBQSxJQUVBLFdBQVcsQ0FBQyxTQUFTO0FBQ25CLGFBQU8sUUFBUSxRQUFRLG9CQUFvQixJQUFJLEVBQUU7QUFBQSxJQUNuRDtBQUFBLElBRUEsTUFBTSxPQUFPLEVBQUUsV0FBVyxRQUFRLE1BQU07QUFDdEMsWUFBTSxRQUFRLFVBQVUsSUFBSSxTQUFTO0FBQ3JDLFVBQUksQ0FBQyxPQUFPO0FBQ1YsZUFBTyxJQUFJLGFBQWE7QUFBQSxVQUN0QixRQUFRLFdBQVcsU0FBUztBQUFBLFFBQzlCLENBQUM7QUFBQSxNQUNIO0FBRUEsWUFBTSxLQUFLLFNBQVM7QUFFcEIsWUFBTSxNQUFNLE1BQU0sUUFBUSxRQUFRLElBQUksU0FBUztBQUMvQyxVQUFJLGVBQWUsT0FBTztBQUN4QixlQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsSUFBSSxTQUFTLE9BQU8sSUFBSSxDQUFDO0FBQUEsTUFDN0Q7QUFDQSxVQUFJLE9BQU8sSUFBSSxXQUFXLFdBQVc7QUFDbkMsY0FBTSxTQUFTLE1BQU0sUUFBUSxRQUFRLElBQUk7QUFBQSxVQUN2QyxHQUFHO0FBQUEsVUFDSCxRQUFRO0FBQUEsUUFDVixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTyxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sU0FBUyxPQUFPLE9BQU8sQ0FBQztBQUFBLFFBQ25FO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxJQUVBLFlBQVksQ0FBQyxTQUFTLFdBQVcsRUFBRSxTQUFTLEdBQUcsS0FBSyxDQUFDO0FBQUEsRUFDdkQ7QUFFQSxTQUFPO0FBQ1Q7OztBRWhJQSxZQUFZQyxhQUFZO0FBQ3hCLFNBQVMsV0FBVyx3QkFBd0I7QUFzQnJDLElBQU0sd0JBQXdCLElBQUksS0FBSyxLQUFLO0FBQ25ELElBQU0sa0JBQWtCO0FBQ3hCLElBQU0sd0JBQXdCO0FBRTlCLElBQU0scUJBQXFCLE1BQ3pCLFFBQVEsSUFBSSxhQUFhLFNBQ3JCO0FBQUEsRUFDRSxPQUFPLFFBQVEsSUFBSTtBQUFBLEVBQ25CLFFBQVEsUUFBUSxJQUFJO0FBQUEsRUFDcEIsV0FBVyxRQUFRLElBQUk7QUFDekIsSUFDQSxDQUFDO0FBTVAsSUFBTSxpQkFBaUIsb0JBQUksSUFBNEM7QUFFdkUsSUFBTSx1QkFBdUI7QUFDN0IsSUFBTSxtQkFBbUIsb0JBQUksSUFBb0I7QUFFakQsSUFBTSxnQkFBZ0I7QUFFZixJQUFNLGdCQUFnQixDQUFDO0FBQUEsRUFDNUI7QUFBQSxFQUNBO0FBQUEsRUFDQSwwQkFBMEI7QUFBQSxFQUMxQixTQUFTO0FBQ1gsTUFLZTtBQUNiLFFBQU0sRUFBRSxJQUFJLE9BQU8sSUFBSTtBQUN2QixRQUFNLFFBQVEsT0FBTyxXQUFXLFNBQVM7QUFDekMsUUFBTSxRQUFRLE9BQU87QUFDckIsUUFBTSxVQUFVLG1CQUFtQixXQUFXLGFBQWE7QUFDM0QsUUFBTSxnQkFDSixjQUFjLGtCQUFrQixhQUFhLFdBQ3pDLGNBQWMsbUJBQ2Q7QUFHTixNQUFJLGlCQUFpRTtBQUVyRSxpQkFBZSxtQkFBbUQ7QUFDaEUsVUFBTSxXQUFXLEtBQUssSUFBSSxJQUFJO0FBQzlCLFdBQU8sS0FBSyxJQUFJLElBQUksVUFBVTtBQUM1QixZQUFNLElBQUksUUFBUSxDQUFDLE1BQU0sV0FBVyxHQUFHLHFCQUFxQixDQUFDO0FBQzdELFlBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDM0MsVUFBSSxrQkFBa0IsT0FBTztBQUMzQixlQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxTQUFTLE9BQU8sT0FBTyxDQUFDO0FBQUEsTUFDbkU7QUFDQSxZQUFNLGtCQUNKLFFBQVEsa0JBQWtCLGFBQWEsV0FDbkMsT0FBTyxpQkFBaUIsWUFDeEI7QUFDTixVQUFJLGlCQUFpQjtBQUNuQixlQUFPO0FBQUEsTUFDVDtBQUNBLFVBQUksQ0FBQyxRQUFRLGlCQUFpQjtBQUM1QjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQ0EsV0FBTyxJQUFJLGFBQWE7QUFBQSxNQUN0QixRQUFRO0FBQUEsSUFDVixDQUFDO0FBQUEsRUFDSDtBQUVBLGlCQUFlLDBCQUNiLFlBQ2dDO0FBQ2hDLFdBQU8sTUFBYSxpQkFBUztBQUFBLE1BQzNCLEtBQUssWUFBWTtBQUNmLGNBQU1DLFdBQVUsTUFBTSxpQkFBaUIsT0FBTztBQUFBLFVBQzVDLFFBQVEsRUFBRSxNQUFNLFlBQVksV0FBVztBQUFBLFVBQ3ZDLFdBQVcsRUFBRSxNQUFNO0FBQUEsVUFDbkIsU0FBUztBQUFBLFVBQ1Q7QUFBQSxVQUNBLEdBQUcsbUJBQW1CO0FBQUEsUUFDeEIsQ0FBQztBQUNELGNBQU0sTUFBTSxLQUFLLElBQUk7QUFDckIsY0FBTSxRQUFRLFFBQVEsSUFBSTtBQUFBLFVBQ3hCO0FBQUEsVUFDQTtBQUFBLFVBQ0EsV0FBVztBQUFBLFVBQ1gsZ0JBQWdCO0FBQUEsVUFDaEIsaUJBQWlCO0FBQUEsVUFDakIsaUJBQWlCO0FBQUEsVUFDakIsa0JBQWtCO0FBQUEsWUFDaEIsVUFBVTtBQUFBLFlBQ1YsV0FBV0EsU0FBUTtBQUFBLFlBQ25CO0FBQUEsVUFDRjtBQUFBLFFBQ0YsQ0FBQztBQUNELGVBQU9BLFNBQVE7QUFBQSxNQUNqQjtBQUFBLE1BQ0EsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLElBQ2hFLENBQUM7QUFBQSxFQUNIO0FBRUEsaUJBQWUscUJBQXFEO0FBQ2xFLFdBQU8sTUFBYSxpQkFBUztBQUFBLE1BQzNCLEtBQUssWUFBWTtBQUNmLGNBQU1BLFdBQVUsTUFBTSxpQkFBaUIsT0FBTztBQUFBLFVBQzVDLFdBQVcsRUFBRSxNQUFNO0FBQUEsVUFDbkIsU0FBUztBQUFBLFVBQ1Q7QUFBQSxVQUNBLEdBQUcsbUJBQW1CO0FBQUEsUUFDeEIsQ0FBQztBQUNELGNBQU0sTUFBTSxLQUFLLElBQUk7QUFDckIsY0FBTSxRQUFRLFFBQVEsSUFBSTtBQUFBLFVBQ3hCO0FBQUEsVUFDQTtBQUFBLFVBQ0EsV0FBVztBQUFBLFVBQ1gsZ0JBQWdCO0FBQUEsVUFDaEIsaUJBQWlCO0FBQUEsVUFDakIsaUJBQWlCO0FBQUEsVUFDakIsa0JBQWtCO0FBQUEsWUFDaEIsVUFBVTtBQUFBLFlBQ1YsV0FBV0EsU0FBUTtBQUFBLFlBQ25CLFlBQVk7QUFBQSxVQUNkO0FBQUEsUUFDRixDQUFDO0FBQ0QsZUFBT0EsU0FBUTtBQUFBLE1BQ2pCO0FBQUEsTUFDQSxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsSUFDaEUsQ0FBQztBQUFBLEVBQ0g7QUFFQSxpQkFBZSx5QkFBeUQ7QUFDdEUsUUFBSSxlQUFlLFdBQVc7QUFDNUIsYUFBTyxjQUFjO0FBQUEsSUFDdkI7QUFFQSxVQUFNLFdBQVcsTUFBTSxRQUFRLFFBQVEsSUFBSSxFQUFFO0FBQzdDLFFBQUksb0JBQW9CLE9BQU87QUFDN0IsYUFBTyxJQUFJLGFBQWEsRUFBRSxRQUFRLFNBQVMsU0FBUyxPQUFPLFNBQVMsQ0FBQztBQUFBLElBQ3ZFO0FBRUEsVUFBTSxpQkFDSixVQUFVLGtCQUFrQixhQUFhLFdBQ3JDLFNBQVMsbUJBQ1Q7QUFFTixRQUFJLGdCQUFnQixXQUFXO0FBQzdCLGFBQU8sZUFBZTtBQUFBLElBQ3hCO0FBRUEsVUFBTSxnQkFDSixVQUFVLG1CQUNWLFNBQVMsbUJBQ1QsS0FBSyxJQUFJLElBQUksU0FBUyxrQkFBa0I7QUFFMUMsUUFBSSxlQUFlO0FBQ2pCLGFBQU8saUJBQWlCO0FBQUEsSUFDMUI7QUFFQSxVQUFNLFNBQVMsT0FBTyxXQUFXO0FBQ2pDLFVBQU0sTUFBTSxLQUFLLElBQUk7QUFDckIsVUFBTSxRQUFRLFFBQVEsSUFBSTtBQUFBLE1BQ3hCO0FBQUEsTUFDQTtBQUFBLE1BQ0EsV0FBVyxVQUFVLGFBQWEsY0FBYztBQUFBLE1BQ2hELGdCQUFnQixVQUFVLGtCQUFrQixjQUFjO0FBQUEsTUFDMUQsaUJBQWlCO0FBQUEsTUFDakIsaUJBQWlCO0FBQUEsTUFDakIsa0JBQWtCO0FBQUEsUUFDaEIsVUFBVTtBQUFBLFFBQ1YsV0FBVztBQUFBLFFBQ1gsWUFDRSxnQkFBZ0IsY0FBYyxlQUFlLGNBQWM7QUFBQSxNQUMvRDtBQUFBLElBQ0YsQ0FBQztBQUVELFVBQU0sWUFBWSxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDOUMsUUFBSSxxQkFBcUIsT0FBTztBQUM5QixhQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsVUFBVSxTQUFTLE9BQU8sVUFBVSxDQUFDO0FBQUEsSUFDekU7QUFDQSxRQUFJLFdBQVcsb0JBQW9CLFFBQVE7QUFDekMsYUFBTyxpQkFBaUI7QUFBQSxJQUMxQjtBQUVBLFVBQU0sYUFDSixnQkFBZ0IsY0FDaEIsZUFBZSxjQUNmLE9BQU8sV0FBVztBQUNwQixRQUFJLFlBQVk7QUFDZCxZQUFNLFNBQVMsTUFBTSwwQkFBMEIsVUFBVTtBQUN6RCxVQUFJLEVBQUUsa0JBQWtCLFFBQVE7QUFDOUIsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBRUEsV0FBTyxtQkFBbUI7QUFBQSxFQUM1QjtBQUVBLFdBQVMsdUJBQXVEO0FBQzlELFVBQU0sU0FBUyxlQUFlLElBQUksRUFBRTtBQUNwQyxRQUFJLFFBQVE7QUFDVixhQUFPO0FBQUEsSUFDVDtBQUVBLFVBQU0sVUFBVSx1QkFBdUIsRUFBRSxRQUFRLE1BQU07QUFDckQscUJBQWUsT0FBTyxFQUFFO0FBQUEsSUFDMUIsQ0FBQztBQUNELG1CQUFlLElBQUksSUFBSSxPQUFPO0FBQzlCLFdBQU87QUFBQSxFQUNUO0FBRUEsaUJBQWUsZUFBd0Q7QUFDckUsVUFBTSxrQkFBa0IsTUFBTSxxQkFBcUI7QUFDbkQsUUFBSSwyQkFBMkIsT0FBTztBQUNwQyxhQUFPO0FBQUEsSUFDVDtBQUVBLFdBQWMsaUJBQVM7QUFBQSxNQUNyQixLQUFLLE1BQ0gsaUJBQWlCLElBQUk7QUFBQSxRQUNuQixXQUFXO0FBQUEsUUFDWCxHQUFHLG1CQUFtQjtBQUFBLE1BQ3hCLENBQUM7QUFBQSxNQUNILE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxJQUNoRSxDQUFDO0FBQUEsRUFDSDtBQUVBLFdBQVNDLGNBQXNEO0FBQzdELFFBQUksQ0FBQyxnQkFBZ0I7QUFDbkIsdUJBQWlCLGFBQWE7QUFBQSxJQUNoQztBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsaUJBQWUscUJBQW9DO0FBQ2pELFVBQU0sTUFBTSxLQUFLLElBQUk7QUFDckIsVUFBTSxXQUFXLGlCQUFpQixJQUFJLEVBQUU7QUFDeEMsUUFBSSxZQUFZLE1BQU0sV0FBVyxzQkFBc0I7QUFDckQ7QUFBQSxJQUNGO0FBQ0EscUJBQWlCLElBQUksSUFBSSxHQUFHO0FBRTVCLFVBQU0sV0FBVyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDN0MsUUFBSSxvQkFBb0IsU0FBUyxDQUFDLFVBQVU7QUFDMUM7QUFBQSxJQUNGO0FBQ0EsVUFBTSxpQkFDSixTQUFTLGtCQUFrQixhQUFhLFdBQ3BDLFNBQVMsbUJBQ1Q7QUFDTixVQUFNLFFBQVEsUUFBUSxJQUFJO0FBQUEsTUFDeEIsSUFBSSxTQUFTO0FBQUEsTUFDYixRQUFRLFNBQVM7QUFBQSxNQUNqQixXQUFXLFNBQVM7QUFBQSxNQUNwQixnQkFBZ0I7QUFBQSxNQUNoQixpQkFBaUI7QUFBQSxNQUNqQixpQkFBaUI7QUFBQSxNQUNqQixrQkFBa0Isa0JBQWtCO0FBQUEsUUFDbEMsVUFBVTtBQUFBLFFBQ1YsV0FBVztBQUFBLFFBQ1gsWUFBWTtBQUFBLE1BQ2Q7QUFBQSxJQUNGLENBQUM7QUFFRCxRQUFJLHlCQUF5QjtBQUFBLElBZTdCO0FBQUEsRUFDRjtBQUVBLFFBQU0sWUFBOEI7QUFBQSxJQUNsQyxPQUFPLFlBQVk7QUFDakIsWUFBTUQsV0FBVSxNQUFNQyxZQUFXO0FBQ2pDLFVBQUlELG9CQUFtQixPQUFPO0FBQzVCLGVBQU9BO0FBQUEsTUFDVDtBQUNBLFlBQU0sbUJBQW1CO0FBQ3pCLGFBQU9BLFNBQVE7QUFBQSxJQUNqQjtBQUFBLElBRUEsVUFBVSxZQUFZO0FBQ3BCLFlBQU1BLFdBQVUsTUFBTUMsWUFBVztBQUNqQyxVQUFJRCxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFFQSxhQUFjLGlCQUFTO0FBQUEsUUFDckIsS0FBSyxZQUFZO0FBQ2YsZ0JBQU0sV0FBVyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDN0MsZ0JBQU0sV0FBVyxNQUFNQSxTQUFRLFNBQVM7QUFDeEMsZ0JBQU0sUUFBUSxRQUFRLElBQUk7QUFBQSxZQUN4QjtBQUFBLFlBQ0E7QUFBQSxZQUNBLFdBQ0Usb0JBQW9CLFFBQVEsT0FBTyxVQUFVLGFBQWE7QUFBQSxZQUM1RCxnQkFDRSxvQkFBb0IsUUFDaEIsT0FDQSxVQUFVLGtCQUFrQjtBQUFBLFlBQ2xDLGlCQUFpQjtBQUFBLFlBQ2pCLGlCQUFpQjtBQUFBLFlBQ2pCLGtCQUFrQjtBQUFBLGNBQ2hCLFVBQVU7QUFBQSxjQUNWLFdBQVc7QUFBQSxjQUNYLFlBQVksU0FBUztBQUFBLFlBQ3ZCO0FBQUEsVUFDRixDQUFDO0FBQ0QsaUJBQU8sRUFBRSxZQUFZLFNBQVMsV0FBVztBQUFBLFFBQzNDO0FBQUEsUUFDQSxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsTUFDaEUsQ0FBQztBQUFBLElBQ0g7QUFBQSxJQUVBLE1BQU0sWUFBWTtBQUNoQixZQUFNQSxXQUFVLE1BQU1DLFlBQVc7QUFDakMsVUFBSUQsb0JBQW1CLE9BQU87QUFDNUIsZUFBT0E7QUFBQSxNQUNUO0FBRUEsYUFBYyxpQkFBUztBQUFBLFFBQ3JCLEtBQUssWUFBWTtBQUNmLGdCQUFNQSxTQUFRLEtBQUs7QUFDbkIsZ0JBQU0sV0FBVyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDN0MsY0FBSSxvQkFBb0IsU0FBUyxDQUFDLFVBQVU7QUFDMUMsbUJBQU87QUFBQSxVQUNUO0FBQ0EsZ0JBQU0sUUFBUSxRQUFRLElBQUk7QUFBQSxZQUN4QixJQUFJLFNBQVM7QUFBQSxZQUNiLFFBQVEsU0FBUztBQUFBLFlBQ2pCLFdBQVcsU0FBUztBQUFBLFlBQ3BCLGdCQUFnQixTQUFTO0FBQUEsWUFDekIsaUJBQWlCO0FBQUEsWUFDakIsaUJBQWlCO0FBQUEsWUFDakIsa0JBQWtCO0FBQUEsY0FDaEIsVUFBVTtBQUFBLGNBQ1YsV0FBVztBQUFBLGNBQ1gsWUFBWTtBQUFBLFlBQ2Q7QUFBQSxVQUNGLENBQUM7QUFDRCxpQkFBTztBQUFBLFFBQ1Q7QUFBQSxRQUNBLE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxNQUNoRSxDQUFDO0FBQUEsSUFDSDtBQUFBLElBRUEsV0FBVyxZQUFZO0FBQ3JCLFlBQU1BLFdBQVUsTUFBTUMsWUFBVztBQUNqQyxVQUFJRCxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFDQSxhQUFPQSxTQUFRO0FBQUEsSUFDakI7QUFBQSxJQUVBLGNBQWMsWUFBWTtBQUN4QixZQUFNQSxXQUFVLE1BQU1DLFlBQVc7QUFDakMsVUFBSUQsb0JBQW1CLE9BQU87QUFDNUIsZUFBT0E7QUFBQSxNQUNUO0FBQ0EsYUFBT0EsU0FBUTtBQUFBLElBQ2pCO0FBQUEsSUFFQSxxQkFBcUIsWUFBWTtBQUMvQixZQUFNQSxXQUFVLE1BQU1DLFlBQVc7QUFDakMsVUFBSUQsb0JBQW1CLE9BQU87QUFDNUIsZUFBT0E7QUFBQSxNQUNUO0FBQ0EsYUFBT0EsU0FBUTtBQUFBLElBQ2pCO0FBQUEsRUFDRjtBQUVBLFFBQU0sVUFBbUI7QUFBQSxJQUN2QjtBQUFBLElBQ0E7QUFBQSxJQUNBLE1BQU0sT0FBTyxFQUFFLFNBQVMsTUFBTSxPQUFPLE1BQU07QUFDekMsWUFBTSxXQUFXLE1BQU1DLFlBQVc7QUFDbEMsVUFBSSxvQkFBb0IsT0FBTztBQUM3QixlQUFPO0FBQUEsTUFDVDtBQUVBLFlBQU0sZ0JBQWdCLG1CQUFtQjtBQUV6QyxZQUFNLGFBQWEsTUFBYSxpQkFBUztBQUFBLFFBQ3ZDLEtBQUssWUFBWTtBQUNmLGdCQUFNLFNBQVMsTUFBTSxTQUFTLFdBQVcsU0FBUyxNQUFNLEVBQUUsT0FBTyxDQUFDO0FBRWxFLGNBQUksU0FBUztBQUNiLGNBQUksU0FBUztBQUNiLGdCQUFNLFlBQXdCLENBQUM7QUFDL0IsZ0JBQU0sUUFBUTtBQUFBLFlBQ1osU0FBUztBQUFBLFlBQ1QsVUFBVTtBQUFBLFVBQ1o7QUFFQSxnQkFBTSxlQUFlLFlBQVk7QUFDL0IsNkJBQWlCLE9BQU8sT0FBTyxLQUFLLEdBQUc7QUFDckMsb0JBQU0sUUFDSixJQUFJLFdBQVcsV0FDWCxFQUFFLFFBQVEsVUFBVSxNQUFNLElBQUksS0FBSyxJQUNuQyxFQUFFLFFBQVEsVUFBVSxNQUFNLElBQUksS0FBSztBQUV6QyxrQkFBSSxJQUFJLFdBQVcsVUFBVTtBQUMzQiwwQkFBVSxJQUFJO0FBQUEsY0FDaEIsT0FBTztBQUNMLDBCQUFVLElBQUk7QUFBQSxjQUNoQjtBQUVBLHdCQUFVLEtBQUssS0FBSztBQUNwQixvQkFBTSxVQUFVO0FBQUEsWUFDbEI7QUFDQSxrQkFBTSxXQUFXO0FBQ2pCLGtCQUFNLFVBQVU7QUFBQSxVQUNsQixHQUFHO0FBRUgsMEJBQWdCLE9BQWdDO0FBQzlDLGdCQUFJLFFBQVE7QUFDWixtQkFBTyxDQUFDLE1BQU0sWUFBWSxRQUFRLFVBQVUsUUFBUTtBQUNsRCxrQkFBSSxRQUFRLFVBQVUsUUFBUTtBQUM1QixzQkFBTSxVQUFVLE9BQU87QUFBQSxjQUN6QixPQUFPO0FBQ0wsc0JBQU0sSUFBSSxRQUFjLENBQUMsWUFBWTtBQUNuQyx3QkFBTSxVQUFVO0FBQUEsZ0JBQ2xCLENBQUM7QUFDRCxzQkFBTSxVQUFVO0FBQUEsY0FDbEI7QUFBQSxZQUNGO0FBQUEsVUFDRjtBQUVBLGdCQUFNLFNBQVMsWUFBWSxLQUFLLE9BQU87QUFBQSxZQUNyQztBQUFBLFlBQ0E7QUFBQSxZQUNBLFVBQVUsT0FBTztBQUFBLFVBQ25CLEVBQUU7QUFFRixpQkFBTyxFQUFFLFdBQVcsT0FBTyxPQUFPLE1BQU0sT0FBTztBQUFBLFFBQ2pEO0FBQUEsUUFDQSxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsTUFDaEUsQ0FBQztBQUVELFlBQU07QUFDTixhQUFPO0FBQUEsSUFDVDtBQUFBLElBRUEsV0FBVyxPQUFPLFNBQVM7QUFDekIsWUFBTUQsV0FBVSxNQUFNQyxZQUFXO0FBQ2pDLFVBQUlELG9CQUFtQixPQUFPO0FBQzVCLGVBQU9BO0FBQUEsTUFDVDtBQUVBLFVBQUk7QUFDRixlQUFPQSxTQUFRLE9BQU8sSUFBSTtBQUFBLE1BQzVCLFNBQVMsR0FBRztBQUNWLGVBQU8sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ3pEO0FBQUEsSUFDRjtBQUFBLElBRUEsTUFBTSxPQUFPLEVBQUUsV0FBVyxTQUFTLFdBQVcsTUFBTTtBQUNsRCxZQUFNLFdBQVcsTUFBTUMsWUFBVztBQUNsQyxVQUFJLG9CQUFvQixPQUFPO0FBQzdCLGVBQU87QUFBQSxNQUNUO0FBRUEsWUFBTSxNQUFNLE1BQU0sV0FBVyxRQUFRLElBQUksU0FBUztBQUNsRCxVQUFJLGVBQWUsT0FBTztBQUN4QixlQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsSUFBSSxTQUFTLE9BQU8sSUFBSSxDQUFDO0FBQUEsTUFDN0Q7QUFDQSxVQUFJLE9BQU8sSUFBSSxXQUFXLFdBQVc7QUFDbkMsY0FBTSxTQUFTLE1BQU0sV0FBVyxRQUFRLElBQUk7QUFBQSxVQUMxQyxHQUFHO0FBQUEsVUFDSCxRQUFRO0FBQUEsUUFDVixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTyxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sU0FBUyxPQUFPLE9BQU8sQ0FBQztBQUFBLFFBQ25FO0FBQUEsTUFDRjtBQUNBLGFBQU87QUFBQSxJQUNUO0FBQUEsSUFFQSxZQUFZLENBQUMsU0FBUyxXQUFXLEVBQUUsU0FBUyxHQUFHLEtBQUssQ0FBQztBQUFBLElBRXJEO0FBQUEsRUFDRjtBQUVBLE1BQUksT0FBTyxXQUFXLGNBQWMsT0FBTztBQUN6QyxxQkFBaUIsYUFBYTtBQUFBLEVBQ2hDO0FBRUEsU0FBTztBQUNUOzs7QUN0Z0JPLFNBQVMsV0FBVztBQUFBLEVBQ3pCO0FBQUEsRUFDQTtBQUNGLEdBR1k7QUFDVixRQUFNLEVBQUUsT0FBTyxJQUFJO0FBQ25CLFVBQVEsT0FBTyxNQUFNO0FBQUEsSUFDbkIsS0FBSztBQUNILGFBQU8sYUFBYTtBQUFBLFFBQ2xCO0FBQUEsUUFHQTtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0gsS0FBSztBQUNILGFBQU8sY0FBYztBQUFBLFFBQ25CO0FBQUEsUUFHQTtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0gsS0FBSztBQUNILFlBQU0sSUFBSSxNQUFNLG9DQUFvQztBQUFBLElBQ3REO0FBQ0U7QUFDQSxZQUFNLElBQUk7QUFBQSxRQUNSO0FBQUEsUUFFRyxPQUFlLElBQ2xCO0FBQUEsTUFDRjtBQUFBLEVBQ0o7QUFDRjsiLAogICJuYW1lcyI6IFsiZXhpdENvZGUiLCAic3RkZXJyIiwgImVycm9yZSIsICJzYW5kYm94IiwgImdldFNhbmRib3giXQp9Cg==
|