sonamu 0.11.4 → 0.11.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.
@@ -6,27 +6,16 @@ import { type GenerateOptions, type PathAndCode } from "../types/types";
6
6
  import { TemplateKey } from "../types/types";
7
7
  import { type TemplateOptions } from "../types/types";
8
8
  import { type AbsolutePath } from "../utils/path-utils";
9
- import { findChangedFilesUsingChecksums, renewChecksums } from "./checksum";
10
9
  import { type FileType } from "./file-patterns";
11
10
  import { type LoadedApis, type LoadedModels, type LoadedTypes } from "./module-loader";
12
- import * as SyncerActions from "./syncer-actions";
13
11
  type DiffGroupKey = FileType | "unknown";
14
12
  type DiffGroups = Partial<Record<DiffGroupKey, AbsolutePath[]>>;
15
- export interface SyncerDependencies {
16
- actionCopySharedToTargetsIfNotExists: typeof SyncerActions.actionCopySharedToTargetsIfNotExists;
17
- actionGenerateHttpValidators: typeof SyncerActions.actionGenerateHttpValidators;
18
- actionGenerateSsrEntryServerIfNotExists: typeof SyncerActions.actionGenerateSsrEntryServerIfNotExists;
19
- findChangedFilesUsingChecksums: typeof findChangedFilesUsingChecksums;
20
- renewChecksums: typeof renewChecksums;
21
- }
22
13
  export declare class Syncer {
23
- private readonly dependencies;
24
14
  apis: LoadedApis;
25
15
  types: LoadedTypes;
26
16
  models: LoadedModels;
27
17
  workflows: Map<string, WorkflowMetadata[]>;
28
18
  eventEmitter: EventEmitter;
29
- constructor(dependencies?: SyncerDependencies);
30
19
  /**
31
20
  * 체크섬이 변경된 부분에 대해 싱크를 진행합니다.
32
21
  * dev 서버가 처음 떴을 때, sonamu sync 할 때 실행됩니다. 이후에는 hmrAndSync 경로를 타요.
@@ -82,6 +71,7 @@ export declare class Syncer {
82
71
  handleAuxiliarySymbolChanges(diffGroups: DiffGroups): Promise<void>;
83
72
  handleConfigChanges(): Promise<void>;
84
73
  handleSonamuDictionaryRelatedChanges(): Promise<void>;
74
+ handleHttpValidatorRelatedChanges(): Promise<void>;
85
75
  handleDrifts(drifts: AbsolutePath[]): Promise<void>;
86
76
  /**
87
77
  * 주어진 엔티티와 템플릿 키에 대해, 생성된 코드가 존재하는지 확인합니다.
@@ -1 +1 @@
1
- {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../../src/syncer/syncer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../../src/syncer/syncer.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,7 @@ import { minimatch } from "minimatch";
25
25
  import { EventEmitter } from "events";
26
26
  import { hot } from "@sonamu-kit/hmr-hook";
27
27
  //#region src/syncer/syncer.ts
28
- var defaultSyncerDependencies, Syncer;
28
+ var Syncer;
29
29
  var init_syncer = __esmMin((() => {
30
30
  init_decorators();
31
31
  init_sonamu();
@@ -45,41 +45,30 @@ var init_syncer = __esmMin((() => {
45
45
  init_filesystem_dependencies();
46
46
  init_module_loader();
47
47
  init_syncer_actions();
48
- defaultSyncerDependencies = {
49
- actionCopySharedToTargetsIfNotExists,
50
- actionGenerateHttpValidators,
51
- actionGenerateSsrEntryServerIfNotExists,
52
- findChangedFilesUsingChecksums,
53
- renewChecksums
54
- };
55
48
  Syncer = class {
56
- dependencies;
57
49
  apis = [];
58
50
  types = {};
59
51
  models = {};
60
52
  workflows = /* @__PURE__ */ new Map();
61
53
  eventEmitter = new EventEmitter();
62
- constructor(dependencies = defaultSyncerDependencies) {
63
- this.dependencies = dependencies;
64
- }
65
54
  /**
66
55
  * 체크섬이 변경된 부분에 대해 싱크를 진행합니다.
67
56
  * dev 서버가 처음 떴을 때, sonamu sync 할 때 실행됩니다. 이후에는 hmrAndSync 경로를 타요.
68
57
  * @returns
69
58
  */
70
59
  async sync() {
71
- await this.dependencies.actionCopySharedToTargetsIfNotExists();
72
- await this.dependencies.actionGenerateSsrEntryServerIfNotExists();
73
- const changedFiles = await this.dependencies.findChangedFilesUsingChecksums();
60
+ await actionCopySharedToTargetsIfNotExists();
61
+ await actionGenerateSsrEntryServerIfNotExists();
62
+ const changedFiles = await findChangedFilesUsingChecksums();
74
63
  if (changedFiles.length === 0) {
75
- if (await this.reconcileHttpValidatorRegistry()) await this.dependencies.renewChecksums();
64
+ if (await this.reconcileHttpValidatorRegistry()) await renewChecksums();
76
65
  console.log(chalk.black.bgGreen(centerText("All files are synced!")));
77
66
  return;
78
67
  }
79
68
  await runWithGracefulShutdown(async () => {
80
69
  await this.doSyncActions(changedFiles);
81
70
  await this.reconcileHttpValidatorRegistry();
82
- await this.dependencies.renewChecksums();
71
+ await renewChecksums();
83
72
  }, {
84
73
  whenThisHappens: "SIGUSR2",
85
74
  waitForUpTo: 2e4
@@ -89,7 +78,7 @@ var init_syncer = __esmMin((() => {
89
78
  const registryPath = path.join(Sonamu.apiRootPath, "src/application/sonamu.validators.generated.ts");
90
79
  const policy = Sonamu.config.validation?.zodCompiler;
91
80
  if ((isObjectValue(policy) && policy !== null && policy.api === "aot") === await syncerFileExists(registryPath)) return false;
92
- await this.dependencies.actionGenerateHttpValidators();
81
+ await actionGenerateHttpValidators();
93
82
  return true;
94
83
  }
95
84
  /**
@@ -220,27 +209,15 @@ var init_syncer = __esmMin((() => {
220
209
  async doSyncActions(diffFilePaths) {
221
210
  const diffGroups = this.calculateDiffGroups(diffFilePaths);
222
211
  const diffTypes = Object.keys(diffGroups);
223
- const { changeMatches, nothingMatches, unhandledPaths } = this.changeMatcher(diffTypes, diffGroups);
212
+ const { changeMatches, unhandledPaths, unhandledChangesLeft } = this.changeMatcher(diffTypes, diffGroups);
224
213
  if (changeMatches("entity", "types")) await this.handleTruthSourceChanges(diffGroups);
225
214
  if (changeMatches("model", "frame")) await this.handleImplementationChanges(diffGroups);
226
215
  if (changeMatches("types", "functions")) await this.handleAuxiliarySymbolChanges(diffGroups);
227
216
  if (changeMatches("config")) await this.handleConfigChanges();
217
+ if (changeMatches("workflow")) {}
228
218
  if (changeMatches("i18n", "entity", "config")) await this.handleSonamuDictionaryRelatedChanges();
229
- const metadataChanged = diffTypes.some((type) => [
230
- "entity",
231
- "types",
232
- "model",
233
- "frame",
234
- "config"
235
- ].includes(type));
236
- if (changeMatches("httpValidatorsGenerated") && !metadataChanged) await this.dependencies.actionGenerateHttpValidators();
237
- if (metadataChanged) {
238
- await this.autoloadTypes();
239
- await this.autoloadModels();
240
- await this.autoloadApis();
241
- await this.dependencies.actionGenerateHttpValidators();
242
- }
243
- if (nothingMatches()) await this.handleDrifts(unhandledPaths());
219
+ if (changeMatches("entity", "types", "model", "frame", "config", "httpValidatorsGenerated")) await this.handleHttpValidatorRelatedChanges();
220
+ if (unhandledChangesLeft()) await this.handleDrifts(unhandledPaths());
244
221
  return { diffTypes };
245
222
  }
246
223
  calculateDiffGroups(diffFiles) {
@@ -270,17 +247,17 @@ var init_syncer = __esmMin((() => {
270
247
  return matching.length > 0;
271
248
  };
272
249
  /**
273
- * changeMatches로 매칭된 것이 하나도 없는지 여부를 가져옵니다.
274
- */
275
- const nothingMatches = () => handled.size === 0;
276
- /**
277
250
  * 어떤 changeMatches 호출에도 걸리지 않은 FileType들의 실제 파일 경로를 모아서 반환합니다.
278
251
  */
279
252
  const unhandledPaths = () => diffTypes.filter((t) => !handled.has(t)).flatMap((t) => diffGroups[t] ?? []);
253
+ /**
254
+ * changeMatches 호출에도 걸리지 않은 FileType들이 존재하는지 확인합니다.
255
+ */
256
+ const unhandledChangesLeft = () => unhandledPaths().length > 0;
280
257
  return {
281
258
  changeMatches,
282
- nothingMatches,
283
- unhandledPaths
259
+ unhandledPaths,
260
+ unhandledChangesLeft
284
261
  };
285
262
  }
286
263
  async handleTruthSourceChanges(diffGroups) {
@@ -326,12 +303,17 @@ var init_syncer = __esmMin((() => {
326
303
  async handleSonamuDictionaryRelatedChanges() {
327
304
  await actionSyncSonamuDictionary();
328
305
  }
306
+ async handleHttpValidatorRelatedChanges() {
307
+ await this.autoloadTypes();
308
+ await this.autoloadModels();
309
+ await this.autoloadApis();
310
+ await actionGenerateHttpValidators();
311
+ }
329
312
  async handleDrifts(drifts) {
330
- if (drifts.length > 0) {
331
- console.warn(chalk.yellow("⚠️ Sonamu가 자동 생성한 파일에 대한 변경이 감지되었습니다. 파일이 Sonamu watcher 외부에서 변경된 것으로 추정됩니다."));
332
- for (const p of drifts) console.warn(chalk.yellow(` - ${path.relative(Sonamu.appRootPath, p)}`));
333
- console.warn(chalk.dim(" → `pnpm sonamu sync --force`를 권장합니다."));
334
- }
313
+ if (drifts.length === 0) return;
314
+ console.warn(chalk.yellow("⚠️ Sonamu가 자동 생성한 파일에 대한 변경이 감지되었습니다. 파일이 Sonamu watcher 외부에서 변경된 것으로 추정됩니다."));
315
+ for (const p of drifts) console.warn(chalk.yellow(` - ${path.relative(Sonamu.appRootPath, p)}`));
316
+ console.warn(chalk.dim(" → `pnpm sonamu sync --force`를 권장합니다."));
335
317
  }
336
318
  /**
337
319
  * 주어진 엔티티와 템플릿 키에 대해, 생성된 코드가 존재하는지 확인합니다.
@@ -406,7 +388,7 @@ var init_syncer = __esmMin((() => {
406
388
  * 하위호환용 프록시 메소드입니다.
407
389
  */
408
390
  async renewChecksums() {
409
- return await this.dependencies.renewChecksums();
391
+ return await renewChecksums();
410
392
  }
411
393
  };
412
394
  }));
@@ -414,4 +396,4 @@ var init_syncer = __esmMin((() => {
414
396
  init_syncer();
415
397
  export { Syncer, init_syncer };
416
398
 
417
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2VyLmpzIiwibmFtZXMiOlsiU3luY2VyQWN0aW9ucy5hY3Rpb25Db3B5U2hhcmVkVG9UYXJnZXRzSWZOb3RFeGlzdHMiLCJTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlSHR0cFZhbGlkYXRvcnMiLCJTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlU3NyRW50cnlTZXJ2ZXJJZk5vdEV4aXN0cyIsIlN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVJbml0aWFsVHlwZXMiLCJTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNGaWxlc1RvVGFyZ2V0cyIsIlN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVTY2hlbWFzIiwiU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZVNlcnZpY2VzIiwiU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZUh0dHBzIiwiU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZVNzclF1ZXJpZXMiLCJTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNDb25maWciLCJTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNTb25hbXVEaWN0aW9uYXJ5Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNlci9zeW5jZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tIFwiZXZlbnRzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyBob3QgfSBmcm9tIFwiQHNvbmFtdS1raXQvaG1yLWhvb2tcIjtcbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcbmltcG9ydCB7IG1pbmltYXRjaCB9IGZyb20gXCJtaW5pbWF0Y2hcIjtcbmltcG9ydCB7IHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyB0eXBlIHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IHJlZ2lzdGVyZWRBcGlzIH0gZnJvbSBcIi4uL2FwaS9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgRW50aXR5TmFtZXNSZWNvcmQgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBOYWl0ZSB9IGZyb20gXCIuLi9uYWl0ZS9uYWl0ZVwiO1xuaW1wb3J0IHsgdHlwZSBXb3JrZmxvd01ldGFkYXRhIH0gZnJvbSBcIi4uL3Rhc2tzL2RlY29yYXRvclwiO1xuaW1wb3J0IHsgVGVtcGxhdGVNYW5hZ2VyIH0gZnJvbSBcIi4uL3RlbXBsYXRlL3RlbXBsYXRlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgR2VuZXJhdGVPcHRpb25zLCB0eXBlIFBhdGhBbmRDb2RlIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZUtleSB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBUZW1wbGF0ZU9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG1hcEFzeW5jLCByZWR1Y2VBc3luYyB9IGZyb20gXCIuLi91dGlscy9hc3luYy11dGlsc1wiO1xuaW1wb3J0IHsgY2VudGVyVGV4dCB9IGZyb20gXCIuLi91dGlscy9jb25zb2xlLXV0aWxcIjtcbmltcG9ydCB7IGlzVGVzdCB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5pbXBvcnQgeyB0eXBlIEFic29sdXRlUGF0aCB9IGZyb20gXCIuLi91dGlscy9wYXRoLXV0aWxzXCI7XG5pbXBvcnQgeyBydW5XaXRoR3JhY2VmdWxTaHV0ZG93biB9IGZyb20gXCIuLi91dGlscy9wcm9jZXNzLXV0aWxzXCI7XG5pbXBvcnQgeyBpc09iamVjdFZhbHVlIH0gZnJvbSBcIi4uL3V0aWxzL3J1bnRpbWUtdmFsdWVcIjtcbmltcG9ydCB7IGZpbmRDaGFuZ2VkRmlsZXNVc2luZ0NoZWNrc3VtcywgcmVuZXdDaGVja3N1bXMgfSBmcm9tIFwiLi9jaGVja3N1bVwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVUZW1wbGF0ZSwgcmVuZGVyVGVtcGxhdGUgfSBmcm9tIFwiLi9jb2RlLWdlbmVyYXRvclwiO1xuaW1wb3J0IHsgY3JlYXRlRW50aXR5LCBkZWxFbnRpdHkgfSBmcm9tIFwiLi9lbnRpdHktb3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgZ2V0Q2hlY2tzdW1QYXR0ZXJuR3JvdXAsIGdldENoZWNrc3VtUGF0dGVybkdyb3VwSW5BYnNvbHV0ZVBhdGggfSBmcm9tIFwiLi9maWxlLXBhdHRlcm5zXCI7XG5pbXBvcnQgeyB0eXBlIEZpbGVUeXBlIH0gZnJvbSBcIi4vZmlsZS1wYXR0ZXJuc1wiO1xuaW1wb3J0IHsgc3luY2VyRmlsZUV4aXN0cywgc3luY2VyRmlsZXN5c3RlbSB9IGZyb20gXCIuL2ZpbGVzeXN0ZW0tZGVwZW5kZW5jaWVzXCI7XG5pbXBvcnQgeyBsb2FkQXBpcywgbG9hZE1vZGVscywgbG9hZFR5cGVzLCBsb2FkV29ya2Zsb3dzIH0gZnJvbSBcIi4vbW9kdWxlLWxvYWRlclwiO1xuaW1wb3J0IHsgdHlwZSBMb2FkZWRBcGlzLCB0eXBlIExvYWRlZE1vZGVscywgdHlwZSBMb2FkZWRUeXBlcyB9IGZyb20gXCIuL21vZHVsZS1sb2FkZXJcIjtcbmltcG9ydCAqIGFzIFN5bmNlckFjdGlvbnMgZnJvbSBcIi4vc3luY2VyLWFjdGlvbnNcIjtcblxudHlwZSBEaWZmR3JvdXBLZXkgPSBGaWxlVHlwZSB8IFwidW5rbm93blwiO1xudHlwZSBEaWZmR3JvdXBzID0gUGFydGlhbDxSZWNvcmQ8RGlmZkdyb3VwS2V5LCBBYnNvbHV0ZVBhdGhbXT4+O1xuXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNlckRlcGVuZGVuY2llcyB7XG4gIGFjdGlvbkNvcHlTaGFyZWRUb1RhcmdldHNJZk5vdEV4aXN0czogdHlwZW9mIFN5bmNlckFjdGlvbnMuYWN0aW9uQ29weVNoYXJlZFRvVGFyZ2V0c0lmTm90RXhpc3RzO1xuICBhY3Rpb25HZW5lcmF0ZUh0dHBWYWxpZGF0b3JzOiB0eXBlb2YgU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZUh0dHBWYWxpZGF0b3JzO1xuICBhY3Rpb25HZW5lcmF0ZVNzckVudHJ5U2VydmVySWZOb3RFeGlzdHM6IHR5cGVvZiBTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlU3NyRW50cnlTZXJ2ZXJJZk5vdEV4aXN0cztcbiAgZmluZENoYW5nZWRGaWxlc1VzaW5nQ2hlY2tzdW1zOiB0eXBlb2YgZmluZENoYW5nZWRGaWxlc1VzaW5nQ2hlY2tzdW1zO1xuICByZW5ld0NoZWNrc3VtczogdHlwZW9mIHJlbmV3Q2hlY2tzdW1zO1xufVxuXG5jb25zdCBkZWZhdWx0U3luY2VyRGVwZW5kZW5jaWVzOiBTeW5jZXJEZXBlbmRlbmNpZXMgPSB7XG4gIGFjdGlvbkNvcHlTaGFyZWRUb1RhcmdldHNJZk5vdEV4aXN0czogU3luY2VyQWN0aW9ucy5hY3Rpb25Db3B5U2hhcmVkVG9UYXJnZXRzSWZOb3RFeGlzdHMsXG4gIGFjdGlvbkdlbmVyYXRlSHR0cFZhbGlkYXRvcnM6IFN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVIdHRwVmFsaWRhdG9ycyxcbiAgYWN0aW9uR2VuZXJhdGVTc3JFbnRyeVNlcnZlcklmTm90RXhpc3RzOiBTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlU3NyRW50cnlTZXJ2ZXJJZk5vdEV4aXN0cyxcbiAgZmluZENoYW5nZWRGaWxlc1VzaW5nQ2hlY2tzdW1zLFxuICByZW5ld0NoZWNrc3Vtcyxcbn07XG5cbmV4cG9ydCBjbGFzcyBTeW5jZXIge1xuICBhcGlzOiBMb2FkZWRBcGlzID0gW107XG4gIHR5cGVzOiBMb2FkZWRUeXBlcyA9IHt9O1xuICBtb2RlbHM6IExvYWRlZE1vZGVscyA9IHt9O1xuICB3b3JrZmxvd3M6IE1hcDxzdHJpbmcsIFdvcmtmbG93TWV0YWRhdGFbXT4gPSBuZXcgTWFwKCk7XG4gIGV2ZW50RW1pdHRlcjogRXZlbnRFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZGVwZW5kZW5jaWVzOiBTeW5jZXJEZXBlbmRlbmNpZXMgPSBkZWZhdWx0U3luY2VyRGVwZW5kZW5jaWVzKSB7fVxuXG4gIC8qKlxuICAgKiDssrTtgazshKzsnbQg67OA6rK965CcIOu2gOu2hOyXkCDrjIDtlbQg7Iux7YGs66W8IOynhO2Wie2VqeuLiOuLpC5cbiAgICogZGV2IOyEnOuyhOqwgCDsspjsnYwg65a07J2EIOuVjCwgc29uYW11IHN5bmMg7ZWgIOuVjCDsi6TtlonrkKnri4jri6QuIOydtO2bhOyXkOuKlCBobXJBbmRTeW5jIOqyveuhnOulvCDtg4DsmpQuXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBhc3luYyBzeW5jKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOy0iOq4sCDrtoDtirjsiqTtirjrnqkhIOyWmOuEpOuTpOydgCBpZGVtcG90ZW507ZWY6rOgIOqwgOuzjeq4sCDrlYzrrLjsl5Ag66y07KeA7ISxIOyLpO2Wie2VtOuPhCDrkKnri4jri6QuXG4gICAgLy8g7JaY64Sk65Ok7J2AIHNvbmFtdS5sb2Nr7JeQIOuTpOyWtOqwgOyngOuPhCDslYrqs6Ag65Sw65287IScIEhNUiDqsr3roZzrpbwg7YOA7KeA64+EIOyViuuKlCDsuZzqtazrk6TsnoXri4jri6QuXG4gICAgLy8g6re4656Y7IScIOyVhOustCDrlYzrgpgg6re464OlIOuPjOugpOyjvOuptCDrkJjripTrjbAsIGhtckFuZFN5bmPsl5DshJwg66ek67KIIO2VmOuKlCDqsoPsnYAg64Kt67mE7J2064uIIOyXrOq4sOyEnCDtlZwg67KI66eMIO2VqeuLiOuLpC5cbiAgICBhd2FpdCB0aGlzLmRlcGVuZGVuY2llcy5hY3Rpb25Db3B5U2hhcmVkVG9UYXJnZXRzSWZOb3RFeGlzdHMoKTtcbiAgICBhd2FpdCB0aGlzLmRlcGVuZGVuY2llcy5hY3Rpb25HZW5lcmF0ZVNzckVudHJ5U2VydmVySWZOb3RFeGlzdHMoKTtcblxuICAgIC8vIOuwlOuAkCDqsoPsnbQg7JeG7Jy866m0IOq3uOuDpSDrhJjslrTqsIDsmpQuXG4gICAgY29uc3QgY2hhbmdlZEZpbGVzID0gYXdhaXQgdGhpcy5kZXBlbmRlbmNpZXMuZmluZENoYW5nZWRGaWxlc1VzaW5nQ2hlY2tzdW1zKCk7XG4gICAgaWYgKGNoYW5nZWRGaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChhd2FpdCB0aGlzLnJlY29uY2lsZUh0dHBWYWxpZGF0b3JSZWdpc3RyeSgpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZGVwZW5kZW5jaWVzLnJlbmV3Q2hlY2tzdW1zKCk7XG4gICAgICB9XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5ibGFjay5iZ0dyZWVuKGNlbnRlclRleHQoXCJBbGwgZmlsZXMgYXJlIHN5bmNlZCFcIikpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDsl6zquLDshJwg7Iuk7KCcIOyLse2BrCDrj5nsnpHsnYQg7IiY7ZaJ7ZWp64uI64ukLlxuICAgIC8vIOuLpOunjCDsi7Htgawg7KSR7JeQIO2UhOuhnOyEuOyKpOqwgCDso73snLzrqbQg6rys7Jes67KE66as6riwIOuVjOusuOyXkCxcbiAgICAvLyDsi5zqt7jrhJDsl5Drj4Qg7J6g7IucIOuyhO2LuCDsiJgg7J6I64qUIO2ZmOqyvSDsho3sl5DshJwg7Iux7YGs66W8IOyLpO2Wie2VqeuLiOuLpC5cbiAgICBhd2FpdCBydW5XaXRoR3JhY2VmdWxTaHV0ZG93bihcbiAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8g7JaY6rCAIOyLse2BrCDsnpHsl4Ug7IiY7ZaJ7ZWY64qUIOuzuOyytOyeheuLiOuLpC5cbiAgICAgICAgYXdhaXQgdGhpcy5kb1N5bmNBY3Rpb25zKGNoYW5nZWRGaWxlcyk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVjb25jaWxlSHR0cFZhbGlkYXRvclJlZ2lzdHJ5KCk7XG5cbiAgICAgICAgLy8g7Iux7YGsIOyVoeyFmOydtCDrgZ3rgpjrqbQg7ZWt7IOBIOyytO2BrOyErOydhCDri6Tsi5wg6rCx7Iug7ZWp64uI64ukLlxuICAgICAgICBhd2FpdCB0aGlzLmRlcGVuZGVuY2llcy5yZW5ld0NoZWNrc3VtcygpO1xuICAgICAgfSxcbiAgICAgIHsgd2hlblRoaXNIYXBwZW5zOiBcIlNJR1VTUjJcIiwgd2FpdEZvclVwVG86IDIwMDAwIH0sXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVjb25jaWxlSHR0cFZhbGlkYXRvclJlZ2lzdHJ5KCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHJlZ2lzdHJ5UGF0aCA9IHBhdGguam9pbihcbiAgICAgIFNvbmFtdS5hcGlSb290UGF0aCxcbiAgICAgIFwic3JjL2FwcGxpY2F0aW9uL3NvbmFtdS52YWxpZGF0b3JzLmdlbmVyYXRlZC50c1wiLFxuICAgICk7XG4gICAgY29uc3QgcG9saWN5ID0gU29uYW11LmNvbmZpZy52YWxpZGF0aW9uPy56b2RDb21waWxlcjtcbiAgICBjb25zdCBpc0FvdCA9IGlzT2JqZWN0VmFsdWUocG9saWN5KSAmJiBwb2xpY3kgIT09IG51bGwgJiYgcG9saWN5LmFwaSA9PT0gXCJhb3RcIjtcbiAgICBpZiAoaXNBb3QgPT09IChhd2FpdCBzeW5jZXJGaWxlRXhpc3RzKHJlZ2lzdHJ5UGF0aCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8g67OA6rK9IOuqqeuhneydtCByZWdpc3RyeSDsgq3soJzrpbwg64aT7LOQ64+EIGNoZWNrc3VtIOqwseyLoCDsoITsl5Ag7KCV7LGF6rO8IOyCsOy2nOusvOydhCDri6Tsi5wg66ee7Lal64uI64ukLlxuICAgIGF3YWl0IHRoaXMuZGVwZW5kZW5jaWVzLmFjdGlvbkdlbmVyYXRlSHR0cFZhbGlkYXRvcnMoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDqsJXsoJwg7ZKALeyLse2BrDogbG9ja+ydhCDrrLTsi5ztlZjqs6Ag7LKY7J2M67aA7YSwIOuLpOyLnCDsi7Htgaztlanri4jri6QuXG4gICAqXG4gICAqICoq7IKs7Jqp7LKYKio6IGdpdCBwb3N0LW1lcmdlIGhvb2ssIENJLCBkZXYg7ISc67KE7J2YIGBmYCDtlavtgqQuXG4gICAqICoq7Iuk7YyoIOyViOyghOyEsSoqOiDrj4TspJHsl5Ag7ZSE66Gc7IS47Iqk6rCAIOyjveyWtCBsb2NrIOyXhuuKlCDsg4Htg5zroZwg64Ko7JWE64+EIOustO2VtCDigJQg64uk7J2MIHN5bmPsl5DshJxcbiAgICogbG9jayDsl4bsnLzrqbQg7J6Q7Jew7Iqk65+96rKMIO2SgC3si7HtgazqsIAg7Yq466as6rGw65CY7Ja0IOyDiCBsb2Nr7J20IOyekeyEseuQqC5cbiAgICovXG4gIGFzeW5jIGZvcmNlU3luYygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2NrUGF0aCA9IHBhdGguam9pbihTb25hbXUuYXBpUm9vdFBhdGgsIFwic29uYW11LmxvY2tcIik7XG4gICAgaWYgKGF3YWl0IHN5bmNlckZpbGVFeGlzdHMobG9ja1BhdGgpKSB7XG4gICAgICBhd2FpdCBzeW5jZXJGaWxlc3lzdGVtLnVubGluayhsb2NrUGF0aCk7XG4gICAgfVxuICAgIGF3YWl0IHRoaXMuc3luYygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhdGNoZXLqsIAgYmF0Y2jroZwg66qo7J2AIOuzgOqyvSDtjIzsnbzrk6Tsl5Ag64yA7ZW0IO2VnCDrsojsnZggSE1SL3N5bmMg7IKs7J207YG07J2EIOuPleuLiOuLpC5cbiAgICpcbiAgICogSE1S7J2AIGFwaS9zcmMg7JWI7JeQ7IScIOydvOyWtOuCmOuKlCDrqqjrk6Ag7YyM7J2865Ok7JeQIOuMgO2VtOyEnCDsiJjtlontlanri4jri6QuXG4gICAqIGNoZWNrc3VtUGF0dGVybkdyb3VwIOunpOy5rSDsl6zrtoDsmYAg66y06rSA7ZWY6rKMIGFwaS9zcmMg7KCE7LK0IOuMgOyDgeyeheuLiOuLpC5cbiAgICog6rCA66C5IGFwaS9zcmMvdXRpbHMvc3Vic2V0LWxvYWRlcnMudHMg6rCZ7J2AIO2MjOydvOuPhCDrs4Dqsr3rkJjrqbQgSE1S7J2AIO2VtOykjeuLiOuLpC5cbiAgICpcbiAgICogU3luY+uKlCBjaGVja3N1bVBhdHRlcm5Hcm91cOycvOuhnCDrp6Tsua3rkJjripQg7YyM7J2865Ok7JeQIOuMgO2VtOyEnOunjCDsiJjtlontlanri4jri6QuXG4gICAqIOyXrOq4sOyXkOuKlCB3ZWIvc3Jj64KYIGFwcC9zcmMg6rCZ7J2AIOuLpOuluCB0YXJnZXTsnZgg7YyM7J287J20IO2PrO2VqOuQoCDsiJgg7J6I7Iq164uI64ukLlxuICAgKiDsnbTrn7Agbm9uLWFwaSDqsr3roZzsnZgg7YyM7J2865Ok7J2AIEhNUuqzvOuKlCDslYTrrLQg7IOB6rSA7J20IOyXhuycvOuvgOuhnCwgaW52YWxpZGF0ZeydhCDtlZjsp4Ag7JWK7Iq164uI64ukLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZUV2ZW50cyAtIHBhdGgg4oaSIGV2ZW50IOuntS4gZXZlbnTripQgXCJjaGFuZ2VcIiB8IFwiYWRkXCIuXG4gICAqL1xuICBhc3luYyBobXJBbmRTeW5jKGZpbGVFdmVudHM6IE1hcDxBYnNvbHV0ZVBhdGgsIFwiY2hhbmdlXCIgfCBcImFkZFwiPik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGhtckFjdGlvblJlcXVpcmVkRXZlbnRzID0gdGhpcy5leHRyYWN0SG1yQWN0aW9uUmVxdWlyZWRGaWxlRXZlbnRzKGZpbGVFdmVudHMpO1xuICAgIGNvbnN0IHN5bmNUcmlnZ2VyaW5nUGF0aHMgPSBhd2FpdCB0aGlzLmV4dHJhY3RTeW5jVHJpZ2dlcmluZ0ZpbGVFdmVudFBhdGhzKGZpbGVFdmVudHMpO1xuXG4gICAgLy8gSE1SIOyYgeyXrTog7YyM7J28IOydtOuypO2KuCDspJEgYXBp7J2YIOuqqOuTiCDqt7jrnpjtlITsl5Ag7J6I64qUIO2MjOydvOuTpOyXkCDrjIDtlZwg67OA64+Z7J2AIGhtckFjdGlvblJlcXVpcmVkRXZlbnRz66GcIOyeoe2emeuLiOuLpC5cbiAgICAvLyDsnbQg7Lmc6rWs65Ok7J2AIGludmFsaWRhdGUg7LKY66as7ZW07KSN64uI64ukLlxuICAgIC8vIOydtCDtmLjstpzsnYAg7JWE656YIHN5bmPrs7Tri6Qg66y07KGw6rG0IOuovOyggCDsnbzslrTrgpjslbwg7ZWp64uI64ukIVxuICAgIC8vIOyZnOuDkO2VmOuptCBzeW5j7JeQ7ISc64qUIOuzgOqyveuQnCBtb2RlbCDsvZTrk5zrpbwg7IOI66GcIGltcG9ydO2VtOyEnCDsspjrpqztlbTslbwg7ZWY64qUIOqyveyasOuPhCDsnojquLAg65WM66y47J6F64uI64ukLlxuICAgIGF3YWl0IHRoaXMuaW52YWxpZGF0ZURlcGVuZGVudHNBZmZlY3RlZEJ5RmlsZUV2ZW50cyhobXJBY3Rpb25SZXF1aXJlZEV2ZW50cyk7XG5cbiAgICAvLyBTeW5jIOyYgeyXrTogY2hlY2tzdW1QYXR0ZXJuR3JvdXDsl5Ag66qF7Iuc65CcIO2MjOydvOuTpOyXkCDrjIDtlZwg67OA64+Z7J2AIHN5bmNUcmlnZ2VyaW5nUGF0aHProZwg7J6h7Z6Z64uI64ukLlxuICAgIC8vIOydtCDsuZzqtazrk6TsnYAg7KCB7KCI7ZWcIHN5bmMg7J6R7JeF7Jy866GcIOuMgOydke2VqeuLiOuLpC5cbiAgICBpZiAoc3luY1RyaWdnZXJpbmdQYXRocy5sZW5ndGggPiAwKSB7XG4gICAgICBhd2FpdCB0aGlzLmRvU3luY0FjdGlvbnMoc3luY1RyaWdnZXJpbmdQYXRocyk7XG4gICAgfVxuXG4gICAgLy8g7Iux7YGsIOyekeyXheydtCDrgZ3rgqzsnLzrqbQg66y07KeA7ISxIOuhnOuTnOulvCDsiJjtlontlanri4jri6QuXG4gICAgLy8g7Iux7YGs66W8IOyViCDtlZwg6rK97Jqw7JeQ64+EIOuhnOuTnOuKlCDtlbTslbwg7ZW07JqULiDsnITsl5DshJwg6rSA66Co7J6I64qUIOy5nOq1rOuTpOydgCDri6QgaW52YWxpZGF0ZSDrkJjsl4jqsbDrk6DsmpQhXG4gICAgLy9cbiAgICAvLyDrs4Dqsr3rkJwg7YyM7J2865Ok7JeQIOuMgO2VtOyEnCDsg4jroa3qsowg64u56rKo7Jik64qUKGxvYWQpIO2WieychOuKlCBkb1N5bmNBY3Rpb25z7JeQ7IScIO2VmOyngCDslYrsirXri4jri6QuXG4gICAgLy8gZG9TeW5jQWN0aW9uc+yXkOyEnOuKlCDtjIzsnbzsnYQg7J296rOgIOunjOuTnOuKlCDsi7Htgawg7ZaJ7JyE66eMIO2VqeuLiOuLpC5cbiAgICAvLyDqsbDquLDshJwg65SxIOuzgOqyveuQnCDrtoDrtoTsl5Ag7JiB7Zal67Cb64qUIGF1dG9sb2Fk66eMIOyEoOuzhO2VtOyEnCDsiJjtlontlZjroKTrqbQg64SI66y0IOyngOyggOu2hO2VmOqzoCDrs7XsnqHtlbTsp5Hri4jri6QuXG4gICAgLy9cbiAgICAvLyDtjbztj6zrqLzsiqQg7JiB7Zal7J2AIOustOyLnO2VtOuPhCDsoovsirXri4jri6QuXG4gICAgLy8g7Ja07LCo7ZS8IGhtci1ob29r7JeQIOydmO2VtCBpbnZhbGlkYXRl65CcIOu2gOu2hOuTpOydtCDslYTri4jrnbzrqbQg7LqQ7IucIOq3uOuMgOuhnCDsnKDsp4Dtlanri4jri6QuXG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZE1vZGVscygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRBcGlzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZFdvcmtmbG93cygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRTc3JSb3V0ZXMoKTtcbiAgICBhd2FpdCBTb25hbXUucmVmcmVzaEh0dHBWYWxpZGF0b3JzKCk7XG5cbiAgICB0aGlzLmV2ZW50RW1pdHRlci5lbWl0KFwib25ITVJDb21wbGV0ZWRcIik7XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RIbXJBY3Rpb25SZXF1aXJlZEZpbGVFdmVudHMoXG4gICAgZmlsZUV2ZW50czogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+LFxuICApOiBNYXA8QWJzb2x1dGVQYXRoLCBcImNoYW5nZVwiIHwgXCJhZGRcIj4ge1xuICAgIGNvbnN0IGFwaVNyYyA9IHBhdGguam9pbihTb25hbXUuYXBpUm9vdFBhdGgsIFwic3JjXCIpO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBNYXA8QWJzb2x1dGVQYXRoLCBcImNoYW5nZVwiIHwgXCJhZGRcIj4oKTtcbiAgICBmb3IgKGNvbnN0IFtmaWxlUGF0aCwgZXZlbnRdIG9mIGZpbGVFdmVudHMpIHtcbiAgICAgIGlmICghZmlsZVBhdGguc3RhcnRzV2l0aChhcGlTcmMpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnNldChmaWxlUGF0aCwgZXZlbnQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBleHRyYWN0U3luY1RyaWdnZXJpbmdGaWxlRXZlbnRQYXRocyhcbiAgICBmaWxlRXZlbnRzOiBNYXA8QWJzb2x1dGVQYXRoLCBcImNoYW5nZVwiIHwgXCJhZGRcIj4sXG4gICk6IFByb21pc2U8QWJzb2x1dGVQYXRoW10+IHtcbiAgICBjb25zdCBjaGVja1BhdHRlcm5Hcm91cCA9IGdldENoZWNrc3VtUGF0dGVybkdyb3VwSW5BYnNvbHV0ZVBhdGgoKTtcbiAgICBjb25zdCBzeW5jVHJpZ2dlcmluZ1BhdGhzOiBBYnNvbHV0ZVBhdGhbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgW2RpZmZGaWxlUGF0aF0gb2YgZmlsZUV2ZW50cykge1xuICAgICAgY29uc3QgaXNJbkNoZWNrUGF0dGVybkdyb3VwID0gT2JqZWN0LnZhbHVlcyhjaGVja1BhdHRlcm5Hcm91cCkuc29tZSgocGF0dGVybikgPT5cbiAgICAgICAgbWluaW1hdGNoKGRpZmZGaWxlUGF0aCwgcGF0dGVybiksXG4gICAgICApO1xuICAgICAgaWYgKCFpc0luQ2hlY2tQYXR0ZXJuR3JvdXApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBzeW5jVHJpZ2dlcmluZ1BhdGhzLnB1c2goZGlmZkZpbGVQYXRoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3luY1RyaWdnZXJpbmdQYXRocztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW52YWxpZGF0ZURlcGVuZGVudHNBZmZlY3RlZEJ5RmlsZUV2ZW50cyhcbiAgICBmaWxlRXZlbnRzOiBNYXA8QWJzb2x1dGVQYXRoLCBcImNoYW5nZVwiIHwgXCJhZGRcIj4sXG4gICkge1xuICAgIGZvciAoY29uc3QgW2RpZmZGaWxlUGF0aCwgZXZlbnRdIG9mIGZpbGVFdmVudHMpIHtcbiAgICAgIC8vIOuzgOqyveuQnCDtjIzsnbzqs7wgZGVwZW5kZW50IO2MjOydvOuTpOydhCBpbnZhbGlkYXRlIO2VqeuLiOuLpC5cbiAgICAgIC8vIO2VnCDrsogg7J207IOBIGltcG9ydOuQnCDsuZzqtazrk6Tsl5Ag64yA7ZW07ISc66eMIOyLpOygnCDsnpHsl4XsnbQg7J287Ja064Kp64uI64ukLlxuICAgICAgLy8g6re465+s64uIIOyViOyLrO2VmOqzoCBpbnZhbGlkYXRlIO2VtOuPhCDrkKnri4jri6QuXG4gICAgICAvLyDthYzsiqTtirgg7ZmY6rK97JeQ7ISc64qUIGhvdC5pbnZhbGlkYXRlRmlsZeyLnCDstIjquLAg7JeQ65+s6rCAIOuwnOyDne2VmOq4sCDrlYzrrLjsl5AgaW52YWxpZGF0ZSDtlZjsp4Ag7JWK7Iq164uI64ukLlxuICAgICAgaWYgKCFpc1Rlc3QoKSkge1xuICAgICAgICBjb25zdCBpbnZhbGlkYXRlZFBhdGhzID1cbiAgICAgICAgICAvKiBTQUZFVFk6IFR5cGVTY3JpcHQgQVNUIO2MjOyLseqzvCDrj5nquLDtmZQg7J6F66ClIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIChhd2FpdCBob3QuaW52YWxpZGF0ZUZpbGUoXG4gICAgICAgICAgICBkaWZmRmlsZVBhdGgsXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICApKSBhcyBBYnNvbHV0ZVBhdGhbXTtcblxuICAgICAgICBpZiAoaW52YWxpZGF0ZWRQYXRocy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coY2hhbGsuYm9sZChg8J+UhCBJbnZhbGlkYXRlZDpgKSk7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IGludmFsaWRhdGVkUGF0aCBvZiBpbnZhbGlkYXRlZFBhdGhzKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAvLyDrp4zslb0gbW9kZWwudHMg7YyM7J287J20IOuzgOqyvShpbnZhbGlkYXRlKeuQmOyXiOuLpD8g6re465+s66m0IHJlZ2lzdGVyZWRBcGlzIOykkeyXkOyEnCDsnbQg66qo64247JeQIO2VtOuLue2VmOuKlCBhcGnrk6TsnYAg7KeA7JuM7KSY7JqULlxuICAgICAgICAgICAgICAvLyByZWdpc3RlcmVkQXBpc+uKlCDthrXsnLzroZwg64ukIOuCoOugpOuyhOumtCDsiJgg7JeG7Iq164uI64ukLiByZWdpc3RlcmVkQXBpc+yXkCDsmKzrnbzsmKTripQg7Lmc6rWs65Ok7J2AIOy0iOq4sCDroZzrk5zsi5wg65iQ64qUIEhNUuyLnOyXkOunjCDrk7HroZ3rkJjquLAg65WM66y47J6F64uI64ukLlxuICAgICAgICAgICAgICAvLyDrlLDrnbzshJwgbW9kZWwudHMg7YyM7J287J2YIOuzgOqyveycvOuhnCDri6TsnYzrsogg7IOI66Gc7Jq0IGV2YWzsnbQg7JiI7IOB65CY64qUIOydtCDsi5zsoJDsl5DshJzrp4wsIOydtCDrqqjrjbjsl5DshJwg64KY7JioIHJlZ2lzdGVyZWRBcGlz65Ok7J2EIOyngOybjOykhCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgICAgICAgICBjb25zdCByZW1vdmVkQXBpcyA9IHRoaXMucmVtb3ZlSW52YWxpZGF0ZWRSZWdpc3RlcmVkQXBpcyhpbnZhbGlkYXRlZFBhdGgpO1xuICAgICAgICAgICAgICBpZiAocmVtb3ZlZEFwaXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgY2hhbGsuYmx1ZShgLSAke3BhdGgucmVsYXRpdmUoU29uYW11LmFwaVJvb3RQYXRoLCBpbnZhbGlkYXRlZFBhdGgpfWApLFxuICAgICAgICAgICAgICAgICAgY2hhbGsuZ3JheShgKHdpdGggJHtyZW1vdmVkQXBpcy5sZW5ndGh9IEFQSXMpYCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5ibHVlKGAtICR7cGF0aC5yZWxhdGl2ZShTb25hbXUuYXBpUm9vdFBhdGgsIGludmFsaWRhdGVkUGF0aCl9YCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgY2hhbGsucmVkKGBGYWlsZWQgdG8gcmVtb3ZlIGludmFsaWRhdGVkIHJlZ2lzdGVyZWQgQVBJcyBmb3IgJHtpbnZhbGlkYXRlZFBhdGh9YCksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGRldlJ1bm5lciDtmZzshLHtmZQg7IucLCDrs4Dqsr3rkJwg7IaM7IqkIO2MjOydvOydhCBWaXRlc3Qg66qo65OIIOq3uOuemO2UhOyXkOyEnOuPhCDrrLTtmqjtmZTtlanri4jri6QuXG4gICAgICAvLyBWaXRl7J2YIG1vZHVsZUdyYXBoLmludmFsaWRhdGVNb2R1bGUoKeydtCBpbXBvcnRlciDrsKntlqXsnLzroZwg7J6s6reA7KCBIGNhc2NhZGXtlZjrr4DroZwsXG4gICAgICAvLyDshozsiqQg7YyM7J28IO2VmOuCmOunjCDrrLTtmqjtmZTtlZjrqbQg7J2066W8IGltcG9ydO2VmOuKlCDthYzsiqTtirgg7YyM7J2864+EIOyekOuPmeycvOuhnCDrrLTtmqjtmZTrkKnri4jri6QuXG4gICAgICBpZiAoIWlzVGVzdCgpICYmIFNvbmFtdS5jb25maWcudGVzdD8uZGV2UnVubmVyPy5lbmFibGVkICYmIFNvbmFtdS5kZXZWaXRlc3RNYW5hZ2VyKSB7XG4gICAgICAgIFNvbmFtdS5kZXZWaXRlc3RNYW5hZ2VyLmludmFsaWRhdGVGaWxlcyhbZGlmZkZpbGVQYXRoXSk7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGNoYWxrLmRpbShgVGVzdCBpbnZhbGlkYXRlZDogJHtwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcGlSb290UGF0aCwgZGlmZkZpbGVQYXRoKX1gKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZW1vdmVJbnZhbGlkYXRlZFJlZ2lzdGVyZWRBcGlzKFxuICAgIGludmFsaWRhdGVkUGF0aDogQWJzb2x1dGVQYXRoLFxuICApOiAodHlwZW9mIHJlZ2lzdGVyZWRBcGlzKVtudW1iZXJdW10ge1xuICAgIC8vIOyGjOyKpCDsvZTrk5zrpbwg64uk66Oo64qUIOyDge2ZqeydtOuLiCAudHMg6rK966Gc66GcIOu0heuLiOuLpC5cbiAgICBjb25zdCBpc01vZGVsID0gaW52YWxpZGF0ZWRQYXRoLmVuZHNXaXRoKFwiLm1vZGVsLnRzXCIpO1xuICAgIGNvbnN0IGlzRnJhbWUgPSBpbnZhbGlkYXRlZFBhdGguZW5kc1dpdGgoXCIuZnJhbWUudHNcIik7XG4gICAgaWYgKCFpc01vZGVsICYmICFpc0ZyYW1lKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgZW50aXR5SWQgPSBFbnRpdHlNYW5hZ2VyLmdldEVudGl0eUlkRnJvbVBhdGgoaW52YWxpZGF0ZWRQYXRoKTtcbiAgICBjb25zdCB0YXJnZXRNb2RlbE5hbWUgPSBgJHtlbnRpdHlJZH0ke2lzTW9kZWwgPyBcIk1vZGVsXCIgOiBcIkZyYW1lXCJ9YDtcbiAgICBjb25zdCB0b1JlbW92ZSA9IHJlZ2lzdGVyZWRBcGlzLmZpbHRlcigoYXBpKSA9PiBhcGkubW9kZWxOYW1lID09PSB0YXJnZXRNb2RlbE5hbWUpO1xuICAgIGZvciAoY29uc3QgYXBpIG9mIHRvUmVtb3ZlKSB7XG4gICAgICBjb25zdCBpZHggPSByZWdpc3RlcmVkQXBpcy5pbmRleE9mKGFwaSk7XG4gICAgICBpZiAoaWR4ICE9PSAtMSkge1xuICAgICAgICByZWdpc3RlcmVkQXBpcy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdG9SZW1vdmU7XG4gIH1cblxuICBhc3luYyBhdXRvbG9hZFR5cGVzKCkge1xuICAgIHRoaXMudHlwZXMgPSBhd2FpdCBsb2FkVHlwZXMoKTtcbiAgfVxuXG4gIGFzeW5jIGF1dG9sb2FkTW9kZWxzKCkge1xuICAgIHRoaXMubW9kZWxzID0gYXdhaXQgbG9hZE1vZGVscygpO1xuICB9XG5cbiAgYXN5bmMgYXV0b2xvYWRBcGlzKCkge1xuICAgIHRoaXMuYXBpcyA9IGF3YWl0IGxvYWRBcGlzKCk7XG4gIH1cblxuICBhc3luYyBhdXRvbG9hZFdvcmtmbG93cygpIHtcbiAgICB0aGlzLndvcmtmbG93cyA9IGF3YWl0IGxvYWRXb3JrZmxvd3MoKTtcbiAgICBhd2FpdCBTb25hbXUud29ya2Zsb3dzLnN5bmNocm9uaXplKHRoaXMud29ya2Zsb3dzKTtcbiAgfVxuXG4gIGFzeW5jIGF1dG9sb2FkU3NyUm91dGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNzckNvbmZpZ1BhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwaVJvb3RQYXRoLCBcInNyYy9zc3JcIik7XG5cbiAgICAvLyDquLDsobQgcm91dGVzIOy0iOq4sO2ZlFxuICAgIGNvbnN0IHsgY2xlYXJTU1JSb3V0ZXMgfSA9IGF3YWl0IGltcG9ydChcIi4uL3NzclwiKTtcbiAgICBjbGVhclNTUlJvdXRlcygpO1xuXG4gICAgLy8gc3NyIO2PtOuNlCDsl4bsnLzrqbQg7Iqk7YK1XG4gICAgaWYgKCEoYXdhaXQgc3luY2VyRmlsZUV4aXN0cyhzc3JDb25maWdQYXRoKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBzc3Ig7Y+0642UIOyViOydmCDrqqjrk6AgLnRzIO2MjOydvCDroZzrk5xcbiAgICBjb25zdCB7IGdsb2JBc3luYyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvYXN5bmMtdXRpbHNcIik7XG4gICAgY29uc3QgeyBpbXBvcnRNZW1iZXJzIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9lc20tdXRpbHNcIik7XG4gICAgY29uc3QgeyBydW50aW1lUGF0aCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvcGF0aC11dGlsc1wiKTtcblxuICAgIC8vIHJ1bnRpbWVQYXRo66W8IOyCrOyaqe2VmOyXrCDqsJzrsJwv7ZSE66Gc642V7IWYIO2ZmOqyveyXkCDrp57ripQg7ZmV7J6l7J6QIOyymOumrFxuICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgZ2xvYkFzeW5jKHBhdGguam9pbihzc3JDb25maWdQYXRoLCBydW50aW1lUGF0aChcIioqLyoudHNcIikpKTtcblxuICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gaW1wb3J0TWVtYmVyc+ulvCDsgqzsmqntlZjrqbQg7YyM7J287J2YIHNpZGUgZWZmZWN0KHJlZ2lzdGVyU1NSIO2YuOy2nCnqsIAg7Iuk7ZaJ65CoXG4gICAgICAgIGF3YWl0IGltcG9ydE1lbWJlcnMoZmlsZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBsb2FkIFNTUiByb3V0ZTogJHtmaWxlfWAsIGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDsi6TsoJwg7Iux7YGs66W8IOyImO2Wie2VmOuKlCDrs7jssrTsnoXri4jri6QuXG4gICAqIOuzgOqyveuQnCDtjIzsnbzrk6TsnYQg7YOA7J6F67OE66GcIOu2hOulmO2VmOqzoCDqsIEg7YOA7J6F7JeQIOunnuuKlCDslaHshZjsnYQg7Iuk7ZaJ7ZWp64uI64ukLlxuICAgKlxuICAgKiBAcGFyYW0gZGlmZkZpbGVQYXRocyAtIOuzgOqyveuQnCDtjIzsnbzrk6TsnZgg7KCI64yAIOqyveuhnCDrqqnroZ1cbiAgICogQHJldHVybnMgZGlmZlR5cGVzIC0g67OA6rK965CcIO2MjOydvOydmCDtg4DsnoUg66qp66GdIChlbnRpdHksIHR5cGVzLCBtb2RlbCDrk7EpXG4gICAqL1xuICBhc3luYyBkb1N5bmNBY3Rpb25zKGRpZmZGaWxlUGF0aHM6IEFic29sdXRlUGF0aFtdKTogUHJvbWlzZTx7IGRpZmZUeXBlczogRmlsZVR5cGVbXSB9PiB7XG4gICAgY29uc3QgZGlmZkdyb3VwcyA9IHRoaXMuY2FsY3VsYXRlRGlmZkdyb3VwcyhkaWZmRmlsZVBhdGhzKTtcbiAgICBjb25zdCBkaWZmVHlwZXMgPVxuICAgICAgLyogU0FGRVRZOiBUeXBlU2NyaXB0IEFTVCDtjIzsi7Hqs7wg64+Z6riw7ZmUIOyeheugpSDqs4Tslb3snbQg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyBPYmplY3Qua2V5cyhcbiAgICAgICAgZGlmZkdyb3VwcyxcbiAgICAgICkgYXMgRmlsZVR5cGVbXTtcblxuICAgIC8vIOyXrOq4sOuKlCDrs4TroZwg7KSR7JqU7ZWcIO2MjO2KuOuKlCDslYTri5nri4jri6QuXG4gICAgLy8g7JWE656Y7J2YIGlmIOyghOqwnOulvCDquZTrgZTtlZjqsowg7ZWY66Ck6rOgIOunjOuToCBEU0wg6rCZ7J2AIOqxsOudvOyEnCwg66y07Iuc7ZWY7IWU64+EIOuQqeuLiOuLpC5cbiAgICBjb25zdCB7IGNoYW5nZU1hdGNoZXMsIG5vdGhpbmdNYXRjaGVzLCB1bmhhbmRsZWRQYXRocyB9ID0gdGhpcy5jaGFuZ2VNYXRjaGVyKFxuICAgICAgZGlmZlR5cGVzLFxuICAgICAgZGlmZkdyb3VwcyxcbiAgICApO1xuXG4gICAgaWYgKGNoYW5nZU1hdGNoZXMoXCJlbnRpdHlcIiwgXCJ0eXBlc1wiKSkge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVUcnV0aFNvdXJjZUNoYW5nZXMoZGlmZkdyb3Vwcyk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZU1hdGNoZXMoXCJtb2RlbFwiLCBcImZyYW1lXCIpKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUltcGxlbWVudGF0aW9uQ2hhbmdlcyhkaWZmR3JvdXBzKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlTWF0Y2hlcyhcInR5cGVzXCIsIFwiZnVuY3Rpb25zXCIpKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUF1eGlsaWFyeVN5bWJvbENoYW5nZXMoZGlmZkdyb3Vwcyk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZU1hdGNoZXMoXCJjb25maWdcIikpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ29uZmlnQ2hhbmdlcygpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VNYXRjaGVzKFwiaTE4blwiLCBcImVudGl0eVwiIC8q66CI7J2067iUKi8sIFwiY29uZmlnXCIgLypkZWZhdWx0TG9jYWxl65OxKi8pKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZVNvbmFtdURpY3Rpb25hcnlSZWxhdGVkQ2hhbmdlcygpO1xuICAgIH1cblxuICAgIGNvbnN0IG1ldGFkYXRhQ2hhbmdlZCA9IGRpZmZUeXBlcy5zb21lKCh0eXBlKSA9PlxuICAgICAgW1wiZW50aXR5XCIsIFwidHlwZXNcIiwgXCJtb2RlbFwiLCBcImZyYW1lXCIsIFwiY29uZmlnXCJdLmluY2x1ZGVzKHR5cGUpLFxuICAgICk7XG4gICAgaWYgKGNoYW5nZU1hdGNoZXMoXCJodHRwVmFsaWRhdG9yc0dlbmVyYXRlZFwiKSAmJiAhbWV0YWRhdGFDaGFuZ2VkKSB7XG4gICAgICAvLyByZWdpc3RyeSDsnpDssrQgZHJpZnTripQg7LWc7IugIGluLW1lbW9yeSBtZXRhZGF0YeuhnCDsponsi5wg642u7Ja07I2oIGxvY2sg6rCx7IugIOyghOyXkCDsoJXtlanshLHsnYQg67O16rWs7ZWp64uI64ukLlxuICAgICAgYXdhaXQgdGhpcy5kZXBlbmRlbmNpZXMuYWN0aW9uR2VuZXJhdGVIdHRwVmFsaWRhdG9ycygpO1xuICAgIH1cblxuICAgIGlmIChtZXRhZGF0YUNoYW5nZWQpIHtcbiAgICAgIC8vIOuqqOuToCDsg53shLEv67O17IKsIOyVoeyFmCDrkqQg7LWc7IugIG1ldGFkYXRh66W8IOuLpOyLnCDsnb3slrQgcmVnaXN0cnnrpbwg7ZWcIOuyiOunjCDtmZXsoJXtlanri4jri6QuXG4gICAgICBhd2FpdCB0aGlzLmF1dG9sb2FkVHlwZXMoKTtcbiAgICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRNb2RlbHMoKTtcbiAgICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRBcGlzKCk7XG4gICAgICBhd2FpdCB0aGlzLmRlcGVuZGVuY2llcy5hY3Rpb25HZW5lcmF0ZUh0dHBWYWxpZGF0b3JzKCk7XG4gICAgfVxuXG4gICAgaWYgKG5vdGhpbmdNYXRjaGVzKCkpIHtcbiAgICAgIC8vIO2MjOydvCDrs4Dqsr3snYAg6rCQ7KeA65CY7JeI7Jy864KYIOyggCDsnIQg7Ja064qQIGNoYW5nZU1hdGNoZXPsl5Drj4Qg6rG466as7KeAIOyViuydgCDtjIzsnbzrk6TsnbQgZHJpZnRz7J6F64uI64ukLlxuICAgICAgLy8gc3luY2Vy64qUIOyGjOyKpOydmCDrs4Dqsr3sl5DripQg67CY7J2R7ZWY7KeA66eMIOyCsOy2nOusvOydmCDrs4Dqsr0oZHJpZnQp7JeQ64qUIOyngeygkeyggeycvOuhnCDrsJjsnZHtlZjsp4Ag7JWK7Iq164uI64ukLlxuICAgICAgLy8g64yA7IugIOydtCBkcmlmdOyXkCDrjIDtlbQg6rK96rOgIOygleuPhOunjCDstpzroKXtlbTspI3ri4jri6QuXG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZURyaWZ0cyh1bmhhbmRsZWRQYXRocygpKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGlmZlR5cGVzLFxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVEaWZmR3JvdXBzKGRpZmZGaWxlczogQWJzb2x1dGVQYXRoW10pIHtcbiAgICBjb25zdCBwYXR0ZXJuR3JvdXAgPSBnZXRDaGVja3N1bVBhdHRlcm5Hcm91cCgpO1xuICAgIGNvbnN0IGZpbGVUeXBlcyA9XG4gICAgICAvKiBTQUZFVFk6IFR5cGVTY3JpcHQgQVNUIO2MjOyLseqzvCDrj5nquLDtmZQg7J6F66ClIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIE9iamVjdC5rZXlzKFxuICAgICAgICBwYXR0ZXJuR3JvdXAsXG4gICAgICApIGFzIEZpbGVUeXBlW107XG5cbiAgICBjb25zdCBkaWZmR3JvdXBzOiBEaWZmR3JvdXBzID0ge307XG4gICAgZm9yIChjb25zdCBmaWxlUGF0aCBvZiBkaWZmRmlsZXMpIHtcbiAgICAgIC8vIOygiOuMgCDqsr3roZzrpbwgYXBwUm9vdCDquLDspIAg7IOB64yAIOqyveuhnOuhnCDrsJTqv5Qg7LK07YGs7ISsIO2MqO2EtOqzvCDruYTqtZDtlZzri6QuXG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcHBSb290UGF0aCwgZmlsZVBhdGgpO1xuICAgICAgY29uc3QgZmlsZVR5cGUgPSBmaWxlVHlwZXMuZmluZCgoY2FuZGlkYXRlKSA9PlxuICAgICAgICBtaW5pbWF0Y2gocmVsYXRpdmVQYXRoLCBwYXR0ZXJuR3JvdXBbY2FuZGlkYXRlXSksXG4gICAgICApO1xuICAgICAgY29uc3QgZ3JvdXBLZXk6IERpZmZHcm91cEtleSA9IHJlbGF0aXZlUGF0aC5zdGFydHNXaXRoKFwiLi5cIilcbiAgICAgICAgPyBcInVua25vd25cIlxuICAgICAgICA6IChmaWxlVHlwZSA/PyBcInVua25vd25cIik7XG4gICAgICAoZGlmZkdyb3Vwc1tncm91cEtleV0gPz89IFtdKS5wdXNoKGZpbGVQYXRoKTtcbiAgICB9XG4gICAgcmV0dXJuIGRpZmZHcm91cHM7XG4gIH1cblxuICBwcml2YXRlIGNoYW5nZU1hdGNoZXIoZGlmZlR5cGVzOiBGaWxlVHlwZVtdLCBkaWZmR3JvdXBzOiBEaWZmR3JvdXBzKSB7XG4gICAgY29uc3QgaGFuZGxlZCA9IG5ldyBTZXQ8RmlsZVR5cGU+KCk7XG5cbiAgICAvKipcbiAgICAgKiDrs4Dqsr0g7IKs7ZWt7J20IOyduOyekOuhnCDrsJvsnYAgRmlsZVR5cGXrk6Qg7KSRIO2VmOuCmCDsnbTsg4HsnYQg7Y+s7ZWo7ZWY64qU7KeAIO2ZleyduO2VqeuLiOuLpC5cbiAgICAgKiDqsIDroLkgW1wiZW50aXR5XCJd6rCAIOuzgOqyveuQnCDtmLjstpzsl5DshJwgY2hhbmdlTWF0Y2hlcyhcImVudGl0eVwiKeuKlCB0cnll66W8IOuwmO2ZmO2VmOupsCxcbiAgICAgKiBbXCJ0eXBlc1wiLCBcImkxOG5cIl3snbQg67OA6rK965CcIO2YuOy2nOyXkOyEnCBjaGFuZ2VNYXRjaGVzKFwidHlwZXNcIiwgXCJmdW5jdGlvbnNcIinrj4QgdHJ1ZeulvCDrsJjtmZjtlZjsp4Drp4wsXG4gICAgICogW1wiZnVuY3Rpb25zXCJd6rCAIOuzgOqyveuQnCDtmLjstpzsl5DshJwgY2hhbmdlTWF0Y2hlcyhcImZyYW1lXCIp7J2AIGZhbHNl66W8IOuwmO2ZmO2VqeuLiOuLpC5cbiAgICAgKiBAcGFyYW0gdHlwZXNcbiAgICAgKi9cbiAgICBjb25zdCBjaGFuZ2VNYXRjaGVzID0gKC4uLnR5cGVzOiBGaWxlVHlwZVtdKSA9PiB7XG4gICAgICBjb25zdCBtYXRjaGluZyA9IHR5cGVzLmZpbHRlcigodCkgPT4gZGlmZlR5cGVzLmluY2x1ZGVzKHQpKTtcbiAgICAgIG1hdGNoaW5nLmZvckVhY2goKHQpID0+IGhhbmRsZWQuYWRkKHQpKTtcbiAgICAgIHJldHVybiBtYXRjaGluZy5sZW5ndGggPiAwO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBjaGFuZ2VNYXRjaGVz66GcIOunpOy5reuQnCDqsoPsnbQg7ZWY64KY64+EIOyXhuuKlOyngCDsl6zrtoDrpbwg6rCA7KC47Ji164uI64ukLlxuICAgICAqL1xuICAgIGNvbnN0IG5vdGhpbmdNYXRjaGVzID0gKCkgPT4gaGFuZGxlZC5zaXplID09PSAwO1xuXG4gICAgLyoqXG4gICAgICog7Ja065akIGNoYW5nZU1hdGNoZXMg7Zi47Lac7JeQ64+EIOqxuOumrOyngCDslYrsnYAgRmlsZVR5cGXrk6TsnZgg7Iuk7KCcIO2MjOydvCDqsr3roZzrpbwg66qo7JWE7IScIOuwmO2ZmO2VqeuLiOuLpC5cbiAgICAgKi9cbiAgICBjb25zdCB1bmhhbmRsZWRQYXRocyA9ICgpOiBBYnNvbHV0ZVBhdGhbXSA9PlxuICAgICAgZGlmZlR5cGVzLmZpbHRlcigodCkgPT4gIWhhbmRsZWQuaGFzKHQpKS5mbGF0TWFwKCh0KSA9PiBkaWZmR3JvdXBzW3RdID8/IFtdKTtcblxuICAgIHJldHVybiB7IGNoYW5nZU1hdGNoZXMsIG5vdGhpbmdNYXRjaGVzLCB1bmhhbmRsZWRQYXRocyB9O1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlVHJ1dGhTb3VyY2VDaGFuZ2VzKGRpZmZHcm91cHM6IERpZmZHcm91cHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBOYWl0ZS50KFwiaGFuZGxlVHJ1dGhTb3VyY2VDaGFuZ2VzXCIsIHsgZGlmZkdyb3VwcyB9KTtcblxuICAgIGF3YWl0IEVudGl0eU1hbmFnZXIucmVsb2FkKCk7XG5cbiAgICAvLyB0eXBlcyDsg53shLEoZW50aXR5IOyDiOuhnCDstpTqsIDrkJwg6rK97JqwKVxuICAgIC8vIHBhcmVudElk6rCAIOyXhuqzoCwgdHlwZXPqsIAg7JeG64qUIOqyveyasOyXkOunjCDsg53shLFcbiAgICBjb25zdCBlbnRpdHlQYXRoID0gZGlmZkdyb3Vwcy5lbnRpdHk/LmF0KDApO1xuICAgIGlmIChlbnRpdHlQYXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGVudGl0eUlkID0gRW50aXR5TWFuYWdlci5nZXRFbnRpdHlJZEZyb21QYXRoKGVudGl0eVBhdGgpO1xuICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAvLyDtlITroZzsoJ3tirjsl5Ag7IOd7ISx65CY7Ja07JW8IO2VmOuKlCAudHMg7YyM7J287J2YIOqyveuhnOyeheuLiOuLpC5cbiAgICAgIGNvbnN0IHR5cGVGaWxlUGF0aCA9XG4gICAgICAgIC8qIFNBRkVUWTogVHlwZVNjcmlwdCBBU1Qg7YyM7Iux6rO8IOuPmeq4sO2ZlCDsnoXroKUg6rOE7JW97J20IOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gcGF0aC5qb2luKFxuICAgICAgICAgIFNvbmFtdS5hcGlSb290UGF0aCxcbiAgICAgICAgICBgc3JjL2FwcGxpY2F0aW9uLyR7ZW50aXR5Lm5hbWVzLmZzfS8ke2VudGl0eS5uYW1lcy5mc30udHlwZXMudHNgLFxuICAgICAgICApIGFzIEFic29sdXRlUGF0aDtcblxuICAgICAgaWYgKGVudGl0eS5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkICYmICEoYXdhaXQgc3luY2VyRmlsZUV4aXN0cyh0eXBlRmlsZVBhdGgpKSkge1xuICAgICAgICAvLyAqLnR5cGVzLnRz6rCAIOunjOuTpOyWtOynkeuLiOuLpC5cbiAgICAgICAgY29uc3QgdHlwZXMgPSBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlSW5pdGlhbFR5cGVzKGVudGl0eUlkKTtcblxuICAgICAgICAvLyDqt7jqsbgg7YOA6rKf7JeQIOqwluuLpOuRrOyalC5cbiAgICAgICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25TeW5jRmlsZXNUb1RhcmdldHModHlwZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNvbmFtdS5nZW5lcmF0ZWQudHPsmYAgc29uYW11LmdlbmVyYXRlZC5zc28udHPqsIAg66eM65Ok7Ja07KeR64uI64ukLlxuICAgIGNvbnN0IGdlbmVyYXRlZCA9IGF3YWl0IFN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVTY2hlbWFzKCk7XG5cbiAgICAvLyDrqqjrk6Ag6rKD65Ok7J2EIHRhcmdldOyXkCDrs7TrgrTsp4DripQg7JWK7Iq164uI64ukLlxuICAgIC8vIHNvbmFtdS5nZW5lcmF0ZWQuc3NvLnRz64qUIHNlcnZpY2Utc2lkZS1vbmx564uI6rmMIOuwsOygnO2VqeuLiOuLpC5cbiAgICAvLyBUT0RPKOuzkeykgCk6IOydtCDtlZjrk5zsvZTrk5zrpbwg64iE6rCAIO2VtOqysCDsooAg7ZW07KO87IS47JqULiDsnbzri6jsnYAg6rCQ64u5IOqwgOuKpe2VmOuLiCDrhpTrkZDqsqDsirXri4jri6QuLi5cbiAgICBjb25zdCBkaXN0cmlidXRhYmxlID0gZ2VuZXJhdGVkLmZpbHRlcigocCkgPT4gIXAuZW5kc1dpdGgoXCIuc3NvLnRzXCIpKTtcblxuICAgIC8vIOydtOygnCDrs7Trgrwg6rKD65Ok66eMIHRhcmdldOyXkCDrs7TrgrTsmpQuXG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25TeW5jRmlsZXNUb1RhcmdldHMoZGlzdHJpYnV0YWJsZSk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVJbXBsZW1lbnRhdGlvbkNoYW5nZXMoZGlmZkdyb3VwczogRGlmZkdyb3Vwcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIE5haXRlLnQoXCJoYW5kbGVJbXBsZW1lbnRhdGlvbkNoYW5nZXNcIiwgeyBkaWZmR3JvdXBzIH0pO1xuICAgIGNvbnN0IG1lcmdlZEdyb3VwID0gWy4uLihkaWZmR3JvdXBzLm1vZGVsID8/IFtdKSwgLi4uKGRpZmZHcm91cHMuZnJhbWUgPz8gW10pXTtcblxuICAgIC8vIGdlbmVyYXRlZF9odHRwLnRlbXBsYXRlLnRz7JeQ7IScIHN5bmNlci50eXBlc+ulvCDslIHri4jri6QuXG4gICAgLy8gc2VydmljZS50ZW1wbGF0ZS50c+yXkOyEnCBzeW5jZXIuYXBpc+ulvCDslIHri4jri6QuXG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZE1vZGVscygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRUeXBlcygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRBcGlzKCk7XG5cbiAgICBjb25zdCBwYXJhbXM6IHtcbiAgICAgIG5hbWVzUmVjb3JkOiBFbnRpdHlOYW1lc1JlY29yZDtcbiAgICB9W10gPSBtZXJnZWRHcm91cC5tYXAoKG1vZGVsUGF0aCkgPT4ge1xuICAgICAgaWYgKG1vZGVsUGF0aC5lbmRzV2l0aChcIi5tb2RlbC50c1wiKSB8fCBtb2RlbFBhdGguZW5kc1dpdGgoXCIuZnJhbWUudHNcIikpIHtcbiAgICAgICAgY29uc3QgZW50aXR5SWQgPSBFbnRpdHlNYW5hZ2VyLmdldEVudGl0eUlkRnJvbVBhdGgobW9kZWxQYXRoKTtcbiAgICAgICAgYXNzZXJ0KGVudGl0eUlkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lc1JlY29yZDogRW50aXR5TWFuYWdlci5nZXROYW1lc0Zyb21JZChlbnRpdHlJZCksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJub3QgcmVhY2hhYmxlXCIpO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZVNlcnZpY2VzKHBhcmFtcyk7XG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZUh0dHBzKCk7XG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZVNzclF1ZXJpZXMoKTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUF1eGlsaWFyeVN5bWJvbENoYW5nZXMoZGlmZkdyb3VwczogRGlmZkdyb3Vwcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIE5haXRlLnQoXCJoYW5kbGVBdXhpbGlhcnlTeW1ib2xDaGFuZ2VzXCIsIHsgZGlmZkdyb3VwcyB9KTtcbiAgICBjb25zdCB0c1BhdGhzID0gdW5pcXVlKFsuLi4oZGlmZkdyb3Vwcy50eXBlcyA/PyBbXSksIC4uLihkaWZmR3JvdXBzLmZ1bmN0aW9ucyA/PyBbXSldKTtcbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNGaWxlc1RvVGFyZ2V0cyh0c1BhdGhzKTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUNvbmZpZ0NoYW5nZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHByb2Nlc3MuZW52LkhPVCA9PT0gXCJ5ZXNcIikge1xuICAgICAgY29uc3QgeyBsb2FkQ29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9hcGkvY29uZmlnXCIpO1xuICAgICAgU29uYW11LmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcoU29uYW11LmFwaVJvb3RQYXRoKTtcbiAgICB9XG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25TeW5jQ29uZmlnKCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVTb25hbXVEaWN0aW9uYXJ5UmVsYXRlZENoYW5nZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25TeW5jU29uYW11RGljdGlvbmFyeSgpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlRHJpZnRzKGRyaWZ0czogQWJzb2x1dGVQYXRoW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoZHJpZnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgIFwi4pqg77iPIFNvbmFtdeqwgCDsnpDrj5kg7IOd7ISx7ZWcIO2MjOydvOyXkCDrjIDtlZwg67OA6rK97J20IOqwkOyngOuQmOyXiOyKteuLiOuLpC4g7YyM7J287J20IFNvbmFtdSB3YXRjaGVyIOyZuOu2gOyXkOyEnCDrs4Dqsr3rkJwg6rKD7Jy866GcIOy2lOygleuQqeuLiOuLpC5cIixcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IHAgb2YgZHJpZnRzKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihjaGFsay55ZWxsb3coYCAgLSAke3BhdGgucmVsYXRpdmUoU29uYW11LmFwcFJvb3RQYXRoLCBwKX1gKSk7XG4gICAgICB9XG4gICAgICBjb25zb2xlLndhcm4oY2hhbGsuZGltKFwiICDihpIgYHBucG0gc29uYW11IHN5bmMgLS1mb3JjZWDrpbwg6raM7J6l7ZWp64uI64ukLlwiKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOyjvOyWtOynhCDsl5Tti7Dti7DsmYAg7YWc7ZSM66a/IO2CpOyXkCDrjIDtlbQsIOyDneyEseuQnCDsvZTrk5zqsIAg7KG07J6s7ZWY64qU7KeAIO2ZleyduO2VqeuLiOuLpC5cbiAgICogQHBhcmFtIGVudGl0eUlkIOyXlO2LsO2LsCBJRFxuICAgKiBAcGFyYW0gdGVtcGxhdGVLZXkg7YWc7ZSM66a/IO2CpFxuICAgKiBAcGFyYW0gZW51bUlkIOyXtOqxsO2YlSBJRFxuICAgKiBAcmV0dXJucyDsg53shLHrkJwg7L2U65Oc6rCAIOyhtOyerO2VmOuKlOyngCDsl6zrtoBcbiAgICovXG4gIGFzeW5jIGNoZWNrRXhpc3RzR2VuQ29kZShcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIHRlbXBsYXRlS2V5OiBUZW1wbGF0ZUtleSxcbiAgICBlbnVtSWQ/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8eyBzdWJQYXRoOiBzdHJpbmc7IGZ1bGxQYXRoOiBzdHJpbmc7IGlzRXhpc3RzOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCB7IHRhcmdldCwgcGF0aDogZ2VuUGF0aCB9ID0gVGVtcGxhdGVNYW5hZ2VyLmdldCh0ZW1wbGF0ZUtleSkuZ2V0VGFyZ2V0QW5kUGF0aChcbiAgICAgIEVudGl0eU1hbmFnZXIuZ2V0TmFtZXNGcm9tSWQoZW50aXR5SWQpLFxuICAgICAgZW51bUlkLFxuICAgICk7XG5cbiAgICBjb25zdCBzdWJQYXRoID0gcGF0aC5qb2luKHRhcmdldCwgZ2VuUGF0aCk7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCBzdWJQYXRoKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3ViUGF0aCxcbiAgICAgIGZ1bGxQYXRoLFxuICAgICAgaXNFeGlzdHM6IGF3YWl0IHN5bmNlckZpbGVFeGlzdHMoZnVsbFBhdGgpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICog7KO87Ja07KeEIOyXlO2LsO2LsOyZgCDsl7TqsbDtmJXsl5Ag64yA7ZW0LCDsg53shLHrkJwg7L2U65Oc6rCAIOyhtOyerO2VmOuKlOyngCDtmZXsnbjtlanri4jri6QuXG4gICAqIEBwYXJhbSBlbnRpdHlJZCDsl5Tti7Dti7AgSURcbiAgICogQHBhcmFtIGVudW1zIOyXtOqxsO2YlSDroIjsnbTruJRcbiAgICogQHJldHVybnMg7IOd7ISx65CcIOy9lOuTnOqwgCDsobTsnqztlZjripTsp4Ag7Jes67aAXG4gICAqL1xuICBhc3luYyBjaGVja0V4aXN0cyhcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIGVudW1zOiB7XG4gICAgICBbbmFtZTogc3RyaW5nXTogei5ab2RFbnVtO1xuICAgIH0sXG4gICk6IFByb21pc2U8UmVjb3JkPGAke1RlbXBsYXRlS2V5fSR7c3RyaW5nfWAsIGJvb2xlYW4+PiB7XG4gICAgY29uc3Qga2V5czogVGVtcGxhdGVLZXlbXSA9IFRlbXBsYXRlS2V5Lm9wdGlvbnM7XG4gICAgY29uc3QgbmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKGVudGl0eUlkKTtcbiAgICBjb25zdCBlbnVtc0tleXMgPSBPYmplY3Qua2V5cyhlbnVtcykuZmlsdGVyKChuYW1lKSA9PiBuYW1lICE9PSBuYW1lcy5jb25zdGFudCk7XG5cbiAgICByZXR1cm4gYXdhaXQgcmVkdWNlQXN5bmMoXG4gICAgICBrZXlzLFxuICAgICAgYXN5bmMgKHJlc3VsdCwga2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IHRwbCA9IFRlbXBsYXRlTWFuYWdlci5nZXQoa2V5KTtcbiAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKFwidmlld19lbnVtc1wiKSkge1xuICAgICAgICAgIGF3YWl0IG1hcEFzeW5jKGVudW1zS2V5cywgYXN5bmMgKGNvbXBvbmVudElkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHRhcmdldCwgcGF0aDogcCB9ID0gdHBsLmdldFRhcmdldEFuZFBhdGgobmFtZXMsIGNvbXBvbmVudElkKTtcbiAgICAgICAgICAgIHJlc3VsdFtgJHtrZXl9X18ke2NvbXBvbmVudElkfWBdID0gYXdhaXQgc3luY2VyRmlsZUV4aXN0cyhcbiAgICAgICAgICAgICAgcGF0aC5qb2luKFNvbmFtdS5hcHBSb290UGF0aCwgdGFyZ2V0LCBwKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgdGFyZ2V0LCBwYXRoOiBwIH0gPSB0cGwuZ2V0VGFyZ2V0QW5kUGF0aChuYW1lcyk7XG4gICAgICAgIGNvbnN0IHsgdGFyZ2V0cyB9ID0gU29uYW11LmNvbmZpZy5zeW5jO1xuICAgICAgICBpZiAodGFyZ2V0LmluY2x1ZGVzKFwiOnRhcmdldFwiKSkge1xuICAgICAgICAgIGF3YWl0IG1hcEFzeW5jKHRhcmdldHMsIGFzeW5jICh0KSA9PiB7XG4gICAgICAgICAgICByZXN1bHRbYCR7a2V5fV9fJHt0fWBdID0gYXdhaXQgc3luY2VyRmlsZUV4aXN0cyhcbiAgICAgICAgICAgICAgcGF0aC5qb2luKFNvbmFtdS5hcHBSb290UGF0aCwgdGFyZ2V0LnJlcGxhY2UoXCI6dGFyZ2V0XCIsIHQpLCBwKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W2tleV0gPSBhd2FpdCBzeW5jZXJGaWxlRXhpc3RzKHBhdGguam9pbihTb25hbXUuYXBwUm9vdFBhdGgsIHRhcmdldCwgcCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICAvKiBTQUZFVFk6IFR5cGVTY3JpcHQgQVNUIO2MjOyLseqzvCDrj5nquLDtmZQg7J6F66ClIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIHt9IGFzIFJlY29yZDxcbiAgICAgICAgYCR7VGVtcGxhdGVLZXl9JHtzdHJpbmd9YCxcbiAgICAgICAgYm9vbGVhblxuICAgICAgPixcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgY3JlYXRlRW50aXR5KGZvcm06IFRlbXBsYXRlT3B0aW9uc1tcImVudGl0eVwiXSkge1xuICAgIHJldHVybiBhd2FpdCBjcmVhdGVFbnRpdHkoZm9ybSk7XG4gIH1cblxuICAvKipcbiAgICog7ZWY7JyE7Zi47ZmY7JqpIO2UhOuhneyLnCDrqZTshozrk5zsnoXri4jri6QuXG4gICAqL1xuICBhc3luYyBkZWxFbnRpdHkoZW50aXR5SWQ6IHN0cmluZyk6IFByb21pc2U8eyBkZWxQYXRoczogc3RyaW5nW10gfT4ge1xuICAgIHJldHVybiBhd2FpdCBkZWxFbnRpdHkoZW50aXR5SWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGVUZW1wbGF0ZTxUIGV4dGVuZHMgVGVtcGxhdGVLZXk+KFxuICAgIGtleTogVCxcbiAgICB0ZW1wbGF0ZU9wdGlvbnM6IFRlbXBsYXRlT3B0aW9uc1tUXSxcbiAgICBfZ2VuZXJhdGVPcHRpb25zPzogR2VuZXJhdGVPcHRpb25zLFxuICApOiBQcm9taXNlPEFic29sdXRlUGF0aFtdPiB7XG4gICAgcmV0dXJuIGF3YWl0IGdlbmVyYXRlVGVtcGxhdGUoa2V5LCB0ZW1wbGF0ZU9wdGlvbnMsIF9nZW5lcmF0ZU9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgcmVuZGVyVGVtcGxhdGU8VCBleHRlbmRzIGtleW9mIFRlbXBsYXRlT3B0aW9ucz4oXG4gICAga2V5OiBULFxuICAgIHRlbXBsYXRlT3B0aW9uczogVGVtcGxhdGVPcHRpb25zW1RdLFxuICApOiBQcm9taXNlPFBhdGhBbmRDb2RlW10+IHtcbiAgICByZXR1cm4gYXdhaXQgcmVuZGVyVGVtcGxhdGUoa2V5LCB0ZW1wbGF0ZU9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgcmVuZXdDaGVja3N1bXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZGVwZW5kZW5jaWVzLnJlbmV3Q2hlY2tzdW1zKCk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7aUJBVWtEO2FBQ1o7cUJBQ2tCO1lBRWxCO3VCQUV3QjtZQUVsQjtrQkFFZ0I7bUJBQ1Y7aUJBQ047b0JBRW9CO29CQUNWO2VBQ3FCO3FCQUNSO3dCQUNOO29CQUNtQzs4QkFFbEI7b0JBQ0U7cUJBRS9CO0NBYTNDLDRCQUFnRDtFQUNkQTtFQUNSQztFQUNXQztFQUN6QztFQUNBO0NBQ0Y7Q0FFYSxTQUFiLE1BQW9CO0VBT1c7RUFON0IsT0FBbUIsQ0FBQztFQUNwQixRQUFxQixDQUFDO0VBQ3RCLFNBQXVCLENBQUM7RUFDeEIsNEJBQTZDLElBQUksSUFBSTtFQUNyRCxlQUE2QixJQUFJLGFBQWE7RUFFOUMsWUFBWSxlQUFvRCwyQkFBMkI7R0FBOUQsS0FBQSxlQUFBO0VBQStEOzs7Ozs7RUFPNUYsTUFBTSxPQUFzQjtHQUkxQixNQUFNLEtBQUssYUFBYSxxQ0FBcUM7R0FDN0QsTUFBTSxLQUFLLGFBQWEsd0NBQXdDO0dBR2hFLE1BQU0sZUFBZSxNQUFNLEtBQUssYUFBYSwrQkFBK0I7R0FDNUUsSUFBSSxhQUFhLFdBQVcsR0FBRztJQUM3QixJQUFJLE1BQU0sS0FBSywrQkFBK0IsR0FDNUMsTUFBTSxLQUFLLGFBQWEsZUFBZTtJQUV6QyxRQUFRLElBQUksTUFBTSxNQUFNLFFBQVEsV0FBVyx1QkFBdUIsQ0FBQyxDQUFDO0lBQ3BFO0dBQ0Y7R0FLQSxNQUFN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
399
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2VyLmpzIiwibmFtZXMiOlsiU3luY2VyQWN0aW9ucy5hY3Rpb25Db3B5U2hhcmVkVG9UYXJnZXRzSWZOb3RFeGlzdHMiLCJTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlU3NyRW50cnlTZXJ2ZXJJZk5vdEV4aXN0cyIsIlN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVIdHRwVmFsaWRhdG9ycyIsIlN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVJbml0aWFsVHlwZXMiLCJTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNGaWxlc1RvVGFyZ2V0cyIsIlN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVTY2hlbWFzIiwiU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZVNlcnZpY2VzIiwiU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZUh0dHBzIiwiU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZVNzclF1ZXJpZXMiLCJTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNDb25maWciLCJTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNTb25hbXVEaWN0aW9uYXJ5Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNlci9zeW5jZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tIFwiZXZlbnRzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyBob3QgfSBmcm9tIFwiQHNvbmFtdS1raXQvaG1yLWhvb2tcIjtcbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcbmltcG9ydCB7IG1pbmltYXRjaCB9IGZyb20gXCJtaW5pbWF0Y2hcIjtcbmltcG9ydCB7IHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyB0eXBlIHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IHJlZ2lzdGVyZWRBcGlzIH0gZnJvbSBcIi4uL2FwaS9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgRW50aXR5TmFtZXNSZWNvcmQgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBOYWl0ZSB9IGZyb20gXCIuLi9uYWl0ZS9uYWl0ZVwiO1xuaW1wb3J0IHsgdHlwZSBXb3JrZmxvd01ldGFkYXRhIH0gZnJvbSBcIi4uL3Rhc2tzL2RlY29yYXRvclwiO1xuaW1wb3J0IHsgVGVtcGxhdGVNYW5hZ2VyIH0gZnJvbSBcIi4uL3RlbXBsYXRlL3RlbXBsYXRlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgR2VuZXJhdGVPcHRpb25zLCB0eXBlIFBhdGhBbmRDb2RlIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZUtleSB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBUZW1wbGF0ZU9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG1hcEFzeW5jLCByZWR1Y2VBc3luYyB9IGZyb20gXCIuLi91dGlscy9hc3luYy11dGlsc1wiO1xuaW1wb3J0IHsgY2VudGVyVGV4dCB9IGZyb20gXCIuLi91dGlscy9jb25zb2xlLXV0aWxcIjtcbmltcG9ydCB7IGlzVGVzdCB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5pbXBvcnQgeyB0eXBlIEFic29sdXRlUGF0aCB9IGZyb20gXCIuLi91dGlscy9wYXRoLXV0aWxzXCI7XG5pbXBvcnQgeyBydW5XaXRoR3JhY2VmdWxTaHV0ZG93biB9IGZyb20gXCIuLi91dGlscy9wcm9jZXNzLXV0aWxzXCI7XG5pbXBvcnQgeyBpc09iamVjdFZhbHVlIH0gZnJvbSBcIi4uL3V0aWxzL3J1bnRpbWUtdmFsdWVcIjtcbmltcG9ydCB7IGZpbmRDaGFuZ2VkRmlsZXNVc2luZ0NoZWNrc3VtcywgcmVuZXdDaGVja3N1bXMgfSBmcm9tIFwiLi9jaGVja3N1bVwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVUZW1wbGF0ZSwgcmVuZGVyVGVtcGxhdGUgfSBmcm9tIFwiLi9jb2RlLWdlbmVyYXRvclwiO1xuaW1wb3J0IHsgY3JlYXRlRW50aXR5LCBkZWxFbnRpdHkgfSBmcm9tIFwiLi9lbnRpdHktb3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgZ2V0Q2hlY2tzdW1QYXR0ZXJuR3JvdXAsIGdldENoZWNrc3VtUGF0dGVybkdyb3VwSW5BYnNvbHV0ZVBhdGggfSBmcm9tIFwiLi9maWxlLXBhdHRlcm5zXCI7XG5pbXBvcnQgeyB0eXBlIEZpbGVUeXBlIH0gZnJvbSBcIi4vZmlsZS1wYXR0ZXJuc1wiO1xuaW1wb3J0IHsgc3luY2VyRmlsZUV4aXN0cywgc3luY2VyRmlsZXN5c3RlbSB9IGZyb20gXCIuL2ZpbGVzeXN0ZW0tZGVwZW5kZW5jaWVzXCI7XG5pbXBvcnQgeyBsb2FkQXBpcywgbG9hZE1vZGVscywgbG9hZFR5cGVzLCBsb2FkV29ya2Zsb3dzIH0gZnJvbSBcIi4vbW9kdWxlLWxvYWRlclwiO1xuaW1wb3J0IHsgdHlwZSBMb2FkZWRBcGlzLCB0eXBlIExvYWRlZE1vZGVscywgdHlwZSBMb2FkZWRUeXBlcyB9IGZyb20gXCIuL21vZHVsZS1sb2FkZXJcIjtcbmltcG9ydCAqIGFzIFN5bmNlckFjdGlvbnMgZnJvbSBcIi4vc3luY2VyLWFjdGlvbnNcIjtcblxudHlwZSBEaWZmR3JvdXBLZXkgPSBGaWxlVHlwZSB8IFwidW5rbm93blwiO1xudHlwZSBEaWZmR3JvdXBzID0gUGFydGlhbDxSZWNvcmQ8RGlmZkdyb3VwS2V5LCBBYnNvbHV0ZVBhdGhbXT4+O1xuXG5leHBvcnQgY2xhc3MgU3luY2VyIHtcbiAgYXBpczogTG9hZGVkQXBpcyA9IFtdO1xuICB0eXBlczogTG9hZGVkVHlwZXMgPSB7fTtcbiAgbW9kZWxzOiBMb2FkZWRNb2RlbHMgPSB7fTtcbiAgd29ya2Zsb3dzOiBNYXA8c3RyaW5nLCBXb3JrZmxvd01ldGFkYXRhW10+ID0gbmV3IE1hcCgpO1xuICBldmVudEVtaXR0ZXI6IEV2ZW50RW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAvKipcbiAgICog7LK07YGs7ISs7J20IOuzgOqyveuQnCDrtoDrtoTsl5Ag64yA7ZW0IOyLse2BrOulvCDsp4Ttlontlanri4jri6QuXG4gICAqIGRldiDshJzrsoTqsIAg7LKY7J2MIOuWtOydhCDrlYwsIHNvbmFtdSBzeW5jIO2VoCDrlYwg7Iuk7ZaJ65Cp64uI64ukLiDsnbTtm4Tsl5DripQgaG1yQW5kU3luYyDqsr3roZzrpbwg7YOA7JqULlxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgYXN5bmMgc3luYygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDstIjquLAg67aA7Yq47Iqk7Yq4656pISDslpjrhKTrk6TsnYAgaWRlbXBvdGVudO2VmOqzoCDqsIDrs43quLAg65WM66y47JeQIOustOyngOyEsSDsi6TtlontlbTrj4Qg65Cp64uI64ukLlxuICAgIC8vIOyWmOuEpOuTpOydgCBzb25hbXUubG9ja+yXkCDrk6TslrTqsIDsp4Drj4Qg7JWK6rOgIOuUsOudvOyEnCBITVIg6rK966Gc66W8IO2DgOyngOuPhCDslYrripQg7Lmc6rWs65Ok7J6F64uI64ukLlxuICAgIC8vIOq3uOuemOyEnCDslYTrrLQg65WM64KYIOq3uOuDpSDrj4zroKTso7zrqbQg65CY64qU642wLCBobXJBbmRTeW5j7JeQ7IScIOunpOuyiCDtlZjripQg6rKD7J2AIOuCreu5hOydtOuLiCDsl6zquLDshJwg7ZWcIOuyiOunjCDtlanri4jri6QuXG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25Db3B5U2hhcmVkVG9UYXJnZXRzSWZOb3RFeGlzdHMoKTtcbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlU3NyRW50cnlTZXJ2ZXJJZk5vdEV4aXN0cygpO1xuXG4gICAgLy8g67CU64CQIOqyg+ydtCDsl4bsnLzrqbQg6re464OlIOuEmOyWtOqwgOyalC5cbiAgICBjb25zdCBjaGFuZ2VkRmlsZXMgPSBhd2FpdCBmaW5kQ2hhbmdlZEZpbGVzVXNpbmdDaGVja3N1bXMoKTtcbiAgICBpZiAoY2hhbmdlZEZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKGF3YWl0IHRoaXMucmVjb25jaWxlSHR0cFZhbGlkYXRvclJlZ2lzdHJ5KCkpIHtcbiAgICAgICAgYXdhaXQgcmVuZXdDaGVja3N1bXMoKTtcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmJsYWNrLmJnR3JlZW4oY2VudGVyVGV4dChcIkFsbCBmaWxlcyBhcmUgc3luY2VkIVwiKSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOyXrOq4sOyEnCDsi6TsoJwg7Iux7YGsIOuPmeyekeydhCDsiJjtlontlanri4jri6QuXG4gICAgLy8g64uk66eMIOyLse2BrCDspJHsl5Ag7ZSE66Gc7IS47Iqk6rCAIOyjveycvOuptCDqvKzsl6zrsoTrpqzquLAg65WM66y47JeQLFxuICAgIC8vIOyLnOq3uOuEkOyXkOuPhCDsnqDsi5wg67KE7Yu4IOyImCDsnojripQg7ZmY6rK9IOyGjeyXkOyEnCDsi7Htgazrpbwg7Iuk7ZaJ7ZWp64uI64ukLlxuICAgIGF3YWl0IHJ1bldpdGhHcmFjZWZ1bFNodXRkb3duKFxuICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyDslpjqsIAg7Iux7YGsIOyekeyXhSDsiJjtlontlZjripQg67O47LK07J6F64uI64ukLlxuICAgICAgICBhd2FpdCB0aGlzLmRvU3luY0FjdGlvbnMoY2hhbmdlZEZpbGVzKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWNvbmNpbGVIdHRwVmFsaWRhdG9yUmVnaXN0cnkoKTtcblxuICAgICAgICAvLyDsi7Htgawg7JWh7IWY7J20IOuBneuCmOuptCDtla3sg4Eg7LK07YGs7ISs7J2EIOuLpOyLnCDqsLHsi6Dtlanri4jri6QuXG4gICAgICAgIGF3YWl0IHJlbmV3Q2hlY2tzdW1zKCk7XG4gICAgICB9LFxuICAgICAgeyB3aGVuVGhpc0hhcHBlbnM6IFwiU0lHVVNSMlwiLCB3YWl0Rm9yVXBUbzogMjAwMDAgfSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWNvbmNpbGVIdHRwVmFsaWRhdG9yUmVnaXN0cnkoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgcmVnaXN0cnlQYXRoID0gcGF0aC5qb2luKFxuICAgICAgU29uYW11LmFwaVJvb3RQYXRoLFxuICAgICAgXCJzcmMvYXBwbGljYXRpb24vc29uYW11LnZhbGlkYXRvcnMuZ2VuZXJhdGVkLnRzXCIsXG4gICAgKTtcbiAgICBjb25zdCBwb2xpY3kgPSBTb25hbXUuY29uZmlnLnZhbGlkYXRpb24/LnpvZENvbXBpbGVyO1xuICAgIGNvbnN0IGlzQW90ID0gaXNPYmplY3RWYWx1ZShwb2xpY3kpICYmIHBvbGljeSAhPT0gbnVsbCAmJiBwb2xpY3kuYXBpID09PSBcImFvdFwiO1xuICAgIGlmIChpc0FvdCA9PT0gKGF3YWl0IHN5bmNlckZpbGVFeGlzdHMocmVnaXN0cnlQYXRoKSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyDrs4Dqsr0g66qp66Gd7J20IHJlZ2lzdHJ5IOyCreygnOulvCDrhpPss5Drj4QgY2hlY2tzdW0g6rCx7IugIOyghOyXkCDsoJXssYXqs7wg7IKw7Lac66y87J2EIOuLpOyLnCDrp57stqXri4jri6QuXG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZUh0dHBWYWxpZGF0b3JzKCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICog6rCV7KCcIO2SgC3si7Htgaw6IGxvY2vsnYQg66y07Iuc7ZWY6rOgIOyymOydjOu2gO2EsCDri6Tsi5wg7Iux7YGs7ZWp64uI64ukLlxuICAgKlxuICAgKiAqKuyCrOyaqeyymCoqOiBnaXQgcG9zdC1tZXJnZSBob29rLCBDSSwgZGV2IOyEnOuyhOydmCBgZmAg7ZWr7YKkLlxuICAgKiAqKuyLpO2MqCDslYjsoITshLEqKjog64+E7KSR7JeQIO2UhOuhnOyEuOyKpOqwgCDso73slrQgbG9jayDsl4bripQg7IOB7YOc66GcIOuCqOyVhOuPhCDrrLTtlbQg4oCUIOuLpOydjCBzeW5j7JeQ7IScXG4gICAqIGxvY2sg7JeG7Jy866m0IOyekOyXsOyKpOufveqyjCDtkoAt7Iux7YGs6rCAIO2KuOumrOqxsOuQmOyWtCDsg4ggbG9ja+ydtCDsnpHshLHrkKguXG4gICAqL1xuICBhc3luYyBmb3JjZVN5bmMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9ja1BhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwaVJvb3RQYXRoLCBcInNvbmFtdS5sb2NrXCIpO1xuICAgIGlmIChhd2FpdCBzeW5jZXJGaWxlRXhpc3RzKGxvY2tQYXRoKSkge1xuICAgICAgYXdhaXQgc3luY2VyRmlsZXN5c3RlbS51bmxpbmsobG9ja1BhdGgpO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLnN5bmMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYXRjaGVy6rCAIGJhdGNo66GcIOuqqOydgCDrs4Dqsr0g7YyM7J2865Ok7JeQIOuMgO2VtCDtlZwg67KI7J2YIEhNUi9zeW5jIOyCrOydtO2BtOydhCDrj5Xri4jri6QuXG4gICAqXG4gICAqIEhNUuydgCBhcGkvc3JjIOyViOyXkOyEnCDsnbzslrTrgpjripQg66qo65OgIO2MjOydvOuTpOyXkCDrjIDtlbTshJwg7IiY7ZaJ7ZWp64uI64ukLlxuICAgKiBjaGVja3N1bVBhdHRlcm5Hcm91cCDrp6Tsua0g7Jes67aA7JmAIOustOq0gO2VmOqyjCBhcGkvc3JjIOyghOyytCDrjIDsg4HsnoXri4jri6QuXG4gICAqIOqwgOuguSBhcGkvc3JjL3V0aWxzL3N1YnNldC1sb2FkZXJzLnRzIOqwmeydgCDtjIzsnbzrj4Qg67OA6rK965CY66m0IEhNUuydgCDtlbTspI3ri4jri6QuXG4gICAqXG4gICAqIFN5bmPripQgY2hlY2tzdW1QYXR0ZXJuR3JvdXDsnLzroZwg66ek7Lmt65CY64qUIO2MjOydvOuTpOyXkCDrjIDtlbTshJzrp4wg7IiY7ZaJ7ZWp64uI64ukLlxuICAgKiDsl6zquLDsl5DripQgd2ViL3NyY+uCmCBhcHAvc3JjIOqwmeydgCDri6TrpbggdGFyZ2V07J2YIO2MjOydvOydtCDtj6ztlajrkKAg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7J2065+wIG5vbi1hcGkg6rK966Gc7J2YIO2MjOydvOuTpOydgCBITVLqs7zripQg7JWE66y0IOyDgeq0gOydtCDsl4bsnLzrr4DroZwsIGludmFsaWRhdGXsnYQg7ZWY7KeAIOyViuyKteuLiOuLpC5cbiAgICpcbiAgICogQHBhcmFtIGZpbGVFdmVudHMgLSBwYXRoIOKGkiBldmVudCDrp7UuIGV2ZW5064qUIFwiY2hhbmdlXCIgfCBcImFkZFwiLlxuICAgKi9cbiAgYXN5bmMgaG1yQW5kU3luYyhmaWxlRXZlbnRzOiBNYXA8QWJzb2x1dGVQYXRoLCBcImNoYW5nZVwiIHwgXCJhZGRcIj4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBobXJBY3Rpb25SZXF1aXJlZEV2ZW50cyA9IHRoaXMuZXh0cmFjdEhtckFjdGlvblJlcXVpcmVkRmlsZUV2ZW50cyhmaWxlRXZlbnRzKTtcbiAgICBjb25zdCBzeW5jVHJpZ2dlcmluZ1BhdGhzID0gYXdhaXQgdGhpcy5leHRyYWN0U3luY1RyaWdnZXJpbmdGaWxlRXZlbnRQYXRocyhmaWxlRXZlbnRzKTtcblxuICAgIC8vIEhNUiDsmIHsl606IO2MjOydvCDsnbTrsqTtirgg7KSRIGFwaeydmCDrqqjrk4gg6re4656Y7ZSE7JeQIOyeiOuKlCDtjIzsnbzrk6Tsl5Ag64yA7ZWcIOuzgOuPmeydgCBobXJBY3Rpb25SZXF1aXJlZEV2ZW50c+uhnCDsnqHtnpnri4jri6QuXG4gICAgLy8g7J20IOy5nOq1rOuTpOydgCBpbnZhbGlkYXRlIOyymOumrO2VtOykjeuLiOuLpC5cbiAgICAvLyDsnbQg7Zi47Lac7J2AIOyVhOuemCBzeW5j67O064ukIOustOyhsOqxtCDrqLzsoIAg7J287Ja064KY7JW8IO2VqeuLiOuLpCFcbiAgICAvLyDsmZzrg5DtlZjrqbQgc3luY+yXkOyEnOuKlCDrs4Dqsr3rkJwgbW9kZWwg7L2U65Oc66W8IOyDiOuhnCBpbXBvcnTtlbTshJwg7LKY66as7ZW07JW8IO2VmOuKlCDqsr3smrDrj4Qg7J6I6riwIOuVjOusuOyeheuLiOuLpC5cbiAgICBhd2FpdCB0aGlzLmludmFsaWRhdGVEZXBlbmRlbnRzQWZmZWN0ZWRCeUZpbGVFdmVudHMoaG1yQWN0aW9uUmVxdWlyZWRFdmVudHMpO1xuXG4gICAgLy8gU3luYyDsmIHsl606IGNoZWNrc3VtUGF0dGVybkdyb3Vw7JeQIOuqheyLnOuQnCDtjIzsnbzrk6Tsl5Ag64yA7ZWcIOuzgOuPmeydgCBzeW5jVHJpZ2dlcmluZ1BhdGhz66GcIOyeoe2emeuLiOuLpC5cbiAgICAvLyDsnbQg7Lmc6rWs65Ok7J2AIOyggeygiO2VnCBzeW5jIOyekeyXheycvOuhnCDrjIDsnZHtlanri4jri6QuXG4gICAgaWYgKHN5bmNUcmlnZ2VyaW5nUGF0aHMubGVuZ3RoID4gMCkge1xuICAgICAgYXdhaXQgdGhpcy5kb1N5bmNBY3Rpb25zKHN5bmNUcmlnZ2VyaW5nUGF0aHMpO1xuICAgIH1cblxuICAgIC8vIOyLse2BrCDsnpHsl4XsnbQg64Gd64Ks7Jy866m0IOustOyngOyEsSDroZzrk5zrpbwg7IiY7ZaJ7ZWp64uI64ukLlxuICAgIC8vIOyLse2BrOulvCDslYgg7ZWcIOqyveyasOyXkOuPhCDroZzrk5zripQg7ZW07JW8IO2VtOyalC4g7JyE7JeQ7IScIOq0gOugqOyeiOuKlCDsuZzqtazrk6TsnYAg64ukIGludmFsaWRhdGUg65CY7JeI6rGw65Og7JqUIVxuICAgIC8vXG4gICAgLy8g67OA6rK965CcIO2MjOydvOuTpOyXkCDrjIDtlbTshJwg7IOI66Gt6rKMIOuLueqyqOyYpOuKlChsb2FkKSDtlonsnITripQgZG9TeW5jQWN0aW9uc+yXkOyEnCDtlZjsp4Ag7JWK7Iq164uI64ukLlxuICAgIC8vIGRvU3luY0FjdGlvbnPsl5DshJzripQg7YyM7J287J2EIOydveqzoCDrp4zrk5zripQg7Iux7YGsIO2WieychOunjCDtlanri4jri6QuXG4gICAgLy8g6rGw6riw7IScIOuUsSDrs4Dqsr3rkJwg67aA67aE7JeQIOyYge2Wpeuwm+uKlCBhdXRvbG9hZOunjCDshKDrs4TtlbTshJwg7IiY7ZaJ7ZWY66Ck66m0IOuEiOustCDsp4DsoIDrtoTtlZjqs6Ag67O17J6h7ZW07KeR64uI64ukLlxuICAgIC8vXG4gICAgLy8g7Y287Y+s66i87IqkIOyYge2WpeydgCDrrLTsi5ztlbTrj4Qg7KKL7Iq164uI64ukLlxuICAgIC8vIOyWtOywqO2UvCBobXItaG9va+yXkCDsnZjtlbQgaW52YWxpZGF0ZeuQnCDrtoDrtoTrk6TsnbQg7JWE64uI652866m0IOy6kOyLnCDqt7jrjIDroZwg7Jyg7KeA7ZWp64uI64ukLlxuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRUeXBlcygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRNb2RlbHMoKTtcbiAgICBhd2FpdCB0aGlzLmF1dG9sb2FkQXBpcygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRXb3JrZmxvd3MoKTtcbiAgICBhd2FpdCB0aGlzLmF1dG9sb2FkU3NyUm91dGVzKCk7XG4gICAgYXdhaXQgU29uYW11LnJlZnJlc2hIdHRwVmFsaWRhdG9ycygpO1xuXG4gICAgdGhpcy5ldmVudEVtaXR0ZXIuZW1pdChcIm9uSE1SQ29tcGxldGVkXCIpO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0SG1yQWN0aW9uUmVxdWlyZWRGaWxlRXZlbnRzKFxuICAgIGZpbGVFdmVudHM6IE1hcDxBYnNvbHV0ZVBhdGgsIFwiY2hhbmdlXCIgfCBcImFkZFwiPixcbiAgKTogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+IHtcbiAgICBjb25zdCBhcGlTcmMgPSBwYXRoLmpvaW4oU29uYW11LmFwaVJvb3RQYXRoLCBcInNyY1wiKTtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+KCk7XG4gICAgZm9yIChjb25zdCBbZmlsZVBhdGgsIGV2ZW50XSBvZiBmaWxlRXZlbnRzKSB7XG4gICAgICBpZiAoIWZpbGVQYXRoLnN0YXJ0c1dpdGgoYXBpU3JjKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5zZXQoZmlsZVBhdGgsIGV2ZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZXh0cmFjdFN5bmNUcmlnZ2VyaW5nRmlsZUV2ZW50UGF0aHMoXG4gICAgZmlsZUV2ZW50czogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+LFxuICApOiBQcm9taXNlPEFic29sdXRlUGF0aFtdPiB7XG4gICAgY29uc3QgY2hlY2tQYXR0ZXJuR3JvdXAgPSBnZXRDaGVja3N1bVBhdHRlcm5Hcm91cEluQWJzb2x1dGVQYXRoKCk7XG4gICAgY29uc3Qgc3luY1RyaWdnZXJpbmdQYXRoczogQWJzb2x1dGVQYXRoW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IFtkaWZmRmlsZVBhdGhdIG9mIGZpbGVFdmVudHMpIHtcbiAgICAgIGNvbnN0IGlzSW5DaGVja1BhdHRlcm5Hcm91cCA9IE9iamVjdC52YWx1ZXMoY2hlY2tQYXR0ZXJuR3JvdXApLnNvbWUoKHBhdHRlcm4pID0+XG4gICAgICAgIG1pbmltYXRjaChkaWZmRmlsZVBhdGgsIHBhdHRlcm4pLFxuICAgICAgKTtcbiAgICAgIGlmICghaXNJbkNoZWNrUGF0dGVybkdyb3VwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgc3luY1RyaWdnZXJpbmdQYXRocy5wdXNoKGRpZmZGaWxlUGF0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN5bmNUcmlnZ2VyaW5nUGF0aHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGludmFsaWRhdGVEZXBlbmRlbnRzQWZmZWN0ZWRCeUZpbGVFdmVudHMoXG4gICAgZmlsZUV2ZW50czogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+LFxuICApIHtcbiAgICBmb3IgKGNvbnN0IFtkaWZmRmlsZVBhdGgsIGV2ZW50XSBvZiBmaWxlRXZlbnRzKSB7XG4gICAgICAvLyDrs4Dqsr3rkJwg7YyM7J286rO8IGRlcGVuZGVudCDtjIzsnbzrk6TsnYQgaW52YWxpZGF0ZSDtlanri4jri6QuXG4gICAgICAvLyDtlZwg67KIIOydtOyDgSBpbXBvcnTrkJwg7Lmc6rWs65Ok7JeQIOuMgO2VtOyEnOunjCDsi6TsoJwg7J6R7JeF7J20IOydvOyWtOuCqeuLiOuLpC5cbiAgICAgIC8vIOq3uOufrOuLiCDslYjsi6ztlZjqs6AgaW52YWxpZGF0ZSDtlbTrj4Qg65Cp64uI64ukLlxuICAgICAgLy8g7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnOuKlCBob3QuaW52YWxpZGF0ZUZpbGXsi5wg7LSI6riwIOyXkOufrOqwgCDrsJzsg53tlZjquLAg65WM66y47JeQIGludmFsaWRhdGUg7ZWY7KeAIOyViuyKteuLiOuLpC5cbiAgICAgIGlmICghaXNUZXN0KCkpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZGF0ZWRQYXRocyA9XG4gICAgICAgICAgLyogU0FGRVRZOiBUeXBlU2NyaXB0IEFTVCDtjIzsi7Hqs7wg64+Z6riw7ZmUIOyeheugpSDqs4Tslb3snbQg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyAoYXdhaXQgaG90LmludmFsaWRhdGVGaWxlKFxuICAgICAgICAgICAgZGlmZkZpbGVQYXRoLFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgKSkgYXMgQWJzb2x1dGVQYXRoW107XG5cbiAgICAgICAgaWYgKGludmFsaWRhdGVkUGF0aHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmJvbGQoYPCflIQgSW52YWxpZGF0ZWQ6YCkpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBpbnZhbGlkYXRlZFBhdGggb2YgaW52YWxpZGF0ZWRQYXRocykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8g66eM7JW9IG1vZGVsLnRzIO2MjOydvOydtCDrs4Dqsr0oaW52YWxpZGF0ZSnrkJjsl4jri6Q/IOq3uOufrOuptCByZWdpc3RlcmVkQXBpcyDspJHsl5DshJwg7J20IOuqqOuNuOyXkCDtlbTri7ntlZjripQgYXBp65Ok7J2AIOyngOybjOykmOyalC5cbiAgICAgICAgICAgICAgLy8gcmVnaXN0ZXJlZEFwaXPripQg7Ya17Jy866GcIOuLpCDrgqDroKTrsoTrprQg7IiYIOyXhuyKteuLiOuLpC4gcmVnaXN0ZXJlZEFwaXPsl5Ag7Jis65287Jik64qUIOy5nOq1rOuTpOydgCDstIjquLAg66Gc65Oc7IucIOuYkOuKlCBITVLsi5zsl5Drp4wg65Ox66Gd65CY6riwIOuVjOusuOyeheuLiOuLpC5cbiAgICAgICAgICAgICAgLy8g65Sw65287IScIG1vZGVsLnRzIO2MjOydvOydmCDrs4Dqsr3snLzroZwg64uk7J2M67KIIOyDiOuhnOyatCBldmFs7J20IOyYiOyDgeuQmOuKlCDsnbQg7Iuc7KCQ7JeQ7ISc66eMLCDsnbQg66qo64247JeQ7IScIOuCmOyYqCByZWdpc3RlcmVkQXBpc+uTpOydhCDsp4Dsm4zspIQg7IiYIOyeiOyKteuLiOuLpC5cbiAgICAgICAgICAgICAgY29uc3QgcmVtb3ZlZEFwaXMgPSB0aGlzLnJlbW92ZUludmFsaWRhdGVkUmVnaXN0ZXJlZEFwaXMoaW52YWxpZGF0ZWRQYXRoKTtcbiAgICAgICAgICAgICAgaWYgKHJlbW92ZWRBcGlzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoYC0gJHtwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcGlSb290UGF0aCwgaW52YWxpZGF0ZWRQYXRoKX1gKSxcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmdyYXkoYCh3aXRoICR7cmVtb3ZlZEFwaXMubGVuZ3RofSBBUElzKWApLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShgLSAke3BhdGgucmVsYXRpdmUoU29uYW11LmFwaVJvb3RQYXRoLCBpbnZhbGlkYXRlZFBhdGgpfWApKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICAgIGNoYWxrLnJlZChgRmFpbGVkIHRvIHJlbW92ZSBpbnZhbGlkYXRlZCByZWdpc3RlcmVkIEFQSXMgZm9yICR7aW52YWxpZGF0ZWRQYXRofWApLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBkZXZSdW5uZXIg7Zmc7ISx7ZmUIOyLnCwg67OA6rK965CcIOyGjOyKpCDtjIzsnbzsnYQgVml0ZXN0IOuqqOuTiCDqt7jrnpjtlITsl5DshJzrj4Qg66y07Zqo7ZmU7ZWp64uI64ukLlxuICAgICAgLy8gVml0ZeydmCBtb2R1bGVHcmFwaC5pbnZhbGlkYXRlTW9kdWxlKCnsnbQgaW1wb3J0ZXIg67Cp7Zal7Jy866GcIOyerOq3gOyggSBjYXNjYWRl7ZWY66+A66GcLFxuICAgICAgLy8g7IaM7IqkIO2MjOydvCDtlZjrgpjrp4wg66y07Zqo7ZmU7ZWY66m0IOydtOulvCBpbXBvcnTtlZjripQg7YWM7Iqk7Yq4IO2MjOydvOuPhCDsnpDrj5nsnLzroZwg66y07Zqo7ZmU65Cp64uI64ukLlxuICAgICAgaWYgKCFpc1Rlc3QoKSAmJiBTb25hbXUuY29uZmlnLnRlc3Q/LmRldlJ1bm5lcj8uZW5hYmxlZCAmJiBTb25hbXUuZGV2Vml0ZXN0TWFuYWdlcikge1xuICAgICAgICBTb25hbXUuZGV2Vml0ZXN0TWFuYWdlci5pbnZhbGlkYXRlRmlsZXMoW2RpZmZGaWxlUGF0aF0pO1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICBjaGFsay5kaW0oYFRlc3QgaW52YWxpZGF0ZWQ6ICR7cGF0aC5yZWxhdGl2ZShTb25hbXUuYXBpUm9vdFBhdGgsIGRpZmZGaWxlUGF0aCl9YCksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlSW52YWxpZGF0ZWRSZWdpc3RlcmVkQXBpcyhcbiAgICBpbnZhbGlkYXRlZFBhdGg6IEFic29sdXRlUGF0aCxcbiAgKTogKHR5cGVvZiByZWdpc3RlcmVkQXBpcylbbnVtYmVyXVtdIHtcbiAgICAvLyDshozsiqQg7L2U65Oc66W8IOuLpOujqOuKlCDsg4HtmansnbTri4ggLnRzIOqyveuhnOuhnCDrtIXri4jri6QuXG4gICAgY29uc3QgaXNNb2RlbCA9IGludmFsaWRhdGVkUGF0aC5lbmRzV2l0aChcIi5tb2RlbC50c1wiKTtcbiAgICBjb25zdCBpc0ZyYW1lID0gaW52YWxpZGF0ZWRQYXRoLmVuZHNXaXRoKFwiLmZyYW1lLnRzXCIpO1xuICAgIGlmICghaXNNb2RlbCAmJiAhaXNGcmFtZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGVudGl0eUlkID0gRW50aXR5TWFuYWdlci5nZXRFbnRpdHlJZEZyb21QYXRoKGludmFsaWRhdGVkUGF0aCk7XG4gICAgY29uc3QgdGFyZ2V0TW9kZWxOYW1lID0gYCR7ZW50aXR5SWR9JHtpc01vZGVsID8gXCJNb2RlbFwiIDogXCJGcmFtZVwifWA7XG4gICAgY29uc3QgdG9SZW1vdmUgPSByZWdpc3RlcmVkQXBpcy5maWx0ZXIoKGFwaSkgPT4gYXBpLm1vZGVsTmFtZSA9PT0gdGFyZ2V0TW9kZWxOYW1lKTtcbiAgICBmb3IgKGNvbnN0IGFwaSBvZiB0b1JlbW92ZSkge1xuICAgICAgY29uc3QgaWR4ID0gcmVnaXN0ZXJlZEFwaXMuaW5kZXhPZihhcGkpO1xuICAgICAgaWYgKGlkeCAhPT0gLTEpIHtcbiAgICAgICAgcmVnaXN0ZXJlZEFwaXMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRvUmVtb3ZlO1xuICB9XG5cbiAgYXN5bmMgYXV0b2xvYWRUeXBlcygpIHtcbiAgICB0aGlzLnR5cGVzID0gYXdhaXQgbG9hZFR5cGVzKCk7XG4gIH1cblxuICBhc3luYyBhdXRvbG9hZE1vZGVscygpIHtcbiAgICB0aGlzLm1vZGVscyA9IGF3YWl0IGxvYWRNb2RlbHMoKTtcbiAgfVxuXG4gIGFzeW5jIGF1dG9sb2FkQXBpcygpIHtcbiAgICB0aGlzLmFwaXMgPSBhd2FpdCBsb2FkQXBpcygpO1xuICB9XG5cbiAgYXN5bmMgYXV0b2xvYWRXb3JrZmxvd3MoKSB7XG4gICAgdGhpcy53b3JrZmxvd3MgPSBhd2FpdCBsb2FkV29ya2Zsb3dzKCk7XG4gICAgYXdhaXQgU29uYW11LndvcmtmbG93cy5zeW5jaHJvbml6ZSh0aGlzLndvcmtmbG93cyk7XG4gIH1cblxuICBhc3luYyBhdXRvbG9hZFNzclJvdXRlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzc3JDb25maWdQYXRoID0gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzcmMvc3NyXCIpO1xuXG4gICAgLy8g6riw7KG0IHJvdXRlcyDstIjquLDtmZRcbiAgICBjb25zdCB7IGNsZWFyU1NSUm91dGVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zc3JcIik7XG4gICAgY2xlYXJTU1JSb3V0ZXMoKTtcblxuICAgIC8vIHNzciDtj7TrjZQg7JeG7Jy866m0IOyKpO2CtVxuICAgIGlmICghKGF3YWl0IHN5bmNlckZpbGVFeGlzdHMoc3NyQ29uZmlnUGF0aCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc3NyIO2PtOuNlCDslYjsnZgg66qo65OgIC50cyDtjIzsnbwg66Gc65OcXG4gICAgY29uc3QgeyBnbG9iQXN5bmMgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL2FzeW5jLXV0aWxzXCIpO1xuICAgIGNvbnN0IHsgaW1wb3J0TWVtYmVycyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvZXNtLXV0aWxzXCIpO1xuICAgIGNvbnN0IHsgcnVudGltZVBhdGggfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIik7XG5cbiAgICAvLyBydW50aW1lUGF0aOulvCDsgqzsmqntlZjsl6wg6rCc67CcL+2UhOuhnOuNleyFmCDtmZjqsr3sl5Ag66ee64qUIO2ZleyepeyekCDsspjrpqxcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IGdsb2JBc3luYyhwYXRoLmpvaW4oc3NyQ29uZmlnUGF0aCwgcnVudGltZVBhdGgoXCIqKi8qLnRzXCIpKSk7XG5cbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIGltcG9ydE1lbWJlcnPrpbwg7IKs7Jqp7ZWY66m0IO2MjOydvOydmCBzaWRlIGVmZmVjdChyZWdpc3RlclNTUiDtmLjstpwp6rCAIOyLpO2WieuQqFxuICAgICAgICBhd2FpdCBpbXBvcnRNZW1iZXJzKGZpbGUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gbG9hZCBTU1Igcm91dGU6ICR7ZmlsZX1gLCBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog7Iuk7KCcIOyLse2BrOulvCDsiJjtlontlZjripQg67O47LK07J6F64uI64ukLlxuICAgKiDrs4Dqsr3rkJwg7YyM7J2865Ok7J2EIO2DgOyeheuzhOuhnCDrtoTrpZjtlZjqs6Ag6rCBIO2DgOyeheyXkCDrp57ripQg7JWh7IWY7J2EIOyLpO2Wie2VqeuLiOuLpC5cbiAgICpcbiAgICogQHBhcmFtIGRpZmZGaWxlUGF0aHMgLSDrs4Dqsr3rkJwg7YyM7J2865Ok7J2YIOygiOuMgCDqsr3roZwg66qp66GdXG4gICAqIEByZXR1cm5zIGRpZmZUeXBlcyAtIOuzgOqyveuQnCDtjIzsnbzsnZgg7YOA7J6FIOuqqeuhnSAoZW50aXR5LCB0eXBlcywgbW9kZWwg65OxKVxuICAgKi9cbiAgYXN5bmMgZG9TeW5jQWN0aW9ucyhkaWZmRmlsZVBhdGhzOiBBYnNvbHV0ZVBhdGhbXSk6IFByb21pc2U8eyBkaWZmVHlwZXM6IEZpbGVUeXBlW10gfT4ge1xuICAgIGNvbnN0IGRpZmZHcm91cHMgPSB0aGlzLmNhbGN1bGF0ZURpZmZHcm91cHMoZGlmZkZpbGVQYXRocyk7XG4gICAgY29uc3QgZGlmZlR5cGVzID1cbiAgICAgIC8qIFNBRkVUWTogVHlwZVNjcmlwdCBBU1Qg7YyM7Iux6rO8IOuPmeq4sO2ZlCDsnoXroKUg6rOE7JW97J20IOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gT2JqZWN0LmtleXMoXG4gICAgICAgIGRpZmZHcm91cHMsXG4gICAgICApIGFzIEZpbGVUeXBlW107XG5cbiAgICAvLyDsl6zquLDripQg67OE66GcIOykkeyalO2VnCDtjIztirjripQg7JWE64uZ64uI64ukLlxuICAgIC8vIOyVhOuemOydmCBpZiDsoITqsJzrpbwg6rmU64GU7ZWY6rKMIO2VmOugpOqzoCDrp4zrk6AgRFNMIOqwmeydgCDqsbDrnbzshJwsIOustOyLnO2VmOyFlOuPhCDrkKnri4jri6QuXG4gICAgY29uc3QgeyBjaGFuZ2VNYXRjaGVzLCB1bmhhbmRsZWRQYXRocywgdW5oYW5kbGVkQ2hhbmdlc0xlZnQgfSA9IHRoaXMuY2hhbmdlTWF0Y2hlcihcbiAgICAgIGRpZmZUeXBlcyxcbiAgICAgIGRpZmZHcm91cHMsXG4gICAgKTtcblxuICAgIGlmIChjaGFuZ2VNYXRjaGVzKFwiZW50aXR5XCIsIFwidHlwZXNcIikpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlVHJ1dGhTb3VyY2VDaGFuZ2VzKGRpZmZHcm91cHMpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VNYXRjaGVzKFwibW9kZWxcIiwgXCJmcmFtZVwiKSkge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVJbXBsZW1lbnRhdGlvbkNoYW5nZXMoZGlmZkdyb3Vwcyk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZU1hdGNoZXMoXCJ0eXBlc1wiLCBcImZ1bmN0aW9uc1wiKSkge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVBdXhpbGlhcnlTeW1ib2xDaGFuZ2VzKGRpZmZHcm91cHMpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VNYXRjaGVzKFwiY29uZmlnXCIpKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUNvbmZpZ0NoYW5nZXMoKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlTWF0Y2hlcyhcIndvcmtmbG93XCIpKSB7XG4gICAgICAvLyDrrZAg65Sx7Z6IIOyViCDtlbTsmpQuIOq3uOuemOuPhCDsnbQgaWYg7KGw6rG07J2AIGV2YWzrkJjslrTslbwg7ZWY6riwIOuVjOusuOyXkCDrgqjqsqjrkaHri4jri6Qg44WO44WOXG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZU1hdGNoZXMoXCJpMThuXCIsIFwiZW50aXR5XCIgLyrroIjsnbTruJQqLywgXCJjb25maWdcIiAvKmRlZmF1bHRMb2NhbGXrk7EqLykpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlU29uYW11RGljdGlvbmFyeVJlbGF0ZWRDaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZU1hdGNoZXMoXCJlbnRpdHlcIiwgXCJ0eXBlc1wiLCBcIm1vZGVsXCIsIFwiZnJhbWVcIiwgXCJjb25maWdcIiwgXCJodHRwVmFsaWRhdG9yc0dlbmVyYXRlZFwiKSkge1xuICAgICAgLy8g7IOd7ISx66y8KGh0dHBWYWxpZGF0b3JzR2VuZXJhdGVkKeyXkCDrk5zrpqztlITtirjqsIAg7IOd6ri0IOqyveyasOuPhCDsspjrpqztlanri4jri6QuXG4gICAgICAvLyDri6Trpbgg6rKDIOyViCDrsJTrgIzqs6Ag65SxIGh0dHBWYWxpZGF0b3JzR2VuZXJhdGVk66eMIOuwlOuAkCDqsr3smrDsl5Drj4Qg64+Z65Ox7ZWcIOyymOumrCg966y07KeA7ISxIOyYpO2GoOuhnOuTnCnrpbwg7ZWp64uI64ukLiDqt7jrg6Ug7J2067uQ7ISc7JqUIOOFi1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVIdHRwVmFsaWRhdG9yUmVsYXRlZENoYW5nZXMoKTtcbiAgICB9XG5cbiAgICAvLyDsnITsl5DshJwg7LKY66asIOyViCDrkJwg67OA6rK965Ok7J20IOyeiOuLpD9cbiAgICAvLyDssrTtgazshKwg6rSA66asIOuMgOyDgeydtOq4tCDtlZzrjbAg7JyE7JeQ7IScIO2VuOuTpOungeydtCDslYgg65CcIOqyg+ydtOudvOuptCDqsrDqta0g7IOd7ISx66y87J6F64uI64ukLlxuICAgIC8vIOydtCDsuZzqtazrk6TsnbQg67OA6rK965CcIOqyg+ydgCBkcmlmdOuhnCDqsITso7ztlbTrj4Qg66eI65WF7ZWp64uI64ukLlxuICAgIGlmICh1bmhhbmRsZWRDaGFuZ2VzTGVmdCgpKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZURyaWZ0cyh1bmhhbmRsZWRQYXRocygpKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGlmZlR5cGVzLFxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVEaWZmR3JvdXBzKGRpZmZGaWxlczogQWJzb2x1dGVQYXRoW10pIHtcbiAgICBjb25zdCBwYXR0ZXJuR3JvdXAgPSBnZXRDaGVja3N1bVBhdHRlcm5Hcm91cCgpO1xuICAgIGNvbnN0IGZpbGVUeXBlcyA9XG4gICAgICAvKiBTQUZFVFk6IFR5cGVTY3JpcHQgQVNUIO2MjOyLseqzvCDrj5nquLDtmZQg7J6F66ClIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIE9iamVjdC5rZXlzKFxuICAgICAgICBwYXR0ZXJuR3JvdXAsXG4gICAgICApIGFzIEZpbGVUeXBlW107XG5cbiAgICBjb25zdCBkaWZmR3JvdXBzOiBEaWZmR3JvdXBzID0ge307XG4gICAgZm9yIChjb25zdCBmaWxlUGF0aCBvZiBkaWZmRmlsZXMpIHtcbiAgICAgIC8vIOygiOuMgCDqsr3roZzrpbwgYXBwUm9vdCDquLDspIAg7IOB64yAIOqyveuhnOuhnCDrsJTqv5Qg7LK07YGs7ISsIO2MqO2EtOqzvCDruYTqtZDtlZzri6QuXG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcHBSb290UGF0aCwgZmlsZVBhdGgpO1xuICAgICAgY29uc3QgZmlsZVR5cGUgPSBmaWxlVHlwZXMuZmluZCgoY2FuZGlkYXRlKSA9PlxuICAgICAgICBtaW5pbWF0Y2gocmVsYXRpdmVQYXRoLCBwYXR0ZXJuR3JvdXBbY2FuZGlkYXRlXSksXG4gICAgICApO1xuICAgICAgY29uc3QgZ3JvdXBLZXk6IERpZmZHcm91cEtleSA9IHJlbGF0aXZlUGF0aC5zdGFydHNXaXRoKFwiLi5cIilcbiAgICAgICAgPyBcInVua25vd25cIlxuICAgICAgICA6IChmaWxlVHlwZSA/PyBcInVua25vd25cIik7XG4gICAgICAoZGlmZkdyb3Vwc1tncm91cEtleV0gPz89IFtdKS5wdXNoKGZpbGVQYXRoKTtcbiAgICB9XG4gICAgcmV0dXJuIGRpZmZHcm91cHM7XG4gIH1cblxuICBwcml2YXRlIGNoYW5nZU1hdGNoZXIoZGlmZlR5cGVzOiBGaWxlVHlwZVtdLCBkaWZmR3JvdXBzOiBEaWZmR3JvdXBzKSB7XG4gICAgY29uc3QgaGFuZGxlZCA9IG5ldyBTZXQ8RmlsZVR5cGU+KCk7XG5cbiAgICAvKipcbiAgICAgKiDrs4Dqsr0g7IKs7ZWt7J20IOyduOyekOuhnCDrsJvsnYAgRmlsZVR5cGXrk6Qg7KSRIO2VmOuCmCDsnbTsg4HsnYQg7Y+s7ZWo7ZWY64qU7KeAIO2ZleyduO2VqeuLiOuLpC5cbiAgICAgKiDqsIDroLkgW1wiZW50aXR5XCJd6rCAIOuzgOqyveuQnCDtmLjstpzsl5DshJwgY2hhbmdlTWF0Y2hlcyhcImVudGl0eVwiKeuKlCB0cnll66W8IOuwmO2ZmO2VmOupsCxcbiAgICAgKiBbXCJ0eXBlc1wiLCBcImkxOG5cIl3snbQg67OA6rK965CcIO2YuOy2nOyXkOyEnCBjaGFuZ2VNYXRjaGVzKFwidHlwZXNcIiwgXCJmdW5jdGlvbnNcIinrj4QgdHJ1ZeulvCDrsJjtmZjtlZjsp4Drp4wsXG4gICAgICogW1wiZnVuY3Rpb25zXCJd6rCAIOuzgOqyveuQnCDtmLjstpzsl5DshJwgY2hhbmdlTWF0Y2hlcyhcImZyYW1lXCIp7J2AIGZhbHNl66W8IOuwmO2ZmO2VqeuLiOuLpC5cbiAgICAgKiBAcGFyYW0gdHlwZXNcbiAgICAgKi9cbiAgICBjb25zdCBjaGFuZ2VNYXRjaGVzID0gKC4uLnR5cGVzOiBGaWxlVHlwZVtdKSA9PiB7XG4gICAgICBjb25zdCBtYXRjaGluZyA9IHR5cGVzLmZpbHRlcigodCkgPT4gZGlmZlR5cGVzLmluY2x1ZGVzKHQpKTtcbiAgICAgIG1hdGNoaW5nLmZvckVhY2goKHQpID0+IGhhbmRsZWQuYWRkKHQpKTtcbiAgICAgIHJldHVybiBtYXRjaGluZy5sZW5ndGggPiAwO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiDslrTrlqQgY2hhbmdlTWF0Y2hlcyDtmLjstpzsl5Drj4Qg6rG466as7KeAIOyViuydgCBGaWxlVHlwZeuTpOydmCDsi6TsoJwg7YyM7J28IOqyveuhnOulvCDrqqjslYTshJwg67CY7ZmY7ZWp64uI64ukLlxuICAgICAqL1xuICAgIGNvbnN0IHVuaGFuZGxlZFBhdGhzID0gKCk6IEFic29sdXRlUGF0aFtdID0+XG4gICAgICBkaWZmVHlwZXMuZmlsdGVyKCh0KSA9PiAhaGFuZGxlZC5oYXModCkpLmZsYXRNYXAoKHQpID0+IGRpZmZHcm91cHNbdF0gPz8gW10pO1xuXG4gICAgLyoqXG4gICAgICogY2hhbmdlTWF0Y2hlcyDtmLjstpzsl5Drj4Qg6rG466as7KeAIOyViuydgCBGaWxlVHlwZeuTpOydtCDsobTsnqztlZjripTsp4Ag7ZmV7J247ZWp64uI64ukLlxuICAgICAqL1xuICAgIGNvbnN0IHVuaGFuZGxlZENoYW5nZXNMZWZ0ID0gKCkgPT4gdW5oYW5kbGVkUGF0aHMoKS5sZW5ndGggPiAwO1xuXG4gICAgcmV0dXJuIHsgY2hhbmdlTWF0Y2hlcywgdW5oYW5kbGVkUGF0aHMsIHVuaGFuZGxlZENoYW5nZXNMZWZ0IH07XG4gIH1cblxuICBhc3luYyBoYW5kbGVUcnV0aFNvdXJjZUNoYW5nZXMoZGlmZkdyb3VwczogRGlmZkdyb3Vwcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIE5haXRlLnQoXCJoYW5kbGVUcnV0aFNvdXJjZUNoYW5nZXNcIiwgeyBkaWZmR3JvdXBzIH0pO1xuXG4gICAgYXdhaXQgRW50aXR5TWFuYWdlci5yZWxvYWQoKTtcblxuICAgIC8vIHR5cGVzIOyDneyEsShlbnRpdHkg7IOI66GcIOy2lOqwgOuQnCDqsr3smrApXG4gICAgLy8gcGFyZW50SWTqsIAg7JeG6rOgLCB0eXBlc+qwgCDsl4bripQg6rK97Jqw7JeQ66eMIOyDneyEsVxuICAgIGNvbnN0IGVudGl0eVBhdGggPSBkaWZmR3JvdXBzLmVudGl0eT8uYXQoMCk7XG4gICAgaWYgKGVudGl0eVBhdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZW50aXR5SWQgPSBFbnRpdHlNYW5hZ2VyLmdldEVudGl0eUlkRnJvbVBhdGgoZW50aXR5UGF0aCk7XG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgIC8vIO2UhOuhnOygne2KuOyXkCDsg53shLHrkJjslrTslbwg7ZWY64qUIC50cyDtjIzsnbzsnZgg6rK966Gc7J6F64uI64ukLlxuICAgICAgY29uc3QgdHlwZUZpbGVQYXRoID1cbiAgICAgICAgLyogU0FGRVRZOiBUeXBlU2NyaXB0IEFTVCDtjIzsi7Hqs7wg64+Z6riw7ZmUIOyeheugpSDqs4Tslb3snbQg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyBwYXRoLmpvaW4oXG4gICAgICAgICAgU29uYW11LmFwaVJvb3RQYXRoLFxuICAgICAgICAgIGBzcmMvYXBwbGljYXRpb24vJHtlbnRpdHkubmFtZXMuZnN9LyR7ZW50aXR5Lm5hbWVzLmZzfS50eXBlcy50c2AsXG4gICAgICAgICkgYXMgQWJzb2x1dGVQYXRoO1xuXG4gICAgICBpZiAoZW50aXR5LnBhcmVudElkID09PSB1bmRlZmluZWQgJiYgIShhd2FpdCBzeW5jZXJGaWxlRXhpc3RzKHR5cGVGaWxlUGF0aCkpKSB7XG4gICAgICAgIC8vICoudHlwZXMudHPqsIAg66eM65Ok7Ja07KeR64uI64ukLlxuICAgICAgICBjb25zdCB0eXBlcyA9IGF3YWl0IFN5bmNlckFjdGlvbnMuYWN0aW9uR2VuZXJhdGVJbml0aWFsVHlwZXMoZW50aXR5SWQpO1xuXG4gICAgICAgIC8vIOq3uOqxuCDtg4Dqsp/sl5Ag6rCW64uk65Gs7JqULlxuICAgICAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNGaWxlc1RvVGFyZ2V0cyh0eXBlcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc29uYW11LmdlbmVyYXRlZC50c+yZgCBzb25hbXUuZ2VuZXJhdGVkLnNzby50c+qwgCDrp4zrk6TslrTsp5Hri4jri6QuXG4gICAgY29uc3QgZ2VuZXJhdGVkID0gYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZVNjaGVtYXMoKTtcblxuICAgIC8vIOuqqOuToCDqsoPrk6TsnYQgdGFyZ2V07JeQIOuztOuCtOyngOuKlCDslYrsirXri4jri6QuXG4gICAgLy8gc29uYW11LmdlbmVyYXRlZC5zc28udHPripQgc2VydmljZS1zaWRlLW9ubHnri4jquYwg67Cw7KCc7ZWp64uI64ukLlxuICAgIC8vIFRPRE8o67OR7KSAKTog7J20IO2VmOuTnOy9lOuTnOulvCDriITqsIAg7ZW06rKwIOyigCDtlbTso7zshLjsmpQuIOydvOuLqOydgCDqsJDri7kg6rCA64ql7ZWY64uIIOuGlOuRkOqyoOyKteuLiOuLpC4uLlxuICAgIGNvbnN0IGRpc3RyaWJ1dGFibGUgPSBnZW5lcmF0ZWQuZmlsdGVyKChwKSA9PiAhcC5lbmRzV2l0aChcIi5zc28udHNcIikpO1xuXG4gICAgLy8g7J207KCcIOuztOuCvCDqsoPrk6Trp4wgdGFyZ2V07JeQIOuztOuCtOyalC5cbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNGaWxlc1RvVGFyZ2V0cyhkaXN0cmlidXRhYmxlKTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUltcGxlbWVudGF0aW9uQ2hhbmdlcyhkaWZmR3JvdXBzOiBEaWZmR3JvdXBzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgTmFpdGUudChcImhhbmRsZUltcGxlbWVudGF0aW9uQ2hhbmdlc1wiLCB7IGRpZmZHcm91cHMgfSk7XG4gICAgY29uc3QgbWVyZ2VkR3JvdXAgPSBbLi4uKGRpZmZHcm91cHMubW9kZWwgPz8gW10pLCAuLi4oZGlmZkdyb3Vwcy5mcmFtZSA/PyBbXSldO1xuXG4gICAgLy8gZ2VuZXJhdGVkX2h0dHAudGVtcGxhdGUudHPsl5DshJwgc3luY2VyLnR5cGVz66W8IOyUgeuLiOuLpC5cbiAgICAvLyBzZXJ2aWNlLnRlbXBsYXRlLnRz7JeQ7IScIHN5bmNlci5hcGlz66W8IOyUgeuLiOuLpC5cbiAgICBhd2FpdCB0aGlzLmF1dG9sb2FkTW9kZWxzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZEFwaXMoKTtcblxuICAgIGNvbnN0IHBhcmFtczoge1xuICAgICAgbmFtZXNSZWNvcmQ6IEVudGl0eU5hbWVzUmVjb3JkO1xuICAgIH1bXSA9IG1lcmdlZEdyb3VwLm1hcCgobW9kZWxQYXRoKSA9PiB7XG4gICAgICBpZiAobW9kZWxQYXRoLmVuZHNXaXRoKFwiLm1vZGVsLnRzXCIpIHx8IG1vZGVsUGF0aC5lbmRzV2l0aChcIi5mcmFtZS50c1wiKSkge1xuICAgICAgICBjb25zdCBlbnRpdHlJZCA9IEVudGl0eU1hbmFnZXIuZ2V0RW50aXR5SWRGcm9tUGF0aChtb2RlbFBhdGgpO1xuICAgICAgICBhc3NlcnQoZW50aXR5SWQpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWVzUmVjb3JkOiBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKGVudGl0eUlkKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vdCByZWFjaGFibGVcIik7XG4gICAgfSk7XG5cbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlU2VydmljZXMocGFyYW1zKTtcbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlSHR0cHMoKTtcbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvbkdlbmVyYXRlU3NyUXVlcmllcygpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQXV4aWxpYXJ5U3ltYm9sQ2hhbmdlcyhkaWZmR3JvdXBzOiBEaWZmR3JvdXBzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgTmFpdGUudChcImhhbmRsZUF1eGlsaWFyeVN5bWJvbENoYW5nZXNcIiwgeyBkaWZmR3JvdXBzIH0pO1xuICAgIGNvbnN0IHRzUGF0aHMgPSB1bmlxdWUoWy4uLihkaWZmR3JvdXBzLnR5cGVzID8/IFtdKSwgLi4uKGRpZmZHcm91cHMuZnVuY3Rpb25zID8/IFtdKV0pO1xuICAgIGF3YWl0IFN5bmNlckFjdGlvbnMuYWN0aW9uU3luY0ZpbGVzVG9UYXJnZXRzKHRzUGF0aHMpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQ29uZmlnQ2hhbmdlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuSE9UID09PSBcInllc1wiKSB7XG4gICAgICBjb25zdCB7IGxvYWRDb25maWcgfSA9IGF3YWl0IGltcG9ydChcIi4uL2FwaS9jb25maWdcIik7XG4gICAgICBTb25hbXUuY29uZmlnID0gYXdhaXQgbG9hZENvbmZpZyhTb25hbXUuYXBpUm9vdFBhdGgpO1xuICAgIH1cbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNDb25maWcoKTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVNvbmFtdURpY3Rpb25hcnlSZWxhdGVkQ2hhbmdlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBTeW5jZXJBY3Rpb25zLmFjdGlvblN5bmNTb25hbXVEaWN0aW9uYXJ5KCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVIdHRwVmFsaWRhdG9yUmVsYXRlZENoYW5nZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZE1vZGVscygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRBcGlzKCk7XG4gICAgYXdhaXQgU3luY2VyQWN0aW9ucy5hY3Rpb25HZW5lcmF0ZUh0dHBWYWxpZGF0b3JzKCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVEcmlmdHMoZHJpZnRzOiBBYnNvbHV0ZVBhdGhbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChkcmlmdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICBcIuKaoO+4jyBTb25hbXXqsIAg7J6Q64+ZIOyDneyEse2VnCDtjIzsnbzsl5Ag64yA7ZWcIOuzgOqyveydtCDqsJDsp4DrkJjsl4jsirXri4jri6QuIO2MjOydvOydtCBTb25hbXUgd2F0Y2hlciDsmbjrtoDsl5DshJwg67OA6rK965CcIOqyg+ycvOuhnCDstpTsoJXrkKnri4jri6QuXCIsXG4gICAgICApLFxuICAgICk7XG4gICAgZm9yIChjb25zdCBwIG9mIGRyaWZ0cykge1xuICAgICAgY29uc29sZS53YXJuKGNoYWxrLnllbGxvdyhgICAtICR7cGF0aC5yZWxhdGl2ZShTb25hbXUuYXBwUm9vdFBhdGgsIHApfWApKTtcbiAgICB9XG4gICAgY29uc29sZS53YXJuKGNoYWxrLmRpbShcIiAg4oaSIGBwbnBtIHNvbmFtdSBzeW5jIC0tZm9yY2Vg66W8IOq2jOyepe2VqeuLiOuLpC5cIikpO1xuICB9XG5cbiAgLyoqXG4gICAqIOyjvOyWtOynhCDsl5Tti7Dti7DsmYAg7YWc7ZSM66a/IO2CpOyXkCDrjIDtlbQsIOyDneyEseuQnCDsvZTrk5zqsIAg7KG07J6s7ZWY64qU7KeAIO2ZleyduO2VqeuLiOuLpC5cbiAgICogQHBhcmFtIGVudGl0eUlkIOyXlO2LsO2LsCBJRFxuICAgKiBAcGFyYW0gdGVtcGxhdGVLZXkg7YWc7ZSM66a/IO2CpFxuICAgKiBAcGFyYW0gZW51bUlkIOyXtOqxsO2YlSBJRFxuICAgKiBAcmV0dXJucyDsg53shLHrkJwg7L2U65Oc6rCAIOyhtOyerO2VmOuKlOyngCDsl6zrtoBcbiAgICovXG4gIGFzeW5jIGNoZWNrRXhpc3RzR2VuQ29kZShcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIHRlbXBsYXRlS2V5OiBUZW1wbGF0ZUtleSxcbiAgICBlbnVtSWQ/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8eyBzdWJQYXRoOiBzdHJpbmc7IGZ1bGxQYXRoOiBzdHJpbmc7IGlzRXhpc3RzOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCB7IHRhcmdldCwgcGF0aDogZ2VuUGF0aCB9ID0gVGVtcGxhdGVNYW5hZ2VyLmdldCh0ZW1wbGF0ZUtleSkuZ2V0VGFyZ2V0QW5kUGF0aChcbiAgICAgIEVudGl0eU1hbmFnZXIuZ2V0TmFtZXNGcm9tSWQoZW50aXR5SWQpLFxuICAgICAgZW51bUlkLFxuICAgICk7XG5cbiAgICBjb25zdCBzdWJQYXRoID0gcGF0aC5qb2luKHRhcmdldCwgZ2VuUGF0aCk7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCBzdWJQYXRoKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3ViUGF0aCxcbiAgICAgIGZ1bGxQYXRoLFxuICAgICAgaXNFeGlzdHM6IGF3YWl0IHN5bmNlckZpbGVFeGlzdHMoZnVsbFBhdGgpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICog7KO87Ja07KeEIOyXlO2LsO2LsOyZgCDsl7TqsbDtmJXsl5Ag64yA7ZW0LCDsg53shLHrkJwg7L2U65Oc6rCAIOyhtOyerO2VmOuKlOyngCDtmZXsnbjtlanri4jri6QuXG4gICAqIEBwYXJhbSBlbnRpdHlJZCDsl5Tti7Dti7AgSURcbiAgICogQHBhcmFtIGVudW1zIOyXtOqxsO2YlSDroIjsnbTruJRcbiAgICogQHJldHVybnMg7IOd7ISx65CcIOy9lOuTnOqwgCDsobTsnqztlZjripTsp4Ag7Jes67aAXG4gICAqL1xuICBhc3luYyBjaGVja0V4aXN0cyhcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIGVudW1zOiB7XG4gICAgICBbbmFtZTogc3RyaW5nXTogei5ab2RFbnVtO1xuICAgIH0sXG4gICk6IFByb21pc2U8UmVjb3JkPGAke1RlbXBsYXRlS2V5fSR7c3RyaW5nfWAsIGJvb2xlYW4+PiB7XG4gICAgY29uc3Qga2V5czogVGVtcGxhdGVLZXlbXSA9IFRlbXBsYXRlS2V5Lm9wdGlvbnM7XG4gICAgY29uc3QgbmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKGVudGl0eUlkKTtcbiAgICBjb25zdCBlbnVtc0tleXMgPSBPYmplY3Qua2V5cyhlbnVtcykuZmlsdGVyKChuYW1lKSA9PiBuYW1lICE9PSBuYW1lcy5jb25zdGFudCk7XG5cbiAgICByZXR1cm4gYXdhaXQgcmVkdWNlQXN5bmMoXG4gICAgICBrZXlzLFxuICAgICAgYXN5bmMgKHJlc3VsdCwga2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IHRwbCA9IFRlbXBsYXRlTWFuYWdlci5nZXQoa2V5KTtcbiAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKFwidmlld19lbnVtc1wiKSkge1xuICAgICAgICAgIGF3YWl0IG1hcEFzeW5jKGVudW1zS2V5cywgYXN5bmMgKGNvbXBvbmVudElkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHRhcmdldCwgcGF0aDogcCB9ID0gdHBsLmdldFRhcmdldEFuZFBhdGgobmFtZXMsIGNvbXBvbmVudElkKTtcbiAgICAgICAgICAgIHJlc3VsdFtgJHtrZXl9X18ke2NvbXBvbmVudElkfWBdID0gYXdhaXQgc3luY2VyRmlsZUV4aXN0cyhcbiAgICAgICAgICAgICAgcGF0aC5qb2luKFNvbmFtdS5hcHBSb290UGF0aCwgdGFyZ2V0LCBwKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgdGFyZ2V0LCBwYXRoOiBwIH0gPSB0cGwuZ2V0VGFyZ2V0QW5kUGF0aChuYW1lcyk7XG4gICAgICAgIGNvbnN0IHsgdGFyZ2V0cyB9ID0gU29uYW11LmNvbmZpZy5zeW5jO1xuICAgICAgICBpZiAodGFyZ2V0LmluY2x1ZGVzKFwiOnRhcmdldFwiKSkge1xuICAgICAgICAgIGF3YWl0IG1hcEFzeW5jKHRhcmdldHMsIGFzeW5jICh0KSA9PiB7XG4gICAgICAgICAgICByZXN1bHRbYCR7a2V5fV9fJHt0fWBdID0gYXdhaXQgc3luY2VyRmlsZUV4aXN0cyhcbiAgICAgICAgICAgICAgcGF0aC5qb2luKFNvbmFtdS5hcHBSb290UGF0aCwgdGFyZ2V0LnJlcGxhY2UoXCI6dGFyZ2V0XCIsIHQpLCBwKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W2tleV0gPSBhd2FpdCBzeW5jZXJGaWxlRXhpc3RzKHBhdGguam9pbihTb25hbXUuYXBwUm9vdFBhdGgsIHRhcmdldCwgcCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICAvKiBTQUZFVFk6IFR5cGVTY3JpcHQgQVNUIO2MjOyLseqzvCDrj5nquLDtmZQg7J6F66ClIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIHt9IGFzIFJlY29yZDxcbiAgICAgICAgYCR7VGVtcGxhdGVLZXl9JHtzdHJpbmd9YCxcbiAgICAgICAgYm9vbGVhblxuICAgICAgPixcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgY3JlYXRlRW50aXR5KGZvcm06IFRlbXBsYXRlT3B0aW9uc1tcImVudGl0eVwiXSkge1xuICAgIHJldHVybiBhd2FpdCBjcmVhdGVFbnRpdHkoZm9ybSk7XG4gIH1cblxuICAvKipcbiAgICog7ZWY7JyE7Zi47ZmY7JqpIO2UhOuhneyLnCDrqZTshozrk5zsnoXri4jri6QuXG4gICAqL1xuICBhc3luYyBkZWxFbnRpdHkoZW50aXR5SWQ6IHN0cmluZyk6IFByb21pc2U8eyBkZWxQYXRoczogc3RyaW5nW10gfT4ge1xuICAgIHJldHVybiBhd2FpdCBkZWxFbnRpdHkoZW50aXR5SWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGVUZW1wbGF0ZTxUIGV4dGVuZHMgVGVtcGxhdGVLZXk+KFxuICAgIGtleTogVCxcbiAgICB0ZW1wbGF0ZU9wdGlvbnM6IFRlbXBsYXRlT3B0aW9uc1tUXSxcbiAgICBfZ2VuZXJhdGVPcHRpb25zPzogR2VuZXJhdGVPcHRpb25zLFxuICApOiBQcm9taXNlPEFic29sdXRlUGF0aFtdPiB7XG4gICAgcmV0dXJuIGF3YWl0IGdlbmVyYXRlVGVtcGxhdGUoa2V5LCB0ZW1wbGF0ZU9wdGlvbnMsIF9nZW5lcmF0ZU9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgcmVuZGVyVGVtcGxhdGU8VCBleHRlbmRzIGtleW9mIFRlbXBsYXRlT3B0aW9ucz4oXG4gICAga2V5OiBULFxuICAgIHRlbXBsYXRlT3B0aW9uczogVGVtcGxhdGVPcHRpb25zW1RdLFxuICApOiBQcm9taXNlPFBhdGhBbmRDb2RlW10+IHtcbiAgICByZXR1cm4gYXdhaXQgcmVuZGVyVGVtcGxhdGUoa2V5LCB0ZW1wbGF0ZU9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgcmVuZXdDaGVja3N1bXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGF3YWl0IHJlbmV3Q2hlY2tzdW1zKCk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7aUJBVWtEO2FBQ1o7cUJBQ2tCO1lBRWxCO3VCQUV3QjtZQUVsQjtrQkFFZ0I7bUJBQ1Y7aUJBQ047b0JBRW9CO29CQUNWO2VBQ3FCO3FCQUNSO3dCQUNOO29CQUNtQzs4QkFFbEI7b0JBQ0U7cUJBRS9CO0NBS3BDLFNBQWIsTUFBb0I7RUFDbEIsT0FBbUIsQ0FBQztFQUNwQixRQUFxQixDQUFDO0VBQ3RCLFNBQXVCLENBQUM7RUFDeEIsNEJBQTZDLElBQUksSUFBSTtFQUNyRCxlQUE2QixJQUFJLGFBQWE7Ozs7OztFQU85QyxNQUFNLE9BQXNCO0dBSTFCLE1BQU1BLHFDQUFtRDtHQUN6RCxNQUFNQyx3Q0FBc0Q7R0FHNUQsTUFBTSxlQUFlLE1BQU0sK0JBQStCO0dBQzFELElBQUksYUFBYSxXQUFXLEdBQUc7SUFDN0IsSUFBSSxNQUFNLEtBQUssK0JBQStCLEdBQzVDLE1BQU0sZUFBZTtJQUV2QixRQUFRLElBQUksTUFBTSxNQUFNLFFBQVEsV0FBVyx1QkFBdUIsQ0FBQyxDQUFDO0lBQ3BFO0dBQ0Y7R0FLQSxNQUFNLHdCQUNKLFlBQVk7SUFFVixNQUFNLEtBQUssY0FBYyxZQUFZO0lBQ3JDLE1BQU0sS0FBSywrQkFBK0I7SUFHMUMsTUFBTSxlQUFlO0dBQ3ZCLEdBQ0E7SUFBRSxpQkFBaUI7SUFBVyxhQUFhO0dBQU0sQ0FDbkQ7RUFDRjtFQUVBLE1BQWMsaUNBQW1EO0dBQy9ELE1BQU0sZUFBZSxLQUFLLEtBQ3hCLE9BQU8sYUFDUCxnREFDRjtHQUNBLE1BQU0sU0FBUyxPQUFPLE9B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