experimental-agent 0.2.1 → 0.3.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.
Files changed (71) hide show
  1. package/README.md +55 -254
  2. package/dist/adapter-BigchkkI.d.mts +201 -0
  3. package/dist/adapter-BigchkkI.d.ts +201 -0
  4. package/dist/chunk-BFFNCESS.mjs +302 -0
  5. package/dist/chunk-C4VSUEY2.mjs +72 -0
  6. package/dist/chunk-DOD4MC5D.mjs +196 -0
  7. package/dist/chunk-ELWIUJUK.mjs +96 -0
  8. package/dist/chunk-GKASMIBR.mjs +50 -0
  9. package/dist/chunk-JO3JDCH5.mjs +107 -0
  10. package/dist/chunk-MSWINCCM.mjs +128 -0
  11. package/dist/chunk-RT72C52I.mjs +324 -0
  12. package/dist/chunk-ZUFJJYC4.mjs +150 -0
  13. package/dist/{handler-FRUPZ4LX.mjs → docker-QPCLWLYR.mjs} +3 -4
  14. package/dist/entry-BmQ8FO-5.d.ts +36 -0
  15. package/dist/entry-CZd9aAwn.d.mts +36 -0
  16. package/dist/index.d.mts +415 -18
  17. package/dist/index.d.ts +415 -18
  18. package/dist/index.js +3036 -5494
  19. package/dist/index.mjs +3264 -1142
  20. package/dist/lifecycle-workflow-steps.d.mts +5 -0
  21. package/dist/lifecycle-workflow-steps.d.ts +5 -0
  22. package/dist/lifecycle-workflow-steps.js +263 -0
  23. package/dist/lifecycle-workflow-steps.mjs +9 -0
  24. package/dist/lifecycle-workflow.d.mts +6 -6
  25. package/dist/lifecycle-workflow.d.ts +6 -6
  26. package/dist/lifecycle-workflow.js +192 -905
  27. package/dist/lifecycle-workflow.mjs +3 -1
  28. package/dist/local-KJ3BSIFJ.mjs +8 -0
  29. package/dist/next/loader.d.mts +1 -0
  30. package/dist/next/loader.d.ts +1 -0
  31. package/dist/next/loader.js +44 -18
  32. package/dist/next/loader.mjs +18 -13
  33. package/dist/next.js +32 -9
  34. package/dist/next.mjs +6 -4
  35. package/dist/{process-manager-JDUJDYGU.mjs → process-manager-WQHAIVRB.mjs} +1 -1
  36. package/dist/sandbox.d.mts +6 -0
  37. package/dist/sandbox.d.ts +6 -0
  38. package/dist/sandbox.js +1070 -0
  39. package/dist/sandbox.mjs +19 -0
  40. package/dist/steps-BnkRQKlc.d.ts +173 -0
  41. package/dist/steps-u-mGDbP_.d.mts +173 -0
  42. package/dist/storage.d.mts +11 -0
  43. package/dist/storage.d.ts +11 -0
  44. package/dist/storage.js +234 -0
  45. package/dist/storage.mjs +12 -0
  46. package/dist/vercel-QZ6INPMV.mjs +11 -0
  47. package/package.json +26 -5
  48. package/dist/agent-workflow.d.mts +0 -30
  49. package/dist/agent-workflow.d.ts +0 -30
  50. package/dist/agent-workflow.js +0 -5433
  51. package/dist/agent-workflow.mjs +0 -14
  52. package/dist/chunk-AML2VCQS.mjs +0 -1287
  53. package/dist/chunk-FQ67QZOI.mjs +0 -75
  54. package/dist/chunk-NO7RHGTH.mjs +0 -2367
  55. package/dist/chunk-NXDVNJRS.mjs +0 -106
  56. package/dist/chunk-OZZVS6L5.mjs +0 -139
  57. package/dist/chunk-QRWGDFFY.mjs +0 -75
  58. package/dist/chunk-SJVFFE5D.mjs +0 -402
  59. package/dist/chunk-TAXLUVIC.mjs +0 -1
  60. package/dist/chunk-TGNVXSMX.mjs +0 -399
  61. package/dist/chunk-YRYXN7W4.mjs +0 -48
  62. package/dist/chunk-ZIAHPXOJ.mjs +0 -595
  63. package/dist/client-BKA7XBGW.mjs +0 -15
  64. package/dist/client-CEeSFGva.d.mts +0 -2376
  65. package/dist/client-CEeSFGva.d.ts +0 -2376
  66. package/dist/docker-FB2MJTHJ.mjs +0 -12
  67. package/dist/local-fs-handlers-SYOCKTPN.mjs +0 -447
  68. package/dist/sandbox-UENKQV3T.mjs +0 -21
  69. package/dist/storage-LSDMRW73.mjs +0 -20
  70. package/dist/vercel-SD3JTECG.mjs +0 -20
  71. package/dist/vercel-sdk-I6A4MVAN.mjs +0 -8
@@ -1,595 +0,0 @@
1
- import {
2
- createLogger
3
- } from "./chunk-OZZVS6L5.mjs";
4
- import {
5
- SandboxError
6
- } from "./chunk-YRYXN7W4.mjs";
7
-
8
- // src/sandbox/bindings/docker.ts
9
- import { execSync, spawn } from "child_process";
10
- import * as fs from "fs/promises";
11
- import * as os from "os";
12
- import * as path2 from "path";
13
- import * as errore from "errore";
14
- import { ulid } from "ulid";
15
-
16
- // src/sandbox/setup-poll.ts
17
- var log = createLogger({ subsystem: "sandbox:setup" });
18
- var SETUP_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
19
- var SETUP_POLL_INTERVAL_MS = 50;
20
- async function pollForSetupCompletion({
21
- storage,
22
- sandboxId,
23
- setupKey
24
- }) {
25
- const deadline = Date.now() + SETUP_POLL_TIMEOUT_MS;
26
- const done = log.time(
27
- "waiting for setup completion",
28
- { sandboxId, setupKey },
29
- { logOnStart: true }
30
- );
31
- while (Date.now() < deadline) {
32
- const record = await storage.sandbox.get(sandboxId);
33
- if (!(record instanceof Error) && record) {
34
- if (record.setupCompletedAt && record.setupKey === setupKey) {
35
- done();
36
- return;
37
- }
38
- if (!record.setupKey) {
39
- throw new Error(
40
- `Setup was reset for sandbox "${sandboxId}" (setupKey cleared). Will retry on next operation.`
41
- );
42
- }
43
- }
44
- await new Promise((r) => setTimeout(r, SETUP_POLL_INTERVAL_MS));
45
- }
46
- throw new Error(
47
- `Timed out waiting for sandbox setup to complete (sandbox="${sandboxId}")`
48
- );
49
- }
50
- async function markSetupComplete({
51
- storage,
52
- sandboxId,
53
- setupKey
54
- }) {
55
- const result = await storage.sandbox.update({
56
- id: sandboxId,
57
- setupKey,
58
- setupCompletedAt: Date.now()
59
- });
60
- if (result instanceof Error) {
61
- throw result;
62
- }
63
- }
64
- async function resetSetupState({
65
- storage,
66
- sandboxId,
67
- setupKey
68
- }) {
69
- await storage.sandbox.update({
70
- id: sandboxId,
71
- setupKey: null,
72
- setupCompletedAt: null
73
- }).catch((e) => {
74
- log.warn("failed to clear setupKey", { sandboxId, error: String(e) });
75
- });
76
- await storage.setup.delete(setupKey).catch((e) => {
77
- log.warn("failed to delete setup record", { setupKey, error: String(e) });
78
- });
79
- }
80
-
81
- // src/sandbox/write-files.ts
82
- import * as path from "path";
83
- var MAX_RETRIES = 2;
84
- var RETRY_BASE_MS = 500;
85
- async function execChecked(sandbox, opts, errorLabel) {
86
- for (let attempt = 0; ; attempt++) {
87
- const execResult = await sandbox.exec(opts);
88
- if (execResult instanceof Error) {
89
- throw execResult;
90
- }
91
- const result = await execResult.result;
92
- if (result.exitCode === 0) {
93
- return result;
94
- }
95
- const isTransient = result.exitCode === 255 && !result.stderr.trim();
96
- if (isTransient && attempt < MAX_RETRIES) {
97
- await new Promise((r) => setTimeout(r, RETRY_BASE_MS * (attempt + 1)));
98
- continue;
99
- }
100
- throw new Error(
101
- `${errorLabel} with exit code ${result.exitCode}: ${result.stderr}`
102
- );
103
- }
104
- }
105
- async function writeFiles(opts) {
106
- const { sandbox, files, destPath } = opts;
107
- if (files.length === 0) {
108
- return;
109
- }
110
- const filePaths = files.map((file) => path.posix.join(destPath, file.path));
111
- const parentDirs = Array.from(
112
- new Set(filePaths.map((p) => path.posix.dirname(p)))
113
- );
114
- const shellScripts = filePaths.filter((p) => p.endsWith(".sh"));
115
- const mkdirResult = await sandbox.exec({
116
- command: "mkdir",
117
- args: ["-p", ...parentDirs]
118
- });
119
- if (mkdirResult instanceof Error) {
120
- throw mkdirResult;
121
- }
122
- await mkdirResult.result;
123
- const CHUNK_SIZE = 5e4;
124
- for (let i = 0; i < files.length; i++) {
125
- const file = files[i];
126
- const fullPath = filePaths[i];
127
- const base64Content = toBase64(file.content);
128
- if (base64Content.length < CHUNK_SIZE) {
129
- const marker = `EOF_${i}`;
130
- await execChecked(
131
- sandbox,
132
- {
133
- command: "bash",
134
- args: [
135
- "-c",
136
- `base64 -d > ${quote(fullPath)} << '${marker}'
137
- ${base64Content}
138
- ${marker}`
139
- ]
140
- },
141
- "writeFiles failed"
142
- );
143
- } else {
144
- const tempB64 = `/tmp/chunk-${Date.now()}-${i}.b64`;
145
- const clearResult = await sandbox.exec({
146
- command: "bash",
147
- args: ["-c", `> ${quote(tempB64)}`]
148
- });
149
- if (clearResult instanceof Error) {
150
- throw clearResult;
151
- }
152
- await clearResult.result;
153
- for (let offset = 0; offset < base64Content.length; offset += CHUNK_SIZE) {
154
- const chunk = base64Content.slice(offset, offset + CHUNK_SIZE);
155
- const marker = `CHUNK_${offset}`;
156
- await execChecked(
157
- sandbox,
158
- {
159
- command: "bash",
160
- args: [
161
- "-c",
162
- `cat >> ${quote(tempB64)} << '${marker}'
163
- ${chunk}
164
- ${marker}`
165
- ]
166
- },
167
- "writeFiles chunk failed"
168
- );
169
- }
170
- await execChecked(
171
- sandbox,
172
- {
173
- command: "bash",
174
- args: [
175
- "-c",
176
- `base64 -d < ${quote(tempB64)} > ${quote(fullPath)} && rm -f ${quote(tempB64)}`
177
- ]
178
- },
179
- "writeFiles decode failed"
180
- );
181
- }
182
- }
183
- if (shellScripts.length > 0) {
184
- const chmodResult = await sandbox.exec({
185
- command: "chmod",
186
- args: ["+x", ...shellScripts]
187
- });
188
- if (chmodResult instanceof Error) {
189
- throw chmodResult;
190
- }
191
- await chmodResult.result;
192
- }
193
- }
194
- function toBase64(content) {
195
- if (typeof content === "string") {
196
- return Buffer.from(content).toString("base64");
197
- }
198
- return content.toString("base64");
199
- }
200
- function quote(s) {
201
- return `'${s.replace(/'/g, "'\\''")}'`;
202
- }
203
-
204
- // src/sandbox/bindings/docker.ts
205
- var dockerAvailable = null;
206
- async function isDockerSandboxAvailable() {
207
- if (dockerAvailable !== null) {
208
- return dockerAvailable;
209
- }
210
- try {
211
- const result = await execDocker(["version"], { timeoutMs: 5e3 });
212
- dockerAvailable = result.exitCode === 0;
213
- } catch {
214
- dockerAvailable = false;
215
- }
216
- return dockerAvailable;
217
- }
218
- function execDocker(args, opts) {
219
- return new Promise((resolve, reject) => {
220
- const child = spawn("docker", ["sandbox", ...args], {
221
- signal: opts?.signal
222
- });
223
- let stdout = "";
224
- let stderr = "";
225
- child.stdout.on("data", (data) => {
226
- stdout += data.toString();
227
- });
228
- child.stderr.on("data", (data) => {
229
- stderr += data.toString();
230
- });
231
- const timeoutId = opts?.timeoutMs ? setTimeout(() => {
232
- child.kill("SIGTERM");
233
- reject(new Error(`docker sandbox ${args[0]} timed out`));
234
- }, opts.timeoutMs) : void 0;
235
- child.on("error", (err) => {
236
- if (timeoutId) {
237
- clearTimeout(timeoutId);
238
- }
239
- reject(err);
240
- });
241
- child.on("close", (code) => {
242
- if (timeoutId) {
243
- clearTimeout(timeoutId);
244
- }
245
- resolve({ stdout, stderr, exitCode: code ?? 0 });
246
- });
247
- });
248
- }
249
- var ensurePromises = /* @__PURE__ */ new Map();
250
- var activeSandboxes = /* @__PURE__ */ new Set();
251
- var cleanupRegistered = false;
252
- function registerCleanup() {
253
- if (cleanupRegistered) {
254
- return;
255
- }
256
- cleanupRegistered = true;
257
- const cleanup = () => {
258
- for (const name of Array.from(activeSandboxes)) {
259
- try {
260
- execSync(`docker sandbox stop ${name}`, {
261
- timeout: 1e4,
262
- stdio: "pipe"
263
- });
264
- } catch {
265
- }
266
- }
267
- };
268
- process.on("exit", cleanup);
269
- process.on("SIGINT", () => {
270
- cleanup();
271
- process.exit(130);
272
- });
273
- process.on("SIGTERM", () => {
274
- cleanup();
275
- process.exit(143);
276
- });
277
- }
278
- async function ensureSandbox(sandboxId) {
279
- const existing = ensurePromises.get(sandboxId);
280
- if (existing) {
281
- return existing;
282
- }
283
- const promise = (async () => {
284
- const ls = await execDocker(["ls", "-q"], { timeoutMs: 1e4 });
285
- const existingNames = ls.exitCode === 0 ? ls.stdout.split("\n").map((s) => s.trim()).filter(Boolean) : [];
286
- if (existingNames.includes(sandboxId)) {
287
- activeSandboxes.add(sandboxId);
288
- registerCleanup();
289
- return;
290
- }
291
- const workspaceDir = path2.join(
292
- os.tmpdir(),
293
- "agent-docker-sandbox",
294
- sandboxId
295
- );
296
- await fs.mkdir(workspaceDir, { recursive: true });
297
- const create = await execDocker(
298
- ["create", "--name", sandboxId, "shell", workspaceDir],
299
- { timeoutMs: 6e4 }
300
- );
301
- if (create.exitCode !== 0) {
302
- if (create.stderr.includes("already exists")) {
303
- activeSandboxes.add(sandboxId);
304
- registerCleanup();
305
- return;
306
- }
307
- throw new Error(
308
- `Failed to create docker sandbox "${sandboxId}": ${create.stderr}`
309
- );
310
- }
311
- activeSandboxes.add(sandboxId);
312
- registerCleanup();
313
- })();
314
- ensurePromises.set(sandboxId, promise);
315
- try {
316
- await promise;
317
- } catch (e) {
318
- ensurePromises.delete(sandboxId);
319
- throw e;
320
- }
321
- }
322
- var dockerSandbox = ({
323
- sandboxRecord,
324
- storage,
325
- setup,
326
- onRestart
327
- }) => {
328
- const sandboxName = sandboxRecord.id;
329
- const cwd = sandboxRecord.config.cwd ?? "/home/agent/workspace";
330
- const processes = /* @__PURE__ */ new Map();
331
- let startPromise = null;
332
- const sandbox = {
333
- id: sandboxRecord.id,
334
- config: sandboxRecord.config,
335
- cwd,
336
- exec: ({ command, args, cwd: cwd2, env, signal, sudo }) => {
337
- return errore.tryAsync({
338
- try: async () => {
339
- await ensureSandbox(sandboxName);
340
- const commandId = `command_${ulid()}`;
341
- const envFlags = env === void 0 ? [] : Object.entries(env).flatMap(([k, v]) => ["-e", `${k}=${v}`]);
342
- const cwdFlags = cwd2 ? ["-w", cwd2] : [];
343
- const baseCmd = sudo ? ["sudo", command, ...args ?? []] : args ? [command, ...args] : [command];
344
- const fullCmd = baseCmd;
345
- const child = spawn(
346
- "docker",
347
- [
348
- "sandbox",
349
- "exec",
350
- ...envFlags,
351
- ...cwdFlags,
352
- sandboxName,
353
- ...fullCmd
354
- ],
355
- { signal }
356
- );
357
- processes.set(commandId, child);
358
- let stdout = "";
359
- let stderr = "";
360
- const logQueue = [];
361
- let logResolve = null;
362
- let closed = false;
363
- child.stdout.on("data", (data) => {
364
- const str = String(data);
365
- stdout += str;
366
- logQueue.push({ stream: "stdout", data: str });
367
- logResolve?.();
368
- });
369
- child.stderr.on("data", (data) => {
370
- const str = String(data);
371
- stderr += str;
372
- logQueue.push({ stream: "stderr", data: str });
373
- logResolve?.();
374
- });
375
- const result = new Promise((resolve, reject) => {
376
- child.on("error", (err) => {
377
- processes.delete(commandId);
378
- closed = true;
379
- logResolve?.();
380
- reject(err);
381
- });
382
- child.on("close", (code) => {
383
- processes.delete(commandId);
384
- closed = true;
385
- logResolve?.();
386
- resolve({ stdout, stderr, exitCode: code ?? 0 });
387
- });
388
- });
389
- async function* logs() {
390
- while (!closed || logQueue.length > 0) {
391
- const entry = logQueue.shift();
392
- if (entry) {
393
- yield entry;
394
- } else if (!closed) {
395
- await new Promise((resolve) => {
396
- logResolve = resolve;
397
- });
398
- logResolve = null;
399
- }
400
- }
401
- }
402
- return { commandId, logs, result };
403
- },
404
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
405
- });
406
- },
407
- getDomain: (port) => {
408
- return Promise.resolve(`http://localhost:${port}`);
409
- },
410
- kill: async ({ commandId, storage: storage2 }) => {
411
- const child = processes.get(commandId);
412
- if (!child) {
413
- return new SandboxError({
414
- reason: `Command ${commandId} not found or already finished`
415
- });
416
- }
417
- child.kill("SIGTERM");
418
- const cmd = await storage2.command.get(commandId);
419
- if (cmd instanceof Error) {
420
- return new SandboxError({ reason: cmd.message, cause: cmd });
421
- }
422
- if (cmd && cmd.status === "running") {
423
- const result = await storage2.command.set({
424
- ...cmd,
425
- status: "killed"
426
- });
427
- if (result instanceof Error) {
428
- return new SandboxError({ reason: result.message, cause: result });
429
- }
430
- }
431
- },
432
- readFile: async ({ path: filePath }) => {
433
- try {
434
- await ensureSandbox(sandboxName);
435
- const result = await execDocker(
436
- [
437
- "exec",
438
- sandboxName,
439
- "bash",
440
- "-c",
441
- `base64 '${filePath.replace(/'/g, "'\\''")}'`
442
- ],
443
- { timeoutMs: 3e4 }
444
- );
445
- if (result.exitCode !== 0) {
446
- if (result.stderr.includes("No such file") || result.stderr.includes("ENOENT")) {
447
- return null;
448
- }
449
- return new SandboxError({
450
- reason: `readFile failed: ${result.stderr}`
451
- });
452
- }
453
- return Buffer.from(result.stdout.trim(), "base64");
454
- } catch (e) {
455
- return new SandboxError({ reason: String(e), cause: e });
456
- }
457
- },
458
- writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
459
- updateNetworkPolicy: () => Promise.resolve(
460
- new SandboxError({
461
- reason: "updateNetworkPolicy is not yet available for Docker sandboxes"
462
- })
463
- ),
464
- lifecycle: {
465
- start: () => {
466
- if (startPromise) {
467
- return startPromise;
468
- }
469
- startPromise = (async () => {
470
- await ensureSandbox(sandboxName);
471
- if (!setup && sandboxRecord.setupKey) {
472
- await pollForSetupCompletion({
473
- storage,
474
- sandboxId: sandboxRecord.id,
475
- setupKey: sandboxRecord.setupKey
476
- });
477
- }
478
- if (setup) {
479
- const existing = await storage.setup.get(setup.key);
480
- if (existing instanceof Error || !existing) {
481
- try {
482
- await setup.run(sandbox);
483
- await storage.setup.set({
484
- key: setup.key,
485
- snapshotId: null,
486
- createdAt: Date.now(),
487
- lastUsedAt: null,
488
- acquiringLockId: null,
489
- acquiringLockAt: null
490
- });
491
- await markSetupComplete({
492
- storage,
493
- sandboxId: sandboxRecord.id,
494
- setupKey: setup.key
495
- });
496
- } catch (e) {
497
- await resetSetupState({
498
- storage,
499
- sandboxId: sandboxRecord.id,
500
- setupKey: setup.key
501
- });
502
- throw e;
503
- }
504
- }
505
- }
506
- if (onRestart) {
507
- await onRestart(sandbox);
508
- }
509
- return void 0;
510
- })().catch((e) => {
511
- startPromise = null;
512
- throw e;
513
- });
514
- return startPromise;
515
- },
516
- snapshot: () => Promise.resolve(
517
- new SandboxError({
518
- reason: "snapshot is not supported for Docker sandboxes"
519
- })
520
- ),
521
- stop: async () => {
522
- try {
523
- await execDocker(["stop", sandboxName], { timeoutMs: 3e4 });
524
- activeSandboxes.delete(sandboxName);
525
- ensurePromises.delete(sandboxName);
526
- return void 0;
527
- } catch (e) {
528
- return new SandboxError({ reason: String(e), cause: e });
529
- }
530
- },
531
- getStatus: () => Promise.resolve(
532
- new SandboxError({
533
- reason: "getStatus is not supported for Docker sandboxes"
534
- })
535
- ),
536
- getCreatedAt: () => Promise.resolve(
537
- new SandboxError({
538
- reason: "getCreatedAt is not supported for Docker sandboxes"
539
- })
540
- ),
541
- getRemainingTimeout: () => Promise.resolve(
542
- new SandboxError({
543
- reason: "getRemainingTimeout is not supported for Docker sandboxes"
544
- })
545
- )
546
- },
547
- tag: {
548
- list: async () => {
549
- const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
550
- if (sandboxRecord2 instanceof Error) {
551
- return sandboxRecord2;
552
- }
553
- return sandboxRecord2.tags ?? {};
554
- },
555
- get: async (key) => {
556
- const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
557
- if (sandboxRecord2 instanceof Error) {
558
- return sandboxRecord2;
559
- }
560
- return sandboxRecord2.tags?.[key];
561
- },
562
- set: async (key, value) => {
563
- const result = await storage.sandbox.tag.set({
564
- sandboxId: sandbox.id,
565
- tags: { [key]: value }
566
- });
567
- if (result instanceof Error) {
568
- return result;
569
- }
570
- return void 0;
571
- },
572
- setMany: async (tags) => {
573
- const result = await storage.sandbox.tag.set({
574
- sandboxId: sandbox.id,
575
- tags
576
- });
577
- if (result instanceof Error) {
578
- return result;
579
- }
580
- return void 0;
581
- }
582
- }
583
- };
584
- return sandbox;
585
- };
586
-
587
- export {
588
- pollForSetupCompletion,
589
- markSetupComplete,
590
- resetSetupState,
591
- writeFiles,
592
- isDockerSandboxAvailable,
593
- dockerSandbox
594
- };
595
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvZG9ja2VyLnRzIiwgIi4uL3NyYy9zYW5kYm94L3NldHVwLXBvbGwudHMiLCAiLi4vc3JjL3NhbmRib3gvd3JpdGUtZmlsZXMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB0eXBlIHsgQ2hpbGRQcm9jZXNzIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgZXhlY1N5bmMsIHNwYXduIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCAqIGFzIG9zIGZyb20gXCJub2RlOm9zXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCAqIGFzIGVycm9yZSBmcm9tIFwiZXJyb3JlXCI7XG5pbXBvcnQgeyB1bGlkIH0gZnJvbSBcInVsaWRcIjtcbmltcG9ydCB7IFNhbmRib3hFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgVGFnc1NjaGVtYSB9IGZyb20gXCIuLi8uLi9pbmRleFwiO1xuaW1wb3J0IHR5cGUgeyBTYW5kYm94UmVjb3JkLCBTdG9yYWdlIH0gZnJvbSBcIi4uLy4uL3N0b3JhZ2VcIjtcbmltcG9ydCB7XG4gIG1hcmtTZXR1cENvbXBsZXRlLFxuICBwb2xsRm9yU2V0dXBDb21wbGV0aW9uLFxuICByZXNldFNldHVwU3RhdGUsXG59IGZyb20gXCIuLi9zZXR1cC1wb2xsXCI7XG5pbXBvcnQgdHlwZSB7IExvZ0VudHJ5LCBPblJlc3RhcnQsIFNhbmRib3gsIFNhbmRib3hTZXR1cCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgd3JpdGVGaWxlcyB9IGZyb20gXCIuLi93cml0ZS1maWxlc1wiO1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYGRvY2tlciBzYW5kYm94YCBDTEkgaXMgYXZhaWxhYmxlLlxuICogQ2FjaGVzIHRoZSByZXN1bHQgZm9yIHRoZSBsaWZldGltZSBvZiB0aGUgcHJvY2Vzcy5cbiAqL1xubGV0IGRvY2tlckF2YWlsYWJsZTogYm9vbGVhbiB8IG51bGwgPSBudWxsO1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlzRG9ja2VyU2FuZGJveEF2YWlsYWJsZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgaWYgKGRvY2tlckF2YWlsYWJsZSAhPT0gbnVsbCkge1xuICAgIHJldHVybiBkb2NrZXJBdmFpbGFibGU7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBleGVjRG9ja2VyKFtcInZlcnNpb25cIl0sIHsgdGltZW91dE1zOiA1XzAwMCB9KTtcbiAgICBkb2NrZXJBdmFpbGFibGUgPSByZXN1bHQuZXhpdENvZGUgPT09IDA7XG4gIH0gY2F0Y2gge1xuICAgIGRvY2tlckF2YWlsYWJsZSA9IGZhbHNlO1xuICB9XG4gIHJldHVybiBkb2NrZXJBdmFpbGFibGU7XG59XG5cbi8qKlxuICogUnVuIGEgYGRvY2tlciBzYW5kYm94YCBDTEkgY29tbWFuZCBhbmQgcmV0dXJuIGl0cyBvdXRwdXQuXG4gKi9cbmZ1bmN0aW9uIGV4ZWNEb2NrZXIoXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBvcHRzPzogeyB0aW1lb3V0TXM/OiBudW1iZXI7IHNpZ25hbD86IEFib3J0U2lnbmFsIH1cbik6IFByb21pc2U8eyBzdGRvdXQ6IHN0cmluZzsgc3RkZXJyOiBzdHJpbmc7IGV4aXRDb2RlOiBudW1iZXIgfT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oXCJkb2NrZXJcIiwgW1wic2FuZGJveFwiLCAuLi5hcmdzXSwge1xuICAgICAgc2lnbmFsOiBvcHRzPy5zaWduYWwsXG4gICAgfSk7XG5cbiAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICBsZXQgc3RkZXJyID0gXCJcIjtcblxuICAgIGNoaWxkLnN0ZG91dC5vbihcImRhdGFcIiwgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgc3Rkb3V0ICs9IGRhdGEudG9TdHJpbmcoKTtcbiAgICB9KTtcbiAgICBjaGlsZC5zdGRlcnIub24oXCJkYXRhXCIsIChkYXRhOiBCdWZmZXIpID0+IHtcbiAgICAgIHN0ZGVyciArPSBkYXRhLnRvU3RyaW5nKCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCB0aW1lb3V0SWQgPSBvcHRzPy50aW1lb3V0TXNcbiAgICAgID8gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgZG9ja2VyIHNhbmRib3ggJHthcmdzWzBdfSB0aW1lZCBvdXRgKSk7XG4gICAgICAgIH0sIG9wdHMudGltZW91dE1zKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBjaGlsZC5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgIGlmICh0aW1lb3V0SWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICB9XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKGNvZGUpID0+IHtcbiAgICAgIGlmICh0aW1lb3V0SWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICB9XG4gICAgICByZXNvbHZlKHsgc3Rkb3V0LCBzdGRlcnIsIGV4aXRDb2RlOiBjb2RlID8/IDAgfSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFRyYWNrIHdoaWNoIHNhbmRib3hlcyBoYXZlIGJlZW4gdmVyaWZpZWQgdG8gZXhpc3QgaW4gdGhpcyBwcm9jZXNzLlxuICogTWFwcyBzYW5kYm94IG5hbWUgLT4gUHJvbWlzZSBzbyBjb25jdXJyZW50IGNhbGxlcnMgd2FpdCBvbiB0aGUgc2FtZSBjaGVjay5cbiAqL1xuY29uc3QgZW5zdXJlUHJvbWlzZXMgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx2b2lkPj4oKTtcblxuLyoqXG4gKiBTYW5kYm94ZXMgdGhhdCB0aGlzIHByb2Nlc3MgaGFzIHVzZWQuIFN0b3BwZWQgb24gcHJvY2VzcyBleGl0LlxuICovXG5jb25zdCBhY3RpdmVTYW5kYm94ZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxubGV0IGNsZWFudXBSZWdpc3RlcmVkID0gZmFsc2U7XG5mdW5jdGlvbiByZWdpc3RlckNsZWFudXAoKSB7XG4gIGlmIChjbGVhbnVwUmVnaXN0ZXJlZCkge1xuICAgIHJldHVybjtcbiAgfVxuICBjbGVhbnVwUmVnaXN0ZXJlZCA9IHRydWU7XG5cbiAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgQXJyYXkuZnJvbShhY3RpdmVTYW5kYm94ZXMpKSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBleGVjU3luYyBpcyB0aGUgb25seSBvcHRpb24gaW4gZXhpdC9zaWduYWwgaGFuZGxlcnNcbiAgICAgICAgZXhlY1N5bmMoYGRvY2tlciBzYW5kYm94IHN0b3AgJHtuYW1lfWAsIHtcbiAgICAgICAgICB0aW1lb3V0OiAxMF8wMDAsXG4gICAgICAgICAgc3RkaW86IFwicGlwZVwiLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBCZXN0LWVmZm9ydCBcdTIwMTQgc2FuZGJveCBtYXkgYWxyZWFkeSBiZSBzdG9wcGVkXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByb2Nlc3Mub24oXCJleGl0XCIsIGNsZWFudXApO1xuICBwcm9jZXNzLm9uKFwiU0lHSU5UXCIsICgpID0+IHtcbiAgICBjbGVhbnVwKCk7XG4gICAgcHJvY2Vzcy5leGl0KDEzMCk7XG4gIH0pO1xuICBwcm9jZXNzLm9uKFwiU0lHVEVSTVwiLCAoKSA9PiB7XG4gICAgY2xlYW51cCgpO1xuICAgIHByb2Nlc3MuZXhpdCgxNDMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBFbnN1cmUgYSBEb2NrZXIgc2FuZGJveCBleGlzdHMgZm9yIHRoZSBnaXZlbiBJRC5cbiAqIElmIGl0IGFscmVhZHkgZXhpc3RzIChmcm9tIGEgcHJldmlvdXMgcHJvY2VzcyksIHJldXNlcyBpdC5cbiAqIElmIGl0IGRvZXNuJ3QgZXhpc3QsIGNyZWF0ZXMgaXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVuc3VyZVNhbmRib3goc2FuZGJveElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgZXhpc3RpbmcgPSBlbnN1cmVQcm9taXNlcy5nZXQoc2FuZGJveElkKTtcbiAgaWYgKGV4aXN0aW5nKSB7XG4gICAgcmV0dXJuIGV4aXN0aW5nO1xuICB9XG5cbiAgY29uc3QgcHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgLy8gQ2hlY2sgaWYgc2FuZGJveCBhbHJlYWR5IGV4aXN0cyB2aWEgbHMgLXEgKHN1cnZpdmVzIHByb2Nlc3MgcmVzdGFydHMpXG4gICAgY29uc3QgbHMgPSBhd2FpdCBleGVjRG9ja2VyKFtcImxzXCIsIFwiLXFcIl0sIHsgdGltZW91dE1zOiAxMF8wMDAgfSk7XG4gICAgY29uc3QgZXhpc3RpbmdOYW1lcyA9XG4gICAgICBscy5leGl0Q29kZSA9PT0gMFxuICAgICAgICA/IGxzLnN0ZG91dFxuICAgICAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAgICAgICAubWFwKChzKSA9PiBzLnRyaW0oKSlcbiAgICAgICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgOiBbXTtcblxuICAgIGlmIChleGlzdGluZ05hbWVzLmluY2x1ZGVzKHNhbmRib3hJZCkpIHtcbiAgICAgIGFjdGl2ZVNhbmRib3hlcy5hZGQoc2FuZGJveElkKTtcbiAgICAgIHJlZ2lzdGVyQ2xlYW51cCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhIHRlbXAgd29ya3NwYWNlIGRpcmVjdG9yeSBvbiB0aGUgaG9zdCB0byBtb3VudCBpbnRvIHRoZSBzYW5kYm94LlxuICAgIC8vIEVhY2ggc2FuZGJveCBnZXRzIGl0cyBvd24gZGlyZWN0b3J5IGZvciBmaWxlc3lzdGVtIGlzb2xhdGlvbi5cbiAgICBjb25zdCB3b3Jrc3BhY2VEaXIgPSBwYXRoLmpvaW4oXG4gICAgICBvcy50bXBkaXIoKSxcbiAgICAgIFwiYWdlbnQtZG9ja2VyLXNhbmRib3hcIixcbiAgICAgIHNhbmRib3hJZFxuICAgICk7XG4gICAgYXdhaXQgZnMubWtkaXIod29ya3NwYWNlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAgIGNvbnN0IGNyZWF0ZSA9IGF3YWl0IGV4ZWNEb2NrZXIoXG4gICAgICBbXCJjcmVhdGVcIiwgXCItLW5hbWVcIiwgc2FuZGJveElkLCBcInNoZWxsXCIsIHdvcmtzcGFjZURpcl0sXG4gICAgICB7IHRpbWVvdXRNczogNjBfMDAwIH1cbiAgICApO1xuXG4gICAgaWYgKGNyZWF0ZS5leGl0Q29kZSAhPT0gMCkge1xuICAgICAgLy8gQW5vdGhlciBwcm9jZXNzIG1heSBoYXZlIGNyZWF0ZWQgaXQgYmV0d2VlbiBpbnNwZWN0IGFuZCBjcmVhdGVcbiAgICAgIGlmIChjcmVhdGUuc3RkZXJyLmluY2x1ZGVzKFwiYWxyZWFkeSBleGlzdHNcIikpIHtcbiAgICAgICAgYWN0aXZlU2FuZGJveGVzLmFkZChzYW5kYm94SWQpO1xuICAgICAgICByZWdpc3RlckNsZWFudXAoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGNyZWF0ZSBkb2NrZXIgc2FuZGJveCBcIiR7c2FuZGJveElkfVwiOiAke2NyZWF0ZS5zdGRlcnJ9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBhY3RpdmVTYW5kYm94ZXMuYWRkKHNhbmRib3hJZCk7XG4gICAgcmVnaXN0ZXJDbGVhbnVwKCk7XG4gIH0pKCk7XG5cbiAgZW5zdXJlUHJvbWlzZXMuc2V0KHNhbmRib3hJZCwgcHJvbWlzZSk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCBwcm9taXNlO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gQWxsb3cgcmV0cnkgb24gZmFpbHVyZVxuICAgIGVuc3VyZVByb21pc2VzLmRlbGV0ZShzYW5kYm94SWQpO1xuICAgIHRocm93IGU7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRvY2tlclNhbmRib3ggPSA8VFRhZ3MgZXh0ZW5kcyBUYWdzU2NoZW1hID0gVGFnc1NjaGVtYT4oe1xuICBzYW5kYm94UmVjb3JkLFxuICBzdG9yYWdlLFxuICBzZXR1cCxcbiAgb25SZXN0YXJ0LFxufToge1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkICYgeyBjb25maWc6IHsgdHlwZTogXCJkb2NrZXJcIiB9IH07XG4gIHN0b3JhZ2U6IFN0b3JhZ2U7XG4gIHNldHVwPzogU2FuZGJveFNldHVwO1xuICBvblJlc3RhcnQ/OiBPblJlc3RhcnQ7XG59KTogU2FuZGJveDxUVGFncz4gPT4ge1xuICBjb25zdCBzYW5kYm94TmFtZSA9IHNhbmRib3hSZWNvcmQuaWQ7XG4gIGNvbnN0IGN3ZCA9IHNhbmRib3hSZWNvcmQuY29uZmlnLmN3ZCA/PyBcIi9ob21lL2FnZW50L3dvcmtzcGFjZVwiO1xuICBjb25zdCBwcm9jZXNzZXMgPSBuZXcgTWFwPHN0cmluZywgQ2hpbGRQcm9jZXNzPigpO1xuXG4gIGxldCBzdGFydFByb21pc2U6IFByb21pc2U8U2FuZGJveEVycm9yIHwgdW5kZWZpbmVkPiB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0IHNhbmRib3g6IFNhbmRib3g8VFRhZ3M+ID0ge1xuICAgIGlkOiBzYW5kYm94UmVjb3JkLmlkLFxuICAgIGNvbmZpZzogc2FuZGJveFJlY29yZC5jb25maWcsXG4gICAgY3dkLFxuXG4gICAgZXhlYzogKHsgY29tbWFuZCwgYXJncywgY3dkLCBlbnYsIHNpZ25hbCwgc3VkbyB9KSA9PiB7XG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgZW5zdXJlU2FuZGJveChzYW5kYm94TmFtZSk7XG5cbiAgICAgICAgICBjb25zdCBjb21tYW5kSWQgPSBgY29tbWFuZF8ke3VsaWQoKX1gO1xuICAgICAgICAgIGNvbnN0IGVudkZsYWdzID1cbiAgICAgICAgICAgIGVudiA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gW11cbiAgICAgICAgICAgICAgOiBPYmplY3QuZW50cmllcyhlbnYpLmZsYXRNYXAoKFtrLCB2XSkgPT4gW1wiLWVcIiwgYCR7a309JHt2fWBdKTtcbiAgICAgICAgICBjb25zdCBjd2RGbGFncyA9IGN3ZCA/IFtcIi13XCIsIGN3ZF0gOiBbXTtcbiAgICAgICAgICBjb25zdCBiYXNlQ21kID0gc3Vkb1xuICAgICAgICAgICAgPyBbXCJzdWRvXCIsIGNvbW1hbmQsIC4uLihhcmdzID8/IFtdKV1cbiAgICAgICAgICAgIDogYXJnc1xuICAgICAgICAgICAgICA/IFtjb21tYW5kLCAuLi5hcmdzXVxuICAgICAgICAgICAgICA6IFtjb21tYW5kXTtcbiAgICAgICAgICBjb25zdCBmdWxsQ21kID0gYmFzZUNtZDtcblxuICAgICAgICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oXG4gICAgICAgICAgICBcImRvY2tlclwiLFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICBcInNhbmRib3hcIixcbiAgICAgICAgICAgICAgXCJleGVjXCIsXG4gICAgICAgICAgICAgIC4uLmVudkZsYWdzLFxuICAgICAgICAgICAgICAuLi5jd2RGbGFncyxcbiAgICAgICAgICAgICAgc2FuZGJveE5hbWUsXG4gICAgICAgICAgICAgIC4uLmZ1bGxDbWQsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgeyBzaWduYWwgfVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBwcm9jZXNzZXMuc2V0KGNvbW1hbmRJZCwgY2hpbGQpO1xuXG4gICAgICAgICAgbGV0IHN0ZG91dCA9IFwiXCI7XG4gICAgICAgICAgbGV0IHN0ZGVyciA9IFwiXCI7XG4gICAgICAgICAgY29uc3QgbG9nUXVldWU6IExvZ0VudHJ5W10gPSBbXTtcbiAgICAgICAgICBsZXQgbG9nUmVzb2x2ZTogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gICAgICAgICAgbGV0IGNsb3NlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgY2hpbGQuc3Rkb3V0Lm9uKFwiZGF0YVwiLCAoZGF0YTogc3RyaW5nIHwgQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHIgPSBTdHJpbmcoZGF0YSk7XG4gICAgICAgICAgICBzdGRvdXQgKz0gc3RyO1xuICAgICAgICAgICAgbG9nUXVldWUucHVzaCh7IHN0cmVhbTogXCJzdGRvdXRcIiwgZGF0YTogc3RyIH0pO1xuICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjaGlsZC5zdGRlcnIub24oXCJkYXRhXCIsIChkYXRhOiBzdHJpbmcgfCBCdWZmZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0ciA9IFN0cmluZyhkYXRhKTtcbiAgICAgICAgICAgIHN0ZGVyciArPSBzdHI7XG4gICAgICAgICAgICBsb2dRdWV1ZS5wdXNoKHsgc3RyZWFtOiBcInN0ZGVyclwiLCBkYXRhOiBzdHIgfSk7XG4gICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBQcm9taXNlPHtcbiAgICAgICAgICAgIHN0ZG91dDogc3RyaW5nO1xuICAgICAgICAgICAgc3RkZXJyOiBzdHJpbmc7XG4gICAgICAgICAgICBleGl0Q29kZTogbnVtYmVyO1xuICAgICAgICAgIH0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNoaWxkLm9uKFwiZXJyb3JcIiwgKGVycikgPT4ge1xuICAgICAgICAgICAgICBwcm9jZXNzZXMuZGVsZXRlKGNvbW1hbmRJZCk7XG4gICAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7XG4gICAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjaGlsZC5vbihcImNsb3NlXCIsIChjb2RlOiBudW1iZXIgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgIHByb2Nlc3Nlcy5kZWxldGUoY29tbWFuZElkKTtcbiAgICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgICAgIHJlc29sdmUoeyBzdGRvdXQsIHN0ZGVyciwgZXhpdENvZGU6IGNvZGUgPz8gMCB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXN5bmMgZnVuY3Rpb24qIGxvZ3MoKTogQXN5bmNJdGVyYWJsZTxMb2dFbnRyeT4ge1xuICAgICAgICAgICAgd2hpbGUgKCFjbG9zZWQgfHwgbG9nUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRyeSA9IGxvZ1F1ZXVlLnNoaWZ0KCk7XG4gICAgICAgICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgICAgICAgIHlpZWxkIGVudHJ5O1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFjbG9zZWQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgbG9nUmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbG9nUmVzb2x2ZSA9IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4geyBjb21tYW5kSWQsIGxvZ3MsIHJlc3VsdCB9O1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGU6IHVua25vd24pID0+XG4gICAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXREb21haW46IChwb3J0KSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gKTtcbiAgICB9LFxuXG4gICAga2lsbDogYXN5bmMgKHsgY29tbWFuZElkLCBzdG9yYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IGNoaWxkID0gcHJvY2Vzc2VzLmdldChjb21tYW5kSWQpO1xuICAgICAgaWYgKCFjaGlsZCkge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgcmVhc29uOiBgQ29tbWFuZCAke2NvbW1hbmRJZH0gbm90IGZvdW5kIG9yIGFscmVhZHkgZmluaXNoZWRgLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG5cbiAgICAgIGNvbnN0IGNtZCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmIChjbWQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogY21kLm1lc3NhZ2UsIGNhdXNlOiBjbWQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY21kICYmIGNtZC5zdGF0dXMgPT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5zZXQoe1xuICAgICAgICAgIC4uLmNtZCxcbiAgICAgICAgICBzdGF0dXM6IFwia2lsbGVkXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogcmVzdWx0Lm1lc3NhZ2UsIGNhdXNlOiByZXN1bHQgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVhZEZpbGU6IGFzeW5jICh7IHBhdGg6IGZpbGVQYXRoIH0pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGVuc3VyZVNhbmRib3goc2FuZGJveE5hbWUpO1xuXG4gICAgICAgIC8vIFVzZSBkb2NrZXIgc2FuZGJveCBleGVjIHRvIGNhdCB0aGUgZmlsZSBhbmQgZ2V0IGl0cyBiYXNlNjQgY29udGVudFxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBleGVjRG9ja2VyKFxuICAgICAgICAgIFtcbiAgICAgICAgICAgIFwiZXhlY1wiLFxuICAgICAgICAgICAgc2FuZGJveE5hbWUsXG4gICAgICAgICAgICBcImJhc2hcIixcbiAgICAgICAgICAgIFwiLWNcIixcbiAgICAgICAgICAgIGBiYXNlNjQgJyR7ZmlsZVBhdGgucmVwbGFjZSgvJy9nLCBcIidcXFxcJydcIil9J2AsXG4gICAgICAgICAgXSxcbiAgICAgICAgICB7IHRpbWVvdXRNczogMzBfMDAwIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocmVzdWx0LmV4aXRDb2RlICE9PSAwKSB7XG4gICAgICAgICAgLy8gRmlsZSBub3QgZm91bmRcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICByZXN1bHQuc3RkZXJyLmluY2x1ZGVzKFwiTm8gc3VjaCBmaWxlXCIpIHx8XG4gICAgICAgICAgICByZXN1bHQuc3RkZXJyLmluY2x1ZGVzKFwiRU5PRU5UXCIpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgICAgcmVhc29uOiBgcmVhZEZpbGUgZmFpbGVkOiAke3Jlc3VsdC5zdGRlcnJ9YCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShyZXN1bHQuc3Rkb3V0LnRyaW0oKSwgXCJiYXNlNjRcIik7XG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICB3cml0ZUZpbGVzOiAob3B0cykgPT4gd3JpdGVGaWxlcyh7IHNhbmRib3gsIC4uLm9wdHMgfSksXG5cbiAgICB1cGRhdGVOZXR3b3JrUG9saWN5OiAoKSA9PlxuICAgICAgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICBuZXcgU2FuZGJveEVycm9yKHtcbiAgICAgICAgICByZWFzb246XG4gICAgICAgICAgICBcInVwZGF0ZU5ldHdvcmtQb2xpY3kgaXMgbm90IHlldCBhdmFpbGFibGUgZm9yIERvY2tlciBzYW5kYm94ZXNcIixcbiAgICAgICAgfSlcbiAgICAgICksXG5cbiAgICBsaWZlY3ljbGU6IHtcbiAgICAgIHN0YXJ0OiAoKSA9PiB7XG4gICAgICAgIGlmIChzdGFydFByb21pc2UpIHtcbiAgICAgICAgICByZXR1cm4gc3RhcnRQcm9taXNlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0UHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgZW5zdXJlU2FuZGJveChzYW5kYm94TmFtZSk7XG5cbiAgICAgICAgICBpZiAoIXNldHVwICYmIHNhbmRib3hSZWNvcmQuc2V0dXBLZXkpIHtcbiAgICAgICAgICAgIGF3YWl0IHBvbGxGb3JTZXR1cENvbXBsZXRpb24oe1xuICAgICAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3hSZWNvcmQuaWQsXG4gICAgICAgICAgICAgIHNldHVwS2V5OiBzYW5kYm94UmVjb3JkLnNldHVwS2V5LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNldHVwKSB7XG4gICAgICAgICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2V0dXAuZ2V0KHNldHVwLmtleSk7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBFcnJvciB8fCAhZXhpc3RpbmcpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBzZXR1cC5ydW4oc2FuZGJveCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgc3RvcmFnZS5zZXR1cC5zZXQoe1xuICAgICAgICAgICAgICAgICAga2V5OiBzZXR1cC5rZXksXG4gICAgICAgICAgICAgICAgICBzbmFwc2hvdElkOiBudWxsLFxuICAgICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgICAgbGFzdFVzZWRBdDogbnVsbCxcbiAgICAgICAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBhd2FpdCBtYXJrU2V0dXBDb21wbGV0ZSh7XG4gICAgICAgICAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94UmVjb3JkLmlkLFxuICAgICAgICAgICAgICAgICAgc2V0dXBLZXk6IHNldHVwLmtleSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlc2V0U2V0dXBTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94UmVjb3JkLmlkLFxuICAgICAgICAgICAgICAgICAgc2V0dXBLZXk6IHNldHVwLmtleSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG9uUmVzdGFydCkge1xuICAgICAgICAgICAgYXdhaXQgb25SZXN0YXJ0KHNhbmRib3gpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9KSgpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgc3RhcnRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHN0YXJ0UHJvbWlzZTtcbiAgICAgIH0sXG4gICAgICBzbmFwc2hvdDogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgICAgcmVhc29uOiBcInNuYXBzaG90IGlzIG5vdCBzdXBwb3J0ZWQgZm9yIERvY2tlciBzYW5kYm94ZXNcIixcbiAgICAgICAgICB9KVxuICAgICAgICApLFxuICAgICAgc3RvcDogYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGV4ZWNEb2NrZXIoW1wic3RvcFwiLCBzYW5kYm94TmFtZV0sIHsgdGltZW91dE1zOiAzMF8wMDAgfSk7XG4gICAgICAgICAgYWN0aXZlU2FuZGJveGVzLmRlbGV0ZShzYW5kYm94TmFtZSk7XG4gICAgICAgICAgZW5zdXJlUHJvbWlzZXMuZGVsZXRlKHNhbmRib3hOYW1lKTtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBnZXRTdGF0dXM6ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgICBuZXcgU2FuZGJveEVycm9yKHtcbiAgICAgICAgICAgIHJlYXNvbjogXCJnZXRTdGF0dXMgaXMgbm90IHN1cHBvcnRlZCBmb3IgRG9ja2VyIHNhbmRib3hlc1wiLFxuICAgICAgICAgIH0pXG4gICAgICAgICksXG4gICAgICBnZXRDcmVhdGVkQXQ6ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgICBuZXcgU2FuZGJveEVycm9yKHtcbiAgICAgICAgICAgIHJlYXNvbjogXCJnZXRDcmVhdGVkQXQgaXMgbm90IHN1cHBvcnRlZCBmb3IgRG9ja2VyIHNhbmRib3hlc1wiLFxuICAgICAgICAgIH0pXG4gICAgICAgICksXG4gICAgICBnZXRSZW1haW5pbmdUaW1lb3V0OiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgICByZWFzb246IFwiZ2V0UmVtYWluaW5nVGltZW91dCBpcyBub3Qgc3VwcG9ydGVkIGZvciBEb2NrZXIgc2FuZGJveGVzXCIsXG4gICAgICAgICAgfSlcbiAgICAgICAgKSxcbiAgICB9LFxuXG4gICAgdGFnOiB7XG4gICAgICBsaXN0OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3hSZWNvcmQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KHNhbmRib3guaWQpO1xuICAgICAgICBpZiAoc2FuZGJveFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChzYW5kYm94UmVjb3JkLnRhZ3MgPz8ge30pIGFzIFRUYWdzO1xuICAgICAgfSxcbiAgICAgIGdldDogYXN5bmMgKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3hSZWNvcmQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KHNhbmRib3guaWQpO1xuICAgICAgICBpZiAoc2FuZGJveFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQudGFncz8uW2tleSBhcyBzdHJpbmddIGFzXG4gICAgICAgICAgfCBUVGFnc1t0eXBlb2Yga2V5XVxuICAgICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIHNldDogYXN5bmMgKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3gudGFnLnNldCh7XG4gICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LmlkLFxuICAgICAgICAgIHRhZ3M6IHsgW2tleV06IHZhbHVlIH0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICAgc2V0TWFueTogYXN5bmMgKHRhZ3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC50YWcuc2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3guaWQsXG4gICAgICAgICAgdGFnczogdGFncyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gc2FuZGJveDtcbn07XG4iLCAiaW1wb3J0IHR5cGUgeyBTdG9yYWdlIH0gZnJvbSBcIi4uL3N0b3JhZ2VcIjtcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gXCIuLi91dGlscy9sb2dnZXJcIjtcblxuY29uc3QgbG9nID0gY3JlYXRlTG9nZ2VyKHsgc3Vic3lzdGVtOiBcInNhbmRib3g6c2V0dXBcIiB9KTtcblxuY29uc3QgU0VUVVBfUE9MTF9USU1FT1VUX01TID0gNSAqIDYwICogMTAwMDtcbmNvbnN0IFNFVFVQX1BPTExfSU5URVJWQUxfTVMgPSA1MDtcblxuLyoqXG4gKiBQb2xscyBzdG9yYWdlIHVudGlsIHNldHVwQ29tcGxldGVkQXQgaXMgd3JpdHRlbiBmb3IgdGhlIGdpdmVuIHNhbmRib3gra2V5LlxuICogVXNlZCBieSBjb2xkLXN0YXJ0IHdvcmtlcnMgdGhhdCBkb24ndCBoYXZlIHRoZSBzZXR1cCBmdW5jdGlvbiAoaXQncyBub3RcbiAqIHNlcmlhbGl6YWJsZSkgYnV0IG5lZWQgdG8gd2FpdCB1bnRpbCB0aGUgc2Vzc2lvbiB3b3JrZXIgZmluaXNoZXMgc2V0dXBcbiAqIGJlZm9yZSBleGVjdXRpbmcgY29tbWFuZHMuXG4gKlxuICogQWxzbyBkZXRlY3RzIHdoZW4gc2V0dXBLZXkgaXMgY2xlYXJlZCAoc2V0dXAgZmFpbGVkIGFuZCBzdGF0ZSB3YXMgcmVzZXQpLFxuICogdGhyb3dpbmcgaW1tZWRpYXRlbHkgc28gdGhlIGNhbGxlciBjYW4gcmV0cnkgaW5zdGVhZCBvZiBwb2xsaW5nIHRvIHRpbWVvdXQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwb2xsRm9yU2V0dXBDb21wbGV0aW9uKHtcbiAgc3RvcmFnZSxcbiAgc2FuZGJveElkLFxuICBzZXR1cEtleSxcbn06IHtcbiAgc3RvcmFnZTogU3RvcmFnZTtcbiAgc2FuZGJveElkOiBzdHJpbmc7XG4gIHNldHVwS2V5OiBzdHJpbmc7XG59KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIFNFVFVQX1BPTExfVElNRU9VVF9NUztcbiAgY29uc3QgZG9uZSA9IGxvZy50aW1lKFxuICAgIFwid2FpdGluZyBmb3Igc2V0dXAgY29tcGxldGlvblwiLFxuICAgIHsgc2FuZGJveElkLCBzZXR1cEtleSB9LFxuICAgIHsgbG9nT25TdGFydDogdHJ1ZSB9XG4gICk7XG5cbiAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoc2FuZGJveElkKTtcbiAgICBpZiAoIShyZWNvcmQgaW5zdGFuY2VvZiBFcnJvcikgJiYgcmVjb3JkKSB7XG4gICAgICBpZiAocmVjb3JkLnNldHVwQ29tcGxldGVkQXQgJiYgcmVjb3JkLnNldHVwS2V5ID09PSBzZXR1cEtleSkge1xuICAgICAgICBkb25lKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjb3JkLnNldHVwS2V5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgU2V0dXAgd2FzIHJlc2V0IGZvciBzYW5kYm94IFwiJHtzYW5kYm94SWR9XCIgKHNldHVwS2V5IGNsZWFyZWQpLiBXaWxsIHJldHJ5IG9uIG5leHQgb3BlcmF0aW9uLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgU0VUVVBfUE9MTF9JTlRFUlZBTF9NUykpO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgVGltZWQgb3V0IHdhaXRpbmcgZm9yIHNhbmRib3ggc2V0dXAgdG8gY29tcGxldGUgKHNhbmRib3g9XCIke3NhbmRib3hJZH1cIilgXG4gICk7XG59XG5cbi8qKlxuICogV3JpdGVzIHNldHVwQ29tcGxldGVkQXQgdG8gdGhlIHNhbmRib3ggcmVjb3JkIHNvIGNvbGQtc3RhcnQgd29ya2Vyc1xuICogcG9sbGluZyBmb3Igc2V0dXAgY29tcGxldGlvbiBrbm93IGl0J3Mgc2FmZSB0byBwcm9jZWVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWFya1NldHVwQ29tcGxldGUoe1xuICBzdG9yYWdlLFxuICBzYW5kYm94SWQsXG4gIHNldHVwS2V5LFxufToge1xuICBzdG9yYWdlOiBTdG9yYWdlO1xuICBzYW5kYm94SWQ6IHN0cmluZztcbiAgc2V0dXBLZXk6IHN0cmluZztcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LnVwZGF0ZSh7XG4gICAgaWQ6IHNhbmRib3hJZCxcbiAgICBzZXR1cEtleSxcbiAgICBzZXR1cENvbXBsZXRlZEF0OiBEYXRlLm5vdygpLFxuICB9KTtcbiAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgdGhyb3cgcmVzdWx0O1xuICB9XG59XG5cbi8qKlxuICogUmVzZXRzIHNldHVwLXJlbGF0ZWQgc3RhdGUgb24gdGhlIHNhbmRib3ggcmVjb3JkIGFuZCBkZWxldGVzIHRoZSBzZXR1cFxuICogcmVjb3JkLiBDYWxsZWQgd2hlbiBzZXR1cCBmYWlscyBzbyB0aGF0OlxuICogMS4gQ29sZC1zdGFydCB3b3JrZXJzIGRldGVjdCB0aGUgY2xlYXJlZCBzZXR1cEtleSBhbmQgc3RvcCBwb2xsaW5nXG4gKiAyLiBBbnkgd29ya2VyIHJldHJ5aW5nIHdpbGwgc2VlIG5vIHNldHVwIHJlY29yZCBhbmQgcmUtcnVuIHNldHVwXG4gKlxuICogQmVzdC1lZmZvcnQ6IGZhaWx1cmVzIGFyZSBsb2dnZWQgYnV0IG5vdCB0aHJvd24sIHNpbmNlIHdlJ3JlIGFscmVhZHlcbiAqIGluIGFuIGVycm9yIHBhdGggYW5kIHRoZSBvcmlnaW5hbCBlcnJvciBtYXR0ZXJzIG1vcmUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNldFNldHVwU3RhdGUoe1xuICBzdG9yYWdlLFxuICBzYW5kYm94SWQsXG4gIHNldHVwS2V5LFxufToge1xuICBzdG9yYWdlOiBTdG9yYWdlO1xuICBzYW5kYm94SWQ6IHN0cmluZztcbiAgc2V0dXBLZXk6IHN0cmluZztcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgc3RvcmFnZS5zYW5kYm94XG4gICAgLnVwZGF0ZSh7XG4gICAgICBpZDogc2FuZGJveElkLFxuICAgICAgc2V0dXBLZXk6IG51bGwsXG4gICAgICBzZXR1cENvbXBsZXRlZEF0OiBudWxsLFxuICAgIH0pXG4gICAgLmNhdGNoKChlKSA9PiB7XG4gICAgICBsb2cud2FybihcImZhaWxlZCB0byBjbGVhciBzZXR1cEtleVwiLCB7IHNhbmRib3hJZCwgZXJyb3I6IFN0cmluZyhlKSB9KTtcbiAgICB9KTtcblxuICBhd2FpdCBzdG9yYWdlLnNldHVwLmRlbGV0ZShzZXR1cEtleSkuY2F0Y2goKGUpID0+IHtcbiAgICBsb2cud2FybihcImZhaWxlZCB0byBkZWxldGUgc2V0dXAgcmVjb3JkXCIsIHsgc2V0dXBLZXksIGVycm9yOiBTdHJpbmcoZSkgfSk7XG4gIH0pO1xufVxuIiwgImltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBVcGxvYWRhYmxlRmlsZSB9IGZyb20gXCIuLi9za2lsbHMvdHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgU2FuZGJveCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmNvbnN0IE1BWF9SRVRSSUVTID0gMjtcbmNvbnN0IFJFVFJZX0JBU0VfTVMgPSA1MDA7XG5cbi8qKlxuICogRXhlYyBhIGNvbW1hbmQgYW5kIGFzc2VydCBleGl0IGNvZGUgMC4gUmV0cmllcyBvbiB0cmFuc2llbnQgZmFpbHVyZXNcbiAqIChleGl0IGNvZGUgMjU1IHdpdGggZW1wdHkgc3RkZXJyIFx1MjAxNCB0eXBpY2FsbHkgYSBzYW5kYm94IHByb2Nlc3Mga2lsbGVkXG4gKiBiZWZvcmUgaXQgY291bGQgcHJvZHVjZSBvdXRwdXQpLlxuICovXG5hc3luYyBmdW5jdGlvbiBleGVjQ2hlY2tlZChcbiAgc2FuZGJveDogUGljazxTYW5kYm94LCBcImV4ZWNcIj4sXG4gIG9wdHM6IHsgY29tbWFuZDogc3RyaW5nOyBhcmdzPzogc3RyaW5nW10gfSxcbiAgZXJyb3JMYWJlbDogc3RyaW5nXG4pOiBQcm9taXNlPHsgc3Rkb3V0OiBzdHJpbmc7IHN0ZGVycjogc3RyaW5nOyBleGl0Q29kZTogbnVtYmVyIH0+IHtcbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IDsgYXR0ZW1wdCsrKSB7XG4gICAgY29uc3QgZXhlY1Jlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyhvcHRzKTtcbiAgICBpZiAoZXhlY1Jlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBleGVjUmVzdWx0O1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBleGVjUmVzdWx0LnJlc3VsdDtcbiAgICBpZiAocmVzdWx0LmV4aXRDb2RlID09PSAwKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGNvbnN0IGlzVHJhbnNpZW50ID0gcmVzdWx0LmV4aXRDb2RlID09PSAyNTUgJiYgIXJlc3VsdC5zdGRlcnIudHJpbSgpO1xuICAgIGlmIChpc1RyYW5zaWVudCAmJiBhdHRlbXB0IDwgTUFYX1JFVFJJRVMpIHtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIFJFVFJZX0JBU0VfTVMgKiAoYXR0ZW1wdCArIDEpKSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgJHtlcnJvckxhYmVsfSB3aXRoIGV4aXQgY29kZSAke3Jlc3VsdC5leGl0Q29kZX06ICR7cmVzdWx0LnN0ZGVycn1gXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIFdyaXRlcyBmaWxlcyB0byBhIHNhbmRib3ggYXQgdGhlIHNwZWNpZmllZCBkZXN0aW5hdGlvbiBwYXRoLlxuICogU2hlbGwgc2NyaXB0cyAoLnNoIGZpbGVzKSBhcmUgYXV0b21hdGljYWxseSBtYWRlIGV4ZWN1dGFibGUuXG4gKlxuICogRm9yIHNtYWxsIGZpbGVzICg8MTAwS0IgdG90YWwpLCB1c2VzIHNpbmdsZSBleGVjIHdpdGggaGVyZWRvYy5cbiAqIEZvciBsYXJnZSBmaWxlcywgd3JpdGVzIGJhc2U2NCBjaHVua3MgdGhlbiBkZWNvZGVzIHRvIGF2b2lkIEFSR19NQVggbGltaXRzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVGaWxlcyhvcHRzOiB7XG4gIHNhbmRib3g6IFBpY2s8U2FuZGJveCwgXCJleGVjXCI+O1xuICBmaWxlczogVXBsb2FkYWJsZUZpbGVbXTtcbiAgZGVzdFBhdGg6IHN0cmluZztcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBzYW5kYm94LCBmaWxlcywgZGVzdFBhdGggfSA9IG9wdHM7XG5cbiAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGZpbGVQYXRocyA9IGZpbGVzLm1hcCgoZmlsZSkgPT4gcGF0aC5wb3NpeC5qb2luKGRlc3RQYXRoLCBmaWxlLnBhdGgpKTtcbiAgY29uc3QgcGFyZW50RGlycyA9IEFycmF5LmZyb20oXG4gICAgbmV3IFNldChmaWxlUGF0aHMubWFwKChwKSA9PiBwYXRoLnBvc2l4LmRpcm5hbWUocCkpKVxuICApO1xuICBjb25zdCBzaGVsbFNjcmlwdHMgPSBmaWxlUGF0aHMuZmlsdGVyKChwKSA9PiBwLmVuZHNXaXRoKFwiLnNoXCIpKTtcblxuICBjb25zdCBta2RpclJlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgY29tbWFuZDogXCJta2RpclwiLFxuICAgIGFyZ3M6IFtcIi1wXCIsIC4uLnBhcmVudERpcnNdLFxuICB9KTtcbiAgaWYgKG1rZGlyUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICB0aHJvdyBta2RpclJlc3VsdDtcbiAgfVxuICBhd2FpdCBta2RpclJlc3VsdC5yZXN1bHQ7XG5cbiAgY29uc3QgQ0hVTktfU0laRSA9IDUwXzAwMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgZmlsZSA9IGZpbGVzW2ldO1xuICAgIGNvbnN0IGZ1bGxQYXRoID0gZmlsZVBhdGhzW2ldO1xuICAgIGNvbnN0IGJhc2U2NENvbnRlbnQgPSB0b0Jhc2U2NChmaWxlLmNvbnRlbnQpO1xuXG4gICAgaWYgKGJhc2U2NENvbnRlbnQubGVuZ3RoIDwgQ0hVTktfU0laRSkge1xuICAgICAgY29uc3QgbWFya2VyID0gYEVPRl8ke2l9YDtcbiAgICAgIGF3YWl0IGV4ZWNDaGVja2VkKFxuICAgICAgICBzYW5kYm94LFxuICAgICAgICB7XG4gICAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgICAgYXJnczogW1xuICAgICAgICAgICAgXCItY1wiLFxuICAgICAgICAgICAgYGJhc2U2NCAtZCA+ICR7cXVvdGUoZnVsbFBhdGgpfSA8PCAnJHttYXJrZXJ9J1xuJHtiYXNlNjRDb250ZW50fVxuJHttYXJrZXJ9YCxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBcIndyaXRlRmlsZXMgZmFpbGVkXCJcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRlbXBCNjQgPSBgL3RtcC9jaHVuay0ke0RhdGUubm93KCl9LSR7aX0uYjY0YDtcblxuICAgICAgY29uc3QgY2xlYXJSZXN1bHQgPSBhd2FpdCBzYW5kYm94LmV4ZWMoe1xuICAgICAgICBjb21tYW5kOiBcImJhc2hcIixcbiAgICAgICAgYXJnczogW1wiLWNcIiwgYD4gJHtxdW90ZSh0ZW1wQjY0KX1gXSxcbiAgICAgIH0pO1xuICAgICAgaWYgKGNsZWFyUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgY2xlYXJSZXN1bHQ7XG4gICAgICB9XG4gICAgICBhd2FpdCBjbGVhclJlc3VsdC5yZXN1bHQ7XG5cbiAgICAgIGZvciAoXG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgICBvZmZzZXQgPCBiYXNlNjRDb250ZW50Lmxlbmd0aDtcbiAgICAgICAgb2Zmc2V0ICs9IENIVU5LX1NJWkVcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjaHVuayA9IGJhc2U2NENvbnRlbnQuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBDSFVOS19TSVpFKTtcbiAgICAgICAgY29uc3QgbWFya2VyID0gYENIVU5LXyR7b2Zmc2V0fWA7XG4gICAgICAgIGF3YWl0IGV4ZWNDaGVja2VkKFxuICAgICAgICAgIHNhbmRib3gsXG4gICAgICAgICAge1xuICAgICAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgICAgIFwiLWNcIixcbiAgICAgICAgICAgICAgYGNhdCA+PiAke3F1b3RlKHRlbXBCNjQpfSA8PCAnJHttYXJrZXJ9J1xuJHtjaHVua31cbiR7bWFya2VyfWAsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJ3cml0ZUZpbGVzIGNodW5rIGZhaWxlZFwiXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGV4ZWNDaGVja2VkKFxuICAgICAgICBzYW5kYm94LFxuICAgICAgICB7XG4gICAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgICAgYXJnczogW1xuICAgICAgICAgICAgXCItY1wiLFxuICAgICAgICAgICAgYGJhc2U2NCAtZCA8ICR7cXVvdGUodGVtcEI2NCl9ID4gJHtxdW90ZShmdWxsUGF0aCl9ICYmIHJtIC1mICR7cXVvdGUodGVtcEI2NCl9YCxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBcIndyaXRlRmlsZXMgZGVjb2RlIGZhaWxlZFwiXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzaGVsbFNjcmlwdHMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGNobW9kUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgIGNvbW1hbmQ6IFwiY2htb2RcIixcbiAgICAgIGFyZ3M6IFtcIit4XCIsIC4uLnNoZWxsU2NyaXB0c10sXG4gICAgfSk7XG4gICAgaWYgKGNobW9kUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHRocm93IGNobW9kUmVzdWx0O1xuICAgIH1cbiAgICBhd2FpdCBjaG1vZFJlc3VsdC5yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gdG9CYXNlNjQoY29udGVudDogc3RyaW5nIHwgQnVmZmVyKTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiBjb250ZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNvbnRlbnQpLnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xuICB9XG4gIHJldHVybiBjb250ZW50LnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCcke3MucmVwbGFjZSgvJy9nLCBcIidcXFxcJydcIil9J2A7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7OztBQUNBLFNBQVMsVUFBVSxhQUFhO0FBQ2hDLFlBQVksUUFBUTtBQUNwQixZQUFZLFFBQVE7QUFDcEIsWUFBWUEsV0FBVTtBQUN0QixZQUFZLFlBQVk7QUFDeEIsU0FBUyxZQUFZOzs7QUNIckIsSUFBTSxNQUFNLGFBQWEsRUFBRSxXQUFXLGdCQUFnQixDQUFDO0FBRXZELElBQU0sd0JBQXdCLElBQUksS0FBSztBQUN2QyxJQUFNLHlCQUF5QjtBQVcvQixlQUFzQix1QkFBdUI7QUFBQSxFQUMzQztBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0YsR0FJa0I7QUFDaEIsUUFBTSxXQUFXLEtBQUssSUFBSSxJQUFJO0FBQzlCLFFBQU0sT0FBTyxJQUFJO0FBQUEsSUFDZjtBQUFBLElBQ0EsRUFBRSxXQUFXLFNBQVM7QUFBQSxJQUN0QixFQUFFLFlBQVksS0FBSztBQUFBLEVBQ3JCO0FBRUEsU0FBTyxLQUFLLElBQUksSUFBSSxVQUFVO0FBQzVCLFVBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLFNBQVM7QUFDbEQs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WUFBSUEsMEJBQXlCLE9BQU87QUFDbEMsaUJBQU9BO0FBQUEsUUFDVDtBQUNBLGVBQU9BLGVBQWMsT0FBTyxHQUFhO0FBQUEsTUFHM0M7QUFBQSxNQUNBLEtBQUssT0FBTyxLQUFhLFVBQW1CO0FBQzFDLGNBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLElBQUk7QUFBQSxVQUMzQyxXQUFXLFFBQVE7QUFBQSxVQUNuQixNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsTUFBTTtBQUFBLFFBQ3ZCLENBQUM7QUFDRCxZQUFJLGtCQUFrQixPQUFPO0FBQzNCLGlCQUFPO0FBQUEsUUFDVDtBQUNBLGVBQU87QUFBQSxNQUNUO0FBQUEsTUFDQSxTQUFTLE9BQU8sU0FBa0M7QUFDaEQsY0FBTSxTQUFTLE1BQU0sUUFBUSxRQUFRLElBQUksSUFBSTtBQUFBLFVBQzNDLFdBQVcsUUFBUTtBQUFBLFVBQ25CO0FBQUEsUUFDRixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTztBQUFBLFFBQ1Q7QUFDQSxlQUFPO0FBQUEsTUFDVDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsU0FBTztBQUNUOyIsCiAgIm5hbWVzIjogWyJwYXRoIiwgImN3ZCIsICJzdG9yYWdlIiwgInNhbmRib3hSZWNvcmQiXQp9Cg==