@decohere/flux 0.0.1-dev.9 → 0.0.1-dev.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commonjs/src/deferred-script-runner.js +58 -0
- package/commonjs/src/flux.command.js +3 -1
- package/commonjs/src/flux.js +58 -0
- package/commonjs/src/flux.module.js +6 -2
- package/commonjs/src/hot-reload-server.js +268 -194
- package/commonjs/src/index.js +35 -1
- package/commonjs/src/rewrite-serve-specifier.js +46 -0
- package/commonjs/src/run.action.js +49 -0
- package/commonjs/src/run.command.js +67 -0
- package/commonjs/src/serve.action.js +77 -4
- package/commonjs/src/serve.command.js +32 -2
- package/commonjs/src/slice-serve.js +132 -0
- package/commonjs/src/source-module-loader.js +216 -0
- package/es6/src/deferred-script-runner.js +48 -0
- package/es6/src/flux.command.js +3 -1
- package/es6/src/flux.js +43 -0
- package/es6/src/flux.module.js +6 -2
- package/es6/src/hot-reload-server.js +249 -151
- package/es6/src/index.js +6 -2
- package/es6/src/rewrite-serve-specifier.js +40 -0
- package/es6/src/run.action.js +40 -0
- package/es6/src/run.command.js +57 -0
- package/es6/src/serve.action.js +73 -4
- package/es6/src/serve.command.js +32 -2
- package/es6/src/slice-serve.js +107 -0
- package/es6/src/source-module-loader.js +160 -0
- package/package.json +7 -6
- package/types/src/deferred-script-runner.d.ts +18 -0
- package/types/src/flux.d.ts +43 -0
- package/types/src/flux.module.d.ts +2 -0
- package/types/src/hot-reload-server.d.ts +45 -22
- package/types/src/index.d.ts +8 -1
- package/types/src/rewrite-serve-specifier.d.ts +13 -0
- package/types/src/run.action.d.ts +15 -0
- package/types/src/run.command.d.ts +11 -0
- package/types/src/serve.action.d.ts +11 -1
- package/types/src/serve.command.d.ts +5 -0
- package/types/src/slice-serve.d.ts +52 -0
- 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 {
|
|
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
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
25
|
-
|
|
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.
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|
40
|
-
this.watchSubscription =
|
|
41
|
-
this.
|
|
42
|
-
|
|
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.
|
|
50
|
-
await this.
|
|
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
|
|
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
|
|
59
|
-
|
|
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
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
|
90
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
// ──
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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.
|
|
168
|
-
const parentIsSource = this.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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,
|
|
363
|
+
versionedUrl.searchParams.set(VERSION_URL_PARAM, String(++moduleVersionSeq));
|
|
295
364
|
return versionedUrl.toString();
|
|
296
365
|
}
|
|
297
|
-
|
|
366
|
+
invalidateModuleCaches(...modules) {
|
|
298
367
|
for (const module of modules){
|
|
299
368
|
this.moduleCache.set(module, null);
|
|
300
|
-
this.
|
|
301
|
-
|
|
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.
|
|
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/LnJvb3REaXI7XG5cdFx0aWYgKHJvb3QgIT0gbnVsbCkge1xuXHRcdFx0Y29uc3QgcmVsID0gcGF0aC5yZWxhdGl2ZShwYXRoLnJlc29sdmUocm9vdCksIGZ1bGxQYXRoKTtcblx0XHRcdGlmIChyZWwgIT09IFwiXCIgJiYgIXJlbC5zdGFydHNXaXRoKFwiLi5cIikgJiYgIXBhdGguaXNBYnNvbHV0ZShyZWwpKSB7XG5cdFx0XHRcdHJldHVybiByZWwucmVwbGFjZUFsbChcIlxcXFxcIiwgXCIvXCIpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcGF0aC5iYXNlbmFtZShmdWxsUGF0aCk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJFdmVudEVtaXR0ZXIiLCJwYXRoIiwiaW8iLCJkZWJvdW5jZSIsInNjcmliZSIsIlNvdXJjZU1vZHVsZUxvYWRlciIsImN1cnJlbnRGaWxlUGF0aCIsImZpbGVVcmxUb1BhdGgiLCJ1cmwiLCJWRVJTSU9OX1VSTF9QQVJBTSIsIkRFRkFVTFRfUkVCT09UX0RFQk9VTkNFX01TIiwiTUFYX1JFQk9PVF9UUklHR0VSX1BBVEhTIiwicmVzb2x2ZVJlYm9vdERlYm91bmNlTXMiLCJ2YWx1ZSIsImRlbGF5IiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJFcnJvciIsIlN0cmluZyIsImZvcm1hdFRyaWdnZXJMaXN0IiwidHJpZ2dlcnMiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJqb2luIiwic2xpY2UiLCJCQU5ORVJfUlVMRSIsInJlcGVhdCIsIndyYXBGbHV4QmFubmVyIiwidGl0bGUiLCJkZXRhaWxzIiwiYm9keSIsIm1hcCIsImxpbmUiLCJmb3JtYXRGbHV4UmVib290U3RhcnQiLCJsYWJlbHMiLCJ3aG8iLCJmaWxlcyIsImZvcm1hdEZsdXhSZWJvb3RSZWFkeSIsImVsYXBzZWRNcyIsIk1hdGgiLCJtYXgiLCJyb3VuZCIsIm1vZHVsZVZlcnNpb25TZXEiLCJIb3RSZWxvYWRTZXJ2ZXIiLCJsb2dnZXIiLCJuYW1lIiwibG9hZGVyIiwiZGlzcG9zZWQiLCJlbnRyaWVzIiwiTWFwIiwicGVuZGluZ0VudHJ5UmVib290cyIsIlNldCIsInBlbmRpbmdUcmlnZ2VycyIsIndhdGNoU3Vic2NyaXB0aW9uIiwibW9kdWxlQ2FjaGUiLCJkZXBlbmRlbmNpZXMiLCJyZWJvb3RUYWlsIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWJvb3REZWJvdW5jZUdlbiIsInJlYm9vdEluRmxpZ2h0IiwicmVib290Rm9sbG93VXAiLCJyZWJvb3RRdWV1ZWQiLCJwZW5kaW5nR3JhcGhQcnVuZSIsInNjaGVkdWxlUmVib290Iiwic3RhcnQiLCJvcHRpb25zIiwiY2xlYXIiLCJiaW5kU2NoZWR1bGVSZWJvb3QiLCJyZWJvb3REZWJvdW5jZU1zIiwiYnVpbGRDb25maWciLCJjb25maWd1cmUiLCJ3b3Jrc3BhY2UiLCJ2ZXJzaW9uRmlsZVVybCIsImZpbGVVcmwiLCJnZXRDYWNoZWRPck5ldyIsIm9uUmVzb2x2ZWQiLCJvblBvc3RSZXNvbHZlIiwicmVxdWlyZVdvcmtzcGFjZSIsInNlbGVjdGVkIiwicmVzb2x2ZVByb2plY3RzIiwicHJvamVjdCIsImVudHJ5UGF0aCIsImdldFNvdXJjZUVudHJ5UGF0aCIsInNldCIsImxhYmVsIiwicmVnaXN0ZXJIb29rcyIsImludmFsaWRhdGVBbGxTb3VyY2VGaWxlcyIsIndhdGNoIiwicHJvamVjdEZpbGVDaGFuZ2VkJCIsInN1YnNjcmliZSIsIm9uRmlsZUNoYW5nZSIsImVudHJ5IiwidmFsdWVzIiwidHJhY2UiLCJib290RW50cmllcyIsImtleXMiLCJlbWl0IiwiZGlzcG9zZSIsInVuc3Vic2NyaWJlIiwiZGlzcG9zZUVudHJpZXMiLCJTeW1ib2wiLCJhc3luY0Rpc3Bvc2UiLCJlbnRyeVBhdGhzIiwiYWxsIiwiYm9vdEVudHJ5Iiwic3RhdGUiLCJnZXQiLCJtb2QiLCJpbXBvcnRFbnRyeSIsIm1vZHVsZSIsImRlZmF1bHQiLCJlcnJvciIsImRlbGF5TXMiLCJnZW4iLCJyZXF1ZXN0UmVib290IiwidGhlbiIsInJ1blJlYm9vdCIsInRvUmVib290Iiwic2l6ZSIsInBydW5lUGVuZGluZ0RlcGVuZGVuY3lFZGdlcyIsInN0YXJ0ZWRBdCIsIkRhdGUiLCJub3ciLCJsYWJlbHNGb3IiLCJ0YWtlVHJpZ2dlcnMiLCJpbmZvIiwibmVlZHNGb2xsb3dVcCIsImRpc3Bvc2VFbnRyeSIsInBhdGhzIiwicCIsImdldFdvcmtzcGFjZSIsInByb2plY3RzIiwiZ2V0UHJvamVjdHMiLCJuYW1lcyIsImZpcnN0IiwiYXQiLCJmb3VuZCIsImZpbmQiLCJwdXNoIiwicmVzdWx0IiwicGFyZW50VXJsIiwicGFyZW50VXJsQ2xlYW4iLCJzcGxpdCIsImZpbGVQYXRoIiwicGFyZW50UGF0aCIsInVybE9iaiIsIlVSTCIsInNlYXJjaCIsInRvU3RyaW5nIiwiaXNTb3VyY2UiLCJoYXNTb3VyY2VGaWxlIiwicGFyZW50SXNTb3VyY2UiLCJ0cmFja0RlcGVuZGVuY3kiLCJldnQiLCJmaWxlIiwiZXZlbnROYW1lIiwiZnVsbFBhdGgiLCJXYXRjaEV2ZW50cyIsInVubGluayIsImludmFsaWRhdGVUcmFuc3BpbGUiLCJhZGQiLCJpc1NvdXJjZUZpbGUiLCJzZXRTb3VyY2VGaWxlIiwicmVsb2FkSWZBZmZlY3RlZCIsImRlcHMiLCJnZXREZXBlbmRlbmN5R3JhcGgiLCJtb2R1bGVzIiwiYWZmZWN0ZWRFbnRyaWVzIiwiZmlsdGVyIiwiaW5jbHVkZXMiLCJpbnZhbGlkYXRlTW9kdWxlQ2FjaGVzIiwibW9kdWxlSWQiLCJwYXJlbnRNb2R1bGVzIiwiaXNTZWxmIiwibW9kdWxlRGVwcyIsInN1YkRlcHMiLCJkZXAiLCJzdWJzIiwidXBkYXRlZERlcHMiLCJtb2R1bGVVcmwiLCJjYWNoZWQiLCJ2ZXJzaW9uZWQiLCJ2ZXJzaW9uTW9kdWxlIiwidmVyc2lvbmVkVXJsIiwic2VhcmNoUGFyYW1zIiwicHJ1bmVEZXBlbmRlbmN5UGFyZW50cyIsImtleSIsInBhcmVudHMiLCJmaWx0ZXJlZCIsImRlbGV0ZSIsInNvdXJjZUZpbGVQYXRocyIsImJhc2VuYW1lIiwiZm9ybWF0VHJpZ2dlciIsInJvb3QiLCJyb290RGlyIiwicmVsIiwicmVsYXRpdmUiLCJzdGFydHNXaXRoIiwiaXNBYnNvbHV0ZSIsInJlcGxhY2VBbGwiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFlBQVksUUFBUSxjQUFjO0FBRTNDLE9BQU9DLFVBQVUsWUFBWTtBQUU3QixTQUFTQyxFQUFFLFFBQVEscUJBQXFCO0FBQ3hDLFNBQVNDLFFBQVEsUUFBUSx5QkFBeUI7QUFDbEQsU0FBc0JDLE1BQU0sUUFBUSxtQkFBbUI7QUFFdkQsU0FBU0Msa0JBQWtCLFFBQVEsNEJBQTRCO0FBRS9ELE1BQU1DLGtCQUFrQkosR0FBR0ssYUFBYSxDQUFDLFlBQVlDLEdBQUc7QUFDeEQsTUFBTUMsb0JBQW9CO0FBQzFCLHNEQUFzRCxHQUN0RCxPQUFPLE1BQU1DLDZCQUE2QixJQUFJO0FBQzlDLHVFQUF1RSxHQUN2RSxNQUFNQywyQkFBMkI7QUFFakMsT0FBTyxTQUFTQyx3QkFBd0JDLEtBQXlCO0lBQ2hFLE1BQU1DLFFBQVFELFNBQVNIO0lBQ3ZCLElBQUksQ0FBQ0ssT0FBT0MsUUFBUSxDQUFDRixVQUFVQSxRQUFRLEdBQUc7UUFDekMsTUFBTSxJQUFJRyxNQUFNLENBQUMsb0RBQW9ELEVBQUVDLE9BQU9MLFFBQVE7SUFDdkY7SUFDQSxPQUFPQztBQUNSO0FBRUEsU0FBU0ssa0JBQWtCQyxRQUEyQjtJQUNyRCxJQUFJQSxTQUFTQyxNQUFNLEtBQUssR0FBRyxPQUFPQztJQUNsQyxJQUFJRixTQUFTQyxNQUFNLElBQUlWLDBCQUEwQixPQUFPUyxTQUFTRyxJQUFJLENBQUM7SUFDdEUsT0FBTyxHQUFHSCxTQUFTSSxLQUFLLENBQUMsR0FBR2IsMEJBQTBCWSxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUVILFNBQVNDLE1BQU0sR0FBR1YsMEJBQTBCO0FBQ25IO0FBRUEsTUFBTWMsY0FBYyxJQUFJQyxNQUFNLENBQUM7QUFFL0IsU0FBU0MsZUFBZUMsS0FBYSxFQUFFQyxPQUEwQjtJQUNoRSxNQUFNQyxPQUFPRCxRQUFRRSxHQUFHLENBQUMsQ0FBQ0MsT0FBUyxDQUFDLEVBQUUsRUFBRUEsTUFBTSxFQUFFVCxJQUFJLENBQUM7SUFDckQsT0FBTyxDQUFDLEVBQUUsRUFBRUUsWUFBWSxJQUFJLEVBQUVHLE1BQU0sRUFBRSxFQUFFRSxLQUFLLEVBQUUsRUFBRUwsWUFBWSxFQUFFLENBQUM7QUFDakU7QUFFQSxvR0FBb0csR0FDcEcsT0FBTyxTQUFTUSxzQkFDZkMsTUFBeUIsRUFDekJkLFdBQThCLEVBQUU7SUFFaEMsTUFBTWUsTUFBTUQsT0FBT1gsSUFBSSxDQUFDLFNBQVM7SUFDakMsTUFBTWEsUUFBUWpCLGtCQUFrQkM7SUFDaEMsTUFBTVMsVUFBVU8sU0FBUyxPQUFPO1FBQUNEO0tBQUksR0FBRztRQUFDQTtRQUFLQztLQUFNO0lBQ3BELE9BQU9ULGVBQWUsZUFBZUU7QUFDdEM7QUFFQSxpQ0FBaUMsR0FDakMsT0FBTyxTQUFTUSxzQkFBc0JILE1BQXlCLEVBQUVJLFNBQWlCO0lBQ2pGLE1BQU1ILE1BQU1ELE9BQU9YLElBQUksQ0FBQyxTQUFTO0lBQ2pDLE9BQU9JLGVBQWUsY0FBYztRQUFDUTtRQUFLLEdBQUdJLEtBQUtDLEdBQUcsQ0FBQyxHQUFHRCxLQUFLRSxLQUFLLENBQUNILFlBQVksRUFBRSxDQUFDO0tBQUM7QUFDckY7QUFFQSxrR0FBa0csR0FDbEcsSUFBSUksbUJBQW1CO0FBK0J2QixPQUFPLE1BQU1DLHdCQUF3QjNDO0lBQ3BDLDRFQUE0RTtJQUMzRDRDLFNBQWlCeEMsT0FBT3dDLE1BQU0sQ0FBQ0QsZ0JBQWdCRSxJQUFJLEVBQUU7SUFDckRDLFNBQVMsSUFBSXpDLHFCQUFxQjtJQUMzQzBDLFdBQVcsTUFBTTtJQUN6QixtRUFBbUUsR0FDbkUsQUFBUUMsVUFBVSxJQUFJQyxNQUEwQjtJQUN4Q0Msc0JBQXNCLElBQUlDLE1BQWM7SUFDaEQsbUZBQW1GLEdBQ25GLEFBQVFDLGtCQUFrQixJQUFJRCxNQUFjO0lBQ3BDRSxrQkFBaUM7SUFDakNDLGNBQWMsSUFBSUwsTUFBNkI7SUFDL0NNLGVBQWUsSUFBSU4sTUFBd0I7SUFDM0NPLGFBQTRCQyxRQUFRQyxPQUFPLEdBQUc7SUFDOUNDLG9CQUFvQixFQUFFO0lBQ3RCQyxpQkFBaUIsTUFBTTtJQUN2QkMsaUJBQWlCLE1BQU07SUFDdkJDLGVBQWUsTUFBTTtJQUM3Qiw2RUFBNkUsR0FDN0UsQUFBUUMsb0JBQW9CLElBQUlaLE1BQWM7SUFDdENhLGlCQUE2QixLQUFPLEVBQUU7SUFFOUMsNEVBQTRFO0lBRTVFLE1BQWFDLE1BQU1DLE9BQStCLEVBQUU7UUFDbkQsSUFBSSxDQUFDbkIsUUFBUSxHQUFHO1FBQ2hCLElBQUksQ0FBQ1EsWUFBWSxDQUFDWSxLQUFLO1FBQ3ZCLElBQUksQ0FBQ2IsV0FBVyxDQUFDYSxLQUFLO1FBQ3RCLElBQUksQ0FBQ25CLE9BQU8sQ0FBQ21CLEtBQUs7UUFDbEIsSUFBSSxDQUFDakIsbUJBQW1CLENBQUNpQixLQUFLO1FBQzlCLElBQUksQ0FBQ2YsZUFBZSxDQUFDZSxLQUFLO1FBQzFCLElBQUksQ0FBQ0osaUJBQWlCLENBQUNJLEtBQUs7UUFDNUIsSUFBSSxDQUFDWCxVQUFVLEdBQUdDLFFBQVFDLE9BQU87UUFDakMsSUFBSSxDQUFDRSxjQUFjLEdBQUc7UUFDdEIsSUFBSSxDQUFDQyxjQUFjLEdBQUc7UUFDdEIsSUFBSSxDQUFDQyxZQUFZLEdBQUc7UUFDcEIsSUFBSSxDQUFDTSxrQkFBa0IsQ0FBQ3hELHdCQUF3QnNELFFBQVFHLGdCQUFnQjtRQUV4RSxNQUFNLEVBQUVDLFdBQVcsRUFBRSxHQUFHSjtRQUV4QixNQUFNLElBQUksQ0FBQ3BCLE1BQU0sQ0FBQ3lCLFNBQVMsQ0FBQztZQUMzQkQ7WUFDQUUsV0FBV04sUUFBUU0sU0FBUztZQUM1QkMsZ0JBQWdCLENBQUNDLFVBQVksSUFBSSxDQUFDQyxjQUFjLENBQUNEO1lBQ2pERSxZQUFZLElBQUksQ0FBQ0MsYUFBYTtRQUMvQjtRQUVBLE1BQU1MLFlBQVksSUFBSSxDQUFDTSxnQkFBZ0I7UUFDdkMsTUFBTUMsV0FBVyxJQUFJLENBQUNDLGVBQWUsQ0FBQ1YsYUFBYUo7UUFDbkQsS0FBSyxNQUFNZSxXQUFXRixTQUFVO1lBQy9CLE1BQU1HLFlBQVlqRixLQUFLeUQsT0FBTyxDQUFDdUIsUUFBUUUsa0JBQWtCO1lBQ3pELElBQUksQ0FBQ25DLE9BQU8sQ0FBQ29DLEdBQUcsQ0FBQ0YsV0FBVztnQkFBRWpGLE1BQU1pRjtnQkFBV0csT0FBT0osUUFBUXBDLElBQUk7WUFBQztRQUNwRTtRQUVBLElBQUksQ0FBQ0MsTUFBTSxDQUFDd0MsYUFBYTtRQUN6QixJQUFJLENBQUNDLHdCQUF3QjtRQUU3QixNQUFNZixVQUFVZ0IsS0FBSyxDQUFDbEI7UUFDdEIsSUFBSSxDQUFDakIsaUJBQWlCLEdBQUdtQixVQUFVaUIsbUJBQW1CLENBQUNDLFNBQVMsQ0FBQyxJQUFJLENBQUNDLFlBQVk7UUFFbEYsS0FBSyxNQUFNQyxTQUFTLElBQUksQ0FBQzVDLE9BQU8sQ0FBQzZDLE1BQU0sR0FBSTtZQUMxQyxJQUFJLENBQUNqRCxNQUFNLENBQUNrRCxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUVGLE1BQU0zRixJQUFJLEVBQUU7UUFDMUM7UUFDQSxNQUFNLElBQUksQ0FBQzhGLFdBQVcsQ0FBQztlQUFJLElBQUksQ0FBQy9DLE9BQU8sQ0FBQ2dELElBQUk7U0FBRztRQUMvQyxJQUFJLENBQUNDLElBQUksQ0FBQztJQUNYO0lBRUEsTUFBYUMsVUFBVTtRQUN0QixJQUFJLElBQUksQ0FBQ25ELFFBQVEsRUFBRTtRQUNuQixJQUFJLENBQUNBLFFBQVEsR0FBRztRQUNoQixJQUFJLENBQUNZLGlCQUFpQixJQUFJO1FBQzFCLElBQUksQ0FBQ04saUJBQWlCLEVBQUU4QztRQUN4QixNQUFNLElBQUksQ0FBQzNDLFVBQVU7UUFDckIsTUFBTSxJQUFJLENBQUM0QyxjQUFjLENBQUM7ZUFBSSxJQUFJLENBQUNwRCxPQUFPLENBQUNnRCxJQUFJO1NBQUc7UUFDbEQsSUFBSSxDQUFDbEQsTUFBTSxDQUFDb0QsT0FBTztJQUNwQjtJQUVBLE1BQWEsQ0FBQ0csT0FBT0MsWUFBWSxDQUFDLEdBQUc7UUFDcEMsTUFBTSxJQUFJLENBQUNKLE9BQU87SUFDbkI7SUFFQSw0RUFBNEU7SUFFNUUsTUFBY0gsWUFBWVEsVUFBNkIsRUFBRTtRQUN4RCxNQUFNOUMsUUFBUStDLEdBQUcsQ0FBQ0QsV0FBV3hFLEdBQUcsQ0FBQyxDQUFDbUQsWUFBYyxJQUFJLENBQUN1QixTQUFTLENBQUN2QjtJQUNoRTtJQUVBLE1BQWN1QixVQUFVdkIsU0FBaUIsRUFBRTtRQUMxQyxNQUFNd0IsUUFBUSxJQUFJLENBQUMxRCxPQUFPLENBQUMyRCxHQUFHLENBQUN6QjtRQUMvQixJQUFJd0IsU0FBUyxNQUFNO1FBQ25CLElBQUk7WUFDSCxNQUFNRSxNQUFPLE1BQU0sSUFBSSxDQUFDOUQsTUFBTSxDQUFDK0QsV0FBVyxDQUFDM0I7WUFHM0N3QixNQUFNSSxNQUFNLEdBQUdGLEtBQUtHO1FBQ3JCLEVBQUUsT0FBT0MsT0FBTztZQUNmTixNQUFNSSxNQUFNLEdBQUd4RjtZQUNmLElBQUksQ0FBQ3NCLE1BQU0sQ0FBQ29FLEtBQUssQ0FDaEIsNkZBQ0FBO1FBRUY7SUFDRDtJQUVRNUMsbUJBQW1CNkMsT0FBZSxFQUFFO1FBQzNDLE1BQU1DLE1BQU0sRUFBRSxJQUFJLENBQUN2RCxpQkFBaUI7UUFDcEMsSUFBSSxDQUFDSyxjQUFjLEdBQUc3RCxTQUFTO1lBQzlCLElBQUksSUFBSSxDQUFDNEMsUUFBUSxJQUFJbUUsUUFBUSxJQUFJLENBQUN2RCxpQkFBaUIsRUFBRTtZQUNyRCxJQUFJLENBQUN3RCxhQUFhO1FBQ25CLEdBQUdGO0lBQ0o7SUFFUUUsZ0JBQWdCO1FBQ3ZCLElBQUksSUFBSSxDQUFDcEUsUUFBUSxFQUFFO1FBQ25CLElBQUksSUFBSSxDQUFDYSxjQUFjLEVBQUU7WUFDeEIsSUFBSSxDQUFDQyxjQUFjLEdBQUc7WUFDdEI7UUFDRDtRQUNBLElBQUksSUFBSSxDQUFDQyxZQUFZLEVBQUU7UUFDdkIsSUFBSSxDQUFDQSxZQUFZLEdBQUc7UUFDcEIsSUFBSSxDQUFDTixVQUFVLEdBQUcsSUFBSSxDQUFDQSxVQUFVLENBQUM0RCxJQUFJLENBQ3JDLElBQU0sSUFBSSxDQUFDQyxTQUFTLElBQ3BCLElBQU0sSUFBSSxDQUFDQSxTQUFTO0lBRXRCO0lBRUEsTUFBY0EsWUFBWTtRQUN6QixJQUFJLENBQUN2RCxZQUFZLEdBQUc7UUFDcEIsSUFBSSxJQUFJLENBQUNmLFFBQVEsRUFBRTtRQUNuQixJQUFJLENBQUNhLGNBQWMsR0FBRztRQUN0QixJQUFJO1lBQ0gsR0FBRztnQkFDRixJQUFJLENBQUNDLGNBQWMsR0FBRztnQkFDdEIsSUFBSSxJQUFJLENBQUNkLFFBQVEsRUFBRTtnQkFDbkIsTUFBTXVFLFdBQ0wsSUFBSSxDQUFDcEUsbUJBQW1CLENBQUNxRSxJQUFJLEdBQUcsSUFDN0I7dUJBQUksSUFBSSxDQUFDckUsbUJBQW1CO2lCQUFDLEdBQzdCO3VCQUFJLElBQUksQ0FBQ0YsT0FBTyxDQUFDZ0QsSUFBSTtpQkFBRztnQkFDNUIsSUFBSSxDQUFDOUMsbUJBQW1CLENBQUNpQixLQUFLO2dCQUM5Qix3RUFBd0U7Z0JBQ3hFLDZEQUE2RDtnQkFDN0QsSUFBSSxDQUFDcUQsMkJBQTJCO2dCQUNoQyxNQUFNQyxZQUFZQyxLQUFLQyxHQUFHO2dCQUMxQixNQUFNekYsU0FBUyxJQUFJLENBQUMwRixTQUFTLENBQUNOO2dCQUM5QixNQUFNbEcsV0FBVyxJQUFJLENBQUN5RyxZQUFZO2dCQUNsQyxJQUFJLENBQUNqRixNQUFNLENBQUNrRixJQUFJLENBQUM3RixzQkFBc0JDLFFBQVFkO2dCQUMvQyxNQUFNLElBQUksQ0FBQ2dGLGNBQWMsQ0FBQ2tCO2dCQUMxQixNQUFNLElBQUksQ0FBQ3ZCLFdBQVcsQ0FBQ3VCO2dCQUN2QixJQUFJLENBQUMxRSxNQUFNLENBQUNrRixJQUFJLENBQUN6RixzQkFBc0JILFFBQVF3RixLQUFLQyxHQUFHLEtBQUtGO2dCQUM1RCxJQUFJLENBQUN4QixJQUFJLENBQUM7WUFDWCxRQUFTLElBQUksQ0FBQ3BDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQ2QsUUFBUSxDQUFFO1FBQ2pELFNBQVU7WUFDVCxNQUFNZ0YsZ0JBQWdCLElBQUksQ0FBQ2xFLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQ2QsUUFBUTtZQUMzRCxJQUFJLENBQUNjLGNBQWMsR0FBRztZQUN0QixJQUFJLENBQUNELGNBQWMsR0FBRztZQUN0QixJQUFJbUUsZUFBZSxJQUFJLENBQUNaLGFBQWE7UUFDdEM7SUFDRDtJQUVBLE1BQWNmLGVBQWVHLFVBQTZCLEVBQUU7UUFDM0QsTUFBTTlDLFFBQVErQyxHQUFHLENBQUNELFdBQVd4RSxHQUFHLENBQUMsQ0FBQ21ELFlBQWMsSUFBSSxDQUFDOEMsWUFBWSxDQUFDOUM7SUFDbkU7SUFFQSxNQUFjOEMsYUFBYTlDLFNBQWtCLEVBQUU7UUFDOUMsTUFBTStDLFFBQVEvQyxhQUFhLE9BQU87WUFBQ0E7U0FBVSxHQUFHO2VBQUksSUFBSSxDQUFDbEMsT0FBTyxDQUFDZ0QsSUFBSTtTQUFHO1FBQ3hFLEtBQUssTUFBTWtDLEtBQUtELE1BQU87WUFDdEIsTUFBTXZCLFFBQVEsSUFBSSxDQUFDMUQsT0FBTyxDQUFDMkQsR0FBRyxDQUFDdUI7WUFDL0IsSUFBSXhCLFNBQVMsTUFBTTtZQUNuQixNQUFNZCxRQUFRYyxNQUFNSSxNQUFNO1lBQzFCSixNQUFNSSxNQUFNLEdBQUd4RjtZQUNmLElBQUk7Z0JBQ0gsTUFBTXNFLE9BQU8sQ0FBQ1MsT0FBT0MsWUFBWSxDQUFDO1lBQ25DLEVBQUUsT0FBT1UsT0FBTztnQkFDZixJQUFJLENBQUNwRSxNQUFNLENBQUNvRSxLQUFLLENBQUMsNkJBQTZCQTtZQUNoRDtRQUNEO0lBQ0Q7SUFFQSw0RUFBNEU7SUFFcEVsQyxtQkFBOEI7UUFDckMsTUFBTU4sWUFBWSxJQUFJLENBQUMxQixNQUFNLENBQUNxRixZQUFZO1FBQzFDLElBQUkzRCxhQUFhLE1BQU07WUFDdEIsTUFBTSxJQUFJdkQsTUFBTTtRQUNqQjtRQUNBLE9BQU91RDtJQUNSO0lBRVFRLGdCQUFnQlYsV0FBbUIsRUFBRUosT0FBK0IsRUFBYTtRQUN4RixNQUFNa0UsV0FBVyxJQUFJLENBQUN0RixNQUFNLENBQUNxRixZQUFZLElBQUlFLFlBQVkvRCxnQkFBZ0IsRUFBRTtRQUMzRSxNQUFNZ0UsUUFDTHBFLFFBQVFrRSxRQUFRLElBQUksUUFBUWxFLFFBQVFrRSxRQUFRLENBQUMvRyxNQUFNLEdBQUcsSUFDbkQ2QyxRQUFRa0UsUUFBUSxHQUNoQmxFLFFBQVFlLE9BQU8sSUFBSSxPQUNsQjtZQUFDZixRQUFRZSxPQUFPO1NBQUMsR0FDakIzRDtRQUVMLElBQUlnSCxTQUFTLE1BQU07WUFDbEIsTUFBTUMsUUFBUUgsU0FBU0ksRUFBRSxDQUFDO1lBQzFCLElBQUlELFNBQVMsTUFBTTtnQkFDbEIsTUFBTSxJQUFJdEgsTUFBTSxDQUFDLHFDQUFxQyxFQUFFcUQsYUFBYTtZQUN0RTtZQUNBLE9BQU87Z0JBQUNpRTthQUFNO1FBQ2Y7UUFFQSxNQUFNeEQsV0FBc0IsRUFBRTtRQUM5QixLQUFLLE1BQU1sQyxRQUFReUYsTUFBTztZQUN6QixNQUFNRyxRQUFRTCxTQUFTTSxJQUFJLENBQUMsQ0FBQ1IsSUFBTUEsRUFBRXJGLElBQUksS0FBS0E7WUFDOUMsSUFBSTRGLFNBQVMsTUFBTTtnQkFDbEIsTUFBTSxJQUFJeEgsTUFBTSxDQUFDLFNBQVMsRUFBRTRCLEtBQUssd0JBQXdCLENBQUM7WUFDM0Q7WUFDQWtDLFNBQVM0RCxJQUFJLENBQUNGO1FBQ2Y7UUFDQSxPQUFPMUQ7SUFDUjtJQUVBOzs7RUFHQyxHQUNELEFBQVFGLGdCQUFnQixDQUFDK0QsUUFBeUJDO1FBQ2pELE1BQU0sRUFBRXJJLEdBQUcsRUFBRSxHQUFHb0k7UUFDaEIsTUFBTUUsaUJBQWlCRCxVQUFVRSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFFOUMsSUFBSUM7UUFDSixJQUFJQztRQUVKLElBQUk7WUFDSCxNQUFNQyxTQUFTLElBQUlDLElBQUkzSTtZQUN2QjBJLE9BQU9FLE1BQU0sR0FBRztZQUNoQkosV0FBVzlJLEdBQUdLLGFBQWEsQ0FBQzJJLE9BQU9HLFFBQVE7UUFDNUMsRUFBRSxPQUFNO1lBQ1A7UUFDRDtRQUVBLElBQUk7WUFDSEosYUFBYS9JLEdBQUdLLGFBQWEsQ0FBQ3VJO1FBQy9CLEVBQUUsT0FBTTtZQUNQRyxhQUFhO1FBQ2Q7UUFFQSxNQUFNSyxXQUFXLElBQUksQ0FBQ3hHLE1BQU0sQ0FBQ3lHLGFBQWEsQ0FBQ1A7UUFDM0MsTUFBTVEsaUJBQWlCLElBQUksQ0FBQzFHLE1BQU0sQ0FBQ3lHLGFBQWEsQ0FBQ047UUFFakQsSUFBSUssWUFBWUUsZ0JBQWdCO1lBQy9CLElBQUksQ0FBQ0MsZUFBZSxDQUFDVCxVQUFVQztRQUNoQztJQUNELEVBQUU7SUFFRiw0RUFBNEU7SUFFcEV0RCxlQUFlLENBQUMrRDtRQUN2QixNQUFNLEVBQUVDLElBQUksRUFBRUMsU0FBUyxFQUFFM0UsT0FBTyxFQUFFLEdBQUd5RTtRQUNyQyxNQUFNRyxXQUFXRixLQUFLRSxRQUFRO1FBRTlCLElBQUksQ0FBQ2pILE1BQU0sQ0FBQ2tELEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRThELFVBQVUsRUFBRSxFQUFFQyxVQUFVO1FBRWxELElBQUlELGNBQWMxSixHQUFHNEosV0FBVyxDQUFDQyxNQUFNLEVBQUU7WUFDeEMsSUFBSSxDQUFDakgsTUFBTSxDQUFDa0gsbUJBQW1CLENBQUNIO1lBQ2hDLElBQUksQ0FBQ3ZHLFdBQVcsQ0FBQzhCLEdBQUcsQ0FBQ3lFLFVBQVU7WUFDL0I7UUFDRDtRQUVBLElBQUlELGNBQWMxSixHQUFHNEosV0FBVyxDQUFDRyxHQUFHLEVBQUU7WUFDckMsSUFBSWhGLFFBQVFpRixZQUFZLENBQUNQLE9BQU87Z0JBQy9CLElBQUksQ0FBQzdHLE1BQU0sQ0FBQ3FILGFBQWEsQ0FBQ04sVUFBVTVFO2dCQUNwQyxJQUFJLENBQUMzQixXQUFXLENBQUM4QixHQUFHLENBQUN5RSxVQUFVO2dCQUMvQixJQUFJLENBQUNPLGdCQUFnQixDQUFDUDtZQUN2QjtZQUNBO1FBQ0Q7UUFFQSxTQUFTO1FBQ1QsSUFBSSxDQUFDNUUsUUFBUWlGLFlBQVksQ0FBQ1AsT0FBTztRQUNqQyxJQUFJLENBQUM3RyxNQUFNLENBQUNrSCxtQkFBbUIsQ0FBQ0g7UUFDaEMsSUFBSSxDQUFDTyxnQkFBZ0IsQ0FBQ1A7SUFDdkIsRUFBRTtJQUVNTyxpQkFBaUJQLFFBQWdCLEVBQVc7UUFDbkQsTUFBTVEsT0FBTyxJQUFJLENBQUNDLGtCQUFrQixDQUFDVDtRQUNyQyxNQUFNVSxVQUFVO2VBQUksSUFBSXBILElBQUk7bUJBQUlrSDtnQkFBTVI7YUFBUztTQUFFO1FBQ2pELE1BQU1XLGtCQUFrQjtlQUFJLElBQUksQ0FBQ3hILE9BQU8sQ0FBQ2dELElBQUk7U0FBRyxDQUFDeUUsTUFBTSxDQUFDLENBQUN2RixZQUN4RHFGLFFBQVFHLFFBQVEsQ0FBQ3hGO1FBR2xCLElBQUlzRixnQkFBZ0JuSixNQUFNLEtBQUssR0FBRztZQUNqQyxJQUFJLENBQUN1QixNQUFNLENBQUNrRCxLQUFLLENBQUMsQ0FBQyxVQUFVLEVBQUUrRCxTQUFTLHdDQUF3QyxDQUFDO1lBQ2pGLE9BQU87UUFDUjtRQUVBLElBQUksQ0FBQ2pILE1BQU0sQ0FBQ2tELEtBQUssQ0FDaEIsQ0FBQyxVQUFVLEVBQUUrRCxTQUFTLFNBQVMsRUFBRVUsUUFBUWxKLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQztRQUVoRixJQUFJLENBQUNzSixzQkFBc0IsSUFBSUo7UUFDL0IsS0FBSyxNQUFNekQsVUFBVXlELFFBQVM7WUFDN0IsSUFBSSxDQUFDeEcsaUJBQWlCLENBQUNrRyxHQUFHLENBQUNuRDtRQUM1QjtRQUNBLEtBQUssTUFBTTVCLGFBQWFzRixnQkFBaUI7WUFDeEMsSUFBSSxDQUFDdEgsbUJBQW1CLENBQUMrRyxHQUFHLENBQUMvRTtRQUM5QjtRQUNBLElBQUksQ0FBQzlCLGVBQWUsQ0FBQzZHLEdBQUcsQ0FBQ0o7UUFDekIsSUFBSSxDQUFDN0YsY0FBYztRQUNuQixPQUFPO0lBQ1I7SUFFQSw0RUFBNEU7SUFFcEVzRyxtQkFBbUJNLFFBQWdCLEVBQUVDLGdCQUEwQixFQUFFLEVBQVk7UUFDcEYsSUFBSSxJQUFJLENBQUNDLE1BQU0sQ0FBQ0YsV0FBVyxPQUFPLEVBQUU7UUFFcEMsTUFBTUcsYUFBYSxJQUFJLENBQUN4SCxZQUFZLENBQUNvRCxHQUFHLENBQUNpRSxhQUFhLEVBQUU7UUFDeEQsSUFBSUMsY0FBY0gsUUFBUSxDQUFDRSxXQUFXO1lBQ3JDLElBQUksQ0FBQ2hJLE1BQU0sQ0FBQ29FLEtBQUssQ0FBQyxDQUFDLDZCQUE2QixFQUFFNEQsVUFBVTtZQUM1RCxPQUFPLEVBQUU7UUFDVjtRQUVBLElBQUlJLFVBQW9CLEVBQUU7UUFDMUIsS0FBSyxNQUFNQyxPQUFPRixXQUFZO1lBQzdCLElBQUksQ0FBQyxJQUFJLENBQUNqSSxNQUFNLENBQUN5RyxhQUFhLENBQUMwQixNQUFNO1lBQ3JDLE1BQU1DLE9BQU8sSUFBSSxDQUFDWixrQkFBa0IsQ0FBQ1csS0FBSztnQkFBQ0w7bUJBQWFDO2FBQWM7WUFDdEVHLFVBQVU7bUJBQUlBO21CQUFZRTthQUFLO1FBQ2hDO1FBRUEsT0FBTztlQUFJLElBQUkvSCxJQUFJO21CQUFJNEg7bUJBQWVDO2FBQVE7U0FBRTtJQUNqRDtJQUVRdkIsZ0JBQWdCVCxRQUFnQixFQUFFQyxVQUFrQixFQUFFO1FBQzdELElBQUksQ0FBQ0EsWUFBWTtRQUNqQixNQUFNb0IsT0FBTyxJQUFJLENBQUM5RyxZQUFZLENBQUNvRCxHQUFHLENBQUNxQyxhQUFhLEVBQUU7UUFDbEQsTUFBTW1DLGNBQWMsSUFBSWhJLElBQUk7ZUFBSWtIO1lBQU1wQjtTQUFXO1FBQ2pELElBQUksQ0FBQzFGLFlBQVksQ0FBQzZCLEdBQUcsQ0FBQzRELFVBQVU7ZUFBSW1DO1NBQVk7SUFDakQ7SUFFQSw0RUFBNEU7SUFFcEV4RyxlQUFleUcsU0FBaUIsRUFBRTtRQUN6QyxNQUFNcEMsV0FBVzlJLEdBQUdLLGFBQWEsQ0FBQzZLO1FBQ2xDLE1BQU1DLFNBQVMsSUFBSSxDQUFDL0gsV0FBVyxDQUFDcUQsR0FBRyxDQUFDcUM7UUFDcEMsTUFBTXNDLFlBQVlELFVBQVUsSUFBSSxDQUFDRSxhQUFhLENBQUNIO1FBQy9DLElBQUksQ0FBQzlILFdBQVcsQ0FBQzhCLEdBQUcsQ0FBQzRELFVBQVVzQztRQUMvQixPQUFPQTtJQUNSO0lBRVFDLGNBQWNILFNBQWlCLEVBQUU7UUFDeEMsTUFBTUksZUFBZSxJQUFJckMsSUFBSWlDO1FBQzdCSSxhQUFhQyxZQUFZLENBQUNyRyxHQUFHLENBQUMzRSxtQkFBbUJTLE9BQU8sRUFBRXdCO1FBQzFELE9BQU84SSxhQUFhbkMsUUFBUTtJQUM3QjtJQUVRc0IsdUJBQXVCLEdBQUdKLE9BQWlCLEVBQUU7UUFDcEQsS0FBSyxNQUFNekQsVUFBVXlELFFBQVM7WUFDN0IsSUFBSSxDQUFDakgsV0FBVyxDQUFDOEIsR0FBRyxDQUFDMEIsUUFBUTtZQUM3QixJQUFJLENBQUNoRSxNQUFNLENBQUNrSCxtQkFBbUIsQ0FBQ2xEO1FBQ2pDO0lBQ0Q7SUFFUVUsOEJBQThCO1FBQ3JDLE1BQU0rQyxVQUFVO2VBQUksSUFBSSxDQUFDeEcsaUJBQWlCO1NBQUM7UUFDM0MsSUFBSSxDQUFDQSxpQkFBaUIsQ0FBQ0ksS0FBSztRQUM1QixJQUFJLENBQUN1SCxzQkFBc0IsSUFBSW5CO0lBQ2hDO0lBRUEsdUZBQXVGLEdBQ3ZGLEFBQVFtQix1QkFBdUIsR0FBR25CLE9BQWlCLEVBQUU7UUFDcEQsS0FBSyxNQUFNekQsVUFBVXlELFFBQVM7WUFDN0IsS0FBSyxNQUFNLENBQUNvQixLQUFLQyxRQUFRLElBQUksSUFBSSxDQUFDckksWUFBWSxDQUFFO2dCQUMvQyxNQUFNc0ksV0FBV0QsUUFBUW5CLE1BQU0sQ0FBQyxDQUFDdkMsSUFBTUEsTUFBTXBCO2dCQUM3QyxJQUFJK0UsU0FBU3hLLE1BQU0sS0FBSyxHQUFHO29CQUMxQixJQUFJLENBQUNrQyxZQUFZLENBQUN1SSxNQUFNLENBQUNIO2dCQUMxQixPQUFPO29CQUNOLElBQUksQ0FBQ3BJLFlBQVksQ0FBQzZCLEdBQUcsQ0FBQ3VHLEtBQUtFO2dCQUM1QjtZQUNEO1FBQ0Q7SUFDRDtJQUVRdEcsMkJBQTJCO1FBQ2xDLEtBQUssTUFBTXlELFlBQVksSUFBSSxDQUFDbEcsTUFBTSxDQUFDaUosZUFBZSxHQUFJO1lBQ3JELElBQUksQ0FBQ3pJLFdBQVcsQ0FBQzhCLEdBQUcsQ0FBQzRELFVBQVU7UUFDaEM7SUFDRDtJQUVROEIsT0FBTzlCLFFBQWdCLEVBQUU7UUFDaEMsT0FBTzFJLG9CQUFvQkwsS0FBS3lELE9BQU8sQ0FBQ3NGO0lBQ3pDO0lBRVFwQixVQUFVckIsVUFBNkIsRUFBWTtRQUMxRCxPQUFPQSxXQUFXeEUsR0FBRyxDQUNwQixDQUFDbUQsWUFBYyxJQUFJLENBQUNsQyxPQUFPLENBQUMyRCxHQUFHLENBQUN6QixZQUFZRyxTQUFTcEYsS0FBSytMLFFBQVEsQ0FBQzlHO0lBRXJFO0lBRVEyQyxlQUF5QjtRQUNoQyxNQUFNekcsV0FBVztlQUFJLElBQUksQ0FBQ2dDLGVBQWU7U0FBQyxDQUFDckIsR0FBRyxDQUFDLENBQUM4SCxXQUFhLElBQUksQ0FBQ29DLGFBQWEsQ0FBQ3BDO1FBQ2hGLElBQUksQ0FBQ3pHLGVBQWUsQ0FBQ2UsS0FBSztRQUMxQixPQUFPL0M7SUFDUjtJQUVRNkssY0FBY3BDLFFBQWdCLEVBQVU7UUFDL0MsTUFBTXFDLE9BQU8sSUFBSSxDQUFDcEosTUFBTSxDQUFDcUYsWUFBWSxJQUFJZ0U7UUFDekMsSUFBSUQsUUFBUSxNQUFNO1lBQ2pCLE1BQU1FLE1BQU1uTSxLQUFLb00sUUFBUSxDQUFDcE0sS0FBS3lELE9BQU8sQ0FBQ3dJLE9BQU9yQztZQUM5QyxJQUFJdUMsUUFBUSxNQUFNLENBQUNBLElBQUlFLFVBQVUsQ0FBQyxTQUFTLENBQUNyTSxLQUFLc00sVUFBVSxDQUFDSCxNQUFNO2dCQUNqRSxPQUFPQSxJQUFJSSxVQUFVLENBQUMsTUFBTTtZQUM3QjtRQUNEO1FBQ0EsT0FBT3ZNLEtBQUsrTCxRQUFRLENBQUNuQztJQUN0QjtBQUNEIn0=
|