experimental-agent 0.0.2 → 0.0.4

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.
Files changed (57) hide show
  1. package/README.md +13 -2
  2. package/dist/agent-workflow.d.mts +11 -3
  3. package/dist/agent-workflow.d.ts +11 -3
  4. package/dist/agent-workflow.js +1921 -1144
  5. package/dist/agent-workflow.mjs +7 -3
  6. package/dist/chunk-3ODWQVIA.mjs +12 -0
  7. package/dist/chunk-64THY7Y7.mjs +155 -0
  8. package/dist/chunk-GSRJYPWF.mjs +284 -0
  9. package/dist/chunk-HJGPUEFC.mjs +42 -0
  10. package/dist/chunk-JCPQQWIK.mjs +2057 -0
  11. package/dist/chunk-JEE2FQ4O.mjs +844 -0
  12. package/dist/chunk-T7PMZLOX.mjs +79 -0
  13. package/dist/chunk-TQRCSTCF.mjs +103 -0
  14. package/dist/chunk-VBLZWXVE.mjs +318 -0
  15. package/dist/{types-DPXFq_r6.d.ts → client-6g79J0s3.d.mts} +866 -31
  16. package/dist/{types-DPXFq_r6.d.mts → client-6g79J0s3.d.ts} +866 -31
  17. package/dist/client-SREKHM6I.mjs +15 -0
  18. package/dist/client.d.mts +37 -0
  19. package/dist/client.d.ts +37 -0
  20. package/dist/client.js +58 -0
  21. package/dist/client.mjs +30 -0
  22. package/dist/{client-HUG4HT5L.mjs → handler-36FM5H35.mjs} +4 -5
  23. package/dist/index.d.mts +3 -4
  24. package/dist/index.d.ts +3 -4
  25. package/dist/index.js +3102 -1438
  26. package/dist/index.mjs +720 -147
  27. package/dist/lifecycle-workflow.d.mts +3 -10
  28. package/dist/lifecycle-workflow.d.ts +3 -10
  29. package/dist/lifecycle-workflow.js +170 -1246
  30. package/dist/lifecycle-workflow.mjs +5 -41
  31. package/dist/local-fs-handlers-P4WGW3QY.mjs +235 -0
  32. package/dist/next/loader.d.mts +14 -0
  33. package/dist/next/loader.d.ts +14 -0
  34. package/dist/next/loader.js +206 -0
  35. package/dist/next/loader.mjs +103 -0
  36. package/dist/next.d.mts +34 -0
  37. package/dist/next.d.ts +34 -0
  38. package/dist/next.js +329 -0
  39. package/dist/next.mjs +224 -0
  40. package/dist/process-manager-JAKAXROL.mjs +10 -0
  41. package/dist/{client-4Y3UPWFR.mjs → sandbox-QAPGBVYM.mjs} +4 -3
  42. package/dist/storage-Q376OZH3.mjs +20 -0
  43. package/dist/{vercel-2CFDMEHB.mjs → vercel-LLXAHKVJ.mjs} +3 -1
  44. package/dist/vercel-sdk-VHKEX2GQ.mjs +8 -0
  45. package/package.json +32 -19
  46. package/dist/chunk-24DJSI7C.mjs +0 -374
  47. package/dist/chunk-4RGMKC2M.mjs +0 -755
  48. package/dist/chunk-6ICYKNCC.mjs +0 -284
  49. package/dist/chunk-PGYYQ3WZ.mjs +0 -1088
  50. package/dist/client-BBpD9kKL.d.ts +0 -193
  51. package/dist/client-BGJViybU.d.mts +0 -193
  52. package/dist/lifecycle-workflow-steps-HHN46ZAD.mjs +0 -20
  53. package/dist/local-BYPFRMLZ.mjs +0 -282
  54. package/dist/process-manager-H2HF6G4G.mjs +0 -153
  55. package/dist/sandbox-BFA4ECEQ.mjs +0 -10
  56. package/dist/storage-2U2QFNWI.mjs +0 -27
  57. /package/dist/{chunk-36X6L7SK.mjs → chunk-TAXLUVIC.mjs} +0 -0
@@ -0,0 +1,844 @@
1
+ import {
2
+ sandboxLifecycleWorkflow
3
+ } from "./chunk-TQRCSTCF.mjs";
4
+ import {
5
+ SandboxError,
6
+ SandboxNotFoundError
7
+ } from "./chunk-HJGPUEFC.mjs";
8
+
9
+ // src/sandbox/bindings/local.ts
10
+ import { spawn } from "node:child_process";
11
+ import * as errore from "errore";
12
+ import { ulid } from "ulid";
13
+
14
+ // src/sandbox/write-files.ts
15
+ import * as path from "node:path";
16
+ async function writeFiles(opts) {
17
+ const { sandbox, files, destPath } = opts;
18
+ if (files.length === 0) {
19
+ return;
20
+ }
21
+ const filePaths = files.map((file) => path.posix.join(destPath, file.path));
22
+ const parentDirs = Array.from(
23
+ new Set(filePaths.map((p) => path.posix.dirname(p)))
24
+ );
25
+ const shellScripts = filePaths.filter((p) => p.endsWith(".sh"));
26
+ const mkdirResult = await sandbox.exec({
27
+ command: "mkdir",
28
+ args: ["-p", ...parentDirs]
29
+ });
30
+ if (mkdirResult instanceof Error) {
31
+ throw mkdirResult;
32
+ }
33
+ await mkdirResult.result;
34
+ const CHUNK_SIZE = 5e4;
35
+ for (let i = 0; i < files.length; i++) {
36
+ const file = files[i];
37
+ const fullPath = filePaths[i];
38
+ const base64Content = toBase64(file.content);
39
+ if (base64Content.length < CHUNK_SIZE) {
40
+ const marker = `EOF_${i}`;
41
+ const execResult = await sandbox.exec({
42
+ command: "bash",
43
+ args: [
44
+ "-c",
45
+ `base64 -d > ${quote(fullPath)} << '${marker}'
46
+ ${base64Content}
47
+ ${marker}`
48
+ ]
49
+ });
50
+ if (execResult instanceof Error) {
51
+ throw execResult;
52
+ }
53
+ const { exitCode, stderr } = await execResult.result;
54
+ if (exitCode !== 0) {
55
+ throw new Error(
56
+ `writeFiles failed with exit code ${exitCode}: ${stderr}`
57
+ );
58
+ }
59
+ } else {
60
+ const tempB64 = `/tmp/chunk-${Date.now()}-${i}.b64`;
61
+ const clearResult = await sandbox.exec({
62
+ command: "bash",
63
+ args: ["-c", `> ${quote(tempB64)}`]
64
+ });
65
+ if (clearResult instanceof Error) {
66
+ throw clearResult;
67
+ }
68
+ await clearResult.result;
69
+ for (let offset = 0; offset < base64Content.length; offset += CHUNK_SIZE) {
70
+ const chunk = base64Content.slice(offset, offset + CHUNK_SIZE);
71
+ const marker = `CHUNK_${offset}`;
72
+ const appendResult = await sandbox.exec({
73
+ command: "bash",
74
+ args: [
75
+ "-c",
76
+ `cat >> ${quote(tempB64)} << '${marker}'
77
+ ${chunk}
78
+ ${marker}`
79
+ ]
80
+ });
81
+ if (appendResult instanceof Error) {
82
+ throw appendResult;
83
+ }
84
+ const { exitCode: exitCode2, stderr: stderr2 } = await appendResult.result;
85
+ if (exitCode2 !== 0) {
86
+ throw new Error(
87
+ `writeFiles chunk failed with exit code ${exitCode2}: ${stderr2}`
88
+ );
89
+ }
90
+ }
91
+ const decodeResult = await sandbox.exec({
92
+ command: "bash",
93
+ args: [
94
+ "-c",
95
+ `base64 -d < ${quote(tempB64)} > ${quote(fullPath)} && rm -f ${quote(tempB64)}`
96
+ ]
97
+ });
98
+ if (decodeResult instanceof Error) {
99
+ throw decodeResult;
100
+ }
101
+ const { exitCode, stderr } = await decodeResult.result;
102
+ if (exitCode !== 0) {
103
+ throw new Error(
104
+ `writeFiles decode failed with exit code ${exitCode}: ${stderr}`
105
+ );
106
+ }
107
+ }
108
+ }
109
+ if (shellScripts.length > 0) {
110
+ const chmodResult = await sandbox.exec({
111
+ command: "chmod",
112
+ args: ["+x", ...shellScripts]
113
+ });
114
+ if (chmodResult instanceof Error) {
115
+ throw chmodResult;
116
+ }
117
+ await chmodResult.result;
118
+ }
119
+ }
120
+ function toBase64(content) {
121
+ if (typeof content === "string") {
122
+ return Buffer.from(content).toString("base64");
123
+ }
124
+ return content.toString("base64");
125
+ }
126
+ function quote(s) {
127
+ return `'${s.replace(/'/g, "'\\''")}'`;
128
+ }
129
+
130
+ // src/sandbox/bindings/local.ts
131
+ var localSandbox = ({
132
+ sandboxRecord,
133
+ storage
134
+ }) => {
135
+ const config = sandboxRecord.config;
136
+ const basePath = config.path ?? process.cwd();
137
+ const processes = /* @__PURE__ */ new Map();
138
+ const sandbox = {
139
+ id: sandboxRecord.id,
140
+ config: sandboxRecord.config,
141
+ exec: ({ command, args, signal }) => {
142
+ return errore.tryAsync({
143
+ try: () => {
144
+ const commandId = `command_${ulid()}`;
145
+ const child = spawn(command, args, {
146
+ cwd: basePath,
147
+ signal
148
+ });
149
+ processes.set(commandId, child);
150
+ let stdout = "";
151
+ let stderr = "";
152
+ const logQueue = [];
153
+ let logResolve = null;
154
+ let closed = false;
155
+ child.stdout.on("data", (data) => {
156
+ const str = String(data);
157
+ stdout += str;
158
+ logQueue.push({ stream: "stdout", data: str });
159
+ logResolve?.();
160
+ });
161
+ child.stderr.on("data", (data) => {
162
+ const str = String(data);
163
+ stderr += str;
164
+ logQueue.push({ stream: "stderr", data: str });
165
+ logResolve?.();
166
+ });
167
+ const result = new Promise((resolve, reject) => {
168
+ child.on("error", (err) => {
169
+ processes.delete(commandId);
170
+ closed = true;
171
+ logResolve?.();
172
+ reject(err);
173
+ });
174
+ child.on("close", (code) => {
175
+ processes.delete(commandId);
176
+ closed = true;
177
+ logResolve?.();
178
+ resolve({ stdout, stderr, exitCode: code ?? 0 });
179
+ });
180
+ });
181
+ async function* logs() {
182
+ while (!closed || logQueue.length > 0) {
183
+ const entry = logQueue.shift();
184
+ if (entry) {
185
+ yield entry;
186
+ } else if (!closed) {
187
+ await new Promise((resolve) => {
188
+ logResolve = resolve;
189
+ });
190
+ logResolve = null;
191
+ }
192
+ }
193
+ }
194
+ return Promise.resolve({ commandId, logs, result });
195
+ },
196
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
197
+ });
198
+ },
199
+ getDomain: (port) => {
200
+ return Promise.resolve(`http://localhost:${port}`);
201
+ },
202
+ kill: async ({ commandId, storage: storage2 }) => {
203
+ const child = processes.get(commandId);
204
+ if (!child) {
205
+ return new SandboxError({
206
+ reason: `Command ${commandId} not found or already finished`
207
+ });
208
+ }
209
+ child.kill("SIGTERM");
210
+ const cmd = await storage2.command.get(commandId);
211
+ if (cmd instanceof Error) {
212
+ return new SandboxError({ reason: cmd.message, cause: cmd });
213
+ }
214
+ if (cmd && cmd.status === "running") {
215
+ const result = await storage2.command.set({
216
+ ...cmd,
217
+ status: "killed"
218
+ });
219
+ if (result instanceof Error) {
220
+ return new SandboxError({ reason: result.message, cause: result });
221
+ }
222
+ }
223
+ },
224
+ writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
225
+ tag: {
226
+ list: async () => {
227
+ const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
228
+ if (sandboxRecord2 instanceof Error) {
229
+ return sandboxRecord2;
230
+ }
231
+ return sandboxRecord2.tags ?? {};
232
+ },
233
+ get: async (key) => {
234
+ const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
235
+ if (sandboxRecord2 instanceof Error) {
236
+ return sandboxRecord2;
237
+ }
238
+ return sandboxRecord2.tags?.[key];
239
+ },
240
+ set: async (key, value) => {
241
+ const result = await storage.sandbox.tag.set({
242
+ sandboxId: sandbox.id,
243
+ tags: { [key]: value }
244
+ });
245
+ if (result instanceof Error) {
246
+ return result;
247
+ }
248
+ return void 0;
249
+ },
250
+ setMany: async (tags) => {
251
+ const result = await storage.sandbox.tag.set({
252
+ sandboxId: sandbox.id,
253
+ tags
254
+ });
255
+ if (result instanceof Error) {
256
+ return result;
257
+ }
258
+ return void 0;
259
+ }
260
+ }
261
+ };
262
+ return sandbox;
263
+ };
264
+
265
+ // src/sandbox/bindings/vercel.ts
266
+ import * as errore2 from "errore";
267
+ import { Sandbox as VercelSandboxSDK } from "sandbox";
268
+ import { start } from "workflow/api";
269
+ var VERCEL_MAX_TIMEOUT_MS = 5 * 60 * 60 * 1e3;
270
+ var LOCK_TIMEOUT_MS = 2 * 60 * 1e3;
271
+ var LOCK_POLL_INTERVAL_MS = 200;
272
+ var getTestCredentials = () => process.env.NODE_ENV === "test" ? {
273
+ token: process.env.TEST_VERCEL_TOKEN,
274
+ teamId: process.env.TEST_VERCEL_TEAM_ID,
275
+ projectId: process.env.TEST_VERCEL_PROJECT_ID
276
+ } : {};
277
+ var createPromises = /* @__PURE__ */ new Map();
278
+ var ACTIVITY_THROTTLE_MS = 1e4;
279
+ var lastActivitySent = /* @__PURE__ */ new Map();
280
+ var DEFAULT_VCPUS = 2;
281
+ function isSandboxGoneError(e) {
282
+ if (!(e instanceof Error)) {
283
+ return false;
284
+ }
285
+ const errorWithResponse = e;
286
+ const errorWithCause = e;
287
+ const status = errorWithResponse.response?.status ?? errorWithCause.cause?.response?.status;
288
+ if (status === 410 || status === 422) {
289
+ return true;
290
+ }
291
+ const message = e.message || String(e);
292
+ if (message.includes("Expected a stream of command data") || message.includes("Expected a stream of logs")) {
293
+ return true;
294
+ }
295
+ return false;
296
+ }
297
+ var vercelSandbox = ({
298
+ sandboxRecord,
299
+ storageConfig,
300
+ enableLifecycleWorkflow,
301
+ storage,
302
+ rpc
303
+ }) => {
304
+ const { id, config } = sandboxRecord;
305
+ const vcpus = config.resources?.vcpus ?? DEFAULT_VCPUS;
306
+ const ports = config.ports;
307
+ const initialVercel = sandboxRecord.providerMetadata?.provider === "vercel" ? sandboxRecord.providerMetadata : null;
308
+ let sandboxPromise = null;
309
+ let recoveredFromStale = false;
310
+ const HOME_DIR = "/home/vercel-sandbox";
311
+ async function pollForSandboxId() {
312
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
313
+ while (Date.now() < deadline) {
314
+ await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
315
+ const record = await storage.sandbox.get(id);
316
+ if (record instanceof Error) {
317
+ return new SandboxError({ reason: record.message, cause: record });
318
+ }
319
+ const vercelSandboxId = record?.providerMetadata?.provider === "vercel" ? record.providerMetadata.sandboxId : null;
320
+ if (vercelSandboxId) {
321
+ return vercelSandboxId;
322
+ }
323
+ if (!record?.acquiringLockAt) {
324
+ const finalCheck = await storage.sandbox.get(id);
325
+ if (finalCheck instanceof Error) {
326
+ return new SandboxError({
327
+ reason: finalCheck.message,
328
+ cause: finalCheck
329
+ });
330
+ }
331
+ const finalVercelSandboxId = finalCheck?.providerMetadata?.provider === "vercel" ? finalCheck.providerMetadata.sandboxId : null;
332
+ if (finalVercelSandboxId) {
333
+ return finalVercelSandboxId;
334
+ }
335
+ return doGetOrCreateSandboxId();
336
+ }
337
+ }
338
+ return new SandboxError({
339
+ reason: "Timed out waiting for sandbox creation by another process"
340
+ });
341
+ }
342
+ async function startLifecycleWorkflow(vercelSandboxId) {
343
+ if (!enableLifecycleWorkflow) {
344
+ return;
345
+ }
346
+ const lifecycleInput = {
347
+ id,
348
+ vercelSandboxId,
349
+ storageConfig,
350
+ rpc
351
+ };
352
+ await start(sandboxLifecycleWorkflow, [{ input: lifecycleInput }]).catch(
353
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: intentionally ignored - workflow start is fire-and-forget
354
+ () => {
355
+ }
356
+ );
357
+ }
358
+ async function createSandboxFromSnapshot(snapshotId) {
359
+ return await errore2.tryAsync({
360
+ try: async () => {
361
+ const sandbox2 = await VercelSandboxSDK.create({
362
+ source: { type: "snapshot", snapshotId },
363
+ resources: { vcpus },
364
+ timeout: VERCEL_MAX_TIMEOUT_MS,
365
+ ports,
366
+ ...getTestCredentials()
367
+ });
368
+ const now = Date.now();
369
+ await storage.sandbox.set({
370
+ id,
371
+ config,
372
+ tags: sandboxRecord.tags,
373
+ createdAt: now,
374
+ lastActivityAt: now,
375
+ acquiringLockId: null,
376
+ acquiringLockAt: null,
377
+ providerMetadata: {
378
+ provider: "vercel",
379
+ sandboxId: sandbox2.sandboxId,
380
+ snapshotId
381
+ }
382
+ });
383
+ await startLifecycleWorkflow(sandbox2.sandboxId);
384
+ return sandbox2.sandboxId;
385
+ },
386
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
387
+ });
388
+ }
389
+ async function createFreshSandbox() {
390
+ return await errore2.tryAsync({
391
+ try: async () => {
392
+ const sandbox2 = await VercelSandboxSDK.create({
393
+ resources: { vcpus },
394
+ timeout: VERCEL_MAX_TIMEOUT_MS,
395
+ ports,
396
+ ...getTestCredentials()
397
+ });
398
+ const now = Date.now();
399
+ await storage.sandbox.set({
400
+ id,
401
+ config,
402
+ tags: sandboxRecord.tags,
403
+ createdAt: now,
404
+ lastActivityAt: now,
405
+ acquiringLockId: null,
406
+ acquiringLockAt: null,
407
+ providerMetadata: {
408
+ provider: "vercel",
409
+ sandboxId: sandbox2.sandboxId,
410
+ snapshotId: null
411
+ }
412
+ });
413
+ await startLifecycleWorkflow(sandbox2.sandboxId);
414
+ return sandbox2.sandboxId;
415
+ },
416
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
417
+ });
418
+ }
419
+ async function doGetOrCreateSandboxId() {
420
+ if (initialVercel?.sandboxId && !recoveredFromStale) {
421
+ return initialVercel.sandboxId;
422
+ }
423
+ const existing = await storage.sandbox.get(id);
424
+ if (existing instanceof Error) {
425
+ if (existing instanceof SandboxNotFoundError) {
426
+ } else {
427
+ return new SandboxError({ reason: existing.message, cause: existing });
428
+ }
429
+ }
430
+ const existingRecord = existing instanceof SandboxNotFoundError ? null : existing;
431
+ const existingVercel = existingRecord?.providerMetadata?.provider === "vercel" ? existingRecord.providerMetadata : null;
432
+ if (existingVercel?.sandboxId) {
433
+ return existingVercel.sandboxId;
434
+ }
435
+ const hasActiveLock = existingRecord?.acquiringLockId && existingRecord.acquiringLockAt && Date.now() - existingRecord.acquiringLockAt < LOCK_TIMEOUT_MS;
436
+ if (hasActiveLock) {
437
+ return pollForSandboxId();
438
+ }
439
+ const lockId = crypto.randomUUID();
440
+ const now = Date.now();
441
+ await storage.sandbox.set({
442
+ id,
443
+ config,
444
+ tags: existingRecord?.tags ?? sandboxRecord.tags,
445
+ createdAt: existingRecord?.createdAt ?? sandboxRecord.createdAt,
446
+ lastActivityAt: existingRecord?.lastActivityAt ?? sandboxRecord.lastActivityAt,
447
+ acquiringLockId: lockId,
448
+ acquiringLockAt: now,
449
+ providerMetadata: {
450
+ provider: "vercel",
451
+ sandboxId: null,
452
+ snapshotId: existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? null
453
+ }
454
+ });
455
+ const afterLock = await storage.sandbox.get(id);
456
+ if (afterLock instanceof Error) {
457
+ return new SandboxError({ reason: afterLock.message, cause: afterLock });
458
+ }
459
+ if (afterLock?.acquiringLockId !== lockId) {
460
+ return pollForSandboxId();
461
+ }
462
+ const snapshotId = existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? config.lifecycle?.snapshotId;
463
+ if (snapshotId) {
464
+ const result = await createSandboxFromSnapshot(snapshotId);
465
+ if (!(result instanceof Error)) {
466
+ return result;
467
+ }
468
+ }
469
+ return createFreshSandbox();
470
+ }
471
+ function getOrCreateSandboxId() {
472
+ const cached = createPromises.get(id);
473
+ if (cached) {
474
+ return cached;
475
+ }
476
+ const promise = doGetOrCreateSandboxId().finally(() => {
477
+ createPromises.delete(id);
478
+ });
479
+ createPromises.set(id, promise);
480
+ return promise;
481
+ }
482
+ async function doGetSandbox() {
483
+ const vercelSandboxId = await getOrCreateSandboxId();
484
+ if (vercelSandboxId instanceof Error) {
485
+ return vercelSandboxId;
486
+ }
487
+ return errore2.tryAsync({
488
+ try: () => VercelSandboxSDK.get({
489
+ sandboxId: vercelSandboxId,
490
+ ...getTestCredentials()
491
+ }),
492
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
493
+ });
494
+ }
495
+ function getSandbox2() {
496
+ if (!sandboxPromise) {
497
+ sandboxPromise = doGetSandbox();
498
+ }
499
+ return sandboxPromise;
500
+ }
501
+ async function recoverFromStaleSandbox() {
502
+ sandboxPromise = null;
503
+ recoveredFromStale = true;
504
+ const existing = await storage.sandbox.get(id);
505
+ if (existing instanceof Error || !existing) {
506
+ return;
507
+ }
508
+ const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
509
+ if (existingVercel?.sandboxId) {
510
+ await storage.sandbox.set({
511
+ id: existing.id,
512
+ config: existing.config,
513
+ tags: existing.tags,
514
+ createdAt: existing.createdAt,
515
+ lastActivityAt: existing.lastActivityAt,
516
+ acquiringLockId: null,
517
+ acquiringLockAt: null,
518
+ providerMetadata: {
519
+ provider: "vercel",
520
+ sandboxId: null,
521
+ snapshotId: existingVercel.snapshotId
522
+ }
523
+ });
524
+ }
525
+ }
526
+ async function updateLastActivity() {
527
+ const now = Date.now();
528
+ const lastSent = lastActivitySent.get(id);
529
+ if (lastSent && now - lastSent < ACTIVITY_THROTTLE_MS) {
530
+ return;
531
+ }
532
+ lastActivitySent.set(id, now);
533
+ const existing = await storage.sandbox.get(id);
534
+ if (existing instanceof Error || !existing) {
535
+ return;
536
+ }
537
+ const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
538
+ await storage.sandbox.set({
539
+ id: existing.id,
540
+ config: existing.config,
541
+ tags: existing.tags,
542
+ createdAt: existing.createdAt,
543
+ lastActivityAt: now,
544
+ acquiringLockId: null,
545
+ acquiringLockAt: null,
546
+ providerMetadata: existingVercel ?? {
547
+ provider: "vercel",
548
+ sandboxId: null,
549
+ snapshotId: null
550
+ }
551
+ });
552
+ }
553
+ const lifecycle = {
554
+ start: async () => {
555
+ const sandbox2 = await getSandbox2();
556
+ if (sandbox2 instanceof Error) {
557
+ return sandbox2;
558
+ }
559
+ await updateLastActivity();
560
+ return sandbox2.status;
561
+ },
562
+ snapshot: async () => {
563
+ const sandbox2 = await getSandbox2();
564
+ if (sandbox2 instanceof Error) {
565
+ return sandbox2;
566
+ }
567
+ return errore2.tryAsync({
568
+ try: async () => {
569
+ const existing = await storage.sandbox.get(id);
570
+ const snapshot = await sandbox2.snapshot();
571
+ await storage.sandbox.set({
572
+ id,
573
+ config,
574
+ tags: existing instanceof Error ? null : existing?.tags ?? null,
575
+ createdAt: existing instanceof Error ? null : existing?.createdAt ?? null,
576
+ lastActivityAt: existing instanceof Error ? null : existing?.lastActivityAt ?? null,
577
+ acquiringLockId: null,
578
+ acquiringLockAt: null,
579
+ providerMetadata: {
580
+ provider: "vercel",
581
+ sandboxId: null,
582
+ snapshotId: snapshot.snapshotId
583
+ }
584
+ });
585
+ return { snapshotId: snapshot.snapshotId };
586
+ },
587
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
588
+ });
589
+ },
590
+ stop: async () => {
591
+ const sandbox2 = await getSandbox2();
592
+ if (sandbox2 instanceof Error) {
593
+ return sandbox2;
594
+ }
595
+ return errore2.tryAsync({
596
+ try: async () => {
597
+ await sandbox2.stop();
598
+ const existing = await storage.sandbox.get(id);
599
+ if (existing instanceof Error || !existing) {
600
+ return void 0;
601
+ }
602
+ await storage.sandbox.set({
603
+ id: existing.id,
604
+ config: existing.config,
605
+ tags: existing.tags,
606
+ createdAt: existing.createdAt,
607
+ lastActivityAt: existing.lastActivityAt,
608
+ acquiringLockId: null,
609
+ acquiringLockAt: null,
610
+ providerMetadata: {
611
+ provider: "vercel",
612
+ sandboxId: null,
613
+ snapshotId: null
614
+ }
615
+ });
616
+ return void 0;
617
+ },
618
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
619
+ });
620
+ },
621
+ getStatus: async () => {
622
+ const sandbox2 = await getSandbox2();
623
+ if (sandbox2 instanceof Error) {
624
+ return sandbox2;
625
+ }
626
+ return sandbox2.status;
627
+ },
628
+ getCreatedAt: async () => {
629
+ const sandbox2 = await getSandbox2();
630
+ if (sandbox2 instanceof Error) {
631
+ return sandbox2;
632
+ }
633
+ return sandbox2.createdAt;
634
+ },
635
+ getRemainingTimeout: async () => {
636
+ const sandbox2 = await getSandbox2();
637
+ if (sandbox2 instanceof Error) {
638
+ return sandbox2;
639
+ }
640
+ return sandbox2.timeout;
641
+ }
642
+ };
643
+ async function doExec({
644
+ command,
645
+ args,
646
+ signal
647
+ }) {
648
+ const instance = await getSandbox2();
649
+ if (instance instanceof Error) {
650
+ return instance;
651
+ }
652
+ const updatePromise = updateLastActivity();
653
+ const execResult = await errore2.tryAsync({
654
+ try: async () => {
655
+ const output = await instance.runCommand({
656
+ cwd: HOME_DIR,
657
+ args,
658
+ cmd: command,
659
+ signal,
660
+ detached: true
661
+ });
662
+ let stdout = "";
663
+ let stderr = "";
664
+ const logBuffer = [];
665
+ const state = {
666
+ resolve: null,
667
+ consumed: false
668
+ };
669
+ const consumeLogs = (async () => {
670
+ try {
671
+ for await (const log of output.logs()) {
672
+ const entry = log.stream === "stdout" ? { stream: "stdout", data: log.data } : { stream: "stderr", data: log.data };
673
+ if (log.stream === "stdout") {
674
+ stdout += log.data;
675
+ } else {
676
+ stderr += log.data;
677
+ }
678
+ logBuffer.push(entry);
679
+ state.resolve?.();
680
+ }
681
+ } catch {
682
+ }
683
+ state.consumed = true;
684
+ state.resolve?.();
685
+ })();
686
+ async function* logs() {
687
+ let index = 0;
688
+ while (!state.consumed || index < logBuffer.length) {
689
+ if (index < logBuffer.length) {
690
+ yield logBuffer[index++];
691
+ } else {
692
+ await new Promise((resolve) => {
693
+ state.resolve = resolve;
694
+ });
695
+ state.resolve = null;
696
+ }
697
+ }
698
+ }
699
+ const result = consumeLogs.then(async () => {
700
+ try {
701
+ const finished = await output.wait();
702
+ return {
703
+ stdout,
704
+ stderr,
705
+ exitCode: finished.exitCode
706
+ };
707
+ } catch (e) {
708
+ if (isSandboxGoneError(e)) {
709
+ return { stdout, stderr, exitCode: 1 };
710
+ }
711
+ throw e;
712
+ }
713
+ });
714
+ return { commandId: output.cmdId, logs, result };
715
+ },
716
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
717
+ });
718
+ await updatePromise;
719
+ return execResult;
720
+ }
721
+ const sandbox = {
722
+ id,
723
+ config,
724
+ exec: async (opts) => {
725
+ const result = await doExec(opts);
726
+ if (result instanceof SandboxError && isSandboxGoneError(result.cause)) {
727
+ await recoverFromStaleSandbox();
728
+ return await doExec(opts);
729
+ }
730
+ return result;
731
+ },
732
+ getDomain: async (port) => {
733
+ const sandbox2 = await getSandbox2();
734
+ if (sandbox2 instanceof Error) {
735
+ return sandbox2;
736
+ }
737
+ try {
738
+ return sandbox2.domain(port);
739
+ } catch (e) {
740
+ return new SandboxError({ reason: String(e), cause: e });
741
+ }
742
+ },
743
+ kill: async ({ commandId, storage: cmdStorage }) => {
744
+ const instance = await getSandbox2();
745
+ if (instance instanceof Error) {
746
+ return instance;
747
+ }
748
+ const cmd = await cmdStorage.command.get(commandId);
749
+ if (cmd instanceof Error) {
750
+ return new SandboxError({ reason: cmd.message, cause: cmd });
751
+ }
752
+ if (cmd && cmd.status === "running") {
753
+ const result = await cmdStorage.command.set({
754
+ ...cmd,
755
+ status: "killed"
756
+ });
757
+ if (result instanceof Error) {
758
+ return new SandboxError({ reason: result.message, cause: result });
759
+ }
760
+ }
761
+ return void 0;
762
+ },
763
+ writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
764
+ lifecycle,
765
+ tag: {
766
+ list: async () => {
767
+ const sandboxRecord2 = await storage.sandbox.get(id);
768
+ if (sandboxRecord2 instanceof Error) {
769
+ return sandboxRecord2;
770
+ }
771
+ return sandboxRecord2.tags ?? {};
772
+ },
773
+ get: async (key) => {
774
+ const sandboxRecord2 = await storage.sandbox.get(id);
775
+ if (sandboxRecord2 instanceof Error) {
776
+ return sandboxRecord2;
777
+ }
778
+ return sandboxRecord2.tags?.[key];
779
+ },
780
+ set: async (key, value) => {
781
+ const result = await storage.sandbox.tag.set({
782
+ sandboxId: id,
783
+ tags: { [key]: value }
784
+ });
785
+ if (result instanceof Error) {
786
+ return result;
787
+ }
788
+ return void 0;
789
+ },
790
+ setMany: async (tags) => {
791
+ const result = await storage.sandbox.tag.set({
792
+ sandboxId: id,
793
+ tags
794
+ });
795
+ if (result instanceof Error) {
796
+ return result;
797
+ }
798
+ return void 0;
799
+ }
800
+ }
801
+ };
802
+ if (config.lifecycle?.autoStart !== false) {
803
+ sandboxPromise = doGetSandbox();
804
+ }
805
+ return sandbox;
806
+ };
807
+
808
+ // src/sandbox/client.ts
809
+ function getSandbox({
810
+ sandboxRecord,
811
+ storageConfig,
812
+ storage,
813
+ rpc,
814
+ enableLifecycleWorkflow = true
815
+ }) {
816
+ switch (sandboxRecord.config.type) {
817
+ case "local":
818
+ return localSandbox({
819
+ sandboxRecord,
820
+ storage
821
+ });
822
+ case "vercel":
823
+ return vercelSandbox({
824
+ sandboxRecord,
825
+ storageConfig,
826
+ storage,
827
+ rpc,
828
+ enableLifecycleWorkflow
829
+ });
830
+ case "custom":
831
+ throw new Error("Custom sandboxes are not supported");
832
+ default:
833
+ sandboxRecord.config;
834
+ throw new Error(
835
+ `Unknown sandbox type: ${// biome-ignore lint/suspicious/noExplicitAny: .
836
+ sandboxRecord.config.type}`
837
+ );
838
+ }
839
+ }
840
+
841
+ export {
842
+ getSandbox
843
+ };
844
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvbG9jYWwudHMiLCAiLi4vc3JjL3NhbmRib3gvd3JpdGUtZmlsZXMudHMiLCAiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvdmVyY2VsLnRzIiwgIi4uL3NyYy9zYW5kYm94L2NsaWVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCAqIGFzIGVycm9yZSBmcm9tIFwiZXJyb3JlXCI7XG5pbXBvcnQgeyB1bGlkIH0gZnJvbSBcInVsaWRcIjtcbmltcG9ydCB7IFNhbmRib3hFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgVGFnc1NjaGVtYSB9IGZyb20gXCIuLi8uLi9pbmRleFwiO1xuaW1wb3J0IHR5cGUgeyBTYW5kYm94UmVjb3JkLCBTdG9yYWdlIH0gZnJvbSBcIi4uLy4uL3N0b3JhZ2VcIjtcbmltcG9ydCB0eXBlIHsgTG9nRW50cnksIFNhbmRib3ggfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IHdyaXRlRmlsZXMgfSBmcm9tIFwiLi4vd3JpdGUtZmlsZXNcIjtcblxuZXhwb3J0IGNvbnN0IGxvY2FsU2FuZGJveCA9IDxUVGFncyBleHRlbmRzIFRhZ3NTY2hlbWEgPSBUYWdzU2NoZW1hPih7XG4gIHNhbmRib3hSZWNvcmQsXG4gIHN0b3JhZ2UsXG59OiB7XG4gIHNhbmRib3hSZWNvcmQ6IFNhbmRib3hSZWNvcmQgJiB7IGNvbmZpZzogeyB0eXBlOiBcImxvY2FsXCIgfSB9O1xuICBzdG9yYWdlOiBTdG9yYWdlO1xufSk6IFNhbmRib3g8VFRhZ3M+ID0+IHtcbiAgY29uc3QgY29uZmlnID0gc2FuZGJveFJlY29yZC5jb25maWc7XG4gIGNvbnN0IGJhc2VQYXRoID0gY29uZmlnLnBhdGggPz8gcHJvY2Vzcy5jd2QoKTtcbiAgY29uc3QgcHJvY2Vzc2VzID0gbmV3IE1hcDxzdHJpbmcsIENoaWxkUHJvY2Vzcz4oKTtcblxuICBjb25zdCBzYW5kYm94OiBTYW5kYm94PFRUYWdzPiA9IHtcbiAgICBpZDogc2FuZGJveFJlY29yZC5pZCxcbiAgICBjb25maWc6IHNhbmRib3hSZWNvcmQuY29uZmlnLFxuICAgIGV4ZWM6ICh7IGNvbW1hbmQsIGFyZ3MsIHNpZ25hbCB9KSA9PiB7XG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY29tbWFuZElkID0gYGNvbW1hbmRfJHt1bGlkKCl9YDtcblxuICAgICAgICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oY29tbWFuZCwgYXJncywge1xuICAgICAgICAgICAgY3dkOiBiYXNlUGF0aCxcbiAgICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHByb2Nlc3Nlcy5zZXQoY29tbWFuZElkLCBjaGlsZCk7XG5cbiAgICAgICAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICAgICAgICBsZXQgc3RkZXJyID0gXCJcIjtcbiAgICAgICAgICBjb25zdCBsb2dRdWV1ZTogTG9nRW50cnlbXSA9IFtdO1xuICAgICAgICAgIGxldCBsb2dSZXNvbHZlOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgICAgICAgICBsZXQgY2xvc2VkID0gZmFsc2U7XG5cbiAgICAgICAgICBjaGlsZC5zdGRvdXQub24oXCJkYXRhXCIsIChkYXRhOiBzdHJpbmcgfCBCdWZmZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0ciA9IFN0cmluZyhkYXRhKTtcbiAgICAgICAgICAgIHN0ZG91dCArPSBzdHI7XG4gICAgICAgICAgICBsb2dRdWV1ZS5wdXNoKHsgc3RyZWFtOiBcInN0ZG91dFwiLCBkYXRhOiBzdHIgfSk7XG4gICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNoaWxkLnN0ZGVyci5vbihcImRhdGFcIiwgKGRhdGE6IHN0cmluZyB8IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGRhdGEpO1xuICAgICAgICAgICAgc3RkZXJyICs9IHN0cjtcbiAgICAgICAgICAgIGxvZ1F1ZXVlLnB1c2goeyBzdHJlYW06IFwic3RkZXJyXCIsIGRhdGE6IHN0ciB9KTtcbiAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gbmV3IFByb21pc2U8e1xuICAgICAgICAgICAgc3Rkb3V0OiBzdHJpbmc7XG4gICAgICAgICAgICBzdGRlcnI6IHN0cmluZztcbiAgICAgICAgICAgIGV4aXRDb2RlOiBudW1iZXI7XG4gICAgICAgICAgfT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY2hpbGQub24oXCJlcnJvclwiLCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHByb2Nlc3Nlcy5kZWxldGUoY29tbWFuZElkKTtcbiAgICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKGNvZGU6IG51bWJlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VzLmRlbGV0ZShjb21tYW5kSWQpO1xuICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICAgICAgcmVzb2x2ZSh7IHN0ZG91dCwgc3RkZXJyLCBleGl0Q29kZTogY29kZSA/PyAwIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhc3luYyBmdW5jdGlvbiogbG9ncygpOiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PiB7XG4gICAgICAgICAgICB3aGlsZSAoIWNsb3NlZCB8fCBsb2dRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gbG9nUXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgeWllbGQgZW50cnk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWNsb3NlZCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBsb2dSZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBsb2dSZXNvbHZlID0gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyBjb21tYW5kSWQsIGxvZ3MsIHJlc3VsdCB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlOiB1bmtub3duKSA9PlxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgZ2V0RG9tYWluOiAocG9ydCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShgaHR0cDovL2xvY2FsaG9zdDoke3BvcnR9YCk7XG4gICAgfSxcblxuICAgIGtpbGw6IGFzeW5jICh7IGNvbW1hbmRJZCwgc3RvcmFnZSB9KSA9PiB7XG4gICAgICBjb25zdCBjaGlsZCA9IHByb2Nlc3Nlcy5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmICghY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgIHJlYXNvbjogYENvbW1hbmQgJHtjb21tYW5kSWR9IG5vdCBmb3VuZCBvciBhbHJlYWR5IGZpbmlzaGVkYCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuXG4gICAgICBjb25zdCBjbWQgPSBhd2FpdCBzdG9yYWdlLmNvbW1hbmQuZ2V0KGNvbW1hbmRJZCk7XG4gICAgICBpZiAoY21kIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IGNtZC5tZXNzYWdlLCBjYXVzZTogY21kIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGNtZCAmJiBjbWQuc3RhdHVzID09PSBcInJ1bm5pbmdcIikge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLmNvbW1hbmQuc2V0KHtcbiAgICAgICAgICAuLi5jbWQsXG4gICAgICAgICAgc3RhdHVzOiBcImtpbGxlZFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IHJlc3VsdC5tZXNzYWdlLCBjYXVzZTogcmVzdWx0IH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIHdyaXRlRmlsZXM6IChvcHRzKSA9PiB3cml0ZUZpbGVzKHsgc2FuZGJveCwgLi4ub3B0cyB9KSxcblxuICAgIHRhZzoge1xuICAgICAgbGlzdDogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94UmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChzYW5kYm94LmlkKTtcbiAgICAgICAgaWYgKHNhbmRib3hSZWNvcmQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBzYW5kYm94UmVjb3JkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoc2FuZGJveFJlY29yZC50YWdzID8/IHt9KSBhcyBUVGFncztcbiAgICAgIH0sXG4gICAgICBnZXQ6IGFzeW5jIChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94UmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChzYW5kYm94LmlkKTtcbiAgICAgICAgaWYgKHNhbmRib3hSZWNvcmQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBzYW5kYm94UmVjb3JkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzYW5kYm94UmVjb3JkLnRhZ3M/LltrZXkgYXMgc3RyaW5nXSBhc1xuICAgICAgICAgIHwgVFRhZ3NbdHlwZW9mIGtleV1cbiAgICAgICAgICB8IHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgICBzZXQ6IGFzeW5jIChrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LnRhZy5zZXQoe1xuICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveC5pZCxcbiAgICAgICAgICB0YWdzOiB7IFtrZXldOiB2YWx1ZSB9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIHNldE1hbnk6IGFzeW5jICh0YWdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3gudGFnLnNldCh7XG4gICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LmlkLFxuICAgICAgICAgIHRhZ3M6IHRhZ3MgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgIH0sXG4gIH07XG5cbiAgcmV0dXJuIHNhbmRib3g7XG59O1xuIiwgImltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBVcGxvYWRhYmxlRmlsZSB9IGZyb20gXCIuLi9za2lsbHMvdHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgU2FuZGJveCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogV3JpdGVzIGZpbGVzIHRvIGEgc2FuZGJveCBhdCB0aGUgc3BlY2lmaWVkIGRlc3RpbmF0aW9uIHBhdGguXG4gKiBTaGVsbCBzY3JpcHRzICguc2ggZmlsZXMpIGFyZSBhdXRvbWF0aWNhbGx5IG1hZGUgZXhlY3V0YWJsZS5cbiAqXG4gKiBGb3Igc21hbGwgZmlsZXMgKDwxMDBLQiB0b3RhbCksIHVzZXMgc2luZ2xlIGV4ZWMgd2l0aCBoZXJlZG9jLlxuICogRm9yIGxhcmdlIGZpbGVzLCB3cml0ZXMgYmFzZTY0IGNodW5rcyB0aGVuIGRlY29kZXMgdG8gYXZvaWQgQVJHX01BWCBsaW1pdHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZUZpbGVzKG9wdHM6IHtcbiAgc2FuZGJveDogUGljazxTYW5kYm94LCBcImV4ZWNcIj47XG4gIGZpbGVzOiBVcGxvYWRhYmxlRmlsZVtdO1xuICBkZXN0UGF0aDogc3RyaW5nO1xufSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IHNhbmRib3gsIGZpbGVzLCBkZXN0UGF0aCB9ID0gb3B0cztcblxuICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgZmlsZVBhdGhzID0gZmlsZXMubWFwKChmaWxlKSA9PiBwYXRoLnBvc2l4LmpvaW4oZGVzdFBhdGgsIGZpbGUucGF0aCkpO1xuICBjb25zdCBwYXJlbnREaXJzID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KGZpbGVQYXRocy5tYXAoKHApID0+IHBhdGgucG9zaXguZGlybmFtZShwKSkpXG4gICk7XG4gIGNvbnN0IHNoZWxsU2NyaXB0cyA9IGZpbGVQYXRocy5maWx0ZXIoKHApID0+IHAuZW5kc1dpdGgoXCIuc2hcIikpO1xuXG4gIGNvbnN0IG1rZGlyUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICBjb21tYW5kOiBcIm1rZGlyXCIsXG4gICAgYXJnczogW1wiLXBcIiwgLi4ucGFyZW50RGlyc10sXG4gIH0pO1xuICBpZiAobWtkaXJSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIHRocm93IG1rZGlyUmVzdWx0O1xuICB9XG4gIGF3YWl0IG1rZGlyUmVzdWx0LnJlc3VsdDtcblxuICBjb25zdCBDSFVOS19TSVpFID0gNTBfMDAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBmaWxlID0gZmlsZXNbaV07XG4gICAgY29uc3QgZnVsbFBhdGggPSBmaWxlUGF0aHNbaV07XG4gICAgY29uc3QgYmFzZTY0Q29udGVudCA9IHRvQmFzZTY0KGZpbGUuY29udGVudCk7XG5cbiAgICBpZiAoYmFzZTY0Q29udGVudC5sZW5ndGggPCBDSFVOS19TSVpFKSB7XG4gICAgICBjb25zdCBtYXJrZXIgPSBgRU9GXyR7aX1gO1xuICAgICAgY29uc3QgZXhlY1Jlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgXCItY1wiLFxuICAgICAgICAgIGBiYXNlNjQgLWQgPiAke3F1b3RlKGZ1bGxQYXRoKX0gPDwgJyR7bWFya2VyfSdcbiR7YmFzZTY0Q29udGVudH1cbiR7bWFya2VyfWAsXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgaWYgKGV4ZWNSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBleGVjUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGV4aXRDb2RlLCBzdGRlcnIgfSA9IGF3YWl0IGV4ZWNSZXN1bHQucmVzdWx0O1xuICAgICAgaWYgKGV4aXRDb2RlICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgd3JpdGVGaWxlcyBmYWlsZWQgd2l0aCBleGl0IGNvZGUgJHtleGl0Q29kZX06ICR7c3RkZXJyfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGVtcEI2NCA9IGAvdG1wL2NodW5rLSR7RGF0ZS5ub3coKX0tJHtpfS5iNjRgO1xuXG4gICAgICBjb25zdCBjbGVhclJlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICBhcmdzOiBbXCItY1wiLCBgPiAke3F1b3RlKHRlbXBCNjQpfWBdLFxuICAgICAgfSk7XG4gICAgICBpZiAoY2xlYXJSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBjbGVhclJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGNsZWFyUmVzdWx0LnJlc3VsdDtcblxuICAgICAgZm9yIChcbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAgIG9mZnNldCA8IGJhc2U2NENvbnRlbnQubGVuZ3RoO1xuICAgICAgICBvZmZzZXQgKz0gQ0hVTktfU0laRVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGNodW5rID0gYmFzZTY0Q29udGVudC5zbGljZShvZmZzZXQsIG9mZnNldCArIENIVU5LX1NJWkUpO1xuICAgICAgICBjb25zdCBtYXJrZXIgPSBgQ0hVTktfJHtvZmZzZXR9YDtcbiAgICAgICAgY29uc3QgYXBwZW5kUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgICAgICBjb21tYW5kOiBcImJhc2hcIixcbiAgICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgICBgY2F0ID4+ICR7cXVvdGUodGVtcEI2NCl9IDw8ICcke21hcmtlcn0nXG4ke2NodW5rfVxuJHttYXJrZXJ9YCxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoYXBwZW5kUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBhcHBlbmRSZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGV4aXRDb2RlLCBzdGRlcnIgfSA9IGF3YWl0IGFwcGVuZFJlc3VsdC5yZXN1bHQ7XG4gICAgICAgIGlmIChleGl0Q29kZSAhPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGB3cml0ZUZpbGVzIGNodW5rIGZhaWxlZCB3aXRoIGV4aXQgY29kZSAke2V4aXRDb2RlfTogJHtzdGRlcnJ9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgZGVjb2RlUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgYGJhc2U2NCAtZCA8ICR7cXVvdGUodGVtcEI2NCl9ID4gJHtxdW90ZShmdWxsUGF0aCl9ICYmIHJtIC1mICR7cXVvdGUodGVtcEI2NCl9YCxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZGVjb2RlUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZGVjb2RlUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGV4aXRDb2RlLCBzdGRlcnIgfSA9IGF3YWl0IGRlY29kZVJlc3VsdC5yZXN1bHQ7XG4gICAgICBpZiAoZXhpdENvZGUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGB3cml0ZUZpbGVzIGRlY29kZSBmYWlsZWQgd2l0aCBleGl0IGNvZGUgJHtleGl0Q29kZX06ICR7c3RkZXJyfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoc2hlbGxTY3JpcHRzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjaG1vZFJlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICBjb21tYW5kOiBcImNobW9kXCIsXG4gICAgICBhcmdzOiBbXCIreFwiLCAuLi5zaGVsbFNjcmlwdHNdLFxuICAgIH0pO1xuICAgIGlmIChjaG1vZFJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBjaG1vZFJlc3VsdDtcbiAgICB9XG4gICAgYXdhaXQgY2htb2RSZXN1bHQucmVzdWx0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHRvQmFzZTY0KGNvbnRlbnQ6IHN0cmluZyB8IEJ1ZmZlcik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgY29udGVudCA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShjb250ZW50KS50b1N0cmluZyhcImJhc2U2NFwiKTtcbiAgfVxuICByZXR1cm4gY29udGVudC50b1N0cmluZyhcImJhc2U2NFwiKTtcbn1cblxuZnVuY3Rpb24gcXVvdGUoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAnJHtzLnJlcGxhY2UoLycvZywgXCInXFxcXCcnXCIpfSdgO1xufVxuIiwgImltcG9ydCAqIGFzIGVycm9yZSBmcm9tIFwiZXJyb3JlXCI7XG5pbXBvcnQgeyBTYW5kYm94IGFzIFZlcmNlbFNhbmRib3hTREsgfSBmcm9tIFwic2FuZGJveFwiO1xuaW1wb3J0IHsgc3RhcnQgfSBmcm9tIFwid29ya2Zsb3cvYXBpXCI7XG5pbXBvcnQgeyBTYW5kYm94RXJyb3IsIFNhbmRib3hOb3RGb3VuZEVycm9yIH0gZnJvbSBcIi4uLy4uL2Vycm9yc1wiO1xuaW1wb3J0IHR5cGUgeyBUYWdzU2NoZW1hIH0gZnJvbSBcIi4uLy4uL2luZGV4XCI7XG5pbXBvcnQgdHlwZSB7XG4gIFJwY0ZuLFxuICBTYW5kYm94UmVjb3JkLFxuICBTdG9yYWdlLFxuICBTdG9yYWdlQ29uZmlnLFxufSBmcm9tIFwiLi4vLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHR5cGUge1xuICBMb2dFbnRyeSxcbiAgU2FuZGJveCxcbiAgU2FuZGJveExpZmVjeWNsZSxcbiAgU2FuZGJveExpZmVjeWNsZUlucHV0LFxuICBTYW5kYm94U3RhdHVzLFxufSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IHdyaXRlRmlsZXMgfSBmcm9tIFwiLi4vd3JpdGUtZmlsZXNcIjtcbmltcG9ydCB7IHNhbmRib3hMaWZlY3ljbGVXb3JrZmxvdyB9IGZyb20gXCIuL2xpZmVjeWNsZS13b3JrZmxvd1wiO1xuXG5leHBvcnQgdHlwZSBWZXJjZWxTYW5kYm94Q3JlYXRlT3B0aW9ucyA9IEV4dHJhY3Q8XG4gIFBhcmFtZXRlcnM8dHlwZW9mIFZlcmNlbFNhbmRib3hTREsuY3JlYXRlPlswXSxcbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvY29tcGxleGl0eS9ub0Jhbm5lZFR5cGVzOiAuXG4gIHt9XG4+O1xuXG5leHBvcnQgY29uc3QgVkVSQ0VMX01BWF9USU1FT1VUX01TID0gNSAqIDYwICogNjAgKiAxMDAwOyAvLyA1IGhvdXJzXG5jb25zdCBMT0NLX1RJTUVPVVRfTVMgPSAyICogNjAgKiAxMDAwOyAvLyAyIG1pbnV0ZXMgLSBpZiBsb2NrIG9sZGVyIHRoYW4gdGhpcywgY29uc2lkZXIgaXQgc3RhbGVcbmNvbnN0IExPQ0tfUE9MTF9JTlRFUlZBTF9NUyA9IDIwMDtcblxuY29uc3QgZ2V0VGVzdENyZWRlbnRpYWxzID0gKCkgPT5cbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiXG4gICAgPyB7XG4gICAgICAgIHRva2VuOiBwcm9jZXNzLmVudi5URVNUX1ZFUkNFTF9UT0tFTixcbiAgICAgICAgdGVhbUlkOiBwcm9jZXNzLmVudi5URVNUX1ZFUkNFTF9URUFNX0lELFxuICAgICAgICBwcm9qZWN0SWQ6IHByb2Nlc3MuZW52LlRFU1RfVkVSQ0VMX1BST0pFQ1RfSUQsXG4gICAgICB9XG4gICAgOiB7fTtcblxuLyoqXG4gKiBNb2R1bGUtbGV2ZWwgY2FjaGUgZm9yIGluLWZsaWdodCBzYW5kYm94IGNyZWF0aW9uIHByb21pc2VzLlxuICogUHJldmVudHMgcGFyYWxsZWwgcmVxdWVzdHMgd2l0aGluIHRoZSBzYW1lIHByb2Nlc3MgZnJvbSBjcmVhdGluZyBkdXBsaWNhdGUgc2FuZGJveGVzLlxuICovXG5jb25zdCBjcmVhdGVQcm9taXNlcyA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4+KCk7XG5cbmNvbnN0IEFDVElWSVRZX1RIUk9UVExFX01TID0gMTBfMDAwO1xuY29uc3QgbGFzdEFjdGl2aXR5U2VudCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbmNvbnN0IERFRkFVTFRfVkNQVVMgPSAyO1xuXG5mdW5jdGlvbiBpc1NhbmRib3hHb25lRXJyb3IoZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgZXJyb3JXaXRoUmVzcG9uc2UgPSBlIGFzIHsgcmVzcG9uc2U/OiB7IHN0YXR1cz86IG51bWJlciB9IH07XG4gIGNvbnN0IGVycm9yV2l0aENhdXNlID0gZSBhcyB7IGNhdXNlPzogeyByZXNwb25zZT86IHsgc3RhdHVzPzogbnVtYmVyIH0gfSB9O1xuXG4gIGNvbnN0IHN0YXR1cyA9XG4gICAgZXJyb3JXaXRoUmVzcG9uc2UucmVzcG9uc2U/LnN0YXR1cyA/P1xuICAgIGVycm9yV2l0aENhdXNlLmNhdXNlPy5yZXNwb25zZT8uc3RhdHVzO1xuXG4gIGlmIChzdGF0dXMgPT09IDQxMCB8fCBzdGF0dXMgPT09IDQyMikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3QgbWVzc2FnZSA9IGUubWVzc2FnZSB8fCBTdHJpbmcoZSk7XG4gIGlmIChcbiAgICBtZXNzYWdlLmluY2x1ZGVzKFwiRXhwZWN0ZWQgYSBzdHJlYW0gb2YgY29tbWFuZCBkYXRhXCIpIHx8XG4gICAgbWVzc2FnZS5pbmNsdWRlcyhcIkV4cGVjdGVkIGEgc3RyZWFtIG9mIGxvZ3NcIilcbiAgKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBjb25zdCB2ZXJjZWxTYW5kYm94ID0gPFRUYWdzIGV4dGVuZHMgVGFnc1NjaGVtYSA9IFRhZ3NTY2hlbWE+KHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3csXG4gIHN0b3JhZ2UsXG4gIHJwYyxcbn06IHtcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZCAmIHsgY29uZmlnOiB7IHR5cGU6IFwidmVyY2VsXCIgfSB9O1xuICBzdG9yYWdlQ29uZmlnOiBTdG9yYWdlQ29uZmlnO1xuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdzogYm9vbGVhbjtcbiAgc3RvcmFnZTogU3RvcmFnZTtcbiAgcnBjOiBScGNGbjtcbn0pOiBTYW5kYm94PFRUYWdzPiA9PiB7XG4gIGNvbnN0IHsgaWQsIGNvbmZpZyB9ID0gc2FuZGJveFJlY29yZDtcbiAgY29uc3QgdmNwdXMgPSBjb25maWcucmVzb3VyY2VzPy52Y3B1cyA/PyBERUZBVUxUX1ZDUFVTO1xuICBjb25zdCBwb3J0cyA9IGNvbmZpZy5wb3J0cztcbiAgY29uc3QgaW5pdGlhbFZlcmNlbCA9XG4gICAgc2FuZGJveFJlY29yZC5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgPyBzYW5kYm94UmVjb3JkLnByb3ZpZGVyTWV0YWRhdGFcbiAgICAgIDogbnVsbDtcblxuICB0eXBlIFNhbmRib3hJbnN0YW5jZSA9IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgVmVyY2VsU2FuZGJveFNESy5nZXQ+PjtcbiAgbGV0IHNhbmRib3hQcm9taXNlOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IFNhbmRib3hJbnN0YW5jZT4gfCBudWxsID0gbnVsbDtcbiAgbGV0IHJlY292ZXJlZEZyb21TdGFsZSA9IGZhbHNlO1xuICBjb25zdCBIT01FX0RJUiA9IFwiL2hvbWUvdmVyY2VsLXNhbmRib3hcIjtcblxuICBhc3luYyBmdW5jdGlvbiBwb2xsRm9yU2FuZGJveElkKCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgTE9DS19USU1FT1VUX01TO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIExPQ0tfUE9MTF9JTlRFUlZBTF9NUykpO1xuICAgICAgY29uc3QgcmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICBpZiAocmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IHJlY29yZC5tZXNzYWdlLCBjYXVzZTogcmVjb3JkIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgdmVyY2VsU2FuZGJveElkID1cbiAgICAgICAgcmVjb3JkPy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICAgID8gcmVjb3JkLnByb3ZpZGVyTWV0YWRhdGEuc2FuZGJveElkXG4gICAgICAgICAgOiBudWxsO1xuICAgICAgaWYgKHZlcmNlbFNhbmRib3hJZCkge1xuICAgICAgICByZXR1cm4gdmVyY2VsU2FuZGJveElkO1xuICAgICAgfVxuICAgICAgaWYgKCFyZWNvcmQ/LmFjcXVpcmluZ0xvY2tBdCkge1xuICAgICAgICBjb25zdCBmaW5hbENoZWNrID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICAgIGlmIChmaW5hbENoZWNrIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgICByZWFzb246IGZpbmFsQ2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgIGNhdXNlOiBmaW5hbENoZWNrLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbmFsVmVyY2VsU2FuZGJveElkID1cbiAgICAgICAgICBmaW5hbENoZWNrPy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICAgICAgPyBmaW5hbENoZWNrLnByb3ZpZGVyTWV0YWRhdGEuc2FuZGJveElkXG4gICAgICAgICAgICA6IG51bGw7XG4gICAgICAgIGlmIChmaW5hbFZlcmNlbFNhbmRib3hJZCkge1xuICAgICAgICAgIHJldHVybiBmaW5hbFZlcmNlbFNhbmRib3hJZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICByZWFzb246IFwiVGltZWQgb3V0IHdhaXRpbmcgZm9yIHNhbmRib3ggY3JlYXRpb24gYnkgYW5vdGhlciBwcm9jZXNzXCIsXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBzdGFydExpZmVjeWNsZVdvcmtmbG93KFxuICAgIHZlcmNlbFNhbmRib3hJZDogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3cpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGlmZWN5Y2xlSW5wdXQ6IFNhbmRib3hMaWZlY3ljbGVJbnB1dCA9IHtcbiAgICAgIGlkLFxuICAgICAgdmVyY2VsU2FuZGJveElkLFxuICAgICAgc3RvcmFnZUNvbmZpZyxcbiAgICAgIHJwYyxcbiAgICB9O1xuICAgIGF3YWl0IHN0YXJ0KHNhbmRib3hMaWZlY3ljbGVXb3JrZmxvdywgW3sgaW5wdXQ6IGxpZmVjeWNsZUlucHV0IH1dKS5jYXRjaChcbiAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FbXB0eUJsb2NrU3RhdGVtZW50czogaW50ZW50aW9uYWxseSBpZ25vcmVkIC0gd29ya2Zsb3cgc3RhcnQgaXMgZmlyZS1hbmQtZm9yZ2V0XG4gICAgICAoKSA9PiB7fVxuICAgICk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBjcmVhdGVTYW5kYm94RnJvbVNuYXBzaG90KFxuICAgIHNuYXBzaG90SWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIHJldHVybiBhd2FpdCBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZSh7XG4gICAgICAgICAgc291cmNlOiB7IHR5cGU6IFwic25hcHNob3RcIiwgc25hcHNob3RJZCB9LFxuICAgICAgICAgIHJlc291cmNlczogeyB2Y3B1cyB9LFxuICAgICAgICAgIHRpbWVvdXQ6IFZFUkNFTF9NQVhfVElNRU9VVF9NUyxcbiAgICAgICAgICBwb3J0cyxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICB0YWdzOiBzYW5kYm94UmVjb3JkLnRhZ3MsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LnNhbmRib3hJZCxcbiAgICAgICAgICAgIHNuYXBzaG90SWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHN0YXJ0TGlmZWN5Y2xlV29ya2Zsb3coc2FuZGJveC5zYW5kYm94SWQpO1xuICAgICAgICByZXR1cm4gc2FuZGJveC5zYW5kYm94SWQ7XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRnJlc2hTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IFZlcmNlbFNhbmRib3hTREsuY3JlYXRlKHtcbiAgICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgICAgcG9ydHMsXG4gICAgICAgICAgLi4uZ2V0VGVzdENyZWRlbnRpYWxzKCksXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgdGFnczogc2FuZGJveFJlY29yZC50YWdzLFxuICAgICAgICAgIGNyZWF0ZWRBdDogbm93LFxuICAgICAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICBwcm92aWRlcjogXCJ2ZXJjZWxcIixcbiAgICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveC5zYW5kYm94SWQsXG4gICAgICAgICAgICBzbmFwc2hvdElkOiBudWxsLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBzdGFydExpZmVjeWNsZVdvcmtmbG93KHNhbmRib3guc2FuZGJveElkKTtcbiAgICAgICAgcmV0dXJuIHNhbmRib3guc2FuZGJveElkO1xuICAgICAgfSxcbiAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRvR2V0T3JDcmVhdGVTYW5kYm94SWQoKTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBzdHJpbmc+IHtcbiAgICBpZiAoaW5pdGlhbFZlcmNlbD8uc2FuZGJveElkICYmICFyZWNvdmVyZWRGcm9tU3RhbGUpIHtcbiAgICAgIHJldHVybiBpbml0aWFsVmVyY2VsLnNhbmRib3hJZDtcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBTYW5kYm94Tm90Rm91bmRFcnJvcikge1xuICAgICAgICAvLyBTYW5kYm94IGRvZXNuJ3QgZXhpc3QgeWV0LCBjb250aW51ZSB3aXRoIGNyZWF0aW9uXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogZXhpc3RpbmcubWVzc2FnZSwgY2F1c2U6IGV4aXN0aW5nIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nUmVjb3JkID1cbiAgICAgIGV4aXN0aW5nIGluc3RhbmNlb2YgU2FuZGJveE5vdEZvdW5kRXJyb3IgPyBudWxsIDogZXhpc3Rpbmc7XG4gICAgY29uc3QgZXhpc3RpbmdWZXJjZWwgPVxuICAgICAgZXhpc3RpbmdSZWNvcmQ/LnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmdSZWNvcmQucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG5cbiAgICBpZiAoZXhpc3RpbmdWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nVmVyY2VsLnNhbmRib3hJZDtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNBY3RpdmVMb2NrID1cbiAgICAgIGV4aXN0aW5nUmVjb3JkPy5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgIGV4aXN0aW5nUmVjb3JkLmFjcXVpcmluZ0xvY2tBdCAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGV4aXN0aW5nUmVjb3JkLmFjcXVpcmluZ0xvY2tBdCA8IExPQ0tfVElNRU9VVF9NUztcblxuICAgIGlmIChoYXNBY3RpdmVMb2NrKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGxvY2tJZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgIGlkLFxuICAgICAgY29uZmlnLFxuICAgICAgdGFnczogZXhpc3RpbmdSZWNvcmQ/LnRhZ3MgPz8gc2FuZGJveFJlY29yZC50YWdzLFxuICAgICAgY3JlYXRlZEF0OiBleGlzdGluZ1JlY29yZD8uY3JlYXRlZEF0ID8/IHNhbmRib3hSZWNvcmQuY3JlYXRlZEF0LFxuICAgICAgbGFzdEFjdGl2aXR5QXQ6XG4gICAgICAgIGV4aXN0aW5nUmVjb3JkPy5sYXN0QWN0aXZpdHlBdCA/PyBzYW5kYm94UmVjb3JkLmxhc3RBY3Rpdml0eUF0LFxuICAgICAgYWNxdWlyaW5nTG9ja0lkOiBsb2NrSWQsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG5vdyxcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgc25hcHNob3RJZDpcbiAgICAgICAgICBleGlzdGluZ1ZlcmNlbD8uc25hcHNob3RJZCA/PyBpbml0aWFsVmVyY2VsPy5zbmFwc2hvdElkID8/IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgYWZ0ZXJMb2NrID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGFmdGVyTG9jayBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogYWZ0ZXJMb2NrLm1lc3NhZ2UsIGNhdXNlOiBhZnRlckxvY2sgfSk7XG4gICAgfVxuICAgIGlmIChhZnRlckxvY2s/LmFjcXVpcmluZ0xvY2tJZCAhPT0gbG9ja0lkKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHNuYXBzaG90SWQgPVxuICAgICAgZXhpc3RpbmdWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGluaXRpYWxWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGNvbmZpZy5saWZlY3ljbGU/LnNuYXBzaG90SWQ7XG4gICAgaWYgKHNuYXBzaG90SWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3Qoc25hcHNob3RJZCk7XG4gICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlRnJlc2hTYW5kYm94KCk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZVNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGNyZWF0ZVByb21pc2VzLmdldChpZCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlID0gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgY3JlYXRlUHJvbWlzZXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcbiAgICBjcmVhdGVQcm9taXNlcy5zZXQoaWQsIHByb21pc2UpO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZG9HZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgY29uc3QgdmVyY2VsU2FuZGJveElkID0gYXdhaXQgZ2V0T3JDcmVhdGVTYW5kYm94SWQoKTtcbiAgICBpZiAodmVyY2VsU2FuZGJveElkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiB2ZXJjZWxTYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6ICgpID0+XG4gICAgICAgIFZlcmNlbFNhbmRib3hTREsuZ2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHZlcmNlbFNhbmRib3hJZCxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSksXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgaWYgKCFzYW5kYm94UHJvbWlzZSkge1xuICAgICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcbiAgICB9XG4gICAgcmV0dXJuIHNhbmRib3hQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVjb3ZlckZyb21TdGFsZVNhbmRib3goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgc2FuZGJveFByb21pc2UgPSBudWxsO1xuICAgIHJlY292ZXJlZEZyb21TdGFsZSA9IHRydWU7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nVmVyY2VsID1cbiAgICAgIGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG5cbiAgICBpZiAoZXhpc3RpbmdWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgIGlkOiBleGlzdGluZy5pZCxcbiAgICAgICAgY29uZmlnOiBleGlzdGluZy5jb25maWcsXG4gICAgICAgIHRhZ3M6IGV4aXN0aW5nLnRhZ3MsXG4gICAgICAgIGNyZWF0ZWRBdDogZXhpc3RpbmcuY3JlYXRlZEF0LFxuICAgICAgICBsYXN0QWN0aXZpdHlBdDogZXhpc3RpbmcubGFzdEFjdGl2aXR5QXQsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgc2FuZGJveElkOiBudWxsLFxuICAgICAgICAgIHNuYXBzaG90SWQ6IGV4aXN0aW5nVmVyY2VsLnNuYXBzaG90SWQsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiB1cGRhdGVMYXN0QWN0aXZpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBsYXN0U2VudCA9IGxhc3RBY3Rpdml0eVNlbnQuZ2V0KGlkKTtcbiAgICBpZiAobGFzdFNlbnQgJiYgbm93IC0gbGFzdFNlbnQgPCBBQ1RJVklUWV9USFJPVFRMRV9NUykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsYXN0QWN0aXZpdHlTZW50LnNldChpZCwgbm93KTtcblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IgfHwgIWV4aXN0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nVmVyY2VsID1cbiAgICAgIGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG4gICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICBpZDogZXhpc3RpbmcuaWQsXG4gICAgICBjb25maWc6IGV4aXN0aW5nLmNvbmZpZyxcbiAgICAgIHRhZ3M6IGV4aXN0aW5nLnRhZ3MsXG4gICAgICBjcmVhdGVkQXQ6IGV4aXN0aW5nLmNyZWF0ZWRBdCxcbiAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICBwcm92aWRlck1ldGFkYXRhOiBleGlzdGluZ1ZlcmNlbCA/PyB7XG4gICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgbGlmZWN5Y2xlOiBTYW5kYm94TGlmZWN5Y2xlID0ge1xuICAgIHN0YXJ0OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHVwZGF0ZUxhc3RBY3Rpdml0eSgpO1xuICAgICAgcmV0dXJuIHNhbmRib3guc3RhdHVzIGFzIFNhbmRib3hTdGF0dXM7XG4gICAgfSxcblxuICAgIHNuYXBzaG90OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICAgICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCBzYW5kYm94LnNuYXBzaG90KCk7XG4gICAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIHRhZ3M6IGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IgPyBudWxsIDogKGV4aXN0aW5nPy50YWdzID8/IG51bGwpLFxuICAgICAgICAgICAgY3JlYXRlZEF0OlxuICAgICAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yID8gbnVsbCA6IChleGlzdGluZz8uY3JlYXRlZEF0ID8/IG51bGwpLFxuICAgICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6XG4gICAgICAgICAgICAgIGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgICAgICAgICA/IG51bGxcbiAgICAgICAgICAgICAgICA6IChleGlzdGluZz8ubGFzdEFjdGl2aXR5QXQgPz8gbnVsbCksXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgICAgICAgIHNuYXBzaG90SWQ6IHNuYXBzaG90LnNuYXBzaG90SWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiB7IHNuYXBzaG90SWQ6IHNuYXBzaG90LnNuYXBzaG90SWQgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIHN0b3A6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc2FuZGJveC5zdG9wKCk7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICAgICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBFcnJvciB8fCAhZXhpc3RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgICAgICAgaWQ6IGV4aXN0aW5nLmlkLFxuICAgICAgICAgICAgY29uZmlnOiBleGlzdGluZy5jb25maWcsXG4gICAgICAgICAgICB0YWdzOiBleGlzdGluZy50YWdzLFxuICAgICAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZy5jcmVhdGVkQXQsXG4gICAgICAgICAgICBsYXN0QWN0aXZpdHlBdDogZXhpc3RpbmcubGFzdEFjdGl2aXR5QXQsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH0sXG4gICAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXRTdGF0dXM6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNhbmRib3guc3RhdHVzIGFzIFNhbmRib3hTdGF0dXM7XG4gICAgfSxcblxuICAgIGdldENyZWF0ZWRBdDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2FuZGJveC5jcmVhdGVkQXQ7XG4gICAgfSxcblxuICAgIGdldFJlbWFpbmluZ1RpbWVvdXQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNhbmRib3gudGltZW91dDtcbiAgICB9LFxuICB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGRvRXhlYyh7XG4gICAgY29tbWFuZCxcbiAgICBhcmdzLFxuICAgIHNpZ25hbCxcbiAgfToge1xuICAgIGNvbW1hbmQ6IHN0cmluZztcbiAgICBhcmdzPzogc3RyaW5nW107XG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIH0pOiBQcm9taXNlPFxuICAgIHwgU2FuZGJveEVycm9yXG4gICAgfCB7XG4gICAgICAgIGNvbW1hbmRJZDogc3RyaW5nO1xuICAgICAgICBsb2dzOiAoKSA9PiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PjtcbiAgICAgICAgcmVzdWx0OiBQcm9taXNlPHsgc3Rkb3V0OiBzdHJpbmc7IHN0ZGVycjogc3RyaW5nOyBleGl0Q29kZTogbnVtYmVyIH0+O1xuICAgICAgfVxuICA+IHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIGNvbnN0IHVwZGF0ZVByb21pc2UgPSB1cGRhdGVMYXN0QWN0aXZpdHkoKTtcblxuICAgIC8qKlxuICAgICAqIGRldGFjaGVkOiB0cnVlIG1ha2VzIHJ1bkNvbW1hbmQgcmV0dXJuIGltbWVkaWF0ZWx5IHdpdGggYSBDb21tYW5kIGhhbmRsZVxuICAgICAqIGluc3RlYWQgb2YgYmxvY2tpbmcgdW50aWwgdGhlIHByb2Nlc3MgZXhpdHMuIFRoaXMgaXMgY3JpdGljYWwgZm9yXG4gICAgICogbG9uZy1ydW5uaW5nIGNvbW1hbmRzIHdoZXJlIHRoZSBjYWxsZXIgbmVlZHMgdG8gaW50ZXJhY3Qgd2l0aCB0aGUgcHJvY2Vzc1xuICAgICAqIChlLmcuIHJlYWRpbmcgbG9ncyBhbmQgd3JpdGluZyBmaWxlcykgd2hpbGUgaXQncyBzdGlsbCBydW5uaW5nLlxuICAgICAqL1xuICAgIGNvbnN0IGV4ZWNSZXN1bHQgPSBhd2FpdCBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IGF3YWl0IGluc3RhbmNlLnJ1bkNvbW1hbmQoe1xuICAgICAgICAgIGN3ZDogSE9NRV9ESVIsXG4gICAgICAgICAgYXJncyxcbiAgICAgICAgICBjbWQ6IGNvbW1hbmQsXG4gICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgIGRldGFjaGVkOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICAgICAgbGV0IHN0ZGVyciA9IFwiXCI7XG4gICAgICAgIGNvbnN0IGxvZ0J1ZmZlcjogTG9nRW50cnlbXSA9IFtdO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHtcbiAgICAgICAgICByZXNvbHZlOiBudWxsIGFzICgoKSA9PiB2b2lkKSB8IG51bGwsXG4gICAgICAgICAgY29uc3VtZWQ6IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGNvbnN1bWVMb2dzID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBsb2cgb2Ygb3V0cHV0LmxvZ3MoKSkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPVxuICAgICAgICAgICAgICAgIGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCJcbiAgICAgICAgICAgICAgICAgID8geyBzdHJlYW06IFwic3Rkb3V0XCIsIGRhdGE6IGxvZy5kYXRhIH1cbiAgICAgICAgICAgICAgICAgIDogeyBzdHJlYW06IFwic3RkZXJyXCIsIGRhdGE6IGxvZy5kYXRhIH07XG5cbiAgICAgICAgICAgICAgaWYgKGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCIpIHtcbiAgICAgICAgICAgICAgICBzdGRvdXQgKz0gbG9nLmRhdGE7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RkZXJyICs9IGxvZy5kYXRhO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgbG9nQnVmZmVyLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICBzdGF0ZS5yZXNvbHZlPy4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIFNhbmRib3ggbWF5IGhhdmUgYmVlbiBzdG9wcGVkIC0gbG9ncyBlbmRwb2ludCByZXR1cm5zIDQyMlxuICAgICAgICAgIH1cbiAgICAgICAgICBzdGF0ZS5jb25zdW1lZCA9IHRydWU7XG4gICAgICAgICAgc3RhdGUucmVzb2x2ZT8uKCk7XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgYXN5bmMgZnVuY3Rpb24qIGxvZ3MoKTogQXN5bmNJdGVyYWJsZTxMb2dFbnRyeT4ge1xuICAgICAgICAgIGxldCBpbmRleCA9IDA7XG4gICAgICAgICAgd2hpbGUgKCFzdGF0ZS5jb25zdW1lZCB8fCBpbmRleCA8IGxvZ0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChpbmRleCA8IGxvZ0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgeWllbGQgbG9nQnVmZmVyW2luZGV4KytdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHN0YXRlLnJlc29sdmUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnN1bWVMb2dzLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaW5pc2hlZCA9IGF3YWl0IG91dHB1dC53YWl0KCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBzdGRvdXQsXG4gICAgICAgICAgICAgIHN0ZGVycixcbiAgICAgICAgICAgICAgZXhpdENvZGU6IGZpbmlzaGVkLmV4aXRDb2RlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNTYW5kYm94R29uZUVycm9yKGUpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7IHN0ZG91dCwgc3RkZXJyLCBleGl0Q29kZTogMSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IGNvbW1hbmRJZDogb3V0cHV0LmNtZElkLCBsb2dzLCByZXN1bHQgfTtcbiAgICAgIH0sXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG5cbiAgICBhd2FpdCB1cGRhdGVQcm9taXNlO1xuICAgIHJldHVybiBleGVjUmVzdWx0O1xuICB9XG5cbiAgY29uc3Qgc2FuZGJveDogU2FuZGJveDxUVGFncz4gPSB7XG4gICAgaWQsXG4gICAgY29uZmlnLFxuICAgIGV4ZWM6IGFzeW5jIChvcHRzKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkb0V4ZWMob3B0cyk7XG5cbiAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBTYW5kYm94RXJyb3IgJiYgaXNTYW5kYm94R29uZUVycm9yKHJlc3VsdC5jYXVzZSkpIHtcbiAgICAgICAgYXdhaXQgcmVjb3ZlckZyb21TdGFsZVNhbmRib3goKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGRvRXhlYyhvcHRzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgZ2V0RG9tYWluOiBhc3luYyAocG9ydCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94LmRvbWFpbihwb3J0KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGtpbGw6IGFzeW5jICh7IGNvbW1hbmRJZCwgc3RvcmFnZTogY21kU3RvcmFnZSB9KSA9PiB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY21kID0gYXdhaXQgY21kU3RvcmFnZS5jb21tYW5kLmdldChjb21tYW5kSWQpO1xuICAgICAgaWYgKGNtZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBjbWQubWVzc2FnZSwgY2F1c2U6IGNtZCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjbWQgJiYgY21kLnN0YXR1cyA9PT0gXCJydW5uaW5nXCIpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY21kU3RvcmFnZS5jb21tYW5kLnNldCh7XG4gICAgICAgICAgLi4uY21kLFxuICAgICAgICAgIHN0YXR1czogXCJraWxsZWRcIixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiByZXN1bHQubWVzc2FnZSwgY2F1c2U6IHJlc3VsdCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9LFxuXG4gICAgd3JpdGVGaWxlczogKG9wdHMpID0+IHdyaXRlRmlsZXMoeyBzYW5kYm94LCAuLi5vcHRzIH0pLFxuXG4gICAgbGlmZWN5Y2xlLFxuXG4gICAgdGFnOiB7XG4gICAgICBsaXN0OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3hSZWNvcmQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICAgICAgaWYgKHNhbmRib3hSZWNvcmQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBzYW5kYm94UmVjb3JkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoc2FuZGJveFJlY29yZC50YWdzID8/IHt9KSBhcyBUVGFncztcbiAgICAgIH0sXG4gICAgICBnZXQ6IGFzeW5jIChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94UmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICAgIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZC50YWdzPy5ba2V5IGFzIHN0cmluZ10gYXNcbiAgICAgICAgICB8IFRUYWdzW3R5cGVvZiBrZXldXG4gICAgICAgICAgfCB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICAgc2V0OiBhc3luYyAoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC50YWcuc2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IGlkLFxuICAgICAgICAgIHRhZ3M6IHsgW2tleV06IHZhbHVlIH0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICAgc2V0TWFueTogYXN5bmMgKHRhZ3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC50YWcuc2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IGlkLFxuICAgICAgICAgIHRhZ3M6IHRhZ3MgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgIH0sXG4gIH07XG5cbiAgaWYgKGNvbmZpZy5saWZlY3ljbGU/LmF1dG9TdGFydCAhPT0gZmFsc2UpIHtcbiAgICBzYW5kYm94UHJvbWlzZSA9IGRvR2V0U2FuZGJveCgpO1xuICB9XG5cbiAgcmV0dXJuIHNhbmRib3g7XG59O1xuIiwgImltcG9ydCB0eXBlIHsgVGFnc1NjaGVtYSB9IGZyb20gXCIuLi9pbmRleFwiO1xuaW1wb3J0IHR5cGUgeyBScGNGbiwgU2FuZGJveFJlY29yZCwgU3RvcmFnZSwgU3RvcmFnZUNvbmZpZyB9IGZyb20gXCIuLi9zdG9yYWdlXCI7XG5pbXBvcnQgeyBsb2NhbFNhbmRib3ggfSBmcm9tIFwiLi9iaW5kaW5ncy9sb2NhbFwiO1xuaW1wb3J0IHsgdmVyY2VsU2FuZGJveCB9IGZyb20gXCIuL2JpbmRpbmdzL3ZlcmNlbFwiO1xuaW1wb3J0IHR5cGUgeyBTYW5kYm94IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNhbmRib3g8VFRhZ3MgZXh0ZW5kcyBUYWdzU2NoZW1hID0gVGFnc1NjaGVtYT4oe1xuICBzYW5kYm94UmVjb3JkLFxuICBzdG9yYWdlQ29uZmlnLFxuICBzdG9yYWdlLFxuICBycGMsXG4gIGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93ID0gdHJ1ZSxcbn06IHtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZDtcbiAgc3RvcmFnZTogU3RvcmFnZTtcbiAgcnBjOiBScGNGbjtcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3c/OiBib29sZWFuO1xufSk6IFNhbmRib3g8VFRhZ3M+IHtcbiAgc3dpdGNoIChzYW5kYm94UmVjb3JkLmNvbmZpZy50eXBlKSB7XG4gICAgY2FzZSBcImxvY2FsXCI6XG4gICAgICByZXR1cm4gbG9jYWxTYW5kYm94PFRUYWdzPih7XG4gICAgICAgIHNhbmRib3hSZWNvcmQ6IHNhbmRib3hSZWNvcmQgYXMgU2FuZGJveFJlY29yZCAmIHtcbiAgICAgICAgICBjb25maWc6IHsgdHlwZTogXCJsb2NhbFwiIH07XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICB9KTtcbiAgICBjYXNlIFwidmVyY2VsXCI6XG4gICAgICByZXR1cm4gdmVyY2VsU2FuZGJveDxUVGFncz4oe1xuICAgICAgICBzYW5kYm94UmVjb3JkOiBzYW5kYm94UmVjb3JkIGFzIFNhbmRib3hSZWNvcmQgJiB7XG4gICAgICAgICAgY29uZmlnOiB7IHR5cGU6IFwidmVyY2VsXCIgfTtcbiAgICAgICAgfSxcbiAgICAgICAgc3RvcmFnZUNvbmZpZyxcbiAgICAgICAgc3RvcmFnZSxcbiAgICAgICAgcnBjLFxuICAgICAgICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdyxcbiAgICAgIH0pO1xuICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkN1c3RvbSBzYW5kYm94ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgZGVmYXVsdDpcbiAgICAgIHNhbmRib3hSZWNvcmQuY29uZmlnIHNhdGlzZmllcyBuZXZlcjtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFVua25vd24gc2FuZGJveCB0eXBlOiAke1xuICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogLlxuICAgICAgICAgIChzYW5kYm94UmVjb3JkLmNvbmZpZyBhcyBhbnkpLnR5cGVcbiAgICAgICAgfWBcbiAgICAgICk7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7OztBQUNBLFNBQVMsYUFBYTtBQUN0QixZQUFZLFlBQVk7QUFDeEIsU0FBUyxZQUFZOzs7QUNIckIsWUFBWSxVQUFVO0FBV3RCLGVBQXNCLFdBQVcsTUFJZjtBQUNoQixRQUFNLEVBQUUsU0FBUyxP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QUFBQSxNQUNUO0FBQUEsTUFDQSxTQUFTLE9BQU8sU0FBa0M7QUFDaEQsY0FBTSxTQUFTLE1BQU0sUUFBUSxRQUFRLElBQUksSUFBSTtBQUFBLFVBQzNDLFdBQVc7QUFBQSxVQUNYO0FBQUEsUUFDRixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTztBQUFBLFFBQ1Q7QUFDQSxlQUFPO0FBQUEsTUFDVDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsTUFBSSxPQUFPLFdBQVcsY0FBYyxPQUFPO0FBQ3pDLHFCQUFpQixhQUFhO0FBQUEsRUFDaEM7QUFFQSxTQUFPO0FBQ1Q7OztBQ2hzQk8sU0FBUyxXQUFrRDtBQUFBLEVBQ2hFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQSwwQkFBMEI7QUFDNUIsR0FNbUI7QUFDakIsVUFBUSxjQUFjLE9BQU8sTUFBTTtBQUFBLElBQ2pDLEtBQUs7QUFDSCxhQUFPLGFBQW9CO0FBQUEsUUFDekI7QUFBQSxRQUdBO0FBQUEsTUFDRixDQUFDO0FBQUEsSUFDSCxLQUFLO0FBQ0gsYUFBTyxjQUFxQjtBQUFBLFFBQzFCO0FBQUEsUUFHQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0gsS0FBSztBQUNILFlBQU0sSUFBSSxNQUFNLG9DQUFvQztBQUFBLElBQ3REO0FBQ0Usb0JBQWM7QUFDZCxZQUFNLElBQUk7QUFBQSxRQUNSO0FBQUEsUUFFRyxjQUFjLE9BQWUsSUFDaEM7QUFBQSxNQUNGO0FBQUEsRUFDSjtBQUNGOyIsCiAgIm5hbWVzIjogWyJleGl0Q29kZSIsICJzdGRlcnIiLCAic3RvcmFnZSIsICJzYW5kYm94UmVjb3JkIiwgImVycm9yZSIsICJzYW5kYm94IiwgImdldFNhbmRib3giLCAic2FuZGJveFJlY29yZCJdCn0K