@decohere/flux 0.0.1-dev.9 → 0.0.1-dev.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/commonjs/src/deferred-script-runner.js +58 -0
  2. package/commonjs/src/flux.command.js +3 -1
  3. package/commonjs/src/flux.js +58 -0
  4. package/commonjs/src/flux.module.js +6 -2
  5. package/commonjs/src/hot-reload-server.js +268 -194
  6. package/commonjs/src/index.js +35 -1
  7. package/commonjs/src/rewrite-serve-specifier.js +46 -0
  8. package/commonjs/src/run.action.js +49 -0
  9. package/commonjs/src/run.command.js +67 -0
  10. package/commonjs/src/serve.action.js +77 -4
  11. package/commonjs/src/serve.command.js +32 -2
  12. package/commonjs/src/slice-serve.js +132 -0
  13. package/commonjs/src/source-module-loader.js +216 -0
  14. package/es6/src/deferred-script-runner.js +48 -0
  15. package/es6/src/flux.command.js +3 -1
  16. package/es6/src/flux.js +43 -0
  17. package/es6/src/flux.module.js +6 -2
  18. package/es6/src/hot-reload-server.js +249 -151
  19. package/es6/src/index.js +6 -2
  20. package/es6/src/rewrite-serve-specifier.js +40 -0
  21. package/es6/src/run.action.js +40 -0
  22. package/es6/src/run.command.js +57 -0
  23. package/es6/src/serve.action.js +73 -4
  24. package/es6/src/serve.command.js +32 -2
  25. package/es6/src/slice-serve.js +107 -0
  26. package/es6/src/source-module-loader.js +160 -0
  27. package/package.json +7 -6
  28. package/types/src/deferred-script-runner.d.ts +18 -0
  29. package/types/src/flux.d.ts +43 -0
  30. package/types/src/flux.module.d.ts +2 -0
  31. package/types/src/hot-reload-server.d.ts +45 -22
  32. package/types/src/index.d.ts +8 -1
  33. package/types/src/rewrite-serve-specifier.d.ts +13 -0
  34. package/types/src/run.action.d.ts +15 -0
  35. package/types/src/run.command.d.ts +11 -0
  36. package/types/src/serve.action.d.ts +11 -1
  37. package/types/src/serve.command.d.ts +5 -0
  38. package/types/src/slice-serve.d.ts +52 -0
  39. package/types/src/source-module-loader.d.ts +49 -0
@@ -1,149 +1,241 @@
1
1
  import { EventEmitter } from "node:events";
2
- import { registerHooks } from "node:module";
3
2
  import path from "node:path";
4
- import { BuildTargets, SwcTranspiler, WorkspaceDefaults } from "@decohere/forge";
5
- import { WorkspaceFactory } from "@decohere/mesh";
6
- import { FileEx, io } from "@decohere/nexus/io";
3
+ import { io } from "@decohere/nexus/io";
7
4
  import { debounce } from "@decohere/nexus/system";
8
5
  import { scribe } from "@decohere/scribe";
6
+ import { SourceModuleLoader } from "./source-module-loader.js";
9
7
  const currentFilePath = io.fileUrlToPath(import.meta.url);
10
8
  const VERSION_URL_PARAM = "version";
11
- const REBOOT_DEBOUNCE_MS = 250;
9
+ /** Default quiet window before a file-change reboot. */ export const DEFAULT_REBOOT_DEBOUNCE_MS = 250;
10
+ /** How many triggering paths to print on the info banner before `+N`. */ const MAX_REBOOT_TRIGGER_PATHS = 4;
11
+ export function resolveRebootDebounceMs(value) {
12
+ const delay = value ?? DEFAULT_REBOOT_DEBOUNCE_MS;
13
+ if (!Number.isFinite(delay) || delay < 0) {
14
+ throw new Error(`rebootDebounceMs must be a non-negative number, got ${String(value)}`);
15
+ }
16
+ return delay;
17
+ }
18
+ function formatTriggerList(triggers) {
19
+ if (triggers.length === 0) return undefined;
20
+ if (triggers.length <= MAX_REBOOT_TRIGGER_PATHS) return triggers.join(", ");
21
+ return `${triggers.slice(0, MAX_REBOOT_TRIGGER_PATHS).join(", ")}, +${triggers.length - MAX_REBOOT_TRIGGER_PATHS}`;
22
+ }
23
+ const BANNER_RULE = "═".repeat(56);
24
+ function wrapFluxBanner(title, details) {
25
+ const body = details.map((line)=>` ${line}`).join("\n");
26
+ return `\n${BANNER_RULE}\n ${title}\n${body}\n${BANNER_RULE}\n`;
27
+ }
28
+ /** Info-level HMR start block — keep `flux reboot` in the text so operators can search the buffer. */ export function formatFluxRebootStart(labels, triggers = []) {
29
+ const who = labels.join(", ") || "entry";
30
+ const files = formatTriggerList(triggers);
31
+ const details = files == null ? [
32
+ who
33
+ ] : [
34
+ who,
35
+ files
36
+ ];
37
+ return wrapFluxBanner("FLUX REBOOT", details);
38
+ }
39
+ /** Info-level HMR finish block. */ export function formatFluxRebootReady(labels, elapsedMs) {
40
+ const who = labels.join(", ") || "entry";
41
+ return wrapFluxBanner("FLUX READY", [
42
+ who,
43
+ `${Math.max(0, Math.round(elapsedMs))}ms`
44
+ ]);
45
+ }
46
+ /** Process-wide: Node's ESM cache is process-global, including across HotReloadServer instances. */ let moduleVersionSeq = 0;
12
47
  export class HotReloadServer extends EventEmitter {
13
48
  // ── State ────────────────────────────────────────────────────────────────
14
49
  logger = scribe.logger(HotReloadServer.name);
50
+ loader = new SourceModuleLoader();
15
51
  disposed = false;
16
- hooksRegistered = false;
17
- entryModulePath;
18
- entryModule;
19
- workspace;
52
+ /** Absolute entry paths currently served (one or more Flux apps). */ entries = new Map();
53
+ pendingEntryReboots = new Set();
54
+ /** Source paths that scheduled the next reboot (cleared when that reboot starts). */ pendingTriggers = new Set();
20
55
  watchSubscription;
21
- /** Map from absolute .ts source file path to project info */ fileInfoMap = new Map();
22
56
  moduleCache = new Map();
23
57
  dependencies = new Map();
24
- transpileCache = new Map();
25
- transpiler = new SwcTranspiler();
58
+ rebootTail = Promise.resolve();
59
+ rebootDebounceGen = 0;
60
+ rebootInFlight = false;
61
+ rebootFollowUp = false;
62
+ rebootQueued = false;
63
+ /** Modules whose reverse-graph edges are pruned at reboot, not on schedule. */ pendingGraphPrune = new Set();
64
+ scheduleReboot = ()=>{};
26
65
  // ── Public API ───────────────────────────────────────────────────────────
27
66
  async start(options) {
28
67
  this.disposed = false;
29
68
  this.dependencies.clear();
30
69
  this.moduleCache.clear();
31
- this.transpileCache.clear();
70
+ this.entries.clear();
71
+ this.pendingEntryReboots.clear();
72
+ this.pendingTriggers.clear();
73
+ this.pendingGraphPrune.clear();
74
+ this.rebootTail = Promise.resolve();
75
+ this.rebootInFlight = false;
76
+ this.rebootFollowUp = false;
77
+ this.rebootQueued = false;
78
+ this.bindScheduleReboot(resolveRebootDebounceMs(options.rebootDebounceMs));
32
79
  const { buildConfig } = options;
33
- this.workspace = await this.resolveWorkspace(options);
34
- const project = this.resolveProject(buildConfig, options.project);
35
- this.entryModulePath = path.resolve(project.getSourceEntryPath());
36
- this.fileInfoMap = await this.buildFileInfoMap(buildConfig);
37
- this.registerHooks();
80
+ await this.loader.configure({
81
+ buildConfig,
82
+ workspace: options.workspace,
83
+ versionFileUrl: (fileUrl)=>this.getCachedOrNew(fileUrl),
84
+ onResolved: this.onPostResolve
85
+ });
86
+ const workspace = this.requireWorkspace();
87
+ const selected = this.resolveProjects(buildConfig, options);
88
+ for (const project of selected){
89
+ const entryPath = path.resolve(project.getSourceEntryPath());
90
+ this.entries.set(entryPath, {
91
+ path: entryPath,
92
+ label: project.name
93
+ });
94
+ }
95
+ this.loader.registerHooks();
38
96
  this.invalidateAllSourceFiles();
39
- await this.workspace.watch(buildConfig);
40
- this.watchSubscription = this.workspace.projectFileChanged$.subscribe(this.onFileChange);
41
- this.logger.trace(`Serving ${this.entryModulePath}`);
42
- await this.bootEntry();
97
+ await workspace.watch(buildConfig);
98
+ this.watchSubscription = workspace.projectFileChanged$.subscribe(this.onFileChange);
99
+ for (const entry of this.entries.values()){
100
+ this.logger.trace(`Serving ${entry.path}`);
101
+ }
102
+ await this.bootEntries([
103
+ ...this.entries.keys()
104
+ ]);
43
105
  this.emit("start");
44
106
  }
45
107
  async dispose() {
46
108
  if (this.disposed) return;
47
109
  this.disposed = true;
110
+ this.rebootDebounceGen += 1;
48
111
  this.watchSubscription?.unsubscribe();
49
- this.workspace?.[Symbol.dispose]();
50
- await this.disposeEntry();
112
+ await this.rebootTail;
113
+ await this.disposeEntries([
114
+ ...this.entries.keys()
115
+ ]);
116
+ this.loader.dispose();
51
117
  }
52
118
  async [Symbol.asyncDispose]() {
53
119
  await this.dispose();
54
120
  }
55
121
  // ── Lifecycle ────────────────────────────────────────────────────────────
56
- async bootEntry() {
122
+ async bootEntries(entryPaths) {
123
+ await Promise.all(entryPaths.map((entryPath)=>this.bootEntry(entryPath)));
124
+ }
125
+ async bootEntry(entryPath) {
126
+ const state = this.entries.get(entryPath);
127
+ if (state == null) return;
57
128
  try {
58
- const url = this.versionModule(io.pathToFileUrl(this.entryModulePath));
59
- this.entryModule = (await import(url))?.default;
129
+ const mod = await this.loader.importEntry(entryPath);
130
+ state.module = mod?.default;
60
131
  } catch (error) {
132
+ state.module = undefined;
61
133
  this.logger.error("There was an error booting the entry point. Your application may not function as expected", error);
62
134
  }
63
135
  }
64
- async reboot() {
65
- this.logger.trace("Rebooting entry module");
66
- await this.disposeEntry();
67
- this.emit("reboot");
68
- await this.bootEntry();
69
- }
70
- async disposeEntry() {
71
- await this.entryModule?.[Symbol.asyncDispose]();
136
+ bindScheduleReboot(delayMs) {
137
+ const gen = ++this.rebootDebounceGen;
138
+ this.scheduleReboot = debounce(async ()=>{
139
+ if (this.disposed || gen !== this.rebootDebounceGen) return;
140
+ this.requestReboot();
141
+ }, delayMs);
72
142
  }
73
- scheduleReboot = debounce(()=>this.reboot(), REBOOT_DEBOUNCE_MS);
74
- // ── Setup ────────────────────────────────────────────────────────────────
75
- async resolveWorkspace(options) {
76
- return options.workspace ?? WorkspaceFactory.create({
77
- ...WorkspaceDefaults,
78
- rootDir: process.cwd()
79
- });
143
+ requestReboot() {
144
+ if (this.disposed) return;
145
+ if (this.rebootInFlight) {
146
+ this.rebootFollowUp = true;
147
+ return;
148
+ }
149
+ if (this.rebootQueued) return;
150
+ this.rebootQueued = true;
151
+ this.rebootTail = this.rebootTail.then(()=>this.runReboot(), ()=>this.runReboot());
80
152
  }
81
- resolveProject(buildConfig, name) {
82
- const projects = this.workspace?.getProjects(buildConfig) ?? [];
83
- const found = name == null ? projects.at(0) : projects.find((p)=>p.name === name);
84
- if (found == null) {
85
- throw new Error(name == null ? `No projects found for configuration: ${buildConfig}` : `Project "${name}" not found in workspace`);
153
+ async runReboot() {
154
+ this.rebootQueued = false;
155
+ if (this.disposed) return;
156
+ this.rebootInFlight = true;
157
+ try {
158
+ do {
159
+ this.rebootFollowUp = false;
160
+ if (this.disposed) return;
161
+ const toReboot = this.pendingEntryReboots.size > 0 ? [
162
+ ...this.pendingEntryReboots
163
+ ] : [
164
+ ...this.entries.keys()
165
+ ];
166
+ this.pendingEntryReboots.clear();
167
+ // Drop reverse edges only when rebooting so later saves in the debounce
168
+ // window can still walk the graph and reset the quiet timer.
169
+ this.prunePendingDependencyEdges();
170
+ const startedAt = Date.now();
171
+ const labels = this.labelsFor(toReboot);
172
+ const triggers = this.takeTriggers();
173
+ this.logger.info(formatFluxRebootStart(labels, triggers));
174
+ await this.disposeEntries(toReboot);
175
+ await this.bootEntries(toReboot);
176
+ this.logger.info(formatFluxRebootReady(labels, Date.now() - startedAt));
177
+ this.emit("reboot");
178
+ }while (this.rebootFollowUp && !this.disposed)
179
+ } finally{
180
+ const needsFollowUp = this.rebootFollowUp && !this.disposed;
181
+ this.rebootFollowUp = false;
182
+ this.rebootInFlight = false;
183
+ if (needsFollowUp) this.requestReboot();
86
184
  }
87
- return found;
88
185
  }
89
- async buildFileInfoMap(buildConfig) {
90
- const projects = this.workspace?.getProjects(buildConfig) ?? [];
91
- const entries = await Promise.all(projects.map(async (project)=>{
92
- const files = await project.getAllFiles();
93
- return files.map((file)=>[
94
- file.fullPath,
95
- {
96
- project
97
- }
98
- ]);
99
- }));
100
- return new Map(entries.flat());
186
+ async disposeEntries(entryPaths) {
187
+ await Promise.all(entryPaths.map((entryPath)=>this.disposeEntry(entryPath)));
101
188
  }
102
- registerHooks() {
103
- if (this.hooksRegistered) return;
104
- this.hooksRegistered = true;
105
- registerHooks({
106
- resolve: (specifier, context, next)=>{
107
- if (this.disposed) return next(specifier, context);
108
- const parentUrl = context.parentURL ?? "";
109
- const rewritten = this.rewriteJsToTs(specifier, parentUrl) ?? specifier;
110
- const result = next(rewritten, context);
111
- this.onPostResolve(result, parentUrl);
112
- return result;
113
- },
114
- load: (url, context, next)=>{
115
- if (this.disposed) return next(url, context);
116
- const result = this.loadTs(url);
117
- if (result != null) return {
118
- format: "module",
119
- source: result.source,
120
- shortCircuit: true
121
- };
122
- return next(url, context);
189
+ async disposeEntry(entryPath) {
190
+ const paths = entryPath != null ? [
191
+ entryPath
192
+ ] : [
193
+ ...this.entries.keys()
194
+ ];
195
+ for (const p of paths){
196
+ const state = this.entries.get(p);
197
+ if (state == null) continue;
198
+ const entry = state.module;
199
+ state.module = undefined;
200
+ try {
201
+ await entry?.[Symbol.asyncDispose]();
202
+ } catch (error) {
203
+ this.logger.error("Entry asyncDispose failed", error);
123
204
  }
124
- });
205
+ }
125
206
  }
126
- // ── Module hooks ─────────────────────────────────────────────────────────
127
- /**
128
- * Pre-next specifier rewriter: if specifier is a .js import that maps to a
129
- * known .ts source file, returns the versioned .ts file URL so next() never
130
- * tries to load a non-existent .js file from disk.
131
- */ rewriteJsToTs = (specifier, parentUrl)=>{
132
- if (!specifier.endsWith(".js")) return null;
133
- const parentClean = parentUrl.split("?")[0];
134
- if (!parentClean) return null;
135
- let jsPath;
136
- try {
137
- const resolved = new URL(specifier, parentClean);
138
- jsPath = io.fileUrlToPath(resolved.toString());
139
- } catch {
140
- return null;
207
+ // ── Setup ────────────────────────────────────────────────────────────────
208
+ requireWorkspace() {
209
+ const workspace = this.loader.getWorkspace();
210
+ if (workspace == null) {
211
+ throw new Error("SourceModuleLoader has no workspace after configure");
141
212
  }
142
- if (!jsPath.endsWith(".js")) return null;
143
- const tsPath = jsPath.replace(/\.js$/, ".ts");
144
- if (!this.fileInfoMap.has(tsPath)) return null;
145
- return this.getCachedOrNew(io.pathToFileUrl(tsPath));
146
- };
213
+ return workspace;
214
+ }
215
+ resolveProjects(buildConfig, options) {
216
+ const projects = this.loader.getWorkspace()?.getProjects(buildConfig) ?? [];
217
+ const names = options.projects != null && options.projects.length > 0 ? options.projects : options.project != null ? [
218
+ options.project
219
+ ] : undefined;
220
+ if (names == null) {
221
+ const first = projects.at(0);
222
+ if (first == null) {
223
+ throw new Error(`No projects found for configuration: ${buildConfig}`);
224
+ }
225
+ return [
226
+ first
227
+ ];
228
+ }
229
+ const selected = [];
230
+ for (const name of names){
231
+ const found = projects.find((p)=>p.name === name);
232
+ if (found == null) {
233
+ throw new Error(`Project "${name}" not found in workspace`);
234
+ }
235
+ selected.push(found);
236
+ }
237
+ return selected;
238
+ }
147
239
  /**
148
240
  * Post-next dependency tracker: records which source files import which
149
241
  * other source files so that reloadIfAffected can traverse the graph.
@@ -164,55 +256,25 @@ export class HotReloadServer extends EventEmitter {
164
256
  } catch {
165
257
  parentPath = "";
166
258
  }
167
- const isSource = this.fileInfoMap.has(filePath);
168
- const parentIsSource = this.fileInfoMap.has(parentPath);
259
+ const isSource = this.loader.hasSourceFile(filePath);
260
+ const parentIsSource = this.loader.hasSourceFile(parentPath);
169
261
  if (isSource || parentIsSource) {
170
262
  this.trackDependency(filePath, parentPath);
171
263
  }
172
264
  };
173
- loadTs = (url)=>{
174
- if (!url.startsWith("file:")) return null;
175
- const cleanPath = new URL(url).pathname;
176
- const fileInfo = this.fileInfoMap.get(cleanPath);
177
- if (fileInfo == null) return null;
178
- const cached = this.transpileCache.get(cleanPath);
179
- if (cached != null) return {
180
- source: cached
181
- };
182
- const { project } = fileInfo;
183
- const tsConfig = project.getTsConfigSync();
184
- const userConfig = project.getSwcConfigSync();
185
- const file = new FileEx({
186
- fullPath: cleanPath
187
- });
188
- const response = this.transpiler.transformFileSync(file, BuildTargets.es6, {
189
- tsConfig,
190
- aliasPaths: true,
191
- userConfig
192
- });
193
- if (response.outcome !== "success") {
194
- this.logger.error(`Failed to transpile ${cleanPath}`, response);
195
- return null;
196
- }
197
- this.transpileCache.set(cleanPath, response.code);
198
- return {
199
- source: response.code
200
- };
201
- };
202
265
  // ── File watching ────────────────────────────────────────────────────────
203
266
  onFileChange = (evt)=>{
204
267
  const { file, eventName, project } = evt;
205
268
  const fullPath = file.fullPath;
206
269
  this.logger.trace(`File ${eventName}: ${fullPath}`);
207
270
  if (eventName === io.WatchEvents.unlink) {
208
- this.fileInfoMap.delete(fullPath);
271
+ this.loader.invalidateTranspile(fullPath);
272
+ this.moduleCache.set(fullPath, null);
209
273
  return;
210
274
  }
211
275
  if (eventName === io.WatchEvents.add) {
212
276
  if (project.isSourceFile(file)) {
213
- this.fileInfoMap.set(fullPath, {
214
- project
215
- });
277
+ this.loader.setSourceFile(fullPath, project);
216
278
  this.moduleCache.set(fullPath, null);
217
279
  this.reloadIfAffected(fullPath);
218
280
  }
@@ -220,10 +282,7 @@ export class HotReloadServer extends EventEmitter {
220
282
  }
221
283
  // change
222
284
  if (!project.isSourceFile(file)) return;
223
- this.transpileCache.delete(fullPath);
224
- this.transpiler.invalidateContentCache(new FileEx({
225
- fullPath
226
- }));
285
+ this.loader.invalidateTranspile(fullPath);
227
286
  this.reloadIfAffected(fullPath);
228
287
  };
229
288
  reloadIfAffected(fullPath) {
@@ -234,12 +293,22 @@ export class HotReloadServer extends EventEmitter {
234
293
  fullPath
235
294
  ])
236
295
  ];
237
- if (!modules.includes(this.entryModulePath)) {
296
+ const affectedEntries = [
297
+ ...this.entries.keys()
298
+ ].filter((entryPath)=>modules.includes(entryPath));
299
+ if (affectedEntries.length === 0) {
238
300
  this.logger.trace(`Change in ${fullPath} does not affect entry — skipping reload`);
239
301
  return false;
240
302
  }
241
303
  this.logger.trace(`Change in ${fullPath} affects ${modules.length} module(s) — scheduling reload`);
242
- this.invalidateModule(...modules);
304
+ this.invalidateModuleCaches(...modules);
305
+ for (const module of modules){
306
+ this.pendingGraphPrune.add(module);
307
+ }
308
+ for (const entryPath of affectedEntries){
309
+ this.pendingEntryReboots.add(entryPath);
310
+ }
311
+ this.pendingTriggers.add(fullPath);
243
312
  this.scheduleReboot();
244
313
  return true;
245
314
  }
@@ -253,7 +322,7 @@ export class HotReloadServer extends EventEmitter {
253
322
  }
254
323
  let subDeps = [];
255
324
  for (const dep of moduleDeps){
256
- if (!this.fileInfoMap.has(dep)) continue;
325
+ if (!this.loader.hasSourceFile(dep)) continue;
257
326
  const subs = this.getDependencyGraph(dep, [
258
327
  moduleId,
259
328
  ...parentModules
@@ -291,14 +360,24 @@ export class HotReloadServer extends EventEmitter {
291
360
  }
292
361
  versionModule(moduleUrl) {
293
362
  const versionedUrl = new URL(moduleUrl);
294
- versionedUrl.searchParams.set(VERSION_URL_PARAM, Date.now().toString());
363
+ versionedUrl.searchParams.set(VERSION_URL_PARAM, String(++moduleVersionSeq));
295
364
  return versionedUrl.toString();
296
365
  }
297
- invalidateModule(...modules) {
366
+ invalidateModuleCaches(...modules) {
298
367
  for (const module of modules){
299
368
  this.moduleCache.set(module, null);
300
- this.transpileCache.delete(module);
301
- // Prune stale outgoing edges: remove this module as a parent from all dependency lists
369
+ this.loader.invalidateTranspile(module);
370
+ }
371
+ }
372
+ prunePendingDependencyEdges() {
373
+ const modules = [
374
+ ...this.pendingGraphPrune
375
+ ];
376
+ this.pendingGraphPrune.clear();
377
+ this.pruneDependencyParents(...modules);
378
+ }
379
+ /** Remove these modules as parents so boot can rebuild edges without stale importers. */ pruneDependencyParents(...modules) {
380
+ for (const module of modules){
302
381
  for (const [key, parents] of this.dependencies){
303
382
  const filtered = parents.filter((p)=>p !== module);
304
383
  if (filtered.length === 0) {
@@ -310,14 +389,33 @@ export class HotReloadServer extends EventEmitter {
310
389
  }
311
390
  }
312
391
  invalidateAllSourceFiles() {
313
- for (const filePath of this.fileInfoMap.keys()){
392
+ for (const filePath of this.loader.sourceFilePaths()){
314
393
  this.moduleCache.set(filePath, null);
315
394
  }
316
395
  }
317
- // ── Utilities ────────────────────────────────────────────────────────────
318
396
  isSelf(filePath) {
319
397
  return currentFilePath === path.resolve(filePath);
320
398
  }
399
+ labelsFor(entryPaths) {
400
+ return entryPaths.map((entryPath)=>this.entries.get(entryPath)?.label ?? path.basename(entryPath));
401
+ }
402
+ takeTriggers() {
403
+ const triggers = [
404
+ ...this.pendingTriggers
405
+ ].map((fullPath)=>this.formatTrigger(fullPath));
406
+ this.pendingTriggers.clear();
407
+ return triggers;
408
+ }
409
+ formatTrigger(fullPath) {
410
+ const root = this.loader.getWorkspace()?.rootDir;
411
+ if (root != null) {
412
+ const rel = path.relative(path.resolve(root), fullPath);
413
+ if (rel !== "" && !rel.startsWith("..") && !path.isAbsolute(rel)) {
414
+ return rel.replaceAll("\\", "/");
415
+ }
416
+ }
417
+ return path.basename(fullPath);
418
+ }
321
419
  }
322
420
 
323
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZsdXgvc3JjL2hvdC1yZWxvYWQtc2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gXCJub2RlOmV2ZW50c1wiO1xuaW1wb3J0IHR5cGUge1xuXHRMb2FkRm5PdXRwdXQsXG5cdExvYWRIb29rQ29udGV4dCxcblx0UmVzb2x2ZUZuT3V0cHV0LFxuXHRSZXNvbHZlSG9va0NvbnRleHQsXG59IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuaW1wb3J0IHsgcmVnaXN0ZXJIb29rcyB9IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgQnVpbGRUYXJnZXRzLCBTd2NUcmFuc3BpbGVyLCBXb3Jrc3BhY2VEZWZhdWx0cyB9IGZyb20gXCJAZGVjb2hlcmUvZm9yZ2VcIjtcbmltcG9ydCB0eXBlIHsgUHJvamVjdCwgUHJvamVjdEZpbGVFdmVudCwgV29ya3NwYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyBXb3Jrc3BhY2VGYWN0b3J5IH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyBGaWxlRXgsIGlvIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9pb1wiO1xuaW1wb3J0IHsgZGVib3VuY2UgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL3N5c3RlbVwiO1xuaW1wb3J0IHsgdHlwZSBMb2dnZXIsIHNjcmliZSB9IGZyb20gXCJAZGVjb2hlcmUvc2NyaWJlXCI7XG5pbXBvcnQgdHlwZSB7IFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5cbnR5cGUgTG9hZERlbGVnYXRlID0gKHVybDogc3RyaW5nKSA9PiB7IHNvdXJjZTogc3RyaW5nIH0gfCBudWxsO1xuXG5jb25zdCBjdXJyZW50RmlsZVBhdGggPSBpby5maWxlVXJsVG9QYXRoKGltcG9ydC5tZXRhLnVybCk7XG5jb25zdCBWRVJTSU9OX1VSTF9QQVJBTSA9IFwidmVyc2lvblwiO1xuY29uc3QgUkVCT09UX0RFQk9VTkNFX01TID0gMjUwO1xuXG5leHBvcnQgaW50ZXJmYWNlIEhvdFJlbG9hZFNlcnZlckV2ZW50cyB7XG5cdHN0YXJ0OiBbXTtcblx0cmVib290OiBbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIb3RSZWxvYWRTZXJ2ZXJPcHRpb25zIHtcblx0LyoqIEJ1aWxkIGNvbmZpZ3VyYXRpb24gbmFtZS4gKi9cblx0YnVpbGRDb25maWc6IHN0cmluZztcblx0LyoqIE5hbWUgb2YgdGhlIHByb2plY3QgdG8gc2VydmUuIERlZmF1bHRzIHRvIHRoZSBmaXJzdCBwcm9qZWN0IGluIHRoZSB3b3Jrc3BhY2UuICovXG5cdHByb2plY3Q/OiBzdHJpbmc7XG5cdC8qKlxuXHQgKiBQcmUtYnVpbHQgV29ya3NwYWNlIGluc3RhbmNlIHRvIHVzZSBpbnN0ZWFkIG9mIHJ1bm5pbmcgV29ya3NwYWNlRmFjdG9yeS5cblx0ICogVXNlZnVsIGluIHRlc3RzIHRvIGJ5cGFzcyBmaWxlc3lzdGVtLWJhc2VkIHdvcmtzcGFjZSBkaXNjb3ZlcnkuXG5cdCAqL1xuXHR3b3Jrc3BhY2U/OiBXb3Jrc3BhY2U7XG59XG5cbnR5cGUgRmlsZUluZm8gPSB7IHByb2plY3Q6IFByb2plY3QgfTtcblxuZXhwb3J0IGNsYXNzIEhvdFJlbG9hZFNlcnZlciBleHRlbmRzIEV2ZW50RW1pdHRlcjxIb3RSZWxvYWRTZXJ2ZXJFdmVudHM+IHtcblx0Ly8g4pSA4pSAIFN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXHRwcml2YXRlIHJlYWRvbmx5IGxvZ2dlcjogTG9nZ2VyID0gc2NyaWJlLmxvZ2dlcihIb3RSZWxvYWRTZXJ2ZXIubmFtZSk7XG5cdHByaXZhdGUgZGlzcG9zZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBob29rc1JlZ2lzdGVyZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBlbnRyeU1vZHVsZVBhdGghOiBzdHJpbmc7XG5cdHByaXZhdGUgZW50cnlNb2R1bGU/OiBBc3luY0Rpc3Bvc2FibGU7XG5cdHByaXZhdGUgd29ya3NwYWNlPzogV29ya3NwYWNlO1xuXHRwcml2YXRlIHdhdGNoU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXHQvKiogTWFwIGZyb20gYWJzb2x1dGUgLnRzIHNvdXJjZSBmaWxlIHBhdGggdG8gcHJvamVjdCBpbmZvICovXG5cdHByaXZhdGUgZmlsZUluZm9NYXAgPSBuZXcgTWFwPHN0cmluZywgRmlsZUluZm8+KCk7XG5cdHByaXZhdGUgbW9kdWxlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nIHwgbnVsbD4oKTtcblx0cHJpdmF0ZSBkZXBlbmRlbmNpZXMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KCk7XG5cdHByaXZhdGUgdHJhbnNwaWxlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXHRwcml2YXRlIHRyYW5zcGlsZXIgPSBuZXcgU3djVHJhbnNwaWxlcigpO1xuXG5cdC8vIOKUgOKUgCBQdWJsaWMgQVBJIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cdHB1YmxpYyBhc3luYyBzdGFydChvcHRpb25zOiBIb3RSZWxvYWRTZXJ2ZXJPcHRpb25zKSB7XG5cdFx0dGhpcy5kaXNwb3NlZCA9IGZhbHNlO1xuXHRcdHRoaXMuZGVwZW5kZW5jaWVzLmNsZWFyKCk7XG5cdFx0dGhpcy5tb2R1bGVDYWNoZS5jbGVhcigpO1xuXHRcdHRoaXMudHJhbnNwaWxlQ2FjaGUuY2xlYXIoKTtcblxuXHRcdGNvbnN0IHsgYnVpbGRDb25maWcgfSA9IG9wdGlvbnM7XG5cdFx0dGhpcy53b3Jrc3BhY2UgPSBhd2FpdCB0aGlzLnJlc29sdmVXb3Jrc3BhY2Uob3B0aW9ucyk7XG5cdFx0Y29uc3QgcHJvamVjdCA9IHRoaXMucmVzb2x2ZVByb2plY3QoYnVpbGRDb25maWcsIG9wdGlvbnMucHJvamVjdCk7XG5cblx0XHR0aGlzLmVudHJ5TW9kdWxlUGF0aCA9IHBhdGgucmVzb2x2ZShwcm9qZWN0LmdldFNvdXJjZUVudHJ5UGF0aCgpKTtcblx0XHR0aGlzLmZpbGVJbmZvTWFwID0gYXdhaXQgdGhpcy5idWlsZEZpbGVJbmZvTWFwKGJ1aWxkQ29uZmlnKTtcblxuXHRcdHRoaXMucmVnaXN0ZXJIb29rcygpO1xuXHRcdHRoaXMuaW52YWxpZGF0ZUFsbFNvdXJjZUZpbGVzKCk7XG5cblx0XHRhd2FpdCB0aGlzLndvcmtzcGFjZS53YXRjaChidWlsZENvbmZpZyk7XG5cdFx0dGhpcy53YXRjaFN1YnNjcmlwdGlvbiA9IHRoaXMud29ya3NwYWNlLnByb2plY3RGaWxlQ2hhbmdlZCQuc3Vic2NyaWJlKHRoaXMub25GaWxlQ2hhbmdlKTtcblxuXHRcdHRoaXMubG9nZ2VyLnRyYWNlKGBTZXJ2aW5nICR7dGhpcy5lbnRyeU1vZHVsZVBhdGh9YCk7XG5cdFx0YXdhaXQgdGhpcy5ib290RW50cnkoKTtcblx0XHR0aGlzLmVtaXQoXCJzdGFydFwiKTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBkaXNwb3NlKCkge1xuXHRcdGlmICh0aGlzLmRpc3Bvc2VkKSByZXR1cm47XG5cdFx0dGhpcy5kaXNwb3NlZCA9IHRydWU7XG5cdFx0dGhpcy53YXRjaFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcblx0XHR0aGlzLndvcmtzcGFjZT8uW1N5bWJvbC5kaXNwb3NlXSgpO1xuXHRcdGF3YWl0IHRoaXMuZGlzcG9zZUVudHJ5KCk7XG5cdH1cblxuXHRwdWJsaWMgYXN5bmMgW1N5bWJvbC5hc3luY0Rpc3Bvc2VdKCkge1xuXHRcdGF3YWl0IHRoaXMuZGlzcG9zZSgpO1xuXHR9XG5cblx0Ly8g4pSA4pSAIExpZmVjeWNsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwcml2YXRlIGFzeW5jIGJvb3RFbnRyeSgpIHtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgdXJsID0gdGhpcy52ZXJzaW9uTW9kdWxlKGlvLnBhdGhUb0ZpbGVVcmwodGhpcy5lbnRyeU1vZHVsZVBhdGgpKTtcblx0XHRcdHRoaXMuZW50cnlNb2R1bGUgPSAoYXdhaXQgaW1wb3J0KHVybCkpPy5kZWZhdWx0O1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihcblx0XHRcdFx0XCJUaGVyZSB3YXMgYW4gZXJyb3IgYm9vdGluZyB0aGUgZW50cnkgcG9pbnQuIFlvdXIgYXBwbGljYXRpb24gbWF5IG5vdCBmdW5jdGlvbiBhcyBleHBlY3RlZFwiLFxuXHRcdFx0XHRlcnJvcixcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyByZWJvb3QoKSB7XG5cdFx0dGhpcy5sb2dnZXIudHJhY2UoXCJSZWJvb3RpbmcgZW50cnkgbW9kdWxlXCIpO1xuXHRcdGF3YWl0IHRoaXMuZGlzcG9zZUVudHJ5KCk7XG5cdFx0dGhpcy5lbWl0KFwicmVib290XCIpO1xuXHRcdGF3YWl0IHRoaXMuYm9vdEVudHJ5KCk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGRpc3Bvc2VFbnRyeSgpIHtcblx0XHRhd2FpdCB0aGlzLmVudHJ5TW9kdWxlPy5bU3ltYm9sLmFzeW5jRGlzcG9zZV0oKTtcblx0fVxuXG5cdHByaXZhdGUgc2NoZWR1bGVSZWJvb3QgPSBkZWJvdW5jZSgoKSA9PiB0aGlzLnJlYm9vdCgpLCBSRUJPT1RfREVCT1VOQ0VfTVMpO1xuXG5cdC8vIOKUgOKUgCBTZXR1cCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwcml2YXRlIGFzeW5jIHJlc29sdmVXb3Jrc3BhY2Uob3B0aW9uczogSG90UmVsb2FkU2VydmVyT3B0aW9ucyk6IFByb21pc2U8V29ya3NwYWNlPiB7XG5cdFx0cmV0dXJuIChcblx0XHRcdG9wdGlvbnMud29ya3NwYWNlID8/XG5cdFx0XHRXb3Jrc3BhY2VGYWN0b3J5LmNyZWF0ZSh7IC4uLldvcmtzcGFjZURlZmF1bHRzLCByb290RGlyOiBwcm9jZXNzLmN3ZCgpIH0pXG5cdFx0KTtcblx0fVxuXG5cdHByaXZhdGUgcmVzb2x2ZVByb2plY3QoYnVpbGRDb25maWc6IHN0cmluZywgbmFtZT86IHN0cmluZyk6IFByb2plY3Qge1xuXHRcdGNvbnN0IHByb2plY3RzID0gdGhpcy53b3Jrc3BhY2U/LmdldFByb2plY3RzKGJ1aWxkQ29uZmlnKSA/PyBbXTtcblx0XHRjb25zdCBmb3VuZCA9IG5hbWUgPT0gbnVsbCA/IHByb2plY3RzLmF0KDApIDogcHJvamVjdHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBuYW1lKTtcblx0XHRpZiAoZm91bmQgPT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRuYW1lID09IG51bGxcblx0XHRcdFx0XHQ/IGBObyBwcm9qZWN0cyBmb3VuZCBmb3IgY29uZmlndXJhdGlvbjogJHtidWlsZENvbmZpZ31gXG5cdFx0XHRcdFx0OiBgUHJvamVjdCBcIiR7bmFtZX1cIiBub3QgZm91bmQgaW4gd29ya3NwYWNlYCxcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHJldHVybiBmb3VuZDtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgYnVpbGRGaWxlSW5mb01hcChidWlsZENvbmZpZzogc3RyaW5nKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBGaWxlSW5mbz4+IHtcblx0XHRjb25zdCBwcm9qZWN0cyA9IHRoaXMud29ya3NwYWNlPy5nZXRQcm9qZWN0cyhidWlsZENvbmZpZykgPz8gW107XG5cdFx0Y29uc3QgZW50cmllcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuXHRcdFx0cHJvamVjdHMubWFwKGFzeW5jIChwcm9qZWN0KSA9PiB7XG5cdFx0XHRcdGNvbnN0IGZpbGVzID0gYXdhaXQgcHJvamVjdC5nZXRBbGxGaWxlcygpO1xuXHRcdFx0XHRyZXR1cm4gZmlsZXMubWFwKChmaWxlKTogW3N0cmluZywgRmlsZUluZm9dID0+IFtmaWxlLmZ1bGxQYXRoLCB7IHByb2plY3QgfV0pO1xuXHRcdFx0fSksXG5cdFx0KTtcblx0XHRyZXR1cm4gbmV3IE1hcChlbnRyaWVzLmZsYXQoKSk7XG5cdH1cblxuXHRwcml2YXRlIHJlZ2lzdGVySG9va3MoKSB7XG5cdFx0aWYgKHRoaXMuaG9va3NSZWdpc3RlcmVkKSByZXR1cm47XG5cdFx0dGhpcy5ob29rc1JlZ2lzdGVyZWQgPSB0cnVlO1xuXHRcdHJlZ2lzdGVySG9va3Moe1xuXHRcdFx0cmVzb2x2ZTogKFxuXHRcdFx0XHRzcGVjaWZpZXI6IHN0cmluZyxcblx0XHRcdFx0Y29udGV4dDogUmVzb2x2ZUhvb2tDb250ZXh0LFxuXHRcdFx0XHRuZXh0OiAoc3BlY2lmaWVyOiBzdHJpbmcsIGNvbnRleHQ/OiBQYXJ0aWFsPFJlc29sdmVIb29rQ29udGV4dD4pID0+IFJlc29sdmVGbk91dHB1dCxcblx0XHRcdCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuIG5leHQoc3BlY2lmaWVyLCBjb250ZXh0KTtcblx0XHRcdFx0Y29uc3QgcGFyZW50VXJsID0gY29udGV4dC5wYXJlbnRVUkwgPz8gXCJcIjtcblx0XHRcdFx0Y29uc3QgcmV3cml0dGVuID0gdGhpcy5yZXdyaXRlSnNUb1RzKHNwZWNpZmllciwgcGFyZW50VXJsKSA/PyBzcGVjaWZpZXI7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IG5leHQocmV3cml0dGVuLCBjb250ZXh0KSBhcyBSZXNvbHZlRm5PdXRwdXQ7XG5cdFx0XHRcdHRoaXMub25Qb3N0UmVzb2x2ZShyZXN1bHQsIHBhcmVudFVybCk7XG5cdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHR9LFxuXHRcdFx0bG9hZDogKFxuXHRcdFx0XHR1cmw6IHN0cmluZyxcblx0XHRcdFx0Y29udGV4dDogTG9hZEhvb2tDb250ZXh0LFxuXHRcdFx0XHRuZXh0OiAodXJsOiBzdHJpbmcsIGNvbnRleHQ/OiBQYXJ0aWFsPExvYWRIb29rQ29udGV4dD4pID0+IExvYWRGbk91dHB1dCxcblx0XHRcdCk6IExvYWRGbk91dHB1dCA9PiB7XG5cdFx0XHRcdGlmICh0aGlzLmRpc3Bvc2VkKSByZXR1cm4gbmV4dCh1cmwsIGNvbnRleHQpO1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSB0aGlzLmxvYWRUcyh1cmwpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICE9IG51bGwpXG5cdFx0XHRcdFx0cmV0dXJuIHsgZm9ybWF0OiBcIm1vZHVsZVwiLCBzb3VyY2U6IHJlc3VsdC5zb3VyY2UsIHNob3J0Q2lyY3VpdDogdHJ1ZSB9O1xuXHRcdFx0XHRyZXR1cm4gbmV4dCh1cmwsIGNvbnRleHQpO1xuXHRcdFx0fSxcblx0XHR9KTtcblx0fVxuXG5cdC8vIOKUgOKUgCBNb2R1bGUgaG9va3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cblx0LyoqXG5cdCAqIFByZS1uZXh0IHNwZWNpZmllciByZXdyaXRlcjogaWYgc3BlY2lmaWVyIGlzIGEgLmpzIGltcG9ydCB0aGF0IG1hcHMgdG8gYVxuXHQgKiBrbm93biAudHMgc291cmNlIGZpbGUsIHJldHVybnMgdGhlIHZlcnNpb25lZCAudHMgZmlsZSBVUkwgc28gbmV4dCgpIG5ldmVyXG5cdCAqIHRyaWVzIHRvIGxvYWQgYSBub24tZXhpc3RlbnQgLmpzIGZpbGUgZnJvbSBkaXNrLlxuXHQgKi9cblx0cHJpdmF0ZSByZXdyaXRlSnNUb1RzID0gKHNwZWNpZmllcjogc3RyaW5nLCBwYXJlbnRVcmw6IHN0cmluZyk6IHN0cmluZyB8IG51bGwgPT4ge1xuXHRcdGlmICghc3BlY2lmaWVyLmVuZHNXaXRoKFwiLmpzXCIpKSByZXR1cm4gbnVsbDtcblxuXHRcdGNvbnN0IHBhcmVudENsZWFuID0gcGFyZW50VXJsLnNwbGl0KFwiP1wiKVswXTtcblx0XHRpZiAoIXBhcmVudENsZWFuKSByZXR1cm4gbnVsbDtcblxuXHRcdGxldCBqc1BhdGg6IHN0cmluZztcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgcmVzb2x2ZWQgPSBuZXcgVVJMKHNwZWNpZmllciwgcGFyZW50Q2xlYW4pO1xuXHRcdFx0anNQYXRoID0gaW8uZmlsZVVybFRvUGF0aChyZXNvbHZlZC50b1N0cmluZygpKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblxuXHRcdGlmICghanNQYXRoLmVuZHNXaXRoKFwiLmpzXCIpKSByZXR1cm4gbnVsbDtcblx0XHRjb25zdCB0c1BhdGggPSBqc1BhdGgucmVwbGFjZSgvXFwuanMkLywgXCIudHNcIik7XG5cdFx0aWYgKCF0aGlzLmZpbGVJbmZvTWFwLmhhcyh0c1BhdGgpKSByZXR1cm4gbnVsbDtcblxuXHRcdHJldHVybiB0aGlzLmdldENhY2hlZE9yTmV3KGlvLnBhdGhUb0ZpbGVVcmwodHNQYXRoKSk7XG5cdH07XG5cblx0LyoqXG5cdCAqIFBvc3QtbmV4dCBkZXBlbmRlbmN5IHRyYWNrZXI6IHJlY29yZHMgd2hpY2ggc291cmNlIGZpbGVzIGltcG9ydCB3aGljaFxuXHQgKiBvdGhlciBzb3VyY2UgZmlsZXMgc28gdGhhdCByZWxvYWRJZkFmZmVjdGVkIGNhbiB0cmF2ZXJzZSB0aGUgZ3JhcGguXG5cdCAqL1xuXHRwcml2YXRlIG9uUG9zdFJlc29sdmUgPSAocmVzdWx0OiBSZXNvbHZlRm5PdXRwdXQsIHBhcmVudFVybDogc3RyaW5nKSA9PiB7XG5cdFx0Y29uc3QgeyB1cmwgfSA9IHJlc3VsdDtcblx0XHRjb25zdCBwYXJlbnRVcmxDbGVhbiA9IHBhcmVudFVybC5zcGxpdChcIj9cIilbMF07XG5cblx0XHRsZXQgZmlsZVBhdGg6IHN0cmluZztcblx0XHRsZXQgcGFyZW50UGF0aDogc3RyaW5nO1xuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHVybE9iaiA9IG5ldyBVUkwodXJsKTtcblx0XHRcdHVybE9iai5zZWFyY2ggPSBcIlwiO1xuXHRcdFx0ZmlsZVBhdGggPSBpby5maWxlVXJsVG9QYXRoKHVybE9iai50b1N0cmluZygpKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0cGFyZW50UGF0aCA9IGlvLmZpbGVVcmxUb1BhdGgocGFyZW50VXJsQ2xlYW4pO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cGFyZW50UGF0aCA9IFwiXCI7XG5cdFx0fVxuXG5cdFx0Y29uc3QgaXNTb3VyY2UgPSB0aGlzLmZpbGVJbmZvTWFwLmhhcyhmaWxlUGF0aCk7XG5cdFx0Y29uc3QgcGFyZW50SXNTb3VyY2UgPSB0aGlzLmZpbGVJbmZvTWFwLmhhcyhwYXJlbnRQYXRoKTtcblxuXHRcdGlmIChpc1NvdXJjZSB8fCBwYXJlbnRJc1NvdXJjZSkge1xuXHRcdFx0dGhpcy50cmFja0RlcGVuZGVuY3koZmlsZVBhdGgsIHBhcmVudFBhdGgpO1xuXHRcdH1cblx0fTtcblxuXHRwcml2YXRlIGxvYWRUczogTG9hZERlbGVnYXRlID0gKHVybDogc3RyaW5nKSA9PiB7XG5cdFx0aWYgKCF1cmwuc3RhcnRzV2l0aChcImZpbGU6XCIpKSByZXR1cm4gbnVsbDtcblxuXHRcdGNvbnN0IGNsZWFuUGF0aCA9IG5ldyBVUkwodXJsKS5wYXRobmFtZTtcblx0XHRjb25zdCBmaWxlSW5mbyA9IHRoaXMuZmlsZUluZm9NYXAuZ2V0KGNsZWFuUGF0aCk7XG5cdFx0aWYgKGZpbGVJbmZvID09IG51bGwpIHJldHVybiBudWxsO1xuXG5cdFx0Y29uc3QgY2FjaGVkID0gdGhpcy50cmFuc3BpbGVDYWNoZS5nZXQoY2xlYW5QYXRoKTtcblx0XHRpZiAoY2FjaGVkICE9IG51bGwpIHJldHVybiB7IHNvdXJjZTogY2FjaGVkIH07XG5cblx0XHRjb25zdCB7IHByb2plY3QgfSA9IGZpbGVJbmZvO1xuXHRcdGNvbnN0IHRzQ29uZmlnID0gcHJvamVjdC5nZXRUc0NvbmZpZ1N5bmMoKTtcblx0XHRjb25zdCB1c2VyQ29uZmlnID0gcHJvamVjdC5nZXRTd2NDb25maWdTeW5jKCk7XG5cblx0XHRjb25zdCBmaWxlID0gbmV3IEZpbGVFeCh7IGZ1bGxQYXRoOiBjbGVhblBhdGggfSk7XG5cdFx0Y29uc3QgcmVzcG9uc2UgPSB0aGlzLnRyYW5zcGlsZXIudHJhbnNmb3JtRmlsZVN5bmMoZmlsZSwgQnVpbGRUYXJnZXRzLmVzNiwge1xuXHRcdFx0dHNDb25maWcsXG5cdFx0XHRhbGlhc1BhdGhzOiB0cnVlLFxuXHRcdFx0dXNlckNvbmZpZyxcblx0XHR9KTtcblxuXHRcdGlmIChyZXNwb25zZS5vdXRjb21lICE9PSBcInN1Y2Nlc3NcIikge1xuXHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYEZhaWxlZCB0byB0cmFuc3BpbGUgJHtjbGVhblBhdGh9YCwgcmVzcG9uc2UpO1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0dGhpcy50cmFuc3BpbGVDYWNoZS5zZXQoY2xlYW5QYXRoLCByZXNwb25zZS5jb2RlKTtcblx0XHRyZXR1cm4geyBzb3VyY2U6IHJlc3BvbnNlLmNvZGUgfTtcblx0fTtcblxuXHQvLyDilIDilIAgRmlsZSB3YXRjaGluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwcml2YXRlIG9uRmlsZUNoYW5nZSA9IChldnQ6IFByb2plY3RGaWxlRXZlbnQpID0+IHtcblx0XHRjb25zdCB7IGZpbGUsIGV2ZW50TmFtZSwgcHJvamVjdCB9ID0gZXZ0O1xuXHRcdGNvbnN0IGZ1bGxQYXRoID0gZmlsZS5mdWxsUGF0aDtcblxuXHRcdHRoaXMubG9nZ2VyLnRyYWNlKGBGaWxlICR7ZXZlbnROYW1lfTogJHtmdWxsUGF0aH1gKTtcblxuXHRcdGlmIChldmVudE5hbWUgPT09IGlvLldhdGNoRXZlbnRzLnVubGluaykge1xuXHRcdFx0dGhpcy5maWxlSW5mb01hcC5kZWxldGUoZnVsbFBhdGgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChldmVudE5hbWUgPT09IGlvLldhdGNoRXZlbnRzLmFkZCkge1xuXHRcdFx0aWYgKHByb2plY3QuaXNTb3VyY2VGaWxlKGZpbGUpKSB7XG5cdFx0XHRcdHRoaXMuZmlsZUluZm9NYXAuc2V0KGZ1bGxQYXRoLCB7IHByb2plY3QgfSk7XG5cdFx0XHRcdHRoaXMubW9kdWxlQ2FjaGUuc2V0KGZ1bGxQYXRoLCBudWxsKTtcblx0XHRcdFx0dGhpcy5yZWxvYWRJZkFmZmVjdGVkKGZ1bGxQYXRoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBjaGFuZ2Vcblx0XHRpZiAoIXByb2plY3QuaXNTb3VyY2VGaWxlKGZpbGUpKSByZXR1cm47XG5cdFx0dGhpcy50cmFuc3BpbGVDYWNoZS5kZWxldGUoZnVsbFBhdGgpO1xuXHRcdHRoaXMudHJhbnNwaWxlci5pbnZhbGlkYXRlQ29udGVudENhY2hlKG5ldyBGaWxlRXgoeyBmdWxsUGF0aCB9KSk7XG5cdFx0dGhpcy5yZWxvYWRJZkFmZmVjdGVkKGZ1bGxQYXRoKTtcblx0fTtcblxuXHRwcml2YXRlIHJlbG9hZElmQWZmZWN0ZWQoZnVsbFBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRcdGNvbnN0IGRlcHMgPSB0aGlzLmdldERlcGVuZGVuY3lHcmFwaChmdWxsUGF0aCk7XG5cdFx0Y29uc3QgbW9kdWxlcyA9IFsuLi5uZXcgU2V0KFsuLi5kZXBzLCBmdWxsUGF0aF0pXTtcblxuXHRcdGlmICghbW9kdWxlcy5pbmNsdWRlcyh0aGlzLmVudHJ5TW9kdWxlUGF0aCkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLnRyYWNlKGBDaGFuZ2UgaW4gJHtmdWxsUGF0aH0gZG9lcyBub3QgYWZmZWN0IGVudHJ5IOKAlCBza2lwcGluZyByZWxvYWRgKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHR0aGlzLmxvZ2dlci50cmFjZShcblx0XHRcdGBDaGFuZ2UgaW4gJHtmdWxsUGF0aH0gYWZmZWN0cyAke21vZHVsZXMubGVuZ3RofSBtb2R1bGUocykg4oCUIHNjaGVkdWxpbmcgcmVsb2FkYCxcblx0XHQpO1xuXHRcdHRoaXMuaW52YWxpZGF0ZU1vZHVsZSguLi5tb2R1bGVzKTtcblx0XHR0aGlzLnNjaGVkdWxlUmVib290KCk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvLyDilIDilIAgRGVwZW5kZW5jeSBncmFwaCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwcml2YXRlIGdldERlcGVuZGVuY3lHcmFwaChtb2R1bGVJZDogc3RyaW5nLCBwYXJlbnRNb2R1bGVzOiBzdHJpbmdbXSA9IFtdKTogc3RyaW5nW10ge1xuXHRcdGlmICh0aGlzLmlzU2VsZihtb2R1bGVJZCkpIHJldHVybiBbXTtcblxuXHRcdGNvbnN0IG1vZHVsZURlcHMgPSB0aGlzLmRlcGVuZGVuY2llcy5nZXQobW9kdWxlSWQpID8/IFtdO1xuXHRcdGlmIChwYXJlbnRNb2R1bGVzLmluY2x1ZGVzKG1vZHVsZUlkKSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYENpcmN1bGFyIHJlZmVyZW5jZSBkZXRlY3RlZDogJHttb2R1bGVJZH1gKTtcblx0XHRcdHJldHVybiBbXTtcblx0XHR9XG5cblx0XHRsZXQgc3ViRGVwczogc3RyaW5nW10gPSBbXTtcblx0XHRmb3IgKGNvbnN0IGRlcCBvZiBtb2R1bGVEZXBzKSB7XG5cdFx0XHRpZiAoIXRoaXMuZmlsZUluZm9NYXAuaGFzKGRlcCkpIGNvbnRpbnVlO1xuXHRcdFx0Y29uc3Qgc3VicyA9IHRoaXMuZ2V0RGVwZW5kZW5jeUdyYXBoKGRlcCwgW21vZHVsZUlkLCAuLi5wYXJlbnRNb2R1bGVzXSk7XG5cdFx0XHRzdWJEZXBzID0gWy4uLnN1YkRlcHMsIC4uLnN1YnNdO1xuXHRcdH1cblxuXHRcdHJldHVybiBbLi4ubmV3IFNldChbLi4ubW9kdWxlRGVwcywgLi4uc3ViRGVwc10pXTtcblx0fVxuXG5cdHByaXZhdGUgdHJhY2tEZXBlbmRlbmN5KGZpbGVQYXRoOiBzdHJpbmcsIHBhcmVudFBhdGg6IHN0cmluZykge1xuXHRcdGlmICghcGFyZW50UGF0aCkgcmV0dXJuO1xuXHRcdGNvbnN0IGRlcHMgPSB0aGlzLmRlcGVuZGVuY2llcy5nZXQoZmlsZVBhdGgpID8/IFtdO1xuXHRcdGNvbnN0IHVwZGF0ZWREZXBzID0gbmV3IFNldChbLi4uZGVwcywgcGFyZW50UGF0aF0pO1xuXHRcdHRoaXMuZGVwZW5kZW5jaWVzLnNldChmaWxlUGF0aCwgWy4uLnVwZGF0ZWREZXBzXSk7XG5cdH1cblxuXHQvLyDilIDilIAgTW9kdWxlIGNhY2hlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cdHByaXZhdGUgZ2V0Q2FjaGVkT3JOZXcobW9kdWxlVXJsOiBzdHJpbmcpIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IGlvLmZpbGVVcmxUb1BhdGgobW9kdWxlVXJsKTtcblx0XHRjb25zdCBjYWNoZWQgPSB0aGlzLm1vZHVsZUNhY2hlLmdldChmaWxlUGF0aCk7XG5cdFx0Y29uc3QgdmVyc2lvbmVkID0gY2FjaGVkID8/IHRoaXMudmVyc2lvbk1vZHVsZShtb2R1bGVVcmwpO1xuXHRcdHRoaXMubW9kdWxlQ2FjaGUuc2V0KGZpbGVQYXRoLCB2ZXJzaW9uZWQpO1xuXHRcdHJldHVybiB2ZXJzaW9uZWQ7XG5cdH1cblxuXHRwcml2YXRlIHZlcnNpb25Nb2R1bGUobW9kdWxlVXJsOiBzdHJpbmcpIHtcblx0XHRjb25zdCB2ZXJzaW9uZWRVcmwgPSBuZXcgVVJMKG1vZHVsZVVybCk7XG5cdFx0dmVyc2lvbmVkVXJsLnNlYXJjaFBhcmFtcy5zZXQoVkVSU0lPTl9VUkxfUEFSQU0sIERhdGUubm93KCkudG9TdHJpbmcoKSk7XG5cdFx0cmV0dXJuIHZlcnNpb25lZFVybC50b1N0cmluZygpO1xuXHR9XG5cblx0cHJpdmF0ZSBpbnZhbGlkYXRlTW9kdWxlKC4uLm1vZHVsZXM6IHN0cmluZ1tdKSB7XG5cdFx0Zm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuXHRcdFx0dGhpcy5tb2R1bGVDYWNoZS5zZXQobW9kdWxlLCBudWxsKTtcblx0XHRcdHRoaXMudHJhbnNwaWxlQ2FjaGUuZGVsZXRlKG1vZHVsZSk7XG5cdFx0XHQvLyBQcnVuZSBzdGFsZSBvdXRnb2luZyBlZGdlczogcmVtb3ZlIHRoaXMgbW9kdWxlIGFzIGEgcGFyZW50IGZyb20gYWxsIGRlcGVuZGVuY3kgbGlzdHNcblx0XHRcdGZvciAoY29uc3QgW2tleSwgcGFyZW50c10gb2YgdGhpcy5kZXBlbmRlbmNpZXMpIHtcblx0XHRcdFx0Y29uc3QgZmlsdGVyZWQgPSBwYXJlbnRzLmZpbHRlcigocCkgPT4gcCAhPT0gbW9kdWxlKTtcblx0XHRcdFx0aWYgKGZpbHRlcmVkLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdHRoaXMuZGVwZW5kZW5jaWVzLmRlbGV0ZShrZXkpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuZGVwZW5kZW5jaWVzLnNldChrZXksIGZpbHRlcmVkKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgaW52YWxpZGF0ZUFsbFNvdXJjZUZpbGVzKCkge1xuXHRcdGZvciAoY29uc3QgZmlsZVBhdGggb2YgdGhpcy5maWxlSW5mb01hcC5rZXlzKCkpIHtcblx0XHRcdHRoaXMubW9kdWxlQ2FjaGUuc2V0KGZpbGVQYXRoLCBudWxsKTtcblx0XHR9XG5cdH1cblxuXHQvLyDilIDilIAgVXRpbGl0aWVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cdHByaXZhdGUgaXNTZWxmKGZpbGVQYXRoOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gY3VycmVudEZpbGVQYXRoID09PSBwYXRoLnJlc29sdmUoZmlsZVBhdGgpO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiRXZlbnRFbWl0dGVyIiwicmVnaXN0ZXJIb29rcyIsInBhdGgiLCJCdWlsZFRhcmdldHMiLCJTd2NUcmFuc3BpbGVyIiwiV29ya3NwYWNlRGVmYXVsdHMiLCJXb3Jrc3BhY2VGYWN0b3J5IiwiRmlsZUV4IiwiaW8iLCJkZWJvdW5jZSIsInNjcmliZSIsImN1cnJlbnRGaWxlUGF0aCIsImZpbGVVcmxUb1BhdGgiLCJ1cmwiLCJWRVJTSU9OX1VSTF9QQVJBTSIsIlJFQk9PVF9ERUJPVU5DRV9NUyIsIkhvdFJlbG9hZFNlcnZlciIsImxvZ2dlciIsIm5hbWUiLCJkaXNwb3NlZCIsImhvb2tzUmVnaXN0ZXJlZCIsImVudHJ5TW9kdWxlUGF0aCIsImVudHJ5TW9kdWxlIiwid29ya3NwYWNlIiwid2F0Y2hTdWJzY3JpcHRpb24iLCJmaWxlSW5mb01hcCIsIk1hcCIsIm1vZHVsZUNhY2hlIiwiZGVwZW5kZW5jaWVzIiwidHJhbnNwaWxlQ2FjaGUiLCJ0cmFuc3BpbGVyIiwic3RhcnQiLCJvcHRpb25zIiwiY2xlYXIiLCJidWlsZENvbmZpZyIsInJlc29sdmVXb3Jrc3BhY2UiLCJwcm9qZWN0IiwicmVzb2x2ZVByb2plY3QiLCJyZXNvbHZlIiwiZ2V0U291cmNlRW50cnlQYXRoIiwiYnVpbGRGaWxlSW5mb01hcCIsImludmFsaWRhdGVBbGxTb3VyY2VGaWxlcyIsIndhdGNoIiwicHJvamVjdEZpbGVDaGFuZ2VkJCIsInN1YnNjcmliZSIsIm9uRmlsZUNoYW5nZSIsInRyYWNlIiwiYm9vdEVudHJ5IiwiZW1pdCIsImRpc3Bvc2UiLCJ1bnN1YnNjcmliZSIsIlN5bWJvbCIsImRpc3Bvc2VFbnRyeSIsImFzeW5jRGlzcG9zZSIsInZlcnNpb25Nb2R1bGUiLCJwYXRoVG9GaWxlVXJsIiwiZGVmYXVsdCIsImVycm9yIiwicmVib290Iiwic2NoZWR1bGVSZWJvb3QiLCJjcmVhdGUiLCJyb290RGlyIiwicHJvY2VzcyIsImN3ZCIsInByb2plY3RzIiwiZ2V0UHJvamVjdHMiLCJmb3VuZCIsImF0IiwiZmluZCIsInAiLCJFcnJvciIsImVudHJpZXMiLCJQcm9taXNlIiwiYWxsIiwibWFwIiwiZmlsZXMiLCJnZXRBbGxGaWxlcyIsImZpbGUiLCJmdWxsUGF0aCIsImZsYXQiLCJzcGVjaWZpZXIiLCJjb250ZXh0IiwibmV4dCIsInBhcmVudFVybCIsInBhcmVudFVSTCIsInJld3JpdHRlbiIsInJld3JpdGVKc1RvVHMiLCJyZXN1bHQiLCJvblBvc3RSZXNvbHZlIiwibG9hZCIsImxvYWRUcyIsImZvcm1hdCIsInNvdXJjZSIsInNob3J0Q2lyY3VpdCIsImVuZHNXaXRoIiwicGFyZW50Q2xlYW4iLCJzcGxpdCIsImpzUGF0aCIsInJlc29sdmVkIiwiVVJMIiwidG9TdHJpbmciLCJ0c1BhdGgiLCJyZXBsYWNlIiwiaGFzIiwiZ2V0Q2FjaGVkT3JOZXciLCJwYXJlbnRVcmxDbGVhbiIsImZpbGVQYXRoIiwicGFyZW50UGF0aCIsInVybE9iaiIsInNlYXJjaCIsImlzU291cmNlIiwicGFyZW50SXNTb3VyY2UiLCJ0cmFja0RlcGVuZGVuY3kiLCJzdGFydHNXaXRoIiwiY2xlYW5QYXRoIiwicGF0aG5hbWUiLCJmaWxlSW5mbyIsImdldCIsImNhY2hlZCIsInRzQ29uZmlnIiwiZ2V0VHNDb25maWdTeW5jIiwidXNlckNvbmZpZyIsImdldFN3Y0NvbmZpZ1N5bmMiLCJyZXNwb25zZSIsInRyYW5zZm9ybUZpbGVTeW5jIiwiZXM2IiwiYWxpYXNQYXRocyIsIm91dGNvbWUiLCJzZXQiLCJjb2RlIiwiZXZ0IiwiZXZlbnROYW1lIiwiV2F0Y2hFdmVudHMiLCJ1bmxpbmsiLCJkZWxldGUiLCJhZGQiLCJpc1NvdXJjZUZpbGUiLCJyZWxvYWRJZkFmZmVjdGVkIiwiaW52YWxpZGF0ZUNvbnRlbnRDYWNoZSIsImRlcHMiLCJnZXREZXBlbmRlbmN5R3JhcGgiLCJtb2R1bGVzIiwiU2V0IiwiaW5jbHVkZXMiLCJsZW5ndGgiLCJpbnZhbGlkYXRlTW9kdWxlIiwibW9kdWxlSWQiLCJwYXJlbnRNb2R1bGVzIiwiaXNTZWxmIiwibW9kdWxlRGVwcyIsInN1YkRlcHMiLCJkZXAiLCJzdWJzIiwidXBkYXRlZERlcHMiLCJtb2R1bGVVcmwiLCJ2ZXJzaW9uZWQiLCJ2ZXJzaW9uZWRVcmwiLCJzZWFyY2hQYXJhbXMiLCJEYXRlIiwibm93IiwibW9kdWxlIiwia2V5IiwicGFyZW50cyIsImZpbHRlcmVkIiwiZmlsdGVyIiwia2V5cyJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsWUFBWSxRQUFRLGNBQWM7QUFPM0MsU0FBU0MsYUFBYSxRQUFRLGNBQWM7QUFDNUMsT0FBT0MsVUFBVSxZQUFZO0FBQzdCLFNBQVNDLFlBQVksRUFBRUMsYUFBYSxFQUFFQyxpQkFBaUIsUUFBUSxrQkFBa0I7QUFFakYsU0FBU0MsZ0JBQWdCLFFBQVEsaUJBQWlCO0FBQ2xELFNBQVNDLE1BQU0sRUFBRUMsRUFBRSxRQUFRLHFCQUFxQjtBQUNoRCxTQUFTQyxRQUFRLFFBQVEseUJBQXlCO0FBQ2xELFNBQXNCQyxNQUFNLFFBQVEsbUJBQW1CO0FBS3ZELE1BQU1DLGtCQUFrQkgsR0FBR0ksYUFBYSxDQUFDLFlBQVlDLEdBQUc7QUFDeEQsTUFBTUMsb0JBQW9CO0FBQzFCLE1BQU1DLHFCQUFxQjtBQXFCM0IsT0FBTyxNQUFNQyx3QkFBd0JoQjtJQUNwQyw0RUFBNEU7SUFDM0RpQixTQUFpQlAsT0FBT08sTUFBTSxDQUFDRCxnQkFBZ0JFLElBQUksRUFBRTtJQUM5REMsV0FBVyxNQUFNO0lBQ2pCQyxrQkFBa0IsTUFBTTtJQUN4QkMsZ0JBQXlCO0lBQ3pCQyxZQUE4QjtJQUM5QkMsVUFBc0I7SUFDdEJDLGtCQUFpQztJQUN6QywyREFBMkQsR0FDM0QsQUFBUUMsY0FBYyxJQUFJQyxNQUF3QjtJQUMxQ0MsY0FBYyxJQUFJRCxNQUE2QjtJQUMvQ0UsZUFBZSxJQUFJRixNQUF3QjtJQUMzQ0cs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
421
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZsdXgvc3JjL2hvdC1yZWxvYWQtc2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gXCJub2RlOmV2ZW50c1wiO1xuaW1wb3J0IHR5cGUgeyBSZXNvbHZlRm5PdXRwdXQgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB0eXBlIHsgUHJvamVjdCwgUHJvamVjdEZpbGVFdmVudCwgV29ya3NwYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyBpbyB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvaW9cIjtcbmltcG9ydCB7IGRlYm91bmNlIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9zeXN0ZW1cIjtcbmltcG9ydCB7IHR5cGUgTG9nZ2VyLCBzY3JpYmUgfSBmcm9tIFwiQGRlY29oZXJlL3NjcmliZVwiO1xuaW1wb3J0IHR5cGUgeyBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgU291cmNlTW9kdWxlTG9hZGVyIH0gZnJvbSBcIi4vc291cmNlLW1vZHVsZS1sb2FkZXIuanNcIjtcblxuY29uc3QgY3VycmVudEZpbGVQYXRoID0gaW8uZmlsZVVybFRvUGF0aChpbXBvcnQubWV0YS51cmwpO1xuY29uc3QgVkVSU0lPTl9VUkxfUEFSQU0gPSBcInZlcnNpb25cIjtcbi8qKiBEZWZhdWx0IHF1aWV0IHdpbmRvdyBiZWZvcmUgYSBmaWxlLWNoYW5nZSByZWJvb3QuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9SRUJPT1RfREVCT1VOQ0VfTVMgPSAyNTA7XG4vKiogSG93IG1hbnkgdHJpZ2dlcmluZyBwYXRocyB0byBwcmludCBvbiB0aGUgaW5mbyBiYW5uZXIgYmVmb3JlIGArTmAuICovXG5jb25zdCBNQVhfUkVCT09UX1RSSUdHRVJfUEFUSFMgPSA0O1xuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVJlYm9vdERlYm91bmNlTXModmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG5cdGNvbnN0IGRlbGF5ID0gdmFsdWUgPz8gREVGQVVMVF9SRUJPT1RfREVCT1VOQ0VfTVM7XG5cdGlmICghTnVtYmVyLmlzRmluaXRlKGRlbGF5KSB8fCBkZWxheSA8IDApIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoYHJlYm9vdERlYm91bmNlTXMgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIsIGdvdCAke1N0cmluZyh2YWx1ZSl9YCk7XG5cdH1cblx0cmV0dXJuIGRlbGF5O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRUcmlnZ2VyTGlzdCh0cmlnZ2VyczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuXHRpZiAodHJpZ2dlcnMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXHRpZiAodHJpZ2dlcnMubGVuZ3RoIDw9IE1BWF9SRUJPT1RfVFJJR0dFUl9QQVRIUykgcmV0dXJuIHRyaWdnZXJzLmpvaW4oXCIsIFwiKTtcblx0cmV0dXJuIGAke3RyaWdnZXJzLnNsaWNlKDAsIE1BWF9SRUJPT1RfVFJJR0dFUl9QQVRIUykuam9pbihcIiwgXCIpfSwgKyR7dHJpZ2dlcnMubGVuZ3RoIC0gTUFYX1JFQk9PVF9UUklHR0VSX1BBVEhTfWA7XG59XG5cbmNvbnN0IEJBTk5FUl9SVUxFID0gXCLilZBcIi5yZXBlYXQoNTYpO1xuXG5mdW5jdGlvbiB3cmFwRmx1eEJhbm5lcih0aXRsZTogc3RyaW5nLCBkZXRhaWxzOiByZWFkb25seSBzdHJpbmdbXSk6IHN0cmluZyB7XG5cdGNvbnN0IGJvZHkgPSBkZXRhaWxzLm1hcCgobGluZSkgPT4gYCAgJHtsaW5lfWApLmpvaW4oXCJcXG5cIik7XG5cdHJldHVybiBgXFxuJHtCQU5ORVJfUlVMRX1cXG4gICR7dGl0bGV9XFxuJHtib2R5fVxcbiR7QkFOTkVSX1JVTEV9XFxuYDtcbn1cblxuLyoqIEluZm8tbGV2ZWwgSE1SIHN0YXJ0IGJsb2NrIOKAlCBrZWVwIGBmbHV4IHJlYm9vdGAgaW4gdGhlIHRleHQgc28gb3BlcmF0b3JzIGNhbiBzZWFyY2ggdGhlIGJ1ZmZlci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRGbHV4UmVib290U3RhcnQoXG5cdGxhYmVsczogcmVhZG9ubHkgc3RyaW5nW10sXG5cdHRyaWdnZXJzOiByZWFkb25seSBzdHJpbmdbXSA9IFtdLFxuKTogc3RyaW5nIHtcblx0Y29uc3Qgd2hvID0gbGFiZWxzLmpvaW4oXCIsIFwiKSB8fCBcImVudHJ5XCI7XG5cdGNvbnN0IGZpbGVzID0gZm9ybWF0VHJpZ2dlckxpc3QodHJpZ2dlcnMpO1xuXHRjb25zdCBkZXRhaWxzID0gZmlsZXMgPT0gbnVsbCA/IFt3aG9dIDogW3dobywgZmlsZXNdO1xuXHRyZXR1cm4gd3JhcEZsdXhCYW5uZXIoXCJGTFVYIFJFQk9PVFwiLCBkZXRhaWxzKTtcbn1cblxuLyoqIEluZm8tbGV2ZWwgSE1SIGZpbmlzaCBibG9jay4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRGbHV4UmVib290UmVhZHkobGFiZWxzOiByZWFkb25seSBzdHJpbmdbXSwgZWxhcHNlZE1zOiBudW1iZXIpOiBzdHJpbmcge1xuXHRjb25zdCB3aG8gPSBsYWJlbHMuam9pbihcIiwgXCIpIHx8IFwiZW50cnlcIjtcblx0cmV0dXJuIHdyYXBGbHV4QmFubmVyKFwiRkxVWCBSRUFEWVwiLCBbd2hvLCBgJHtNYXRoLm1heCgwLCBNYXRoLnJvdW5kKGVsYXBzZWRNcykpfW1zYF0pO1xufVxuXG4vKiogUHJvY2Vzcy13aWRlOiBOb2RlJ3MgRVNNIGNhY2hlIGlzIHByb2Nlc3MtZ2xvYmFsLCBpbmNsdWRpbmcgYWNyb3NzIEhvdFJlbG9hZFNlcnZlciBpbnN0YW5jZXMuICovXG5sZXQgbW9kdWxlVmVyc2lvblNlcSA9IDA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSG90UmVsb2FkU2VydmVyRXZlbnRzIHtcblx0c3RhcnQ6IFtdO1xuXHRyZWJvb3Q6IFtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhvdFJlbG9hZFNlcnZlck9wdGlvbnMge1xuXHQvKiogQnVpbGQgY29uZmlndXJhdGlvbiBuYW1lLiAqL1xuXHRidWlsZENvbmZpZzogc3RyaW5nO1xuXHQvKiogTmFtZSBvZiB0aGUgcHJvamVjdCB0byBzZXJ2ZS4gRGVmYXVsdHMgdG8gdGhlIGZpcnN0IHByb2plY3QgaW4gdGhlIHdvcmtzcGFjZS4gKi9cblx0cHJvamVjdD86IHN0cmluZztcblx0LyoqXG5cdCAqIE11bHRpcGxlIEZsdXggYXBwIHBhY2thZ2UgbmFtZXMgdG8gYm9vdCBpbiBvbmUgcHJvY2VzcyAoZGlyZWN0b3J5IHNsaWNlKS5cblx0ICogV2hlbiBzZXQsIHRha2VzIHByZWNlZGVuY2Ugb3ZlciB7QGxpbmsgcHJvamVjdH0uXG5cdCAqL1xuXHRwcm9qZWN0cz86IHJlYWRvbmx5IHN0cmluZ1tdO1xuXHQvKipcblx0ICogUHJlLWJ1aWx0IFdvcmtzcGFjZSBpbnN0YW5jZSB0byB1c2UgaW5zdGVhZCBvZiBydW5uaW5nIFdvcmtzcGFjZUZhY3RvcnkuXG5cdCAqIFVzZWZ1bCBpbiB0ZXN0cyB0byBieXBhc3MgZmlsZXN5c3RlbS1iYXNlZCB3b3Jrc3BhY2UgZGlzY292ZXJ5LlxuXHQgKi9cblx0d29ya3NwYWNlPzogV29ya3NwYWNlO1xuXHQvKipcblx0ICogUXVpZXQgd2luZG93IGluIG1pbGxpc2Vjb25kcyBhZnRlciB0aGUgbGFzdCBhZmZlY3Rpbmcgc2F2ZSBiZWZvcmUgYSByZWJvb3QuXG5cdCAqIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX1JFQk9PVF9ERUJPVU5DRV9NU30uIFJhaXNlIHRoaXMgZm9yIGFnZW50IHNhdmUgdHJhaW5zLlxuXHQgKi9cblx0cmVib290RGVib3VuY2VNcz86IG51bWJlcjtcbn1cblxudHlwZSBFbnRyeVN0YXRlID0geyBwYXRoOiBzdHJpbmc7IGxhYmVsOiBzdHJpbmc7IG1vZHVsZT86IEFzeW5jRGlzcG9zYWJsZSB9O1xuXG5leHBvcnQgY2xhc3MgSG90UmVsb2FkU2VydmVyIGV4dGVuZHMgRXZlbnRFbWl0dGVyPEhvdFJlbG9hZFNlcnZlckV2ZW50cz4ge1xuXHQvLyDilIDilIAgU3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cdHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyOiBMb2dnZXIgPSBzY3JpYmUubG9nZ2VyKEhvdFJlbG9hZFNlcnZlci5uYW1lKTtcblx0cHJpdmF0ZSByZWFkb25seSBsb2FkZXIgPSBuZXcgU291cmNlTW9kdWxlTG9hZGVyKCk7XG5cdHByaXZhdGUgZGlzcG9zZWQgPSBmYWxzZTtcblx0LyoqIEFic29sdXRlIGVudHJ5IHBhdGhzIGN1cnJlbnRseSBzZXJ2ZWQgKG9uZSBvciBtb3JlIEZsdXggYXBwcykuICovXG5cdHByaXZhdGUgZW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBFbnRyeVN0YXRlPigpO1xuXHRwcml2YXRlIHBlbmRpbmdFbnRyeVJlYm9vdHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblx0LyoqIFNvdXJjZSBwYXRocyB0aGF0IHNjaGVkdWxlZCB0aGUgbmV4dCByZWJvb3QgKGNsZWFyZWQgd2hlbiB0aGF0IHJlYm9vdCBzdGFydHMpLiAqL1xuXHRwcml2YXRlIHBlbmRpbmdUcmlnZ2VycyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXHRwcml2YXRlIHdhdGNoU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXHRwcml2YXRlIG1vZHVsZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZyB8IG51bGw+KCk7XG5cdHByaXZhdGUgZGVwZW5kZW5jaWVzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpO1xuXHRwcml2YXRlIHJlYm9vdFRhaWw6IFByb21pc2U8dm9pZD4gPSBQcm9taXNlLnJlc29sdmUoKTtcblx0cHJpdmF0ZSByZWJvb3REZWJvdW5jZUdlbiA9IDA7XG5cdHByaXZhdGUgcmVib290SW5GbGlnaHQgPSBmYWxzZTtcblx0cHJpdmF0ZSByZWJvb3RGb2xsb3dVcCA9IGZhbHNlO1xuXHRwcml2YXRlIHJlYm9vdFF1ZXVlZCA9IGZhbHNlO1xuXHQvKiogTW9kdWxlcyB3aG9zZSByZXZlcnNlLWdyYXBoIGVkZ2VzIGFyZSBwcnVuZWQgYXQgcmVib290LCBub3Qgb24gc2NoZWR1bGUuICovXG5cdHByaXZhdGUgcGVuZGluZ0dyYXBoUHJ1bmUgPSBuZXcgU2V0PHN0cmluZz4oKTtcblx0cHJpdmF0ZSBzY2hlZHVsZVJlYm9vdDogKCkgPT4gdm9pZCA9ICgpID0+IHt9O1xuXG5cdC8vIOKUgOKUgCBQdWJsaWMgQVBJIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cdHB1YmxpYyBhc3luYyBzdGFydChvcHRpb25zOiBIb3RSZWxvYWRTZXJ2ZXJPcHRpb25zKSB7XG5cdFx0dGhpcy5kaXNwb3NlZCA9IGZhbHNlO1xuXHRcdHRoaXMuZGVwZW5kZW5jaWVzLmNsZWFyKCk7XG5cdFx0dGhpcy5tb2R1bGVDYWNoZS5jbGVhcigpO1xuXHRcdHRoaXMuZW50cmllcy5jbGVhcigpO1xuXHRcdHRoaXMucGVuZGluZ0VudHJ5UmVib290cy5jbGVhcigpO1xuXHRcdHRoaXMucGVuZGluZ1RyaWdnZXJzLmNsZWFyKCk7XG5cdFx0dGhpcy5wZW5kaW5nR3JhcGhQcnVuZS5jbGVhcigpO1xuXHRcdHRoaXMucmVib290VGFpbCA9IFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdHRoaXMucmVib290SW5GbGlnaHQgPSBmYWxzZTtcblx0XHR0aGlzLnJlYm9vdEZvbGxvd1VwID0gZmFsc2U7XG5cdFx0dGhpcy5yZWJvb3RRdWV1ZWQgPSBmYWxzZTtcblx0XHR0aGlzLmJpbmRTY2hlZHVsZVJlYm9vdChyZXNvbHZlUmVib290RGVib3VuY2VNcyhvcHRpb25zLnJlYm9vdERlYm91bmNlTXMpKTtcblxuXHRcdGNvbnN0IHsgYnVpbGRDb25maWcgfSA9IG9wdGlvbnM7XG5cblx0XHRhd2FpdCB0aGlzLmxvYWRlci5jb25maWd1cmUoe1xuXHRcdFx0YnVpbGRDb25maWcsXG5cdFx0XHR3b3Jrc3BhY2U6IG9wdGlvbnMud29ya3NwYWNlLFxuXHRcdFx0dmVyc2lvbkZpbGVVcmw6IChmaWxlVXJsKSA9PiB0aGlzLmdldENhY2hlZE9yTmV3KGZpbGVVcmwpLFxuXHRcdFx0b25SZXNvbHZlZDogdGhpcy5vblBvc3RSZXNvbHZlLFxuXHRcdH0pO1xuXG5cdFx0Y29uc3Qgd29ya3NwYWNlID0gdGhpcy5yZXF1aXJlV29ya3NwYWNlKCk7XG5cdFx0Y29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnJlc29sdmVQcm9qZWN0cyhidWlsZENvbmZpZywgb3B0aW9ucyk7XG5cdFx0Zm9yIChjb25zdCBwcm9qZWN0IG9mIHNlbGVjdGVkKSB7XG5cdFx0XHRjb25zdCBlbnRyeVBhdGggPSBwYXRoLnJlc29sdmUocHJvamVjdC5nZXRTb3VyY2VFbnRyeVBhdGgoKSk7XG5cdFx0XHR0aGlzLmVudHJpZXMuc2V0KGVudHJ5UGF0aCwgeyBwYXRoOiBlbnRyeVBhdGgsIGxhYmVsOiBwcm9qZWN0Lm5hbWUgfSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5sb2FkZXIucmVnaXN0ZXJIb29rcygpO1xuXHRcdHRoaXMuaW52YWxpZGF0ZUFsbFNvdXJjZUZpbGVzKCk7XG5cblx0XHRhd2FpdCB3b3Jrc3BhY2Uud2F0Y2goYnVpbGRDb25maWcpO1xuXHRcdHRoaXMud2F0Y2hTdWJzY3JpcHRpb24gPSB3b3Jrc3BhY2UucHJvamVjdEZpbGVDaGFuZ2VkJC5zdWJzY3JpYmUodGhpcy5vbkZpbGVDaGFuZ2UpO1xuXG5cdFx0Zm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLmVudHJpZXMudmFsdWVzKCkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLnRyYWNlKGBTZXJ2aW5nICR7ZW50cnkucGF0aH1gKTtcblx0XHR9XG5cdFx0YXdhaXQgdGhpcy5ib290RW50cmllcyhbLi4udGhpcy5lbnRyaWVzLmtleXMoKV0pO1xuXHRcdHRoaXMuZW1pdChcInN0YXJ0XCIpO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGRpc3Bvc2UoKSB7XG5cdFx0aWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcblx0XHR0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcblx0XHR0aGlzLnJlYm9vdERlYm91bmNlR2VuICs9IDE7XG5cdFx0dGhpcy53YXRjaFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcblx0XHRhd2FpdCB0aGlzLnJlYm9vdFRhaWw7XG5cdFx0YXdhaXQgdGhpcy5kaXNwb3NlRW50cmllcyhbLi4udGhpcy5lbnRyaWVzLmtleXMoKV0pO1xuXHRcdHRoaXMubG9hZGVyLmRpc3Bvc2UoKTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBbU3ltYm9sLmFzeW5jRGlzcG9zZV0oKSB7XG5cdFx0YXdhaXQgdGhpcy5kaXNwb3NlKCk7XG5cdH1cblxuXHQvLyDilIDilIAgTGlmZWN5Y2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cdHByaXZhdGUgYXN5bmMgYm9vdEVudHJpZXMoZW50cnlQYXRoczogcmVhZG9ubHkgc3RyaW5nW10pIHtcblx0XHRhd2FpdCBQcm9taXNlLmFsbChlbnRyeVBhdGhzLm1hcCgoZW50cnlQYXRoKSA9PiB0aGlzLmJvb3RFbnRyeShlbnRyeVBhdGgpKSk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGJvb3RFbnRyeShlbnRyeVBhdGg6IHN0cmluZykge1xuXHRcdGNvbnN0IHN0YXRlID0gdGhpcy5lbnRyaWVzLmdldChlbnRyeVBhdGgpO1xuXHRcdGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm47XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG1vZCA9IChhd2FpdCB0aGlzLmxvYWRlci5pbXBvcnRFbnRyeShlbnRyeVBhdGgpKSBhcyB7XG5cdFx0XHRcdGRlZmF1bHQ/OiBBc3luY0Rpc3Bvc2FibGU7XG5cdFx0XHR9O1xuXHRcdFx0c3RhdGUubW9kdWxlID0gbW9kPy5kZWZhdWx0O1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRzdGF0ZS5tb2R1bGUgPSB1bmRlZmluZWQ7XG5cdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihcblx0XHRcdFx0XCJUaGVyZSB3YXMgYW4gZXJyb3IgYm9vdGluZyB0aGUgZW50cnkgcG9pbnQuIFlvdXIgYXBwbGljYXRpb24gbWF5IG5vdCBmdW5jdGlvbiBhcyBleHBlY3RlZFwiLFxuXHRcdFx0XHRlcnJvcixcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBiaW5kU2NoZWR1bGVSZWJvb3QoZGVsYXlNczogbnVtYmVyKSB7XG5cdFx0Y29uc3QgZ2VuID0gKyt0aGlzLnJlYm9vdERlYm91bmNlR2VuO1xuXHRcdHRoaXMuc2NoZWR1bGVSZWJvb3QgPSBkZWJvdW5jZShhc3luYyAoKSA9PiB7XG5cdFx0XHRpZiAodGhpcy5kaXNwb3NlZCB8fCBnZW4gIT09IHRoaXMucmVib290RGVib3VuY2VHZW4pIHJldHVybjtcblx0XHRcdHRoaXMucmVxdWVzdFJlYm9vdCgpO1xuXHRcdH0sIGRlbGF5TXMpO1xuXHR9XG5cblx0cHJpdmF0ZSByZXF1ZXN0UmVib290KCkge1xuXHRcdGlmICh0aGlzLmRpc3Bvc2VkKSByZXR1cm47XG5cdFx0aWYgKHRoaXMucmVib290SW5GbGlnaHQpIHtcblx0XHRcdHRoaXMucmVib290Rm9sbG93VXAgPSB0cnVlO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodGhpcy5yZWJvb3RRdWV1ZWQpIHJldHVybjtcblx0XHR0aGlzLnJlYm9vdFF1ZXVlZCA9IHRydWU7XG5cdFx0dGhpcy5yZWJvb3RUYWlsID0gdGhpcy5yZWJvb3RUYWlsLnRoZW4oXG5cdFx0XHQoKSA9PiB0aGlzLnJ1blJlYm9vdCgpLFxuXHRcdFx0KCkgPT4gdGhpcy5ydW5SZWJvb3QoKSxcblx0XHQpO1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBydW5SZWJvb3QoKSB7XG5cdFx0dGhpcy5yZWJvb3RRdWV1ZWQgPSBmYWxzZTtcblx0XHRpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuXHRcdHRoaXMucmVib290SW5GbGlnaHQgPSB0cnVlO1xuXHRcdHRyeSB7XG5cdFx0XHRkbyB7XG5cdFx0XHRcdHRoaXMucmVib290Rm9sbG93VXAgPSBmYWxzZTtcblx0XHRcdFx0aWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcblx0XHRcdFx0Y29uc3QgdG9SZWJvb3QgPVxuXHRcdFx0XHRcdHRoaXMucGVuZGluZ0VudHJ5UmVib290cy5zaXplID4gMFxuXHRcdFx0XHRcdFx0PyBbLi4udGhpcy5wZW5kaW5nRW50cnlSZWJvb3RzXVxuXHRcdFx0XHRcdFx0OiBbLi4udGhpcy5lbnRyaWVzLmtleXMoKV07XG5cdFx0XHRcdHRoaXMucGVuZGluZ0VudHJ5UmVib290cy5jbGVhcigpO1xuXHRcdFx0XHQvLyBEcm9wIHJldmVyc2UgZWRnZXMgb25seSB3aGVuIHJlYm9vdGluZyBzbyBsYXRlciBzYXZlcyBpbiB0aGUgZGVib3VuY2Vcblx0XHRcdFx0Ly8gd2luZG93IGNhbiBzdGlsbCB3YWxrIHRoZSBncmFwaCBhbmQgcmVzZXQgdGhlIHF1aWV0IHRpbWVyLlxuXHRcdFx0XHR0aGlzLnBydW5lUGVuZGluZ0RlcGVuZGVuY3lFZGdlcygpO1xuXHRcdFx0XHRjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuXHRcdFx0XHRjb25zdCBsYWJlbHMgPSB0aGlzLmxhYmVsc0Zvcih0b1JlYm9vdCk7XG5cdFx0XHRcdGNvbnN0IHRyaWdnZXJzID0gdGhpcy50YWtlVHJpZ2dlcnMoKTtcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhmb3JtYXRGbHV4UmVib290U3RhcnQobGFiZWxzLCB0cmlnZ2VycykpO1xuXHRcdFx0XHRhd2FpdCB0aGlzLmRpc3Bvc2VFbnRyaWVzKHRvUmVib290KTtcblx0XHRcdFx0YXdhaXQgdGhpcy5ib290RW50cmllcyh0b1JlYm9vdCk7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oZm9ybWF0Rmx1eFJlYm9vdFJlYWR5KGxhYmVscywgRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCkpO1xuXHRcdFx0XHR0aGlzLmVtaXQoXCJyZWJvb3RcIik7XG5cdFx0XHR9IHdoaWxlICh0aGlzLnJlYm9vdEZvbGxvd1VwICYmICF0aGlzLmRpc3Bvc2VkKTtcblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0Y29uc3QgbmVlZHNGb2xsb3dVcCA9IHRoaXMucmVib290Rm9sbG93VXAgJiYgIXRoaXMuZGlzcG9zZWQ7XG5cdFx0XHR0aGlzLnJlYm9vdEZvbGxvd1VwID0gZmFsc2U7XG5cdFx0XHR0aGlzLnJlYm9vdEluRmxpZ2h0ID0gZmFsc2U7XG5cdFx0XHRpZiAobmVlZHNGb2xsb3dVcCkgdGhpcy5yZXF1ZXN0UmVib290KCk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBkaXNwb3NlRW50cmllcyhlbnRyeVBhdGhzOiByZWFkb25seSBzdHJpbmdbXSkge1xuXHRcdGF3YWl0IFByb21pc2UuYWxsKGVudHJ5UGF0aHMubWFwKChlbnRyeVBhdGgpID0+IHRoaXMuZGlzcG9zZUVudHJ5KGVudHJ5UGF0aCkpKTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgZGlzcG9zZUVudHJ5KGVudHJ5UGF0aD86IHN0cmluZykge1xuXHRcdGNvbnN0IHBhdGhzID0gZW50cnlQYXRoICE9IG51bGwgPyBbZW50cnlQYXRoXSA6IFsuLi50aGlzLmVudHJpZXMua2V5cygpXTtcblx0XHRmb3IgKGNvbnN0IHAgb2YgcGF0aHMpIHtcblx0XHRcdGNvbnN0IHN0YXRlID0gdGhpcy5lbnRyaWVzLmdldChwKTtcblx0XHRcdGlmIChzdGF0ZSA9PSBudWxsKSBjb250aW51ZTtcblx0XHRcdGNvbnN0IGVudHJ5ID0gc3RhdGUubW9kdWxlO1xuXHRcdFx0c3RhdGUubW9kdWxlID0gdW5kZWZpbmVkO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0YXdhaXQgZW50cnk/LltTeW1ib2wuYXN5bmNEaXNwb3NlXSgpO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoXCJFbnRyeSBhc3luY0Rpc3Bvc2UgZmFpbGVkXCIsIGVycm9yKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyDilIDilIAgU2V0dXAg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cblx0cHJpdmF0ZSByZXF1aXJlV29ya3NwYWNlKCk6IFdvcmtzcGFjZSB7XG5cdFx0Y29uc3Qgd29ya3NwYWNlID0gdGhpcy5sb2FkZXIuZ2V0V29ya3NwYWNlKCk7XG5cdFx0aWYgKHdvcmtzcGFjZSA9PSBudWxsKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJTb3VyY2VNb2R1bGVMb2FkZXIgaGFzIG5vIHdvcmtzcGFjZSBhZnRlciBjb25maWd1cmVcIik7XG5cdFx0fVxuXHRcdHJldHVybiB3b3Jrc3BhY2U7XG5cdH1cblxuXHRwcml2YXRlIHJlc29sdmVQcm9qZWN0cyhidWlsZENvbmZpZzogc3RyaW5nLCBvcHRpb25zOiBIb3RSZWxvYWRTZXJ2ZXJPcHRpb25zKTogUHJvamVjdFtdIHtcblx0XHRjb25zdCBwcm9qZWN0cyA9IHRoaXMubG9hZGVyLmdldFdvcmtzcGFjZSgpPy5nZXRQcm9qZWN0cyhidWlsZENvbmZpZykgPz8gW107XG5cdFx0Y29uc3QgbmFtZXMgPVxuXHRcdFx0b3B0aW9ucy5wcm9qZWN0cyAhPSBudWxsICYmIG9wdGlvbnMucHJvamVjdHMubGVuZ3RoID4gMFxuXHRcdFx0XHQ/IG9wdGlvbnMucHJvamVjdHNcblx0XHRcdFx0OiBvcHRpb25zLnByb2plY3QgIT0gbnVsbFxuXHRcdFx0XHRcdD8gW29wdGlvbnMucHJvamVjdF1cblx0XHRcdFx0XHQ6IHVuZGVmaW5lZDtcblxuXHRcdGlmIChuYW1lcyA9PSBudWxsKSB7XG5cdFx0XHRjb25zdCBmaXJzdCA9IHByb2plY3RzLmF0KDApO1xuXHRcdFx0aWYgKGZpcnN0ID09IG51bGwpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBObyBwcm9qZWN0cyBmb3VuZCBmb3IgY29uZmlndXJhdGlvbjogJHtidWlsZENvbmZpZ31gKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBbZmlyc3RdO1xuXHRcdH1cblxuXHRcdGNvbnN0IHNlbGVjdGVkOiBQcm9qZWN0W10gPSBbXTtcblx0XHRmb3IgKGNvbnN0IG5hbWUgb2YgbmFtZXMpIHtcblx0XHRcdGNvbnN0IGZvdW5kID0gcHJvamVjdHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBuYW1lKTtcblx0XHRcdGlmIChmb3VuZCA9PSBudWxsKSB7XG5cdFx0XHRcdHRocm93IG5ldyBFcnJvcihgUHJvamVjdCBcIiR7bmFtZX1cIiBub3QgZm91bmQgaW4gd29ya3NwYWNlYCk7XG5cdFx0XHR9XG5cdFx0XHRzZWxlY3RlZC5wdXNoKGZvdW5kKTtcblx0XHR9XG5cdFx0cmV0dXJuIHNlbGVjdGVkO1xuXHR9XG5cblx0LyoqXG5cdCAqIFBvc3QtbmV4dCBkZXBlbmRlbmN5IHRyYWNrZXI6IHJlY29yZHMgd2hpY2ggc291cmNlIGZpbGVzIGltcG9ydCB3aGljaFxuXHQgKiBvdGhlciBzb3VyY2UgZmlsZXMgc28gdGhhdCByZWxvYWRJZkFmZmVjdGVkIGNhbiB0cmF2ZXJzZSB0aGUgZ3JhcGguXG5cdCAqL1xuXHRwcml2YXRlIG9uUG9zdFJlc29sdmUgPSAocmVzdWx0OiBSZXNvbHZlRm5PdXRwdXQsIHBhcmVudFVybDogc3RyaW5nKSA9PiB7XG5cdFx0Y29uc3QgeyB1cmwgfSA9IHJlc3VsdDtcblx0XHRjb25zdCBwYXJlbnRVcmxDbGVhbiA9IHBhcmVudFVybC5zcGxpdChcIj9cIilbMF07XG5cblx0XHRsZXQgZmlsZVBhdGg6IHN0cmluZztcblx0XHRsZXQgcGFyZW50UGF0aDogc3RyaW5nO1xuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHVybE9iaiA9IG5ldyBVUkwodXJsKTtcblx0XHRcdHVybE9iai5zZWFyY2ggPSBcIlwiO1xuXHRcdFx0ZmlsZVBhdGggPSBpby5maWxlVXJsVG9QYXRoKHVybE9iai50b1N0cmluZygpKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0cGFyZW50UGF0aCA9IGlvLmZpbGVVcmxUb1BhdGgocGFyZW50VXJsQ2xlYW4pO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cGFyZW50UGF0aCA9IFwiXCI7XG5cdFx0fVxuXG5cdFx0Y29uc3QgaXNTb3VyY2UgPSB0aGlzLmxvYWRlci5oYXNTb3VyY2VGaWxlKGZpbGVQYXRoKTtcblx0XHRjb25zdCBwYXJlbnRJc1NvdXJjZSA9IHRoaXMubG9hZGVyLmhhc1NvdXJjZUZpbGUocGFyZW50UGF0aCk7XG5cblx0XHRpZiAoaXNTb3VyY2UgfHwgcGFyZW50SXNTb3VyY2UpIHtcblx0XHRcdHRoaXMudHJhY2tEZXBlbmRlbmN5KGZpbGVQYXRoLCBwYXJlbnRQYXRoKTtcblx0XHR9XG5cdH07XG5cblx0Ly8g4pSA4pSAIEZpbGUgd2F0Y2hpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cblx0cHJpdmF0ZSBvbkZpbGVDaGFuZ2UgPSAoZXZ0OiBQcm9qZWN0RmlsZUV2ZW50KSA9PiB7XG5cdFx0Y29uc3QgeyBmaWxlLCBldmVudE5hbWUsIHByb2plY3QgfSA9IGV2dDtcblx0XHRjb25zdCBmdWxsUGF0aCA9IGZpbGUuZnVsbFBhdGg7XG5cblx0XHR0aGlzLmxvZ2dlci50cmFjZShgRmlsZSAke2V2ZW50TmFtZX06ICR7ZnVsbFBhdGh9YCk7XG5cblx0XHRpZiAoZXZlbnROYW1lID09PSBpby5XYXRjaEV2ZW50cy51bmxpbmspIHtcblx0XHRcdHRoaXMubG9hZGVyLmludmFsaWRhdGVUcmFuc3BpbGUoZnVsbFBhdGgpO1xuXHRcdFx0dGhpcy5tb2R1bGVDYWNoZS5zZXQoZnVsbFBhdGgsIG51bGwpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChldmVudE5hbWUgPT09IGlvLldhdGNoRXZlbnRzLmFkZCkge1xuXHRcdFx0aWYgKHByb2plY3QuaXNTb3VyY2VGaWxlKGZpbGUpKSB7XG5cdFx0XHRcdHRoaXMubG9hZGVyLnNldFNvdXJjZUZpbGUoZnVsbFBhdGgsIHByb2plY3QpO1xuXHRcdFx0XHR0aGlzLm1vZHVsZUNhY2hlLnNldChmdWxsUGF0aCwgbnVsbCk7XG5cdFx0XHRcdHRoaXMucmVsb2FkSWZBZmZlY3RlZChmdWxsUGF0aCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gY2hhbmdlXG5cdFx0aWYgKCFwcm9qZWN0LmlzU291cmNlRmlsZShmaWxlKSkgcmV0dXJuO1xuXHRcdHRoaXMubG9hZGVyLmludmFsaWRhdGVUcmFuc3BpbGUoZnVsbFBhdGgpO1xuXHRcdHRoaXMucmVsb2FkSWZBZmZlY3RlZChmdWxsUGF0aCk7XG5cdH07XG5cblx0cHJpdmF0ZSByZWxvYWRJZkFmZmVjdGVkKGZ1bGxQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcblx0XHRjb25zdCBkZXBzID0gdGhpcy5nZXREZXBlbmRlbmN5R3JhcGgoZnVsbFBhdGgpO1xuXHRcdGNvbnN0IG1vZHVsZXMgPSBbLi4ubmV3IFNldChbLi4uZGVwcywgZnVsbFBhdGhdKV07XG5cdFx0Y29uc3QgYWZmZWN0ZWRFbnRyaWVzID0gWy4uLnRoaXMuZW50cmllcy5rZXlzKCldLmZpbHRlcigoZW50cnlQYXRoKSA9PlxuXHRcdFx0bW9kdWxlcy5pbmNsdWRlcyhlbnRyeVBhdGgpLFxuXHRcdCk7XG5cblx0XHRpZiAoYWZmZWN0ZWRFbnRyaWVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0dGhpcy5sb2dnZXIudHJhY2UoYENoYW5nZSBpbiAke2Z1bGxQYXRofSBkb2VzIG5vdCBhZmZlY3QgZW50cnkg4oCUIHNraXBwaW5nIHJlbG9hZGApO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHRoaXMubG9nZ2VyLnRyYWNlKFxuXHRcdFx0YENoYW5nZSBpbiAke2Z1bGxQYXRofSBhZmZlY3RzICR7bW9kdWxlcy5sZW5ndGh9IG1vZHVsZShzKSDigJQgc2NoZWR1bGluZyByZWxvYWRgLFxuXHRcdCk7XG5cdFx0dGhpcy5pbnZhbGlkYXRlTW9kdWxlQ2FjaGVzKC4uLm1vZHVsZXMpO1xuXHRcdGZvciAoY29uc3QgbW9kdWxlIG9mIG1vZHVsZXMpIHtcblx0XHRcdHRoaXMucGVuZGluZ0dyYXBoUHJ1bmUuYWRkKG1vZHVsZSk7XG5cdFx0fVxuXHRcdGZvciAoY29uc3QgZW50cnlQYXRoIG9mIGFmZmVjdGVkRW50cmllcykge1xuXHRcdFx0dGhpcy5wZW5kaW5nRW50cnlSZWJvb3RzLmFkZChlbnRyeVBhdGgpO1xuXHRcdH1cblx0XHR0aGlzLnBlbmRpbmdUcmlnZ2Vycy5hZGQoZnVsbFBhdGgpO1xuXHRcdHRoaXMuc2NoZWR1bGVSZWJvb3QoKTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8vIOKUgOKUgCBEZXBlbmRlbmN5IGdyYXBoIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cdHByaXZhdGUgZ2V0RGVwZW5kZW5jeUdyYXBoKG1vZHVsZUlkOiBzdHJpbmcsIHBhcmVudE1vZHVsZXM6IHN0cmluZ1tdID0gW10pOiBzdHJpbmdbXSB7XG5cdFx0aWYgKHRoaXMuaXNTZWxmKG1vZHVsZUlkKSkgcmV0dXJuIFtdO1xuXG5cdFx0Y29uc3QgbW9kdWxlRGVwcyA9IHRoaXMuZGVwZW5kZW5jaWVzLmdldChtb2R1bGVJZCkgPz8gW107XG5cdFx0aWYgKHBhcmVudE1vZHVsZXMuaW5jbHVkZXMobW9kdWxlSWQpKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgQ2lyY3VsYXIgcmVmZXJlbmNlIGRldGVjdGVkOiAke21vZHVsZUlkfWApO1xuXHRcdFx0cmV0dXJuIFtdO1xuXHRcdH1cblxuXHRcdGxldCBzdWJEZXBzOiBzdHJpbmdbXSA9IFtdO1xuXHRcdGZvciAoY29uc3QgZGVwIG9mIG1vZHVsZURlcHMpIHtcblx0XHRcdGlmICghdGhpcy5sb2FkZXIuaGFzU291cmNlRmlsZShkZXApKSBjb250aW51ZTtcblx0XHRcdGNvbnN0IHN1YnMgPSB0aGlzLmdldERlcGVuZGVuY3lHcmFwaChkZXAsIFttb2R1bGVJZCwgLi4ucGFyZW50TW9kdWxlc10pO1xuXHRcdFx0c3ViRGVwcyA9IFsuLi5zdWJEZXBzLCAuLi5zdWJzXTtcblx0XHR9XG5cblx0XHRyZXR1cm4gWy4uLm5ldyBTZXQoWy4uLm1vZHVsZURlcHMsIC4uLnN1YkRlcHNdKV07XG5cdH1cblxuXHRwcml2YXRlIHRyYWNrRGVwZW5kZW5jeShmaWxlUGF0aDogc3RyaW5nLCBwYXJlbnRQYXRoOiBzdHJpbmcpIHtcblx0XHRpZiAoIXBhcmVudFBhdGgpIHJldHVybjtcblx0XHRjb25zdCBkZXBzID0gdGhpcy5kZXBlbmRlbmNpZXMuZ2V0KGZpbGVQYXRoKSA/PyBbXTtcblx0XHRjb25zdCB1cGRhdGVkRGVwcyA9IG5ldyBTZXQoWy4uLmRlcHMsIHBhcmVudFBhdGhdKTtcblx0XHR0aGlzLmRlcGVuZGVuY2llcy5zZXQoZmlsZVBhdGgsIFsuLi51cGRhdGVkRGVwc10pO1xuXHR9XG5cblx0Ly8g4pSA4pSAIE1vZHVsZSBjYWNoZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwcml2YXRlIGdldENhY2hlZE9yTmV3KG1vZHVsZVVybDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgZmlsZVBhdGggPSBpby5maWxlVXJsVG9QYXRoKG1vZHVsZVVybCk7XG5cdFx0Y29uc3QgY2FjaGVkID0gdGhpcy5tb2R1bGVDYWNoZS5nZXQoZmlsZVBhdGgpO1xuXHRcdGNvbnN0IHZlcnNpb25lZCA9IGNhY2hlZCA/PyB0aGlzLnZlcnNpb25Nb2R1bGUobW9kdWxlVXJsKTtcblx0XHR0aGlzLm1vZHVsZUNhY2hlLnNldChmaWxlUGF0aCwgdmVyc2lvbmVkKTtcblx0XHRyZXR1cm4gdmVyc2lvbmVkO1xuXHR9XG5cblx0cHJpdmF0ZSB2ZXJzaW9uTW9kdWxlKG1vZHVsZVVybDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgdmVyc2lvbmVkVXJsID0gbmV3IFVSTChtb2R1bGVVcmwpO1xuXHRcdHZlcnNpb25lZFVybC5zZWFyY2hQYXJhbXMuc2V0KFZFUlNJT05fVVJMX1BBUkFNLCBTdHJpbmcoKyttb2R1bGVWZXJzaW9uU2VxKSk7XG5cdFx0cmV0dXJuIHZlcnNpb25lZFVybC50b1N0cmluZygpO1xuXHR9XG5cblx0cHJpdmF0ZSBpbnZhbGlkYXRlTW9kdWxlQ2FjaGVzKC4uLm1vZHVsZXM6IHN0cmluZ1tdKSB7XG5cdFx0Zm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuXHRcdFx0dGhpcy5tb2R1bGVDYWNoZS5zZXQobW9kdWxlLCBudWxsKTtcblx0XHRcdHRoaXMubG9hZGVyLmludmFsaWRhdGVUcmFuc3BpbGUobW9kdWxlKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIHBydW5lUGVuZGluZ0RlcGVuZGVuY3lFZGdlcygpIHtcblx0XHRjb25zdCBtb2R1bGVzID0gWy4uLnRoaXMucGVuZGluZ0dyYXBoUHJ1bmVdO1xuXHRcdHRoaXMucGVuZGluZ0dyYXBoUHJ1bmUuY2xlYXIoKTtcblx0XHR0aGlzLnBydW5lRGVwZW5kZW5jeVBhcmVudHMoLi4ubW9kdWxlcyk7XG5cdH1cblxuXHQvKiogUmVtb3ZlIHRoZXNlIG1vZHVsZXMgYXMgcGFyZW50cyBzbyBib290IGNhbiByZWJ1aWxkIGVkZ2VzIHdpdGhvdXQgc3RhbGUgaW1wb3J0ZXJzLiAqL1xuXHRwcml2YXRlIHBydW5lRGVwZW5kZW5jeVBhcmVudHMoLi4ubW9kdWxlczogc3RyaW5nW10pIHtcblx0XHRmb3IgKGNvbnN0IG1vZHVsZSBvZiBtb2R1bGVzKSB7XG5cdFx0XHRmb3IgKGNvbnN0IFtrZXksIHBhcmVudHNdIG9mIHRoaXMuZGVwZW5kZW5jaWVzKSB7XG5cdFx0XHRcdGNvbnN0IGZpbHRlcmVkID0gcGFyZW50cy5maWx0ZXIoKHApID0+IHAgIT09IG1vZHVsZSk7XG5cdFx0XHRcdGlmIChmaWx0ZXJlZC5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0XHR0aGlzLmRlcGVuZGVuY2llcy5kZWxldGUoa2V5KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLmRlcGVuZGVuY2llcy5zZXQoa2V5LCBmaWx0ZXJlZCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGludmFsaWRhdGVBbGxTb3VyY2VGaWxlcygpIHtcblx0XHRmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHRoaXMubG9hZGVyLnNvdXJjZUZpbGVQYXRocygpKSB7XG5cdFx0XHR0aGlzLm1vZHVsZUNhY2hlLnNldChmaWxlUGF0aCwgbnVsbCk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBpc1NlbGYoZmlsZVBhdGg6IHN0cmluZykge1xuXHRcdHJldHVybiBjdXJyZW50RmlsZVBhdGggPT09IHBhdGgucmVzb2x2ZShmaWxlUGF0aCk7XG5cdH1cblxuXHRwcml2YXRlIGxhYmVsc0ZvcihlbnRyeVBhdGhzOiByZWFkb25seSBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcblx0XHRyZXR1cm4gZW50cnlQYXRocy5tYXAoXG5cdFx0XHQoZW50cnlQYXRoKSA9PiB0aGlzLmVudHJpZXMuZ2V0KGVudHJ5UGF0aCk/LmxhYmVsID8/IHBhdGguYmFzZW5hbWUoZW50cnlQYXRoKSxcblx0XHQpO1xuXHR9XG5cblx0cHJpdmF0ZSB0YWtlVHJpZ2dlcnMoKTogc3RyaW5nW10ge1xuXHRcdGNvbnN0IHRyaWdnZXJzID0gWy4uLnRoaXMucGVuZGluZ1RyaWdnZXJzXS5tYXAoKGZ1bGxQYXRoKSA9PiB0aGlzLmZvcm1hdFRyaWdnZXIoZnVsbFBhdGgpKTtcblx0XHR0aGlzLnBlbmRpbmdUcmlnZ2Vycy5jbGVhcigpO1xuXHRcdHJldHVybiB0cmlnZ2Vycztcblx0fVxuXG5cdHByaXZhdGUgZm9ybWF0VHJpZ2dlcihmdWxsUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcblx0XHRjb25zdCByb290ID0gdGhpcy5sb2FkZXIuZ2V0V29ya3NwYWNlKCk/LnJvb3REaXI7XG5cdFx0aWYgKHJvb3QgIT0gbnVsbCkge1xuXHRcdFx0Y29uc3QgcmVsID0gcGF0aC5yZWxhdGl2ZShwYXRoLnJlc29sdmUocm9vdCksIGZ1bGxQYXRoKTtcblx0XHRcdGlmIChyZWwgIT09IFwiXCIgJiYgIXJlbC5zdGFydHNXaXRoKFwiLi5cIikgJiYgIXBhdGguaXNBYnNvbHV0ZShyZWwpKSB7XG5cdFx0XHRcdHJldHVybiByZWwucmVwbGFjZUFsbChcIlxcXFxcIiwgXCIvXCIpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcGF0aC5iYXNlbmFtZShmdWxsUGF0aCk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJFdmVudEVtaXR0ZXIiLCJwYXRoIiwiaW8iLCJkZWJvdW5jZSIsInNjcmliZSIsIlNvdXJjZU1vZHVsZUxvYWRlciIsImN1cnJlbnRGaWxlUGF0aCIsImZpbGVVcmxUb1BhdGgiLCJ1cmwiLCJWRVJTSU9OX1VSTF9QQVJBTSIsIkRFRkFVTFRfUkVCT09UX0RFQk9VTkNFX01TIiwiTUFYX1JFQk9PVF9UUklHR0VSX1BBVEhTIiwicmVzb2x2ZVJlYm9vdERlYm91bmNlTXMiLCJ2YWx1ZSIsImRlbGF5IiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJFcnJvciIsIlN0cmluZyIsImZvcm1hdFRyaWdnZXJMaXN0IiwidHJpZ2dlcnMiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJqb2luIiwic2xpY2UiLCJCQU5ORVJfUlVMRSIsInJlcGVhdCIsIndyYXBGbHV4QmFubmVyIiwidGl0bGUiLCJkZXRhaWxzIiwiYm9keSIsIm1hcCIsImxpbmUiLCJmb3JtYXRGbHV4UmVib290U3RhcnQiLCJsYWJlbHMiLCJ3aG8iLCJmaWxlcyIsImZvcm1hdEZsdXhSZWJvb3RSZWFkeSIsImVsYXBzZWRNcyIsIk1hdGgiLCJtYXgiLCJyb3VuZCIsIm1vZHVsZVZlcnNpb25TZXEiLCJIb3RSZWxvYWRTZXJ2ZXIiLCJsb2dnZXIiLCJuYW1lIiwibG9hZGVyIiwiZGlzcG9zZWQiLCJlbnRyaWVzIiwiTWFwIiwicGVuZGluZ0VudHJ5UmVib290cyIsIlNldCIsInBlbmRpbmdUcmlnZ2VycyIsIndhdGNoU3Vic2NyaXB0aW9uIiwibW9kdWxlQ2FjaGUiLCJkZXBlbmRlbmNpZXMiLCJyZWJvb3RUYWlsIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWJvb3REZWJvdW5jZUdlbiIsInJlYm9vdEluRmxpZ2h0IiwicmVib290Rm9sbG93VXAiLCJyZWJvb3RRdWV1ZWQiLCJwZW5kaW5nR3JhcGhQcnVuZSIsInNjaGVkdWxlUmVib290Iiwic3RhcnQiLCJvcHRpb25zIiwiY2xlYXIiLCJiaW5kU2NoZWR1bGVSZWJvb3QiLCJyZWJvb3REZWJvdW5jZU1zIiwiYnVpbGRDb25maWciLCJjb25maWd1cmUiLCJ3b3Jrc3BhY2UiLCJ2ZXJzaW9uRmlsZVVybCIsImZpbGVVcmwiLCJnZXRDYWNoZWRPck5ldyIsIm9uUmVzb2x2ZWQiLCJvblBvc3RSZXNvbHZlIiwicmVxdWlyZVdvcmtzcGFjZSIsInNlbGVjdGVkIiwicmVzb2x2ZVByb2plY3RzIiwicHJvamVjdCIsImVudHJ5UGF0aCIsImdldFNvdXJjZUVudHJ5UGF0aCIsInNldCIsImxhYmVsIiwicmVnaXN0ZXJIb29rcyIsImludmFsaWRhdGVBbGxTb3VyY2VGaWxlcyIsIndhdGNoIiwicHJvamVjdEZpbGVDaGFuZ2VkJCIsInN1YnNjcmliZSIsIm9uRmlsZUNoYW5nZSIsImVudHJ5IiwidmFsdWVzIiwidHJhY2UiLCJib290RW50cmllcyIsImtleXMiLCJlbWl0IiwiZGlzcG9zZSIsInVuc3Vic2NyaWJlIiwiZGlzcG9zZUVudHJpZXMiLCJTeW1ib2wiLCJhc3luY0Rpc3Bvc2UiLCJlbnRyeVBhdGhzIiwiYWxsIiwiYm9vdEVudHJ5Iiwic3RhdGUiLCJnZXQiLCJtb2QiLCJpbXBvcnRFbnRyeSIsIm1vZHVsZSIsImRlZmF1bHQiLCJlcnJvciIsImRlbGF5TXMiLCJnZW4iLCJyZXF1ZXN0UmVib290IiwidGhlbiIsInJ1blJlYm9vdCIsInRvUmVib290Iiwic2l6ZSIsInBydW5lUGVuZGluZ0RlcGVuZGVuY3lFZGdlcyIsInN0YXJ0ZWRBdCIsIkRhdGUiLCJub3ciLCJsYWJlbHNGb3IiLCJ0YWtlVHJpZ2dlcnMiLCJpbmZvIiwibmVlZHNGb2xsb3dVcCIsImRpc3Bvc2VFbnRyeSIsInBhdGhzIiwicCIsImdldFdvcmtzcGFjZSIsInByb2plY3RzIiwiZ2V0UHJvamVjdHMiLCJuYW1lcyIsImZpcnN0IiwiYXQiLCJmb3VuZCIsImZpbmQiLCJwdXNoIiwicmVzdWx0IiwicGFyZW50VXJsIiwicGFyZW50VXJsQ2xlYW4iLCJzcGxpdCIsImZpbGVQYXRoIiwicGFyZW50UGF0aCIsInVybE9iaiIsIlVSTCIsInNlYXJjaCIsInRvU3RyaW5nIiwiaXNTb3VyY2UiLCJoYXNTb3VyY2VGaWxlIiwicGFyZW50SXNTb3VyY2UiLCJ0cmFja0RlcGVuZGVuY3kiLCJldnQiLCJmaWxlIiwiZXZlbnROYW1lIiwiZnVsbFBhdGgiLCJXYXRjaEV2ZW50cyIsInVubGluayIsImludmFsaWRhdGVUcmFuc3BpbGUiLCJhZGQiLCJpc1NvdXJjZUZpbGUiLCJzZXRTb3VyY2VGaWxlIiwicmVsb2FkSWZBZmZlY3RlZCIsImRlcHMiLCJnZXREZXBlbmRlbmN5R3JhcGgiLCJtb2R1bGVzIiwiYWZmZWN0ZWRFbnRyaWVzIiwiZmlsdGVyIiwiaW5jbHVkZXMiLCJpbnZhbGlkYXRlTW9kdWxlQ2FjaGVzIiwibW9kdWxlSWQiLCJwYXJlbnRNb2R1bGVzIiwiaXNTZWxmIiwibW9kdWxlRGVwcyIsInN1YkRlcHMiLCJkZXAiLCJzdWJzIiwidXBkYXRlZERlcHMiLCJtb2R1bGVVcmwiLCJjYWNoZWQiLCJ2ZXJzaW9uZWQiLCJ2ZXJzaW9uTW9kdWxlIiwidmVyc2lvbmVkVXJsIiwic2VhcmNoUGFyYW1zIiwicHJ1bmVEZXBlbmRlbmN5UGFyZW50cyIsImtleSIsInBhcmVudHMiLCJmaWx0ZXJlZCIsImRlbGV0ZSIsInNvdXJjZUZpbGVQYXRocyIsImJhc2VuYW1lIiwiZm9ybWF0VHJpZ2dlciIsInJvb3QiLCJyb290RGlyIiwicmVsIiwicmVsYXRpdmUi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