experimental-agent 0.0.3 → 0.0.5

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 (38) hide show
  1. package/dist/agent-workflow.d.mts +1 -1
  2. package/dist/agent-workflow.d.ts +1 -1
  3. package/dist/agent-workflow.js +739 -319
  4. package/dist/agent-workflow.mjs +1 -1
  5. package/dist/chunk-2IIWVPZB.mjs +334 -0
  6. package/dist/{chunk-TQRCSTCF.mjs → chunk-CQB6AOJ7.mjs} +2 -2
  7. package/dist/{chunk-UFVWOC5L.mjs → chunk-CRDAPJEY.mjs} +3 -3
  8. package/dist/chunk-GJETDXOU.mjs +361 -0
  9. package/dist/chunk-M2XPBOZD.mjs +1980 -0
  10. package/dist/chunk-ZWP7RQZT.mjs +1239 -0
  11. package/dist/{client-SREKHM6I.mjs → client-5C4CNU6H.mjs} +1 -1
  12. package/dist/{client-BlSrVoPI.d.mts → client-9A8NO6x9.d.mts} +268 -7
  13. package/dist/{client-BlSrVoPI.d.ts → client-9A8NO6x9.d.ts} +268 -7
  14. package/dist/{handler-36FM5H35.mjs → handler-SZDTM3MC.mjs} +1 -1
  15. package/dist/index.d.mts +2 -2
  16. package/dist/index.d.ts +2 -2
  17. package/dist/index.js +875 -341
  18. package/dist/index.mjs +96 -24
  19. package/dist/lifecycle-workflow.d.mts +1 -1
  20. package/dist/lifecycle-workflow.d.ts +1 -1
  21. package/dist/lifecycle-workflow.js +97 -4
  22. package/dist/lifecycle-workflow.mjs +1 -1
  23. package/dist/local-fs-handlers-BZVA3XAU.mjs +277 -0
  24. package/dist/next/loader.js +3 -3
  25. package/dist/next/loader.mjs +1 -1
  26. package/dist/next.js +6 -3
  27. package/dist/next.mjs +5 -2
  28. package/dist/{sandbox-QAPGBVYM.mjs → sandbox-M24R3JLM.mjs} +2 -2
  29. package/dist/{storage-Q376OZH3.mjs → storage-TMZQJ2OQ.mjs} +2 -2
  30. package/dist/vercel-WGN2NY3D.mjs +20 -0
  31. package/dist/{vercel-sdk-VHKEX2GQ.mjs → vercel-sdk-UKBD5JDI.mjs} +2 -2
  32. package/package.json +2 -2
  33. package/dist/chunk-GSRJYPWF.mjs +0 -284
  34. package/dist/chunk-JEE2FQ4O.mjs +0 -844
  35. package/dist/chunk-VBLZWXVE.mjs +0 -318
  36. package/dist/chunk-ZASQBPOI.mjs +0 -2057
  37. package/dist/local-fs-handlers-P4WGW3QY.mjs +0 -235
  38. package/dist/vercel-LLXAHKVJ.mjs +0 -20
@@ -0,0 +1,1239 @@
1
+ import {
2
+ sandboxLifecycleWorkflow
3
+ } from "./chunk-CQB6AOJ7.mjs";
4
+ import {
5
+ SandboxError,
6
+ SandboxNotFoundError
7
+ } from "./chunk-HJGPUEFC.mjs";
8
+
9
+ // src/utils/debug.ts
10
+ var enabled = process.env.AGENT_DEBUG === "1" || process.env.AGENT_DEBUG === "true";
11
+ function debug(...args) {
12
+ if (enabled) {
13
+ console.log(...args);
14
+ }
15
+ }
16
+
17
+ // src/sandbox/bindings/local.ts
18
+ import { spawn } from "node:child_process";
19
+ import * as fs from "node:fs/promises";
20
+ import * as path2 from "node:path";
21
+ import * as errore from "errore";
22
+ import { ulid } from "ulid";
23
+
24
+ // src/sandbox/write-files.ts
25
+ import * as path from "node:path";
26
+ var MAX_RETRIES = 2;
27
+ var RETRY_BASE_MS = 500;
28
+ async function execChecked(sandbox, opts, errorLabel) {
29
+ for (let attempt = 0; ; attempt++) {
30
+ const execResult = await sandbox.exec(opts);
31
+ if (execResult instanceof Error) {
32
+ throw execResult;
33
+ }
34
+ const result = await execResult.result;
35
+ if (result.exitCode === 0) {
36
+ return result;
37
+ }
38
+ const isTransient = result.exitCode === 255 && !result.stderr.trim();
39
+ if (isTransient && attempt < MAX_RETRIES) {
40
+ await new Promise((r) => setTimeout(r, RETRY_BASE_MS * (attempt + 1)));
41
+ continue;
42
+ }
43
+ throw new Error(
44
+ `${errorLabel} with exit code ${result.exitCode}: ${result.stderr}`
45
+ );
46
+ }
47
+ }
48
+ async function writeFiles(opts) {
49
+ const { sandbox, files, destPath } = opts;
50
+ if (files.length === 0) {
51
+ return;
52
+ }
53
+ const filePaths = files.map((file) => path.posix.join(destPath, file.path));
54
+ const parentDirs = Array.from(
55
+ new Set(filePaths.map((p) => path.posix.dirname(p)))
56
+ );
57
+ const shellScripts = filePaths.filter((p) => p.endsWith(".sh"));
58
+ const mkdirResult = await sandbox.exec({
59
+ command: "mkdir",
60
+ args: ["-p", ...parentDirs]
61
+ });
62
+ if (mkdirResult instanceof Error) {
63
+ throw mkdirResult;
64
+ }
65
+ await mkdirResult.result;
66
+ const CHUNK_SIZE = 5e4;
67
+ for (let i = 0; i < files.length; i++) {
68
+ const file = files[i];
69
+ const fullPath = filePaths[i];
70
+ const base64Content = toBase64(file.content);
71
+ if (base64Content.length < CHUNK_SIZE) {
72
+ const marker = `EOF_${i}`;
73
+ await execChecked(
74
+ sandbox,
75
+ {
76
+ command: "bash",
77
+ args: [
78
+ "-c",
79
+ `base64 -d > ${quote(fullPath)} << '${marker}'
80
+ ${base64Content}
81
+ ${marker}`
82
+ ]
83
+ },
84
+ "writeFiles failed"
85
+ );
86
+ } else {
87
+ const tempB64 = `/tmp/chunk-${Date.now()}-${i}.b64`;
88
+ const clearResult = await sandbox.exec({
89
+ command: "bash",
90
+ args: ["-c", `> ${quote(tempB64)}`]
91
+ });
92
+ if (clearResult instanceof Error) {
93
+ throw clearResult;
94
+ }
95
+ await clearResult.result;
96
+ for (let offset = 0; offset < base64Content.length; offset += CHUNK_SIZE) {
97
+ const chunk = base64Content.slice(offset, offset + CHUNK_SIZE);
98
+ const marker = `CHUNK_${offset}`;
99
+ await execChecked(
100
+ sandbox,
101
+ {
102
+ command: "bash",
103
+ args: [
104
+ "-c",
105
+ `cat >> ${quote(tempB64)} << '${marker}'
106
+ ${chunk}
107
+ ${marker}`
108
+ ]
109
+ },
110
+ "writeFiles chunk failed"
111
+ );
112
+ }
113
+ await execChecked(
114
+ sandbox,
115
+ {
116
+ command: "bash",
117
+ args: [
118
+ "-c",
119
+ `base64 -d < ${quote(tempB64)} > ${quote(fullPath)} && rm -f ${quote(tempB64)}`
120
+ ]
121
+ },
122
+ "writeFiles decode failed"
123
+ );
124
+ }
125
+ }
126
+ if (shellScripts.length > 0) {
127
+ const chmodResult = await sandbox.exec({
128
+ command: "chmod",
129
+ args: ["+x", ...shellScripts]
130
+ });
131
+ if (chmodResult instanceof Error) {
132
+ throw chmodResult;
133
+ }
134
+ await chmodResult.result;
135
+ }
136
+ }
137
+ function toBase64(content) {
138
+ if (typeof content === "string") {
139
+ return Buffer.from(content).toString("base64");
140
+ }
141
+ return content.toString("base64");
142
+ }
143
+ function quote(s) {
144
+ return `'${s.replace(/'/g, "'\\''")}'`;
145
+ }
146
+
147
+ // src/sandbox/bindings/local.ts
148
+ var localSandbox = ({
149
+ sandboxRecord,
150
+ storage,
151
+ setup,
152
+ onRestart
153
+ }) => {
154
+ const config = sandboxRecord.config;
155
+ const basePath = config.path ?? process.cwd();
156
+ const processes = /* @__PURE__ */ new Map();
157
+ const sandbox = {
158
+ id: sandboxRecord.id,
159
+ config: sandboxRecord.config,
160
+ exec: ({ command, args, signal }) => {
161
+ return errore.tryAsync({
162
+ try: () => {
163
+ const commandId = `command_${ulid()}`;
164
+ const child = spawn(command, args, {
165
+ cwd: basePath,
166
+ signal
167
+ });
168
+ processes.set(commandId, child);
169
+ let stdout = "";
170
+ let stderr = "";
171
+ const logQueue = [];
172
+ let logResolve = null;
173
+ let closed = false;
174
+ child.stdout.on("data", (data) => {
175
+ const str = String(data);
176
+ stdout += str;
177
+ logQueue.push({ stream: "stdout", data: str });
178
+ logResolve?.();
179
+ });
180
+ child.stderr.on("data", (data) => {
181
+ const str = String(data);
182
+ stderr += str;
183
+ logQueue.push({ stream: "stderr", data: str });
184
+ logResolve?.();
185
+ });
186
+ const result2 = new Promise((resolve, reject) => {
187
+ child.on("error", (err) => {
188
+ processes.delete(commandId);
189
+ closed = true;
190
+ logResolve?.();
191
+ reject(err);
192
+ });
193
+ child.on("close", (code) => {
194
+ processes.delete(commandId);
195
+ closed = true;
196
+ logResolve?.();
197
+ resolve({ stdout, stderr, exitCode: code ?? 0 });
198
+ });
199
+ });
200
+ async function* logs() {
201
+ while (!closed || logQueue.length > 0) {
202
+ const entry = logQueue.shift();
203
+ if (entry) {
204
+ yield entry;
205
+ } else if (!closed) {
206
+ await new Promise((resolve) => {
207
+ logResolve = resolve;
208
+ });
209
+ logResolve = null;
210
+ }
211
+ }
212
+ }
213
+ return Promise.resolve({ commandId, logs, result: result2 });
214
+ },
215
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
216
+ });
217
+ },
218
+ getDomain: (port) => {
219
+ return Promise.resolve(`http://localhost:${port}`);
220
+ },
221
+ kill: async ({ commandId, storage: storage2 }) => {
222
+ const child = processes.get(commandId);
223
+ if (!child) {
224
+ return new SandboxError({
225
+ reason: `Command ${commandId} not found or already finished`
226
+ });
227
+ }
228
+ child.kill("SIGTERM");
229
+ const cmd = await storage2.command.get(commandId);
230
+ if (cmd instanceof Error) {
231
+ return new SandboxError({ reason: cmd.message, cause: cmd });
232
+ }
233
+ if (cmd && cmd.status === "running") {
234
+ const result2 = await storage2.command.set({
235
+ ...cmd,
236
+ status: "killed"
237
+ });
238
+ if (result2 instanceof Error) {
239
+ return new SandboxError({ reason: result2.message, cause: result2 });
240
+ }
241
+ }
242
+ },
243
+ readFile: async ({ path: filePath }) => {
244
+ const fullPath = path2.join(basePath, filePath);
245
+ try {
246
+ return await fs.readFile(fullPath);
247
+ } catch (e) {
248
+ if (e instanceof Error && "code" in e && e.code === "ENOENT") {
249
+ return null;
250
+ }
251
+ return new SandboxError({ reason: String(e), cause: e });
252
+ }
253
+ },
254
+ writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
255
+ updateNetworkPolicy: () => Promise.resolve(
256
+ new SandboxError({
257
+ reason: "updateNetworkPolicy is only available for Vercel sandboxes"
258
+ })
259
+ ),
260
+ tag: {
261
+ list: async () => {
262
+ const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
263
+ if (sandboxRecord2 instanceof Error) {
264
+ return sandboxRecord2;
265
+ }
266
+ return sandboxRecord2.tags ?? {};
267
+ },
268
+ get: async (key) => {
269
+ const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
270
+ if (sandboxRecord2 instanceof Error) {
271
+ return sandboxRecord2;
272
+ }
273
+ return sandboxRecord2.tags?.[key];
274
+ },
275
+ set: async (key, value) => {
276
+ const result2 = await storage.sandbox.tag.set({
277
+ sandboxId: sandbox.id,
278
+ tags: { [key]: value }
279
+ });
280
+ if (result2 instanceof Error) {
281
+ return result2;
282
+ }
283
+ return void 0;
284
+ },
285
+ setMany: async (tags) => {
286
+ const result2 = await storage.sandbox.tag.set({
287
+ sandboxId: sandbox.id,
288
+ tags
289
+ });
290
+ if (result2 instanceof Error) {
291
+ return result2;
292
+ }
293
+ return void 0;
294
+ }
295
+ }
296
+ };
297
+ const result = sandbox;
298
+ if (setup || onRestart) {
299
+ result._onReady = (async () => {
300
+ let needsSetup = !!setup;
301
+ if (setup) {
302
+ const existing = await storage.setup.get(setup.key);
303
+ if (!(existing instanceof Error) && existing) {
304
+ debug(
305
+ `[sandbox:setup] setup already complete for key "${setup.key}", skipping`
306
+ );
307
+ needsSetup = false;
308
+ }
309
+ }
310
+ if (needsSetup && setup) {
311
+ debug(`[sandbox:setup] running setup.run (local, key="${setup.key}")`);
312
+ await setup.run(sandbox);
313
+ await storage.setup.set({
314
+ key: setup.key,
315
+ snapshotId: null,
316
+ createdAt: Date.now(),
317
+ lastUsedAt: null,
318
+ acquiringLockId: null,
319
+ acquiringLockAt: null
320
+ });
321
+ debug(
322
+ `[sandbox:setup] setup complete, stored record (key="${setup.key}")`
323
+ );
324
+ }
325
+ if (onRestart) {
326
+ debug("[sandbox:setup] running onRestart (local)");
327
+ await onRestart(sandbox);
328
+ }
329
+ })();
330
+ }
331
+ return result;
332
+ };
333
+
334
+ // src/sandbox/bindings/vercel.ts
335
+ import * as path3 from "node:path";
336
+ import * as errore2 from "errore";
337
+ import { Sandbox as VercelSandboxSDK } from "@vercel/sandbox";
338
+ import { start } from "workflow/api";
339
+ var VERCEL_MAX_TIMEOUT_MS = 5 * 60 * 60 * 1e3;
340
+ var LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
341
+ var LOCK_POLL_INTERVAL_MS = 200;
342
+ var getTestCredentials = () => process.env.NODE_ENV === "test" ? {
343
+ token: process.env.TEST_VERCEL_TOKEN,
344
+ teamId: process.env.TEST_VERCEL_TEAM_ID,
345
+ projectId: process.env.TEST_VERCEL_PROJECT_ID
346
+ } : {};
347
+ var createPromises = /* @__PURE__ */ new Map();
348
+ var ACTIVITY_THROTTLE_MS = 1e4;
349
+ var lastActivitySent = /* @__PURE__ */ new Map();
350
+ var DEFAULT_VCPUS = 2;
351
+ function isSandboxGoneError(e) {
352
+ if (!(e instanceof Error)) {
353
+ return false;
354
+ }
355
+ const errorWithResponse = e;
356
+ const errorWithCause = e;
357
+ const status = errorWithResponse.response?.status ?? errorWithCause.cause?.response?.status;
358
+ if (status === 410 || status === 422) {
359
+ return true;
360
+ }
361
+ const message = e.message || String(e);
362
+ if (message.includes("Expected a stream of command data") || message.includes("Expected a stream of logs")) {
363
+ return true;
364
+ }
365
+ return false;
366
+ }
367
+ var vercelSandbox = ({
368
+ sandboxRecord,
369
+ storageConfig,
370
+ enableLifecycleWorkflow,
371
+ storage,
372
+ rpc,
373
+ setup,
374
+ onRestart
375
+ }) => {
376
+ const { id, config } = sandboxRecord;
377
+ const vcpus = config.resources?.vcpus ?? DEFAULT_VCPUS;
378
+ const ports = config.ports;
379
+ const networkPolicy = config.networkPolicy;
380
+ const initialVercel = sandboxRecord.providerMetadata?.provider === "vercel" ? sandboxRecord.providerMetadata : null;
381
+ let sandboxPromise = null;
382
+ let recoveredFromStale = false;
383
+ let createdFromSnapshot = false;
384
+ let needsSetupRun = false;
385
+ const HOME_DIR = "/home/vercel-sandbox";
386
+ async function pollForSandboxId() {
387
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
388
+ while (Date.now() < deadline) {
389
+ await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
390
+ const record = await storage.sandbox.get(id);
391
+ if (record instanceof Error) {
392
+ return new SandboxError({ reason: record.message, cause: record });
393
+ }
394
+ const vercelSandboxId = record?.providerMetadata?.provider === "vercel" ? record.providerMetadata.sandboxId : null;
395
+ if (vercelSandboxId) {
396
+ return vercelSandboxId;
397
+ }
398
+ if (!record?.acquiringLockAt) {
399
+ const finalCheck = await storage.sandbox.get(id);
400
+ if (finalCheck instanceof Error) {
401
+ return new SandboxError({
402
+ reason: finalCheck.message,
403
+ cause: finalCheck
404
+ });
405
+ }
406
+ const finalVercelSandboxId = finalCheck?.providerMetadata?.provider === "vercel" ? finalCheck.providerMetadata.sandboxId : null;
407
+ if (finalVercelSandboxId) {
408
+ return finalVercelSandboxId;
409
+ }
410
+ return doGetOrCreateSandboxId();
411
+ }
412
+ }
413
+ return new SandboxError({
414
+ reason: "Timed out waiting for sandbox creation by another process"
415
+ });
416
+ }
417
+ async function startLifecycleWorkflow(vercelSandboxId) {
418
+ if (!enableLifecycleWorkflow) {
419
+ return;
420
+ }
421
+ const lifecycleInput = {
422
+ id,
423
+ vercelSandboxId,
424
+ storageConfig,
425
+ rpc
426
+ };
427
+ await start(sandboxLifecycleWorkflow, [{ input: lifecycleInput }]).catch(
428
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: intentionally ignored - workflow start is fire-and-forget
429
+ () => {
430
+ }
431
+ );
432
+ }
433
+ async function createSandboxFromSnapshot(snapshotId) {
434
+ return await errore2.tryAsync({
435
+ try: async () => {
436
+ const sandbox2 = await VercelSandboxSDK.create({
437
+ source: { type: "snapshot", snapshotId },
438
+ resources: { vcpus },
439
+ timeout: VERCEL_MAX_TIMEOUT_MS,
440
+ ports,
441
+ networkPolicy,
442
+ ...getTestCredentials()
443
+ });
444
+ const now = Date.now();
445
+ await storage.sandbox.set({
446
+ id,
447
+ config,
448
+ tags: sandboxRecord.tags,
449
+ createdAt: now,
450
+ lastActivityAt: now,
451
+ acquiringLockId: null,
452
+ acquiringLockAt: null,
453
+ providerMetadata: {
454
+ provider: "vercel",
455
+ sandboxId: sandbox2.sandboxId,
456
+ snapshotId
457
+ }
458
+ });
459
+ await startLifecycleWorkflow(sandbox2.sandboxId);
460
+ return sandbox2.sandboxId;
461
+ },
462
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
463
+ });
464
+ }
465
+ async function createFreshSandbox() {
466
+ return await errore2.tryAsync({
467
+ try: async () => {
468
+ const sandbox2 = await VercelSandboxSDK.create({
469
+ resources: { vcpus },
470
+ timeout: VERCEL_MAX_TIMEOUT_MS,
471
+ ports,
472
+ networkPolicy,
473
+ ...getTestCredentials()
474
+ });
475
+ const now = Date.now();
476
+ await storage.sandbox.set({
477
+ id,
478
+ config,
479
+ tags: sandboxRecord.tags,
480
+ createdAt: now,
481
+ lastActivityAt: now,
482
+ acquiringLockId: null,
483
+ acquiringLockAt: null,
484
+ providerMetadata: {
485
+ provider: "vercel",
486
+ sandboxId: sandbox2.sandboxId,
487
+ snapshotId: null
488
+ }
489
+ });
490
+ await startLifecycleWorkflow(sandbox2.sandboxId);
491
+ return sandbox2.sandboxId;
492
+ },
493
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
494
+ });
495
+ }
496
+ function execOnInstance(instance, {
497
+ command,
498
+ args,
499
+ signal
500
+ }) {
501
+ return errore2.tryAsync({
502
+ try: async () => {
503
+ const output = await instance.runCommand({
504
+ cwd: HOME_DIR,
505
+ args,
506
+ cmd: command,
507
+ signal,
508
+ detached: true
509
+ });
510
+ let stdout = "";
511
+ let stderr = "";
512
+ const logBuffer = [];
513
+ const state = {
514
+ resolve: null,
515
+ consumed: false
516
+ };
517
+ const consumeLogs = (async () => {
518
+ try {
519
+ for await (const log of output.logs()) {
520
+ const entry = log.stream === "stdout" ? { stream: "stdout", data: log.data } : { stream: "stderr", data: log.data };
521
+ if (log.stream === "stdout") {
522
+ stdout += log.data;
523
+ } else {
524
+ stderr += log.data;
525
+ }
526
+ logBuffer.push(entry);
527
+ state.resolve?.();
528
+ }
529
+ } catch {
530
+ }
531
+ state.consumed = true;
532
+ state.resolve?.();
533
+ })();
534
+ async function* logs() {
535
+ let index = 0;
536
+ while (!state.consumed || index < logBuffer.length) {
537
+ if (index < logBuffer.length) {
538
+ yield logBuffer[index++];
539
+ } else {
540
+ await new Promise((resolve) => {
541
+ state.resolve = resolve;
542
+ });
543
+ state.resolve = null;
544
+ }
545
+ }
546
+ }
547
+ const result = consumeLogs.then(async () => {
548
+ try {
549
+ const finished = await output.wait();
550
+ return {
551
+ stdout,
552
+ stderr,
553
+ exitCode: finished.exitCode
554
+ };
555
+ } catch (e) {
556
+ if (isSandboxGoneError(e)) {
557
+ return { stdout, stderr, exitCode: 1 };
558
+ }
559
+ throw e;
560
+ }
561
+ });
562
+ return { commandId: output.cmdId, logs, result };
563
+ },
564
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
565
+ });
566
+ }
567
+ function readFileOnInstance(instance, { path: path4 }) {
568
+ return errore2.tryAsync({
569
+ try: () => instance.readFileToBuffer({ path: path4, cwd: HOME_DIR }),
570
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
571
+ });
572
+ }
573
+ async function writeFilesOnInstance(instance, opts) {
574
+ const { files, destPath } = opts;
575
+ if (files.length === 0) {
576
+ return;
577
+ }
578
+ const nativeFiles = files.map((file) => {
579
+ const filePath = path3.posix.join(destPath, file.path);
580
+ const absolutePath = path3.posix.isAbsolute(filePath) ? filePath : path3.posix.join(HOME_DIR, filePath);
581
+ return {
582
+ path: absolutePath,
583
+ content: typeof file.content === "string" ? Buffer.from(file.content) : file.content
584
+ };
585
+ });
586
+ await instance.writeFiles(nativeFiles);
587
+ const shellScripts = nativeFiles.filter((f) => f.path.endsWith(".sh"));
588
+ if (shellScripts.length > 0) {
589
+ const chmodResult = await execOnInstance(instance, {
590
+ command: "chmod",
591
+ args: ["+x", ...shellScripts.map((f) => f.path)]
592
+ });
593
+ if (chmodResult instanceof Error) {
594
+ throw chmodResult;
595
+ }
596
+ await chmodResult.result;
597
+ }
598
+ }
599
+ function createTempSandbox(instance) {
600
+ const tempSandbox = {
601
+ id: `__setup_temp_${Date.now()}`,
602
+ config,
603
+ exec: (opts) => execOnInstance(instance, opts),
604
+ readFile: (opts) => readFileOnInstance(instance, opts),
605
+ getDomain: () => Promise.resolve(
606
+ new SandboxError({ reason: "not available during setup" })
607
+ ),
608
+ kill: () => Promise.resolve(
609
+ new SandboxError({ reason: "not available during setup" })
610
+ ),
611
+ writeFiles: (opts) => writeFilesOnInstance(instance, opts),
612
+ updateNetworkPolicy: (policy) => errore2.tryAsync({
613
+ try: () => instance.updateNetworkPolicy(policy),
614
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
615
+ }),
616
+ tag: {
617
+ list: async () => ({}),
618
+ get: async () => void 0,
619
+ set: async () => void 0,
620
+ setMany: async () => void 0
621
+ }
622
+ };
623
+ return tempSandbox;
624
+ }
625
+ async function pollForSetupSnapshot(key) {
626
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
627
+ while (Date.now() < deadline) {
628
+ await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
629
+ const record = await storage.setup.get(key);
630
+ if (record instanceof Error) {
631
+ return null;
632
+ }
633
+ if (record?.snapshotId) {
634
+ return record.snapshotId;
635
+ }
636
+ if (!record?.acquiringLockId) {
637
+ return null;
638
+ }
639
+ }
640
+ return null;
641
+ }
642
+ async function createSetupSnapshot(opts) {
643
+ if (!setup) {
644
+ return;
645
+ }
646
+ const setupKey = setup.key;
647
+ if (!opts?.force) {
648
+ const existing = await storage.setup.get(setupKey);
649
+ if (!(existing instanceof Error) && existing?.snapshotId) {
650
+ return;
651
+ }
652
+ }
653
+ debug(`[sandbox:setup] acquiring lock for setup key "${setupKey}"`);
654
+ const lockId = crypto.randomUUID();
655
+ const locked = await storage.setup.acquireLock(
656
+ setupKey,
657
+ lockId,
658
+ LOCK_TIMEOUT_MS
659
+ );
660
+ if (locked instanceof Error || !locked) {
661
+ debug(
662
+ `[sandbox:setup] lock not acquired for key "${setupKey}" (another process holds it)`
663
+ );
664
+ return;
665
+ }
666
+ if (!opts?.force && locked.snapshotId) {
667
+ debug(
668
+ `[sandbox:setup] snapshot already exists after lock for key "${setupKey}", skipping`
669
+ );
670
+ return;
671
+ }
672
+ let tempInstance = null;
673
+ try {
674
+ debug(
675
+ `[sandbox:setup] creating temp sandbox for snapshot (key="${setupKey}")`
676
+ );
677
+ tempInstance = await VercelSandboxSDK.create({
678
+ resources: { vcpus },
679
+ timeout: VERCEL_MAX_TIMEOUT_MS,
680
+ ports,
681
+ networkPolicy,
682
+ ...getTestCredentials()
683
+ });
684
+ const tempSandbox = createTempSandbox(
685
+ tempInstance
686
+ );
687
+ await setup.run(tempSandbox);
688
+ debug(
689
+ `[sandbox:setup] setup.run complete, snapshotting (key="${setupKey}")`
690
+ );
691
+ const snapshot = await tempInstance.snapshot();
692
+ await storage.setup.set({
693
+ key: setupKey,
694
+ snapshotId: snapshot.snapshotId,
695
+ createdAt: locked.createdAt,
696
+ lastUsedAt: null,
697
+ acquiringLockId: null,
698
+ acquiringLockAt: null
699
+ });
700
+ debug(
701
+ `[sandbox:setup] snapshot stored: ${snapshot.snapshotId} (key="${setupKey}")`
702
+ );
703
+ await tempInstance.stop().catch(() => void 0);
704
+ } catch (e) {
705
+ console.error(
706
+ `[sandbox:setup] failed to create setup snapshot (key="${setupKey}"):`,
707
+ e
708
+ );
709
+ if (tempInstance) {
710
+ await tempInstance.stop().catch(() => void 0);
711
+ }
712
+ await storage.setup.set({
713
+ key: setupKey,
714
+ snapshotId: null,
715
+ createdAt: locked.createdAt,
716
+ lastUsedAt: null,
717
+ acquiringLockId: null,
718
+ acquiringLockAt: null
719
+ }).catch(() => void 0);
720
+ }
721
+ }
722
+ async function doGetOrCreateSandboxId() {
723
+ if (initialVercel?.sandboxId && !recoveredFromStale) {
724
+ return initialVercel.sandboxId;
725
+ }
726
+ const existing = await storage.sandbox.get(id);
727
+ if (existing instanceof Error) {
728
+ if (existing instanceof SandboxNotFoundError) {
729
+ } else {
730
+ return new SandboxError({ reason: existing.message, cause: existing });
731
+ }
732
+ }
733
+ const existingRecord = existing instanceof SandboxNotFoundError ? null : existing;
734
+ const existingVercel = existingRecord?.providerMetadata?.provider === "vercel" ? existingRecord.providerMetadata : null;
735
+ if (existingVercel?.sandboxId) {
736
+ return existingVercel.sandboxId;
737
+ }
738
+ const hasActiveLock = existingRecord?.acquiringLockId && existingRecord.acquiringLockAt && Date.now() - existingRecord.acquiringLockAt < LOCK_TIMEOUT_MS;
739
+ if (hasActiveLock) {
740
+ return pollForSandboxId();
741
+ }
742
+ const lockId = crypto.randomUUID();
743
+ const now = Date.now();
744
+ const locked = await storage.sandbox.acquireLock(
745
+ {
746
+ id,
747
+ config,
748
+ tags: existingRecord?.tags ?? sandboxRecord.tags,
749
+ createdAt: existingRecord?.createdAt ?? sandboxRecord.createdAt,
750
+ lastActivityAt: existingRecord?.lastActivityAt ?? sandboxRecord.lastActivityAt,
751
+ acquiringLockId: lockId,
752
+ acquiringLockAt: now,
753
+ providerMetadata: {
754
+ provider: "vercel",
755
+ sandboxId: null,
756
+ snapshotId: existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? null
757
+ }
758
+ },
759
+ LOCK_TIMEOUT_MS
760
+ );
761
+ if (locked instanceof Error) {
762
+ return new SandboxError({ reason: locked.message, cause: locked });
763
+ }
764
+ if (!locked) {
765
+ return pollForSandboxId();
766
+ }
767
+ const lockedRecord = locked;
768
+ async function releaseSandboxLock() {
769
+ await storage.sandbox.set({
770
+ ...lockedRecord,
771
+ acquiringLockId: null,
772
+ acquiringLockAt: null
773
+ }).catch(() => void 0);
774
+ }
775
+ const lockedVercel = lockedRecord.providerMetadata?.provider === "vercel" ? lockedRecord.providerMetadata : null;
776
+ if (lockedVercel?.sandboxId) {
777
+ await releaseSandboxLock();
778
+ return lockedVercel.sandboxId;
779
+ }
780
+ const snapshotId = lockedVercel?.snapshotId ?? initialVercel?.snapshotId ?? config.lifecycle?.snapshotId;
781
+ if (snapshotId) {
782
+ const result = await createSandboxFromSnapshot(snapshotId);
783
+ if (!(result instanceof Error)) {
784
+ createdFromSnapshot = true;
785
+ return result;
786
+ }
787
+ }
788
+ if (setup) {
789
+ let forceRecreateSnapshot = false;
790
+ const setupRecord = await storage.setup.get(setup.key);
791
+ if (!(setupRecord instanceof Error) && setupRecord) {
792
+ if (setupRecord.snapshotId) {
793
+ debug(
794
+ `[sandbox:setup] found setup snapshot ${setupRecord.snapshotId} for key "${setup.key}"`
795
+ );
796
+ const result = await createSandboxFromSnapshot(
797
+ setupRecord.snapshotId
798
+ );
799
+ if (!(result instanceof Error)) {
800
+ createdFromSnapshot = true;
801
+ storage.setup.set({
802
+ ...setupRecord,
803
+ lastUsedAt: Date.now()
804
+ }).catch(() => void 0);
805
+ return result;
806
+ }
807
+ debug(
808
+ `[sandbox:setup] snapshot ${setupRecord.snapshotId} failed (expired?), will recreate`
809
+ );
810
+ forceRecreateSnapshot = true;
811
+ } else if (setupRecord.acquiringLockId && setupRecord.acquiringLockAt && Date.now() - setupRecord.acquiringLockAt < LOCK_TIMEOUT_MS) {
812
+ debug(
813
+ `[sandbox:setup] snapshot in progress for key "${setup.key}", waiting...`
814
+ );
815
+ const snapshotId2 = await pollForSetupSnapshot(setup.key);
816
+ if (snapshotId2) {
817
+ debug(
818
+ `[sandbox:setup] snapshot ready: ${snapshotId2} for key "${setup.key}"`
819
+ );
820
+ const result = await createSandboxFromSnapshot(snapshotId2);
821
+ if (!(result instanceof Error)) {
822
+ createdFromSnapshot = true;
823
+ return result;
824
+ }
825
+ }
826
+ }
827
+ }
828
+ debug(
829
+ `[sandbox:setup] no snapshot for key "${setup.key}", will run setup on this sandbox`
830
+ );
831
+ needsSetupRun = true;
832
+ createSetupSnapshot({ force: forceRecreateSnapshot }).catch((e) => {
833
+ console.error(
834
+ "[sandbox:setup] failed to create background snapshot:",
835
+ e
836
+ );
837
+ });
838
+ }
839
+ const freshResult = await createFreshSandbox();
840
+ if (freshResult instanceof Error) {
841
+ await releaseSandboxLock();
842
+ }
843
+ return freshResult;
844
+ }
845
+ function getOrCreateSandboxId() {
846
+ const cached = createPromises.get(id);
847
+ if (cached) {
848
+ return cached;
849
+ }
850
+ const promise = doGetOrCreateSandboxId().finally(() => {
851
+ createPromises.delete(id);
852
+ });
853
+ createPromises.set(id, promise);
854
+ return promise;
855
+ }
856
+ async function doGetSandbox() {
857
+ const vercelSandboxId = await getOrCreateSandboxId();
858
+ if (vercelSandboxId instanceof Error) {
859
+ return vercelSandboxId;
860
+ }
861
+ return errore2.tryAsync({
862
+ try: () => VercelSandboxSDK.get({
863
+ sandboxId: vercelSandboxId,
864
+ ...getTestCredentials()
865
+ }),
866
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
867
+ });
868
+ }
869
+ function getSandbox2() {
870
+ if (!sandboxPromise) {
871
+ sandboxPromise = doGetSandbox();
872
+ }
873
+ return sandboxPromise;
874
+ }
875
+ async function recoverFromStaleSandbox() {
876
+ sandboxPromise = null;
877
+ recoveredFromStale = true;
878
+ const existing = await storage.sandbox.get(id);
879
+ if (existing instanceof Error || !existing) {
880
+ return;
881
+ }
882
+ const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
883
+ if (existingVercel?.sandboxId) {
884
+ await storage.sandbox.set({
885
+ id: existing.id,
886
+ config: existing.config,
887
+ tags: existing.tags,
888
+ createdAt: existing.createdAt,
889
+ lastActivityAt: existing.lastActivityAt,
890
+ acquiringLockId: null,
891
+ acquiringLockAt: null,
892
+ providerMetadata: {
893
+ provider: "vercel",
894
+ sandboxId: null,
895
+ snapshotId: existingVercel.snapshotId
896
+ }
897
+ });
898
+ }
899
+ }
900
+ async function updateLastActivity() {
901
+ const now = Date.now();
902
+ const lastSent = lastActivitySent.get(id);
903
+ if (lastSent && now - lastSent < ACTIVITY_THROTTLE_MS) {
904
+ return;
905
+ }
906
+ lastActivitySent.set(id, now);
907
+ const existing = await storage.sandbox.get(id);
908
+ if (existing instanceof Error || !existing) {
909
+ return;
910
+ }
911
+ const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
912
+ await storage.sandbox.set({
913
+ id: existing.id,
914
+ config: existing.config,
915
+ tags: existing.tags,
916
+ createdAt: existing.createdAt,
917
+ lastActivityAt: now,
918
+ acquiringLockId: null,
919
+ acquiringLockAt: null,
920
+ providerMetadata: existingVercel ?? {
921
+ provider: "vercel",
922
+ sandboxId: null,
923
+ snapshotId: null
924
+ }
925
+ });
926
+ }
927
+ const lifecycle = {
928
+ start: async () => {
929
+ const sandbox2 = await getSandbox2();
930
+ if (sandbox2 instanceof Error) {
931
+ return sandbox2;
932
+ }
933
+ await updateLastActivity();
934
+ return sandbox2.status;
935
+ },
936
+ snapshot: async () => {
937
+ const sandbox2 = await getSandbox2();
938
+ if (sandbox2 instanceof Error) {
939
+ return sandbox2;
940
+ }
941
+ return errore2.tryAsync({
942
+ try: async () => {
943
+ const existing = await storage.sandbox.get(id);
944
+ const snapshot = await sandbox2.snapshot();
945
+ await storage.sandbox.set({
946
+ id,
947
+ config,
948
+ tags: existing instanceof Error ? null : existing?.tags ?? null,
949
+ createdAt: existing instanceof Error ? null : existing?.createdAt ?? null,
950
+ lastActivityAt: existing instanceof Error ? null : existing?.lastActivityAt ?? null,
951
+ acquiringLockId: null,
952
+ acquiringLockAt: null,
953
+ providerMetadata: {
954
+ provider: "vercel",
955
+ sandboxId: null,
956
+ snapshotId: snapshot.snapshotId
957
+ }
958
+ });
959
+ return { snapshotId: snapshot.snapshotId };
960
+ },
961
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
962
+ });
963
+ },
964
+ stop: async () => {
965
+ const sandbox2 = await getSandbox2();
966
+ if (sandbox2 instanceof Error) {
967
+ return sandbox2;
968
+ }
969
+ return errore2.tryAsync({
970
+ try: async () => {
971
+ await sandbox2.stop();
972
+ const existing = await storage.sandbox.get(id);
973
+ if (existing instanceof Error || !existing) {
974
+ return void 0;
975
+ }
976
+ await storage.sandbox.set({
977
+ id: existing.id,
978
+ config: existing.config,
979
+ tags: existing.tags,
980
+ createdAt: existing.createdAt,
981
+ lastActivityAt: existing.lastActivityAt,
982
+ acquiringLockId: null,
983
+ acquiringLockAt: null,
984
+ providerMetadata: {
985
+ provider: "vercel",
986
+ sandboxId: null,
987
+ snapshotId: null
988
+ }
989
+ });
990
+ return void 0;
991
+ },
992
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
993
+ });
994
+ },
995
+ getStatus: async () => {
996
+ const sandbox2 = await getSandbox2();
997
+ if (sandbox2 instanceof Error) {
998
+ return sandbox2;
999
+ }
1000
+ return sandbox2.status;
1001
+ },
1002
+ getCreatedAt: async () => {
1003
+ const sandbox2 = await getSandbox2();
1004
+ if (sandbox2 instanceof Error) {
1005
+ return sandbox2;
1006
+ }
1007
+ return sandbox2.createdAt;
1008
+ },
1009
+ getRemainingTimeout: async () => {
1010
+ const sandbox2 = await getSandbox2();
1011
+ if (sandbox2 instanceof Error) {
1012
+ return sandbox2;
1013
+ }
1014
+ return sandbox2.timeout;
1015
+ }
1016
+ };
1017
+ async function doExec(opts) {
1018
+ const instance = await getSandbox2();
1019
+ if (instance instanceof Error) {
1020
+ return instance;
1021
+ }
1022
+ const updatePromise = updateLastActivity();
1023
+ const execResult = await execOnInstance(instance, opts);
1024
+ await updatePromise;
1025
+ return execResult;
1026
+ }
1027
+ const sandbox = {
1028
+ id,
1029
+ config,
1030
+ exec: async (opts) => {
1031
+ const result = await doExec(opts);
1032
+ if (result instanceof SandboxError && isSandboxGoneError(result.cause)) {
1033
+ await recoverFromStaleSandbox();
1034
+ return await doExec(opts);
1035
+ }
1036
+ return result;
1037
+ },
1038
+ getDomain: async (port) => {
1039
+ const sandbox2 = await getSandbox2();
1040
+ if (sandbox2 instanceof Error) {
1041
+ return sandbox2;
1042
+ }
1043
+ try {
1044
+ return sandbox2.domain(port);
1045
+ } catch (e) {
1046
+ return new SandboxError({ reason: String(e), cause: e });
1047
+ }
1048
+ },
1049
+ kill: async ({ commandId, storage: cmdStorage }) => {
1050
+ const instance = await getSandbox2();
1051
+ if (instance instanceof Error) {
1052
+ return instance;
1053
+ }
1054
+ const cmd = await cmdStorage.command.get(commandId);
1055
+ if (cmd instanceof Error) {
1056
+ return new SandboxError({ reason: cmd.message, cause: cmd });
1057
+ }
1058
+ if (cmd && cmd.status === "running") {
1059
+ const result = await cmdStorage.command.set({
1060
+ ...cmd,
1061
+ status: "killed"
1062
+ });
1063
+ if (result instanceof Error) {
1064
+ return new SandboxError({ reason: result.message, cause: result });
1065
+ }
1066
+ }
1067
+ return void 0;
1068
+ },
1069
+ readFile: async (opts) => {
1070
+ const instance = await getSandbox2();
1071
+ if (instance instanceof Error) {
1072
+ return instance;
1073
+ }
1074
+ return readFileOnInstance(instance, opts);
1075
+ },
1076
+ writeFiles: async (opts) => {
1077
+ const instance = await getSandbox2();
1078
+ if (instance instanceof Error) {
1079
+ throw instance;
1080
+ }
1081
+ return writeFilesOnInstance(instance, opts);
1082
+ },
1083
+ lifecycle,
1084
+ updateNetworkPolicy: async (policy) => {
1085
+ const instance = await getSandbox2();
1086
+ if (instance instanceof Error) {
1087
+ return instance;
1088
+ }
1089
+ return errore2.tryAsync({
1090
+ try: () => instance.updateNetworkPolicy(policy),
1091
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
1092
+ });
1093
+ },
1094
+ tag: {
1095
+ list: async () => {
1096
+ const sandboxRecord2 = await storage.sandbox.get(id);
1097
+ if (sandboxRecord2 instanceof Error) {
1098
+ return sandboxRecord2;
1099
+ }
1100
+ return sandboxRecord2.tags ?? {};
1101
+ },
1102
+ get: async (key) => {
1103
+ const sandboxRecord2 = await storage.sandbox.get(id);
1104
+ if (sandboxRecord2 instanceof Error) {
1105
+ return sandboxRecord2;
1106
+ }
1107
+ return sandboxRecord2.tags?.[key];
1108
+ },
1109
+ set: async (key, value) => {
1110
+ const result = await storage.sandbox.tag.set({
1111
+ sandboxId: id,
1112
+ tags: { [key]: value }
1113
+ });
1114
+ if (result instanceof Error) {
1115
+ return result;
1116
+ }
1117
+ return void 0;
1118
+ },
1119
+ setMany: async (tags) => {
1120
+ const result = await storage.sandbox.tag.set({
1121
+ sandboxId: id,
1122
+ tags
1123
+ });
1124
+ if (result instanceof Error) {
1125
+ return result;
1126
+ }
1127
+ return void 0;
1128
+ }
1129
+ }
1130
+ };
1131
+ let onReadyPromise = Promise.resolve();
1132
+ if (config.lifecycle?.autoStart !== false) {
1133
+ sandboxPromise = doGetSandbox();
1134
+ onReadyPromise = sandboxPromise.then(async (instance) => {
1135
+ if (instance instanceof Error) {
1136
+ return;
1137
+ }
1138
+ if (needsSetupRun && setup) {
1139
+ debug(
1140
+ `[sandbox:setup] running setup.run on session sandbox (key="${setup.key}")`
1141
+ );
1142
+ await setup.run(sandbox);
1143
+ debug("[sandbox:setup] setup.run complete on session sandbox");
1144
+ }
1145
+ if (createdFromSnapshot && onRestart) {
1146
+ debug("[sandbox:setup] running onRestart (created from snapshot)");
1147
+ await onRestart(sandbox);
1148
+ }
1149
+ });
1150
+ }
1151
+ sandbox._onReady = onReadyPromise;
1152
+ return sandbox;
1153
+ };
1154
+
1155
+ // src/sandbox/client.ts
1156
+ var sandboxCache = /* @__PURE__ */ new Map();
1157
+ async function getSandbox({
1158
+ sandboxRecord,
1159
+ storageConfig,
1160
+ storage,
1161
+ rpc,
1162
+ enableLifecycleWorkflow = true,
1163
+ setup,
1164
+ onRestart
1165
+ }) {
1166
+ const canCache = !(setup || onRestart);
1167
+ if (canCache) {
1168
+ const cached = sandboxCache.get(sandboxRecord.id);
1169
+ if (cached) {
1170
+ debug("[getSandbox] cache hit for", sandboxRecord.id);
1171
+ return cached;
1172
+ }
1173
+ }
1174
+ const promise = createSandbox({
1175
+ sandboxRecord,
1176
+ storageConfig,
1177
+ storage,
1178
+ rpc,
1179
+ enableLifecycleWorkflow,
1180
+ setup,
1181
+ onRestart
1182
+ });
1183
+ if (canCache) {
1184
+ sandboxCache.set(sandboxRecord.id, promise);
1185
+ promise.catch(() => {
1186
+ sandboxCache.delete(sandboxRecord.id);
1187
+ });
1188
+ }
1189
+ return await promise;
1190
+ }
1191
+ async function createSandbox({
1192
+ sandboxRecord,
1193
+ storageConfig,
1194
+ storage,
1195
+ rpc,
1196
+ enableLifecycleWorkflow = true,
1197
+ setup,
1198
+ onRestart
1199
+ }) {
1200
+ let sbx;
1201
+ switch (sandboxRecord.config.type) {
1202
+ case "local":
1203
+ sbx = localSandbox({
1204
+ sandboxRecord,
1205
+ storage,
1206
+ setup,
1207
+ onRestart
1208
+ });
1209
+ break;
1210
+ case "vercel":
1211
+ sbx = vercelSandbox({
1212
+ sandboxRecord,
1213
+ storageConfig,
1214
+ storage,
1215
+ rpc,
1216
+ enableLifecycleWorkflow,
1217
+ setup,
1218
+ onRestart
1219
+ });
1220
+ break;
1221
+ case "custom":
1222
+ throw new Error("Custom sandboxes are not supported");
1223
+ default:
1224
+ sandboxRecord.config;
1225
+ throw new Error(
1226
+ `Unknown sandbox type: ${// biome-ignore lint/suspicious/noExplicitAny: .
1227
+ sandboxRecord.config.type}`
1228
+ );
1229
+ }
1230
+ if (sbx._onReady) {
1231
+ await sbx._onReady;
1232
+ }
1233
+ return sbx;
1234
+ }
1235
+
1236
+ export {
1237
+ getSandbox
1238
+ };
1239
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3V0aWxzL2RlYnVnLnRzIiwgIi4uL3NyYy9zYW5kYm94L2JpbmRpbmdzL2xvY2FsLnRzIiwgIi4uL3NyYy9zYW5kYm94L3dyaXRlLWZpbGVzLnRzIiwgIi4uL3NyYy9zYW5kYm94L2JpbmRpbmdzL3ZlcmNlbC50cyIsICIuLi9zcmMvc2FuZGJveC9jbGllbnQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IGVuYWJsZWQgPVxuICBwcm9jZXNzLmVudi5BR0VOVF9ERUJVRyA9PT0gXCIxXCIgfHwgcHJvY2Vzcy5lbnYuQUdFTlRfREVCVUcgPT09IFwidHJ1ZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gZGVidWcoLi4uYXJnczogdW5rbm93bltdKSB7XG4gIGlmIChlbmFibGVkKSB7XG4gICAgY29uc29sZS5sb2coLi4uYXJncyk7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IENoaWxkUHJvY2VzcyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHNwYXduIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0ICogYXMgZXJyb3JlIGZyb20gXCJlcnJvcmVcIjtcbmltcG9ydCB7IHVsaWQgfSBmcm9tIFwidWxpZFwiO1xuaW1wb3J0IHsgU2FuZGJveEVycm9yIH0gZnJvbSBcIi4uLy4uL2Vycm9yc1wiO1xuaW1wb3J0IHR5cGUgeyBUYWdzU2NoZW1hIH0gZnJvbSBcIi4uLy4uL2luZGV4XCI7XG5pbXBvcnQgdHlwZSB7IFNhbmRib3hSZWNvcmQsIFN0b3JhZ2UgfSBmcm9tIFwiLi4vLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHsgZGVidWcgfSBmcm9tIFwiLi4vLi4vdXRpbHMvZGVidWdcIjtcbmltcG9ydCB0eXBlIHsgTG9nRW50cnksIE9uUmVzdGFydCwgU2FuZGJveCwgU2FuZGJveFNldHVwIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyB3cml0ZUZpbGVzIH0gZnJvbSBcIi4uL3dyaXRlLWZpbGVzXCI7XG5cbmV4cG9ydCBjb25zdCBsb2NhbFNhbmRib3ggPSA8VFRhZ3MgZXh0ZW5kcyBUYWdzU2NoZW1hID0gVGFnc1NjaGVtYT4oe1xuICBzYW5kYm94UmVjb3JkLFxuICBzdG9yYWdlLFxuICBzZXR1cCxcbiAgb25SZXN0YXJ0LFxufToge1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkICYgeyBjb25maWc6IHsgdHlwZTogXCJsb2NhbFwiIH0gfTtcbiAgc3RvcmFnZTogU3RvcmFnZTtcbiAgc2V0dXA/OiBTYW5kYm94U2V0dXA7XG4gIG9uUmVzdGFydD86IE9uUmVzdGFydDtcbn0pOiBTYW5kYm94PFRUYWdzPiAmIHsgX29uUmVhZHk/OiBQcm9taXNlPHZvaWQ+IH0gPT4ge1xuICBjb25zdCBjb25maWcgPSBzYW5kYm94UmVjb3JkLmNvbmZpZztcbiAgY29uc3QgYmFzZVBhdGggPSBjb25maWcucGF0aCA/PyBwcm9jZXNzLmN3ZCgpO1xuICBjb25zdCBwcm9jZXNzZXMgPSBuZXcgTWFwPHN0cmluZywgQ2hpbGRQcm9jZXNzPigpO1xuXG4gIGNvbnN0IHNhbmRib3g6IFNhbmRib3g8VFRhZ3M+ID0ge1xuICAgIGlkOiBzYW5kYm94UmVjb3JkLmlkLFxuICAgIGNvbmZpZzogc2FuZGJveFJlY29yZC5jb25maWcsXG4gICAgZXhlYzogKHsgY29tbWFuZCwgYXJncywgc2lnbmFsIH0pID0+IHtcbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kSWQgPSBgY29tbWFuZF8ke3VsaWQoKX1gO1xuXG4gICAgICAgICAgY29uc3QgY2hpbGQgPSBzcGF3bihjb21tYW5kLCBhcmdzLCB7XG4gICAgICAgICAgICBjd2Q6IGJhc2VQYXRoLFxuICAgICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcHJvY2Vzc2VzLnNldChjb21tYW5kSWQsIGNoaWxkKTtcblxuICAgICAgICAgIGxldCBzdGRvdXQgPSBcIlwiO1xuICAgICAgICAgIGxldCBzdGRlcnIgPSBcIlwiO1xuICAgICAgICAgIGNvbnN0IGxvZ1F1ZXVlOiBMb2dFbnRyeVtdID0gW107XG4gICAgICAgICAgbGV0IGxvZ1Jlc29sdmU6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICAgICAgICAgIGxldCBjbG9zZWQgPSBmYWxzZTtcblxuICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbihcImRhdGFcIiwgKGRhdGE6IHN0cmluZyB8IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGRhdGEpO1xuICAgICAgICAgICAgc3Rkb3V0ICs9IHN0cjtcbiAgICAgICAgICAgIGxvZ1F1ZXVlLnB1c2goeyBzdHJlYW06IFwic3Rkb3V0XCIsIGRhdGE6IHN0ciB9KTtcbiAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2hpbGQuc3RkZXJyLm9uKFwiZGF0YVwiLCAoZGF0YTogc3RyaW5nIHwgQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHIgPSBTdHJpbmcoZGF0YSk7XG4gICAgICAgICAgICBzdGRlcnIgKz0gc3RyO1xuICAgICAgICAgICAgbG9nUXVldWUucHVzaCh7IHN0cmVhbTogXCJzdGRlcnJcIiwgZGF0YTogc3RyIH0pO1xuICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgUHJvbWlzZTx7XG4gICAgICAgICAgICBzdGRvdXQ6IHN0cmluZztcbiAgICAgICAgICAgIHN0ZGVycjogc3RyaW5nO1xuICAgICAgICAgICAgZXhpdENvZGU6IG51bWJlcjtcbiAgICAgICAgICB9PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjaGlsZC5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VzLmRlbGV0ZShjb21tYW5kSWQpO1xuICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2hpbGQub24oXCJjbG9zZVwiLCAoY29kZTogbnVtYmVyIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgICBwcm9jZXNzZXMuZGVsZXRlKGNvbW1hbmRJZCk7XG4gICAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7XG4gICAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgICAgICByZXNvbHZlKHsgc3Rkb3V0LCBzdGRlcnIsIGV4aXRDb2RlOiBjb2RlID8/IDAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGFzeW5jIGZ1bmN0aW9uKiBsb2dzKCk6IEFzeW5jSXRlcmFibGU8TG9nRW50cnk+IHtcbiAgICAgICAgICAgIHdoaWxlICghY2xvc2VkIHx8IGxvZ1F1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgY29uc3QgZW50cnkgPSBsb2dRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBlbnRyeTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghY2xvc2VkKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgICAgICAgIGxvZ1Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGxvZ1Jlc29sdmUgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGNvbW1hbmRJZCwgbG9ncywgcmVzdWx0IH0pO1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGU6IHVua25vd24pID0+XG4gICAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXREb21haW46IChwb3J0KSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gKTtcbiAgICB9LFxuXG4gICAga2lsbDogYXN5bmMgKHsgY29tbWFuZElkLCBzdG9yYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IGNoaWxkID0gcHJvY2Vzc2VzLmdldChjb21tYW5kSWQpO1xuICAgICAgaWYgKCFjaGlsZCkge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgcmVhc29uOiBgQ29tbWFuZCAke2NvbW1hbmRJZH0gbm90IGZvdW5kIG9yIGFscmVhZHkgZmluaXNoZWRgLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG5cbiAgICAgIGNvbnN0IGNtZCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmIChjbWQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogY21kLm1lc3NhZ2UsIGNhdXNlOiBjbWQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY21kICYmIGNtZC5zdGF0dXMgPT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5zZXQoe1xuICAgICAgICAgIC4uLmNtZCxcbiAgICAgICAgICBzdGF0dXM6IFwia2lsbGVkXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogcmVzdWx0Lm1lc3NhZ2UsIGNhdXNlOiByZXN1bHQgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVhZEZpbGU6IGFzeW5jICh7IHBhdGg6IGZpbGVQYXRoIH0pID0+IHtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gcGF0aC5qb2luKGJhc2VQYXRoLCBmaWxlUGF0aCk7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgZnMucmVhZEZpbGUoZnVsbFBhdGgpO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZSBpbnN0YW5jZW9mIEVycm9yICYmXG4gICAgICAgICAgXCJjb2RlXCIgaW4gZSAmJlxuICAgICAgICAgIChlIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gXCJFTk9FTlRcIlxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgd3JpdGVGaWxlczogKG9wdHMpID0+IHdyaXRlRmlsZXMoeyBzYW5kYm94LCAuLi5vcHRzIH0pLFxuXG4gICAgdXBkYXRlTmV0d29ya1BvbGljeTogKCkgPT5cbiAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgcmVhc29uOiBcInVwZGF0ZU5ldHdvcmtQb2xpY3kgaXMgb25seSBhdmFpbGFibGUgZm9yIFZlcmNlbCBzYW5kYm94ZXNcIixcbiAgICAgICAgfSlcbiAgICAgICksXG5cbiAgICB0YWc6IHtcbiAgICAgIGxpc3Q6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoc2FuZGJveC5pZCk7XG4gICAgICAgIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHNhbmRib3hSZWNvcmQudGFncyA/PyB7fSkgYXMgVFRhZ3M7XG4gICAgICB9LFxuICAgICAgZ2V0OiBhc3luYyAoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoc2FuZGJveC5pZCk7XG4gICAgICAgIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZC50YWdzPy5ba2V5IGFzIHN0cmluZ10gYXNcbiAgICAgICAgICB8IFRUYWdzW3R5cGVvZiBrZXldXG4gICAgICAgICAgfCB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICAgc2V0OiBhc3luYyAoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC50YWcuc2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3guaWQsXG4gICAgICAgICAgdGFnczogeyBba2V5XTogdmFsdWUgfSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgICBzZXRNYW55OiBhc3luYyAodGFnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LnRhZy5zZXQoe1xuICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveC5pZCxcbiAgICAgICAgICB0YWdzOiB0YWdzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IHJlc3VsdDogU2FuZGJveDxUVGFncz4gJiB7IF9vblJlYWR5PzogUHJvbWlzZTx2b2lkPiB9ID0gc2FuZGJveDtcblxuICBpZiAoc2V0dXAgfHwgb25SZXN0YXJ0KSB7XG4gICAgcmVzdWx0Ll9vblJlYWR5ID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBuZWVkc1NldHVwID0gISFzZXR1cDtcbiAgICAgIGlmIChzZXR1cCkge1xuICAgICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2V0dXAuZ2V0KHNldHVwLmtleSk7XG4gICAgICAgIGlmICghKGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IpICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHNldHVwIGFscmVhZHkgY29tcGxldGUgZm9yIGtleSBcIiR7c2V0dXAua2V5fVwiLCBza2lwcGluZ2BcbiAgICAgICAgICApO1xuICAgICAgICAgIG5lZWRzU2V0dXAgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG5lZWRzU2V0dXAgJiYgc2V0dXApIHtcbiAgICAgICAgZGVidWcoYFtzYW5kYm94OnNldHVwXSBydW5uaW5nIHNldHVwLnJ1biAobG9jYWwsIGtleT1cIiR7c2V0dXAua2V5fVwiKWApO1xuICAgICAgICBhd2FpdCBzZXR1cC5ydW4oc2FuZGJveCk7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2V0dXAuc2V0KHtcbiAgICAgICAgICBrZXk6IHNldHVwLmtleSxcbiAgICAgICAgICBzbmFwc2hvdElkOiBudWxsLFxuICAgICAgICAgIGNyZWF0ZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgICBsYXN0VXNlZEF0OiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHNldHVwIGNvbXBsZXRlLCBzdG9yZWQgcmVjb3JkIChrZXk9XCIke3NldHVwLmtleX1cIilgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAob25SZXN0YXJ0KSB7XG4gICAgICAgIGRlYnVnKFwiW3NhbmRib3g6c2V0dXBdIHJ1bm5pbmcgb25SZXN0YXJ0IChsb2NhbClcIik7XG4gICAgICAgIGF3YWl0IG9uUmVzdGFydChzYW5kYm94KTtcbiAgICAgIH1cbiAgICB9KSgpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCAiaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IFVwbG9hZGFibGVGaWxlIH0gZnJvbSBcIi4uL3NraWxscy90eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBTYW5kYm94IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuY29uc3QgTUFYX1JFVFJJRVMgPSAyO1xuY29uc3QgUkVUUllfQkFTRV9NUyA9IDUwMDtcblxuLyoqXG4gKiBFeGVjIGEgY29tbWFuZCBhbmQgYXNzZXJ0IGV4aXQgY29kZSAwLiBSZXRyaWVzIG9uIHRyYW5zaWVudCBmYWlsdXJlc1xuICogKGV4aXQgY29kZSAyNTUgd2l0aCBlbXB0eSBzdGRlcnIgXHUyMDE0IHR5cGljYWxseSBhIHNhbmRib3ggcHJvY2VzcyBraWxsZWRcbiAqIGJlZm9yZSBpdCBjb3VsZCBwcm9kdWNlIG91dHB1dCkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4ZWNDaGVja2VkKFxuICBzYW5kYm94OiBQaWNrPFNhbmRib3gsIFwiZXhlY1wiPixcbiAgb3B0czogeyBjb21tYW5kOiBzdHJpbmc7IGFyZ3M/OiBzdHJpbmdbXSB9LFxuICBlcnJvckxhYmVsOiBzdHJpbmdcbik6IFByb21pc2U8eyBzdGRvdXQ6IHN0cmluZzsgc3RkZXJyOiBzdHJpbmc7IGV4aXRDb2RlOiBudW1iZXIgfT4ge1xuICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgOyBhdHRlbXB0KyspIHtcbiAgICBjb25zdCBleGVjUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKG9wdHMpO1xuICAgIGlmIChleGVjUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHRocm93IGV4ZWNSZXN1bHQ7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGV4ZWNSZXN1bHQucmVzdWx0O1xuICAgIGlmIChyZXN1bHQuZXhpdENvZGUgPT09IDApIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgY29uc3QgaXNUcmFuc2llbnQgPSByZXN1bHQuZXhpdENvZGUgPT09IDI1NSAmJiAhcmVzdWx0LnN0ZGVyci50cmltKCk7XG4gICAgaWYgKGlzVHJhbnNpZW50ICYmIGF0dGVtcHQgPCBNQVhfUkVUUklFUykge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgUkVUUllfQkFTRV9NUyAqIChhdHRlbXB0ICsgMSkpKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGAke2Vycm9yTGFiZWx9IHdpdGggZXhpdCBjb2RlICR7cmVzdWx0LmV4aXRDb2RlfTogJHtyZXN1bHQuc3RkZXJyfWBcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogV3JpdGVzIGZpbGVzIHRvIGEgc2FuZGJveCBhdCB0aGUgc3BlY2lmaWVkIGRlc3RpbmF0aW9uIHBhdGguXG4gKiBTaGVsbCBzY3JpcHRzICguc2ggZmlsZXMpIGFyZSBhdXRvbWF0aWNhbGx5IG1hZGUgZXhlY3V0YWJsZS5cbiAqXG4gKiBGb3Igc21hbGwgZmlsZXMgKDwxMDBLQiB0b3RhbCksIHVzZXMgc2luZ2xlIGV4ZWMgd2l0aCBoZXJlZG9jLlxuICogRm9yIGxhcmdlIGZpbGVzLCB3cml0ZXMgYmFzZTY0IGNodW5rcyB0aGVuIGRlY29kZXMgdG8gYXZvaWQgQVJHX01BWCBsaW1pdHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZUZpbGVzKG9wdHM6IHtcbiAgc2FuZGJveDogUGljazxTYW5kYm94LCBcImV4ZWNcIj47XG4gIGZpbGVzOiBVcGxvYWRhYmxlRmlsZVtdO1xuICBkZXN0UGF0aDogc3RyaW5nO1xufSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IHNhbmRib3gsIGZpbGVzLCBkZXN0UGF0aCB9ID0gb3B0cztcblxuICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgZmlsZVBhdGhzID0gZmlsZXMubWFwKChmaWxlKSA9PiBwYXRoLnBvc2l4LmpvaW4oZGVzdFBhdGgsIGZpbGUucGF0aCkpO1xuICBjb25zdCBwYXJlbnREaXJzID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KGZpbGVQYXRocy5tYXAoKHApID0+IHBhdGgucG9zaXguZGlybmFtZShwKSkpXG4gICk7XG4gIGNvbnN0IHNoZWxsU2NyaXB0cyA9IGZpbGVQYXRocy5maWx0ZXIoKHApID0+IHAuZW5kc1dpdGgoXCIuc2hcIikpO1xuXG4gIGNvbnN0IG1rZGlyUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICBjb21tYW5kOiBcIm1rZGlyXCIsXG4gICAgYXJnczogW1wiLXBcIiwgLi4ucGFyZW50RGlyc10sXG4gIH0pO1xuICBpZiAobWtkaXJSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIHRocm93IG1rZGlyUmVzdWx0O1xuICB9XG4gIGF3YWl0IG1rZGlyUmVzdWx0LnJlc3VsdDtcblxuICBjb25zdCBDSFVOS19TSVpFID0gNTBfMDAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBmaWxlID0gZmlsZXNbaV07XG4gICAgY29uc3QgZnVsbFBhdGggPSBmaWxlUGF0aHNbaV07XG4gICAgY29uc3QgYmFzZTY0Q29udGVudCA9IHRvQmFzZTY0KGZpbGUuY29udGVudCk7XG5cbiAgICBpZiAoYmFzZTY0Q29udGVudC5sZW5ndGggPCBDSFVOS19TSVpFKSB7XG4gICAgICBjb25zdCBtYXJrZXIgPSBgRU9GXyR7aX1gO1xuICAgICAgYXdhaXQgZXhlY0NoZWNrZWQoXG4gICAgICAgIHNhbmRib3gsXG4gICAgICAgIHtcbiAgICAgICAgICBjb21tYW5kOiBcImJhc2hcIixcbiAgICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgICBgYmFzZTY0IC1kID4gJHtxdW90ZShmdWxsUGF0aCl9IDw8ICcke21hcmtlcn0nXG4ke2Jhc2U2NENvbnRlbnR9XG4ke21hcmtlcn1gLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIFwid3JpdGVGaWxlcyBmYWlsZWRcIlxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGVtcEI2NCA9IGAvdG1wL2NodW5rLSR7RGF0ZS5ub3coKX0tJHtpfS5iNjRgO1xuXG4gICAgICBjb25zdCBjbGVhclJlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICBhcmdzOiBbXCItY1wiLCBgPiAke3F1b3RlKHRlbXBCNjQpfWBdLFxuICAgICAgfSk7XG4gICAgICBpZiAoY2xlYXJSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBjbGVhclJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGNsZWFyUmVzdWx0LnJlc3VsdDtcblxuICAgICAgZm9yIChcbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAgIG9mZnNldCA8IGJhc2U2NENvbnRlbnQubGVuZ3RoO1xuICAgICAgICBvZmZzZXQgKz0gQ0hVTktfU0laRVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGNodW5rID0gYmFzZTY0Q29udGVudC5zbGljZShvZmZzZXQsIG9mZnNldCArIENIVU5LX1NJWkUpO1xuICAgICAgICBjb25zdCBtYXJrZXIgPSBgQ0hVTktfJHtvZmZzZXR9YDtcbiAgICAgICAgYXdhaXQgZXhlY0NoZWNrZWQoXG4gICAgICAgICAgc2FuZGJveCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb21tYW5kOiBcImJhc2hcIixcbiAgICAgICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAgICAgXCItY1wiLFxuICAgICAgICAgICAgICBgY2F0ID4+ICR7cXVvdGUodGVtcEI2NCl9IDw8ICcke21hcmtlcn0nXG4ke2NodW5rfVxuJHttYXJrZXJ9YCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBcIndyaXRlRmlsZXMgY2h1bmsgZmFpbGVkXCJcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgZXhlY0NoZWNrZWQoXG4gICAgICAgIHNhbmRib3gsXG4gICAgICAgIHtcbiAgICAgICAgICBjb21tYW5kOiBcImJhc2hcIixcbiAgICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgICBgYmFzZTY0IC1kIDwgJHtxdW90ZSh0ZW1wQjY0KX0gPiAke3F1b3RlKGZ1bGxQYXRoKX0gJiYgcm0gLWYgJHtxdW90ZSh0ZW1wQjY0KX1gLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIFwid3JpdGVGaWxlcyBkZWNvZGUgZmFpbGVkXCJcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNoZWxsU2NyaXB0cy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgY2htb2RSZXN1bHQgPSBhd2FpdCBzYW5kYm94LmV4ZWMoe1xuICAgICAgY29tbWFuZDogXCJjaG1vZFwiLFxuICAgICAgYXJnczogW1wiK3hcIiwgLi4uc2hlbGxTY3JpcHRzXSxcbiAgICB9KTtcbiAgICBpZiAoY2htb2RSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgY2htb2RSZXN1bHQ7XG4gICAgfVxuICAgIGF3YWl0IGNobW9kUmVzdWx0LnJlc3VsdDtcbiAgfVxufVxuXG5mdW5jdGlvbiB0b0Jhc2U2NChjb250ZW50OiBzdHJpbmcgfCBCdWZmZXIpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIGNvbnRlbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oY29udGVudCkudG9TdHJpbmcoXCJiYXNlNjRcIik7XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnQudG9TdHJpbmcoXCJiYXNlNjRcIik7XG59XG5cbmZ1bmN0aW9uIHF1b3RlKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJyR7cy5yZXBsYWNlKC8nL2csIFwiJ1xcXFwnJ1wiKX0nYDtcbn1cbiIsICJpbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCAqIGFzIGVycm9yZSBmcm9tIFwiZXJyb3JlXCI7XG5pbXBvcnQgeyBTYW5kYm94IGFzIFZlcmNlbFNhbmRib3hTREsgfSBmcm9tIFwiQHZlcmNlbC9zYW5kYm94XCI7XG5pbXBvcnQgeyBzdGFydCB9IGZyb20gXCJ3b3JrZmxvdy9hcGlcIjtcbmltcG9ydCB7IFNhbmRib3hFcnJvciwgU2FuZGJveE5vdEZvdW5kRXJyb3IgfSBmcm9tIFwiLi4vLi4vZXJyb3JzXCI7XG5pbXBvcnQgdHlwZSB7IFRhZ3NTY2hlbWEgfSBmcm9tIFwiLi4vLi4vaW5kZXhcIjtcbmltcG9ydCB0eXBlIHtcbiAgUnBjRm4sXG4gIFNhbmRib3hSZWNvcmQsXG4gIFN0b3JhZ2UsXG4gIFN0b3JhZ2VDb25maWcsXG59IGZyb20gXCIuLi8uLi9zdG9yYWdlXCI7XG5pbXBvcnQgeyBkZWJ1ZyB9IGZyb20gXCIuLi8uLi91dGlscy9kZWJ1Z1wiO1xuaW1wb3J0IHR5cGUge1xuICBMb2dFbnRyeSxcbiAgT25SZXN0YXJ0LFxuICBTYW5kYm94LFxuICBTYW5kYm94TGlmZWN5Y2xlLFxuICBTYW5kYm94TGlmZWN5Y2xlSW5wdXQsXG4gIFNhbmRib3hTZXR1cCxcbiAgU2FuZGJveFN0YXR1cyxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBzYW5kYm94TGlmZWN5Y2xlV29ya2Zsb3cgfSBmcm9tIFwiLi9saWZlY3ljbGUtd29ya2Zsb3dcIjtcblxuZXhwb3J0IHR5cGUgVmVyY2VsU2FuZGJveENyZWF0ZU9wdGlvbnMgPSBFeHRyYWN0PFxuICBQYXJhbWV0ZXJzPHR5cGVvZiBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZT5bMF0sXG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvbXBsZXhpdHkvbm9CYW5uZWRUeXBlczogLlxuICB7fVxuPjtcblxuZXhwb3J0IGNvbnN0IFZFUkNFTF9NQVhfVElNRU9VVF9NUyA9IDUgKiA2MCAqIDYwICogMTAwMDsgLy8gNSBob3Vyc1xuY29uc3QgTE9DS19USU1FT1VUX01TID0gNSAqIDYwICogMTAwMDsgLy8gNSBtaW51dGVzIC0gaWYgbG9jayBvbGRlciB0aGFuIHRoaXMsIGNvbnNpZGVyIGl0IHN0YWxlXG5jb25zdCBMT0NLX1BPTExfSU5URVJWQUxfTVMgPSAyMDA7XG5cbmNvbnN0IGdldFRlc3RDcmVkZW50aWFscyA9ICgpID0+XG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcInRlc3RcIlxuICAgID8ge1xuICAgICAgICB0b2tlbjogcHJvY2Vzcy5lbnYuVEVTVF9WRVJDRUxfVE9LRU4sXG4gICAgICAgIHRlYW1JZDogcHJvY2Vzcy5lbnYuVEVTVF9WRVJDRUxfVEVBTV9JRCxcbiAgICAgICAgcHJvamVjdElkOiBwcm9jZXNzLmVudi5URVNUX1ZFUkNFTF9QUk9KRUNUX0lELFxuICAgICAgfVxuICAgIDoge307XG5cbi8qKlxuICogTW9kdWxlLWxldmVsIGNhY2hlIGZvciBpbi1mbGlnaHQgc2FuZGJveCBjcmVhdGlvbiBwcm9taXNlcy5cbiAqIFByZXZlbnRzIHBhcmFsbGVsIHJlcXVlc3RzIHdpdGhpbiB0aGUgc2FtZSBwcm9jZXNzIGZyb20gY3JlYXRpbmcgZHVwbGljYXRlIHNhbmRib3hlcy5cbiAqL1xuY29uc3QgY3JlYXRlUHJvbWlzZXMgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBzdHJpbmc+PigpO1xuXG5jb25zdCBBQ1RJVklUWV9USFJPVFRMRV9NUyA9IDEwXzAwMDtcbmNvbnN0IGxhc3RBY3Rpdml0eVNlbnQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG5jb25zdCBERUZBVUxUX1ZDUFVTID0gMjtcblxuZnVuY3Rpb24gaXNTYW5kYm94R29uZUVycm9yKGU6IHVua25vd24pOiBib29sZWFuIHtcbiAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IGVycm9yV2l0aFJlc3BvbnNlID0gZSBhcyB7IHJlc3BvbnNlPzogeyBzdGF0dXM/OiBudW1iZXIgfSB9O1xuICBjb25zdCBlcnJvcldpdGhDYXVzZSA9IGUgYXMgeyBjYXVzZT86IHsgcmVzcG9uc2U/OiB7IHN0YXR1cz86IG51bWJlciB9IH0gfTtcblxuICBjb25zdCBzdGF0dXMgPVxuICAgIGVycm9yV2l0aFJlc3BvbnNlLnJlc3BvbnNlPy5zdGF0dXMgPz9cbiAgICBlcnJvcldpdGhDYXVzZS5jYXVzZT8ucmVzcG9uc2U/LnN0YXR1cztcblxuICBpZiAoc3RhdHVzID09PSA0MTAgfHwgc3RhdHVzID09PSA0MjIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGNvbnN0IG1lc3NhZ2UgPSBlLm1lc3NhZ2UgfHwgU3RyaW5nKGUpO1xuICBpZiAoXG4gICAgbWVzc2FnZS5pbmNsdWRlcyhcIkV4cGVjdGVkIGEgc3RyZWFtIG9mIGNvbW1hbmQgZGF0YVwiKSB8fFxuICAgIG1lc3NhZ2UuaW5jbHVkZXMoXCJFeHBlY3RlZCBhIHN0cmVhbSBvZiBsb2dzXCIpXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgY29uc3QgdmVyY2VsU2FuZGJveCA9IDxUVGFncyBleHRlbmRzIFRhZ3NTY2hlbWEgPSBUYWdzU2NoZW1hPih7XG4gIHNhbmRib3hSZWNvcmQsXG4gIHN0b3JhZ2VDb25maWcsXG4gIGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93LFxuICBzdG9yYWdlLFxuICBycGMsXG4gIHNldHVwLFxuICBvblJlc3RhcnQsXG59OiB7XG4gIHNhbmRib3hSZWNvcmQ6IFNhbmRib3hSZWNvcmQgJiB7IGNvbmZpZzogeyB0eXBlOiBcInZlcmNlbFwiIH0gfTtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3c6IGJvb2xlYW47XG4gIHN0b3JhZ2U6IFN0b3JhZ2U7XG4gIHJwYzogUnBjRm47XG4gIHNldHVwPzogU2FuZGJveFNldHVwO1xuICBvblJlc3RhcnQ/OiBPblJlc3RhcnQ7XG59KTogU2FuZGJveDxUVGFncz4gJiB7IF9vblJlYWR5PzogUHJvbWlzZTx2b2lkPiB9ID0+IHtcbiAgY29uc3QgeyBpZCwgY29uZmlnIH0gPSBzYW5kYm94UmVjb3JkO1xuICBjb25zdCB2Y3B1cyA9IGNvbmZpZy5yZXNvdXJjZXM/LnZjcHVzID8/IERFRkFVTFRfVkNQVVM7XG4gIGNvbnN0IHBvcnRzID0gY29uZmlnLnBvcnRzO1xuICBjb25zdCBuZXR3b3JrUG9saWN5ID0gY29uZmlnLm5ldHdvcmtQb2xpY3k7XG4gIGNvbnN0IGluaXRpYWxWZXJjZWwgPVxuICAgIHNhbmRib3hSZWNvcmQucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgID8gc2FuZGJveFJlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICA6IG51bGw7XG5cbiAgdHlwZSBTYW5kYm94SW5zdGFuY2UgPSBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIFZlcmNlbFNhbmRib3hTREsuZ2V0Pj47XG4gIGxldCBzYW5kYm94UHJvbWlzZTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBTYW5kYm94SW5zdGFuY2U+IHwgbnVsbCA9IG51bGw7XG4gIGxldCByZWNvdmVyZWRGcm9tU3RhbGUgPSBmYWxzZTtcbiAgbGV0IGNyZWF0ZWRGcm9tU25hcHNob3QgPSBmYWxzZTtcbiAgbGV0IG5lZWRzU2V0dXBSdW4gPSBmYWxzZTtcbiAgY29uc3QgSE9NRV9ESVIgPSBcIi9ob21lL3ZlcmNlbC1zYW5kYm94XCI7XG5cbiAgYXN5bmMgZnVuY3Rpb24gcG9sbEZvclNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIExPQ0tfVElNRU9VVF9NUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBMT0NLX1BPTExfSU5URVJWQUxfTVMpKTtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgaWYgKHJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiByZWNvcmQubWVzc2FnZSwgY2F1c2U6IHJlY29yZCB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZlcmNlbFNhbmRib3hJZCA9XG4gICAgICAgIHJlY29yZD8ucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgICAgICA/IHJlY29yZC5wcm92aWRlck1ldGFkYXRhLnNhbmRib3hJZFxuICAgICAgICAgIDogbnVsbDtcbiAgICAgIGlmICh2ZXJjZWxTYW5kYm94SWQpIHtcbiAgICAgICAgcmV0dXJuIHZlcmNlbFNhbmRib3hJZDtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjb3JkPy5hY3F1aXJpbmdMb2NrQXQpIHtcbiAgICAgICAgY29uc3QgZmluYWxDaGVjayA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgICBpZiAoZmluYWxDaGVjayBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgICAgcmVhc29uOiBmaW5hbENoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICBjYXVzZTogZmluYWxDaGVjayxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaW5hbFZlcmNlbFNhbmRib3hJZCA9XG4gICAgICAgICAgZmluYWxDaGVjaz8ucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgICAgICAgID8gZmluYWxDaGVjay5wcm92aWRlck1ldGFkYXRhLnNhbmRib3hJZFxuICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICBpZiAoZmluYWxWZXJjZWxTYW5kYm94SWQpIHtcbiAgICAgICAgICByZXR1cm4gZmluYWxWZXJjZWxTYW5kYm94SWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRvR2V0T3JDcmVhdGVTYW5kYm94SWQoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgcmVhc29uOiBcIlRpbWVkIG91dCB3YWl0aW5nIGZvciBzYW5kYm94IGNyZWF0aW9uIGJ5IGFub3RoZXIgcHJvY2Vzc1wiLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gc3RhcnRMaWZlY3ljbGVXb3JrZmxvdyhcbiAgICB2ZXJjZWxTYW5kYm94SWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWVuYWJsZUxpZmVjeWNsZVdvcmtmbG93KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxpZmVjeWNsZUlucHV0OiBTYW5kYm94TGlmZWN5Y2xlSW5wdXQgPSB7XG4gICAgICBpZCxcbiAgICAgIHZlcmNlbFNhbmRib3hJZCxcbiAgICAgIHN0b3JhZ2VDb25maWcsXG4gICAgICBycGMsXG4gICAgfTtcbiAgICBhd2FpdCBzdGFydChzYW5kYm94TGlmZWN5Y2xlV29ya2Zsb3csIFt7IGlucHV0OiBsaWZlY3ljbGVJbnB1dCB9XSkuY2F0Y2goXG4gICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRW1wdHlCbG9ja1N0YXRlbWVudHM6IGludGVudGlvbmFsbHkgaWdub3JlZCAtIHdvcmtmbG93IHN0YXJ0IGlzIGZpcmUtYW5kLWZvcmdldFxuICAgICAgKCkgPT4ge31cbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU2FuZGJveEZyb21TbmFwc2hvdChcbiAgICBzbmFwc2hvdElkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBzdHJpbmc+IHtcbiAgICByZXR1cm4gYXdhaXQgZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgVmVyY2VsU2FuZGJveFNESy5jcmVhdGUoe1xuICAgICAgICAgIHNvdXJjZTogeyB0eXBlOiBcInNuYXBzaG90XCIsIHNuYXBzaG90SWQgfSxcbiAgICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgICAgcG9ydHMsXG4gICAgICAgICAgbmV0d29ya1BvbGljeSxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICB0YWdzOiBzYW5kYm94UmVjb3JkLnRhZ3MsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LnNhbmRib3hJZCxcbiAgICAgICAgICAgIHNuYXBzaG90SWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHN0YXJ0TGlmZWN5Y2xlV29ya2Zsb3coc2FuZGJveC5zYW5kYm94SWQpO1xuICAgICAgICByZXR1cm4gc2FuZGJveC5zYW5kYm94SWQ7XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRnJlc2hTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IFZlcmNlbFNhbmRib3hTREsuY3JlYXRlKHtcbiAgICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgICAgcG9ydHMsXG4gICAgICAgICAgbmV0d29ya1BvbGljeSxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICB0YWdzOiBzYW5kYm94UmVjb3JkLnRhZ3MsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LnNhbmRib3hJZCxcbiAgICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHN0YXJ0TGlmZWN5Y2xlV29ya2Zsb3coc2FuZGJveC5zYW5kYm94SWQpO1xuICAgICAgICByZXR1cm4gc2FuZGJveC5zYW5kYm94SWQ7XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvcmUgZXhlYyBsb2dpYyBhZ2FpbnN0IGEgcmF3IFZlcmNlbCBTREsgaW5zdGFuY2UuXG4gICAqIFNoYXJlZCBiZXR3ZWVuIHRoZSBtYWluIHNhbmRib3ggd3JhcHBlciBhbmQgdGVtcG9yYXJ5IHNldHVwIHNhbmRib3hlcy5cbiAgICovXG4gIGZ1bmN0aW9uIGV4ZWNPbkluc3RhbmNlKFxuICAgIGluc3RhbmNlOiBTYW5kYm94SW5zdGFuY2UsXG4gICAge1xuICAgICAgY29tbWFuZCxcbiAgICAgIGFyZ3MsXG4gICAgICBzaWduYWwsXG4gICAgfTogeyBjb21tYW5kOiBzdHJpbmc7IGFyZ3M/OiBzdHJpbmdbXTsgc2lnbmFsPzogQWJvcnRTaWduYWwgfVxuICApOiBQcm9taXNlPFxuICAgIHwgU2FuZGJveEVycm9yXG4gICAgfCB7XG4gICAgICAgIGNvbW1hbmRJZDogc3RyaW5nO1xuICAgICAgICBsb2dzOiAoKSA9PiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PjtcbiAgICAgICAgcmVzdWx0OiBQcm9taXNlPHsgc3Rkb3V0OiBzdHJpbmc7IHN0ZGVycjogc3RyaW5nOyBleGl0Q29kZTogbnVtYmVyIH0+O1xuICAgICAgfVxuICA+IHtcbiAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBhd2FpdCBpbnN0YW5jZS5ydW5Db21tYW5kKHtcbiAgICAgICAgICBjd2Q6IEhPTUVfRElSLFxuICAgICAgICAgIGFyZ3MsXG4gICAgICAgICAgY21kOiBjb21tYW5kLFxuICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgICBkZXRhY2hlZDogdHJ1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IHN0ZG91dCA9IFwiXCI7XG4gICAgICAgIGxldCBzdGRlcnIgPSBcIlwiO1xuICAgICAgICBjb25zdCBsb2dCdWZmZXI6IExvZ0VudHJ5W10gPSBbXTtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSB7XG4gICAgICAgICAgcmVzb2x2ZTogbnVsbCBhcyAoKCkgPT4gdm9pZCkgfCBudWxsLFxuICAgICAgICAgIGNvbnN1bWVkOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBjb25zdW1lTG9ncyA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgbG9nIG9mIG91dHB1dC5sb2dzKCkpIHtcbiAgICAgICAgICAgICAgY29uc3QgZW50cnk6IExvZ0VudHJ5ID1cbiAgICAgICAgICAgICAgICBsb2cuc3RyZWFtID09PSBcInN0ZG91dFwiXG4gICAgICAgICAgICAgICAgICA/IHsgc3RyZWFtOiBcInN0ZG91dFwiLCBkYXRhOiBsb2cuZGF0YSB9XG4gICAgICAgICAgICAgICAgICA6IHsgc3RyZWFtOiBcInN0ZGVyclwiLCBkYXRhOiBsb2cuZGF0YSB9O1xuXG4gICAgICAgICAgICAgIGlmIChsb2cuc3RyZWFtID09PSBcInN0ZG91dFwiKSB7XG4gICAgICAgICAgICAgICAgc3Rkb3V0ICs9IGxvZy5kYXRhO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0ZGVyciArPSBsb2cuZGF0YTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGxvZ0J1ZmZlci5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgICAgc3RhdGUucmVzb2x2ZT8uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBTYW5kYm94IG1heSBoYXZlIGJlZW4gc3RvcHBlZCAtIGxvZ3MgZW5kcG9pbnQgcmV0dXJucyA0MjJcbiAgICAgICAgICB9XG4gICAgICAgICAgc3RhdGUuY29uc3VtZWQgPSB0cnVlO1xuICAgICAgICAgIHN0YXRlLnJlc29sdmU/LigpO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIGFzeW5jIGZ1bmN0aW9uKiBsb2dzKCk6IEFzeW5jSXRlcmFibGU8TG9nRW50cnk+IHtcbiAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICAgIHdoaWxlICghc3RhdGUuY29uc3VtZWQgfHwgaW5kZXggPCBsb2dCdWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPCBsb2dCdWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHlpZWxkIGxvZ0J1ZmZlcltpbmRleCsrXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgc3RhdGUucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBzdGF0ZS5yZXNvbHZlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQgPSBjb25zdW1lTG9ncy50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZmluaXNoZWQgPSBhd2FpdCBvdXRwdXQud2FpdCgpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgc3Rkb3V0LFxuICAgICAgICAgICAgICBzdGRlcnIsXG4gICAgICAgICAgICAgIGV4aXRDb2RlOiBmaW5pc2hlZC5leGl0Q29kZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKGlzU2FuZGJveEdvbmVFcnJvcihlKSkge1xuICAgICAgICAgICAgICByZXR1cm4geyBzdGRvdXQsIHN0ZGVyciwgZXhpdENvZGU6IDEgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyBjb21tYW5kSWQ6IG91dHB1dC5jbWRJZCwgbG9ncywgcmVzdWx0IH07XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEZpbGVPbkluc3RhbmNlKFxuICAgIGluc3RhbmNlOiBTYW5kYm94SW5zdGFuY2UsXG4gICAgeyBwYXRoIH06IHsgcGF0aDogc3RyaW5nIH1cbiAgKTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBCdWZmZXIgfCBudWxsPiB7XG4gICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6ICgpID0+IGluc3RhbmNlLnJlYWRGaWxlVG9CdWZmZXIoeyBwYXRoLCBjd2Q6IEhPTUVfRElSIH0pLFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gd3JpdGVGaWxlc09uSW5zdGFuY2UoXG4gICAgaW5zdGFuY2U6IFNhbmRib3hJbnN0YW5jZSxcbiAgICBvcHRzOiB7XG4gICAgICBmaWxlczogeyBwYXRoOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB8IEJ1ZmZlciB9W107XG4gICAgICBkZXN0UGF0aDogc3RyaW5nO1xuICAgIH1cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBmaWxlcywgZGVzdFBhdGggfSA9IG9wdHM7XG4gICAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5hdGl2ZUZpbGVzID0gZmlsZXMubWFwKChmaWxlKSA9PiB7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGgucG9zaXguam9pbihkZXN0UGF0aCwgZmlsZS5wYXRoKTtcbiAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgucG9zaXguaXNBYnNvbHV0ZShmaWxlUGF0aClcbiAgICAgICAgPyBmaWxlUGF0aFxuICAgICAgICA6IHBhdGgucG9zaXguam9pbihIT01FX0RJUiwgZmlsZVBhdGgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGF0aDogYWJzb2x1dGVQYXRoLFxuICAgICAgICBjb250ZW50OlxuICAgICAgICAgIHR5cGVvZiBmaWxlLmNvbnRlbnQgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgID8gQnVmZmVyLmZyb20oZmlsZS5jb250ZW50KVxuICAgICAgICAgICAgOiBmaWxlLmNvbnRlbnQsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgYXdhaXQgaW5zdGFuY2Uud3JpdGVGaWxlcyhuYXRpdmVGaWxlcyk7XG5cbiAgICBjb25zdCBzaGVsbFNjcmlwdHMgPSBuYXRpdmVGaWxlcy5maWx0ZXIoKGYpID0+IGYucGF0aC5lbmRzV2l0aChcIi5zaFwiKSk7XG4gICAgaWYgKHNoZWxsU2NyaXB0cy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBjaG1vZFJlc3VsdCA9IGF3YWl0IGV4ZWNPbkluc3RhbmNlKGluc3RhbmNlLCB7XG4gICAgICAgIGNvbW1hbmQ6IFwiY2htb2RcIixcbiAgICAgICAgYXJnczogW1wiK3hcIiwgLi4uc2hlbGxTY3JpcHRzLm1hcCgoZikgPT4gZi5wYXRoKV0sXG4gICAgICB9KTtcbiAgICAgIGlmIChjaG1vZFJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGNobW9kUmVzdWx0O1xuICAgICAgfVxuICAgICAgYXdhaXQgY2htb2RSZXN1bHQucmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbWluaW1hbCBTYW5kYm94IHdyYXBwZXIgYXJvdW5kIGEgcmF3IFZlcmNlbCBTREsgaW5zdGFuY2UuXG4gICAqIFVzZWQgZm9yIHJ1bm5pbmcgc2V0dXAucnVuKCkgb24gYSB0ZW1wb3Jhcnkgc2FuZGJveCBmb3Igc25hcHNob3QgY3JlYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBjcmVhdGVUZW1wU2FuZGJveChpbnN0YW5jZTogU2FuZGJveEluc3RhbmNlKTogU2FuZGJveCB7XG4gICAgY29uc3QgdGVtcFNhbmRib3g6IFNhbmRib3ggPSB7XG4gICAgICBpZDogYF9fc2V0dXBfdGVtcF8ke0RhdGUubm93KCl9YCxcbiAgICAgIGNvbmZpZyxcbiAgICAgIGV4ZWM6IChvcHRzKSA9PiBleGVjT25JbnN0YW5jZShpbnN0YW5jZSwgb3B0cyksXG4gICAgICByZWFkRmlsZTogKG9wdHMpID0+IHJlYWRGaWxlT25JbnN0YW5jZShpbnN0YW5jZSwgb3B0cyksXG4gICAgICBnZXREb21haW46ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgICBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBcIm5vdCBhdmFpbGFibGUgZHVyaW5nIHNldHVwXCIgfSlcbiAgICAgICAgKSxcbiAgICAgIGtpbGw6ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgICBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBcIm5vdCBhdmFpbGFibGUgZHVyaW5nIHNldHVwXCIgfSlcbiAgICAgICAgKSxcbiAgICAgIHdyaXRlRmlsZXM6IChvcHRzKSA9PiB3cml0ZUZpbGVzT25JbnN0YW5jZShpbnN0YW5jZSwgb3B0cyksXG4gICAgICB1cGRhdGVOZXR3b3JrUG9saWN5OiAocG9saWN5KSA9PlxuICAgICAgICBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICAgIHRyeTogKCkgPT4gaW5zdGFuY2UudXBkYXRlTmV0d29ya1BvbGljeShwb2xpY3kpLFxuICAgICAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgICAgfSksXG4gICAgICB0YWc6IHtcbiAgICAgICAgbGlzdDogYXN5bmMgKCkgPT4gKHt9KSBhcyBUVGFncyxcbiAgICAgICAgZ2V0OiBhc3luYyAoKSA9PiB1bmRlZmluZWQsXG4gICAgICAgIHNldDogYXN5bmMgKCkgPT4gdW5kZWZpbmVkLFxuICAgICAgICBzZXRNYW55OiBhc3luYyAoKSA9PiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIH07XG4gICAgcmV0dXJuIHRlbXBTYW5kYm94O1xuICB9XG5cbiAgLyoqXG4gICAqIFBvbGxzIGZvciBhIHNldHVwIHNuYXBzaG90IHRvIGJlY29tZSBhdmFpbGFibGUuIFJldHVybnMgdGhlIHNuYXBzaG90SWRcbiAgICogaWYgb25lIGFwcGVhcnMgYmVmb3JlIHRoZSBsb2NrIHRpbWVzIG91dCwgb3IgbnVsbCBpZiBpdCBkb2Vzbid0LlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gcG9sbEZvclNldHVwU25hcHNob3Qoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBMT0NLX1RJTUVPVVRfTVM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgTE9DS19QT0xMX0lOVEVSVkFMX01TKSk7XG4gICAgICBjb25zdCByZWNvcmQgPSBhd2FpdCBzdG9yYWdlLnNldHVwLmdldChrZXkpO1xuICAgICAgaWYgKHJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKHJlY29yZD8uc25hcHNob3RJZCkge1xuICAgICAgICByZXR1cm4gcmVjb3JkLnNuYXBzaG90SWQ7XG4gICAgICB9XG4gICAgICAvLyBMb2NrIHJlbGVhc2VkIGJ1dCBubyBzbmFwc2hvdCBcdTIwMTQgY3JlYXRpb24gZmFpbGVkXG4gICAgICBpZiAoIXJlY29yZD8uYWNxdWlyaW5nTG9ja0lkKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgYmFja2dyb3VuZCBzYW5kYm94LCBydW5zIHNldHVwLCBzbmFwc2hvdHMgaXQsIGFuZCBzdG9yZXMgdGhlXG4gICAqIHNuYXBzaG90IElELiBVc2VzIGF0b21pYyBsb2NraW5nIHRvIGVuc3VyZSBvbmx5IG9uZSBwcm9jZXNzIGNyZWF0ZXMgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBmb3JjZSAtIFNraXAgdGhlIFwic25hcHNob3QgYWxyZWFkeSBleGlzdHNcIiBlYXJseSBleGl0LiBVc2VkIHdoZW5cbiAgICogICB0aGUgY2FsbGVyIGtub3dzIHRoZSBleGlzdGluZyBzbmFwc2hvdCBpcyBzdGFsZS9leHBpcmVkLlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU2V0dXBTbmFwc2hvdChvcHRzPzoge1xuICAgIGZvcmNlPzogYm9vbGVhbjtcbiAgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghc2V0dXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc2V0dXBLZXkgPSBzZXR1cC5rZXk7XG5cbiAgICAvLyBDaGVjayBpZiBzbmFwc2hvdCBhbHJlYWR5IGV4aXN0cyAoZmFzdCBwYXRoIFx1MjAxNCBhdm9pZHMgbG9jayBhdHRlbXB0KVxuICAgIGlmICghb3B0cz8uZm9yY2UpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zZXR1cC5nZXQoc2V0dXBLZXkpO1xuICAgICAgaWYgKCEoZXhpc3RpbmcgaW5zdGFuY2VvZiBFcnJvcikgJiYgZXhpc3Rpbmc/LnNuYXBzaG90SWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEF0b21pY2FsbHkgYWNxdWlyZSBsb2NrIChoYW5kbGVzIGFjdGl2ZS1sb2NrIGRldGVjdGlvbiBpbnRlcm5hbGx5KVxuICAgIGRlYnVnKGBbc2FuZGJveDpzZXR1cF0gYWNxdWlyaW5nIGxvY2sgZm9yIHNldHVwIGtleSBcIiR7c2V0dXBLZXl9XCJgKTtcbiAgICBjb25zdCBsb2NrSWQgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgIGNvbnN0IGxvY2tlZCA9IGF3YWl0IHN0b3JhZ2Uuc2V0dXAuYWNxdWlyZUxvY2soXG4gICAgICBzZXR1cEtleSxcbiAgICAgIGxvY2tJZCxcbiAgICAgIExPQ0tfVElNRU9VVF9NU1xuICAgICk7XG4gICAgaWYgKGxvY2tlZCBpbnN0YW5jZW9mIEVycm9yIHx8ICFsb2NrZWQpIHtcbiAgICAgIGRlYnVnKFxuICAgICAgICBgW3NhbmRib3g6c2V0dXBdIGxvY2sgbm90IGFjcXVpcmVkIGZvciBrZXkgXCIke3NldHVwS2V5fVwiIChhbm90aGVyIHByb2Nlc3MgaG9sZHMgaXQpYFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBSZS1jaGVjazogYW5vdGhlciB3b3JrZXIgbWF5IGhhdmUgY3JlYXRlZCB0aGUgc25hcHNob3QgYmV0d2VlbiBvdXJcbiAgICAvLyBwcmUtY2hlY2sgYW5kIGxvY2sgYWNxdWlzaXRpb24uIElmIHNvLCBza2lwIHVubGVzcyBmb3JjZSAoc3RhbGUgc25hcHNob3QpLlxuICAgIGlmICghb3B0cz8uZm9yY2UgJiYgbG9ja2VkLnNuYXBzaG90SWQpIHtcbiAgICAgIGRlYnVnKFxuICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHNuYXBzaG90IGFscmVhZHkgZXhpc3RzIGFmdGVyIGxvY2sgZm9yIGtleSBcIiR7c2V0dXBLZXl9XCIsIHNraXBwaW5nYFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgdGVtcEluc3RhbmNlOiBBd2FpdGVkPFxuICAgICAgUmV0dXJuVHlwZTx0eXBlb2YgVmVyY2VsU2FuZGJveFNESy5jcmVhdGU+XG4gICAgPiB8IG51bGwgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICAvLyBDcmVhdGUgYSB0ZW1wb3Jhcnkgc2FuZGJveCBmb3Igc25hcHNob3R0aW5nLlxuICAgICAgZGVidWcoXG4gICAgICAgIGBbc2FuZGJveDpzZXR1cF0gY3JlYXRpbmcgdGVtcCBzYW5kYm94IGZvciBzbmFwc2hvdCAoa2V5PVwiJHtzZXR1cEtleX1cIilgXG4gICAgICApO1xuICAgICAgdGVtcEluc3RhbmNlID0gYXdhaXQgVmVyY2VsU2FuZGJveFNESy5jcmVhdGUoe1xuICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgdGltZW91dDogVkVSQ0VMX01BWF9USU1FT1VUX01TLFxuICAgICAgICBwb3J0cyxcbiAgICAgICAgbmV0d29ya1BvbGljeSxcbiAgICAgICAgLi4uZ2V0VGVzdENyZWRlbnRpYWxzKCksXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcFNhbmRib3ggPSBjcmVhdGVUZW1wU2FuZGJveChcbiAgICAgICAgdGVtcEluc3RhbmNlIGFzIHVua25vd24gYXMgU2FuZGJveEluc3RhbmNlXG4gICAgICApO1xuICAgICAgYXdhaXQgc2V0dXAucnVuKHRlbXBTYW5kYm94KTtcbiAgICAgIGRlYnVnKFxuICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHNldHVwLnJ1biBjb21wbGV0ZSwgc25hcHNob3R0aW5nIChrZXk9XCIke3NldHVwS2V5fVwiKWBcbiAgICAgICk7XG4gICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHRlbXBJbnN0YW5jZS5zbmFwc2hvdCgpO1xuXG4gICAgICBhd2FpdCBzdG9yYWdlLnNldHVwLnNldCh7XG4gICAgICAgIGtleTogc2V0dXBLZXksXG4gICAgICAgIHNuYXBzaG90SWQ6IHNuYXBzaG90LnNuYXBzaG90SWQsXG4gICAgICAgIGNyZWF0ZWRBdDogbG9ja2VkLmNyZWF0ZWRBdCxcbiAgICAgICAgbGFzdFVzZWRBdDogbnVsbCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICB9KTtcbiAgICAgIGRlYnVnKFxuICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHNuYXBzaG90IHN0b3JlZDogJHtzbmFwc2hvdC5zbmFwc2hvdElkfSAoa2V5PVwiJHtzZXR1cEtleX1cIilgXG4gICAgICApO1xuXG4gICAgICAvLyBTdG9wIHRoZSB0ZW1wIHNhbmRib3ggXHUyMDE0IG5vIGxvbmdlciBuZWVkZWQgYWZ0ZXIgc25hcHNob3R0aW5nXG4gICAgICBhd2FpdCB0ZW1wSW5zdGFuY2Uuc3RvcCgpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgYFtzYW5kYm94OnNldHVwXSBmYWlsZWQgdG8gY3JlYXRlIHNldHVwIHNuYXBzaG90IChrZXk9XCIke3NldHVwS2V5fVwiKTpgLFxuICAgICAgICBlXG4gICAgICApO1xuICAgICAgLy8gU3RvcCB0aGUgdGVtcCBzYW5kYm94IG9uIGZhaWx1cmVcbiAgICAgIGlmICh0ZW1wSW5zdGFuY2UpIHtcbiAgICAgICAgYXdhaXQgdGVtcEluc3RhbmNlLnN0b3AoKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgICAgLy8gQ2xlYW4gdXAgbG9jayBvbiBmYWlsdXJlXG4gICAgICBhd2FpdCBzdG9yYWdlLnNldHVwXG4gICAgICAgIC5zZXQoe1xuICAgICAgICAgIGtleTogc2V0dXBLZXksXG4gICAgICAgICAgc25hcHNob3RJZDogbnVsbCxcbiAgICAgICAgICBjcmVhdGVkQXQ6IGxvY2tlZC5jcmVhdGVkQXQsXG4gICAgICAgICAgbGFzdFVzZWRBdDogbnVsbCxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBkb0dldE9yQ3JlYXRlU2FuZGJveElkKCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgaWYgKGluaXRpYWxWZXJjZWw/LnNhbmRib3hJZCAmJiAhcmVjb3ZlcmVkRnJvbVN0YWxlKSB7XG4gICAgICByZXR1cm4gaW5pdGlhbFZlcmNlbC5zYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgU2FuZGJveE5vdEZvdW5kRXJyb3IpIHtcbiAgICAgICAgLy8gU2FuZGJveCBkb2Vzbid0IGV4aXN0IHlldCwgY29udGludWUgd2l0aCBjcmVhdGlvblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IGV4aXN0aW5nLm1lc3NhZ2UsIGNhdXNlOiBleGlzdGluZyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZ1JlY29yZCA9XG4gICAgICBleGlzdGluZyBpbnN0YW5jZW9mIFNhbmRib3hOb3RGb3VuZEVycm9yID8gbnVsbCA6IGV4aXN0aW5nO1xuICAgIGNvbnN0IGV4aXN0aW5nVmVyY2VsID1cbiAgICAgIGV4aXN0aW5nUmVjb3JkPy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICA/IGV4aXN0aW5nUmVjb3JkLnByb3ZpZGVyTWV0YWRhdGFcbiAgICAgICAgOiBudWxsO1xuXG4gICAgaWYgKGV4aXN0aW5nVmVyY2VsPy5zYW5kYm94SWQpIHtcbiAgICAgIHJldHVybiBleGlzdGluZ1ZlcmNlbC5zYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgY29uc3QgaGFzQWN0aXZlTG9jayA9XG4gICAgICBleGlzdGluZ1JlY29yZD8uYWNxdWlyaW5nTG9ja0lkICYmXG4gICAgICBleGlzdGluZ1JlY29yZC5hY3F1aXJpbmdMb2NrQXQgJiZcbiAgICAgIERhdGUubm93KCkgLSBleGlzdGluZ1JlY29yZC5hY3F1aXJpbmdMb2NrQXQgPCBMT0NLX1RJTUVPVVRfTVM7XG5cbiAgICBpZiAoaGFzQWN0aXZlTG9jaykge1xuICAgICAgcmV0dXJuIHBvbGxGb3JTYW5kYm94SWQoKTtcbiAgICB9XG5cbiAgICBjb25zdCBsb2NrSWQgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgbG9ja2VkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmFjcXVpcmVMb2NrKFxuICAgICAge1xuICAgICAgICBpZCxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICB0YWdzOiBleGlzdGluZ1JlY29yZD8udGFncyA/PyBzYW5kYm94UmVjb3JkLnRhZ3MsXG4gICAgICAgIGNyZWF0ZWRBdDogZXhpc3RpbmdSZWNvcmQ/LmNyZWF0ZWRBdCA/PyBzYW5kYm94UmVjb3JkLmNyZWF0ZWRBdCxcbiAgICAgICAgbGFzdEFjdGl2aXR5QXQ6XG4gICAgICAgICAgZXhpc3RpbmdSZWNvcmQ/Lmxhc3RBY3Rpdml0eUF0ID8/IHNhbmRib3hSZWNvcmQubGFzdEFjdGl2aXR5QXQsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbG9ja0lkLFxuICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG5vdyxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgICBzbmFwc2hvdElkOlxuICAgICAgICAgICAgZXhpc3RpbmdWZXJjZWw/LnNuYXBzaG90SWQgPz8gaW5pdGlhbFZlcmNlbD8uc25hcHNob3RJZCA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIExPQ0tfVElNRU9VVF9NU1xuICAgICk7XG5cbiAgICBpZiAobG9ja2VkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBsb2NrZWQubWVzc2FnZSwgY2F1c2U6IGxvY2tlZCB9KTtcbiAgICB9XG4gICAgaWYgKCFsb2NrZWQpIHtcbiAgICAgIHJldHVybiBwb2xsRm9yU2FuZGJveElkKCk7XG4gICAgfVxuXG4gICAgLy8gQ2FwdHVyZSB0aGUgbG9ja2VkIHJlY29yZCBmb3IgdXNlIGluIHRoZSByZWxlYXNlIGhlbHBlci5cbiAgICAvLyBUUyBjYW4ndCBuYXJyb3cgYGxvY2tlZGAgaW5zaWRlIG5lc3RlZCBmdW5jdGlvbnMsIHNvIHdlIGJpbmQgaXQgaGVyZS5cbiAgICBjb25zdCBsb2NrZWRSZWNvcmQgPSBsb2NrZWQ7XG5cbiAgICAvLyBSZWxlYXNlIHRoZSBzYW5kYm94IGxvY2sgc28gb3RoZXIgd29ya2VycyBjYW4gcmV0cnkgcXVpY2tseVxuICAgIC8vIGluc3RlYWQgb2Ygd2FpdGluZyBmb3IgbG9jayB0aW1lb3V0LlxuICAgIGFzeW5jIGZ1bmN0aW9uIHJlbGVhc2VTYW5kYm94TG9jaygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveFxuICAgICAgICAuc2V0KHtcbiAgICAgICAgICAuLi5sb2NrZWRSZWNvcmQsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgLy8gUmUtY2hlY2sgYWZ0ZXIgbG9jazogYW5vdGhlciB3b3JrZXIgbWF5IGhhdmUgY3JlYXRlZCB0aGUgc2FuZGJveFxuICAgIC8vIGJldHdlZW4gb3VyIGluaXRpYWwgY2hlY2sgYW5kIGxvY2sgYWNxdWlzaXRpb24uXG4gICAgY29uc3QgbG9ja2VkVmVyY2VsID1cbiAgICAgIGxvY2tlZFJlY29yZC5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICA/IGxvY2tlZFJlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICAgIDogbnVsbDtcbiAgICBpZiAobG9ja2VkVmVyY2VsPy5zYW5kYm94SWQpIHtcbiAgICAgIGF3YWl0IHJlbGVhc2VTYW5kYm94TG9jaygpO1xuICAgICAgcmV0dXJuIGxvY2tlZFZlcmNlbC5zYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgc25hcHNob3RJZCA9XG4gICAgICBsb2NrZWRWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGluaXRpYWxWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGNvbmZpZy5saWZlY3ljbGU/LnNuYXBzaG90SWQ7XG4gICAgaWYgKHNuYXBzaG90SWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3Qoc25hcHNob3RJZCk7XG4gICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgY3JlYXRlZEZyb21TbmFwc2hvdCA9IHRydWU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIHNldHVwIHNuYXBzaG90XG4gICAgaWYgKHNldHVwKSB7XG4gICAgICBsZXQgZm9yY2VSZWNyZWF0ZVNuYXBzaG90ID0gZmFsc2U7XG4gICAgICBjb25zdCBzZXR1cFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2V0dXAuZ2V0KHNldHVwLmtleSk7XG4gICAgICBpZiAoIShzZXR1cFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSAmJiBzZXR1cFJlY29yZCkge1xuICAgICAgICBpZiAoc2V0dXBSZWNvcmQuc25hcHNob3RJZCkge1xuICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgYFtzYW5kYm94OnNldHVwXSBmb3VuZCBzZXR1cCBzbmFwc2hvdCAke3NldHVwUmVjb3JkLnNuYXBzaG90SWR9IGZvciBrZXkgXCIke3NldHVwLmtleX1cImBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3QoXG4gICAgICAgICAgICBzZXR1cFJlY29yZC5zbmFwc2hvdElkXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3QgPSB0cnVlO1xuICAgICAgICAgICAgLy8gVXBkYXRlIGxhc3RVc2VkQXQgKGZpcmUtYW5kLWZvcmdldClcbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0dXBcbiAgICAgICAgICAgICAgLnNldCh7XG4gICAgICAgICAgICAgICAgLi4uc2V0dXBSZWNvcmQsXG4gICAgICAgICAgICAgICAgbGFzdFVzZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTbmFwc2hvdCBpcyBzdGFsZS9leHBpcmVkIFx1MjAxNCBmb3JjZSBiYWNrZ3JvdW5kIHRvIG92ZXJ3cml0ZSBpdFxuICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgYFtzYW5kYm94OnNldHVwXSBzbmFwc2hvdCAke3NldHVwUmVjb3JkLnNuYXBzaG90SWR9IGZhaWxlZCAoZXhwaXJlZD8pLCB3aWxsIHJlY3JlYXRlYFxuICAgICAgICAgICk7XG4gICAgICAgICAgZm9yY2VSZWNyZWF0ZVNuYXBzaG90ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzZXR1cFJlY29yZC5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgICAgICBzZXR1cFJlY29yZC5hY3F1aXJpbmdMb2NrQXQgJiZcbiAgICAgICAgICBEYXRlLm5vdygpIC0gc2V0dXBSZWNvcmQuYWNxdWlyaW5nTG9ja0F0IDwgTE9DS19USU1FT1VUX01TXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEFub3RoZXIgcHJvY2VzcyBpcyBjcmVhdGluZyB0aGUgc2V0dXAgc25hcHNob3QgXHUyMDE0IHdhaXQgZm9yIGl0XG4gICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHNuYXBzaG90IGluIHByb2dyZXNzIGZvciBrZXkgXCIke3NldHVwLmtleX1cIiwgd2FpdGluZy4uLmBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHNuYXBzaG90SWQgPSBhd2FpdCBwb2xsRm9yU2V0dXBTbmFwc2hvdChzZXR1cC5rZXkpO1xuICAgICAgICAgIGlmIChzbmFwc2hvdElkKSB7XG4gICAgICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICAgICAgYFtzYW5kYm94OnNldHVwXSBzbmFwc2hvdCByZWFkeTogJHtzbmFwc2hvdElkfSBmb3Iga2V5IFwiJHtzZXR1cC5rZXl9XCJgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY3JlYXRlU2FuZGJveEZyb21TbmFwc2hvdChzbmFwc2hvdElkKTtcbiAgICAgICAgICAgIGlmICghKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICAgICAgICBjcmVhdGVkRnJvbVNuYXBzaG90ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUG9sbCBmYWlsZWQgb3Igc25hcHNob3QgY3JlYXRpb24gZmFpbGVkIFx1MjAxNCBmYWxsIHRocm91Z2ggdG8gY29sZCBwYXRoXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIE5vIHNldHVwIHNuYXBzaG90IGF2YWlsYWJsZSBcdTIwMTQgY3JlYXRlIGZyZXNoIGFuZCBydW4gc2V0dXAgbGF0ZXIuXG4gICAgICAvLyBLaWNrIG9mZiBiYWNrZ3JvdW5kIHNuYXBzaG90IGltbWVkaWF0ZWx5IHNvIGl0IHJ1bnMgaW4gcGFyYWxsZWxcbiAgICAgIC8vIHdpdGggc2V0dXAucnVuIG9uIHRoZSBzZXNzaW9uIHNhbmRib3guXG4gICAgICBkZWJ1ZyhcbiAgICAgICAgYFtzYW5kYm94OnNldHVwXSBubyBzbmFwc2hvdCBmb3Iga2V5IFwiJHtzZXR1cC5rZXl9XCIsIHdpbGwgcnVuIHNldHVwIG9uIHRoaXMgc2FuZGJveGBcbiAgICAgICk7XG4gICAgICBuZWVkc1NldHVwUnVuID0gdHJ1ZTtcbiAgICAgIGNyZWF0ZVNldHVwU25hcHNob3QoeyBmb3JjZTogZm9yY2VSZWNyZWF0ZVNuYXBzaG90IH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgXCJbc2FuZGJveDpzZXR1cF0gZmFpbGVkIHRvIGNyZWF0ZSBiYWNrZ3JvdW5kIHNuYXBzaG90OlwiLFxuICAgICAgICAgIGVcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGZyZXNoUmVzdWx0ID0gYXdhaXQgY3JlYXRlRnJlc2hTYW5kYm94KCk7XG4gICAgaWYgKGZyZXNoUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGF3YWl0IHJlbGVhc2VTYW5kYm94TG9jaygpO1xuICAgIH1cbiAgICByZXR1cm4gZnJlc2hSZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZVNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGNyZWF0ZVByb21pc2VzLmdldChpZCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlID0gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgY3JlYXRlUHJvbWlzZXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcbiAgICBjcmVhdGVQcm9taXNlcy5zZXQoaWQsIHByb21pc2UpO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZG9HZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgY29uc3QgdmVyY2VsU2FuZGJveElkID0gYXdhaXQgZ2V0T3JDcmVhdGVTYW5kYm94SWQoKTtcbiAgICBpZiAodmVyY2VsU2FuZGJveElkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiB2ZXJjZWxTYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6ICgpID0+XG4gICAgICAgIFZlcmNlbFNhbmRib3hTREsuZ2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHZlcmNlbFNhbmRib3hJZCxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSksXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgaWYgKCFzYW5kYm94UHJvbWlzZSkge1xuICAgICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcbiAgICB9XG4gICAgcmV0dXJuIHNhbmRib3hQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVjb3ZlckZyb21TdGFsZVNhbmRib3goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgc2FuZGJveFByb21pc2UgPSBudWxsO1xuICAgIHJlY292ZXJlZEZyb21TdGFsZSA9IHRydWU7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nVmVyY2VsID1cbiAgICAgIGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG5cbiAgICBpZiAoZXhpc3RpbmdWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgIGlkOiBleGlzdGluZy5pZCxcbiAgICAgICAgY29uZmlnOiBleGlzdGluZy5jb25maWcsXG4gICAgICAgIHRhZ3M6IGV4aXN0aW5nLnRhZ3MsXG4gICAgICAgIGNyZWF0ZWRBdDogZXhpc3RpbmcuY3JlYXRlZEF0LFxuICAgICAgICBsYXN0QWN0aXZpdHlBdDogZXhpc3RpbmcubGFzdEFjdGl2aXR5QXQsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgc2FuZGJveElkOiBudWxsLFxuICAgICAgICAgIHNuYXBzaG90SWQ6IGV4aXN0aW5nVmVyY2VsLnNuYXBzaG90SWQsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiB1cGRhdGVMYXN0QWN0aXZpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBsYXN0U2VudCA9IGxhc3RBY3Rpdml0eVNlbnQuZ2V0KGlkKTtcbiAgICBpZiAobGFzdFNlbnQgJiYgbm93IC0gbGFzdFNlbnQgPCBBQ1RJVklUWV9USFJPVFRMRV9NUykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsYXN0QWN0aXZpdHlTZW50LnNldChpZCwgbm93KTtcblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IgfHwgIWV4aXN0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nVmVyY2VsID1cbiAgICAgIGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG4gICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICBpZDogZXhpc3RpbmcuaWQsXG4gICAgICBjb25maWc6IGV4aXN0aW5nLmNvbmZpZyxcbiAgICAgIHRhZ3M6IGV4aXN0aW5nLnRhZ3MsXG4gICAgICBjcmVhdGVkQXQ6IGV4aXN0aW5nLmNyZWF0ZWRBdCxcbiAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICBwcm92aWRlck1ldGFkYXRhOiBleGlzdGluZ1ZlcmNlbCA/PyB7XG4gICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgbGlmZWN5Y2xlOiBTYW5kYm94TGlmZWN5Y2xlID0ge1xuICAgIHN0YXJ0OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHVwZGF0ZUxhc3RBY3Rpdml0eSgpO1xuICAgICAgcmV0dXJuIHNhbmRib3guc3RhdHVzIGFzIFNhbmRib3hTdGF0dXM7XG4gICAgfSxcblxuICAgIHNuYXBzaG90OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICAgICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCBzYW5kYm94LnNuYXBzaG90KCk7XG4gICAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIHRhZ3M6IGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IgPyBudWxsIDogKGV4aXN0aW5nPy50YWdzID8/IG51bGwpLFxuICAgICAgICAgICAgY3JlYXRlZEF0OlxuICAgICAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yID8gbnVsbCA6IChleGlzdGluZz8uY3JlYXRlZEF0ID8/IG51bGwpLFxuICAgICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6XG4gICAgICAgICAgICAgIGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgICAgICAgICA/IG51bGxcbiAgICAgICAgICAgICAgICA6IChleGlzdGluZz8ubGFzdEFjdGl2aXR5QXQgPz8gbnVsbCksXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgICAgICAgIHNuYXBzaG90SWQ6IHNuYXBzaG90LnNuYXBzaG90SWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiB7IHNuYXBzaG90SWQ6IHNuYXBzaG90LnNuYXBzaG90SWQgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIHN0b3A6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc2FuZGJveC5zdG9wKCk7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICAgICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBFcnJvciB8fCAhZXhpc3RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgICAgICAgaWQ6IGV4aXN0aW5nLmlkLFxuICAgICAgICAgICAgY29uZmlnOiBleGlzdGluZy5jb25maWcsXG4gICAgICAgICAgICB0YWdzOiBleGlzdGluZy50YWdzLFxuICAgICAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZy5jcmVhdGVkQXQsXG4gICAgICAgICAgICBsYXN0QWN0aXZpdHlBdDogZXhpc3RpbmcubGFzdEFjdGl2aXR5QXQsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH0sXG4gICAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXRTdGF0dXM6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNhbmRib3guc3RhdHVzIGFzIFNhbmRib3hTdGF0dXM7XG4gICAgfSxcblxuICAgIGdldENyZWF0ZWRBdDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2FuZGJveC5jcmVhdGVkQXQ7XG4gICAgfSxcblxuICAgIGdldFJlbWFpbmluZ1RpbWVvdXQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNhbmRib3gudGltZW91dDtcbiAgICB9LFxuICB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGRvRXhlYyhvcHRzOiB7XG4gICAgY29tbWFuZDogc3RyaW5nO1xuICAgIGFyZ3M/OiBzdHJpbmdbXTtcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgfSkge1xuICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgY29uc3QgdXBkYXRlUHJvbWlzZSA9IHVwZGF0ZUxhc3RBY3Rpdml0eSgpO1xuICAgIGNvbnN0IGV4ZWNSZXN1bHQgPSBhd2FpdCBleGVjT25JbnN0YW5jZShpbnN0YW5jZSwgb3B0cyk7XG4gICAgYXdhaXQgdXBkYXRlUHJvbWlzZTtcbiAgICByZXR1cm4gZXhlY1Jlc3VsdDtcbiAgfVxuXG4gIGNvbnN0IHNhbmRib3g6IFNhbmRib3g8VFRhZ3M+ICYgeyBfb25SZWFkeT86IFByb21pc2U8dm9pZD4gfSA9IHtcbiAgICBpZCxcbiAgICBjb25maWcsXG4gICAgZXhlYzogYXN5bmMgKG9wdHMpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRvRXhlYyhvcHRzKTtcblxuICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFNhbmRib3hFcnJvciAmJiBpc1NhbmRib3hHb25lRXJyb3IocmVzdWx0LmNhdXNlKSkge1xuICAgICAgICBhd2FpdCByZWNvdmVyRnJvbVN0YWxlU2FuZGJveCgpO1xuICAgICAgICByZXR1cm4gYXdhaXQgZG9FeGVjKG9wdHMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICBnZXREb21haW46IGFzeW5jIChwb3J0KSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3guZG9tYWluKHBvcnQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAga2lsbDogYXN5bmMgKHsgY29tbWFuZElkLCBzdG9yYWdlOiBjbWRTdG9yYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjbWQgPSBhd2FpdCBjbWRTdG9yYWdlLmNvbW1hbmQuZ2V0KGNvbW1hbmRJZCk7XG4gICAgICBpZiAoY21kIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IGNtZC5tZXNzYWdlLCBjYXVzZTogY21kIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGNtZCAmJiBjbWQuc3RhdHVzID09PSBcInJ1bm5pbmdcIikge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjbWRTdG9yYWdlLmNvbW1hbmQuc2V0KHtcbiAgICAgICAgICAuLi5jbWQsXG4gICAgICAgICAgc3RhdHVzOiBcImtpbGxlZFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IHJlc3VsdC5tZXNzYWdlLCBjYXVzZTogcmVzdWx0IH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0sXG5cbiAgICByZWFkRmlsZTogYXN5bmMgKG9wdHMpID0+IHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlYWRGaWxlT25JbnN0YW5jZShpbnN0YW5jZSwgb3B0cyk7XG4gICAgfSxcblxuICAgIHdyaXRlRmlsZXM6IGFzeW5jIChvcHRzKSA9PiB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGluc3RhbmNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyaXRlRmlsZXNPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKTtcbiAgICB9LFxuXG4gICAgbGlmZWN5Y2xlLFxuXG4gICAgdXBkYXRlTmV0d29ya1BvbGljeTogYXN5bmMgKHBvbGljeSkgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiAoKSA9PiBpbnN0YW5jZS51cGRhdGVOZXR3b3JrUG9saWN5KHBvbGljeSksXG4gICAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICB0YWc6IHtcbiAgICAgIGxpc3Q6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgICBpZiAoc2FuZGJveFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChzYW5kYm94UmVjb3JkLnRhZ3MgPz8ge30pIGFzIFRUYWdzO1xuICAgICAgfSxcbiAgICAgIGdldDogYXN5bmMgKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3hSZWNvcmQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICAgICAgaWYgKHNhbmRib3hSZWNvcmQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBzYW5kYm94UmVjb3JkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzYW5kYm94UmVjb3JkLnRhZ3M/LltrZXkgYXMgc3RyaW5nXSBhc1xuICAgICAgICAgIHwgVFRhZ3NbdHlwZW9mIGtleV1cbiAgICAgICAgICB8IHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgICBzZXQ6IGFzeW5jIChrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LnRhZy5zZXQoe1xuICAgICAgICAgIHNhbmRib3hJZDogaWQsXG4gICAgICAgICAgdGFnczogeyBba2V5XTogdmFsdWUgfSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgICBzZXRNYW55OiBhc3luYyAodGFnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LnRhZy5zZXQoe1xuICAgICAgICAgIHNhbmRib3hJZDogaWQsXG4gICAgICAgICAgdGFnczogdGFncyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcblxuICBsZXQgb25SZWFkeVByb21pc2U6IFByb21pc2U8dm9pZD4gPSBQcm9taXNlLnJlc29sdmUoKTtcblxuICBpZiAoY29uZmlnLmxpZmVjeWNsZT8uYXV0b1N0YXJ0ICE9PSBmYWxzZSkge1xuICAgIHNhbmRib3hQcm9taXNlID0gZG9HZXRTYW5kYm94KCk7XG5cbiAgICAvLyBBZnRlciBzYW5kYm94IGluc3RhbmNlIGlzIHJlYWR5LCBydW4gc2V0dXAgYW5kL29yIG9uUmVzdGFydC5cbiAgICAvLyBzYW5kYm94UHJvbWlzZSBpcyBhbHJlYWR5IHJlc29sdmVkIGJ5IHRoZSB0aW1lIC50aGVuKCkgcnVucyxcbiAgICAvLyBzbyBzZXR1cC5ydW4gLyBvblJlc3RhcnQgY2FsbGluZyBzYW5kYm94LmV4ZWMoKSB3b24ndCBkZWFkbG9jay5cbiAgICBvblJlYWR5UHJvbWlzZSA9IHNhbmRib3hQcm9taXNlLnRoZW4oYXN5bmMgKGluc3RhbmNlKSA9PiB7XG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChuZWVkc1NldHVwUnVuICYmIHNldHVwKSB7XG4gICAgICAgIGRlYnVnKFxuICAgICAgICAgIGBbc2FuZGJveDpzZXR1cF0gcnVubmluZyBzZXR1cC5ydW4gb24gc2Vzc2lvbiBzYW5kYm94IChrZXk9XCIke3NldHVwLmtleX1cIilgXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHNldHVwLnJ1bihzYW5kYm94KTtcbiAgICAgICAgZGVidWcoXCJbc2FuZGJveDpzZXR1cF0gc2V0dXAucnVuIGNvbXBsZXRlIG9uIHNlc3Npb24gc2FuZGJveFwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNyZWF0ZWRGcm9tU25hcHNob3QgJiYgb25SZXN0YXJ0KSB7XG4gICAgICAgIGRlYnVnKFwiW3NhbmRib3g6c2V0dXBdIHJ1bm5pbmcgb25SZXN0YXJ0IChjcmVhdGVkIGZyb20gc25hcHNob3QpXCIpO1xuICAgICAgICBhd2FpdCBvblJlc3RhcnQoc2FuZGJveCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzYW5kYm94Ll9vblJlYWR5ID0gb25SZWFkeVByb21pc2U7XG4gIHJldHVybiBzYW5kYm94O1xufTtcbiIsICJpbXBvcnQgdHlwZSB7IFRhZ3NTY2hlbWEgfSBmcm9tIFwiLi4vaW5kZXhcIjtcbmltcG9ydCB0eXBlIHsgUnBjRm4sIFNhbmRib3hSZWNvcmQsIFN0b3JhZ2UsIFN0b3JhZ2VDb25maWcgfSBmcm9tIFwiLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHsgZGVidWcgfSBmcm9tIFwiLi4vdXRpbHMvZGVidWdcIjtcbmltcG9ydCB7IGxvY2FsU2FuZGJveCB9IGZyb20gXCIuL2JpbmRpbmdzL2xvY2FsXCI7XG5pbXBvcnQgeyB2ZXJjZWxTYW5kYm94IH0gZnJvbSBcIi4vYmluZGluZ3MvdmVyY2VsXCI7XG5pbXBvcnQgdHlwZSB7IE9uUmVzdGFydCwgU2FuZGJveCwgU2FuZGJveFNldHVwIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBNb2R1bGUtbGV2ZWwgY2FjaGUgZm9yIHNhbmRib3ggaW5zdGFuY2VzIGtleWVkIGJ5IHNhbmRib3ggcmVjb3JkIElELlxuICpcbiAqIE9ubHkgdXNlZCBmb3IgdGhlIFwic2ltcGxlXCIgcGF0aCAobm8gc2V0dXAvb25SZXN0YXJ0KSB3aGljaCBpcyB0aGUgaG90IHBhdGhcbiAqIGNhbGxlZCByZXBlYXRlZGx5IGZyb20gc3RyZWFtVGV4dFN0ZXAgYW5kIHJwYy1kaXNwYXRjaCB0b29scy5leGVjdXRlLlxuICogU2Vzc2lvbi1jcmVhdGlvbiBjYWxscyB0aGF0IHByb3ZpZGUgc2V0dXAvb25SZXN0YXJ0IGFsd2F5cyBjcmVhdGUgZnJlc2guXG4gKi9cbmNvbnN0IHNhbmRib3hDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPFNhbmRib3g+PigpO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0U2FuZGJveDxUVGFncyBleHRlbmRzIFRhZ3NTY2hlbWEgPSBUYWdzU2NoZW1hPih7XG4gIHNhbmRib3hSZWNvcmQsXG4gIHN0b3JhZ2VDb25maWcsXG4gIHN0b3JhZ2UsXG4gIHJwYyxcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3cgPSB0cnVlLFxuICBzZXR1cCxcbiAgb25SZXN0YXJ0LFxufToge1xuICBzdG9yYWdlQ29uZmlnOiBTdG9yYWdlQ29uZmlnO1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkO1xuICBzdG9yYWdlOiBTdG9yYWdlO1xuICBycGM6IFJwY0ZuO1xuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdz86IGJvb2xlYW47XG4gIHNldHVwPzogU2FuZGJveFNldHVwO1xuICBvblJlc3RhcnQ/OiBPblJlc3RhcnQ7XG59KTogUHJvbWlzZTxTYW5kYm94PFRUYWdzPj4ge1xuICAvLyBPbmx5IGNhY2hlIHRoZSBzaW1wbGUgaG90LXBhdGggY2FsbHMgKG5vIHNldHVwL29uUmVzdGFydCkuXG4gIC8vIFNlc3Npb24gY3JlYXRpb24gcGFzc2VzIHNldHVwL29uUmVzdGFydCBhbmQgc2hvdWxkIGFsd2F5cyBjcmVhdGUgZnJlc2guXG4gIGNvbnN0IGNhbkNhY2hlID0gIShzZXR1cCB8fCBvblJlc3RhcnQpO1xuXG4gIGlmIChjYW5DYWNoZSkge1xuICAgIGNvbnN0IGNhY2hlZCA9IHNhbmRib3hDYWNoZS5nZXQoc2FuZGJveFJlY29yZC5pZCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgZGVidWcoXCJbZ2V0U2FuZGJveF0gY2FjaGUgaGl0IGZvclwiLCBzYW5kYm94UmVjb3JkLmlkKTtcbiAgICAgIHJldHVybiBjYWNoZWQgYXMgUHJvbWlzZTxTYW5kYm94PFRUYWdzPj47XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcHJvbWlzZSA9IGNyZWF0ZVNhbmRib3g8VFRhZ3M+KHtcbiAgICBzYW5kYm94UmVjb3JkLFxuICAgIHN0b3JhZ2VDb25maWcsXG4gICAgc3RvcmFnZSxcbiAgICBycGMsXG4gICAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3csXG4gICAgc2V0dXAsXG4gICAgb25SZXN0YXJ0LFxuICB9KTtcblxuICBpZiAoY2FuQ2FjaGUpIHtcbiAgICBzYW5kYm94Q2FjaGUuc2V0KHNhbmRib3hSZWNvcmQuaWQsIHByb21pc2UgYXMgUHJvbWlzZTxTYW5kYm94Pik7XG5cbiAgICAvLyBJZiBjcmVhdGlvbiBmYWlscywgcmVtb3ZlIGZyb20gY2FjaGUgc28gbmV4dCBjYWxsIHJldHJpZXNcbiAgICBwcm9taXNlLmNhdGNoKCgpID0+IHtcbiAgICAgIHNhbmRib3hDYWNoZS5kZWxldGUoc2FuZGJveFJlY29yZC5pZCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYXdhaXQgcHJvbWlzZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlU2FuZGJveDxUVGFncyBleHRlbmRzIFRhZ3NTY2hlbWEgPSBUYWdzU2NoZW1hPih7XG4gIHNhbmRib3hSZWNvcmQsXG4gIHN0b3JhZ2VDb25maWcsXG4gIHN0b3JhZ2UsXG4gIHJwYyxcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3cgPSB0cnVlLFxuICBzZXR1cCxcbiAgb25SZXN0YXJ0LFxufToge1xuICBzdG9yYWdlQ29uZmlnOiBTdG9yYWdlQ29uZmlnO1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkO1xuICBzdG9yYWdlOiBTdG9yYWdlO1xuICBycGM6IFJwY0ZuO1xuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdz86IGJvb2xlYW47XG4gIHNldHVwPzogU2FuZGJveFNldHVwO1xuICBvblJlc3RhcnQ/OiBPblJlc3RhcnQ7XG59KTogUHJvbWlzZTxTYW5kYm94PFRUYWdzPj4ge1xuICBsZXQgc2J4OiBTYW5kYm94PFRUYWdzPiAmIHsgX29uUmVhZHk/OiBQcm9taXNlPHZvaWQ+IH07XG5cbiAgc3dpdGNoIChzYW5kYm94UmVjb3JkLmNvbmZpZy50eXBlKSB7XG4gICAgY2FzZSBcImxvY2FsXCI6XG4gICAgICBzYnggPSBsb2NhbFNhbmRib3g8VFRhZ3M+KHtcbiAgICAgICAgc2FuZGJveFJlY29yZDogc2FuZGJveFJlY29yZCBhcyBTYW5kYm94UmVjb3JkICYge1xuICAgICAgICAgIGNvbmZpZzogeyB0eXBlOiBcImxvY2FsXCIgfTtcbiAgICAgICAgfSxcbiAgICAgICAgc3RvcmFnZSxcbiAgICAgICAgc2V0dXAsXG4gICAgICAgIG9uUmVzdGFydCxcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBcInZlcmNlbFwiOlxuICAgICAgc2J4ID0gdmVyY2VsU2FuZGJveDxUVGFncz4oe1xuICAgICAgICBzYW5kYm94UmVjb3JkOiBzYW5kYm94UmVjb3JkIGFzIFNhbmRib3hSZWNvcmQgJiB7XG4gICAgICAgICAgY29uZmlnOiB7IHR5cGU6IFwidmVyY2VsXCIgfTtcbiAgICAgICAgfSxcbiAgICAgICAgc3RvcmFnZUNvbmZpZyxcbiAgICAgICAgc3RvcmFnZSxcbiAgICAgICAgcnBjLFxuICAgICAgICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdyxcbiAgICAgICAgc2V0dXAsXG4gICAgICAgIG9uUmVzdGFydCxcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBcImN1c3RvbVwiOlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ3VzdG9tIHNhbmRib3hlcyBhcmUgbm90IHN1cHBvcnRlZFwiKTtcbiAgICBkZWZhdWx0OlxuICAgICAgc2FuZGJveFJlY29yZC5jb25maWcgc2F0aXNmaWVzIG5ldmVyO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVW5rbm93biBzYW5kYm94IHR5cGU6ICR7XG4gICAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiAuXG4gICAgICAgICAgKHNhbmRib3hSZWNvcmQuY29uZmlnIGFzIGFueSkudHlwZVxuICAgICAgICB9YFxuICAgICAgKTtcbiAgfVxuXG4gIGlmIChzYnguX29uUmVhZHkpIHtcbiAgICBhd2FpdCBzYnguX29uUmVhZHk7XG4gIH1cbiAgcmV0dXJuIHNieDtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7OztBQUFBLElBQU0sVUFDSixRQUFRLElBQUksZ0JBQWdCLE9BQU8sUUFBUSxJQUFJLGdCQUFnQjtBQUUxRCxTQUFTLFNBQVMsTUFBaUI7QUFDeEMsTUFBSSxTQUFTO0FBQ1gsWUFBUSxJQUFJLEdBQUcsSUFBSTtBQUFBLEVBQ3JCO0FBQ0Y7OztBQ05BLFNBQVMsYUFBYTtBQUN0QixZQUFZLFFBQVE7QUFDcEIsWUFBWUEsV0FBVTtBQUN0QixZQUFZLFlBQVk7QUFDeEIsU0FBUyxZQUFZOzs7QUNMckIsWUFBWSxVQUFVO0FBSXRCLElBQU0sY0FBYztBQUNwQixJQUFNLGdCQUFnQjtBQU90QixlQUFlLFlBQ2IsU0FDQSxNQUNBLFlBQytEO0FBQy9ELFdBQVMsVUFBVSxLQUFLLFdBQVc7QUFDakMsVUFBTSxhQUFhLE1BQU0sUUFBUSxLQUFLLElBQUk7QUFDMUMsUUFBSSxzQkFBc0IsT0FBTztBQUMvQixZQUFNO0FBQUEsSUFDUjtBQUNBLFVBQU0sU0FBUyxNQUFNLFdBQVc7QUFDaEMsUUFBSSxPQUFPLGFBQWEsR0FBRztBQUN6QixhQUFPO0FBQUEsSUFDVDtBQUVBLFVBQU0sY0FBYyxPQUFPLGFBQWEsT0FBTyxDQUFDLE9BQU8sT0FBTyxLQUFLO0FBQ25FLFFBQUksZUFBZSxVQUFVLGFBQWE7QUFDeEMsWUFBTSxJQUFJLFFBQVEsQ0FBQyxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsVUFBVSxFQUFFLENBQUM7QUFDckU7QUFBQSxJQUNGO0FBRUEsVUFBTSxJQUFJO0FBQUEsTUFDUixHQUFHLFVBQVUsbUJBQW1CLE9BQU8sUUFBUSxLQUFLLE9BQU8sTUFBTTtBQUFBLElBQ25FO0FBQUEsRUFDRjtBQUNGO0FBU0EsZUFBc0IsV0FBVyxNQUlmO0FBQ2hCLFFBQU0sRUFBRSxTQUFTLE9BQU8sU0FBUyxJQUFJO0FBRXJDLE1BQUksTUFBTSxXQUFXLEdBQUc7QUFDdEI7QUFBQSxFQUNGO0FBRUEsUUFBTSxZQUFZLE1BQU0sSUFBSSxDQUFDLFNBQWMsV0FBTSxLQUFLLFVBQVUsS0FBSyxJQUFJLENBQUM7QUFDMUUsUUFBTSxhQUFhLE1BQU07QUFBQSxJQUN2QixJQUFJLElBQUksVUFBVSxJQUFJLENBQUMsTUFBVyxXQUFNLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFBQSxFQUNyRDtBQUNBLFFBQU0sZUFBZSxVQUFVLE9BQU8sQ0FBQyxNQUFNLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFFOUQsUUFBTSxjQUFjLE1BQU0sUUFBUSxLQUFLO0FBQUEsSUFDckMsU0FBUztBQUFBLElBQ1QsTUFBTSxDQUFDLE1BQU0sR0FBRyxVQUFVO0FBQUEsRUFDNUIsQ0FBQztBQUNELE1BQUksdUJBQXVCLE9BQU87QUFDaEMsVUFBTTtBQUFBLEVBQ1I7QUFDQSxRQUFNLFlBQVk7QUFFbEIsUUFBTSxhQUFhO0FBRW5CLFdBQVMsSUFBSSxHQUFHLElBQUksTUFBTSxRQUFRLEtBQUs7QUFDckMsVUFBTSxPQUFPLE1BQU0sQ0FBQztBQUNwQixVQUFNLFdBQVcsVUFBVSxDQUFDO0FBQzVCLFVBQU0sZ0JBQWdCLFNBQVMsS0FBSyxPQUFPO0FBRTNDLFFBQUksY0FBYyxTQUFTLFlBQVk7QUFDckMsWUFBTSxTQUFTLE9BQU8sQ0FBQztBQUN2QixZQUFNO0FBQUEsUUFDSjtBQUFBLFFBQ0E7QUFBQSxVQUNFLFNBQVM7QUFBQSxVQUNULE1BQU07QUFBQSxZQUNKO0FBQUEsWUFDQSxlQUFlLE1BQU0sUUFBUSxDQUFDLFFBQVEsTUFBTTtBQUFBLEVBQ3RELGFBQWE7QUFBQSxFQUNiLE1BQU07QUFBQSxVQUNFO0FBQUEsUUFDRjtBQUFBLFFBQ0E7QUFBQSxNQUNGO0FBQUEsSUFDRixPQUFPO0FBQ0wsWUFBTSxVQUFVLGNBQWMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBRTdDLFlBQU0sY0FBYyxNQUFNLFFBQVEsS0FBSztBQUFBLFFBQ3JDLFNBQVM7QUFBQSxRQUNULE1BQU0sQ0FBQyxNQUFNLEtBQUssTUFBTSxPQUFPLENBQUMsRUFBRTtBQUFBLE1BQ3BDLENBQUM7QUFDRCxVQUFJLHVCQUF1QixPQUFPO0FBQ2hDLGNBQU07QUFBQSxNQUNSO0FBQ0EsWUFBTSxZQUFZO0FBRWxCLGVBQ00sU0FBUyxHQUNiLFNBQVMsY0FBYyxRQUN2QixVQUFVLFlBQ1Y7QUFDQSxjQUFNLFFBQVEsY0FBYyxNQUFNLFFBQVEsU0FBUyxVQUFVO0FBQzdELGNBQU0sU0FBUyxTQUFTLE1BQU07QUFDOUIsY0FBTTtBQUFBLFVBQ0o7QUFBQSxVQUNBO0FBQUEsWUFDRSxTQUFTO0FBQUEsWUFDVCxNQUFNO0FBQUEsY0FDSjtBQUFBLGNBQ0EsVUFBVSxNQUFNLE9BQU8sQ0FBQyxRQUFRLE1BQU07QUFBQSxFQUNsRCxLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsWUFDSTtBQUFBLFVBQ0Y7QUFBQSxVQUNBO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFFQSxZQUFNO0FBQUEsUUFDSjtBQUFBLFFBQ0E7QUFBQSxVQUNFLFNBQVM7QUFBQSxVQUNULE1BQU07QUFBQSxZQUNKO0FBQUEsWUFDQSxlQUFlLE1BQU0sT0FBTyxDQUFDLE1BQU0sTUFBTSxRQUFRLENBQUMsYUFBYSxNQUFNLE9BQU8sQ0FBQztBQUFBLFVBQy9FO0FBQUEsUUFDRjtBQUFBLFFBQ0E7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxNQUFJLGFBQWEsU0FBUyxHQUFHO0FBQzNCLFVBQU0sY0FBYyxNQUFNLFFBQVEsS0FBSztBQUFBLE1BQ3JDLFNBQVM7QUFBQSxNQUNULE1BQU0sQ0FBQyxNQUFNLEdBQUcsWUFBWTtBQUFBLElBQzlCLENBQUM7QUFDRCxRQUFJLHVCQUF1QixPQUFPO0FBQ2hDLFlBQU07QUFBQSxJQUNSO0FBQ0EsVUFBTSxZQUFZO0FBQUEsRUFDcEI7QUFDRjtBQUVBLFNBQVMsU0FBUyxTQUFrQztBQUNsRCxNQUFJLE9BQU8sWUFBWSxVQUFVO0FBQy9CLFdBQU8sT0FBTyxLQUFLLE9BQU8sRUFBRSxTQUFTLFFBQVE7QUFBQSxFQUMvQztBQUNBLFNBQU8sUUFBUSxTQUFTLFFBQVE7QUFDbEM7QUFFQSxTQUFTLE1BQU0sR0FBbUI7QUFDaEMsU0FBTyxJQUFJLEVBQUUsUUFBUSxNQUFNLE9BQU8sQ0FBQztBQUNyQzs7O0FEdEpPLElBQU0sZUFBZSxDQUF3QztBQUFBLEVBQ2xFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0YsTUFLcUQ7QUFDbkQsUUFBTSxTQUFTLGNBQWM7QUFDN0IsUUFBTSxXQUFXLE9BQU8sUUFBUSxRQUFRLElBQUk7QUFDNUMsUUFBTSxZQUFZLG9CQUFJLElBQTBCO0FBRWhELFFBQU0sVUFBMEI7QUFBQSxJQUM5QixJQUFJLGNBQWM7QUFBQSxJQUNsQixRQUFRLGNBQWM7QUFBQSxJQUN0QixNQUFNLENBQUMsRUFBRSxTQUFTLE1BQU0sT0FBTyxNQUFNO0FBQ25DLGFBQWMsZ0JBQVM7QUFBQSxRQUNyQixLQUFLLE1BQU07QUFDVCxnQkFBTSxZQUFZLFdBQVcsS0FBSyxDQUFDO0FBRW5DLGdCQUFNLFFBQVEsTUFBTSxTQUFTLE1BQU07QUFBQSxZQUNqQyxLQUFLO0FBQUEsWUFDTDtBQUFBLFVBQ0YsQ0FBQztBQUVELG9CQUFVLElBQUksV0FBVyxLQUFLO0FBRTlCLGNBQUksU0FBUztBQUNiLGNBQUksU0FBUztBQUNiLGdCQUFNLFdBQXVCLENBQUM7QUFDOUIsY0FBSSxhQUFrQztBQUN0QyxjQUFJLFNBQVM7QUFFYixnQkFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFNBQTBCO0FBQ2pELGtCQUFNLE1BQU0sT0FBTyxJQUFJO0FBQ3ZCLHNCQUFVO0FBQ1YscUJBQVMsS0FBSyxFQUFFLFFBQVEsVUFBVSxNQUFNLElBQUksQ0FBQztBQUM3Qyx5QkFBYTtBQUFBLFVBQ2YsQ0FBQztBQUVELGdCQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBMEI7QUFDakQsa0JBQU0sTUFBTSxPQUFPLElBQUk7QUFDdkIsc0JBQVU7QUFDVixxQkFBUyxLQUFLLEVBQUUsUUFBUSxVQUFVLE1BQU0sSUFBSSxDQUFDO0FBQzdDLHlCQUFhO0FBQUEsVUFDZixDQUFDO0FBRUQsZ0JBQU1DLFVBQVMsSUFBSSxRQUloQixDQUFDLFNBQVMsV0FBVztBQUN0QixrQkFBTSxHQUFHLFNBQVMsQ0FBQyxRQUFRO0FBQ3pCLHdCQUFVLE9BQU8sU0FBUztBQUMxQix1QkFBUztBQUNULDJCQUFhO0FBQ2IscUJBQU8sR0FBRztBQUFBLFlBQ1osQ0FBQztBQUVELGtCQUFNLEdBQUcsU0FBUyxDQUFDLFNBQXdCO0FBQ3pDLHdCQUFVLE9BQU8sU0FBUztBQUMxQix1QkFBUztBQUNULDJCQUFhO0FBQ2Isc0JBQVEsRUFBRSxRQUFRLFFBQVEsVUFBVSxRQUFRLEVBQUUsQ0FBQztBQUFBLFlBQ2pELENBQUM7QUFBQSxVQUNILENBQUM7QUFFRCwwQkFBZ0IsT0FBZ0M7QUFDOUMsbUJBQU8sQ0FBQyxVQUFVLFNBQVMsU0FBUyxHQUFHO0FBQ3JDLG9CQUFNLFFBQVEsU0FBUyxNQUFNO0FBQzdCLGtCQUFJLE9BQU87QUFDVCxzQkFBTTtBQUFBLGNBQ1IsV0FBVyxDQUFDLFFBQVE7QUFDbEIsc0JBQU0sSUFBSSxRQUFjLENBQUMsWUFBWTtBQUNuQywrQkFBYTtBQUFBLGdCQUNmLENBQUM7QUFDRCw2QkFBYTtBQUFBLGNBQ2Y7QUFBQSxZQUNGO0FBQUEsVUFDRjtBQUVBLGlCQUFPLFFBQVEsUUFBUSxFQUFFLFdBQVcsTUFBTSxRQUFBQSxRQUFPLENBQUM7QUFBQSxRQUNwRDtBQUFBLFFBQ0EsT0FBTyxDQUFDLE1BQ04sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ3BELENBQUM7QUFBQSxJQUNIO0FBQUEsSUFFQSxXQUFXLENBQUMsU0FBUztBQUNuQixhQUFPLFFBQVEsUUFBUSxvQkFBb0IsSUFBSSxFQUFFO0FBQUEsSUFDbkQ7QUFBQSxJQUVBLE1BQU0sT0FBTyxFQUFFLFdBQVcsU0FBQUMsU0FBUSxNQUFNO0FBQ3RDLFlBQU0sUUFBUSxVQUFVLElBQUksU0FBUztBQUNyQyxVQUFJLENBQUMsT0FBTztBQUNWLGVBQU8sSUFBSSxhQUFhO0FBQUEsVUFDdEIsUUFBUSxXQUFXLFNBQVM7QUFBQSxRQUM5QixDQUFDO0FBQUEsTUFDSDtBQUVBLFlBQU0sS0FBSyxTQUFTO0FBRXBCLFlBQU0sTUFBTSxNQUFNQSxTQUFRLFFBQVEsSUFBSSxTQUFTO0FBQy9DLFVBQUksZUFBZSxPQUFPO0FBQ3hCLGVBQU8sSUFBSSxhQUFhLEVBQUUsUUFBUSxJQUFJLFNBQVMsT0FBTyxJQUFJLENBQUM7QUFBQSxNQUM3RDtBQUNBLFVBQUksT0FBTyxJQUFJLFdBQVcsV0FBVztBQUNuQyxjQUFNRCxVQUFTLE1BQU1DLFNBQVEsUUFBUSxJQUFJO0FBQUEsVUFDdkMsR0FBRztBQUFBLFVBQ0gsUUFBUTtBQUFBLFFBQ1YsQ0FBQztBQUNELFlBQUlELG1CQUFrQixPQUFPO0FBQzNCLGlCQUFPLElBQUksYUFBYSxFQUFFLFFBQVFBLFFBQU8sU0FBUyxPQUFPQSxRQUFPLENBQUM7QUFBQSxRQUNuRTtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsSUFFQSxVQUFVLE9BQU8sRUFBRSxNQUFNLFNBQVMsTUFBTTtBQUN0QyxZQUFNLFdBQWdCLFdBQUssVUFBVSxRQUFRO0FBQzdDLFVBQUk7QUFDRixlQUFPLE1BQVMsWUFBUyxRQUFRO0FBQUEsTUFDbkMsU0FBUyxHQUFZO0FBQ25CLFlBQ0UsYUFBYSxTQUNiLFVBQVUsS0FDVCxFQUE0QixTQUFTLFVBQ3RDO0FBQ0EsaUJBQU87QUFBQSxRQUNUO0FBQ0EsZUFBTyxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsTUFDekQ7QUFBQSxJQUNGO0FBQUEsSUFFQSxZQUFZLENBQUMsU0FBUyxXQUFXLEVBQUUsU0FBUyxHQUFHLEtBQUssQ0FBQztBQUFBLElBRXJELHFCQUFxQixNQUNuQixRQUFRO0FBQUEsTUFDTixJQUFJLGFBQWE7QUFBQSxRQUNmLFFBQVE7QUFBQSxNQUNWLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFFRixLQUFLO0FBQUEsTUFDSCxNQUFNLFlBQVk7QUFDaEIsY0FBTUUsaUJBQWdCLE1BQU0sUUFBUSxRQUFRLElBQUksUUFBUSxFQUFFO0FBQzFELFlBQUlBLDBCQUF5QixPQUFPO0FBQ2xDLGlCQUFPQTtBQUFBLFFBQ1Q7QUFDQSxlQUFRQSxlQUFjLFFBQVEsQ0FBQztBQUFBLE1BQ2pDO0FBQUEsTUFDQSxLQUFLLE9BQU8sUUFBZ0I7QUFDMUIsY0FBTUEsaUJBQWdCLE1BQU0sUUFBUSxRQUFRLElBQUksUUFBUSxFQUFFO0FBQzFELFlBQUlBLDBCQUF5QixPQUFPO0FBQ2xDLGlCQUFPQTtBQUFBLFFBQ1Q7QUFDQSxlQUFPQSxlQUFjLE9BQU8sR0FBYTtBQUFBLE1BRzNDO0FBQUEsTUFDQSxLQUFLLE9BQU8sS0FBYSxVQUFtQjtBQUMxQyxjQUFNRixVQUFTLE1BQU0sUUFBUSxRQUFRLElBQUksSUFBSTtBQUFBLFVBQzNDLFdBQVcsUUFBUTtBQUFBLFVBQ25CLE1BQU0sRUFBRSxDQUFDLEdBQUcsR0FBRyxNQUFNO0FBQUEsUUFDdkIsQ0FBQztBQUNELFlBQUlBLG1CQUFrQixPQUFPO0FBQzNCLGlCQUFPQTtBQUFBLFFBQ1Q7QUFDQSxlQUFPO0FBQUEsTUFDVDtBQUFBLE1BQ0EsU0FBUyxPQUFPLFNBQWtDO0FBQ2hELGNBQU1BLFVBQVMsTUFBTSxRQUFRLFFBQVEsSUFBSSxJQUFJO0FBQUEsVUFDM0MsV0FBVyxRQUFRO0FBQUEsVUFDbkI7QUFBQSxRQUNGLENBQUM7QUFDRCxZQUFJQSxtQkFBa0IsT0FBTztBQUMzQixpQkFBT0E7QUFBQSxRQUNUO0FBQ0EsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUVBLFFBQU0sU0FBd0Q7QUFFOUQsTUFBSSxTQUFTLFdBQVc7QUFDdEIsV0FBTyxZQUFZLFlBQVk7QUFDN0IsVUFBSSxhQUFhLENBQUMsQ0FBQztBQUNuQixVQUFJLE9BQU87QUFDVCxjQUFNLFdBQVcsTUFBTSxRQUFRLE1BQU0sSUFBSSxNQUFNLEdBQUc7QUFDbEQsWUFBSSxFQUFFLG9CQUFvQixVQUFVLFVBQVU7QUFDNUM7QUFBQSxZQUNFLG1EQUFtRCxNQUFNLEdBQUc7QUFBQSxVQUM5RDtBQUNBLHVCQUFhO0FBQUEsUUFDZjtBQUFBLE1BQ0Y7QUFDQSxVQUFJLGNBQWMsT0FBTztBQUN2QixjQUFNLGtEQUFrRCxNQUFNLEdBQUcsSUFBSTtBQUNyRSxjQUFNLE1BQU0sSUFBSSxPQUFPO0FBQ3ZCLGNBQU0sUUFBUSxNQUFNLElBQUk7QUFBQSxVQUN0QixLQUFLLE1BQU07QUFBQSxVQUNYLFlBQVk7QUFBQSxVQUNaLFdBQVcsS0FBSyxJQUFJO0FBQUEsVUFDcEIsWUFBWTtBQUFBLFVBQ1osaUJBQWlCO0FBQUEsVUFDakIsaUJBQWlCO0FBQUEsUUFDbkIsQ0FBQztBQUNEO0FBQUEsVUFDRSx1REFBdUQsTUFBTSxHQUFHO0FBQUEsUUFDbEU7QUFBQSxNQUNGO0FBQ0EsVUFBSSxXQUFXO0FBQ2IsY0FBTSwyQ0FBMkM7QUFDakQsY0FBTSxVQUFVLE9BQU87QUFBQSxNQUN6QjtBQUFBLElBQ0YsR0FBRztBQUFBLEVBQ0w7QUFFQSxTQUFPO0FBQ1Q7OztBRTNPQSxZQUFZRyxXQUFVO0FBQ3RCLFlBQVlDLGFBQVk7QUFDeEIsU0FBUyxXQUFXLHdCQUF3QjtBQUM1QyxTQUFTLGFBQWE7QUEyQmYsSUFBTSx3QkFBd0IsSUFBSSxLQUFLLEtBQUs7QUFDbkQsSUFBTSxrQkFBa0IsSUFBSSxLQUFLO0FBQ2pDLElBQU0sd0JBQXdCO0FBRTlCLElBQU0scUJBQXFCLE1BQ3pCLFFBQVEsSUFBSSxhQUFhLFNBQ3JCO0FBQUEsRUFDRSxPQUFPLFFBQVEsSUFBSTtBQUFBLEVBQ25CLFFBQVEsUUFBUSxJQUFJO0FBQUEsRUFDcEIsV0FBVyxRQUFRLElBQUk7QUFDekIsSUFDQSxDQUFDO0FBTVAsSUFBTSxpQkFBaUIsb0JBQUksSUFBNEM7QUFFdkUsSUFBTSx1QkFBdUI7QUFDN0IsSUFBTSxtQkFBbUIsb0JBQUksSUFBb0I7QUFFakQsSUFBTSxnQkFBZ0I7QUFFdEIsU0FBUyxtQkFBbUIsR0FBcUI7QUFDL0MsTUFBSSxFQUFFLGFBQWEsUUFBUTtBQUN6QixXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sb0JBQW9CO0FBQzFCLFFBQU0saUJBQWlCO0FBRXZCLFFBQU0sU0FDSixrQkFBa0IsVUFBVSxVQUM1QixlQUFlLE9BQU8sVUFBVTtBQUVsQyxNQUFJLFdBQVcsT0FBTyxXQUFXLEtBQUs7QUFDcEMsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLFVBQVUsRUFBRSxXQUFXLE9BQU8sQ0FBQztBQUNyQyxNQUNFLFFBQVEsU0FBUyxtQ0FBbUMsS0FDcEQsUUFBUSxTQUFTLDJCQUEyQixHQUM1QztBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsU0FBTztBQUNUO0FBRU8sSUFBTSxnQkFBZ0IsQ0FBd0M7QUFBQSxFQUNuRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUNGLE1BUXFEO0FBQ25ELFFBQU0sRUFBRSxJQUFJLE9BQU8sSUFBSTtBQUN2QixRQUFNLFFBQVEsT0FBTyxXQUFXLFNBQVM7QUFDekMsUUFBTSxRQUFRLE9BQU87QUFDckIsUUFBTSxnQkFBZ0IsT0FBTztBQUM3QixRQUFNLGdCQUNKLGNBQWMsa0JBQWtCLGFBQWEsV0FDekMsY0FBYyxtQkFDZDtBQUdOLE1BQUksaUJBQWlFO0FBQ3JFLE1BQUkscUJBQXFCO0FBQ3pCLE1BQUksc0JBQXNCO0FBQzFCLE1BQUksZ0JBQWdCO0FBQ3BCLFFBQU0sV0FBVztBQUVqQixpQkFBZSxtQkFBbUQ7QUFDaEUsVUFBTSxXQUFXLEtBQUssSUFBSSxJQUFJO0FBQzlCLFdBQU8sS0FBSyxJQUFJLElBQUksVUFBVTtBQUM1QixZQUFNLElBQUksUUFBUSxDQUFDLE1BQU0sV0FBVyxHQUFHLHFCQUFxQixDQUFDO0FBQzdELFlBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDM0MsVUFBSSxrQkFBa0IsT0FBTztBQUMzQixlQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxTQUFTLE9BQU8sT0FBTyxDQUFDO0FBQUEsTUFDbkU7QUFDQSxZQUFNLGtCQUNKLFFBQVEsa0JBQWtCLGFBQWEsV0FDbkMsT0FBTyxpQkFBaUIsWUFDeEI7QUFDTixVQUFJLGlCQUFpQjtBQUNuQixlQUFPO0FBQUEsTUFDVDtBQUNBLFVBQUksQ0FBQyxRQUFRLGlCQUFpQjtBQUM1QixjQUFNLGFBQWEsTUFBTSxRQUFRLFFBQVEsSUFBSSxFQUFFO0FBQy9DLFlBQUksc0JBQXNCLE9BQU87QUFDL0IsaUJBQU8sSUFBSSxhQUFhO0FBQUEsWUFDdEIsUUFBUSxXQUFXO0FBQUEsWUFDbkIsT0FBTztBQUFBLFVBQ1QsQ0FBQztBQUFBLFFBQ0g7QUFDQSxjQUFNLHVCQUNKLFlBQVksa0JBQWtCLGFBQWEsV0FDdkMsV0FBVyxpQkFBaUIsWUFDNUI7QUFDTixZQUFJLHNCQUFzQjtBQUN4QixpQkFBTztBQUFBLFFBQ1Q7QUFDQSxlQUFPLHVCQUF1QjtBQUFBLE1BQ2hDO0FBQUEsSUFDRjtBQUNBLFdBQU8sSUFBSSxhQUFhO0FBQUEsTUFDdEIsUUFBUTtBQUFBLElBQ1YsQ0FBQztBQUFBLEVBQ0g7QUFFQSxpQkFBZSx1QkFDYixpQkFDZTtBQUNmLFFBQUksQ0FBQyx5QkFBeUI7QUFDNUI7QUFBQSxJQUNGO0FBQ0EsVUFBTSxpQkFBd0M7QUFBQSxNQUM1QztBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLElBQ0Y7QUFDQSxVQUFNLE1BQU0sMEJBQTBCLENBQUMsRUFBRSxPQUFPLGVBQWUsQ0FBQyxDQUFDLEVBQUU7QUFBQTtBQUFBLE1BRWpFLE1BQU07QUFBQSxNQUFDO0FBQUEsSUFDVDtBQUFBLEVBQ0Y7QUFFQSxpQkFBZSwwQkFDYixZQUNnQztBQUNoQyxXQUFPLE1BQWEsaUJBQVM7QUFBQSxNQUMzQixLQUFLLFlBQVk7QUFDZixjQUFNQyxXQUFVLE1BQU0saUJBQWlCLE9BQU87QUFBQSxVQUM1QyxRQUFRLEVBQUUsTUFBTSxZQUFZLFdBQVc7QUFBQSxVQUN2QyxXQUFXLEVBQUUsTUFBTTtBQUFBLFVBQ25CLFNBQVM7QUFBQSxVQUNUO0FBQUEsVUFDQTtBQUFBLFVBQ0EsR0FBRyxtQkFBbUI7QUFBQSxRQUN4QixDQUFDO0FBQ0QsY0FBTSxNQUFNLEtBQUssSUFBSTtBQUNyQixjQUFNLFFBQVEsUUFBUSxJQUFJO0FBQUEsVUFDeEI7QUFBQSxVQUNBO0FBQUEsVUFDQSxNQUFNLGNBQWM7QUFBQSxVQUNwQixXQUFXO0FBQUEsVUFDWCxnQkFBZ0I7QUFBQSxVQUNoQixpQkFBaUI7QUFBQSxVQUNqQixpQkFBaUI7QUFBQSxVQUNqQixrQkFBa0I7QUFBQSxZQUNoQixVQUFVO0FBQUEsWUFDVixXQUFXQSxTQUFRO0FBQUEsWUFDbkI7QUFBQSxVQUNGO0FBQUEsUUFDRixDQUFDO0FBQ0QsY0FBTSx1QkFBdUJBLFNBQVEsU0FBUztBQUM5QyxlQUFPQSxTQUFRO0FBQUEsTUFDakI7QUFBQSxNQUNBLE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxJQUNoRSxDQUFDO0FBQUEsRUFDSDtBQUVBLGlCQUFlLHFCQUFxRDtBQUNsRSxXQUFPLE1BQWEsaUJBQVM7QUFBQSxNQUMzQixLQUFLLFlBQVk7QUFDZixjQUFNQSxXQUFVLE1BQU0saUJBQWlCLE9BQU87QUFBQSxVQUM1QyxXQUFXLEVBQUUsTUFBTTtBQUFBLFVBQ25CLFNBQVM7QUFBQSxVQUNUO0FBQUEsVUFDQTtBQUFBLFVBQ0EsR0FBRyxtQkFBbUI7QUFBQSxRQUN4QixDQUFDO0FBQ0QsY0FBTSxNQUFNLEtBQUssSUFBSTtBQUNyQixjQUFNLFFBQVEsUUFBUSxJQUFJO0FBQUEsVUFDeEI7QUFBQSxVQUNBO0FBQUEsVUFDQSxNQUFNLGNBQWM7QUFBQSxVQUNwQixXQUFXO0FBQUEsVUFDWCxnQkFBZ0I7QUFBQSxVQUNoQixpQkFBaUI7QUFBQSxVQUNqQixpQkFBaUI7QUFBQSxVQUNqQixrQkFBa0I7QUFBQSxZQUNoQixVQUFVO0FBQUEsWUFDVixXQUFXQSxTQUFRO0FBQUEsWUFDbkIsWUFBWTtBQUFBLFVBQ2Q7QUFBQSxRQUNGLENBQUM7QUFDRCxjQUFNLHVCQUF1QkEsU0FBUSxTQUFTO0FBQzlDLGVBQU9BLFNBQVE7QUFBQSxNQUNqQjtBQUFBLE1BQ0EsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLElBQ2hFLENBQUM7QUFBQSxFQUNIO0FBTUEsV0FBUyxlQUNQLFVBQ0E7QUFBQSxJQUNFO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGLEdBUUE7QUFDQSxXQUFjLGlCQUFTO0FBQUEsTUFDckIsS0FBSyxZQUFZO0FBQ2YsY0FBTSxTQUFTLE1BQU0sU0FBUyxXQUFXO0FBQUEsVUFDdkMsS0FBSztBQUFBLFVBQ0w7QUFBQSxVQUNBLEtBQUs7QUFBQSxVQUNMO0FBQUEsVUFDQSxVQUFVO0FBQUEsUUFDWixDQUFDO0FBRUQsWUFBSSxTQUFTO0FBQ2IsWUFBSSxTQUFTO0FBQ2IsY0FBTSxZQUF3QixDQUFDO0FBQy9CLGNBQU0sUUFBUTtBQUFBLFVBQ1osU0FBUztBQUFBLFVBQ1QsVUFBVTtBQUFBLFFBQ1o7QUFFQSxjQUFNLGVBQWUsWUFBWTtBQUMvQixjQUFJO0FBQ0YsNkJBQWlCLE9BQU8sT0FBTyxLQUFLLEdBQUc7QUFDckMsb0JBQU0sUUFDSixJQUFJLFdBQVcsV0FDWCxFQUFFLFFBQVEsVUFBVSxNQUFNLElBQUksS0FBSyxJQUNuQyxFQUFFLFFBQVEsVUFBVSxNQUFNLElBQUksS0FBSztBQUV6QyxrQkFBSSxJQUFJLFdBQVcsVUFBVTtBQUMzQiwwQkFBVSxJQUFJO0FBQUEsY0FDaEIsT0FBTztBQUNMLDBCQUFVLElBQUk7QUFBQSxjQUNoQjtBQUVBLHdCQUFVLEtBQUssS0FBSztBQUNwQixvQkFBTSxVQUFVO0FBQUEsWUFDbEI7QUFBQSxVQUNGLFFBQVE7QUFBQSxVQUVSO0FBQ0EsZ0JBQU0sV0FBVztBQUNqQixnQkFBTSxVQUFVO0FBQUEsUUFDbEIsR0FBRztBQUVILHdCQUFnQixPQUFnQztBQUM5QyxjQUFJLFFBQVE7QUFDWixpQkFBTyxDQUFDLE1BQU0sWUFBWSxRQUFRLFVBQVUsUUFBUTtBQUNsRCxnQkFBSSxRQUFRLFVBQVUsUUFBUTtBQUM1QixvQkFBTSxVQUFVLE9BQU87QUFBQSxZQUN6QixPQUFPO0FBQ0wsb0JBQU0sSUFBSSxRQUFjLENBQUMsWUFBWTtBQUNuQyxzQkFBTSxVQUFVO0FBQUEsY0FDbEIsQ0FBQztBQUNELG9CQUFNLFVBQVU7QUFBQSxZQUNsQjtBQUFBLFVBQ0Y7QUFBQSxRQUNGO0FBRUEsY0FBTSxTQUFTLFlBQVksS0FBSyxZQUFZO0FBQzFDLGNBQUk7QUFDRixrQkFBTSxXQUFXLE1BQU0sT0FBTyxLQUFLO0FBQ25DLG1CQUFPO0FBQUEsY0FDTDtBQUFBLGNBQ0E7QUFBQSxjQUNBLFVBQVUsU0FBUztBQUFBLFlBQ3JCO0FBQUEsVUFDRixTQUFTLEdBQUc7QUFDVixnQkFBSSxtQkFBbUIsQ0FBQyxHQUFHO0FBQ3pCLHFCQUFPLEVBQUUsUUFBUSxRQUFRLFVBQVUsRUFBRTtBQUFBLFlBQ3ZDO0FBQ0Esa0JBQU07QUFBQSxVQUNSO0FBQUEsUUFDRixDQUFDO0FBRUQsZUFBTyxFQUFFLFdBQVcsT0FBTyxPQUFPLE1BQU0sT0FBTztBQUFBLE1BQ2pEO0FBQUEsTUFDQSxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsSUFDaEUsQ0FBQztBQUFBLEVBQ0g7QUFFQSxXQUFTLG1CQUNQLFVBQ0EsRUFBRSxNQUFBQyxNQUFLLEdBQ2dDO0FBQ3ZDLFdBQWMsaUJBQVM7QUFBQSxNQUNyQixLQUFLLE1BQU0sU0FBUyxpQkFBaUIsRUFBRSxNQUFBQSxPQUFNLEtBQUssU0FBUyxDQUFDO0FBQUEsTUFDNUQsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLElBQ2hFLENBQUM7QUFBQSxFQUNIO0FBRUEsaUJBQWUscUJBQ2IsVUFDQSxNQUllO0FBQ2YsVUFBTSxFQUFFLE9BQU8sU0FBUyxJQUFJO0FBQzVCLFFBQUksTUFBTSxXQUFXLEdBQUc7QUFDdEI7QUFBQSxJQUNGO0FBRUEsVUFBTSxjQUFjLE1BQU0sSUFBSSxDQUFDLFNBQVM7QUFDdEMsWUFBTSxXQUFnQixZQUFNLEtBQUssVUFBVSxLQUFLLElBQUk7QUFDcEQsWUFBTSxlQUFvQixZQUFNLFdBQVcsUUFBUSxJQUMvQyxXQUNLLFlBQU0sS0FBSyxVQUFVLFFBQVE7QUFDdEMsYUFBTztBQUFBLFFBQ0wsTUFBTTtBQUFBLFFBQ04sU0FDRSxPQUFPLEtBQUssWUFBWSxXQUNwQixPQUFPLEtBQUssS0FBSyxPQUFPLElBQ3hCLEtBQUs7QUFBQSxNQUNiO0FBQUEsSUFDRixDQUFDO0FBRUQsVUFBTSxTQUFTLFdBQVcsV0FBVztBQUVyQyxVQUFNLGVBQWUsWUFBWSxPQUFPLENBQUMsTUFBTSxFQUFFLEtBQUssU0FBUyxLQUFLLENBQUM7QUFDckUsUUFBSSxhQUFhLFNBQVMsR0FBRztBQUMzQixZQUFNLGNBQWMsTUFBTSxlQUFlLFVBQVU7QUFBQSxRQUNqRCxTQUFTO0FBQUEsUUFDVCxNQUFNLENBQUMsTUFBTSxHQUFHLGFBQWEsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUM7QUFBQSxNQUNqRCxDQUFDO0FBQ0QsVUFBSSx1QkFBdUIsT0FBTztBQUNoQyxjQUFNO0FBQUEsTUFDUjtBQUNBLFlBQU0sWUFBWTtBQUFBLElBQ3BCO0FBQUEsRUFDRjtBQU1BLFdBQVMsa0JBQWtCLFVBQW9DO0FBQzdELFVBQU0sY0FBdUI7QUFBQSxNQUMzQixJQUFJLGdCQUFnQixLQUFLLElBQUksQ0FBQztBQUFBLE1BQzlCO0FBQUEsTUFDQSxNQUFNLENBQUMsU0FBUyxlQUFlLFVBQVUsSUFBSTtBQUFBLE1BQzdDLFVBQVUsQ0FBQyxTQUFTLG1CQUFtQixVQUFVLElBQUk7QUFBQSxNQUNyRCxXQUFXLE1BQ1QsUUFBUTtBQUFBLFFBQ04sSUFBSSxhQUFhLEVBQUUsUUFBUSw2QkFBNkIsQ0FBQztBQUFBLE1BQzNEO0FBQUEsTUFDRixNQUFNLE1BQ0osUUFBUTtBQUFBLFFBQ04sSUFBSSxhQUFhLEVBQUUsUUFBUSw2QkFBNkIsQ0FBQztBQUFBLE1BQzNEO0FBQUEsTUFDRixZQUFZLENBQUMsU0FBUyxxQkFBcUIsVUFBVSxJQUFJO0FBQUEsTUFDekQscUJBQXFCLENBQUMsV0FDYixpQkFBUztBQUFBLFFBQ2QsS0FBSyxNQUFNLFNBQVMsb0JBQW9CLE1BQU07QUFBQSxRQUM5QyxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsTUFDaEUsQ0FBQztBQUFBLE1BQ0gsS0FBSztBQUFBLFFBQ0gsTUFBTSxhQUFhLENBQUM7QUFBQSxRQUNwQixLQUFLLFlBQVk7QUFBQSxRQUNqQixLQUFLLFlBQVk7QUFBQSxRQUNqQixTQUFTLFlBQVk7QUFBQSxNQUN2QjtBQUFBLElBQ0Y7QUFDQSxXQUFPO0FBQUEsRUFDVDtBQU1BLGlCQUFlLHFCQUFxQixLQUFxQztBQUN2RSxVQUFNLFdBQVcsS0FBSyxJQUFJLElBQUk7QUFDOUIsV0FBTyxLQUFLLElBQUksSUFBSSxVQUFVO0FBQzVCLFlBQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxXQUFXLEdBQUcscUJBQXFCLENBQUM7QUFDN0QsWUFBTSxTQUFTLE1BQU0sUUFBUSxNQUFNLElBQUksR0FBRztBQUMxQyxVQUFJLGtCQUFrQixPQUFPO0FBQzNCLGVBQU87QUFBQSxNQUNUO0FBQ0EsVUFBSSxRQUFRLFlBQVk7QUFDdEIsZUFBTyxPQUFPO0FBQUEsTUFDaEI7QUFFQSxVQUFJLENBQUMsUUFBUSxpQkFBaUI7QUFDNUIsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFTQSxpQkFBZSxvQkFBb0IsTUFFakI7QUFDaEIsUUFBSSxDQUFDLE9BQU87QUFDVjtBQUFBLElBQ0Y7QUFDQSxVQUFNLFdBQVcsTUFBTTtBQUd2QixRQUFJLENBQUMsTUFBTSxPQUFPO0FBQ2hCLFlBQU0sV0FBVyxNQUFNLFFBQVEsTUFBTSxJQUFJLFFBQVE7QUFDakQsVUFBSSxFQUFFLG9CQUFvQixVQUFVLFVBQVUsWUFBWTtBQUN4RDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBR0EsVUFBTSxpREFBaUQsUUFBUSxHQUFHO0FBQ2xFLFVBQU0sU0FBUyxPQUFPLFdBQVc7QUFDakMsVUFBTSxTQUFTLE1BQU0sUUFBUSxNQUFNO0FBQUEsTUFDakM7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLElBQ0Y7QUFDQSxRQUFJLGtCQUFrQixTQUFTLENBQUMsUUFBUTtBQUN0QztBQUFBLFFBQ0UsOENBQThDLFFBQVE7QUFBQSxNQUN4RDtBQUNBO0FBQUEsSUFDRjtBQUlBLFFBQUksQ0FBQyxNQUFNLFNBQVMsT0FBTyxZQUFZO0FBQ3JDO0FBQUEsUUFDRSwrREFBK0QsUUFBUTtBQUFBLE1BQ3pFO0FBQ0E7QUFBQSxJQUNGO0FBRUEsUUFBSSxlQUVPO0FBQ1gsUUFBSTtBQUVGO0FBQUEsUUFDRSw0REFBNEQsUUFBUTtBQUFBLE1BQ3RFO0FBQ0EscUJBQWUsTUFBTSxpQkFBaUIsT0FBTztBQUFBLFFBQzNDLFdBQVcsRUFBRSxNQUFNO0FBQUEsUUFDbkIsU0FBUztBQUFBLFFBQ1Q7QUFBQSxRQUNBO0FBQUEsUUFDQSxHQUFHLG1CQUFtQjtBQUFBLE1BQ3hCLENBQUM7QUFFRCxZQUFNLGNBQWM7QUFBQSxRQUNsQjtBQUFBLE1BQ0Y7QUFDQSxZQUFNLE1BQU0sSUFBSSxXQUFXO0FBQzNCO0FBQUEsUUFDRSwwREFBMEQsUUFBUTtBQUFBLE1BQ3BFO0FBQ0EsWUFBTSxXQUFXLE1BQU0sYUFBYSxTQUFTO0FBRTdDLFlBQU0sUUFBUSxNQUFNLElBQUk7QUFBQSxRQUN0QixLQUFLO0FBQUEsUUFDTCxZQUFZLFNBQVM7QUFBQSxRQUNyQixXQUFXLE9BQU87QUFBQSxRQUNsQixZQUFZO0FBQUEsUUFDWixpQkFBaUI7QUFBQSxRQUNqQixpQkFBaUI7QUFBQSxNQUNuQixDQUFDO0FBQ0Q7QUFBQSxRQUNFLG9DQUFvQyxTQUFTLFVBQVUsVUFBVSxRQUFRO0FBQUEsTUFDM0U7QUFHQSxZQUFNLGFBQWEsS0FBSyxFQUFFLE1BQU0sTUFBTSxNQUFTO0FBQUEsSUFDakQsU0FBUyxHQUFHO0FBQ1YsY0FBUTtBQUFBLFFBQ04seURBQXlELFFBQVE7QUFBQSxRQUNqRTtBQUFBLE1BQ0Y7QUFFQSxVQUFJLGNBQWM7QUFDaEIsY0FBTSxhQUFhLEtBQUssRUFBRSxNQUFNLE1BQU0sTUFBUztBQUFBLE1BQ2pEO0FBRUEsWUFBTSxRQUFRLE1BQ1gsSUFBSTtBQUFBLFFBQ0gsS0FBSztBQUFBLFFBQ0wsWUFBWTtBQUFBLFFBQ1osV0FBVyxPQUFPO0FBQUEsUUFDbEIsWUFBWTtBQUFBLFFBQ1osaUJBQWlCO0FBQUEsUUFDakIsaUJBQWlCO0FBQUEsTUFDbkIsQ0FBQyxFQUNBLE1BQU0sTUFBTSxNQUFTO0FBQUEsSUFDMUI7QUFBQSxFQUNGO0FBRUEsaUJBQWUseUJBQXlEO0FBQ3RFLFFBQUksZUFBZSxhQUFhLENBQUMsb0JBQW9CO0FBQ25ELGFBQU8sY0FBYztBQUFBLElBQ3ZCO0FBRUEsVUFBTSxXQUFXLE1BQU0sUUFBUSxRQUFRLElBQUksRUFBRTtBQUM3QyxRQUFJLG9CQUFvQixPQUFPO0FBQzdCLFVBQUksb0JBQW9CLHNCQUFzQjtBQUFBLE1BRTlDLE9BQU87QUFDTCxlQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsU0FBUyxTQUFTLE9BQU8sU0FBUyxDQUFDO0FBQUEsTUFDdkU7QUFBQSxJQUNGO0FBRUEsVUFBTSxpQkFDSixvQkFBb0IsdUJBQXVCLE9BQU87QUFDcEQsVUFBTSxpQkFDSixnQkFBZ0Isa0JBQWtCLGFBQWEsV0FDM0MsZUFBZSxtQkFDZjtBQUVOLFFBQUksZ0JBQWdCLFdBQVc7QUFDN0IsYUFBTyxlQUFlO0FBQUEsSUFDeEI7QUFFQSxVQUFNLGdCQUNKLGdCQUFnQixtQkFDaEIsZUFBZSxtQkFDZixLQUFLLElBQUksSUFBSSxlQUFlLGtCQUFrQjtBQUVoRCxRQUFJLGVBQWU7QUFDakIsYUFBTyxpQkFBaUI7QUFBQSxJQUMxQjtBQUVBLFVBQU0sU0FBUyxPQUFPLFdBQVc7QUFDakMsVUFBTSxNQUFNLEtBQUssSUFBSTtBQUNyQixVQUFNLFNBQVMsTUFBTSxRQUFRLFFBQVE7QUFBQSxNQUNuQztBQUFBLFFBQ0U7QUFBQSxRQUNBO0FBQUEsUUFDQSxNQUFNLGdCQUFnQixRQUFRLGNBQWM7QUFBQSxRQUM1QyxXQUFXLGdCQUFnQixhQUFhLGNBQWM7QUFBQSxRQUN0RCxnQkFDRSxnQkFBZ0Isa0JBQWtCLGNBQWM7QUFBQSxRQUNsRCxpQkFBaUI7QUFBQSxRQUNqQixpQkFBaUI7QUFBQSxRQUNqQixrQkFBa0I7QUFBQSxVQUNoQixVQUFVO0FBQUEsVUFDVixXQUFXO0FBQUEsVUFDWCxZQUNFLGdCQUFnQixjQUFjLGVBQWUsY0FBYztBQUFBLFFBQy9EO0FBQUEsTUFDRjtBQUFBLE1BQ0E7QUFBQSxJQUNGO0FBRUEsUUFBSSxrQkFBa0IsT0FBTztBQUMzQixhQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxTQUFTLE9BQU8sT0FBTyxDQUFDO0FBQUEsSUFDbkU7QUFDQSxRQUFJLENBQUMsUUFBUTtBQUNYLGFBQU8saUJBQWlCO0FBQUEsSUFDMUI7QUFJQSxVQUFNLGVBQWU7QUFJckIsbUJBQWUscUJBQW9DO0FBQ2pELFlBQU0sUUFBUSxRQUNYLElBQUk7QUFBQSxRQUNILEdBQUc7QUFBQSxRQUNILGlCQUFpQjtBQUFBLFFBQ2pCLGlCQUFpQjtBQUFBLE1BQ25CLENBQUMsRUFDQSxNQUFNLE1BQU0sTUFBUztBQUFBLElBQzFCO0FBSUEsVUFBTSxlQUNKLGFBQWEsa0JBQWtCLGFBQWEsV0FDeEMsYUFBYSxtQkFDYjtBQUNOLFFBQUksY0FBYyxXQUFXO0FBQzNCLFlBQU0sbUJBQW1CO0FBQ3pCLGFBQU8sYUFBYTtBQUFBLElBQ3RCO0FBRUEsVUFBTSxhQUNKLGNBQWMsY0FDZCxlQUFlLGNBQ2YsT0FBTyxXQUFXO0FBQ3BCLFFBQUksWUFBWTtBQUNkLFlBQU0sU0FBUyxNQUFNLDBCQUEwQixVQUFVO0FBQ3pELFVBQUksRUFBRSxrQkFBa0IsUUFBUTtBQUM5Qiw4QkFBc0I7QUFDdEIsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBR0EsUUFBSSxPQUFPO0FBQ1QsVUFBSSx3QkFBd0I7QUFDNUIsWUFBTSxjQUFjLE1BQU0sUUFBUSxNQUFNLElBQUksTUFBTSxHQUFHO0FBQ3JELFVBQUksRUFBRSx1QkFBdUIsVUFBVSxhQUFhO0FBQ2xELFlBQUksWUFBWSxZQUFZO0FBQzFCO0FBQUEsWUFDRSx3Q0FBd0MsWUFBWSxVQUFVLGFBQWEsTUFBTSxHQUFHO0FBQUEsVUFDdEY7QUFDQSxnQkFBTSxTQUFTLE1BQU07QUFBQSxZQUNuQixZQUFZO0FBQUEsVUFDZDtBQUNBLGNBQUksRUFBRSxrQkFBa0IsUUFBUTtBQUM5QixrQ0FBc0I7QUFFdEIsb0JBQVEsTUFDTCxJQUFJO0FBQUEsY0FDSCxHQUFHO0FBQUEsY0FDSCxZQUFZLEtBQUssSUFBSTtBQUFBLFlBQ3ZCLENBQUMsRUFDQSxNQUFNLE1BQU0sTUFBUztBQUN4QixtQkFBTztBQUFBLFVBQ1Q7QUFFQTtBQUFBLFlBQ0UsNEJBQTRCLFlBQVksVUFBVTtBQUFBLFVBQ3BEO0FBQ0Esa0NBQXdCO0FBQUEsUUFDMUIsV0FDRSxZQUFZLG1CQUNaLFlBQVksbUJBQ1osS0FBSyxJQUFJLElBQUksWUFBWSxrQkFBa0IsaUJBQzNDO0FBRUE7QUFBQSxZQUNFLGlEQUFpRCxNQUFNLEdBQUc7QUFBQSxVQUM1RDtBQUNBLGdCQUFNQyxjQUFhLE1BQU0scUJBQXFCLE1BQU0sR0FBRztBQUN2RCxjQUFJQSxhQUFZO0FBQ2Q7QUFBQSxjQUNFLG1DQUFtQ0EsV0FBVSxhQUFhLE1BQU0sR0FBRztBQUFBLFlBQ3JFO0FBQ0Esa0JBQU0sU0FBUyxNQUFNLDBCQUEwQkEsV0FBVTtBQUN6RCxnQkFBSSxFQUFFLGtCQUFrQixRQUFRO0FBQzlCLG9DQUFzQjtBQUN0QixxQkFBTztBQUFBLFlBQ1Q7QUFBQSxVQUNGO0FBQUEsUUFFRjtBQUFBLE1BQ0Y7QUFJQTtBQUFBLFFBQ0Usd0NBQXdDLE1BQU0sR0FBRztBQUFBLE1BQ25EO0FBQ0Esc0JBQWdCO0FBQ2hCLDBCQUFvQixFQUFFLE9BQU8sc0JBQXNCLENBQUMsRUFBRSxNQUFNLENBQUMsTUFBTTtBQUNqRSxnQkFBUTtBQUFBLFVBQ047QUFBQSxVQUNBO0FBQUEsUUFDRjtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0g7QUFFQSxVQUFNLGNBQWMsTUFBTSxtQkFBbUI7QUFDN0MsUUFBSSx1QkFBdUIsT0FBTztBQUNoQyxZQUFNLG1CQUFtQjtBQUFBLElBQzNCO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFFQSxXQUFTLHVCQUF1RDtBQUM5RCxVQUFNLFNBQVMsZUFBZSxJQUFJLEVBQUU7QUFDcEMsUUFBSSxRQUFRO0FBQ1YsYUFBTztBQUFBLElBQ1Q7QUFFQSxVQUFNLFVBQVUsdUJBQXVCLEVBQUUsUUFBUSxNQUFNO0FBQ3JELHFCQUFlLE9BQU8sRUFBRTtBQUFBLElBQzFCLENBQUM7QUFDRCxtQkFBZSxJQUFJLElBQUksT0FBTztBQUM5QixXQUFPO0FBQUEsRUFDVDtBQUVBLGlCQUFlLGVBQXdEO0FBQ3JFLFVBQU0sa0JBQWtCLE1BQU0scUJBQXFCO0FBQ25ELFFBQUksMkJBQTJCLE9BQU87QUFDcEMsYUFBTztBQUFBLElBQ1Q7QUFFQSxXQUFjLGlCQUFTO0FBQUEsTUFDckIsS0FBSyxNQUNILGlCQUFpQixJQUFJO0FBQUEsUUFDbkIsV0FBVztBQUFBLFFBQ1gsR0FBRyxtQkFBbUI7QUFBQSxNQUN4QixDQUFDO0FBQUEsTUFDSCxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsSUFDaEUsQ0FBQztBQUFBLEVBQ0g7QUFFQSxXQUFTQyxjQUFzRDtBQUM3RCxRQUFJLENBQUMsZ0JBQWdCO0FBQ25CLHVCQUFpQixhQUFhO0FBQUEsSUFDaEM7QUFDQSxXQUFPO0FBQUEsRUFDVDtBQUVBLGlCQUFlLDBCQUF5QztBQUN0RCxxQkFBaUI7QUFDakIseUJBQXFCO0FBRXJCLFVBQU0sV0FBVyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDN0MsUUFBSSxvQkFBb0IsU0FBUyxDQUFDLFVBQVU7QUFDMUM7QUFBQSxJQUNGO0FBRUEsVUFBTSxpQkFDSixTQUFTLGtCQUFrQixhQUFhLFdBQ3BDLFNBQVMsbUJBQ1Q7QUFFTixRQUFJLGdCQUFnQixXQUFXO0FBQzdCLFlBQU0sUUFBUSxRQUFRLElBQUk7QUFBQSxRQUN4QixJQUFJLFNBQVM7QUFBQSxRQUNiLFFBQVEsU0FBUztBQUFBLFFBQ2pCLE1BQU0sU0FBUztBQUFBLFFBQ2YsV0FBVyxTQUFTO0FBQUEsUUFDcEIsZ0JBQWdCLFNBQVM7QUFBQSxRQUN6QixpQkFBaUI7QUFBQSxRQUNqQixpQkFBaUI7QUFBQSxRQUNqQixrQkFBa0I7QUFBQSxVQUNoQixVQUFVO0FBQUEsVUFDVixXQUFXO0FBQUEsVUFDWCxZQUFZLGVBQWU7QUFBQSxRQUM3QjtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0g7QUFBQSxFQUNGO0FBRUEsaUJBQWUscUJBQW9DO0FBQ2pELFVBQU0sTUFBTSxLQUFLLElBQUk7QUFDckIsVUFBTSxXQUFXLGlCQUFpQixJQUFJLEVBQUU7QUFDeEMsUUFBSSxZQUFZLE1BQU0sV0FBVyxzQkFBc0I7QUFDckQ7QUFBQSxJQUNGO0FBQ0EscUJBQWlCLElBQUksSUFBSSxHQUFHO0FBRTVCLFVBQU0sV0FBVyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDN0MsUUFBSSxvQkFBb0IsU0FBUyxDQUFDLFVBQVU7QUFDMUM7QUFBQSxJQUNGO0FBQ0EsVUFBTSxpQkFDSixTQUFTLGtCQUFrQixhQUFhLFdBQ3BDLFNBQVMsbUJBQ1Q7QUFDTixVQUFNLFFBQVEsUUFBUSxJQUFJO0FBQUEsTUFDeEIsSUFBSSxTQUFTO0FBQUEsTUFDYixRQUFRLFNBQVM7QUFBQSxNQUNqQixNQUFNLFNBQVM7QUFBQSxNQUNmLFdBQVcsU0FBUztBQUFBLE1BQ3BCLGdCQUFnQjtBQUFBLE1BQ2hCLGlCQUFpQjtBQUFBLE1BQ2pCLGlCQUFpQjtBQUFBLE1BQ2pCLGtCQUFrQixrQkFBa0I7QUFBQSxRQUNsQyxVQUFVO0FBQUEsUUFDVixXQUFXO0FBQUEsUUFDWCxZQUFZO0FBQUEsTUFDZDtBQUFBLElBQ0YsQ0FBQztBQUFBLEVBQ0g7QUFFQSxRQUFNLFlBQThCO0FBQUEsSUFDbEMsT0FBTyxZQUFZO0FBQ2pCLFlBQU1ILFdBQVUsTUFBTUcsWUFBVztBQUNqQyxVQUFJSCxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFDQSxZQUFNLG1CQUFtQjtBQUN6QixhQUFPQSxTQUFRO0FBQUEsSUFDakI7QUFBQSxJQUVBLFVBQVUsWUFBWTtBQUNwQixZQUFNQSxXQUFVLE1BQU1HLFlBQVc7QUFDakMsVUFBSUgsb0JBQW1CLE9BQU87QUFDNUIsZUFBT0E7QUFBQSxNQUNUO0FBRUEsYUFBYyxpQkFBUztBQUFBLFFBQ3JCLEtBQUssWUFBWTtBQUNmLGdCQUFNLFdBQVcsTUFBTSxRQUFRLFFBQVEsSUFBSSxFQUFFO0FBQzdDLGdCQUFNLFdBQVcsTUFBTUEsU0FBUSxTQUFTO0FBQ3hDLGdCQUFNLFFBQVEsUUFBUSxJQUFJO0FBQUEsWUFDeEI7QUFBQSxZQUNBO0FBQUEsWUFDQSxNQUFNLG9CQUFvQixRQUFRLE9BQVEsVUFBVSxRQUFRO0FBQUEsWUFDNUQsV0FDRSxvQkFBb0IsUUFBUSxPQUFRLFVBQVUsYUFBYTtBQUFBLFlBQzdELGdCQUNFLG9CQUFvQixRQUNoQixPQUNDLFVBQVUsa0JBQWtCO0FBQUEsWUFDbkMsaUJBQWlCO0FBQUEsWUFDakIsaUJBQWlCO0FBQUEsWUFDakIsa0JBQWtCO0FBQUEsY0FDaEIsVUFBVTtBQUFBLGNBQ1YsV0FBVztBQUFBLGNBQ1gsWUFBWSxTQUFTO0FBQUEsWUFDdkI7QUFBQSxVQUNGLENBQUM7QUFDRCxpQkFBTyxFQUFFLFlBQVksU0FBUyxXQUFXO0FBQUEsUUFDM0M7QUFBQSxRQUNBLE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxNQUNoRSxDQUFDO0FBQUEsSUFDSDtBQUFBLElBRUEsTUFBTSxZQUFZO0FBQ2hCLFlBQU1BLFdBQVUsTUFBTUcsWUFBVztBQUNqQyxVQUFJSCxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFFQSxhQUFjLGlCQUFTO0FBQUEsUUFDckIsS0FBSyxZQUFZO0FBQ2YsZ0JBQU1BLFNBQVEsS0FBSztBQUNuQixnQkFBTSxXQUFXLE1BQU0sUUFBUSxRQUFRLElBQUksRUFBRTtBQUM3QyxjQUFJLG9CQUFvQixTQUFTLENBQUMsVUFBVTtBQUMxQyxtQkFBTztBQUFBLFVBQ1Q7QUFDQSxnQkFBTSxRQUFRLFFBQVEsSUFBSTtBQUFBLFlBQ3hCLElBQUksU0FBUztBQUFBLFlBQ2IsUUFBUSxTQUFTO0FBQUEsWUFDakIsTUFBTSxTQUFTO0FBQUEsWUFDZixXQUFXLFNBQVM7QUFBQSxZQUNwQixnQkFBZ0IsU0FBUztBQUFBLFlBQ3pCLGlCQUFpQjtBQUFBLFlBQ2pCLGlCQUFpQjtBQUFBLFlBQ2pCLGtCQUFrQjtBQUFBLGNBQ2hCLFVBQVU7QUFBQSxjQUNWLFdBQVc7QUFBQSxjQUNYLFlBQVk7QUFBQSxZQUNkO0FBQUEsVUFDRixDQUFDO0FBQ0QsaUJBQU87QUFBQSxRQUNUO0FBQUEsUUFDQSxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsTUFDaEUsQ0FBQztBQUFBLElBQ0g7QUFBQSxJQUVBLFdBQVcsWUFBWTtBQUNyQixZQUFNQSxXQUFVLE1BQU1HLFlBQVc7QUFDakMsVUFBSUgsb0JBQW1CLE9BQU87QUFDNUIsZUFBT0E7QUFBQSxNQUNUO0FBQ0EsYUFBT0EsU0FBUTtBQUFBLElBQ2pCO0FBQUEsSUFFQSxjQUFjLFlBQVk7QUFDeEIsWUFBTUEsV0FBVSxNQUFNRyxZQUFXO0FBQ2pDLFVBQUlILG9CQUFtQixPQUFPO0FBQzVCLGVBQU9BO0FBQUEsTUFDVDtBQUNBLGFBQU9BLFNBQVE7QUFBQSxJQUNqQjtBQUFBLElBRUEscUJBQXFCLFlBQVk7QUFDL0IsWUFBTUEsV0FBVSxNQUFNRyxZQUFXO0FBQ2pDLFVBQUlILG9CQUFtQixPQUFPO0FBQzVCLGVBQU9BO0FBQUEsTUFDVDtBQUNBLGFBQU9BLFNBQVE7QUFBQSxJQUNqQjtBQUFBLEVBQ0Y7QUFFQSxpQkFBZSxPQUFPLE1BSW5CO0FBQ0QsVUFBTSxXQUFXLE1BQU1HLFlBQVc7QUFDbEMsUUFBSSxvQkFBb0IsT0FBTztBQUM3QixhQUFPO0FBQUEsSUFDVDtBQUVBLFVBQU0sZ0JBQWdCLG1CQUFtQjtBQUN6QyxVQUFNLGFBQWEsTUFBTSxlQUFlLFVBQVUsSUFBSTtBQUN0RCxVQUFNO0FBQ04sV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLFVBQXlEO0FBQUEsSUFDN0Q7QUFBQSxJQUNBO0FBQUEsSUFDQSxNQUFNLE9BQU8sU0FBUztBQUNwQixZQUFNLFNBQVMsTUFBTSxPQUFPLElBQUk7QUFFaEMsVUFBSSxrQkFBa0IsZ0JBQWdCLG1CQUFtQixPQUFPLEtBQUssR0FBRztBQUN0RSxjQUFNLHdCQUF3QjtBQUM5QixlQUFPLE1BQU0sT0FBTyxJQUFJO0FBQUEsTUFDMUI7QUFFQSxhQUFPO0FBQUEsSUFDVDtBQUFBLElBRUEsV0FBVyxPQUFPLFNBQVM7QUFDekIsWUFBTUgsV0FBVSxNQUFNRyxZQUFXO0FBQ2pDLFVBQUlILG9CQUFtQixPQUFPO0FBQzVCLGVBQU9BO0FBQUEsTUFDVDtBQUVBLFVBQUk7QUFDRixlQUFPQSxTQUFRLE9BQU8sSUFBSTtBQUFBLE1BQzVCLFNBQVMsR0FBRztBQUNWLGVBQU8sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ3pEO0FBQUEsSUFDRjtBQUFBLElBRUEsTUFBTSxPQUFPLEVBQUUsV0FBVyxTQUFTLFdBQVcsTUFBTTtBQUNsRCxZQUFNLFdBQVcsTUFBTUcsWUFBVztBQUNsQyxVQUFJLG9CQUFvQixPQUFPO0FBQzdCLGVBQU87QUFBQSxNQUNUO0FBRUEsWUFBTSxNQUFNLE1BQU0sV0FBVyxRQUFRLElBQUksU0FBUztBQUNsRCxVQUFJLGVBQWUsT0FBTztBQUN4QixlQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsSUFBSSxTQUFTLE9BQU8sSUFBSSxDQUFDO0FBQUEsTUFDN0Q7QUFDQSxVQUFJLE9BQU8sSUFBSSxXQUFXLFdBQVc7QUFDbkMsY0FBTSxTQUFTLE1BQU0sV0FBVyxRQUFRLElBQUk7QUFBQSxVQUMxQyxHQUFHO0FBQUEsVUFDSCxRQUFRO0FBQUEsUUFDVixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTyxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sU0FBUyxPQUFPLE9BQU8sQ0FBQztBQUFBLFFBQ25FO0FBQUEsTUFDRjtBQUNBLGFBQU87QUFBQSxJQUNUO0FBQUEsSUFFQSxVQUFVLE9BQU8sU0FBUztBQUN4QixZQUFNLFdBQVcsTUFBTUEsWUFBVztBQUNsQyxVQUFJLG9CQUFvQixPQUFPO0FBQzdCLGVBQU87QUFBQSxNQUNUO0FBQ0EsYUFBTyxtQkFBbUIsVUFBVSxJQUFJO0FBQUEsSUFDMUM7QUFBQSxJQUVBLFlBQVksT0FBTyxTQUFTO0FBQzFCLFlBQU0sV0FBVyxNQUFNQSxZQUFXO0FBQ2xDLFVBQUksb0JBQW9CLE9BQU87QUFDN0IsY0FBTTtBQUFBLE1BQ1I7QUFDQSxhQUFPLHFCQUFxQixVQUFVLElBQUk7QUFBQSxJQUM1QztBQUFBLElBRUE7QUFBQSxJQUVBLHFCQUFxQixPQUFPLFdBQVc7QUFDckMsWUFBTSxXQUFXLE1BQU1BLFlBQVc7QUFDbEMsVUFBSSxvQkFBb0IsT0FBTztBQUM3QixlQUFPO0FBQUEsTUFDVDtBQUNBLGFBQWMsaUJBQVM7QUFBQSxRQUNyQixLQUFLLE1BQU0sU0FBUyxvQkFBb0IsTUFBTTtBQUFBLFFBQzlDLE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxNQUNoRSxDQUFDO0FBQUEsSUFDSDtBQUFBLElBRUEsS0FBSztBQUFBLE1BQ0gsTUFBTSxZQUFZO0FBQ2hCLGNBQU1DLGlCQUFnQixNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDbEQsWUFBSUEsMEJBQXlCLE9BQU87QUFDbEMsaUJBQU9BO0FBQUEsUUFDVDtBQUNBLGVBQVFBLGVBQWMsUUFBUSxDQUFDO0FBQUEsTUFDakM7QUFBQSxNQUNBLEtBQUssT0FBTyxRQUFnQjtBQUMxQixjQUFNQSxpQkFBZ0IsTUFBTSxRQUFRLFFBQVEsSUFBSSxFQUFFO0FBQ2xELFlBQUlBLDBCQUF5QixPQUFPO0FBQ2xDLGlCQUFPQTtBQUFBLFFBQ1Q7QUFDQSxlQUFPQSxlQUFjLE9BQU8sR0FBYTtBQUFBLE1BRzNDO0FBQUEsTUFDQSxLQUFLLE9BQU8sS0FBYSxVQUFtQjtBQUMxQyxjQUFNLFNBQVMsTUFBTSxRQUFRLFFBQVEsSUFBSSxJQUFJO0FBQUEsVUFDM0MsV0FBVztBQUFBLFVBQ1gsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHLE1BQU07QUFBQSxRQUN2QixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTztBQUFBLFFBQ1Q7QUFDQSxlQUFPO0FBQUEsTUFDVDtBQUFBLE1BQ0EsU0FBUyxPQUFPLFNBQWtDO0FBQ2hELGNBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLElBQUk7QUFBQSxVQUMzQyxXQUFXO0FBQUEsVUFDWDtBQUFBLFFBQ0YsQ0FBQztBQUNELFlBQUksa0JBQWtCLE9BQU87QUFDM0IsaUJBQU87QUFBQSxRQUNUO0FBQ0EsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUVBLE1BQUksaUJBQWdDLFFBQVEsUUFBUTtBQUVwRCxNQUFJLE9BQU8sV0FBVyxjQUFjLE9BQU87QUFDekMscUJBQWlCLGFBQWE7QUFLOUIscUJBQWlCLGVBQWUsS0FBSyxPQUFPLGFBQWE7QUFDdkQsVUFBSSxvQkFBb0IsT0FBTztBQUM3QjtBQUFBLE1BQ0Y7QUFFQSxVQUFJLGlCQUFpQixPQUFPO0FBQzFCO0FBQUEsVUFDRSw4REFBOEQsTUFBTSxHQUFHO0FBQUEsUUFDekU7QUFDQSxjQUFNLE1BQU0sSUFBSSxPQUFPO0FBQ3ZCLGNBQU0sdURBQXVEO0FBQUEsTUFDL0Q7QUFFQSxVQUFJLHVCQUF1QixXQUFXO0FBQ3BDLGNBQU0sMkRBQTJEO0FBQ2pFLGNBQU0sVUFBVSxPQUFPO0FBQUEsTUFDekI7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBRUEsVUFBUSxXQUFXO0FBQ25CLFNBQU87QUFDVDs7O0FDdGpDQSxJQUFNLGVBQWUsb0JBQUksSUFBOEI7QUFFdkQsZUFBc0IsV0FBa0Q7QUFBQSxFQUN0RTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0EsMEJBQTBCO0FBQUEsRUFDMUI7QUFBQSxFQUNBO0FBQ0YsR0FRNEI7QUFHMUIsUUFBTSxXQUFXLEVBQUUsU0FBUztBQUU1QixNQUFJLFVBQVU7QUFDWixVQUFNLFNBQVMsYUFBYSxJQUFJLGNBQWMsRUFBRTtBQUNoRCxRQUFJLFFBQVE7QUFDVixZQUFNLDhCQUE4QixjQUFjLEVBQUU7QUFDcEQsYUFBTztBQUFBLElBQ1Q7QUFBQSxFQUNGO0FBRUEsUUFBTSxVQUFVLGNBQXFCO0FBQUEsSUFDbkM7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGLENBQUM7QUFFRCxNQUFJLFVBQVU7QUFDWixpQkFBYSxJQUFJLGNBQWMsSUFBSSxPQUEyQjtBQUc5RCxZQUFRLE1BQU0sTUFBTTtBQUNsQixtQkFBYSxPQUFPLGNBQWMsRUFBRTtBQUFBLElBQ3RDLENBQUM7QUFBQSxFQUNIO0FBRUEsU0FBTyxNQUFNO0FBQ2Y7QUFFQSxlQUFlLGNBQXFEO0FBQUEsRUFDbEU7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBLDBCQUEwQjtBQUFBLEVBQzFCO0FBQUEsRUFDQTtBQUNGLEdBUTRCO0FBQzFCLE1BQUk7QUFFSixVQUFRLGNBQWMsT0FBTyxNQUFNO0FBQUEsSUFDakMsS0FBSztBQUNILFlBQU0sYUFBb0I7QUFBQSxRQUN4QjtBQUFBLFFBR0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLE1BQ0YsQ0FBQztBQUNEO0FBQUEsSUFDRixLQUFLO0FBQ0gsWUFBTSxjQUFxQjtBQUFBLFFBQ3pCO0FBQUEsUUFHQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsTUFDRixDQUFDO0FBQ0Q7QUFBQSxJQUNGLEtBQUs7QUFDSCxZQUFNLElBQUksTUFBTSxvQ0FBb0M7QUFBQSxJQUN0RDtBQUNFLG9CQUFjO0FBQ2QsWUFBTSxJQUFJO0FBQUEsUUFDUjtBQUFBLFFBRUcsY0FBYyxPQUFlLElBQ2hDO0FBQUEsTUFDRjtBQUFBLEVBQ0o7QUFFQSxNQUFJLElBQUksVUFBVTtBQUNoQixVQUFNLElBQUk7QUFBQSxFQUNaO0FBQ0EsU0FBTztBQUNUOyIsCiAgIm5hbWVzIjogWyJwYXRoIiwgInJlc3VsdCIsICJzdG9yYWdlIiwgInNhbmRib3hSZWNvcmQiLCAicGF0aCIsICJlcnJvcmUiLCAic2FuZGJveCIsICJwYXRoIiwgInNuYXBzaG90SWQiLCAiZ2V0U2FuZGJveCIsICJzYW5kYm94UmVjb3JkIl0KfQo=