sonamu 0.9.4 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/providers/rtzr/utils.js +2 -2
- package/dist/api/config.d.ts +13 -2
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +1 -1
- package/dist/api/context.d.ts +17 -7
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts +18 -0
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +54 -3
- package/dist/api/index.js +8 -3
- package/dist/api/sonamu.d.ts +24 -9
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +365 -79
- package/dist/api/websocket-helpers.d.ts +24 -0
- package/dist/api/websocket-helpers.d.ts.map +1 -0
- package/dist/api/websocket-helpers.js +77 -0
- package/dist/bin/cli.js +12 -4
- package/dist/database/upsert-builder.js +4 -4
- package/dist/dict/sonamu-dictionary.js +6 -6
- package/dist/entity/entity-manager.js +1 -1
- package/dist/entity/entity.js +3 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -4
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +8 -9
- package/dist/stream/index.d.ts +6 -0
- package/dist/stream/index.d.ts.map +1 -1
- package/dist/stream/index.js +13 -2
- package/dist/stream/ws-audience-resolver.d.ts +15 -0
- package/dist/stream/ws-audience-resolver.d.ts.map +1 -0
- package/dist/stream/ws-audience-resolver.js +31 -0
- package/dist/stream/ws-audience.d.ts +28 -0
- package/dist/stream/ws-audience.d.ts.map +1 -0
- package/dist/stream/ws-audience.js +46 -0
- package/dist/stream/ws-cluster-bus.d.ts +23 -0
- package/dist/stream/ws-cluster-bus.d.ts.map +1 -0
- package/dist/stream/ws-cluster-bus.js +18 -0
- package/dist/stream/ws-core.d.ts +15 -0
- package/dist/stream/ws-core.d.ts.map +1 -0
- package/dist/stream/ws-core.js +1 -0
- package/dist/stream/ws-delivery.d.ts +24 -0
- package/dist/stream/ws-delivery.d.ts.map +1 -0
- package/dist/stream/ws-delivery.js +103 -0
- package/dist/stream/ws-local-connection-store.d.ts +10 -0
- package/dist/stream/ws-local-connection-store.d.ts.map +1 -0
- package/dist/stream/ws-local-connection-store.js +44 -0
- package/dist/stream/ws-presence-store.d.ts +61 -0
- package/dist/stream/ws-presence-store.d.ts.map +1 -0
- package/dist/stream/ws-presence-store.js +236 -0
- package/dist/stream/ws-registry.d.ts +42 -0
- package/dist/stream/ws-registry.d.ts.map +1 -0
- package/dist/stream/ws-registry.js +108 -0
- package/dist/stream/ws.d.ts +52 -0
- package/dist/stream/ws.d.ts.map +1 -0
- package/dist/stream/ws.js +397 -0
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +72 -2
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +13 -12
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +7 -4
- package/dist/syncer/event-batcher.d.ts +27 -0
- package/dist/syncer/event-batcher.d.ts.map +1 -0
- package/dist/syncer/event-batcher.js +69 -0
- package/dist/syncer/file-patterns.d.ts +48 -26
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +71 -23
- package/dist/syncer/file-tracking.d.ts +13 -0
- package/dist/syncer/file-tracking.d.ts.map +1 -0
- package/dist/syncer/file-tracking.js +33 -0
- package/dist/syncer/index.js +2 -2
- package/dist/syncer/module-loader.d.ts +2 -11
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +3 -3
- package/dist/syncer/syncer-actions.d.ts +39 -6
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +125 -10
- package/dist/syncer/syncer.d.ts +33 -19
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +168 -168
- package/dist/syncer/watcher.d.ts +8 -0
- package/dist/syncer/watcher.d.ts.map +1 -0
- package/dist/syncer/watcher.js +105 -0
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +2 -1
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +36 -1
- package/dist/testing/bootstrap.d.ts.map +1 -1
- package/dist/testing/bootstrap.js +8 -1
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/data-explorer.js +5 -3
- package/dist/testing/fixture-manager.js +1 -1
- package/dist/types/types.d.ts +2 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +2 -2
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +4 -3
- package/dist/ui/cdd-service.js +1 -1
- package/dist/ui-web/assets/{index-C5KUjXm0.js → index-BmThfg-s.js} +39 -39
- package/dist/ui-web/assets/index-D4rYm-Xz.css +1 -0
- package/dist/ui-web/index.html +2 -2
- package/dist/utils/async-utils.d.ts +27 -3
- package/dist/utils/async-utils.d.ts.map +1 -1
- package/dist/utils/async-utils.js +56 -6
- package/dist/utils/formatter.d.ts +7 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +95 -60
- package/dist/utils/fs-utils.d.ts +2 -0
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +10 -2
- package/dist/utils/process-utils.d.ts +6 -0
- package/dist/utils/process-utils.d.ts.map +1 -1
- package/dist/utils/process-utils.js +16 -3
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +2 -2
- package/package.json +7 -5
- package/src/ai/providers/rtzr/utils.ts +1 -1
- package/src/api/__tests__/sonamu.websocket.test.ts +64 -0
- package/src/api/__tests__/websocket-context.types.test.ts +58 -0
- package/src/api/config.ts +28 -2
- package/src/api/context.ts +21 -7
- package/src/api/decorators.ts +101 -1
- package/src/api/sonamu.ts +529 -127
- package/src/api/websocket-helpers.ts +122 -0
- package/src/bin/cli.ts +10 -2
- package/src/database/upsert-builder.ts +3 -3
- package/src/dict/sonamu-dictionary.ts +3 -3
- package/src/entity/entity.ts +1 -1
- package/src/index.ts +6 -0
- package/src/migration/code-generation.ts +6 -11
- package/src/shared/app.shared.ts.txt +312 -4
- package/src/shared/web.shared.ts.txt +340 -4
- package/src/stream/__tests__/ws-contracts.test.ts +381 -0
- package/src/stream/__tests__/ws.test.ts +449 -0
- package/src/stream/index.ts +6 -0
- package/src/stream/ws-audience-resolver.ts +35 -0
- package/src/stream/ws-audience.ts +62 -0
- package/src/stream/ws-cluster-bus.ts +32 -0
- package/src/stream/ws-core.ts +16 -0
- package/src/stream/ws-delivery.ts +138 -0
- package/src/stream/ws-local-connection-store.ts +44 -0
- package/src/stream/ws-presence-store.ts +326 -0
- package/src/stream/ws-registry.ts +138 -0
- package/src/stream/ws.ts +591 -0
- package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +78 -0
- package/src/syncer/api-parser.ts +112 -1
- package/src/syncer/checksum.ts +23 -29
- package/src/syncer/code-generator.ts +4 -1
- package/src/syncer/event-batcher.ts +72 -0
- package/src/syncer/file-patterns.ts +98 -30
- package/src/syncer/file-tracking.ts +27 -0
- package/src/syncer/module-loader.ts +5 -12
- package/src/syncer/syncer-actions.ts +179 -17
- package/src/syncer/syncer.ts +250 -287
- package/src/syncer/watcher.ts +128 -0
- package/src/tasks/workflow-manager.ts +1 -0
- package/src/template/__tests__/services.template.websocket.test.ts +79 -0
- package/src/template/implementations/services.template.ts +69 -0
- package/src/testing/bootstrap.ts +8 -1
- package/src/testing/data-explorer.ts +3 -2
- package/src/types/types.ts +20 -2
- package/src/ui/api.ts +10 -1
- package/src/utils/async-utils.ts +71 -4
- package/src/utils/formatter.ts +114 -75
- package/src/utils/fs-utils.ts +9 -0
- package/src/utils/process-utils.ts +17 -0
- package/src/utils/utils.ts +1 -1
- package/dist/ui-web/assets/index-Dr8pRJC_.css +0 -1
package/dist/api/sonamu.js
CHANGED
|
@@ -8,15 +8,18 @@ import { NotFoundException, init_so_exceptions } from "../exceptions/so-exceptio
|
|
|
8
8
|
import { BufferedFile, init_buffered_file } from "../storage/buffered-file.js";
|
|
9
9
|
import { UploadedFile, init_uploaded_file } from "../storage/uploaded-file.js";
|
|
10
10
|
import { createMockSSEFactory, init_sse } from "../stream/sse.js";
|
|
11
|
+
import { WebSocketRuntime, init_ws } from "../stream/ws.js";
|
|
12
|
+
import { centerText, init_console_util } from "../utils/console-util.js";
|
|
11
13
|
import { init_controller, isDaemonServer } from "../utils/controller.js";
|
|
12
14
|
import { exists, fileExists, init_fs_utils } from "../utils/fs-utils.js";
|
|
13
15
|
import { convertFastifyHeadersToStandard, init_utils, merge } from "../utils/utils.js";
|
|
14
16
|
import { getSecrets, init_secret } from "./secret.js";
|
|
17
|
+
import { createWebSocketReplyStub, init_websocket_helpers, resolveIntegratedViteHmrOptions, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions } from "./websocket-helpers.js";
|
|
15
18
|
import { AsyncLocalStorage } from "async_hooks";
|
|
16
19
|
import { dispose } from "@logtape/logtape";
|
|
17
|
-
import assert from "assert";
|
|
18
20
|
import fs from "fs/promises";
|
|
19
21
|
import path from "path";
|
|
22
|
+
import chalk from "chalk";
|
|
20
23
|
import os from "os";
|
|
21
24
|
import mime, { lookup } from "mime-types";
|
|
22
25
|
|
|
@@ -37,6 +40,11 @@ function formatTime(ms) {
|
|
|
37
40
|
function isLocalHost(host) {
|
|
38
41
|
return LOCAL_HOSTS.has(host);
|
|
39
42
|
}
|
|
43
|
+
function runGuards({ guards, config, request, api }) {
|
|
44
|
+
for (const guard of guards ?? []) {
|
|
45
|
+
config.guardHandler(guard, request, api);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
40
48
|
var SonamuClass, Sonamu, LOCAL_HOSTS;
|
|
41
49
|
var init_sonamu = __esmMin((() => {
|
|
42
50
|
init_better_auth_entities();
|
|
@@ -48,10 +56,13 @@ var init_sonamu = __esmMin((() => {
|
|
|
48
56
|
init_buffered_file();
|
|
49
57
|
init_uploaded_file();
|
|
50
58
|
init_sse();
|
|
59
|
+
init_ws();
|
|
60
|
+
init_console_util();
|
|
51
61
|
init_controller();
|
|
52
62
|
init_fs_utils();
|
|
53
63
|
init_utils();
|
|
54
64
|
init_secret();
|
|
65
|
+
init_websocket_helpers();
|
|
55
66
|
SonamuClass = class {
|
|
56
67
|
isInitialized = false;
|
|
57
68
|
forTesting = false;
|
|
@@ -63,10 +74,14 @@ var init_sonamu = __esmMin((() => {
|
|
|
63
74
|
}
|
|
64
75
|
if (process.env.NODE_ENV === "test") {
|
|
65
76
|
return {
|
|
77
|
+
transport: "http",
|
|
66
78
|
request: null,
|
|
67
79
|
reply: null,
|
|
68
80
|
headers: {},
|
|
69
81
|
createSSE: (schema) => createMockSSEFactory(schema),
|
|
82
|
+
locale: "",
|
|
83
|
+
user: null,
|
|
84
|
+
session: null,
|
|
70
85
|
naiteStore: new Map()
|
|
71
86
|
};
|
|
72
87
|
} else {
|
|
@@ -158,9 +173,18 @@ var init_sonamu = __esmMin((() => {
|
|
|
158
173
|
set devVitestManager(manager) {
|
|
159
174
|
this._devVitestManager = manager;
|
|
160
175
|
}
|
|
176
|
+
_websocketRuntime = null;
|
|
177
|
+
websocketPluginServers = new WeakSet();
|
|
178
|
+
get websocketRuntime() {
|
|
179
|
+
if (!this._websocketRuntime) {
|
|
180
|
+
throw new Error("WebSocket runtime has not been initialized.");
|
|
181
|
+
}
|
|
182
|
+
return this._websocketRuntime;
|
|
183
|
+
}
|
|
184
|
+
set websocketRuntime(runtime) {
|
|
185
|
+
this._websocketRuntime = runtime;
|
|
186
|
+
}
|
|
161
187
|
watcher = null;
|
|
162
|
-
pendingFiles = [];
|
|
163
|
-
hmrStartTime = 0;
|
|
164
188
|
server = null;
|
|
165
189
|
async initForTesting() {
|
|
166
190
|
await this.init(true, false, undefined, true);
|
|
@@ -214,7 +238,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
214
238
|
await this.syncer.autoloadWorkflows();
|
|
215
239
|
const { TemplateManager } = await import("../template/index.js");
|
|
216
240
|
await TemplateManager.autoload();
|
|
217
|
-
await this.syncer.
|
|
241
|
+
await this.syncer.autoloadSsrRoutes();
|
|
218
242
|
const { isLocal, isTest, isHotReloadServer } = await import("../utils/controller.js");
|
|
219
243
|
if (isLocal() && !isTest() && isHotReloadServer() && enableSync) {
|
|
220
244
|
await this.syncer.sync();
|
|
@@ -238,6 +262,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
238
262
|
logger: this.config.logging !== false ? getLogTapeFastifyLogger({ category: this.config.logging?.fastifyCategory ?? ["fastify"] }) : undefined
|
|
239
263
|
});
|
|
240
264
|
this.server = server;
|
|
265
|
+
this.websocketRuntime = new WebSocketRuntime(options.websocket);
|
|
241
266
|
if (options.storage) {
|
|
242
267
|
const { StorageManager } = await import("../storage/storage-manager.js");
|
|
243
268
|
this._storage = new StorageManager(options.storage);
|
|
@@ -263,6 +288,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
263
288
|
await this.init(options?.doSilent, options?.enableSync);
|
|
264
289
|
}
|
|
265
290
|
this.server = server;
|
|
291
|
+
this.websocketRuntime ??= new WebSocketRuntime(this.config.server.websocket);
|
|
266
292
|
const timezone = this.config.api.timezone;
|
|
267
293
|
if (timezone) {
|
|
268
294
|
const { formatInTimeZone } = await import("date-fns-tz");
|
|
@@ -319,6 +345,15 @@ var init_sonamu = __esmMin((() => {
|
|
|
319
345
|
if (this.syncer.models[api.modelName] === undefined) {
|
|
320
346
|
throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);
|
|
321
347
|
}
|
|
348
|
+
if (api.websocketOptions) {
|
|
349
|
+
server.route({
|
|
350
|
+
method: "GET",
|
|
351
|
+
url: this.config.api.route.prefix + api.path,
|
|
352
|
+
handler: this.createWebSocketUpgradeRequiredHandler(),
|
|
353
|
+
wsHandler: this.createWebSocketHandler(api, config)
|
|
354
|
+
});
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
322
357
|
server.route({
|
|
323
358
|
method: api.options.httpMethod ?? "GET",
|
|
324
359
|
url: this.config.api.route.prefix + api.path,
|
|
@@ -337,12 +372,22 @@ var init_sonamu = __esmMin((() => {
|
|
|
337
372
|
* 요청이 /api(정확히는 this.config.api.route.prefix)로 시작하지 않는 경우라면 null을 반환하며 끝냅니다.
|
|
338
373
|
*/
|
|
339
374
|
handleDevApiRequest(request, config) {
|
|
375
|
+
const matchedApi = this.findMatchedApi(request);
|
|
376
|
+
if (!matchedApi) {
|
|
377
|
+
throw new NotFoundException(SD("error.api.notFound"));
|
|
378
|
+
}
|
|
379
|
+
if (matchedApi.websocketOptions) {
|
|
380
|
+
return this.createWebSocketUpgradeRequiredHandler();
|
|
381
|
+
}
|
|
382
|
+
return this.createApiHandler(matchedApi, config);
|
|
383
|
+
}
|
|
384
|
+
findMatchedApi(request) {
|
|
340
385
|
const url = this.getPathnameFromUrl(request.url);
|
|
341
386
|
const method = request.method;
|
|
342
387
|
if (!url.startsWith(this.config.api.route.prefix)) {
|
|
343
|
-
return
|
|
388
|
+
return undefined;
|
|
344
389
|
}
|
|
345
|
-
|
|
390
|
+
return this.syncer.apis.find((api) => {
|
|
346
391
|
if (this.syncer.models[api.modelName] === undefined) {
|
|
347
392
|
return false;
|
|
348
393
|
}
|
|
@@ -351,19 +396,28 @@ var init_sonamu = __esmMin((() => {
|
|
|
351
396
|
const fullPath = this.config.api.route.prefix + api.path;
|
|
352
397
|
return this.isPathPatternMatch(fullPath, url);
|
|
353
398
|
});
|
|
354
|
-
if (!matchedApi) {
|
|
355
|
-
throw new NotFoundException(SD("error.api.notFound"));
|
|
356
|
-
}
|
|
357
|
-
return this.createApiHandler(matchedApi, config);
|
|
358
399
|
}
|
|
359
400
|
/**
|
|
360
401
|
* dev api 모드: Vite 없이 API 동적 라우팅만 제공합니다.
|
|
361
402
|
* HMR을 위해 catch-all에서 매 요청마다 syncer.apis를 조회합니다.
|
|
362
403
|
*/
|
|
363
404
|
setupDevServer(server, config) {
|
|
405
|
+
server.route({
|
|
406
|
+
method: "GET",
|
|
407
|
+
url: `${this.config.api.route.prefix}/*`,
|
|
408
|
+
handler: async (request, reply) => {
|
|
409
|
+
const handler = this.handleDevApiRequest(request, config);
|
|
410
|
+
if (handler) {
|
|
411
|
+
return handler(request, reply);
|
|
412
|
+
}
|
|
413
|
+
throw new NotFoundException(SD("error.api.notFound"));
|
|
414
|
+
},
|
|
415
|
+
wsHandler: async (connection, request) => {
|
|
416
|
+
await this.handleDevWebSocketRequest(connection.socket, request, config);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
364
419
|
server.route({
|
|
365
420
|
method: [
|
|
366
|
-
"GET",
|
|
367
421
|
"HEAD",
|
|
368
422
|
"POST",
|
|
369
423
|
"PUT",
|
|
@@ -388,11 +442,16 @@ var init_sonamu = __esmMin((() => {
|
|
|
388
442
|
async setupDevServerWithVite(server, webPath, config) {
|
|
389
443
|
await server.register((await import("@fastify/middie")).default);
|
|
390
444
|
const vite = await import("vite");
|
|
445
|
+
const requiresDedicatedHmrServer = Boolean(this.config.server.plugins?.ws);
|
|
446
|
+
const hmr = resolveIntegratedViteHmrOptions({
|
|
447
|
+
httpServer: server.server,
|
|
448
|
+
requiresDedicatedWebSocketServer: requiresDedicatedHmrServer
|
|
449
|
+
});
|
|
391
450
|
this.viteServer = await vite.createServer({
|
|
392
451
|
root: webPath,
|
|
393
452
|
server: {
|
|
394
453
|
middlewareMode: true,
|
|
395
|
-
hmr
|
|
454
|
+
hmr
|
|
396
455
|
},
|
|
397
456
|
appType: "custom"
|
|
398
457
|
});
|
|
@@ -402,21 +461,41 @@ var init_sonamu = __esmMin((() => {
|
|
|
402
461
|
}
|
|
403
462
|
return this.viteServer.middlewares(req, res, next);
|
|
404
463
|
});
|
|
464
|
+
server.route({
|
|
465
|
+
method: "GET",
|
|
466
|
+
url: `${this.config.api.route.prefix}/*`,
|
|
467
|
+
handler: async (request, reply) => {
|
|
468
|
+
const result = this.handleDevApiRequest(request, config);
|
|
469
|
+
if (result) {
|
|
470
|
+
return result(request, reply);
|
|
471
|
+
}
|
|
472
|
+
throw new NotFoundException(SD("error.api.notFound"));
|
|
473
|
+
},
|
|
474
|
+
wsHandler: async (connection, request) => {
|
|
475
|
+
await this.handleDevWebSocketRequest(connection.socket, request, config);
|
|
476
|
+
}
|
|
477
|
+
});
|
|
405
478
|
server.route({
|
|
406
479
|
method: [
|
|
407
|
-
"GET",
|
|
408
480
|
"HEAD",
|
|
409
481
|
"POST",
|
|
410
482
|
"PUT",
|
|
411
483
|
"DELETE",
|
|
412
484
|
"PATCH"
|
|
413
485
|
],
|
|
414
|
-
url:
|
|
486
|
+
url: `${this.config.api.route.prefix}/*`,
|
|
415
487
|
handler: async (request, reply) => {
|
|
416
488
|
const result = this.handleDevApiRequest(request, config);
|
|
417
489
|
if (result) {
|
|
418
490
|
return result(request, reply);
|
|
419
491
|
}
|
|
492
|
+
throw new NotFoundException(SD("error.api.notFound"));
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
server.route({
|
|
496
|
+
method: ["GET", "HEAD"],
|
|
497
|
+
url: "/*",
|
|
498
|
+
handler: async (request, reply) => {
|
|
420
499
|
const url = request.url;
|
|
421
500
|
const { matchSSRRoute, renderSSR } = await import("../ssr/index.js");
|
|
422
501
|
const ssrMatch = matchSSRRoute(url);
|
|
@@ -443,8 +522,11 @@ var init_sonamu = __esmMin((() => {
|
|
|
443
522
|
server.addHook("onClose", async () => {
|
|
444
523
|
await this.viteServer.close();
|
|
445
524
|
});
|
|
446
|
-
const chalk = (await import("chalk")).default;
|
|
447
|
-
|
|
525
|
+
const chalk$1 = (await import("chalk")).default;
|
|
526
|
+
if ("port" in hmr) {
|
|
527
|
+
console.log(chalk$1.dim(`✓ Vite HMR using dedicated websocket port ${hmr.port} to avoid Fastify websocket conflicts`));
|
|
528
|
+
}
|
|
529
|
+
console.log(chalk$1.dim("✓ Vite dev server integrated"));
|
|
448
530
|
}
|
|
449
531
|
async setupStaticWebServer(server, config, globalCompressOptions) {
|
|
450
532
|
const webDistPath = path.join(this.apiRootPath, "web-dist", "client");
|
|
@@ -575,7 +657,12 @@ var init_sonamu = __esmMin((() => {
|
|
|
575
657
|
return async (request, reply) => {
|
|
576
658
|
const context = await this.createContext(config, request, reply);
|
|
577
659
|
return this.asyncLocalStorage.run({ context }, async () => {
|
|
578
|
-
(
|
|
660
|
+
runGuards({
|
|
661
|
+
guards: api.options.guards,
|
|
662
|
+
config,
|
|
663
|
+
request,
|
|
664
|
+
api
|
|
665
|
+
});
|
|
579
666
|
const { getZodObjectFromApi } = await import("./code-converters.js");
|
|
580
667
|
const ReqType = getZodObjectFromApi(api, this.syncer.types);
|
|
581
668
|
const which = api.options.httpMethod === "GET" ? "query" : "body";
|
|
@@ -667,6 +754,151 @@ var init_sonamu = __esmMin((() => {
|
|
|
667
754
|
});
|
|
668
755
|
};
|
|
669
756
|
}
|
|
757
|
+
createWebSocketUpgradeRequiredHandler() {
|
|
758
|
+
return async (_request, reply) => {
|
|
759
|
+
reply.header("connection", "Upgrade").header("upgrade", "websocket").status(426).send({ message: "WebSocket upgrade required" });
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
async handleDevWebSocketRequest(socket, request, config) {
|
|
763
|
+
const matchedApi = this.findMatchedApi(request);
|
|
764
|
+
if (!matchedApi?.websocketOptions) {
|
|
765
|
+
socket.close(1008, "WebSocket route not found");
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
const handler = this.createWebSocketHandler(matchedApi, config);
|
|
769
|
+
await handler({ socket }, request);
|
|
770
|
+
}
|
|
771
|
+
createWebSocketHandler(api, config) {
|
|
772
|
+
return async (connection, request) => {
|
|
773
|
+
const socket = connection.socket;
|
|
774
|
+
let wsContext = null;
|
|
775
|
+
let rawWs = null;
|
|
776
|
+
try {
|
|
777
|
+
runGuards({
|
|
778
|
+
guards: api.options.guards,
|
|
779
|
+
config,
|
|
780
|
+
request,
|
|
781
|
+
api
|
|
782
|
+
});
|
|
783
|
+
const reqBody = await this.parseWebSocketRequestParams(api, request);
|
|
784
|
+
rawWs = this.websocketRuntime.registerConnection(socket, {
|
|
785
|
+
outEvents: api.websocketOptions.outEvents,
|
|
786
|
+
inEvents: api.websocketOptions.inEvents,
|
|
787
|
+
namespace: api.websocketOptions.namespace,
|
|
788
|
+
heartbeat: api.websocketOptions.heartbeat,
|
|
789
|
+
maxPayload: api.websocketOptions.maxPayload,
|
|
790
|
+
active: false
|
|
791
|
+
});
|
|
792
|
+
const scopedWs = this.createScopedWebSocketConnection(rawWs, () => wsContext);
|
|
793
|
+
wsContext = await this.createWebSocketContext(config, request, scopedWs);
|
|
794
|
+
this.websocketRuntime.activateConnection(rawWs.id);
|
|
795
|
+
const { ApiParamType } = await import("../types/types.js");
|
|
796
|
+
const args = api.parameters.map((param) => {
|
|
797
|
+
if (ApiParamType.isContext(param.type)) {
|
|
798
|
+
return wsContext;
|
|
799
|
+
}
|
|
800
|
+
return reqBody[param.name];
|
|
801
|
+
});
|
|
802
|
+
await this.asyncLocalStorage.run({ context: wsContext }, async () => {
|
|
803
|
+
await this.invokeModelMethod(api, args);
|
|
804
|
+
});
|
|
805
|
+
} catch (error) {
|
|
806
|
+
const closeDescriptor = resolveWebSocketCloseDescriptor(error);
|
|
807
|
+
if (rawWs) {
|
|
808
|
+
rawWs.close(closeDescriptor.code, closeDescriptor.reason);
|
|
809
|
+
} else if (socket.readyState < 2) {
|
|
810
|
+
socket.close(closeDescriptor.code, closeDescriptor.reason);
|
|
811
|
+
}
|
|
812
|
+
if (this.server?.log) {
|
|
813
|
+
const payload = {
|
|
814
|
+
err: error,
|
|
815
|
+
modelName: api.modelName,
|
|
816
|
+
methodName: api.methodName,
|
|
817
|
+
path: api.path
|
|
818
|
+
};
|
|
819
|
+
if (closeDescriptor.logLevel === "warn") {
|
|
820
|
+
this.server.log.warn(payload, closeDescriptor.reason);
|
|
821
|
+
} else {
|
|
822
|
+
this.server.log.error(payload, closeDescriptor.reason);
|
|
823
|
+
}
|
|
824
|
+
} else {
|
|
825
|
+
if (closeDescriptor.logLevel === "warn") {
|
|
826
|
+
console.warn(closeDescriptor.reason, error);
|
|
827
|
+
} else {
|
|
828
|
+
console.error(closeDescriptor.reason, error);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
createScopedWebSocketConnection(ws, getContext) {
|
|
835
|
+
const runInContext = (callback) => {
|
|
836
|
+
const context = getContext();
|
|
837
|
+
if (!context) {
|
|
838
|
+
return callback();
|
|
839
|
+
}
|
|
840
|
+
return this.asyncLocalStorage.run({ context }, callback);
|
|
841
|
+
};
|
|
842
|
+
return {
|
|
843
|
+
get id() {
|
|
844
|
+
return ws.id;
|
|
845
|
+
},
|
|
846
|
+
get namespace() {
|
|
847
|
+
return ws.namespace;
|
|
848
|
+
},
|
|
849
|
+
get closed() {
|
|
850
|
+
return ws.closed;
|
|
851
|
+
},
|
|
852
|
+
transport: "ws",
|
|
853
|
+
publishUntyped(event, data) {
|
|
854
|
+
ws.publishUntyped(event, data);
|
|
855
|
+
},
|
|
856
|
+
close(code, reason) {
|
|
857
|
+
ws.close(code, reason);
|
|
858
|
+
},
|
|
859
|
+
onClose(callback) {
|
|
860
|
+
ws.onClose(() => runInContext(callback));
|
|
861
|
+
},
|
|
862
|
+
onMessage(event, handler) {
|
|
863
|
+
ws.onMessage(event, (data) => runInContext(() => handler(data)));
|
|
864
|
+
},
|
|
865
|
+
publish(event, data) {
|
|
866
|
+
ws.publish(event, data);
|
|
867
|
+
},
|
|
868
|
+
waitForClose() {
|
|
869
|
+
return ws.waitForClose();
|
|
870
|
+
},
|
|
871
|
+
join(roomId) {
|
|
872
|
+
ws.join(roomId);
|
|
873
|
+
},
|
|
874
|
+
leave(roomId) {
|
|
875
|
+
ws.leave(roomId);
|
|
876
|
+
},
|
|
877
|
+
setUserId(userId) {
|
|
878
|
+
ws.setUserId(userId);
|
|
879
|
+
},
|
|
880
|
+
clearUserId() {
|
|
881
|
+
ws.clearUserId();
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
async parseWebSocketRequestParams(api, request) {
|
|
886
|
+
const { getZodObjectFromApi } = await import("./code-converters.js");
|
|
887
|
+
const ReqType = getZodObjectFromApi(api, this.syncer.types);
|
|
888
|
+
try {
|
|
889
|
+
const { fastifyCaster } = await import("./caster.js");
|
|
890
|
+
return fastifyCaster(ReqType).parse(request.query ?? {});
|
|
891
|
+
} catch (e) {
|
|
892
|
+
const { ZodError } = await import("zod");
|
|
893
|
+
if (e instanceof ZodError) {
|
|
894
|
+
const { humanizeZodError } = await import("../utils/zod-error.js");
|
|
895
|
+
const messages = humanizeZodError(e).map((issue) => issue.message).join(" ");
|
|
896
|
+
const { BadRequestException } = await import("../exceptions/so-exceptions.js");
|
|
897
|
+
throw new BadRequestException(messages, { zodError: e });
|
|
898
|
+
}
|
|
899
|
+
throw e;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
670
902
|
/**
|
|
671
903
|
* URL에서 path params를 추출합니다.
|
|
672
904
|
* 예: pattern="/admin/companies/:companyId", url="/admin/companies/123" → { companyId: "123" }
|
|
@@ -762,7 +994,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
762
994
|
async invokeModelMethod(api, args, reply) {
|
|
763
995
|
const model = this.syncer.models[api.modelName];
|
|
764
996
|
const result = await model[api.methodName].apply(model, args);
|
|
765
|
-
reply
|
|
997
|
+
reply?.type(api.options.contentType ?? "application/json");
|
|
766
998
|
return result;
|
|
767
999
|
}
|
|
768
1000
|
async createContext(config, request, reply) {
|
|
@@ -771,7 +1003,8 @@ var init_sonamu = __esmMin((() => {
|
|
|
771
1003
|
const locale = this.detectLocale(request.headers["accept-language"], this.config.i18n.supportedLocales) ?? this.config.i18n.defaultLocale;
|
|
772
1004
|
const headers = convertFastifyHeadersToStandard(request.headers);
|
|
773
1005
|
const session = await this._auth?.api.getSession({ headers }) ?? null;
|
|
774
|
-
const context =
|
|
1006
|
+
const context = await Promise.resolve(config.contextProvider({
|
|
1007
|
+
transport: "http",
|
|
775
1008
|
request,
|
|
776
1009
|
reply,
|
|
777
1010
|
headers: request.headers,
|
|
@@ -780,9 +1013,50 @@ var init_sonamu = __esmMin((() => {
|
|
|
780
1013
|
locale,
|
|
781
1014
|
user: session?.user ?? null,
|
|
782
1015
|
session: session?.session ?? null
|
|
783
|
-
}, request, reply))
|
|
1016
|
+
}, request, reply));
|
|
784
1017
|
return context;
|
|
785
1018
|
}
|
|
1019
|
+
async createWebSocketContext(config, request, ws) {
|
|
1020
|
+
const locale = this.detectLocale(request.headers["accept-language"], this.config.i18n.supportedLocales) ?? this.config.i18n.defaultLocale;
|
|
1021
|
+
const headers = convertFastifyHeadersToStandard(request.headers);
|
|
1022
|
+
const session = await this._auth?.api.getSession({ headers }) ?? null;
|
|
1023
|
+
const defaultContext = {
|
|
1024
|
+
transport: "ws",
|
|
1025
|
+
request,
|
|
1026
|
+
headers: request.headers,
|
|
1027
|
+
ws,
|
|
1028
|
+
naiteStore: new Map(),
|
|
1029
|
+
locale,
|
|
1030
|
+
user: session?.user ?? null,
|
|
1031
|
+
session: session?.session ?? null
|
|
1032
|
+
};
|
|
1033
|
+
if (config.websocketContextProvider) {
|
|
1034
|
+
return { ...await Promise.resolve(config.websocketContextProvider(defaultContext, request)) };
|
|
1035
|
+
}
|
|
1036
|
+
const replyStub = createWebSocketReplyStub();
|
|
1037
|
+
const createSSE = (_events) => {
|
|
1038
|
+
throw new Error("createSSE is not available in websocket context. Define websocketContextProvider if your context setup depends on SSE helpers.");
|
|
1039
|
+
};
|
|
1040
|
+
const httpLikeContext = await Promise.resolve(config.contextProvider({
|
|
1041
|
+
transport: "http",
|
|
1042
|
+
request,
|
|
1043
|
+
reply: replyStub,
|
|
1044
|
+
headers: request.headers,
|
|
1045
|
+
createSSE,
|
|
1046
|
+
naiteStore: defaultContext.naiteStore,
|
|
1047
|
+
locale,
|
|
1048
|
+
user: defaultContext.user,
|
|
1049
|
+
session: defaultContext.session
|
|
1050
|
+
}, request, replyStub));
|
|
1051
|
+
const { transport: _transport, reply: _reply, createSSE: _createSSE, bufferedFiles: _bufferedFiles, uploadedFiles: _uploadedFiles, ...rest } = httpLikeContext;
|
|
1052
|
+
return {
|
|
1053
|
+
...rest,
|
|
1054
|
+
transport: "ws",
|
|
1055
|
+
request,
|
|
1056
|
+
headers: request.headers,
|
|
1057
|
+
ws
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
786
1060
|
/**
|
|
787
1061
|
* Accept-Language 헤더에서 지원하는 locale을 찾습니다.
|
|
788
1062
|
* @example "ko-KR,ko;q=0.9,en;q=0.8" → "ko"
|
|
@@ -796,33 +1070,24 @@ var init_sonamu = __esmMin((() => {
|
|
|
796
1070
|
return langs.find((lang) => supported.includes(lang));
|
|
797
1071
|
}
|
|
798
1072
|
async startWatcher() {
|
|
799
|
-
const
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)} - Restarting...`));
|
|
818
|
-
process.kill(process.pid, "SIGUSR2");
|
|
819
|
-
return;
|
|
820
|
-
}
|
|
821
|
-
await this.handleFileChange(event, absolutePath);
|
|
822
|
-
} catch (e) {
|
|
823
|
-
console.error(e);
|
|
824
|
-
}
|
|
825
|
-
});
|
|
1073
|
+
const { setupWatcher } = await import("../syncer/watcher.js");
|
|
1074
|
+
this.watcher = await setupWatcher((fileEvents) => this.runHmrSyncCycle(fileEvents));
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Watcher가 100ms batch로 모은 fileEvents 하나에 대해 한 번의 HMR/sync 사이클을 돕니다.
|
|
1078
|
+
* batch 큐잉 덕에 한 시점에 하나만 실행됨이 보장됩니다 (event-batcher가 직렬화).
|
|
1079
|
+
*/
|
|
1080
|
+
async runHmrSyncCycle(fileEvents) {
|
|
1081
|
+
const startedAt = Date.now();
|
|
1082
|
+
for (const [filePath, event] of fileEvents) {
|
|
1083
|
+
const relativePath = path.relative(this.appRootPath, filePath);
|
|
1084
|
+
console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)}`));
|
|
1085
|
+
}
|
|
1086
|
+
await this.syncer.hmrAndSync(fileEvents);
|
|
1087
|
+
await this.syncer.renewChecksums();
|
|
1088
|
+
const totalTime = Date.now() - startedAt;
|
|
1089
|
+
const msg = `HMR Done! ${chalk.bold.white(`${totalTime}ms`)}`;
|
|
1090
|
+
console.log(chalk.black.bgGreen(centerText(msg)));
|
|
826
1091
|
}
|
|
827
1092
|
async runScript(fn) {
|
|
828
1093
|
await this.init(true, false, undefined, false);
|
|
@@ -875,10 +1140,51 @@ var init_sonamu = __esmMin((() => {
|
|
|
875
1140
|
for (const [key, pluginName] of Object.entries(pluginsModules)) {
|
|
876
1141
|
await registerPlugin(key, pluginName);
|
|
877
1142
|
}
|
|
1143
|
+
if (plugins.ws) {
|
|
1144
|
+
await this.ensureWebSocketPlugin(server);
|
|
1145
|
+
}
|
|
878
1146
|
if (plugins.custom) {
|
|
879
1147
|
plugins.custom(server);
|
|
880
1148
|
}
|
|
881
1149
|
}
|
|
1150
|
+
async ensureWebSocketPlugin(server) {
|
|
1151
|
+
if (this.websocketPluginServers.has(server)) {
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const pluginOption = this.config.server.plugins?.ws;
|
|
1155
|
+
if (!pluginOption) {
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
const websocketPlugin = (await import("@fastify/websocket")).default;
|
|
1159
|
+
const resolvedPluginOptions = resolveWebSocketPluginOptions({
|
|
1160
|
+
rawPluginOption: pluginOption,
|
|
1161
|
+
apis: this.syncer.apis
|
|
1162
|
+
});
|
|
1163
|
+
if (resolvedPluginOptions) {
|
|
1164
|
+
await server.register(websocketPlugin, resolvedPluginOptions);
|
|
1165
|
+
} else {
|
|
1166
|
+
await server.register(websocketPlugin);
|
|
1167
|
+
}
|
|
1168
|
+
this.websocketPluginServers.add(server);
|
|
1169
|
+
this.warnOnPotentialWebSocketTimeoutConflicts(server);
|
|
1170
|
+
}
|
|
1171
|
+
warnOnPotentialWebSocketTimeoutConflicts(server) {
|
|
1172
|
+
const heartbeats = this.syncer.apis.map((api) => api.websocketOptions?.heartbeat ?? 3e4).filter((heartbeat) => heartbeat > 0);
|
|
1173
|
+
if (heartbeats.length === 0) {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
const keepAliveTimeout = this.config.server.fastify?.keepAliveTimeout;
|
|
1177
|
+
if (!keepAliveTimeout || keepAliveTimeout <= 0) {
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1180
|
+
const largestHeartbeat = Math.max(...heartbeats);
|
|
1181
|
+
if (largestHeartbeat >= keepAliveTimeout) {
|
|
1182
|
+
server.log.warn({
|
|
1183
|
+
keepAliveTimeout,
|
|
1184
|
+
largestHeartbeat
|
|
1185
|
+
}, "WebSocket heartbeat is greater than or equal to keepAliveTimeout; align infrastructure idle timeouts to avoid unexpected disconnects.");
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
882
1188
|
/**
|
|
883
1189
|
* better-auth 라우트를 등록합니다.
|
|
884
1190
|
* /api/auth/* 경로로 인증 API가 자동 등록됩니다.
|
|
@@ -916,11 +1222,11 @@ var init_sonamu = __esmMin((() => {
|
|
|
916
1222
|
});
|
|
917
1223
|
}
|
|
918
1224
|
async printStartupSummary() {
|
|
919
|
-
const chalk = (await import("chalk")).default;
|
|
1225
|
+
const chalk$1 = (await import("chalk")).default;
|
|
920
1226
|
const env = process.env.NODE_ENV ?? "development";
|
|
921
1227
|
const activePreset = env === "production" ? "production_master" : "development_master";
|
|
922
|
-
const dim = (msg) => console.log(chalk.dim(`✓ ${msg}`));
|
|
923
|
-
const green = (msg) => console.log(chalk.green(`✓ ${msg}`));
|
|
1228
|
+
const dim = (msg) => console.log(chalk$1.dim(`✓ ${msg}`));
|
|
1229
|
+
const green = (msg) => console.log(chalk$1.green(`✓ ${msg}`));
|
|
924
1230
|
dim(`Config loaded${formatTime(this._configElapsed)}`);
|
|
925
1231
|
green("DB");
|
|
926
1232
|
const { isLocal } = await import("../utils/controller.js");
|
|
@@ -931,11 +1237,11 @@ var init_sonamu = __esmMin((() => {
|
|
|
931
1237
|
const host = conn?.host ?? "localhost";
|
|
932
1238
|
const addr = `@ ${host}:${conn?.port ?? 5432}/${conn?.database ?? this.config.database.name}`;
|
|
933
1239
|
const padded = name.padEnd(maxLen);
|
|
934
|
-
const remoteTag = isLocal() && !isLocalHost(host) ? chalk.yellow(` \u26a0 remote`) : "";
|
|
1240
|
+
const remoteTag = isLocal() && !isLocalHost(host) ? chalk$1.yellow(` \u26a0 remote`) : "";
|
|
935
1241
|
if (name === activePreset) {
|
|
936
|
-
console.log(chalk.green(` \u25b8 ${padded} ${addr}`) + remoteTag);
|
|
1242
|
+
console.log(chalk$1.green(` \u25b8 ${padded} ${addr}`) + remoteTag);
|
|
937
1243
|
} else {
|
|
938
|
-
console.log(chalk.dim(` ${padded} ${addr}`) + remoteTag);
|
|
1244
|
+
console.log(chalk$1.dim(` ${padded} ${addr}`) + remoteTag);
|
|
939
1245
|
}
|
|
940
1246
|
}
|
|
941
1247
|
if (this.config.server.auth) {
|
|
@@ -1011,43 +1317,23 @@ var init_sonamu = __esmMin((() => {
|
|
|
1011
1317
|
await this.workflows.startWorker();
|
|
1012
1318
|
await options.lifecycle?.onStart?.(server);
|
|
1013
1319
|
}).catch(async (err) => {
|
|
1014
|
-
const chalk = (await import("chalk")).default;
|
|
1015
|
-
console.error(chalk.red("Failed to start server:", err));
|
|
1320
|
+
const chalk$1 = (await import("chalk")).default;
|
|
1321
|
+
console.error(chalk$1.red("Failed to start server:", err));
|
|
1016
1322
|
await shutdown();
|
|
1017
1323
|
});
|
|
1018
1324
|
}
|
|
1019
|
-
async handleFileChange(event, filePath) {
|
|
1020
|
-
if (this.pendingFiles.length === 0) {
|
|
1021
|
-
this.hmrStartTime = Date.now();
|
|
1022
|
-
}
|
|
1023
|
-
this.pendingFiles.push(filePath);
|
|
1024
|
-
const relativePath = path.relative(this.apiRootPath, filePath);
|
|
1025
|
-
const chalk = (await import("chalk")).default;
|
|
1026
|
-
console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)}`));
|
|
1027
|
-
await this.syncer.syncFromWatcher(event, filePath);
|
|
1028
|
-
this.pendingFiles = this.pendingFiles.slice(1);
|
|
1029
|
-
if (this.pendingFiles.length === 0) {
|
|
1030
|
-
await this.finishHMR();
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
async finishHMR() {
|
|
1034
|
-
await this.syncer.renewChecksums();
|
|
1035
|
-
const endTime = Date.now();
|
|
1036
|
-
const totalTime = endTime - this.hmrStartTime;
|
|
1037
|
-
const [chalk, { centerText }] = await Promise.all([(await import("chalk")).default, import("../utils/console-util.js")]);
|
|
1038
|
-
const msg = `HMR Done! ${chalk.bold.white(`${totalTime}ms`)}`;
|
|
1039
|
-
console.log(chalk.black.bgGreen(centerText(msg)));
|
|
1040
|
-
}
|
|
1041
1325
|
async destroy() {
|
|
1042
1326
|
const { BaseModel } = await import("../database/base-model.js");
|
|
1043
1327
|
await BaseModel.destroy();
|
|
1044
1328
|
await Promise.allSettled([
|
|
1329
|
+
this._websocketRuntime?.shutdown() ?? Promise.resolve(),
|
|
1045
1330
|
this._workflows?.destroy() ?? Promise.resolve(),
|
|
1046
1331
|
this._cache?.disconnect() ?? Promise.resolve(),
|
|
1047
1332
|
this._devVitestManager?.shutdown() ?? Promise.resolve(),
|
|
1048
1333
|
this.watcher?.close() ?? Promise.resolve(),
|
|
1049
1334
|
dispose()
|
|
1050
1335
|
]);
|
|
1336
|
+
this._websocketRuntime = null;
|
|
1051
1337
|
}
|
|
1052
1338
|
};
|
|
1053
1339
|
Sonamu = new SonamuClass();
|
|
@@ -1061,5 +1347,5 @@ var init_sonamu = __esmMin((() => {
|
|
|
1061
1347
|
|
|
1062
1348
|
//#endregion
|
|
1063
1349
|
init_sonamu();
|
|
1064
|
-
export { Sonamu, init_sonamu };
|
|
1065
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmpzIiwibmFtZXMiOlsiREIiLCJhdXRoT3B0aW9uczogQmV0dGVyQXV0aE9wdGlvbnMiLCJnbG9iYWxDb21wcmVzc09wdGlvbnM6IENvbXByZXNzT3B0aW9ucyB8IHVuZGVmaW5lZCIsImZzIiwiY2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QiLCJmaWxlUGF0aCIsImNzckNhY2hlUmVxOiBDYWNoZUNvbnRyb2xSZXF1ZXN0IiwibWltZUxvb2t1cCIsImNvbnRleHQ6IENvbnRleHQiLCJyZXFCb2R5OiB7XG4gICAgICAgICAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbiAgICAgICAgfSIsImZpbGVzOiB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogQnVmZmVyZWRGaWxlW107XG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogVXBsb2FkZWRGaWxlW107XG4gICAgICAgIH0iLCJmaWVsZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4iLCJrZXlHZW5lcmF0b3I6IEtleUdlbmVyYXRvciIsInBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiIsInBhdGgiLCJsb2d0YXBlRGlzcG9zZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvc29uYW11LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwiYXN5bmNfaG9va3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlciwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyBkaXNwb3NlIGFzIGxvZ3RhcGVEaXNwb3NlIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IHR5cGUgQXV0aCwgdHlwZSBCZXR0ZXJBdXRoT3B0aW9ucyB9IGZyb20gXCJiZXR0ZXItYXV0aFwiO1xuaW1wb3J0IHsgdHlwZSBGU1dhdGNoZXIgfSBmcm9tIFwiY2hva2lkYXJcIjtcbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlLCB0eXBlIEZhc3RpZnlSZXBseSwgdHlwZSBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgbWltZSwgeyBsb29rdXAgYXMgbWltZUxvb2t1cCB9IGZyb20gXCJtaW1lLXR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIFpvZE9iamVjdCB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgQkFTRV9GSUVMRF9NQVBQSU5HUyB9IGZyb20gXCIuLi9hdXRoL2JldHRlci1hdXRoLWVudGl0aWVzXCI7XG5pbXBvcnQgeyBhcHBseUNhY2hlSGVhZGVycywgQ2FjaGVQcmVzZXRzIH0gZnJvbSBcIi4uL2NhY2hlLWNvbnRyb2wvY2FjaGUtY29udHJvbFwiO1xuaW1wb3J0IHsgdHlwZSBDYWNoZUNvbnRyb2xDb25maWcsIHR5cGUgQ2FjaGVDb250cm9sUmVxdWVzdCB9IGZyb20gXCIuLi9jYWNoZS1jb250cm9sL3R5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIENhY2hlQ29uZmlnLCB0eXBlIENhY2hlTWFuYWdlciB9IGZyb20gXCIuLi9jYWNoZS90eXBlc1wiO1xuaW1wb3J0IHsgdG9GYXN0aWZ5Q29tcHJlc3NPcHRpb24gfSBmcm9tIFwiLi4vY29tcHJlc3MvY29tcHJlc3NcIjtcbmltcG9ydCB7IHR5cGUgQ29tcHJlc3NPcHRpb25zIH0gZnJvbSBcIi4uL2NvbXByZXNzL3R5cGVzXCI7XG5pbXBvcnQgeyBEQiB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgU0QsIHNldFNEQ29uZmlnIH0gZnJvbSBcIi4uL2RpY3Qvc2RcIjtcbmltcG9ydCB7IHR5cGUgTG9jYWxpemVkU3RyaW5nIH0gZnJvbSBcIi4uL2RpY3QvdHlwZXNcIjtcbmltcG9ydCB7IE5vdEZvdW5kRXhjZXB0aW9uIH0gZnJvbSBcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiO1xuaW1wb3J0IHsgQnVmZmVyZWRGaWxlIH0gZnJvbSBcIi4uL3N0b3JhZ2UvYnVmZmVyZWQtZmlsZVwiO1xuaW1wb3J0IHsgdHlwZSBTdG9yYWdlTWFuYWdlciB9IGZyb20gXCIuLi9zdG9yYWdlL3N0b3JhZ2UtbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBLZXlHZW5lcmF0b3IgfSBmcm9tIFwiLi4vc3RvcmFnZS90eXBlc1wiO1xuaW1wb3J0IHsgVXBsb2FkZWRGaWxlIH0gZnJvbSBcIi4uL3N0b3JhZ2UvdXBsb2FkZWQtZmlsZVwiO1xuaW1wb3J0IHsgY3JlYXRlTW9ja1NTRUZhY3RvcnkgfSBmcm9tIFwiLi4vc3RyZWFtL3NzZVwiO1xuaW1wb3J0IHsgdHlwZSBTeW5jZXIgfSBmcm9tIFwiLi4vc3luY2VyL3N5bmNlclwiO1xuaW1wb3J0IHsgdHlwZSBXb3JrZmxvd01hbmFnZXIgfSBmcm9tIFwiLi4vdGFza3Mvd29ya2Zsb3ctbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBEZXZWaXRlc3RNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZGV2LXZpdGVzdC1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdUZhc3RpZnlDb25maWcgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGlzRGFlbW9uU2VydmVyIH0gZnJvbSBcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIjtcbmltcG9ydCB7IGV4aXN0cywgZmlsZUV4aXN0cyB9IGZyb20gXCIuLi91dGlscy9mcy11dGlsc1wiO1xuaW1wb3J0IHsgdHlwZSBBYnNvbHV0ZVBhdGggfSBmcm9tIFwiLi4vdXRpbHMvcGF0aC11dGlsc1wiO1xuaW1wb3J0IHsgY29udmVydEZhc3RpZnlIZWFkZXJzVG9TdGFuZGFyZCwgbWVyZ2UgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11Q29uZmlnLCB0eXBlIFNvbmFtdVNlcnZlck9wdGlvbnMsIHR5cGUgU29uYW11VGFza09wdGlvbnMgfSBmcm9tIFwiLi9jb25maWdcIjtcbmltcG9ydCB7IHR5cGUgQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB7IHR5cGUgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBnZXRTZWNyZXRzIH0gZnJvbSBcIi4vc2VjcmV0XCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdVNlY3JldHMgfSBmcm9tIFwiLi9zZWNyZXRcIjtcblxuY2xhc3MgU29uYW11Q2xhc3Mge1xuICBwdWJsaWMgaXNJbml0aWFsaXplZDogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgZm9yVGVzdGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgYXN5bmNMb2NhbFN0b3JhZ2U6IEFzeW5jTG9jYWxTdG9yYWdlPHtcbiAgICBjb250ZXh0OiBDb250ZXh0O1xuICB9PiA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZSgpO1xuXG4gIHB1YmxpYyBnZXRDb250ZXh0KCk6IENvbnRleHQge1xuICAgIGNvbnN0IHN0b3JlID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpO1xuICAgIGlmIChzdG9yZT8uY29udGV4dCkge1xuICAgICAgcmV0dXJuIHN0b3JlLmNvbnRleHQ7XG4gICAgfVxuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcInRlc3RcIikge1xuICAgICAgLy8g7YWM7Iqk7YyFIO2ZmOqyveyXkOyEnCDsu6jthY3siqTtirjqsIAg7KO87J6F65CY7KeAIOyViuydgCDqsr3smrAg67mIIOy7qO2FjeyKpO2KuCDrpqzthLRcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlcXVlc3Q6IG51bGwsXG4gICAgICAgIHJlcGx5OiBudWxsLFxuICAgICAgICBoZWFkZXJzOiB7fSxcbiAgICAgICAgY3JlYXRlU1NFOiAoc2NoZW1hOiBab2RPYmplY3QpID0+IGNyZWF0ZU1vY2tTU0VGYWN0b3J5KHNjaGVtYSksXG4gICAgICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55IC0tIO2FjOyKpO2MhSDtmZjqsr3sl5DshJwg7Luo7YWN7Iqk7Yq46rCAIOyjvOyeheuQmOyngCDslYrsnYAg6rK97JqwIOu5iCDsu6jthY3siqTtirgg66as7YS0XG4gICAgICAgIG5haXRlU3RvcmU6IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCksXG4gICAgICB9IGFzIHVua25vd24gYXMgQ29udGV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGNhbm5vdCBmaW5kIGNvbnRleHRcIik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCB8IG51bGwgPSBudWxsO1xuICBzZXQgYXBpUm9vdFBhdGgoYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCkge1xuICAgIHRoaXMuX2FwaVJvb3RQYXRoID0gYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwaVJvb3RQYXRoKCk6IEFic29sdXRlUGF0aCB7XG4gICAgaWYgKHRoaXMuX2FwaVJvb3RQYXRoID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwcFJvb3RQYXRoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXBpUm9vdFBhdGguc3BsaXQocGF0aC5zZXApLnNsaWNlKDAsIC0xKS5qb2luKHBhdGguc2VwKTtcbiAgfVxuXG4gIHByaXZhdGUgX2RiQ29uZmlnOiBTb25hbXVEQkNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgZGJDb25maWcoZGJDb25maWc6IFNvbmFtdURCQ29uZmlnKSB7XG4gICAgdGhpcy5fZGJDb25maWcgPSBkYkNvbmZpZztcbiAgfVxuICBnZXQgZGJDb25maWcoKTogU29uYW11REJDb25maWcge1xuICAgIGlmICh0aGlzLl9kYkNvbmZpZyA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2RiQ29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3luY2VyOiBTeW5jZXIgfCBudWxsID0gbnVsbDtcbiAgc2V0IHN5bmNlcihzeW5jZXI6IFN5bmNlcikge1xuICAgIHRoaXMuX3N5bmNlciA9IHN5bmNlcjtcbiAgfVxuICBnZXQgc3luY2VyKCk6IFN5bmNlciB7XG4gICAgaWYgKHRoaXMuX3N5bmNlciA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N5bmNlcjtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbmZpZzogU29uYW11Q29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHNldCBjb25maWcoY29uZmlnOiBTb25hbXVDb25maWcpIHtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gIH1cbiAgZ2V0IGNvbmZpZygpOiBTb25hbXVDb25maWcge1xuICAgIGlmICh0aGlzLl9jb25maWcgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0czogU29uYW11U2VjcmV0cyA9IGdldFNlY3JldHMoKTtcblxuICBwcml2YXRlIF9zdG9yYWdlOiBTdG9yYWdlTWFuYWdlciB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogU3RvcmFnZU1hbmFnZXIg7J247Iqk7YS07IqkXG4gICAqL1xuICBnZXQgc3RvcmFnZSgpOiBTdG9yYWdlTWFuYWdlciB7XG4gICAgaWYgKCF0aGlzLl9zdG9yYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTdG9yYWdlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC4gQ2hlY2sgc3RvcmFnZSBjb25maWcuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RvcmFnZTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhY2hlOiBDYWNoZU1hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIENhY2hlTWFuYWdlciDsnbjsiqTthLTsiqQgKEJlbnRvQ2FjaGUpXG4gICAqL1xuICBnZXQgY2FjaGUoKTogQ2FjaGVNYW5hZ2VyIHtcbiAgICBpZiAoIXRoaXMuX2NhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQuIENoZWNrIGNhY2hlIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlO1xuICB9XG5cbiAgcHJpdmF0ZSBfd29ya2Zsb3dzOiBXb3JrZmxvd01hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgZ2V0IHdvcmtmbG93cygpOiBXb3JrZmxvd01hbmFnZXIge1xuICAgIGlmICh0aGlzLl93b3JrZmxvd3MgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3dvcmtmbG93cztcbiAgfVxuXG4gIHByaXZhdGUgX2F1dGg6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHwgbnVsbCA9IG51bGw7XG4gIGdldCBhdXRoKCk6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHtcbiAgICBpZiAoIXRoaXMuX2F1dGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkF1dGggaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLiBDaGVjayBhdXRoIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2F1dGg7XG4gIH1cblxuICBwcml2YXRlIF9kZXZWaXRlc3RNYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIGdldCBkZXZWaXRlc3RNYW5hZ2VyKCk6IERldlZpdGVzdE1hbmFnZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fZGV2Vml0ZXN0TWFuYWdlcjtcbiAgfVxuICBzZXQgZGV2Vml0ZXN0TWFuYWdlcihtYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCkge1xuICAgIHRoaXMuX2RldlZpdGVzdE1hbmFnZXIgPSBtYW5hZ2VyO1xuICB9XG5cbiAgLy8gSE1SIOyymOumrFxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcGVuZGluZ0ZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIGhtclN0YXJ0VGltZTogbnVtYmVyID0gMDtcblxuICBwdWJsaWMgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UgfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBpbml0Rm9yVGVzdGluZygpIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBpbml0KFxuICAgIGRvU2lsZW50OiBib29sZWFuID0gZmFsc2UsXG4gICAgZW5hYmxlU3luYzogYm9vbGVhbiA9IHRydWUsXG4gICAgYXBpUm9vdFBhdGg/OiBBYnNvbHV0ZVBhdGgsXG4gICAgZm9yVGVzdGluZzogYm9vbGVhbiA9IGZhbHNlLFxuICApIHtcbiAgICB0aGlzLmZvclRlc3RpbmcgPSBmb3JUZXN0aW5nO1xuXG4gICAgaWYgKHRoaXMuaXNJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRTdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuXG4gICAgLy8gQVBJIOujqO2KuCDtjKjsiqRcbiAgICBjb25zdCB7IGZpbmRBcGlSb290UGF0aCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvdXRpbHNcIik7XG4gICAgdGhpcy5hcGlSb290UGF0aCA9IGFwaVJvb3RQYXRoID8/IGZpbmRBcGlSb290UGF0aCgpO1xuXG4gICAgLy8g7ISk7KCV7J2EIOuhnOuUqe2VmOuKlCDqsoPrtoDthLAg7Iuc7J6RXG4gICAgY29uc3QgY29uZmlnU3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBjb25zdCB7IGxvYWRDb25maWcgfSA9IGF3YWl0IGltcG9ydChcIi4vY29uZmlnXCIpO1xuICAgIHRoaXMuY29uZmlnID0gYXdhaXQgbG9hZENvbmZpZyh0aGlzLmFwaVJvb3RQYXRoKTtcbiAgICBjb25zdCBjb25maWdUaW1lID0gcGVyZm9ybWFuY2Uubm93KCkgLSBjb25maWdTdGFydDtcbiAgICBzZXRTRENvbmZpZyh0aGlzLmNvbmZpZy5pMThuKTtcbiAgICAvLyBzb25hbXUuY29uZmlnLnRzIOq4sOuzuOqwkiDshKTsoJVcbiAgICB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA9IHRoaXMuY29uZmlnLmRhdGFiYXNlLmRhdGFiYXNlID8/IFwicGdcIjtcbiAgICB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kZWZhdWx0T3B0aW9ucy5jbGllbnQgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG5cbiAgICAvLyDroZzquYUg7ISk7KCVXG4gICAgY29uc3QgeyBjb25maWd1cmVMb2dUYXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9sb2dnZXIvY29uZmlndXJlXCIpO1xuICAgIGlmICh0aGlzLmNvbmZpZy5sb2dnaW5nICE9PSBmYWxzZSkge1xuICAgICAgYXdhaXQgY29uZmlndXJlTG9nVGFwZSh7XG4gICAgICAgIC4uLnRoaXMuY29uZmlnLmxvZ2dpbmcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBEQiDroZzrk5xcbiAgICBjb25zdCB7IERCIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kYlwiKTtcbiAgICB0aGlzLmRiQ29uZmlnID0gREIuZ2VuZXJhdGVEQkNvbmZpZyh0aGlzLmNvbmZpZy5kYXRhYmFzZSk7XG4gICAgREIuc2V0Q29uZmlnKHRoaXMuZGJDb25maWcpO1xuXG4gICAgLy8gRW50aXR5IOuhnOuTnFxuICAgIC8vIO2FjOyKpO2KuOyXkOyEnOuPhCBFbnRpdHkg7KCV67O064qUIO2VhOyalO2VqeuLiOuLpC5cbiAgICAvLyB1cHNlcnTqsIAg7KCc64yA66GcIOyekeuPme2VmOugpOuptCBlbnRpdHnsnZggdW5pcXVlIGluZGV4IOygleuztOqwgCDtlYTsmpTtlZjquLAg65WM66y47J6F64uI64ukLlxuICAgIGNvbnN0IHsgRW50aXR5TWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCIpO1xuICAgIGF3YWl0IEVudGl0eU1hbmFnZXIuYXV0b2xvYWQoZG9TaWxlbnQpO1xuXG4gICAgLy8gQ2FjaGUg7LSI6riw7ZmUXG4gICAgYXdhaXQgdGhpcy5pbml0aWFsaXplQ2FjaGUodGhpcy5jb25maWcuc2VydmVyLmNhY2hlLCBmb3JUZXN0aW5nKTtcblxuICAgIC8vIEJldHRlckF1dGgg7LSI6riw7ZmUXG4gICAgY29uc3QgYXV0aENvbmZpZyA9IHRoaXMuY29uZmlnLnNlcnZlci5hdXRoO1xuICAgIGlmIChhdXRoQ29uZmlnKSB7XG4gICAgICAvLyDsgqzsmqnsnpAg7ISk7KCV6rO8IOq4sOuzuOqwkuydhCBtZXJnZVxuICAgICAgY29uc3QgbWVyZ2VkRmllbGRNYXBwaW5ncyA9IG1lcmdlKEJBU0VfRklFTERfTUFQUElOR1MsIGF1dGhDb25maWcpO1xuXG4gICAgICAvLyBiZXR0ZXItYXV0aCDsnbjsiqTthLTsiqQg7IOd7ISxXG4gICAgICBjb25zdCB7IGJldHRlckF1dGggfSA9IGF3YWl0IGltcG9ydChcImJldHRlci1hdXRoXCIpO1xuICAgICAgY29uc3QgeyBzb25hbXVLbmV4QWRhcHRlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vYXV0aC9rbmV4LWFkYXB0ZXJcIik7XG5cbiAgICAgIGNvbnN0IGF1dGhPcHRpb25zOiBCZXR0ZXJBdXRoT3B0aW9ucyA9IHtcbiAgICAgICAgZGF0YWJhc2U6IHNvbmFtdUtuZXhBZGFwdGVyKCksXG4gICAgICAgIC4uLm1lcmdlZEZpZWxkTWFwcGluZ3MsXG4gICAgICB9O1xuICAgICAgdGhpcy5fYXV0aCA9IGJldHRlckF1dGgoYXV0aE9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8vIO2FjOyKpO2MheyduCDqsr3smrAg7Iux7YGsIOyXhuydtCDspJHri6hcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUYXNrIOuTseuhnVxuICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZVdvcmtmbG93cyh0aGlzLmNvbmZpZy50YXNrcyk7XG5cbiAgICAvLyBTeW5jZXJcbiAgICBjb25zdCB7IFN5bmNlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3luY2VyL3N5bmNlclwiKTtcbiAgICB0aGlzLnN5bmNlciA9IG5ldyBTeW5jZXIoKTtcblxuICAgIC8vIEF1dG9sb2FkOiBNb2RlbHMgLyBUeXBlcyAvIEFQSXMgLyBXb3JrZmxvd3MgLyBUZW1wbGF0ZXMgLyBTU1IgUm91dGVzXG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRUeXBlcygpO1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkTW9kZWxzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRBcGlzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRXb3JrZmxvd3MoKTtcbiAgICBjb25zdCB7IFRlbXBsYXRlTWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdGVtcGxhdGVcIik7XG4gICAgYXdhaXQgVGVtcGxhdGVNYW5hZ2VyLmF1dG9sb2FkKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRTU1JSb3V0ZXMoKTtcblxuICAgIGNvbnN0IHsgaXNMb2NhbCwgaXNUZXN0LCBpc0hvdFJlbG9hZFNlcnZlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBpZiAoaXNMb2NhbCgpICYmICFpc1Rlc3QoKSAmJiBpc0hvdFJlbG9hZFNlcnZlcigpICYmIGVuYWJsZVN5bmMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY2VyLnN5bmMoKTtcbiAgICAgIGF3YWl0IHRoaXMuc3RhcnRXYXRjaGVyKCk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB0aGlzLl9pbml0RWxhcHNlZCA9IHBlcmZvcm1hbmNlLm5vdygpIC0gaW5pdFN0YXJ0O1xuICAgIHRoaXMuX2NvbmZpZ0VsYXBzZWQgPSBjb25maWdUaW1lO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdEVsYXBzZWQgPSAwO1xuICBwcml2YXRlIF9jb25maWdFbGFwc2VkID0gMDtcblxuICBhc3luYyBjcmVhdGVTZXJ2ZXIoaW5pdE9wdGlvbnM/OiB7IGVuYWJsZVN5bmM/OiBib29sZWFuOyBkb1NpbGVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICghdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXQoaW5pdE9wdGlvbnM/LmRvU2lsZW50LCBpbml0T3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuY29uZmlnLnNlcnZlcjtcbiAgICBjb25zdCB7IGRlZmF1bHQ6IGZhc3RpZnkgfSA9IGF3YWl0IGltcG9ydChcImZhc3RpZnlcIik7XG4gICAgY29uc3QgeyBnZXRMb2dUYXBlRmFzdGlmeUxvZ2dlciB9ID0gYXdhaXQgaW1wb3J0KFwiQGxvZ3RhcGUvZmFzdGlmeVwiKTtcbiAgICBjb25zdCBzZXJ2ZXIgPSBmYXN0aWZ5KHtcbiAgICAgIC4uLm9wdGlvbnMuZmFzdGlmeSxcbiAgICAgIGxvZ2dlcjpcbiAgICAgICAgdGhpcy5jb25maWcubG9nZ2luZyAhPT0gZmFsc2VcbiAgICAgICAgICA/IGdldExvZ1RhcGVGYXN0aWZ5TG9nZ2VyKHtcbiAgICAgICAgICAgICAgY2F0ZWdvcnk6IHRoaXMuY29uZmlnLmxvZ2dpbmc/LmZhc3RpZnlDYXRlZ29yeSA/PyBbXCJmYXN0aWZ5XCJdLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcblxuICAgIC8vIFN0b3JhZ2Ug7ISk7KCVIOKGkiBTdG9yYWdlTWFuYWdlciDsg53shLFcbiAgICBpZiAob3B0aW9ucy5zdG9yYWdlKSB7XG4gICAgICBjb25zdCB7IFN0b3JhZ2VNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zdG9yYWdlL3N0b3JhZ2UtbWFuYWdlclwiKTtcbiAgICAgIHRoaXMuX3N0b3JhZ2UgPSBuZXcgU3RvcmFnZU1hbmFnZXIob3B0aW9ucy5zdG9yYWdlKTtcbiAgICB9XG5cbiAgICAvLyDtlIzrn6zqt7jsnbgg65Ox66GdXG4gICAgaWYgKG9wdGlvbnMucGx1Z2lucykge1xuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlclBsdWdpbnMoc2VydmVyLCBvcHRpb25zLnBsdWdpbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmF1dGgpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJCZXR0ZXJBdXRoKHNlcnZlciwgb3B0aW9ucy5hdXRoKTtcbiAgICB9XG5cbiAgICAvLyBBUEkg65287Jqw7YyFIOyEpOyglVxuICAgIGF3YWl0IHRoaXMud2l0aEZhc3RpZnkoc2VydmVyLCBvcHRpb25zLmFwaUNvbmZpZywge1xuICAgICAgZW5hYmxlU3luYzogaW5pdE9wdGlvbnM/LmVuYWJsZVN5bmMsXG4gICAgICBkb1NpbGVudDogaW5pdE9wdGlvbnM/LmRvU2lsZW50LFxuICAgIH0pO1xuXG4gICAgLy8g7ISc67KEIOyLnOyekVxuICAgIGF3YWl0IHRoaXMuYm9vdChzZXJ2ZXIsIG9wdGlvbnMpO1xuXG4gICAgaWYgKCFpbml0T3B0aW9ucz8uZG9TaWxlbnQpIHtcbiAgICAgIHRoaXMucHJpbnRTdGFydHVwU3VtbWFyeSgpO1xuICAgIH1cblxuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICBhc3luYyB3aXRoRmFzdGlmeShcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICBvcHRpb25zPzoge1xuICAgICAgZW5hYmxlU3luYz86IGJvb2xlYW47XG4gICAgICBkb1NpbGVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKSB7XG4gICAgaWYgKCF0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChvcHRpb25zPy5kb1NpbGVudCwgb3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG5cbiAgICAvLyB0aW1lem9uZSDshKTsoJVcbiAgICBjb25zdCB0aW1lem9uZSA9IHRoaXMuY29uZmlnLmFwaS50aW1lem9uZTtcbiAgICBpZiAodGltZXpvbmUpIHtcbiAgICAgIC8vIO2DgOyehOyhtOyXkCDrp57qsowg7J2R64u1IOuCoOynnCDsiqTtirjrp4HsnYQg67OA7ZmY7ZW07KO87Ja07JW8IO2VqeuLiOuLpC5cbiAgICAgIC8vIOqwgOuguSB0aW1lem9uZeydtCBcIkFzaWEvU2VvdWxcIiDsnbTrqbRcbiAgICAgIC8vIFwiMjAyNS0xMS0yMVQwMDowMDowMC4wMDBaXCIg66W8IFwiMjAyNS0xMS0yMVQwOTowMDowMCswOTowMFwiIOycvOuhnCDrs4DtmZjtlbTso7zslrTslbwg7ZWp64uI64ukLlxuICAgICAgY29uc3QgeyBmb3JtYXRJblRpbWVab25lIH0gPSBhd2FpdCBpbXBvcnQoXCJkYXRlLWZucy10elwiKTtcblxuICAgICAgLy8gSVNPIDg2MDEg64Kg7KecIO2YleyLnSDsoJXqt5zsi50gKOyYiDogMjAyNC0wMS0xNVQwOTozMDowMC4wMDBaKVxuICAgICAgY29uc3QgSVNPX0RBVEVfUkVHRVggPSAvXlxcZHs0fS1cXGR7Mn0tXFxkezJ9VFxcZHsyfTpcXGR7Mn06XFxkezJ9KFxcLlxcZHszfSk/WiQvO1xuXG4gICAgICAvLyBU66W8IOuRmOufrOyLvCDsnpHsnYDrlLDsmLTtkZzqsIAg7JeG64uk66m0IFwiMjAyNS0xMS0xOTE3NjM1NDYxODkwMDAxODo1NjoyOSswOTowMFwi7JmAIOqwmeydgCDqsrDqs7zqsIAg64KY7Ji164uI64ukLlxuICAgICAgLy8g7J2064qUIGRhdGUtZm5zIO2KueyeheuLiOuLpC5cbiAgICAgIC8vIOydtOugh+qyjCDtlbTrj4Qg6rSc7LCu7Iq164uI64ukLiBcIjIwMjUtMTEtMTlUMTg6NTY6MjkrMDk6MDBcIiDrqqjslpHsnLzroZwg7J6YIOuCmOyYteuLiOuLpC5cbiAgICAgIGNvbnN0IERBVEVfRk9STUFUID0gXCJ5eXl5LU1NLWRkJ1QnSEg6bW06c3NYWFhcIjtcblxuICAgICAgc2VydmVyLnNldFJlcGx5U2VyaWFsaXplcigocGF5bG9hZCkgPT4ge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgKF9rZXksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiBJU09fREFURV9SRUdFWC50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdEluVGltZVpvbmUoXG4gICAgICAgICAgICAgIG5ldyBEYXRlKHZhbHVlKSxcbiAgICAgICAgICAgICAgdGltZXpvbmUgYXMgYCR7c3RyaW5nfS8ke3N0cmluZ31gLFxuICAgICAgICAgICAgICBEQVRFX0ZPUk1BVCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIC8vIFRpbWV6b25lIOuhnOq3uOuKlCBwcmludFN0YXJ0dXBTdW1tYXJ57JeQ7IScIO2Gte2VqSDstpzroKVcbiAgICB9XG5cbiAgICAvLyDsoITssrQg65287Jqw7YyFIOumrOyKpO2KuFxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9yb3V0ZXNgLFxuICAgICAgYXN5bmMgKF9yZXF1ZXN0LCBfcmVwbHkpOiBQcm9taXNlPHR5cGVvZiB0aGlzLnN5bmNlci5hcGlzPiA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5bmNlci5hcGlzO1xuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gSGVhbHRoY2hlY2sgQVBJXG4gICAgc2VydmVyLmdldChcbiAgICAgIGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9L2hlYWx0aGNoZWNrYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgcmV0dXJuIFwib2tcIjtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIFNvbmFtdSBVSSBBUEkgKOuhnOy7rCDtmZjqsr3sl5DshJzrp4wpXG4gICAgY29uc3QgeyBpc0xvY2FsIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9jb250cm9sbGVyXCIpO1xuICAgIGlmIChpc0xvY2FsKCkpIHtcbiAgICAgIGNvbnN0IHsgc29uYW11VUlBcGlQbHVnaW4gfSA9IGF3YWl0IGltcG9ydChcIi4uL3VpL2FwaVwiKTtcbiAgICAgIHNlcnZlci5yZWdpc3Rlcihzb25hbXVVSUFwaVBsdWdpbik7XG4gICAgfVxuXG4gICAgLy8gRGV2UnVubmVyIO2FjOyKpO2KuCDsl5Trk5ztj6zsnbjtirggKOuhnOy7rCDtmZjqsr0gKyBkZXZSdW5uZXIg7Zmc7ISx7ZmUIOyLnClcbiAgICBpZiAoaXNMb2NhbCgpICYmIHRoaXMuY29uZmlnLnRlc3Q/LmRldlJ1bm5lcj8uZW5hYmxlZCkge1xuICAgICAgY29uc3QgeyByZWdpc3RlckRldlRlc3RSb3V0ZXMgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rlc3RpbmcvZGV2LXRlc3Qtcm91dGVzXCIpO1xuICAgICAgYXdhaXQgcmVnaXN0ZXJEZXZUZXN0Um91dGVzKHNlcnZlciwgdGhpcy5jb25maWcudGVzdC5kZXZSdW5uZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHdlYlBhdGggPSBwYXRoLmpvaW4odGhpcy5hcHBSb290UGF0aCwgXCJ3ZWJcIik7XG4gICAgY29uc3QgaGFzV2ViID0gYXdhaXQgZXhpc3RzKHdlYlBhdGgpO1xuXG4gICAgLy8g7KCE7JetIGNvbXByZXNzIOyYteyFmCDqs4TsgrAgKHJvdXRlLmNvbXByZXNzOiB0cnVl7J28IOuVjCDsgqzsmqkpXG4gICAgY29uc3QgcGx1Z2luQ29tcHJlc3MgPSB0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8uY29tcHJlc3M7XG4gICAgY29uc3QgZ2xvYmFsQ29tcHJlc3NPcHRpb25zOiBDb21wcmVzc09wdGlvbnMgfCB1bmRlZmluZWQgPSBwbHVnaW5Db21wcmVzc1xuICAgICAgPyBwbHVnaW5Db21wcmVzcyA9PT0gdHJ1ZVxuICAgICAgICA/IHsgdGhyZXNob2xkOiAxMDI0LCBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIHRocmVzaG9sZDogcGx1Z2luQ29tcHJlc3MudGhyZXNob2xkLFxuICAgICAgICAgICAgZW5jb2RpbmdzOiBwbHVnaW5Db21wcmVzcy5lbmNvZGluZ3MsXG4gICAgICAgICAgICBjdXN0b21UeXBlczogcGx1Z2luQ29tcHJlc3MuY3VzdG9tVHlwZXMsXG4gICAgICAgICAgfVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoaXNMb2NhbCgpKSB7XG4gICAgICAvLyDroZzsu6wg6rCc67CcIO2ZmOqyvTogY2F0Y2gtYWxs66GcIEFQSeulvCDrj5nsoIEg66ek7Lmt7ZWY7JesIEhNUuydhCDsp4Dsm5Dtlanri4jri6QuXG4gICAgICAvLyBTT05BTVVfRElTQUJMRV9JTlRFR1JBVEVEX1dFQj15ZXProZwg7ISk7KCV7ZWY66m0IGRldl9hcGkg66qo65Oc7JeQ7IScIFZpdGUg7Ya17ZWp7J2EIOu5hO2ZnOyEse2ZlO2VoCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgY29uc3QgZGlzYWJsZUludGVncmF0ZWRXZWIgPSBwcm9jZXNzLmVudi5TT05BTVVfRElTQUJMRV9JTlRFR1JBVEVEX1dFQiA9PT0gXCJ5ZXNcIjtcbiAgICAgIGlmIChoYXNXZWIgJiYgIWRpc2FibGVJbnRlZ3JhdGVkV2ViKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0dXBEZXZTZXJ2ZXJXaXRoVml0ZShzZXJ2ZXIsIHdlYlBhdGgsIGNvbmZpZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldHVwRGV2U2VydmVyKHNlcnZlciwgY29uZmlnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8g7ZSE66Gc642V7IWYIO2ZmOqyvTog6rCc67OEIEFQSSDrnbzsmrDtirggKyDsoJXsoIEg7YyM7J28IOyEnOu5mVxuICAgICAgZm9yIChjb25zdCBhcGkgb2YgdGhpcy5zeW5jZXIuYXBpcykge1xuICAgICAgICBpZiAodGhpcy5zeW5jZXIubW9kZWxzW2FwaS5tb2RlbE5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOygleydmOuQmOyngCDslYrsnYAg66qo64247JeQIOygkeq3vCAke2FwaS5tb2RlbE5hbWV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgICAgIG1ldGhvZDogYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA/PyBcIkdFVFwiLFxuICAgICAgICAgIHVybDogdGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCArIGFwaS5wYXRoLFxuICAgICAgICAgIGhhbmRsZXI6IHRoaXMuY3JlYXRlQXBpSGFuZGxlcihhcGksIGNvbmZpZyksXG4gICAgICAgICAgY29tcHJlc3M6IHRvRmFzdGlmeUNvbXByZXNzT3B0aW9uKGFwaS5vcHRpb25zLmNvbXByZXNzLCBnbG9iYWxDb21wcmVzc09wdGlvbnMpLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8g7ZSE66Gc642V7IWY7JeQ7ISc64qUIHdlYiDshozsiqQoYXBwUm9vdC93ZWIpIOycoOustOyZgCDrrLTqtIDtlZjqsowsXG4gICAgICAvLyBhcGkvd2ViLWRpc3Qg7KG07J6sIOyXrOu2gOulvCBzZXR1cFN0YXRpY1dlYlNlcnZlciDrgrTrtoDsl5DshJwg7YyQ64uo7ZWp64uI64ukLlxuICAgICAgYXdhaXQgdGhpcy5zZXR1cFN0YXRpY1dlYlNlcnZlcihzZXJ2ZXIsIGNvbmZpZywgZ2xvYmFsQ29tcHJlc3NPcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZGV2IOuqqOuTnCDqs7XthrU6IGNhdGNoLWFsbOyXkOyEnCBzeW5jZXIuYXBpc+ulvCDrj5nsoIHsnLzroZwg7YOQ7IOJ7ZWY7JesIEFQSSDsmpTssq3snYQg7LKY66as7ZWp64uI64ukLlxuICAgKiBzZXJ2ZXIucm91dGUoKeuhnCDqsJzrs4Qg65Ox66Gd7ZWY66m0IGhhbmRsZXLqsIAg6rOg7KCV65CY7Ja0IEhNUuydtCDrj5nsnpHtlZjsp4Ag7JWK7Jy866+A66GcLFxuICAgKiDrp6Qg7JqU7LKt66eI64ukIHN5bmNlci5hcGlz66W8IOyhsO2ajO2VmOuKlCDsnbQg67Cp7Iud7J2EIOyCrOyaqe2VqeuLiOuLpC5cbiAgICpcbiAgICog7JqU7LKt7J20IC9hcGko7KCV7ZmV7Z6I64qUIHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgp66GcIOyLnOyeke2VmOyngCDslYrripQg6rK97Jqw652866m0IG51bGzsnYQg67CY7ZmY7ZWY66mwIOuBneuDheuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgaGFuZGxlRGV2QXBpUmVxdWVzdChcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6ICgocmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpID0+IFByb21pc2U8dW5rbm93bj4pIHwgbnVsbCB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRQYXRobmFtZUZyb21VcmwocmVxdWVzdC51cmwpO1xuICAgIGNvbnN0IG1ldGhvZCA9IHJlcXVlc3QubWV0aG9kO1xuXG4gICAgaWYgKCF1cmwuc3RhcnRzV2l0aCh0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4KSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gc3luY2VyLmFwaXPsnZggcGF0aOuKlCA6cGFyYW0g7ZiV7YOc66W8IO2PrO2VqO2VoCDsiJgg7J6I7Jy866+A66GcIOyEuOq3uOuovO2KuCDri6jsnITroZwg66ek7Lmt7ZWp64uI64ukLlxuICAgIC8vIOygleq3nOyLnSDsg53shLEg67Cp7Iud7J2AIHBhdGgg66y47J6Q7Je0IOuCtCDtirnsiJjrrLjsnpAoLiwgKywgKCwgWyDrk7Ep66GcIOyYpOyekeuPme2VoCDsiJgg7J6I7Ja0IOyCrOyaqe2VmOyngCDslYrsirXri4jri6QuXG4gICAgY29uc3QgbWF0Y2hlZEFwaSA9IHRoaXMuc3luY2VyLmFwaXMuZmluZCgoYXBpKSA9PiB7XG4gICAgICBpZiAodGhpcy5zeW5jZXIubW9kZWxzW2FwaS5tb2RlbE5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgYXBpTWV0aG9kID0gYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA/PyBcIkdFVFwiO1xuICAgICAgaWYgKGFwaU1ldGhvZCAhPT0gbWV0aG9kKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gdGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCArIGFwaS5wYXRoO1xuICAgICAgcmV0dXJuIHRoaXMuaXNQYXRoUGF0dGVybk1hdGNoKGZ1bGxQYXRoLCB1cmwpO1xuICAgIH0pO1xuXG4gICAgaWYgKCFtYXRjaGVkQXBpKSB7XG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUFwaUhhbmRsZXIobWF0Y2hlZEFwaSwgY29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBkZXYgYXBpIOuqqOuTnDogVml0ZSDsl4bsnbQgQVBJIOuPmeyggSDrnbzsmrDtjIXrp4wg7KCc6rO17ZWp64uI64ukLlxuICAgKiBITVLsnYQg7JyE7ZW0IGNhdGNoLWFsbOyXkOyEnCDrp6Qg7JqU7LKt66eI64ukIHN5bmNlci5hcGlz66W8IOyhsO2ajO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgc2V0dXBEZXZTZXJ2ZXIoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IHZvaWQge1xuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkdFVFwiLCBcIkhFQURcIiwgXCJQT1NUXCIsIFwiUFVUXCIsIFwiREVMRVRFXCIsIFwiUEFUQ0hcIl0sXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmhhbmRsZURldkFwaVJlcXVlc3QocmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlcihyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g65Ox66Gd65CcIEFQSeyZgCDsnbzsuZjtlZjsp4Ag7JWK64qUIOyalOyyreyXkCDrjIDtlZwgZmFsbGJhY2vsnoXri4jri6QuXG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLy8gb3hsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgLS0gVml0ZURldlNlcnZlciDtg4DsnoXsnYQg64+Z7KCB7Jy866GcIOuhnOuTnO2VtOyVvCDtlahcbiAgcHJpdmF0ZSB2aXRlU2VydmVyOiBhbnkgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBkZXYgYWxsIOuqqOuTnDogVml0ZSBEZXYgU2VydmVy66W8IO2Gte2Vqe2VmOyXrCBBUEkgKyBTU1IgKyBDU1LsnYQg66qo65GQIOygnOqzte2VqeuLiOuLpC5cbiAgICogQVBJIOuPmeyggSDrp6Tsua3snYAgaGFuZGxlRGV2QXBpUmVxdWVzdOulvCDqs7XsnKDtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNldHVwRGV2U2VydmVyV2l0aFZpdGUoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICB3ZWJQYXRoOiBzdHJpbmcsXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBAZmFzdGlmeS9taWRkaWUg65Ox66GdIChDb25uZWN0LXN0eWxlIG1pZGRsZXdhcmUg7KeA7JuQKVxuICAgIGF3YWl0IHNlcnZlci5yZWdpc3RlcigoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvbWlkZGllXCIpKS5kZWZhdWx0KTtcblxuICAgIGNvbnN0IHZpdGUgPSBhd2FpdCBpbXBvcnQoXCJ2aXRlXCIpO1xuXG4gICAgdGhpcy52aXRlU2VydmVyID0gYXdhaXQgdml0ZS5jcmVhdGVTZXJ2ZXIoe1xuICAgICAgcm9vdDogd2ViUGF0aCxcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBtaWRkbGV3YXJlTW9kZTogdHJ1ZSxcbiAgICAgICAgaG1yOiB7XG4gICAgICAgICAgc2VydmVyOiBzZXJ2ZXIuc2VydmVyLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFwcFR5cGU6IFwiY3VzdG9tXCIsXG4gICAgfSk7XG5cbiAgICAvLyBWaXRlIG1pZGRsZXdhcmUg65Ox66GdIChWaXRlIOyXkOyFiyDsspjrpqwpXG4gICAgc2VydmVyLnVzZSgocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICAgIC8vIEFQSeyZgCBTb25hbXUgVUnripQgRmFzdGlmeSDrnbzsmrDtirjqsIAg7LKY66as7ZWY64+E66GdIHNraXBcbiAgICAgIGlmIChyZXEudXJsPy5zdGFydHNXaXRoKHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgpIHx8IHJlcS51cmw/LnN0YXJ0c1dpdGgoXCIvc29uYW11LXVpXCIpKSB7XG4gICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICB9XG4gICAgICAvLyDrgpjrqLjsp4DripQgVml0ZSBtaWRkbGV3YXJl66GcIOyghOuLrFxuICAgICAgcmV0dXJuIHRoaXMudml0ZVNlcnZlci5taWRkbGV3YXJlcyhyZXEsIHJlcywgbmV4dCk7XG4gICAgfSk7XG5cbiAgICAvLyBjYXRjaC1hbGwg65287Jqw7Yq47JeQ7IScIOuPmeyggeycvOuhnCBBUEkvU1NSIOyymOumrFxuICAgIC8vIOqwnOuwnCDtmZjqsr3sl5DshJzripQg65287Jqw7Yq467OEIGNvbXByZXNzIOyYteyFmOydhCDtj6zquLDtlZjqs6AgSE1SIOydtOygkOydhCDst6jtlanri4jri6QuXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiLCBcIlBPU1RcIiwgXCJQVVRcIiwgXCJERUxFVEVcIiwgXCJQQVRDSFwiXSxcbiAgICAgIHVybDogXCIvKlwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIC8vIDEuIEFQSSDsmpTssq0g7LKY66asXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdChyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1cmwgPSByZXF1ZXN0LnVybDtcblxuICAgICAgICAvLyAyLiBTU1Ig65287Jqw7Yq4IOyymOumrFxuICAgICAgICBjb25zdCB7IG1hdGNoU1NSUm91dGUsIHJlbmRlclNTUiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyXCIpO1xuICAgICAgICBjb25zdCBzc3JNYXRjaCA9IG1hdGNoU1NSUm91dGUodXJsKTtcbiAgICAgICAgaWYgKHNzck1hdGNoKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYFtTU1JdIE1hdGNoZWQgcm91dGU6ICR7c3NyTWF0Y2gucm91dGUucGF0aH1gKTtcbiAgICAgICAgICBjb25zdCBodG1sID0gYXdhaXQgcmVuZGVyU1NSKFxuICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgc3NyTWF0Y2gucm91dGUsXG4gICAgICAgICAgICBzc3JNYXRjaC5wYXJhbXMsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgcmVwbHksXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICB0aGlzLnZpdGVTZXJ2ZXIsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXBseS50eXBlKFwidGV4dC9odG1sXCIpO1xuICAgICAgICAgIHJldHVybiBodG1sO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gMy4gQ1NSIGZhbGxiYWNrXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZnMgPSBhd2FpdCBpbXBvcnQoXCJub2RlOmZzL3Byb21pc2VzXCIpO1xuICAgICAgICAgIGxldCB0ZW1wbGF0ZSA9IGF3YWl0IGZzLnJlYWRGaWxlKFxuICAgICAgICAgICAgcGF0aC5qb2luKHRoaXMudml0ZVNlcnZlci5jb25maWcucm9vdCwgXCJpbmRleC5odG1sXCIpLFxuICAgICAgICAgICAgXCJ1dGYtOFwiLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGVtcGxhdGUgPSBhd2FpdCB0aGlzLnZpdGVTZXJ2ZXIudHJhbnNmb3JtSW5kZXhIdG1sKHVybCwgdGVtcGxhdGUpO1xuXG4gICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICB0aGlzLnZpdGVTZXJ2ZXIuc3NyRml4U3RhY2t0cmFjZShlIGFzIEVycm9yKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgIHJldHVybiAoZSBhcyBFcnJvcikubWVzc2FnZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIOyEnOuyhCDsooXro4wg7IucIFZpdGXrj4Qg7KKF66OMXG4gICAgc2VydmVyLmFkZEhvb2soXCJvbkNsb3NlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMudml0ZVNlcnZlci5jbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgY29uc29sZS5sb2coY2hhbGsuZGltKFwi4pyTIFZpdGUgZGV2IHNlcnZlciBpbnRlZ3JhdGVkXCIpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2V0dXBTdGF0aWNXZWJTZXJ2ZXIoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgZ2xvYmFsQ29tcHJlc3NPcHRpb25zOiBDb21wcmVzc09wdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOqyveuhnCDrqoXtmZXtmZQ6IGFwaS93ZWItZGlzdC9jbGllbnQgKOygleyggSDtjIzsnbwpLCBhcGkvd2ViLWRpc3Qvc2VydmVyIChTU1IgZW50cnkpLCBhcGkvZGlzdC9zc3IgKFNTUiByb3V0ZXMgLSBBUEkg7IaM7JygKVxuICAgIGNvbnN0IHdlYkRpc3RQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwid2ViLWRpc3RcIiwgXCJjbGllbnRcIik7XG4gICAgY29uc3Qgc3NyUGF0aCA9IHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcIndlYi1kaXN0XCIsIFwic2VydmVyXCIpO1xuICAgIGNvbnN0IHNzckVudHJ5UGF0aCA9IHBhdGguam9pbihzc3JQYXRoLCBcImVudHJ5LXNlcnZlci5nZW5lcmF0ZWQuanNcIik7XG4gICAgY29uc3Qgc3NyUm91dGVzUGF0aCA9IHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcImRpc3RcIiwgXCJzc3JcIiwgXCJyb3V0ZXMuanNcIik7XG5cbiAgICBpZiAoIShhd2FpdCBleGlzdHMod2ViRGlzdFBhdGgpKSkge1xuICAgICAgY29uc29sZS53YXJuKGDimqAgV2ViIGRpc3Qgbm90IGZvdW5kOiAke3dlYkRpc3RQYXRofWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNTUiBlbnRyeSDsobTsnqwg7Jes67aAIO2ZleyduFxuICAgIGNvbnN0IHNzckF2YWlsYWJsZSA9IGF3YWl0IGV4aXN0cyhzc3JFbnRyeVBhdGgpO1xuXG4gICAgaWYgKCFzc3JBdmFpbGFibGUpIHtcbiAgICAgIGNvbnNvbGUud2Fybihg4pqgIFNTUiBlbnRyeSBub3QgZm91bmQ6ICR7c3NyRW50cnlQYXRofWApO1xuICAgICAgY29uc29sZS53YXJuKFwiICBTU1Igd2lsbCBiZSBkaXNhYmxlZC4gT25seSBDU1Igd2lsbCB3b3JrLlwiKTtcbiAgICB9XG5cbiAgICAvLyBTU1Ig65287Jqw7Yq4IOuhnOuTnCAocHJvZHVjdGlvbuyXkOyEnOunjCwg7IKs7Jqp7J6QIO2UhOuhnOygne2KuOydmCBzc3Ivcm91dGVzLnRzKVxuICAgIGlmIChzc3JBdmFpbGFibGUpIHtcbiAgICAgIGlmIChhd2FpdCBleGlzdHMoc3NyUm91dGVzUGF0aCkpIHtcbiAgICAgICAgLy8gdHMtbG9hZGVy652866m0IFwiZmlsZTovL1wi66GcIOyLnOyeke2VmOuKlCBmdWxseS1yZXNvbHZlZCBwYXRo66eMIOuwm+q4sOyXkCDsnbTrpbwg7LKY66as7ZW07KO864qUIGltcG9ydE1lbWJlcnPrpbwg7IKs7Jqp7ZW07JW8IO2WiOqyoOyngOunjCxcbiAgICAgICAgLy8g7Jes6riw64qUIO2UhOuhnOuNleyFmCDtmZjqsr3sl5DshJwgbG9hZGVyIOyXhuydtCDrj4zslYTqsIDquLAg65WM66y47JeQIFwi7KeE7KecIGpzIO2MjOydvFwi7J2YIFwi6re464OlXCIg7KCI64yA6rK966Gc66W8IOuwlOuhnCBpbXBvcnTtlbTrj4Qg65Cp64uI64ukLlxuICAgICAgICAvLyDsnbQg64K07Jqp7J2AIOydtCDtlajsiJgg64K07JeQ7IScIOyVhOuemOyXkCDrgpjsmKwg64uk66W4IGltcG9ydCDtmLjstpzsl5Drj4Qg64+Z7J287ZWY6rKMIOyggeyaqeuQqeuLiOuLpC5cbiAgICAgICAgYXdhaXQgaW1wb3J0KHNzclJvdXRlc1BhdGgpO1xuICAgICAgICBjb25zb2xlLmxvZyhcIuKckyBTU1Igcm91dGVzIGxvYWRlZFwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihg4pqgIFNTUiByb3V0ZXMgbm90IGZvdW5kOiAke3NzclJvdXRlc1BhdGh9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g66Gk66eBIOyXheuNsOydtO2KuCDrjIDsnZE6IGFzc2V0IGhhc2gg67aI7J287LmYIOyLnCDtmITsnqwg67KE7KCEIOyngeygkSDshJzruZlcbiAgICBzZXJ2ZXIuZ2V0KFwiL2Fzc2V0cy86ZmlsZW5hbWVcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ZWRGaWxlID0gKHJlcXVlc3QucGFyYW1zIGFzIHsgZmlsZW5hbWU6IHN0cmluZyB9KS5maWxlbmFtZTtcbiAgICAgIGNvbnN0IGFzc2V0c0RpciA9IHBhdGguam9pbih3ZWJEaXN0UGF0aCwgXCJhc3NldHNcIik7XG4gICAgICBjb25zdCBzYWZlRmlsZVBhdGggPSB0aGlzLnJlc29sdmVQYXRoV2l0aGluQmFzZURpcihhc3NldHNEaXIsIHJlcXVlc3RlZEZpbGUpO1xuICAgICAgaWYgKHNhZmVGaWxlUGF0aCA9PT0gbnVsbCkge1xuICAgICAgICByZXBseS5zdGF0dXMoNDAzKS5zZW5kKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlID0gcGF0aC5yZWxhdGl2ZShhc3NldHNEaXIsIHNhZmVGaWxlUGF0aCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG5cbiAgICAgIGNvbnN0IGFzc2V0UGF0aCA9IGAvYXNzZXRzLyR7bm9ybWFsaXplZFJlcXVlc3RlZEZpbGV9YDtcblxuICAgICAgLy8gQ2FjaGUtQ29udHJvbCDtl6TrjZQg6rKw7KCVXG4gICAgICBjb25zdCBnZXRDYWNoZUNvbnRyb2xGb3JBc3NldCA9ICgpOiBDYWNoZUNvbnRyb2xDb25maWcgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgICB0eXBlOiBcImFzc2V0c1wiLFxuICAgICAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICAgICAgcGF0aDogYXNzZXRQYXRoLFxuICAgICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8g7IKs7Jqp7J6QIOygleydmCDtlbjrk6Trn6wg7Jqw7ISgXG4gICAgICAgIGlmIChjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcikge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKGNhY2hlUmVxKTtcbiAgICAgICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g6riw67O46rCSOiBpbW11dGFibGVcbiAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5pbW11dGFibGU7XG4gICAgICB9O1xuXG4gICAgICAvLyBpbmRleC0qLmpzIOuYkOuKlCBpbmRleC0qLmNzcyDsmpTssq3snbgg6rK97JqwXG4gICAgICBpZiAoL15pbmRleC1bYS1mMC05XStcXC4oanN8Y3NzKSQvLnRlc3Qobm9ybWFsaXplZFJlcXVlc3RlZEZpbGUpKSB7XG4gICAgICAgIGNvbnN0IGV4dCA9IG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlLnNwbGl0KFwiLlwiKS5wb3AoKTtcbiAgICAgICAgY29uc3QgZmlsZXMgPSBhd2FpdCBmcy5yZWFkZGlyKGFzc2V0c0Rpcik7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaWxlID0gZmlsZXMuZmluZCgoZikgPT4gZi5zdGFydHNXaXRoKFwiaW5kZXgtXCIpICYmIGYuZW5kc1dpdGgoYC4ke2V4dH1gKSk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRGaWxlKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oYXNzZXRzRGlyLCBjdXJyZW50RmlsZSk7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgICByZXBseS50eXBlKGV4dCA9PT0gXCJqc1wiID8gXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCIgOiBcInRleHQvY3NzXCIpO1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBnZXRDYWNoZUNvbnRyb2xGb3JBc3NldCgpKTtcbiAgICAgICAgICByZXR1cm4gcmVwbHkuc2VuZChjb250ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyDsnbzrsJgg7YyM7J28IOyEnOu5mVxuICAgICAgY29uc3QgZmlsZVBhdGggPSBzYWZlRmlsZVBhdGg7XG4gICAgICBpZiAoYXdhaXQgZXhpc3RzKGZpbGVQYXRoKSkge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICBjb25zdCBleHQgPSBub3JtYWxpemVkUmVxdWVzdGVkRmlsZS5zcGxpdChcIi5cIikucG9wKCk7XG4gICAgICAgIHJlcGx5LnR5cGUoZXh0ID09PSBcImpzXCIgPyBcImFwcGxpY2F0aW9uL2phdmFzY3JpcHRcIiA6IGV4dCA9PT0gXCJjc3NcIiA/IFwidGV4dC9jc3NcIiA6IFwiXCIpO1xuICAgICAgICBpZiAobm9ybWFsaXplZFJlcXVlc3RlZEZpbGUuaW5jbHVkZXMoXCItXCIpKSB7XG4gICAgICAgICAgYXBwbHlDYWNoZUhlYWRlcnMocmVwbHksIGdldENhY2hlQ29udHJvbEZvckFzc2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXBseS5zZW5kKGNvbnRlbnQpO1xuICAgICAgfVxuXG4gICAgICByZXBseS5zdGF0dXMoNDA0KS5zZW5kKCk7XG4gICAgfSk7XG5cbiAgICAvLyBTU1Ig65287Jqw7Yq4IOqwnOuzhCDrk7HroZ0gKGNvbXByZXNzIOyYteyFmOydtCDrnbzsmrDtirjrs4TroZwg7KCB7Jqp65CY64+E66GdKVxuICAgIGlmIChzc3JBdmFpbGFibGUpIHtcbiAgICAgIGNvbnN0IHsgZ2V0U1NSUm91dGVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zc3JcIik7XG4gICAgICBjb25zdCB7IHJlbmRlclNTUiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyL3JlbmRlcmVyXCIpO1xuICAgICAgY29uc3Qgc3NyUm91dGVzID0gZ2V0U1NSUm91dGVzKCk7XG5cbiAgICAgIGZvciAoY29uc3Qgcm91dGUgb2Ygc3NyUm91dGVzKSB7XG4gICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJIRUFEXCJdLFxuICAgICAgICAgIHVybDogcm91dGUucGF0aCxcbiAgICAgICAgICBjb21wcmVzczogdG9GYXN0aWZ5Q29tcHJlc3NPcHRpb24ocm91dGUuY29tcHJlc3MgPz8gdHJ1ZSwgZ2xvYmFsQ29tcHJlc3NPcHRpb25zKSxcbiAgICAgICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHJlcXVlc3QudXJsO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFtTU1JdIE1hdGNoZWQgcm91dGU6ICR7cm91dGUucGF0aH1gKTtcblxuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0gdGhpcy5leHRyYWN0UGF0aFBhcmFtcyhyb3V0ZS5wYXRoLCB1cmwpO1xuICAgICAgICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlbmRlclNTUih1cmwsIHJvdXRlLCBwYXJhbXMsIHJlcXVlc3QsIHJlcGx5LCBjb25maWcpO1xuXG4gICAgICAgICAgICByZXBseS50eXBlKFwidGV4dC9odG1sXCIpO1xuICAgICAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ1NSIG9yIFN0YXRpYyBGaWxlIEZhbGxiYWNrIChTU1Ig65287Jqw7Yq47JeQIOunpOy5reuQmOyngCDslYrripQg66qo65OgIOyalOyyrSlcbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJIRUFEXCJdLFxuICAgICAgdXJsOiBcIipcIixcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICAvLyAvYXBpLCAvc29uYW11LXVp64qUIDQwNCDqt7jrjIDroZxcbiAgICAgICAgaWYgKHJlcXVlc3QudXJsLnN0YXJ0c1dpdGgoXCIvYXBpXCIpIHx8IHJlcXVlc3QudXJsLnN0YXJ0c1dpdGgoXCIvc29uYW11LXVpXCIpKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwNCkuc2VuZCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENTUuyaqSBDYWNoZS1Db250cm9sIO2XpOuNlCDshKTsoJVcbiAgICAgICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICAgICAgY29uc3QgY3NyQ2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QgPSB7XG4gICAgICAgICAgICB0eXBlOiBcImNzclwiLFxuICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICAgIHBhdGg6IHJlcXVlc3QudXJsLnNwbGl0KFwiP1wiKVswXSxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBjc3JDYWNoZUNvbmZpZyA9IGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKGNzckNhY2hlUmVxKTtcblxuICAgICAgICAgIGlmIChjc3JDYWNoZUNvbmZpZykge1xuICAgICAgICAgICAgYXBwbHlDYWNoZUhlYWRlcnMocmVwbHksIGNzckNhY2hlQ29uZmlnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyDsoJXsoIEg7YyM7J287J20IOyhtOyerO2VoCDqsr3smrAsIOygleyggSDtjIzsnbzsnYQg66i87KCAIOyEnOu5me2VtOyVvO2VqFxuICAgICAgICBjb25zdCByZXF1ZXN0UGF0aCA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHJlcXVlc3QudXJsKTtcbiAgICAgICAgY29uc3Qgc2FmZUZpbGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIod2ViRGlzdFBhdGgsIHJlcXVlc3RQYXRoKTtcbiAgICAgICAgaWYgKHNhZmVGaWxlUGF0aCA9PT0gbnVsbCkge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDMpLnNlbmQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF3YWl0IGZpbGVFeGlzdHMoc2FmZUZpbGVQYXRoKSkge1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShzYWZlRmlsZVBhdGgpO1xuICAgICAgICAgIHJldHVybiByZXBseS50eXBlKG1pbWVMb29rdXAoc2FmZUZpbGVQYXRoKSB8fCBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiKS5zZW5kKGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ1NSIGZhbGxiYWNrOiBpbmRleC5odG1sIOyEnOu5mVxuICAgICAgICBjb25zdCBpbmRleFBhdGggPSBwYXRoLmpvaW4od2ViRGlzdFBhdGgsIFwiaW5kZXguaHRtbFwiKTtcbiAgICAgICAgcmV0dXJuIHJlcGx5LnR5cGUoXCJ0ZXh0L2h0bWxcIikuc2VuZChhd2FpdCBmcy5yZWFkRmlsZShpbmRleFBhdGgsIFwidXRmLThcIikpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKGDinJMgU3RhdGljIHdlYiBzZXJ2ZXIgY29uZmlndXJlZCB3aXRoICR7c3NyQXZhaWxhYmxlID8gXCJTU1JcIiA6IFwiQ1NSIG9ubHlcIn0gc3VwcG9ydGApO1xuICB9XG5cbiAgY3JlYXRlQXBpSGFuZGxlcihcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogKHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KSA9PiBQcm9taXNlPHVua25vd24+IHtcbiAgICByZXR1cm4gYXN5bmMgKHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KTogUHJvbWlzZTx1bmtub3duPiA9PiB7XG4gICAgICAvLyBDb250ZXh0IOyDneyEsVxuICAgICAgY29uc3QgY29udGV4dDogQ29udGV4dCA9IGF3YWl0IHRoaXMuY3JlYXRlQ29udGV4dChjb25maWcsIHJlcXVlc3QsIHJlcGx5KTtcblxuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIGd1YXJkcyDsspjrpqxcbiAgICAgICAgKGFwaS5vcHRpb25zLmd1YXJkcyA/PyBbXSkuZXZlcnkoKGd1YXJkKSA9PiBjb25maWcuZ3VhcmRIYW5kbGVyKGd1YXJkLCByZXF1ZXN0LCBhcGkpKTtcblxuICAgICAgICAvLyDtjIzrnbzrr7jthLAg7KCV67O066GcIHpvZCDsiqTtgqTrp4gg67mM65OcXG4gICAgICAgIGNvbnN0IHsgZ2V0Wm9kT2JqZWN0RnJvbUFwaSB9ID0gYXdhaXQgaW1wb3J0KFwiLi9jb2RlLWNvbnZlcnRlcnNcIik7XG4gICAgICAgIGNvbnN0IFJlcVR5cGUgPSBnZXRab2RPYmplY3RGcm9tQXBpKGFwaSwgdGhpcy5zeW5jZXIudHlwZXMpO1xuXG4gICAgICAgIC8vIHJlcXVlc3Qg7YyM7IuxXG4gICAgICAgIGNvbnN0IHdoaWNoID0gYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA9PT0gXCJHRVRcIiA/IFwicXVlcnlcIiA6IFwiYm9keVwiO1xuICAgICAgICBsZXQgcmVxQm9keToge1xuICAgICAgICAgIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gICAgICAgIH07XG4gICAgICAgIC8vIO2MjOydvCDsl4XroZzrk5wg7J6I64qUIOqyveyasCDsnoTsi5wg642w7J207YSwXG4gICAgICAgIGNvbnN0IGZpbGVzOiB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogQnVmZmVyZWRGaWxlW107XG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogVXBsb2FkZWRGaWxlW107XG4gICAgICAgIH0gPSB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogW10sXG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogW10sXG4gICAgICAgIH07XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBib2R5ID0gKHJlcXVlc3Rbd2hpY2hdID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRzID0gcmVxdWVzdC5wYXJ0cyh7XG4gICAgICAgICAgICAgIGxpbWl0czogYXBpLnVwbG9hZE9wdGlvbnMubGltaXRzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEZvcm1EYXRh7J2YIGZpZWxk65Ok7J2EIOyehOyLnOuhnCDsoIDsnqVcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA9PT0gXCJidWZmZXJcIiB8fCAhYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSkge1xuICAgICAgICAgICAgICAvLyBCdWZmZXIg66qo65OcOiDrqZTrqqjrpqzsl5Ag66Gc65OcXG4gICAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09IFwiZmlsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAvLyBDUklUSUNBTDog7YyM7J28IOyKpO2KuOumvOydhCDsponsi5wgY29uc3VtZe2VtOyVvCDri6TsnYwgcGFydOuhnCDrhJjslrTqsIgg7IiYIOyeiOydjFxuICAgICAgICAgICAgICAgICAgLy8g7J20IO2YuOy2nOydtCDsl4bsnLzrqbQg7KKF7KKFIG11bHRpcGFydCDtjIzsi7HsnbQgcGVuZGluZyDsg4Htg5zroZwg7YOA7J6E7JWE7JuDIOuwnOyDnVxuICAgICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgcGFydC50b0J1ZmZlcigpO1xuICAgICAgICAgICAgICAgICAgZmlsZXMuYnVmZmVyZWRGaWxlcy5wdXNoKG5ldyBCdWZmZXJlZEZpbGUocGFydCwgYnVmZmVyKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwiZmllbGRcIikge1xuICAgICAgICAgICAgICAgICAgZmllbGRzW3BhcnQuZmllbGRuYW1lXSA9IFN0cmluZyhwYXJ0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA9PT0gXCJzdHJlYW1cIikge1xuICAgICAgICAgICAgICAvLyBTdHJlYW0g66qo65OcOiDsponsi5wg7KCA7J6l7IaM66GcIOyKpO2KuOumrOuwjVxuICAgICAgICAgICAgICBjb25zdCBkaXNrTmFtZSA9IGFwaS51cGxvYWRPcHRpb25zLmRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgICBjb25zdCBkaXNrID0gdGhpcy5zdG9yYWdlLnVzZShkaXNrTmFtZSk7XG5cbiAgICAgICAgICAgICAgLy8g7Jqw7ISg7Iic7JyEOiDrjbDsvZTroIjsnbTthLAgPiDsoITsl60g7ISk7KCVID4g6riw67O46rCSXG4gICAgICAgICAgICAgIGNvbnN0IGtleUdlbmVyYXRvcjogS2V5R2VuZXJhdG9yID1cbiAgICAgICAgICAgICAgICBhcGkudXBsb2FkT3B0aW9ucy5rZXlHZW5lcmF0b3IgPz9cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5zZXJ2ZXIuc3RvcmFnZT8ua2V5R2VuZXJhdG9yID8/XG4gICAgICAgICAgICAgICAgZGVmYXVsdEtleUdlbmVyYXRvcjtcblxuICAgICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydC50eXBlID09PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQga2V5R2VuZXJhdG9yKHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgIG1pbWV0eXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGF3YWl0IGRpc2sucHV0U3RyZWFtKGtleSwgcGFydC5maWxlLCB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IGF3YWl0IGRpc2suZ2V0VXJsKGtleSk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBzaWduZWRVcmwgPSBhd2FpdCBkaXNrLmdldFNpZ25lZFVybChrZXkpO1xuXG4gICAgICAgICAgICAgICAgICBmaWxlcy51cGxvYWRlZEZpbGVzLnB1c2goXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVcGxvYWRlZEZpbGUoe1xuICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXJ0LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIG1pbWV0eXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgICAgIHNpemU6IHBhcnQuZmlsZS5ieXRlc1JlYWQsXG4gICAgICAgICAgICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgICAgICAgICAgIHNpZ25lZFVybCxcbiAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgZGlza05hbWUsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJmaWVsZFwiKSB7XG4gICAgICAgICAgICAgICAgICBmaWVsZHNbcGFydC5maWVsZG5hbWVdID0gU3RyaW5nKHBhcnQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBxc+uhnCDspJHssqkg6rWs7KGwIO2MjOyLsTogcGFyYW1zW2NhdGVnb3J5XSDihpIgeyBwYXJhbXM6IHsgY2F0ZWdvcnk6IFwidGVzdFwiIH0gfVxuICAgICAgICAgICAgY29uc3QgcXMgPSBhd2FpdCBpbXBvcnQoXCJxc1wiKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHFzLmRlZmF1bHQucGFyc2UoZmllbGRzKTtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oYm9keSwgcGFyc2VkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB7IGZhc3RpZnlDYXN0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4vY2FzdGVyXCIpO1xuICAgICAgICAgIHJlcUJvZHkgPSBmYXN0aWZ5Q2FzdGVyKFJlcVR5cGUpLnBhcnNlKGJvZHkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc3QgeyBab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiem9kXCIpO1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgWm9kRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgaHVtYW5pemVab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvem9kLWVycm9yXCIpO1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBodW1hbml6ZVpvZEVycm9yKGUpXG4gICAgICAgICAgICAgIC5tYXAoKGlzc3VlKSA9PiBpc3N1ZS5tZXNzYWdlKVxuICAgICAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgICAgICBjb25zdCB7IEJhZFJlcXVlc3RFeGNlcHRpb24gfSA9IGF3YWl0IGltcG9ydChcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKG1lc3NhZ2VzIGFzIExvY2FsaXplZFN0cmluZywge1xuICAgICAgICAgICAgICB6b2RFcnJvcjogZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbnRlbnQtVHlwZVxuICAgICAgICByZXBseS50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgICAgICAvLyBDYWNoZS1Db250cm9sIO2XpOuNlCDshKTsoJVcbiAgICAgICAgY29uc3QgYXBpQ2FjaGVDb25maWcgPSB0aGlzLmdldEFwaUNhY2hlQ29udHJvbChhcGksIHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChhcGlDYWNoZUNvbmZpZykge1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBhcGlDYWNoZUNvbmZpZyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDsl4XroZzrk5wg7Ji17IWY7J20IOyeiOuKlCDqsr3smrAg7YyM7J28IOuNsOydtO2EsOulvCBDb250ZXh07JeQIOy2lOqwgFxuICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMpIHtcbiAgICAgICAgICBjb25zdCBjb25zdW1lID0gYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA/PyBcImJ1ZmZlclwiO1xuICAgICAgICAgIGlmIChjb25zdW1lID09PSBcImJ1ZmZlclwiKSB7XG4gICAgICAgICAgICBjb250ZXh0LmJ1ZmZlcmVkRmlsZXMgPSBmaWxlcy5idWZmZXJlZEZpbGVzO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3VtZSA9PT0gXCJzdHJlYW1cIikge1xuICAgICAgICAgICAgY29udGV4dC51cGxvYWRlZEZpbGVzID0gZmlsZXMudXBsb2FkZWRGaWxlcztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyDrqqjrjbgg66mU7IaM65OcIGFyZ3Mg7IOd7ISx7ZWY7JesIO2YuOy2nFxuICAgICAgICBjb25zdCB7IEFwaVBhcmFtVHlwZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIik7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgICAgLy8gQ29udGV4dCDsnbjsoJ3shZhcbiAgICAgICAgICBpZiAoQXBpUGFyYW1UeXBlLmlzQ29udGV4dChwYXJhbS50eXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXFCb2R5W3BhcmFtLm5hbWVdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaW52b2tlTW9kZWxNZXRob2QoYXBpLCBhcmdzLCByZXBseSk7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFVSTOyXkOyEnCBwYXRoIHBhcmFtc+ulvCDstpTstpztlanri4jri6QuXG4gICAqIOyYiDogcGF0dGVybj1cIi9hZG1pbi9jb21wYW5pZXMvOmNvbXBhbnlJZFwiLCB1cmw9XCIvYWRtaW4vY29tcGFuaWVzLzEyM1wiIOKGkiB7IGNvbXBhbnlJZDogXCIxMjNcIiB9XG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3RQYXRoUGFyYW1zKHBhdHRlcm46IHN0cmluZywgdXJsOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBwYXR0ZXJuUGFydHMgPSBwYXR0ZXJuLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgdXJsUGFydHMgPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybCh1cmwpLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHBhdHRlcm5QYXJ0c1tpXS5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICBwYXJhbXNbcGF0dGVyblBhcnRzW2ldLnNsaWNlKDEpXSA9IHVybFBhcnRzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1BhdGhQYXR0ZXJuTWF0Y2gocGF0dGVybjogc3RyaW5nLCB1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhdHRlcm5QYXJ0cyA9IHBhdHRlcm4uc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCB1cmxQYXJ0cyA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHVybCkuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcblxuICAgIGlmIChwYXR0ZXJuUGFydHMubGVuZ3RoICE9PSB1cmxQYXJ0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGF0dGVyblBhcnQgPSBwYXR0ZXJuUGFydHNbaV07XG4gICAgICBjb25zdCB1cmxQYXJ0ID0gdXJsUGFydHNbaV07XG4gICAgICBpZiAocGF0dGVyblBhcnQuc3RhcnRzV2l0aChcIjpcIikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocGF0dGVyblBhcnQgIT09IHVybFBhcnQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYXRobmFtZUZyb21VcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB1cmwuc3BsaXQoXCI/XCIpWzBdO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYmFzZURpcjogc3RyaW5nLCBpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlVVJJQ29tcG9uZW50KGlucHV0UGF0aCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG4gICAgICBpZiAoZGVjb2RlZC5pbmNsdWRlcyhcIlxcMFwiKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGRlY29kZWQucmVwbGFjZSgvXlxcLysvLCBcIlwiKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IHBhdGgucmVzb2x2ZShiYXNlRGlyLCByZWxhdGl2ZVBhdGgpO1xuICAgICAgY29uc3QgcmVsYXRpdmVGcm9tQmFzZSA9IHBhdGgucmVsYXRpdmUoYmFzZURpciwgcmVzb2x2ZWRQYXRoKTtcbiAgICAgIGlmIChyZWxhdGl2ZUZyb21CYXNlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmVGcm9tQmFzZSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFQSSDsnZHri7Xsl5Ag7KCB7Jqp7ZWgIENhY2hlLUNvbnRyb2wg7ISk7KCV7J2EIOqysOygle2VqeuLiOuLpC5cbiAgICog7Jqw7ISg7Iic7JyEOiDqsJzrs4Qg7KeA7KCVID4gY2FjaGVDb250cm9sSGFuZGxlclxuICAgKi9cbiAgcHJpdmF0ZSBnZXRBcGlDYWNoZUNvbnRyb2woXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICkge1xuICAgIC8vIOuNsOy9lOugiOydtO2EsCDshKTsoJUg7Jqw7ISgXG4gICAgaWYgKGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbCkge1xuICAgICAgcmV0dXJuIGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbDtcbiAgICB9XG5cbiAgICAvLyDsoITsl60g7ZW465Ok65+sXG4gICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICBjb25zdCBjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgdHlwZTogXCJhcGlcIixcbiAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgcGF0aDogcmVxdWVzdC5yb3V0ZU9wdGlvbnM/LnVybCA/PyByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgIGFwaSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNTUuyaqSBBUEkg7Zi47LacIChIVFRQIOyYpOuyhO2XpOuTnCDsl4bsnbQg7KeB7KCRIO2YuOy2nClcbiAgICogY3JlYXRlQXBpSGFuZGxlcuydmCDroZzsp4HsnYQg7J6s7IKs7Jqp7ZWY65CYLCByZXF1ZXN0IO2MjOyLsSDrjIDsi6AgcGFyYW1zIOyngeygkSDsgqzsmqlcbiAgICovXG4gIGFzeW5jIGludm9rZUFwaUZvclNTUihcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55IC0tIFNTUuyXkOyEnCDri6TslpHtlZwg7YOA7J6F7J2YIHBhcmFtc+ulvCDrsJvslYTslbwg7ZWoXG4gICAgcGFyYW1zOiBhbnlbXSxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgcmVwbHk6IEZhc3RpZnlSZXBseSxcbiAgKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgLy8gQ29udGV4dCDsg53shLEgKOq4sOyhtCDrqZTshozrk5wg7J6s7IKs7JqpKVxuICAgIGNvbnN0IGNvbnRleHQgPSBhd2FpdCB0aGlzLmNyZWF0ZUNvbnRleHQoY29uZmlnLCByZXF1ZXN0LCByZXBseSk7XG5cbiAgICByZXR1cm4gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oeyBjb250ZXh0IH0sIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGFyZ3Mg7IOd7ISxOiBDb250ZXh0IO2MjOudvOuvuO2EsOuKlCDso7zsnoUsIOuCmOuouOyngOuKlCBwYXJhbXPsl5DshJwg6rCA7KC47Jik6riwXG4gICAgICBjb25zdCB7IEFwaVBhcmFtVHlwZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIik7XG4gICAgICBsZXQgcGFyYW1zSW5kZXggPSAwO1xuICAgICAgY29uc3QgYXJncyA9IGFwaS5wYXJhbWV0ZXJzLm1hcCgocGFyYW0pID0+IHtcbiAgICAgICAgaWYgKEFwaVBhcmFtVHlwZS5pc0NvbnRleHQocGFyYW0udHlwZSkpIHtcbiAgICAgICAgICByZXR1cm4gY29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFyYW1zW3BhcmFtc0luZGV4KytdO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIOuqqOuNuCDrqZTshJzrk5wg7Zi47LacICjquLDsobQg66mU7ISc65OcIOyerOyCrOyaqSlcbiAgICAgIHJldHVybiB0aGlzLmludm9rZU1vZGVsTWV0aG9kKGFwaSwgYXJncywgcmVwbHkpO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgaW52b2tlTW9kZWxNZXRob2QoXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICBhcmdzOiB1bmtub3duW10sXG4gICAgcmVwbHk6IEZhc3RpZnlSZXBseSxcbiAgKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLnN5bmNlci5tb2RlbHNbYXBpLm1vZGVsTmFtZV07XG4gICAgLy8gb3hsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgLS0gbW9kZWzsnYAg66qo6424IOyduOyKpO2EtOyKpOydtOuvgOuhnCDrqZTshJzrk5wg7Zi47LacIOqwgOuKpVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChtb2RlbCBhcyBhbnkpW2FwaS5tZXRob2ROYW1lXS5hcHBseShtb2RlbCwgYXJncyk7XG4gICAgcmVwbHkudHlwZShhcGkub3B0aW9ucy5jb250ZW50VHlwZSA/PyBcImFwcGxpY2F0aW9uL2pzb25cIik7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlQ29udGV4dChcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgcmVwbHk6IEZhc3RpZnlSZXBseSxcbiAgKTogUHJvbWlzZTxDb250ZXh0PiB7XG4gICAgLy8gY3JlYXRlU1NFRmFjdG9yeSDtlajsiJjsl5Ag66+466asIHJlcXVlc3TsnZggc29ja2V06rO8IHJlcGx566W8IOuwlOyduOuUqS5cbiAgICBjb25zdCB7IGNyZWF0ZVNTRUZhY3RvcnkgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N0cmVhbS9zc2VcIik7XG4gICAgY29uc3QgY3JlYXRlU1NFID0gKDxUIGV4dGVuZHMgWm9kT2JqZWN0PihcbiAgICAgIF9yZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICAgIF9yZXBseTogRmFzdGlmeVJlcGx5LFxuICAgICAgX2V2ZW50czogVCxcbiAgICApID0+IGNyZWF0ZVNTRUZhY3RvcnkoX3JlcXVlc3Quc29ja2V0LCBfcmVwbHksIF9ldmVudHMpKS5iaW5kKG51bGwsIHJlcXVlc3QsIHJlcGx5KTtcblxuICAgIC8vIGxvY2FsZSDqsJDsp4BcbiAgICBjb25zdCBsb2NhbGUgPVxuICAgICAgdGhpcy5kZXRlY3RMb2NhbGUocmVxdWVzdC5oZWFkZXJzW1wiYWNjZXB0LWxhbmd1YWdlXCJdLCB0aGlzLmNvbmZpZy5pMThuLnN1cHBvcnRlZExvY2FsZXMpID8/XG4gICAgICB0aGlzLmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGU7XG5cbiAgICAvLyBhdXRoIGNvbnRleHQg7LaU6rCAXG4gICAgY29uc3QgaGVhZGVycyA9IGNvbnZlcnRGYXN0aWZ5SGVhZGVyc1RvU3RhbmRhcmQocmVxdWVzdC5oZWFkZXJzKTtcbiAgICBjb25zdCBzZXNzaW9uID0gKGF3YWl0IHRoaXMuX2F1dGg/LmFwaS5nZXRTZXNzaW9uKHsgaGVhZGVycyB9KSkgPz8gbnVsbDtcblxuICAgIGNvbnN0IGNvbnRleHQ6IENvbnRleHQgPSB7XG4gICAgICAuLi4oYXdhaXQgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICBjb25maWcuY29udGV4dFByb3ZpZGVyKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICByZXBseSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICAgIG5haXRlU3RvcmU6IG5ldyBNYXAoKSxcbiAgICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICAgIC8vIGF1dGhcbiAgICAgICAgICAgIHVzZXI6IHNlc3Npb24/LnVzZXIgPz8gbnVsbCxcbiAgICAgICAgICAgIHNlc3Npb246IHNlc3Npb24/LnNlc3Npb24gPz8gbnVsbCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgcmVwbHksXG4gICAgICAgICksXG4gICAgICApKSxcbiAgICB9O1xuICAgIHJldHVybiBjb250ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFjY2VwdC1MYW5ndWFnZSDtl6TrjZTsl5DshJwg7KeA7JuQ7ZWY64qUIGxvY2FsZeydhCDssL7sirXri4jri6QuXG4gICAqIEBleGFtcGxlIFwia28tS1Isa287cT0wLjksZW47cT0wLjhcIiDihpIgXCJrb1wiXG4gICAqL1xuICBwcml2YXRlIGRldGVjdExvY2FsZShcbiAgICBhY2NlcHRMYW5ndWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIHN1cHBvcnRlZDogc3RyaW5nW10sXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFhY2NlcHRMYW5ndWFnZSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIC8vIEFjY2VwdC1MYW5ndWFnZToga28tS1Isa287cT0wLjksZW47cT0wLjhcbiAgICBjb25zdCBsYW5ncyA9IGFjY2VwdExhbmd1YWdlLnNwbGl0KFwiLFwiKS5tYXAoKGxhbmcpID0+IHtcbiAgICAgIGNvbnN0IFtjb2RlXSA9IGxhbmcuc3BsaXQoXCI7XCIpO1xuICAgICAgcmV0dXJuIGNvZGUudHJpbSgpLnNwbGl0KFwiLVwiKVswXTsgLy8ga28tS1Ig4oaSIGtvXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbGFuZ3MuZmluZCgobGFuZykgPT4gc3VwcG9ydGVkLmluY2x1ZGVzKGxhbmcpKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0V2F0Y2hlcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB3YXRjaFBhdGggPSBbcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwic3JjXCIpXTtcblxuICAgIGNvbnN0IGNob2tpZGFyID0gKGF3YWl0IGltcG9ydChcImNob2tpZGFyXCIpKS5kZWZhdWx0O1xuICAgIHRoaXMud2F0Y2hlciA9IGNob2tpZGFyLndhdGNoKHdhdGNoUGF0aCwge1xuICAgICAgaWdub3JlZDogKHBhdGgsIHN0YXRzKSA9PlxuICAgICAgICAhIXN0YXRzPy5pc0ZpbGUoKSAmJiAhcGF0aC5lbmRzV2l0aChcIi50c1wiKSAmJiAhcGF0aC5lbmRzV2l0aChcIi5qc29uXCIpLFxuICAgICAgcGVyc2lzdGVudDogdHJ1ZSxcbiAgICAgIGlnbm9yZUluaXRpYWw6IHRydWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLndhdGNoZXIub24oXCJhbGxcIiwgYXN5bmMgKGV2ZW50OiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IGZpbGVQYXRoIGFzIEFic29sdXRlUGF0aDtcbiAgICAgIGFzc2VydChcbiAgICAgICAgYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgodGhpcy5hcGlSb290UGF0aCksXG4gICAgICAgIFwiRmlsZSBwYXRoIGlzIG5vdCB3aXRoaW4gdGhlIEFQSSByb290IHBhdGhcIixcbiAgICAgICk7XG5cbiAgICAgIGlmIChldmVudCAhPT0gXCJjaGFuZ2VcIiAmJiBldmVudCAhPT0gXCJhZGRcIikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIHNvbmFtdS5jb25maWcudHMg67OA6rK9IOyLnCDsnqzsi5zsnpFcbiAgICAgICAgY29uc3QgaXNDb25maWdUcyA9IGZpbGVQYXRoID09PSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJzcmNcIiwgXCJzb25hbXUuY29uZmlnLnRzXCIpO1xuXG4gICAgICAgIGlmIChpc0NvbmZpZ1RzKSB7XG4gICAgICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gZmlsZVBhdGgucmVwbGFjZSh0aGlzLmFwaVJvb3RQYXRoLCBcImFwaVwiKTtcbiAgICAgICAgICBjb25zdCBjaGFsayA9IChhd2FpdCBpbXBvcnQoXCJjaGFsa1wiKSkuZGVmYXVsdDtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGNoYWxrLmJvbGQoYERldGVjdGVkKCR7ZXZlbnR9KTogJHtjaGFsay5ibHVlKHJlbGF0aXZlUGF0aCl9IC0gUmVzdGFydGluZy4uLmApLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcHJvY2Vzcy5raWxsKHByb2Nlc3MucGlkLCBcIlNJR1VTUjJcIik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVGaWxlQ2hhbmdlKGV2ZW50LCBhYnNvbHV0ZVBhdGgpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLypcbiAgICAgQSBmdW5jdGlvbiB0aGF0IGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbml0IGFuZCBkZXN0cm95IHdoZW4gdXNpbmcgU29uYW11IHZpYSBzY3JpcHRzLlxuICAqL1xuICBhc3luYyBydW5TY3JpcHQoZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmbigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSwgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl0pIHtcbiAgICBpZiAoIXBsdWdpbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjb21wcmVzcyDtlIzrn6zqt7jsnbjsnYAg64uk66W4IO2UjOufrOq3uOyduOuztOuLpCDrqLzsoIAg65Ox66Gd65CY7Ja07JW8IO2VqeuLiOuLpC5cbiAgICBpZiAocGx1Z2lucy5jb21wcmVzcykge1xuICAgICAgY29uc3QgY29tcHJlc3NQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvY29tcHJlc3NcIikpLmRlZmF1bHQ7XG4gICAgICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgICAgdGhyZXNob2xkOiAxMDI0LFxuICAgICAgICBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gYXMgKFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJkZWZsYXRlXCIpW10sXG4gICAgICB9O1xuXG4gICAgICBpZiAocGx1Z2lucy5jb21wcmVzcyA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoY29tcHJlc3NQbHVnaW4sIGRlZmF1bHRPcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlcnZlci5yZWdpc3Rlcihjb21wcmVzc1BsdWdpbiwge1xuICAgICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICAgIC4uLnBsdWdpbnMuY29tcHJlc3MsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpbnNNb2R1bGVzID0ge1xuICAgICAgY29yczogXCJAZmFzdGlmeS9jb3JzXCIsXG4gICAgICBmb3JtYm9keTogXCJAZmFzdGlmeS9mb3JtYm9keVwiLFxuICAgICAgbXVsdGlwYXJ0OiBcIkBmYXN0aWZ5L211bHRpcGFydFwiLFxuICAgICAgcXM6IFwiZmFzdGlmeS1xc1wiLFxuICAgICAgc3NlOiBcImZhc3RpZnktc3NlLXYyXCIsXG4gICAgICBzdGF0aWM6IFwiQGZhc3RpZnkvc3RhdGljXCIsXG4gICAgfSBhcyBjb25zdDtcblxuICAgIGNvbnN0IHJlZ2lzdGVyUGx1Z2luID0gYXN5bmMgPEsgZXh0ZW5kcyBrZXlvZiBOb25OdWxsYWJsZTx0eXBlb2YgcGx1Z2lucz4+KFxuICAgICAga2V5OiBLLFxuICAgICAgcGx1Z2luTmFtZTogc3RyaW5nLFxuICAgICkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uID0gcGx1Z2luc1trZXldO1xuICAgICAgaWYgKCFvcHRpb24pIHJldHVybjtcblxuICAgICAgaWYgKG9wdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCwgb3B0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBwbHVnaW5OYW1lXSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykpIHtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyUGx1Z2luKGtleSBhcyBrZXlvZiB0eXBlb2YgcGx1Z2lucywgcGx1Z2luTmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMuY3VzdG9tKSB7XG4gICAgICBwbHVnaW5zLmN1c3RvbShzZXJ2ZXIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBiZXR0ZXItYXV0aCDrnbzsmrDtirjrpbwg65Ox66Gd7ZWp64uI64ukLlxuICAgKiAvYXBpL2F1dGgvKiDqsr3roZzroZwg7J247KadIEFQSeqwgCDsnpDrj5kg65Ox66Gd65Cp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckJldHRlckF1dGgoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsXG4gICAgb3B0aW9uczogTm9uTnVsbGFibGU8U29uYW11U2VydmVyT3B0aW9uc1tcImF1dGhcIl0+LFxuICApIHtcbiAgICBpZiAoIW9wdGlvbnMpIHJldHVybjtcblxuICAgIGNvbnN0IGJhc2VQYXRoID0gb3B0aW9ucy5iYXNlUGF0aCA/PyBcIi9hcGkvYXV0aFwiO1xuXG4gICAgLy8gYmV0dGVyLWF1dGgg65287Jqw7Yq4IOuTseuhnVxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkdFVFwiLCBcIlBPU1RcIl0sXG4gICAgICB1cmw6IGAke2Jhc2VQYXRofS8qYCxcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcXVlc3QudXJsLCBgaHR0cDovLyR7cmVxdWVzdC5oZWFkZXJzLmhvc3R9YCk7XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBjb252ZXJ0RmFzdGlmeUhlYWRlcnNUb1N0YW5kYXJkKHJlcXVlc3QuaGVhZGVycyk7XG5cbiAgICAgICAgLy8gSVAg7Zek642UIGZhbGxiYWNrOiDtlITroZ3si5zqsIAg7ZGc7KSAIElQIO2XpOuNlOulvCDso7zsnoXtlZjsp4Ag7JWK64qUIO2ZmOqyveyXkOyEnOuPhFxuICAgICAgICAvLyBiZXR0ZXItYXV0aC9pbmZyYeydmCBnZXRDbGllbnRJcEZyb21SZXF1ZXN0KCnqsIAgSVDrpbwg7J247Iud7ZWgIOyImCDsnojrj4TroZ1cbiAgICAgICAgLy8gRmFzdGlmeeqwgCByZXNvbHZl7ZWcIHJlcXVlc3QuaXDrpbwgeC1yZWFsLWlw66GcIOyjvOyehe2VnOuLpC5cbiAgICAgICAgY29uc3QgSVBfSEVBREVSUyA9IFtcbiAgICAgICAgICBcImNmLWNvbm5lY3RpbmctaXBcIixcbiAgICAgICAgICBcIngtZm9yd2FyZGVkLWZvclwiLFxuICAgICAgICAgIFwieC1yZWFsLWlwXCIsXG4gICAgICAgICAgXCJ4LXZlcmNlbC1mb3J3YXJkZWQtZm9yXCIsXG4gICAgICAgIF07XG4gICAgICAgIGlmIChyZXF1ZXN0LmlwICYmICFJUF9IRUFERVJTLnNvbWUoKGgpID0+IGhlYWRlcnMuaGFzKGgpKSkge1xuICAgICAgICAgIGhlYWRlcnMuc2V0KFwieC1yZWFsLWlwXCIsIHJlcXVlc3QuaXApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVxID0gbmV3IFJlcXVlc3QodXJsLnRvU3RyaW5nKCksIHtcbiAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgLi4uKHJlcXVlc3QuYm9keSA/IHsgYm9keTogSlNPTi5zdHJpbmdpZnkocmVxdWVzdC5ib2R5KSB9IDoge30pLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYXV0aC5oYW5kbGVyKHJlcSk7XG5cbiAgICAgICAgcmVwbHkuc3RhdHVzKHJlc3BvbnNlLnN0YXR1cyk7XG4gICAgICAgIHJlc3BvbnNlLmhlYWRlcnMuZm9yRWFjaCgodmFsdWU6IHN0cmluZywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICByZXBseS5oZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVwbHkuc2VuZChyZXNwb25zZS5ib2R5ID8gYXdhaXQgcmVzcG9uc2UudGV4dCgpIDogbnVsbCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcmludFN0YXJ0dXBTdW1tYXJ5KCkge1xuICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgIGNvbnN0IGVudiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID8/IFwiZGV2ZWxvcG1lbnRcIjtcbiAgICBjb25zdCBhY3RpdmVQcmVzZXQgPSBlbnYgPT09IFwicHJvZHVjdGlvblwiID8gXCJwcm9kdWN0aW9uX21hc3RlclwiIDogXCJkZXZlbG9wbWVudF9tYXN0ZXJcIjtcblxuICAgIGNvbnN0IGRpbSA9IChtc2c6IHN0cmluZykgPT4gY29uc29sZS5sb2coY2hhbGsuZGltKGDinJMgJHttc2d9YCkpO1xuICAgIGNvbnN0IGdyZWVuID0gKG1zZzogc3RyaW5nKSA9PiBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTICR7bXNnfWApKTtcblxuICAgIGRpbShgQ29uZmlnIGxvYWRlZCR7Zm9ybWF0VGltZSh0aGlzLl9jb25maWdFbGFwc2VkKX1gKTtcblxuICAgIC8vIERCIHByZXNldCDrqqnroZ1cbiAgICBncmVlbihcIkRCXCIpO1xuICAgIGNvbnN0IHsgaXNMb2NhbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBjb25zdCBwcmVzZXROYW1lcyA9IE9iamVjdC5rZXlzKHRoaXMuZGJDb25maWcpIGFzIChrZXlvZiBTb25hbXVEQkNvbmZpZylbXTtcbiAgICBjb25zdCBtYXhMZW4gPSBNYXRoLm1heCguLi5wcmVzZXROYW1lcy5tYXAoKG4pID0+IG4ubGVuZ3RoKSk7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHByZXNldE5hbWVzKSB7XG4gICAgICBjb25zdCBjb25uID0gdGhpcy5kYkNvbmZpZ1tuYW1lXS5jb25uZWN0aW9uIGFzXG4gICAgICAgIHwgeyBob3N0Pzogc3RyaW5nOyBwb3J0PzogbnVtYmVyOyBkYXRhYmFzZT86IHN0cmluZyB9XG4gICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaG9zdCA9IGNvbm4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICAgIGNvbnN0IGFkZHIgPSBgQCAke2hvc3R9OiR7Y29ubj8ucG9ydCA/PyA1NDMyfS8ke2Nvbm4/LmRhdGFiYXNlID8/IHRoaXMuY29uZmlnLmRhdGFiYXNlLm5hbWV9YDtcbiAgICAgIGNvbnN0IHBhZGRlZCA9IG5hbWUucGFkRW5kKG1heExlbik7XG4gICAgICBjb25zdCByZW1vdGVUYWcgPSBpc0xvY2FsKCkgJiYgIWlzTG9jYWxIb3N0KGhvc3QpID8gY2hhbGsueWVsbG93KGAgXFx1MjZhMCByZW1vdGVgKSA6IFwiXCI7XG5cbiAgICAgIGlmIChuYW1lID09PSBhY3RpdmVQcmVzZXQpIHtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYCAgXFx1MjViOCAke3BhZGRlZH0gJHthZGRyfWApICsgcmVtb3RlVGFnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShgICAgICR7cGFkZGVkfSAke2FkZHJ9YCkgKyByZW1vdGVUYWcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aCkge1xuICAgICAgY29uc3QgYmFzZVBhdGggPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aC5iYXNlUGF0aCA/PyBcIi9hcGkvYXV0aFwiO1xuICAgICAgZGltKGBBdXRoOiBiZXR0ZXItYXV0aCBhdCAke2Jhc2VQYXRofS8qYCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZy5hcGkudGltZXpvbmUpIHtcbiAgICAgIGRpbShgVGltZXpvbmU6ICR7dGhpcy5jb25maWcuYXBpLnRpbWV6b25lfWApO1xuICAgIH1cbiAgICBncmVlbihgU29uYW11IHJlYWR5JHtmb3JtYXRUaW1lKHRoaXMuX2luaXRFbGFwc2VkKX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZUNhY2hlKGNvbmZpZzogQ2FjaGVDb25maWcgfCB1bmRlZmluZWQsIGZvclRlc3Rpbmc6IGJvb2xlYW4pIHtcbiAgICBjb25zdCB7IHNldENhY2hlTWFuYWdlclJlZiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY2FjaGUvZGVjb3JhdG9yXCIpO1xuXG4gICAgLy8g7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnCDrqZTrqqjrpqwg65Oc65287J2067KEIOyekOuPmSDsgqzsmqlcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgY29uc3QgeyBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jYWNoZS9jYWNoZS1tYW5hZ2VyXCIpO1xuICAgICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyKCk7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOyEpOygleydtCDsl4bsnLzrqbQg7LqQ7IucIOu5hO2ZnOyEse2ZlFxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYobnVsbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g7ISk7KCV7JeQIOuUsOudvCBDYWNoZU1hbmFnZXIg7IOd7ISxXG4gICAgY29uc3QgeyBjcmVhdGVDYWNoZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NhY2hlL2NhY2hlLW1hbmFnZXJcIik7XG4gICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVDYWNoZU1hbmFnZXIoY29uZmlnKTtcbiAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbml0aWFsaXplV29ya2Zsb3dzKG9wdGlvbnM6IFNvbmFtdVRhc2tPcHRpb25zIHwgdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgeyBXb3JrZmxvd01hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rhc2tzL3dvcmtmbG93LW1hbmFnZXJcIik7XG4gICAgLy8gTk9URTogQHNvbmFtdS1raXQvdGFza3Mg7JWI7JeQ7ISgIGtuZXggY29uZmln66W8IOyImOygle2VmOq4sCDrlYzrrLjsl5AgY29ubmVjdGlvbuydtCDslYTri4wgY29uZmlnIOynuOuhnCDrs7Trg4Xri4jri6QuXG4gICAgdGhpcy5fd29ya2Zsb3dzID0gbmV3IFdvcmtmbG93TWFuYWdlcihEQi5nZXREQkNvbmZpZyhcIndcIikpO1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVuYWJsZVdvcmtlciA9IG9wdGlvbnMuZW5hYmxlV29ya2VyID8/IGlzRGFlbW9uU2VydmVyKCk7XG4gICAgY29uc3QgZGVmYXVsdFdvcmtlck9wdGlvbnMgPSB7XG4gICAgICBjb25jdXJyZW5jeTogb3MuY3B1cygpLmxlbmd0aCAtIDEsXG4gICAgICB1c2VQdWJTdWI6IHRydWUsXG4gICAgICBsaXN0ZW5EZWxheTogNTAwLFxuICAgIH07XG5cbiAgICBpZiAoZW5hYmxlV29ya2VyKSB7XG4gICAgICB0aGlzLndvcmtmbG93cy5zZXR1cFdvcmtlcih7XG4gICAgICAgIC4uLmRlZmF1bHRXb3JrZXJPcHRpb25zLFxuICAgICAgICAuLi5vcHRpb25zLndvcmtlck9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3Qoc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsIG9wdGlvbnM6IFNvbmFtdVNlcnZlck9wdGlvbnMpIHtcbiAgICBjb25zdCBwb3J0ID0gb3B0aW9ucy5saXN0ZW4/LnBvcnQgPz8gMzAwMDtcbiAgICBjb25zdCBob3N0ID0gb3B0aW9ucy5saXN0ZW4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcblxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TaHV0ZG93bj8uKHNlcnZlcik7XG4gICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5kZXN0cm95KCk7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHNodXRkb3duID0gYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZHVyaW5nIHNodXRkb3duOlwiLCBlcnIpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgc2h1dGRvd24pO1xuICAgIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHNodXRkb3duKTtcblxuICAgIGlmIChvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcikge1xuICAgICAgc2VydmVyLnNldEVycm9ySGFuZGxlcihvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcik7XG4gICAgfVxuXG4gICAgc2VydmVyXG4gICAgICAubGlzdGVuKHsgcG9ydCwgaG9zdCB9KVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5zdGFydFdvcmtlcigpO1xuICAgICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TdGFydD8uKHNlcnZlcik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnIpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hhbGsucmVkKFwiRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjpcIiwgZXJyKSk7XG4gICAgICAgIGF3YWl0IHNodXRkb3duKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRmlsZUNoYW5nZShldmVudDogc3RyaW5nLCBmaWxlUGF0aDogQWJzb2x1dGVQYXRoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g7LKrIOuyiOynuCDtjIzsnbzsnbTrqbQgSE1SIOyLnOyekSDsi5zqsIQg6riw66GdXG4gICAgaWYgKHRoaXMucGVuZGluZ0ZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5obXJTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIH1cbiAgICB0aGlzLnBlbmRpbmdGaWxlcy5wdXNoKGZpbGVQYXRoKTtcblxuICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IHBhdGgucmVsYXRpdmUodGhpcy5hcGlSb290UGF0aCwgZmlsZVBhdGgpO1xuICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLmJvbGQoYERldGVjdGVkKCR7ZXZlbnR9KTogJHtjaGFsay5ibHVlKHJlbGF0aXZlUGF0aCl9YCkpO1xuXG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuc3luY0Zyb21XYXRjaGVyKGV2ZW50LCBmaWxlUGF0aCk7XG5cbiAgICAvLyDsspjrpqwg7JmE66OM65CcIO2MjOydvOydhCDrjIDquLAg66qp66Gd7JeQ7IScIOygnOqxsFxuICAgIHRoaXMucGVuZGluZ0ZpbGVzID0gdGhpcy5wZW5kaW5nRmlsZXMuc2xpY2UoMSk7XG5cbiAgICAvLyDrqqjrk6Ag7YyM7J28IOyymOumrOqwgCDsmYTro4zrkJjrqbQg7LWc7KKFIOuplOyLnOyngCDstpzroKVcbiAgICBpZiAodGhpcy5wZW5kaW5nRmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBhd2FpdCB0aGlzLmZpbmlzaEhNUigpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmluaXNoSE1SKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLnJlbmV3Q2hlY2tzdW1zKCk7XG5cbiAgICBjb25zdCBlbmRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCB0b3RhbFRpbWUgPSBlbmRUaW1lIC0gdGhpcy5obXJTdGFydFRpbWU7XG4gICAgY29uc3QgW2NoYWxrLCB7IGNlbnRlclRleHQgfV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQsXG4gICAgICBpbXBvcnQoXCIuLi91dGlscy9jb25zb2xlLXV0aWxcIiksXG4gICAgXSk7XG4gICAgY29uc3QgbXNnID0gYEhNUiBEb25lISAke2NoYWxrLmJvbGQud2hpdGUoYCR7dG90YWxUaW1lfW1zYCl9YDtcblxuICAgIGNvbnNvbGUubG9nKGNoYWxrLmJsYWNrLmJnR3JlZW4oY2VudGVyVGV4dChtc2cpKSk7XG4gIH1cblxuICBhc3luYyBkZXN0cm95KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgQmFzZU1vZGVsIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9iYXNlLW1vZGVsXCIpO1xuICAgIC8vIOuovOyggCDsspjrpqztlbTslbztlaguXG4gICAgYXdhaXQgQmFzZU1vZGVsLmRlc3Ryb3koKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoW1xuICAgICAgdGhpcy5fd29ya2Zsb3dzPy5kZXN0cm95KCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICB0aGlzLl9jYWNoZT8uZGlzY29ubmVjdCgpID8/IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5fZGV2Vml0ZXN0TWFuYWdlcj8uc2h1dGRvd24oKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIHRoaXMud2F0Y2hlcj8uY2xvc2UoKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIGxvZ3RhcGVEaXNwb3NlKCksXG4gICAgXSk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IFNvbmFtdSA9IG5ldyBTb25hbXVDbGFzcygpO1xuXG4vKipcbiAqIHN0cmVhbSDrqqjrk5zsl5DshJwg7YKkIOyDneyEsSDtlajsiJjqsIAg7KeA7KCV65CY7KeAIOyViuyVmOydhCDrlYwg7IKs7Jqp7ZWY64qUIOq4sOuzuCDtlajsiJjsnoXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRLZXlHZW5lcmF0b3IoZmlsZTogeyBmaWxlbmFtZTogc3RyaW5nOyBtaW1ldHlwZTogc3RyaW5nIH0pOiBzdHJpbmcge1xuICBjb25zdCBleHQgPSBtaW1lLmV4dGVuc2lvbihmaWxlLm1pbWV0eXBlKSB8fCBcImJpblwiO1xuICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICBjb25zdCByYW5kb20gPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KTtcbiAgcmV0dXJuIGB1cGxvYWRzLyR7dGltZXN0YW1wfS0ke3JhbmRvbX0uJHtleHR9YDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VGltZShtczogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZm9ybWF0dGVkID0gbXMgPj0gMTAwMCA/IGAkeyhtcyAvIDEwMDApLnRvRml4ZWQoMil9c2AgOiBgJHtNYXRoLnJvdW5kKG1zKX1tc2A7XG4gIHJldHVybiBgICgke2Zvcm1hdHRlZH0pYDtcbn1cblxuY29uc3QgTE9DQUxfSE9TVFMgPSBuZXcgU2V0KFtcImxvY2FsaG9zdFwiLCBcIjEyNy4wLjAuMVwiLCBcIjAuMC4wLjBcIiwgXCI6OjFcIl0pO1xuZnVuY3Rpb24gaXNMb2NhbEhvc3QoaG9zdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBMT0NBTF9IT1NUUy5oYXMoaG9zdCk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBazhDQSxTQUFTLG9CQUFvQixNQUFzRDtDQUNqRixNQUFNLE1BQU0sS0FBSyxVQUFVLEtBQUssU0FBUyxJQUFJO0NBQzdDLE1BQU0sWUFBWSxLQUFLLEtBQUs7Q0FDNUIsTUFBTSxTQUFTLEtBQUssUUFBUSxDQUFDLFNBQVMsR0FBRyxDQUFDLE1BQU0sR0FBRyxFQUFFO0FBQ3JELFFBQU8sV0FBVyxVQUFVLEdBQUcsT0FBTyxHQUFHOztBQUczQyxTQUFTLFdBQVcsSUFBb0I7Q0FDdEMsTUFBTSxZQUFZLE1BQU0sTUFBTyxJQUFJLEtBQUssS0FBTSxRQUFRLEVBQUUsQ0FBQyxLQUFLLEdBQUcsS0FBSyxNQUFNLEdBQUcsQ0FBQztBQUNoRixRQUFPLEtBQUssVUFBVTs7QUFJeEIsU0FBUyxZQUFZLE1BQXVCO0FBQzFDLFFBQU8sWUFBWSxJQUFJLEtBQUs7Ozs7NEJBbDhDcUM7cUJBQ2M7Z0JBR2xCO1VBRTNCO1VBRVM7cUJBRW1CO3FCQUNSO3FCQUdBO1dBQ0g7a0JBS0E7Z0JBQ0U7YUFFaUI7Y0FJbEM7Q0FHaEMsY0FBTixNQUFrQjtFQUNoQixBQUFPLGdCQUF5QjtFQUNoQyxBQUFPLGFBQXNCO0VBQzdCLEFBQU8sb0JBRUYsSUFBSSxtQkFBbUI7RUFFNUIsQUFBTyxhQUFzQjtHQUMzQixNQUFNLFFBQVEsS0FBSyxrQkFBa0IsVUFBVTtBQUMvQyxPQUFJLE9BQU8sU0FBUztBQUNsQixXQUFPLE1BQU07O0FBR2YsT0FBSSxRQUFRLElB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
|
|
1350
|
+
export { Sonamu, createWebSocketReplyStub, init_sonamu, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions };
|
|
1351
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmpzIiwibmFtZXMiOlsiREIiLCJhdXRoT3B0aW9uczogQmV0dGVyQXV0aE9wdGlvbnMiLCJnbG9iYWxDb21wcmVzc09wdGlvbnM6IENvbXByZXNzT3B0aW9ucyB8IHVuZGVmaW5lZCIsImZzIiwiY2hhbGsiLCJjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCIsImZpbGVQYXRoIiwiY3NyQ2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QiLCJtaW1lTG9va3VwIiwiY29udGV4dDogQ29udGV4dCIsInJlcUJvZHk6IHtcbiAgICAgICAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICAgICAgICB9IiwiZmlsZXM6IHtcbiAgICAgICAgICBidWZmZXJlZEZpbGVzOiBCdWZmZXJlZEZpbGVbXTtcbiAgICAgICAgICB1cGxvYWRlZEZpbGVzOiBVcGxvYWRlZEZpbGVbXTtcbiAgICAgICAgfSIsImZpZWxkczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiIsImtleUdlbmVyYXRvcjogS2V5R2VuZXJhdG9yIiwid3NDb250ZXh0OiBXZWJTb2NrZXRDb250ZXh0IHwgbnVsbCIsInJhd1dzOiBSZXR1cm5UeXBlPFdlYlNvY2tldFJ1bnRpbWVbXCJyZWdpc3RlckNvbm5lY3Rpb25cIl0+IHwgbnVsbCIsInBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiIsImxvZ3RhcGVEaXNwb3NlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9zb25hbXUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwiYXN5bmNfaG9va3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlciwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgdHlwZSB7fSBmcm9tIFwiQGZhc3RpZnkvd2Vic29ja2V0XCI7XG5pbXBvcnQgeyBkaXNwb3NlIGFzIGxvZ3RhcGVEaXNwb3NlIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IHR5cGUgQXV0aCwgdHlwZSBCZXR0ZXJBdXRoT3B0aW9ucyB9IGZyb20gXCJiZXR0ZXItYXV0aFwiO1xuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IHsgdHlwZSBGU1dhdGNoZXIgfSBmcm9tIFwiY2hva2lkYXJcIjtcbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlLCB0eXBlIEZhc3RpZnlSZXBseSwgdHlwZSBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgbWltZSwgeyBsb29rdXAgYXMgbWltZUxvb2t1cCB9IGZyb20gXCJtaW1lLXR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIFdlYlNvY2tldCB9IGZyb20gXCJ3c1wiO1xuaW1wb3J0IHsgdHlwZSBab2RPYmplY3QgfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IEJBU0VfRklFTERfTUFQUElOR1MgfSBmcm9tIFwiLi4vYXV0aC9iZXR0ZXItYXV0aC1lbnRpdGllc1wiO1xuaW1wb3J0IHsgYXBwbHlDYWNoZUhlYWRlcnMsIENhY2hlUHJlc2V0cyB9IGZyb20gXCIuLi9jYWNoZS1jb250cm9sL2NhY2hlLWNvbnRyb2xcIjtcbmltcG9ydCB7IHR5cGUgQ2FjaGVDb250cm9sQ29uZmlnLCB0eXBlIENhY2hlQ29udHJvbFJlcXVlc3QgfSBmcm9tIFwiLi4vY2FjaGUtY29udHJvbC90eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBDYWNoZUNvbmZpZywgdHlwZSBDYWNoZU1hbmFnZXIgfSBmcm9tIFwiLi4vY2FjaGUvdHlwZXNcIjtcbmltcG9ydCB7IHRvRmFzdGlmeUNvbXByZXNzT3B0aW9uIH0gZnJvbSBcIi4uL2NvbXByZXNzL2NvbXByZXNzXCI7XG5pbXBvcnQgeyB0eXBlIENvbXByZXNzT3B0aW9ucyB9IGZyb20gXCIuLi9jb21wcmVzcy90eXBlc1wiO1xuaW1wb3J0IHsgREIgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11REJDb25maWcgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IFNELCBzZXRTRENvbmZpZyB9IGZyb20gXCIuLi9kaWN0L3NkXCI7XG5pbXBvcnQgeyB0eXBlIExvY2FsaXplZFN0cmluZyB9IGZyb20gXCIuLi9kaWN0L3R5cGVzXCI7XG5pbXBvcnQgeyBOb3RGb3VuZEV4Y2VwdGlvbiB9IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IEJ1ZmZlcmVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL2J1ZmZlcmVkLWZpbGVcIjtcbmltcG9ydCB7IHR5cGUgU3RvcmFnZU1hbmFnZXIgfSBmcm9tIFwiLi4vc3RvcmFnZS9zdG9yYWdlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgS2V5R2VuZXJhdG9yIH0gZnJvbSBcIi4uL3N0b3JhZ2UvdHlwZXNcIjtcbmltcG9ydCB7IFVwbG9hZGVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL3VwbG9hZGVkLWZpbGVcIjtcbmltcG9ydCB7IGNyZWF0ZU1vY2tTU0VGYWN0b3J5IH0gZnJvbSBcIi4uL3N0cmVhbS9zc2VcIjtcbmltcG9ydCB7IFdlYlNvY2tldFJ1bnRpbWUsIHR5cGUgV2ViU29ja2V0Q29ubmVjdGlvbiwgdHlwZSBXZWJTb2NrZXRFdmVudE1hcCB9IGZyb20gXCIuLi9zdHJlYW0vd3NcIjtcbmltcG9ydCB7IHR5cGUgU3luY2VyIH0gZnJvbSBcIi4uL3N5bmNlci9zeW5jZXJcIjtcbmltcG9ydCB7IHR5cGUgV29ya2Zsb3dNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rhc2tzL3dvcmtmbG93LW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgRGV2Vml0ZXN0TWFuYWdlciB9IGZyb20gXCIuLi90ZXN0aW5nL2Rldi12aXRlc3QtbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVGYXN0aWZ5Q29uZmlnIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBjZW50ZXJUZXh0IH0gZnJvbSBcIi4uL3V0aWxzL2NvbnNvbGUtdXRpbFwiO1xuaW1wb3J0IHsgaXNEYWVtb25TZXJ2ZXIgfSBmcm9tIFwiLi4vdXRpbHMvY29udHJvbGxlclwiO1xuaW1wb3J0IHsgZXhpc3RzLCBmaWxlRXhpc3RzIH0gZnJvbSBcIi4uL3V0aWxzL2ZzLXV0aWxzXCI7XG5pbXBvcnQgeyB0eXBlIEFic29sdXRlUGF0aCB9IGZyb20gXCIuLi91dGlscy9wYXRoLXV0aWxzXCI7XG5pbXBvcnQgeyBjb252ZXJ0RmFzdGlmeUhlYWRlcnNUb1N0YW5kYXJkLCBtZXJnZSB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVDb25maWcsIHR5cGUgU29uYW11U2VydmVyT3B0aW9ucywgdHlwZSBTb25hbXVUYXNrT3B0aW9ucyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0IHsgdHlwZSBDb250ZXh0LCB0eXBlIFJ1bnRpbWVDb250ZXh0LCB0eXBlIFdlYlNvY2tldENvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0XCI7XG5pbXBvcnQgeyB0eXBlIEV4dGVuZGVkQXBpIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgZ2V0U2VjcmV0cyB9IGZyb20gXCIuL3NlY3JldFwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVTZWNyZXRzIH0gZnJvbSBcIi4vc2VjcmV0XCI7XG5pbXBvcnQge1xuICBjcmVhdGVXZWJTb2NrZXRSZXBseVN0dWIsXG4gIHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3IsXG4gIHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zLFxuICByZXNvbHZlSW50ZWdyYXRlZFZpdGVIbXJPcHRpb25zLFxufSBmcm9tIFwiLi93ZWJzb2NrZXQtaGVscGVyc1wiO1xuXG5leHBvcnQge1xuICBjcmVhdGVXZWJTb2NrZXRSZXBseVN0dWIsXG4gIHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3IsXG4gIHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zLFxufSBmcm9tIFwiLi93ZWJzb2NrZXQtaGVscGVyc1wiO1xuXG5jbGFzcyBTb25hbXVDbGFzcyB7XG4gIHB1YmxpYyBpc0luaXRpYWxpemVkOiBib29sZWFuID0gZmFsc2U7XG4gIHB1YmxpYyBmb3JUZXN0aW5nOiBib29sZWFuID0gZmFsc2U7XG4gIHB1YmxpYyBhc3luY0xvY2FsU3RvcmFnZTogQXN5bmNMb2NhbFN0b3JhZ2U8e1xuICAgIGNvbnRleHQ6IFJ1bnRpbWVDb250ZXh0O1xuICB9PiA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZSgpO1xuXG4gIHB1YmxpYyBnZXRDb250ZXh0PFQgZXh0ZW5kcyBSdW50aW1lQ29udGV4dCA9IENvbnRleHQ+KCk6IFQge1xuICAgIGNvbnN0IHN0b3JlID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpO1xuICAgIGlmIChzdG9yZT8uY29udGV4dCkge1xuICAgICAgcmV0dXJuIHN0b3JlLmNvbnRleHQgYXMgVDtcbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICAvLyDthYzsiqTtjIUg7ZmY6rK97JeQ7IScIOy7qO2FjeyKpO2KuOqwgCDso7zsnoXrkJjsp4Ag7JWK7J2AIOqyveyasCDruYgg7Luo7YWN7Iqk7Yq4IOumrO2EtFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHJhbnNwb3J0OiBcImh0dHBcIixcbiAgICAgICAgcmVxdWVzdDogbnVsbCxcbiAgICAgICAgcmVwbHk6IG51bGwsXG4gICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICBjcmVhdGVTU0U6IChzY2hlbWE6IFpvZE9iamVjdCkgPT4gY3JlYXRlTW9ja1NTRUZhY3Rvcnkoc2NoZW1hKSxcbiAgICAgICAgbG9jYWxlOiBcIlwiLFxuICAgICAgICB1c2VyOiBudWxsLFxuICAgICAgICBzZXNzaW9uOiBudWxsLFxuICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwPHN0cmluZywgYW55PigpLFxuICAgICAgfSBhcyB1bmtub3duIGFzIFQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBjYW5ub3QgZmluZCBjb250ZXh0XCIpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2FwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGggfCBudWxsID0gbnVsbDtcbiAgc2V0IGFwaVJvb3RQYXRoKGFwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGgpIHtcbiAgICB0aGlzLl9hcGlSb290UGF0aCA9IGFwaVJvb3RQYXRoO1xuICB9XG4gIGdldCBhcGlSb290UGF0aCgpOiBBYnNvbHV0ZVBhdGgge1xuICAgIGlmICh0aGlzLl9hcGlSb290UGF0aCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2FwaVJvb3RQYXRoO1xuICB9XG4gIGdldCBhcHBSb290UGF0aCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFwaVJvb3RQYXRoLnNwbGl0KHBhdGguc2VwKS5zbGljZSgwLCAtMSkuam9pbihwYXRoLnNlcCk7XG4gIH1cblxuICBwcml2YXRlIF9kYkNvbmZpZzogU29uYW11REJDb25maWcgfCBudWxsID0gbnVsbDtcbiAgc2V0IGRiQ29uZmlnKGRiQ29uZmlnOiBTb25hbXVEQkNvbmZpZykge1xuICAgIHRoaXMuX2RiQ29uZmlnID0gZGJDb25maWc7XG4gIH1cbiAgZ2V0IGRiQ29uZmlnKCk6IFNvbmFtdURCQ29uZmlnIHtcbiAgICBpZiAodGhpcy5fZGJDb25maWcgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9kYkNvbmZpZztcbiAgfVxuXG4gIHByaXZhdGUgX3N5bmNlcjogU3luY2VyIHwgbnVsbCA9IG51bGw7XG4gIHNldCBzeW5jZXIoc3luY2VyOiBTeW5jZXIpIHtcbiAgICB0aGlzLl9zeW5jZXIgPSBzeW5jZXI7XG4gIH1cbiAgZ2V0IHN5bmNlcigpOiBTeW5jZXIge1xuICAgIGlmICh0aGlzLl9zeW5jZXIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zeW5jZXI7XG4gIH1cblxuICBwcml2YXRlIF9jb25maWc6IFNvbmFtdUNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgY29uZmlnKGNvbmZpZzogU29uYW11Q29uZmlnKSB7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuICB9XG4gIGdldCBjb25maWcoKTogU29uYW11Q29uZmlnIHtcbiAgICBpZiAodGhpcy5fY29uZmlnID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IHNlY3JldHM6IFNvbmFtdVNlY3JldHMgPSBnZXRTZWNyZXRzKCk7XG5cbiAgcHJpdmF0ZSBfc3RvcmFnZTogU3RvcmFnZU1hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIFN0b3JhZ2VNYW5hZ2VyIOyduOyKpO2EtOyKpFxuICAgKi9cbiAgZ2V0IHN0b3JhZ2UoKTogU3RvcmFnZU1hbmFnZXIge1xuICAgIGlmICghdGhpcy5fc3RvcmFnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3RvcmFnZSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQuIENoZWNrIHN0b3JhZ2UgY29uZmlnLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2U7XG4gIH1cblxuICBwcml2YXRlIF9jYWNoZTogQ2FjaGVNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIC8qKlxuICAgKiBDYWNoZU1hbmFnZXIg7J247Iqk7YS07IqkIChCZW50b0NhY2hlKVxuICAgKi9cbiAgZ2V0IGNhY2hlKCk6IENhY2hlTWFuYWdlciB7XG4gICAgaWYgKCF0aGlzLl9jYWNoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FjaGUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLiBDaGVjayBjYWNoZSBjb25maWcgaW4gc29uYW11LmNvbmZpZy50cy5cIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jYWNoZTtcbiAgfVxuXG4gIHByaXZhdGUgX3dvcmtmbG93czogV29ya2Zsb3dNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIGdldCB3b3JrZmxvd3MoKTogV29ya2Zsb3dNYW5hZ2VyIHtcbiAgICBpZiAodGhpcy5fd29ya2Zsb3dzID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl93b3JrZmxvd3M7XG4gIH1cblxuICBwcml2YXRlIF9hdXRoOiBBdXRoPEJldHRlckF1dGhPcHRpb25zPiB8IG51bGwgPSBudWxsO1xuICBnZXQgYXV0aCgpOiBBdXRoPEJldHRlckF1dGhPcHRpb25zPiB7XG4gICAgaWYgKCF0aGlzLl9hdXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBdXRoIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC4gQ2hlY2sgYXV0aCBjb25maWcgaW4gc29uYW11LmNvbmZpZy50cy5cIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hdXRoO1xuICB9XG5cbiAgcHJpdmF0ZSBfZGV2Vml0ZXN0TWFuYWdlcjogRGV2Vml0ZXN0TWFuYWdlciB8IG51bGwgPSBudWxsO1xuICBnZXQgZGV2Vml0ZXN0TWFuYWdlcigpOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2RldlZpdGVzdE1hbmFnZXI7XG4gIH1cbiAgc2V0IGRldlZpdGVzdE1hbmFnZXIobWFuYWdlcjogRGV2Vml0ZXN0TWFuYWdlciB8IG51bGwpIHtcbiAgICB0aGlzLl9kZXZWaXRlc3RNYW5hZ2VyID0gbWFuYWdlcjtcbiAgfVxuXG4gIC8vIFNvbmFtdeqwgCBydW50aW1l7J2EIOyngeygkSDshozsnKDtlbQgcmVnaXN0cnkvY29ubmVjdGlvbiBsaWZlY3ljbGXsnYQg7JWg7ZSM66as7LyA7J207IWYIOyImOuqheyjvOq4sOyZgCDrj5nquLDtmZTtlahcbiAgcHJpdmF0ZSBfd2Vic29ja2V0UnVudGltZTogV2ViU29ja2V0UnVudGltZSB8IG51bGwgPSBudWxsO1xuICAvLyDqsJnsnYAgRmFzdGlmeSDsnbjsiqTthLTsiqTsl5AgQGZhc3RpZnkvd2Vic29ja2V07J2EIOykkeuztSDrk7HroZ3tlZjripQg6rKD7J2EIFdlYWtTZXTsnLzroZwg7LCo64uo7ZWoXG4gIHByaXZhdGUgcmVhZG9ubHkgd2Vic29ja2V0UGx1Z2luU2VydmVycyA9IG5ldyBXZWFrU2V0PFxuICAgIEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+XG4gID4oKTtcbiAgZ2V0IHdlYnNvY2tldFJ1bnRpbWUoKTogV2ViU29ja2V0UnVudGltZSB7XG4gICAgaWYgKCF0aGlzLl93ZWJzb2NrZXRSdW50aW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXZWJTb2NrZXQgcnVudGltZSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fd2Vic29ja2V0UnVudGltZTtcbiAgfVxuICBzZXQgd2Vic29ja2V0UnVudGltZShydW50aW1lOiBXZWJTb2NrZXRSdW50aW1lIHwgbnVsbCkge1xuICAgIHRoaXMuX3dlYnNvY2tldFJ1bnRpbWUgPSBydW50aW1lO1xuICB9XG5cbiAgLy8gSE1SIOyymOumrDog7YyM7J28IOyLnOyKpO2FnCDqsJDsi5wgKyBITVIvc3luYyDsgqzsnbTtgbQg7Iuk7ZaJ7J2AIHdhdGNoZXIg66qo65OI66GcIOychOyehO2VqeuLiOuLpC5cbiAgcHVibGljIHdhdGNoZXI6IEZTV2F0Y2hlciB8IG51bGwgPSBudWxsO1xuXG4gIHB1YmxpYyBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSB8IG51bGwgPSBudWxsO1xuXG4gIGFzeW5jIGluaXRGb3JUZXN0aW5nKCkge1xuICAgIGF3YWl0IHRoaXMuaW5pdCh0cnVlLCBmYWxzZSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfVxuXG4gIGFzeW5jIGluaXQoXG4gICAgZG9TaWxlbnQ6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBlbmFibGVTeW5jOiBib29sZWFuID0gdHJ1ZSxcbiAgICBhcGlSb290UGF0aD86IEFic29sdXRlUGF0aCxcbiAgICBmb3JUZXN0aW5nOiBib29sZWFuID0gZmFsc2UsXG4gICkge1xuICAgIHRoaXMuZm9yVGVzdGluZyA9IGZvclRlc3Rpbmc7XG5cbiAgICBpZiAodGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdFN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG5cbiAgICAvLyBBUEkg66Oo7Yq4IO2MqOyKpFxuICAgIGNvbnN0IHsgZmluZEFwaVJvb3RQYXRoIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy91dGlsc1wiKTtcbiAgICB0aGlzLmFwaVJvb3RQYXRoID0gYXBpUm9vdFBhdGggPz8gZmluZEFwaVJvb3RQYXRoKCk7XG5cbiAgICAvLyDshKTsoJXsnYQg66Gc65Sp7ZWY64qUIOqyg+u2gO2EsCDsi5zsnpFcbiAgICBjb25zdCBjb25maWdTdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIGNvbnN0IHsgbG9hZENvbmZpZyB9ID0gYXdhaXQgaW1wb3J0KFwiLi9jb25maWdcIik7XG4gICAgdGhpcy5jb25maWcgPSBhd2FpdCBsb2FkQ29uZmlnKHRoaXMuYXBpUm9vdFBhdGgpO1xuICAgIGNvbnN0IGNvbmZpZ1RpbWUgPSBwZXJmb3JtYW5jZS5ub3coKSAtIGNvbmZpZ1N0YXJ0O1xuICAgIHNldFNEQ29uZmlnKHRoaXMuY29uZmlnLmkxOG4pO1xuICAgIC8vIHNvbmFtdS5jb25maWcudHMg6riw67O46rCSIOyEpOyglVxuICAgIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRhdGFiYXNlID0gdGhpcy5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UgPz8gXCJwZ1wiO1xuICAgIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRlZmF1bHRPcHRpb25zLmNsaWVudCA9IHRoaXMuY29uZmlnLmRhdGFiYXNlLmRhdGFiYXNlID8/IFwicGdcIjtcblxuICAgIC8vIOuhnOq5hSDshKTsoJVcbiAgICBjb25zdCB7IGNvbmZpZ3VyZUxvZ1RhcGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL2xvZ2dlci9jb25maWd1cmVcIik7XG4gICAgaWYgKHRoaXMuY29uZmlnLmxvZ2dpbmcgIT09IGZhbHNlKSB7XG4gICAgICBhd2FpdCBjb25maWd1cmVMb2dUYXBlKHtcbiAgICAgICAgLi4udGhpcy5jb25maWcubG9nZ2luZyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIERCIOuhnOuTnFxuICAgIGNvbnN0IHsgREIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2RhdGFiYXNlL2RiXCIpO1xuICAgIHRoaXMuZGJDb25maWcgPSBEQi5nZW5lcmF0ZURCQ29uZmlnKHRoaXMuY29uZmlnLmRhdGFiYXNlKTtcbiAgICBEQi5zZXRDb25maWcodGhpcy5kYkNvbmZpZyk7XG5cbiAgICAvLyBFbnRpdHkg66Gc65OcXG4gICAgLy8g7YWM7Iqk7Yq47JeQ7ISc64+EIEVudGl0eSDsoJXrs7TripQg7ZWE7JqU7ZWp64uI64ukLlxuICAgIC8vIHVwc2VydOqwgCDsoJzrjIDroZwg7J6R64+Z7ZWY66Ck66m0IGVudGl0eeydmCB1bmlxdWUgaW5kZXgg7KCV67O06rCAIO2VhOyalO2VmOq4sCDrlYzrrLjsnoXri4jri6QuXG4gICAgY29uc3QgeyBFbnRpdHlNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIik7XG4gICAgYXdhaXQgRW50aXR5TWFuYWdlci5hdXRvbG9hZChkb1NpbGVudCk7XG5cbiAgICAvLyBDYWNoZSDstIjquLDtmZRcbiAgICBhd2FpdCB0aGlzLmluaXRpYWxpemVDYWNoZSh0aGlzLmNvbmZpZy5zZXJ2ZXIuY2FjaGUsIGZvclRlc3RpbmcpO1xuXG4gICAgLy8gQmV0dGVyQXV0aCDstIjquLDtmZRcbiAgICBjb25zdCBhdXRoQ29uZmlnID0gdGhpcy5jb25maWcuc2VydmVyLmF1dGg7XG4gICAgaWYgKGF1dGhDb25maWcpIHtcbiAgICAgIC8vIOyCrOyaqeyekCDshKTsoJXqs7wg6riw67O46rCS7J2EIG1lcmdlXG4gICAgICBjb25zdCBtZXJnZWRGaWVsZE1hcHBpbmdzID0gbWVyZ2UoQkFTRV9GSUVMRF9NQVBQSU5HUywgYXV0aENvbmZpZyk7XG5cbiAgICAgIC8vIGJldHRlci1hdXRoIOyduOyKpO2EtOyKpCDsg53shLFcbiAgICAgIGNvbnN0IHsgYmV0dGVyQXV0aCB9ID0gYXdhaXQgaW1wb3J0KFwiYmV0dGVyLWF1dGhcIik7XG4gICAgICBjb25zdCB7IHNvbmFtdUtuZXhBZGFwdGVyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9hdXRoL2tuZXgtYWRhcHRlclwiKTtcblxuICAgICAgY29uc3QgYXV0aE9wdGlvbnM6IEJldHRlckF1dGhPcHRpb25zID0ge1xuICAgICAgICBkYXRhYmFzZTogc29uYW11S25leEFkYXB0ZXIoKSxcbiAgICAgICAgLi4ubWVyZ2VkRmllbGRNYXBwaW5ncyxcbiAgICAgIH07XG4gICAgICB0aGlzLl9hdXRoID0gYmV0dGVyQXV0aChhdXRoT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8g7YWM7Iqk7YyF7J24IOqyveyasCDsi7Htgawg7JeG7J20IOykkeuLqFxuICAgIGlmIChmb3JUZXN0aW5nKSB7XG4gICAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRhc2sg65Ox66GdXG4gICAgYXdhaXQgdGhpcy5pbml0aWFsaXplV29ya2Zsb3dzKHRoaXMuY29uZmlnLnRhc2tzKTtcblxuICAgIC8vIFN5bmNlclxuICAgIGNvbnN0IHsgU3luY2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zeW5jZXIvc3luY2VyXCIpO1xuICAgIHRoaXMuc3luY2VyID0gbmV3IFN5bmNlcigpO1xuXG4gICAgLy8gQXV0b2xvYWQ6IE1vZGVscyAvIFR5cGVzIC8gQVBJcyAvIFdvcmtmbG93cyAvIFRlbXBsYXRlcyAvIFNTUiBSb3V0ZXNcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRNb2RlbHMoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZEFwaXMoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFdvcmtmbG93cygpO1xuICAgIGNvbnN0IHsgVGVtcGxhdGVNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90ZW1wbGF0ZVwiKTtcbiAgICBhd2FpdCBUZW1wbGF0ZU1hbmFnZXIuYXV0b2xvYWQoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFNzclJvdXRlcygpO1xuXG4gICAgY29uc3QgeyBpc0xvY2FsLCBpc1Rlc3QsIGlzSG90UmVsb2FkU2VydmVyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9jb250cm9sbGVyXCIpO1xuICAgIGlmIChpc0xvY2FsKCkgJiYgIWlzVGVzdCgpICYmIGlzSG90UmVsb2FkU2VydmVyKCkgJiYgZW5hYmxlU3luYykge1xuICAgICAgYXdhaXQgdGhpcy5zeW5jZXIuc3luYygpO1xuICAgICAgYXdhaXQgdGhpcy5zdGFydFdhdGNoZXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIHRoaXMuX2luaXRFbGFwc2VkID0gcGVyZm9ybWFuY2Uubm93KCkgLSBpbml0U3RhcnQ7XG4gICAgdGhpcy5fY29uZmlnRWxhcHNlZCA9IGNvbmZpZ1RpbWU7XG4gIH1cblxuICBwcml2YXRlIF9pbml0RWxhcHNlZCA9IDA7XG4gIHByaXZhdGUgX2NvbmZpZ0VsYXBzZWQgPSAwO1xuXG4gIGFzeW5jIGNyZWF0ZVNlcnZlcihpbml0T3B0aW9ucz86IHsgZW5hYmxlU3luYz86IGJvb2xlYW47IGRvU2lsZW50PzogYm9vbGVhbiB9KSB7XG4gICAgaWYgKCF0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChpbml0T3B0aW9ucz8uZG9TaWxlbnQsIGluaXRPcHRpb25zPy5lbmFibGVTeW5jKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5jb25maWcuc2VydmVyO1xuICAgIGNvbnN0IHsgZGVmYXVsdDogZmFzdGlmeSB9ID0gYXdhaXQgaW1wb3J0KFwiZmFzdGlmeVwiKTtcbiAgICBjb25zdCB7IGdldExvZ1RhcGVGYXN0aWZ5TG9nZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCJAbG9ndGFwZS9mYXN0aWZ5XCIpO1xuICAgIGNvbnN0IHNlcnZlciA9IGZhc3RpZnkoe1xuICAgICAgLi4ub3B0aW9ucy5mYXN0aWZ5LFxuICAgICAgbG9nZ2VyOlxuICAgICAgICB0aGlzLmNvbmZpZy5sb2dnaW5nICE9PSBmYWxzZVxuICAgICAgICAgID8gZ2V0TG9nVGFwZUZhc3RpZnlMb2dnZXIoe1xuICAgICAgICAgICAgICBjYXRlZ29yeTogdGhpcy5jb25maWcubG9nZ2luZz8uZmFzdGlmeUNhdGVnb3J5ID8/IFtcImZhc3RpZnlcIl0sXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH0pO1xuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuICAgIHRoaXMud2Vic29ja2V0UnVudGltZSA9IG5ldyBXZWJTb2NrZXRSdW50aW1lKG9wdGlvbnMud2Vic29ja2V0KTtcblxuICAgIC8vIFN0b3JhZ2Ug7ISk7KCVIOKGkiBTdG9yYWdlTWFuYWdlciDsg53shLFcbiAgICBpZiAob3B0aW9ucy5zdG9yYWdlKSB7XG4gICAgICBjb25zdCB7IFN0b3JhZ2VNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zdG9yYWdlL3N0b3JhZ2UtbWFuYWdlclwiKTtcbiAgICAgIHRoaXMuX3N0b3JhZ2UgPSBuZXcgU3RvcmFnZU1hbmFnZXIob3B0aW9ucy5zdG9yYWdlKTtcbiAgICB9XG5cbiAgICAvLyDtlIzrn6zqt7jsnbgg65Ox66GdXG4gICAgaWYgKG9wdGlvbnMucGx1Z2lucykge1xuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlclBsdWdpbnMoc2VydmVyLCBvcHRpb25zLnBsdWdpbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmF1dGgpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJCZXR0ZXJBdXRoKHNlcnZlciwgb3B0aW9ucy5hdXRoKTtcbiAgICB9XG5cbiAgICAvLyBBUEkg65287Jqw7YyFIOyEpOyglVxuICAgIGF3YWl0IHRoaXMud2l0aEZhc3RpZnkoc2VydmVyLCBvcHRpb25zLmFwaUNvbmZpZywge1xuICAgICAgZW5hYmxlU3luYzogaW5pdE9wdGlvbnM/LmVuYWJsZVN5bmMsXG4gICAgICBkb1NpbGVudDogaW5pdE9wdGlvbnM/LmRvU2lsZW50LFxuICAgIH0pO1xuXG4gICAgLy8g7ISc67KEIOyLnOyekVxuICAgIGF3YWl0IHRoaXMuYm9vdChzZXJ2ZXIsIG9wdGlvbnMpO1xuXG4gICAgaWYgKCFpbml0T3B0aW9ucz8uZG9TaWxlbnQpIHtcbiAgICAgIHRoaXMucHJpbnRTdGFydHVwU3VtbWFyeSgpO1xuICAgIH1cblxuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICBhc3luYyB3aXRoRmFzdGlmeShcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICBvcHRpb25zPzoge1xuICAgICAgZW5hYmxlU3luYz86IGJvb2xlYW47XG4gICAgICBkb1NpbGVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKSB7XG4gICAgaWYgKCF0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChvcHRpb25zPy5kb1NpbGVudCwgb3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lID8/PSBuZXcgV2ViU29ja2V0UnVudGltZSh0aGlzLmNvbmZpZy5zZXJ2ZXIud2Vic29ja2V0KTtcblxuICAgIC8vIHRpbWV6b25lIOyEpOyglVxuICAgIGNvbnN0IHRpbWV6b25lID0gdGhpcy5jb25maWcuYXBpLnRpbWV6b25lO1xuICAgIGlmICh0aW1lem9uZSkge1xuICAgICAgLy8g7YOA7J6E7KG07JeQIOunnuqyjCDsnZHri7Ug64Kg7KecIOyKpO2KuOungeydhCDrs4DtmZjtlbTso7zslrTslbwg7ZWp64uI64ukLlxuICAgICAgLy8g6rCA66C5IHRpbWV6b25l7J20IFwiQXNpYS9TZW91bFwiIOydtOuptFxuICAgICAgLy8gXCIyMDI1LTExLTIxVDAwOjAwOjAwLjAwMFpcIiDrpbwgXCIyMDI1LTExLTIxVDA5OjAwOjAwKzA5OjAwXCIg7Jy866GcIOuzgO2ZmO2VtOyjvOyWtOyVvCDtlanri4jri6QuXG4gICAgICBjb25zdCB7IGZvcm1hdEluVGltZVpvbmUgfSA9IGF3YWl0IGltcG9ydChcImRhdGUtZm5zLXR6XCIpO1xuXG4gICAgICAvLyBJU08gODYwMSDrgqDsp5wg7ZiV7IudIOygleq3nOyLnSAo7JiIOiAyMDI0LTAxLTE1VDA5OjMwOjAwLjAwMFopXG4gICAgICBjb25zdCBJU09fREFURV9SRUdFWCA9IC9eXFxkezR9LVxcZHsyfS1cXGR7Mn1UXFxkezJ9OlxcZHsyfTpcXGR7Mn0oXFwuXFxkezN9KT9aJC87XG5cbiAgICAgIC8vIFTrpbwg65GY65+s7Iu8IOyekeydgOuUsOyYtO2RnOqwgCDsl4bri6TrqbQgXCIyMDI1LTExLTE5MTc2MzU0NjE4OTAwMDE4OjU2OjI5KzA5OjAwXCLsmYAg6rCZ7J2AIOqysOqzvOqwgCDrgpjsmLXri4jri6QuXG4gICAgICAvLyDsnbTripQgZGF0ZS1mbnMg7Yq57J6F64uI64ukLlxuICAgICAgLy8g7J2066CH6rKMIO2VtOuPhCDqtJzssK7sirXri4jri6QuIFwiMjAyNS0xMS0xOVQxODo1NjoyOSswOTowMFwiIOuqqOyWkeycvOuhnCDsnpgg64KY7Ji164uI64ukLlxuICAgICAgY29uc3QgREFURV9GT1JNQVQgPSBcInl5eXktTU0tZGQnVCdISDptbTpzc1hYWFwiO1xuXG4gICAgICBzZXJ2ZXIuc2V0UmVwbHlTZXJpYWxpemVyKChwYXlsb2FkKSA9PiB7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShwYXlsb2FkLCAoX2tleSwgdmFsdWUpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIElTT19EQVRFX1JFR0VYLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0SW5UaW1lWm9uZShcbiAgICAgICAgICAgICAgbmV3IERhdGUodmFsdWUpLFxuICAgICAgICAgICAgICB0aW1lem9uZSBhcyBgJHtzdHJpbmd9LyR7c3RyaW5nfWAsXG4gICAgICAgICAgICAgIERBVEVfRk9STUFULFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgLy8gVGltZXpvbmUg66Gc6re464qUIHByaW50U3RhcnR1cFN1bW1hcnnsl5DshJwg7Ya17ZWpIOy2nOugpVxuICAgIH1cblxuICAgIC8vIOyghOyytCDrnbzsmrDtjIUg66as7Iqk7Yq4XG4gICAgc2VydmVyLmdldChcbiAgICAgIGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9L3JvdXRlc2AsXG4gICAgICBhc3luYyAoX3JlcXVlc3QsIF9yZXBseSk6IFByb21pc2U8dHlwZW9mIHRoaXMuc3luY2VyLmFwaXM+ID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3luY2VyLmFwaXM7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBIZWFsdGhjaGVjayBBUElcbiAgICBzZXJ2ZXIuZ2V0KFxuICAgICAgYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vaGVhbHRoY2hlY2tgLFxuICAgICAgYXN5bmMgKF9yZXF1ZXN0LCBfcmVwbHkpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgICByZXR1cm4gXCJva1wiO1xuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gU29uYW11IFVJIEFQSSAo66Gc7LusIO2ZmOqyveyXkOyEnOunjClcbiAgICBjb25zdCB7IGlzTG9jYWwgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIik7XG4gICAgaWYgKGlzTG9jYWwoKSkge1xuICAgICAgY29uc3QgeyBzb25hbXVVSUFwaVBsdWdpbiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdWkvYXBpXCIpO1xuICAgICAgc2VydmVyLnJlZ2lzdGVyKHNvbmFtdVVJQXBpUGx1Z2luKTtcbiAgICB9XG5cbiAgICAvLyBEZXZSdW5uZXIg7YWM7Iqk7Yq4IOyXlOuTnO2PrOyduO2KuCAo66Gc7LusIO2ZmOqyvSArIGRldlJ1bm5lciDtmZzshLHtmZQg7IucKVxuICAgIGlmIChpc0xvY2FsKCkgJiYgdGhpcy5jb25maWcudGVzdD8uZGV2UnVubmVyPy5lbmFibGVkKSB7XG4gICAgICBjb25zdCB7IHJlZ2lzdGVyRGV2VGVzdFJvdXRlcyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdGVzdGluZy9kZXYtdGVzdC1yb3V0ZXNcIik7XG4gICAgICBhd2FpdCByZWdpc3RlckRldlRlc3RSb3V0ZXMoc2VydmVyLCB0aGlzLmNvbmZpZy50ZXN0LmRldlJ1bm5lcik7XG4gICAgfVxuXG4gICAgY29uc3Qgd2ViUGF0aCA9IHBhdGguam9pbih0aGlzLmFwcFJvb3RQYXRoLCBcIndlYlwiKTtcbiAgICBjb25zdCBoYXNXZWIgPSBhd2FpdCBleGlzdHMod2ViUGF0aCk7XG5cbiAgICAvLyDsoITsl60gY29tcHJlc3Mg7Ji17IWYIOqzhOyCsCAocm91dGUuY29tcHJlc3M6IHRydWXsnbwg65WMIOyCrOyaqSlcbiAgICBjb25zdCBwbHVnaW5Db21wcmVzcyA9IHRoaXMuY29uZmlnLnNlcnZlci5wbHVnaW5zPy5jb21wcmVzcztcbiAgICBjb25zdCBnbG9iYWxDb21wcmVzc09wdGlvbnM6IENvbXByZXNzT3B0aW9ucyB8IHVuZGVmaW5lZCA9IHBsdWdpbkNvbXByZXNzXG4gICAgICA/IHBsdWdpbkNvbXByZXNzID09PSB0cnVlXG4gICAgICAgID8geyB0aHJlc2hvbGQ6IDEwMjQsIGVuY29kaW5nczogW1wiYnJcIiwgXCJnemlwXCIsIFwiZGVmbGF0ZVwiXSB9XG4gICAgICAgIDoge1xuICAgICAgICAgICAgdGhyZXNob2xkOiBwbHVnaW5Db21wcmVzcy50aHJlc2hvbGQsXG4gICAgICAgICAgICBlbmNvZGluZ3M6IHBsdWdpbkNvbXByZXNzLmVuY29kaW5ncyxcbiAgICAgICAgICAgIGN1c3RvbVR5cGVzOiBwbHVnaW5Db21wcmVzcy5jdXN0b21UeXBlcyxcbiAgICAgICAgICB9XG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChpc0xvY2FsKCkpIHtcbiAgICAgIC8vIOuhnOy7rCDqsJzrsJwg7ZmY6rK9OiBjYXRjaC1hbGzroZwgQVBJ66W8IOuPmeyggSDrp6Tsua3tlZjsl6wgSE1S7J2EIOyngOybkO2VqeuLiOuLpC5cbiAgICAgIC8vIFNPTkFNVV9ESVNBQkxFX0lOVEVHUkFURURfV0VCPXllc+uhnCDshKTsoJXtlZjrqbQgZGV2X2FwaSDrqqjrk5zsl5DshJwgVml0ZSDthrXtlansnYQg67mE7Zmc7ISx7ZmU7ZWgIOyImCDsnojsirXri4jri6QuXG4gICAgICBjb25zdCBkaXNhYmxlSW50ZWdyYXRlZFdlYiA9IHByb2Nlc3MuZW52LlNPTkFNVV9ESVNBQkxFX0lOVEVHUkFURURfV0VCID09PSBcInllc1wiO1xuICAgICAgaWYgKGhhc1dlYiAmJiAhZGlzYWJsZUludGVncmF0ZWRXZWIpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zZXR1cERldlNlcnZlcldpdGhWaXRlKHNlcnZlciwgd2ViUGF0aCwgY29uZmlnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0dXBEZXZTZXJ2ZXIoc2VydmVyLCBjb25maWcpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyDtlITroZzrjZXshZgg7ZmY6rK9OiDqsJzrs4QgQVBJIOudvOyasO2KuCArIOygleyggSDtjIzsnbwg7ISc67mZXG4gICAgICBmb3IgKGNvbnN0IGFwaSBvZiB0aGlzLnN5bmNlci5hcGlzKSB7XG4gICAgICAgIGlmICh0aGlzLnN5bmNlci5tb2RlbHNbYXBpLm1vZGVsTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7KCV7J2Y65CY7KeAIOyViuydgCDrqqjrjbjsl5Ag7KCR6re8ICR7YXBpLm1vZGVsTmFtZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEB3ZWJzb2NrZXQgcm91dGXripQgd3NIYW5kbGVy66GcIOuTseuhne2VmOqzoCwg6rCZ7J2AIHBhdGjsnZgg7J2867CYIEhUVFAgR0VU7J2AIDQyNiDsnZHri7XsnLzroZwgdXBncmFkZeulvCDqsJXsoJztlahcbiAgICAgICAgaWYgKGFwaS53ZWJzb2NrZXRPcHRpb25zKSB7XG4gICAgICAgICAgc2VydmVyLnJvdXRlKHtcbiAgICAgICAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgICAgICAgIHVybDogdGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCArIGFwaS5wYXRoLFxuICAgICAgICAgICAgaGFuZGxlcjogdGhpcy5jcmVhdGVXZWJTb2NrZXRVcGdyYWRlUmVxdWlyZWRIYW5kbGVyKCksXG4gICAgICAgICAgICB3c0hhbmRsZXI6IHRoaXMuY3JlYXRlV2ViU29ja2V0SGFuZGxlcihhcGksIGNvbmZpZyksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgICAgIG1ldGhvZDogYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA/PyBcIkdFVFwiLFxuICAgICAgICAgIHVybDogdGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCArIGFwaS5wYXRoLFxuICAgICAgICAgIGhhbmRsZXI6IHRoaXMuY3JlYXRlQXBpSGFuZGxlcihhcGksIGNvbmZpZyksXG4gICAgICAgICAgY29tcHJlc3M6IHRvRmFzdGlmeUNvbXByZXNzT3B0aW9uKGFwaS5vcHRpb25zLmNvbXByZXNzLCBnbG9iYWxDb21wcmVzc09wdGlvbnMpLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8g7ZSE66Gc642V7IWY7JeQ7ISc64qUIHdlYiDshozsiqQoYXBwUm9vdC93ZWIpIOycoOustOyZgCDrrLTqtIDtlZjqsowsXG4gICAgICAvLyBhcGkvd2ViLWRpc3Qg7KG07J6sIOyXrOu2gOulvCBzZXR1cFN0YXRpY1dlYlNlcnZlciDrgrTrtoDsl5DshJwg7YyQ64uo7ZWp64uI64ukLlxuICAgICAgYXdhaXQgdGhpcy5zZXR1cFN0YXRpY1dlYlNlcnZlcihzZXJ2ZXIsIGNvbmZpZywgZ2xvYmFsQ29tcHJlc3NPcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZGV2IOuqqOuTnCDqs7XthrU6IGNhdGNoLWFsbOyXkOyEnCBzeW5jZXIuYXBpc+ulvCDrj5nsoIHsnLzroZwg7YOQ7IOJ7ZWY7JesIEFQSSDsmpTssq3snYQg7LKY66as7ZWp64uI64ukLlxuICAgKiBzZXJ2ZXIucm91dGUoKeuhnCDqsJzrs4Qg65Ox66Gd7ZWY66m0IGhhbmRsZXLqsIAg6rOg7KCV65CY7Ja0IEhNUuydtCDrj5nsnpHtlZjsp4Ag7JWK7Jy866+A66GcLFxuICAgKiDrp6Qg7JqU7LKt66eI64ukIHN5bmNlci5hcGlz66W8IOyhsO2ajO2VmOuKlCDsnbQg67Cp7Iud7J2EIOyCrOyaqe2VqeuLiOuLpC5cbiAgICpcbiAgICog7JqU7LKt7J20IC9hcGko7KCV7ZmV7Z6I64qUIHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgp66GcIOyLnOyeke2VmOyngCDslYrripQg6rK97Jqw652866m0IG51bGzsnYQg67CY7ZmY7ZWY66mwIOuBneuDheuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgaGFuZGxlRGV2QXBpUmVxdWVzdChcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6ICgocmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpID0+IFByb21pc2U8dW5rbm93bj4pIHwgbnVsbCB7XG4gICAgY29uc3QgbWF0Y2hlZEFwaSA9IHRoaXMuZmluZE1hdGNoZWRBcGkocmVxdWVzdCk7XG5cbiAgICBpZiAoIW1hdGNoZWRBcGkpIHtcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgfVxuXG4gICAgLy8gd2Vic29ja2V0IHJvdXRl66W8IOydvOuwmCBIVFRQ66GcIOyngeygkSDtmLjstpztlZwg6rK97JqwIDQyNuydhCDrj4zroKTspJggdXBncmFkZSDsl4bsnbQg7KCR6re87ZWY64qUIOqyg+ydhCDssKjri6jtlahcbiAgICBpZiAobWF0Y2hlZEFwaS53ZWJzb2NrZXRPcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVXZWJTb2NrZXRVcGdyYWRlUmVxdWlyZWRIYW5kbGVyKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlQXBpSGFuZGxlcihtYXRjaGVkQXBpLCBjb25maWcpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWF0Y2hlZEFwaShyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCk6IEV4dGVuZGVkQXBpIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybChyZXF1ZXN0LnVybCk7XG4gICAgY29uc3QgbWV0aG9kID0gcmVxdWVzdC5tZXRob2Q7XG5cbiAgICBpZiAoIXVybC5zdGFydHNXaXRoKHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN5bmNlci5hcGlzLmZpbmQoKGFwaSkgPT4ge1xuICAgICAgaWYgKHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFwaU1ldGhvZCA9IGFwaS5vcHRpb25zLmh0dHBNZXRob2QgPz8gXCJHRVRcIjtcbiAgICAgIGlmIChhcGlNZXRob2QgIT09IG1ldGhvZCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aDtcbiAgICAgIHJldHVybiB0aGlzLmlzUGF0aFBhdHRlcm5NYXRjaChmdWxsUGF0aCwgdXJsKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBkZXYgYXBpIOuqqOuTnDogVml0ZSDsl4bsnbQgQVBJIOuPmeyggSDrnbzsmrDtjIXrp4wg7KCc6rO17ZWp64uI64ukLlxuICAgKiBITVLsnYQg7JyE7ZW0IGNhdGNoLWFsbOyXkOyEnCDrp6Qg7JqU7LKt66eI64ukIHN5bmNlci5hcGlz66W8IOyhsO2ajO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgc2V0dXBEZXZTZXJ2ZXIoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IHZvaWQge1xuICAgIC8vIHVwZ3JhZGXripQg7Iuk7KeI7KCB7Jy866GcIEdFVOyXkOyEnOunjCDshLHrpr3tlZjrr4DroZwgR0VUICsgd3NIYW5kbGVyIOyZgCDqt7gg7Jm4IG1ldGhvZOulvCDrs4Trj4Qgcm91dGXroZwg67aE66as7ZWoXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIHJldHVybiBoYW5kbGVyKHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyDrk7HroZ3rkJwgQVBJ7JmAIOydvOy5mO2VmOyngCDslYrripQg7JqU7LKt7JeQIOuMgO2VnCBmYWxsYmFja+yeheuLiOuLpC5cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFNEKFwiZXJyb3IuYXBpLm5vdEZvdW5kXCIpKTtcbiAgICAgIH0sXG4gICAgICB3c0hhbmRsZXI6IGFzeW5jIChjb25uZWN0aW9uLCByZXF1ZXN0KSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlRGV2V2ViU29ja2V0UmVxdWVzdChjb25uZWN0aW9uLnNvY2tldCwgcmVxdWVzdCwgY29uZmlnKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJIRUFEXCIsIFwiUE9TVFwiLCBcIlBVVFwiLCBcIkRFTEVURVwiLCBcIlBBVENIXCJdLFxuICAgICAgdXJsOiBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS8qYCxcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5oYW5kbGVEZXZBcGlSZXF1ZXN0KHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZXIocmVxdWVzdCwgcmVwbHkpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB2aXRlU2VydmVyOiBhbnkgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBkZXYgYWxsIOuqqOuTnDogVml0ZSBEZXYgU2VydmVy66W8IO2Gte2Vqe2VmOyXrCBBUEkgKyBTU1IgKyBDU1LsnYQg66qo65GQIOygnOqzte2VqeuLiOuLpC5cbiAgICogQVBJIOuPmeyggSDrp6Tsua3snYAgaGFuZGxlRGV2QXBpUmVxdWVzdOulvCDqs7XsnKDtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNldHVwRGV2U2VydmVyV2l0aFZpdGUoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICB3ZWJQYXRoOiBzdHJpbmcsXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBAZmFzdGlmeS9taWRkaWUg65Ox66GdIChDb25uZWN0LXN0eWxlIG1pZGRsZXdhcmUg7KeA7JuQKVxuICAgIGF3YWl0IHNlcnZlci5yZWdpc3RlcigoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvbWlkZGllXCIpKS5kZWZhdWx0KTtcblxuICAgIGNvbnN0IHZpdGUgPSBhd2FpdCBpbXBvcnQoXCJ2aXRlXCIpO1xuICAgIC8vIEBmYXN0aWZ5L3dlYnNvY2tldCDtlIzrn6zqt7jsnbjsnbQg7Zmc7ISx7ZmU65CY66m0IEhNUiB3ZWJzb2NrZXTqs7wgc2VydmVyIHNvY2tldOydtCDstqnrj4ztlZjrr4DroZwgZGVkaWNhdGVkIO2PrO2KuOuhnCDrtoTrpqztlahcbiAgICBjb25zdCByZXF1aXJlc0RlZGljYXRlZEhtclNlcnZlciA9IEJvb2xlYW4odGhpcy5jb25maWcuc2VydmVyLnBsdWdpbnM/LndzKTtcbiAgICBjb25zdCBobXIgPSByZXNvbHZlSW50ZWdyYXRlZFZpdGVIbXJPcHRpb25zKHtcbiAgICAgIGh0dHBTZXJ2ZXI6IHNlcnZlci5zZXJ2ZXIsXG4gICAgICByZXF1aXJlc0RlZGljYXRlZFdlYlNvY2tldFNlcnZlcjogcmVxdWlyZXNEZWRpY2F0ZWRIbXJTZXJ2ZXIsXG4gICAgfSk7XG5cbiAgICB0aGlzLnZpdGVTZXJ2ZXIgPSBhd2FpdCB2aXRlLmNyZWF0ZVNlcnZlcih7XG4gICAgICByb290OiB3ZWJQYXRoLFxuICAgICAgc2VydmVyOiB7XG4gICAgICAgIG1pZGRsZXdhcmVNb2RlOiB0cnVlLFxuICAgICAgICBobXIsXG4gICAgICB9LFxuICAgICAgYXBwVHlwZTogXCJjdXN0b21cIixcbiAgICB9KTtcblxuICAgIC8vIFZpdGUgbWlkZGxld2FyZSDrk7HroZ0gKFZpdGUg7JeQ7IWLIOyymOumrClcbiAgICBzZXJ2ZXIudXNlKChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICAgICAgLy8gQVBJ7JmAIFNvbmFtdSBVSeuKlCBGYXN0aWZ5IOudvOyasO2KuOqwgCDsspjrpqztlZjrj4TroZ0gc2tpcFxuICAgICAgaWYgKHJlcS51cmw/LnN0YXJ0c1dpdGgodGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCkgfHwgcmVxLnVybD8uc3RhcnRzV2l0aChcIi9zb25hbXUtdWlcIikpIHtcbiAgICAgICAgcmV0dXJuIG5leHQoKTtcbiAgICAgIH1cbiAgICAgIC8vIOuCmOuouOyngOuKlCBWaXRlIG1pZGRsZXdhcmXroZwg7KCE64usXG4gICAgICByZXR1cm4gdGhpcy52aXRlU2VydmVyLm1pZGRsZXdhcmVzKHJlcSwgcmVzLCBuZXh0KTtcbiAgICB9KTtcblxuICAgIC8vIFdTIHVwZ3JhZGUg6rK966GcKEdFVCnsmYAg7J2867CYIEhUVFAg66mU7ISc65Oc66W8IOuzhOuPhCByb3V0ZeuhnCDrtoTrpqztlbQgd2Vic29ja2V0IHJvdXRl6rCAIEhUTUwgZmFsbGJhY2vsl5Ag66i57Z6I7KeAIOyViuuPhOuhnSDtlahcbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgdXJsOiBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS8qYCxcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmhhbmRsZURldkFwaVJlcXVlc3QocmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQocmVxdWVzdCwgcmVwbHkpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgICB9LFxuICAgICAgd3NIYW5kbGVyOiBhc3luYyAoY29ubmVjdGlvbiwgcmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmhhbmRsZURldldlYlNvY2tldFJlcXVlc3QoY29ubmVjdGlvbi5zb2NrZXQsIHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiSEVBRFwiLCBcIlBPU1RcIiwgXCJQVVRcIiwgXCJERUxFVEVcIiwgXCJQQVRDSFwiXSxcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5oYW5kbGVEZXZBcGlSZXF1ZXN0KHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0KHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIGNhdGNoLWFsbCDrnbzsmrDtirjsl5DshJwgU1NSL0NTUiDsspjrpqxcbiAgICAvLyDqsJzrsJwg7ZmY6rK97JeQ7ISc64qUIOudvOyasO2KuOuzhCBjb21wcmVzcyDsmLXshZjsnYQg7Y+s6riw7ZWY6rOgIEhNUiDsnbTsoJDsnYQg7Leo7ZWp64uI64ukLlxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkdFVFwiLCBcIkhFQURcIl0sXG4gICAgICB1cmw6IFwiLypcIixcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB1cmwgPSByZXF1ZXN0LnVybDtcblxuICAgICAgICAvLyAxLiBTU1Ig65287Jqw7Yq4IOyymOumrFxuICAgICAgICBjb25zdCB7IG1hdGNoU1NSUm91dGUsIHJlbmRlclNTUiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyXCIpO1xuICAgICAgICBjb25zdCBzc3JNYXRjaCA9IG1hdGNoU1NSUm91dGUodXJsKTtcbiAgICAgICAgaWYgKHNzck1hdGNoKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYFtTU1JdIE1hdGNoZWQgcm91dGU6ICR7c3NyTWF0Y2gucm91dGUucGF0aH1gKTtcbiAgICAgICAgICBjb25zdCBodG1sID0gYXdhaXQgcmVuZGVyU1NSKFxuICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgc3NyTWF0Y2gucm91dGUsXG4gICAgICAgICAgICBzc3JNYXRjaC5wYXJhbXMsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgcmVwbHksXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICB0aGlzLnZpdGVTZXJ2ZXIsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXBseS50eXBlKFwidGV4dC9odG1sXCIpO1xuICAgICAgICAgIHJldHVybiBodG1sO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gMi4gQ1NSIGZhbGxiYWNrXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZnMgPSBhd2FpdCBpbXBvcnQoXCJub2RlOmZzL3Byb21pc2VzXCIpO1xuICAgICAgICAgIGxldCB0ZW1wbGF0ZSA9IGF3YWl0IGZzLnJlYWRGaWxlKFxuICAgICAgICAgICAgcGF0aC5qb2luKHRoaXMudml0ZVNlcnZlci5jb25maWcucm9vdCwgXCJpbmRleC5odG1sXCIpLFxuICAgICAgICAgICAgXCJ1dGYtOFwiLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGVtcGxhdGUgPSBhd2FpdCB0aGlzLnZpdGVTZXJ2ZXIudHJhbnNmb3JtSW5kZXhIdG1sKHVybCwgdGVtcGxhdGUpO1xuXG4gICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICB0aGlzLnZpdGVTZXJ2ZXIuc3NyRml4U3RhY2t0cmFjZShlIGFzIEVycm9yKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgIHJldHVybiAoZSBhcyBFcnJvcikubWVzc2FnZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIOyEnOuyhCDsooXro4wg7IucIFZpdGXrj4Qg7KKF66OMXG4gICAgc2VydmVyLmFkZEhvb2soXCJvbkNsb3NlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMudml0ZVNlcnZlci5jbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgaWYgKFwicG9ydFwiIGluIGhtcikge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGNoYWxrLmRpbShcbiAgICAgICAgICBg4pyTIFZpdGUgSE1SIHVzaW5nIGRlZGljYXRlZCB3ZWJzb2NrZXQgcG9ydCAke2htci5wb3J0fSB0byBhdm9pZCBGYXN0aWZ5IHdlYnNvY2tldCBjb25mbGljdHNgLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coY2hhbGsuZGltKFwi4pyTIFZpdGUgZGV2IHNlcnZlciBpbnRlZ3JhdGVkXCIpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2V0dXBTdGF0aWNXZWJTZXJ2ZXIoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgZ2xvYmFsQ29tcHJlc3NPcHRpb25zOiBDb21wcmVzc09wdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOqyveuhnCDrqoXtmZXtmZQ6IGFwaS93ZWItZGlzdC9jbGllbnQgKOygleyggSDtjIzsnbwpLCBhcGkvd2ViLWRpc3Qvc2VydmVyIChTU1IgZW50cnkpLCBhcGkvZGlzdC9zc3IgKFNTUiByb3V0ZXMgLSBBUEkg7IaM7JygKVxuICAgIGNvbnN0IHdlYkRpc3RQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwid2ViLWRpc3RcIiwgXCJjbGllbnRcIik7XG4gICAgY29uc3Qgc3NyUGF0aCA9IHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcIndlYi1kaXN0XCIsIFwic2VydmVyXCIpO1xuICAgIGNvbnN0IHNzckVudHJ5UGF0aCA9IHBhdGguam9pbihzc3JQYXRoLCBcImVudHJ5LXNlcnZlci5nZW5lcmF0ZWQuanNcIik7XG4gICAgY29uc3Qgc3NyUm91dGVzUGF0aCA9IHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcImRpc3RcIiwgXCJzc3JcIiwgXCJyb3V0ZXMuanNcIik7XG5cbiAgICBpZiAoIShhd2FpdCBleGlzdHMod2ViRGlzdFBhdGgpKSkge1xuICAgICAgY29uc29sZS53YXJuKGDimqAgV2ViIGRpc3Qgbm90IGZvdW5kOiAke3dlYkRpc3RQYXRofWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNTUiBlbnRyeSDsobTsnqwg7Jes67aAIO2ZleyduFxuICAgIGNvbnN0IHNzckF2YWlsYWJsZSA9IGF3YWl0IGV4aXN0cyhzc3JFbnRyeVBhdGgpO1xuXG4gICAgaWYgKCFzc3JBdmFpbGFibGUpIHtcbiAgICAgIGNvbnNvbGUud2Fybihg4pqgIFNTUiBlbnRyeSBub3QgZm91bmQ6ICR7c3NyRW50cnlQYXRofWApO1xuICAgICAgY29uc29sZS53YXJuKFwiICBTU1Igd2lsbCBiZSBkaXNhYmxlZC4gT25seSBDU1Igd2lsbCB3b3JrLlwiKTtcbiAgICB9XG5cbiAgICAvLyBTU1Ig65287Jqw7Yq4IOuhnOuTnCAocHJvZHVjdGlvbuyXkOyEnOunjCwg7IKs7Jqp7J6QIO2UhOuhnOygne2KuOydmCBzc3Ivcm91dGVzLnRzKVxuICAgIGlmIChzc3JBdmFpbGFibGUpIHtcbiAgICAgIGlmIChhd2FpdCBleGlzdHMoc3NyUm91dGVzUGF0aCkpIHtcbiAgICAgICAgLy8gdHMtbG9hZGVy652866m0IFwiZmlsZTovL1wi66GcIOyLnOyeke2VmOuKlCBmdWxseS1yZXNvbHZlZCBwYXRo66eMIOuwm+q4sOyXkCDsnbTrpbwg7LKY66as7ZW07KO864qUIGltcG9ydE1lbWJlcnPrpbwg7IKs7Jqp7ZW07JW8IO2WiOqyoOyngOunjCxcbiAgICAgICAgLy8g7Jes6riw64qUIO2UhOuhnOuNleyFmCDtmZjqsr3sl5DshJwgbG9hZGVyIOyXhuydtCDrj4zslYTqsIDquLAg65WM66y47JeQIFwi7KeE7KecIGpzIO2MjOydvFwi7J2YIFwi6re464OlXCIg7KCI64yA6rK966Gc66W8IOuwlOuhnCBpbXBvcnTtlbTrj4Qg65Cp64uI64ukLlxuICAgICAgICAvLyDsnbQg64K07Jqp7J2AIOydtCDtlajsiJgg64K07JeQ7IScIOyVhOuemOyXkCDrgpjsmKwg64uk66W4IGltcG9ydCDtmLjstpzsl5Drj4Qg64+Z7J287ZWY6rKMIOyggeyaqeuQqeuLiOuLpC5cbiAgICAgICAgYXdhaXQgaW1wb3J0KHNzclJvdXRlc1BhdGgpO1xuICAgICAgICBjb25zb2xlLmxvZyhcIuKckyBTU1Igcm91dGVzIGxvYWRlZFwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihg4pqgIFNTUiByb3V0ZXMgbm90IGZvdW5kOiAke3NzclJvdXRlc1BhdGh9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g66Gk66eBIOyXheuNsOydtO2KuCDrjIDsnZE6IGFzc2V0IGhhc2gg67aI7J287LmYIOyLnCDtmITsnqwg67KE7KCEIOyngeygkSDshJzruZlcbiAgICBzZXJ2ZXIuZ2V0KFwiL2Fzc2V0cy86ZmlsZW5hbWVcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ZWRGaWxlID0gKHJlcXVlc3QucGFyYW1zIGFzIHsgZmlsZW5hbWU6IHN0cmluZyB9KS5maWxlbmFtZTtcbiAgICAgIGNvbnN0IGFzc2V0c0RpciA9IHBhdGguam9pbih3ZWJEaXN0UGF0aCwgXCJhc3NldHNcIik7XG4gICAgICBjb25zdCBzYWZlRmlsZVBhdGggPSB0aGlzLnJlc29sdmVQYXRoV2l0aGluQmFzZURpcihhc3NldHNEaXIsIHJlcXVlc3RlZEZpbGUpO1xuICAgICAgaWYgKHNhZmVGaWxlUGF0aCA9PT0gbnVsbCkge1xuICAgICAgICByZXBseS5zdGF0dXMoNDAzKS5zZW5kKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlID0gcGF0aC5yZWxhdGl2ZShhc3NldHNEaXIsIHNhZmVGaWxlUGF0aCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG5cbiAgICAgIGNvbnN0IGFzc2V0UGF0aCA9IGAvYXNzZXRzLyR7bm9ybWFsaXplZFJlcXVlc3RlZEZpbGV9YDtcblxuICAgICAgLy8gQ2FjaGUtQ29udHJvbCDtl6TrjZQg6rKw7KCVXG4gICAgICBjb25zdCBnZXRDYWNoZUNvbnRyb2xGb3JBc3NldCA9ICgpOiBDYWNoZUNvbnRyb2xDb25maWcgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgICB0eXBlOiBcImFzc2V0c1wiLFxuICAgICAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICAgICAgcGF0aDogYXNzZXRQYXRoLFxuICAgICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8g7IKs7Jqp7J6QIOygleydmCDtlbjrk6Trn6wg7Jqw7ISgXG4gICAgICAgIGlmIChjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcikge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKGNhY2hlUmVxKTtcbiAgICAgICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g6riw67O46rCSOiBpbW11dGFibGVcbiAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5pbW11dGFibGU7XG4gICAgICB9O1xuXG4gICAgICAvLyBpbmRleC0qLmpzIOuYkOuKlCBpbmRleC0qLmNzcyDsmpTssq3snbgg6rK97JqwXG4gICAgICBpZiAoL15pbmRleC1bYS1mMC05XStcXC4oanN8Y3NzKSQvLnRlc3Qobm9ybWFsaXplZFJlcXVlc3RlZEZpbGUpKSB7XG4gICAgICAgIGNvbnN0IGV4dCA9IG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlLnNwbGl0KFwiLlwiKS5wb3AoKTtcbiAgICAgICAgY29uc3QgZmlsZXMgPSBhd2FpdCBmcy5yZWFkZGlyKGFzc2V0c0Rpcik7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaWxlID0gZmlsZXMuZmluZCgoZikgPT4gZi5zdGFydHNXaXRoKFwiaW5kZXgtXCIpICYmIGYuZW5kc1dpdGgoYC4ke2V4dH1gKSk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRGaWxlKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oYXNzZXRzRGlyLCBjdXJyZW50RmlsZSk7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgICByZXBseS50eXBlKGV4dCA9PT0gXCJqc1wiID8gXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCIgOiBcInRleHQvY3NzXCIpO1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBnZXRDYWNoZUNvbnRyb2xGb3JBc3NldCgpKTtcbiAgICAgICAgICByZXR1cm4gcmVwbHkuc2VuZChjb250ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyDsnbzrsJgg7YyM7J28IOyEnOu5mVxuICAgICAgY29uc3QgZmlsZVBhdGggPSBzYWZlRmlsZVBhdGg7XG4gICAgICBpZiAoYXdhaXQgZXhpc3RzKGZpbGVQYXRoKSkge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICBjb25zdCBleHQgPSBub3JtYWxpemVkUmVxdWVzdGVkRmlsZS5zcGxpdChcIi5cIikucG9wKCk7XG4gICAgICAgIHJlcGx5LnR5cGUoZXh0ID09PSBcImpzXCIgPyBcImFwcGxpY2F0aW9uL2phdmFzY3JpcHRcIiA6IGV4dCA9PT0gXCJjc3NcIiA/IFwidGV4dC9jc3NcIiA6IFwiXCIpO1xuICAgICAgICBpZiAobm9ybWFsaXplZFJlcXVlc3RlZEZpbGUuaW5jbHVkZXMoXCItXCIpKSB7XG4gICAgICAgICAgYXBwbHlDYWNoZUhlYWRlcnMocmVwbHksIGdldENhY2hlQ29udHJvbEZvckFzc2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXBseS5zZW5kKGNvbnRlbnQpO1xuICAgICAgfVxuXG4gICAgICByZXBseS5zdGF0dXMoNDA0KS5zZW5kKCk7XG4gICAgfSk7XG5cbiAgICAvLyBTU1Ig65287Jqw7Yq4IOqwnOuzhCDrk7HroZ0gKGNvbXByZXNzIOyYteyFmOydtCDrnbzsmrDtirjrs4TroZwg7KCB7Jqp65CY64+E66GdKVxuICAgIGlmIChzc3JBdmFpbGFibGUpIHtcbiAgICAgIGNvbnN0IHsgZ2V0U1NSUm91dGVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zc3JcIik7XG4gICAgICBjb25zdCB7IHJlbmRlclNTUiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyL3JlbmRlcmVyXCIpO1xuICAgICAgY29uc3Qgc3NyUm91dGVzID0gZ2V0U1NSUm91dGVzKCk7XG5cbiAgICAgIGZvciAoY29uc3Qgcm91dGUgb2Ygc3NyUm91dGVzKSB7XG4gICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJIRUFEXCJdLFxuICAgICAgICAgIHVybDogcm91dGUucGF0aCxcbiAgICAgICAgICBjb21wcmVzczogdG9GYXN0aWZ5Q29tcHJlc3NPcHRpb24ocm91dGUuY29tcHJlc3MgPz8gdHJ1ZSwgZ2xvYmFsQ29tcHJlc3NPcHRpb25zKSxcbiAgICAgICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHJlcXVlc3QudXJsO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFtTU1JdIE1hdGNoZWQgcm91dGU6ICR7cm91dGUucGF0aH1gKTtcblxuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0gdGhpcy5leHRyYWN0UGF0aFBhcmFtcyhyb3V0ZS5wYXRoLCB1cmwpO1xuICAgICAgICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlbmRlclNTUih1cmwsIHJvdXRlLCBwYXJhbXMsIHJlcXVlc3QsIHJlcGx5LCBjb25maWcpO1xuXG4gICAgICAgICAgICByZXBseS50eXBlKFwidGV4dC9odG1sXCIpO1xuICAgICAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ1NSIG9yIFN0YXRpYyBGaWxlIEZhbGxiYWNrIChTU1Ig65287Jqw7Yq47JeQIOunpOy5reuQmOyngCDslYrripQg66qo65OgIOyalOyyrSlcbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJIRUFEXCJdLFxuICAgICAgdXJsOiBcIipcIixcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICAvLyAvYXBpLCAvc29uYW11LXVp64qUIDQwNCDqt7jrjIDroZxcbiAgICAgICAgaWYgKHJlcXVlc3QudXJsLnN0YXJ0c1dpdGgoXCIvYXBpXCIpIHx8IHJlcXVlc3QudXJsLnN0YXJ0c1dpdGgoXCIvc29uYW11LXVpXCIpKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwNCkuc2VuZCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENTUuyaqSBDYWNoZS1Db250cm9sIO2XpOuNlCDshKTsoJVcbiAgICAgICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICAgICAgY29uc3QgY3NyQ2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QgPSB7XG4gICAgICAgICAgICB0eXBlOiBcImNzclwiLFxuICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICAgIHBhdGg6IHJlcXVlc3QudXJsLnNwbGl0KFwiP1wiKVswXSxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBjc3JDYWNoZUNvbmZpZyA9IGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKGNzckNhY2hlUmVxKTtcblxuICAgICAgICAgIGlmIChjc3JDYWNoZUNvbmZpZykge1xuICAgICAgICAgICAgYXBwbHlDYWNoZUhlYWRlcnMocmVwbHksIGNzckNhY2hlQ29uZmlnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyDsoJXsoIEg7YyM7J287J20IOyhtOyerO2VoCDqsr3smrAsIOygleyggSDtjIzsnbzsnYQg66i87KCAIOyEnOu5me2VtOyVvO2VqFxuICAgICAgICBjb25zdCByZXF1ZXN0UGF0aCA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHJlcXVlc3QudXJsKTtcbiAgICAgICAgY29uc3Qgc2FmZUZpbGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIod2ViRGlzdFBhdGgsIHJlcXVlc3RQYXRoKTtcbiAgICAgICAgaWYgKHNhZmVGaWxlUGF0aCA9PT0gbnVsbCkge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDMpLnNlbmQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF3YWl0IGZpbGVFeGlzdHMoc2FmZUZpbGVQYXRoKSkge1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShzYWZlRmlsZVBhdGgpO1xuICAgICAgICAgIHJldHVybiByZXBseS50eXBlKG1pbWVMb29rdXAoc2FmZUZpbGVQYXRoKSB8fCBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiKS5zZW5kKGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ1NSIGZhbGxiYWNrOiBpbmRleC5odG1sIOyEnOu5mVxuICAgICAgICBjb25zdCBpbmRleFBhdGggPSBwYXRoLmpvaW4od2ViRGlzdFBhdGgsIFwiaW5kZXguaHRtbFwiKTtcbiAgICAgICAgcmV0dXJuIHJlcGx5LnR5cGUoXCJ0ZXh0L2h0bWxcIikuc2VuZChhd2FpdCBmcy5yZWFkRmlsZShpbmRleFBhdGgsIFwidXRmLThcIikpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKGDinJMgU3RhdGljIHdlYiBzZXJ2ZXIgY29uZmlndXJlZCB3aXRoICR7c3NyQXZhaWxhYmxlID8gXCJTU1JcIiA6IFwiQ1NSIG9ubHlcIn0gc3VwcG9ydGApO1xuICB9XG5cbiAgY3JlYXRlQXBpSGFuZGxlcihcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogKHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KSA9PiBQcm9taXNlPHVua25vd24+IHtcbiAgICByZXR1cm4gYXN5bmMgKHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KTogUHJvbWlzZTx1bmtub3duPiA9PiB7XG4gICAgICAvLyBDb250ZXh0IOyDneyEsVxuICAgICAgY29uc3QgY29udGV4dDogQ29udGV4dCA9IGF3YWl0IHRoaXMuY3JlYXRlQ29udGV4dChjb25maWcsIHJlcXVlc3QsIHJlcGx5KTtcblxuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIGd1YXJkcyDsspjrpqxcbiAgICAgICAgcnVuR3VhcmRzKHtcbiAgICAgICAgICBndWFyZHM6IGFwaS5vcHRpb25zLmd1YXJkcyxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICBhcGksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIO2MjOudvOuvuO2EsCDsoJXrs7TroZwgem9kIOyKpO2CpOuniCDruYzrk5xcbiAgICAgICAgY29uc3QgeyBnZXRab2RPYmplY3RGcm9tQXBpIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvZGUtY29udmVydGVyc1wiKTtcbiAgICAgICAgY29uc3QgUmVxVHlwZSA9IGdldFpvZE9iamVjdEZyb21BcGkoYXBpLCB0aGlzLnN5bmNlci50eXBlcyk7XG5cbiAgICAgICAgLy8gcmVxdWVzdCDtjIzsi7FcbiAgICAgICAgY29uc3Qgd2hpY2ggPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID09PSBcIkdFVFwiID8gXCJxdWVyeVwiIDogXCJib2R5XCI7XG4gICAgICAgIGxldCByZXFCb2R5OiB7XG4gICAgICAgICAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbiAgICAgICAgfTtcbiAgICAgICAgLy8g7YyM7J28IOyXheuhnOuTnCDsnojripQg6rK97JqwIOyehOyLnCDrjbDsnbTthLBcbiAgICAgICAgY29uc3QgZmlsZXM6IHtcbiAgICAgICAgICBidWZmZXJlZEZpbGVzOiBCdWZmZXJlZEZpbGVbXTtcbiAgICAgICAgICB1cGxvYWRlZEZpbGVzOiBVcGxvYWRlZEZpbGVbXTtcbiAgICAgICAgfSA9IHtcbiAgICAgICAgICBidWZmZXJlZEZpbGVzOiBbXSxcbiAgICAgICAgICB1cGxvYWRlZEZpbGVzOiBbXSxcbiAgICAgICAgfTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGJvZHkgPSAocmVxdWVzdFt3aGljaF0gPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICAgIGlmIChhcGkudXBsb2FkT3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgcGFydHMgPSByZXF1ZXN0LnBhcnRzKHtcbiAgICAgICAgICAgICAgbGltaXRzOiBhcGkudXBsb2FkT3B0aW9ucy5saW1pdHMsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gRm9ybURhdGHsnZggZmllbGTrk6TsnYQg7J6E7Iuc66GcIOyggOyepVxuICAgICAgICAgICAgY29uc3QgZmllbGRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICAgICAgICAgIGlmIChhcGkudXBsb2FkT3B0aW9ucy5jb25zdW1lID09PSBcImJ1ZmZlclwiIHx8ICFhcGkudXBsb2FkT3B0aW9ucy5jb25zdW1lKSB7XG4gICAgICAgICAgICAgIC8vIEJ1ZmZlciDrqqjrk5w6IOuplOuqqOumrOyXkCDroZzrk5xcbiAgICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gXCJmaWxlXCIpIHtcbiAgICAgICAgICAgICAgICAgIC8vIENSSVRJQ0FMOiDtjIzsnbwg7Iqk7Yq466a87J2EIOymieyLnCBjb25zdW1l7ZW07JW8IOuLpOydjCBwYXJ066GcIOuEmOyWtOqwiCDsiJgg7J6I7J2MXG4gICAgICAgICAgICAgICAgICAvLyDsnbQg7Zi47Lac7J20IOyXhuycvOuptCDsooXsooUgbXVsdGlwYXJ0IO2MjOyLseydtCBwZW5kaW5nIOyDge2DnOuhnCDtg4DsnoTslYTsm4Mg67Cc7IOdXG4gICAgICAgICAgICAgICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCBwYXJ0LnRvQnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgICBmaWxlcy5idWZmZXJlZEZpbGVzLnB1c2gobmV3IEJ1ZmZlcmVkRmlsZShwYXJ0LCBidWZmZXIpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJmaWVsZFwiKSB7XG4gICAgICAgICAgICAgICAgICBmaWVsZHNbcGFydC5maWVsZG5hbWVdID0gU3RyaW5nKHBhcnQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChhcGkudXBsb2FkT3B0aW9ucy5jb25zdW1lID09PSBcInN0cmVhbVwiKSB7XG4gICAgICAgICAgICAgIC8vIFN0cmVhbSDrqqjrk5w6IOymieyLnCDsoIDsnqXshozroZwg7Iqk7Yq466as67CNXG4gICAgICAgICAgICAgIGNvbnN0IGRpc2tOYW1lID0gYXBpLnVwbG9hZE9wdGlvbnMuZGVzdGluYXRpb247XG4gICAgICAgICAgICAgIGNvbnN0IGRpc2sgPSB0aGlzLnN0b3JhZ2UudXNlKGRpc2tOYW1lKTtcblxuICAgICAgICAgICAgICAvLyDsmrDshKDsiJzsnIQ6IOuNsOy9lOugiOydtO2EsCA+IOyghOyXrSDshKTsoJUgPiDquLDrs7jqsJJcbiAgICAgICAgICAgICAgY29uc3Qga2V5R2VuZXJhdG9yOiBLZXlHZW5lcmF0b3IgPVxuICAgICAgICAgICAgICAgIGFwaS51cGxvYWRPcHRpb25zLmtleUdlbmVyYXRvciA/P1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLnNlcnZlci5zdG9yYWdlPy5rZXlHZW5lcmF0b3IgPz9cbiAgICAgICAgICAgICAgICBkZWZhdWx0S2V5R2VuZXJhdG9yO1xuXG4gICAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09IFwiZmlsZVwiKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBrZXlHZW5lcmF0b3Ioe1xuICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogcGFydC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbWltZXR5cGU6IHBhcnQubWltZXR5cGUsXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgYXdhaXQgZGlzay5wdXRTdHJlYW0oa2V5LCBwYXJ0LmZpbGUsIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGU6IHBhcnQubWltZXR5cGUsXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgY29uc3QgdXJsID0gYXdhaXQgZGlzay5nZXRVcmwoa2V5KTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHNpZ25lZFVybCA9IGF3YWl0IGRpc2suZ2V0U2lnbmVkVXJsKGtleSk7XG5cbiAgICAgICAgICAgICAgICAgIGZpbGVzLnVwbG9hZGVkRmlsZXMucHVzaChcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVwbG9hZGVkRmlsZSh7XG4gICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgbWltZXR5cGU6IHBhcnQubWltZXR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgc2l6ZTogcGFydC5maWxlLmJ5dGVzUmVhZCxcbiAgICAgICAgICAgICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgc2lnbmVkVXJsLFxuICAgICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICBkaXNrTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcImZpZWxkXCIpIHtcbiAgICAgICAgICAgICAgICAgIGZpZWxkc1twYXJ0LmZpZWxkbmFtZV0gPSBTdHJpbmcocGFydC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHFz66GcIOykkeyyqSDqtazsobAg7YyM7IuxOiBwYXJhbXNbY2F0ZWdvcnldIOKGkiB7IHBhcmFtczogeyBjYXRlZ29yeTogXCJ0ZXN0XCIgfSB9XG4gICAgICAgICAgICBjb25zdCBxcyA9IGF3YWl0IGltcG9ydChcInFzXCIpO1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gcXMuZGVmYXVsdC5wYXJzZShmaWVsZHMpO1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihib2R5LCBwYXJzZWQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHsgZmFzdGlmeUNhc3RlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi9jYXN0ZXJcIik7XG4gICAgICAgICAgcmVxQm9keSA9IGZhc3RpZnlDYXN0ZXIoUmVxVHlwZSkucGFyc2UoYm9keSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zdCB7IFpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCJ6b2RcIik7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBab2RFcnJvcikge1xuICAgICAgICAgICAgY29uc3QgeyBodW1hbml6ZVpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy96b2QtZXJyb3JcIik7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGh1bWFuaXplWm9kRXJyb3IoZSlcbiAgICAgICAgICAgICAgLm1hcCgoaXNzdWUpID0+IGlzc3VlLm1lc3NhZ2UpXG4gICAgICAgICAgICAgIC5qb2luKFwiIFwiKTtcbiAgICAgICAgICAgIGNvbnN0IHsgQmFkUmVxdWVzdEV4Y2VwdGlvbiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCIpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24obWVzc2FnZXMgYXMgTG9jYWxpemVkU3RyaW5nLCB7XG4gICAgICAgICAgICAgIHpvZEVycm9yOiBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29udGVudC1UeXBlXG4gICAgICAgIHJlcGx5LnR5cGUoYXBpLm9wdGlvbnMuY29udGVudFR5cGUgPz8gXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xuXG4gICAgICAgIC8vIENhY2hlLUNvbnRyb2wg7Zek642UIOyEpOyglVxuICAgICAgICBjb25zdCBhcGlDYWNoZUNvbmZpZyA9IHRoaXMuZ2V0QXBpQ2FjaGVDb250cm9sKGFwaSwgcmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKGFwaUNhY2hlQ29uZmlnKSB7XG4gICAgICAgICAgYXBwbHlDYWNoZUhlYWRlcnMocmVwbHksIGFwaUNhY2hlQ29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOyXheuhnOuTnCDsmLXshZjsnbQg7J6I64qUIOqyveyasCDtjIzsnbwg642w7J207YSw66W8IENvbnRleHTsl5Ag7LaU6rCAXG4gICAgICAgIGlmIChhcGkudXBsb2FkT3B0aW9ucykge1xuICAgICAgICAgIGNvbnN0IGNvbnN1bWUgPSBhcGkudXBsb2FkT3B0aW9ucy5jb25zdW1lID8/IFwiYnVmZmVyXCI7XG4gICAgICAgICAgaWYgKGNvbnN1bWUgPT09IFwiYnVmZmVyXCIpIHtcbiAgICAgICAgICAgIGNvbnRleHQuYnVmZmVyZWRGaWxlcyA9IGZpbGVzLmJ1ZmZlcmVkRmlsZXM7XG4gICAgICAgICAgfSBlbHNlIGlmIChjb25zdW1lID09PSBcInN0cmVhbVwiKSB7XG4gICAgICAgICAgICBjb250ZXh0LnVwbG9hZGVkRmlsZXMgPSBmaWxlcy51cGxvYWRlZEZpbGVzO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOuqqOuNuCDrqZTshozrk5wgYXJncyDsg53shLHtlZjsl6wg7Zi47LacXG4gICAgICAgIGNvbnN0IHsgQXBpUGFyYW1UeXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90eXBlcy90eXBlc1wiKTtcbiAgICAgICAgY29uc3QgYXJncyA9IGFwaS5wYXJhbWV0ZXJzLm1hcCgocGFyYW0pID0+IHtcbiAgICAgICAgICAvLyBDb250ZXh0IOyduOygneyFmFxuICAgICAgICAgIGlmIChBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHJlcUJvZHlbcGFyYW0ubmFtZV07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MsIHJlcGx5KTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cblxuICAvLyBXUyBwYXRo66W8IOydvOuwmCBIVFRQIEdFVOycvOuhnCDtmLjstpztlZwg6rK97JqwIDQyNiArIFVwZ3JhZGUg7Zek642U66GcIOuqheyLnOyggeycvOuhnCB3ZWJzb2NrZXQg7KCR7IaN7J2EIOycoOuPhO2VqFxuICBwcml2YXRlIGNyZWF0ZVdlYlNvY2tldFVwZ3JhZGVSZXF1aXJlZEhhbmRsZXIoKSB7XG4gICAgcmV0dXJuIGFzeW5jIChfcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIHJlcGx5LmhlYWRlcihcImNvbm5lY3Rpb25cIiwgXCJVcGdyYWRlXCIpLmhlYWRlcihcInVwZ3JhZGVcIiwgXCJ3ZWJzb2NrZXRcIikuc3RhdHVzKDQyNikuc2VuZCh7XG4gICAgICAgIG1lc3NhZ2U6IFwiV2ViU29ja2V0IHVwZ3JhZGUgcmVxdWlyZWRcIixcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cblxuICAvLyBkZXYg66qo65Oc7J2YIGNhdGNoLWFsbCB3c0hhbmRsZXLsl5DshJwg7Iuk7KCcIFdTIEFQSeuhnCDrlJTsiqTtjKjsuZjtlaguIOunpOy5reuQmOuKlCByb3V0ZeqwgCDsl4bsnLzrqbQgMTAwOOuhnCDri6vsnYxcbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVEZXZXZWJTb2NrZXRSZXF1ZXN0KFxuICAgIHNvY2tldDogV2ViU29ja2V0LFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbWF0Y2hlZEFwaSA9IHRoaXMuZmluZE1hdGNoZWRBcGkocmVxdWVzdCk7XG4gICAgaWYgKCFtYXRjaGVkQXBpPy53ZWJzb2NrZXRPcHRpb25zKSB7XG4gICAgICBzb2NrZXQuY2xvc2UoMTAwOCwgXCJXZWJTb2NrZXQgcm91dGUgbm90IGZvdW5kXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmNyZWF0ZVdlYlNvY2tldEhhbmRsZXIobWF0Y2hlZEFwaSwgY29uZmlnKTtcbiAgICBhd2FpdCBoYW5kbGVyKHsgc29ja2V0IH0sIHJlcXVlc3QpO1xuICB9XG5cbiAgLy8gV1Mgcm91dGUg7ZW465Ok65+s7J2YIOyLpO2WiSDsiJzshJzrpbwg6rOg7KCV7ZWoOlxuICAvLyAxKSBndWFyZOulvCBjb25uZWN0aW9uIOuTseuhnSDsnbTsoITsl5Ag64+M66CkIOyduOymnSDsi6TtjKgg7IucIOu2gOu2hCDrk7HroZ0g7IOB7YOc66W8IOuCqOq4sOyngCDslYrsnYxcbiAgLy8gMikgcXVlcnkgcGFyYW0g7YyM7Iux64+EIGFjdGl2YXRpb24g7KCE7JeQIOuBneuCtCBoYW5kc2hha2Ug7Iuk7Yyo6rCAIHJlZ2lzdHJ57JeQIOuFuOy2nOuQmOyngCDslYrqsowg7ZWoXG4gIC8vIDMpIGBhY3RpdmU6IGZhbHNlYOuhnCDrqLzsoIAg65Ox66Gd7ZWY6rOgLCBjb250ZXh0IOykgOu5hOqwgCDrgZ3rgpwg65KkIGBhY3RpdmF0ZSgpYO2VtCDruIzroZzrk5zsupDsiqTtirjqsIAg7LSI6riw7ZmUIOykkeqwhCDsg4Htg5zrpbwg67O07KeAIOuqu+2VmOqyjCDtlahcbiAgLy8g7JeQ65+sIOuwnOyDnSDsi5zsl5DripQgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvciDsoJXssYXsl5Ag65Sw6528IGNsb3NlIGNvZGXrpbwg66ek7ZWR7ZWoXG4gIHByaXZhdGUgY3JlYXRlV2ViU29ja2V0SGFuZGxlcihhcGk6IEV4dGVuZGVkQXBpLCBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcpIHtcbiAgICByZXR1cm4gYXN5bmMgKFxuICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICBzb2NrZXQ6IFdlYlNvY2tldDtcbiAgICAgIH0sXG4gICAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGNvbnN0IHNvY2tldCA9IGNvbm5lY3Rpb24uc29ja2V0O1xuICAgICAgbGV0IHdzQ29udGV4dDogV2ViU29ja2V0Q29udGV4dCB8IG51bGwgPSBudWxsO1xuICAgICAgbGV0IHJhd1dzOiBSZXR1cm5UeXBlPFdlYlNvY2tldFJ1bnRpbWVbXCJyZWdpc3RlckNvbm5lY3Rpb25cIl0+IHwgbnVsbCA9IG51bGw7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJ1bkd1YXJkcyh7XG4gICAgICAgICAgZ3VhcmRzOiBhcGkub3B0aW9ucy5ndWFyZHMsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgYXBpLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXFCb2R5ID0gYXdhaXQgdGhpcy5wYXJzZVdlYlNvY2tldFJlcXVlc3RQYXJhbXMoYXBpLCByZXF1ZXN0KTtcbiAgICAgICAgcmF3V3MgPSB0aGlzLndlYnNvY2tldFJ1bnRpbWUucmVnaXN0ZXJDb25uZWN0aW9uKHNvY2tldCwge1xuICAgICAgICAgIG91dEV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLm91dEV2ZW50cyxcbiAgICAgICAgICBpbkV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLmluRXZlbnRzLFxuICAgICAgICAgIG5hbWVzcGFjZTogYXBpLndlYnNvY2tldE9wdGlvbnMhLm5hbWVzcGFjZSxcbiAgICAgICAgICBoZWFydGJlYXQ6IGFwaS53ZWJzb2NrZXRPcHRpb25zIS5oZWFydGJlYXQsXG4gICAgICAgICAgbWF4UGF5bG9hZDogYXBpLndlYnNvY2tldE9wdGlvbnMhLm1heFBheWxvYWQsXG4gICAgICAgICAgYWN0aXZlOiBmYWxzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2NvcGVkV3MgPSB0aGlzLmNyZWF0ZVNjb3BlZFdlYlNvY2tldENvbm5lY3Rpb24ocmF3V3MsICgpID0+IHdzQ29udGV4dCk7XG4gICAgICAgIHdzQ29udGV4dCA9IGF3YWl0IHRoaXMuY3JlYXRlV2ViU29ja2V0Q29udGV4dChjb25maWcsIHJlcXVlc3QsIHNjb3BlZFdzKTtcbiAgICAgICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lLmFjdGl2YXRlQ29ubmVjdGlvbihyYXdXcy5pZCk7XG5cbiAgICAgICAgY29uc3QgeyBBcGlQYXJhbVR5cGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpO1xuICAgICAgICBjb25zdCBhcmdzID0gYXBpLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICAgIGlmIChBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gd3NDb250ZXh0O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiByZXFCb2R5W3BhcmFtLm5hbWVdO1xuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQ6IHdzQ29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnN0IGNsb3NlRGVzY3JpcHRvciA9IHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3IoZXJyb3IpO1xuICAgICAgICBpZiAocmF3V3MpIHtcbiAgICAgICAgICByYXdXcy5jbG9zZShjbG9zZURlc2NyaXB0b3IuY29kZSwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgIH0gZWxzZSBpZiAoc29ja2V0LnJlYWR5U3RhdGUgPCAyKSB7XG4gICAgICAgICAgc29ja2V0LmNsb3NlKGNsb3NlRGVzY3JpcHRvci5jb2RlLCBjbG9zZURlc2NyaXB0b3IucmVhc29uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNlcnZlcj8ubG9nKSB7XG4gICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGVycjogZXJyb3IsXG4gICAgICAgICAgICBtb2RlbE5hbWU6IGFwaS5tb2RlbE5hbWUsXG4gICAgICAgICAgICBtZXRob2ROYW1lOiBhcGkubWV0aG9kTmFtZSxcbiAgICAgICAgICAgIHBhdGg6IGFwaS5wYXRoLFxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKGNsb3NlRGVzY3JpcHRvci5sb2dMZXZlbCA9PT0gXCJ3YXJuXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmxvZy53YXJuKHBheWxvYWQsIGNsb3NlRGVzY3JpcHRvci5yZWFzb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlcnZlci5sb2cuZXJyb3IocGF5bG9hZCwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjbG9zZURlc2NyaXB0b3IubG9nTGV2ZWwgPT09IFwid2FyblwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oY2xvc2VEZXNjcmlwdG9yLnJlYXNvbiwgZXJyb3IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGNsb3NlRGVzY3JpcHRvci5yZWFzb24sIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gb25NZXNzYWdlL29uQ2xvc2Xsspjrn7wg64uk66W4IHRpY2vsl5DshJwg7Iuk7ZaJ65CY64qUIGNhbGxiYWNr7J2AIEFMUyBjb250ZXh06rCAIOuBiuq4sOuvgOuhnCB3cmFwcGVy7JeQ7IScIGBhc3luY0xvY2FsU3RvcmFnZS5ydW5g7Jy866GcIOuLpOyLnCDqsJDsi7gg67O17JuQ7ZWoXG4gIC8vIHB1Ymxpc2gvam9pbi9sZWF2ZS9zZXRVc2VySWQg6rCZ7J2AIOymieyLnCDsi6TtlokgQVBJ64qUIOuLqOyInCDsnITsnoTrp4wg7ZWY6rOgLCBkZWZlcnJlZCBjYWxsYmFja+yXkOunjCBjb250ZXh0IOuzteybkOydhCDsoIHsmqntlahcbiAgcHJpdmF0ZSBjcmVhdGVTY29wZWRXZWJTb2NrZXRDb25uZWN0aW9uPFxuICAgIFRPdXQgZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgICBUSW4gZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgPihcbiAgICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxUT3V0LCBUSW4+LFxuICAgIGdldENvbnRleHQ6ICgpID0+IFdlYlNvY2tldENvbnRleHQgfCBudWxsLFxuICApOiBXZWJTb2NrZXRDb25uZWN0aW9uPFRPdXQsIFRJbj4ge1xuICAgIGNvbnN0IHJ1bkluQ29udGV4dCA9IDxUPihjYWxsYmFjazogKCkgPT4gVCk6IFQgPT4ge1xuICAgICAgY29uc3QgY29udGV4dCA9IGdldENvbnRleHQoKTtcbiAgICAgIGlmICghY29udGV4dCkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBnZXQgaWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5pZDtcbiAgICAgIH0sXG4gICAgICBnZXQgbmFtZXNwYWNlKCkge1xuICAgICAgICByZXR1cm4gd3MubmFtZXNwYWNlO1xuICAgICAgfSxcbiAgICAgIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5jbG9zZWQ7XG4gICAgICB9LFxuICAgICAgdHJhbnNwb3J0OiBcIndzXCIsXG4gICAgICBwdWJsaXNoVW50eXBlZChldmVudCwgZGF0YSkge1xuICAgICAgICB3cy5wdWJsaXNoVW50eXBlZChldmVudCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgY2xvc2UoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICB9LFxuICAgICAgb25DbG9zZShjYWxsYmFjaykge1xuICAgICAgICB3cy5vbkNsb3NlKCgpID0+IHJ1bkluQ29udGV4dChjYWxsYmFjaykpO1xuICAgICAgfSxcbiAgICAgIG9uTWVzc2FnZShldmVudCwgaGFuZGxlcikge1xuICAgICAgICB3cy5vbk1lc3NhZ2UoZXZlbnQsIChkYXRhKSA9PiBydW5JbkNvbnRleHQoKCkgPT4gaGFuZGxlcihkYXRhKSkpO1xuICAgICAgfSxcbiAgICAgIHB1Ymxpc2goZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgd3MucHVibGlzaChldmVudCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgd2FpdEZvckNsb3NlKCkge1xuICAgICAgICByZXR1cm4gd3Mud2FpdEZvckNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgam9pbihyb29tSWQpIHtcbiAgICAgICAgd3Muam9pbihyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIGxlYXZlKHJvb21JZCkge1xuICAgICAgICB3cy5sZWF2ZShyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIHNldFVzZXJJZCh1c2VySWQpIHtcbiAgICAgICAgd3Muc2V0VXNlcklkKHVzZXJJZCk7XG4gICAgICB9LFxuICAgICAgY2xlYXJVc2VySWQoKSB7XG4gICAgICAgIHdzLmNsZWFyVXNlcklkKCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBhcnNlV2ViU29ja2V0UmVxdWVzdFBhcmFtcyhcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgY29uc3QgeyBnZXRab2RPYmplY3RGcm9tQXBpIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvZGUtY29udmVydGVyc1wiKTtcbiAgICBjb25zdCBSZXFUeXBlID0gZ2V0Wm9kT2JqZWN0RnJvbUFwaShhcGksIHRoaXMuc3luY2VyLnR5cGVzKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZhc3RpZnlDYXN0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4vY2FzdGVyXCIpO1xuICAgICAgcmV0dXJuIGZhc3RpZnlDYXN0ZXIoUmVxVHlwZSkucGFyc2UoKHJlcXVlc3QucXVlcnkgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCB7IFpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCJ6b2RcIik7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIFpvZEVycm9yKSB7XG4gICAgICAgIGNvbnN0IHsgaHVtYW5pemVab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvem9kLWVycm9yXCIpO1xuICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGh1bWFuaXplWm9kRXJyb3IoZSlcbiAgICAgICAgICAubWFwKChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSlcbiAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgIGNvbnN0IHsgQmFkUmVxdWVzdEV4Y2VwdGlvbiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCIpO1xuICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihtZXNzYWdlcyBhcyBMb2NhbGl6ZWRTdHJpbmcsIHtcbiAgICAgICAgICB6b2RFcnJvcjogZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVSTOyXkOyEnCBwYXRoIHBhcmFtc+ulvCDstpTstpztlanri4jri6QuXG4gICAqIOyYiDogcGF0dGVybj1cIi9hZG1pbi9jb21wYW5pZXMvOmNvbXBhbnlJZFwiLCB1cmw9XCIvYWRtaW4vY29tcGFuaWVzLzEyM1wiIOKGkiB7IGNvbXBhbnlJZDogXCIxMjNcIiB9XG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3RQYXRoUGFyYW1zKHBhdHRlcm46IHN0cmluZywgdXJsOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBwYXR0ZXJuUGFydHMgPSBwYXR0ZXJuLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgdXJsUGFydHMgPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybCh1cmwpLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHBhdHRlcm5QYXJ0c1tpXS5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICBwYXJhbXNbcGF0dGVyblBhcnRzW2ldLnNsaWNlKDEpXSA9IHVybFBhcnRzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1BhdGhQYXR0ZXJuTWF0Y2gocGF0dGVybjogc3RyaW5nLCB1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhdHRlcm5QYXJ0cyA9IHBhdHRlcm4uc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCB1cmxQYXJ0cyA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHVybCkuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcblxuICAgIGlmIChwYXR0ZXJuUGFydHMubGVuZ3RoICE9PSB1cmxQYXJ0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGF0dGVyblBhcnQgPSBwYXR0ZXJuUGFydHNbaV07XG4gICAgICBjb25zdCB1cmxQYXJ0ID0gdXJsUGFydHNbaV07XG4gICAgICBpZiAocGF0dGVyblBhcnQuc3RhcnRzV2l0aChcIjpcIikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocGF0dGVyblBhcnQgIT09IHVybFBhcnQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYXRobmFtZUZyb21VcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB1cmwuc3BsaXQoXCI/XCIpWzBdO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYmFzZURpcjogc3RyaW5nLCBpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlVVJJQ29tcG9uZW50KGlucHV0UGF0aCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG4gICAgICBpZiAoZGVjb2RlZC5pbmNsdWRlcyhcIlxcMFwiKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGRlY29kZWQucmVwbGFjZSgvXlxcLysvLCBcIlwiKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IHBhdGgucmVzb2x2ZShiYXNlRGlyLCByZWxhdGl2ZVBhdGgpO1xuICAgICAgY29uc3QgcmVsYXRpdmVGcm9tQmFzZSA9IHBhdGgucmVsYXRpdmUoYmFzZURpciwgcmVzb2x2ZWRQYXRoKTtcbiAgICAgIGlmIChyZWxhdGl2ZUZyb21CYXNlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmVGcm9tQmFzZSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFQSSDsnZHri7Xsl5Ag7KCB7Jqp7ZWgIENhY2hlLUNvbnRyb2wg7ISk7KCV7J2EIOqysOygle2VqeuLiOuLpC5cbiAgICog7Jqw7ISg7Iic7JyEOiDqsJzrs4Qg7KeA7KCVID4gY2FjaGVDb250cm9sSGFuZGxlclxuICAgKi9cbiAgcHJpdmF0ZSBnZXRBcGlDYWNoZUNvbnRyb2woXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICkge1xuICAgIC8vIOuNsOy9lOugiOydtO2EsCDshKTsoJUg7Jqw7ISgXG4gICAgaWYgKGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbCkge1xuICAgICAgcmV0dXJuIGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbDtcbiAgICB9XG5cbiAgICAvLyDsoITsl60g7ZW465Ok65+sXG4gICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICBjb25zdCBjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgdHlwZTogXCJhcGlcIixcbiAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgcGF0aDogcmVxdWVzdC5yb3V0ZU9wdGlvbnM/LnVybCA/PyByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgIGFwaSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNTUuyaqSBBUEkg7Zi47LacIChIVFRQIOyYpOuyhO2XpOuTnCDsl4bsnbQg7KeB7KCRIO2YuOy2nClcbiAgICogY3JlYXRlQXBpSGFuZGxlcuydmCDroZzsp4HsnYQg7J6s7IKs7Jqp7ZWY65CYLCByZXF1ZXN0IO2MjOyLsSDrjIDsi6AgcGFyYW1zIOyngeygkSDsgqzsmqlcbiAgICovXG4gIGFzeW5jIGludm9rZUFwaUZvclNTUihcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHBhcmFtczogYW55W10sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHJlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIC8vIENvbnRleHQg7IOd7ISxICjquLDsobQg66mU7IaM65OcIOyerOyCrOyaqSlcbiAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBhcmdzIOyDneyEsTogQ29udGV4dCDtjIzrnbzrr7jthLDripQg7KO87J6FLCDrgpjrqLjsp4DripQgcGFyYW1z7JeQ7IScIOqwgOyguOyYpOq4sFxuICAgICAgY29uc3QgeyBBcGlQYXJhbVR5cGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpO1xuICAgICAgbGV0IHBhcmFtc0luZGV4ID0gMDtcbiAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgIGlmIChBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcmFtc1twYXJhbXNJbmRleCsrXTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyDrqqjrjbgg66mU7ISc65OcIO2YuOy2nCAo6riw7KG0IOuplOyEnOuTnCDsnqzsgqzsmqkpXG4gICAgICByZXR1cm4gdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MsIHJlcGx5KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFdTIOqyveuhnOyXkOyEnOuKlCBIVFRQIHJlcGx56rCAIOyXhuycvOuvgOuhnCByZXBseeulvCBvcHRpb25hbOuhnCDrsJvslYQg6rO17Ya1IO2YuOy2nCDqsr3roZzrpbwg7Jyg7KeA7ZWoXG4gIGFzeW5jIGludm9rZU1vZGVsTWV0aG9kKFxuICAgIGFwaTogRXh0ZW5kZWRBcGksXG4gICAgYXJnczogdW5rbm93bltdLFxuICAgIHJlcGx5PzogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPHVua25vd24+IHtcbiAgICBjb25zdCBtb2RlbCA9IHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCAobW9kZWwgYXMgYW55KVthcGkubWV0aG9kTmFtZV0uYXBwbHkobW9kZWwsIGFyZ3MpO1xuICAgIHJlcGx5Py50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBjcmVhdGVDb250ZXh0KFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICByZXBseTogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPENvbnRleHQ+IHtcbiAgICAvLyBjcmVhdGVTU0VGYWN0b3J5IO2VqOyImOyXkCDrr7jrpqwgcmVxdWVzdOydmCBzb2NrZXTqs7wgcmVwbHnrpbwg67CU7J2465SpLlxuICAgIGNvbnN0IHsgY3JlYXRlU1NFRmFjdG9yeSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3RyZWFtL3NzZVwiKTtcbiAgICBjb25zdCBjcmVhdGVTU0UgPSAoPFQgZXh0ZW5kcyBab2RPYmplY3Q+KFxuICAgICAgX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgICAgX3JlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICAgICBfZXZlbnRzOiBULFxuICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQobnVsbCwgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgLy8gbG9jYWxlIOqwkOyngFxuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIC8vIGF1dGggY29udGV4dCDstpTqsIBcbiAgICBjb25zdCBoZWFkZXJzID0gY29udmVydEZhc3RpZnlIZWFkZXJzVG9TdGFuZGFyZChyZXF1ZXN0LmhlYWRlcnMpO1xuICAgIGNvbnN0IHNlc3Npb24gPSAoYXdhaXQgdGhpcy5fYXV0aD8uYXBpLmdldFNlc3Npb24oeyBoZWFkZXJzIH0pKSA/PyBudWxsO1xuXG4gICAgY29uc3QgY29udGV4dDogQ29udGV4dCA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShcbiAgICAgIGNvbmZpZy5jb250ZXh0UHJvdmlkZXIoXG4gICAgICAgIHtcbiAgICAgICAgICB0cmFuc3BvcnQ6IFwiaHR0cFwiLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgcmVwbHksXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwKCksXG4gICAgICAgICAgbG9jYWxlLFxuICAgICAgICAgIC8vIGF1dGhcbiAgICAgICAgICB1c2VyOiBzZXNzaW9uPy51c2VyID8/IG51bGwsXG4gICAgICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICByZXBseSxcbiAgICAgICksXG4gICAgKTtcbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxuXG4gIC8vIHNlc3Npb24vbG9jYWxlL3N0b3JlIOqwmeydgCDqs7XthrUgc3RhdGXripQgSFRUUCBjb250ZXh07JmAIOqzteycoO2VmOuQmCwgcmVwbHkvY3JlYXRlU1NFIOqwmeydgCBIVFRQIOyghOyaqSBoZWxwZXLripQg64W47Lac7ZWY7KeAIOyViuydjFxuICAvLyDsgqzsmqnsnpDqsIAgd2Vic29ja2V0Q29udGV4dFByb3ZpZGVy66W8IOyjvOuptCDqt7jrjIDroZwg7JyE7J6E7ZWY6rOgLCDsl4bsnLzrqbQg6riw7KG0IGNvbnRleHRQcm92aWRlcuulvCByZXBseS9TU0Ugc3R1YuqzvCDtlajqu5gg7J6s7Zmc7Jqp7ZWoXG4gIGFzeW5jIGNyZWF0ZVdlYlNvY2tldENvbnRleHQoXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHdzOiBXZWJTb2NrZXRDb250ZXh0W1wid3NcIl0sXG4gICk6IFByb21pc2U8V2ViU29ja2V0Q29udGV4dD4ge1xuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIGNvbnN0IGhlYWRlcnMgPSBjb252ZXJ0RmFzdGlmeUhlYWRlcnNUb1N0YW5kYXJkKHJlcXVlc3QuaGVhZGVycyk7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IChhd2FpdCB0aGlzLl9hdXRoPy5hcGkuZ2V0U2Vzc2lvbih7IGhlYWRlcnMgfSkpID8/IG51bGw7XG5cbiAgICBjb25zdCBkZWZhdWx0Q29udGV4dCA9IHtcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiIGFzIGNvbnN0LFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcCgpLFxuICAgICAgbG9jYWxlLFxuICAgICAgdXNlcjogc2Vzc2lvbj8udXNlciA/PyBudWxsLFxuICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgIH07XG5cbiAgICBpZiAoY29uZmlnLndlYnNvY2tldENvbnRleHRQcm92aWRlcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGF3YWl0IFByb21pc2UucmVzb2x2ZShjb25maWcud2Vic29ja2V0Q29udGV4dFByb3ZpZGVyKGRlZmF1bHRDb250ZXh0LCByZXF1ZXN0KSkpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyByZXBseS9jcmVhdGVTU0Xsl5Ag7J2Y7KG07ZWY64qUIGNvbnRleHRQcm92aWRlcuqwgCDsnojsnLzrqbQg7KaJ7IucIOyXkOufrOulvCDrjZjsoLggdHJhbnNwb3J0IG1pc3VzZeulvCDruajrpqwg65Oc65+s64OEXG4gICAgY29uc3QgcmVwbHlTdHViID0gY3JlYXRlV2ViU29ja2V0UmVwbHlTdHViKCk7XG4gICAgY29uc3QgY3JlYXRlU1NFID0gPFQgZXh0ZW5kcyBab2RPYmplY3Q+KF9ldmVudHM6IFQpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJjcmVhdGVTU0UgaXMgbm90IGF2YWlsYWJsZSBpbiB3ZWJzb2NrZXQgY29udGV4dC4gRGVmaW5lIHdlYnNvY2tldENvbnRleHRQcm92aWRlciBpZiB5b3VyIGNvbnRleHQgc2V0dXAgZGVwZW5kcyBvbiBTU0UgaGVscGVycy5cIixcbiAgICAgICk7XG4gICAgfTtcbiAgICBjb25zdCBodHRwTGlrZUNvbnRleHQgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoXG4gICAgICBjb25maWcuY29udGV4dFByb3ZpZGVyKFxuICAgICAgICB7XG4gICAgICAgICAgdHJhbnNwb3J0OiBcImh0dHBcIixcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIHJlcGx5OiByZXBseVN0dWIsXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBkZWZhdWx0Q29udGV4dC5uYWl0ZVN0b3JlLFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICB1c2VyOiBkZWZhdWx0Q29udGV4dC51c2VyLFxuICAgICAgICAgIHNlc3Npb246IGRlZmF1bHRDb250ZXh0LnNlc3Npb24sXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIHJlcGx5U3R1YixcbiAgICAgICksXG4gICAgKTtcblxuICAgIGNvbnN0IHtcbiAgICAgIHRyYW5zcG9ydDogX3RyYW5zcG9ydCxcbiAgICAgIHJlcGx5OiBfcmVwbHksXG4gICAgICBjcmVhdGVTU0U6IF9jcmVhdGVTU0UsXG4gICAgICBidWZmZXJlZEZpbGVzOiBfYnVmZmVyZWRGaWxlcyxcbiAgICAgIHVwbG9hZGVkRmlsZXM6IF91cGxvYWRlZEZpbGVzLFxuICAgICAgLi4ucmVzdFxuICAgIH0gPSBodHRwTGlrZUNvbnRleHQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ucmVzdCxcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiLFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQWNjZXB0LUxhbmd1YWdlIO2XpOuNlOyXkOyEnCDsp4Dsm5DtlZjripQgbG9jYWxl7J2EIOywvuyKteuLiOuLpC5cbiAgICogQGV4YW1wbGUgXCJrby1LUixrbztxPTAuOSxlbjtxPTAuOFwiIOKGkiBcImtvXCJcbiAgICovXG4gIHByaXZhdGUgZGV0ZWN0TG9jYWxlKFxuICAgIGFjY2VwdExhbmd1YWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgc3VwcG9ydGVkOiBzdHJpbmdbXSxcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWFjY2VwdExhbmd1YWdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgLy8gQWNjZXB0LUxhbmd1YWdlOiBrby1LUixrbztxPTAuOSxlbjtxPTAuOFxuICAgIGNvbnN0IGxhbmdzID0gYWNjZXB0TGFuZ3VhZ2Uuc3BsaXQoXCIsXCIpLm1hcCgobGFuZykgPT4ge1xuICAgICAgY29uc3QgW2NvZGVdID0gbGFuZy5zcGxpdChcIjtcIik7XG4gICAgICByZXR1cm4gY29kZS50cmltKCkuc3BsaXQoXCItXCIpWzBdOyAvLyBrby1LUiDihpIga29cbiAgICB9KTtcblxuICAgIHJldHVybiBsYW5ncy5maW5kKChsYW5nKSA9PiBzdXBwb3J0ZWQuaW5jbHVkZXMobGFuZykpO1xuICB9XG5cbiAgYXN5bmMgc3RhcnRXYXRjaGVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHdhdGNoZXIg66qo65OI7J2AIGZpbGUtcGF0dGVybnMg4oaSIFNvbmFtdSDsiJztmZjsnYQg7ZS87ZWY6riwIOychO2VtCBkeW5hbWljIGltcG9ydCDtlanri4jri6QuXG4gICAgY29uc3QgeyBzZXR1cFdhdGNoZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N5bmNlci93YXRjaGVyXCIpO1xuICAgIHRoaXMud2F0Y2hlciA9IGF3YWl0IHNldHVwV2F0Y2hlcigoZmlsZUV2ZW50cykgPT4gdGhpcy5ydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhdGNoZXLqsIAgMTAwbXMgYmF0Y2jroZwg66qo7J2AIGZpbGVFdmVudHMg7ZWY64KY7JeQIOuMgO2VtCDtlZwg67KI7J2YIEhNUi9zeW5jIOyCrOydtO2BtOydhCDrj5Xri4jri6QuXG4gICAqIGJhdGNoIO2BkOyeiSDrjZXsl5Ag7ZWcIOyLnOygkOyXkCDtlZjrgpjrp4wg7Iuk7ZaJ65Co7J20IOuztOyepeuQqeuLiOuLpCAoZXZlbnQtYmF0Y2hlcuqwgCDsp4HroKztmZQpLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50czogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBldmVudF0gb2YgZmlsZUV2ZW50cykge1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLmFwcFJvb3RQYXRoLCBmaWxlUGF0aCk7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5ib2xkKGBEZXRlY3RlZCgke2V2ZW50fSk6ICR7Y2hhbGsuYmx1ZShyZWxhdGl2ZVBhdGgpfWApKTtcbiAgICB9XG5cbiAgICAvLyDrs7jssrQ6IOuzgOqyvSDtnaHsiJggKyDssrTtgazshKwg6rCx7IugLlxuICAgIGF3YWl0IHRoaXMuc3luY2VyLmhtckFuZFN5bmMoZmlsZUV2ZW50cyk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIucmVuZXdDaGVja3N1bXMoKTtcblxuICAgIGNvbnN0IHRvdGFsVGltZSA9IERhdGUubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgY29uc3QgbXNnID0gYEhNUiBEb25lISAke2NoYWxrLmJvbGQud2hpdGUoYCR7dG90YWxUaW1lfW1zYCl9YDtcbiAgICBjb25zb2xlLmxvZyhjaGFsay5ibGFjay5iZ0dyZWVuKGNlbnRlclRleHQobXNnKSkpO1xuICB9XG5cbiAgLypcbiAgICAgQSBmdW5jdGlvbiB0aGF0IGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbml0IGFuZCBkZXN0cm95IHdoZW4gdXNpbmcgU29uYW11IHZpYSBzY3JpcHRzLlxuICAqL1xuICBhc3luYyBydW5TY3JpcHQoZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmbigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSwgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl0pIHtcbiAgICBpZiAoIXBsdWdpbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjb21wcmVzcyDtlIzrn6zqt7jsnbjsnYAg64uk66W4IO2UjOufrOq3uOyduOuztOuLpCDrqLzsoIAg65Ox66Gd65CY7Ja07JW8IO2VqeuLiOuLpC5cbiAgICBpZiAocGx1Z2lucy5jb21wcmVzcykge1xuICAgICAgY29uc3QgY29tcHJlc3NQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvY29tcHJlc3NcIikpLmRlZmF1bHQ7XG4gICAgICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgICAgdGhyZXNob2xkOiAxMDI0LFxuICAgICAgICBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gYXMgKFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJkZWZsYXRlXCIpW10sXG4gICAgICB9O1xuXG4gICAgICBpZiAocGx1Z2lucy5jb21wcmVzcyA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoY29tcHJlc3NQbHVnaW4sIGRlZmF1bHRPcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlcnZlci5yZWdpc3Rlcihjb21wcmVzc1BsdWdpbiwge1xuICAgICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICAgIC4uLnBsdWdpbnMuY29tcHJlc3MsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpbnNNb2R1bGVzID0ge1xuICAgICAgY29yczogXCJAZmFzdGlmeS9jb3JzXCIsXG4gICAgICBmb3JtYm9keTogXCJAZmFzdGlmeS9mb3JtYm9keVwiLFxuICAgICAgbXVsdGlwYXJ0OiBcIkBmYXN0aWZ5L211bHRpcGFydFwiLFxuICAgICAgcXM6IFwiZmFzdGlmeS1xc1wiLFxuICAgICAgc3NlOiBcImZhc3RpZnktc3NlLXYyXCIsXG4gICAgICBzdGF0aWM6IFwiQGZhc3RpZnkvc3RhdGljXCIsXG4gICAgfSBhcyBjb25zdDtcblxuICAgIGNvbnN0IHJlZ2lzdGVyUGx1Z2luID0gYXN5bmMgPEsgZXh0ZW5kcyBrZXlvZiBOb25OdWxsYWJsZTx0eXBlb2YgcGx1Z2lucz4+KFxuICAgICAga2V5OiBLLFxuICAgICAgcGx1Z2luTmFtZTogc3RyaW5nLFxuICAgICkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uID0gcGx1Z2luc1trZXldO1xuICAgICAgaWYgKCFvcHRpb24pIHJldHVybjtcblxuICAgICAgaWYgKG9wdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCwgb3B0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBwbHVnaW5OYW1lXSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykpIHtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyUGx1Z2luKGtleSBhcyBrZXlvZiB0eXBlb2YgcGx1Z2lucywgcGx1Z2luTmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMud3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViU29ja2V0UGx1Z2luKHNlcnZlcik7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMuY3VzdG9tKSB7XG4gICAgICBwbHVnaW5zLmN1c3RvbShzZXJ2ZXIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEBmYXN0aWZ5L3dlYnNvY2tldOydgCBwbHVnaW5zLndz6rCAIOyEpOygleuQnCDqsr3smrDsl5Drp4wg65Ox66Gd7ZWY6rOgLCDqsJnsnYAgc2VydmVy7JeQIOykkeuztSDrk7HroZ3rkJjsp4Ag7JWK64+E66GdIFdlYWtTZXTsnLzroZwg6riw66Gd7ZWoXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlV2ViU29ja2V0UGx1Z2luKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLndlYnNvY2tldFBsdWdpblNlcnZlcnMuaGFzKHNlcnZlcikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwbHVnaW5PcHRpb24gPSB0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8ud3M7XG4gICAgaWYgKCFwbHVnaW5PcHRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB3ZWJzb2NrZXRQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvd2Vic29ja2V0XCIpKS5kZWZhdWx0O1xuICAgIGNvbnN0IHJlc29sdmVkUGx1Z2luT3B0aW9ucyA9IHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zKHtcbiAgICAgIHJhd1BsdWdpbk9wdGlvbjogcGx1Z2luT3B0aW9uLFxuICAgICAgYXBpczogdGhpcy5zeW5jZXIuYXBpcyxcbiAgICB9KTtcbiAgICBpZiAocmVzb2x2ZWRQbHVnaW5PcHRpb25zKSB7XG4gICAgICBhd2FpdCBzZXJ2ZXIucmVnaXN0ZXIod2Vic29ja2V0UGx1Z2luLCByZXNvbHZlZFBsdWdpbk9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBzZXJ2ZXIucmVnaXN0ZXIod2Vic29ja2V0UGx1Z2luKTtcbiAgICB9XG5cbiAgICB0aGlzLndlYnNvY2tldFBsdWdpblNlcnZlcnMuYWRkKHNlcnZlcik7XG4gICAgdGhpcy53YXJuT25Qb3RlbnRpYWxXZWJTb2NrZXRUaW1lb3V0Q29uZmxpY3RzKHNlcnZlcik7XG4gIH1cblxuICAvLyBoZWFydGJlYXQgaW50ZXJ2YWzsnbQgRmFzdGlmeSBrZWVwQWxpdmVUaW1lb3V0IOydtOyDgeydtOuptCDsnbjtlITrnbzqsIAg66i87KCAIGlkbGUg7Jew6rKw7J2EIOuBiuydhCDsiJgg7J6I7Ja0IOqyveqzoOunjCDrgqjquLDqs6Ag64SY7Ja06rCQXG4gIHByaXZhdGUgd2Fybk9uUG90ZW50aWFsV2ViU29ja2V0VGltZW91dENvbmZsaWN0cyhcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBoZWFydGJlYXRzID0gdGhpcy5zeW5jZXIuYXBpc1xuICAgICAgLm1hcCgoYXBpKSA9PiBhcGkud2Vic29ja2V0T3B0aW9ucz8uaGVhcnRiZWF0ID8/IDMwMDAwKVxuICAgICAgLmZpbHRlcigoaGVhcnRiZWF0KSA9PiBoZWFydGJlYXQgPiAwKTtcblxuICAgIGlmIChoZWFydGJlYXRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGtlZXBBbGl2ZVRpbWVvdXQgPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuZmFzdGlmeT8ua2VlcEFsaXZlVGltZW91dDtcbiAgICBpZiAoIWtlZXBBbGl2ZVRpbWVvdXQgfHwga2VlcEFsaXZlVGltZW91dCA8PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbGFyZ2VzdEhlYXJ0YmVhdCA9IE1hdGgubWF4KC4uLmhlYXJ0YmVhdHMpO1xuICAgIGlmIChsYXJnZXN0SGVhcnRiZWF0ID49IGtlZXBBbGl2ZVRpbWVvdXQpIHtcbiAgICAgIHNlcnZlci5sb2cud2FybihcbiAgICAgICAge1xuICAgICAgICAgIGtlZXBBbGl2ZVRpbWVvdXQsXG4gICAgICAgICAgbGFyZ2VzdEhlYXJ0YmVhdCxcbiAgICAgICAgfSxcbiAgICAgICAgXCJXZWJTb2NrZXQgaGVhcnRiZWF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBrZWVwQWxpdmVUaW1lb3V0OyBhbGlnbiBpbmZyYXN0cnVjdHVyZSBpZGxlIHRpbWVvdXRzIHRvIGF2b2lkIHVuZXhwZWN0ZWQgZGlzY29ubmVjdHMuXCIsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBiZXR0ZXItYXV0aCDrnbzsmrDtirjrpbwg65Ox66Gd7ZWp64uI64ukLlxuICAgKiAvYXBpL2F1dGgvKiDqsr3roZzroZwg7J247KadIEFQSeqwgCDsnpDrj5kg65Ox66Gd65Cp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckJldHRlckF1dGgoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsXG4gICAgb3B0aW9uczogTm9uTnVsbGFibGU8U29uYW11U2VydmVyT3B0aW9uc1tcImF1dGhcIl0+LFxuICApIHtcbiAgICBpZiAoIW9wdGlvbnMpIHJldHVybjtcblxuICAgIGNvbnN0IGJhc2VQYXRoID0gb3B0aW9ucy5iYXNlUGF0aCA/PyBcIi9hcGkvYXV0aFwiO1xuXG4gICAgLy8gYmV0dGVyLWF1dGgg65287Jqw7Yq4IOuTseuhnVxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkdFVFwiLCBcIlBPU1RcIl0sXG4gICAgICB1cmw6IGAke2Jhc2VQYXRofS8qYCxcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcXVlc3QudXJsLCBgaHR0cDovLyR7cmVxdWVzdC5oZWFkZXJzLmhvc3R9YCk7XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBjb252ZXJ0RmFzdGlmeUhlYWRlcnNUb1N0YW5kYXJkKHJlcXVlc3QuaGVhZGVycyk7XG5cbiAgICAgICAgLy8gSVAg7Zek642UIGZhbGxiYWNrOiDtlITroZ3si5zqsIAg7ZGc7KSAIElQIO2XpOuNlOulvCDso7zsnoXtlZjsp4Ag7JWK64qUIO2ZmOqyveyXkOyEnOuPhFxuICAgICAgICAvLyBiZXR0ZXItYXV0aC9pbmZyYeydmCBnZXRDbGllbnRJcEZyb21SZXF1ZXN0KCnqsIAgSVDrpbwg7J247Iud7ZWgIOyImCDsnojrj4TroZ1cbiAgICAgICAgLy8gRmFzdGlmeeqwgCByZXNvbHZl7ZWcIHJlcXVlc3QuaXDrpbwgeC1yZWFsLWlw66GcIOyjvOyehe2VnOuLpC5cbiAgICAgICAgY29uc3QgSVBfSEVBREVSUyA9IFtcbiAgICAgICAgICBcImNmLWNvbm5lY3RpbmctaXBcIixcbiAgICAgICAgICBcIngtZm9yd2FyZGVkLWZvclwiLFxuICAgICAgICAgIFwieC1yZWFsLWlwXCIsXG4gICAgICAgICAgXCJ4LXZlcmNlbC1mb3J3YXJkZWQtZm9yXCIsXG4gICAgICAgIF07XG4gICAgICAgIGlmIChyZXF1ZXN0LmlwICYmICFJUF9IRUFERVJTLnNvbWUoKGgpID0+IGhlYWRlcnMuaGFzKGgpKSkge1xuICAgICAgICAgIGhlYWRlcnMuc2V0KFwieC1yZWFsLWlwXCIsIHJlcXVlc3QuaXApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVxID0gbmV3IFJlcXVlc3QodXJsLnRvU3RyaW5nKCksIHtcbiAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgLi4uKHJlcXVlc3QuYm9keSA/IHsgYm9keTogSlNPTi5zdHJpbmdpZnkocmVxdWVzdC5ib2R5KSB9IDoge30pLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYXV0aC5oYW5kbGVyKHJlcSk7XG5cbiAgICAgICAgcmVwbHkuc3RhdHVzKHJlc3BvbnNlLnN0YXR1cyk7XG4gICAgICAgIHJlc3BvbnNlLmhlYWRlcnMuZm9yRWFjaCgodmFsdWU6IHN0cmluZywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICByZXBseS5oZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVwbHkuc2VuZChyZXNwb25zZS5ib2R5ID8gYXdhaXQgcmVzcG9uc2UudGV4dCgpIDogbnVsbCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcmludFN0YXJ0dXBTdW1tYXJ5KCkge1xuICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgIGNvbnN0IGVudiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID8/IFwiZGV2ZWxvcG1lbnRcIjtcbiAgICBjb25zdCBhY3RpdmVQcmVzZXQgPSBlbnYgPT09IFwicHJvZHVjdGlvblwiID8gXCJwcm9kdWN0aW9uX21hc3RlclwiIDogXCJkZXZlbG9wbWVudF9tYXN0ZXJcIjtcblxuICAgIGNvbnN0IGRpbSA9IChtc2c6IHN0cmluZykgPT4gY29uc29sZS5sb2coY2hhbGsuZGltKGDinJMgJHttc2d9YCkpO1xuICAgIGNvbnN0IGdyZWVuID0gKG1zZzogc3RyaW5nKSA9PiBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTICR7bXNnfWApKTtcblxuICAgIGRpbShgQ29uZmlnIGxvYWRlZCR7Zm9ybWF0VGltZSh0aGlzLl9jb25maWdFbGFwc2VkKX1gKTtcblxuICAgIC8vIERCIHByZXNldCDrqqnroZ1cbiAgICBncmVlbihcIkRCXCIpO1xuICAgIGNvbnN0IHsgaXNMb2NhbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBjb25zdCBwcmVzZXROYW1lcyA9IE9iamVjdC5rZXlzKHRoaXMuZGJDb25maWcpIGFzIChrZXlvZiBTb25hbXVEQkNvbmZpZylbXTtcbiAgICBjb25zdCBtYXhMZW4gPSBNYXRoLm1heCguLi5wcmVzZXROYW1lcy5tYXAoKG4pID0+IG4ubGVuZ3RoKSk7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHByZXNldE5hbWVzKSB7XG4gICAgICBjb25zdCBjb25uID0gdGhpcy5kYkNvbmZpZ1tuYW1lXS5jb25uZWN0aW9uIGFzXG4gICAgICAgIHwgeyBob3N0Pzogc3RyaW5nOyBwb3J0PzogbnVtYmVyOyBkYXRhYmFzZT86IHN0cmluZyB9XG4gICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaG9zdCA9IGNvbm4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICAgIGNvbnN0IGFkZHIgPSBgQCAke2hvc3R9OiR7Y29ubj8ucG9ydCA/PyA1NDMyfS8ke2Nvbm4/LmRhdGFiYXNlID8/IHRoaXMuY29uZmlnLmRhdGFiYXNlLm5hbWV9YDtcbiAgICAgIGNvbnN0IHBhZGRlZCA9IG5hbWUucGFkRW5kKG1heExlbik7XG4gICAgICBjb25zdCByZW1vdGVUYWcgPSBpc0xvY2FsKCkgJiYgIWlzTG9jYWxIb3N0KGhvc3QpID8gY2hhbGsueWVsbG93KGAgXFx1MjZhMCByZW1vdGVgKSA6IFwiXCI7XG5cbiAgICAgIGlmIChuYW1lID09PSBhY3RpdmVQcmVzZXQpIHtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYCAgXFx1MjViOCAke3BhZGRlZH0gJHthZGRyfWApICsgcmVtb3RlVGFnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShgICAgICR7cGFkZGVkfSAke2FkZHJ9YCkgKyByZW1vdGVUYWcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aCkge1xuICAgICAgY29uc3QgYmFzZVBhdGggPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aC5iYXNlUGF0aCA/PyBcIi9hcGkvYXV0aFwiO1xuICAgICAgZGltKGBBdXRoOiBiZXR0ZXItYXV0aCBhdCAke2Jhc2VQYXRofS8qYCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZy5hcGkudGltZXpvbmUpIHtcbiAgICAgIGRpbShgVGltZXpvbmU6ICR7dGhpcy5jb25maWcuYXBpLnRpbWV6b25lfWApO1xuICAgIH1cbiAgICBncmVlbihgU29uYW11IHJlYWR5JHtmb3JtYXRUaW1lKHRoaXMuX2luaXRFbGFwc2VkKX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZUNhY2hlKGNvbmZpZzogQ2FjaGVDb25maWcgfCB1bmRlZmluZWQsIGZvclRlc3Rpbmc6IGJvb2xlYW4pIHtcbiAgICBjb25zdCB7IHNldENhY2hlTWFuYWdlclJlZiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY2FjaGUvZGVjb3JhdG9yXCIpO1xuXG4gICAgLy8g7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnCDrqZTrqqjrpqwg65Oc65287J2067KEIOyekOuPmSDsgqzsmqlcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgY29uc3QgeyBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jYWNoZS9jYWNoZS1tYW5hZ2VyXCIpO1xuICAgICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyKCk7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOyEpOygleydtCDsl4bsnLzrqbQg7LqQ7IucIOu5hO2ZnOyEse2ZlFxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYobnVsbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g7ISk7KCV7JeQIOuUsOudvCBDYWNoZU1hbmFnZXIg7IOd7ISxXG4gICAgY29uc3QgeyBjcmVhdGVDYWNoZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NhY2hlL2NhY2hlLW1hbmFnZXJcIik7XG4gICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVDYWNoZU1hbmFnZXIoY29uZmlnKTtcbiAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbml0aWFsaXplV29ya2Zsb3dzKG9wdGlvbnM6IFNvbmFtdVRhc2tPcHRpb25zIHwgdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgeyBXb3JrZmxvd01hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rhc2tzL3dvcmtmbG93LW1hbmFnZXJcIik7XG4gICAgLy8gTk9URTogQHNvbmFtdS1raXQvdGFza3Mg7JWI7JeQ7ISgIGtuZXggY29uZmln66W8IOyImOygle2VmOq4sCDrlYzrrLjsl5AgY29ubmVjdGlvbuydtCDslYTri4wgY29uZmlnIOynuOuhnCDrs7Trg4Xri4jri6QuXG4gICAgdGhpcy5fd29ya2Zsb3dzID0gbmV3IFdvcmtmbG93TWFuYWdlcihEQi5nZXREQkNvbmZpZyhcIndcIikpO1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVuYWJsZVdvcmtlciA9IG9wdGlvbnMuZW5hYmxlV29ya2VyID8/IGlzRGFlbW9uU2VydmVyKCk7XG4gICAgY29uc3QgZGVmYXVsdFdvcmtlck9wdGlvbnMgPSB7XG4gICAgICBjb25jdXJyZW5jeTogb3MuY3B1cygpLmxlbmd0aCAtIDEsXG4gICAgICB1c2VQdWJTdWI6IHRydWUsXG4gICAgICBsaXN0ZW5EZWxheTogNTAwLFxuICAgIH07XG5cbiAgICBpZiAoZW5hYmxlV29ya2VyKSB7XG4gICAgICB0aGlzLndvcmtmbG93cy5zZXR1cFdvcmtlcih7XG4gICAgICAgIC4uLmRlZmF1bHRXb3JrZXJPcHRpb25zLFxuICAgICAgICAuLi5vcHRpb25zLndvcmtlck9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3Qoc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsIG9wdGlvbnM6IFNvbmFtdVNlcnZlck9wdGlvbnMpIHtcbiAgICBjb25zdCBwb3J0ID0gb3B0aW9ucy5saXN0ZW4/LnBvcnQgPz8gMzAwMDtcbiAgICBjb25zdCBob3N0ID0gb3B0aW9ucy5saXN0ZW4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcblxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TaHV0ZG93bj8uKHNlcnZlcik7XG4gICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5kZXN0cm95KCk7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHNodXRkb3duID0gYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZHVyaW5nIHNodXRkb3duOlwiLCBlcnIpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgc2h1dGRvd24pO1xuICAgIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHNodXRkb3duKTtcblxuICAgIGlmIChvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcikge1xuICAgICAgc2VydmVyLnNldEVycm9ySGFuZGxlcihvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcik7XG4gICAgfVxuXG4gICAgc2VydmVyXG4gICAgICAubGlzdGVuKHsgcG9ydCwgaG9zdCB9KVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5zdGFydFdvcmtlcigpO1xuICAgICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TdGFydD8uKHNlcnZlcik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnIpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hhbGsucmVkKFwiRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjpcIiwgZXJyKSk7XG4gICAgICAgIGF3YWl0IHNodXRkb3duKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBCYXNlTW9kZWwgfSA9IGF3YWl0IGltcG9ydChcIi4uL2RhdGFiYXNlL2Jhc2UtbW9kZWxcIik7XG4gICAgLy8g66i87KCAIOyymOumrO2VtOyVvO2VqC5cbiAgICBhd2FpdCBCYXNlTW9kZWwuZGVzdHJveSgpO1xuICAgIC8vIO2UhOuhnOyEuOyKpCDsooXro4wg7IucIOyCtOyVhOyeiOuKlCBXUyDsl7DqsrDsnYQg66i87KCAIOygleumrO2VtCDsnbTtm4Qg64uk66W4IOumrOyGjOyKpCDtlbTsoJwg6rO87KCV7JeQ7IScIOyelOyXrCBjYWxsYmFja+ydtCDtioDsp4Ag7JWK6rKMIO2VqFxuICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbXG4gICAgICB0aGlzLl93ZWJzb2NrZXRSdW50aW1lPy5zaHV0ZG93bigpID8/IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5fd29ya2Zsb3dzPy5kZXN0cm95KCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICB0aGlzLl9jYWNoZT8uZGlzY29ubmVjdCgpID8/IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5fZGV2Vml0ZXN0TWFuYWdlcj8uc2h1dGRvd24oKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIHRoaXMud2F0Y2hlcj8uY2xvc2UoKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIGxvZ3RhcGVEaXNwb3NlKCksXG4gICAgXSk7XG4gICAgdGhpcy5fd2Vic29ja2V0UnVudGltZSA9IG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IFNvbmFtdSA9IG5ldyBTb25hbXVDbGFzcygpO1xuXG4vKipcbiAqIHN0cmVhbSDrqqjrk5zsl5DshJwg7YKkIOyDneyEsSDtlajsiJjqsIAg7KeA7KCV65CY7KeAIOyViuyVmOydhCDrlYwg7IKs7Jqp7ZWY64qUIOq4sOuzuCDtlajsiJjsnoXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRLZXlHZW5lcmF0b3IoZmlsZTogeyBmaWxlbmFtZTogc3RyaW5nOyBtaW1ldHlwZTogc3RyaW5nIH0pOiBzdHJpbmcge1xuICBjb25zdCBleHQgPSBtaW1lLmV4dGVuc2lvbihmaWxlLm1pbWV0eXBlKSB8fCBcImJpblwiO1xuICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICBjb25zdCByYW5kb20gPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KTtcbiAgcmV0dXJuIGB1cGxvYWRzLyR7dGltZXN0YW1wfS0ke3JhbmRvbX0uJHtleHR9YDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VGltZShtczogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZm9ybWF0dGVkID0gbXMgPj0gMTAwMCA/IGAkeyhtcyAvIDEwMDApLnRvRml4ZWQoMil9c2AgOiBgJHtNYXRoLnJvdW5kKG1zKX1tc2A7XG4gIHJldHVybiBgICgke2Zvcm1hdHRlZH0pYDtcbn1cblxuY29uc3QgTE9DQUxfSE9TVFMgPSBuZXcgU2V0KFtcImxvY2FsaG9zdFwiLCBcIjEyNy4wLjAuMVwiLCBcIjAuMC4wLjBcIiwgXCI6OjFcIl0pO1xuZnVuY3Rpb24gaXNMb2NhbEhvc3QoaG9zdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBMT0NBTF9IT1NUUy5oYXMoaG9zdCk7XG59XG5cbi8vIGAuZXZlcnkoKWDqsIAg7LKrIGd1YXJkIOydtO2bhCDsiJztmozrpbwg66mI7LaU64qUIOusuOygnOqwgCDsnojslrQgYGZvci4uLm9mYOuhnCDrqqjrk6AgZ3VhcmTrpbwg7Iic7ISc64yA66GcIOyLpO2Wie2VmOuPhOuhnSDqs6DsoJXtlahcbmZ1bmN0aW9uIHJ1bkd1YXJkcyh7XG4gIGd1YXJkcyxcbiAgY29uZmlnLFxuICByZXF1ZXN0LFxuICBhcGksXG59OiB7XG4gIGd1YXJkczogRXh0ZW5kZWRBcGlbXCJvcHRpb25zXCJdW1wiZ3VhcmRzXCJdIHwgdW5kZWZpbmVkO1xuICBjb25maWc6IFBpY2s8U29uYW11RmFzdGlmeUNvbmZpZywgXCJndWFyZEhhbmRsZXJcIj47XG4gIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0O1xuICBhcGk6IEV4dGVuZGVkQXBpO1xufSk6IHZvaWQge1xuICBmb3IgKGNvbnN0IGd1YXJkIG9mIGd1YXJkcyA/PyBbXSkge1xuICAgIGNvbmZpZy5ndWFyZEhhbmRsZXIoZ3VhcmQsIHJlcXVlc3QsIGFwaSk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtMERBLFNBQVMsb0JBQW9CLE1BQXNEO0NBQ2pGLE1BQU0sTUFBTSxLQUFLLFVBQVUsS0FBSyxTQUFTLElBQUk7Q0FDN0MsTUFBTSxZQUFZLEtBQUssS0FBSztDQUM1QixNQUFNLFNBQVMsS0FBSyxRQUFRLENBQUMsU0FBUyxHQUFHLENBQUMsTUFBTSxHQUFHLEVBQUU7QUFDckQsUUFBTyxXQUFXLFVBQVUsR0FBRyxPQUFPLEdBQUc7O0FBRzNDLFNBQVMsV0FBVyxJQUFvQjtDQUN0QyxNQUFNLFlBQVksTUFBTSxNQUFPLElBQUksS0FBSyxLQUFNLFFBQVEsRUFBRSxDQUFDLEtBQUssR0FBRyxLQUFLLE1BQU0sR0FBRyxDQUFDO0FBQ2hGLFFBQU8sS0FBSyxVQUFVOztBQUl4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
|